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