1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * Fibre Channel SCSI ULP Mapping driver
26  */
27 
28 #include <sys/scsi/scsi.h>
29 #include <sys/types.h>
30 #include <sys/varargs.h>
31 #include <sys/devctl.h>
32 #include <sys/thread.h>
33 #include <sys/thread.h>
34 #include <sys/open.h>
35 #include <sys/file.h>
36 #include <sys/sunndi.h>
37 #include <sys/console.h>
38 #include <sys/proc.h>
39 #include <sys/time.h>
40 #include <sys/utsname.h>
41 #include <sys/scsi/impl/scsi_reset_notify.h>
42 #include <sys/ndi_impldefs.h>
43 #include <sys/byteorder.h>
44 #include <sys/fs/dv_node.h>
45 #include <sys/ctype.h>
46 #include <sys/sunmdi.h>
47 
48 #include <sys/fibre-channel/fc.h>
49 #include <sys/fibre-channel/impl/fc_ulpif.h>
50 #include <sys/fibre-channel/ulp/fcpvar.h>
51 
52 /*
53  * Discovery Process
54  * =================
55  *
56  *    The discovery process is a major function of FCP.	 In order to help
57  * understand that function a flow diagram is given here.  This diagram
58  * doesn't claim to cover all the cases and the events that can occur during
59  * the discovery process nor the subtleties of the code.  The code paths shown
60  * are simplified.  Its purpose is to help the reader (and potentially bug
61  * fixer) have an overall view of the logic of the code.  For that reason the
62  * diagram covers the simple case of the line coming up cleanly or of a new
63  * port attaching to FCP the link being up.  The reader must keep in mind
64  * that:
65  *
66  *	- There are special cases where bringing devices online and offline
67  *	  is driven by Ioctl.
68  *
69  *	- The behavior of the discovery process can be modified through the
70  *	  .conf file.
71  *
72  *	- The line can go down and come back up at any time during the
73  *	  discovery process which explains some of the complexity of the code.
74  *
75  * ............................................................................
76  *
77  * STEP 1: The line comes up or a new Fibre Channel port attaches to FCP.
78  *
79  *
80  *			+-------------------------+
81  *   fp/fctl module --->|    fcp_port_attach	  |
82  *			+-------------------------+
83  *	   |			     |
84  *	   |			     |
85  *	   |			     v
86  *	   |		+-------------------------+
87  *	   |		| fcp_handle_port_attach  |
88  *	   |		+-------------------------+
89  *	   |				|
90  *	   |				|
91  *	   +--------------------+	|
92  *				|	|
93  *				v	v
94  *			+-------------------------+
95  *			|   fcp_statec_callback	  |
96  *			+-------------------------+
97  *				    |
98  *				    |
99  *				    v
100  *			+-------------------------+
101  *			|    fcp_handle_devices	  |
102  *			+-------------------------+
103  *				    |
104  *				    |
105  *				    v
106  *			+-------------------------+
107  *			|   fcp_handle_mapflags	  |
108  *			+-------------------------+
109  *				    |
110  *				    |
111  *				    v
112  *			+-------------------------+
113  *			|     fcp_send_els	  |
114  *			|			  |
115  *			| PLOGI or PRLI To all the|
116  *			| reachable devices.	  |
117  *			+-------------------------+
118  *
119  *
120  * ............................................................................
121  *
122  * STEP 2: The callback functions of the PLOGI and/or PRLI requests sent during
123  *	   STEP 1 are called (it is actually the same function).
124  *
125  *
126  *			+-------------------------+
127  *			|    fcp_icmd_callback	  |
128  *   fp/fctl module --->|			  |
129  *			| callback for PLOGI and  |
130  *			| PRLI.			  |
131  *			+-------------------------+
132  *				     |
133  *				     |
134  *	    Received PLOGI Accept   /-\	  Received PRLI Accept
135  *		       _ _ _ _ _ _ /   \_ _ _ _ _ _
136  *		      |		   \   /	   |
137  *		      |		    \-/		   |
138  *		      |				   |
139  *		      v				   v
140  *	+-------------------------+	+-------------------------+
141  *	|     fcp_send_els	  |	|     fcp_send_scsi	  |
142  *	|			  |	|			  |
143  *	|	  PRLI		  |	|	REPORT_LUN	  |
144  *	+-------------------------+	+-------------------------+
145  *
146  * ............................................................................
147  *
148  * STEP 3: The callback functions of the SCSI commands issued by FCP are called
149  *	   (It is actually the same function).
150  *
151  *
152  *			    +-------------------------+
153  *   fp/fctl module ------->|	 fcp_scsi_callback    |
154  *			    +-------------------------+
155  *					|
156  *					|
157  *					|
158  *	Receive REPORT_LUN reply       /-\	Receive INQUIRY PAGE83 reply
159  *		  _ _ _ _ _ _ _ _ _ _ /	  \_ _ _ _ _ _ _ _ _ _ _ _
160  *		 |		      \	  /			  |
161  *		 |		       \-/			  |
162  *		 |			|			  |
163  *		 | Receive INQUIRY reply|			  |
164  *		 |			|			  |
165  *		 v			v			  v
166  * +------------------------+ +----------------------+ +----------------------+
167  * |  fcp_handle_reportlun  | |	 fcp_handle_inquiry  | |  fcp_handle_page83   |
168  * |(Called for each Target)| | (Called for each LUN)| |(Called for each LUN) |
169  * +------------------------+ +----------------------+ +----------------------+
170  *		 |			|			  |
171  *		 |			|			  |
172  *		 |			|			  |
173  *		 v			v			  |
174  *     +-----------------+	+-----------------+		  |
175  *     |  fcp_send_scsi	 |	|  fcp_send_scsi  |		  |
176  *     |		 |	|		  |		  |
177  *     |     INQUIRY	 |	| INQUIRY PAGE83  |		  |
178  *     |  (To each LUN)	 |	+-----------------+		  |
179  *     +-----------------+					  |
180  *								  |
181  *								  v
182  *						      +------------------------+
183  *						      |	 fcp_call_finish_init  |
184  *						      +------------------------+
185  *								  |
186  *								  v
187  *						 +-----------------------------+
188  *						 |  fcp_call_finish_init_held  |
189  *						 +-----------------------------+
190  *								  |
191  *								  |
192  *			   All LUNs scanned			 /-\
193  *			       _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ /   \
194  *			      |					\   /
195  *			      |					 \-/
196  *			      v					  |
197  *		     +------------------+			  |
198  *		     |	fcp_finish_tgt	|			  |
199  *		     +------------------+			  |
200  *			      |	  Target Not Offline and	  |
201  *  Target Not Offline and    |	  not marked and tgt_node_state	  |
202  *  marked		     /-\  not FCP_TGT_NODE_ON_DEMAND	  |
203  *		_ _ _ _ _ _ /	\_ _ _ _ _ _ _ _		  |
204  *	       |	    \	/		|		  |
205  *	       |	     \-/		|		  |
206  *	       v				v		  |
207  * +----------------------------+     +-------------------+	  |
208  * |	 fcp_offline_target	|     |	 fcp_create_luns  |	  |
209  * |				|     +-------------------+	  |
210  * | A structure fcp_tgt_elem	|		|		  |
211  * | is created and queued in	|		v		  |
212  * | the FCP port list		|     +-------------------+	  |
213  * | port_offline_tgts.	 It	|     |	 fcp_pass_to_hp	  |	  |
214  * | will be unqueued by the	|     |			  |	  |
215  * | watchdog timer.		|     | Called for each	  |	  |
216  * +----------------------------+     | LUN. Dispatches	  |	  |
217  *		  |		      | fcp_hp_task	  |	  |
218  *		  |		      +-------------------+	  |
219  *		  |				|		  |
220  *		  |				|		  |
221  *		  |				|		  |
222  *		  |				+---------------->|
223  *		  |						  |
224  *		  +---------------------------------------------->|
225  *								  |
226  *								  |
227  *		All the targets (devices) have been scanned	 /-\
228  *				_ _ _ _	_ _ _ _	_ _ _ _ _ _ _ _ /   \
229  *			       |				\   /
230  *			       |				 \-/
231  *	    +-------------------------------------+		  |
232  *	    |		fcp_finish_init		  |		  |
233  *	    |					  |		  |
234  *	    | Signal broadcasts the condition	  |		  |
235  *	    | variable port_config_cv of the FCP  |		  |
236  *	    | port.  One potential code sequence  |		  |
237  *	    | waiting on the condition variable	  |		  |
238  *	    | the code sequence handling	  |		  |
239  *	    | BUS_CONFIG_ALL and BUS_CONFIG_DRIVER|		  |
240  *	    | The other is in the function	  |		  |
241  *	    | fcp_reconfig_wait which is called	  |		  |
242  *	    | in the transmit path preventing IOs |		  |
243  *	    | from going through till the disco-  |		  |
244  *	    | very process is over.		  |		  |
245  *	    +-------------------------------------+		  |
246  *			       |				  |
247  *			       |				  |
248  *			       +--------------------------------->|
249  *								  |
250  *								  v
251  *								Return
252  *
253  * ............................................................................
254  *
255  * STEP 4: The hot plug task is called (for each fcp_hp_elem).
256  *
257  *
258  *			+-------------------------+
259  *			|      fcp_hp_task	  |
260  *			+-------------------------+
261  *				     |
262  *				     |
263  *				     v
264  *			+-------------------------+
265  *			|     fcp_trigger_lun	  |
266  *			+-------------------------+
267  *				     |
268  *				     |
269  *				     v
270  *		   Bring offline    /-\	 Bring online
271  *		  _ _ _ _ _ _ _ _ _/   \_ _ _ _ _ _ _ _ _ _
272  *		 |		   \   /		   |
273  *		 |		    \-/			   |
274  *		 v					   v
275  *    +---------------------+			+-----------------------+
276  *    |	 fcp_offline_child  |			|      fcp_get_cip	|
277  *    +---------------------+			|			|
278  *						| Creates a dev_info_t	|
279  *						| or a mdi_pathinfo_t	|
280  *						| depending on whether	|
281  *						| mpxio is on or off.	|
282  *						+-----------------------+
283  *							   |
284  *							   |
285  *							   v
286  *						+-----------------------+
287  *						|  fcp_online_child	|
288  *						|			|
289  *						| Set device online	|
290  *						| using NDI or MDI.	|
291  *						+-----------------------+
292  *
293  * ............................................................................
294  *
295  * STEP 5: The watchdog timer expires.	The watch dog timer does much more that
296  *	   what is described here.  We only show the target offline path.
297  *
298  *
299  *			 +--------------------------+
300  *			 |	  fcp_watch	    |
301  *			 +--------------------------+
302  *				       |
303  *				       |
304  *				       v
305  *			 +--------------------------+
306  *			 |  fcp_scan_offline_tgts   |
307  *			 +--------------------------+
308  *				       |
309  *				       |
310  *				       v
311  *			 +--------------------------+
312  *			 |  fcp_offline_target_now  |
313  *			 +--------------------------+
314  *				       |
315  *				       |
316  *				       v
317  *			 +--------------------------+
318  *			 |   fcp_offline_tgt_luns   |
319  *			 +--------------------------+
320  *				       |
321  *				       |
322  *				       v
323  *			 +--------------------------+
324  *			 |     fcp_offline_lun	    |
325  *			 +--------------------------+
326  *				       |
327  *				       |
328  *				       v
329  *		     +----------------------------------+
330  *		     |	     fcp_offline_lun_now	|
331  *		     |					|
332  *		     | A request (or two if mpxio) is	|
333  *		     | sent to the hot plug task using	|
334  *		     | a fcp_hp_elem structure.		|
335  *		     +----------------------------------+
336  */
337 
338 /*
339  * Functions registered with DDI framework
340  */
341 static int fcp_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
342 static int fcp_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
343 static int fcp_open(dev_t *devp, int flag, int otype, cred_t *credp);
344 static int fcp_close(dev_t dev, int flag, int otype, cred_t *credp);
345 static int fcp_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
346     cred_t *credp, int *rval);
347 
348 /*
349  * Functions registered with FC Transport framework
350  */
351 static int fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo,
352     fc_attach_cmd_t cmd,  uint32_t s_id);
353 static int fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info,
354     fc_detach_cmd_t cmd);
355 static int fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev,
356     int cmd, intptr_t data, int mode, cred_t *credp, int *rval,
357     uint32_t claimed);
358 static int fcp_els_callback(opaque_t ulph, opaque_t port_handle,
359     fc_unsol_buf_t *buf, uint32_t claimed);
360 static int fcp_data_callback(opaque_t ulph, opaque_t port_handle,
361     fc_unsol_buf_t *buf, uint32_t claimed);
362 static void fcp_statec_callback(opaque_t ulph, opaque_t port_handle,
363     uint32_t port_state, uint32_t port_top, fc_portmap_t *devlist,
364     uint32_t  dev_cnt, uint32_t port_sid);
365 
366 /*
367  * Functions registered with SCSA framework
368  */
369 static int fcp_phys_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
370     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
371 static int fcp_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
372     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
373 static void fcp_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
374     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
375 static int fcp_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt);
376 static int fcp_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
377 static int fcp_scsi_reset(struct scsi_address *ap, int level);
378 static int fcp_scsi_getcap(struct scsi_address *ap, char *cap, int whom);
379 static int fcp_scsi_setcap(struct scsi_address *ap, char *cap, int value,
380     int whom);
381 static void fcp_pkt_teardown(struct scsi_pkt *pkt);
382 static int fcp_scsi_reset_notify(struct scsi_address *ap, int flag,
383     void (*callback)(caddr_t), caddr_t arg);
384 static int fcp_scsi_bus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
385     char *name, ddi_eventcookie_t *event_cookiep);
386 static int fcp_scsi_bus_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
387     ddi_eventcookie_t eventid, void (*callback)(), void *arg,
388     ddi_callback_id_t *cb_id);
389 static int fcp_scsi_bus_remove_eventcall(dev_info_t *devi,
390     ddi_callback_id_t cb_id);
391 static int fcp_scsi_bus_post_event(dev_info_t *dip, dev_info_t *rdip,
392     ddi_eventcookie_t eventid, void *impldata);
393 static int fcp_scsi_bus_config(dev_info_t *parent, uint_t flag,
394     ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
395 static int fcp_scsi_bus_unconfig(dev_info_t *parent, uint_t flag,
396     ddi_bus_config_op_t op, void *arg);
397 
398 /*
399  * Internal functions
400  */
401 static int fcp_setup_device_data_ioctl(int cmd, struct fcp_ioctl *data,
402     int mode, int *rval);
403 
404 static int fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi,
405     int mode, int *rval);
406 static int fcp_copyin_scsi_cmd(caddr_t base_addr,
407     struct fcp_scsi_cmd *fscsi, int mode);
408 static int fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi,
409     caddr_t base_addr, int mode);
410 static int fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi);
411 
412 static struct fcp_tgt *fcp_port_create_tgt(struct fcp_port *pptr,
413     la_wwn_t *pwwn, int	*ret_val, int *fc_status, int *fc_pkt_state,
414     int *fc_pkt_reason, int *fc_pkt_action);
415 static int fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status,
416     int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action);
417 static int fcp_tgt_send_prli(struct fcp_tgt	*ptgt, int *fc_status,
418     int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action);
419 static void fcp_ipkt_sema_init(struct fcp_ipkt *icmd);
420 static int fcp_ipkt_sema_wait(struct fcp_ipkt *icmd);
421 static void fcp_ipkt_sema_callback(struct fc_packet *fpkt);
422 static void fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd);
423 
424 static void fcp_handle_devices(struct fcp_port *pptr,
425     fc_portmap_t devlist[], uint32_t dev_cnt, int link_cnt,
426     fcp_map_tag_t *map_tag, int cause);
427 static int fcp_handle_mapflags(struct fcp_port *pptr,
428     struct fcp_tgt *ptgt, fc_portmap_t *map_entry, int link_cnt,
429     int tgt_cnt, int cause);
430 static int fcp_handle_reportlun_changed(struct fcp_tgt *ptgt, int cause);
431 static int fcp_send_els(struct fcp_port *pptr, struct fcp_tgt *ptgt,
432     struct fcp_ipkt *icmd, uchar_t opcode, int lcount, int tcount, int cause);
433 static void fcp_update_state(struct fcp_port *pptr, uint32_t state,
434     int cause);
435 static void fcp_update_tgt_state(struct fcp_tgt *ptgt, int flag,
436     uint32_t state);
437 static struct fcp_port *fcp_get_port(opaque_t port_handle);
438 static void fcp_unsol_callback(fc_packet_t *fpkt);
439 static void fcp_unsol_resp_init(fc_packet_t *pkt, fc_unsol_buf_t *buf,
440     uchar_t r_ctl, uchar_t type);
441 static int fcp_unsol_prli(struct fcp_port *pptr, fc_unsol_buf_t *buf);
442 static struct fcp_ipkt *fcp_icmd_alloc(struct fcp_port *pptr,
443     struct fcp_tgt *ptgt, int cmd_len, int resp_len, int data_len,
444     int nodma, int lcount, int tcount, int cause, uint32_t rscn_count);
445 static void fcp_icmd_free(struct fcp_port *pptr, struct fcp_ipkt *icmd);
446 static int fcp_alloc_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd,
447     int nodma, int flags);
448 static void fcp_free_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd);
449 static struct fcp_tgt *fcp_lookup_target(struct fcp_port *pptr,
450     uchar_t *wwn);
451 static struct fcp_tgt *fcp_get_target_by_did(struct fcp_port *pptr,
452     uint32_t d_id);
453 static void fcp_icmd_callback(fc_packet_t *fpkt);
454 static int fcp_send_scsi(struct fcp_lun *plun, uchar_t opcode,
455     int len, int lcount, int tcount, int cause, uint32_t rscn_count);
456 static int fcp_check_reportlun(struct fcp_rsp *rsp, fc_packet_t *fpkt);
457 static void fcp_scsi_callback(fc_packet_t *fpkt);
458 static void fcp_retry_scsi_cmd(fc_packet_t *fpkt);
459 static void fcp_handle_inquiry(fc_packet_t *fpkt, struct fcp_ipkt *icmd);
460 static void fcp_handle_reportlun(fc_packet_t *fpkt, struct fcp_ipkt *icmd);
461 static struct fcp_lun *fcp_get_lun(struct fcp_tgt *ptgt,
462     uint16_t lun_num);
463 static int fcp_finish_tgt(struct fcp_port *pptr, struct fcp_tgt *ptgt,
464     int link_cnt, int tgt_cnt, int cause);
465 static void fcp_finish_init(struct fcp_port *pptr);
466 static void fcp_create_luns(struct fcp_tgt *ptgt, int link_cnt,
467     int tgt_cnt, int cause);
468 static int fcp_trigger_lun(struct fcp_lun *plun, child_info_t *cip,
469     int old_mpxio, int online, int link_cnt, int tgt_cnt, int flags);
470 static int fcp_offline_target(struct fcp_port *pptr, struct fcp_tgt *ptgt,
471     int link_cnt, int tgt_cnt, int nowait, int flags);
472 static void fcp_offline_target_now(struct fcp_port *pptr,
473     struct fcp_tgt *ptgt, int link_cnt, int tgt_cnt, int flags);
474 static void fcp_offline_tgt_luns(struct fcp_tgt *ptgt, int link_cnt,
475     int tgt_cnt, int flags);
476 static void fcp_offline_lun(struct fcp_lun *plun, int link_cnt, int tgt_cnt,
477     int nowait, int flags);
478 static void fcp_prepare_offline_lun(struct fcp_lun *plun, int link_cnt,
479     int tgt_cnt);
480 static void fcp_offline_lun_now(struct fcp_lun *plun, int link_cnt,
481     int tgt_cnt, int flags);
482 static void fcp_scan_offline_luns(struct fcp_port *pptr);
483 static void fcp_scan_offline_tgts(struct fcp_port *pptr);
484 static void fcp_update_offline_flags(struct fcp_lun *plun);
485 static struct fcp_pkt *fcp_scan_commands(struct fcp_lun *plun);
486 static void fcp_abort_commands(struct fcp_pkt *head, struct
487     fcp_port *pptr);
488 static void fcp_cmd_callback(fc_packet_t *fpkt);
489 static void fcp_complete_pkt(fc_packet_t *fpkt);
490 static int fcp_validate_fcp_response(struct fcp_rsp *rsp,
491     struct fcp_port *pptr);
492 static int fcp_device_changed(struct fcp_port *pptr, struct fcp_tgt *ptgt,
493     fc_portmap_t *map_entry, int link_cnt, int tgt_cnt, int cause);
494 static struct fcp_lun *fcp_alloc_lun(struct fcp_tgt *ptgt);
495 static void fcp_dealloc_lun(struct fcp_lun *plun);
496 static struct fcp_tgt *fcp_alloc_tgt(struct fcp_port *pptr,
497     fc_portmap_t *map_entry, int link_cnt);
498 static void fcp_dealloc_tgt(struct fcp_tgt *ptgt);
499 static void fcp_queue_ipkt(struct fcp_port *pptr, fc_packet_t *fpkt);
500 static int fcp_transport(opaque_t port_handle, fc_packet_t *fpkt,
501     int internal);
502 static void fcp_log(int level, dev_info_t *dip, const char *fmt, ...);
503 static int fcp_handle_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo,
504     uint32_t s_id, int instance);
505 static int fcp_handle_port_detach(struct fcp_port *pptr, int flag,
506     int instance);
507 static void fcp_cleanup_port(struct fcp_port *pptr, int instance);
508 static int fcp_kmem_cache_constructor(struct scsi_pkt *, scsi_hba_tran_t *,
509     int);
510 static void fcp_kmem_cache_destructor(struct  scsi_pkt *, scsi_hba_tran_t *);
511 static int fcp_pkt_setup(struct scsi_pkt *, int (*)(), caddr_t);
512 static int fcp_alloc_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt,
513     int flags);
514 static void fcp_free_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt);
515 static int fcp_reset_target(struct scsi_address *ap, int level);
516 static int fcp_commoncap(struct scsi_address *ap, char *cap,
517     int val, int tgtonly, int doset);
518 static int fcp_scsi_get_name(struct scsi_device *sd, char *name, int len);
519 static int fcp_scsi_get_bus_addr(struct scsi_device *sd, char *name, int len);
520 static int fcp_linkreset(struct fcp_port *pptr, struct scsi_address *ap,
521     int sleep);
522 static int fcp_handle_port_resume(opaque_t ulph, fc_ulp_port_info_t *pinfo,
523     uint32_t s_id, fc_attach_cmd_t cmd, int instance);
524 static void fcp_cp_pinfo(struct fcp_port *pptr, fc_ulp_port_info_t *pinfo);
525 static void fcp_process_elem(struct fcp_hp_elem *elem, int result);
526 static child_info_t *fcp_get_cip(struct fcp_lun *plun, child_info_t *cip,
527     int lcount, int tcount);
528 static int fcp_is_dip_present(struct fcp_lun *plun, dev_info_t *cdip);
529 static int fcp_is_child_present(struct fcp_lun *plun, child_info_t *cip);
530 static dev_info_t *fcp_create_dip(struct fcp_lun *plun, int link_cnt,
531     int tgt_cnt);
532 static dev_info_t *fcp_find_existing_dip(struct fcp_lun *plun,
533     dev_info_t *pdip, caddr_t name);
534 static int fcp_online_child(struct fcp_lun *plun, child_info_t *cip,
535     int lcount, int tcount, int flags, int *circ);
536 static int fcp_offline_child(struct fcp_lun *plun, child_info_t *cip,
537     int lcount, int tcount, int flags, int *circ);
538 static void fcp_remove_child(struct fcp_lun *plun);
539 static void fcp_watch(void *arg);
540 static void fcp_check_reset_delay(struct fcp_port *pptr);
541 static void fcp_abort_all(struct fcp_port *pptr, struct fcp_tgt *ttgt,
542     struct fcp_lun *rlun, int tgt_cnt);
543 struct fcp_port *fcp_soft_state_unlink(struct fcp_port *pptr);
544 static struct fcp_lun *fcp_lookup_lun(struct fcp_port *pptr,
545     uchar_t *wwn, uint16_t lun);
546 static void fcp_prepare_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd,
547     struct fcp_lun *plun);
548 static void fcp_post_callback(struct fcp_pkt *cmd);
549 static int fcp_dopoll(struct fcp_port *pptr, struct fcp_pkt *cmd);
550 static struct fcp_port *fcp_dip2port(dev_info_t *dip);
551 struct fcp_lun *fcp_get_lun_from_cip(struct fcp_port *pptr,
552     child_info_t *cip);
553 static int fcp_pass_to_hp_and_wait(struct fcp_port *pptr,
554     struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt,
555     int tgt_cnt, int flags);
556 static struct fcp_hp_elem *fcp_pass_to_hp(struct fcp_port *pptr,
557     struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt,
558     int tgt_cnt, int flags, int wait);
559 static void fcp_retransport_cmd(struct fcp_port *pptr,
560     struct fcp_pkt *cmd);
561 static void fcp_fail_cmd(struct fcp_pkt *cmd, uchar_t reason,
562     uint_t statistics);
563 static void fcp_queue_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd);
564 static void fcp_update_targets(struct fcp_port *pptr,
565     fc_portmap_t *dev_list, uint32_t count, uint32_t state, int cause);
566 static int fcp_call_finish_init(struct fcp_port *pptr,
567     struct fcp_tgt *ptgt, int lcount, int tcount, int cause);
568 static int fcp_call_finish_init_held(struct fcp_port *pptr,
569     struct fcp_tgt *ptgt, int lcount, int tcount, int cause);
570 static void fcp_reconfigure_luns(void * tgt_handle);
571 static void fcp_free_targets(struct fcp_port *pptr);
572 static void fcp_free_target(struct fcp_tgt *ptgt);
573 static int fcp_is_retryable(struct fcp_ipkt *icmd);
574 static int fcp_create_on_demand(struct fcp_port *pptr, uchar_t *pwwn);
575 static void fcp_ascii_to_wwn(caddr_t string, uchar_t bytes[], unsigned int);
576 static void fcp_wwn_to_ascii(uchar_t bytes[], char *string);
577 static void fcp_print_error(fc_packet_t *fpkt);
578 static int fcp_handle_ipkt_errors(struct fcp_port *pptr,
579     struct fcp_tgt *ptgt, struct fcp_ipkt *icmd, int rval, caddr_t op);
580 static int fcp_outstanding_lun_cmds(struct fcp_tgt *ptgt);
581 static fc_portmap_t *fcp_construct_map(struct fcp_port *pptr,
582     uint32_t *dev_cnt);
583 static void fcp_offline_all(struct fcp_port *pptr, int lcount, int cause);
584 static int fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval);
585 static int fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *, int, int *,
586     struct fcp_ioctl *, struct fcp_port **);
587 static char *fcp_get_lun_path(struct fcp_lun *plun);
588 static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode,
589     int *rval);
590 static int fcp_do_ns_registry(struct fcp_port *pptr, uint32_t s_id);
591 static void fcp_retry_ns_registry(struct fcp_port *pptr, uint32_t s_id);
592 static char *fcp_get_lun_path(struct fcp_lun *plun);
593 static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode,
594     int *rval);
595 static void fcp_reconfig_wait(struct fcp_port *pptr);
596 
597 /*
598  * New functions added for mpxio support
599  */
600 static int fcp_virt_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
601     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
602 static mdi_pathinfo_t *fcp_create_pip(struct fcp_lun *plun, int lcount,
603     int tcount);
604 static mdi_pathinfo_t *fcp_find_existing_pip(struct fcp_lun *plun,
605     dev_info_t *pdip);
606 static int fcp_is_pip_present(struct fcp_lun *plun, mdi_pathinfo_t *pip);
607 static void fcp_handle_page83(fc_packet_t *, struct fcp_ipkt *, int);
608 static void fcp_update_mpxio_path_verifybusy(struct fcp_port *pptr);
609 static int fcp_copy_guid_2_lun_block(struct fcp_lun *plun, char *guidp);
610 static int fcp_update_mpxio_path(struct fcp_lun *plun, child_info_t *cip,
611     int what);
612 static int fcp_is_reconfig_needed(struct fcp_tgt *ptgt,
613     fc_packet_t *fpkt);
614 static int fcp_symmetric_device_probe(struct fcp_lun *plun);
615 
616 /*
617  * New functions added for lun masking support
618  */
619 static void fcp_read_blacklist(dev_info_t *dip,
620     struct fcp_black_list_entry **pplun_blacklist);
621 static void fcp_mask_pwwn_lun(char *curr_pwwn, char *curr_lun,
622     struct fcp_black_list_entry **pplun_blacklist);
623 static void fcp_add_one_mask(char *curr_pwwn, uint32_t lun_id,
624     struct fcp_black_list_entry **pplun_blacklist);
625 static int fcp_should_mask(la_wwn_t *wwn, uint32_t lun_id);
626 static void fcp_cleanup_blacklist(struct fcp_black_list_entry **lun_blacklist);
627 
628 /*
629  * New functions to support software FCA (like fcoei)
630  */
631 static struct scsi_pkt *fcp_pseudo_init_pkt(
632 	struct scsi_address *ap, struct scsi_pkt *pkt,
633 	struct buf *bp, int cmdlen, int statuslen,
634 	int tgtlen, int flags, int (*callback)(), caddr_t arg);
635 static void fcp_pseudo_destroy_pkt(
636 	struct scsi_address *ap, struct scsi_pkt *pkt);
637 static void fcp_pseudo_sync_pkt(
638 	struct scsi_address *ap, struct scsi_pkt *pkt);
639 static int fcp_pseudo_start(struct scsi_address *ap, struct scsi_pkt *pkt);
640 static void fcp_pseudo_dmafree(
641 	struct scsi_address *ap, struct scsi_pkt *pkt);
642 
643 extern struct mod_ops	mod_driverops;
644 /*
645  * This variable is defined in modctl.c and set to '1' after the root driver
646  * and fs are loaded.  It serves as an indication that the root filesystem can
647  * be used.
648  */
649 extern int		modrootloaded;
650 /*
651  * This table contains strings associated with the SCSI sense key codes.  It
652  * is used by FCP to print a clear explanation of the code returned in the
653  * sense information by a device.
654  */
655 extern char		*sense_keys[];
656 /*
657  * This device is created by the SCSI pseudo nexus driver (SCSI vHCI).	It is
658  * under this device that the paths to a physical device are created when
659  * MPxIO is used.
660  */
661 extern dev_info_t	*scsi_vhci_dip;
662 
663 /*
664  * Report lun processing
665  */
666 #define	FCP_LUN_ADDRESSING		0x80
667 #define	FCP_PD_ADDRESSING		0x00
668 #define	FCP_VOLUME_ADDRESSING		0x40
669 
670 #define	FCP_SVE_THROTTLE		0x28 /* Vicom */
671 #define	MAX_INT_DMA			0x7fffffff
672 /*
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 
1833 			/* Loop through all LUNs on this target */
1834 			for (plun = ptgt->tgt_lun; plun != NULL;
1835 			    plun = plun->lun_next) {
1836 				if (plun->lun_state & FCP_LUN_OFFLINE) {
1837 					continue;
1838 				}
1839 
1840 				path = fcp_get_lun_path(plun);
1841 				if (path == NULL) {
1842 					continue;
1843 				}
1844 
1845 				if (mapIndex >= listlen) {
1846 					mapIndex ++;
1847 					kmem_free(path, MAXPATHLEN);
1848 					continue;
1849 				}
1850 				map = &mappings->entries[mapIndex++];
1851 				bcopy(path, map->targetDriver,
1852 				    sizeof (map->targetDriver));
1853 				map->d_id = ptgt->tgt_d_id;
1854 				map->busNumber = 0;
1855 				map->targetNumber = ptgt->tgt_d_id;
1856 				map->osLUN = plun->lun_num;
1857 
1858 				/*
1859 				 * We had swapped lun when we stored it in
1860 				 * lun_addr. We need to swap it back before
1861 				 * returning it to user land
1862 				 */
1863 
1864 				sam_lun_addr.ent_addr_0 =
1865 				    BE_16(plun->lun_addr.ent_addr_0);
1866 				sam_lun_addr.ent_addr_1 =
1867 				    BE_16(plun->lun_addr.ent_addr_1);
1868 				sam_lun_addr.ent_addr_2 =
1869 				    BE_16(plun->lun_addr.ent_addr_2);
1870 				sam_lun_addr.ent_addr_3 =
1871 				    BE_16(plun->lun_addr.ent_addr_3);
1872 
1873 				bcopy(&sam_lun_addr, &map->samLUN,
1874 				    FCP_LUN_SIZE);
1875 				bcopy(ptgt->tgt_node_wwn.raw_wwn,
1876 				    map->NodeWWN.raw_wwn, sizeof (la_wwn_t));
1877 				bcopy(ptgt->tgt_port_wwn.raw_wwn,
1878 				    map->PortWWN.raw_wwn, sizeof (la_wwn_t));
1879 
1880 				if (plun->lun_guid) {
1881 
1882 					/* convert ascii wwn to bytes */
1883 					fcp_ascii_to_wwn(plun->lun_guid,
1884 					    map->guid, sizeof (map->guid));
1885 
1886 					if ((sizeof (map->guid)) <
1887 					    plun->lun_guid_size / 2) {
1888 						cmn_err(CE_WARN,
1889 						    "fcp_get_target_mappings:"
1890 						    "guid copy space "
1891 						    "insufficient."
1892 						    "Copy Truncation - "
1893 						    "available %d; need %d",
1894 						    (int)sizeof (map->guid),
1895 						    (int)
1896 						    plun->lun_guid_size / 2);
1897 					}
1898 				}
1899 				kmem_free(path, MAXPATHLEN);
1900 			}
1901 		}
1902 	}
1903 	mutex_exit(&pptr->port_mutex);
1904 	mappings->numLuns = mapIndex;
1905 
1906 	if (ddi_copyout(mappings, fioctl.list, mappingSize, mode)) {
1907 		kmem_free(mappings, mappingSize);
1908 		return (EFAULT);
1909 	}
1910 	kmem_free(mappings, mappingSize);
1911 
1912 #ifdef	_MULTI_DATAMODEL
1913 	switch (ddi_model_convert_from(mode & FMODELS)) {
1914 	case DDI_MODEL_ILP32: {
1915 		struct fcp32_ioctl f32_ioctl;
1916 
1917 		f32_ioctl.fp_minor = fioctl.fp_minor;
1918 		f32_ioctl.listlen = fioctl.listlen;
1919 		f32_ioctl.list = (caddr32_t)(long)fioctl.list;
1920 		if (ddi_copyout((void *)&f32_ioctl, (void *)data,
1921 		    sizeof (struct fcp32_ioctl), mode)) {
1922 			return (EFAULT);
1923 		}
1924 		break;
1925 	}
1926 	case DDI_MODEL_NONE:
1927 		if (ddi_copyout((void *)&fioctl, (void *)data,
1928 		    sizeof (struct fcp_ioctl), mode)) {
1929 			return (EFAULT);
1930 		}
1931 		break;
1932 	}
1933 #else	/* _MULTI_DATAMODEL */
1934 
1935 	if (ddi_copyout((void *)&fioctl, (void *)data,
1936 	    sizeof (struct fcp_ioctl), mode)) {
1937 		return (EFAULT);
1938 	}
1939 #endif	/* _MULTI_DATAMODEL */
1940 
1941 	return (0);
1942 }
1943 
1944 /*
1945  * fcp_setup_scsi_ioctl
1946  *	Setup handler for the "scsi passthru" style of
1947  *	ioctl for FCP.	See "fcp_util.h" for data structure
1948  *	definition.
1949  *
1950  * Input:
1951  *	u_fscsi	= ioctl data (user address space)
1952  *	mode	= See ioctl(9E)
1953  *
1954  * Output:
1955  *	u_fscsi	= ioctl data (user address space)
1956  *	rval	= return value - see ioctl(9E)
1957  *
1958  * Returns:
1959  *	0	= OK
1960  *	EAGAIN	= See errno.h
1961  *	EBUSY	= See errno.h
1962  *	EFAULT	= See errno.h
1963  *	EINTR	= See errno.h
1964  *	EINVAL	= See errno.h
1965  *	EIO	= See errno.h
1966  *	ENOMEM	= See errno.h
1967  *	ENXIO	= See errno.h
1968  *
1969  * Context:
1970  *	Kernel context.
1971  */
1972 /* ARGSUSED */
1973 static int
1974 fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi,
1975     int mode, int *rval)
1976 {
1977 	int			ret		= 0;
1978 	int			temp_ret;
1979 	caddr_t			k_cdbbufaddr	= NULL;
1980 	caddr_t			k_bufaddr	= NULL;
1981 	caddr_t			k_rqbufaddr	= NULL;
1982 	caddr_t			u_cdbbufaddr;
1983 	caddr_t			u_bufaddr;
1984 	caddr_t			u_rqbufaddr;
1985 	struct fcp_scsi_cmd	k_fscsi;
1986 
1987 	/*
1988 	 * Get fcp_scsi_cmd array element from user address space
1989 	 */
1990 	if ((ret = fcp_copyin_scsi_cmd((caddr_t)u_fscsi, &k_fscsi, mode))
1991 	    != 0) {
1992 		return (ret);
1993 	}
1994 
1995 
1996 	/*
1997 	 * Even though kmem_alloc() checks the validity of the
1998 	 * buffer length, this check is needed when the
1999 	 * kmem_flags set and the zero buffer length is passed.
2000 	 */
2001 	if ((k_fscsi.scsi_cdblen <= 0) ||
2002 	    (k_fscsi.scsi_buflen <= 0) ||
2003 	    (k_fscsi.scsi_rqlen <= 0)) {
2004 		return (EINVAL);
2005 	}
2006 
2007 	/*
2008 	 * Allocate data for fcp_scsi_cmd pointer fields
2009 	 */
2010 	if (ret == 0) {
2011 		k_cdbbufaddr = kmem_alloc(k_fscsi.scsi_cdblen, KM_NOSLEEP);
2012 		k_bufaddr    = kmem_alloc(k_fscsi.scsi_buflen, KM_NOSLEEP);
2013 		k_rqbufaddr  = kmem_alloc(k_fscsi.scsi_rqlen,  KM_NOSLEEP);
2014 
2015 		if (k_cdbbufaddr == NULL ||
2016 		    k_bufaddr	 == NULL ||
2017 		    k_rqbufaddr	 == NULL) {
2018 			ret = ENOMEM;
2019 		}
2020 	}
2021 
2022 	/*
2023 	 * Get fcp_scsi_cmd pointer fields from user
2024 	 * address space
2025 	 */
2026 	if (ret == 0) {
2027 		u_cdbbufaddr = k_fscsi.scsi_cdbbufaddr;
2028 		u_bufaddr    = k_fscsi.scsi_bufaddr;
2029 		u_rqbufaddr  = k_fscsi.scsi_rqbufaddr;
2030 
2031 		if (ddi_copyin(u_cdbbufaddr,
2032 		    k_cdbbufaddr,
2033 		    k_fscsi.scsi_cdblen,
2034 		    mode)) {
2035 			ret = EFAULT;
2036 		} else if (ddi_copyin(u_bufaddr,
2037 		    k_bufaddr,
2038 		    k_fscsi.scsi_buflen,
2039 		    mode)) {
2040 			ret = EFAULT;
2041 		} else if (ddi_copyin(u_rqbufaddr,
2042 		    k_rqbufaddr,
2043 		    k_fscsi.scsi_rqlen,
2044 		    mode)) {
2045 			ret = EFAULT;
2046 		}
2047 	}
2048 
2049 	/*
2050 	 * Send scsi command (blocking)
2051 	 */
2052 	if (ret == 0) {
2053 		/*
2054 		 * Prior to sending the scsi command, the
2055 		 * fcp_scsi_cmd data structure must contain kernel,
2056 		 * not user, addresses.
2057 		 */
2058 		k_fscsi.scsi_cdbbufaddr	= k_cdbbufaddr;
2059 		k_fscsi.scsi_bufaddr	= k_bufaddr;
2060 		k_fscsi.scsi_rqbufaddr	= k_rqbufaddr;
2061 
2062 		ret = fcp_send_scsi_ioctl(&k_fscsi);
2063 
2064 		/*
2065 		 * After sending the scsi command, the
2066 		 * fcp_scsi_cmd data structure must contain user,
2067 		 * not kernel, addresses.
2068 		 */
2069 		k_fscsi.scsi_cdbbufaddr	= u_cdbbufaddr;
2070 		k_fscsi.scsi_bufaddr	= u_bufaddr;
2071 		k_fscsi.scsi_rqbufaddr	= u_rqbufaddr;
2072 	}
2073 
2074 	/*
2075 	 * Put fcp_scsi_cmd pointer fields to user address space
2076 	 */
2077 	if (ret == 0) {
2078 		if (ddi_copyout(k_cdbbufaddr,
2079 		    u_cdbbufaddr,
2080 		    k_fscsi.scsi_cdblen,
2081 		    mode)) {
2082 			ret = EFAULT;
2083 		} else if (ddi_copyout(k_bufaddr,
2084 		    u_bufaddr,
2085 		    k_fscsi.scsi_buflen,
2086 		    mode)) {
2087 			ret = EFAULT;
2088 		} else if (ddi_copyout(k_rqbufaddr,
2089 		    u_rqbufaddr,
2090 		    k_fscsi.scsi_rqlen,
2091 		    mode)) {
2092 			ret = EFAULT;
2093 		}
2094 	}
2095 
2096 	/*
2097 	 * Free data for fcp_scsi_cmd pointer fields
2098 	 */
2099 	if (k_cdbbufaddr != NULL) {
2100 		kmem_free(k_cdbbufaddr, k_fscsi.scsi_cdblen);
2101 	}
2102 	if (k_bufaddr != NULL) {
2103 		kmem_free(k_bufaddr, k_fscsi.scsi_buflen);
2104 	}
2105 	if (k_rqbufaddr != NULL) {
2106 		kmem_free(k_rqbufaddr, k_fscsi.scsi_rqlen);
2107 	}
2108 
2109 	/*
2110 	 * Put fcp_scsi_cmd array element to user address space
2111 	 */
2112 	temp_ret = fcp_copyout_scsi_cmd(&k_fscsi, (caddr_t)u_fscsi, mode);
2113 	if (temp_ret != 0) {
2114 		ret = temp_ret;
2115 	}
2116 
2117 	/*
2118 	 * Return status
2119 	 */
2120 	return (ret);
2121 }
2122 
2123 
2124 /*
2125  * fcp_copyin_scsi_cmd
2126  *	Copy in fcp_scsi_cmd data structure from user address space.
2127  *	The data may be in 32 bit or 64 bit modes.
2128  *
2129  * Input:
2130  *	base_addr	= from address (user address space)
2131  *	mode		= See ioctl(9E) and ddi_copyin(9F)
2132  *
2133  * Output:
2134  *	fscsi		= to address (kernel address space)
2135  *
2136  * Returns:
2137  *	0	= OK
2138  *	EFAULT	= Error
2139  *
2140  * Context:
2141  *	Kernel context.
2142  */
2143 static int
2144 fcp_copyin_scsi_cmd(caddr_t base_addr, struct fcp_scsi_cmd *fscsi, int mode)
2145 {
2146 #ifdef	_MULTI_DATAMODEL
2147 	struct fcp32_scsi_cmd	f32scsi;
2148 
2149 	switch (ddi_model_convert_from(mode & FMODELS)) {
2150 	case DDI_MODEL_ILP32:
2151 		/*
2152 		 * Copy data from user address space
2153 		 */
2154 		if (ddi_copyin((void *)base_addr,
2155 		    &f32scsi,
2156 		    sizeof (struct fcp32_scsi_cmd),
2157 		    mode)) {
2158 			return (EFAULT);
2159 		}
2160 		/*
2161 		 * Convert from 32 bit to 64 bit
2162 		 */
2163 		FCP32_SCSI_CMD_TO_FCP_SCSI_CMD(&f32scsi, fscsi);
2164 		break;
2165 	case DDI_MODEL_NONE:
2166 		/*
2167 		 * Copy data from user address space
2168 		 */
2169 		if (ddi_copyin((void *)base_addr,
2170 		    fscsi,
2171 		    sizeof (struct fcp_scsi_cmd),
2172 		    mode)) {
2173 			return (EFAULT);
2174 		}
2175 		break;
2176 	}
2177 #else	/* _MULTI_DATAMODEL */
2178 	/*
2179 	 * Copy data from user address space
2180 	 */
2181 	if (ddi_copyin((void *)base_addr,
2182 	    fscsi,
2183 	    sizeof (struct fcp_scsi_cmd),
2184 	    mode)) {
2185 		return (EFAULT);
2186 	}
2187 #endif	/* _MULTI_DATAMODEL */
2188 
2189 	return (0);
2190 }
2191 
2192 
2193 /*
2194  * fcp_copyout_scsi_cmd
2195  *	Copy out fcp_scsi_cmd data structure to user address space.
2196  *	The data may be in 32 bit or 64 bit modes.
2197  *
2198  * Input:
2199  *	fscsi		= to address (kernel address space)
2200  *	mode		= See ioctl(9E) and ddi_copyin(9F)
2201  *
2202  * Output:
2203  *	base_addr	= from address (user address space)
2204  *
2205  * Returns:
2206  *	0	= OK
2207  *	EFAULT	= Error
2208  *
2209  * Context:
2210  *	Kernel context.
2211  */
2212 static int
2213 fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi, caddr_t base_addr, int mode)
2214 {
2215 #ifdef	_MULTI_DATAMODEL
2216 	struct fcp32_scsi_cmd	f32scsi;
2217 
2218 	switch (ddi_model_convert_from(mode & FMODELS)) {
2219 	case DDI_MODEL_ILP32:
2220 		/*
2221 		 * Convert from 64 bit to 32 bit
2222 		 */
2223 		FCP_SCSI_CMD_TO_FCP32_SCSI_CMD(fscsi, &f32scsi);
2224 		/*
2225 		 * Copy data to user address space
2226 		 */
2227 		if (ddi_copyout(&f32scsi,
2228 		    (void *)base_addr,
2229 		    sizeof (struct fcp32_scsi_cmd),
2230 		    mode)) {
2231 			return (EFAULT);
2232 		}
2233 		break;
2234 	case DDI_MODEL_NONE:
2235 		/*
2236 		 * Copy data to user address space
2237 		 */
2238 		if (ddi_copyout(fscsi,
2239 		    (void *)base_addr,
2240 		    sizeof (struct fcp_scsi_cmd),
2241 		    mode)) {
2242 			return (EFAULT);
2243 		}
2244 		break;
2245 	}
2246 #else	/* _MULTI_DATAMODEL */
2247 	/*
2248 	 * Copy data to user address space
2249 	 */
2250 	if (ddi_copyout(fscsi,
2251 	    (void *)base_addr,
2252 	    sizeof (struct fcp_scsi_cmd),
2253 	    mode)) {
2254 		return (EFAULT);
2255 	}
2256 #endif	/* _MULTI_DATAMODEL */
2257 
2258 	return (0);
2259 }
2260 
2261 
2262 /*
2263  * fcp_send_scsi_ioctl
2264  *	Sends the SCSI command in blocking mode.
2265  *
2266  * Input:
2267  *	fscsi		= SCSI command data structure
2268  *
2269  * Output:
2270  *	fscsi		= SCSI command data structure
2271  *
2272  * Returns:
2273  *	0	= OK
2274  *	EAGAIN	= See errno.h
2275  *	EBUSY	= See errno.h
2276  *	EINTR	= See errno.h
2277  *	EINVAL	= See errno.h
2278  *	EIO	= See errno.h
2279  *	ENOMEM	= See errno.h
2280  *	ENXIO	= See errno.h
2281  *
2282  * Context:
2283  *	Kernel context.
2284  */
2285 static int
2286 fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi)
2287 {
2288 	struct fcp_lun	*plun		= NULL;
2289 	struct fcp_port	*pptr		= NULL;
2290 	struct fcp_tgt	*ptgt		= NULL;
2291 	fc_packet_t		*fpkt		= NULL;
2292 	struct fcp_ipkt	*icmd		= NULL;
2293 	int			target_created	= FALSE;
2294 	fc_frame_hdr_t		*hp;
2295 	struct fcp_cmd		fcp_cmd;
2296 	struct fcp_cmd		*fcmd;
2297 	union scsi_cdb		*scsi_cdb;
2298 	la_wwn_t		*wwn_ptr;
2299 	int			nodma;
2300 	struct fcp_rsp		*rsp;
2301 	struct fcp_rsp_info	*rsp_info;
2302 	caddr_t			rsp_sense;
2303 	int			buf_len;
2304 	int			info_len;
2305 	int			sense_len;
2306 	struct scsi_extended_sense	*sense_to = NULL;
2307 	timeout_id_t		tid;
2308 	uint8_t			reconfig_lun = FALSE;
2309 	uint8_t			reconfig_pending = FALSE;
2310 	uint8_t			scsi_cmd;
2311 	int			rsp_len;
2312 	int			cmd_index;
2313 	int			fc_status;
2314 	int			pkt_state;
2315 	int			pkt_action;
2316 	int			pkt_reason;
2317 	int			ret, xport_retval = ~FC_SUCCESS;
2318 	int			lcount;
2319 	int			tcount;
2320 	int			reconfig_status;
2321 	int			port_busy = FALSE;
2322 	uchar_t			*lun_string;
2323 
2324 	/*
2325 	 * Check valid SCSI command
2326 	 */
2327 	scsi_cmd = ((uint8_t *)fscsi->scsi_cdbbufaddr)[0];
2328 	ret = EINVAL;
2329 	for (cmd_index = 0;
2330 	    cmd_index < FCP_NUM_ELEMENTS(scsi_ioctl_list) &&
2331 	    ret != 0;
2332 	    cmd_index++) {
2333 		/*
2334 		 * First byte of CDB is the SCSI command
2335 		 */
2336 		if (scsi_ioctl_list[cmd_index] == scsi_cmd) {
2337 			ret = 0;
2338 		}
2339 	}
2340 
2341 	/*
2342 	 * Check inputs
2343 	 */
2344 	if (fscsi->scsi_flags != FCP_SCSI_READ) {
2345 		ret = EINVAL;
2346 	} else if (fscsi->scsi_cdblen > FCP_CDB_SIZE) {
2347 		/* no larger than */
2348 		ret = EINVAL;
2349 	}
2350 
2351 
2352 	/*
2353 	 * Find FC port
2354 	 */
2355 	if (ret == 0) {
2356 		/*
2357 		 * Acquire global mutex
2358 		 */
2359 		mutex_enter(&fcp_global_mutex);
2360 
2361 		pptr = fcp_port_head;
2362 		while (pptr) {
2363 			if (pptr->port_instance ==
2364 			    (uint32_t)fscsi->scsi_fc_port_num) {
2365 				break;
2366 			} else {
2367 				pptr = pptr->port_next;
2368 			}
2369 		}
2370 
2371 		if (pptr == NULL) {
2372 			ret = ENXIO;
2373 		} else {
2374 			/*
2375 			 * fc_ulp_busy_port can raise power
2376 			 *  so, we must not hold any mutexes involved in PM
2377 			 */
2378 			mutex_exit(&fcp_global_mutex);
2379 			ret = fc_ulp_busy_port(pptr->port_fp_handle);
2380 		}
2381 
2382 		if (ret == 0) {
2383 
2384 			/* remember port is busy, so we will release later */
2385 			port_busy = TRUE;
2386 
2387 			/*
2388 			 * If there is a reconfiguration in progress, wait
2389 			 * for it to complete.
2390 			 */
2391 
2392 			fcp_reconfig_wait(pptr);
2393 
2394 			/* reacquire mutexes in order */
2395 			mutex_enter(&fcp_global_mutex);
2396 			mutex_enter(&pptr->port_mutex);
2397 
2398 			/*
2399 			 * Will port accept DMA?
2400 			 */
2401 			nodma = (pptr->port_fcp_dma == FC_NO_DVMA_SPACE)
2402 			    ? 1 : 0;
2403 
2404 			/*
2405 			 * If init or offline, device not known
2406 			 *
2407 			 * If we are discovering (onlining), we can
2408 			 * NOT obviously provide reliable data about
2409 			 * devices until it is complete
2410 			 */
2411 			if (pptr->port_state &	  (FCP_STATE_INIT |
2412 			    FCP_STATE_OFFLINE)) {
2413 				ret = ENXIO;
2414 			} else if (pptr->port_state & FCP_STATE_ONLINING) {
2415 				ret = EBUSY;
2416 			} else {
2417 				/*
2418 				 * Find target from pwwn
2419 				 *
2420 				 * The wwn must be put into a local
2421 				 * variable to ensure alignment.
2422 				 */
2423 				wwn_ptr = (la_wwn_t *)&(fscsi->scsi_fc_pwwn);
2424 				ptgt = fcp_lookup_target(pptr,
2425 				    (uchar_t *)wwn_ptr);
2426 
2427 				/*
2428 				 * If target not found,
2429 				 */
2430 				if (ptgt == NULL) {
2431 					/*
2432 					 * Note: Still have global &
2433 					 * port mutexes
2434 					 */
2435 					mutex_exit(&pptr->port_mutex);
2436 					ptgt = fcp_port_create_tgt(pptr,
2437 					    wwn_ptr, &ret, &fc_status,
2438 					    &pkt_state, &pkt_action,
2439 					    &pkt_reason);
2440 					mutex_enter(&pptr->port_mutex);
2441 
2442 					fscsi->scsi_fc_status  = fc_status;
2443 					fscsi->scsi_pkt_state  =
2444 					    (uchar_t)pkt_state;
2445 					fscsi->scsi_pkt_reason = pkt_reason;
2446 					fscsi->scsi_pkt_action =
2447 					    (uchar_t)pkt_action;
2448 
2449 					if (ptgt != NULL) {
2450 						target_created = TRUE;
2451 					} else if (ret == 0) {
2452 						ret = ENOMEM;
2453 					}
2454 				}
2455 
2456 				if (ret == 0) {
2457 					/*
2458 					 * Acquire target
2459 					 */
2460 					mutex_enter(&ptgt->tgt_mutex);
2461 
2462 					/*
2463 					 * If target is mark or busy,
2464 					 * then target can not be used
2465 					 */
2466 					if (ptgt->tgt_state &
2467 					    (FCP_TGT_MARK |
2468 					    FCP_TGT_BUSY)) {
2469 						ret = EBUSY;
2470 					} else {
2471 						/*
2472 						 * Mark target as busy
2473 						 */
2474 						ptgt->tgt_state |=
2475 						    FCP_TGT_BUSY;
2476 					}
2477 
2478 					/*
2479 					 * Release target
2480 					 */
2481 					lcount = pptr->port_link_cnt;
2482 					tcount = ptgt->tgt_change_cnt;
2483 					mutex_exit(&ptgt->tgt_mutex);
2484 				}
2485 			}
2486 
2487 			/*
2488 			 * Release port
2489 			 */
2490 			mutex_exit(&pptr->port_mutex);
2491 		}
2492 
2493 		/*
2494 		 * Release global mutex
2495 		 */
2496 		mutex_exit(&fcp_global_mutex);
2497 	}
2498 
2499 	if (ret == 0) {
2500 		uint64_t belun = BE_64(fscsi->scsi_lun);
2501 
2502 		/*
2503 		 * If it's a target device, find lun from pwwn
2504 		 * The wwn must be put into a local
2505 		 * variable to ensure alignment.
2506 		 */
2507 		mutex_enter(&pptr->port_mutex);
2508 		wwn_ptr = (la_wwn_t *)&(fscsi->scsi_fc_pwwn);
2509 		if (!ptgt->tgt_tcap && ptgt->tgt_icap) {
2510 			/* this is not a target */
2511 			fscsi->scsi_fc_status = FC_DEVICE_NOT_TGT;
2512 			ret = ENXIO;
2513 		} else if ((belun << 16) != 0) {
2514 			/*
2515 			 * Since fcp only support PD and LU addressing method
2516 			 * so far, the last 6 bytes of a valid LUN are expected
2517 			 * to be filled with 00h.
2518 			 */
2519 			fscsi->scsi_fc_status = FC_INVALID_LUN;
2520 			cmn_err(CE_WARN, "fcp: Unsupported LUN addressing"
2521 			    " method 0x%02x with LUN number 0x%016" PRIx64,
2522 			    (uint8_t)(belun >> 62), belun);
2523 			ret = ENXIO;
2524 		} else if ((plun = fcp_lookup_lun(pptr, (uchar_t *)wwn_ptr,
2525 		    (uint16_t)((belun >> 48) & 0x3fff))) == NULL) {
2526 			/*
2527 			 * This is a SCSI target, but no LUN at this
2528 			 * address.
2529 			 *
2530 			 * In the future, we may want to send this to
2531 			 * the target, and let it respond
2532 			 * appropriately
2533 			 */
2534 			ret = ENXIO;
2535 		}
2536 		mutex_exit(&pptr->port_mutex);
2537 	}
2538 
2539 	/*
2540 	 * Finished grabbing external resources
2541 	 * Allocate internal packet (icmd)
2542 	 */
2543 	if (ret == 0) {
2544 		/*
2545 		 * Calc rsp len assuming rsp info included
2546 		 */
2547 		rsp_len = sizeof (struct fcp_rsp) +
2548 		    sizeof (struct fcp_rsp_info) + fscsi->scsi_rqlen;
2549 
2550 		icmd = fcp_icmd_alloc(pptr, ptgt,
2551 		    sizeof (struct fcp_cmd),
2552 		    rsp_len,
2553 		    fscsi->scsi_buflen,
2554 		    nodma,
2555 		    lcount,			/* ipkt_link_cnt */
2556 		    tcount,			/* ipkt_change_cnt */
2557 		    0,				/* cause */
2558 		    FC_INVALID_RSCN_COUNT);	/* invalidate the count */
2559 
2560 		if (icmd == NULL) {
2561 			ret = ENOMEM;
2562 		} else {
2563 			/*
2564 			 * Setup internal packet as sema sync
2565 			 */
2566 			fcp_ipkt_sema_init(icmd);
2567 		}
2568 	}
2569 
2570 	if (ret == 0) {
2571 		/*
2572 		 * Init fpkt pointer for use.
2573 		 */
2574 
2575 		fpkt = icmd->ipkt_fpkt;
2576 
2577 		fpkt->pkt_tran_flags	= FC_TRAN_CLASS3 | FC_TRAN_INTR;
2578 		fpkt->pkt_tran_type	= FC_PKT_FCP_READ; /* only rd for now */
2579 		fpkt->pkt_timeout	= fscsi->scsi_timeout;
2580 
2581 		/*
2582 		 * Init fcmd pointer for use by SCSI command
2583 		 */
2584 
2585 		if (nodma) {
2586 			fcmd = (struct fcp_cmd *)fpkt->pkt_cmd;
2587 		} else {
2588 			fcmd = &fcp_cmd;
2589 		}
2590 		bzero(fcmd, sizeof (struct fcp_cmd));
2591 		ptgt = plun->lun_tgt;
2592 
2593 		lun_string = (uchar_t *)&fscsi->scsi_lun;
2594 
2595 		fcmd->fcp_ent_addr.ent_addr_0 =
2596 		    BE_16(*(uint16_t *)&(lun_string[0]));
2597 		fcmd->fcp_ent_addr.ent_addr_1 =
2598 		    BE_16(*(uint16_t *)&(lun_string[2]));
2599 		fcmd->fcp_ent_addr.ent_addr_2 =
2600 		    BE_16(*(uint16_t *)&(lun_string[4]));
2601 		fcmd->fcp_ent_addr.ent_addr_3 =
2602 		    BE_16(*(uint16_t *)&(lun_string[6]));
2603 
2604 		/*
2605 		 * Setup internal packet(icmd)
2606 		 */
2607 		icmd->ipkt_lun		= plun;
2608 		icmd->ipkt_restart	= 0;
2609 		icmd->ipkt_retries	= 0;
2610 		icmd->ipkt_opcode	= 0;
2611 
2612 		/*
2613 		 * Init the frame HEADER Pointer for use
2614 		 */
2615 		hp = &fpkt->pkt_cmd_fhdr;
2616 
2617 		hp->s_id	= pptr->port_id;
2618 		hp->d_id	= ptgt->tgt_d_id;
2619 		hp->r_ctl	= R_CTL_COMMAND;
2620 		hp->type	= FC_TYPE_SCSI_FCP;
2621 		hp->f_ctl	= F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ;
2622 		hp->rsvd	= 0;
2623 		hp->seq_id	= 0;
2624 		hp->seq_cnt	= 0;
2625 		hp->ox_id	= 0xffff;
2626 		hp->rx_id	= 0xffff;
2627 		hp->ro		= 0;
2628 
2629 		fcmd->fcp_cntl.cntl_qtype	= FCP_QTYPE_SIMPLE;
2630 		fcmd->fcp_cntl.cntl_read_data	= 1;	/* only rd for now */
2631 		fcmd->fcp_cntl.cntl_write_data	= 0;
2632 		fcmd->fcp_data_len	= fscsi->scsi_buflen;
2633 
2634 		scsi_cdb = (union scsi_cdb *)fcmd->fcp_cdb;
2635 		bcopy((char *)fscsi->scsi_cdbbufaddr, (char *)scsi_cdb,
2636 		    fscsi->scsi_cdblen);
2637 
2638 		if (!nodma) {
2639 			FCP_CP_OUT((uint8_t *)fcmd, fpkt->pkt_cmd,
2640 			    fpkt->pkt_cmd_acc, sizeof (struct fcp_cmd));
2641 		}
2642 
2643 		/*
2644 		 * Send SCSI command to FC transport
2645 		 */
2646 
2647 		if (ret == 0) {
2648 			mutex_enter(&ptgt->tgt_mutex);
2649 
2650 			if (!FCP_TGT_STATE_CHANGED(ptgt, icmd)) {
2651 				mutex_exit(&ptgt->tgt_mutex);
2652 				fscsi->scsi_fc_status = xport_retval =
2653 				    fc_ulp_transport(pptr->port_fp_handle,
2654 				    fpkt);
2655 				if (fscsi->scsi_fc_status != FC_SUCCESS) {
2656 					ret = EIO;
2657 				}
2658 			} else {
2659 				mutex_exit(&ptgt->tgt_mutex);
2660 				ret = EBUSY;
2661 			}
2662 		}
2663 	}
2664 
2665 	/*
2666 	 * Wait for completion only if fc_ulp_transport was called and it
2667 	 * returned a success. This is the only time callback will happen.
2668 	 * Otherwise, there is no point in waiting
2669 	 */
2670 	if ((ret == 0) && (xport_retval == FC_SUCCESS)) {
2671 		ret = fcp_ipkt_sema_wait(icmd);
2672 	}
2673 
2674 	/*
2675 	 * Copy data to IOCTL data structures
2676 	 */
2677 	rsp = NULL;
2678 	if ((ret == 0) && (xport_retval == FC_SUCCESS)) {
2679 		rsp = (struct fcp_rsp *)fpkt->pkt_resp;
2680 
2681 		if (fcp_validate_fcp_response(rsp, pptr) != FC_SUCCESS) {
2682 			fcp_log(CE_WARN, pptr->port_dip,
2683 			    "!SCSI command to d_id=0x%x lun=0x%x"
2684 			    " failed, Bad FCP response values:"
2685 			    " rsvd1=%x, rsvd2=%x, sts-rsvd1=%x,"
2686 			    " sts-rsvd2=%x, rsplen=%x, senselen=%x",
2687 			    ptgt->tgt_d_id, plun->lun_num,
2688 			    rsp->reserved_0, rsp->reserved_1,
2689 			    rsp->fcp_u.fcp_status.reserved_0,
2690 			    rsp->fcp_u.fcp_status.reserved_1,
2691 			    rsp->fcp_response_len, rsp->fcp_sense_len);
2692 
2693 			ret = EIO;
2694 		}
2695 	}
2696 
2697 	if ((ret == 0) && (rsp != NULL)) {
2698 		/*
2699 		 * Calc response lengths
2700 		 */
2701 		sense_len = 0;
2702 		info_len = 0;
2703 
2704 		if (rsp->fcp_u.fcp_status.rsp_len_set) {
2705 			info_len = rsp->fcp_response_len;
2706 		}
2707 
2708 		rsp_info   = (struct fcp_rsp_info *)
2709 		    ((uint8_t *)rsp + sizeof (struct fcp_rsp));
2710 
2711 		/*
2712 		 * Get SCSI status
2713 		 */
2714 		fscsi->scsi_bufstatus = rsp->fcp_u.fcp_status.scsi_status;
2715 		/*
2716 		 * If a lun was just added or removed and the next command
2717 		 * comes through this interface, we need to capture the check
2718 		 * condition so we can discover the new topology.
2719 		 */
2720 		if (fscsi->scsi_bufstatus != STATUS_GOOD &&
2721 		    rsp->fcp_u.fcp_status.sense_len_set) {
2722 			sense_len = rsp->fcp_sense_len;
2723 			rsp_sense  = (caddr_t)((uint8_t *)rsp_info + info_len);
2724 			sense_to = (struct scsi_extended_sense *)rsp_sense;
2725 			if ((FCP_SENSE_REPORTLUN_CHANGED(sense_to)) ||
2726 			    (FCP_SENSE_NO_LUN(sense_to))) {
2727 				reconfig_lun = TRUE;
2728 			}
2729 		}
2730 
2731 		if (fscsi->scsi_bufstatus == STATUS_GOOD && (ptgt != NULL) &&
2732 		    (reconfig_lun || (scsi_cdb->scc_cmd == SCMD_REPORT_LUN))) {
2733 			if (reconfig_lun == FALSE) {
2734 				reconfig_status =
2735 				    fcp_is_reconfig_needed(ptgt, fpkt);
2736 			}
2737 
2738 			if ((reconfig_lun == TRUE) ||
2739 			    (reconfig_status == TRUE)) {
2740 				mutex_enter(&ptgt->tgt_mutex);
2741 				if (ptgt->tgt_tid == NULL) {
2742 					/*
2743 					 * Either we've been notified the
2744 					 * REPORT_LUN data has changed, or
2745 					 * we've determined on our own that
2746 					 * we're out of date.  Kick off
2747 					 * rediscovery.
2748 					 */
2749 					tid = timeout(fcp_reconfigure_luns,
2750 					    (caddr_t)ptgt, drv_usectohz(1));
2751 
2752 					ptgt->tgt_tid = tid;
2753 					ptgt->tgt_state |= FCP_TGT_BUSY;
2754 					ret = EBUSY;
2755 					reconfig_pending = TRUE;
2756 				}
2757 				mutex_exit(&ptgt->tgt_mutex);
2758 			}
2759 		}
2760 
2761 		/*
2762 		 * Calc residuals and buffer lengths
2763 		 */
2764 
2765 		if (ret == 0) {
2766 			buf_len = fscsi->scsi_buflen;
2767 			fscsi->scsi_bufresid	= 0;
2768 			if (rsp->fcp_u.fcp_status.resid_under) {
2769 				if (rsp->fcp_resid <= fscsi->scsi_buflen) {
2770 					fscsi->scsi_bufresid = rsp->fcp_resid;
2771 				} else {
2772 					cmn_err(CE_WARN, "fcp: bad residue %x "
2773 					    "for txfer len %x", rsp->fcp_resid,
2774 					    fscsi->scsi_buflen);
2775 					fscsi->scsi_bufresid =
2776 					    fscsi->scsi_buflen;
2777 				}
2778 				buf_len -= fscsi->scsi_bufresid;
2779 			}
2780 			if (rsp->fcp_u.fcp_status.resid_over) {
2781 				fscsi->scsi_bufresid = -rsp->fcp_resid;
2782 			}
2783 
2784 			fscsi->scsi_rqresid	= fscsi->scsi_rqlen - sense_len;
2785 			if (fscsi->scsi_rqlen < sense_len) {
2786 				sense_len = fscsi->scsi_rqlen;
2787 			}
2788 
2789 			fscsi->scsi_fc_rspcode	= 0;
2790 			if (rsp->fcp_u.fcp_status.rsp_len_set) {
2791 				fscsi->scsi_fc_rspcode	= rsp_info->rsp_code;
2792 			}
2793 			fscsi->scsi_pkt_state	= fpkt->pkt_state;
2794 			fscsi->scsi_pkt_action	= fpkt->pkt_action;
2795 			fscsi->scsi_pkt_reason	= fpkt->pkt_reason;
2796 
2797 			/*
2798 			 * Copy data and request sense
2799 			 *
2800 			 * Data must be copied by using the FCP_CP_IN macro.
2801 			 * This will ensure the proper byte order since the data
2802 			 * is being copied directly from the memory mapped
2803 			 * device register.
2804 			 *
2805 			 * The response (and request sense) will be in the
2806 			 * correct byte order.	No special copy is necessary.
2807 			 */
2808 
2809 			if (buf_len) {
2810 				FCP_CP_IN(fpkt->pkt_data,
2811 				    fscsi->scsi_bufaddr,
2812 				    fpkt->pkt_data_acc,
2813 				    buf_len);
2814 			}
2815 			bcopy((void *)rsp_sense,
2816 			    (void *)fscsi->scsi_rqbufaddr,
2817 			    sense_len);
2818 		}
2819 	}
2820 
2821 	/*
2822 	 * Cleanup transport data structures if icmd was alloc-ed
2823 	 * So, cleanup happens in the same thread that icmd was alloc-ed
2824 	 */
2825 	if (icmd != NULL) {
2826 		fcp_ipkt_sema_cleanup(icmd);
2827 	}
2828 
2829 	/* restore pm busy/idle status */
2830 	if (port_busy) {
2831 		fc_ulp_idle_port(pptr->port_fp_handle);
2832 	}
2833 
2834 	/*
2835 	 * Cleanup target.  if a reconfig is pending, don't clear the BUSY
2836 	 * flag, it'll be cleared when the reconfig is complete.
2837 	 */
2838 	if ((ptgt != NULL) && !reconfig_pending) {
2839 		/*
2840 		 * If target was created,
2841 		 */
2842 		if (target_created) {
2843 			mutex_enter(&ptgt->tgt_mutex);
2844 			ptgt->tgt_state &= ~FCP_TGT_BUSY;
2845 			mutex_exit(&ptgt->tgt_mutex);
2846 		} else {
2847 			/*
2848 			 * De-mark target as busy
2849 			 */
2850 			mutex_enter(&ptgt->tgt_mutex);
2851 			ptgt->tgt_state &= ~FCP_TGT_BUSY;
2852 			mutex_exit(&ptgt->tgt_mutex);
2853 		}
2854 	}
2855 	return (ret);
2856 }
2857 
2858 
2859 static int
2860 fcp_is_reconfig_needed(struct fcp_tgt *ptgt,
2861     fc_packet_t	*fpkt)
2862 {
2863 	uchar_t			*lun_string;
2864 	uint16_t		lun_num, i;
2865 	int			num_luns;
2866 	int			actual_luns;
2867 	int			num_masked_luns;
2868 	int			lun_buflen;
2869 	struct fcp_lun	*plun	= NULL;
2870 	struct fcp_reportlun_resp	*report_lun;
2871 	uint8_t			reconfig_needed = FALSE;
2872 	uint8_t			lun_exists = FALSE;
2873 	fcp_port_t			*pptr		 = ptgt->tgt_port;
2874 
2875 	report_lun = kmem_zalloc(fpkt->pkt_datalen, KM_SLEEP);
2876 
2877 	FCP_CP_IN(fpkt->pkt_data, report_lun, fpkt->pkt_data_acc,
2878 	    fpkt->pkt_datalen);
2879 
2880 	/* get number of luns (which is supplied as LUNS * 8) */
2881 	num_luns = BE_32(report_lun->num_lun) >> 3;
2882 
2883 	/*
2884 	 * Figure out exactly how many lun strings our response buffer
2885 	 * can hold.
2886 	 */
2887 	lun_buflen = (fpkt->pkt_datalen -
2888 	    2 * sizeof (uint32_t)) / sizeof (longlong_t);
2889 
2890 	/*
2891 	 * Is our response buffer full or not? We don't want to
2892 	 * potentially walk beyond the number of luns we have.
2893 	 */
2894 	if (num_luns <= lun_buflen) {
2895 		actual_luns = num_luns;
2896 	} else {
2897 		actual_luns = lun_buflen;
2898 	}
2899 
2900 	mutex_enter(&ptgt->tgt_mutex);
2901 
2902 	/* Scan each lun to see if we have masked it. */
2903 	num_masked_luns = 0;
2904 	if (fcp_lun_blacklist != NULL) {
2905 		for (i = 0; i < actual_luns; i++) {
2906 			lun_string = (uchar_t *)&(report_lun->lun_string[i]);
2907 			switch (lun_string[0] & 0xC0) {
2908 			case FCP_LUN_ADDRESSING:
2909 			case FCP_PD_ADDRESSING:
2910 			case FCP_VOLUME_ADDRESSING:
2911 				lun_num = ((lun_string[0] & 0x3F) << 8)
2912 				    | lun_string[1];
2913 				if (fcp_should_mask(&ptgt->tgt_port_wwn,
2914 				    lun_num) == TRUE) {
2915 					num_masked_luns++;
2916 				}
2917 				break;
2918 			default:
2919 				break;
2920 			}
2921 		}
2922 	}
2923 
2924 	/*
2925 	 * The quick and easy check.  If the number of LUNs reported
2926 	 * doesn't match the number we currently know about, we need
2927 	 * to reconfigure.
2928 	 */
2929 	if (num_luns && num_luns != (ptgt->tgt_lun_cnt + num_masked_luns)) {
2930 		mutex_exit(&ptgt->tgt_mutex);
2931 		kmem_free(report_lun, fpkt->pkt_datalen);
2932 		return (TRUE);
2933 	}
2934 
2935 	/*
2936 	 * If the quick and easy check doesn't turn up anything, we walk
2937 	 * the list of luns from the REPORT_LUN response and look for
2938 	 * any luns we don't know about.  If we find one, we know we need
2939 	 * to reconfigure. We will skip LUNs that are masked because of the
2940 	 * blacklist.
2941 	 */
2942 	for (i = 0; i < actual_luns; i++) {
2943 		lun_string = (uchar_t *)&(report_lun->lun_string[i]);
2944 		lun_exists = FALSE;
2945 		switch (lun_string[0] & 0xC0) {
2946 		case FCP_LUN_ADDRESSING:
2947 		case FCP_PD_ADDRESSING:
2948 		case FCP_VOLUME_ADDRESSING:
2949 			lun_num = ((lun_string[0] & 0x3F) << 8) | lun_string[1];
2950 
2951 			if ((fcp_lun_blacklist != NULL) && (fcp_should_mask(
2952 			    &ptgt->tgt_port_wwn, lun_num) == TRUE)) {
2953 				lun_exists = TRUE;
2954 				break;
2955 			}
2956 
2957 			for (plun = ptgt->tgt_lun; plun;
2958 			    plun = plun->lun_next) {
2959 				if (plun->lun_num == lun_num) {
2960 					lun_exists = TRUE;
2961 					break;
2962 				}
2963 			}
2964 			break;
2965 		default:
2966 			break;
2967 		}
2968 
2969 		if (lun_exists == FALSE) {
2970 			reconfig_needed = TRUE;
2971 			break;
2972 		}
2973 	}
2974 
2975 	mutex_exit(&ptgt->tgt_mutex);
2976 	kmem_free(report_lun, fpkt->pkt_datalen);
2977 
2978 	return (reconfig_needed);
2979 }
2980 
2981 /*
2982  * This function is called by fcp_handle_page83 and uses inquiry response data
2983  * stored in plun->lun_inq to determine whether or not a device is a member of
2984  * the table fcp_symmetric_disk_table_size. We return 0 if it is in the table,
2985  * otherwise 1.
2986  */
2987 static int
2988 fcp_symmetric_device_probe(struct fcp_lun *plun)
2989 {
2990 	struct scsi_inquiry	*stdinq = &plun->lun_inq;
2991 	char			*devidptr;
2992 	int			i, len;
2993 
2994 	for (i = 0; i < fcp_symmetric_disk_table_size; i++) {
2995 		devidptr = fcp_symmetric_disk_table[i];
2996 		len = (int)strlen(devidptr);
2997 
2998 		if (bcmp(stdinq->inq_vid, devidptr, len) == 0) {
2999 			return (0);
3000 		}
3001 	}
3002 	return (1);
3003 }
3004 
3005 
3006 /*
3007  * This function is called by fcp_ioctl for the FCP_STATE_COUNT ioctl
3008  * It basically returns the current count of # of state change callbacks
3009  * i.e the value of tgt_change_cnt.
3010  *
3011  * INPUT:
3012  *   fcp_ioctl.fp_minor -> The minor # of the fp port
3013  *   fcp_ioctl.listlen	-> 1
3014  *   fcp_ioctl.list	-> Pointer to a 32 bit integer
3015  */
3016 /*ARGSUSED2*/
3017 static int
3018 fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval)
3019 {
3020 	int			ret;
3021 	uint32_t		link_cnt;
3022 	struct fcp_ioctl	fioctl;
3023 	struct fcp_port	*pptr = NULL;
3024 
3025 	if ((ret = fcp_copyin_fcp_ioctl_data(data, mode, rval, &fioctl,
3026 	    &pptr)) != 0) {
3027 		return (ret);
3028 	}
3029 
3030 	ASSERT(pptr != NULL);
3031 
3032 	if (fioctl.listlen != 1) {
3033 		return (EINVAL);
3034 	}
3035 
3036 	mutex_enter(&pptr->port_mutex);
3037 	if (pptr->port_state & FCP_STATE_OFFLINE) {
3038 		mutex_exit(&pptr->port_mutex);
3039 		return (ENXIO);
3040 	}
3041 
3042 	/*
3043 	 * FCP_STATE_INIT is set in 2 cases (not sure why it is overloaded):
3044 	 * When the fcp initially attaches to the port and there are nothing
3045 	 * hanging out of the port or if there was a repeat offline state change
3046 	 * callback (refer fcp_statec_callback() FC_STATE_OFFLINE case).
3047 	 * In the latter case, port_tmp_cnt will be non-zero and that is how we
3048 	 * will differentiate the 2 cases.
3049 	 */
3050 	if ((pptr->port_state & FCP_STATE_INIT) && pptr->port_tmp_cnt) {
3051 		mutex_exit(&pptr->port_mutex);
3052 		return (ENXIO);
3053 	}
3054 
3055 	link_cnt = pptr->port_link_cnt;
3056 	mutex_exit(&pptr->port_mutex);
3057 
3058 	if (ddi_copyout(&link_cnt, fioctl.list, (sizeof (uint32_t)), mode)) {
3059 		return (EFAULT);
3060 	}
3061 
3062 #ifdef	_MULTI_DATAMODEL
3063 	switch (ddi_model_convert_from(mode & FMODELS)) {
3064 	case DDI_MODEL_ILP32: {
3065 		struct fcp32_ioctl f32_ioctl;
3066 
3067 		f32_ioctl.fp_minor = fioctl.fp_minor;
3068 		f32_ioctl.listlen = fioctl.listlen;
3069 		f32_ioctl.list = (caddr32_t)(long)fioctl.list;
3070 		if (ddi_copyout((void *)&f32_ioctl, (void *)data,
3071 		    sizeof (struct fcp32_ioctl), mode)) {
3072 			return (EFAULT);
3073 		}
3074 		break;
3075 	}
3076 	case DDI_MODEL_NONE:
3077 		if (ddi_copyout((void *)&fioctl, (void *)data,
3078 		    sizeof (struct fcp_ioctl), mode)) {
3079 			return (EFAULT);
3080 		}
3081 		break;
3082 	}
3083 #else	/* _MULTI_DATAMODEL */
3084 
3085 	if (ddi_copyout((void *)&fioctl, (void *)data,
3086 	    sizeof (struct fcp_ioctl), mode)) {
3087 		return (EFAULT);
3088 	}
3089 #endif	/* _MULTI_DATAMODEL */
3090 
3091 	return (0);
3092 }
3093 
3094 /*
3095  * This function copies the fcp_ioctl structure passed in from user land
3096  * into kernel land. Handles 32 bit applications.
3097  */
3098 /*ARGSUSED*/
3099 static int
3100 fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *data, int mode, int *rval,
3101     struct fcp_ioctl *fioctl, struct fcp_port **pptr)
3102 {
3103 	struct fcp_port	*t_pptr;
3104 
3105 #ifdef	_MULTI_DATAMODEL
3106 	switch (ddi_model_convert_from(mode & FMODELS)) {
3107 	case DDI_MODEL_ILP32: {
3108 		struct fcp32_ioctl f32_ioctl;
3109 
3110 		if (ddi_copyin((void *)data, (void *)&f32_ioctl,
3111 		    sizeof (struct fcp32_ioctl), mode)) {
3112 			return (EFAULT);
3113 		}
3114 		fioctl->fp_minor = f32_ioctl.fp_minor;
3115 		fioctl->listlen = f32_ioctl.listlen;
3116 		fioctl->list = (caddr_t)(long)f32_ioctl.list;
3117 		break;
3118 	}
3119 	case DDI_MODEL_NONE:
3120 		if (ddi_copyin((void *)data, (void *)fioctl,
3121 		    sizeof (struct fcp_ioctl), mode)) {
3122 			return (EFAULT);
3123 		}
3124 		break;
3125 	}
3126 
3127 #else	/* _MULTI_DATAMODEL */
3128 	if (ddi_copyin((void *)data, (void *)fioctl,
3129 	    sizeof (struct fcp_ioctl), mode)) {
3130 		return (EFAULT);
3131 	}
3132 #endif	/* _MULTI_DATAMODEL */
3133 
3134 	/*
3135 	 * Right now we can assume that the minor number matches with
3136 	 * this instance of fp. If this changes we will need to
3137 	 * revisit this logic.
3138 	 */
3139 	mutex_enter(&fcp_global_mutex);
3140 	t_pptr = fcp_port_head;
3141 	while (t_pptr) {
3142 		if (t_pptr->port_instance == (uint32_t)fioctl->fp_minor) {
3143 			break;
3144 		} else {
3145 			t_pptr = t_pptr->port_next;
3146 		}
3147 	}
3148 	*pptr = t_pptr;
3149 	mutex_exit(&fcp_global_mutex);
3150 	if (t_pptr == NULL) {
3151 		return (ENXIO);
3152 	}
3153 
3154 	return (0);
3155 }
3156 
3157 /*
3158  *     Function: fcp_port_create_tgt
3159  *
3160  *  Description: As the name suggest this function creates the target context
3161  *		 specified by the the WWN provided by the caller.  If the
3162  *		 creation goes well and the target is known by fp/fctl a PLOGI
3163  *		 followed by a PRLI are issued.
3164  *
3165  *     Argument: pptr		fcp port structure
3166  *		 pwwn		WWN of the target
3167  *		 ret_val	Address of the return code.  It could be:
3168  *				EIO, ENOMEM or 0.
3169  *		 fc_status	PLOGI or PRLI status completion
3170  *		 fc_pkt_state	PLOGI or PRLI state completion
3171  *		 fc_pkt_reason	PLOGI or PRLI reason completion
3172  *		 fc_pkt_action	PLOGI or PRLI action completion
3173  *
3174  * Return Value: NULL if it failed
3175  *		 Target structure address if it succeeds
3176  */
3177 static struct fcp_tgt *
3178 fcp_port_create_tgt(struct fcp_port *pptr, la_wwn_t *pwwn, int *ret_val,
3179     int *fc_status, int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action)
3180 {
3181 	struct fcp_tgt	*ptgt = NULL;
3182 	fc_portmap_t		devlist;
3183 	int			lcount;
3184 	int			error;
3185 
3186 	*ret_val = 0;
3187 
3188 	/*
3189 	 * Check FC port device & get port map
3190 	 */
3191 	if (fc_ulp_get_remote_port(pptr->port_fp_handle, pwwn,
3192 	    &error, 1) == NULL) {
3193 		*ret_val = EIO;
3194 	} else {
3195 		if (fc_ulp_pwwn_to_portmap(pptr->port_fp_handle, pwwn,
3196 		    &devlist) != FC_SUCCESS) {
3197 			*ret_val = EIO;
3198 		}
3199 	}
3200 
3201 	/* Set port map flags */
3202 	devlist.map_type = PORT_DEVICE_USER_CREATE;
3203 
3204 	/* Allocate target */
3205 	if (*ret_val == 0) {
3206 		lcount = pptr->port_link_cnt;
3207 		ptgt = fcp_alloc_tgt(pptr, &devlist, lcount);
3208 		if (ptgt == NULL) {
3209 			fcp_log(CE_WARN, pptr->port_dip,
3210 			    "!FC target allocation failed");
3211 			*ret_val = ENOMEM;
3212 		} else {
3213 			/* Setup target */
3214 			mutex_enter(&ptgt->tgt_mutex);
3215 
3216 			ptgt->tgt_statec_cause	= FCP_CAUSE_TGT_CHANGE;
3217 			ptgt->tgt_tmp_cnt	= 1;
3218 			ptgt->tgt_d_id		= devlist.map_did.port_id;
3219 			ptgt->tgt_hard_addr	=
3220 			    devlist.map_hard_addr.hard_addr;
3221 			ptgt->tgt_pd_handle	= devlist.map_pd;
3222 			ptgt->tgt_fca_dev	= NULL;
3223 
3224 			bcopy(&devlist.map_nwwn, &ptgt->tgt_node_wwn.raw_wwn[0],
3225 			    FC_WWN_SIZE);
3226 			bcopy(&devlist.map_pwwn, &ptgt->tgt_port_wwn.raw_wwn[0],
3227 			    FC_WWN_SIZE);
3228 
3229 			mutex_exit(&ptgt->tgt_mutex);
3230 		}
3231 	}
3232 
3233 	/* Release global mutex for PLOGI and PRLI */
3234 	mutex_exit(&fcp_global_mutex);
3235 
3236 	/* Send PLOGI (If necessary) */
3237 	if (*ret_val == 0) {
3238 		*ret_val = fcp_tgt_send_plogi(ptgt, fc_status,
3239 		    fc_pkt_state, fc_pkt_reason, fc_pkt_action);
3240 	}
3241 
3242 	/* Send PRLI (If necessary) */
3243 	if (*ret_val == 0) {
3244 		*ret_val = fcp_tgt_send_prli(ptgt, fc_status,
3245 		    fc_pkt_state, fc_pkt_reason, fc_pkt_action);
3246 	}
3247 
3248 	mutex_enter(&fcp_global_mutex);
3249 
3250 	return (ptgt);
3251 }
3252 
3253 /*
3254  *     Function: fcp_tgt_send_plogi
3255  *
3256  *  Description: This function sends a PLOGI to the target specified by the
3257  *		 caller and waits till it completes.
3258  *
3259  *     Argument: ptgt		Target to send the plogi to.
3260  *		 fc_status	Status returned by fp/fctl in the PLOGI request.
3261  *		 fc_pkt_state	State returned by fp/fctl in the PLOGI request.
3262  *		 fc_pkt_reason	Reason returned by fp/fctl in the PLOGI request.
3263  *		 fc_pkt_action	Action returned by fp/fctl in the PLOGI request.
3264  *
3265  * Return Value: 0
3266  *		 ENOMEM
3267  *		 EIO
3268  *
3269  *	Context: User context.
3270  */
3271 static int
3272 fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status, int *fc_pkt_state,
3273     int *fc_pkt_reason, int *fc_pkt_action)
3274 {
3275 	struct fcp_port	*pptr;
3276 	struct fcp_ipkt	*icmd;
3277 	struct fc_packet	*fpkt;
3278 	fc_frame_hdr_t		*hp;
3279 	struct la_els_logi	logi;
3280 	int			tcount;
3281 	int			lcount;
3282 	int			ret, login_retval = ~FC_SUCCESS;
3283 
3284 	ret = 0;
3285 
3286 	pptr = ptgt->tgt_port;
3287 
3288 	lcount = pptr->port_link_cnt;
3289 	tcount = ptgt->tgt_change_cnt;
3290 
3291 	/* Alloc internal packet */
3292 	icmd = fcp_icmd_alloc(pptr, ptgt, sizeof (la_els_logi_t),
3293 	    sizeof (la_els_logi_t), 0,
3294 	    pptr->port_state & FCP_STATE_FCA_IS_NODMA,
3295 	    lcount, tcount, 0, FC_INVALID_RSCN_COUNT);
3296 
3297 	if (icmd == NULL) {
3298 		ret = ENOMEM;
3299 	} else {
3300 		/*
3301 		 * Setup internal packet as sema sync
3302 		 */
3303 		fcp_ipkt_sema_init(icmd);
3304 
3305 		/*
3306 		 * Setup internal packet (icmd)
3307 		 */
3308 		icmd->ipkt_lun		= NULL;
3309 		icmd->ipkt_restart	= 0;
3310 		icmd->ipkt_retries	= 0;
3311 		icmd->ipkt_opcode	= LA_ELS_PLOGI;
3312 
3313 		/*
3314 		 * Setup fc_packet
3315 		 */
3316 		fpkt = icmd->ipkt_fpkt;
3317 
3318 		fpkt->pkt_tran_flags	= FC_TRAN_CLASS3 | FC_TRAN_INTR;
3319 		fpkt->pkt_tran_type	= FC_PKT_EXCHANGE;
3320 		fpkt->pkt_timeout	= FCP_ELS_TIMEOUT;
3321 
3322 		/*
3323 		 * Setup FC frame header
3324 		 */
3325 		hp = &fpkt->pkt_cmd_fhdr;
3326 
3327 		hp->s_id	= pptr->port_id;	/* source ID */
3328 		hp->d_id	= ptgt->tgt_d_id;	/* dest ID */
3329 		hp->r_ctl	= R_CTL_ELS_REQ;
3330 		hp->type	= FC_TYPE_EXTENDED_LS;
3331 		hp->f_ctl	= F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ;
3332 		hp->seq_id	= 0;
3333 		hp->rsvd	= 0;
3334 		hp->df_ctl	= 0;
3335 		hp->seq_cnt	= 0;
3336 		hp->ox_id	= 0xffff;		/* i.e. none */
3337 		hp->rx_id	= 0xffff;		/* i.e. none */
3338 		hp->ro		= 0;
3339 
3340 		/*
3341 		 * Setup PLOGI
3342 		 */
3343 		bzero(&logi, sizeof (struct la_els_logi));
3344 		logi.ls_code.ls_code = LA_ELS_PLOGI;
3345 
3346 		FCP_CP_OUT((uint8_t *)&logi, fpkt->pkt_cmd,
3347 		    fpkt->pkt_cmd_acc, sizeof (struct la_els_logi));
3348 
3349 		/*
3350 		 * Send PLOGI
3351 		 */
3352 		*fc_status = login_retval =
3353 		    fc_ulp_login(pptr->port_fp_handle, &fpkt, 1);
3354 		if (*fc_status != FC_SUCCESS) {
3355 			ret = EIO;
3356 		}
3357 	}
3358 
3359 	/*
3360 	 * Wait for completion
3361 	 */
3362 	if ((ret == 0) && (login_retval == FC_SUCCESS)) {
3363 		ret = fcp_ipkt_sema_wait(icmd);
3364 
3365 		*fc_pkt_state	= fpkt->pkt_state;
3366 		*fc_pkt_reason	= fpkt->pkt_reason;
3367 		*fc_pkt_action	= fpkt->pkt_action;
3368 	}
3369 
3370 	/*
3371 	 * Cleanup transport data structures if icmd was alloc-ed AND if there
3372 	 * is going to be no callback (i.e if fc_ulp_login() failed).
3373 	 * Otherwise, cleanup happens in callback routine.
3374 	 */
3375 	if (icmd != NULL) {
3376 		fcp_ipkt_sema_cleanup(icmd);
3377 	}
3378 
3379 	return (ret);
3380 }
3381 
3382 /*
3383  *     Function: fcp_tgt_send_prli
3384  *
3385  *  Description: Does nothing as of today.
3386  *
3387  *     Argument: ptgt		Target to send the prli to.
3388  *		 fc_status	Status returned by fp/fctl in the PRLI request.
3389  *		 fc_pkt_state	State returned by fp/fctl in the PRLI request.
3390  *		 fc_pkt_reason	Reason returned by fp/fctl in the PRLI request.
3391  *		 fc_pkt_action	Action returned by fp/fctl in the PRLI request.
3392  *
3393  * Return Value: 0
3394  */
3395 /*ARGSUSED*/
3396 static int
3397 fcp_tgt_send_prli(struct fcp_tgt *ptgt, int *fc_status, int *fc_pkt_state,
3398     int *fc_pkt_reason, int *fc_pkt_action)
3399 {
3400 	return (0);
3401 }
3402 
3403 /*
3404  *     Function: fcp_ipkt_sema_init
3405  *
3406  *  Description: Initializes the semaphore contained in the internal packet.
3407  *
3408  *     Argument: icmd	Internal packet the semaphore of which must be
3409  *			initialized.
3410  *
3411  * Return Value: None
3412  *
3413  *	Context: User context only.
3414  */
3415 static void
3416 fcp_ipkt_sema_init(struct fcp_ipkt *icmd)
3417 {
3418 	struct fc_packet	*fpkt;
3419 
3420 	fpkt = icmd->ipkt_fpkt;
3421 
3422 	/* Create semaphore for sync */
3423 	sema_init(&(icmd->ipkt_sema), 0, NULL, SEMA_DRIVER, NULL);
3424 
3425 	/* Setup the completion callback */
3426 	fpkt->pkt_comp = fcp_ipkt_sema_callback;
3427 }
3428 
3429 /*
3430  *     Function: fcp_ipkt_sema_wait
3431  *
3432  *  Description: Wait on the semaphore embedded in the internal packet.	 The
3433  *		 semaphore is released in the callback.
3434  *
3435  *     Argument: icmd	Internal packet to wait on for completion.
3436  *
3437  * Return Value: 0
3438  *		 EIO
3439  *		 EBUSY
3440  *		 EAGAIN
3441  *
3442  *	Context: User context only.
3443  *
3444  * This function does a conversion between the field pkt_state of the fc_packet
3445  * embedded in the internal packet (icmd) and the code it returns.
3446  */
3447 static int
3448 fcp_ipkt_sema_wait(struct fcp_ipkt *icmd)
3449 {
3450 	struct fc_packet	*fpkt;
3451 	int	ret;
3452 
3453 	ret = EIO;
3454 	fpkt = icmd->ipkt_fpkt;
3455 
3456 	/*
3457 	 * Wait on semaphore
3458 	 */
3459 	sema_p(&(icmd->ipkt_sema));
3460 
3461 	/*
3462 	 * Check the status of the FC packet
3463 	 */
3464 	switch (fpkt->pkt_state) {
3465 	case FC_PKT_SUCCESS:
3466 		ret = 0;
3467 		break;
3468 	case FC_PKT_LOCAL_RJT:
3469 		switch (fpkt->pkt_reason) {
3470 		case FC_REASON_SEQ_TIMEOUT:
3471 		case FC_REASON_RX_BUF_TIMEOUT:
3472 			ret = EAGAIN;
3473 			break;
3474 		case FC_REASON_PKT_BUSY:
3475 			ret = EBUSY;
3476 			break;
3477 		}
3478 		break;
3479 	case FC_PKT_TIMEOUT:
3480 		ret = EAGAIN;
3481 		break;
3482 	case FC_PKT_LOCAL_BSY:
3483 	case FC_PKT_TRAN_BSY:
3484 	case FC_PKT_NPORT_BSY:
3485 	case FC_PKT_FABRIC_BSY:
3486 		ret = EBUSY;
3487 		break;
3488 	case FC_PKT_LS_RJT:
3489 	case FC_PKT_BA_RJT:
3490 		switch (fpkt->pkt_reason) {
3491 		case FC_REASON_LOGICAL_BSY:
3492 			ret = EBUSY;
3493 			break;
3494 		}
3495 		break;
3496 	case FC_PKT_FS_RJT:
3497 		switch (fpkt->pkt_reason) {
3498 		case FC_REASON_FS_LOGICAL_BUSY:
3499 			ret = EBUSY;
3500 			break;
3501 		}
3502 		break;
3503 	}
3504 
3505 	return (ret);
3506 }
3507 
3508 /*
3509  *     Function: fcp_ipkt_sema_callback
3510  *
3511  *  Description: Registered as the completion callback function for the FC
3512  *		 transport when the ipkt semaphore is used for sync. This will
3513  *		 cleanup the used data structures, if necessary and wake up
3514  *		 the user thread to complete the transaction.
3515  *
3516  *     Argument: fpkt	FC packet (points to the icmd)
3517  *
3518  * Return Value: None
3519  *
3520  *	Context: User context only
3521  */
3522 static void
3523 fcp_ipkt_sema_callback(struct fc_packet *fpkt)
3524 {
3525 	struct fcp_ipkt	*icmd;
3526 
3527 	icmd = (struct fcp_ipkt *)fpkt->pkt_ulp_private;
3528 
3529 	/*
3530 	 * Wake up user thread
3531 	 */
3532 	sema_v(&(icmd->ipkt_sema));
3533 }
3534 
3535 /*
3536  *     Function: fcp_ipkt_sema_cleanup
3537  *
3538  *  Description: Called to cleanup (if necessary) the data structures used
3539  *		 when ipkt sema is used for sync.  This function will detect
3540  *		 whether the caller is the last thread (via counter) and
3541  *		 cleanup only if necessary.
3542  *
3543  *     Argument: icmd	Internal command packet
3544  *
3545  * Return Value: None
3546  *
3547  *	Context: User context only
3548  */
3549 static void
3550 fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd)
3551 {
3552 	struct fcp_tgt	*ptgt;
3553 	struct fcp_port	*pptr;
3554 
3555 	ptgt = icmd->ipkt_tgt;
3556 	pptr = icmd->ipkt_port;
3557 
3558 	/*
3559 	 * Acquire data structure
3560 	 */
3561 	mutex_enter(&ptgt->tgt_mutex);
3562 
3563 	/*
3564 	 * Destroy semaphore
3565 	 */
3566 	sema_destroy(&(icmd->ipkt_sema));
3567 
3568 	/*
3569 	 * Cleanup internal packet
3570 	 */
3571 	mutex_exit(&ptgt->tgt_mutex);
3572 	fcp_icmd_free(pptr, icmd);
3573 }
3574 
3575 /*
3576  *     Function: fcp_port_attach
3577  *
3578  *  Description: Called by the transport framework to resume, suspend or
3579  *		 attach a new port.
3580  *
3581  *     Argument: ulph		Port handle
3582  *		 *pinfo		Port information
3583  *		 cmd		Command
3584  *		 s_id		Port ID
3585  *
3586  * Return Value: FC_FAILURE or FC_SUCCESS
3587  */
3588 /*ARGSUSED*/
3589 static int
3590 fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo,
3591     fc_attach_cmd_t cmd, uint32_t s_id)
3592 {
3593 	int	instance;
3594 	int	res = FC_FAILURE; /* default result */
3595 
3596 	ASSERT(pinfo != NULL);
3597 
3598 	instance = ddi_get_instance(pinfo->port_dip);
3599 
3600 	switch (cmd) {
3601 	case FC_CMD_ATTACH:
3602 		/*
3603 		 * this port instance attaching for the first time (or after
3604 		 * being detached before)
3605 		 */
3606 		if (fcp_handle_port_attach(ulph, pinfo, s_id,
3607 		    instance) == DDI_SUCCESS) {
3608 			res = FC_SUCCESS;
3609 		} else {
3610 			ASSERT(ddi_get_soft_state(fcp_softstate,
3611 			    instance) == NULL);
3612 		}
3613 		break;
3614 
3615 	case FC_CMD_RESUME:
3616 	case FC_CMD_POWER_UP:
3617 		/*
3618 		 * this port instance was attached and the suspended and
3619 		 * will now be resumed
3620 		 */
3621 		if (fcp_handle_port_resume(ulph, pinfo, s_id, cmd,
3622 		    instance) == DDI_SUCCESS) {
3623 			res = FC_SUCCESS;
3624 		}
3625 		break;
3626 
3627 	default:
3628 		/* shouldn't happen */
3629 		FCP_TRACE(fcp_logq, "fcp",
3630 		    fcp_trace, FCP_BUF_LEVEL_2, 0,
3631 		    "port_attach: unknown cmdcommand: %d", cmd);
3632 		break;
3633 	}
3634 
3635 	/* return result */
3636 	FCP_DTRACE(fcp_logq, "fcp", fcp_trace,
3637 	    FCP_BUF_LEVEL_1, 0, "fcp_port_attach returning %d", res);
3638 
3639 	return (res);
3640 }
3641 
3642 
3643 /*
3644  * detach or suspend this port instance
3645  *
3646  * acquires and releases the global mutex
3647  *
3648  * acquires and releases the mutex for this port
3649  *
3650  * acquires and releases the hotplug mutex for this port
3651  */
3652 /*ARGSUSED*/
3653 static int
3654 fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info,
3655     fc_detach_cmd_t cmd)
3656 {
3657 	int			flag;
3658 	int			instance;
3659 	struct fcp_port		*pptr;
3660 
3661 	instance = ddi_get_instance(info->port_dip);
3662 	pptr = ddi_get_soft_state(fcp_softstate, instance);
3663 
3664 	switch (cmd) {
3665 	case FC_CMD_SUSPEND:
3666 		FCP_DTRACE(fcp_logq, "fcp",
3667 		    fcp_trace, FCP_BUF_LEVEL_8, 0,
3668 		    "port suspend called for port %d", instance);
3669 		flag = FCP_STATE_SUSPENDED;
3670 		break;
3671 
3672 	case FC_CMD_POWER_DOWN:
3673 		FCP_DTRACE(fcp_logq, "fcp",
3674 		    fcp_trace, FCP_BUF_LEVEL_8, 0,
3675 		    "port power down called for port %d", instance);
3676 		flag = FCP_STATE_POWER_DOWN;
3677 		break;
3678 
3679 	case FC_CMD_DETACH:
3680 		FCP_DTRACE(fcp_logq, "fcp",
3681 		    fcp_trace, FCP_BUF_LEVEL_8, 0,
3682 		    "port detach called for port %d", instance);
3683 		flag = FCP_STATE_DETACHING;
3684 		break;
3685 
3686 	default:
3687 		/* shouldn't happen */
3688 		return (FC_FAILURE);
3689 	}
3690 	FCP_DTRACE(fcp_logq, "fcp", fcp_trace,
3691 	    FCP_BUF_LEVEL_1, 0, "fcp_port_detach returning");
3692 
3693 	return (fcp_handle_port_detach(pptr, flag, instance));
3694 }
3695 
3696 
3697 /*
3698  * called for ioctls on the transport's devctl interface, and the transport
3699  * has passed it to us
3700  *
3701  * this will only be called for device control ioctls (i.e. hotplugging stuff)
3702  *
3703  * return FC_SUCCESS if we decide to claim the ioctl,
3704  * else return FC_UNCLAIMED
3705  *
3706  * *rval is set iff we decide to claim the ioctl
3707  */
3708 /*ARGSUSED*/
3709 static int
3710 fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev, int cmd,
3711     intptr_t data, int mode, cred_t *credp, int *rval, uint32_t claimed)
3712 {
3713 	int			retval = FC_UNCLAIMED;	/* return value */
3714 	struct fcp_port		*pptr = NULL;		/* our soft state */
3715 	struct devctl_iocdata	*dcp = NULL;		/* for devctl */
3716 	dev_info_t		*cdip;
3717 	mdi_pathinfo_t		*pip = NULL;
3718 	char			*ndi_nm;		/* NDI name */
3719 	char			*ndi_addr;		/* NDI addr */
3720 	int			is_mpxio, circ;
3721 	int			devi_entered = 0;
3722 	time_t			end_time;
3723 
3724 	ASSERT(rval != NULL);
3725 
3726 	FCP_DTRACE(fcp_logq, "fcp",
3727 	    fcp_trace, FCP_BUF_LEVEL_8, 0,
3728 	    "fcp_port_ioctl(cmd=0x%x, claimed=%d)", cmd, claimed);
3729 
3730 	/* if already claimed then forget it */
3731 	if (claimed) {
3732 		/*
3733 		 * for now, if this ioctl has already been claimed, then
3734 		 * we just ignore it
3735 		 */
3736 		return (retval);
3737 	}
3738 
3739 	/* get our port info */
3740 	if ((pptr = fcp_get_port(port_handle)) == NULL) {
3741 		fcp_log(CE_WARN, NULL,
3742 		    "!fcp:Invalid port handle handle in ioctl");
3743 		*rval = ENXIO;
3744 		return (retval);
3745 	}
3746 	is_mpxio = pptr->port_mpxio;
3747 
3748 	switch (cmd) {
3749 	case DEVCTL_BUS_GETSTATE:
3750 	case DEVCTL_BUS_QUIESCE:
3751 	case DEVCTL_BUS_UNQUIESCE:
3752 	case DEVCTL_BUS_RESET:
3753 	case DEVCTL_BUS_RESETALL:
3754 
3755 	case DEVCTL_BUS_DEV_CREATE:
3756 		if (ndi_dc_allochdl((void *)data, &dcp) != NDI_SUCCESS) {
3757 			return (retval);
3758 		}
3759 		break;
3760 
3761 	case DEVCTL_DEVICE_GETSTATE:
3762 	case DEVCTL_DEVICE_OFFLINE:
3763 	case DEVCTL_DEVICE_ONLINE:
3764 <