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
9  * http://www.opensource.org/licenses/cddl1.txt.
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 /*
23  * Copyright (c) 2004-2012 Emulex. All rights reserved.
24  * Use is subject to license terms.
25  * Copyright 2020 RackTop Systems, Inc.
26  */
27 
28 #define	DEF_ICFG	1
29 
30 #include <emlxs.h>
31 #include <emlxs_version.h>
32 
33 
34 static char emlxs_copyright[] = EMLXS_COPYRIGHT;
35 char emlxs_revision[] = EMLXS_REVISION;
36 char emlxs_version[] = EMLXS_VERSION;
37 char emlxs_name[] = EMLXS_NAME;
38 char emlxs_label[] = EMLXS_LABEL;
39 
40 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
41 EMLXS_MSG_DEF(EMLXS_SOLARIS_C);
42 
43 #ifdef MENLO_SUPPORT
44 static int32_t  emlxs_send_menlo(emlxs_port_t *port, emlxs_buf_t *sbp);
45 #endif /* MENLO_SUPPORT */
46 
47 static void	emlxs_fca_attach(emlxs_hba_t *hba);
48 static void	emlxs_fca_detach(emlxs_hba_t *hba);
49 static void	emlxs_drv_banner(emlxs_hba_t *hba);
50 
51 static int32_t	emlxs_get_props(emlxs_hba_t *hba);
52 static int32_t	emlxs_send_fcp_cmd(emlxs_port_t *port, emlxs_buf_t *sbp,
53 		    uint32_t *pkt_flags);
54 static int32_t	emlxs_send_fct_status(emlxs_port_t *port, emlxs_buf_t *sbp);
55 static int32_t	emlxs_send_fct_abort(emlxs_port_t *port, emlxs_buf_t *sbp);
56 static int32_t	emlxs_send_ip(emlxs_port_t *port, emlxs_buf_t *sbp);
57 static int32_t	emlxs_send_els(emlxs_port_t *port, emlxs_buf_t *sbp);
58 static int32_t	emlxs_send_els_rsp(emlxs_port_t *port, emlxs_buf_t *sbp);
59 static int32_t	emlxs_send_ct(emlxs_port_t *port, emlxs_buf_t *sbp);
60 static int32_t	emlxs_send_ct_rsp(emlxs_port_t *port, emlxs_buf_t *sbp);
61 static uint32_t emlxs_add_instance(int32_t ddiinst);
62 static void	emlxs_iodone(emlxs_buf_t *sbp);
63 static int	emlxs_pm_lower_power(dev_info_t *dip);
64 static int	emlxs_pm_raise_power(dev_info_t *dip);
65 static void	emlxs_driver_remove(dev_info_t *dip, uint32_t init_flag,
66 		    uint32_t failed);
67 static void	emlxs_iodone_server(void *arg1, void *arg2, void *arg3);
68 static uint32_t	emlxs_integrity_check(emlxs_hba_t *hba);
69 static uint32_t	emlxs_test(emlxs_hba_t *hba, uint32_t test_code,
70 		    uint32_t args, uint32_t *arg);
71 
72 #if (EMLXS_MODREV >= EMLXS_MODREV3) && (EMLXS_MODREV <= EMLXS_MODREV4)
73 static void	emlxs_read_vport_prop(emlxs_hba_t *hba);
74 #endif	/* EMLXS_MODREV3 && EMLXS_MODREV4 */
75 
76 static void	emlxs_mode_init_masks(emlxs_hba_t *hba);
77 
78 
79 extern int
80 emlxs_msiid_to_chan(emlxs_hba_t *hba, int msi_id);
81 extern int
82 emlxs_select_msiid(emlxs_hba_t *hba);
83 extern void
84 emlxs_sli4_zero_queue_stat(emlxs_hba_t *hba);
85 
86 /*
87  * Driver Entry Routines.
88  */
89 static int32_t	emlxs_detach(dev_info_t *, ddi_detach_cmd_t);
90 static int32_t	emlxs_attach(dev_info_t *, ddi_attach_cmd_t);
91 static int32_t	emlxs_open(dev_t *, int32_t, int32_t, cred_t *);
92 static int32_t	emlxs_close(dev_t, int32_t, int32_t, cred_t *);
93 static int32_t	emlxs_ioctl(dev_t, int32_t, intptr_t, int32_t,
94 		    cred_t *, int32_t *);
95 static int32_t	emlxs_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
96 
97 
98 /*
99  * FC_AL Transport Functions.
100  */
101 static opaque_t	emlxs_fca_bind_port(dev_info_t *, fc_fca_port_info_t *,
102 		    fc_fca_bind_info_t *);
103 static void	emlxs_fca_unbind_port(opaque_t);
104 static void	emlxs_initialize_pkt(emlxs_port_t *, emlxs_buf_t *);
105 static int32_t	emlxs_fca_get_cap(opaque_t, char *, void *);
106 static int32_t	emlxs_fca_set_cap(opaque_t, char *, void *);
107 static int32_t	emlxs_fca_get_map(opaque_t, fc_lilpmap_t *);
108 static int32_t	emlxs_fca_ub_alloc(opaque_t, uint64_t *, uint32_t,
109 		    uint32_t *, uint32_t);
110 static int32_t	emlxs_fca_ub_free(opaque_t, uint32_t, uint64_t *);
111 
112 static opaque_t	emlxs_fca_get_device(opaque_t, fc_portid_t);
113 static int32_t	emlxs_fca_notify(opaque_t, uint32_t);
114 static void	emlxs_ub_els_reject(emlxs_port_t *, fc_unsol_buf_t *);
115 
116 /*
117  * Driver Internal Functions.
118  */
119 
120 static void	emlxs_poll(emlxs_port_t *, emlxs_buf_t *);
121 static int32_t	emlxs_power(dev_info_t *, int32_t, int32_t);
122 #ifdef EMLXS_I386
123 #ifdef S11
124 static int32_t	emlxs_quiesce(dev_info_t *);
125 #endif /* S11 */
126 #endif /* EMLXS_I386 */
127 static int32_t	emlxs_hba_resume(dev_info_t *);
128 static int32_t	emlxs_hba_suspend(dev_info_t *);
129 static int32_t	emlxs_hba_detach(dev_info_t *);
130 static int32_t	emlxs_hba_attach(dev_info_t *);
131 static void	emlxs_lock_destroy(emlxs_hba_t *);
132 static void	emlxs_lock_init(emlxs_hba_t *);
133 
134 char *emlxs_pm_components[] = {
135 	"NAME=" DRIVER_NAME "000",
136 	"0=Device D3 State",
137 	"1=Device D0 State"
138 };
139 
140 
141 /*
142  * Default emlx dma limits
143  */
144 ddi_dma_lim_t emlxs_dma_lim = {
145 	(uint32_t)0,				/* dlim_addr_lo */
146 	(uint32_t)0xffffffff,			/* dlim_addr_hi */
147 	(uint_t)0x00ffffff,			/* dlim_cntr_max */
148 	DEFAULT_BURSTSIZE | BURST32 | BURST64,	/* dlim_burstsizes */
149 	1,					/* dlim_minxfer */
150 	0x00ffffff				/* dlim_dmaspeed */
151 };
152 
153 /*
154  * Be careful when using these attributes; the defaults listed below are
155  * (almost) the most general case, permitting allocation in almost any
156  * way supported by the LightPulse family.  The sole exception is the
157  * alignment specified as requiring memory allocation on a 4-byte boundary;
158  * the Lightpulse can DMA memory on any byte boundary.
159  *
160  * The LightPulse family currently is limited to 16M transfers;
161  * this restriction affects the dma_attr_count_max and dma_attr_maxxfer fields.
162  */
163 ddi_dma_attr_t emlxs_dma_attr = {
164 	DMA_ATTR_V0,				/* dma_attr_version */
165 	(uint64_t)0,				/* dma_attr_addr_lo */
166 	(uint64_t)0xffffffffffffffff,		/* dma_attr_addr_hi */
167 	(uint64_t)0x00ffffff,			/* dma_attr_count_max */
168 	1,					/* dma_attr_align */
169 	DEFAULT_BURSTSIZE | BURST32 | BURST64,	/* dma_attr_burstsizes */
170 	1,					/* dma_attr_minxfer */
171 	(uint64_t)0x00ffffff,			/* dma_attr_maxxfer */
172 	(uint64_t)0xffffffff,			/* dma_attr_seg */
173 	1,					/* dma_attr_sgllen */
174 	1,					/* dma_attr_granular */
175 	0					/* dma_attr_flags */
176 };
177 
178 ddi_dma_attr_t emlxs_dma_attr_ro = {
179 	DMA_ATTR_V0,				/* dma_attr_version */
180 	(uint64_t)0,				/* dma_attr_addr_lo */
181 	(uint64_t)0xffffffffffffffff,		/* dma_attr_addr_hi */
182 	(uint64_t)0x00ffffff,			/* dma_attr_count_max */
183 	1,					/* dma_attr_align */
184 	DEFAULT_BURSTSIZE | BURST32 | BURST64,	/* dma_attr_burstsizes */
185 	1,					/* dma_attr_minxfer */
186 	(uint64_t)0x00ffffff,			/* dma_attr_maxxfer */
187 	(uint64_t)0xffffffff,			/* dma_attr_seg */
188 	1,					/* dma_attr_sgllen */
189 	1,					/* dma_attr_granular */
190 	DDI_DMA_RELAXED_ORDERING		/* dma_attr_flags */
191 };
192 
193 ddi_dma_attr_t emlxs_dma_attr_1sg = {
194 	DMA_ATTR_V0,				/* dma_attr_version */
195 	(uint64_t)0,				/* dma_attr_addr_lo */
196 	(uint64_t)0xffffffffffffffff,		/* dma_attr_addr_hi */
197 	(uint64_t)0x00ffffff,			/* dma_attr_count_max */
198 	1,					/* dma_attr_align */
199 	DEFAULT_BURSTSIZE | BURST32 | BURST64,	/* dma_attr_burstsizes */
200 	1,					/* dma_attr_minxfer */
201 	(uint64_t)0x00ffffff,			/* dma_attr_maxxfer */
202 	(uint64_t)0xffffffff,			/* dma_attr_seg */
203 	1,					/* dma_attr_sgllen */
204 	1,					/* dma_attr_granular */
205 	0					/* dma_attr_flags */
206 };
207 
208 #if (EMLXS_MODREV >= EMLXS_MODREV3)
209 ddi_dma_attr_t emlxs_dma_attr_fcip_rsp = {
210 	DMA_ATTR_V0,				/* dma_attr_version */
211 	(uint64_t)0,				/* dma_attr_addr_lo */
212 	(uint64_t)0xffffffffffffffff,		/* dma_attr_addr_hi */
213 	(uint64_t)0x00ffffff,			/* dma_attr_count_max */
214 	1,					/* dma_attr_align */
215 	DEFAULT_BURSTSIZE | BURST32 | BURST64,	/* dma_attr_burstsizes */
216 	1,					/* dma_attr_minxfer */
217 	(uint64_t)0x00ffffff,			/* dma_attr_maxxfer */
218 	(uint64_t)0xffffffff,			/* dma_attr_seg */
219 	1,					/* dma_attr_sgllen */
220 	1,					/* dma_attr_granular */
221 	0					/* dma_attr_flags */
222 };
223 #endif	/* >= EMLXS_MODREV3 */
224 
225 /*
226  * DDI access attributes for device
227  */
228 ddi_device_acc_attr_t emlxs_dev_acc_attr = {
229 	DDI_DEVICE_ATTR_V1,	/* devacc_attr_version		*/
230 	DDI_STRUCTURE_LE_ACC,	/* PCI is Little Endian		*/
231 	DDI_STRICTORDER_ACC,	/* devacc_attr_dataorder	*/
232 	DDI_DEFAULT_ACC		/* devacc_attr_access		*/
233 };
234 
235 /*
236  * DDI access attributes for data
237  */
238 ddi_device_acc_attr_t emlxs_data_acc_attr = {
239 	DDI_DEVICE_ATTR_V1,	/* devacc_attr_version		*/
240 	DDI_NEVERSWAP_ACC,	/* don't swap for Data		*/
241 	DDI_STRICTORDER_ACC,	/* devacc_attr_dataorder	*/
242 	DDI_DEFAULT_ACC		/* devacc_attr_access		*/
243 };
244 
245 /*
246  * Fill in the FC Transport structure,
247  * as defined in the Fibre Channel Transport Programmming Guide.
248  */
249 #if (EMLXS_MODREV == EMLXS_MODREV5)
250 	static fc_fca_tran_t emlxs_fca_tran = {
251 	FCTL_FCA_MODREV_5,		/* fca_version, with SUN NPIV support */
252 	MAX_VPORTS,			/* fca numerb of ports */
253 	sizeof (emlxs_buf_t),		/* fca pkt size */
254 	2048,				/* fca cmd max */
255 	&emlxs_dma_lim,			/* fca dma limits */
256 	0,				/* fca iblock, to be filled in later */
257 	&emlxs_dma_attr,		/* fca dma attributes */
258 	&emlxs_dma_attr_1sg,		/* fca dma fcp cmd attributes */
259 	&emlxs_dma_attr_1sg,		/* fca dma fcp rsp attributes */
260 	&emlxs_dma_attr_ro,		/* fca dma fcp data attributes */
261 	&emlxs_dma_attr_1sg,		/* fca dma fcip cmd attributes */
262 	&emlxs_dma_attr_fcip_rsp,	/* fca dma fcip rsp attributes */
263 	&emlxs_dma_attr_1sg,		/* fca dma fcsm cmd attributes */
264 	&emlxs_dma_attr,		/* fca dma fcsm rsp attributes */
265 	&emlxs_data_acc_attr,		/* fca access atributes */
266 	0,				/* fca_num_npivports */
267 	{0, 0, 0, 0, 0, 0, 0, 0},	/* Physical port WWPN */
268 	emlxs_fca_bind_port,
269 	emlxs_fca_unbind_port,
270 	emlxs_fca_pkt_init,
271 	emlxs_fca_pkt_uninit,
272 	emlxs_fca_transport,
273 	emlxs_fca_get_cap,
274 	emlxs_fca_set_cap,
275 	emlxs_fca_get_map,
276 	emlxs_fca_transport,
277 	emlxs_fca_ub_alloc,
278 	emlxs_fca_ub_free,
279 	emlxs_fca_ub_release,
280 	emlxs_fca_pkt_abort,
281 	emlxs_fca_reset,
282 	emlxs_fca_port_manage,
283 	emlxs_fca_get_device,
284 	emlxs_fca_notify
285 };
286 #endif	/* EMLXS_MODREV5 */
287 
288 
289 #if (EMLXS_MODREV == EMLXS_MODREV4)
290 static fc_fca_tran_t emlxs_fca_tran = {
291 	FCTL_FCA_MODREV_4,		/* fca_version */
292 	MAX_VPORTS,			/* fca numerb of ports */
293 	sizeof (emlxs_buf_t),		/* fca pkt size */
294 	2048,				/* fca cmd max */
295 	&emlxs_dma_lim,			/* fca dma limits */
296 	0,				/* fca iblock, to be filled in later */
297 	&emlxs_dma_attr,		/* fca dma attributes */
298 	&emlxs_dma_attr_1sg,		/* fca dma fcp cmd attributes */
299 	&emlxs_dma_attr_1sg,		/* fca dma fcp rsp attributes */
300 	&emlxs_dma_attr_ro,		/* fca dma fcp data attributes */
301 	&emlxs_dma_attr_1sg,		/* fca dma fcip cmd attributes */
302 	&emlxs_dma_attr_fcip_rsp,	/* fca dma fcip rsp attributes */
303 	&emlxs_dma_attr_1sg,		/* fca dma fcsm cmd attributes */
304 	&emlxs_dma_attr,		/* fca dma fcsm rsp attributes */
305 	&emlxs_data_acc_attr,		/* fca access atributes */
306 	emlxs_fca_bind_port,
307 	emlxs_fca_unbind_port,
308 	emlxs_fca_pkt_init,
309 	emlxs_fca_pkt_uninit,
310 	emlxs_fca_transport,
311 	emlxs_fca_get_cap,
312 	emlxs_fca_set_cap,
313 	emlxs_fca_get_map,
314 	emlxs_fca_transport,
315 	emlxs_fca_ub_alloc,
316 	emlxs_fca_ub_free,
317 	emlxs_fca_ub_release,
318 	emlxs_fca_pkt_abort,
319 	emlxs_fca_reset,
320 	emlxs_fca_port_manage,
321 	emlxs_fca_get_device,
322 	emlxs_fca_notify
323 };
324 #endif	/* EMLXS_MODEREV4 */
325 
326 
327 #if (EMLXS_MODREV == EMLXS_MODREV3)
328 static fc_fca_tran_t emlxs_fca_tran = {
329 	FCTL_FCA_MODREV_3,		/* fca_version */
330 	MAX_VPORTS,			/* fca numerb of ports */
331 	sizeof (emlxs_buf_t),		/* fca pkt size */
332 	2048,				/* fca cmd max */
333 	&emlxs_dma_lim,			/* fca dma limits */
334 	0,				/* fca iblock, to be filled in later */
335 	&emlxs_dma_attr,		/* fca dma attributes */
336 	&emlxs_dma_attr_1sg,		/* fca dma fcp cmd attributes */
337 	&emlxs_dma_attr_1sg,		/* fca dma fcp rsp attributes */
338 	&emlxs_dma_attr_ro,		/* fca dma fcp data attributes */
339 	&emlxs_dma_attr_1sg,		/* fca dma fcip cmd attributes */
340 	&emlxs_dma_attr_fcip_rsp,	/* fca dma fcip rsp attributes */
341 	&emlxs_dma_attr_1sg,		/* fca dma fcsm cmd attributes */
342 	&emlxs_dma_attr,		/* fca dma fcsm rsp attributes */
343 	&emlxs_data_acc_attr,		/* fca access atributes */
344 	emlxs_fca_bind_port,
345 	emlxs_fca_unbind_port,
346 	emlxs_fca_pkt_init,
347 	emlxs_fca_pkt_uninit,
348 	emlxs_fca_transport,
349 	emlxs_fca_get_cap,
350 	emlxs_fca_set_cap,
351 	emlxs_fca_get_map,
352 	emlxs_fca_transport,
353 	emlxs_fca_ub_alloc,
354 	emlxs_fca_ub_free,
355 	emlxs_fca_ub_release,
356 	emlxs_fca_pkt_abort,
357 	emlxs_fca_reset,
358 	emlxs_fca_port_manage,
359 	emlxs_fca_get_device,
360 	emlxs_fca_notify
361 };
362 #endif	/* EMLXS_MODREV3 */
363 
364 
365 #if (EMLXS_MODREV == EMLXS_MODREV2)
366 static fc_fca_tran_t emlxs_fca_tran = {
367 	FCTL_FCA_MODREV_2,		/* fca_version */
368 	MAX_VPORTS,			/* number of ports */
369 	sizeof (emlxs_buf_t),		/* pkt size */
370 	2048,				/* max cmds */
371 	&emlxs_dma_lim,			/* DMA limits */
372 	0,				/* iblock, to be filled in later */
373 	&emlxs_dma_attr,		/* dma attributes */
374 	&emlxs_data_acc_attr,		/* access atributes */
375 	emlxs_fca_bind_port,
376 	emlxs_fca_unbind_port,
377 	emlxs_fca_pkt_init,
378 	emlxs_fca_pkt_uninit,
379 	emlxs_fca_transport,
380 	emlxs_fca_get_cap,
381 	emlxs_fca_set_cap,
382 	emlxs_fca_get_map,
383 	emlxs_fca_transport,
384 	emlxs_fca_ub_alloc,
385 	emlxs_fca_ub_free,
386 	emlxs_fca_ub_release,
387 	emlxs_fca_pkt_abort,
388 	emlxs_fca_reset,
389 	emlxs_fca_port_manage,
390 	emlxs_fca_get_device,
391 	emlxs_fca_notify
392 };
393 #endif	/* EMLXS_MODREV2 */
394 
395 
396 /*
397  * state pointer which the implementation uses as a place to
398  * hang a set of per-driver structures;
399  *
400  */
401 void		*emlxs_soft_state = NULL;
402 
403 /*
404  * Driver Global variables.
405  */
406 int32_t		emlxs_scsi_reset_delay = 3000;	/* milliseconds */
407 
408 emlxs_device_t  emlxs_device;
409 
410 uint32_t	emlxs_instance[MAX_FC_BRDS];	/* uses emlxs_device.lock */
411 uint32_t	emlxs_instance_count = 0;	/* uses emlxs_device.lock */
412 uint32_t	emlxs_instance_flag = 0;	/* uses emlxs_device.lock */
413 #define	EMLXS_FW_SHOW		0x00000001
414 
415 
416 /*
417  * CB ops vector.  Used for administration only.
418  */
419 static struct cb_ops emlxs_cb_ops = {
420 	emlxs_open,	/* cb_open	*/
421 	emlxs_close,	/* cb_close	*/
422 	nodev,		/* cb_strategy	*/
423 	nodev,		/* cb_print	*/
424 	nodev,		/* cb_dump	*/
425 	nodev,		/* cb_read	*/
426 	nodev,		/* cb_write	*/
427 	emlxs_ioctl,	/* cb_ioctl	*/
428 	nodev,		/* cb_devmap	*/
429 	nodev,		/* cb_mmap	*/
430 	nodev,		/* cb_segmap	*/
431 	nochpoll,	/* cb_chpoll	*/
432 	ddi_prop_op,	/* cb_prop_op	*/
433 	0,		/* cb_stream	*/
434 #ifdef _LP64
435 	D_64BIT | D_HOTPLUG | D_MP | D_NEW,	/* cb_flag */
436 #else
437 	D_HOTPLUG | D_MP | D_NEW,		/* cb_flag */
438 #endif
439 	CB_REV,		/* rev		*/
440 	nodev,		/* cb_aread	*/
441 	nodev		/* cb_awrite	*/
442 };
443 
444 static struct dev_ops emlxs_ops = {
445 	DEVO_REV,	/* rev */
446 	0,	/* refcnt */
447 	emlxs_info,	/* getinfo	*/
448 	nulldev,	/* identify	*/
449 	nulldev,	/* probe	*/
450 	emlxs_attach,	/* attach	*/
451 	emlxs_detach,	/* detach	*/
452 	nodev,		/* reset	*/
453 	&emlxs_cb_ops,	/* devo_cb_ops	*/
454 	NULL,		/* devo_bus_ops */
455 	emlxs_power,	/* power ops	*/
456 #ifdef EMLXS_I386
457 #ifdef S11
458 	emlxs_quiesce,	/* quiesce	*/
459 #endif /* S11 */
460 #endif /* EMLXS_I386 */
461 };
462 
463 #include <sys/modctl.h>
464 extern struct mod_ops mod_driverops;
465 
466 #ifdef SAN_DIAG_SUPPORT
467 extern kmutex_t		emlxs_sd_bucket_mutex;
468 extern sd_bucket_info_t	emlxs_sd_bucket;
469 #endif /* SAN_DIAG_SUPPORT */
470 
471 /*
472  * Module linkage information for the kernel.
473  */
474 static struct modldrv emlxs_modldrv = {
475 	&mod_driverops,	/* module type - driver */
476 	emlxs_name,	/* module name */
477 	&emlxs_ops,	/* driver ops */
478 };
479 
480 
481 /*
482  * Driver module linkage structure
483  */
484 static struct modlinkage emlxs_modlinkage = {
485 	MODREV_1,	/* ml_rev - must be MODREV_1 */
486 	&emlxs_modldrv,	/* ml_linkage */
487 	NULL	/* end of driver linkage */
488 };
489 
490 
491 /* We only need to add entries for non-default return codes. */
492 /* Entries do not need to be in order. */
493 /* Default:	FC_PKT_TRAN_ERROR,	FC_REASON_ABORTED, */
494 /*		FC_EXPLN_NONE,		FC_ACTION_RETRYABLE */
495 
496 emlxs_xlat_err_t emlxs_iostat_tbl[] = {
497 /*	{f/w code, pkt_state, pkt_reason,	*/
498 /*		pkt_expln, pkt_action}		*/
499 
500 	/* 0x00 - Do not remove */
501 	{IOSTAT_SUCCESS, FC_PKT_SUCCESS, FC_REASON_NONE,
502 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
503 
504 	/* 0x01 - Do not remove */
505 	{IOSTAT_FCP_RSP_ERROR, FC_PKT_SUCCESS, FC_REASON_NONE,
506 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
507 
508 	/* 0x02 */
509 	{IOSTAT_REMOTE_STOP, FC_PKT_REMOTE_STOP, FC_REASON_ABTS,
510 		FC_EXPLN_NONE, FC_ACTION_NON_RETRYABLE},
511 
512 	/*
513 	 * This is a default entry.
514 	 * The real codes are written dynamically in emlxs_els.c
515 	 */
516 	/* 0x09 */
517 	{IOSTAT_LS_RJT, FC_PKT_LS_RJT, FC_REASON_CMD_UNABLE,
518 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
519 
520 	/* Special error code */
521 	/* 0x10 */
522 	{IOSTAT_DATA_OVERRUN, FC_PKT_TRAN_ERROR, FC_REASON_OVERRUN,
523 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
524 
525 	/* Special error code */
526 	/* 0x11 */
527 	{IOSTAT_DATA_UNDERRUN, FC_PKT_TRAN_ERROR, FC_REASON_ABORTED,
528 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
529 
530 	/* Special error code */
531 	/* 0x12 */
532 	{IOSTAT_RSP_INVALID, FC_PKT_TRAN_ERROR, FC_REASON_ABORTED,
533 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
534 
535 	/* CLASS 2 only */
536 	/* 0x04 */
537 	{IOSTAT_NPORT_RJT, FC_PKT_NPORT_RJT, FC_REASON_PROTOCOL_ERROR,
538 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
539 
540 	/* CLASS 2 only */
541 	/* 0x05 */
542 	{IOSTAT_FABRIC_RJT, FC_PKT_FABRIC_RJT, FC_REASON_PROTOCOL_ERROR,
543 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
544 
545 	/* CLASS 2 only */
546 	/* 0x06 */
547 	{IOSTAT_NPORT_BSY, FC_PKT_NPORT_BSY, FC_REASON_PHYSICAL_BUSY,
548 		FC_EXPLN_NONE, FC_ACTION_SEQ_TERM_RETRY},
549 
550 	/* CLASS 2 only */
551 	/* 0x07 */
552 	{IOSTAT_FABRIC_BSY, FC_PKT_FABRIC_BSY, FC_REASON_FABRIC_BSY,
553 		FC_EXPLN_NONE, FC_ACTION_SEQ_TERM_RETRY},
554 };
555 
556 #define	IOSTAT_MAX (sizeof (emlxs_iostat_tbl)/sizeof (emlxs_xlat_err_t))
557 
558 
559 /* We only need to add entries for non-default return codes. */
560 /* Entries do not need to be in order. */
561 /* Default:	FC_PKT_TRAN_ERROR,	FC_REASON_ABORTED, */
562 /*		FC_EXPLN_NONE,		FC_ACTION_RETRYABLE} */
563 
564 emlxs_xlat_err_t emlxs_ioerr_tbl[] = {
565 /*	{f/w code, pkt_state, pkt_reason,	*/
566 /*		pkt_expln, pkt_action}		*/
567 
568 	/* 0x01 */
569 	{IOERR_MISSING_CONTINUE, FC_PKT_TRAN_ERROR, FC_REASON_OVERRUN,
570 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
571 
572 	/* 0x02 */
573 	{IOERR_SEQUENCE_TIMEOUT, FC_PKT_TIMEOUT, FC_REASON_SEQ_TIMEOUT,
574 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
575 
576 	/* 0x04 */
577 	{IOERR_INVALID_RPI, FC_PKT_PORT_OFFLINE, FC_REASON_OFFLINE,
578 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
579 
580 	/* 0x05 */
581 	{IOERR_NO_XRI, FC_PKT_LOCAL_RJT, FC_REASON_XCHG_DROPPED,
582 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
583 
584 	/* 0x06 */
585 	{IOERR_ILLEGAL_COMMAND,	FC_PKT_LOCAL_RJT, FC_REASON_ILLEGAL_REQ,
586 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
587 
588 	/* 0x07 */
589 	{IOERR_XCHG_DROPPED, FC_PKT_LOCAL_RJT,	FC_REASON_XCHG_DROPPED,
590 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
591 
592 	/* 0x08 */
593 	{IOERR_ILLEGAL_FIELD, FC_PKT_LOCAL_RJT,	FC_REASON_ILLEGAL_REQ,
594 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
595 
596 	/* 0x0B */
597 	{IOERR_RCV_BUFFER_WAITING, FC_PKT_LOCAL_RJT, FC_REASON_NOMEM,
598 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
599 
600 	/* 0x0D */
601 	{IOERR_TX_DMA_FAILED, FC_PKT_LOCAL_RJT,	FC_REASON_DMA_ERROR,
602 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
603 
604 	/* 0x0E */
605 	{IOERR_RX_DMA_FAILED, FC_PKT_LOCAL_RJT,	FC_REASON_DMA_ERROR,
606 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
607 
608 	/* 0x0F */
609 	{IOERR_ILLEGAL_FRAME, FC_PKT_LOCAL_RJT,	FC_REASON_ILLEGAL_FRAME,
610 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
611 
612 	/* 0x11 */
613 	{IOERR_NO_RESOURCES, FC_PKT_LOCAL_RJT,	FC_REASON_NOMEM,
614 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
615 
616 	/* 0x13 */
617 	{IOERR_ILLEGAL_LENGTH, FC_PKT_LOCAL_RJT, FC_REASON_ILLEGAL_LENGTH,
618 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
619 
620 	/* 0x14 */
621 	{IOERR_UNSUPPORTED_FEATURE, FC_PKT_LOCAL_RJT, FC_REASON_UNSUPPORTED,
622 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
623 
624 	/* 0x15 */
625 	{IOERR_ABORT_IN_PROGRESS, FC_PKT_LOCAL_RJT, FC_REASON_ABORTED,
626 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
627 
628 	/* 0x16 */
629 	{IOERR_ABORT_REQUESTED, FC_PKT_LOCAL_RJT, FC_REASON_ABORTED,
630 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
631 
632 	/* 0x17 */
633 	{IOERR_RCV_BUFFER_TIMEOUT, FC_PKT_LOCAL_RJT, FC_REASON_RX_BUF_TIMEOUT,
634 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
635 
636 	/* 0x18 */
637 	{IOERR_LOOP_OPEN_FAILURE, FC_PKT_LOCAL_RJT, FC_REASON_FCAL_OPN_FAIL,
638 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
639 
640 	/* 0x1A */
641 	{IOERR_LINK_DOWN, FC_PKT_PORT_OFFLINE, FC_REASON_OFFLINE,
642 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
643 
644 	/* 0x21 */
645 	{IOERR_BAD_HOST_ADDRESS, FC_PKT_LOCAL_RJT, FC_REASON_BAD_SID,
646 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
647 
648 	/* Occurs at link down */
649 	/* 0x28 */
650 	{IOERR_BUFFER_SHORTAGE, FC_PKT_PORT_OFFLINE, FC_REASON_OFFLINE,
651 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
652 
653 	/* 0xF0 */
654 	{IOERR_ABORT_TIMEOUT, FC_PKT_TIMEOUT, FC_REASON_SEQ_TIMEOUT,
655 		FC_EXPLN_NONE, FC_ACTION_RETRYABLE},
656 };
657 
658 #define	IOERR_MAX    (sizeof (emlxs_ioerr_tbl)/sizeof (emlxs_xlat_err_t))
659 
660 
661 
662 emlxs_table_t emlxs_error_table[] = {
663 	{IOERR_SUCCESS, "No error."},
664 	{IOERR_MISSING_CONTINUE, "Missing continue."},
665 	{IOERR_SEQUENCE_TIMEOUT, "Sequence timeout."},
666 	{IOERR_INTERNAL_ERROR, "Internal error."},
667 	{IOERR_INVALID_RPI, "Invalid RPI."},
668 	{IOERR_NO_XRI, "No XRI."},
669 	{IOERR_ILLEGAL_COMMAND, "Illegal command."},
670 	{IOERR_XCHG_DROPPED, "Exchange dropped."},
671 	{IOERR_ILLEGAL_FIELD, "Illegal field."},
672 	{IOERR_RCV_BUFFER_WAITING, "RX buffer waiting."},
673 	{IOERR_TX_DMA_FAILED, "TX DMA failed."},
674 	{IOERR_RX_DMA_FAILED, "RX DMA failed."},
675 	{IOERR_ILLEGAL_FRAME, "Illegal frame."},
676 	{IOERR_NO_RESOURCES, "No resources."},
677 	{IOERR_ILLEGAL_LENGTH, "Illegal length."},
678 	{IOERR_UNSUPPORTED_FEATURE, "Unsupported feature."},
679 	{IOERR_ABORT_IN_PROGRESS, "Abort in progess."},
680 	{IOERR_ABORT_REQUESTED, "Abort requested."},
681 	{IOERR_RCV_BUFFER_TIMEOUT, "RX buffer timeout."},
682 	{IOERR_LOOP_OPEN_FAILURE, "Loop open failed."},
683 	{IOERR_RING_RESET, "Ring reset."},
684 	{IOERR_LINK_DOWN, "Link down."},
685 	{IOERR_CORRUPTED_DATA, "Corrupted data."},
686 	{IOERR_CORRUPTED_RPI, "Corrupted RPI."},
687 	{IOERR_OUT_OF_ORDER_DATA, "Out-of-order data."},
688 	{IOERR_OUT_OF_ORDER_ACK, "Out-of-order ack."},
689 	{IOERR_DUP_FRAME, "Duplicate frame."},
690 	{IOERR_LINK_CONTROL_FRAME, "Link control frame."},
691 	{IOERR_BAD_HOST_ADDRESS, "Bad host address."},
692 	{IOERR_RCV_HDRBUF_WAITING, "RX header buffer waiting."},
693 	{IOERR_MISSING_HDR_BUFFER, "Missing header buffer."},
694 	{IOERR_MSEQ_CHAIN_CORRUPTED, "MSEQ chain corrupted."},
695 	{IOERR_ABORTMULT_REQUESTED, "Abort multiple requested."},
696 	{IOERR_BUFFER_SHORTAGE, "Buffer shortage."},
697 	{IOERR_XRIBUF_WAITING, "XRI buffer shortage"},
698 	{IOERR_XRIBUF_MISSING, "XRI buffer missing"},
699 	{IOERR_ROFFSET_INVAL, "Relative offset invalid."},
700 	{IOERR_ROFFSET_MISSING, "Relative offset missing."},
701 	{IOERR_INSUF_BUFFER, "Buffer too small."},
702 	{IOERR_MISSING_SI, "ELS frame missing SI"},
703 	{IOERR_MISSING_ES, "Exhausted burst without ES"},
704 	{IOERR_INCOMP_XFER, "Transfer incomplete."},
705 	{IOERR_ABORT_TIMEOUT, "Abort timeout."}
706 
707 };	/* emlxs_error_table */
708 
709 
710 emlxs_table_t emlxs_state_table[] = {
711 	{IOSTAT_SUCCESS, "Success."},
712 	{IOSTAT_FCP_RSP_ERROR, "FCP response error."},
713 	{IOSTAT_REMOTE_STOP, "Remote stop."},
714 	{IOSTAT_LOCAL_REJECT, "Local reject."},
715 	{IOSTAT_NPORT_RJT, "NPort reject."},
716 	{IOSTAT_FABRIC_RJT, "Fabric reject."},
717 	{IOSTAT_NPORT_BSY, "Nport busy."},
718 	{IOSTAT_FABRIC_BSY, "Fabric busy."},
719 	{IOSTAT_INTERMED_RSP, "Intermediate response."},
720 	{IOSTAT_LS_RJT, "LS reject."},
721 	{IOSTAT_CMD_REJECT,		"Cmd reject."},
722 	{IOSTAT_FCP_TGT_LENCHK, "TGT length check."},
723 	{IOSTAT_NEED_BUFF_ENTRY, "Need buffer entry."},
724 	{IOSTAT_DATA_UNDERRUN, "Data underrun."},
725 	{IOSTAT_DATA_OVERRUN,  "Data overrun."},
726 	{IOSTAT_RSP_INVALID,  "Response Invalid."},
727 
728 };	/* emlxs_state_table */
729 
730 
731 #ifdef MENLO_SUPPORT
732 emlxs_table_t emlxs_menlo_cmd_table[] = {
733 	{MENLO_CMD_INITIALIZE,		"MENLO_INIT"},
734 	{MENLO_CMD_FW_DOWNLOAD,		"MENLO_FW_DOWNLOAD"},
735 	{MENLO_CMD_READ_MEMORY,		"MENLO_READ_MEM"},
736 	{MENLO_CMD_WRITE_MEMORY,	"MENLO_WRITE_MEM"},
737 	{MENLO_CMD_FTE_INSERT,		"MENLO_FTE_INSERT"},
738 	{MENLO_CMD_FTE_DELETE,		"MENLO_FTE_DELETE"},
739 
740 	{MENLO_CMD_GET_INIT,		"MENLO_GET_INIT"},
741 	{MENLO_CMD_GET_CONFIG,		"MENLO_GET_CONFIG"},
742 	{MENLO_CMD_GET_PORT_STATS,	"MENLO_GET_PORT_STATS"},
743 	{MENLO_CMD_GET_LIF_STATS,	"MENLO_GET_LIF_STATS"},
744 	{MENLO_CMD_GET_ASIC_STATS,	"MENLO_GET_ASIC_STATS"},
745 	{MENLO_CMD_GET_LOG_CONFIG,	"MENLO_GET_LOG_CFG"},
746 	{MENLO_CMD_GET_LOG_DATA,	"MENLO_GET_LOG_DATA"},
747 	{MENLO_CMD_GET_PANIC_LOG,	"MENLO_GET_PANIC_LOG"},
748 	{MENLO_CMD_GET_LB_MODE,		"MENLO_GET_LB_MODE"},
749 
750 	{MENLO_CMD_SET_PAUSE,		"MENLO_SET_PAUSE"},
751 	{MENLO_CMD_SET_FCOE_COS,	"MENLO_SET_FCOE_COS"},
752 	{MENLO_CMD_SET_UIF_PORT_TYPE,	"MENLO_SET_UIF_TYPE"},
753 
754 	{MENLO_CMD_DIAGNOSTICS,		"MENLO_DIAGNOSTICS"},
755 	{MENLO_CMD_LOOPBACK,		"MENLO_LOOPBACK"},
756 
757 	{MENLO_CMD_RESET,		"MENLO_RESET"},
758 	{MENLO_CMD_SET_MODE,		"MENLO_SET_MODE"}
759 
760 };	/* emlxs_menlo_cmd_table */
761 
762 emlxs_table_t emlxs_menlo_rsp_table[] = {
763 	{MENLO_RSP_SUCCESS,		"SUCCESS"},
764 	{MENLO_ERR_FAILED,		"FAILED"},
765 	{MENLO_ERR_INVALID_CMD,		"INVALID_CMD"},
766 	{MENLO_ERR_INVALID_CREDIT,	"INVALID_CREDIT"},
767 	{MENLO_ERR_INVALID_SIZE,	"INVALID_SIZE"},
768 	{MENLO_ERR_INVALID_ADDRESS,	"INVALID_ADDRESS"},
769 	{MENLO_ERR_INVALID_CONTEXT,	"INVALID_CONTEXT"},
770 	{MENLO_ERR_INVALID_LENGTH,	"INVALID_LENGTH"},
771 	{MENLO_ERR_INVALID_TYPE,	"INVALID_TYPE"},
772 	{MENLO_ERR_INVALID_DATA,	"INVALID_DATA"},
773 	{MENLO_ERR_INVALID_VALUE1,	"INVALID_VALUE1"},
774 	{MENLO_ERR_INVALID_VALUE2,	"INVALID_VALUE2"},
775 	{MENLO_ERR_INVALID_MASK,	"INVALID_MASK"},
776 	{MENLO_ERR_CHECKSUM,		"CHECKSUM_ERROR"},
777 	{MENLO_ERR_UNKNOWN_FCID,	"UNKNOWN_FCID"},
778 	{MENLO_ERR_UNKNOWN_WWN,		"UNKNOWN_WWN"},
779 	{MENLO_ERR_BUSY,		"BUSY"},
780 
781 };	/* emlxs_menlo_rsp_table */
782 
783 #endif /* MENLO_SUPPORT */
784 
785 
786 emlxs_table_t emlxs_mscmd_table[] = {
787 	{SLI_CT_RESPONSE_FS_ACC, "CT_ACC"},
788 	{SLI_CT_RESPONSE_FS_RJT, "CT_RJT"},
789 	{MS_GTIN, "MS_GTIN"},
790 	{MS_GIEL, "MS_GIEL"},
791 	{MS_GIET, "MS_GIET"},
792 	{MS_GDID, "MS_GDID"},
793 	{MS_GMID, "MS_GMID"},
794 	{MS_GFN, "MS_GFN"},
795 	{MS_GIELN, "MS_GIELN"},
796 	{MS_GMAL, "MS_GMAL"},
797 	{MS_GIEIL, "MS_GIEIL"},
798 	{MS_GPL, "MS_GPL"},
799 	{MS_GPT, "MS_GPT"},
800 	{MS_GPPN, "MS_GPPN"},
801 	{MS_GAPNL, "MS_GAPNL"},
802 	{MS_GPS, "MS_GPS"},
803 	{MS_GPSC, "MS_GPSC"},
804 	{MS_GATIN, "MS_GATIN"},
805 	{MS_GSES, "MS_GSES"},
806 	{MS_GPLNL, "MS_GPLNL"},
807 	{MS_GPLT, "MS_GPLT"},
808 	{MS_GPLML, "MS_GPLML"},
809 	{MS_GPAB, "MS_GPAB"},
810 	{MS_GNPL, "MS_GNPL"},
811 	{MS_GPNL, "MS_GPNL"},
812 	{MS_GPFCP, "MS_GPFCP"},
813 	{MS_GPLI, "MS_GPLI"},
814 	{MS_GNID, "MS_GNID"},
815 	{MS_RIELN, "MS_RIELN"},
816 	{MS_RPL, "MS_RPL"},
817 	{MS_RPLN, "MS_RPLN"},
818 	{MS_RPLT, "MS_RPLT"},
819 	{MS_RPLM, "MS_RPLM"},
820 	{MS_RPAB, "MS_RPAB"},
821 	{MS_RPFCP, "MS_RPFCP"},
822 	{MS_RPLI, "MS_RPLI"},
823 	{MS_DPL, "MS_DPL"},
824 	{MS_DPLN, "MS_DPLN"},
825 	{MS_DPLM, "MS_DPLM"},
826 	{MS_DPLML, "MS_DPLML"},
827 	{MS_DPLI, "MS_DPLI"},
828 	{MS_DPAB, "MS_DPAB"},
829 	{MS_DPALL, "MS_DPALL"}
830 
831 };	/* emlxs_mscmd_table */
832 
833 
834 emlxs_table_t emlxs_ctcmd_table[] = {
835 	{SLI_CT_RESPONSE_FS_ACC, "CT_ACC"},
836 	{SLI_CT_RESPONSE_FS_RJT, "CT_RJT"},
837 	{SLI_CTNS_GA_NXT, "GA_NXT"},
838 	{SLI_CTNS_GPN_ID, "GPN_ID"},
839 	{SLI_CTNS_GNN_ID, "GNN_ID"},
840 	{SLI_CTNS_GCS_ID, "GCS_ID"},
841 	{SLI_CTNS_GFT_ID, "GFT_ID"},
842 	{SLI_CTNS_GSPN_ID, "GSPN_ID"},
843 	{SLI_CTNS_GPT_ID, "GPT_ID"},
844 	{SLI_CTNS_GID_PN, "GID_PN"},
845 	{SLI_CTNS_GID_NN, "GID_NN"},
846 	{SLI_CTNS_GIP_NN, "GIP_NN"},
847 	{SLI_CTNS_GIPA_NN, "GIPA_NN"},
848 	{SLI_CTNS_GSNN_NN, "GSNN_NN"},
849 	{SLI_CTNS_GNN_IP, "GNN_IP"},
850 	{SLI_CTNS_GIPA_IP, "GIPA_IP"},
851 	{SLI_CTNS_GID_FT, "GID_FT"},
852 	{SLI_CTNS_GID_PT, "GID_PT"},
853 	{SLI_CTNS_RPN_ID, "RPN_ID"},
854 	{SLI_CTNS_RNN_ID, "RNN_ID"},
855 	{SLI_CTNS_RCS_ID, "RCS_ID"},
856 	{SLI_CTNS_RFT_ID, "RFT_ID"},
857 	{SLI_CTNS_RSPN_ID, "RSPN_ID"},
858 	{SLI_CTNS_RPT_ID, "RPT_ID"},
859 	{SLI_CTNS_RIP_NN, "RIP_NN"},
860 	{SLI_CTNS_RIPA_NN, "RIPA_NN"},
861 	{SLI_CTNS_RSNN_NN, "RSNN_NN"},
862 	{SLI_CTNS_DA_ID, "DA_ID"},
863 	{SLI_CT_LOOPBACK, "LOOPBACK"} /* Driver special */
864 
865 };	/* emlxs_ctcmd_table */
866 
867 
868 
869 emlxs_table_t emlxs_rmcmd_table[] = {
870 	{SLI_CT_RESPONSE_FS_ACC, "CT_ACC"},
871 	{SLI_CT_RESPONSE_FS_RJT, "CT_RJT"},
872 	{CT_OP_GSAT, "RM_GSAT"},
873 	{CT_OP_GHAT, "RM_GHAT"},
874 	{CT_OP_GPAT, "RM_GPAT"},
875 	{CT_OP_GDAT, "RM_GDAT"},
876 	{CT_OP_GPST, "RM_GPST"},
877 	{CT_OP_GDP, "RM_GDP"},
878 	{CT_OP_GDPG, "RM_GDPG"},
879 	{CT_OP_GEPS, "RM_GEPS"},
880 	{CT_OP_GLAT, "RM_GLAT"},
881 	{CT_OP_SSAT, "RM_SSAT"},
882 	{CT_OP_SHAT, "RM_SHAT"},
883 	{CT_OP_SPAT, "RM_SPAT"},
884 	{CT_OP_SDAT, "RM_SDAT"},
885 	{CT_OP_SDP, "RM_SDP"},
886 	{CT_OP_SBBS, "RM_SBBS"},
887 	{CT_OP_RPST, "RM_RPST"},
888 	{CT_OP_VFW, "RM_VFW"},
889 	{CT_OP_DFW, "RM_DFW"},
890 	{CT_OP_RES, "RM_RES"},
891 	{CT_OP_RHD, "RM_RHD"},
892 	{CT_OP_UFW, "RM_UFW"},
893 	{CT_OP_RDP, "RM_RDP"},
894 	{CT_OP_GHDR, "RM_GHDR"},
895 	{CT_OP_CHD, "RM_CHD"},
896 	{CT_OP_SSR, "RM_SSR"},
897 	{CT_OP_RSAT, "RM_RSAT"},
898 	{CT_OP_WSAT, "RM_WSAT"},
899 	{CT_OP_RSAH, "RM_RSAH"},
900 	{CT_OP_WSAH, "RM_WSAH"},
901 	{CT_OP_RACT, "RM_RACT"},
902 	{CT_OP_WACT, "RM_WACT"},
903 	{CT_OP_RKT, "RM_RKT"},
904 	{CT_OP_WKT, "RM_WKT"},
905 	{CT_OP_SSC, "RM_SSC"},
906 	{CT_OP_QHBA, "RM_QHBA"},
907 	{CT_OP_GST, "RM_GST"},
908 	{CT_OP_GFTM, "RM_GFTM"},
909 	{CT_OP_SRL, "RM_SRL"},
910 	{CT_OP_SI, "RM_SI"},
911 	{CT_OP_SRC, "RM_SRC"},
912 	{CT_OP_GPB, "RM_GPB"},
913 	{CT_OP_SPB, "RM_SPB"},
914 	{CT_OP_RPB, "RM_RPB"},
915 	{CT_OP_RAPB, "RM_RAPB"},
916 	{CT_OP_GBC, "RM_GBC"},
917 	{CT_OP_GBS, "RM_GBS"},
918 	{CT_OP_SBS, "RM_SBS"},
919 	{CT_OP_GANI, "RM_GANI"},
920 	{CT_OP_GRV, "RM_GRV"},
921 	{CT_OP_GAPBS, "RM_GAPBS"},
922 	{CT_OP_APBC, "RM_APBC"},
923 	{CT_OP_GDT, "RM_GDT"},
924 	{CT_OP_GDLMI, "RM_GDLMI"},
925 	{CT_OP_GANA, "RM_GANA"},
926 	{CT_OP_GDLV, "RM_GDLV"},
927 	{CT_OP_GWUP, "RM_GWUP"},
928 	{CT_OP_GLM, "RM_GLM"},
929 	{CT_OP_GABS, "RM_GABS"},
930 	{CT_OP_SABS, "RM_SABS"},
931 	{CT_OP_RPR, "RM_RPR"},
932 	{SLI_CT_LOOPBACK, "LOOPBACK"} /* Driver special */
933 
934 };	/* emlxs_rmcmd_table */
935 
936 
937 emlxs_table_t emlxs_elscmd_table[] = {
938 	{ELS_CMD_ACC, "ACC"},
939 	{ELS_CMD_LS_RJT, "LS_RJT"},
940 	{ELS_CMD_PLOGI, "PLOGI"},
941 	{ELS_CMD_FLOGI, "FLOGI"},
942 	{ELS_CMD_LOGO, "LOGO"},
943 	{ELS_CMD_ABTX, "ABTX"},
944 	{ELS_CMD_RCS, "RCS"},
945 	{ELS_CMD_RES, "RES"},
946 	{ELS_CMD_RSS, "RSS"},
947 	{ELS_CMD_RSI, "RSI"},
948 	{ELS_CMD_ESTS, "ESTS"},
949 	{ELS_CMD_ESTC, "ESTC"},
950 	{ELS_CMD_ADVC, "ADVC"},
951 	{ELS_CMD_RTV, "RTV"},
952 	{ELS_CMD_RLS, "RLS"},
953 	{ELS_CMD_ECHO, "ECHO"},
954 	{ELS_CMD_TEST, "TEST"},
955 	{ELS_CMD_RRQ, "RRQ"},
956 	{ELS_CMD_REC, "REC"},
957 	{ELS_CMD_PRLI, "PRLI"},
958 	{ELS_CMD_PRLO, "PRLO"},
959 	{ELS_CMD_SCN, "SCN"},
960 	{ELS_CMD_TPLS, "TPLS"},
961 	{ELS_CMD_GPRLO, "GPRLO"},
962 	{ELS_CMD_GAID, "GAID"},
963 	{ELS_CMD_FACT, "FACT"},
964 	{ELS_CMD_FDACT, "FDACT"},
965 	{ELS_CMD_NACT, "NACT"},
966 	{ELS_CMD_NDACT, "NDACT"},
967 	{ELS_CMD_QoSR, "QoSR"},
968 	{ELS_CMD_RVCS, "RVCS"},
969 	{ELS_CMD_PDISC, "PDISC"},
970 	{ELS_CMD_FDISC, "FDISC"},
971 	{ELS_CMD_ADISC, "ADISC"},
972 	{ELS_CMD_FARP, "FARP"},
973 	{ELS_CMD_FARPR, "FARPR"},
974 	{ELS_CMD_FAN, "FAN"},
975 	{ELS_CMD_RSCN, "RSCN"},
976 	{ELS_CMD_SCR, "SCR"},
977 	{ELS_CMD_LINIT, "LINIT"},
978 	{ELS_CMD_RNID, "RNID"},
979 	{ELS_CMD_AUTH, "AUTH"}
980 
981 };	/* emlxs_elscmd_table */
982 
983 
984 emlxs_table_t emlxs_mode_table[] = {
985 	{MODE_NONE, "NONE"},
986 	{MODE_INITIATOR, "INITIATOR"},
987 	{MODE_TARGET, "TARGET"},
988 	{MODE_ALL, "INITIATOR | TARGET"}
989 };	/* emlxs_mode_table */
990 
991 /*
992  *
993  *	Device Driver Entry Routines
994  *
995  */
996 
997 #ifdef MODSYM_SUPPORT
998 static void emlxs_fca_modclose();
999 static int  emlxs_fca_modopen();
1000 emlxs_modsym_t emlxs_modsym;	/* uses emlxs_device.lock */
1001 
1002 static int
emlxs_fca_modopen()1003 emlxs_fca_modopen()
1004 {
1005 	int err;
1006 
1007 	if (emlxs_modsym.mod_fctl) {
1008 		return (0);
1009 	}
1010 
1011 	/* Leadville (fctl) */
1012 	err = 0;
1013 	emlxs_modsym.mod_fctl =
1014 	    ddi_modopen("misc/fctl", KRTLD_MODE_FIRST, &err);
1015 	if (!emlxs_modsym.mod_fctl) {
1016 		cmn_err(CE_WARN,
1017 		    "?%s: misc/fctl: ddi_modopen misc/fctl failed: error=%d",
1018 		    DRIVER_NAME, err);
1019 
1020 		goto failed;
1021 	}
1022 
1023 	err = 0;
1024 	/* Check if the fctl fc_fca_attach is present */
1025 	emlxs_modsym.fc_fca_attach =
1026 	    (int (*)())ddi_modsym(emlxs_modsym.mod_fctl, "fc_fca_attach",
1027 	    &err);
1028 	if ((void *)emlxs_modsym.fc_fca_attach == NULL) {
1029 		cmn_err(CE_WARN,
1030 		    "?%s: misc/fctl: fc_fca_attach not present", DRIVER_NAME);
1031 		goto failed;
1032 	}
1033 
1034 	err = 0;
1035 	/* Check if the fctl fc_fca_detach is present */
1036 	emlxs_modsym.fc_fca_detach =
1037 	    (int (*)())ddi_modsym(emlxs_modsym.mod_fctl, "fc_fca_detach",
1038 	    &err);
1039 	if ((void *)emlxs_modsym.fc_fca_detach == NULL) {
1040 		cmn_err(CE_WARN,
1041 		    "?%s: misc/fctl: fc_fca_detach not present", DRIVER_NAME);
1042 		goto failed;
1043 	}
1044 
1045 	err = 0;
1046 	/* Check if the fctl fc_fca_init is present */
1047 	emlxs_modsym.fc_fca_init =
1048 	    (int (*)())ddi_modsym(emlxs_modsym.mod_fctl, "fc_fca_init", &err);
1049 	if ((void *)emlxs_modsym.fc_fca_init == NULL) {
1050 		cmn_err(CE_WARN,
1051 		    "?%s: misc/fctl: fc_fca_init not present", DRIVER_NAME);
1052 		goto failed;
1053 	}
1054 
1055 	return (0);
1056 
1057 failed:
1058 
1059 	emlxs_fca_modclose();
1060 
1061 	return (1);
1062 
1063 
1064 } /* emlxs_fca_modopen() */
1065 
1066 
1067 static void
emlxs_fca_modclose()1068 emlxs_fca_modclose()
1069 {
1070 	if (emlxs_modsym.mod_fctl) {
1071 		(void) ddi_modclose(emlxs_modsym.mod_fctl);
1072 		emlxs_modsym.mod_fctl = 0;
1073 	}
1074 
1075 	emlxs_modsym.fc_fca_attach = NULL;
1076 	emlxs_modsym.fc_fca_detach = NULL;
1077 	emlxs_modsym.fc_fca_init   = NULL;
1078 
1079 	return;
1080 
1081 } /* emlxs_fca_modclose() */
1082 
1083 #endif /* MODSYM_SUPPORT */
1084 
1085 
1086 
1087 /*
1088  * Global driver initialization, called once when driver is loaded
1089  */
1090 int
_init(void)1091 _init(void)
1092 {
1093 	int ret;
1094 
1095 	/*
1096 	 * First init call for this driver,
1097 	 * so initialize the emlxs_dev_ctl structure.
1098 	 */
1099 	bzero(&emlxs_device, sizeof (emlxs_device));
1100 
1101 #ifdef MODSYM_SUPPORT
1102 	bzero(&emlxs_modsym, sizeof (emlxs_modsym_t));
1103 #endif /* MODSYM_SUPPORT */
1104 
1105 	mutex_init(&emlxs_device.lock, NULL, MUTEX_DRIVER, NULL);
1106 
1107 	(void) drv_getparm(LBOLT, &emlxs_device.log_timestamp);
1108 	emlxs_device.drv_timestamp = ddi_get_time();
1109 
1110 	for (ret = 0; ret < MAX_FC_BRDS; ret++) {
1111 		emlxs_instance[ret] = (uint32_t)-1;
1112 	}
1113 
1114 	/*
1115 	 * Provide for one ddiinst of the emlxs_dev_ctl structure
1116 	 * for each possible board in the system.
1117 	 */
1118 	if ((ret = ddi_soft_state_init(&emlxs_soft_state,
1119 	    sizeof (emlxs_hba_t), MAX_FC_BRDS)) != 0) {
1120 		cmn_err(CE_WARN,
1121 		    "?%s: _init: ddi_soft_state_init failed. rval=%x",
1122 		    DRIVER_NAME, ret);
1123 
1124 		return (ret);
1125 	}
1126 
1127 #ifdef MODSYM_SUPPORT
1128 	/* Open SFS */
1129 	(void) emlxs_fca_modopen();
1130 #endif /* MODSYM_SUPPORT */
1131 
1132 	/* Setup devops for SFS */
1133 	MODSYM(fc_fca_init)(&emlxs_ops);
1134 
1135 	if ((ret = mod_install(&emlxs_modlinkage)) != 0) {
1136 		(void) ddi_soft_state_fini(&emlxs_soft_state);
1137 #ifdef MODSYM_SUPPORT
1138 		/* Close SFS */
1139 		emlxs_fca_modclose();
1140 #endif /* MODSYM_SUPPORT */
1141 
1142 		return (ret);
1143 	}
1144 
1145 #ifdef SAN_DIAG_SUPPORT
1146 	mutex_init(&emlxs_sd_bucket_mutex, NULL, MUTEX_DRIVER, NULL);
1147 #endif /* SAN_DIAG_SUPPORT */
1148 
1149 	return (ret);
1150 
1151 } /* _init() */
1152 
1153 
1154 /*
1155  * Called when driver is unloaded.
1156  */
1157 int
_fini(void)1158 _fini(void)
1159 {
1160 	int ret;
1161 
1162 	if ((ret = mod_remove(&emlxs_modlinkage)) != 0) {
1163 		return (ret);
1164 	}
1165 #ifdef MODSYM_SUPPORT
1166 	/* Close SFS */
1167 	emlxs_fca_modclose();
1168 #endif /* MODSYM_SUPPORT */
1169 
1170 	/*
1171 	 * Destroy the soft state structure
1172 	 */
1173 	(void) ddi_soft_state_fini(&emlxs_soft_state);
1174 
1175 	/* Destroy the global device lock */
1176 	mutex_destroy(&emlxs_device.lock);
1177 
1178 #ifdef SAN_DIAG_SUPPORT
1179 	mutex_destroy(&emlxs_sd_bucket_mutex);
1180 #endif /* SAN_DIAG_SUPPORT */
1181 
1182 	return (ret);
1183 
1184 } /* _fini() */
1185 
1186 
1187 
1188 int
_info(struct modinfo * modinfop)1189 _info(struct modinfo *modinfop)
1190 {
1191 
1192 	return (mod_info(&emlxs_modlinkage, modinfop));
1193 
1194 } /* _info() */
1195 
1196 
1197 /*
1198  * Attach an ddiinst of an emlx host adapter.
1199  * Allocate data structures, initialize the adapter and we're ready to fly.
1200  */
1201 static int
emlxs_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)1202 emlxs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1203 {
1204 	emlxs_hba_t *hba;
1205 	int ddiinst;
1206 	int emlxinst;
1207 	int rval;
1208 
1209 	switch (cmd) {
1210 	case DDI_ATTACH:
1211 		/* If successful this will set EMLXS_PM_IN_ATTACH */
1212 		rval = emlxs_hba_attach(dip);
1213 		break;
1214 
1215 	case DDI_RESUME:
1216 		/* This will resume the driver */
1217 		rval = emlxs_hba_resume(dip);
1218 		break;
1219 
1220 	default:
1221 		rval = DDI_FAILURE;
1222 	}
1223 
1224 	if (rval == DDI_SUCCESS) {
1225 		ddiinst = ddi_get_instance(dip);
1226 		emlxinst = emlxs_get_instance(ddiinst);
1227 		hba = emlxs_device.hba[emlxinst];
1228 
1229 		if ((hba != NULL) && (hba != (emlxs_hba_t *)-1)) {
1230 
1231 			/* Enable driver dump feature */
1232 			mutex_enter(&EMLXS_PORT_LOCK);
1233 			hba->flag |= FC_DUMP_SAFE;
1234 			mutex_exit(&EMLXS_PORT_LOCK);
1235 		}
1236 	}
1237 
1238 	return (rval);
1239 
1240 } /* emlxs_attach() */
1241 
1242 
1243 /*
1244  * Detach/prepare driver to unload (see detach(9E)).
1245  */
1246 static int
emlxs_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1247 emlxs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1248 {
1249 	emlxs_hba_t *hba;
1250 	emlxs_port_t *port;
1251 	int ddiinst;
1252 	int emlxinst;
1253 	int rval;
1254 
1255 	ddiinst = ddi_get_instance(dip);
1256 	emlxinst = emlxs_get_instance(ddiinst);
1257 	hba = emlxs_device.hba[emlxinst];
1258 
1259 	if (hba == NULL) {
1260 		cmn_err(CE_WARN, "?%s: Detach: NULL device.", DRIVER_NAME);
1261 
1262 		return (DDI_FAILURE);
1263 	}
1264 
1265 	if (hba == (emlxs_hba_t *)-1) {
1266 		cmn_err(CE_WARN, "?%s: Detach: Device attach failed.",
1267 		    DRIVER_NAME);
1268 
1269 		return (DDI_FAILURE);
1270 	}
1271 
1272 	port = &PPORT;
1273 	rval = DDI_SUCCESS;
1274 
1275 	/* Check driver dump */
1276 	mutex_enter(&EMLXS_PORT_LOCK);
1277 
1278 	if (hba->flag & FC_DUMP_ACTIVE) {
1279 		mutex_exit(&EMLXS_PORT_LOCK);
1280 
1281 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_detach_failed_msg,
1282 		    "detach: Driver busy. Driver dump active.");
1283 
1284 		return (DDI_FAILURE);
1285 	}
1286 
1287 #ifdef SFCT_SUPPORT
1288 	if ((port->flag & EMLXS_TGT_BOUND) &&
1289 	    ((port->fct_flags & FCT_STATE_PORT_ONLINE) ||
1290 	    (port->fct_flags & FCT_STATE_NOT_ACKED))) {
1291 		mutex_exit(&EMLXS_PORT_LOCK);
1292 
1293 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_detach_failed_msg,
1294 		    "detach: Driver busy. Target mode active.");
1295 
1296 		return (DDI_FAILURE);
1297 	}
1298 #endif /* SFCT_SUPPORT */
1299 
1300 	if (port->flag & EMLXS_INI_BOUND) {
1301 		mutex_exit(&EMLXS_PORT_LOCK);
1302 
1303 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_detach_failed_msg,
1304 		    "detach: Driver busy. Initiator mode active.");
1305 
1306 		return (DDI_FAILURE);
1307 	}
1308 
1309 	hba->flag &= ~FC_DUMP_SAFE;
1310 
1311 	mutex_exit(&EMLXS_PORT_LOCK);
1312 
1313 	switch (cmd) {
1314 	case DDI_DETACH:
1315 
1316 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_detach_debug_msg,
1317 		    "DDI_DETACH");
1318 
1319 		rval = emlxs_hba_detach(dip);
1320 
1321 		if (rval != DDI_SUCCESS) {
1322 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_detach_failed_msg,
1323 			    "Unable to detach.");
1324 		}
1325 		break;
1326 
1327 	case DDI_SUSPEND:
1328 
1329 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_detach_debug_msg,
1330 		    "DDI_SUSPEND");
1331 
1332 		/* Suspend the driver */
1333 		rval = emlxs_hba_suspend(dip);
1334 
1335 		if (rval != DDI_SUCCESS) {
1336 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_detach_failed_msg,
1337 			    "Unable to suspend driver.");
1338 		}
1339 		break;
1340 
1341 	default:
1342 		cmn_err(CE_WARN, "?%s: Detach: Unknown cmd received. cmd=%x",
1343 		    DRIVER_NAME, cmd);
1344 		rval = DDI_FAILURE;
1345 	}
1346 
1347 	if (rval == DDI_FAILURE) {
1348 		/* Re-Enable driver dump feature */
1349 		mutex_enter(&EMLXS_PORT_LOCK);
1350 		hba->flag |= FC_DUMP_SAFE;
1351 		mutex_exit(&EMLXS_PORT_LOCK);
1352 	}
1353 
1354 	return (rval);
1355 
1356 } /* emlxs_detach() */
1357 
1358 
1359 /* EMLXS_PORT_LOCK must be held when calling this */
1360 extern void
emlxs_port_init(emlxs_port_t * port)1361 emlxs_port_init(emlxs_port_t *port)
1362 {
1363 	emlxs_hba_t *hba = HBA;
1364 
1365 	/* Initialize the base node */
1366 	bzero((caddr_t)&port->node_base, sizeof (NODELIST));
1367 	port->node_base.nlp_Rpi = 0;
1368 	port->node_base.nlp_DID = 0xffffff;
1369 	port->node_base.nlp_list_next = NULL;
1370 	port->node_base.nlp_list_prev = NULL;
1371 	port->node_base.nlp_active = 1;
1372 	port->node_base.nlp_base = 1;
1373 	port->node_count = 0;
1374 
1375 	if (!(port->flag & EMLXS_PORT_ENABLED)) {
1376 		uint8_t dummy_wwn[8] =
1377 		    { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1378 
1379 		bcopy((caddr_t)dummy_wwn, (caddr_t)&port->wwnn,
1380 		    sizeof (NAME_TYPE));
1381 		bcopy((caddr_t)dummy_wwn, (caddr_t)&port->wwpn,
1382 		    sizeof (NAME_TYPE));
1383 	}
1384 
1385 	if (!(port->flag & EMLXS_PORT_CONFIG)) {
1386 		(void) strncpy((caddr_t)port->snn, (caddr_t)hba->snn,
1387 		    (sizeof (port->snn)-1));
1388 		(void) strncpy((caddr_t)port->spn, (caddr_t)hba->spn,
1389 		    (sizeof (port->spn)-1));
1390 	}
1391 
1392 	bcopy((caddr_t)&hba->sparam, (caddr_t)&port->sparam,
1393 	    sizeof (SERV_PARM));
1394 	bcopy((caddr_t)&port->wwnn, (caddr_t)&port->sparam.nodeName,
1395 	    sizeof (NAME_TYPE));
1396 	bcopy((caddr_t)&port->wwpn, (caddr_t)&port->sparam.portName,
1397 	    sizeof (NAME_TYPE));
1398 
1399 	return;
1400 
1401 } /* emlxs_port_init() */
1402 
1403 
1404 void
emlxs_disable_pcie_ce_err(emlxs_hba_t * hba)1405 emlxs_disable_pcie_ce_err(emlxs_hba_t *hba)
1406 {
1407 	uint16_t	reg;
1408 
1409 	if (!hba->pci_cap_offset[PCI_CAP_ID_PCI_E]) {
1410 		return;
1411 	}
1412 
1413 	/* Turn off the Correctable Error Reporting */
1414 	/* (the Device Control Register, bit 0). */
1415 	reg = ddi_get16(hba->pci_acc_handle,
1416 	    (uint16_t *)(hba->pci_addr +
1417 	    hba->pci_cap_offset[PCI_CAP_ID_PCI_E] +
1418 	    PCIE_DEVCTL));
1419 
1420 	reg &= ~1;
1421 
1422 	(void) ddi_put16(hba->pci_acc_handle,
1423 	    (uint16_t *)(hba->pci_addr +
1424 	    hba->pci_cap_offset[PCI_CAP_ID_PCI_E] +
1425 	    PCIE_DEVCTL),
1426 	    reg);
1427 
1428 	return;
1429 
1430 } /* emlxs_disable_pcie_ce_err() */
1431 
1432 
1433 /*
1434  * emlxs_fca_bind_port
1435  *
1436  * Arguments:
1437  *
1438  * dip: the dev_info pointer for the ddiinst
1439  * port_info: pointer to info handed back to the transport
1440  * bind_info: pointer to info from the transport
1441  *
1442  * Return values: a port handle for this port, NULL for failure
1443  *
1444  */
1445 static opaque_t
emlxs_fca_bind_port(dev_info_t * dip,fc_fca_port_info_t * port_info,fc_fca_bind_info_t * bind_info)1446 emlxs_fca_bind_port(dev_info_t *dip, fc_fca_port_info_t *port_info,
1447     fc_fca_bind_info_t *bind_info)
1448 {
1449 	emlxs_hba_t *hba;
1450 	emlxs_port_t *port;
1451 	emlxs_port_t *pport;
1452 	emlxs_port_t *vport;
1453 	int ddiinst;
1454 	emlxs_vpd_t *vpd;
1455 	emlxs_config_t *cfg;
1456 	char *dptr;
1457 	char buffer[16];
1458 	uint32_t length;
1459 	uint32_t len;
1460 	char topology[32];
1461 	char linkspeed[32];
1462 	uint32_t linkstate;
1463 
1464 	ddiinst = ddi_get_instance(dip);
1465 	hba = ddi_get_soft_state(emlxs_soft_state, ddiinst);
1466 	port = &PPORT;
1467 	pport = &PPORT;
1468 
1469 	ddiinst = hba->ddiinst;
1470 	vpd = &VPD;
1471 	cfg = &CFG;
1472 
1473 	mutex_enter(&EMLXS_PORT_LOCK);
1474 
1475 	if (bind_info->port_num > 0) {
1476 #if (EMLXS_MODREV >= EMLXS_MODREV5)
1477 		if (!(hba->flag & FC_NPIV_ENABLED) ||
1478 		    !(bind_info->port_npiv) ||
1479 		    (bind_info->port_num > hba->vpi_max))
1480 #elif (EMLXS_MODREV >= EMLXS_MODREV3)
1481 		if (!(hba->flag & FC_NPIV_ENABLED) ||
1482 		    (bind_info->port_num > hba->vpi_high))
1483 #endif
1484 		{
1485 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
1486 			    "fca_bind_port: Port %d not supported.",
1487 			    bind_info->port_num);
1488 
1489 			mutex_exit(&EMLXS_PORT_LOCK);
1490 
1491 			port_info->pi_error = FC_OUTOFBOUNDS;
1492 			return (NULL);
1493 		}
1494 	}
1495 
1496 	/* Get true port pointer */
1497 	port = &VPORT(bind_info->port_num);
1498 
1499 	/* Make sure the port is not already bound to the transport */
1500 	if (port->flag & EMLXS_INI_BOUND) {
1501 
1502 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
1503 		    "fca_bind_port: Port %d already bound. flag=%x",
1504 		    bind_info->port_num, port->flag);
1505 
1506 		mutex_exit(&EMLXS_PORT_LOCK);
1507 
1508 		port_info->pi_error = FC_ALREADY;
1509 		return (NULL);
1510 	}
1511 
1512 	if (!(pport->flag & EMLXS_INI_ENABLED)) {
1513 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
1514 		    "fca_bind_port: Physical port does not support "
1515 		    "initiator mode.");
1516 
1517 		mutex_exit(&EMLXS_PORT_LOCK);
1518 
1519 		port_info->pi_error = FC_OUTOFBOUNDS;
1520 		return (NULL);
1521 	}
1522 
1523 	/* Make sure port enable flag is set */
1524 	/* Just in case fca_port_unbind is called just prior to fca_port_bind */
1525 	/* without a driver attach or resume operation */
1526 	port->flag |= EMLXS_PORT_ENABLED;
1527 
1528 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
1529 	    "fca_bind_port: Port %d: port_info=%p bind_info=%p",
1530 	    bind_info->port_num, port_info, bind_info);
1531 
1532 #if (EMLXS_MODREV >= EMLXS_MODREV5)
1533 	if (bind_info->port_npiv) {
1534 		/* Leadville is telling us about a new virtual port */
1535 		bcopy((caddr_t)&bind_info->port_nwwn, (caddr_t)&port->wwnn,
1536 		    sizeof (NAME_TYPE));
1537 		bcopy((caddr_t)&bind_info->port_pwwn, (caddr_t)&port->wwpn,
1538 		    sizeof (NAME_TYPE));
1539 		if (port->snn[0] == 0) {
1540 			(void) strncpy((caddr_t)port->snn, (caddr_t)hba->snn,
1541 			    (sizeof (port->snn)-1));
1542 
1543 		}
1544 
1545 		if (port->spn[0] == 0) {
1546 			(void) snprintf((caddr_t)port->spn,
1547 			    (sizeof (port->spn)-1), "%s VPort-%d",
1548 			    (caddr_t)hba->spn, port->vpi);
1549 		}
1550 		port->flag |= EMLXS_PORT_CONFIG;
1551 	}
1552 #endif /* >= EMLXS_MODREV5 */
1553 
1554 	/*
1555 	 * Restricted login should apply both physical and
1556 	 * virtual ports.
1557 	 */
1558 	if (cfg[CFG_VPORT_RESTRICTED].current) {
1559 		port->flag |= EMLXS_PORT_RESTRICTED;
1560 	}
1561 
1562 	/* Perform generic port initialization */
1563 	emlxs_port_init(port);
1564 
1565 	/* Perform SFS specific initialization */
1566 	port->ulp_handle	= bind_info->port_handle;
1567 	port->ulp_statec_cb	= bind_info->port_statec_cb;
1568 	port->ulp_unsol_cb	= bind_info->port_unsol_cb;
1569 
1570 	/* Set the bound flag */
1571 	port->flag |= EMLXS_INI_BOUND;
1572 	hba->num_of_ports++;
1573 
1574 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1575 		mutex_exit(&EMLXS_PORT_LOCK);
1576 		(void) emlxs_vpi_port_bind_notify(port);
1577 		mutex_enter(&EMLXS_PORT_LOCK);
1578 
1579 		linkstate = (port->vpip->state == VPI_STATE_PORT_ONLINE)?
1580 		    FC_LINK_UP:FC_LINK_DOWN;
1581 	} else {
1582 		linkstate = hba->state;
1583 	}
1584 
1585 	/* Update the port info structure */
1586 
1587 	/* Set the topology and state */
1588 	if (port->mode == MODE_TARGET) {
1589 		port_info->pi_port_state = FC_STATE_OFFLINE;
1590 		port_info->pi_topology = FC_TOP_UNKNOWN;
1591 	} else if ((linkstate < FC_LINK_UP) ||
1592 	    ((port->vpi > 0) && (!(port->flag & EMLXS_PORT_ENABLED) ||
1593 	    !(hba->flag & FC_NPIV_SUPPORTED)))) {
1594 		port_info->pi_port_state = FC_STATE_OFFLINE;
1595 		port_info->pi_topology = FC_TOP_UNKNOWN;
1596 	}
1597 #ifdef MENLO_SUPPORT
1598 	else if (hba->flag & FC_MENLO_MODE) {
1599 		port_info->pi_port_state = FC_STATE_OFFLINE;
1600 		port_info->pi_topology = FC_TOP_UNKNOWN;
1601 	}
1602 #endif /* MENLO_SUPPORT */
1603 	else {
1604 		/* Check for loop topology */
1605 		if (hba->topology == TOPOLOGY_LOOP) {
1606 			port_info->pi_port_state = FC_STATE_LOOP;
1607 			(void) strlcpy(topology, ", loop", sizeof (topology));
1608 
1609 			if (hba->flag & FC_FABRIC_ATTACHED) {
1610 				port_info->pi_topology = FC_TOP_PUBLIC_LOOP;
1611 			} else {
1612 				port_info->pi_topology = FC_TOP_PRIVATE_LOOP;
1613 			}
1614 		} else {
1615 			port_info->pi_topology = FC_TOP_FABRIC;
1616 			port_info->pi_port_state = FC_STATE_ONLINE;
1617 			(void) strlcpy(topology, ", fabric", sizeof (topology));
1618 		}
1619 
1620 		/* Set the link speed */
1621 		switch (hba->linkspeed) {
1622 		case 0:
1623 			(void) strlcpy(linkspeed, "Gb", sizeof (linkspeed));
1624 			port_info->pi_port_state |= FC_STATE_1GBIT_SPEED;
1625 			break;
1626 
1627 		case LA_1GHZ_LINK:
1628 			(void) strlcpy(linkspeed, "1Gb", sizeof (linkspeed));
1629 			port_info->pi_port_state |= FC_STATE_1GBIT_SPEED;
1630 			break;
1631 		case LA_2GHZ_LINK:
1632 			(void) strlcpy(linkspeed, "2Gb", sizeof (linkspeed));
1633 			port_info->pi_port_state |= FC_STATE_2GBIT_SPEED;
1634 			break;
1635 		case LA_4GHZ_LINK:
1636 			(void) strlcpy(linkspeed, "4Gb", sizeof (linkspeed));
1637 			port_info->pi_port_state |= FC_STATE_4GBIT_SPEED;
1638 			break;
1639 		case LA_8GHZ_LINK:
1640 			(void) strlcpy(linkspeed, "8Gb", sizeof (linkspeed));
1641 			port_info->pi_port_state |= FC_STATE_8GBIT_SPEED;
1642 			break;
1643 		case LA_10GHZ_LINK:
1644 			(void) strlcpy(linkspeed, "10Gb", sizeof (linkspeed));
1645 			port_info->pi_port_state |= FC_STATE_10GBIT_SPEED;
1646 			break;
1647 		case LA_16GHZ_LINK:
1648 			(void) strlcpy(linkspeed, "16Gb", sizeof (linkspeed));
1649 			port_info->pi_port_state |= FC_STATE_16GBIT_SPEED;
1650 			break;
1651 		case LA_32GHZ_LINK:
1652 			(void) strlcpy(linkspeed, "32Gb", sizeof (linkspeed));
1653 			port_info->pi_port_state |= FC_STATE_32GBIT_SPEED;
1654 			break;
1655 		default:
1656 			(void) snprintf(linkspeed, sizeof (linkspeed),
1657 			    "unknown(0x%x)", hba->linkspeed);
1658 			break;
1659 		}
1660 
1661 		if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
1662 			/* Adjusting port context for link up messages */
1663 			vport = port;
1664 			port = &PPORT;
1665 			if (vport->vpi == 0) {
1666 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg,
1667 				    "%s%s, initiator",
1668 				    linkspeed, topology);
1669 			} else if (!(hba->flag & FC_NPIV_LINKUP)) {
1670 				hba->flag |= FC_NPIV_LINKUP;
1671 				EMLXS_MSGF(EMLXS_CONTEXT,
1672 				    &emlxs_npiv_link_up_msg,
1673 				    "%s%s, initiator", linkspeed, topology);
1674 			}
1675 			port = vport;
1676 		}
1677 	}
1678 
1679 	/* PCIE Correctable Error Reporting workaround */
1680 	if (((hba->model_info.chip == EMLXS_BE2_CHIP) ||
1681 	    (hba->model_info.chip == EMLXS_BE3_CHIP)) &&
1682 	    (bind_info->port_num == 0)) {
1683 		emlxs_disable_pcie_ce_err(hba);
1684 	}
1685 
1686 	/* Save initial state */
1687 	port->ulp_statec = port_info->pi_port_state;
1688 
1689 	/*
1690 	 * The transport needs a copy of the common service parameters
1691 	 * for this port. The transport can get any updates through
1692 	 * the getcap entry point.
1693 	 */
1694 	bcopy((void *) &port->sparam,
1695 	    (void *) &port_info->pi_login_params.common_service,
1696 	    sizeof (SERV_PARM));
1697 
1698 #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1699 	/* Swap the service parameters for ULP */
1700 	emlxs_swap_service_params((SERV_PARM *)&port_info->pi_login_params.
1701 	    common_service);
1702 #endif /* EMLXS_MODREV2X */
1703 
1704 	port_info->pi_login_params.common_service.btob_credit = 0xffff;
1705 
1706 	bcopy((void *) &port->wwnn,
1707 	    (void *) &port_info->pi_login_params.node_ww_name,
1708 	    sizeof (NAME_TYPE));
1709 
1710 	bcopy((void *) &port->wwpn,
1711 	    (void *) &port_info->pi_login_params.nport_ww_name,
1712 	    sizeof (NAME_TYPE));
1713 
1714 	/*
1715 	 * We need to turn off CLASS2 support.
1716 	 * Otherwise, FC transport will use CLASS2 as default class
1717 	 * and never try with CLASS3.
1718 	 */
1719 #if (EMLXS_MODREV >= EMLXS_MODREV3)
1720 #if (EMLXS_MODREVX >= EMLXS_MODREV3X)
1721 	if ((port_info->pi_login_params.class_1.class_opt) & 0x0080) {
1722 		port_info->pi_login_params.class_1.class_opt &= ~0x0080;
1723 	}
1724 
1725 	if ((port_info->pi_login_params.class_2.class_opt) & 0x0080) {
1726 		port_info->pi_login_params.class_2.class_opt &= ~0x0080;
1727 	}
1728 #else	/* EMLXS_SPARC or EMLXS_MODREV2X */
1729 	if ((port_info->pi_login_params.class_1.class_opt) & 0x8000) {
1730 		port_info->pi_login_params.class_1.class_opt &= ~0x8000;
1731 	}
1732 
1733 	if ((port_info->pi_login_params.class_2.class_opt) & 0x8000) {
1734 		port_info->pi_login_params.class_2.class_opt &= ~0x8000;
1735 	}
1736 #endif	/* >= EMLXS_MODREV3X */
1737 #endif	/* >= EMLXS_MODREV3 */
1738 
1739 
1740 #if (EMLXS_MODREV <= EMLXS_MODREV2)
1741 	if ((port_info->pi_login_params.class_1.data[0]) & 0x80) {
1742 		port_info->pi_login_params.class_1.data[0] &= ~0x80;
1743 	}
1744 
1745 	if ((port_info->pi_login_params.class_2.data[0]) & 0x80) {
1746 		port_info->pi_login_params.class_2.data[0] &= ~0x80;
1747 	}
1748 #endif	/* <= EMLXS_MODREV2 */
1749 
1750 	/* Additional parameters */
1751 	port_info->pi_s_id.port_id = port->did;
1752 	port_info->pi_s_id.priv_lilp_posit = 0;
1753 	port_info->pi_hard_addr.hard_addr = cfg[CFG_ASSIGN_ALPA].current;
1754 
1755 	/* Initialize the RNID parameters */
1756 	bzero(&port_info->pi_rnid_params, sizeof (port_info->pi_rnid_params));
1757 
1758 	(void) snprintf((char *)port_info->pi_rnid_params.params.global_id,
1759 	    (sizeof (port_info->pi_rnid_params.params.global_id)-1),
1760 	    "%01x%01x%02x%02x%02x%02x%02x%02x%02x", hba->wwpn.nameType,
1761 	    hba->wwpn.IEEEextMsn, hba->wwpn.IEEEextLsb, hba->wwpn.IEEE[0],
1762 	    hba->wwpn.IEEE[1], hba->wwpn.IEEE[2], hba->wwpn.IEEE[3],
1763 	    hba->wwpn.IEEE[4], hba->wwpn.IEEE[5]);
1764 
1765 	port_info->pi_rnid_params.params.unit_type  = RNID_HBA;
1766 	port_info->pi_rnid_params.params.port_id    = port->did;
1767 	port_info->pi_rnid_params.params.ip_version = RNID_IPV4;
1768 
1769 	/* Initialize the port attributes */
1770 	bzero(&port_info->pi_attrs, sizeof (port_info->pi_attrs));
1771 
1772 	(void) strncpy(port_info->pi_attrs.manufacturer, "Emulex",
1773 	    (sizeof (port_info->pi_attrs.manufacturer)-1));
1774 
1775 	port_info->pi_rnid_params.status = FC_SUCCESS;
1776 
1777 	(void) strncpy(port_info->pi_attrs.serial_number, vpd->serial_num,
1778 	    (sizeof (port_info->pi_attrs.serial_number)-1));
1779 
1780 	(void) snprintf(port_info->pi_attrs.firmware_version,
1781 	    (sizeof (port_info->pi_attrs.firmware_version)-1), "%s (%s)",
1782 	    vpd->fw_version, vpd->fw_label);
1783 
1784 #ifdef EMLXS_I386
1785 	(void) snprintf(port_info->pi_attrs.option_rom_version,
1786 	    (sizeof (port_info->pi_attrs.option_rom_version)-1),
1787 	    "Boot:%s", vpd->boot_version);
1788 #else	/* EMLXS_SPARC */
1789 	(void) snprintf(port_info->pi_attrs.option_rom_version,
1790 	    (sizeof (port_info->pi_attrs.option_rom_version)-1),
1791 	    "Boot:%s Fcode:%s", vpd->boot_version, vpd->fcode_version);
1792 #endif	/* EMLXS_I386 */
1793 
1794 	(void) snprintf(port_info->pi_attrs.driver_version,
1795 	    (sizeof (port_info->pi_attrs.driver_version)-1), "%s (%s)",
1796 	    emlxs_version, emlxs_revision);
1797 
1798 	(void) strncpy(port_info->pi_attrs.driver_name, DRIVER_NAME,
1799 	    (sizeof (port_info->pi_attrs.driver_name)-1));
1800 
1801 	port_info->pi_attrs.vendor_specific_id =
1802 	    (hba->model_info.device_id << 16) | hba->model_info.vendor_id;
1803 
1804 	port_info->pi_attrs.supported_cos = LE_SWAP32(FC_NS_CLASS3);
1805 
1806 	port_info->pi_attrs.max_frame_size = FF_FRAME_SIZE;
1807 
1808 #if (EMLXS_MODREV >= EMLXS_MODREV3)
1809 	port_info->pi_rnid_params.params.num_attached = 0;
1810 
1811 	if ((hba->model_info.chip & EMLXS_LANCER_CHIPS) != 0) {
1812 		uint8_t		byte;
1813 		uint8_t		*wwpn;
1814 		uint32_t	i;
1815 		uint32_t	j;
1816 
1817 		/* Copy the WWPN as a string into the local buffer */
1818 		wwpn = (uint8_t *)&hba->wwpn;
1819 		for (i = 0; i < 16; i++) {
1820 			byte = *wwpn++;
1821 			j = ((byte & 0xf0) >> 4);
1822 			if (j <= 9) {
1823 				buffer[i] =
1824 				    (char)((uint8_t)'0' + (uint8_t)j);
1825 			} else {
1826 				buffer[i] =
1827 				    (char)((uint8_t)'A' + (uint8_t)(j -
1828 				    10));
1829 			}
1830 
1831 			i++;
1832 			j = (byte & 0xf);
1833 			if (j <= 9) {
1834 				buffer[i] =
1835 				    (char)((uint8_t)'0' + (uint8_t)j);
1836 			} else {
1837 				buffer[i] =
1838 				    (char)((uint8_t)'A' + (uint8_t)(j -
1839 				    10));
1840 			}
1841 		}
1842 
1843 		port_info->pi_attrs.hba_fru_details.port_index = 0;
1844 #if ((EMLXS_MODREV == EMLXS_MODREV3) || (EMLXS_MODREV == EMLXS_MODREV4))
1845 
1846 	} else if (hba->flag & FC_NPIV_ENABLED) {
1847 		uint8_t		byte;
1848 		uint8_t		*wwpn;
1849 		uint32_t	i;
1850 		uint32_t	j;
1851 
1852 		/* Copy the WWPN as a string into the local buffer */
1853 		wwpn = (uint8_t *)&hba->wwpn;
1854 		for (i = 0; i < 16; i++) {
1855 			byte = *wwpn++;
1856 			j = ((byte & 0xf0) >> 4);
1857 			if (j <= 9) {
1858 				buffer[i] =
1859 				    (char)((uint8_t)'0' + (uint8_t)j);
1860 			} else {
1861 				buffer[i] =
1862 				    (char)((uint8_t)'A' + (uint8_t)(j -
1863 				    10));
1864 			}
1865 
1866 			i++;
1867 			j = (byte & 0xf);
1868 			if (j <= 9) {
1869 				buffer[i] =
1870 				    (char)((uint8_t)'0' + (uint8_t)j);
1871 			} else {
1872 				buffer[i] =
1873 				    (char)((uint8_t)'A' + (uint8_t)(j -
1874 				    10));
1875 			}
1876 		}
1877 
1878 		port_info->pi_attrs.hba_fru_details.port_index = port->vpi;
1879 #endif /* == EMLXS_MODREV3 || EMLXS_MODREV4 */
1880 
1881 	} else {
1882 		/* Copy the serial number string (right most 16 chars) */
1883 		/* into the right justified local buffer */
1884 		bzero(buffer, sizeof (buffer));
1885 		length = strlen(vpd->serial_num);
1886 		len = (length > 16) ? 16 : length;
1887 		bcopy(&vpd->serial_num[(length - len)],
1888 		    &buffer[(sizeof (buffer) - len)], len);
1889 
1890 		port_info->pi_attrs.hba_fru_details.port_index =
1891 		    vpd->port_index;
1892 	}
1893 
1894 	dptr = (char *)&port_info->pi_attrs.hba_fru_details.high;
1895 	dptr[0] = buffer[0];
1896 	dptr[1] = buffer[1];
1897 	dptr[2] = buffer[2];
1898 	dptr[3] = buffer[3];
1899 	dptr[4] = buffer[4];
1900 	dptr[5] = buffer[5];
1901 	dptr[6] = buffer[6];
1902 	dptr[7] = buffer[7];
1903 	port_info->pi_attrs.hba_fru_details.high =
1904 	    LE_SWAP64(port_info->pi_attrs.hba_fru_details.high);
1905 
1906 	dptr = (char *)&port_info->pi_attrs.hba_fru_details.low;
1907 	dptr[0] = buffer[8];
1908 	dptr[1] = buffer[9];
1909 	dptr[2] = buffer[10];
1910 	dptr[3] = buffer[11];
1911 	dptr[4] = buffer[12];
1912 	dptr[5] = buffer[13];
1913 	dptr[6] = buffer[14];
1914 	dptr[7] = buffer[15];
1915 	port_info->pi_attrs.hba_fru_details.low =
1916 	    LE_SWAP64(port_info->pi_attrs.hba_fru_details.low);
1917 
1918 #endif /* >= EMLXS_MODREV3 */
1919 
1920 #if (EMLXS_MODREV >= EMLXS_MODREV4)
1921 	(void) strncpy((caddr_t)port_info->pi_attrs.sym_node_name,
1922 	    (caddr_t)port->snn, FCHBA_SYMB_NAME_LEN);
1923 	(void) strncpy((caddr_t)port_info->pi_attrs.sym_port_name,
1924 	    (caddr_t)port->spn, FCHBA_SYMB_NAME_LEN);
1925 #endif	/* >= EMLXS_MODREV4 */
1926 
1927 	(void) snprintf(port_info->pi_attrs.hardware_version,
1928 	    (sizeof (port_info->pi_attrs.hardware_version)-1),
1929 	    "%x", vpd->biuRev);
1930 
1931 	/* Set the hba speed limit */
1932 	if (vpd->link_speed & LMT_32GB_CAPABLE) {
1933 		port_info->pi_attrs.supported_speed |=
1934 		    FC_HBA_PORTSPEED_32GBIT;
1935 	}
1936 	if (vpd->link_speed & LMT_16GB_CAPABLE) {
1937 		port_info->pi_attrs.supported_speed |=
1938 		    FC_HBA_PORTSPEED_16GBIT;
1939 	}
1940 	if (vpd->link_speed & LMT_10GB_CAPABLE) {
1941 		port_info->pi_attrs.supported_speed |=
1942 		    FC_HBA_PORTSPEED_10GBIT;
1943 	}
1944 	if (vpd->link_speed & LMT_8GB_CAPABLE) {
1945 		port_info->pi_attrs.supported_speed |= FC_HBA_PORTSPEED_8GBIT;
1946 	}
1947 	if (vpd->link_speed & LMT_4GB_CAPABLE) {
1948 		port_info->pi_attrs.supported_speed |= FC_HBA_PORTSPEED_4GBIT;
1949 	}
1950 	if (vpd->link_speed & LMT_2GB_CAPABLE) {
1951 		port_info->pi_attrs.supported_speed |= FC_HBA_PORTSPEED_2GBIT;
1952 	}
1953 	if (vpd->link_speed & LMT_1GB_CAPABLE) {
1954 		port_info->pi_attrs.supported_speed |= FC_HBA_PORTSPEED_1GBIT;
1955 	}
1956 
1957 	/* Set the hba model info */
1958 	(void) strncpy(port_info->pi_attrs.model, hba->model_info.model,
1959 	    (sizeof (port_info->pi_attrs.model)-1));
1960 	(void) strncpy(port_info->pi_attrs.model_description,
1961 	    hba->model_info.model_desc,
1962 	    (sizeof (port_info->pi_attrs.model_description)-1));
1963 
1964 
1965 	/* Log information */
1966 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1967 	    "Bind info: port_num           = %d", bind_info->port_num);
1968 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1969 	    "Bind info: port_handle        = %p", bind_info->port_handle);
1970 
1971 #if (EMLXS_MODREV >= EMLXS_MODREV5)
1972 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1973 	    "Bind info: port_npiv          = %d", bind_info->port_npiv);
1974 #endif /* >= EMLXS_MODREV5 */
1975 
1976 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1977 	    "Port info: pi_topology        = %x", port_info->pi_topology);
1978 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1979 	    "Port info: pi_error           = %x", port_info->pi_error);
1980 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1981 	    "Port info: pi_port_state      = %x", port_info->pi_port_state);
1982 
1983 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1984 	    "Port info: port_id            = %x", port_info->pi_s_id.port_id);
1985 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1986 	    "Port info: priv_lilp_posit    = %x",
1987 	    port_info->pi_s_id.priv_lilp_posit);
1988 
1989 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1990 	    "Port info: hard_addr          = %x",
1991 	    port_info->pi_hard_addr.hard_addr);
1992 
1993 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1994 	    "Port info: rnid.status        = %x",
1995 	    port_info->pi_rnid_params.status);
1996 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
1997 	    "Port info: rnid.global_id     = %16s",
1998 	    port_info->pi_rnid_params.params.global_id);
1999 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2000 	    "Port info: rnid.unit_type     = %x",
2001 	    port_info->pi_rnid_params.params.unit_type);
2002 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2003 	    "Port info: rnid.port_id       = %x",
2004 	    port_info->pi_rnid_params.params.port_id);
2005 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2006 	    "Port info: rnid.num_attached  = %x",
2007 	    port_info->pi_rnid_params.params.num_attached);
2008 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2009 	    "Port info: rnid.ip_version    = %x",
2010 	    port_info->pi_rnid_params.params.ip_version);
2011 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2012 	    "Port info: rnid.udp_port      = %x",
2013 	    port_info->pi_rnid_params.params.udp_port);
2014 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2015 	    "Port info: rnid.ip_addr       = %16s",
2016 	    port_info->pi_rnid_params.params.ip_addr);
2017 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2018 	    "Port info: rnid.spec_id_resv  = %x",
2019 	    port_info->pi_rnid_params.params.specific_id_resv);
2020 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2021 	    "Port info: rnid.topo_flags    = %x",
2022 	    port_info->pi_rnid_params.params.topo_flags);
2023 
2024 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2025 	    "Port info: manufacturer       = %s",
2026 	    port_info->pi_attrs.manufacturer);
2027 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2028 	    "Port info: serial_num         = %s",
2029 	    port_info->pi_attrs.serial_number);
2030 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2031 	    "Port info: model              = %s", port_info->pi_attrs.model);
2032 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2033 	    "Port info: model_description  = %s",
2034 	    port_info->pi_attrs.model_description);
2035 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2036 	    "Port info: hardware_version   = %s",
2037 	    port_info->pi_attrs.hardware_version);
2038 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2039 	    "Port info: driver_version     = %s",
2040 	    port_info->pi_attrs.driver_version);
2041 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2042 	    "Port info: option_rom_version = %s",
2043 	    port_info->pi_attrs.option_rom_version);
2044 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2045 	    "Port info: firmware_version   = %s",
2046 	    port_info->pi_attrs.firmware_version);
2047 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2048 	    "Port info: driver_name        = %s",
2049 	    port_info->pi_attrs.driver_name);
2050 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2051 	    "Port info: vendor_specific_id = %x",
2052 	    port_info->pi_attrs.vendor_specific_id);
2053 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2054 	    "Port info: supported_cos      = %x",
2055 	    port_info->pi_attrs.supported_cos);
2056 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2057 	    "Port info: supported_speed    = %x",
2058 	    port_info->pi_attrs.supported_speed);
2059 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2060 	    "Port info: max_frame_size     = %x",
2061 	    port_info->pi_attrs.max_frame_size);
2062 
2063 #if (EMLXS_MODREV >= EMLXS_MODREV3)
2064 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2065 	    "Port info: fru_port_index     = %x",
2066 	    port_info->pi_attrs.hba_fru_details.port_index);
2067 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2068 	    "Port info: fru_high           = %llx",
2069 	    port_info->pi_attrs.hba_fru_details.high);
2070 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2071 	    "Port info: fru_low            = %llx",
2072 	    port_info->pi_attrs.hba_fru_details.low);
2073 #endif	/* >= EMLXS_MODREV3 */
2074 
2075 #if (EMLXS_MODREV >= EMLXS_MODREV4)
2076 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2077 	    "Port info: sym_node_name      = %s",
2078 	    port_info->pi_attrs.sym_node_name);
2079 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
2080 	    "Port info: sym_port_name      = %s",
2081 	    port_info->pi_attrs.sym_port_name);
2082 #endif	/* >= EMLXS_MODREV4 */
2083 
2084 	mutex_exit(&EMLXS_PORT_LOCK);
2085 
2086 #ifdef SFCT_SUPPORT
2087 	if (port->flag & EMLXS_TGT_ENABLED) {
2088 		emlxs_fct_bind_port(port);
2089 	}
2090 #endif /* SFCT_SUPPORT */
2091 
2092 	return ((opaque_t)port);
2093 
2094 } /* emlxs_fca_bind_port() */
2095 
2096 
2097 static void
emlxs_fca_unbind_port(opaque_t fca_port_handle)2098 emlxs_fca_unbind_port(opaque_t fca_port_handle)
2099 {
2100 	emlxs_port_t *port = (emlxs_port_t *)fca_port_handle;
2101 	emlxs_hba_t *hba = HBA;
2102 
2103 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2104 	    "fca_unbind_port: port=%p", port);
2105 
2106 	if (!(port->flag & EMLXS_PORT_BOUND)) {
2107 		return;
2108 	}
2109 
2110 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2111 		(void) emlxs_vpi_port_unbind_notify(port, 1);
2112 	}
2113 
2114 	/* Destroy & flush all port nodes, if they exist */
2115 	if (port->node_count) {
2116 		(void) EMLXS_SLI_UNREG_NODE(port, 0, 0, 0, 0);
2117 	}
2118 
2119 #if (EMLXS_MODREV >= EMLXS_MODREV5)
2120 	if ((hba->sli_mode <= EMLXS_HBA_SLI3_MODE) &&
2121 	    (hba->flag & FC_NPIV_ENABLED) &&
2122 	    (port->flag & (EMLXS_PORT_CONFIG | EMLXS_PORT_ENABLED))) {
2123 		(void) emlxs_mb_unreg_vpi(port);
2124 	}
2125 #endif
2126 
2127 	mutex_enter(&EMLXS_PORT_LOCK);
2128 	if (port->flag & EMLXS_INI_BOUND) {
2129 #if (EMLXS_MODREV >= EMLXS_MODREV5)
2130 		port->flag &= ~(EMLXS_PORT_CONFIG | EMLXS_PORT_ENABLED);
2131 #endif
2132 		port->flag &= ~EMLXS_INI_BOUND;
2133 		hba->num_of_ports--;
2134 
2135 		/* Wait until ulp callback interface is idle */
2136 		while (port->ulp_busy) {
2137 			mutex_exit(&EMLXS_PORT_LOCK);
2138 			delay(drv_usectohz(500000));
2139 			mutex_enter(&EMLXS_PORT_LOCK);
2140 		}
2141 
2142 		port->ulp_handle = 0;
2143 		port->ulp_statec = FC_STATE_OFFLINE;
2144 		port->ulp_statec_cb = NULL;
2145 		port->ulp_unsol_cb = NULL;
2146 	}
2147 	mutex_exit(&EMLXS_PORT_LOCK);
2148 
2149 #ifdef SFCT_SUPPORT
2150 	/* Check if port was target bound */
2151 	if (port->flag & EMLXS_TGT_BOUND) {
2152 		emlxs_fct_unbind_port(port);
2153 	}
2154 #endif /* SFCT_SUPPORT */
2155 
2156 	return;
2157 
2158 } /* emlxs_fca_unbind_port() */
2159 
2160 
2161 /*ARGSUSED*/
2162 extern int
emlxs_fca_pkt_init(opaque_t fca_port_handle,fc_packet_t * pkt,int32_t sleep)2163 emlxs_fca_pkt_init(opaque_t fca_port_handle, fc_packet_t *pkt, int32_t sleep)
2164 {
2165 	emlxs_port_t *port = (emlxs_port_t *)fca_port_handle;
2166 	emlxs_hba_t  *hba = HBA;
2167 	emlxs_buf_t  *sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
2168 
2169 	if (!sbp) {
2170 		return (FC_FAILURE);
2171 	}
2172 	bzero((void *)sbp, sizeof (emlxs_buf_t));
2173 
2174 	mutex_init(&sbp->mtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(hba->intr_arg));
2175 	sbp->pkt_flags =
2176 	    PACKET_VALID | PACKET_ULP_OWNED;
2177 	sbp->port = port;
2178 	sbp->pkt = pkt;
2179 	sbp->iocbq.sbp = sbp;
2180 
2181 	return (FC_SUCCESS);
2182 
2183 } /* emlxs_fca_pkt_init() */
2184 
2185 
2186 
2187 static void
emlxs_initialize_pkt(emlxs_port_t * port,emlxs_buf_t * sbp)2188 emlxs_initialize_pkt(emlxs_port_t *port, emlxs_buf_t *sbp)
2189 {
2190 	emlxs_hba_t *hba = HBA;
2191 	emlxs_config_t *cfg = &CFG;
2192 	fc_packet_t *pkt = PRIV2PKT(sbp);
2193 
2194 	mutex_enter(&sbp->mtx);
2195 
2196 	/* Reinitialize */
2197 	sbp->pkt   = pkt;
2198 	sbp->port  = port;
2199 	sbp->bmp   = NULL;
2200 	sbp->pkt_flags &= (PACKET_VALID | PACKET_ALLOCATED);
2201 	sbp->iotag = 0;
2202 	sbp->ticks = 0;
2203 	sbp->abort_attempts = 0;
2204 	sbp->fpkt  = NULL;
2205 	sbp->flush_count = 0;
2206 	sbp->next  = NULL;
2207 
2208 	if (port->mode == MODE_INITIATOR) {
2209 		sbp->node  = NULL;
2210 		sbp->did   = 0;
2211 		sbp->lun   = EMLXS_LUN_NONE;
2212 		sbp->class = 0;
2213 		sbp->channel  = NULL;
2214 	}
2215 
2216 	bzero((void *)&sbp->iocbq, sizeof (IOCBQ));
2217 	sbp->iocbq.sbp = sbp;
2218 
2219 	if ((pkt->pkt_tran_flags & FC_TRAN_NO_INTR) || !pkt->pkt_comp ||
2220 	    ddi_in_panic()) {
2221 		sbp->pkt_flags |= PACKET_POLLED;
2222 	}
2223 
2224 	/* Prepare the fc packet */
2225 	pkt->pkt_state = FC_PKT_SUCCESS;
2226 	pkt->pkt_reason = 0;
2227 	pkt->pkt_action = 0;
2228 	pkt->pkt_expln = 0;
2229 	pkt->pkt_data_resid = 0;
2230 	pkt->pkt_resp_resid = 0;
2231 
2232 	/* Make sure all pkt's have a proper timeout */
2233 	if (!cfg[CFG_TIMEOUT_ENABLE].current) {
2234 		/* This disables all IOCB on chip timeouts */
2235 		pkt->pkt_timeout = 0x80000000;
2236 	} else if (pkt->pkt_timeout == 0 || pkt->pkt_timeout == 0xffffffff) {
2237 		pkt->pkt_timeout = 60;
2238 	}
2239 
2240 	/* Clear the response buffer */
2241 	if (pkt->pkt_rsplen) {
2242 		bzero(pkt->pkt_resp, pkt->pkt_rsplen);
2243 	}
2244 
2245 	mutex_exit(&sbp->mtx);
2246 
2247 	return;
2248 
2249 } /* emlxs_initialize_pkt() */
2250 
2251 
2252 
2253 /*
2254  * We may not need this routine
2255  */
2256 /*ARGSUSED*/
2257 extern int
emlxs_fca_pkt_uninit(opaque_t fca_port_handle,fc_packet_t * pkt)2258 emlxs_fca_pkt_uninit(opaque_t fca_port_handle, fc_packet_t *pkt)
2259 {
2260 	emlxs_buf_t  *sbp = PKT2PRIV(pkt);
2261 
2262 	if (!sbp) {
2263 		return (FC_FAILURE);
2264 	}
2265 
2266 	if (!(sbp->pkt_flags & PACKET_VALID)) {
2267 		return (FC_FAILURE);
2268 	}
2269 	sbp->pkt_flags &= ~PACKET_VALID;
2270 	mutex_destroy(&sbp->mtx);
2271 
2272 	return (FC_SUCCESS);
2273 
2274 } /* emlxs_fca_pkt_uninit() */
2275 
2276 
2277 static int
emlxs_fca_get_cap(opaque_t fca_port_handle,char * cap,void * ptr)2278 emlxs_fca_get_cap(opaque_t fca_port_handle, char *cap, void *ptr)
2279 {
2280 	emlxs_port_t *port = (emlxs_port_t *)fca_port_handle;
2281 	emlxs_hba_t  *hba = HBA;
2282 	int32_t rval;
2283 	emlxs_config_t *cfg = &CFG;
2284 
2285 	if (!(port->flag & EMLXS_INI_BOUND)) {
2286 		return (FC_CAP_ERROR);
2287 	}
2288 
2289 	if (strcmp(cap, FC_NODE_WWN) == 0) {
2290 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2291 		    "fca_get_cap: FC_NODE_WWN");
2292 
2293 		bcopy((void *)&hba->wwnn, (void *)ptr, sizeof (NAME_TYPE));
2294 		rval = FC_CAP_FOUND;
2295 
2296 	} else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
2297 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2298 		    "fca_get_cap: FC_LOGIN_PARAMS");
2299 
2300 		/*
2301 		 * We need to turn off CLASS2 support.
2302 		 * Otherwise, FC transport will use CLASS2 as default class
2303 		 * and never try with CLASS3.
2304 		 */
2305 		hba->sparam.cls2.classValid = 0;
2306 
2307 		bcopy((void *)&hba->sparam, (void *)ptr, sizeof (SERV_PARM));
2308 
2309 		rval = FC_CAP_FOUND;
2310 
2311 	} else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
2312 		int32_t		*num_bufs;
2313 
2314 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2315 		    "fca_get_cap: FC_CAP_UNSOL_BUF (%d)",
2316 		    cfg[CFG_UB_BUFS].current);
2317 
2318 		num_bufs = (int32_t *)ptr;
2319 
2320 		/* We multiply by MAX_VPORTS because ULP uses a */
2321 		/* formula to calculate ub bufs from this */
2322 		*num_bufs = (cfg[CFG_UB_BUFS].current * MAX_VPORTS);
2323 
2324 		rval = FC_CAP_FOUND;
2325 
2326 	} else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
2327 		int32_t		*size;
2328 
2329 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2330 		    "fca_get_cap: FC_CAP_PAYLOAD_SIZE");
2331 
2332 		size = (int32_t *)ptr;
2333 		*size = -1;
2334 		rval = FC_CAP_FOUND;
2335 
2336 	} else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
2337 		fc_reset_action_t *action;
2338 
2339 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2340 		    "fca_get_cap: FC_CAP_POST_RESET_BEHAVIOR");
2341 
2342 		action = (fc_reset_action_t *)ptr;
2343 		*action = FC_RESET_RETURN_ALL;
2344 		rval = FC_CAP_FOUND;
2345 
2346 	} else if (strcmp(cap, FC_CAP_NOSTREAM_ON_UNALIGN_BUF) == 0) {
2347 		fc_dma_behavior_t *behavior;
2348 
2349 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2350 		    "fca_get_cap: FC_CAP_NOSTREAM_ON_UNALIGN_BUF");
2351 
2352 		behavior = (fc_dma_behavior_t *)ptr;
2353 		*behavior = FC_ALLOW_STREAMING;
2354 		rval = FC_CAP_FOUND;
2355 
2356 	} else if (strcmp(cap, FC_CAP_FCP_DMA) == 0) {
2357 		fc_fcp_dma_t   *fcp_dma;
2358 
2359 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2360 		    "fca_get_cap: FC_CAP_FCP_DMA");
2361 
2362 		fcp_dma = (fc_fcp_dma_t *)ptr;
2363 		*fcp_dma = FC_DVMA_SPACE;
2364 		rval = FC_CAP_FOUND;
2365 
2366 	} else {
2367 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2368 		    "fca_get_cap: Unknown capability. [%s]", cap);
2369 
2370 		rval = FC_CAP_ERROR;
2371 
2372 	}
2373 
2374 	return (rval);
2375 
2376 } /* emlxs_fca_get_cap() */
2377 
2378 
2379 
2380 static int
emlxs_fca_set_cap(opaque_t fca_port_handle,char * cap,void * ptr)2381 emlxs_fca_set_cap(opaque_t fca_port_handle, char *cap, void *ptr)
2382 {
2383 	emlxs_port_t *port = (emlxs_port_t *)fca_port_handle;
2384 
2385 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2386 	    "fca_set_cap: cap=[%s] arg=%p", cap, ptr);
2387 
2388 	return (FC_CAP_ERROR);
2389 
2390 } /* emlxs_fca_set_cap() */
2391 
2392 
2393 static opaque_t
emlxs_fca_get_device(opaque_t fca_port_handle,fc_portid_t d_id)2394 emlxs_fca_get_device(opaque_t fca_port_handle, fc_portid_t d_id)
2395 {
2396 	emlxs_port_t *port = (emlxs_port_t *)fca_port_handle;
2397 
2398 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2399 	    "fca_get_device: did=%x", d_id.port_id);
2400 
2401 	return (NULL);
2402 
2403 } /* emlxs_fca_get_device() */
2404 
2405 
2406 static int32_t
emlxs_fca_notify(opaque_t fca_port_handle,uint32_t cmd)2407 emlxs_fca_notify(opaque_t fca_port_handle, uint32_t cmd)
2408 {
2409 	emlxs_port_t *port = (emlxs_port_t *)fca_port_handle;
2410 
2411 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, "fca_notify: cmd=%x",
2412 	    cmd);
2413 
2414 	return (FC_SUCCESS);
2415 
2416 } /* emlxs_fca_notify */
2417 
2418 
2419 
2420 static int
emlxs_fca_get_map(opaque_t fca_port_handle,fc_lilpmap_t * mapbuf)2421 emlxs_fca_get_map(opaque_t fca_port_handle, fc_lilpmap_t *mapbuf)
2422 {
2423 	emlxs_port_t	*port = (emlxs_port_t *)fca_port_handle;
2424 	emlxs_hba_t	*hba = HBA;
2425 	uint32_t	lilp_length;
2426 
2427 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2428 	    "fca_get_map: mapbuf=%p length=%d (%X,%X,%X,%X)", mapbuf,
2429 	    port->alpa_map[0], port->alpa_map[1], port->alpa_map[2],
2430 	    port->alpa_map[3], port->alpa_map[4]);
2431 
2432 	if (!(port->flag & EMLXS_INI_BOUND)) {
2433 		return (FC_NOMAP);
2434 	}
2435 
2436 	if (hba->topology != TOPOLOGY_LOOP) {
2437 		return (FC_NOMAP);
2438 	}
2439 
2440 	/* Check if alpa map is available */
2441 	if (port->alpa_map[0] != 0) {
2442 		mapbuf->lilp_magic  = MAGIC_LILP;
2443 	} else {	/* No LILP map available */
2444 
2445 		/* Set lilp_magic to MAGIC_LISA and this will */
2446 		/* trigger an ALPA scan in ULP */
2447 		mapbuf->lilp_magic  = MAGIC_LISA;
2448 	}
2449 
2450 	mapbuf->lilp_myalpa = port->did;
2451 
2452 	/* The first byte of the alpa_map is the lilp map length */
2453 	/* Add one to include the lilp length byte itself */
2454 	lilp_length = (uint32_t)port->alpa_map[0] + 1;
2455 
2456 	/* Make sure the max transfer is 128 bytes */
2457 	if (lilp_length > 128) {
2458 		lilp_length = 128;
2459 	}
2460 
2461 	/* We start copying from the lilp_length field */
2462 	/* in order to get a word aligned address */
2463 	bcopy((void *)&port->alpa_map, (void *)&mapbuf->lilp_length,
2464 	    lilp_length);
2465 
2466 	return (FC_SUCCESS);
2467 
2468 } /* emlxs_fca_get_map() */
2469 
2470 
2471 
2472 extern int
emlxs_fca_transport(opaque_t fca_port_handle,fc_packet_t * pkt)2473 emlxs_fca_transport(opaque_t fca_port_handle, fc_packet_t *pkt)
2474 {
2475 	emlxs_port_t	*port = (emlxs_port_t *)fca_port_handle;
2476 	emlxs_hba_t	*hba = HBA;
2477 	emlxs_buf_t	*sbp;
2478 	uint32_t	rval;
2479 	uint32_t	pkt_flags;
2480 
2481 	/* Validate packet */
2482 	sbp = PKT2PRIV(pkt);
2483 
2484 	/* Make sure adapter is online */
2485 	if (!(hba->flag & FC_ONLINE_MODE) &&
2486 	    !(sbp->pkt_flags & PACKET_ALLOCATED)) {
2487 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg,
2488 		    "Adapter offline.");
2489 
2490 		rval = (hba->flag & FC_ONLINING_MODE) ?
2491 		    FC_TRAN_BUSY : FC_OFFLINE;
2492 		return (rval);
2493 	}
2494 
2495 	/* Make sure ULP was told that the port was online */
2496 	if ((port->ulp_statec == FC_STATE_OFFLINE) &&
2497 	    !(sbp->pkt_flags & PACKET_ALLOCATED)) {
2498 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
2499 		    "Port offline.");
2500 
2501 		return (FC_OFFLINE);
2502 	}
2503 
2504 	if (sbp->port != port) {
2505 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_error_msg,
2506 		    "Invalid port handle. sbp=%p port=%p flags=%x", sbp,
2507 		    sbp->port, sbp->pkt_flags);
2508 		return (FC_BADPACKET);
2509 	}
2510 
2511 	if (!(sbp->pkt_flags & (PACKET_VALID | PACKET_ULP_OWNED))) {
2512 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_error_msg,
2513 		    "Invalid packet flags. sbp=%p port=%p flags=%x", sbp,
2514 		    sbp->port, sbp->pkt_flags);
2515 		return (FC_BADPACKET);
2516 	}
2517 
2518 #ifdef SFCT_SUPPORT
2519 	if ((port->mode == MODE_TARGET) && !sbp->fct_cmd &&
2520 	    !(sbp->pkt_flags & PACKET_ALLOCATED)) {
2521 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_error_msg,
2522 		    "Packet blocked. Target mode.");
2523 		return (FC_TRANSPORT_ERROR);
2524 	}
2525 #endif /* SFCT_SUPPORT */
2526 
2527 #ifdef IDLE_TIMER
2528 	emlxs_pm_busy_component(hba);
2529 #endif	/* IDLE_TIMER */
2530 
2531 	/* Prepare the packet for transport */
2532 	emlxs_initialize_pkt(port, sbp);
2533 
2534 	/* Save a copy of the pkt flags. */
2535 	/* We will check the polling flag later */
2536 	pkt_flags = sbp->pkt_flags;
2537 
2538 	/* Send the packet */
2539 	switch (pkt->pkt_tran_type) {
2540 	case FC_PKT_FCP_READ:
2541 	case FC_PKT_FCP_WRITE:
2542 		rval = emlxs_send_fcp_cmd(port, sbp, &pkt_flags);
2543 		break;
2544 
2545 	case FC_PKT_IP_WRITE:
2546 	case FC_PKT_BROADCAST:
2547 		rval = emlxs_send_ip(port, sbp);
2548 		break;
2549 
2550 	case FC_PKT_EXCHANGE:
2551 		switch (pkt->pkt_cmd_fhdr.type) {
2552 		case FC_TYPE_SCSI_FCP:
2553 			rval = emlxs_send_fcp_cmd(port, sbp, &pkt_flags);
2554 			break;
2555 
2556 		case FC_TYPE_FC_SERVICES:
2557 			rval = emlxs_send_ct(port, sbp);
2558 			break;
2559 
2560 #ifdef MENLO_SUPPORT
2561 		case EMLXS_MENLO_TYPE:
2562 			rval = emlxs_send_menlo(port, sbp);
2563 			break;
2564 #endif /* MENLO_SUPPORT */
2565 
2566 		default:
2567 			rval = emlxs_send_els(port, sbp);
2568 		}
2569 		break;
2570 
2571 	case FC_PKT_OUTBOUND:
2572 		switch (pkt->pkt_cmd_fhdr.type) {
2573 #ifdef SFCT_SUPPORT
2574 		case FC_TYPE_SCSI_FCP:
2575 			rval = emlxs_send_fct_status(port, sbp);
2576 			break;
2577 
2578 		case FC_TYPE_BASIC_LS:
2579 			rval = emlxs_send_fct_abort(port, sbp);
2580 			break;
2581 #endif /* SFCT_SUPPORT */
2582 
2583 		case FC_TYPE_FC_SERVICES:
2584 			rval = emlxs_send_ct_rsp(port, sbp);
2585 			break;
2586 #ifdef MENLO_SUPPORT
2587 		case EMLXS_MENLO_TYPE:
2588 			rval = emlxs_send_menlo(port, sbp);
2589 			break;
2590 #endif /* MENLO_SUPPORT */
2591 
2592 		default:
2593 			rval = emlxs_send_els_rsp(port, sbp);
2594 		}
2595 		break;
2596 
2597 	default:
2598 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_error_msg,
2599 		    "Unsupported pkt_tran_type. type=%x", pkt->pkt_tran_type);
2600 		rval = FC_TRANSPORT_ERROR;
2601 		break;
2602 	}
2603 
2604 	/* Check if send was not successful */
2605 	if (rval != FC_SUCCESS) {
2606 		/* Return packet to ULP */
2607 		mutex_enter(&sbp->mtx);
2608 		sbp->pkt_flags |= PACKET_ULP_OWNED;
2609 		mutex_exit(&sbp->mtx);
2610 
2611 		return (rval);
2612 	}
2613 
2614 	/* Check if this packet should be polled for completion before */
2615 	/* returning. This check must be done with a saved copy of the */
2616 	/* pkt_flags because the packet itself could already be freed from */
2617 	/* memory if it was not polled. */
2618 	if (pkt_flags & PACKET_POLLED) {
2619 		emlxs_poll(port, sbp);
2620 	}
2621 
2622 	return (FC_SUCCESS);
2623 
2624 } /* emlxs_fca_transport() */
2625 
2626 
2627 
2628 static void
emlxs_poll(emlxs_port_t * port,emlxs_buf_t * sbp)2629 emlxs_poll(emlxs_port_t *port, emlxs_buf_t *sbp)
2630 {
2631 	emlxs_hba_t	*hba = HBA;
2632 	fc_packet_t	*pkt = PRIV2PKT(sbp);
2633 	clock_t		timeout;
2634 	clock_t		time;
2635 	CHANNEL	*cp;
2636 	int		in_panic = 0;
2637 
2638 	mutex_enter(&EMLXS_PORT_LOCK);
2639 	hba->io_poll_count++;
2640 	mutex_exit(&EMLXS_PORT_LOCK);
2641 
2642 	/* Check for panic situation */
2643 	cp = (CHANNEL *)sbp->channel;
2644 
2645 	if (ddi_in_panic()) {
2646 		in_panic = 1;
2647 		/*
2648 		 * In panic situations there will be one thread with
2649 		 * no interrrupts (hard or soft) and no timers
2650 		 */
2651 
2652 		/*
2653 		 * We must manually poll everything in this thread
2654 		 * to keep the driver going.
2655 		 */
2656 
2657 		/* Keep polling the chip until our IO is completed */
2658 		/* Driver's timer will not function during panics. */
2659 		/* Therefore, timer checks must be performed manually. */
2660 		(void) drv_getparm(LBOLT, &time);
2661 		timeout = time + drv_usectohz(1000000);
2662 		while (!(sbp->pkt_flags & PACKET_COMPLETED)) {
2663 			EMLXS_SLI_POLL_INTR(hba);
2664 			(void) drv_getparm(LBOLT, &time);
2665 
2666 			/* Trigger timer checks periodically */
2667 			if (time >= timeout) {
2668 				emlxs_timer_checks(hba);
2669 				timeout = time + drv_usectohz(1000000);
2670 			}
2671 		}
2672 	} else {
2673 		/* Wait for IO completion */
2674 		/* The driver's timer will detect */
2675 		/* any timeout and abort the I/O. */
2676 		mutex_enter(&EMLXS_PKT_LOCK);
2677 		while (!(sbp->pkt_flags & PACKET_COMPLETED)) {
2678 			cv_wait(&EMLXS_PKT_CV, &EMLXS_PKT_LOCK);
2679 		}
2680 		mutex_exit(&EMLXS_PKT_LOCK);
2681 	}
2682 
2683 	/* Check for fcp reset pkt */
2684 	if (sbp->pkt_flags & PACKET_FCP_RESET) {
2685 		if (sbp->pkt_flags & PACKET_FCP_TGT_RESET) {
2686 			/* Flush the IO's on the chipq */
2687 			(void) emlxs_chipq_node_flush(port,
2688 			    &hba->chan[hba->channel_fcp],
2689 			    sbp->node, sbp);
2690 		} else {
2691 			/* Flush the IO's on the chipq for this lun */
2692 			(void) emlxs_chipq_lun_flush(port,
2693 			    sbp->node, sbp->lun, sbp);
2694 		}
2695 
2696 		if (sbp->flush_count == 0) {
2697 			emlxs_node_open(port, sbp->node, hba->channel_fcp);
2698 			goto done;
2699 		}
2700 
2701 		/* Set the timeout so the flush has time to complete */
2702 		timeout = emlxs_timeout(hba, 60);
2703 		(void) drv_getparm(LBOLT, &time);
2704 		while ((time < timeout) && sbp->flush_count > 0) {
2705 			delay(drv_usectohz(500000));
2706 			(void) drv_getparm(LBOLT, &time);
2707 		}
2708 
2709 		if (sbp->flush_count == 0) {
2710 			emlxs_node_open(port, sbp->node, hba->channel_fcp);
2711 			goto done;
2712 		}
2713 
2714 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_flush_timeout_msg,
2715 		    "sbp=%p flush_count=%d. Waiting...", sbp,
2716 		    sbp->flush_count);
2717 
2718 		/* Let's try this one more time */
2719 
2720 		if (sbp->pkt_flags & PACKET_FCP_TGT_RESET) {
2721 			/* Flush the IO's on the chipq */
2722 			(void) emlxs_chipq_node_flush(port,
2723 			    &hba->chan[hba->channel_fcp],
2724 			    sbp->node, sbp);
2725 		} else {
2726 			/* Flush the IO's on the chipq for this lun */
2727 			(void) emlxs_chipq_lun_flush(port,
2728 			    sbp->node, sbp->lun, sbp);
2729 		}
2730 
2731 		/* Reset the timeout so the flush has time to complete */
2732 		timeout = emlxs_timeout(hba, 60);
2733 		(void) drv_getparm(LBOLT, &time);
2734 		while ((time < timeout) && sbp->flush_count > 0) {
2735 			delay(drv_usectohz(500000));
2736 			(void) drv_getparm(LBOLT, &time);
2737 		}
2738 
2739 		if (sbp->flush_count == 0) {
2740 			emlxs_node_open(port, sbp->node, hba->channel_fcp);
2741 			goto done;
2742 		}
2743 
2744 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_flush_timeout_msg,
2745 		    "sbp=%p flush_count=%d. Resetting link.", sbp,
2746 		    sbp->flush_count);
2747 
2748 		/* Let's first try to reset the link */
2749 		(void) emlxs_reset(port, FC_FCA_LINK_RESET);
2750 
2751 		if (sbp->flush_count == 0) {
2752 			goto done;
2753 		}
2754 
2755 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_flush_timeout_msg,
2756 		    "sbp=%p flush_count=%d. Resetting HBA.", sbp,
2757 		    sbp->flush_count);
2758 
2759 		/* If that doesn't work, reset the adapter */
2760 		(void) emlxs_reset(port, FC_FCA_RESET);
2761 
2762 		if (sbp->flush_count != 0) {
2763 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_flush_timeout_msg,
2764 			    "sbp=%p flush_count=%d. Giving up.", sbp,
2765 			    sbp->flush_count);
2766 		}
2767 
2768 	}
2769 	/* PACKET_FCP_RESET */
2770 done:
2771 
2772 	/* Packet has been declared completed and is now ready to be returned */
2773 
2774 #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2775 	emlxs_unswap_pkt(sbp);
2776 #endif	/* EMLXS_MODREV2X */
2777 
2778 	mutex_enter(&sbp->mtx);
2779 	sbp->pkt_flags |= PACKET_ULP_OWNED;
2780 	mutex_exit(&sbp->mtx);
2781 
2782 	mutex_enter(&EMLXS_PORT_LOCK);
2783 	hba->io_poll_count--;
2784 	mutex_exit(&EMLXS_PORT_LOCK);
2785 
2786 #ifdef FMA_SUPPORT
2787 	if (!in_panic) {
2788 		emlxs_check_dma(hba, sbp);
2789 	}
2790 #endif
2791 
2792 	/* Make ULP completion callback if required */
2793 	if (pkt->pkt_comp) {
2794 		cp->ulpCmplCmd++;
2795 		(*pkt->pkt_comp) (pkt);
2796 	}
2797 
2798 #ifdef FMA_SUPPORT
2799 	if (hba->flag & FC_DMA_CHECK_ERROR) {
2800 		emlxs_thread_spawn(hba, emlxs_restart_thread,
2801 		    NULL, NULL);
2802 	}
2803 #endif
2804 
2805 	return;
2806 
2807 } /* emlxs_poll() */
2808 
2809 
2810 static int
emlxs_fca_ub_alloc(opaque_t fca_port_handle,uint64_t tokens[],uint32_t size,uint32_t * count,uint32_t type)2811 emlxs_fca_ub_alloc(opaque_t fca_port_handle, uint64_t tokens[], uint32_t size,
2812     uint32_t *count, uint32_t type)
2813 {
2814 	emlxs_port_t		*port = (emlxs_port_t *)fca_port_handle;
2815 	emlxs_hba_t		*hba = HBA;
2816 	char			*err = NULL;
2817 	emlxs_unsol_buf_t	*pool = NULL;
2818 	emlxs_unsol_buf_t	*new_pool = NULL;
2819 	emlxs_config_t		*cfg = &CFG;
2820 	int32_t			i;
2821 	int			result;
2822 	uint32_t		free_resv;
2823 	uint32_t		free;
2824 	fc_unsol_buf_t		*ubp;
2825 	emlxs_ub_priv_t		*ub_priv;
2826 	int			rc;
2827 
2828 	if (!(port->flag & EMLXS_INI_ENABLED)) {
2829 		if (tokens && count) {
2830 			bzero(tokens, (sizeof (uint64_t) * (*count)));
2831 		}
2832 		return (FC_SUCCESS);
2833 	}
2834 
2835 	if (!(port->flag & EMLXS_INI_BOUND)) {
2836 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2837 		    "fca_ub_alloc failed: Port not bound!  size=%x count=%d "
2838 		    "type=%x", size, *count, type);
2839 
2840 		return (FC_FAILURE);
2841 	}
2842 
2843 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2844 	    "fca_ub_alloc: size=%x count=%d type=%x", size, *count, type);
2845 
2846 	if (count && (*count > EMLXS_MAX_UBUFS)) {
2847 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_msg,
2848 		    "fca_ub_alloc failed: Too many unsolicted buffers "
2849 		    "requested. count=%x", *count);
2850 
2851 		return (FC_FAILURE);
2852 
2853 	}
2854 
2855 	if (tokens == NULL) {
2856 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_msg,
2857 		    "fca_ub_alloc failed: Token array is NULL.");
2858 
2859 		return (FC_FAILURE);
2860 	}
2861 
2862 	/* Clear the token array */
2863 	bzero(tokens, (sizeof (uint64_t) * (*count)));
2864 
2865 	free_resv = 0;
2866 	free = *count;
2867 	switch (type) {
2868 	case FC_TYPE_BASIC_LS:
2869 		err = "BASIC_LS";
2870 		break;
2871 	case FC_TYPE_EXTENDED_LS:
2872 		err = "EXTENDED_LS";
2873 		free = *count / 2;	/* Hold 50% for normal use */
2874 		free_resv = *count - free;	/* Reserve 50% for RSCN use */
2875 		break;
2876 	case FC_TYPE_IS8802:
2877 		err = "IS8802";
2878 		break;
2879 	case FC_TYPE_IS8802_SNAP:
2880 		err = "IS8802_SNAP";
2881 
2882 		if (cfg[CFG_NETWORK_ON].current == 0) {
2883 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2884 			    "fca_ub_alloc failed: IP support is disabled.");
2885 
2886 			return (FC_FAILURE);
2887 		}
2888 		break;
2889 	case FC_TYPE_SCSI_FCP:
2890 		err = "SCSI_FCP";
2891 		break;
2892 	case FC_TYPE_SCSI_GPP:
2893 		err = "SCSI_GPP";
2894 		break;
2895 	case FC_TYPE_HIPP_FP:
2896 		err = "HIPP_FP";
2897 		break;
2898 	case FC_TYPE_IPI3_MASTER:
2899 		err = "IPI3_MASTER";
2900 		break;
2901 	case FC_TYPE_IPI3_SLAVE:
2902 		err = "IPI3_SLAVE";
2903 		break;
2904 	case FC_TYPE_IPI3_PEER:
2905 		err = "IPI3_PEER";
2906 		break;
2907 	case FC_TYPE_FC_SERVICES:
2908 		err = "FC_SERVICES";
2909 		break;
2910 	}
2911 
2912 	mutex_enter(&EMLXS_UB_LOCK);
2913 
2914 	/*
2915 	 * Walk through the list of the unsolicited buffers
2916 	 * for this ddiinst of emlx.
2917 	 */
2918 
2919 	pool = port->ub_pool;
2920 
2921 	/*
2922 	 * The emlxs_fca_ub_alloc() can be called more than once with different
2923 	 * size. We will reject the call if there are
2924 	 * duplicate size with the same FC-4 type.
2925 	 */
2926 	while (pool) {
2927 		if ((pool->pool_type == type) &&
2928 		    (pool->pool_buf_size == size)) {
2929 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_msg,
2930 			    "fca_ub_alloc failed: Unsolicited buffer pool "
2931 			    "for %s of size 0x%x bytes already exists.",
2932 			    err, size);
2933 
2934 			result = FC_FAILURE;
2935 			goto fail;
2936 		}
2937 
2938 		pool = pool->pool_next;
2939 	}
2940 
2941 	mutex_exit(&EMLXS_UB_LOCK);
2942 
2943 	new_pool = (emlxs_unsol_buf_t *)kmem_zalloc(sizeof (emlxs_unsol_buf_t),
2944 	    KM_SLEEP);
2945 
2946 	new_pool->pool_next = NULL;
2947 	new_pool->pool_type = type;
2948 	new_pool->pool_buf_size = size;
2949 	new_pool->pool_nentries = *count;
2950 	new_pool->pool_available = new_pool->pool_nentries;
2951 	new_pool->pool_free = free;
2952 	new_pool->pool_free_resv = free_resv;
2953 	new_pool->fc_ubufs =
2954 	    kmem_zalloc((sizeof (fc_unsol_buf_t) * (*count)), KM_SLEEP);
2955 
2956 	new_pool->pool_first_token = port->ub_count;
2957 	new_pool->pool_last_token = port->ub_count + new_pool->pool_nentries;
2958 
2959 	for (i = 0; i < new_pool->pool_nentries; i++) {
2960 		ubp = (fc_unsol_buf_t *)&new_pool->fc_ubufs[i];
2961 		ubp->ub_port_handle = port->ulp_handle;
2962 		ubp->ub_token = (uint64_t)((unsigned long)ubp);
2963 		ubp->ub_bufsize = size;
2964 		ubp->ub_class = FC_TRAN_CLASS3;
2965 		ubp->ub_port_private = NULL;
2966 		ubp->ub_fca_private =
2967 		    (emlxs_ub_priv_t *)kmem_zalloc(sizeof (emlxs_ub_priv_t),
2968 		    KM_SLEEP);
2969 
2970 		/*
2971 		 * Initialize emlxs_ub_priv_t
2972 		 */
2973 		ub_priv = ubp->ub_fca_private;
2974 		ub_priv->ubp = ubp;
2975 		ub_priv->port = port;
2976 		ub_priv->flags = EMLXS_UB_FREE;
2977 		ub_priv->available = 1;
2978 		ub_priv->pool = new_pool;
2979 		ub_priv->time = 0;
2980 		ub_priv->timeout = 0;
2981 		ub_priv->token = port->ub_count;
2982 		ub_priv->cmd = 0;
2983 
2984 		/* Allocate the actual buffer */
2985 		ubp->ub_buffer = (caddr_t)kmem_zalloc(size, KM_SLEEP);
2986 
2987 
2988 		tokens[i] = (uint64_t)((unsigned long)ubp);
2989 		port->ub_count++;
2990 	}
2991 
2992 	mutex_enter(&EMLXS_UB_LOCK);
2993 
2994 	/* Add the pool to the top of the pool list */
2995 	new_pool->pool_prev = NULL;
2996 	new_pool->pool_next = port->ub_pool;
2997 
2998 	if (port->ub_pool) {
2999 		port->ub_pool->pool_prev = new_pool;
3000 	}
3001 	port->ub_pool = new_pool;
3002 
3003 	/* Set the post counts */
3004 	if (type == FC_TYPE_IS8802_SNAP) {
3005 		MAILBOXQ	*mbox;
3006 
3007 		port->ub_post[hba->channel_ip] += new_pool->pool_nentries;
3008 
3009 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
3010 		    MEM_MBOX))) {
3011 			emlxs_mb_config_farp(hba, mbox);
3012 			rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba,
3013 			    mbox, MBX_NOWAIT, 0);
3014 			if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
3015 				emlxs_mem_put(hba, MEM_MBOX, (void *)mbox);
3016 			}
3017 		}
3018 		port->flag |= EMLXS_PORT_IP_UP;
3019 	} else if (type == FC_TYPE_EXTENDED_LS) {
3020 		port->ub_post[hba->channel_els] += new_pool->pool_nentries;
3021 	} else if (type == FC_TYPE_FC_SERVICES) {
3022 		port->ub_post[hba->channel_ct] += new_pool->pool_nentries;
3023 	}
3024 
3025 	mutex_exit(&EMLXS_UB_LOCK);
3026 
3027 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
3028 	    "%d unsolicited buffers allocated for %s of size 0x%x bytes.",
3029 	    *count, err, size);
3030 
3031 	return (FC_SUCCESS);
3032 
3033 fail:
3034 
3035 	/* Clean the pool */
3036 	for (i = 0; tokens[i] != 0; i++) {
3037 		/* Get the buffer object */
3038 		ubp = (fc_unsol_buf_t *)((unsigned long)tokens[i]);
3039 		ub_priv = (emlxs_ub_priv_t *)ubp->ub_fca_private;
3040 
3041 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_detail_msg,
3042 		    "fca_ub_alloc failed: Freed buffer=%p token=%x size=%x "
3043 		    "type=%x ", ubp, ub_priv->token, ubp->ub_bufsize, type);
3044 
3045 		/* Free the actual buffer */
3046 		kmem_free(ubp->ub_buffer, ubp->ub_bufsize);
3047 
3048 		/* Free the private area of the buffer object */
3049 		kmem_free(ubp->ub_fca_private, sizeof (emlxs_ub_priv_t));
3050 
3051 		tokens[i] = 0;
3052 		port->ub_count--;
3053 	}
3054 
3055 	if (new_pool) {
3056 		/* Free the array of buffer objects in the pool */
3057 		kmem_free((caddr_t)new_pool->fc_ubufs,
3058 		    (sizeof (fc_unsol_buf_t) * new_pool->pool_nentries));
3059 
3060 		/* Free the pool object */
3061 		kmem_free((caddr_t)new_pool, sizeof (emlxs_unsol_buf_t));
3062 	}
3063 
3064 	mutex_exit(&EMLXS_UB_LOCK);
3065 
3066 	return (result);
3067 
3068 } /* emlxs_fca_ub_alloc() */
3069 
3070 
3071 static void
emlxs_ub_els_reject(emlxs_port_t * port,fc_unsol_buf_t * ubp)3072 emlxs_ub_els_reject(emlxs_port_t *port, fc_unsol_buf_t *ubp)
3073 {
3074 	emlxs_hba_t	*hba = HBA;
3075 	emlxs_ub_priv_t	*ub_priv;
3076 	fc_packet_t	*pkt;
3077 	ELS_PKT		*els;
3078 	uint32_t	sid;
3079 
3080 	ub_priv = (emlxs_ub_priv_t *)ubp->ub_fca_private;
3081 
3082 	if (hba->state <= FC_LINK_DOWN) {
3083 		emlxs_abort_els_exchange(hba, port, ubp->ub_frame.rx_id);
3084 		return;
3085 	}
3086 
3087 	if (!(pkt = emlxs_pkt_alloc(port, sizeof (uint32_t) +
3088 	    sizeof (LS_RJT), 0, 0, KM_NOSLEEP))) {
3089 		emlxs_abort_els_exchange(hba, port, ubp->ub_frame.rx_id);
3090 		return;
3091 	}
3092 
3093 	sid = LE_SWAP24_LO(ubp->ub_frame.s_id);
3094 
3095 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
3096 	    "%s dropped: sid=%x. Rejecting.",
3097 	    emlxs_elscmd_xlate(ub_priv->cmd), sid);
3098 
3099 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
3100 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3101 
3102 	if ((uint32_t)ubp->ub_class == FC_TRAN_CLASS2) {
3103 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
3104 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
3105 	}
3106 
3107 	/* Build the fc header */
3108 	pkt->pkt_cmd_fhdr.d_id = ubp->ub_frame.s_id;
3109 	pkt->pkt_cmd_fhdr.r_ctl =
3110 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
3111 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
3112 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
3113 	pkt->pkt_cmd_fhdr.f_ctl =
3114 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
3115 	pkt->pkt_cmd_fhdr.seq_id = 0;
3116 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3117 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3118 	pkt->pkt_cmd_fhdr.ox_id = (ub_priv->cmd >> ELS_CMD_SHIFT) & 0xff;
3119 	pkt->pkt_cmd_fhdr.rx_id = ubp->ub_frame.rx_id;
3120 	pkt->pkt_cmd_fhdr.ro = 0;
3121 
3122 	/* Build the command */
3123 	els = (ELS_PKT *) pkt->pkt_cmd;
3124 	els->elsCode = 0x01;
3125 	els->un.lsRjt.un.b.lsRjtRsvd0 = 0;
3126 	els->un.lsRjt.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
3127 	els->un.lsRjt.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
3128 	els->un.lsRjt.un.b.vendorUnique = 0x02;
3129 
3130 	/* Send the pkt later in another thread */
3131 	(void) emlxs_pkt_send(pkt, 0);
3132 
3133 	return;
3134 
3135 } /* emlxs_ub_els_reject() */
3136 
3137 extern int
emlxs_fca_ub_release(opaque_t fca_port_handle,uint32_t count,uint64_t tokens[])3138 emlxs_fca_ub_release(opaque_t fca_port_handle, uint32_t count,
3139     uint64_t tokens[])
3140 {
3141 	emlxs_port_t		*port = (emlxs_port_t *)fca_port_handle;
3142 	emlxs_hba_t		*hba = HBA;
3143 	fc_unsol_buf_t		*ubp;
3144 	emlxs_ub_priv_t		*ub_priv;
3145 	uint32_t		i;
3146 	uint32_t		time;
3147 	emlxs_unsol_buf_t	*pool;
3148 
3149 	if (count == 0) {
3150 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3151 		    "fca_ub_release: Nothing to do. count=%d", count);
3152 
3153 		return (FC_SUCCESS);
3154 	}
3155 
3156 	if (!(port->flag & EMLXS_INI_BOUND)) {
3157 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3158 		    "fca_ub_release failed: Port not bound. count=%d "
3159 		    "token[0]=%p",
3160 		    count, tokens[0]);
3161 
3162 		return (FC_UNBOUND);
3163 	}
3164 
3165 	mutex_enter(&EMLXS_UB_LOCK);
3166 
3167 	if (!port->ub_pool) {
3168 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3169 		    "fca_ub_release failed: No pools! count=%d token[0]=%p",
3170 		    count, tokens[0]);
3171 
3172 		mutex_exit(&EMLXS_UB_LOCK);
3173 		return (FC_UB_BADTOKEN);
3174 	}
3175 
3176 	for (i = 0; i < count; i++) {
3177 		ubp = (fc_unsol_buf_t *)((unsigned long)tokens[i]);
3178 
3179 		if (!ubp) {
3180 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3181 			    "fca_ub_release failed: count=%d tokens[%d]=0",
3182 			    count, i);
3183 
3184 			mutex_exit(&EMLXS_UB_LOCK);
3185 			return (FC_UB_BADTOKEN);
3186 		}
3187 
3188 		ub_priv = (emlxs_ub_priv_t *)ubp->ub_fca_private;
3189 
3190 		if (!ub_priv || (ub_priv == (emlxs_ub_priv_t *)DEAD_PTR)) {
3191 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3192 			    "fca_ub_release failed: Dead buffer found. ubp=%p",
3193 			    ubp);
3194 
3195 			mutex_exit(&EMLXS_UB_LOCK);
3196 			return (FC_UB_BADTOKEN);
3197 		}
3198 
3199 		if (ub_priv->flags == EMLXS_UB_FREE) {
3200 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3201 			    "fca_ub_release: Buffer already free! ubp=%p "
3202 			    "token=%x",
3203 			    ubp, ub_priv->token);
3204 
3205 			continue;
3206 		}
3207 
3208 		/* Check for dropped els buffer */
3209 		/* ULP will do this sometimes without sending a reply */
3210 		if ((ubp->ub_frame.r_ctl == FC_ELS_REQ) &&
3211 		    !(ub_priv->flags & EMLXS_UB_REPLY)) {
3212 			emlxs_ub_els_reject(port, ubp);
3213 		}
3214 
3215 		/* Mark the buffer free */
3216 		ub_priv->flags = EMLXS_UB_FREE;
3217 		bzero(ubp->ub_buffer, ubp->ub_bufsize);
3218 
3219 		time = hba->timer_tics - ub_priv->time;
3220 		ub_priv->time = 0;
3221 		ub_priv->timeout = 0;
3222 
3223 		pool = ub_priv->pool;
3224 
3225 		if (ub_priv->flags & EMLXS_UB_RESV) {
3226 			pool->pool_free_resv++;
3227 		} else {
3228 			pool->pool_free++;
3229 		}
3230 
3231 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_detail_msg,
3232 		    "fca_ub_release: ubp=%p token=%x time=%d av=%d "
3233 		    "(%d,%d,%d,%d)",
3234 		    ubp, ub_priv->token, time, ub_priv->available,
3235 		    pool->pool_nentries, pool->pool_available,
3236 		    pool->pool_free, pool->pool_free_resv);
3237 
3238 		/* Check if pool can be destroyed now */
3239 		if ((pool->pool_available == 0) &&
3240 		    (pool->pool_free + pool->pool_free_resv ==
3241 		    pool->pool_nentries)) {
3242 			emlxs_ub_destroy(port, pool);
3243 		}
3244 	}
3245 
3246 	mutex_exit(&EMLXS_UB_LOCK);
3247 
3248 	return (FC_SUCCESS);
3249 
3250 } /* emlxs_fca_ub_release() */
3251 
3252 
3253 static int
emlxs_fca_ub_free(opaque_t fca_port_handle,uint32_t count,uint64_t tokens[])3254 emlxs_fca_ub_free(opaque_t fca_port_handle, uint32_t count, uint64_t tokens[])
3255 {
3256 	emlxs_port_t		*port = (emlxs_port_t *)fca_port_handle;
3257 	emlxs_unsol_buf_t	*pool;
3258 	fc_unsol_buf_t		*ubp;
3259 	emlxs_ub_priv_t		*ub_priv;
3260 	uint32_t		i;
3261 
3262 	if (!(port->flag & EMLXS_INI_ENABLED)) {
3263 		return (FC_SUCCESS);
3264 	}
3265 
3266 	if (count == 0) {
3267 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3268 		    "fca_ub_free: Nothing to do. count=%d token[0]=%p", count,
3269 		    tokens[0]);
3270 
3271 		return (FC_SUCCESS);
3272 	}
3273 
3274 	if (!(port->flag & EMLXS_INI_BOUND)) {
3275 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3276 		    "fca_ub_free: Port not bound. count=%d token[0]=%p", count,
3277 		    tokens[0]);
3278 
3279 		return (FC_SUCCESS);
3280 	}
3281 
3282 	mutex_enter(&EMLXS_UB_LOCK);
3283 
3284 	if (!port->ub_pool) {
3285 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3286 		    "fca_ub_free failed: No pools! count=%d token[0]=%p", count,
3287 		    tokens[0]);
3288 
3289 		mutex_exit(&EMLXS_UB_LOCK);
3290 		return (FC_UB_BADTOKEN);
3291 	}
3292 
3293 	/* Process buffer list */
3294 	for (i = 0; i < count; i++) {
3295 		ubp = (fc_unsol_buf_t *)((unsigned long)tokens[i]);
3296 
3297 		if (!ubp) {
3298 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3299 			    "fca_ub_free failed: count=%d tokens[%d]=0", count,
3300 			    i);
3301 
3302 			mutex_exit(&EMLXS_UB_LOCK);
3303 			return (FC_UB_BADTOKEN);
3304 		}
3305 
3306 		/* Mark buffer unavailable */
3307 		ub_priv = (emlxs_ub_priv_t *)ubp->ub_fca_private;
3308 
3309 		if (!ub_priv || (ub_priv == (emlxs_ub_priv_t *)DEAD_PTR)) {
3310 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3311 			    "fca_ub_free failed: Dead buffer found. ubp=%p",
3312 			    ubp);
3313 
3314 			mutex_exit(&EMLXS_UB_LOCK);
3315 			return (FC_UB_BADTOKEN);
3316 		}
3317 
3318 		ub_priv->available = 0;
3319 
3320 		/* Mark one less buffer available in the parent pool */
3321 		pool = ub_priv->pool;
3322 
3323 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_detail_msg,
3324 		    "fca_ub_free: ubp=%p token=%x (%d,%d,%d,%d)", ubp,
3325 		    ub_priv->token, pool->pool_nentries,
3326 		    pool->pool_available - 1, pool->pool_free,
3327 		    pool->pool_free_resv);
3328 
3329 		if (pool->pool_available) {
3330 			pool->pool_available--;
3331 
3332 			/* Check if pool can be destroyed */
3333 			if ((pool->pool_available == 0) &&
3334 			    (pool->pool_free + pool->pool_free_resv ==
3335 			    pool->pool_nentries)) {
3336 				emlxs_ub_destroy(port, pool);
3337 			}
3338 		}
3339 	}
3340 
3341 	mutex_exit(&EMLXS_UB_LOCK);
3342 
3343 	return (FC_SUCCESS);
3344 
3345 } /* emlxs_fca_ub_free() */
3346 
3347 
3348 /* EMLXS_UB_LOCK must be held when calling this routine */
3349 extern void
emlxs_ub_destroy(emlxs_port_t * port,emlxs_unsol_buf_t * pool)3350 emlxs_ub_destroy(emlxs_port_t *port, emlxs_unsol_buf_t *pool)
3351 {
3352 	emlxs_hba_t		*hba = HBA;
3353 	emlxs_unsol_buf_t	*next;
3354 	emlxs_unsol_buf_t	*prev;
3355 	fc_unsol_buf_t		*ubp;
3356 	uint32_t		i;
3357 
3358 	/* Remove the pool object from the pool list */
3359 	next = pool->pool_next;
3360 	prev = pool->pool_prev;
3361 
3362 	if (port->ub_pool == pool) {
3363 		port->ub_pool = next;
3364 	}
3365 
3366 	if (prev) {
3367 		prev->pool_next = next;
3368 	}
3369 
3370 	if (next) {
3371 		next->pool_prev = prev;
3372 	}
3373 
3374 	pool->pool_prev = NULL;
3375 	pool->pool_next = NULL;
3376 
3377 	/* Clear the post counts */
3378 	switch (pool->pool_type) {
3379 	case FC_TYPE_IS8802_SNAP:
3380 		port->ub_post[hba->channel_ip] -= pool->pool_nentries;
3381 		break;
3382 
3383 	case FC_TYPE_EXTENDED_LS:
3384 		port->ub_post[hba->channel_els] -= pool->pool_nentries;
3385 		break;
3386 
3387 	case FC_TYPE_FC_SERVICES:
3388 		port->ub_post[hba->channel_ct] -= pool->pool_nentries;
3389 		break;
3390 	}
3391 
3392 	/* Now free the pool memory */
3393 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
3394 	    "ub_destroy: pool=%p type=%d size=%d count=%d", pool,
3395 	    pool->pool_type, pool->pool_buf_size, pool->pool_nentries);
3396 
3397 	/* Process the array of buffer objects in the pool */
3398 	for (i = 0; i < pool->pool_nentries; i++) {
3399 		/* Get the buffer object */
3400 		ubp = (fc_unsol_buf_t *)&pool->fc_ubufs[i];
3401 
3402 		/* Free the memory the buffer object represents */
3403 		kmem_free(ubp->ub_buffer, ubp->ub_bufsize);
3404 
3405 		/* Free the private area of the buffer object */
3406 		kmem_free(ubp->ub_fca_private, sizeof (emlxs_ub_priv_t));
3407 	}
3408 
3409 	/* Free the array of buffer objects in the pool */
3410 	kmem_free((caddr_t)pool->fc_ubufs,
3411 	    (sizeof (fc_unsol_buf_t)*pool->pool_nentries));
3412 
3413 	/* Free the pool object */
3414 	kmem_free((caddr_t)pool, sizeof (emlxs_unsol_buf_t));
3415 
3416 	return;
3417 
3418 } /* emlxs_ub_destroy() */
3419 
3420 
3421 /*ARGSUSED*/
3422 extern int
emlxs_fca_pkt_abort(opaque_t fca_port_handle,fc_packet_t * pkt,int32_t sleep)3423 emlxs_fca_pkt_abort(opaque_t fca_port_handle, fc_packet_t *pkt, int32_t sleep)
3424 {
3425 	emlxs_port_t	*port = (emlxs_port_t *)fca_port_handle;
3426 	emlxs_hba_t	*hba = HBA;
3427 	emlxs_config_t	*cfg = &CFG;
3428 
3429 	emlxs_buf_t	*sbp;
3430 	NODELIST	*nlp;
3431 	NODELIST	*prev_nlp;
3432 	uint8_t		channelno;
3433 	CHANNEL	*cp;
3434 	clock_t		pkt_timeout;
3435 	clock_t		timer;
3436 	clock_t		time;
3437 	int32_t		pkt_ret;
3438 	IOCBQ		*iocbq;
3439 	IOCBQ		*next;
3440 	IOCBQ		*prev;
3441 	uint32_t	found;
3442 	uint32_t	pass = 0;
3443 
3444 	sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
3445 	iocbq = &sbp->iocbq;
3446 	nlp = (NODELIST *)sbp->node;
3447 	cp = (CHANNEL *)sbp->channel;
3448 	channelno = (cp) ?