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