1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte /*
22bcd6185eSMilos Muzik  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23fcf3ce44SJohn Forte  *
24fcf3ce44SJohn Forte  * Fibre Channel SCSI ULP Mapping driver
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27fcf3ce44SJohn Forte #include <sys/scsi/scsi.h>
28fcf3ce44SJohn Forte #include <sys/types.h>
29fcf3ce44SJohn Forte #include <sys/varargs.h>
30fcf3ce44SJohn Forte #include <sys/devctl.h>
31fcf3ce44SJohn Forte #include <sys/thread.h>
32fcf3ce44SJohn Forte #include <sys/thread.h>
33fcf3ce44SJohn Forte #include <sys/open.h>
34fcf3ce44SJohn Forte #include <sys/file.h>
35fcf3ce44SJohn Forte #include <sys/sunndi.h>
36fcf3ce44SJohn Forte #include <sys/console.h>
37fcf3ce44SJohn Forte #include <sys/proc.h>
38fcf3ce44SJohn Forte #include <sys/time.h>
39fcf3ce44SJohn Forte #include <sys/utsname.h>
40fcf3ce44SJohn Forte #include <sys/scsi/impl/scsi_reset_notify.h>
41fcf3ce44SJohn Forte #include <sys/ndi_impldefs.h>
42fcf3ce44SJohn Forte #include <sys/byteorder.h>
43fcf3ce44SJohn Forte #include <sys/fs/dv_node.h>
44fcf3ce44SJohn Forte #include <sys/ctype.h>
45fcf3ce44SJohn Forte #include <sys/sunmdi.h>
46fcf3ce44SJohn Forte 
47fcf3ce44SJohn Forte #include <sys/fibre-channel/fc.h>
48fcf3ce44SJohn Forte #include <sys/fibre-channel/impl/fc_ulpif.h>
49fcf3ce44SJohn Forte #include <sys/fibre-channel/ulp/fcpvar.h>
50fcf3ce44SJohn Forte 
51fcf3ce44SJohn Forte /*
52fcf3ce44SJohn Forte  * Discovery Process
53fcf3ce44SJohn Forte  * =================
54fcf3ce44SJohn Forte  *
556e0414acSReed  *    The discovery process is a major function of FCP.	 In order to help
56fcf3ce44SJohn Forte  * understand that function a flow diagram is given here.  This diagram
57fcf3ce44SJohn Forte  * doesn't claim to cover all the cases and the events that can occur during
58fcf3ce44SJohn Forte  * the discovery process nor the subtleties of the code.  The code paths shown
59fcf3ce44SJohn Forte  * are simplified.  Its purpose is to help the reader (and potentially bug
60fcf3ce44SJohn Forte  * fixer) have an overall view of the logic of the code.  For that reason the
61fcf3ce44SJohn Forte  * diagram covers the simple case of the line coming up cleanly or of a new
62fcf3ce44SJohn Forte  * port attaching to FCP the link being up.  The reader must keep in mind
63fcf3ce44SJohn Forte  * that:
64fcf3ce44SJohn Forte  *
65fcf3ce44SJohn Forte  *	- There are special cases where bringing devices online and offline
66fcf3ce44SJohn Forte  *	  is driven by Ioctl.
67fcf3ce44SJohn Forte  *
68fcf3ce44SJohn Forte  *	- The behavior of the discovery process can be modified through the
69fcf3ce44SJohn Forte  *	  .conf file.
70fcf3ce44SJohn Forte  *
71fcf3ce44SJohn Forte  *	- The line can go down and come back up at any time during the
72fcf3ce44SJohn Forte  *	  discovery process which explains some of the complexity of the code.
73fcf3ce44SJohn Forte  *
74fcf3ce44SJohn Forte  * ............................................................................
75fcf3ce44SJohn Forte  *
76fcf3ce44SJohn Forte  * STEP 1: The line comes up or a new Fibre Channel port attaches to FCP.
77fcf3ce44SJohn Forte  *
78fcf3ce44SJohn Forte  *
79fcf3ce44SJohn Forte  *			+-------------------------+
80fcf3ce44SJohn Forte  *   fp/fctl module --->|    fcp_port_attach	  |
81fcf3ce44SJohn Forte  *			+-------------------------+
82fcf3ce44SJohn Forte  *	   |			     |
83fcf3ce44SJohn Forte  *	   |			     |
84fcf3ce44SJohn Forte  *	   |			     v
85fcf3ce44SJohn Forte  *	   |		+-------------------------+
86fcf3ce44SJohn Forte  *	   |		| fcp_handle_port_attach  |
87fcf3ce44SJohn Forte  *	   |		+-------------------------+
88fcf3ce44SJohn Forte  *	   |				|
89fcf3ce44SJohn Forte  *	   |				|
90fcf3ce44SJohn Forte  *	   +--------------------+	|
91fcf3ce44SJohn Forte  *				|	|
92fcf3ce44SJohn Forte  *				v	v
93fcf3ce44SJohn Forte  *			+-------------------------+
946e0414acSReed  *			|   fcp_statec_callback	  |
95fcf3ce44SJohn Forte  *			+-------------------------+
96fcf3ce44SJohn Forte  *				    |
97fcf3ce44SJohn Forte  *				    |
98fcf3ce44SJohn Forte  *				    v
99fcf3ce44SJohn Forte  *			+-------------------------+
1006e0414acSReed  *			|    fcp_handle_devices	  |
101fcf3ce44SJohn Forte  *			+-------------------------+
102fcf3ce44SJohn Forte  *				    |
103fcf3ce44SJohn Forte  *				    |
104fcf3ce44SJohn Forte  *				    v
105fcf3ce44SJohn Forte  *			+-------------------------+
1066e0414acSReed  *			|   fcp_handle_mapflags	  |
107fcf3ce44SJohn Forte  *			+-------------------------+
108fcf3ce44SJohn Forte  *				    |
109fcf3ce44SJohn Forte  *				    |
110fcf3ce44SJohn Forte  *				    v
111fcf3ce44SJohn Forte  *			+-------------------------+
112fcf3ce44SJohn Forte  *			|     fcp_send_els	  |
113fcf3ce44SJohn Forte  *			|			  |
114fcf3ce44SJohn Forte  *			| PLOGI or PRLI To all the|
115fcf3ce44SJohn Forte  *			| reachable devices.	  |
116fcf3ce44SJohn Forte  *			+-------------------------+
117fcf3ce44SJohn Forte  *
118fcf3ce44SJohn Forte  *
119fcf3ce44SJohn Forte  * ............................................................................
120fcf3ce44SJohn Forte  *
121fcf3ce44SJohn Forte  * STEP 2: The callback functions of the PLOGI and/or PRLI requests sent during
122fcf3ce44SJohn Forte  *	   STEP 1 are called (it is actually the same function).
123fcf3ce44SJohn Forte  *
124fcf3ce44SJohn Forte  *
125fcf3ce44SJohn Forte  *			+-------------------------+
1266e0414acSReed  *			|    fcp_icmd_callback	  |
127fcf3ce44SJohn Forte  *   fp/fctl module --->|			  |
128fcf3ce44SJohn Forte  *			| callback for PLOGI and  |
129fcf3ce44SJohn Forte  *			| PRLI.			  |
130fcf3ce44SJohn Forte  *			+-------------------------+
131fcf3ce44SJohn Forte  *				     |
132fcf3ce44SJohn Forte  *				     |
133fcf3ce44SJohn Forte  *	    Received PLOGI Accept   /-\	  Received PRLI Accept
134fcf3ce44SJohn Forte  *		       _ _ _ _ _ _ /   \_ _ _ _ _ _
135fcf3ce44SJohn Forte  *		      |		   \   /	   |
136fcf3ce44SJohn Forte  *		      |		    \-/		   |
137fcf3ce44SJohn Forte  *		      |				   |
138fcf3ce44SJohn Forte  *		      v				   v
139fcf3ce44SJohn Forte  *	+-------------------------+	+-------------------------+
140fcf3ce44SJohn Forte  *	|     fcp_send_els	  |	|     fcp_send_scsi	  |
141fcf3ce44SJohn Forte  *	|			  |	|			  |
142fcf3ce44SJohn Forte  *	|	  PRLI		  |	|	REPORT_LUN	  |
143fcf3ce44SJohn Forte  *	+-------------------------+	+-------------------------+
144fcf3ce44SJohn Forte  *
145fcf3ce44SJohn Forte  * ............................................................................
146fcf3ce44SJohn Forte  *
147fcf3ce44SJohn Forte  * STEP 3: The callback functions of the SCSI commands issued by FCP are called
148fcf3ce44SJohn Forte  *	   (It is actually the same function).
149fcf3ce44SJohn Forte  *
150fcf3ce44SJohn Forte  *
151fcf3ce44SJohn Forte  *			    +-------------------------+
1526e0414acSReed  *   fp/fctl module ------->|	 fcp_scsi_callback    |
153fcf3ce44SJohn Forte  *			    +-------------------------+
154fcf3ce44SJohn Forte  *					|
155fcf3ce44SJohn Forte  *					|
156fcf3ce44SJohn Forte  *					|
157fcf3ce44SJohn Forte  *	Receive REPORT_LUN reply       /-\	Receive INQUIRY PAGE83 reply
1586e0414acSReed  *		  _ _ _ _ _ _ _ _ _ _ /	  \_ _ _ _ _ _ _ _ _ _ _ _
1596e0414acSReed  *		 |		      \	  /			  |
160fcf3ce44SJohn Forte  *		 |		       \-/			  |
161fcf3ce44SJohn Forte  *		 |			|			  |
162fcf3ce44SJohn Forte  *		 | Receive INQUIRY reply|			  |
163fcf3ce44SJohn Forte  *		 |			|			  |
164fcf3ce44SJohn Forte  *		 v			v			  v
165fcf3ce44SJohn Forte  * +------------------------+ +----------------------+ +----------------------+
1666e0414acSReed  * |  fcp_handle_reportlun  | |	 fcp_handle_inquiry  | |  fcp_handle_page83   |
167fcf3ce44SJohn Forte  * |(Called for each Target)| | (Called for each LUN)| |(Called for each LUN) |
168fcf3ce44SJohn Forte  * +------------------------+ +----------------------+ +----------------------+
1696e0414acSReed  *		 |			|			  |
1706e0414acSReed  *		 |			|			  |
1716e0414acSReed  *		 |			|			  |
1726e0414acSReed  *		 v			v			  |
173fcf3ce44SJohn Forte  *     +-----------------+	+-----------------+		  |
1746e0414acSReed  *     |  fcp_send_scsi	 |	|  fcp_send_scsi  |		  |
175fcf3ce44SJohn Forte  *     |		 |	|		  |		  |
1766e0414acSReed  *     |     INQUIRY	 |	| INQUIRY PAGE83  |		  |
177fcf3ce44SJohn Forte  *     |  (To each LUN)	 |	+-----------------+		  |
178fcf3ce44SJohn Forte  *     +-----------------+					  |
179fcf3ce44SJohn Forte  *								  |
180fcf3ce44SJohn Forte  *								  v
181fcf3ce44SJohn Forte  *						      +------------------------+
1826e0414acSReed  *						      |	 fcp_call_finish_init  |
183fcf3ce44SJohn Forte  *						      +------------------------+
184fcf3ce44SJohn Forte  *								  |
185fcf3ce44SJohn Forte  *								  v
186fcf3ce44SJohn Forte  *						 +-----------------------------+
187fcf3ce44SJohn Forte  *						 |  fcp_call_finish_init_held  |
188fcf3ce44SJohn Forte  *						 +-----------------------------+
189fcf3ce44SJohn Forte  *								  |
190fcf3ce44SJohn Forte  *								  |
191fcf3ce44SJohn Forte  *			   All LUNs scanned			 /-\
192fcf3ce44SJohn Forte  *			       _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ /   \
1936e0414acSReed  *			      |					\   /
194fcf3ce44SJohn Forte  *			      |					 \-/
195fcf3ce44SJohn Forte  *			      v					  |
196fcf3ce44SJohn Forte  *		     +------------------+			  |
1976e0414acSReed  *		     |	fcp_finish_tgt	|			  |
198fcf3ce44SJohn Forte  *		     +------------------+			  |
199fcf3ce44SJohn Forte  *			      |	  Target Not Offline and	  |
2006e0414acSReed  *  Target Not Offline and    |	  not marked and tgt_node_state	  |
201fcf3ce44SJohn Forte  *  marked		     /-\  not FCP_TGT_NODE_ON_DEMAND	  |
2026e0414acSReed  *		_ _ _ _ _ _ /	\_ _ _ _ _ _ _ _		  |
2036e0414acSReed  *	       |	    \	/		|		  |
204fcf3ce44SJohn Forte  *	       |	     \-/		|		  |
205fcf3ce44SJohn Forte  *	       v				v		  |
206fcf3ce44SJohn Forte  * +----------------------------+     +-------------------+	  |
2076e0414acSReed  * |	 fcp_offline_target	|     |	 fcp_create_luns  |	  |
208fcf3ce44SJohn Forte  * |				|     +-------------------+	  |
209fcf3ce44SJohn Forte  * | A structure fcp_tgt_elem	|		|		  |
210fcf3ce44SJohn Forte  * | is created and queued in	|		v		  |
211fcf3ce44SJohn Forte  * | the FCP port list		|     +-------------------+	  |
2126e0414acSReed  * | port_offline_tgts.	 It	|     |	 fcp_pass_to_hp	  |	  |
2136e0414acSReed  * | will be unqueued by the	|     |			  |	  |
2146e0414acSReed  * | watchdog timer.		|     | Called for each	  |	  |
2156e0414acSReed  * +----------------------------+     | LUN. Dispatches	  |	  |
216fcf3ce44SJohn Forte  *		  |		      | fcp_hp_task	  |	  |
217fcf3ce44SJohn Forte  *		  |		      +-------------------+	  |
218fcf3ce44SJohn Forte  *		  |				|		  |
219fcf3ce44SJohn Forte  *		  |				|		  |
220fcf3ce44SJohn Forte  *		  |				|		  |
221fcf3ce44SJohn Forte  *		  |				+---------------->|
222fcf3ce44SJohn Forte  *		  |						  |
223fcf3ce44SJohn Forte  *		  +---------------------------------------------->|
224fcf3ce44SJohn Forte  *								  |
225fcf3ce44SJohn Forte  *								  |
226fcf3ce44SJohn Forte  *		All the targets (devices) have been scanned	 /-\
227fcf3ce44SJohn Forte  *				_ _ _ _	_ _ _ _	_ _ _ _ _ _ _ _ /   \
228fcf3ce44SJohn Forte  *			       |				\   /
229fcf3ce44SJohn Forte  *			       |				 \-/
230fcf3ce44SJohn Forte  *	    +-------------------------------------+		  |
231fcf3ce44SJohn Forte  *	    |		fcp_finish_init		  |		  |
232fcf3ce44SJohn Forte  *	    |					  |		  |
233fcf3ce44SJohn Forte  *	    | Signal broadcasts the condition	  |		  |
234fcf3ce44SJohn Forte  *	    | variable port_config_cv of the FCP  |		  |
235fcf3ce44SJohn Forte  *	    | port.  One potential code sequence  |		  |
236fcf3ce44SJohn Forte  *	    | waiting on the condition variable	  |		  |
237fcf3ce44SJohn Forte  *	    | the code sequence handling	  |		  |
238fcf3ce44SJohn Forte  *	    | BUS_CONFIG_ALL and BUS_CONFIG_DRIVER|		  |
239fcf3ce44SJohn Forte  *	    | The other is in the function	  |		  |
240fcf3ce44SJohn Forte  *	    | fcp_reconfig_wait which is called	  |		  |
241fcf3ce44SJohn Forte  *	    | in the transmit path preventing IOs |		  |
242fcf3ce44SJohn Forte  *	    | from going through till the disco-  |		  |
243fcf3ce44SJohn Forte  *	    | very process is over.		  |		  |
244fcf3ce44SJohn Forte  *	    +-------------------------------------+		  |
245fcf3ce44SJohn Forte  *			       |				  |
246fcf3ce44SJohn Forte  *			       |				  |
247fcf3ce44SJohn Forte  *			       +--------------------------------->|
248fcf3ce44SJohn Forte  *								  |
249fcf3ce44SJohn Forte  *								  v
250fcf3ce44SJohn Forte  *								Return
251fcf3ce44SJohn Forte  *
252fcf3ce44SJohn Forte  * ............................................................................
253fcf3ce44SJohn Forte  *
254fcf3ce44SJohn Forte  * STEP 4: The hot plug task is called (for each fcp_hp_elem).
255fcf3ce44SJohn Forte  *
256fcf3ce44SJohn Forte  *
257fcf3ce44SJohn Forte  *			+-------------------------+
258fcf3ce44SJohn Forte  *			|      fcp_hp_task	  |
259fcf3ce44SJohn Forte  *			+-------------------------+
260fcf3ce44SJohn Forte  *				     |
261fcf3ce44SJohn Forte  *				     |
262fcf3ce44SJohn Forte  *				     v
263fcf3ce44SJohn Forte  *			+-------------------------+
2646e0414acSReed  *			|     fcp_trigger_lun	  |
265fcf3ce44SJohn Forte  *			+-------------------------+
266fcf3ce44SJohn Forte  *				     |
267fcf3ce44SJohn Forte  *				     |
268fcf3ce44SJohn Forte  *				     v
2696e0414acSReed  *		   Bring offline    /-\	 Bring online
270fcf3ce44SJohn Forte  *		  _ _ _ _ _ _ _ _ _/   \_ _ _ _ _ _ _ _ _ _
271fcf3ce44SJohn Forte  *		 |		   \   /		   |
272fcf3ce44SJohn Forte  *		 |		    \-/			   |
273fcf3ce44SJohn Forte  *		 v					   v
274fcf3ce44SJohn Forte  *    +---------------------+			+-----------------------+
275fcf3ce44SJohn Forte  *    |	 fcp_offline_child  |			|      fcp_get_cip	|
276fcf3ce44SJohn Forte  *    +---------------------+			|			|
277fcf3ce44SJohn Forte  *						| Creates a dev_info_t	|
278fcf3ce44SJohn Forte  *						| or a mdi_pathinfo_t	|
279fcf3ce44SJohn Forte  *						| depending on whether	|
280fcf3ce44SJohn Forte  *						| mpxio is on or off.	|
281fcf3ce44SJohn Forte  *						+-----------------------+
282fcf3ce44SJohn Forte  *							   |
283fcf3ce44SJohn Forte  *							   |
284fcf3ce44SJohn Forte  *							   v
285fcf3ce44SJohn Forte  *						+-----------------------+
286fcf3ce44SJohn Forte  *						|  fcp_online_child	|
287fcf3ce44SJohn Forte  *						|			|
288fcf3ce44SJohn Forte  *						| Set device online	|
2896e0414acSReed  *						| using NDI or MDI.	|
290fcf3ce44SJohn Forte  *						+-----------------------+
291fcf3ce44SJohn Forte  *
292fcf3ce44SJohn Forte  * ............................................................................
293fcf3ce44SJohn Forte  *
2946e0414acSReed  * STEP 5: The watchdog timer expires.	The watch dog timer does much more that
295fcf3ce44SJohn Forte  *	   what is described here.  We only show the target offline path.
296fcf3ce44SJohn Forte  *
297fcf3ce44SJohn Forte  *
298fcf3ce44SJohn Forte  *			 +--------------------------+
299fcf3ce44SJohn Forte  *			 |	  fcp_watch	    |
300fcf3ce44SJohn Forte  *			 +--------------------------+
301fcf3ce44SJohn Forte  *				       |
302fcf3ce44SJohn Forte  *				       |
303fcf3ce44SJohn Forte  *				       v
304fcf3ce44SJohn Forte  *			 +--------------------------+
305fcf3ce44SJohn Forte  *			 |  fcp_scan_offline_tgts   |
306fcf3ce44SJohn Forte  *			 +--------------------------+
307fcf3ce44SJohn Forte  *				       |
308fcf3ce44SJohn Forte  *				       |
309fcf3ce44SJohn Forte  *				       v
310fcf3ce44SJohn Forte  *			 +--------------------------+
311fcf3ce44SJohn Forte  *			 |  fcp_offline_target_now  |
312fcf3ce44SJohn Forte  *			 +--------------------------+
313fcf3ce44SJohn Forte  *				       |
314fcf3ce44SJohn Forte  *				       |
315fcf3ce44SJohn Forte  *				       v
316fcf3ce44SJohn Forte  *			 +--------------------------+
317fcf3ce44SJohn Forte  *			 |   fcp_offline_tgt_luns   |
318fcf3ce44SJohn Forte  *			 +--------------------------+
319fcf3ce44SJohn Forte  *				       |
320fcf3ce44SJohn Forte  *				       |
321fcf3ce44SJohn Forte  *				       v
322fcf3ce44SJohn Forte  *			 +--------------------------+
323fcf3ce44SJohn Forte  *			 |     fcp_offline_lun	    |
324fcf3ce44SJohn Forte  *			 +--------------------------+
325fcf3ce44SJohn Forte  *				       |
326fcf3ce44SJohn Forte  *				       |
327fcf3ce44SJohn Forte  *				       v
328fcf3ce44SJohn Forte  *		     +----------------------------------+
329fcf3ce44SJohn Forte  *		     |	     fcp_offline_lun_now	|
330fcf3ce44SJohn Forte  *		     |					|
331fcf3ce44SJohn Forte  *		     | A request (or two if mpxio) is	|
332fcf3ce44SJohn Forte  *		     | sent to the hot plug task using	|
333fcf3ce44SJohn Forte  *		     | a fcp_hp_elem structure.		|
334fcf3ce44SJohn Forte  *		     +----------------------------------+
335fcf3ce44SJohn Forte  */
336fcf3ce44SJohn Forte 
337fcf3ce44SJohn Forte /*
338fcf3ce44SJohn Forte  * Functions registered with DDI framework
339fcf3ce44SJohn Forte  */
340fcf3ce44SJohn Forte static int fcp_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
341fcf3ce44SJohn Forte static int fcp_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
342fcf3ce44SJohn Forte static int fcp_open(dev_t *devp, int flag, int otype, cred_t *credp);
343fcf3ce44SJohn Forte static int fcp_close(dev_t dev, int flag, int otype, cred_t *credp);
344fcf3ce44SJohn Forte static int fcp_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
345fcf3ce44SJohn Forte     cred_t *credp, int *rval);
346fcf3ce44SJohn Forte 
347fcf3ce44SJohn Forte /*
348fcf3ce44SJohn Forte  * Functions registered with FC Transport framework
349fcf3ce44SJohn Forte  */
350fcf3ce44SJohn Forte static int fcp_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo,
351fcf3ce44SJohn Forte     fc_attach_cmd_t cmd,  uint32_t s_id);
352fcf3ce44SJohn Forte static int fcp_port_detach(opaque_t ulph, fc_ulp_port_info_t *info,
353fcf3ce44SJohn Forte     fc_detach_cmd_t cmd);
354fcf3ce44SJohn Forte static int fcp_port_ioctl(opaque_t ulph, opaque_t port_handle, dev_t dev,
355fcf3ce44SJohn Forte     int cmd, intptr_t data, int mode, cred_t *credp, int *rval,
356fcf3ce44SJohn Forte     uint32_t claimed);
357fcf3ce44SJohn Forte static int fcp_els_callback(opaque_t ulph, opaque_t port_handle,
358fcf3ce44SJohn Forte     fc_unsol_buf_t *buf, uint32_t claimed);
359fcf3ce44SJohn Forte static int fcp_data_callback(opaque_t ulph, opaque_t port_handle,
360fcf3ce44SJohn Forte     fc_unsol_buf_t *buf, uint32_t claimed);
361fcf3ce44SJohn Forte static void fcp_statec_callback(opaque_t ulph, opaque_t port_handle,
362fcf3ce44SJohn Forte     uint32_t port_state, uint32_t port_top, fc_portmap_t *devlist,
363fcf3ce44SJohn Forte     uint32_t  dev_cnt, uint32_t port_sid);
364fcf3ce44SJohn Forte 
365fcf3ce44SJohn Forte /*
366fcf3ce44SJohn Forte  * Functions registered with SCSA framework
367fcf3ce44SJohn Forte  */
368fcf3ce44SJohn Forte static int fcp_phys_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
369fcf3ce44SJohn Forte     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
370fcf3ce44SJohn Forte static int fcp_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
371fcf3ce44SJohn Forte     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
372fcf3ce44SJohn Forte static void fcp_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
373fcf3ce44SJohn Forte     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
374fcf3ce44SJohn Forte static int fcp_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt);
375fcf3ce44SJohn Forte static int fcp_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
376fcf3ce44SJohn Forte static int fcp_scsi_reset(struct scsi_address *ap, int level);
377fcf3ce44SJohn Forte static int fcp_scsi_getcap(struct scsi_address *ap, char *cap, int whom);
378fcf3ce44SJohn Forte static int fcp_scsi_setcap(struct scsi_address *ap, char *cap, int value,
379fcf3ce44SJohn Forte     int whom);
380fcf3ce44SJohn Forte static void fcp_pkt_teardown(struct scsi_pkt *pkt);
381fcf3ce44SJohn Forte static int fcp_scsi_reset_notify(struct scsi_address *ap, int flag,
382fcf3ce44SJohn Forte     void (*callback)(caddr_t), caddr_t arg);
383fcf3ce44SJohn Forte static int fcp_scsi_bus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
384fcf3ce44SJohn Forte     char *name, ddi_eventcookie_t *event_cookiep);
385fcf3ce44SJohn Forte static int fcp_scsi_bus_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
386fcf3ce44SJohn Forte     ddi_eventcookie_t eventid, void (*callback)(), void *arg,
387fcf3ce44SJohn Forte     ddi_callback_id_t *cb_id);
388fcf3ce44SJohn Forte static int fcp_scsi_bus_remove_eventcall(dev_info_t *devi,
389fcf3ce44SJohn Forte     ddi_callback_id_t cb_id);
390fcf3ce44SJohn Forte static int fcp_scsi_bus_post_event(dev_info_t *dip, dev_info_t *rdip,
391fcf3ce44SJohn Forte     ddi_eventcookie_t eventid, void *impldata);
392fcf3ce44SJohn Forte static int fcp_scsi_bus_config(dev_info_t *parent, uint_t flag,
393fcf3ce44SJohn Forte     ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
394fcf3ce44SJohn Forte static int fcp_scsi_bus_unconfig(dev_info_t *parent, uint_t flag,
395fcf3ce44SJohn Forte     ddi_bus_config_op_t op, void *arg);
396fcf3ce44SJohn Forte 
397fcf3ce44SJohn Forte /*
398fcf3ce44SJohn Forte  * Internal functions
399fcf3ce44SJohn Forte  */
400fcf3ce44SJohn Forte static int fcp_setup_device_data_ioctl(int cmd, struct fcp_ioctl *data,
401fcf3ce44SJohn Forte     int mode, int *rval);
402fcf3ce44SJohn Forte 
403fcf3ce44SJohn Forte static int fcp_setup_scsi_ioctl(struct fcp_scsi_cmd *u_fscsi,
404fcf3ce44SJohn Forte     int mode, int *rval);
405fcf3ce44SJohn Forte static int fcp_copyin_scsi_cmd(caddr_t base_addr,
406fcf3ce44SJohn Forte     struct fcp_scsi_cmd *fscsi, int mode);
407fcf3ce44SJohn Forte static int fcp_copyout_scsi_cmd(struct fcp_scsi_cmd *fscsi,
408fcf3ce44SJohn Forte     caddr_t base_addr, int mode);
409fcf3ce44SJohn Forte static int fcp_send_scsi_ioctl(struct fcp_scsi_cmd *fscsi);
410fcf3ce44SJohn Forte 
411fcf3ce44SJohn Forte static struct fcp_tgt *fcp_port_create_tgt(struct fcp_port *pptr,
412fcf3ce44SJohn Forte     la_wwn_t *pwwn, int	*ret_val, int *fc_status, int *fc_pkt_state,
413fcf3ce44SJohn Forte     int *fc_pkt_reason, int *fc_pkt_action);
414fcf3ce44SJohn Forte static int fcp_tgt_send_plogi(struct fcp_tgt *ptgt, int *fc_status,
415fcf3ce44SJohn Forte     int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action);
416fcf3ce44SJohn Forte static int fcp_tgt_send_prli(struct fcp_tgt	*ptgt, int *fc_status,
417fcf3ce44SJohn Forte     int *fc_pkt_state, int *fc_pkt_reason, int *fc_pkt_action);
418fcf3ce44SJohn Forte static void fcp_ipkt_sema_init(struct fcp_ipkt *icmd);
419fcf3ce44SJohn Forte static int fcp_ipkt_sema_wait(struct fcp_ipkt *icmd);
420fcf3ce44SJohn Forte static void fcp_ipkt_sema_callback(struct fc_packet *fpkt);
421fcf3ce44SJohn Forte static void fcp_ipkt_sema_cleanup(struct fcp_ipkt *icmd);
422fcf3ce44SJohn Forte 
423fcf3ce44SJohn Forte static void fcp_handle_devices(struct fcp_port *pptr,
424fcf3ce44SJohn Forte     fc_portmap_t devlist[], uint32_t dev_cnt, int link_cnt,
425fcf3ce44SJohn Forte     fcp_map_tag_t *map_tag, int cause);
426fcf3ce44SJohn Forte static int fcp_handle_mapflags(struct fcp_port *pptr,
427fcf3ce44SJohn Forte     struct fcp_tgt *ptgt, fc_portmap_t *map_entry, int link_cnt,
428fcf3ce44SJohn Forte     int tgt_cnt, int cause);
4291787f503SReed static int fcp_handle_reportlun_changed(struct fcp_tgt *ptgt, int cause);
430fcf3ce44SJohn Forte static int fcp_send_els(struct fcp_port *pptr, struct fcp_tgt *ptgt,
431fcf3ce44SJohn Forte     struct fcp_ipkt *icmd, uchar_t opcode, int lcount, int tcount, int cause);
432fcf3ce44SJohn Forte static void fcp_update_state(struct fcp_port *pptr, uint32_t state,
433fcf3ce44SJohn Forte     int cause);
434fcf3ce44SJohn Forte static void fcp_update_tgt_state(struct fcp_tgt *ptgt, int flag,
435fcf3ce44SJohn Forte     uint32_t state);
436fcf3ce44SJohn Forte static struct fcp_port *fcp_get_port(opaque_t port_handle);
437fcf3ce44SJohn Forte static void fcp_unsol_callback(fc_packet_t *fpkt);
438fcf3ce44SJohn Forte static void fcp_unsol_resp_init(fc_packet_t *pkt, fc_unsol_buf_t *buf,
439fcf3ce44SJohn Forte     uchar_t r_ctl, uchar_t type);
440fcf3ce44SJohn Forte static int fcp_unsol_prli(struct fcp_port *pptr, fc_unsol_buf_t *buf);
441fcf3ce44SJohn Forte static struct fcp_ipkt *fcp_icmd_alloc(struct fcp_port *pptr,
442fcf3ce44SJohn Forte     struct fcp_tgt *ptgt, int cmd_len, int resp_len, int data_len,
443fcf3ce44SJohn Forte     int nodma, int lcount, int tcount, int cause, uint32_t rscn_count);
444fcf3ce44SJohn Forte static void fcp_icmd_free(struct fcp_port *pptr, struct fcp_ipkt *icmd);
445fcf3ce44SJohn Forte static int fcp_alloc_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd,
446fcf3ce44SJohn Forte     int nodma, int flags);
447fcf3ce44SJohn Forte static void fcp_free_dma(struct fcp_port *pptr, struct fcp_ipkt *icmd);
448fcf3ce44SJohn Forte static struct fcp_tgt *fcp_lookup_target(struct fcp_port *pptr,
449fcf3ce44SJohn Forte     uchar_t *wwn);
450fcf3ce44SJohn Forte static struct fcp_tgt *fcp_get_target_by_did(struct fcp_port *pptr,
451fcf3ce44SJohn Forte     uint32_t d_id);
452fcf3ce44SJohn Forte static void fcp_icmd_callback(fc_packet_t *fpkt);
453fcf3ce44SJohn Forte static int fcp_send_scsi(struct fcp_lun *plun, uchar_t opcode,
454fcf3ce44SJohn Forte     int len, int lcount, int tcount, int cause, uint32_t rscn_count);
455fcf3ce44SJohn Forte static int fcp_check_reportlun(struct fcp_rsp *rsp, fc_packet_t *fpkt);
456fcf3ce44SJohn Forte static void fcp_scsi_callback(fc_packet_t *fpkt);
457fcf3ce44SJohn Forte static void fcp_retry_scsi_cmd(fc_packet_t *fpkt);
458fcf3ce44SJohn Forte static void fcp_handle_inquiry(fc_packet_t *fpkt, struct fcp_ipkt *icmd);
459fcf3ce44SJohn Forte static void fcp_handle_reportlun(fc_packet_t *fpkt, struct fcp_ipkt *icmd);
460fcf3ce44SJohn Forte static struct fcp_lun *fcp_get_lun(struct fcp_tgt *ptgt,
461fcf3ce44SJohn Forte     uint16_t lun_num);
462fcf3ce44SJohn Forte static int fcp_finish_tgt(struct fcp_port *pptr, struct fcp_tgt *ptgt,
463fcf3ce44SJohn Forte     int link_cnt, int tgt_cnt, int cause);
464fcf3ce44SJohn Forte static void fcp_finish_init(struct fcp_port *pptr);
465fcf3ce44SJohn Forte static void fcp_create_luns(struct fcp_tgt *ptgt, int link_cnt,
466fcf3ce44SJohn Forte     int tgt_cnt, int cause);
467fcf3ce44SJohn Forte static int fcp_trigger_lun(struct fcp_lun *plun, child_info_t *cip,
468d42c7aecSReed     int old_mpxio, int online, int link_cnt, int tgt_cnt, int flags);
469fcf3ce44SJohn Forte static int fcp_offline_target(struct fcp_port *pptr, struct fcp_tgt *ptgt,
470fcf3ce44SJohn Forte     int link_cnt, int tgt_cnt, int nowait, int flags);
471fcf3ce44SJohn Forte static void fcp_offline_target_now(struct fcp_port *pptr,
472fcf3ce44SJohn Forte     struct fcp_tgt *ptgt, int link_cnt, int tgt_cnt, int flags);
473fcf3ce44SJohn Forte static void fcp_offline_tgt_luns(struct fcp_tgt *ptgt, int link_cnt,
474fcf3ce44SJohn Forte     int tgt_cnt, int flags);
475fcf3ce44SJohn Forte static void fcp_offline_lun(struct fcp_lun *plun, int link_cnt, int tgt_cnt,
476fcf3ce44SJohn Forte     int nowait, int flags);
477fcf3ce44SJohn Forte static void fcp_prepare_offline_lun(struct fcp_lun *plun, int link_cnt,
478fcf3ce44SJohn Forte     int tgt_cnt);
479fcf3ce44SJohn Forte static void fcp_offline_lun_now(struct fcp_lun *plun, int link_cnt,
480fcf3ce44SJohn Forte     int tgt_cnt, int flags);
481fcf3ce44SJohn Forte static void fcp_scan_offline_luns(struct fcp_port *pptr);
482fcf3ce44SJohn Forte static void fcp_scan_offline_tgts(struct fcp_port *pptr);
483fcf3ce44SJohn Forte static void fcp_update_offline_flags(struct fcp_lun *plun);
484fcf3ce44SJohn Forte static struct fcp_pkt *fcp_scan_commands(struct fcp_lun *plun);
485fcf3ce44SJohn Forte static void fcp_abort_commands(struct fcp_pkt *head, struct
486fcf3ce44SJohn Forte     fcp_port *pptr);
487fcf3ce44SJohn Forte static void fcp_cmd_callback(fc_packet_t *fpkt);
488fcf3ce44SJohn Forte static void fcp_complete_pkt(fc_packet_t *fpkt);
489fcf3ce44SJohn Forte static int fcp_validate_fcp_response(struct fcp_rsp *rsp,
490fcf3ce44SJohn Forte     struct fcp_port *pptr);
491fcf3ce44SJohn Forte static int fcp_device_changed(struct fcp_port *pptr, struct fcp_tgt *ptgt,
492fcf3ce44SJohn Forte     fc_portmap_t *map_entry, int link_cnt, int tgt_cnt, int cause);
493fcf3ce44SJohn Forte static struct fcp_lun *fcp_alloc_lun(struct fcp_tgt *ptgt);
494fcf3ce44SJohn Forte static void fcp_dealloc_lun(struct fcp_lun *plun);
495fcf3ce44SJohn Forte static struct fcp_tgt *fcp_alloc_tgt(struct fcp_port *pptr,
496fcf3ce44SJohn Forte     fc_portmap_t *map_entry, int link_cnt);
497fcf3ce44SJohn Forte static void fcp_dealloc_tgt(struct fcp_tgt *ptgt);
498fcf3ce44SJohn Forte static void fcp_queue_ipkt(struct fcp_port *pptr, fc_packet_t *fpkt);
499fcf3ce44SJohn Forte static int fcp_transport(opaque_t port_handle, fc_packet_t *fpkt,
500fcf3ce44SJohn Forte     int internal);
501fcf3ce44SJohn Forte static void fcp_log(int level, dev_info_t *dip, const char *fmt, ...);
502fcf3ce44SJohn Forte static int fcp_handle_port_attach(opaque_t ulph, fc_ulp_port_info_t *pinfo,
503fcf3ce44SJohn Forte     uint32_t s_id, int instance);
504fcf3ce44SJohn Forte static int fcp_handle_port_detach(struct fcp_port *pptr, int flag,
505fcf3ce44SJohn Forte     int instance);
506fcf3ce44SJohn Forte static void fcp_cleanup_port(struct fcp_port *pptr, int instance);
507fcf3ce44SJohn Forte static int fcp_kmem_cache_constructor(struct scsi_pkt *, scsi_hba_tran_t *,
508fcf3ce44SJohn Forte     int);
509fcf3ce44SJohn Forte static void fcp_kmem_cache_destructor(struct  scsi_pkt *, scsi_hba_tran_t *);
510fcf3ce44SJohn Forte static int fcp_pkt_setup(struct scsi_pkt *, int (*)(), caddr_t);
511fcf3ce44SJohn Forte static int fcp_alloc_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt,
512fcf3ce44SJohn Forte     int flags);
513fcf3ce44SJohn Forte static void fcp_free_cmd_resp(struct fcp_port *pptr, fc_packet_t *fpkt);
514fcf3ce44SJohn Forte static int fcp_reset_target(struct scsi_address *ap, int level);
515fcf3ce44SJohn Forte static int fcp_commoncap(struct scsi_address *ap, char *cap,
516fcf3ce44SJohn Forte     int val, int tgtonly, int doset);
517fcf3ce44SJohn Forte static int fcp_scsi_get_name(struct scsi_device *sd, char *name, int len);
518fcf3ce44SJohn Forte static int fcp_scsi_get_bus_addr(struct scsi_device *sd, char *name, int len);
519fcf3ce44SJohn Forte static int fcp_linkreset(struct fcp_port *pptr, struct scsi_address *ap,
520fcf3ce44SJohn Forte     int sleep);
521fcf3ce44SJohn Forte static int fcp_handle_port_resume(opaque_t ulph, fc_ulp_port_info_t *pinfo,
522fcf3ce44SJohn Forte     uint32_t s_id, fc_attach_cmd_t cmd, int instance);
523fcf3ce44SJohn Forte static void fcp_cp_pinfo(struct fcp_port *pptr, fc_ulp_port_info_t *pinfo);
524fcf3ce44SJohn Forte static void fcp_process_elem(struct fcp_hp_elem *elem, int result);
525fcf3ce44SJohn Forte static child_info_t *fcp_get_cip(struct fcp_lun *plun, child_info_t *cip,
526fcf3ce44SJohn Forte     int lcount, int tcount);
527fcf3ce44SJohn Forte static int fcp_is_dip_present(struct fcp_lun *plun, dev_info_t *cdip);
528fcf3ce44SJohn Forte static int fcp_is_child_present(struct fcp_lun *plun, child_info_t *cip);
529fcf3ce44SJohn Forte static dev_info_t *fcp_create_dip(struct fcp_lun *plun, int link_cnt,
530fcf3ce44SJohn Forte     int tgt_cnt);
531fcf3ce44SJohn Forte static dev_info_t *fcp_find_existing_dip(struct fcp_lun *plun,
532fcf3ce44SJohn Forte     dev_info_t *pdip, caddr_t name);
533fcf3ce44SJohn Forte static int fcp_online_child(struct fcp_lun *plun, child_info_t *cip,
534fcf3ce44SJohn Forte     int lcount, int tcount, int flags, int *circ);
535fcf3ce44SJohn Forte static int fcp_offline_child(struct fcp_lun *plun, child_info_t *cip,
536fcf3ce44SJohn Forte     int lcount, int tcount, int flags, int *circ);
537fcf3ce44SJohn Forte static void fcp_remove_child(struct fcp_lun *plun);
538fcf3ce44SJohn Forte static void fcp_watch(void *arg);
539fcf3ce44SJohn Forte static void fcp_check_reset_delay(struct fcp_port *pptr);
540fcf3ce44SJohn Forte static void fcp_abort_all(struct fcp_port *pptr, struct fcp_tgt *ttgt,
541fcf3ce44SJohn Forte     struct fcp_lun *rlun, int tgt_cnt);
542fcf3ce44SJohn Forte struct fcp_port *fcp_soft_state_unlink(struct fcp_port *pptr);
543fcf3ce44SJohn Forte static struct fcp_lun *fcp_lookup_lun(struct fcp_port *pptr,
544fcf3ce44SJohn Forte     uchar_t *wwn, uint16_t lun);
545fcf3ce44SJohn Forte static void fcp_prepare_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd,
546fcf3ce44SJohn Forte     struct fcp_lun *plun);
547fcf3ce44SJohn Forte static void fcp_post_callback(struct fcp_pkt *cmd);
548fcf3ce44SJohn Forte static int fcp_dopoll(struct fcp_port *pptr, struct fcp_pkt *cmd);
549fcf3ce44SJohn Forte static struct fcp_port *fcp_dip2port(dev_info_t *dip);
550fcf3ce44SJohn Forte struct fcp_lun *fcp_get_lun_from_cip(struct fcp_port *pptr,
551fcf3ce44SJohn Forte     child_info_t *cip);
552fcf3ce44SJohn Forte static int fcp_pass_to_hp_and_wait(struct fcp_port *pptr,
553fcf3ce44SJohn Forte     struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt,
554fcf3ce44SJohn Forte     int tgt_cnt, int flags);
555fcf3ce44SJohn Forte static struct fcp_hp_elem *fcp_pass_to_hp(struct fcp_port *pptr,
556fcf3ce44SJohn Forte     struct fcp_lun *plun, child_info_t *cip, int what, int link_cnt,
557fcf3ce44SJohn Forte     int tgt_cnt, int flags, int wait);
558fcf3ce44SJohn Forte static void fcp_retransport_cmd(struct fcp_port *pptr,
559fcf3ce44SJohn Forte     struct fcp_pkt *cmd);
560fcf3ce44SJohn Forte static void fcp_fail_cmd(struct fcp_pkt *cmd, uchar_t reason,
561fcf3ce44SJohn Forte     uint_t statistics);
562fcf3ce44SJohn Forte static void fcp_queue_pkt(struct fcp_port *pptr, struct fcp_pkt *cmd);
563fcf3ce44SJohn Forte static void fcp_update_targets(struct fcp_port *pptr,
564fcf3ce44SJohn Forte     fc_portmap_t *dev_list, uint32_t count, uint32_t state, int cause);
565fcf3ce44SJohn Forte static int fcp_call_finish_init(struct fcp_port *pptr,
566fcf3ce44SJohn Forte     struct fcp_tgt *ptgt, int lcount, int tcount, int cause);
567fcf3ce44SJohn Forte static int fcp_call_finish_init_held(struct fcp_port *pptr,
568fcf3ce44SJohn Forte     struct fcp_tgt *ptgt, int lcount, int tcount, int cause);
569fcf3ce44SJohn Forte static void fcp_reconfigure_luns(void * tgt_handle);
570fcf3ce44SJohn Forte static void fcp_free_targets(struct fcp_port *pptr);
571fcf3ce44SJohn Forte static void fcp_free_target(struct fcp_tgt *ptgt);
572fcf3ce44SJohn Forte static int fcp_is_retryable(struct fcp_ipkt *icmd);
573fcf3ce44SJohn Forte static int fcp_create_on_demand(struct fcp_port *pptr, uchar_t *pwwn);
574fcf3ce44SJohn Forte static void fcp_ascii_to_wwn(caddr_t string, uchar_t bytes[], unsigned int);
575fcf3ce44SJohn Forte static void fcp_wwn_to_ascii(uchar_t bytes[], char *string);
576fcf3ce44SJohn Forte static void fcp_print_error(fc_packet_t *fpkt);
577fcf3ce44SJohn Forte static int fcp_handle_ipkt_errors(struct fcp_port *pptr,
578fcf3ce44SJohn Forte     struct fcp_tgt *ptgt, struct fcp_ipkt *icmd, int rval, caddr_t op);
579fcf3ce44SJohn Forte static int fcp_outstanding_lun_cmds(struct fcp_tgt *ptgt);
580fcf3ce44SJohn Forte static fc_portmap_t *fcp_construct_map(struct fcp_port *pptr,
581fcf3ce44SJohn Forte     uint32_t *dev_cnt);
582fcf3ce44SJohn Forte static void fcp_offline_all(struct fcp_port *pptr, int lcount, int cause);
583fcf3ce44SJohn Forte static int fcp_get_statec_count(struct fcp_ioctl *data, int mode, int *rval);
584fcf3ce44SJohn Forte static int fcp_copyin_fcp_ioctl_data(struct fcp_ioctl *, int, int *,
585fcf3ce44SJohn Forte     struct fcp_ioctl *, struct fcp_port **);
586fcf3ce44SJohn Forte static char *fcp_get_lun_path(struct fcp_lun *plun);
587fcf3ce44SJohn Forte static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode,
588fcf3ce44SJohn Forte     int *rval);
589fcf3ce44SJohn Forte static int fcp_do_ns_registry(struct fcp_port *pptr, uint32_t s_id);
590fcf3ce44SJohn Forte static void fcp_retry_ns_registry(struct fcp_port *pptr, uint32_t s_id);
591fcf3ce44SJohn Forte static char *fcp_get_lun_path(struct fcp_lun *plun);
592fcf3ce44SJohn Forte static int fcp_get_target_mappings(struct fcp_ioctl *data, int mode,
593fcf3ce44SJohn Forte     int *rval);
594fcf3ce44SJohn Forte static void fcp_reconfig_wait(struct fcp_port *pptr);
595fcf3ce44SJohn Forte 
596fcf3ce44SJohn Forte /*
597fcf3ce44SJohn Forte  * New functions added for mpxio support
598fcf3ce44SJohn Forte  */
599fcf3ce44SJohn Forte static int fcp_virt_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
600fcf3ce44SJohn Forte     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
601fcf3ce44SJohn Forte static mdi_pathinfo_t *fcp_create_pip(struct fcp_lun *plun, int lcount,
602fcf3ce44SJohn Forte     int tcount);
603fcf3ce44SJohn Forte static mdi_pathinfo_t *fcp_find_existing_pip(struct fcp_lun *plun,
604fcf3ce44SJohn Forte     dev_info_t *pdip);
605fcf3ce44SJohn Forte static int fcp_is_pip_present(struct fcp_lun *plun, mdi_pathinfo_t *pip);
606fcf3ce44SJohn Forte static void fcp_handle_page83(fc_packet_t *, struct fcp_ipkt *, int);
607fcf3ce44SJohn Forte static void fcp_update_mpxio_path_verifybusy(struct fcp_port *pptr);
608fcf3ce44SJohn Forte static int fcp_copy_guid_2_lun_block(struct fcp_lun *plun, char *guidp);
609fcf3ce44SJohn Forte static int fcp_update_mpxio_path(struct fcp_lun *plun, child_info_t *cip,
610fcf3ce44SJohn Forte     int what);
611fcf3ce44SJohn Forte static int fcp_is_reconfig_needed(struct fcp_tgt *ptgt,
612fcf3ce44SJohn Forte     fc_packet_t *fpkt);
613fcf3ce44SJohn Forte static int fcp_symmetric_device_probe(struct fcp_lun *plun);
614fcf3ce44SJohn Forte 
615fcf3ce44SJohn Forte /*
616fcf3ce44SJohn Forte  * New functions added for lun masking support
617fcf3ce44SJohn Forte  */
618fcf3ce44SJohn Forte static void fcp_read_blacklist(dev_info_t *dip,
619fcf3ce44SJohn Forte     struct fcp_black_list_entry **pplun_blacklist);
620fcf3ce44SJohn Forte static void fcp_mask_pwwn_lun(char *curr_pwwn, char *curr_lun,
621fcf3ce44SJohn Forte     struct fcp_black_list_entry **pplun_blacklist);
622fcf3ce44SJohn Forte static void fcp_add_one_mask(char *curr_pwwn, uint32_t lun_id,
623fcf3ce44SJohn Forte     struct fcp_black_list_entry **pplun_blacklist);
624fcf3ce44SJohn Forte static int fcp_should_mask(la_wwn_t *wwn, uint32_t lun_id);
625fcf3ce44SJohn Forte static void fcp_cleanup_blacklist(struct fcp_black_list_entry **lun_blacklist);
626fcf3ce44SJohn Forte 
6277ff83669SZhong Wang /*
6287ff83669SZhong Wang  * New functions to support software FCA (like fcoei)
6297ff83669SZhong Wang  */
6307ff83669SZhong Wang static struct scsi_pkt *fcp_pseudo_init_pkt(
6317ff83669SZhong Wang 	struct scsi_address *ap, struct scsi_pkt *pkt,
6327ff83669SZhong Wang 	struct buf *bp, int cmdlen, int statuslen,
6337ff83669SZhong Wang 	int tgtlen, int flags, int (*callback)(), caddr_t arg);
6347ff83669SZhong Wang static void fcp_pseudo_destroy_pkt(
6357ff83669SZhong Wang 	struct scsi_address *ap, struct scsi_pkt *pkt);
6367ff83669SZhong Wang static void fcp_pseudo_sync_pkt(
6377ff83669SZhong Wang 	struct scsi_address *ap, struct scsi_pkt *pkt);
6387ff83669SZhong Wang static int fcp_pseudo_start(struct scsi_address *ap, struct scsi_pkt *pkt);
6397ff83669SZhong Wang static void fcp_pseudo_dmafree(
6407ff83669SZhong Wang 	struct scsi_address *ap, struct scsi_pkt *pkt);
6417ff83669SZhong Wang 
6426e0414acSReed extern struct mod_ops	mod_driverops;
643fcf3ce44SJohn Forte /*
644fcf3ce44SJohn Forte  * This variable is defined in modctl.c and set to '1' after the root driver
645fcf3ce44SJohn Forte  * and fs are loaded.  It serves as an indication that the root filesystem can
646fcf3ce44SJohn Forte  * be used.
647fcf3ce44SJohn Forte  */
6486e0414acSReed extern int		modrootloaded;
649fcf3ce44SJohn Forte /*
650fcf3ce44SJohn Forte  * This table contains strings associated with the SCSI sense key codes.  It
651fcf3ce44SJohn Forte  * is used by FCP to print a clear explanation of the code returned in the
652fcf3ce44SJohn Forte  * sense information by a device.
653fcf3ce44SJohn Forte  */
6546e0414acSReed extern char		*sense_keys[];
655fcf3ce44SJohn Forte /*
6566e0414acSReed  * This device is created by the SCSI pseudo nexus driver (SCSI vHCI).	It is
657fcf3ce44SJohn Forte  * under this device that the paths to a physical device are created when
658fcf3ce44SJohn Forte  * MPxIO is used.
659fcf3ce44SJohn Forte  */
660fcf3ce44SJohn Forte extern dev_info_t	*scsi_vhci_dip;
661fcf3ce44SJohn Forte 
662fcf3ce44SJohn Forte /*
663fcf3ce44SJohn Forte  * Report lun processing
664fcf3ce44SJohn Forte  */
665fcf3ce44SJohn Forte #define	FCP_LUN_ADDRESSING		0x80
666fcf3ce44SJohn Forte #define	FCP_PD_ADDRESSING		0x00
667fcf3ce44SJohn Forte #define	FCP_VOLUME_ADDRESSING		0x40
668fcf3ce44SJohn Forte 
669fcf3ce44SJohn Forte #define	FCP_SVE_THROTTLE		0x28 /* Vicom */
670fcf3ce44SJohn Forte #define	MAX_INT_DMA			0x7fffffff
671fcf3ce44SJohn Forte /*
672fcf3ce44SJohn Forte  * Property definitions
673fcf3ce44SJohn Forte  */
674fcf3ce44SJohn Forte #define	NODE_WWN_PROP	(char *)fcp_node_wwn_prop
675fcf3ce44SJohn Forte #define	PORT_WWN_PROP	(char *)fcp_port_wwn_prop
676fcf3ce44SJohn Forte #define	TARGET_PROP	(char *)fcp_target_prop
677fcf3ce44SJohn Forte #define	LUN_PROP	(char *)fcp_lun_prop
678fcf3ce44SJohn Forte #define	SAM_LUN_PROP	(char *)fcp_sam_lun_prop
679fcf3ce44SJohn Forte #define	CONF_WWN_PROP	(char *)fcp_conf_wwn_prop
680fcf3ce44SJohn Forte #define	OBP_BOOT_WWN	(char *)fcp_obp_boot_wwn
681fcf3ce44SJohn Forte #define	MANUAL_CFG_ONLY	(char *)fcp_manual_config_only
6826e0414acSReed #define	INIT_PORT_PROP	(char *)fcp_init_port_prop
6836e0414acSReed #define	TGT_PORT_PROP	(char *)fcp_tgt_port_prop
684fcf3ce44SJohn Forte #define	LUN_BLACKLIST_PROP	(char *)fcp_lun_blacklist_prop
685fcf3ce44SJohn Forte /*
686fcf3ce44SJohn Forte  * Short hand macros.
687fcf3ce44SJohn Forte  */
688fcf3ce44SJohn Forte #define	LUN_PORT	(plun->lun_tgt->tgt_port)
689fcf3ce44SJohn Forte #define	LUN_TGT		(plun->lun_tgt)
690fcf3ce44SJohn Forte 
691fcf3ce44SJohn Forte /*
692fcf3ce44SJohn Forte  * Driver private macros
693fcf3ce44SJohn Forte  */
6946e0414acSReed #define	FCP_ATOB(x)	(((x) >= '0' && (x) <= '9') ? ((x) - '0') :	\
6956e0414acSReed 			((x) >= 'a' && (x) <= 'f') ?			\
696fcf3ce44SJohn Forte 			((x) - 'a' + 10) : ((x) - 'A' + 10))
697fcf3ce44SJohn Forte 
698fcf3ce44SJohn Forte #define	FCP_MAX(a, b)	((a) > (b) ? (a) : (b))
699fcf3ce44SJohn Forte 
7006e0414acSReed #define	FCP_N_NDI_EVENTS						\
701fcf3ce44SJohn Forte 	(sizeof (fcp_ndi_event_defs) / sizeof (ndi_event_definition_t))
702fcf3ce44SJohn Forte 
7036e0414acSReed #define	FCP_LINK_STATE_CHANGED(p, c)			\
704fcf3ce44SJohn Forte 	((p)->port_link_cnt != (c)->ipkt_link_cnt)
705fcf3ce44SJohn Forte 
7066e0414acSReed #define	FCP_TGT_STATE_CHANGED(t, c)			\
707fcf3ce44SJohn Forte 	((t)->tgt_change_cnt != (c)->ipkt_change_cnt)
708fcf3ce44SJohn Forte 
7096e0414acSReed #define	FCP_STATE_CHANGED(p, t, c)		\
710fcf3ce44SJohn Forte 	(FCP_TGT_STATE_CHANGED(t, c))
711fcf3ce44SJohn Forte 
7126e0414acSReed #define	FCP_MUST_RETRY(fpkt)				\
7136e0414acSReed 	((fpkt)->pkt_state == FC_PKT_LOCAL_BSY ||	\
7146e0414acSReed 	(fpkt)->pkt_state == FC_PKT_LOCAL_RJT ||	\
7156e0414acSReed 	(fpkt)->pkt_state == FC_PKT_TRAN_BSY ||	\
7166e0414acSReed 	(fpkt)->pkt_state == FC_PKT_ELS_IN_PROGRESS ||	\
7176e0414acSReed 	(fpkt)->pkt_state == FC_PKT_NPORT_BSY ||	\
7186e0414acSReed 	(fpkt)->pkt_state == FC_PKT_FABRIC_BSY ||	\
7196e0414acSReed 	(fpkt)->pkt_state == FC_PKT_PORT_OFFLINE ||	\
720fcf3ce44SJohn Forte 	(fpkt)->pkt_reason == FC_REASON_OFFLINE)
721fcf3ce44SJohn Forte 
7226e0414acSReed #define	FCP_SENSE_REPORTLUN_CHANGED(es)		\
7236e0414acSReed 	((es)->es_key == KEY_UNIT_ATTENTION &&	\
7246e0414acSReed 	(es)->es_add_code == 0x3f &&		\
725fcf3ce44SJohn Forte 	(es)->es_qual_code == 0x0e)
726fcf3ce44SJohn Forte 
7276e0414acSReed #define	FCP_SENSE_NO_LUN(es)			\
7286e0414acSReed 	((es)->es_key == KEY_ILLEGAL_REQUEST &&	\
7296e0414acSReed 	(es)->es_add_code == 0x25 &&		\
730fcf3ce44SJohn Forte 	(es)->es_qual_code == 0x0)
731fcf3ce44SJohn Forte 
7328acaf345SReed #define	FCP_VERSION		"20091208-1.192"
733fcf3ce44SJohn Forte #define	FCP_NAME_VERSION	"SunFC FCP v" FCP_VERSION
734fcf3ce44SJohn Forte 
7356e0414acSReed #define	FCP_NUM_ELEMENTS(array)			\
7366e0414acSReed 	(sizeof (array) / sizeof ((array)[0]))
737fcf3ce44SJohn Forte 
738fcf3ce44SJohn Forte /*
739fcf3ce44SJohn Forte  * Debugging, Error reporting, and tracing
740fcf3ce44SJohn Forte  */
741fcf3ce44SJohn Forte #define	FCP_LOG_SIZE		1024 * 1024
742fcf3ce44SJohn Forte 
743fcf3ce44SJohn Forte #define	FCP_LEVEL_1		0x00001		/* attach/detach PM CPR */
744fcf3ce44SJohn Forte #define	FCP_LEVEL_2		0x00002		/* failures/Invalid data */
745fcf3ce44SJohn Forte #define	FCP_LEVEL_3		0x00004		/* state change, discovery */
746fcf3ce44SJohn Forte #define	FCP_LEVEL_4		0x00008		/* ULP messages */
747fcf3ce44SJohn Forte #define	FCP_LEVEL_5		0x00010		/* ELS/SCSI cmds */
748fcf3ce44SJohn Forte #define	FCP_LEVEL_6		0x00020		/* Transport failures */
749fcf3ce44SJohn Forte #define	FCP_LEVEL_7		0x00040
750fcf3ce44SJohn Forte #define	FCP_LEVEL_8		0x00080		/* I/O tracing */
751fcf3ce44SJohn Forte #define	FCP_LEVEL_9		0x00100		/* I/O tracing */
752fcf3ce44SJohn Forte 
753fcf3ce44SJohn Forte 
754fcf3ce44SJohn Forte 
755fcf3ce44SJohn Forte /*
756fcf3ce44SJohn Forte  * Log contents to system messages file
757fcf3ce44SJohn Forte  */
758fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_1	(FCP_LEVEL_1 | FC_TRACE_LOG_MSG)
759fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_2	(FCP_LEVEL_2 | FC_TRACE_LOG_MSG)
760fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_3	(FCP_LEVEL_3 | FC_TRACE_LOG_MSG)
761fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_4	(FCP_LEVEL_4 | FC_TRACE_LOG_MSG)
762fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_5	(FCP_LEVEL_5 | FC_TRACE_LOG_MSG)
763fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_6	(FCP_LEVEL_6 | FC_TRACE_LOG_MSG)
764fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_7	(FCP_LEVEL_7 | FC_TRACE_LOG_MSG)
765fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_8	(FCP_LEVEL_8 | FC_TRACE_LOG_MSG)
766fcf3ce44SJohn Forte #define	FCP_MSG_LEVEL_9	(FCP_LEVEL_9 | FC_TRACE_LOG_MSG)
767fcf3ce44SJohn Forte 
768fcf3ce44SJohn Forte 
769fcf3ce44SJohn Forte /*
770fcf3ce44SJohn Forte  * Log contents to trace buffer
771fcf3ce44SJohn Forte  */
772fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_1	(FCP_LEVEL_1 | FC_TRACE_LOG_BUF)
773fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_2	(FCP_LEVEL_2 | FC_TRACE_LOG_BUF)
774fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_3	(FCP_LEVEL_3 | FC_TRACE_LOG_BUF)
775fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_4	(FCP_LEVEL_4 | FC_TRACE_LOG_BUF)
776fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_5	(FCP_LEVEL_5 | FC_TRACE_LOG_BUF)
777fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_6	(FCP_LEVEL_6 | FC_TRACE_LOG_BUF)
778fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_7	(FCP_LEVEL_7 | FC_TRACE_LOG_BUF)
779fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_8	(FCP_LEVEL_8 | FC_TRACE_LOG_BUF)
780fcf3ce44SJohn Forte #define	FCP_BUF_LEVEL_9	(FCP_LEVEL_9 | FC_TRACE_LOG_BUF)
781fcf3ce44SJohn Forte 
782fcf3ce44SJohn Forte 
783fcf3ce44SJohn Forte /*
784fcf3ce44SJohn Forte  * Log contents to both system messages file and trace buffer
785fcf3ce44SJohn Forte  */
7866e0414acSReed #define	FCP_MSG_BUF_LEVEL_1	(FCP_LEVEL_1 | FC_TRACE_LOG_BUF |	\
787fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
7886e0414acSReed #define	FCP_MSG_BUF_LEVEL_2	(FCP_LEVEL_2 | FC_TRACE_LOG_BUF |	\
789fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
7906e0414acSReed #define	FCP_MSG_BUF_LEVEL_3	(FCP_LEVEL_3 | FC_TRACE_LOG_BUF |	\
791fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
7926e0414acSReed #define	FCP_MSG_BUF_LEVEL_4	(FCP_LEVEL_4 | FC_TRACE_LOG_BUF |	\
793fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
7946e0414acSReed #define	FCP_MSG_BUF_LEVEL_5	(FCP_LEVEL_5 | FC_TRACE_LOG_BUF |	\
795fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
7966e0414acSReed #define	FCP_MSG_BUF_LEVEL_6	(FCP_LEVEL_6 | FC_TRACE_LOG_BUF |	\
797fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
7986e0414acSReed #define	FCP_MSG_BUF_LEVEL_7	(FCP_LEVEL_7 | FC_TRACE_LOG_BUF |	\
799fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
8006e0414acSReed #define	FCP_MSG_BUF_LEVEL_8	(FCP_LEVEL_8 | FC_TRACE_LOG_BUF |	\
801fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
8026e0414acSReed #define	FCP_MSG_BUF_LEVEL_9	(FCP_LEVEL_9 | FC_TRACE_LOG_BUF |	\
803fcf3ce44SJohn Forte 				FC_TRACE_LOG_MSG)
804fcf3ce44SJohn Forte #ifdef DEBUG
805fcf3ce44SJohn Forte #define	FCP_DTRACE	fc_trace_debug
806fcf3ce44SJohn Forte #else
807fcf3ce44SJohn Forte #define	FCP_DTRACE
808fcf3ce44SJohn Forte #endif
809fcf3ce44SJohn Forte 
810fcf3ce44SJohn Forte #define	FCP_TRACE	fc_trace_debug
811fcf3ce44SJohn Forte 
812fcf3ce44SJohn Forte static struct cb_ops fcp_cb_ops = {
813fcf3ce44SJohn Forte 	fcp_open,			/* open */
814fcf3ce44SJohn Forte 	fcp_close,			/* close */
815fcf3ce44SJohn Forte 	nodev,				/* strategy */
816fcf3ce44SJohn Forte 	nodev,				/* print */
817fcf3ce44SJohn Forte 	nodev,				/* dump */
818fcf3ce44SJohn Forte 	nodev,				/* read */
819fcf3ce44SJohn Forte 	nodev,				/* write */
820fcf3ce44SJohn Forte 	fcp_ioctl,			/* ioctl */
821fcf3ce44SJohn Forte 	nodev,				/* devmap */
822fcf3ce44SJohn Forte 	nodev,				/* mmap */
823fcf3ce44SJohn Forte 	nodev,				/* segmap */
824fcf3ce44SJohn Forte 	nochpoll,			/* chpoll */
825fcf3ce44SJohn Forte 	ddi_prop_op,			/* cb_prop_op */
826fcf3ce44SJohn Forte 	0,				/* streamtab */
827fcf3ce44SJohn Forte 	D_NEW | D_MP | D_HOTPLUG,	/* cb_flag */
828fcf3ce44SJohn Forte 	CB_REV,				/* rev */
829fcf3ce44SJohn Forte 	nodev,				/* aread */
830fcf3ce44SJohn Forte 	nodev				/* awrite */
831fcf3ce44SJohn Forte };
832fcf3ce44SJohn Forte 
833fcf3ce44SJohn Forte 
834fcf3ce44SJohn Forte static struct dev_ops fcp_ops = {
835fcf3ce44SJohn Forte 	DEVO_REV,
836fcf3ce44SJohn Forte 	0,
837fcf3ce44SJohn Forte 	ddi_getinfo_1to1,
838fcf3ce44SJohn Forte 	nulldev,		/* identify */
839fcf3ce44SJohn Forte 	nulldev,		/* probe */
840fcf3ce44SJohn Forte 	fcp_attach,		/* attach and detach are mandatory */
841fcf3ce44SJohn Forte 	fcp_detach,
842fcf3ce44SJohn Forte 	nodev,			/* reset */
843fcf3ce44SJohn Forte 	&fcp_cb_ops,		/* cb_ops */
844fcf3ce44SJohn Forte 	NULL,			/* bus_ops */
845fcf3ce44SJohn Forte 	NULL,			/* power */
846fcf3ce44SJohn Forte };
847fcf3ce44SJohn Forte 
848fcf3ce44SJohn Forte 
849fcf3ce44SJohn Forte char *fcp_version = FCP_NAME_VERSION;
850fcf3ce44SJohn Forte 
851fcf3ce44SJohn Forte static struct modldrv modldrv = {
852fcf3ce44SJohn Forte 	&mod_driverops,
853fcf3ce44SJohn Forte 	FCP_NAME_VERSION,
854fcf3ce44SJohn Forte 	&fcp_ops
855fcf3ce44SJohn Forte };
856fcf3ce44SJohn Forte 
857fcf3ce44SJohn Forte 
858fcf3ce44SJohn Forte static struct modlinkage modlinkage = {
859fcf3ce44SJohn Forte 	MODREV_1,
860fcf3ce44SJohn Forte 	&modldrv,
861fcf3ce44SJohn Forte 	NULL
862fcf3ce44SJohn Forte };
863fcf3ce44SJohn Forte 
864fcf3ce44SJohn Forte 
865fcf3ce44SJohn Forte static fc_ulp_modinfo_t fcp_modinfo = {
866fcf3ce44SJohn Forte 	&fcp_modinfo,			/* ulp_handle */
867fcf3ce44SJohn Forte 	FCTL_ULP_MODREV_4,		/* ulp_rev */
868fcf3ce44SJohn Forte 	FC4_SCSI_FCP,			/* ulp_type */
869fcf3ce44SJohn Forte 	"fcp",				/* ulp_name */
870fcf3ce44SJohn Forte 	FCP_STATEC_MASK,		/* ulp_statec_mask */
871fcf3ce44SJohn Forte 	fcp_port_attach,		/* ulp_port_attach */
872fcf3ce44SJohn Forte 	fcp_port_detach,		/* ulp_port_detach */
873fcf3ce44SJohn Forte 	fcp_port_ioctl,			/* ulp_port_ioctl */
874fcf3ce44SJohn Forte 	fcp_els_callback,		/* ulp_els_callback */
875fcf3ce44SJohn Forte 	fcp_data_callback,		/* ulp_data_callback */
876fcf3ce44SJohn Forte 	fcp_statec_callback		/* ulp_statec_callback */
877fcf3ce44SJohn Forte };
878fcf3ce44SJohn Forte 
879fcf3ce44SJohn Forte #ifdef	DEBUG
8806e0414acSReed #define	FCP_TRACE_DEFAULT	(FC_TRACE_LOG_MASK | FCP_LEVEL_1 |	\
8816e0414acSReed 				FCP_LEVEL_2 | FCP_LEVEL_3 |		\
8826e0414acSReed 				FCP_LEVEL_4 | FCP_LEVEL_5 |		\
883fcf3ce44SJohn Forte 				FCP_LEVEL_6 | FCP_LEVEL_7)
884fcf3ce44SJohn Forte #else
8856e0414acSReed #define	FCP_TRACE_DEFAULT	(FC_TRACE_LOG_MASK | FCP_LEVEL_1 |	\
8866e0414acSReed 				FCP_LEVEL_2 | FCP_LEVEL_3 |		\
8876e0414acSReed 				FCP_LEVEL_4 | FCP_LEVEL_5 |		\
888fcf3ce44SJohn Forte 				FCP_LEVEL_6 | FCP_LEVEL_7)
889fcf3ce44SJohn Forte #endif
890fcf3ce44SJohn Forte 
891fcf3ce44SJohn Forte /* FCP global variables */
892fcf3ce44SJohn Forte int			fcp_bus_config_debug = 0;
893fcf3ce44SJohn Forte static int		fcp_log_size = FCP_LOG_SIZE;
894fcf3ce44SJohn Forte static int		fcp_trace = FCP_TRACE_DEFAULT;
895fcf3ce44SJohn Forte static fc_trace_logq_t	*fcp_logq = NULL;
896fcf3ce44SJohn Forte static struct fcp_black_list_entry	*fcp_lun_blacklist = NULL;
897fcf3ce44SJohn Forte /*
898fcf3ce44SJohn Forte  * The auto-configuration is set by default.  The only way of disabling it is
899fcf3ce44SJohn Forte  * through the property MANUAL_CFG_ONLY in the fcp.conf file.
900fcf3ce44SJohn Forte  */
901fcf3ce44SJohn Forte static int		fcp_enable_auto_configuration = 1;
902fcf3ce44SJohn Forte static int		fcp_max_bus_config_retries	= 4;
903fcf3ce44SJohn Forte static int		fcp_lun_ready_retry = 300;
904fcf3ce44SJohn Forte /*
905fcf3ce44SJohn Forte  * The value assigned to the following variable has changed several times due
9066e0414acSReed  * to a problem with the data underruns reporting of some firmware(s).	The
907fcf3ce44SJohn Forte  * current value of 50 gives a timeout value of 25 seconds for a max number
908fcf3ce44SJohn Forte  * of 256 LUNs.
909fcf3ce44SJohn Forte  */
910fcf3ce44SJohn Forte static int		fcp_max_target_retries = 50;
911fcf3ce44SJohn Forte /*
912fcf3ce44SJohn Forte  * Watchdog variables
913fcf3ce44SJohn Forte  * ------------------
914fcf3ce44SJohn Forte  *
915fcf3ce44SJohn Forte  * fcp_watchdog_init
916fcf3ce44SJohn Forte  *
917fcf3ce44SJohn Forte  *	Indicates if the watchdog timer is running or not.  This is actually
918fcf3ce44SJohn Forte  *	a counter of the number of Fibre Channel ports that attached.  When
919fcf3ce44SJohn Forte  *	the first port attaches the watchdog is started.  When the last port
920fcf3ce44SJohn Forte  *	detaches the watchdog timer is stopped.
921fcf3ce44SJohn Forte  *
922fcf3ce44SJohn Forte  * fcp_watchdog_time
923fcf3ce44SJohn Forte  *
924fcf3ce44SJohn Forte  *	This is the watchdog clock counter.  It is incremented by
925fcf3ce44SJohn Forte  *	fcp_watchdog_time each time the watchdog timer expires.
926fcf3ce44SJohn Forte  *
927fcf3ce44SJohn Forte  * fcp_watchdog_timeout
928fcf3ce44SJohn Forte  *
929fcf3ce44SJohn Forte  *	Increment value of the variable fcp_watchdog_time as well as the
9306e0414acSReed  *	the timeout value of the watchdog timer.  The unit is 1 second.	 It
9316e0414acSReed  *	is strange that this is not a #define	but a variable since the code
932fcf3ce44SJohn Forte  *	never changes this value.  The reason why it can be said that the
933fcf3ce44SJohn Forte  *	unit is 1 second is because the number of ticks for the watchdog
934fcf3ce44SJohn Forte  *	timer is determined like this:
935fcf3ce44SJohn Forte  *
936fcf3ce44SJohn Forte  *	    fcp_watchdog_tick = fcp_watchdog_timeout *
937fcf3ce44SJohn Forte  *				  drv_usectohz(1000000);
938fcf3ce44SJohn Forte  *
939fcf3ce44SJohn Forte  *	The value 1000000 is hard coded in the code.
940fcf3ce44SJohn Forte  *
941fcf3ce44SJohn Forte  * fcp_watchdog_tick
942fcf3ce44SJohn Forte  *
943fcf3ce44SJohn Forte  *	Watchdog timer value in ticks.
944fcf3ce44SJohn Forte  */
945fcf3ce44SJohn Forte static int		fcp_watchdog_init = 0;
946fcf3ce44SJohn Forte static int		fcp_watchdog_time = 0;
947fcf3ce44SJohn Forte static int		fcp_watchdog_timeout = 1;
948fcf3ce44SJohn Forte static int		fcp_watchdog_tick;
949fcf3ce44SJohn Forte 
950fcf3ce44SJohn Forte /*
951fcf3ce44SJohn Forte  * fcp_offline_delay is a global variable to enable customisation of
952fcf3ce44SJohn Forte  * the timeout on link offlines or RSCNs. The default value is set
953fcf3ce44SJohn Forte  * to match FCP_OFFLINE_DELAY (20sec), which is 2*RA_TOV_els as
954fcf3ce44SJohn Forte  * specified in FCP4 Chapter 11 (see www.t10.org).
955fcf3ce44SJohn Forte  *
956fcf3ce44SJohn Forte  * The variable fcp_offline_delay is specified in SECONDS.
957fcf3ce44SJohn Forte  *
958fcf3ce44SJohn Forte  * If we made this a static var then the user would not be able to
959fcf3ce44SJohn Forte  * change it. This variable is set in fcp_attach().
960fcf3ce44SJohn Forte  */
961fcf3ce44SJohn Forte unsigned int		fcp_offline_delay = FCP_OFFLINE_DELAY;
962fcf3ce44SJohn Forte 
963fcf3ce44SJohn Forte static void		*fcp_softstate = NULL; /* for soft state */
964fcf3ce44SJohn Forte static uchar_t		fcp_oflag = FCP_IDLE; /* open flag */
965fcf3ce44SJohn Forte static kmutex_t		fcp_global_mutex;
966fcf3ce44SJohn Forte static kmutex_t		fcp_ioctl_mutex;
967fcf3ce44SJohn Forte static dev_info_t	*fcp_global_dip = NULL;
968fcf3ce44SJohn Forte static timeout_id_t	fcp_watchdog_id;
969fcf3ce44SJohn Forte const char		*fcp_lun_prop = "lun";
970fcf3ce44SJohn Forte const char		*fcp_sam_lun_prop = "sam-lun";
971fcf3ce44SJohn Forte const char		*fcp_target_prop = "target";
972fcf3ce44SJohn Forte /*
973fcf3ce44SJohn Forte  * NOTE: consumers of "node-wwn" property include stmsboot in ON
974fcf3ce44SJohn Forte  * consolidation.
975fcf3ce44SJohn Forte  */
976fcf3ce44SJohn Forte const char		*fcp_node_wwn_prop = "node-wwn";
977fcf3ce44SJohn Forte const char		*fcp_port_wwn_prop = "port-wwn";
978fcf3ce44SJohn Forte const char		*fcp_conf_wwn_prop = "fc-port-wwn";
979fcf3ce44SJohn Forte const char		*fcp_obp_boot_wwn = "fc-boot-dev-portwwn";
980fcf3ce44SJohn Forte const char		*fcp_manual_config_only = "manual_configuration_only";
981fcf3ce44SJohn Forte const char		*fcp_init_port_prop = "initiator-port";
982fcf3ce44SJohn Forte const char		*fcp_tgt_port_prop = "target-port";
983fcf3ce44SJohn Forte const char		*fcp_lun_blacklist_prop = "pwwn-lun-blacklist";
984fcf3ce44SJohn Forte 
9856e0414acSReed static struct fcp_port	*fcp_port_head = NULL;
986fcf3ce44SJohn Forte static ddi_eventcookie_t	fcp_insert_eid;
987fcf3ce44SJohn Forte static ddi_eventcookie_t	fcp_remove_eid;
988fcf3ce44SJohn Forte 
9896e0414acSReed static ndi_event_definition_t	fcp_ndi_event_defs[] = {
992fcf3ce44SJohn Forte };
993fcf3ce44SJohn Forte 
994fcf3ce44SJohn Forte /*
995fcf3ce44SJohn Forte  * List of valid commands for the scsi_ioctl call
996fcf3ce44SJohn Forte  */
997fcf3ce44SJohn Forte static uint8_t scsi_ioctl_list[] = {
998fcf3ce44SJohn Forte 	SCMD_INQUIRY,
999fcf3ce44SJohn Forte 	SCMD_REPORT_LUN,
1000fcf3ce44SJohn Forte 	SCMD_READ_CAPACITY
1001fcf3ce44SJohn Forte };
1002fcf3ce44SJohn Forte 
1003fcf3ce44SJohn Forte /*
1004fcf3ce44SJohn Forte  * this is used to dummy up a report lun response for cases
1005fcf3ce44SJohn Forte  * where the target doesn't support it
1006fcf3ce44SJohn Forte  */
1007fcf3ce44SJohn Forte static uchar_t fcp_dummy_lun[] = {
1008fcf3ce44SJohn Forte 	0x00,		/* MSB length (length = no of luns * 8) */
1009fcf3ce44SJohn Forte 	0x00,
1010fcf3ce44SJohn Forte 	0x00,
1011fcf3ce44SJohn Forte 	0x08,		/* LSB length */
1012fcf3ce44SJohn Forte 	0x00,		/* MSB reserved */
1013fcf3ce44SJohn Forte 	0x00,
1014fcf3ce44SJohn Forte 	0x00,
1015fcf3ce44SJohn Forte 	0x00,		/* LSB reserved */
1016fcf3ce44SJohn Forte 	FCP_PD_ADDRESSING,
1017fcf3ce44SJohn Forte 	0x00,		/* LUN is ZERO at the first level */
1018fcf3ce44SJohn Forte 	0x00,
1019fcf3ce44SJohn Forte 	0x00,		/* second level is zero */
1020fcf3ce44SJohn Forte 	0x00,
1021fcf3ce44SJohn Forte 	0x00,		/* third level is zero */
1022fcf3ce44SJohn Forte 	0x00,
1023fcf3ce44SJohn Forte 	0x00		/* fourth level is zero */
1024fcf3ce44SJohn Forte };
1025fcf3ce44SJohn Forte 
1026fcf3ce44SJohn Forte static uchar_t fcp_alpa_to_switch[] = {
1027fcf3ce44SJohn Forte 	0x00, 0x7d, 0x7c, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x7a, 0x00,
1028fcf3ce44SJohn Forte 	0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x78, 0x00, 0x00, 0x00,
1029fcf3ce44SJohn Forte 	0x00, 0x00, 0x00, 0x77, 0x76, 0x00, 0x00, 0x75, 0x00, 0x74,
1030fcf3ce44SJohn Forte 	0x73, 0x72, 0x00, 0x00, 0x00, 0x71, 0x00, 0x70, 0x6f, 0x6e,
1031fcf3ce44SJohn Forte 	0x00, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x00, 0x00, 0x67,
1032fcf3ce44SJohn Forte 	0x66, 0x65, 0x64, 0x63, 0x62, 0x00, 0x00, 0x61, 0x60, 0x00,
1033fcf3ce44SJohn Forte 	0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x5d,
1034fcf3ce44SJohn Forte 	0x5c, 0x5b, 0x00, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x00,
1035fcf3ce44SJohn Forte 	0x00, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x00, 0x00, 0x4e,
1036fcf3ce44SJohn Forte 	0x4d, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
1037fcf3ce44SJohn Forte 	0x00, 0x4a, 0x49, 0x48, 0x00, 0x47, 0x46, 0x45, 0x44, 0x43,
1038fcf3ce44SJohn Forte 	0x42, 0x00, 0x00, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x00,
1039fcf3ce44SJohn Forte 	0x00, 0x3b, 0x3a, 0x00, 0x39, 0x00, 0x00, 0x00, 0x38, 0x37,
1040fcf3ce44SJohn Forte 	0x36, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
1041fcf3ce44SJohn Forte 	0x00, 0x00, 0x00, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
1042fcf3ce44SJohn Forte 	0x00, 0x31, 0x30, 0x00, 0x00, 0x2f, 0x00, 0x2e, 0x2d, 0x2c,
1043fcf3ce44SJohn Forte 	0x00, 0x00, 0x00, 0x2b, 0x00, 0x2a, 0x29, 0x28, 0x00, 0x27,
1044fcf3ce44SJohn Forte 	0x26, 0x25, 0x24, 0x23, 0x22, 0x00, 0x00, 0x21, 0x20, 0x1f,
1045fcf3ce44SJohn Forte 	0x1e, 0x1d, 0x1c, 0x00, 0x00, 0x1b, 0x1a, 0x00, 0x19, 0x00,
1046fcf3ce44SJohn Forte 	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x17, 0x16, 0x15,
1047fcf3ce44SJohn Forte 	0x00, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x00, 0x00, 0x0e,
1048fcf3ce44SJohn Forte 	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x00, 0x00, 0x08, 0x07, 0x00,
1049fcf3ce44SJohn Forte 	0x06, 0x00, 0x00, 0x00, 0x05, 0x04, 0x03, 0x00, 0x02, 0x00,
1050fcf3ce44SJohn Forte 	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1051fcf3ce44SJohn Forte };
1052fcf3ce44SJohn Forte 
10536e0414acSReed static caddr_t pid = "SESS01	      ";
1054fcf3ce44SJohn Forte 
1055fcf3ce44SJohn Forte #if	!defined(lint)
1056fcf3ce44SJohn Forte 
1057fcf3ce44SJohn Forte _NOTE(MUTEX_PROTECTS_DATA(fcp_global_mutex,