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