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