1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22eb82ff87SDaniel Beauregard /* Copyright 2010 QLogic Corporation */
23fcf3ce44SJohn Forte 
24fcf3ce44SJohn Forte /*
25*f885d00fSDaniel Beauregard  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26fcf3ce44SJohn Forte  */
27fcf3ce44SJohn Forte 
28eb82ff87SDaniel Beauregard #pragma ident	"Copyright 2010 QLogic Corporation; ql_hba_fru.c"
29fcf3ce44SJohn Forte 
30fcf3ce44SJohn Forte /*
31fcf3ce44SJohn Forte  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
32fcf3ce44SJohn Forte  *
33fcf3ce44SJohn Forte  * ***********************************************************************
34fcf3ce44SJohn Forte  * *									**
35fcf3ce44SJohn Forte  * *				NOTICE					**
36eb82ff87SDaniel Beauregard  * *		COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION		**
37fcf3ce44SJohn Forte  * *			ALL RIGHTS RESERVED				**
38fcf3ce44SJohn Forte  * *									**
39fcf3ce44SJohn Forte  * ***********************************************************************
40fcf3ce44SJohn Forte  *
41fcf3ce44SJohn Forte  */
42fcf3ce44SJohn Forte 
43fcf3ce44SJohn Forte /*
44fcf3ce44SJohn Forte  * Determine HBA FRU card information for T11 FC-HBA
45fcf3ce44SJohn Forte  */
46fcf3ce44SJohn Forte 
47fcf3ce44SJohn Forte #include <ql_apps.h>
48fcf3ce44SJohn Forte #include <ql_api.h>
49fcf3ce44SJohn Forte #include <ql_debug.h>
50fcf3ce44SJohn Forte #include <ql_ioctl.h>
51fcf3ce44SJohn Forte #include <ql_xioctl.h>
52fcf3ce44SJohn Forte 
53fcf3ce44SJohn Forte /*
54fcf3ce44SJohn Forte  * Temporary define until LV headers are updated
55fcf3ce44SJohn Forte  */
56fcf3ce44SJohn Forte #ifndef	FC_HBA_PORTSPEED_8GBIT
57fcf3ce44SJohn Forte #define	FC_HBA_PORTSPEED_8GBIT		16    /* 8 GBit/sec */
58fcf3ce44SJohn Forte #endif
59fcf3ce44SJohn Forte 
60fcf3ce44SJohn Forte /* Local prototypes */
61fcf3ce44SJohn Forte static uint32_t ql_get_basedev_len(ql_adapter_state_t *, uint32_t *,
62fcf3ce44SJohn Forte     uint32_t *);
63fcf3ce44SJohn Forte static ql_adapter_state_t *ql_search_basedev(ql_adapter_state_t *, uint32_t);
64fcf3ce44SJohn Forte 
65fcf3ce44SJohn Forte /* Local structures */
66fcf3ce44SJohn Forte static struct ql_known_models {
67fcf3ce44SJohn Forte 	uint16_t    ssid;		/* Subsystem ID */
68fcf3ce44SJohn Forte 	uint16_t    ssvid;		/* Subsystem Vendor ID */
69fcf3ce44SJohn Forte 	char	    model[256];
70fcf3ce44SJohn Forte 	char	    model_description[256];
71fcf3ce44SJohn Forte 
72fcf3ce44SJohn Forte } models[] = {
73fcf3ce44SJohn Forte 	{
74fcf3ce44SJohn Forte 	    /* QLogic */
75fcf3ce44SJohn Forte 	    0x2, 0x1077, "QLA2200", "QLogic PCI to 1Gb FC, Single Channel"
76fcf3ce44SJohn Forte 	}, {
77fcf3ce44SJohn Forte 	    /* QLogic */
78fcf3ce44SJohn Forte 	    0x9, 0x1077, "QLA2300", "QLogic PCI to 2Gb FC, Single Channel"
79fcf3ce44SJohn Forte 	}, {
80fcf3ce44SJohn Forte 	    /* QLA2200, SUN2200 Amber */
81fcf3ce44SJohn Forte 	    0x4082, 0x1077, "375-3019-xx", "X6799A"
82fcf3ce44SJohn Forte 	}, {
83fcf3ce44SJohn Forte 	    /* QLA2212, SUN2212 Crystal+ */
84fcf3ce44SJohn Forte 	    0x4083, 0x1077, "375-3030-xx", "X6727A"
85fcf3ce44SJohn Forte 	}, {
86fcf3ce44SJohn Forte 	    /* QCP2202, SUNQCP2202 Diamond */
87fcf3ce44SJohn Forte 	    0x4084, 0x1077, "375-0118-xx", "X6748A"
88fcf3ce44SJohn Forte 	}, {
89fcf3ce44SJohn Forte 	    /* QLA2202FS, SUN2202FS Ivory */
90fcf3ce44SJohn Forte 	    0x4085, 0x1077, "375-3048-xx", "X6757A"
91fcf3ce44SJohn Forte 	}, {
92fcf3ce44SJohn Forte 	    /* QLogic */
93fcf3ce44SJohn Forte 	    0x100, 0x1077, "QLA2340",
94fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Single Channel"
95fcf3ce44SJohn Forte 	}, {
96fcf3ce44SJohn Forte 	    /* QLogic */
97fcf3ce44SJohn Forte 	    0x101, 0x1077, "QLA2342",
98fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Dual Channel"
99fcf3ce44SJohn Forte 	}, {
100fcf3ce44SJohn Forte 	    /* QLogic */
101fcf3ce44SJohn Forte 	    0x102, 0x1077, "QLA2344",
102fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Quad Channel"
103fcf3ce44SJohn Forte 	}, {
104fcf3ce44SJohn Forte 	    /* QLogic */
105fcf3ce44SJohn Forte 	    0x103, 0x1077, "QCP2342", "QLogic cPCI to 2Gb FC, Dual Channel"
106fcf3ce44SJohn Forte 	}, {
107fcf3ce44SJohn Forte 	    /* QLogic */
108fcf3ce44SJohn Forte 	    0x104, 0x1077, "QSB2340", "QLogic SBUS to 2Gb FC, Single Channel"
109fcf3ce44SJohn Forte 	}, {
110fcf3ce44SJohn Forte 	    /* QLogic */
111fcf3ce44SJohn Forte 	    0x105, 0x1077, "QSB2342", "QLogic SBUS to 2Gb FC, Dual Channel"
112fcf3ce44SJohn Forte 	}, {
113fcf3ce44SJohn Forte 	    /* QLA2310, SUN-66MHz PCI-X to 2Gb FC, Single Channel, Amber 2 */
114fcf3ce44SJohn Forte 	    0x0106, 0x1077, "375-3102-xx", "SG-XPCI1FC-QF2 (X6767A)"
115fcf3ce44SJohn Forte 	}, {
116fcf3ce44SJohn Forte 	    /* QLogic */
117fcf3ce44SJohn Forte 	    0x109, 0x1077, "QCP2340", "QLogic cPCI to 2Gb FC, Single Channel"
118fcf3ce44SJohn Forte 	}, {
119fcf3ce44SJohn Forte 	    /* QLA2342, SUN-133MHz PCI-X to 2Gb FC, Dualchannel, Crystal 2A */
120fcf3ce44SJohn Forte 	    0x010A, 0x1077, "375-3108-xx", "SG-XPCI2FC-QF2 (X6768A)"
121fcf3ce44SJohn Forte 	}, {
122fcf3ce44SJohn Forte 	    /* QLogic */
123fcf3ce44SJohn Forte 	    0x115, 0x1077, "QLA2360",
124fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Single Channel"
125fcf3ce44SJohn Forte 	}, {
126fcf3ce44SJohn Forte 	    /* QLogic */
127fcf3ce44SJohn Forte 	    0x116, 0x1077, "QLA2362",
128fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Dual Channel"
129fcf3ce44SJohn Forte 	}, {
130fcf3ce44SJohn Forte 	    /* QLogic */
131fcf3ce44SJohn Forte 	    0x117, 0x1077, "QLE2360",
132fcf3ce44SJohn Forte 	    "QLogic PCI-Express to 2Gb FC, Single Channel"
133fcf3ce44SJohn Forte 	}, {
134fcf3ce44SJohn Forte 	    /* QLogic */
135fcf3ce44SJohn Forte 	    0x118, 0x1077, "QLE2362",
136fcf3ce44SJohn Forte 	    "QLogic PCI Express to 2Gb FC, Dual Channel"
137fcf3ce44SJohn Forte 	}, {
138fcf3ce44SJohn Forte 	    /* QLogic */
139fcf3ce44SJohn Forte 	    0x119, 0x1077, "QLA200",
140fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Single Channel"
141fcf3ce44SJohn Forte 	}, {
142fcf3ce44SJohn Forte 	    /* QLogic */
143fcf3ce44SJohn Forte 	    0x11c, 0x1077, "QLA200P",
144fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Single Channel"
145fcf3ce44SJohn Forte 	}, {
146fcf3ce44SJohn Forte 	    /* QLogic */
147fcf3ce44SJohn Forte 	    0x12f, 0x1077, "QLA210",
148fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Single Channel"
149fcf3ce44SJohn Forte 	}, {
150fcf3ce44SJohn Forte 	    /* QLogic */
151fcf3ce44SJohn Forte 	    0x130, 0x1077, "EMC250-051-900",
152fcf3ce44SJohn Forte 	    "QLogic 133MHz PCI-X to 2Gb FC, Single Channel"
153fcf3ce44SJohn Forte 	}, {
154fcf3ce44SJohn Forte 	    /* QLA210, SUN-133MHz PCI-X to 2Gb FC, Single Channel, Prism */
155fcf3ce44SJohn Forte 	    0x132, 0x1077, "375-32X3-01", "SG-PCI1FC-QLC"
156fcf3ce44SJohn Forte 	}, {
157fcf3ce44SJohn Forte 	    /* QLogic */
158fcf3ce44SJohn Forte 	    0x13e, 0x1077, "QLE210",
159fcf3ce44SJohn Forte 	    "QLogic PCI Express 2Gb FC, Single Channel"
160fcf3ce44SJohn Forte 	}, {
161fcf3ce44SJohn Forte 	    /* Sun */
162fcf3ce44SJohn Forte 	    0x149, 0x1077, "QLA2340",
163fcf3ce44SJohn Forte 	    "SUN - 133MHz PCI-X to 2Gb FC, Single Channel"
164fcf3ce44SJohn Forte 	}, {
165fcf3ce44SJohn Forte 	    /* HP */
166fcf3ce44SJohn Forte 	    0x100, 0x0e11, "QLA2340-HP", "PCIX to 2Gb FC, Single Channel"
167fcf3ce44SJohn Forte 	}, {
168fcf3ce44SJohn Forte 	    /* HP */
169fcf3ce44SJohn Forte 	    0x101, 0x0e11, "QLA2342-HP", "PCIX to 2Gb FC, Dual Channel"
170fcf3ce44SJohn Forte 	}, {
171fcf3ce44SJohn Forte 	    /* HP */
172fcf3ce44SJohn Forte 	    0x103, 0x0e11, "QLA2312-HP",
173fcf3ce44SJohn Forte 	    "HP Bladed Server Balcony Card - HP BalcnL"
174fcf3ce44SJohn Forte 	}, {
175fcf3ce44SJohn Forte 	    /* HP */
176fcf3ce44SJohn Forte 	    0x104, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP MezzF"
177fcf3ce44SJohn Forte 	}, {
178fcf3ce44SJohn Forte 	    /* HP */
179fcf3ce44SJohn Forte 	    0x105, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP BalcnL"
180fcf3ce44SJohn Forte 	}, {
181fcf3ce44SJohn Forte 	    /* HP */
182fcf3ce44SJohn Forte 	    0x106, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP BalcnF"
183fcf3ce44SJohn Forte 	}, {
184fcf3ce44SJohn Forte 	    /* HP */
185fcf3ce44SJohn Forte 	    0x107, 0x0e11, "QLA2312-HP", "HP Bladed Server"
186fcf3ce44SJohn Forte 	}, {
187fcf3ce44SJohn Forte 	    /* HP */
188fcf3ce44SJohn Forte 	    0x108, 0x0e11, "QLA2312-HP", "HP Bladed Server"
189fcf3ce44SJohn Forte 	}, {
190fcf3ce44SJohn Forte 	    /* IBM FCEC */
191fcf3ce44SJohn Forte 	    0x27d, 0x1014, "IBM-FCEC",
192fcf3ce44SJohn Forte 	    "IBM eServer Blade Center FC Expansion Card"
193fcf3ce44SJohn Forte 	}, {
194fcf3ce44SJohn Forte 	    /* IBM FCEC */
195fcf3ce44SJohn Forte 	    0x2fb, 0x1014, "IBM-FCEC",
196fcf3ce44SJohn Forte 	    "IBM eServer Blade Center FC SFF Expansion Card"
197fcf3ce44SJohn Forte 	}, {
198fcf3ce44SJohn Forte 	    /* Intel */
199fcf3ce44SJohn Forte 	    0x34ba, 0x8086, "Intel SBFCM",
200fcf3ce44SJohn Forte 	    "Intel Server FC Expansion Card SBFCM"
201fcf3ce44SJohn Forte 	}, {
202fcf3ce44SJohn Forte 	    /* Intel */
203fcf3ce44SJohn Forte 	    0x34a0, 0x8086, "Intel SBEFCM",
204fcf3ce44SJohn Forte 	    "Intel Server SFF FC Expansion Card SBFCM"
205fcf3ce44SJohn Forte 	}, {
206fcf3ce44SJohn Forte 	    /* FCI/O */
207fcf3ce44SJohn Forte 	    0x1051, 0x1734, "FCI/O-CARD2Gb/s",
208fcf3ce44SJohn Forte 	    "FSC-Quanta FC I/O-Card 2GBit/s"
209fcf3ce44SJohn Forte 	}, {
210fcf3ce44SJohn Forte 	    /* Dell */
211fcf3ce44SJohn Forte 	    0x18a, 0x1028, "FCI/O-CARD2Gb/s", "Dell Glacier Blade Server"
212fcf3ce44SJohn Forte 	}, {
213fcf3ce44SJohn Forte 	    /* end of list */
214fcf3ce44SJohn Forte 	    0, 0, 0, 0, 0, 0
215fcf3ce44SJohn Forte 	} };
216fcf3ce44SJohn Forte 
217fcf3ce44SJohn Forte /*
218fcf3ce44SJohn Forte  * ql_populate_hba_fru_details
219fcf3ce44SJohn Forte  *	Sets up HBA fru information for UL utilities
220fcf3ce44SJohn Forte  *	(cfgadm, fcinfo, et. al.)
221fcf3ce44SJohn Forte  *
222fcf3ce44SJohn Forte  * Input:
223fcf3ce44SJohn Forte  *	ha		= adapter state structure
224fcf3ce44SJohn Forte  *	port_info	= ptr to LV port strcture.
225fcf3ce44SJohn Forte  *
226fcf3ce44SJohn Forte  * Returns:
227fcf3ce44SJohn Forte  *
228fcf3ce44SJohn Forte  * Context:
229fcf3ce44SJohn Forte  *	Kernel context.
230fcf3ce44SJohn Forte  */
231fcf3ce44SJohn Forte void
ql_populate_hba_fru_details(ql_adapter_state_t * ha,fc_fca_port_info_t * port_info)232fcf3ce44SJohn Forte ql_populate_hba_fru_details(ql_adapter_state_t *ha,
233fcf3ce44SJohn Forte     fc_fca_port_info_t *port_info)
234fcf3ce44SJohn Forte {
235fcf3ce44SJohn Forte 	fca_port_attrs_t	*attrs = &port_info->pi_attrs;
236fcf3ce44SJohn Forte 	uint16_t		chip = ha->device_id;
237fcf3ce44SJohn Forte 	uint16_t		model = ha->subsys_id;
238fcf3ce44SJohn Forte 	uint16_t		ssdevid = ha->subven_id;
239fcf3ce44SJohn Forte 	size_t			vlen;
240fcf3ce44SJohn Forte 	int32_t			i;
241fcf3ce44SJohn Forte 
2425dfd244aSDaniel Beauregard 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
243fcf3ce44SJohn Forte 
244fcf3ce44SJohn Forte 	attrs = &port_info->pi_attrs;
245fcf3ce44SJohn Forte 
246fcf3ce44SJohn Forte 	/* Constants */
247fcf3ce44SJohn Forte 	(void) snprintf(attrs->manufacturer, FCHBA_MANUFACTURER_LEN,
248fcf3ce44SJohn Forte 	    "QLogic Corp.");
249fcf3ce44SJohn Forte 	(void) snprintf(attrs->driver_name, FCHBA_DRIVER_NAME_LEN,
250fcf3ce44SJohn Forte 	    "%s", QL_NAME);
251fcf3ce44SJohn Forte 	(void) snprintf(attrs->driver_version, FCHBA_DRIVER_VERSION_LEN,
252fcf3ce44SJohn Forte 	    "%s", ha->adapter_stats->revlvl.qlddv);
253fcf3ce44SJohn Forte 
254fcf3ce44SJohn Forte 	if ((i = ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_SN, (uint8_t *)
255fcf3ce44SJohn Forte 	    attrs->serial_number, FCHBA_SERIAL_NUMBER_LEN)) == -1) {
256fcf3ce44SJohn Forte 		attrs->serial_number[0] = '\0';
257fcf3ce44SJohn Forte 	}
258fcf3ce44SJohn Forte 	attrs->hardware_version[0] = '\0';
259fcf3ce44SJohn Forte 
260fcf3ce44SJohn Forte 	/* Dynamic data */
261fcf3ce44SJohn Forte 	(void) snprintf(attrs->firmware_version, FCHBA_FIRMWARE_VERSION_LEN,
262fcf3ce44SJohn Forte 	    "%02d.%02d.%02d", ha->fw_major_version, ha->fw_minor_version,
263fcf3ce44SJohn Forte 	    ha->fw_subminor_version);
264fcf3ce44SJohn Forte 
265fcf3ce44SJohn Forte 	CACHE_LOCK(ha);
266fcf3ce44SJohn Forte 
267fcf3ce44SJohn Forte 	/* Report FCode / BIOS / EFI version(s). */
268fcf3ce44SJohn Forte 	if (ha->fcache != NULL) {
269fcf3ce44SJohn Forte 		uint32_t	types = FTYPE_BIOS|FTYPE_FCODE|FTYPE_EFI;
270fcf3ce44SJohn Forte 		ql_fcache_t	*fptr = ha->fcache;
271fcf3ce44SJohn Forte 		int8_t		*orv = &*attrs->option_rom_version;
272fcf3ce44SJohn Forte 
273fcf3ce44SJohn Forte 		while ((fptr != NULL) && (types != 0)) {
274fcf3ce44SJohn Forte 			/* Get the next image */
275fcf3ce44SJohn Forte 			if ((fptr = ql_get_fbuf(ha->fcache, types)) != NULL) {
276fcf3ce44SJohn Forte 
277fcf3ce44SJohn Forte 				switch (fptr->type) {
278fcf3ce44SJohn Forte 				case FTYPE_FCODE:
279fcf3ce44SJohn Forte 					(void) snprintf(orv,
280fcf3ce44SJohn Forte 					    FCHBA_OPTION_ROM_VERSION_LEN,
281fcf3ce44SJohn Forte 					    "%s fcode: %s;", orv, fptr->verstr);
282fcf3ce44SJohn Forte 					break;
283fcf3ce44SJohn Forte 				case FTYPE_BIOS:
284fcf3ce44SJohn Forte 					(void) snprintf(orv,
285fcf3ce44SJohn Forte 					    FCHBA_OPTION_ROM_VERSION_LEN,
286fcf3ce44SJohn Forte 					    "%s BIOS: %s;", orv, fptr->verstr);
287fcf3ce44SJohn Forte 					break;
288fcf3ce44SJohn Forte 				case FTYPE_EFI:
289fcf3ce44SJohn Forte 					(void) snprintf(orv,
290fcf3ce44SJohn Forte 					    FCHBA_OPTION_ROM_VERSION_LEN,
291fcf3ce44SJohn Forte 					    "%s EFI: %s;", orv, fptr->verstr);
292fcf3ce44SJohn Forte 					break;
293fcf3ce44SJohn Forte 				default:
294fcf3ce44SJohn Forte 					EL(ha, "ignoring ftype: %xh\n",
295fcf3ce44SJohn Forte 					    fptr->type);
296fcf3ce44SJohn Forte 					break;
297fcf3ce44SJohn Forte 				}
298fcf3ce44SJohn Forte 				types &= ~(fptr->type);
299fcf3ce44SJohn Forte 			}
300fcf3ce44SJohn Forte 		}
301fcf3ce44SJohn Forte 	}
302fcf3ce44SJohn Forte 
303fcf3ce44SJohn Forte 	CACHE_UNLOCK(ha);
304fcf3ce44SJohn Forte 
305fcf3ce44SJohn Forte 	if (strlen(attrs->option_rom_version) == 0) {
306fcf3ce44SJohn Forte 		int		rval = -1;
307fcf3ce44SJohn Forte 		uint32_t	i = 0;
308fcf3ce44SJohn Forte 		caddr_t		fcode_ver_buf = NULL;
309fcf3ce44SJohn Forte 
310fcf3ce44SJohn Forte 		if (CFG_IST(ha, CFG_CTRL_2200)) {
311fcf3ce44SJohn Forte 			/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
312fcf3ce44SJohn Forte 			rval = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip,
313fcf3ce44SJohn Forte 			    DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version",
314fcf3ce44SJohn Forte 			    (caddr_t)&fcode_ver_buf, (int32_t *)&i);
315fcf3ce44SJohn Forte 		}
316fcf3ce44SJohn Forte 
317fcf3ce44SJohn Forte 		(void) snprintf(attrs->option_rom_version,
318fcf3ce44SJohn Forte 		    FCHBA_OPTION_ROM_VERSION_LEN, "%s",
319fcf3ce44SJohn Forte 		    (rval == DDI_PROP_SUCCESS ? fcode_ver_buf :
320fcf3ce44SJohn Forte 		    "No boot image detected"));
321fcf3ce44SJohn Forte 
322fcf3ce44SJohn Forte 		if (fcode_ver_buf != NULL) {
323fcf3ce44SJohn Forte 			kmem_free(fcode_ver_buf, (size_t)i);
324fcf3ce44SJohn Forte 		}
325fcf3ce44SJohn Forte 
326fcf3ce44SJohn Forte 	}
327fcf3ce44SJohn Forte 
328fcf3ce44SJohn Forte 	attrs->vendor_specific_id = ha->adapter_features;
329eb82ff87SDaniel Beauregard 	attrs->max_frame_size = CFG_IST(ha, CFG_CTRL_24258081) ?
330fcf3ce44SJohn Forte 	    (ha->init_ctrl_blk.cb24.max_frame_length[1] << 8 |
331fcf3ce44SJohn Forte 	    ha->init_ctrl_blk.cb24.max_frame_length[0]) :
332fcf3ce44SJohn Forte 	    (ha->init_ctrl_blk.cb.max_frame_length[1] << 8 |
333fcf3ce44SJohn Forte 	    ha->init_ctrl_blk.cb.max_frame_length[0]);
334fcf3ce44SJohn Forte 	attrs->supported_cos = 0x10000000; /* Class 3 only */
335fcf3ce44SJohn Forte 
336fcf3ce44SJohn Forte 	switch (chip & 0xFF00) {
337fcf3ce44SJohn Forte 	case 0x2200:
338fcf3ce44SJohn Forte 		attrs->supported_speed = FC_HBA_PORTSPEED_1GBIT;
339fcf3ce44SJohn Forte 		break;
340fcf3ce44SJohn Forte 	case 0x2300:
341fcf3ce44SJohn Forte 		attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT |
342fcf3ce44SJohn Forte 		    FC_HBA_PORTSPEED_1GBIT;
343fcf3ce44SJohn Forte 		break;
344fcf3ce44SJohn Forte 	case 0x2400:
345fcf3ce44SJohn Forte 	case 0x8400:
346fcf3ce44SJohn Forte 		attrs->supported_speed = FC_HBA_PORTSPEED_4GBIT |
348fcf3ce44SJohn Forte 		break;
3494f8b8adcSDaniel Beauregard 	case 0x8000:
3505dfd244aSDaniel Beauregard 		attrs->supported_speed = FC_HBA_PORTSPEED_10GBIT;
3515dfd244aSDaniel Beauregard 		break;
352fcf3ce44SJohn Forte 	case 0x2500:
353fcf3ce44SJohn Forte 		attrs->supported_speed = FC_HBA_PORTSPEED_8GBIT |
354fcf3ce44SJohn Forte 		    FC_HBA_PORTSPEED_4GBIT | FC_HBA_PORTSPEED_2GBIT |
355fcf3ce44SJohn Forte 		    FC_HBA_PORTSPEED_1GBIT;
356fcf3ce44SJohn Forte 
357fcf3ce44SJohn Forte 		/*
358fcf3ce44SJohn Forte 		 * Correct supported speeds based on type of
359fcf3ce44SJohn Forte 		 * sfp that is present
360fcf3ce44SJohn Forte 		 */
361fcf3ce44SJohn Forte 		switch (ha->sfp_stat) {
362fcf3ce44SJohn Forte 		case 2:
363fcf3ce44SJohn Forte 		case 4:
364fcf3ce44SJohn Forte 			/* 4GB sfp */
365fcf3ce44SJohn Forte 			attrs->supported_speed &= ~FC_HBA_PORTSPEED_8GBIT;
366fcf3ce44SJohn Forte 			break;
367fcf3ce44SJohn Forte 		case 3:
368fcf3ce44SJohn Forte 		case 5:
369fcf3ce44SJohn Forte 			/* 8GB sfp */
370fcf3ce44SJohn Forte 			attrs->supported_speed &= ~FC_HBA_PORTSPEED_1GBIT;
371fcf3ce44SJohn Forte 			break;
372fcf3ce44SJohn Forte 		default:
373fcf3ce44SJohn Forte 			EL(ha, "sfp_stat: %xh\n", ha->sfp_stat);
374fcf3ce44SJohn Forte 			break;
375fcf3ce44SJohn Forte 
376fcf3ce44SJohn Forte 		}
377fcf3ce44SJohn Forte 
378fcf3ce44SJohn Forte 		break;
379fcf3ce44SJohn Forte 	case 0x5400:
380fcf3ce44SJohn Forte 		if (model == 0x13e) {
381fcf3ce44SJohn Forte 			/* QLE210 */
382fcf3ce44SJohn Forte 			attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT;
383fcf3ce44SJohn Forte 		} else {
384fcf3ce44SJohn Forte 			attrs->supported_speed = FC_HBA_PORTSPEED_4GBIT;
385fcf3ce44SJohn Forte 		}
386fcf3ce44SJohn Forte 		break;
387fcf3ce44SJohn Forte 	case 0x6300:
388fcf3ce44SJohn Forte 		attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT;
389fcf3ce44SJohn Forte 		break;
390fcf3ce44SJohn Forte 	default:
391fcf3ce44SJohn Forte 		attrs->supported_speed = FC_HBA_PORTSPEED_UNKNOWN;
392fcf3ce44SJohn Forte 		break;
393fcf3ce44SJohn Forte 	}
394fcf3ce44SJohn Forte 
395fcf3ce44SJohn Forte 	/* Use parent dip as adapter identifier */
396fcf3ce44SJohn Forte 	attrs->hba_fru_details.low = 0x514C6F6769630000; /* QLogic */
397fcf3ce44SJohn Forte 
398fcf3ce44SJohn Forte 	if (ha->fru_hba_index == 0) {
399fcf3ce44SJohn Forte 		EL(ha, "unable to generate high_fru details from "
400fcf3ce44SJohn Forte 		    "device path: %s\n", ha->devpath);
401fcf3ce44SJohn Forte 		attrs->hba_fru_details.low = 0;
402fcf3ce44SJohn Forte 		attrs->hba_fru_details.high = 0;
403fcf3ce44SJohn Forte 		attrs->hba_fru_details.port_index = 0;
404fcf3ce44SJohn Forte 	} else {
405fcf3ce44SJohn Forte 		attrs->hba_fru_details.high = ha->fru_hba_index;
406fcf3ce44SJohn Forte 		attrs->hba_fru_details.port_index = ha->fru_port_index;
407fcf3ce44SJohn Forte 	}
408fcf3ce44SJohn Forte 
409fcf3ce44SJohn Forte 	/*
410fcf3ce44SJohn Forte 	 * Populate the model info. Legacy (22xx, 23xx, 63xx) do not
411fcf3ce44SJohn Forte 	 * have vpd info, so use the hard coded table. Anything else
412fcf3ce44SJohn Forte 	 * has VPD (or is suppose to have VPD), so use that. For both
413fcf3ce44SJohn Forte 	 * cases, if the model isn't found, use defaults.
414fcf3ce44SJohn Forte 	 */
415fcf3ce44SJohn Forte 
416fcf3ce44SJohn Forte 	switch (chip & 0xFF00) {
417fcf3ce44SJohn Forte 	case 0x2200:
418fcf3ce44SJohn Forte 	case 0x2300:
419fcf3ce44SJohn Forte 	case 0x6300:
420fcf3ce44SJohn Forte 		/* Table based data */
421fcf3ce44SJohn Forte 		for (i = 0; models[i].ssid; i++) {
422fcf3ce44SJohn Forte 			if ((model == models[i].ssid) &&
423fcf3ce44SJohn Forte 			    (ssdevid == models[i].ssvid)) {
424fcf3ce44SJohn Forte 				break;
425fcf3ce44SJohn Forte 			}
426fcf3ce44SJohn Forte 		}
427fcf3ce44SJohn Forte 
428fcf3ce44SJohn Forte 		if (models[i].ssid) {
429fcf3ce44SJohn Forte 			(void) snprintf(attrs->model, FCHBA_MODEL_LEN, "%s",
430fcf3ce44SJohn Forte 			    models[i].model);
431fcf3ce44SJohn Forte 			(void) snprintf(attrs->model_description,
432fcf3ce44SJohn Forte 			    FCHBA_MODEL_DESCRIPTION_LEN, "%s",
433fcf3ce44SJohn Forte 			    models[i].model_description);
434fcf3ce44SJohn Forte 		} else {
435fcf3ce44SJohn Forte 			(void) snprintf(attrs->model, FCHBA_MODEL_LEN,
436fcf3ce44SJohn Forte 			    "%x", chip);
437fcf3ce44SJohn Forte 			(void) snprintf(attrs->model_description,
438fcf3ce44SJohn Forte 			    FCHBA_MODEL_DESCRIPTION_LEN, "%x", chip);
439fcf3ce44SJohn Forte 		}
440fcf3ce44SJohn Forte 
441fcf3ce44SJohn Forte 		/* Special model handling for RoHS version of the HBA */
442fcf3ce44SJohn Forte 		if (models[i].ssid == 0x10a && ha->adapInfo[10] ==
443fcf3ce44SJohn Forte 		    (uint8_t)0x36) {
444fcf3ce44SJohn Forte 			(void) snprintf(attrs->model, FCHBA_MODEL_LEN, "%s",
445fcf3ce44SJohn Forte 			    "375-3363-xx");
446fcf3ce44SJohn Forte 			(void) snprintf(attrs->model_description,
447fcf3ce44SJohn Forte 			    FCHBA_MODEL_DESCRIPTION_LEN, "%s",
448fcf3ce44SJohn Forte 			    "SG-XPCI2FC-QF2-Z");
449fcf3ce44SJohn Forte 		}
450fcf3ce44SJohn Forte 		break;
451fcf3ce44SJohn Forte 
452fcf3ce44SJohn Forte 	case 0x2400:
453fcf3ce44SJohn Forte 	case 0x2500:
454fcf3ce44SJohn Forte 	case 0x5400:
455fcf3ce44SJohn Forte 	case 0x8400:
4565dfd244aSDaniel Beauregard 	case 0x8000:
457fcf3ce44SJohn Forte 	default:
458fcf3ce44SJohn Forte 		if ((i = ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_PN,
459fcf3ce44SJohn Forte 		    (uint8_t *)attrs->model, FCHBA_MODEL_LEN)) >= 0) {
460fcf3ce44SJohn Forte 			(void) ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_PRODID,
461fcf3ce44SJohn Forte 			    (uint8_t *)attrs->model_description,
462fcf3ce44SJohn Forte 			    FCHBA_MODEL_DESCRIPTION_LEN);
463fcf3ce44SJohn Forte 		} else {
464fcf3ce44SJohn Forte 			(void) snprintf(attrs->model, FCHBA_MODEL_LEN,
465fcf3ce44SJohn Forte 			    "%x", chip);
466fcf3ce44SJohn Forte 			(void) snprintf(attrs->model_description,
467fcf3ce44SJohn Forte 			    FCHBA_MODEL_DESCRIPTION_LEN, "%x", chip);
468fcf3ce44SJohn Forte 		}
469fcf3ce44SJohn Forte 		break;
470fcf3ce44SJohn Forte 	}
471fcf3ce44SJohn Forte 
472fcf3ce44SJohn Forte 	/*
473fcf3ce44SJohn Forte 	 * Populate the LV symbolic node and port name strings
474fcf3ce44SJohn Forte 	 *
475fcf3ce44SJohn Forte 	 * Symbolic node name format is:
476fcf3ce44SJohn Forte 	 *	<hostname>
477fcf3ce44SJohn Forte 	 *
478fcf3ce44SJohn Forte 	 * Symbolic port name format is:
479fcf3ce44SJohn Forte 	 *	<driver_name>(<instance>,<vp index>)
480fcf3ce44SJohn Forte 	 */
481fcf3ce44SJohn Forte 	vlen = (strlen(utsname.nodename) > FCHBA_SYMB_NAME_LEN ?
482fcf3ce44SJohn Forte 	    FCHBA_SYMB_NAME_LEN : strlen(utsname.nodename));
483fcf3ce44SJohn Forte 	(void) snprintf((int8_t *)attrs->sym_node_name, vlen, "%s",
484fcf3ce44SJohn Forte 	    utsname.nodename);
485fcf3ce44SJohn Forte 
486fcf3ce44SJohn Forte 	vlen = (strlen(QL_NAME) + 9 > FCHBA_SYMB_NAME_LEN ?
487fcf3ce44SJohn Forte 	    FCHBA_SYMB_NAME_LEN : strlen(QL_NAME) + 9);
488fcf3ce44SJohn Forte 	(void) snprintf((int8_t *)attrs->sym_port_name, vlen,
489fcf3ce44SJohn Forte 	    "%s(%d,%d)", QL_NAME, ha->instance, ha->vp_index);
490fcf3ce44SJohn Forte 
4915dfd244aSDaniel Beauregard 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
492fcf3ce44SJohn Forte }
493fcf3ce44SJohn Forte 
494fcf3ce44SJohn Forte /*
495fcf3ce44SJohn Forte  * ql_setup_fruinfo
496fcf3ce44SJohn Forte  *	Generates common id's for instances on the same
497fcf3ce44SJohn Forte  *	physical HBA.
498fcf3ce44SJohn Forte  *
499fcf3ce44SJohn Forte  * Input:
500fcf3ce44SJohn Forte  *	ha =  adapter state structure
501fcf3ce44SJohn Forte  *
502fcf3ce44SJohn Forte  * Returns:
503fcf3ce44SJohn Forte  *
504fcf3ce44SJohn Forte  * Context:
505fcf3ce44SJohn Forte  *	Kernel context.
506fcf3ce44SJohn Forte  */
507fcf3ce44SJohn Forte void
ql_setup_fruinfo(ql_adapter_state_t * ha)508fcf3ce44SJohn Forte ql_setup_fruinfo(ql_adapter_state_t *ha)
509fcf3ce44SJohn Forte {
510fcf3ce44SJohn Forte 	uint32_t 		mybasedev_len;
511fcf3ce44SJohn Forte 	ql_adapter_state_t	*base_ha = NULL;
512fcf3ce44SJohn Forte 
5135dfd244aSDaniel Beauregard 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
514fcf3ce44SJohn Forte 
515fcf3ce44SJohn Forte 	/*
516fcf3ce44SJohn Forte 	 * To generate common id for instances residing on the
517fcf3ce44SJohn Forte 	 * the same HBA, the devpath for each instance is parsed
518fcf3ce44SJohn Forte 	 * and those instances which have matching base devpaths are
519fcf3ce44SJohn Forte 	 * given same hba_index, and each port on the same hba are
520fcf3ce44SJohn Forte 	 * then assigned unique port_indexs based on the devpath.
521fcf3ce44SJohn Forte 	 */
522fcf3ce44SJohn Forte 
523fcf3ce44SJohn Forte 	/*
524fcf3ce44SJohn Forte 	 * Get this ha's basedev path and its port index
525fcf3ce44SJohn Forte 	 */
526fcf3ce44SJohn Forte 	if (ql_get_basedev_len(ha, &mybasedev_len, &ha->fru_port_index) == 0) {
527fcf3ce44SJohn Forte 
528fcf3ce44SJohn Forte 		GLOBAL_STATE_LOCK();
529fcf3ce44SJohn Forte 
530fcf3ce44SJohn Forte 		/*
531fcf3ce44SJohn Forte 		 * Search for this basedev against all of the
532fcf3ce44SJohn Forte 		 * ha in the ql_hba global list. If found one
533fcf3ce44SJohn Forte 		 * then we are part of other adapter in the
534fcf3ce44SJohn Forte 		 * ql_hba list and hence use that ha's hba_index.
535fcf3ce44SJohn Forte 		 * If not create a new one from the global hba index.
536fcf3ce44SJohn Forte 		 */
537fcf3ce44SJohn Forte 		base_ha = ql_search_basedev(ha, mybasedev_len);
538fcf3ce44SJohn Forte 		if (base_ha != NULL && base_ha->fru_hba_index != 0) {
539fcf3ce44SJohn Forte 			ha->fru_hba_index = base_ha->fru_hba_index;
540fcf3ce44SJohn Forte 		} else {
541fcf3ce44SJohn Forte 			ha->fru_hba_index = ql_gfru_hba_index++;
542fcf3ce44SJohn Forte 		}
543fcf3ce44SJohn Forte 
544*f885d00fSDaniel Beauregard 		if (CFG_IST(ha, CFG_CTRL_8081)) {
5454f8b8adcSDaniel Beauregard 			/*
5464f8b8adcSDaniel Beauregard 			 * The FC functions on 81xx hbas are functions 2 and 3
5474f8b8adcSDaniel Beauregard 			 * while the Nic functions occupy 0 and 1.  Adjust
5484f8b8adcSDaniel Beauregard 			 * fru port index to be like previous FCAs.
5494f8b8adcSDaniel Beauregard 			 */
550*f885d00fSDaniel Beauregard 			ha->fru_port_index = ha->flags & FUNCTION_1 ? 1 : 0;
551eb82ff87SDaniel Beauregard 		}
5524f8b8adcSDaniel Beauregard 
553fcf3ce44SJohn Forte 		GLOBAL_STATE_UNLOCK();
554fcf3ce44SJohn Forte 
555fcf3ce44SJohn Forte 	} else {
556fcf3ce44SJohn Forte 		ha->fru_hba_index = 0;
557fcf3ce44SJohn Forte 		ha->fru_port_index = 0;
558fcf3ce44SJohn Forte 	}
559fcf3ce44SJohn Forte 
5605dfd244aSDaniel Beauregard 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
561fcf3ce44SJohn Forte }
562fcf3ce44SJohn Forte 
563fcf3ce44SJohn Forte /*
564fcf3ce44SJohn Forte  *  ql_get_basedev_len
565fcf3ce44SJohn Forte  *
566fcf3ce44SJohn Forte  *	Gets the length of the base device name in the
567fcf3ce44SJohn Forte  *	devpath of the current instance.
568fcf3ce44SJohn Forte  *
569fcf3ce44SJohn Forte  * Input:
570fcf3ce44SJohn Forte  *	ha		- adapter state pointer.
571fcf3ce44SJohn Forte  *	basedev_len	- pointer to the integer which
572fcf3ce44SJohn Forte  *			  holds the calculated length.
573fcf3ce44SJohn Forte  *	port_index	- pointer to the integer which
574fcf3ce44SJohn Forte  *			  contains the port index of
575fcf3ce44SJohn Forte  *			  for this device.
576fcf3ce44SJohn Forte  * Returns:
577fcf3ce44SJohn Forte  *	0 if successfully parsed, -1 otherwise.
578fcf3ce44SJohn Forte  *
579fcf3ce44SJohn Forte  * Context:
580fcf3ce44SJohn Forte  *	Kernel context.
581fcf3ce44SJohn Forte  */
582fcf3ce44SJohn Forte static uint32_t
ql_get_basedev_len(ql_adapter_state_t * ha,uint32_t * basedev_len,uint32_t * port_index)583fcf3ce44SJohn Forte ql_get_basedev_len(ql_adapter_state_t *ha, uint32_t *basedev_len,
584fcf3ce44SJohn Forte     uint32_t *port_index)
585fcf3ce44SJohn Forte {
586fcf3ce44SJohn Forte 	int32_t		dev_off;
587fcf3ce44SJohn Forte 	int32_t		port_off;
588fcf3ce44SJohn Forte 	int8_t		*devstr;
589fcf3ce44SJohn Forte 
5905dfd244aSDaniel Beauregard 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
591fcf3ce44SJohn Forte 
592fcf3ce44SJohn Forte 	if (ha->devpath == NULL) {
593fcf3ce44SJohn Forte 		return ((uint32_t)-1);
594fcf3ce44SJohn Forte 	}
595fcf3ce44SJohn Forte 
596fcf3ce44SJohn Forte 	dev_off = (int32_t)(strlen(ha->devpath) - 1);
597fcf3ce44SJohn Forte 	port_off = -1;
598fcf3ce44SJohn Forte 
599fcf3ce44SJohn Forte 	/* Until we reach the first char or a '@' char in the path */
600fcf3ce44SJohn Forte 	while ((dev_off >= 0) && (ha->devpath[dev_off] != '@')) {
601fcf3ce44SJohn Forte 
602fcf3ce44SJohn Forte 		if (ha->devpath[dev_off] == ',') {
603fcf3ce44SJohn Forte 			port_off = dev_off + 1;
604fcf3ce44SJohn Forte 		}
605fcf3ce44SJohn Forte 
606fcf3ce44SJohn Forte 		dev_off--;
607fcf3ce44SJohn Forte 	}
608fcf3ce44SJohn Forte 
609fcf3ce44SJohn Forte 	if (dev_off < 0) {
610fcf3ce44SJohn Forte 		EL(ha, "Invalid device path '%s'. Cannot get basedev\n",
611fcf3ce44SJohn Forte 		    ha->devpath);
612fcf3ce44SJohn Forte 		return ((uint32_t)-1);
613fcf3ce44SJohn Forte 	}
614fcf3ce44SJohn Forte 
615fcf3ce44SJohn Forte 	if (port_off == -1) {
616fcf3ce44SJohn Forte 		*port_index = 0;
617fcf3ce44SJohn Forte 		*basedev_len = (uint32_t)strlen(ha->devpath);
618fcf3ce44SJohn Forte 	} else {
619fcf3ce44SJohn Forte 		/* Get the port index */
620fcf3ce44SJohn Forte 		devstr = ha->devpath + port_off;
621fcf3ce44SJohn Forte 		*port_index = stoi(&devstr);
622fcf3ce44SJohn Forte 		if (*port_index == 0) {
623fcf3ce44SJohn Forte 			EL(ha, "Invalid device path '%s'. Cannot get "
624fcf3ce44SJohn Forte 			    "port_index\n", ha->devpath);
625fcf3ce44SJohn Forte 			return ((uint32_t)-1);
626fcf3ce44SJohn Forte 		}
627fcf3ce44SJohn Forte 
628fcf3ce44SJohn Forte 		*basedev_len = (uint32_t)(port_off - 1);
629fcf3ce44SJohn Forte 	}
630fcf3ce44SJohn Forte 
6315dfd244aSDaniel Beauregard 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
632fcf3ce44SJohn Forte 
633fcf3ce44SJohn Forte 	return (0);
634fcf3ce44SJohn Forte }
635fcf3ce44SJohn Forte 
636fcf3ce44SJohn Forte /*
637fcf3ce44SJohn Forte  * ql_search_basedev
638fcf3ce44SJohn Forte  *	Searches the list of ha instances to find which
639fcf3ce44SJohn Forte  *	ha instance has same base device path as input's.
640fcf3ce44SJohn Forte  *
641fcf3ce44SJohn Forte  * Input:
642fcf3ce44SJohn Forte  *	myha 		= current adapter state pointer.
643fcf3ce44SJohn Forte  *	mybasedev_len	= Length of the base device in the
644fcf3ce44SJohn Forte  *			  device path name.
645fcf3ce44SJohn Forte  *
646fcf3ce44SJohn Forte  * Returns:
647fcf3ce44SJohn Forte  *	If match	= ptr to matching ha structure.
648fcf3ce44SJohn Forte  *	If no match	= NULL ptr.
649fcf3ce44SJohn Forte  *
650fcf3ce44SJohn Forte  * Context:
651fcf3ce44SJohn Forte  *	Kernel context.
652fcf3ce44SJohn Forte  */
653fcf3ce44SJohn Forte static ql_adapter_state_t *
ql_search_basedev(ql_adapter_state_t * myha,uint32_t mybasedev_len)654fcf3ce44SJohn Forte ql_search_basedev(ql_adapter_state_t *myha, uint32_t mybasedev_len)
655fcf3ce44SJohn Forte {
656fcf3ce44SJohn Forte 	ql_link_t		*link;
657fcf3ce44SJohn Forte 	ql_adapter_state_t	*ha;
658fcf3ce44SJohn Forte 	uint32_t		basedev_len, port_index;
659fcf3ce44SJohn Forte 
6605dfd244aSDaniel Beauregard 	QL_PRINT_3(CE_CONT, "(%d): started\n", myha->instance);
661fcf3ce44SJohn Forte 
662fcf3ce44SJohn Forte 	for (link = ql_hba.first; link != NULL; link = link->next) {
663fcf3ce44SJohn Forte 
664fcf3ce44SJohn Forte 		ha = link->base_address;
665fcf3ce44SJohn Forte 
666fcf3ce44SJohn Forte 		if (ha == NULL) {
667fcf3ce44SJohn Forte 			EL(myha, "null ha link detected!\n");
668fcf3ce44SJohn Forte 			return (NULL);
669fcf3ce44SJohn Forte 		}
670fcf3ce44SJohn Forte 
671fcf3ce44SJohn Forte 		if (ha == myha) {
672fcf3ce44SJohn Forte 			continue;
673fcf3ce44SJohn Forte 		}
674fcf3ce44SJohn Forte 
675fcf3ce44SJohn Forte 		if (ql_get_basedev_len(ha, &basedev_len, &port_index) != 0) {
676fcf3ce44SJohn Forte 			if (ha->devpath == NULL) {
677fcf3ce44SJohn Forte 				EL(myha, "Device path NULL. Unable to get "
678fcf3ce44SJohn Forte 				    "the basedev\n");
679fcf3ce44SJohn Forte 			} else {
680fcf3ce44SJohn Forte 				EL(myha, "Invalid device path '%s'. Cannot "
681fcf3ce44SJohn Forte 				    "get the hba index and port index\n",
682fcf3ce44SJohn Forte 				    ha->devpath);
683fcf3ce44SJohn Forte 			}
684fcf3ce44SJohn Forte 			continue;
685fcf3ce44SJohn Forte 		}
686fcf3ce44SJohn Forte 
687fcf3ce44SJohn Forte 		/*
688fcf3ce44SJohn Forte 		 * If both the basedev len do not match, then it
689fcf3ce44SJohn Forte 		 * is obvious that both are not pointing to the
690fcf3ce44SJohn Forte 		 * same base device.
691fcf3ce44SJohn Forte 		 */
692fcf3ce44SJohn Forte 		if ((basedev_len == mybasedev_len) && (strncmp(myha->devpath,
693fcf3ce44SJohn Forte 		    ha->devpath, basedev_len) == 0)) {
694fcf3ce44SJohn Forte 
695fcf3ce44SJohn Forte 			/* We found the ha with same basedev */
6965dfd244aSDaniel Beauregard 			QL_PRINT_3(CE_CONT, "(%d): found, done\n",
697fcf3ce44SJohn Forte 			    myha->instance);
698fcf3ce44SJohn Forte 			return (ha);
699fcf3ce44SJohn Forte 		}
700fcf3ce44SJohn Forte 	}
701fcf3ce44SJohn Forte 
7025dfd244aSDaniel Beauregard 	QL_PRINT_3(CE_CONT, "(%d): not found, done\n", myha->instance);
703fcf3ce44SJohn Forte 
704fcf3ce44SJohn Forte 	return (NULL);
705fcf3ce44SJohn Forte }