1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * Fibre Channel SCSI ULP Mapping driver
26  */
27 
28 #include <sys/scsi/scsi.h>
29 #include <sys/types.h>
30 #include <sys/varargs.h>
31 #include <sys/devctl.h>
32 #include <sys/thread.h>
33 #include <sys/thread.h>
34 #include <sys/open.h>
35 #include <sys/file.h>
36 #include <sys/sunndi.h>
37 #include <sys/console.h>
38 #include <sys/proc.h>
39 #include <sys/time.h>
40 #include <sys/utsname.h>
41 #include <sys/scsi/impl/scsi_reset_notify.h>
42 #include <sys/ndi_impldefs.h>
43 #include <sys/byteorder.h>
44 #include <sys/fs/dv_node.h>
45 #include <sys/ctype.h>
46 #include <sys/sunmdi.h>
47 
48 #include <sys/fibre-channel/fc.h>
49 #include <sys/fibre-channel/impl/fc_ulpif.h>
50 #include <sys/fibre-channel/ulp/fcpvar.h>
51 
52 /*
53  * Discovery Process
54  * =================
55  *
56  *    The discovery process is a major function of FCP.	 In order to help
57  * understand that function a flow diagram is given here.  This diagram
58  * doesn't claim to cover all the cases and the events that can occur during
59  * the discovery process nor the subtleties of the code.  The code paths shown
60  * are simplified.  Its purpose is to help the reader (and potentially bug
61  * fixer) have an overall view of the logic of the code.  For that reason the
62  * diagram covers the simple case of the line coming up cleanly or of a new
63  * port attaching to FCP the link being up.  The reader must keep in mind
64  * that:
65  *
66  *	- There are special cases where bringing devices online and offline
67  *	  is driven by Ioctl.
68  *
69  *	- The behavior of the discovery process can be modified through the
70  *	  .conf file.
71  *
72  *	- The line can go down and come back up at any time during the
73  *	  discovery process which explains some of the complexity of the code.
74  *
75  * ............................................................................
76  *
77  * STEP 1: The line comes up or a new Fibre Channel port attaches to FCP.
78  *
79  *
80  *			+-------------------------+
81  *   fp/fctl module --->|    fcp_port_attach	  |
82  *			+-------------------------+
83  *	   |			     |
84  *	   |			     |
85  *	   |			     v
86  *	   |		+-------------------------+
87  *	   |		| fcp_handle_port_attach  |
88  *	   |		+-------------------------+
89  *	   |				|
90  *	   |				|
91  *	   +--------------------+	|
92  *				|	|
93  *				v	v
94  *			+-------------------------+
95  *			|   fcp_statec_callback	  |
96  *			+-------------------------+
97  *				    |
98  *				    |
99  *				    v
100  *			+-------------------------+
101  *			|    fcp_handle_devices	  |
102  *			+-------------------------+
103  *				    |
104  *				    |
105  *				    v
106  *			+-------------------------+
107  *			|   fcp_handle_mapflags	  |
108  *			+-------------------------+
109  *				    |
110  *				    |
111  *				    v
112  *			+-------------------------+
113  *			|     fcp_send_els	  |
114  *			|			  |
115  *			| PLOGI or PRLI To all the|
116  *			| reachable devices.	  |
117  *			+-------------------------+
118  *
119  *
120  * ............................................................................
121  *
122  * STEP 2: The callback functions of the PLOGI and/or PRLI requests sent during
123  *	   STEP 1 are called (it is actually the same function).
124  *
125  *
126  *			+-------------------------+
127  *			|    fcp_icmd_callback	  |
128  *   fp/fctl module --->|			  |
129  *			| callback for PLOGI and  |
130  *			| PRLI.			  |
131  *			+-------------------------+
132  *				     |
133  *				     |
134  *	    Received PLOGI Accept   /-\	  Received PRLI Accept
135  *		       _ _ _ _ _ _ /   \_ _ _ _ _ _
136  *		      |		   \   /	   |
137  *		      |		    \-/		   |
138  *		      |				   |
139  *		      v				   v
140  *	+-------------------------+	+-------------------------+
141  *	|     fcp_send_els	  |	|     fcp_send_scsi	  |
142  *	|			  |	|			  |
143  *	|	  PRLI		  |	|	REPORT_LUN	  |
144  *	+-------------------------+	+-------------------------+
145  *
146  * ............................................................................
147  *
148  * STEP 3: The callback functions of the SCSI commands issued by FCP are called
149  *	   (It is actually the same function).
150  *
151  *
152  *			    +-------------------------+
153  *   fp/fctl module ------->|	 fcp_scsi_callback    |
154  *			    +-------------------------+
155  *					|
156  *					|
157  *					|
158  *	Receive REPORT_LUN reply       /-\	Receive INQUIRY PAGE83 reply
159  *		  _ _ _ _ _ _ _ _ _ _ /	  \_ _ _ _ _ _ _ _ _ _ _ _
160  *		 |		      \	  /			  |
161  *		 |		       \-/			  |
162  *		 |			|			  |
163  *		 | Receive INQUIRY reply|			  |
164  *		 |			|			  |
165  *		 v			v			  v
166  * +------------------------+ +----------------------+ +----------------------+
167  * |  fcp_handle_reportlun  | |	 fcp_handle_inquiry  | |  fcp_handle_page83   |
168  * |(Called for each Target)| | (Called for each LUN)| |(Called for each LUN) |
169  * +------------------------+ +----------------------+ +----------------------+
170  *		 |			|			  |
171  *		 |			|			  |
172  *		 |			|			  |
173  *		 v			v			  |
174  *     +-----------------+	+-----------------+		  |
175  *     |  fcp_send_scsi	 |	|  fcp_send_scsi  |		  |
176  *     |		 |	|		  |		  |
177  *     |     INQUIRY	 |	| INQUIRY PAGE83  |		  |
178  *     |  (To each LUN)	 |	+-----------------+		  |
179  *     +-----------------+					  |
180  *								  |
181  *								  v
182  *						      +------------------------+
183  *						      |	 fcp_call_finish_init  |
184  *						      +------------------------+
185  *								  |
186  *								  v
187  *						 +-----------------------------+
188  *						 |  fcp_call_finish_init_held  |
189  *						 +-----------------------------+
190  *								  |
191  *								  |
192  *			   All LUNs scanned			 /-\
193  *			       _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ /   \
194  *			      |					\   /
195  *			      |					 \-/
196  *			      v					  |
197  *		     +------------------+			  |
198  *		     |	fcp_finish_tgt	|			  |
199  *		     +------------------+			  |
200  *			      |	  Target Not Offline and	  |
201  *  Target Not Offline and    |	  not marked and tgt_node_state	  |
202  *  marked		     /-\  not FCP_TGT_NODE_ON_DEMAND	  |
203  *		_ _ _ _ _ _ /	\_ _ _ _ _ _ _ _		  |
204  *	       |	    \	/		|		  |
205  *	       |	     \-/		|		  |
206  *	       v				v		  |
207  * +----------------------------+     +-------------------+	  |
208  * |	 fcp_offline_target	|     |	 fcp_create_luns  |	  |
209  * |				|     +-------------------+	  |
210  * | A structure fcp_tgt_elem	|		|		  |
211  * | is created and queued in	|		v		  |
212  * | the FCP port list		|     +-------------------+	  |
213  * | port_offline_tgts.	 It	|     |	 fcp_pass_to_hp	  |	  |
214  * | will be unqueued by the	|     |			  |	  |
215  * | watchdog timer.		|     | Called for each	  |	  |
216  * +----------------------------+     | LUN. Dispatches	  |	  |
217  *		  |		      | fcp_hp_task	  |	  |
218  *		  |		      +-------------------+	  |
219  *		  |				|		  |
220  *		  |				|		  |
221  *		  |				|		  |
222  *		  |				+---------------->|
223  *		  |						  |
224  *		  +---------------------------------------------->|
225  *								  |
226  *								  |
227  *		All the targets (devices) have been scanned	 /-\
228  *				_ _ _ _	_ _ _ _	_ _ _ _ _ _ _ _ /   \
229  *			       |				\   /
230  *			       |				 \-/
231  *	    +-------------------------------------+		  |
232  *	    |		fcp_finish_init		  |		  |
233  *	    |					  |		  |
234  *	    | Signal broadcasts the condition	  |		  |
235  *	    | variable port_config_cv of the FCP  |		  |
236  *	    | port.  One potential code sequence  |		  |
237  *	    | waiting on the condition variable	  |		  |
238  *	    | the code sequence handling	  |		  |
239  *	    | BUS_CONFIG_ALL and BUS_CONFIG_DRIVER|		  |
240  *	    | The other is in the function	  |		  |
241  *	    | fcp_reconfig_wait which is called	  |		  |
242  *	    | in the transmit path preventing IOs |		  |
243  *	    | from going through till the disco-  |		  |
244  *	    | very process is over.		  |		  |
245  *	    +-------------------------------------+		  |
246  *			       |				  |
247  *			       |				  |
248  *			       +--------------------------------->|
249  *								  |
250  *								  v
251  *								Return
252  *
253  * ............................................................................
254  *
255  * STEP 4: The hot plug task is called (for each fcp_hp_elem).
256  *
257  *
258  *			+-------------------------+
259  *			|      fcp_hp_task	  |
260  *			+-------------------------+
261  *				     |
262  *				     |
263  *				     v
264  *			+-------------------------+
265  *			|     fcp_trigger_lun	  |
266  *			+-------------------------+
267  *				     |
268  *				     |
269  *				     v
270  *		   Bring offline    /-\	 Bring online
271  *		  _ _ _ _ _ _ _ _ _/   \_ _ _ _ _ _ _ _ _ _
272  *		 |		   \   /		   |
273  *		 |		    \-/			   |
274  *		 v					   v
275  *    +---------------------+			+-----------------------+
276  *    |	 fcp_offline_child  |			|      fcp_get_cip	|
277  *    +---------------------+			|			|
278  *						| Creates a dev_info_t	|
279  *						| or a mdi_pathinfo_t	|
280  *						| depending on whether	|
281  *						| mpxio is on or off.	|
282  *						+-----------------------+
283  *							   |
284  *							   |
285  *							   v
286  *						+-----------------------+
287  *						|  fcp_online_child	|
288  *						|			|
289  *						| Set device online	|
290  *						| using NDI or MDI.	|
291  *						+-----------------------+
292  *
293  * ............................................................................
294  *
295  * STEP 5: The watchdog timer expires.	The watch dog timer does much more that
296  *	   what is described here.  We only show the target offline path.
297  *
298  *
299  *			 +--------------------------+
300  *			 |	  fcp_watch	    |
301  *			 +--------------------------+
302  *				       |
303  *				       |
304  *				       v
305  *			 +--------------------------+
306  *			 |  fcp_scan_offline_tgts   |
307  *			 +--------------------------+
308  *				       |
309  *				       |
310  *				       v
311  *			 +--------------------------+
312  *			 |  fcp_offline_target_now  |
313  *			 +--------------------------+
314  *				       |
315  *				       |
316  *				       v
317  *			 +--------------------------+
318  *			 |   fcp_offline_tgt_luns   |
319  *			 +--------------------------+
320  *				       |
321  *				       |
322  *				       v
323  *			 +--------------------------+
324  *			 |     fcp_offline_lun	    |
325  *			 +--------------------------+
326  *				       |
327  *				       |
328  *				       v
329  *		     +----------------------------------+
330  *		     |	     fcp_offline_lun_now	|
331  *		     |					|
332  *		     | A request (or two if mpxio) is	|
333  *		     | sent to the hot plug task using	|
334  *		     | a fcp_hp_elem structure.		|
335  *		     +----------------------------------+
336  */
337 
338 /*
339  * Functions registered with DDI framework
340  */
341 static int fcp_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
342 static int fcp_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
343 static int fcp_open(dev_t *devp, int flag, int otype, cred_t *credp);
344 static int fcp_close(dev_t dev, int flag, int otype, cred_t *credp);
345 static int fcp_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
346     cred_t *credp, int *rval);
347 
348 /*
349  * Functions registered with FC Transport framework
350  */
351 static int fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo,
352     fc_attach_cmd_t cmd,  uint32_t s_id);
353 static int fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info,
354     fc_detach_cmd_t cmd);
355 static int fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev,
356     int cmd, intptr_t data, int mode, cred_t *credp, int *rval,
357     uint32_t claimed);
358 static int fcp_els_callback(opaque_t ulph, opaque_t port_handle,
359     fc_unsol_buf_t *buf, uint32_t claimed);
360 static int fcp_data_callback(opaque_t ulph, opaque_t port_handle,
361     fc_unsol_buf_t *buf, uint32_t claimed);
362 static void fcp_statec_callback(opaque_t ulph, opaque_t port_handle,
363     uint32_t port_state, uint32_t port_top, fc_portmap_t *devlist,
364     uint32_t  dev_cnt, uint32_t port_sid);
365 
366 /*
367  * Functions registered with SCSA framework
368  */
369 static int fcp_phys_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
370     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
371 static int fcp_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
372     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
373 static void fcp_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
374     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
375 static int fcp_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt);
376 static int fcp_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
377 static int fcp_scsi_reset(struct scsi_address *ap, int level);
378 static int fcp_scsi_getcap(struct scsi_address *ap, char *cap, int whom);
379 static int fcp_scsi_setcap(struct scsi_address *ap, char *cap, int value,
380     int whom);
381 static void fcp_pkt_teardown(struct scsi_pkt *pkt);
382 static int fcp_scsi_reset_notify(struct scsi_address *ap, int flag,
383     void (*callback)(caddr_t), caddr_t arg);
384 static int fcp_scsi_bus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
385     char *name, ddi_eventcookie_t *event_cookiep);
386 static int fcp_scsi_bus_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
387     ddi_eventcookie_t eventid, void (*callback)(), void *arg,
388     ddi_callback_id_t *cb_id);
389 static int fcp_scsi_bus_remove_eventcall(dev_info_t *devi,
390     ddi_callback_id_t cb_id);
391 static int fcp_scsi_bus_post_event(dev_info_t *dip, dev_info_t *rdip,
392     ddi_eventcookie_t eventid, void *impldata);
393 static int fcp_scsi_bus_config(dev_info_t *parent, uint_t flag,
394     ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
395 static int fcp_scsi_bus_unconfig(dev_info_t *parent, uint_t flag,
396     ddi_bus_config_op_t op, void *arg);
397 
398 /*
399  * Internal functions
400  */
401 static int fcp_setup_device_data_ioctl(int cmd, struct fcp_ioctl *data,
402     int mode, int *rval);
403 
404 static int fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi,
405     int mode, int *rval);
406 static int fcp_copyin_scsi_cmd(caddr_t base_addr,
407     struct fcp_scsi_cmd *fscsi, int mode);
408 static int fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi,
409     caddr_t base_addr, int mode);
410 static int fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi);
411 
412 static struct fcp_tgt *fcp_port_create_tgt(struct fcp_port *pptr,
413     la_wwn_t *pwwn, int	*ret_val, int *fc_status, int *fc_pkt_state,
414     int *fc_pkt_reason, int *fc_pkt_action);
415 static int fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status,
416     int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action);
417 static int fcp_tgt_send_prli(struct fcp_tgt	*ptgt, int *fc_status,
418     int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action);
419 static void fcp_ipkt_sema_init(struct fcp_ipkt *icmd);
420 static int fcp_ipkt_sema_wait(struct fcp_ipkt *icmd);
421 static void fcp_ipkt_sema_callback(struct fc_packet *fpkt);
422 static void fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd);
423 
424 static void fcp_handle_devices(struct fcp_port *pptr,
425     fc_portmap_t devlist[], uint32_t dev_cnt, int link_cnt,
426     fcp_map_tag_t *map_tag, int cause);
427 static int fcp_handle_mapflags(struct fcp_port *pptr,
428     struct fcp_tgt *ptgt, fc_portmap_t *map_entry, int link_cnt,
429     int tgt_cnt, int cause);
430 static int fcp_handle_reportlun_changed(struct fcp_tgt *ptgt, int cause);
431 static int fcp_send_els(struct fcp_port *pptr, struct fcp_tgt *ptgt,
432     struct fcp_ipkt *icmd, uchar_t opcode, int lcount, int tcount, int cause);
433 static void fcp_update_state(struct fcp_port *pptr, uint32_t state,
434     int cause);
435 static void fcp_update_tgt_state(struct fcp_tgt *ptgt, int flag,
436     uint32_t state);
437 static struct fcp_port *fcp_get_port(opaque_t port_handle);
438 static void fcp_unsol_callback(fc_packet_t *fpkt);
439 static void fcp_unsol_resp_init(fc_packet_t *pkt, fc_unsol_buf_t *buf,
440     uchar_t r_ctl, uchar_t type);
441 static int fcp_unsol_prli(struct fcp_port *pptr, fc_unsol_buf_t *buf);
442 static struct fcp_ipkt *fcp_icmd_alloc(struct fcp_port *pptr,
443     struct fcp_tgt *ptgt, int cmd_len, int resp_len, int data_len,
444     int nodma, int lcount, int tcount, int cause, uint32_t rscn_count);
445 static void fcp_icmd_free(struct fcp_port *pptr, struct fcp_ipkt *icmd);
446 static int fcp_alloc_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd,
447     int nodma, int flags);
448 static void fcp_free_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd);
449 static struct fcp_tgt *fcp_lookup_target(struct fcp_port *pptr,
450     uchar_t *wwn);
451 static struct fcp_tgt *fcp_get_target_by_did(struct fcp_port *pptr,
452     uint32_t d_id);
453 static void fcp_icmd_callback(fc_packet_t *fpkt);
454 static int fcp_send_scsi(struct fcp_lun *plun, uchar_t opcode,
455     int len, int lcount, int tcount, int cause, uint32_t rscn_count);
456 static int fcp_check_reportlun(struct fcp_rsp *rsp, fc_packet_t *fpkt);
457 static void fcp_scsi_callback(fc_packet_t *fpkt);
458 static void fcp_retry_scsi_cmd(fc_packet_t *fpkt);
459 static void fcp_handle_inquiry(fc_packet_t *fpkt, struct fcp_ipkt *icmd);
460 static void fcp_handle_reportlun(fc_packet_t *fpkt, struct fcp_ipkt *icmd);
461 static struct fcp_lun *fcp_get_lun(struct fcp_tgt *ptgt,
462     uint16_t lun_num);
463 static int fcp_finish_tgt(struct fcp_port *pptr, struct fcp_tgt *ptgt,
464     int link_cnt, int tgt_cnt, int cause);
465 static void fcp_finish_init(struct fcp_port *pptr);
466 static void fcp_create_luns(struct fcp_tgt *ptgt, int link_cnt,
467     int tgt_cnt, int cause);
468 static int fcp_trigger_lun(struct fcp_lun *plun, child_info_t *cip,
469     int old_mpxio, int online, int link_cnt, int tgt_cnt, int flags);
470 static int fcp_offline_target(struct fcp_port *pptr, struct fcp_tgt *ptgt,
471     int link_cnt, int tgt_cnt, int nowait, int flags);
472 static void fcp_offline_target_now(struct fcp_port *pptr,
473     struct fcp_tgt *ptgt, int link_cnt, int tgt_cnt, int flags);
474 static void fcp_offline_tgt_luns(struct fcp_tgt *ptgt, int link_cnt,
475     int tgt_cnt, int flags);
476 static void fcp_offline_lun(struct fcp_lun *plun, int link_cnt, int tgt_cnt,
477     int nowait, int flags);
478 static void fcp_prepare_offline_lun(struct fcp_lun *plun, int link_cnt,
479     int tgt_cnt);
480 static void fcp_offline_lun_now(struct fcp_lun *plun, int link_cnt,
481     int tgt_cnt, int flags);
482 static void fcp_scan_offline_luns(struct fcp_port *pptr);
483 static void fcp_scan_offline_tgts(struct fcp_port *pptr);
484 static void fcp_update_offline_flags(struct fcp_lun *plun);
485 static struct fcp_pkt *fcp_scan_commands(struct fcp_lun *plun);
486 static void fcp_abort_commands(struct fcp_pkt *head, struct
487     fcp_port *pptr);
488 static void fcp_cmd_callback(fc_packet_t *fpkt);
489 static void fcp_complete_pkt(fc_packet_t *fpkt);
490 static int fcp_validate_fcp_response(struct fcp_rsp *rsp,
491     struct fcp_port *pptr);
492 static int fcp_device_changed(struct fcp_port *pptr, struct fcp_tgt *ptgt,
493     fc_portmap_t *map_entry, int link_cnt, int tgt_cnt, int cause);
494 static struct fcp_lun *fcp_alloc_lun(struct fcp_tgt *ptgt);
495 static void fcp_dealloc_lun(struct fcp_lun *plun);
496 static struct fcp_tgt *fcp_alloc_tgt(struct fcp_port *pptr,
497     fc_portmap_t *map_entry, int link_cnt);
498 static void fcp_dealloc_tgt(struct fcp_tgt *ptgt);
499 static void fcp_queue_ipkt(struct fcp_port *pptr, fc_packet_t *fpkt);
500 static int fcp_transport(opaque_t port_handle, fc_packet_t *fpkt,
501     int internal);
502 static void fcp_log(int level, dev_info_t *dip, const char *fmt, ...);
503 static int fcp_handle_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo,
504     uint32_t s_id, int instance);
505 static int fcp_handle_port_detach(struct fcp_port *pptr, int flag,
506     int instance);
507 static void fcp_cleanup_port(struct fcp_port *pptr, int instance);
508 static int fcp_kmem_cache_constructor(struct scsi_pkt *, scsi_hba_tran_t *,
509     int);
510 static void fcp_kmem_cache_destructor(struct  scsi_pkt *, scsi_hba_tran_t *);
511 static int fcp_pkt_setup(struct scsi_pkt *, int (*)(), caddr_t);
512 static int fcp_alloc_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt,
513     int flags);
514 static void fcp_free_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt);
515 static int fcp_reset_target(struct scsi_address *ap, int level);
516 static int fcp_commoncap(struct scsi_address *ap, char *cap,
517     int val, int tgtonly, int doset);
518 static int fcp_scsi_get_name(struct scsi_device *sd, char *name, int len);
519 static int fcp_scsi_get_bus_addr(struct scsi_device *sd, char *name, int len);
520 static int fcp_linkreset(struct fcp_port *pptr, struct scsi_address *ap,
521     int sleep);
522 static int fcp_handle_port_resume(opaque_t ulph, fc_ulp_port_info_t *pinfo,
523     uint32_t s_id, fc_attach_cmd_t cmd, int instance);
524 static void fcp_cp_pinfo(struct fcp_port *pptr, fc_ulp_port_info_t *pinfo);
525 static void fcp_process_elem(struct fcp_hp_elem *elem, int result);
526 static child_info_t *fcp_get_cip(struct fcp_lun *plun, child_info_t *cip,
527     int lcount, int tcount);
528 static int fcp_is_dip_present(struct fcp_lun *plun, dev_info_t *cdip);
529 static int fcp_is_child_present(struct fcp_lun *plun, child_info_t *cip);
530 static dev_info_t *fcp_create_dip(struct fcp_lun *plun, int link_cnt,
531     int tgt_cnt);
532 static dev_info_t *fcp_find_existing_dip(struct fcp_lun *plun,
533     dev_info_t *pdip, caddr_t name);
534 static int fcp_online_child(struct fcp_lun *plun, child_info_t *cip,
535     int lcount, int tcount, int flags, int *circ);
536 static int fcp_offline_child(struct fcp_lun *plun, child_info_t *cip,
537     int lcount, int tcount, int flags, int *circ);
538 static void fcp_remove_child(struct fcp_lun *plun);
539 static void fcp_watch(void *arg);
540 static void fcp_check_reset_delay(struct fcp_port *pptr);
541 static void fcp_abort_all(struct fcp_port *pptr, struct fcp_tgt *ttgt,
542     struct fcp_lun *rlun, int tgt_cnt);
543 struct fcp_port *fcp_soft_state_unlink(struct fcp_port *pptr);
544 static struct fcp_lun *fcp_lookup_lun(struct fcp_port *pptr,
545     uchar_t *wwn, uint16_t lun);
546 static void fcp_prepare_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd,
547     struct fcp_lun *plun);
548 static void fcp_post_callback(struct fcp_pkt *cmd);
549 static int fcp_dopoll(struct fcp_port *pptr, struct fcp_pkt *cmd);
550 static struct fcp_port *fcp_dip2port(dev_info_t *dip);
551 struct fcp_lun *fcp_get_lun_from_cip(struct fcp_port *pptr,
552     child_info_t *cip);
553 static int fcp_pass_to_hp_and_wait(struct fcp_port *pptr,
554     struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt,
555     int tgt_cnt, int flags);
556 static struct fcp_hp_elem *fcp_pass_to_hp(struct fcp_port *pptr,
557     struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt,
558     int tgt_cnt, int flags, int wait);
559 static void fcp_retransport_cmd(struct fcp_port *pptr,
560     struct fcp_pkt *cmd);
561 static void fcp_fail_cmd(struct fcp_pkt *cmd, uchar_t reason,
562     uint_t statistics);
563 static void fcp_queue_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd);
564 static void fcp_update_targets(struct fcp_port *pptr,
565     fc_portmap_t *dev_list, uint32_t count, uint32_t state, int cause);
566 static int fcp_call_finish_init(struct fcp_port *pptr,
567     struct fcp_tgt *ptgt, int lcount, int tcount, int cause);
568 static int fcp_call_finish_init_held(struct fcp_port *pptr,
569     struct fcp_tgt *ptgt, int lcount, int tcount, int cause);
570 static void fcp_reconfigure_luns(void * tgt_handle);
571 static void fcp_free_targets(struct fcp_port *pptr);
572 static void fcp_free_target(struct fcp_tgt *ptgt);
573 static int fcp_is_retryable(struct fcp_ipkt *icmd);
574 static int fcp_create_on_demand(struct fcp_port *pptr, uchar_t *pwwn);
575 static void fcp_ascii_to_wwn(caddr_t string, uchar_t bytes[], unsigned int);
576 static void fcp_wwn_to_ascii(uchar_t bytes[], char *string);
577 static void fcp_print_error(fc_packet_t *fpkt);
578 static int fcp_handle_ipkt_errors(struct fcp_port *pptr,
579     struct fcp_tgt *ptgt, struct fcp_ipkt *icmd, int rval, caddr_t op);
580 static int fcp_outstanding_lun_cmds(struct fcp_tgt *ptgt);
581 static fc_portmap_t *fcp_construct_map(struct fcp_port *pptr,
582     uint32_t *dev_cnt);
583 static void fcp_offline_all(struct fcp_port *pptr, int lcount, int cause);
584 static int fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval);
585 static int fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *, int, int *,
586     struct fcp_ioctl *, struct fcp_port **);
587 static char *fcp_get_lun_path(struct fcp_lun *plun);
588 static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode,
589     int *rval);
590 static int fcp_do_ns_registry(struct fcp_port *pptr, uint32_t s_id);
591 static void fcp_retry_ns_registry(struct fcp_port *pptr, uint32_t s_id);
592 static char *fcp_get_lun_path(struct fcp_lun *plun);
593 static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode,
594     int *rval);
595 static void fcp_reconfig_wait(struct fcp_port *pptr);
596 
597 /*
598  * New functions added for mpxio support
599  */
600 static int fcp_virt_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
601     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
602 static mdi_pathinfo_t *fcp_create_pip(struct fcp_lun *plun, int lcount,
603     int tcount);
604 static mdi_pathinfo_t *fcp_find_existing_pip(struct fcp_lun *plun,
605     dev_info_t *pdip);
606 static int fcp_is_pip_present(struct fcp_lun *plun, mdi_pathinfo_t *pip);
607 static void fcp_handle_page83(fc_packet_t *, struct fcp_ipkt *, int);
608 static void fcp_update_mpxio_path_verifybusy(struct fcp_port *pptr);
609 static int fcp_copy_guid_2_lun_block(struct fcp_lun *plun, char *guidp);
610 static int fcp_update_mpxio_path(struct fcp_lun *plun, child_info_t *cip,
611     int what);
612 static int fcp_is_reconfig_needed(struct fcp_tgt *ptgt,
613     fc_packet_t *fpkt);
614 static int fcp_symmetric_device_probe(struct fcp_lun *plun);
615 
616 /*
617  * New functions added for lun masking support
618  */
619 static void fcp_read_blacklist(dev_info_t *dip,
620     struct fcp_black_list_entry **pplun_blacklist);
621 static void fcp_mask_pwwn_lun(char *curr_pwwn, char *curr_lun,
622     struct fcp_black_list_entry **pplun_blacklist);
623 static void fcp_add_one_mask(char *curr_pwwn, uint32_t lun_id,
624     struct fcp_black_list_entry **pplun_blacklist);
625 static int fcp_should_mask(la_wwn_t *wwn, uint32_t lun_id);
626 static void fcp_cleanup_blacklist(struct fcp_black_list_entry **lun_blacklist);
627 
628 /*
629  * New functions to support software FCA (like fcoei)
630  */
631 static struct scsi_pkt *fcp_pseudo_init_pkt(
632 	struct scsi_address *ap, struct scsi_pkt *pkt,
633 	struct buf *bp, int cmdlen, int statuslen,
634 	int tgtlen, int flags, int (*callback)(), caddr_t arg);
635 static void fcp_pseudo_destroy_pkt(
636 	struct scsi_address *ap, struct scsi_pkt *pkt);
637 static void fcp_pseudo_sync_pkt(
638 	struct scsi_address *ap, struct scsi_pkt *pkt);
639 static int fcp_pseudo_start(struct scsi_address *ap, struct scsi_pkt *pkt);
640 static void fcp_pseudo_dmafree(
641 	struct scsi_address *ap, struct scsi_pkt *pkt);
642 
643 extern struct mod_ops	mod_driverops;
644 /*
645  * This variable is defined in modctl.c and set to '1' after the root driver
646  * and fs are loaded.  It serves as an indication that the root filesystem can
647  * be used.
648  */
649 extern int		modrootloaded;
650 /*
651  * This table contains strings associated with the SCSI sense key codes.  It
652  * is used by FCP to print a clear explanation of the code returned in the
653  * sense information by a device.
654  */
655 extern char		*sense_keys[];
656 /*
657  * This device is created by the SCSI pseudo nexus driver (SCSI vHCI).	It is
658  * under this device that the paths to a physical device are created when
659  * MPxIO is used.
660  */
661 extern dev_info_t	*scsi_vhci_dip;
662 
663 /*
664  * Report lun processing
665  */
666 #define	FCP_LUN_ADDRESSING		0x80
667 #define	FCP_PD_ADDRESSING		0x00
668 #define	FCP_VOLUME_ADDRESSING		0x40
669 
670 #define	FCP_SVE_THROTTLE		0x28 /* Vicom */
671 #define	MAX_INT_DMA			0x7fffffff
672 #define	FCP_MAX_SENSE_LEN		252
673 #define	FCP_MAX_RESPONSE_LEN		0xffffff
674 /*
675  * Property definitions
676  */
677 #define	NODE_WWN_PROP	(char *)fcp_node_wwn_prop
678 #define	PORT_WWN_PROP	(char *)fcp_port_wwn_prop
679 #define	TARGET_PROP	(char *)fcp_target_prop
680 #define	LUN_PROP	(char *)fcp_lun_prop
681 #define	SAM_LUN_PROP	(char *)fcp_sam_lun_prop
682 #define	CONF_WWN_PROP	(char *)fcp_conf_wwn_prop
683 #define	OBP_BOOT_WWN	(char *)fcp_obp_boot_wwn
684 #define	MANUAL_CFG_ONLY	(char *)fcp_manual_config_only
685 #define	INIT_PORT_PROP	(char *)fcp_init_port_prop
686 #define	TGT_PORT_PROP	(char *)fcp_tgt_port_prop
687 #define	LUN_BLACKLIST_PROP	(char *)fcp_lun_blacklist_prop
688 /*
689  * Short hand macros.
690  */
691 #define	LUN_PORT	(plun->lun_tgt->tgt_port)
692 #define	LUN_TGT		(plun->lun_tgt)
693 
694 /*
695  * Driver private macros
696  */
697 #define	FCP_ATOB(x)	(((x) >= '0' && (x) <= '9') ? ((x) - '0') :	\
698 			((x) >= 'a' && (x) <= 'f') ?			\
699 			((x) - 'a' + 10) : ((x) - 'A' + 10))
700 
701 #define	FCP_MAX(a, b)	((a) > (b) ? (a) : (b))
702 
703 #define	FCP_N_NDI_EVENTS						\
704 	(sizeof (fcp_ndi_event_defs) / sizeof (ndi_event_definition_t))
705 
706 #define	FCP_LINK_STATE_CHANGED(p, c)			\
707 	((p)->port_link_cnt != (c)->ipkt_link_cnt)
708 
709 #define	FCP_TGT_STATE_CHANGED(t, c)			\
710 	((t)->tgt_change_cnt != (c)->ipkt_change_cnt)
711 
712 #define	FCP_STATE_CHANGED(p, t, c)		\
713 	(FCP_TGT_STATE_CHANGED(t, c))
714 
715 #define	FCP_MUST_RETRY(fpkt)				\
716 	((fpkt)->pkt_state == FC_PKT_LOCAL_BSY ||	\
717 	(fpkt)->pkt_state == FC_PKT_LOCAL_RJT ||	\
718 	(fpkt)->pkt_state == FC_PKT_TRAN_BSY ||	\
719 	(fpkt)->pkt_state == FC_PKT_ELS_IN_PROGRESS ||	\
720 	(fpkt)->pkt_state == FC_PKT_NPORT_BSY ||	\
721 	(fpkt)->pkt_state == FC_PKT_FABRIC_BSY ||	\
722 	(fpkt)->pkt_state == FC_PKT_PORT_OFFLINE ||	\
723 	(fpkt)->pkt_reason == FC_REASON_OFFLINE)
724 
725 #define	FCP_SENSE_REPORTLUN_CHANGED(es)		\
726 	((es)->es_key == KEY_UNIT_ATTENTION &&	\
727 	(es)->es_add_code == 0x3f &&		\
728 	(es)->es_qual_code == 0x0e)
729 
730 #define	FCP_SENSE_NO_LUN(es)			\
731 	((es)->es_key == KEY_ILLEGAL_REQUEST &&	\
732 	(es)->es_add_code == 0x25 &&		\
733 	(es)->es_qual_code == 0x0)
734 
735 #define	FCP_VERSION		"20090729-1.190"
736 #define	FCP_NAME_VERSION	"SunFC FCP v" FCP_VERSION
737 
738 #define	FCP_NUM_ELEMENTS(array)			\
739 	(sizeof (array) / sizeof ((array)[0]))
740 
741 /*
742  * Debugging, Error reporting, and tracing
743  */
744 #define	FCP_LOG_SIZE		1024 * 1024
745 
746 #define	FCP_LEVEL_1		0x00001		/* attach/detach PM CPR */
747 #define	FCP_LEVEL_2		0x00002		/* failures/Invalid data */
748 #define	FCP_LEVEL_3		0x00004		/* state change, discovery */
749 #define	FCP_LEVEL_4		0x00008		/* ULP messages */
750 #define	FCP_LEVEL_5		0x00010		/* ELS/SCSI cmds */
751 #define	FCP_LEVEL_6		0x00020		/* Transport failures */
752 #define	FCP_LEVEL_7		0x00040
753 #define	FCP_LEVEL_8		0x00080		/* I/O tracing */
754 #define	FCP_LEVEL_9		0x00100		/* I/O tracing */
755 
756 
757 
758 /*
759  * Log contents to system messages file
760  */
761 #define	FCP_MSG_LEVEL_1	(FCP_LEVEL_1 | FC_TRACE_LOG_MSG)
762 #define	FCP_MSG_LEVEL_2	(FCP_LEVEL_2 | FC_TRACE_LOG_MSG)
763 #define	FCP_MSG_LEVEL_3	(FCP_LEVEL_3 | FC_TRACE_LOG_MSG)
764 #define	FCP_MSG_LEVEL_4	(FCP_LEVEL_4 | FC_TRACE_LOG_MSG)
765 #define	FCP_MSG_LEVEL_5	(FCP_LEVEL_5 | FC_TRACE_LOG_MSG)
766 #define	FCP_MSG_LEVEL_6	(FCP_LEVEL_6 | FC_TRACE_LOG_MSG)
767 #define	FCP_MSG_LEVEL_7	(FCP_LEVEL_7 | FC_TRACE_LOG_MSG)
768 #define	FCP_MSG_LEVEL_8	(FCP_LEVEL_8 | FC_TRACE_LOG_MSG)
769 #define	FCP_MSG_LEVEL_9	(FCP_LEVEL_9 | FC_TRACE_LOG_MSG)
770 
771 
772 /*
773  * Log contents to trace buffer
774  */
775 #define	FCP_BUF_LEVEL_1	(FCP_LEVEL_1 | FC_TRACE_LOG_BUF)
776 #define	FCP_BUF_LEVEL_2	(FCP_LEVEL_2 | FC_TRACE_LOG_BUF)
777 #define	FCP_BUF_LEVEL_3	(FCP_LEVEL_3 | FC_TRACE_LOG_BUF)
778 #define	FCP_BUF_LEVEL_4	(FCP_LEVEL_4 | FC_TRACE_LOG_BUF)
779 #define	FCP_BUF_LEVEL_5	(FCP_LEVEL_5 | FC_TRACE_LOG_BUF)
780 #define	FCP_BUF_LEVEL_6	(FCP_LEVEL_6 | FC_TRACE_LOG_BUF)
781 #define	FCP_BUF_LEVEL_7	(FCP_LEVEL_7 | FC_TRACE_LOG_BUF)
782 #define	FCP_BUF_LEVEL_8	(FCP_LEVEL_8 | FC_TRACE_LOG_BUF)
783 #define	FCP_BUF_LEVEL_9	(FCP_LEVEL_9 | FC_TRACE_LOG_BUF)
784 
785 
786 /*
787  * Log contents to both system messages file and trace buffer
788  */
789 #define	FCP_MSG_BUF_LEVEL_1	(FCP_LEVEL_1 | FC_TRACE_LOG_BUF |	\
790 				FC_TRACE_LOG_MSG)
791 #define	FCP_MSG_BUF_LEVEL_2	(FCP_LEVEL_2 | FC_TRACE_LOG_BUF |	\
792 				FC_TRACE_LOG_MSG)
793 #define	FCP_MSG_BUF_LEVEL_3	(FCP_LEVEL_3 | FC_TRACE_LOG_BUF |	\
794 				FC_TRACE_LOG_MSG)
795 #define	FCP_MSG_BUF_LEVEL_4	(FCP_LEVEL_4 | FC_TRACE_LOG_BUF |	\
796 				FC_TRACE_LOG_MSG)
797 #define	FCP_MSG_BUF_LEVEL_5	(FCP_LEVEL_5 | FC_TRACE_LOG_BUF |	\
798 				FC_TRACE_LOG_MSG)
799 #define	FCP_MSG_BUF_LEVEL_6	(FCP_LEVEL_6 | FC_TRACE_LOG_BUF |	\
800 				FC_TRACE_LOG_MSG)
801 #define	FCP_MSG_BUF_LEVEL_7	(FCP_LEVEL_7 | FC_TRACE_LOG_BUF |	\
802 				FC_TRACE_LOG_MSG)
803 #define	FCP_MSG_BUF_LEVEL_8	(FCP_LEVEL_8 | FC_TRACE_LOG_BUF |	\
804 				FC_TRACE_LOG_MSG)
805 #define	FCP_MSG_BUF_LEVEL_9	(FCP_LEVEL_9 | FC_TRACE_LOG_BUF |	\
806 				FC_TRACE_LOG_MSG)
807 #ifdef DEBUG
808 #define	FCP_DTRACE	fc_trace_debug
809 #else
810 #define	FCP_DTRACE
811 #endif
812 
813 #define	FCP_TRACE	fc_trace_debug
814 
815 static struct cb_ops fcp_cb_ops = {
816 	fcp_open,			/* open */
817 	fcp_close,			/* close */
818 	nodev,				/* strategy */
819 	nodev,				/* print */
820 	nodev,				/* dump */
821 	nodev,				/* read */
822 	nodev,				/* write */
823 	fcp_ioctl,			/* ioctl */
824 	nodev,				/* devmap */
825 	nodev,				/* mmap */
826 	nodev,				/* segmap */
827 	nochpoll,			/* chpoll */
828 	ddi_prop_op,			/* cb_prop_op */
829 	0,				/* streamtab */
830 	D_NEW | D_MP | D_HOTPLUG,	/* cb_flag */
831 	CB_REV,				/* rev */
832 	nodev,				/* aread */
833 	nodev				/* awrite */
834 };
835 
836 
837 static struct dev_ops fcp_ops = {
838 	DEVO_REV,
839 	0,
840 	ddi_getinfo_1to1,
841 	nulldev,		/* identify */
842 	nulldev,		/* probe */
843 	fcp_attach,		/* attach and detach are mandatory */
844 	fcp_detach,
845 	nodev,			/* reset */
846 	&fcp_cb_ops,		/* cb_ops */
847 	NULL,			/* bus_ops */
848 	NULL,			/* power */
849 };
850 
851 
852 char *fcp_version = FCP_NAME_VERSION;
853 
854 static struct modldrv modldrv = {
855 	&mod_driverops,
856 	FCP_NAME_VERSION,
857 	&fcp_ops
858 };
859 
860 
861 static struct modlinkage modlinkage = {
862 	MODREV_1,
863 	&modldrv,
864 	NULL
865 };
866 
867 
868 static fc_ulp_modinfo_t fcp_modinfo = {
869 	&fcp_modinfo,			/* ulp_handle */
870 	FCTL_ULP_MODREV_4,		/* ulp_rev */
871 	FC4_SCSI_FCP,			/* ulp_type */
872 	"fcp",				/* ulp_name */
873 	FCP_STATEC_MASK,		/* ulp_statec_mask */
874 	fcp_port_attach,		/* ulp_port_attach */
875 	fcp_port_detach,		/* ulp_port_detach */
876 	fcp_port_ioctl,			/* ulp_port_ioctl */
877 	fcp_els_callback,		/* ulp_els_callback */
878 	fcp_data_callback,		/* ulp_data_callback */
879 	fcp_statec_callback		/* ulp_statec_callback */
880 };
881 
882 #ifdef	DEBUG
883 #define	FCP_TRACE_DEFAULT	(FC_TRACE_LOG_MASK | FCP_LEVEL_1 |	\
884 				FCP_LEVEL_2 | FCP_LEVEL_3 |		\
885 				FCP_LEVEL_4 | FCP_LEVEL_5 |		\
886 				FCP_LEVEL_6 | FCP_LEVEL_7)
887 #else
888 #define	FCP_TRACE_DEFAULT	(FC_TRACE_LOG_MASK | FCP_LEVEL_1 |	\
889 				FCP_LEVEL_2 | FCP_LEVEL_3 |		\
890 				FCP_LEVEL_4 | FCP_LEVEL_5 |		\
891 				FCP_LEVEL_6 | FCP_LEVEL_7)
892 #endif
893 
894 /* FCP global variables */
895 int			fcp_bus_config_debug = 0;
896 static int		fcp_log_size = FCP_LOG_SIZE;
897 static int		fcp_trace = FCP_TRACE_DEFAULT;
898 static fc_trace_logq_t	*fcp_logq = NULL;
899 static struct fcp_black_list_entry	*fcp_lun_blacklist = NULL;
900 /*
901  * The auto-configuration is set by default.  The only way of disabling it is
902  * through the property MANUAL_CFG_ONLY in the fcp.conf file.
903  */
904 static int		fcp_enable_auto_configuration = 1;
905 static int		fcp_max_bus_config_retries	= 4;
906 static int		fcp_lun_ready_retry = 300;
907 /*
908  * The value assigned to the following variable has changed several times due
909  * to a problem with the data underruns reporting of some firmware(s).	The
910  * current value of 50 gives a timeout value of 25 seconds for a max number
911  * of 256 LUNs.
912  */
913 static int		fcp_max_target_retries = 50;
914 /*
915  * Watchdog variables
916  * ------------------
917  *
918  * fcp_watchdog_init
919  *
920  *	Indicates if the watchdog timer is running or not.  This is actually
921  *	a counter of the number of Fibre Channel ports that attached.  When
922  *	the first port attaches the watchdog is started.  When the last port
923  *	detaches the watchdog timer is stopped.
924  *
925  * fcp_watchdog_time
926  *
927  *	This is the watchdog clock counter.  It is incremented by
928  *	fcp_watchdog_time each time the watchdog timer expires.
929  *
930  * fcp_watchdog_timeout
931  *
932  *	Increment value of the variable fcp_watchdog_time as well as the
933  *	the timeout value of the watchdog timer.  The unit is 1 second.	 It
934  *	is strange that this is not a #define	but a variable since the code
935  *	never changes this value.  The reason why it can be said that the
936  *	unit is 1 second is because the number of ticks for the watchdog
937  *	timer is determined like this:
938  *
939  *	    fcp_watchdog_tick = fcp_watchdog_timeout *
940  *				  drv_usectohz(1000000);
941  *
942  *	The value 1000000 is hard coded in the code.
943  *
944  * fcp_watchdog_tick
945  *
946  *	Watchdog timer value in ticks.
947  */
948 static int		fcp_watchdog_init = 0;
949 static int		fcp_watchdog_time = 0;
950 static int		fcp_watchdog_timeout = 1;
951 static int		fcp_watchdog_tick;
952 
953 /*
954  * fcp_offline_delay is a global variable to enable customisation of
955  * the timeout on link offlines or RSCNs. The default value is set
956  * to match FCP_OFFLINE_DELAY (20sec), which is 2*RA_TOV_els as
957  * specified in FCP4 Chapter 11 (see www.t10.org).
958  *
959  * The variable fcp_offline_delay is specified in SECONDS.
960  *
961  * If we made this a static var then the user would not be able to
962  * change it. This variable is set in fcp_attach().
963  */
964 unsigned int		fcp_offline_delay = FCP_OFFLINE_DELAY;
965 
966 static void		*fcp_softstate = NULL; /* for soft state */
967 static uchar_t		fcp_oflag = FCP_IDLE; /* open flag */
968 static kmutex_t		fcp_global_mutex;
969 static kmutex_t		fcp_ioctl_mutex;
970 static dev_info_t	*fcp_global_dip = NULL;
971 static timeout_id_t	fcp_watchdog_id;
972 const char		*fcp_lun_prop = "lun";
973 const char		*fcp_sam_lun_prop = "sam-lun";
974 const char		*fcp_target_prop = "target";
975 /*
976  * NOTE: consumers of "node-wwn" property include stmsboot in ON
977  * consolidation.
978  */
979 const char		*fcp_node_wwn_prop = "node-wwn";
980 const char		*fcp_port_wwn_prop = "port-wwn";
981 const char		*fcp_conf_wwn_prop = "fc-port-wwn";
982 const char		*fcp_obp_boot_wwn = "fc-boot-dev-portwwn";
983 const char		*fcp_manual_config_only = "manual_configuration_only";
984 const char		*fcp_init_port_prop = "initiator-port";
985 const char		*fcp_tgt_port_prop = "target-port";
986 const char		*fcp_lun_blacklist_prop = "pwwn-lun-blacklist";
987 
988 static struct fcp_port	*fcp_port_head = NULL;
989 static ddi_eventcookie_t	fcp_insert_eid;
990 static ddi_eventcookie_t	fcp_remove_eid;
991 
992 static ndi_event_definition_t	fcp_ndi_event_defs[] = {
993 	{ FCP_EVENT_TAG_INSERT, FCAL_INSERT_EVENT, EPL_KERNEL },
994 	{ FCP_EVENT_TAG_REMOVE, FCAL_REMOVE_EVENT, EPL_INTERRUPT }
995 };
996 
997 /*
998  * List of valid commands for the scsi_ioctl call
999  */
1000 static uint8_t scsi_ioctl_list[] = {
1001 	SCMD_INQUIRY,
1002 	SCMD_REPORT_LUN,
1003 	SCMD_READ_CAPACITY
1004 };
1005 
1006 /*
1007  * this is used to dummy up a report lun response for cases
1008  * where the target doesn't support it
1009  */
1010 static uchar_t fcp_dummy_lun[] = {
1011 	0x00,		/* MSB length (length = no of luns * 8) */
1012 	0x00,
1013 	0x00,
1014 	0x08,		/* LSB length */
1015 	0x00,		/* MSB reserved */
1016 	0x00,
1017 	0x00,
1018 	0x00,		/* LSB reserved */
1019 	FCP_PD_ADDRESSING,
1020 	0x00,		/* LUN is ZERO at the first level */
1021 	0x00,
1022 	0x00,		/* second level is zero */
1023 	0x00,
1024 	0x00,		/* third level is zero */
1025 	0x00,
1026 	0x00		/* fourth level is zero */
1027 };
1028 
1029 static uchar_t fcp_alpa_to_switch[] = {
1030 	0x00, 0x7d, 0x7c, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x7a, 0x00,
1031 	0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x78, 0x00, 0x00, 0x00,
1032 	0x00, 0x00, 0x00, 0x77, 0x76, 0x00, 0x00, 0x75, 0x00, 0x74,
1033 	0x73, 0x72, 0x00, 0x00, 0x00, 0x71, 0x00, 0x70, 0x6f, 0x6e,
1034 	0x00, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x00, 0x00, 0x67,
1035 	0x66, 0x65, 0x64, 0x63, 0x62, 0x00, 0x00, 0x61, 0x60, 0x00,
1036 	0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x5d,
1037 	0x5c, 0x5b, 0x00, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x00,
1038 	0x00, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x00, 0x00, 0x4e,
1039 	0x4d, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
1040 	0x00, 0x4a, 0x49, 0x48, 0x00, 0x47, 0x46, 0x45, 0x44, 0x43,
1041 	0x42, 0x00, 0x00, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x00,
1042 	0x00, 0x3b, 0x3a, 0x00, 0x39, 0x00, 0x00, 0x00, 0x38, 0x37,
1043 	0x36, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
1044 	0x00, 0x00, 0x00, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
1045 	0x00, 0x31, 0x30, 0x00, 0x00, 0x2f, 0x00, 0x2e, 0x2d, 0x2c,
1046 	0x00, 0x00, 0x00, 0x2b, 0x00, 0x2a, 0x29, 0x28, 0x00, 0x27,
1047 	0x26, 0x25, 0x24, 0x23, 0x22, 0x00, 0x00, 0x21, 0x20, 0x1f,
1048 	0x1e, 0x1d, 0x1c, 0x00, 0x00, 0x1b, 0x1a, 0x00, 0x19, 0x00,
1049 	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x17, 0x16, 0x15,
1050 	0x00, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x00, 0x00, 0x0e,
1051 	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x00, 0x00, 0x08, 0x07, 0x00,
1052 	0x06, 0x00, 0x00, 0x00, 0x05, 0x04, 0x03, 0x00, 0x02, 0x00,
1053 	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1054 };
1055 
1056 static caddr_t pid = "SESS01	      ";
1057 
1058 #if	!defined(lint)
1059 
1060 _NOTE(MUTEX_PROTECTS_DATA(fcp_global_mutex,
1061     fcp_port::fcp_next fcp_watchdog_id))
1062 
1063 _NOTE(DATA_READABLE_WITHOUT_LOCK(fcp_watchdog_time))
1064 
1065 _NOTE(SCHEME_PROTECTS_DATA("Unshared",
1066     fcp_insert_eid
1067     fcp_remove_eid
1068     fcp_watchdog_time))
1069 
1070 _NOTE(SCHEME_PROTECTS_DATA("Unshared",
1071     fcp_cb_ops
1072     fcp_ops
1073     callb_cpr))
1074 
1075 #endif /* lint */
1076 
1077 /*
1078  * This table is used to determine whether or not it's safe to copy in
1079  * the target node name for a lun.  Since all luns behind the same target
1080  * have the same wwnn, only tagets that do not support multiple luns are
1081  * eligible to be enumerated under mpxio if they aren't page83 compliant.
1082  */
1083 
1084 char *fcp_symmetric_disk_table[] = {
1085 	"SEAGATE ST",
1086 	"IBM	 DDYFT",
1087 	"SUNW	 SUNWGS",	/* Daktari enclosure */
1088 	"SUN	 SENA",		/* SES device */
1089 	"SUN	 SESS01"	/* VICOM SVE box */
1090 };
1091 
1092 int fcp_symmetric_disk_table_size =
1093 	sizeof (fcp_symmetric_disk_table)/sizeof (char *);
1094 
1095 /*
1096  * This structure is bogus. scsi_hba_attach_setup() requires, as in the kernel
1097  * will panic if you don't pass this in to the routine, this information.
1098  * Need to determine what the actual impact to the system is by providing
1099  * this information if any. Since dma allocation is done in pkt_init it may
1100  * not have any impact. These values are straight from the Writing Device
1101  * Driver manual.
1102  */
1103 static ddi_dma_attr_t pseudo_fca_dma_attr = {
1104 	DMA_ATTR_V0,	/* ddi_dma_attr version */
1105 	0,		/* low address */
1106 	0xffffffff,	/* high address */
1107 	0x00ffffff,	/* counter upper bound */
1108 	1,		/* alignment requirements */
1109 	0x3f,		/* burst sizes */
1110 	1,		/* minimum DMA access */
1111 	0xffffffff,	/* maximum DMA access */
1112 	(1 << 24) - 1,	/* segment boundary restrictions */
1113 	1,		/* scater/gather list length */
1114 	512,		/* device granularity */
1115 	0		/* DMA flags */
1116 };
1117 
1118 /*
1119  * The _init(9e) return value should be that of mod_install(9f). Under
1120  * some circumstances, a failure may not be related mod_install(9f) and
1121  * one would then require a return value to indicate the failure. Looking
1122  * at mod_install(9f), it is expected to return 0 for success and non-zero
1123  * for failure. mod_install(9f) for device drivers, further goes down the
1124  * calling chain and ends up in ddi_installdrv(), whose return values are
1125  * DDI_SUCCESS and DDI_FAILURE - There are also other functions in the
1126  * calling chain of mod_install(9f) which return values like EINVAL and
1127  * in some even return -1.
1128  *
1129  * To work around the vagaries of the mod_install() calling chain, return
1130  * either 0 or ENODEV depending on the success or failure of mod_install()
1131  */
1132 int
1133 _init(void)
1134 {
1135 	int rval;
1136 
1137 	/*
1138 	 * Allocate soft state and prepare to do ddi_soft_state_zalloc()
1139 	 * before registering with the transport first.
1140 	 */
1141 	if (ddi_soft_state_init(&fcp_softstate,
1142 	    sizeof (struct fcp_port), FCP_INIT_ITEMS) != 0) {
1143 		return (EINVAL);
1144 	}
1145 
1146 	mutex_init(&fcp_global_mutex, NULL, MUTEX_DRIVER, NULL);
1147 	mutex_init(&fcp_ioctl_mutex, NULL, MUTEX_DRIVER, NULL);
1148 
1149 	if ((rval = fc_ulp_add(&fcp_modinfo)) != FC_SUCCESS) {
1150 		cmn_err(CE_WARN, "fcp: fc_ulp_add failed");
1151 		mutex_destroy(&fcp_global_mutex);
1152 		mutex_destroy(&fcp_ioctl_mutex);
1153 		ddi_soft_state_fini(&fcp_softstate);
1154 		return (ENODEV);
1155 	}
1156 
1157 	fcp_logq = fc_trace_alloc_logq(fcp_log_size);
1158 
1159 	if ((rval = mod_install(&modlinkage)) != 0) {
1160 		fc_trace_free_logq(fcp_logq);
1161 		(void) fc_ulp_remove(&fcp_modinfo);
1162 		mutex_destroy(&fcp_global_mutex);
1163 		mutex_destroy(&fcp_ioctl_mutex);
1164 		ddi_soft_state_fini(&fcp_softstate);
1165 		rval = ENODEV;
1166 	}
1167 
1168 	return (rval);
1169 }
1170 
1171 
1172 /*
1173  * the system is done with us as a driver, so clean up
1174  */
1175 int
1176 _fini(void)
1177 {
1178 	int rval;
1179 
1180 	/*
1181 	 * don't start cleaning up until we know that the module remove
1182 	 * has worked  -- if this works, then we know that each instance
1183 	 * has successfully been DDI_DETACHed
1184 	 */
1185 	if ((rval = mod_remove(&modlinkage)) != 0) {
1186 		return (rval);
1187 	}
1188 
1189 	(void) fc_ulp_remove(&fcp_modinfo);
1190 
1191 	ddi_soft_state_fini(&fcp_softstate);
1192 	mutex_destroy(&fcp_global_mutex);
1193 	mutex_destroy(&fcp_ioctl_mutex);
1194 	fc_trace_free_logq(fcp_logq);
1195 
1196 	return (rval);
1197 }
1198 
1199 
1200 int
1201 _info(struct modinfo *modinfop)
1202 {
1203 	return (mod_info(&modlinkage, modinfop));
1204 }
1205 
1206 
1207 /*
1208  * attach the module
1209  */
1210 static int
1211 fcp_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
1212 {
1213 	int rval = DDI_SUCCESS;
1214 
1215 	FCP_DTRACE(fcp_logq, "fcp", fcp_trace,
1216 	    FCP_BUF_LEVEL_8, 0, "fcp module attach: cmd=0x%x", cmd);
1217 
1218 	if (cmd == DDI_ATTACH) {
1219 		/* The FCP pseudo device is created here. */
1220 		mutex_enter(&fcp_global_mutex);
1221 		fcp_global_dip = devi;
1222 		mutex_exit(&fcp_global_mutex);
1223 
1224 		if (ddi_create_minor_node(fcp_global_dip, "fcp", S_IFCHR,
1225 		    0, DDI_PSEUDO, 0) == DDI_SUCCESS) {
1226 			ddi_report_dev(fcp_global_dip);
1227 		} else {
1228 			cmn_err(CE_WARN, "FCP: Cannot create minor node");
1229 			mutex_enter(&fcp_global_mutex);
1230 			fcp_global_dip = NULL;
1231 			mutex_exit(&fcp_global_mutex);
1232 
1233 			rval = DDI_FAILURE;
1234 		}
1235 		/*
1236 		 * We check the fcp_offline_delay property at this
1237 		 * point. This variable is global for the driver,
1238 		 * not specific to an instance.
1239 		 *
1240 		 * We do not recommend setting the value to less
1241 		 * than 10 seconds (RA_TOV_els), or greater than
1242 		 * 60 seconds.
1243 		 */
1244 		fcp_offline_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
1245 		    devi, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1246 		    "fcp_offline_delay", FCP_OFFLINE_DELAY);
1247 		if ((fcp_offline_delay < 10) ||
1248 		    (fcp_offline_delay > 60)) {
1249 			cmn_err(CE_WARN, "Setting fcp_offline_delay "
1250 			    "to %d second(s). This is outside the "
1251 			    "recommended range of 10..60 seconds.",
1252 			    fcp_offline_delay);
1253 		}
1254 	}
1255 
1256 	return (rval);
1257 }
1258 
1259 
1260 /*ARGSUSED*/
1261 static int
1262 fcp_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
1263 {
1264 	int	res = DDI_SUCCESS;
1265 
1266 	FCP_DTRACE(fcp_logq, "fcp", fcp_trace,
1267 	    FCP_BUF_LEVEL_8, 0,	 "module detach: cmd=0x%x", cmd);
1268 
1269 	if (cmd == DDI_DETACH) {
1270 		/*
1271 		 * Check if there are active ports/threads. If there
1272 		 * are any, we will fail, else we will succeed (there
1273 		 * should not be much to clean up)
1274 		 */
1275 		mutex_enter(&fcp_global_mutex);
1276 		FCP_DTRACE(fcp_logq, "fcp",
1277 		    fcp_trace, FCP_BUF_LEVEL_8, 0,  "port_head=%p",
1278 		    (void *) fcp_port_head);
1279 
1280 		if (fcp_port_head == NULL) {
1281 			ddi_remove_minor_node(fcp_global_dip, NULL);
1282 			fcp_global_dip = NULL;
1283 			mutex_exit(&fcp_global_mutex);
1284 		} else {
1285 			mutex_exit(&fcp_global_mutex);
1286 			res = DDI_FAILURE;
1287 		}
1288 	}
1289 	FCP_DTRACE(fcp_logq, "fcp", fcp_trace,
1290 	    FCP_BUF_LEVEL_8, 0,	 "module detach returning %d", res);
1291 
1292 	return (res);
1293 }
1294 
1295 
1296 /* ARGSUSED */
1297 static int
1298 fcp_open(dev_t *devp, int flag, int otype, cred_t *credp)
1299 {
1300 	if (otype != OTYP_CHR) {
1301 		return (EINVAL);
1302 	}
1303 
1304 	/*
1305 	 * Allow only root to talk;
1306 	 */
1307 	if (drv_priv(credp)) {
1308 		return (EPERM);
1309 	}
1310 
1311 	mutex_enter(&fcp_global_mutex);
1312 	if (fcp_oflag & FCP_EXCL) {
1313 		mutex_exit(&fcp_global_mutex);
1314 		return (EBUSY);
1315 	}
1316 
1317 	if (flag & FEXCL) {
1318 		if (fcp_oflag & FCP_OPEN) {
1319 			mutex_exit(&fcp_global_mutex);
1320 			return (EBUSY);
1321 		}
1322 		fcp_oflag |= FCP_EXCL;
1323 	}
1324 	fcp_oflag |= FCP_OPEN;
1325 	mutex_exit(&fcp_global_mutex);
1326 
1327 	return (0);
1328 }
1329 
1330 
1331 /* ARGSUSED */
1332 static int
1333 fcp_close(dev_t dev, int flag, int otype, cred_t *credp)
1334 {
1335 	if (otype != OTYP_CHR) {
1336 		return (EINVAL);
1337 	}
1338 
1339 	mutex_enter(&fcp_global_mutex);
1340 	if (!(fcp_oflag & FCP_OPEN)) {
1341 		mutex_exit(&fcp_global_mutex);
1342 		return (ENODEV);
1343 	}
1344 	fcp_oflag = FCP_IDLE;
1345 	mutex_exit(&fcp_global_mutex);
1346 
1347 	return (0);
1348 }
1349 
1350 
1351 /*
1352  * fcp_ioctl
1353  *	Entry point for the FCP ioctls
1354  *
1355  * Input:
1356  *	See ioctl(9E)
1357  *
1358  * Output:
1359  *	See ioctl(9E)
1360  *
1361  * Returns:
1362  *	See ioctl(9E)
1363  *
1364  * Context:
1365  *	Kernel context.
1366  */
1367 /* ARGSUSED */
1368 static int
1369 fcp_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
1370     int *rval)
1371 {
1372 	int			ret = 0;
1373 
1374 	mutex_enter(&fcp_global_mutex);
1375 	if (!(fcp_oflag & FCP_OPEN)) {
1376 		mutex_exit(&fcp_global_mutex);
1377 		return (ENXIO);
1378 	}
1379 	mutex_exit(&fcp_global_mutex);
1380 
1381 	switch (cmd) {
1382 	case FCP_TGT_INQUIRY:
1383 	case FCP_TGT_CREATE:
1384 	case FCP_TGT_DELETE:
1385 		ret = fcp_setup_device_data_ioctl(cmd,
1386 		    (struct fcp_ioctl *)data, mode, rval);
1387 		break;
1388 
1389 	case FCP_TGT_SEND_SCSI:
1390 		mutex_enter(&fcp_ioctl_mutex);
1391 		ret = fcp_setup_scsi_ioctl(
1392 		    (struct fcp_scsi_cmd *)data, mode, rval);
1393 		mutex_exit(&fcp_ioctl_mutex);
1394 		break;
1395 
1396 	case FCP_STATE_COUNT:
1397 		ret = fcp_get_statec_count((struct fcp_ioctl *)data,
1398 		    mode, rval);
1399 		break;
1400 	case FCP_GET_TARGET_MAPPINGS:
1401 		ret = fcp_get_target_mappings((struct fcp_ioctl *)data,
1402 		    mode, rval);
1403 		break;
1404 	default:
1405 		fcp_log(CE_WARN, NULL,
1406 		    "!Invalid ioctl opcode = 0x%x", cmd);
1407 		ret	= EINVAL;
1408 	}
1409 
1410 	return (ret);
1411 }
1412 
1413 
1414 /*
1415  * fcp_setup_device_data_ioctl
1416  *	Setup handler for the "device data" style of
1417  *	ioctl for FCP.	See "fcp_util.h" for data structure
1418  *	definition.
1419  *
1420  * Input:
1421  *	cmd	= FCP ioctl command
1422  *	data	= ioctl data
1423  *	mode	= See ioctl(9E)
1424  *
1425  * Output:
1426  *	data	= ioctl data
1427  *	rval	= return value - see ioctl(9E)
1428  *
1429  * Returns:
1430  *	See ioctl(9E)
1431  *
1432  * Context:
1433  *	Kernel context.
1434  */
1435 /* ARGSUSED */
1436 static int
1437 fcp_setup_device_data_ioctl(int cmd, struct fcp_ioctl *data, int mode,
1438     int *rval)
1439 {
1440 	struct fcp_port	*pptr;
1441 	struct	device_data	*dev_data;
1442 	uint32_t		link_cnt;
1443 	la_wwn_t		*wwn_ptr = NULL;
1444 	struct fcp_tgt		*ptgt = NULL;
1445 	struct fcp_lun		*plun = NULL;
1446 	int			i, error;
1447 	struct fcp_ioctl	fioctl;
1448 
1449 #ifdef	_MULTI_DATAMODEL
1450 	switch (ddi_model_convert_from(mode & FMODELS)) {
1451 	case DDI_MODEL_ILP32: {
1452 		struct fcp32_ioctl f32_ioctl;
1453 
1454 		if (ddi_copyin((void *)data, (void *)&f32_ioctl,
1455 		    sizeof (struct fcp32_ioctl), mode)) {
1456 			return (EFAULT);
1457 		}
1458 		fioctl.fp_minor = f32_ioctl.fp_minor;
1459 		fioctl.listlen = f32_ioctl.listlen;
1460 		fioctl.list = (caddr_t)(long)f32_ioctl.list;
1461 		break;
1462 	}
1463 	case DDI_MODEL_NONE:
1464 		if (ddi_copyin((void *)data, (void *)&fioctl,
1465 		    sizeof (struct fcp_ioctl), mode)) {
1466 			return (EFAULT);
1467 		}
1468 		break;
1469 	}
1470 
1471 #else	/* _MULTI_DATAMODEL */
1472 	if (ddi_copyin((void *)data, (void *)&fioctl,
1473 	    sizeof (struct fcp_ioctl), mode)) {
1474 		return (EFAULT);
1475 	}
1476 #endif	/* _MULTI_DATAMODEL */
1477 
1478 	/*
1479 	 * Right now we can assume that the minor number matches with
1480 	 * this instance of fp. If this changes we will need to
1481 	 * revisit this logic.
1482 	 */
1483 	mutex_enter(&fcp_global_mutex);
1484 	pptr = fcp_port_head;
1485 	while (pptr) {
1486 		if (pptr->port_instance == (uint32_t)fioctl.fp_minor) {
1487 			break;
1488 		} else {
1489 			pptr = pptr->port_next;
1490 		}
1491 	}
1492 	mutex_exit(&fcp_global_mutex);
1493 	if (pptr == NULL) {
1494 		return (ENXIO);
1495 	}
1496 	mutex_enter(&pptr->port_mutex);
1497 
1498 
1499 	if ((dev_data = kmem_zalloc((sizeof (struct device_data)) *
1500 	    fioctl.listlen, KM_NOSLEEP)) == NULL) {
1501 		mutex_exit(&pptr->port_mutex);
1502 		return (ENOMEM);
1503 	}
1504 
1505 	if (ddi_copyin(fioctl.list, dev_data,
1506 	    (sizeof (struct device_data)) * fioctl.listlen, mode)) {
1507 		kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen);
1508 		mutex_exit(&pptr->port_mutex);
1509 		return (EFAULT);
1510 	}
1511 	link_cnt = pptr->port_link_cnt;
1512 
1513 	if (cmd == FCP_TGT_INQUIRY) {
1514 		wwn_ptr = (la_wwn_t *)&(dev_data[0].dev_pwwn);
1515 		if (bcmp(wwn_ptr->raw_wwn, pptr->port_pwwn.raw_wwn,
1516 		    sizeof (wwn_ptr->raw_wwn)) == 0) {
1517 			/* This ioctl is requesting INQ info of local HBA */
1518 			mutex_exit(&pptr->port_mutex);
1519 			dev_data[0].dev0_type = DTYPE_UNKNOWN;
1520 			dev_data[0].dev_status = 0;
1521 			if (ddi_copyout(dev_data, fioctl.list,
1522 			    (sizeof (struct device_data)) * fioctl.listlen,
1523 			    mode)) {
1524 				kmem_free(dev_data,
1525 				    sizeof (*dev_data) * fioctl.listlen);
1526 				return (EFAULT);
1527 			}
1528 			kmem_free(dev_data,
1529 			    sizeof (*dev_data) * fioctl.listlen);
1530 #ifdef	_MULTI_DATAMODEL
1531 			switch (ddi_model_convert_from(mode & FMODELS)) {
1532 			case DDI_MODEL_ILP32: {
1533 				struct fcp32_ioctl f32_ioctl;
1534 				f32_ioctl.fp_minor = fioctl.fp_minor;
1535 				f32_ioctl.listlen = fioctl.listlen;
1536 				f32_ioctl.list = (caddr32_t)(long)fioctl.list;
1537 				if (ddi_copyout((void *)&f32_ioctl,
1538 				    (void *)data,
1539 				    sizeof (struct fcp32_ioctl), mode)) {
1540 					return (EFAULT);
1541 				}
1542 				break;
1543 			}
1544 			case DDI_MODEL_NONE:
1545 				if (ddi_copyout((void *)&fioctl, (void *)data,
1546 				    sizeof (struct fcp_ioctl), mode)) {
1547 					return (EFAULT);
1548 				}
1549 				break;
1550 			}
1551 #else	/* _MULTI_DATAMODEL */
1552 			if (ddi_copyout((void *)&fioctl, (void *)data,
1553 			    sizeof (struct fcp_ioctl), mode)) {
1554 				return (EFAULT);
1555 			}
1556 #endif	/* _MULTI_DATAMODEL */
1557 			return (0);
1558 		}
1559 	}
1560 
1561 	if (pptr->port_state & (FCP_STATE_INIT | FCP_STATE_OFFLINE)) {
1562 		kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen);
1563 		mutex_exit(&pptr->port_mutex);
1564 		return (ENXIO);
1565 	}
1566 
1567 	for (i = 0; (i < fioctl.listlen) && (link_cnt == pptr->port_link_cnt);
1568 	    i++) {
1569 		wwn_ptr = (la_wwn_t *)&(dev_data[i].dev_pwwn);
1570 
1571 		dev_data[i].dev0_type = DTYPE_UNKNOWN;
1572 
1573 
1574 		dev_data[i].dev_status = ENXIO;
1575 
1576 		if ((ptgt = fcp_lookup_target(pptr,
1577 		    (uchar_t *)wwn_ptr)) == NULL) {
1578 			mutex_exit(&pptr->port_mutex);
1579 			if (fc_ulp_get_remote_port(pptr->port_fp_handle,
1580 			    wwn_ptr, &error, 0) == NULL) {
1581 				dev_data[i].dev_status = ENODEV;
1582 				mutex_enter(&pptr->port_mutex);
1583 				continue;
1584 			} else {
1585 
1586 				dev_data[i].dev_status = EAGAIN;
1587 
1588 				mutex_enter(&pptr->port_mutex);
1589 				continue;
1590 			}
1591 		} else {
1592 			mutex_enter(&ptgt->tgt_mutex);
1593 			if (ptgt->tgt_state & (FCP_TGT_MARK |
1594 			    FCP_TGT_BUSY)) {
1595 				dev_data[i].dev_status = EAGAIN;
1596 				mutex_exit(&ptgt->tgt_mutex);
1597 				continue;
1598 			}
1599 
1600 			if (ptgt->tgt_state & FCP_TGT_OFFLINE) {
1601 				if (ptgt->tgt_icap && !ptgt->tgt_tcap) {
1602 					dev_data[i].dev_status = ENOTSUP;
1603 				} else {
1604 					dev_data[i].dev_status = ENXIO;
1605 				}
1606 				mutex_exit(&ptgt->tgt_mutex);
1607 				continue;
1608 			}
1609 
1610 			switch (cmd) {
1611 			case FCP_TGT_INQUIRY:
1612 				/*
1613 				 * The reason we give device type of
1614 				 * lun 0 only even though in some
1615 				 * cases(like maxstrat) lun 0 device
1616 				 * type may be 0x3f(invalid) is that
1617 				 * for bridge boxes target will appear
1618 				 * as luns and the first lun could be
1619 				 * a device that utility may not care
1620 				 * about (like a tape device).
1621 				 */
1622 				dev_data[i].dev_lun_cnt = ptgt->tgt_lun_cnt;
1623 				dev_data[i].dev_status = 0;
1624 				mutex_exit(&ptgt->tgt_mutex);
1625 
1626 				if ((plun = fcp_get_lun(ptgt, 0)) == NULL) {
1627 					dev_data[i].dev0_type = DTYPE_UNKNOWN;
1628 				} else {
1629 					dev_data[i].dev0_type = plun->lun_type;
1630 				}
1631 				mutex_enter(&ptgt->tgt_mutex);
1632 				break;
1633 
1634 			case FCP_TGT_CREATE:
1635 				mutex_exit(&ptgt->tgt_mutex);
1636 				mutex_exit(&pptr->port_mutex);
1637 
1638 				/*
1639 				 * serialize state change call backs.
1640 				 * only one call back will be handled
1641 				 * at a time.
1642 				 */
1643 				mutex_enter(&fcp_global_mutex);
1644 				if (fcp_oflag & FCP_BUSY) {
1645 					mutex_exit(&fcp_global_mutex);
1646 					if (dev_data) {
1647 						kmem_free(dev_data,
1648 						    sizeof (*dev_data) *
1649 						    fioctl.listlen);
1650 					}
1651 					return (EBUSY);
1652 				}
1653 				fcp_oflag |= FCP_BUSY;
1654 				mutex_exit(&fcp_global_mutex);
1655 
1656 				dev_data[i].dev_status =
1657 				    fcp_create_on_demand(pptr,
1658 				    wwn_ptr->raw_wwn);
1659 
1660 				if (dev_data[i].dev_status != 0) {
1661 					char	buf[25];
1662 
1663 					for (i = 0; i < FC_WWN_SIZE; i++) {
1664 						(void) sprintf(&buf[i << 1],
1665 						    "%02x",
1666 						    wwn_ptr->raw_wwn[i]);
1667 					}
1668 
1669 					fcp_log(CE_WARN, pptr->port_dip,
1670 					    "!Failed to create nodes for"
1671 					    " pwwn=%s; error=%x", buf,
1672 					    dev_data[i].dev_status);
1673 				}
1674 
1675 				/* allow state change call backs again */
1676 				mutex_enter(&fcp_global_mutex);
1677 				fcp_oflag &= ~FCP_BUSY;
1678 				mutex_exit(&fcp_global_mutex);
1679 
1680 				mutex_enter(&pptr->port_mutex);
1681 				mutex_enter(&ptgt->tgt_mutex);
1682 
1683 				break;
1684 
1685 			case FCP_TGT_DELETE:
1686 				break;
1687 
1688 			default:
1689 				fcp_log(CE_WARN, pptr->port_dip,
1690 				    "!Invalid device data ioctl "
1691 				    "opcode = 0x%x", cmd);
1692 			}
1693 			mutex_exit(&ptgt->tgt_mutex);
1694 		}
1695 	}
1696 	mutex_exit(&pptr->port_mutex);
1697 
1698 	if (ddi_copyout(dev_data, fioctl.list,
1699 	    (sizeof (struct device_data)) * fioctl.listlen, mode)) {
1700 		kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen);
1701 		return (EFAULT);
1702 	}
1703 	kmem_free(dev_data, sizeof (*dev_data) * fioctl.listlen);
1704 
1705 #ifdef	_MULTI_DATAMODEL
1706 	switch (ddi_model_convert_from(mode & FMODELS)) {
1707 	case DDI_MODEL_ILP32: {
1708 		struct fcp32_ioctl f32_ioctl;
1709 
1710 		f32_ioctl.fp_minor = fioctl.fp_minor;
1711 		f32_ioctl.listlen = fioctl.listlen;
1712 		f32_ioctl.list = (caddr32_t)(long)fioctl.list;
1713 		if (ddi_copyout((void *)&f32_ioctl, (void *)data,
1714 		    sizeof (struct fcp32_ioctl), mode)) {
1715 			return (EFAULT);
1716 		}
1717 		break;
1718 	}
1719 	case DDI_MODEL_NONE:
1720 		if (ddi_copyout((void *)&fioctl, (void *)data,
1721 		    sizeof (struct fcp_ioctl), mode)) {
1722 			return (EFAULT);
1723 		}
1724 		break;
1725 	}
1726 #else	/* _MULTI_DATAMODEL */
1727 
1728 	if (ddi_copyout((void *)&fioctl, (void *)data,
1729 	    sizeof (struct fcp_ioctl), mode)) {
1730 		return (EFAULT);
1731 	}
1732 #endif	/* _MULTI_DATAMODEL */
1733 
1734 	return (0);
1735 }
1736 
1737 /*
1738  * Fetch the target mappings (path, etc.) for all LUNs
1739  * on this port.
1740  */
1741 /* ARGSUSED */
1742 static int
1743 fcp_get_target_mappings(struct fcp_ioctl *data,
1744     int mode, int *rval)
1745 {
1746 	struct fcp_port	    *pptr;
1747 	fc_hba_target_mappings_t    *mappings;
1748 	fc_hba_mapping_entry_t	    *map;
1749 	struct fcp_tgt	    *ptgt = NULL;
1750 	struct fcp_lun	    *plun = NULL;
1751 	int			    i, mapIndex, mappingSize;
1752 	int			    listlen;
1753 	struct fcp_ioctl	    fioctl;
1754 	char			    *path;
1755 	fcp_ent_addr_t		    sam_lun_addr;
1756 
1757 #ifdef	_MULTI_DATAMODEL
1758 	switch (ddi_model_convert_from(mode & FMODELS)) {
1759 	case DDI_MODEL_ILP32: {
1760 		struct fcp32_ioctl f32_ioctl;
1761 
1762 		if (ddi_copyin((void *)data, (void *)&f32_ioctl,
1763 		    sizeof (struct fcp32_ioctl), mode)) {
1764 			return (EFAULT);
1765 		}
1766 		fioctl.fp_minor = f32_ioctl.fp_minor;
1767 		fioctl.listlen = f32_ioctl.listlen;
1768 		fioctl.list = (caddr_t)(long)f32_ioctl.list;
1769 		break;
1770 	}
1771 	case DDI_MODEL_NONE:
1772 		if (ddi_copyin((void *)data, (void *)&fioctl,
1773 		    sizeof (struct fcp_ioctl), mode)) {
1774 			return (EFAULT);
1775 		}
1776 		break;
1777 	}
1778 
1779 #else	/* _MULTI_DATAMODEL */
1780 	if (ddi_copyin((void *)data, (void *)&fioctl,
1781 	    sizeof (struct fcp_ioctl), mode)) {
1782 		return (EFAULT);
1783 	}
1784 #endif	/* _MULTI_DATAMODEL */
1785 
1786 	/*
1787 	 * Right now we can assume that the minor number matches with
1788 	 * this instance of fp. If this changes we will need to
1789 	 * revisit this logic.
1790 	 */
1791 	mutex_enter(&fcp_global_mutex);
1792 	pptr = fcp_port_head;
1793 	while (pptr) {
1794 		if (pptr->port_instance == (uint32_t)fioctl.fp_minor) {
1795 			break;
1796 		} else {
1797 			pptr = pptr->port_next;
1798 		}
1799 	}
1800 	mutex_exit(&fcp_global_mutex);
1801 	if (pptr == NULL) {
1802 		cmn_err(CE_NOTE, "target mappings: unknown instance number: %d",
1803 		    fioctl.fp_minor);
1804 		return (ENXIO);
1805 	}
1806 
1807 
1808 	/* We use listlen to show the total buffer size */
1809 	mappingSize = fioctl.listlen;
1810 
1811 	/* Now calculate how many mapping entries will fit */
1812 	listlen = fioctl.listlen + sizeof (fc_hba_mapping_entry_t)
1813 	    - sizeof (fc_hba_target_mappings_t);
1814 	if (listlen <= 0) {
1815 		cmn_err(CE_NOTE, "target mappings: Insufficient buffer");
1816 		return (ENXIO);
1817 	}
1818 	listlen = listlen / sizeof (fc_hba_mapping_entry_t);
1819 
1820 	if ((mappings = kmem_zalloc(mappingSize, KM_SLEEP)) == NULL) {
1821 		return (ENOMEM);
1822 	}
1823 	mappings->version = FC_HBA_TARGET_MAPPINGS_VERSION;
1824 
1825 	/* Now get to work */
1826 	mapIndex = 0;
1827 
1828 	mutex_enter(&pptr->port_mutex);
1829 	/* Loop through all targets on this port */
1830 	for (i = 0; i < FCP_NUM_HASH; i++) {
1831 		for (ptgt = pptr->port_tgt_hash_table[i]; ptgt != NULL;
1832 		    ptgt = ptgt->tgt_next) {
1833 
1834 
1835 			/* Loop through all LUNs on this target */
1836 			for (plun = ptgt->tgt_lun; plun != NULL;
1837 			    plun = plun->lun_next) {
1838 				if (plun->lun_state & FCP_LUN_OFFLINE) {
1839 					continue;
1840 				}
1841 
1842 				path = fcp_get_lun_path(plun);
1843 				if (path == NULL) {
1844 					continue;
1845 				}
1846 
1847 				if (mapIndex >= listlen) {
1848 					mapIndex ++;
1849 					kmem_free(path, MAXPATHLEN);
1850 					continue;
1851 				}
1852 				map = &mappings->entries[mapIndex++];
1853 				bcopy(path, map->targetDriver,
1854 				    sizeof (map->targetDriver));
1855 				map->d_id = ptgt->tgt_d_id;
1856 				map->busNumber = 0;
1857 				map->targetNumber = ptgt->tgt_d_id;
1858 				map->osLUN = plun->lun_num;
1859 
1860 				/*
1861 				 * We had swapped lun when we stored it in
1862 				 * lun_addr. We need to swap it back before
1863 				 * returning it to user land
1864 				 */
1865 
1866 				sam_lun_addr.ent_addr_0 =
1867 				    BE_16(plun->lun_addr.ent_addr_0);
1868 				sam_lun_addr.ent_addr_1 =
1869 				    BE_16(plun->lun_addr.ent_addr_1);
1870 				sam_lun_addr.ent_addr_2 =
1871 				    BE_16(plun->lun_addr.ent_addr_2);
1872 				sam_lun_addr.ent_addr_3 =
1873 				    BE_16(plun->lun_addr.ent_addr_3);
1874 
1875 				bcopy(&sam_lun_addr, &map->samLUN,
1876 				    FCP_LUN_SIZE);
1877 				bcopy(ptgt->tgt_node_wwn.raw_wwn,
1878 				    map->NodeWWN.raw_wwn, sizeof (la_wwn_t));
1879 				bcopy(ptgt->tgt_port_wwn.raw_wwn,
1880 				    map->PortWWN.raw_wwn, sizeof (la_wwn_t));
1881 
1882 				if (plun->lun_guid) {
1883 
1884 					/* convert ascii wwn to bytes */
1885 					fcp_ascii_to_wwn(plun->lun_guid,
1886 					    map->guid, sizeof (map->guid));
1887 
1888 					if ((sizeof (map->guid)) <
1889 					    plun->lun_guid_size / 2) {
1890 						cmn_err(CE_WARN,
1891 						    "fcp_get_target_mappings:"
1892 						    "guid copy space "
1893 						    "insufficient."
1894 						    "Copy Truncation - "
1895 						    "available %d; need %d",
1896 						    (int)sizeof (map->guid),
1897 						    (int)
1898 						    plun->lun_guid_size / 2);
1899 					}
1900 				}
1901 				kmem_free(path, MAXPATHLEN);
1902 			}
1903 		}
1904 	}
1905 	mutex_exit(&pptr->port_mutex);
1906 	mappings->numLuns = mapIndex;
1907 
1908 	if (ddi_copyout(mappings, fioctl.list, mappingSize, mode)) {
1909 		kmem_free(mappings, mappingSize);
1910 		return (EFAULT);
1911 	}
1912 	kmem_free(mappings, mappingSize);
1913 
1914 #ifdef	_MULTI_DATAMODEL
1915 	switch (ddi_model_convert_from(mode & FMODELS)) {
1916 	case DDI_MODEL_ILP32: {
1917 		struct fcp32_ioctl f32_ioctl;
1918 
1919 		f32_ioctl.fp_minor = fioctl.fp_minor;
1920 		f32_ioctl.listlen = fioctl.listlen;
1921 		f32_ioctl.list = (caddr32_t)(long)fioctl.list;
1922 		if (ddi_copyout((void *)&f32_ioctl, (void *)data,
1923 		    sizeof (struct fcp32_ioctl), mode)) {
1924 			return (EFAULT);
1925 		}
1926 		break;
1927 	}
1928 	case DDI_MODEL_NONE:
1929 		if (ddi_copyout((void *)&fioctl, (void *)data,
1930 		    sizeof (struct fcp_ioctl), mode)) {
1931 			return (EFAULT);
1932 		}
1933 		break;
1934 	}
1935 #else	/* _MULTI_DATAMODEL */
1936 
1937 	if (ddi_copyout((void *)&fioctl, (void *)data,
1938 	    sizeof (struct fcp_ioctl), mode)) {
1939 		return (EFAULT);
1940 	}
1941 #endif	/* _MULTI_DATAMODEL */
1942 
1943 	return (0);
1944 }
1945 
1946 /*
1947  * fcp_setup_scsi_ioctl
1948  *	Setup handler for the "scsi passthru" style of
1949  *	ioctl for FCP.	See "fcp_util.h" for data structure
1950  *	definition.
1951  *
1952  * Input:
1953  *	u_fscsi	= ioctl data (user address space)
1954  *	mode	= See ioctl(9E)
1955  *
1956  * Output:
1957  *	u_fscsi	= ioctl data (user address space)
1958  *	rval	= return value - see ioctl(9E)
1959  *
1960  * Returns:
1961  *	0	= OK
1962  *	EAGAIN	= See errno.h
1963  *	EBUSY	= See errno.h
1964  *	EFAULT	= See errno.h
1965  *	EINTR	= See errno.h
1966  *	EINVAL	= See errno.h
1967  *	EIO	= See errno.h
1968  *	ENOMEM	= See errno.h
1969  *	ENXIO	= See errno.h
1970  *
1971  * Context:
1972  *	Kernel context.
1973  */
1974 /* ARGSUSED */
1975 static int
1976 fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi,
1977     int mode, int *rval)
1978 {
1979 	int			ret		= 0;
1980 	int			temp_ret;
1981 	caddr_t			k_cdbbufaddr	= NULL;
1982 	caddr_t			k_bufaddr	= NULL;
1983 	caddr_t			k_rqbufaddr	= NULL;
1984 	caddr_t			u_cdbbufaddr;
1985 	caddr_t			u_bufaddr;
1986 	caddr_t			u_rqbufaddr;
1987 	struct fcp_scsi_cmd	k_fscsi;
1988 
1989 	/*
1990 	 * Get fcp_scsi_cmd array element from user address space
1991 	 */
1992 	if ((ret = fcp_copyin_scsi_cmd((caddr_t)u_fscsi, &k_fscsi, mode))
1993 	    != 0) {
1994 		return (ret);
1995 	}
1996 
1997 
1998 	/*
1999 	 * Even though kmem_alloc() checks the validity of the
2000 	 * buffer length, this check is needed when the
2001 	 * kmem_flags set and the zero buffer length is passed.
2002 	 */
2003 	if ((k_fscsi.scsi_cdblen <= 0) ||
2004 	    (k_fscsi.scsi_buflen <= 0) ||
2005 	    (k_fscsi.scsi_buflen > FCP_MAX_RESPONSE_LEN) ||
2006 	    (k_fscsi.scsi_rqlen <= 0) ||
2007 	    (k_fscsi.scsi_rqlen > FCP_MAX_SENSE_LEN)) {
2008 		return (EINVAL);
2009 	}
2010 
2011 	/*
2012 	 * Allocate data for fcp_scsi_cmd pointer fields
2013 	 */
2014 	if (ret == 0) {
2015 		k_cdbbufaddr = kmem_alloc(k_fscsi.scsi_cdblen, KM_NOSLEEP);
2016 		k_bufaddr    = kmem_alloc(k_fscsi.scsi_buflen, KM_NOSLEEP);
2017 		k_rqbufaddr  = kmem_alloc(k_fscsi.scsi_rqlen,  KM_NOSLEEP);
2018 
2019 		if (k_cdbbufaddr == NULL ||
2020 		    k_bufaddr	 == NULL ||
2021 		    k_rqbufaddr	 == NULL) {
2022 			ret = ENOMEM;
2023 		}
2024 	}
2025 
2026 	/*
2027 	 * Get fcp_scsi_cmd pointer fields from user
2028 	 * address space
2029 	 */
2030 	if (ret == 0) {
2031 		u_cdbbufaddr = k_fscsi.scsi_cdbbufaddr;
2032 		u_bufaddr    = k_fscsi.scsi_bufaddr;
2033 		u_rqbufaddr  = k_fscsi.scsi_rqbufaddr;
2034 
2035 		if (ddi_copyin(u_cdbbufaddr,
2036 		    k_cdbbufaddr,
2037 		    k_fscsi.scsi_cdblen,
2038 		    mode)) {
2039 			ret = EFAULT;
2040 		} else if (ddi_copyin(u_bufaddr,
2041 		    k_bufaddr,
2042 		    k_fscsi.scsi_buflen,
2043 		    mode)) {
2044 			ret = EFAULT;
2045 		} else if (ddi_copyin(u_rqbufaddr,
2046 		    k_rqbufaddr,
2047 		    k_fscsi.scsi_rqlen,
2048 		    mode)) {
2049 			ret = EFAULT;
2050 		}
2051 	}
2052 
2053 	/*
2054 	 * Send scsi command (blocking)
2055 	 */
2056 	if (ret == 0) {
2057 		/*
2058 		 * Prior to sending the scsi command, the
2059 		 * fcp_scsi_cmd data structure must contain kernel,
2060 		 * not user, addresses.
2061 		 */
2062 		k_fscsi.scsi_cdbbufaddr	= k_cdbbufaddr;
2063 		k_fscsi.scsi_bufaddr	= k_bufaddr;
2064 		k_fscsi.scsi_rqbufaddr	= k_rqbufaddr;
2065 
2066 		ret = fcp_send_scsi_ioctl(&k_fscsi);
2067 
2068 		/*
2069 		 * After sending the scsi command, the
2070 		 * fcp_scsi_cmd data structure must contain user,
2071 		 * not kernel, addresses.
2072 		 */
2073 		k_fscsi.scsi_cdbbufaddr	= u_cdbbufaddr;
2074 		k_fscsi.scsi_bufaddr	= u_bufaddr;
2075 		k_fscsi.scsi_rqbufaddr	= u_rqbufaddr;
2076 	}
2077 
2078 	/*
2079 	 * Put fcp_scsi_cmd pointer fields to user address space
2080 	 */
2081 	if (ret == 0) {
2082 		if (ddi_copyout(k_cdbbufaddr,
2083 		    u_cdbbufaddr,
2084 		    k_fscsi.scsi_cdblen,
2085 		    mode)) {
2086 			ret = EFAULT;
2087 		} else if (ddi_copyout(k_bufaddr,
2088 		    u_bufaddr,
2089 		    k_fscsi.scsi_buflen,
2090 		    mode)) {
2091 			ret = EFAULT;
2092 		} else if (ddi_copyout(k_rqbufaddr,
2093 		    u_rqbufaddr,
2094 		    k_fscsi.scsi_rqlen,
2095 		    mode)) {
2096 			ret = EFAULT;
2097 		}
2098 	}
2099 
2100 	/*
2101 	 * Free data for fcp_scsi_cmd pointer fields
2102 	 */
2103 	if (k_cdbbufaddr != NULL) {
2104 		kmem_free(k_cdbbufaddr, k_fscsi.scsi_cdblen);
2105 	}
2106 	if (k_bufaddr != NULL) {
2107 		kmem_free(k_bufaddr, k_fscsi.scsi_buflen);
2108 	}
2109 	if (k_rqbufaddr != NULL) {
2110 		kmem_free(k_rqbufaddr, k_fscsi.scsi_rqlen);
2111 	}
2112 
2113 	/*
2114 	 * Put fcp_scsi_cmd array element to user address space
2115 	 */
2116 	temp_ret = fcp_copyout_scsi_cmd(&k_fscsi, (caddr_t)u_fscsi, mode);
2117 	if (temp_ret != 0) {
2118 		ret = temp_ret;
2119 	}
2120 
2121 	/*
2122 	 * Return status
2123 	 */
2124 	return (ret);
2125 }
2126 
2127 
2128 /*
2129  * fcp_copyin_scsi_cmd
2130  *	Copy in fcp_scsi_cmd data structure from user address space.
2131  *	The data may be in 32 bit or 64 bit modes.
2132  *
2133  * Input:
2134  *	base_addr	= from address (user address space)
2135  *	mode		= See ioctl(9E) and ddi_copyin(9F)
2136  *
2137  * Output:
2138  *	fscsi		= to address (kernel address space)
2139  *
2140  * Returns:
2141  *	0	= OK
2142  *	EFAULT	= Error
2143  *
2144  * Context:
2145  *	Kernel context.
2146  */
2147 static int
2148 fcp_copyin_scsi_cmd(caddr_t base_addr, struct fcp_scsi_cmd *fscsi, int mode)
2149 {
2150 #ifdef	_MULTI_DATAMODEL
2151 	struct fcp32_scsi_cmd	f32scsi;
2152 
2153 	switch (ddi_model_convert_from(mode & FMODELS)) {
2154 	case DDI_MODEL_ILP32:
2155 		/*
2156 		 * Copy data from user address space
2157 		 */
2158 		if (ddi_copyin((void *)base_addr,
2159 		    &f32scsi,
2160 		    sizeof (struct fcp32_scsi_cmd),
2161 		    mode)) {
2162 			return (EFAULT);
2163 		}
2164 		/*
2165 		 * Convert from 32 bit to 64 bit
2166 		 */
2167 		FCP32_SCSI_CMD_TO_FCP_SCSI_CMD(&f32scsi, fscsi);
2168 		break;
2169 	case DDI_MODEL_NONE:
2170 		/*
2171 		 * Copy data from user address space
2172 		 */
2173 		if (ddi_copyin((void *)base_addr,
2174 		    fscsi,
2175 		    sizeof (struct fcp_scsi_cmd),
2176 		    mode)) {
2177 			return (EFAULT);
2178 		}
2179 		break;
2180 	}
2181 #else	/* _MULTI_DATAMODEL */
2182 	/*
2183 	 * Copy data from user address space
2184 	 */
2185 	if (ddi_copyin((void *)base_addr,
2186 	    fscsi,
2187 	    sizeof (struct fcp_scsi_cmd),
2188 	    mode)) {
2189 		return (EFAULT);
2190 	}
2191 #endif	/* _MULTI_DATAMODEL */
2192 
2193 	return (0);
2194 }
2195 
2196 
2197 /*
2198  * fcp_copyout_scsi_cmd
2199  *	Copy out fcp_scsi_cmd data structure to user address space.
2200  *	The data may be in 32 bit or 64 bit modes.
2201  *
2202  * Input:
2203  *	fscsi		= to address (kernel address space)
2204  *	mode		= See ioctl(9E) and ddi_copyin(9F)
2205  *
2206  * Output:
2207  *	base_addr	= from address (user address space)
2208  *
2209  * Returns:
2210  *	0	= OK
2211  *	EFAULT	= Error
2212  *
2213  * Context:
2214  *	Kernel context.
2215  */
2216 static int
2217 fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi, caddr_t base_addr, int mode)
2218 {
2219 #ifdef	_MULTI_DATAMODEL
2220 	struct fcp32_scsi_cmd	f32scsi;
2221 
2222 	switch (ddi_model_convert_from(mode & FMODELS)) {
2223 	case DDI_MODEL_ILP32:
2224 		/*
2225 		 * Convert from 64 bit to 32 bit
2226 		 */
2227 		FCP_SCSI_CMD_TO_FCP32_SCSI_CMD(fscsi, &f32scsi);
2228 		/*
2229 		 * Copy data to user address space
2230 		 */
2231 		if (ddi_copyout(&f32scsi,
2232 		    (void *)base_addr,
2233 		    sizeof (struct fcp32_scsi_cmd),
2234 		    mode)) {
2235 			return (EFAULT);
2236 		}
2237 		break;
2238 	case DDI_MODEL_NONE:
2239 		/*
2240 		 * Copy data to user address space
2241 		 */
2242 		if (ddi_copyout(fscsi,
2243 		    (void *)base_addr,
2244 		    sizeof (struct fcp_scsi_cmd),
2245 		    mode)) {
2246 			return (EFAULT);
2247 		}
2248 		break;
2249 	}
2250 #else	/* _MULTI_DATAMODEL */
2251 	/*
2252 	 * Copy data to user address space
2253 	 */
2254 	if (ddi_copyout(fscsi,
2255 	    (void *)base_addr,
2256 	    sizeof (struct fcp_scsi_cmd),
2257 	    mode)) {
2258 		return (EFAULT);
2259 	}
2260 #endif	/* _MULTI_DATAMODEL */
2261 
2262 	return (0);
2263 }
2264 
2265 
2266 /*
2267  * fcp_send_scsi_ioctl
2268  *	Sends the SCSI command in blocking mode.
2269  *
2270  * Input:
2271  *	fscsi		= SCSI command data structure
2272  *
2273  * Output:
2274  *	fscsi		= SCSI command data structure
2275  *
2276  * Returns:
2277  *	0	= OK
2278  *	EAGAIN	= See errno.h
2279  *	EBUSY	= See errno.h
2280  *	EINTR	= See errno.h
2281  *	EINVAL	= See errno.h
2282  *	EIO	= See errno.h
2283  *	ENOMEM	= See errno.h
2284  *	ENXIO	= See errno.h
2285  *
2286  * Context:
2287  *	Kernel context.
2288  */
2289 static int
2290 fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi)
2291 {
2292 	struct fcp_lun	*plun		= NULL;
2293 	struct fcp_port	*pptr		= NULL;
2294 	struct fcp_tgt	*ptgt		= NULL;
2295 	fc_packet_t		*fpkt		= NULL;
2296 	struct fcp_ipkt	*icmd		= NULL;
2297 	int			target_created	= FALSE;
2298 	fc_frame_hdr_t		*hp;
2299 	struct fcp_cmd		fcp_cmd;
2300 	struct fcp_cmd		*fcmd;
2301 	union scsi_cdb		*scsi_cdb;
2302 	la_wwn_t		*wwn_ptr;
2303 	int			nodma;
2304 	struct fcp_rsp		*rsp;
2305 	struct fcp_rsp_info	*rsp_info;
2306 	caddr_t			rsp_sense;
2307 	int			buf_len;
2308 	int			info_len;
2309 	int			sense_len;
2310 	struct scsi_extended_sense	*sense_to = NULL;
2311 	timeout_id_t		tid;
2312 	uint8_t			reconfig_lun = FALSE;
2313 	uint8_t			reconfig_pending = FALSE;
2314 	uint8_t			scsi_cmd;
2315 	int			rsp_len;
2316 	int			cmd_index;
2317 	int			fc_status;
2318 	int			pkt_state;
2319 	int			pkt_action;
2320 	int			pkt_reason;
2321 	int			ret, xport_retval = ~FC_SUCCESS;
2322 	int			lcount;
2323 	int			tcount;
2324 	int			reconfig_status;
2325 	int			port_busy = FALSE;
2326 	uchar_t			*lun_string;
2327 
2328 	/*
2329 	 * Check valid SCSI command
2330 	 */
2331 	scsi_cmd = ((uint8_t *)fscsi->scsi_cdbbufaddr)[0];
2332 	ret = EINVAL;
2333 	for (cmd_index = 0;
2334 	    cmd_index < FCP_NUM_ELEMENTS(scsi_ioctl_list) &&
2335 	    ret != 0;
2336 	    cmd_index++) {
2337 		/*
2338 		 * First byte of CDB is the SCSI command
2339 		 */
2340 		if (scsi_ioctl_list[cmd_index] == scsi_cmd) {
2341 			ret = 0;
2342 		}
2343 	}
2344 
2345 	/*
2346 	 * Check inputs
2347 	 */
2348 	if (fscsi->scsi_flags != FCP_SCSI_READ) {
2349 		ret = EINVAL;
2350 	} else if (fscsi->scsi_cdblen > FCP_CDB_SIZE) {
2351 		/* no larger than */
2352 		ret = EINVAL;
2353 	}
2354 
2355 
2356 	/*
2357 	 * Find FC port
2358 	 */
2359 	if (ret == 0) {
2360 		/*
2361 		 * Acquire global mutex
2362 		 */
2363 		mutex_enter(&fcp_global_mutex);
2364 
2365 		pptr = fcp_port_head;
2366 		while (pptr) {
2367 			if (pptr->port_instance ==
2368 			    (uint32_t)fscsi->scsi_fc_port_num) {
2369 				break;
2370 			} else {
2371 				pptr = pptr->port_next;
2372 			}
2373 		}
2374 
2375 		if (pptr == NULL) {
2376 			ret = ENXIO;
2377 		} else {
2378 			/*
2379 			 * fc_ulp_busy_port can raise power
2380 			 *  so, we must not hold any mutexes involved in PM
2381 			 */
2382 			mutex_exit(&fcp_global_mutex);
2383 			ret = fc_ulp_busy_port(pptr->port_fp_handle);
2384 		}
2385 
2386 		if (ret == 0) {
2387 
2388 			/* remember port is busy, so we will release later */
2389 			port_busy = TRUE;
2390 
2391 			/*
2392 			 * If there is a reconfiguration in progress, wait
2393 			 * for it to complete.
2394 			 */
2395 
2396 			fcp_reconfig_wait(pptr);
2397 
2398 			/* reacquire mutexes in order */
2399 			mutex_enter(&fcp_global_mutex);
2400 			mutex_enter(&pptr->port_mutex);
2401 
2402 			/*
2403 			 * Will port accept DMA?
2404 			 */
2405 			nodma = (pptr->port_fcp_dma == FC_NO_DVMA_SPACE)
2406 			    ? 1 : 0;
2407 
2408 			/*
2409 			 * If init or offline, device not known
2410 			 *
2411 			 * If we are discovering (onlining), we can
2412 			 * NOT obviously provide reliable data about
2413 			 * devices until it is complete
2414 			 */
2415 			if (pptr->port_state &	  (FCP_STATE_INIT |
2416 			    FCP_STATE_OFFLINE)) {
2417 				ret = ENXIO;
2418 			} else if (pptr->port_state & FCP_STATE_ONLINING) {
2419 				ret = EBUSY;
2420 			} else {
2421 				/*
2422 				 * Find target from pwwn
2423 				 *
2424 				 * The wwn must be put into a local
2425 				 * variable to ensure alignment.
2426 				 */
2427 				wwn_ptr = (la_wwn_t *)&(fscsi->scsi_fc_pwwn);
2428 				ptgt = fcp_lookup_target(pptr,
2429 				    (uchar_t *)wwn_ptr);
2430 
2431 				/*
2432 				 * If target not found,
2433 				 */
2434 				if (ptgt == NULL) {
2435 					/*
2436 					 * Note: Still have global &
2437 					 * port mutexes
2438 					 */
2439 					mutex_exit(&pptr->port_mutex);
2440 					ptgt = fcp_port_create_tgt(pptr,
2441 					    wwn_ptr, &ret, &fc_status,
2442 					    &pkt_state, &pkt_action,
2443 					    &pkt_reason);
2444 					mutex_enter(&pptr->port_mutex);
2445 
2446 					fscsi->scsi_fc_status  = fc_status;
2447 					fscsi->scsi_pkt_state  =
2448 					    (uchar_t)pkt_state;
2449 					fscsi->scsi_pkt_reason = pkt_reason;
2450 					fscsi->scsi_pkt_action =
2451 					    (uchar_t)pkt_action;
2452 
2453 					if (ptgt != NULL) {
2454 						target_created = TRUE;
2455 					} else if (ret == 0) {
2456 						ret = ENOMEM;
2457 					}
2458 				}
2459 
2460 				if (ret == 0) {
2461 					/*
2462 					 * Acquire target
2463 					 */
2464 					mutex_enter(&ptgt->tgt_mutex);
2465 
2466 					/*
2467 					 * If target is mark or busy,
2468 					 * then target can not be used
2469 					 */
2470 					if (ptgt->tgt_state &
2471 					    (FCP_TGT_MARK |
2472 					    FCP_TGT_BUSY)) {
2473 						ret = EBUSY;
2474 					} else {
2475 						/*
2476 						 * Mark target as busy
2477 						 */
2478 						ptgt->tgt_state |=
2479 						    FCP_TGT_BUSY;
2480 					}
2481 
2482 					/*
2483 					 * Release target
2484 					 */
2485 					lcount = pptr->port_link_cnt;
2486 					tcount = ptgt->tgt_change_cnt;
2487 					mutex_exit(&ptgt->tgt_mutex);
2488 				}
2489 			}
2490 
2491 			/*
2492 			 * Release port
2493 			 */
2494 			mutex_exit(&pptr->port_mutex);
2495 		}
2496 
2497 		/*
2498 		 * Release global mutex
2499 		 */
2500 		mutex_exit(&fcp_global_mutex);
2501 	}
2502 
2503 	if (ret == 0) {
2504 		uint64_t belun = BE_64(fscsi->scsi_lun);
2505 
2506 		/*
2507 		 * If it's a target device, find lun from pwwn
2508 		 * The wwn must be put into a local
2509 		 * variable to ensure alignment.
2510 		 */
2511 		mutex_enter(&pptr->port_mutex);
2512 		wwn_ptr = (la_wwn_t *)&(fscsi->scsi_fc_pwwn);
2513 		if (!ptgt->tgt_tcap && ptgt->tgt_icap) {
2514 			/* this is not a target */
2515 			fscsi->scsi_fc_status = FC_DEVICE_NOT_TGT;
2516 			ret = ENXIO;
2517 		} else if ((belun << 16) != 0) {
2518 			/*
2519 			 * Since fcp only support PD and LU addressing method
2520 			 * so far, the last 6 bytes of a valid LUN are expected
2521 			 * to be filled with 00h.
2522 			 */
2523 			fscsi->scsi_fc_status = FC_INVALID_LUN;
2524 			cmn_err(CE_WARN, "fcp: Unsupported LUN addressing"
2525 			    " method 0x%02x with LUN number 0x%016" PRIx64,
2526 			    (uint8_t)(belun >> 62), belun);
2527 			ret = ENXIO;
2528 		} else if ((plun = fcp_lookup_lun(pptr, (uchar_t *)wwn_ptr,
2529 		    (uint16_t)((belun >> 48) & 0x3fff))) == NULL) {
2530 			/*
2531 			 * This is a SCSI target, but no LUN at this
2532 			 * address.
2533 			 *
2534 			 * In the future, we may want to send this to
2535 			 * the target, and let it respond
2536 			 * appropriately
2537 			 */
2538 			ret = ENXIO;
2539 		}
2540 		mutex_exit(&pptr->port_mutex);
2541 	}
2542 
2543 	/*
2544 	 * Finished grabbing external resources
2545 	 * Allocate internal packet (icmd)
2546 	 */
2547 	if (ret == 0) {
2548 		/*
2549 		 * Calc rsp len assuming rsp info included
2550 		 */
2551 		rsp_len = sizeof (struct fcp_rsp) +
2552 		    sizeof (struct fcp_rsp_info) + fscsi->scsi_rqlen;
2553 
2554 		icmd = fcp_icmd_alloc(pptr, ptgt,
2555 		    sizeof (struct fcp_cmd),
2556 		    rsp_len,
2557 		    fscsi->scsi_buflen,
2558 		    nodma,
2559 		    lcount,			/* ipkt_link_cnt */
2560 		    tcount,			/* ipkt_change_cnt */
2561 		    0,				/* cause */
2562 		    FC_INVALID_RSCN_COUNT);	/* invalidate the count */
2563 
2564 		if (icmd == NULL) {
2565 			ret = ENOMEM;
2566 		} else {
2567 			/*
2568 			 * Setup internal packet as sema sync
2569 			 */
2570 			fcp_ipkt_sema_init(icmd);
2571 		}
2572 	}
2573 
2574 	if (ret == 0) {
2575 		/*
2576 		 * Init fpkt pointer for use.
2577 		 */
2578 
2579 		fpkt = icmd->ipkt_fpkt;
2580 
2581 		fpkt->pkt_tran_flags	= FC_TRAN_CLASS3 | FC_TRAN_INTR;
2582 		fpkt->pkt_tran_type	= FC_PKT_FCP_READ; /* only rd for now */
2583 		fpkt->pkt_timeout	= fscsi->scsi_timeout;
2584 
2585 		/*
2586 		 * Init fcmd pointer for use by SCSI command
2587 		 */
2588 
2589 		if (nodma) {
2590 			fcmd = (struct fcp_cmd *)fpkt->pkt_cmd;
2591 		} else {
2592 			fcmd = &fcp_cmd;
2593 		}
2594 		bzero(fcmd, sizeof (struct fcp_cmd));
2595 		ptgt = plun->lun_tgt;
2596 
2597 		lun_string = (uchar_t *)&fscsi->scsi_lun;
2598 
2599 		fcmd->fcp_ent_addr.ent_addr_0 =
2600 		    BE_16(*(uint16_t *)&(lun_string[0]));
2601 		fcmd->fcp_ent_addr.ent_addr_1 =
2602 		    BE_16(*(uint16_t *)&(lun_string[2]));
2603 		fcmd->fcp_ent_addr.ent_addr_2 =
2604 		    BE_16(*(uint16_t *)&(lun_string[4]));
2605 		fcmd->fcp_ent_addr.ent_addr_3 =
2606 		    BE_16(*(uint16_t *)&(lun_string[6]));
2607 
2608 		/*
2609 		 * Setup internal packet(icmd)
2610 		 */
2611 		icmd->ipkt_lun		= plun;
2612 		icmd->ipkt_restart	= 0;
2613 		icmd->ipkt_retries	= 0;
2614 		icmd->ipkt_opcode	= 0;
2615 
2616 		/*
2617 		 * Init the frame HEADER Pointer for use
2618 		 */
2619 		hp = &fpkt->pkt_cmd_fhdr;
2620 
2621 		hp->s_id	= pptr->port_id;
2622 		hp->d_id	= ptgt->tgt_d_id;
2623 		hp->r_ctl	= R_CTL_COMMAND;
2624 		hp->type	= FC_TYPE_SCSI_FCP;
2625 		hp->f_ctl	= F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ;
2626 		hp->rsvd	= 0;
2627 		hp->seq_id	= 0;
2628 		hp->seq_cnt	= 0;
2629 		hp->ox_id	= 0xffff;
2630 		hp->rx_id	= 0xffff;
2631 		hp->ro		= 0;
2632 
2633 		fcmd->fcp_cntl.cntl_qtype	= FCP_QTYPE_SIMPLE;
2634 		fcmd->fcp_cntl.cntl_read_data	= 1;	/* only rd for now */
2635 		fcmd->fcp_cntl.cntl_write_data	= 0;
2636 		fcmd->fcp_data_len	= fscsi->scsi_buflen;
2637 
2638 		scsi_cdb = (union scsi_cdb *)fcmd->fcp_cdb;
2639 		bcopy((char *)fscsi->scsi_cdbbufaddr, (char *)scsi_cdb,
2640 		    fscsi->scsi_cdblen);
2641 
2642 		if (!nodma) {
2643 			FCP_CP_OUT((uint8_t *)fcmd, fpkt->pkt_cmd,
2644 			    fpkt->pkt_cmd_acc, sizeof (struct fcp_cmd));
2645 		}
2646 
2647 		/*
2648 		 * Send SCSI command to FC transport
2649 		 */
2650 
2651 		if (ret == 0) {
2652 			mutex_enter(&ptgt->tgt_mutex);
2653 
2654 			if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) {
2655 				mutex_exit(&ptgt->tgt_mutex);
2656 				fscsi->scsi_fc_status = xport_retval =
2657 				    fc_ulp_transport(pptr->port_fp_handle,
2658 				    fpkt);
2659 				if (fscsi->scsi_fc_status != FC_SUCCESS) {
2660 					ret = EIO;
2661 				}
2662 			} else {
2663 				mutex_exit(&ptgt->tgt_mutex);
2664 				ret = EBUSY;
2665 			}
2666 		}
2667 	}
2668 
2669 	/*
2670 	 * Wait for completion only if fc_ulp_transport was called and it
2671 	 * returned a success. This is the only time callback will happen.
2672 	 * Otherwise, there is no point in waiting
2673 	 */
2674 	if ((ret == 0) && (xport_retval == FC_SUCCESS)) {
2675 		ret = fcp_ipkt_sema_wait(icmd);
2676 	}
2677 
2678 	/*
2679 	 * Copy data to IOCTL data structures
2680 	 */
2681 	rsp = NULL;
2682 	if ((ret == 0) && (xport_retval == FC_SUCCESS)) {
2683 		rsp = (struct fcp_rsp *)fpkt->pkt_resp;
2684 
2685 		if (fcp_validate_fcp_response(rsp, pptr) != FC_SUCCESS) {
2686 			fcp_log(CE_WARN, pptr->port_dip,
2687 			    "!SCSI command to d_id=0x%x lun=0x%x"
2688 			    " failed, Bad FCP response values:"
2689 			    " rsvd1=%x, rsvd2=%x, sts-rsvd1=%x,"
2690 			    " sts-rsvd2=%x, rsplen=%x, senselen=%x",
2691 			    ptgt->tgt_d_id, plun->lun_num,
2692 			    rsp->reserved_0, rsp->reserved_1,
2693 			    rsp->fcp_u.fcp_status.reserved_0,
2694 			    rsp->fcp_u.fcp_status.reserved_1,
2695 			    rsp->fcp_response_len, rsp->fcp_sense_len);
2696 
2697 			ret = EIO;
2698 		}
2699 	}
2700 
2701 	if ((ret == 0) && (rsp != NULL)) {
2702 		/*
2703 		 * Calc response lengths
2704 		 */
2705 		sense_len = 0;
2706 		info_len = 0;
2707 
2708 		if (rsp->fcp_u.fcp_status.rsp_len_set) {
2709 			info_len = rsp->fcp_response_len;
2710 		}
2711 
2712 		rsp_info   = (struct fcp_rsp_info *)
2713 		    ((uint8_t *)rsp + sizeof (struct fcp_rsp));
2714 
2715 		/*
2716 		 * Get SCSI status
2717 		 */
2718 		fscsi->scsi_bufstatus = rsp->fcp_u.fcp_status.scsi_status;
2719 		/*
2720 		 * If a lun was just added or removed and the next command
2721 		 * comes through this interface, we need to capture the check
2722 		 * condition so we can discover the new topology.
2723 		 */
2724 		if (fscsi->scsi_bufstatus != STATUS_GOOD &&
2725 		    rsp->fcp_u.fcp_status.sense_len_set) {
2726 			sense_len = rsp->fcp_sense_len;
2727 			rsp_sense  = (caddr_t)((uint8_t *)rsp_info + info_len);
2728 			sense_to = (struct scsi_extended_sense *)rsp_sense;
2729 			if ((FCP_SENSE_REPORTLUN_CHANGED(sense_to)) ||
2730 			    (FCP_SENSE_NO_LUN(sense_to))) {
2731 				reconfig_lun = TRUE;
2732 			}
2733 		}
2734 
2735 		if (fscsi->scsi_bufstatus == STATUS_GOOD && (ptgt != NULL) &&
2736 		    (reconfig_lun || (scsi_cdb->scc_cmd == SCMD_REPORT_LUN))) {
2737 			if (reconfig_lun == FALSE) {
2738 				reconfig_status =
2739 				    fcp_is_reconfig_needed(ptgt, fpkt);
2740 			}
2741 
2742 			if ((reconfig_lun == TRUE) ||
2743 			    (reconfig_status == TRUE)) {
2744 				mutex_enter(&ptgt->tgt_mutex);
2745 				if (ptgt->tgt_tid == NULL) {
2746 					/*
2747 					 * Either we've been notified the
2748 					 * REPORT_LUN data has changed, or
2749 					 * we've determined on our own that
2750 					 * we're out of date.  Kick off
2751 					 * rediscovery.
2752 					 */
2753 					tid = timeout(fcp_reconfigure_luns,
2754 					    (caddr_t)ptgt, drv_usectohz(1));
2755 
2756 					ptgt->tgt_tid = tid;
2757 					ptgt->tgt_state |= FCP_TGT_BUSY;
2758 					ret = EBUSY;
2759 					reconfig_pending = TRUE;
2760 				}
2761 				mutex_exit(&ptgt->tgt_mutex);
2762 			}
2763 		}
2764 
2765 		/*
2766 		 * Calc residuals and buffer lengths
2767 		 */
2768 
2769 		if (ret == 0) {
2770 			buf_len = fscsi->scsi_buflen;
2771 			fscsi->scsi_bufresid	= 0;
2772 			if (rsp->fcp_u.fcp_status.resid_under) {
2773 				if (rsp->fcp_resid <= fscsi->scsi_buflen) {
2774 					fscsi->scsi_bufresid = rsp->fcp_resid;
2775 				} else {
2776 					cmn_err(CE_WARN, "fcp: bad residue %x "
2777 					    "for txfer len %x", rsp->fcp_resid,
2778 					    fscsi->scsi_buflen);
2779 					fscsi->scsi_bufresid =
2780 					    fscsi->scsi_buflen;
2781 				}
2782 				buf_len -= fscsi->scsi_bufresid;
2783 			}
2784 			if (rsp->fcp_u.fcp_status.resid_over) {
2785 				fscsi->scsi_bufresid = -rsp->fcp_resid;
2786 			}
2787 
2788 			fscsi->scsi_rqresid	= fscsi->scsi_rqlen - sense_len;
2789 			if (fscsi->scsi_rqlen < sense_len) {
2790 				sense_len = fscsi->scsi_rqlen;
2791 			}
2792 
2793 			fscsi->scsi_fc_rspcode	= 0;
2794 			if (rsp->fcp_u.fcp_status.rsp_len_set) {
2795 				fscsi->scsi_fc_rspcode	= rsp_info->rsp_code;
2796 			}
2797 			fscsi->scsi_pkt_state	= fpkt->pkt_state;
2798 			fscsi->scsi_pkt_action	= fpkt->pkt_action;
2799 			fscsi->scsi_pkt_reason	= fpkt->pkt_reason;
2800 
2801 			/*
2802 			 * Copy data and request sense
2803 			 *
2804 			 * Data must be copied by using the FCP_CP_IN macro.
2805 			 * This will ensure the proper byte order since the data
2806 			 * is being copied directly from the memory mapped
2807 			 * device register.
2808 			 *
2809 			 * The response (and request sense) will be in the
2810 			 * correct byte order.	No special copy is necessary.
2811 			 */
2812 
2813 			if (buf_len) {
2814 				FCP_CP_IN(fpkt->pkt_data,
2815 				    fscsi->scsi_bufaddr,
2816 				    fpkt->pkt_data_acc,
2817 				    buf_len);
2818 			}
2819 			bcopy((void *)rsp_sense,
2820 			    (void *)fscsi->scsi_rqbufaddr,
2821 			    sense_len);
2822 		}
2823 	}
2824 
2825 	/*
2826 	 * Cleanup transport data structures if icmd was alloc-ed
2827 	 * So, cleanup happens in the same thread that icmd was alloc-ed
2828 	 */
2829 	if (icmd != NULL) {
2830 		fcp_ipkt_sema_cleanup(icmd);
2831 	}
2832 
2833 	/* restore pm busy/idle status */
2834 	if (port_busy) {
2835 		fc_ulp_idle_port(pptr->port_fp_handle);
2836 	}
2837 
2838 	/*
2839 	 * Cleanup target.  if a reconfig is pending, don't clear the BUSY
2840 	 * flag, it'll be cleared when the reconfig is complete.
2841 	 */
2842 	if ((ptgt != NULL) && !reconfig_pending) {
2843 		/*
2844 		 * If target was created,
2845 		 */
2846 		if (target_created) {
2847 			mutex_enter(&ptgt->tgt_mutex);
2848 			ptgt->tgt_state &= ~FCP_TGT_BUSY;
2849 			mutex_exit(&ptgt->tgt_mutex);
2850 		} else {
2851 			/*
2852 			 * De-mark target as busy
2853 			 */
2854 			mutex_enter(&ptgt->tgt_mutex);
2855 			ptgt->tgt_state &= ~FCP_TGT_BUSY;
2856 			mutex_exit(&ptgt->tgt_mutex);
2857 		}
2858 	}
2859 	return (ret);
2860 }
2861 
2862 
2863 static int
2864 fcp_is_reconfig_needed(struct fcp_tgt *ptgt,
2865     fc_packet_t	*fpkt)
2866 {
2867 	uchar_t			*lun_string;
2868 	uint16_t		lun_num, i;
2869 	int			num_luns;
2870 	int			actual_luns;
2871 	int			num_masked_luns;
2872 	int			lun_buflen;
2873 	struct fcp_lun	*plun	= NULL;
2874 	struct fcp_reportlun_resp	*report_lun;
2875 	uint8_t			reconfig_needed = FALSE;
2876 	uint8_t			lun_exists = FALSE;
2877 	fcp_port_t			*pptr		 = ptgt->tgt_port;
2878 
2879 	report_lun = kmem_zalloc(fpkt->pkt_datalen, KM_SLEEP);
2880 
2881 	FCP_CP_IN(fpkt->pkt_data, report_lun, fpkt->pkt_data_acc,
2882 	    fpkt->pkt_datalen);
2883 
2884 	/* get number of luns (which is supplied as LUNS * 8) */
2885 	num_luns = BE_32(report_lun->num_lun) >> 3;
2886 
2887 	/*
2888 	 * Figure out exactly how many lun strings our response buffer
2889 	 * can hold.
2890 	 */
2891 	lun_buflen = (fpkt->pkt_datalen -
2892 	    2 * sizeof (uint32_t)) / sizeof (longlong_t);
2893 
2894 	/*
2895 	 * Is our response buffer full or not? We don't want to
2896 	 * potentially walk beyond the number of luns we have.
2897 	 */
2898 	if (num_luns <= lun_buflen) {
2899 		actual_luns = num_luns;
2900 	} else {
2901 		actual_luns = lun_buflen;
2902 	}
2903 
2904 	mutex_enter(&ptgt->tgt_mutex);
2905 
2906 	/* Scan each lun to see if we have masked it. */
2907 	num_masked_luns = 0;
2908 	if (fcp_lun_blacklist != NULL) {
2909 		for (i = 0; i < actual_luns; i++) {
2910 			lun_string = (uchar_t *)&(report_lun->lun_string[i]);
2911 			switch (lun_string[0] & 0xC0) {
2912 			case FCP_LUN_ADDRESSING:
2913 			case FCP_PD_ADDRESSING:
2914 			case FCP_VOLUME_ADDRESSING:
2915 				lun_num = ((lun_string[0] & 0x3F) << 8)
2916 				    | lun_string[1];
2917 				if (fcp_should_mask(&ptgt->tgt_port_wwn,
2918 				    lun_num) == TRUE) {
2919 					num_masked_luns++;
2920 				}
2921 				break;
2922 			default:
2923 				break;
2924 			}
2925 		}
2926 	}
2927 
2928 	/*
2929 	 * The quick and easy check.  If the number of LUNs reported
2930 	 * doesn't match the number we currently know about, we need
2931 	 * to reconfigure.
2932 	 */
2933 	if (num_luns && num_luns != (ptgt->tgt_lun_cnt + num_masked_luns)) {
2934 		mutex_exit(&ptgt->tgt_mutex);
2935 		kmem_free(report_lun, fpkt->pkt_datalen);
2936 		return (TRUE);
2937 	}
2938 
2939 	/*
2940 	 * If the quick and easy check doesn't turn up anything, we walk
2941 	 * the list of luns from the REPORT_LUN response and look for
2942 	 * any luns we don't know about.  If we find one, we know we need
2943 	 * to reconfigure. We will skip LUNs that are masked because of the
2944 	 * blacklist.
2945 	 */
2946 	for (i = 0; i < actual_luns; i++) {
2947 		lun_string = (uchar_t *)&(report_lun->lun_string[i]);
2948 		lun_exists = FALSE;
2949 		switch (lun_string[0] & 0xC0) {
2950 		case FCP_LUN_ADDRESSING:
2951 		case FCP_PD_ADDRESSING:
2952 		case FCP_VOLUME_ADDRESSING:
2953 			lun_num = ((lun_string[0] & 0x3F) << 8) | lun_string[1];
2954 
2955 			if ((fcp_lun_blacklist != NULL) && (fcp_should_mask(
2956 			    &ptgt->tgt_port_wwn, lun_num) == TRUE)) {
2957 				lun_exists = TRUE;
2958 				break;
2959 			}
2960 
2961 			for (plun = ptgt->tgt_lun; plun;
2962 			    plun = plun->lun_next) {
2963 				if (plun->lun_num == lun_num) {
2964 					lun_exists = TRUE;
2965 					break;
2966 				}
2967 			}
2968 			break;
2969 		default:
2970 			break;
2971 		}
2972 
2973 		if (lun_exists == FALSE) {
2974 			reconfig_needed = TRUE;
2975 			break;
2976 		}
2977 	}
2978 
2979 	mutex_exit(&ptgt->tgt_mutex);
2980 	kmem_free(report_lun, fpkt->pkt_datalen);
2981 
2982 	return (reconfig_needed);
2983 }
2984 
2985 /*
2986  * This function is called by fcp_handle_page83 and uses inquiry response data
2987  * stored in plun->lun_inq to determine whether or not a device is a member of
2988  * the table fcp_symmetric_disk_table_size. We return 0 if it is in the table,
2989  * otherwise 1.
2990  */
2991 static int
2992 fcp_symmetric_device_probe(struct fcp_lun *plun)
2993 {
2994 	struct scsi_inquiry	*stdinq = &plun->lun_inq;
2995 	char			*devidptr;
2996 	int			i, len;
2997 
2998 	for (i = 0; i < fcp_symmetric_disk_table_size; i++) {
2999 		devidptr = fcp_symmetric_disk_table[i];
3000 		len = (int)strlen(devidptr);
3001 
3002 		if (bcmp(stdinq->inq_vid, devidptr, len) == 0) {
3003 			return (0);
3004 		}
3005 	}
3006 	return (1);
3007 }
3008 
3009 
3010 /*
3011  * This function is called by fcp_ioctl for the FCP_STATE_COUNT ioctl
3012  * It basically returns the current count of # of state change callbacks
3013  * i.e the value of tgt_change_cnt.
3014  *
3015  * INPUT:
3016  *   fcp_ioctl.fp_minor -> The minor # of the fp port
3017  *   fcp_ioctl.listlen	-> 1
3018  *   fcp_ioctl.list	-> Pointer to a 32 bit integer
3019  */
3020 /*ARGSUSED2*/
3021 static int
3022 fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval)
3023 {
3024 	int			ret;
3025 	uint32_t		link_cnt;
3026 	struct fcp_ioctl	fioctl;
3027 	struct fcp_port	*pptr = NULL;
3028 
3029 	if ((ret = fcp_copyin_fcp_ioctl_data(data, mode, rval, &fioctl,
3030 	    &pptr)) != 0) {
3031 		return (ret);
3032 	}
3033 
3034 	ASSERT(pptr != NULL);
3035 
3036 	if (fioctl.listlen != 1) {
3037 		return (EINVAL);
3038 	}
3039 
3040 	mutex_enter(&pptr->port_mutex);
3041 	if (pptr->port_state & FCP_STATE_OFFLINE) {
3042 		mutex_exit(&pptr->port_mutex);
3043 		return (ENXIO);
3044 	}
3045 
3046 	/*
3047 	 * FCP_STATE_INIT is set in 2 cases (not sure why it is overloaded):
3048 	 * When the fcp initially attaches to the port and there are nothing
3049 	 * hanging out of the port or if there was a repeat offline state change
3050 	 * callback (refer fcp_statec_callback() FC_STATE_OFFLINE case).
3051 	 * In the latter case, port_tmp_cnt will be non-zero and that is how we
3052 	 * will differentiate the 2 cases.
3053 	 */
3054 	if ((pptr->port_state & FCP_STATE_INIT) && pptr->port_tmp_cnt) {
3055 		mutex_exit(&pptr->port_mutex);
3056 		return (ENXIO);
3057 	}
3058 
3059 	link_cnt = pptr->port_link_cnt;
3060 	mutex_exit(&pptr->port_mutex);
3061 
3062 	if (ddi_copyout(&link_cnt, fioctl.list, (sizeof (uint32_t)), mode)) {
3063 		return (EFAULT);
3064 	}
3065 
3066 #ifdef	_MULTI_DATAMODEL
3067 	switch (ddi_model_convert_from(mode & FMODELS)) {
3068 	case DDI_MODEL_ILP32: {
3069 		struct fcp32_ioctl f32_ioctl;
3070 
3071 		f32_ioctl.fp_minor = fioctl.fp_minor;
3072 		f32_ioctl.listlen = fioctl.listlen;
3073 		f32_ioctl.list = (caddr32_t)(long)fioctl.list;
3074 		if (ddi_copyout((void *)&f32_ioctl, (void *)data,
3075 		    sizeof (struct fcp32_ioctl), mode)) {
3076 			return (EFAULT);
3077 		}
3078 		break;
3079 	}
3080 	case DDI_MODEL_NONE:
3081 		if (ddi_copyout((void *)&fioctl, (void *)data,
3082 		    sizeof (struct fcp_ioctl), mode)) {
3083 			return (EFAULT);
3084 		}
3085 		break;
3086 	}
3087 #else	/* _MULTI_DATAMODEL */
3088 
3089 	if (ddi_copyout((void *)&fioctl, (void *)data,
3090 	    sizeof (struct fcp_ioctl), mode)) {
3091 		return (EFAULT);
3092 	}
3093 #endif	/* _MULTI_DATAMODEL */
3094 
3095 	return (0);
3096 }
3097 
3098 /*
3099  * This function copies the fcp_ioctl structure passed in from user land
3100  * into kernel land. Handles 32 bit applications.
3101  */
3102 /*ARGSUSED*/
3103 static int
3104 fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *data, int mode, int *rval,
3105     struct fcp_ioctl *fioctl, struct fcp_port **pptr)
3106 {
3107 	struct fcp_port	*t_pptr;
3108 
3109 #ifdef	_MULTI_DATAMODEL
3110 	switch (ddi_model_convert_from(mode & FMODELS)) {
3111 	case DDI_MODEL_ILP32: {
3112 		struct fcp32_ioctl f32_ioctl;
3113 
3114 		if (ddi_copyin((void *)data, (void *)&f32_ioctl,
3115 		    sizeof (struct fcp32_ioctl), mode)) {
3116 			return (EFAULT);
3117 		}
3118 		fioctl->fp_minor = f32_ioctl.fp_minor;
3119 		fioctl->listlen = f32_ioctl.listlen;
3120 		fioctl->list = (caddr_t)(long)f32_ioctl.list;
3121 		break;
3122 	}
3123 	case DDI_MODEL_NONE:
3124 		if (ddi_copyin((void *)data, (void *)fioctl,
3125 		    sizeof (struct fcp_ioctl), mode)) {
3126 			return (EFAULT);
3127 		}
3128 		break;
3129 	}
3130 
3131 #else	/* _MULTI_DATAMODEL */
3132 	if (ddi_copyin((void *)data, (void *)fioctl,
3133 	    sizeof (struct fcp_ioctl), mode)) {
3134 		return (EFAULT);
3135 	}
3136 #endif	/* _MULTI_DATAMODEL */
3137 
3138 	/*
3139 	 * Right now we can assume that the minor number matches with
3140 	 * this instance of fp. If this changes we will need to
3141 	 * revisit this logic.
3142 	 */
3143 	mutex_enter(&fcp_global_mutex);
3144 	t_pptr = fcp_port_head;
3145 	while (t_pptr) {
3146 		if (t_pptr->port_instance == (uint32_t)fioctl->fp_minor) {
3147 			break;
3148 		} else {
3149 			t_pptr = t_pptr->port_next;
3150 		}
3151 	}
3152 	*pptr = t_pptr;
3153 	mutex_exit(&fcp_global_mutex);
3154 	if (t_pptr == NULL) {
3155 		return (ENXIO);
3156 	}
3157 
3158 	return (0);
3159 }
3160 
3161 /*
3162  *     Function: fcp_port_create_tgt
3163  *
3164  *  Description: As the name suggest this function creates the target context
3165  *		 specified by the the WWN provided by the caller.  If the
3166  *		 creation goes well and the target is known by fp/fctl a PLOGI
3167  *		 followed by a PRLI are issued.
3168  *
3169  *     Argument: pptr		fcp port structure
3170  *		 pwwn		WWN of the target
3171  *		 ret_val	Address of the return code.  It could be:
3172  *				EIO, ENOMEM or 0.
3173  *		 fc_status	PLOGI or PRLI status completion
3174  *		 fc_pkt_state	PLOGI or PRLI state completion
3175  *		 fc_pkt_reason	PLOGI or PRLI reason completion
3176  *		 fc_pkt_action	PLOGI or PRLI action completion
3177  *
3178  * Return Value: NULL if it failed
3179  *		 Target structure address if it succeeds
3180  */
3181 static struct fcp_tgt *
3182 fcp_port_create_tgt(struct fcp_port *pptr, la_wwn_t *pwwn, int *ret_val,
3183     int *fc_status, int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action)
3184 {
3185 	struct fcp_tgt	*ptgt = NULL;
3186 	fc_portmap_t		devlist;
3187 	int			lcount;
3188 	int			error;
3189 
3190 	*ret_val = 0;
3191 
3192 	/*
3193 	 * Check FC port device & get port map
3194 	 */
3195 	if (fc_ulp_get_remote_port(pptr->port_fp_handle, pwwn,
3196 	    &error, 1) == NULL) {
3197 		*ret_val = EIO;
3198 	} else {
3199 		if (fc_ulp_pwwn_to_portmap(pptr->port_fp_handle, pwwn,
3200 		    &devlist) != FC_SUCCESS) {
3201 			*ret_val = EIO;
3202 		}
3203 	}
3204 
3205 	/* Set port map flags */
3206 	devlist.map_type = PORT_DEVICE_USER_CREATE;
3207 
3208 	/* Allocate target */
3209 	if (*ret_val == 0) {
3210 		lcount = pptr->port_link_cnt;
3211 		ptgt = fcp_alloc_tgt(pptr, &devlist, lcount);
3212 		if (ptgt == NULL) {
3213 			fcp_log(CE_WARN, pptr->port_dip,
3214 			    "!FC target allocation failed");
3215 			*ret_val = ENOMEM;
3216 		} else {
3217 			/* Setup target */
3218 			mutex_enter(&ptgt->tgt_mutex);
3219 
3220 			ptgt->tgt_statec_cause	= FCP_CAUSE_TGT_CHANGE;
3221 			ptgt->tgt_tmp_cnt	= 1;
3222 			ptgt->tgt_d_id		= devlist.map_did.port_id;
3223 			ptgt->tgt_hard_addr	=
3224 			    devlist.map_hard_addr.hard_addr;
3225 			ptgt->tgt_pd_handle	= devlist.map_pd;
3226 			ptgt->tgt_fca_dev	= NULL;
3227 
3228 			bcopy(&devlist.map_nwwn, &ptgt->tgt_node_wwn.raw_wwn[0],
3229 			    FC_WWN_SIZE);
3230 			bcopy(&devlist.map_pwwn, &ptgt->tgt_port_wwn.raw_wwn[0],
3231 			    FC_WWN_SIZE);
3232 
3233 			mutex_exit(&ptgt->tgt_mutex);
3234 		}
3235 	}
3236 
3237 	/* Release global mutex for PLOGI and PRLI */
3238 	mutex_exit(&fcp_global_mutex);
3239 
3240 	/* Send PLOGI (If necessary) */
3241 	if (*ret_val == 0) {
3242 		*ret_val = fcp_tgt_send_plogi(ptgt, fc_status,
3243 		    fc_pkt_state, fc_pkt_reason, fc_pkt_action);
3244 	}
3245 
3246 	/* Send PRLI (If necessary) */
3247 	if (*ret_val == 0) {
3248 		*ret_val = fcp_tgt_send_prli(ptgt, fc_status,
3249 		    fc_pkt_state, fc_pkt_reason, fc_pkt_action);
3250 	}
3251 
3252 	mutex_enter(&fcp_global_mutex);
3253 
3254 	return (ptgt);
3255 }
3256 
3257 /*
3258  *     Function: fcp_tgt_send_plogi
3259  *
3260  *  Description: This function sends a PLOGI to the target specified by the
3261  *		 caller and waits till it completes.
3262  *
3263  *     Argument: ptgt		Target to send the plogi to.
3264  *		 fc_status	Status returned by fp/fctl in the PLOGI request.
3265  *		 fc_pkt_state	State returned by fp/fctl in the PLOGI request.
3266  *		 fc_pkt_reason	Reason returned by fp/fctl in the PLOGI request.
3267  *		 fc_pkt_action	Action returned by fp/fctl in the PLOGI request.
3268  *
3269  * Return Value: 0
3270  *		 ENOMEM
3271  *		 EIO
3272  *
3273  *	Context: User context.
3274  */
3275 static int
3276 fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status, int *fc_pkt_state,
3277     int *fc_pkt_reason, int *fc_pkt_action)
3278 {
3279 	struct fcp_port	*pptr;
3280 	struct fcp_ipkt	*icmd;
3281 	struct fc_packet	*fpkt;
3282 	fc_frame_hdr_t		*hp;
3283 	struct la_els_logi	logi;
3284 	int			tcount;
3285 	int			lcount;
3286 	int			ret, login_retval = ~FC_SUCCESS;
3287 
3288 	ret = 0;
3289 
3290 	pptr = ptgt->tgt_port;
3291 
3292 	lcount = pptr->port_link_cnt;
3293 	tcount = ptgt->tgt_change_cnt;
3294 
3295 	/* Alloc internal packet */
3296 	icmd = fcp_icmd_alloc(pptr, ptgt, sizeof (la_els_logi_t),
3297 	    sizeof (la_els_logi_t), 0,
3298 	    pptr->port_state & FCP_STATE_FCA_IS_NODMA,
3299 	    lcount, tcount, 0, FC_INVALID_RSCN_COUNT);
3300 
3301 	if (icmd == NULL) {
3302 		ret = ENOMEM;
3303 	} else {
3304 		/*
3305 		 * Setup internal packet as sema sync
3306 		 */
3307 		fcp_ipkt_sema_init(icmd);
3308 
3309 		/*
3310 		 * Setup internal packet (icmd)
3311 		 */
3312 		icmd->ipkt_lun		= NULL;
3313 		icmd->ipkt_restart	= 0;
3314 		icmd->ipkt_retries	= 0;
3315 		icmd->ipkt_opcode	= LA_ELS_PLOGI;
3316 
3317 		/*
3318 		 * Setup fc_packet
3319 		 */
3320 		fpkt = icmd->ipkt_fpkt;
3321 
3322 		fpkt->pkt_tran_flags	= FC_TRAN_CLASS3 | FC_TRAN_INTR;
3323 		fpkt->pkt_tran_type	= FC_PKT_EXCHANGE;
3324 		fpkt->pkt_timeout	= FCP_ELS_TIMEOUT;
3325 
3326 		/*
3327 		 * Setup FC frame header
3328 		 */
3329 		hp = &fpkt->pkt_cmd_fhdr;
3330 
3331 		hp->s_id	= pptr->port_id;	/* source ID */
3332 		hp->d_id	= ptgt->tgt_d_id;	/* dest ID */
3333 		hp->r_ctl	= R_CTL_ELS_REQ;
3334 		hp->type	= FC_TYPE_EXTENDED_LS;
3335 		hp->f_ctl	= F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ;
3336 		hp->seq_id	= 0;
3337 		hp->rsvd	= 0;
3338 		hp->df_ctl	= 0;
3339 		hp->seq_cnt	= 0;
3340 		hp->ox_id	= 0xffff;		/* i.e. none */
3341 		hp->rx_id	= 0xffff;		/* i.e. none */
3342 		hp->ro		= 0;
3343 
3344 		/*
3345 		 * Setup PLOGI
3346 		 */
3347 		bzero(&logi, sizeof (struct la_els_logi));
3348 		logi.ls_code.ls_code = LA_ELS_PLOGI;
3349 
3350 		FCP_CP_OUT((uint8_t *)&logi, fpkt->pkt_cmd,
3351 		    fpkt->pkt_cmd_acc, sizeof (struct la_els_logi));
3352 
3353 		/*
3354 		 * Send PLOGI
3355 		 */
3356 		*fc_status = login_retval =
3357 		    fc_ulp_login(pptr->port_fp_handle, &fpkt, 1);
3358 		if (*fc_status != FC_SUCCESS) {
3359 			ret = EIO;
3360 		}
3361 	}
3362 
3363 	/*
3364 	 * Wait for completion
3365 	 */
3366 	if ((ret == 0) && (login_retval == FC_SUCCESS)) {
3367 		ret = fcp_ipkt_sema_wait(icmd);
3368 
3369 		*fc_pkt_state	= fpkt->pkt_state;
3370 		*fc_pkt_reason	= fpkt->pkt_reason;
3371 		*fc_pkt_action	= fpkt->pkt_action;
3372 	}
3373 
3374 	/*
3375 	 * Cleanup transport data structures if icmd was alloc-ed AND if there
3376 	 * is going to be no callback (i.e if fc_ulp_login() failed).
3377 	 * Otherwise, cleanup happens in callback routine.
3378 	 */
3379 	if (icmd != NULL) {
3380 		fcp_ipkt_sema_cleanup(icmd);
3381 	}
3382 
3383 	return (ret);
3384 }
3385 
3386 /*
3387  *     Function: fcp_tgt_send_prli
3388  *
3389  *  Description: Does nothing as of today.
3390  *
3391  *     Argument: ptgt		Target to send the prli to.
3392  *		 fc_status	Status returned by fp/fctl in the PRLI request.
3393  *		 fc_pkt_state	State returned by fp/fctl in the PRLI request.
3394  *		 fc_pkt_reason	Reason returned by fp/fctl in the PRLI request.
3395  *		 fc_pkt_action	Action returned by fp/fctl in the PRLI request.
3396  *
3397  * Return Value: 0
3398  */
3399 /*ARGSUSED*/
3400 static int
3401 fcp_tgt_send_prli(struct fcp_tgt *ptgt, int *fc_status, int *fc_pkt_state,
3402     int *fc_pkt_reason, int *fc_pkt_action)
3403 {
3404 	return (0);
3405 }
3406 
3407 /*
3408  *     Function: fcp_ipkt_sema_init
3409  *
3410  *  Description: Initializes the semaphore contained in the internal packet.
3411  *
3412  *     Argument: icmd	Internal packet the semaphore of which must be
3413  *			initialized.
3414  *
3415  * Return Value: None
3416  *
3417  *	Context: User context only.
3418  */
3419 static void
3420 fcp_ipkt_sema_init(struct fcp_ipkt *icmd)
3421 {
3422 	struct fc_packet	*fpkt;
3423 
3424 	fpkt = icmd->ipkt_fpkt;
3425 
3426 	/* Create semaphore for sync */
3427 	sema_init(&(icmd->ipkt_sema), 0, NULL, SEMA_DRIVER, NULL);
3428 
3429 	/* Setup the completion callback */
3430 	fpkt->pkt_comp = fcp_ipkt_sema_callback;
3431 }
3432 
3433 /*
3434  *     Function: fcp_ipkt_sema_wait
3435  *
3436  *  Description: Wait on the semaphore embedded in the internal packet.	 The
3437  *		 semaphore is released in the callback.
3438  *
3439  *     Argument: icmd	Internal packet to wait on for completion.
3440  *
3441  * Return Value: 0
3442  *		 EIO
3443  *		 EBUSY
3444  *		 EAGAIN
3445  *
3446  *	Context: User context only.
3447  *
3448  * This function does a conversion between the field pkt_state of the fc_packet
3449  * embedded in the internal packet (icmd) and the code it returns.
3450  */
3451 static int
3452 fcp_ipkt_sema_wait(struct fcp_ipkt *icmd)
3453 {
3454 	struct fc_packet	*fpkt;
3455 	int	ret;
3456 
3457 	ret = EIO;
3458 	fpkt = icmd->ipkt_fpkt;
3459 
3460 	/*
3461 	 * Wait on semaphore
3462 	 */
3463 	sema_p(&(icmd->ipkt_sema));
3464 
3465 	/*
3466 	 * Check the status of the FC packet
3467 	 */
3468 	switch (fpkt->pkt_state) {
3469 	case FC_PKT_SUCCESS:
3470 		ret = 0;
3471 		break;
3472 	case FC_PKT_LOCAL_RJT:
3473 		switch (fpkt->pkt_reason) {
3474 		case FC_REASON_SEQ_TIMEOUT:
3475 		case FC_REASON_RX_BUF_TIMEOUT:
3476 			ret = EAGAIN;
3477 			break;
3478 		case FC_REASON_PKT_BUSY:
3479 			ret = EBUSY;
3480 			break;
3481 		}
3482 		break;
3483 	case FC_PKT_TIMEOUT:
3484 		ret = EAGAIN;
3485 		break;
3486 	case FC_PKT_LOCAL_BSY:
3487 	case FC_PKT_TRAN_BSY:
3488 	case FC_PKT_NPORT_BSY:
3489 	case FC_PKT_FABRIC_BSY:
3490 		ret = EBUSY;
3491 		break;
3492 	case FC_PKT_LS_RJT:
3493 	case FC_PKT_BA_RJT:
3494 		switch (fpkt->pkt_reason) {
3495 		case FC_REASON_LOGICAL_BSY:
3496 			ret = EBUSY;
3497 			break;
3498 		}
3499 		break;
3500 	case FC_PKT_FS_RJT:
3501 		switch (fpkt->pkt_reason) {
3502 		case FC_REASON_FS_LOGICAL_BUSY:
3503 			ret = EBUSY;
3504 			break;
3505 		}
3506 		break;
3507 	}
3508 
3509 	return (ret);
3510 }
3511 
3512 /*
3513  *     Function: fcp_ipkt_sema_callback
3514  *
3515  *  Description: Registered as the completion callback function for the FC
3516  *		 transport when the ipkt semaphore is used for sync. This will
3517  *		 cleanup the used data structures, if necessary and wake up
3518  *		 the user thread to complete the transaction.
3519  *
3520  *     Argument: fpkt	FC packet (points to the icmd)
3521  *
3522  * Return Value: None
3523  *
3524  *	Context: User context only
3525  */
3526 static void
3527 fcp_ipkt_sema_callback(struct fc_packet *fpkt)
3528 {
3529 	struct fcp_ipkt	*icmd;
3530 
3531 	icmd = (struct fcp_ipkt *)fpkt->pkt_ulp_private;
3532 
3533 	/*
3534 	 * Wake up user thread
3535 	 */
3536 	sema_v(&(icmd->ipkt_sema));
3537 }
3538 
3539 /*
3540  *     Function: fcp_ipkt_sema_cleanup
3541  *
3542  *  Description: Called to cleanup (if necessary) the data structures used
3543  *		 when ipkt sema is used for sync.  This function will detect
3544  *		 whether the caller is the last thread (via counter) and
3545  *		 cleanup only if necessary.
3546  *
3547  *     Argument: icmd	Internal command packet
3548  *
3549  * Return Value: None
3550  *
3551  *	Context: User context only
3552  */
3553 static void
3554 fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd)
3555 {
3556 	struct fcp_tgt	*ptgt;
3557 	struct fcp_port	*pptr;
3558 
3559 	ptgt = icmd->ipkt_tgt;
3560 	pptr = icmd->ipkt_port;
3561 
3562 	/*
3563 	 * Acquire data structure
3564 	 */
3565 	mutex_enter(&ptgt->tgt_mutex);
3566 
3567 	/*
3568 	 * Destroy semaphore
3569 	 */
3570 	sema_destroy(&(icmd->ipkt_sema));
3571 
3572 	/*
3573 	 * Cleanup internal packet
3574 	 */
3575 	mutex_exit(&ptgt->tgt_mutex);
3576 	fcp_icmd_free(pptr, icmd);
3577 }
3578 
3579 /*
3580  *     Function: fcp_port_attach
3581  *
3582  *  Description: Called by the transport framework to resume, suspend or
3583  *		 attach a new port.
3584  *
3585  *     Argument: ulph		Port handle
3586  *		 *pinfo		Port information
3587  *		 cmd		Command
3588  *		 s_id		Port ID
3589  *
3590  * Return Value: FC_FAILURE or FC_SUCCESS
3591  */
3592 /*ARGSUSED*/
3593 static int
3594 fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo,
3595     fc_attach_cmd_t cmd, uint32_t s_id)
3596 {
3597 	int	instance;
3598 	int	res = FC_FAILURE; /* default result */
3599 
3600 	ASSERT(pinfo != NULL);
3601 
3602 	instance = ddi_get_instance(pinfo->port_dip);
3603 
3604 	switch (cmd) {
3605 	case FC_CMD_ATTACH:
3606 		/*
3607 		 * this port instance attaching for the first time (or after
3608 		 * being detached before)
3609 		 */
3610 		if (fcp_handle_port_attach(ulph, pinfo, s_id,
3611 		    instance) == DDI_SUCCESS) {
3612 			res = FC_SUCCESS;
3613 		} else {
3614 			ASSERT(ddi_get_soft_state(fcp_softstate,
3615 			    instance) == NULL);
3616 		}
3617 		break;
3618 
3619 	case FC_CMD_RESUME:
3620 	case FC_CMD_POWER_UP:
3621 		/*
3622 		 * this port instance was attached and the suspended and
3623 		 * will now be resumed
3624 		 */
3625 		if (fcp_handle_port_resume(ulph, pinfo, s_id, cmd,
3626 		    instance) == DDI_SUCCESS) {
3627 			res = FC_SUCCESS;
3628 		}
3629 		break;
3630 
3631 	default:
3632 		/* shouldn't happen */
3633 		FCP_TRACE(fcp_logq, "fcp",
3634 		    fcp_trace, FCP_BUF_LEVEL_2, 0,
3635 		    "port_attach: unknown cmdcommand: %d", cmd);
3636 		break;
3637 	}
3638 
3639 	/* return result */
3640 	FCP_DTRACE(fcp_logq, "fcp", fcp_trace,
3641 	    FCP_BUF_LEVEL_1, 0, "fcp_port_attach returning %d", res);
3642 
3643 	return (res);
3644 }
3645 
3646 
3647 /*
3648  * detach or suspend this port instance
3649  *
3650  * acquires and releases the global mutex
3651  *
3652  * acquires and releases the mutex for this port
3653  *
3654  * acquires and releases the hotplug mutex for this port
3655  */
3656 /*ARGSUSED*/
3657 static int
3658 fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info,
3659     fc_detach_cmd_t cmd)
3660 {
3661 	int			flag;
3662 	int			instance;
3663 	struct fcp_port		*pptr;
3664 
3665 	instance = ddi_get_instance(info->port_dip);
3666 	pptr = ddi_get_soft_state(fcp_softstate, instance);
3667 
3668 	switch (cmd) {
3669 	case FC_CMD_SUSPEND:
3670 		FCP_DTRACE(fcp_logq, "fcp",
3671 		    fcp_trace, FCP_BUF_LEVEL_8, 0,
3672 		    "port suspend called for port %d", instance);
3673 		flag = FCP_STATE_SUSPENDED;
3674 		break;
3675 
3676 	case FC_CMD_POWER_DOWN:
3677 		FCP_DTRACE(fcp_logq, "fcp",
3678 		    fcp_trace, FCP_BUF_LEVEL_8, 0,
3679 		    "port power down called for port %d", instance);
3680 		flag = FCP_STATE_POWER_DOWN;
3681 		break;
3682 
3683 	case FC_CMD_DETACH:
3684 		FCP_DTRACE(fcp_logq, "fcp",
3685 		    fcp_trace, FCP_BUF_LEVEL_8, 0,
3686 		    "port detach called for port %d", instance);
3687 		flag = FCP_STATE_DETACHING;
3688 		break;
3689 
3690 	default:
3691 		/* shouldn't happen */
3692 		return (FC_FAILURE);
3693 	}
3694 	FCP_DTRACE(fcp_logq, "fcp", fcp_trace,
3695 	    FCP_BUF_LEVEL_1, 0, "fcp_port_detach returning");
3696 
3697 	return (fcp_handle_port_detach(pptr, flag, instance));
3698 }
3699 
3700 
3701 /*
3702  * called for ioctls on the transport's devctl interface, and the transport
3703  * has passed it to us
3704  *
3705  * this will only be called for device control ioctls (i.e. hotplugging stuff)
3706  *
3707  * return FC_SUCCESS if we decide to claim the ioctl,
3708  * else return FC_UNCLAIMED
3709  *
3710  * *rval is set iff we decide to claim the ioctl
3711  */
3712 /*ARGSUSED*/
3713 static int
3714 fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev, int cmd,
3715     intptr_t data, int mode, cred_t *credp, int *rval, uint32_t claimed)
3716 {
3717 	int			retval = FC_UNCLAIMED;	/* return value */
3718 	struct fcp_port		*pptr = NULL;		/* our soft state */
3719 	struct devctl_iocdata	*dcp = NULL;		/* for devctl */
3720 	dev_info_t		*cdip;
3721 	mdi_pathinfo_t		*pip = NULL;
3722 	char			*ndi_nm;		/* NDI name */
3723 	char			*ndi_addr;		/* NDI addr */
3724 	int			is_mpxio, circ;
3725 	int			devi_entered = 0;
3726 	time_t			end_time;
3727 
3728 	ASSERT(rval != NULL);
3729 
3730 	FCP_DTRACE(fcp_logq, "fcp",
3731 	    fcp_trace, FCP_BUF_LEVEL_8, 0,
3732 	    "fcp_port_ioctl(cmd=0x%x, claimed=%d)", cmd, claimed);
3733 
3734 	/* if already claimed then forget it */
3735 	if (claimed) {
3736 		/*
3737 		 * for now, if this ioctl has already been claimed, then
3738 		 * we just ignore it
3739 		 */
3740 		return (retval);
3741 	}
3742 
3743 	/* get our port info */
3744 	if ((pptr = fcp_get_port(port_handle)) == NULL) {
3745 		fcp_log(CE_WARN, NULL,
3746 		    "!fcp:Invalid port handle handle in ioctl");
3747 		*rval = ENXIO;
3748 		return (retval);
3749 	}
3750 	is_mpxio = pptr->port_mpxio;
3751 
3752 	switch (cmd) {
3753 	case DEVCTL_BUS_GETSTATE:
3754 	case DEVCTL_BUS_QUIESCE:
3755 	case DEVCTL_BUS_UNQUIESCE:
3756 	case DEVCTL_BUS_RESET:
3757 	case DEVCTL_BUS_RESETALL:
3758 
3759 	case DEVCTL_BUS_DEV_CREATE:
3760 		if (ndi_dc_allochdl((void *)data, &