2
* Copyright(c) 2009 Intel Corporation. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms and conditions of the GNU General Public License,
6
* version 2, as published by the Free Software Foundation.
8
* This program is distributed in the hope it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* You should have received a copy of the GNU General Public License along with
14
* this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17
* Maintained at www.Open-FCoE.org
22
/* #define TEST_HBAAPI_V1 */
24
#define HBA_FCP_SCSI_ENTRY HBA_FCPSCSIENTRY
25
#define HBA_FCP_TARGET_MAPPING HBA_FCPTARGETMAPPING
27
#define HBA_FCP_SCSI_ENTRY HBA_FCPSCSIENTRYV2
28
#define HBA_FCP_TARGET_MAPPING HBA_FCPTARGETMAPPINGV2
30
/* #define TEST_REPORT_LUNS */
31
/* #define TEST_READ_CAP_V1 */
32
/* #define TEST_DEV_SERIAL_NO */
34
/* Maximum number of HBA the display routines support */
35
#define MAX_HBA_COUNT 128
38
#define FC_TYPE_FCP 0x08 /* SCSI FCP */
40
/* Constant defined in fcoe_def.h of fcoe driver */
41
#define FCOE_WORD_TO_BYTE 4
43
/* Minimum byte size of the received inquiry data */
44
#define MIN_INQ_DATA_SIZE 36
51
struct sa_nameval port_states[] = {
52
{ "Not Present", HBA_PORTSTATE_UNKNOWN },
53
{ "Online", HBA_PORTSTATE_ONLINE },
54
{ "Offline", HBA_PORTSTATE_OFFLINE },
55
{ "Blocked", HBA_PORTSTATE_UNKNOWN },
56
{ "Bypassed", HBA_PORTSTATE_BYPASSED },
57
{ "Diagnostics", HBA_PORTSTATE_DIAGNOSTICS },
58
{ "Linkdown", HBA_PORTSTATE_LINKDOWN },
59
{ "Error", HBA_PORTSTATE_ERROR },
60
{ "Loopback", HBA_PORTSTATE_LOOPBACK },
61
{ "Deleted", HBA_PORTSTATE_UNKNOWN },
66
* table of /sys port speed strings to HBA-API values.
68
struct sa_nameval port_speeds[] = {
69
{ "10 Gbit", HBA_PORTSPEED_10GBIT },
70
{ "2 Gbit", HBA_PORTSPEED_2GBIT },
71
{ "1 Gbit", HBA_PORTSPEED_1GBIT },
72
{ "Not Negotiated", HBA_PORTSPEED_NOT_NEGOTIATED },
73
{ "Unknown", HBA_PORTSPEED_UNKNOWN },
77
/** sa_enum_decode(buf, len, tp, val)
79
* @param buf buffer for result (may be used or not).
80
* @param len size of buffer (at least 32 bytes recommended).
81
* @param tp pointer to table of names and values, struct sa_nameval.
82
* @param val value to be decoded into a name.
83
* @returns pointer to name string. Unknown values are put into buffer in hex.
86
sa_enum_decode(char *buf, size_t len,
87
const struct sa_nameval *tp, u_int32_t val)
89
snprintf(buf, len, "Unknown");
90
for (; tp->nv_name != NULL; tp++) {
91
if (tp->nv_val == val) {
92
strncpy(buf, tp->nv_name, len);
100
sa_dump_wwn(void *Data, int Length, int Break)
102
unsigned char *pc = (unsigned char *)Data;
105
for (i = 1; i <= Length; i++) {
106
printf("%02X", (int)*pc++);
107
if ((Break != 0) && (!(i % Break)))
113
* Make a printable NUL-terminated copy of the string.
114
* The source buffer might not be NUL-terminated.
117
sa_strncpy_safe(char *dest, size_t len, const char *src, size_t src_len)
120
const char *sp = src;
122
while (len-- > 1 && src_len-- > 0 && *sp != '\0') {
123
*dp++ = isprint(*sp) ? *sp : (isspace(*sp) ? ' ' : '.');
129
* Take off trailing blanks.
131
while (--dp >= dest && isspace(*dp))
138
* Read a line from the specified file in the specified directory
139
* into the buffer. The file is opened and closed.
140
* Any trailing white space is trimmed off.
141
* This is useful for accessing /sys files.
142
* Returns 0 or an error number.
145
sa_sys_read_line(const char *dir, const char *file, char *buf, size_t len)
152
snprintf(file_name, sizeof(file_name), "%s/%s", dir, file);
153
fp = fopen(file_name, "r");
157
cp = fgets(buf, len, fp);
159
fprintf(stderr, "read error or empty file %s,"
160
" errno=0x%x\n", file_name, errno);
165
* Trim off trailing newline or other white space.
167
cp = buf + strlen(buf);
168
while (--cp >= buf && isspace(*cp))
177
sa_sys_read_u32(const char *dir, const char *file, u_int32_t *vp)
184
rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
186
val = strtoul(buf, &endptr, 0);
187
if (*endptr != '\0') {
189
"parse error. file %s/%s line '%s'\n",
198
static void show_wwn(unsigned char *pWwn)
200
sa_dump_wwn(pWwn, 8, 0);
204
show_hba_info(int hba_index, HBA_ADAPTERATTRIBUTES *hba_info, int flags)
207
printf("HBA #%d\n", hba_index);
208
printf(" Description: %s\n", hba_info->ModelDescription);
209
printf(" Revision: %s\n", hba_info->HardwareVersion);
210
printf(" Manufacturer: %s\n", hba_info->Manufacturer);
211
printf(" Serial Number: %s\n", hba_info->SerialNumber);
212
printf(" Driver: %s %s\n", hba_info->DriverName,
213
hba_info->DriverVersion);
214
printf(" Number of Ports: %d\n", hba_info->NumberOfPorts);
218
show_port_info(int hba_index, int lp_index,
219
HBA_ADAPTERATTRIBUTES *hba_info,
220
HBA_PORTATTRIBUTES *lp_info)
223
int len = sizeof(buf);
225
printf("\n Port #%d\n", lp_index);
227
printf(" Symbolic Name: %s\n",
228
lp_info->PortSymbolicName);
230
printf(" OS Device Name: %s\n",
231
lp_info->OSDeviceName);
233
printf(" Node Name: 0x");
234
show_wwn(lp_info->NodeWWN.wwn);
237
printf(" Port Name: 0x");
238
show_wwn(lp_info->PortWWN.wwn);
241
printf(" FabricName: 0x");
242
show_wwn(lp_info->FabricName.wwn);
245
sa_enum_decode(buf, len, port_speeds, lp_info->PortSpeed);
246
printf(" Speed: %s\n", buf);
248
sa_enum_decode(buf, len, port_speeds, lp_info->PortSupportedSpeed);
249
printf(" Supported Speed: %s\n", buf);
251
printf(" MaxFrameSize: %d\n",
252
lp_info->PortMaxFrameSize);
254
printf(" FC-ID (Port ID): 0x%06X\n",
257
sa_enum_decode(buf, sizeof(buf), port_states, lp_info->PortState);
258
printf(" State: %s\n", buf);
260
/* TODO: Display PortSupportedFc4Types and PortActiveFc4Types */
264
show_target_info(int hba_index, int lp_index, int rp_index,
265
HBA_ADAPTERATTRIBUTES *hba_info,
266
HBA_PORTATTRIBUTES *rp_info)
272
printf("Target #%d @ %s\n",
273
rp_index, hba_info->NodeSymbolicName + 5);
275
rc = sa_sys_read_line(rp_info->OSDeviceName, "roles", buf, sizeof(buf));
276
printf(" Roles: %s\n", buf);
278
printf(" Node Name: 0x");
279
show_wwn(rp_info->NodeWWN.wwn);
282
printf(" Port Name: 0x");
283
show_wwn(rp_info->PortWWN.wwn);
286
rc = sa_sys_read_u32(rp_info->OSDeviceName, "scsi_target_id", &tgt_id);
288
printf(" Target ID: %d\n", tgt_id);
290
printf(" MaxFrameSize: %d\n", rp_info->PortMaxFrameSize);
292
printf(" OS Device Name: %s\n",
293
strrchr(rp_info->OSDeviceName, '/') + 1);
295
printf(" FC-ID (Port ID): 0x%06X\n", rp_info->PortFcId);
297
sa_enum_decode(buf, sizeof(buf), port_states, rp_info->PortState);
298
printf(" State: %s\n", buf);
304
show_sense_data(char *dev, char *sense, int slen)
308
printf(" Sense Key=0x%02x", sense[2]);
310
printf(" ASC=0x%02x", sense[12]);
312
printf(" ASCQ=0x%02x\n", sense[13]);
316
#ifdef TEST_HBAAPI_V1
318
get_inquiry_data_v1(HBA_HANDLE hba_handle,
319
HBA_FCPSCSIENTRY *ep,
320
char *inqbuf, size_t inqlen)
327
memset(inqbuf, 0, inqlen);
328
memset(sense, 0, sizeof(sense));
329
rlen = (HBA_UINT32) inqlen;
330
slen = (HBA_UINT32) sizeof(sense);
331
status = HBA_SendScsiInquiry(hba_handle,
340
if ((status != HBA_STATUS_OK) ||
341
(rlen < MIN_INQ_DATA_SIZE)) {
343
"%s: HBA_SendScsiInquiry failed, "
344
"status=0x%x, rlen=%d\n",
345
__func__, status, rlen);
346
show_sense_data(ep->ScsiId.OSDeviceName, sense, slen);
347
return HBA_STATUS_ERROR;
349
return HBA_STATUS_OK;
353
get_inquiry_data_v2(HBA_HANDLE hba_handle,
354
HBA_PORTATTRIBUTES *lp_info,
355
HBA_FCPSCSIENTRYV2 *ep,
356
char *inqbuf, size_t inqlen)
364
memset(inqbuf, 0, inqlen);
365
memset(sense, 0, sizeof(sense));
366
rlen = (HBA_UINT32) inqlen;
367
slen = (HBA_UINT32) sizeof(sense);
368
sstat = SCSI_ST_GOOD;
369
status = HBA_ScsiInquiryV2(hba_handle,
380
if ((status != HBA_STATUS_OK) ||
381
(sstat != SCSI_ST_GOOD) ||
382
(rlen < MIN_INQ_DATA_SIZE)) {
384
"%s: HBA_ScsiInquiryV2 failed, "
385
"status=0x%x, sstat=0x%x, rlen=%d\n",
386
__func__, status, sstat, rlen);
387
if (sstat != SCSI_ST_GOOD)
388
show_sense_data(ep->ScsiId.OSDeviceName, sense, slen);
389
return HBA_STATUS_ERROR;
391
return HBA_STATUS_OK;
395
#ifdef TEST_HBAAPI_V1
397
get_device_capacity_v1(HBA_HANDLE hba_handle,
398
HBA_FCPSCSIENTRY *ep,
399
char *buf, size_t len)
405
int retry_count = 10;
407
while (retry_count--) {
409
memset(sense, 0, sizeof(sense));
410
rlen = (HBA_UINT32)len;
411
slen = (HBA_UINT32)sizeof(sense);
412
status = HBA_SendReadCapacity(hba_handle,
419
if (status == HBA_STATUS_OK)
420
return HBA_STATUS_OK;
421
if (sense[2] == 0x06)
424
"%s: HBA_SendReadCapacity failed, "
425
"status=0x%x, slen=%d\n",
426
__func__, status, slen);
427
show_sense_data(ep->ScsiId.OSDeviceName, sense, slen);
428
return HBA_STATUS_ERROR;
430
/* retry count exhausted */
431
return HBA_STATUS_ERROR;
435
get_device_capacity_v2(HBA_HANDLE hba_handle,
436
HBA_PORTATTRIBUTES *lp_info,
437
HBA_FCPSCSIENTRYV2 *ep,
438
char *buf, size_t len)
445
int retry_count = 10;
447
while (retry_count--) {
449
memset(sense, 0, sizeof(sense));
450
rlen = (HBA_UINT32)len;
451
slen = (HBA_UINT32)sizeof(sense);
452
sstat = SCSI_ST_GOOD;
453
status = HBA_ScsiReadCapacityV2(hba_handle,
462
if ((status == HBA_STATUS_OK) && (sstat == SCSI_ST_GOOD))
463
return HBA_STATUS_OK;
464
if ((sstat == SCSI_ST_CHECK) && (sense[2] == 0x06))
467
"%s: HBA_ScsiReadCapacityV2 failed, "
468
"status=0x%x, sstat=0x%x, slen=%d\n",
469
__func__, status, sstat, slen);
470
if (sstat != SCSI_ST_GOOD)
471
show_sense_data(ep->ScsiId.OSDeviceName, sense, slen);
472
return HBA_STATUS_ERROR;
474
/* retry count exhausted */
475
return HBA_STATUS_ERROR;
479
#ifdef TEST_DEV_SERIAL_NO
481
get_device_serial_number(HBA_HANDLE hba_handle,
482
HBA_FCPSCSIENTRYV2 *ep,
483
char *buf, size_t buflen)
485
struct scsi_inquiry_unit_sn *unit_sn;
492
memset(rspbuf, 0, sizeof(rspbuf));
493
memset(sense, 0, sizeof(sense));
494
rlen = (HBA_UINT32) sizeof(rspbuf);
495
slen = (HBA_UINT32) sizeof(sense);
496
status = HBA_SendScsiInquiry(hba_handle,
505
if (status != HBA_STATUS_OK) {
507
"%s: inquiry page 0x80 failed, status=0x%x\n",
509
show_sense_data(ep->ScsiId.OSDeviceName, sense, slen);
510
return HBA_STATUS_ERROR;
512
unit_sn = (struct scsi_inquiry_unit_sn *)rspbuf;
513
unit_sn->is_serial[unit_sn->is_page_len] = '\0';
514
sa_strncpy_safe(buf, buflen, (char *)unit_sn->is_serial,
515
(size_t)unit_sn->is_page_len);
516
return HBA_STATUS_OK;
520
#ifdef TEST_REPORT_LUNS
522
show_report_luns_data(char *rspbuf)
524
struct scsi_report_luns_resp *rp;
529
rp = (struct scsi_report_luns_resp *)rspbuf;
530
list_len = net32_get(&rp->rl_len);
531
printf("\tTotal Number of LUNs=%lu\n", list_len/sizeof(u_int64_t));
533
for (lp = rp->rl_lun; list_len > 0; lp++, list_len -= sizeof(*lp)) {
534
lun_id = net64_get(lp);
535
if (!(lun_id & ((0xfc01ULL << 48) - 1)))
536
printf("\tLUN %u\n", (u_int32_t)(lun_id >> 48));
538
printf("\tLUN %lx\n", (u_int64_t)lun_id);
543
get_report_luns_data_v1(HBA_HANDLE hba_handle, HBA_FCPSCSIENTRYV2 *ep)
546
char rspbuf[512 * sizeof(u_int64_t)]; /* max 512 luns */
550
int retry_count = 10;
552
while (retry_count--) {
553
memset(rspbuf, 0, sizeof(rspbuf));
554
memset(sense, 0, sizeof(sense));
555
rlen = (HBA_UINT32) sizeof(rspbuf);
556
slen = (HBA_UINT32) sizeof(sense);
557
status = HBA_SendReportLUNs(hba_handle,
563
if (status == HBA_STATUS_OK) {
564
show_report_luns_data(rspbuf);
565
return HBA_STATUS_OK;
567
if (sense[2] == 0x06)
570
"%s: HBA_SendReportLUNs failed, "
571
"status=0x%x, slen=%d\n",
572
__func__, status, slen);
573
show_sense_data(ep->ScsiId.OSDeviceName, sense, slen);
574
return HBA_STATUS_ERROR;
576
/* retry count exhausted */
577
return HBA_STATUS_ERROR;
581
get_report_luns_data_v2(HBA_HANDLE hba_handle,
582
HBA_PORTATTRIBUTES *lp_info,
583
HBA_FCPSCSIENTRYV2 *ep)
586
char rspbuf[512 * sizeof(u_int64_t)]; /* max 512 luns */
591
int retry_count = 10;
593
while (retry_count--) {
594
memset(rspbuf, 0, sizeof(rspbuf));
595
memset(sense, 0, sizeof(sense));
596
rlen = (HBA_UINT32) sizeof(rspbuf);
597
slen = (HBA_UINT32) sizeof(sense);
598
sstat = SCSI_ST_GOOD;
599
status = HBA_ScsiReportLUNsV2(hba_handle,
607
if ((status == HBA_STATUS_OK) && (sstat == SCSI_ST_GOOD)) {
608
show_report_luns_data(rspbuf);
609
return HBA_STATUS_OK;
611
if ((sstat == SCSI_ST_CHECK) && (sense[2] == 0x06))
614
"%s: HBA_ScsiReportLUNsV2 failed, "
615
"status=0x%x, sstat=0x%x, slen=%d\n",
616
__func__, status, sstat, slen);
617
if (sstat != SCSI_ST_GOOD)
618
show_sense_data(ep->ScsiId.OSDeviceName, sense, slen);
619
return HBA_STATUS_ERROR;
621
/* retry count exhausted */
622
return HBA_STATUS_ERROR;
627
show_short_lun_info_header(void)
629
printf(" LUN ID Device Name Capacity "
630
"Block Size Description\n");
631
printf(" ------ ----------- ---------- ---------- "
632
"----------------------------\n");
636
show_short_lun_info(HBA_FCP_SCSI_ENTRY *ep, char *inqbuf,
637
struct scsi_rcap10_resp *rcap_resp)
639
struct scsi_inquiry_std *inq = (struct scsi_inquiry_std *)inqbuf;
648
memset(vendor, 0, sizeof(vendor));
649
memset(model, 0, sizeof(model));
650
memset(capstr, 0, sizeof(capstr));
651
memset(rev, 0, sizeof(rev));
653
/* Get device capacity */
654
cap = (u_int64_t) net32_get(&rcap_resp->rc_block_len) *
655
net32_get(&rcap_resp->rc_lba);
656
cap_abbr = cap / (1024.0 * 1024.0);
658
if (cap_abbr >= 1024) {
662
if (cap_abbr >= 1024) {
666
if (cap_abbr >= 1024) {
670
snprintf(capstr, sizeof(capstr), "%0.2f %s", cap_abbr, abbr);
672
/* Get the device description */
673
sa_strncpy_safe(vendor, sizeof(vendor),
674
inq->is_vendor_id, sizeof(inq->is_vendor_id));
675
sa_strncpy_safe(model, sizeof(model),
676
inq->is_product, sizeof(inq->is_product));
677
sa_strncpy_safe(rev, sizeof(rev), inq->is_rev_level,
678
sizeof(inq->is_rev_level));
680
/* Show the LUN info */
681
printf("%10d %-11s %10s %7d %s %s (rev %s)\n",
682
ep->ScsiId.ScsiOSLun, ep->ScsiId.OSDeviceName,
683
capstr, net32_get(&rcap_resp->rc_block_len),
688
show_full_lun_info(HBA_HANDLE hba_handle,
689
HBA_ADAPTERATTRIBUTES *hba_info,
690
HBA_PORTATTRIBUTES *lp_info,
691
HBA_PORTATTRIBUTES *rp_info,
692
HBA_FCP_SCSI_ENTRY *ep,
694
struct scsi_rcap10_resp *rcap_resp)
696
struct scsi_inquiry_std *inq = (struct scsi_inquiry_std *)inqbuf;
706
#ifdef TEST_DEV_SERIAL_NO
708
char serial_number[32];
711
memset(vendor, 0, sizeof(vendor));
712
memset(model, 0, sizeof(model));
713
memset(capstr, 0, sizeof(capstr));
714
memset(rev, 0, sizeof(rev));
716
/* Get device description */
717
sa_strncpy_safe(vendor, sizeof(vendor),
718
inq->is_vendor_id, sizeof(inq->is_vendor_id));
719
sa_strncpy_safe(model, sizeof(model),
720
inq->is_product, sizeof(inq->is_product));
721
sa_strncpy_safe(rev, sizeof(rev), inq->is_rev_level,
722
sizeof(inq->is_rev_level));
724
/* Get device capacity */
725
cap = (u_int64_t) net32_get(&rcap_resp->rc_block_len) *
726
net32_get(&rcap_resp->rc_lba);
727
cap_abbr = cap / (1024.0 * 1024.0);
729
if (cap_abbr >= 1024) {
733
if (cap_abbr >= 1024) {
737
if (cap_abbr >= 1024) {
741
snprintf(capstr, sizeof(capstr), "%0.2f %s", cap_abbr, abbr);
743
/* Get SCSI target ID */
744
sa_sys_read_u32(rp_info->OSDeviceName,
745
"scsi_target_id", &tgt_id);
748
printf(" LUN #%d Information:\n", ep->ScsiId.ScsiOSLun);
749
printf(" OS Device Name: %s\n",
750
ep->ScsiId.OSDeviceName);
751
printf(" Description: %s %s (rev %s)\n",
753
printf(" Ethernet Port FCID: 0x%06X\n",
755
printf(" Target FCID: 0x%06X\n",
758
printf(" Target ID: (None)\n");
760
printf(" Target ID: %u\n", tgt_id);
761
printf(" LUN ID: %d\n",
762
ep->ScsiId.ScsiOSLun);
764
printf(" Capacity: %s\n", capstr);
765
printf(" Capacity in Blocks: %d\n",
766
net32_get(&rcap_resp->rc_lba));
767
printf(" Block Size: %d bytes\n",
768
net32_get(&rcap_resp->rc_block_len));
769
pqual = inq->is_periph & SCSI_INQ_PQUAL_MASK;
770
if (pqual == SCSI_PQUAL_ATT)
771
printf(" Status: Attached\n");
772
else if (pqual == SCSI_PQUAL_DET)
773
printf(" Status: Detached\n");
774
else if (pqual == SCSI_PQUAL_NC)
776
"Not capable of attachment\n");
778
#ifdef TEST_DEV_SERIAL_NO
779
/* Show the serial number of the device */
780
status = get_device_serial_number(hba_handle, ep,
781
serial_number, sizeof(serial_number));
782
if (status == HBA_STATUS_OK)
783
printf(" Serial Number: %s\n", serial_number);
789
/* Compare two LUN mappings for qsort */
791
lun_compare(const void *arg1, const void *arg2)
793
const HBA_FCP_SCSI_ENTRY *e1 = arg1;
794
const HBA_FCP_SCSI_ENTRY *e2 = arg2;
797
diff = e2->FcpId.FcId - e1->FcpId.FcId;
799
diff = e1->ScsiId.ScsiOSLun - e2->ScsiId.ScsiOSLun;
805
get_device_map(HBA_HANDLE hba_handle, HBA_PORTATTRIBUTES *lp_info,
806
HBA_FCP_TARGET_MAPPING **tgtmap, u_int32_t *lun_count)
809
HBA_FCP_TARGET_MAPPING *map = NULL;
810
HBA_FCP_SCSI_ENTRY *ep;
814
#define LUN_COUNT_START 8 /* number of LUNs to start with */
815
#define LUN_COUNT_INCR 4 /* excess to allocate */
818
* Get buffer large enough to retrieve all the mappings.
819
* If they don't fit, increase the size of the buffer and retry.
822
limit = LUN_COUNT_START;
824
i = (limit - 1) * sizeof(*ep) + sizeof(*map);
827
fprintf(stderr, "%s: malloc failed\n", __func__);
828
return HBA_STATUS_ERROR;
830
memset((char *)map, 0, i);
831
map->NumberOfEntries = limit;
832
#ifdef TEST_HBAAPI_V1
833
status = HBA_GetFcpTargetMapping(hba_handle, map);
835
status = HBA_GetFcpTargetMappingV2(
836
hba_handle, lp_info->PortWWN, map);
838
if (map->NumberOfEntries > limit) {
839
limit = map->NumberOfEntries + LUN_COUNT_INCR;
843
if (status != HBA_STATUS_OK) {
845
"%s: HBA_GetFcpTargetMappingV2 failed\n",
848
return HBA_STATUS_ERROR;
854
fprintf(stderr, "%s: map == NULL\n", __func__);
855
return HBA_STATUS_ERROR;
858
if (map->NumberOfEntries > limit) {
859
fprintf(stderr, "%s: map->NumberOfEntries=%d too big\n",
860
__func__, map->NumberOfEntries);
861
return HBA_STATUS_ERROR;
865
limit = map->NumberOfEntries;
867
/* Sort the response by LUN number */
868
qsort(ep, limit, sizeof(*ep), lun_compare);
872
return HBA_STATUS_OK;
876
scan_device_map(HBA_HANDLE hba_handle,
877
HBA_ADAPTERATTRIBUTES *hba_info,
878
HBA_PORTATTRIBUTES *lp_info,
879
HBA_PORTATTRIBUTES *rp_info,
880
struct opt_info *opt_info)
883
HBA_FCP_TARGET_MAPPING *map = NULL;
885
HBA_FCP_SCSI_ENTRY *ep;
889
struct scsi_rcap10_resp rcap_resp;
891
int print_header = 0;
893
status = get_device_map(hba_handle, lp_info, &map, &limit);
894
if (status != HBA_STATUS_OK) {
895
fprintf(stderr, "%s: get_device_map() failed\n", __func__);
900
for (i = 0; i < limit; i++, ep++) {
901
if (ep->FcpId.FcId != rp_info->PortFcId)
904
if (opt_info->l_flag &&
905
opt_info->l_fcid_present &&
906
opt_info->l_lun_id_present &&
907
ep->ScsiId.ScsiOSLun != opt_info->l_lun_id)
910
dev = ep->ScsiId.OSDeviceName;
911
if (strstr(dev, "/dev/") == dev)
914
/* Issue standard inquiry */
915
#ifdef TEST_HBAAPI_V1
916
status = get_inquiry_data_v1(hba_handle, ep,
917
inqbuf, sizeof(inqbuf));
919
status = get_inquiry_data_v2(hba_handle, lp_info,
920
ep, inqbuf, sizeof(inqbuf));
922
if (status != HBA_STATUS_OK)
926
/* Issue read capacity */
927
#ifdef TEST_HBAAPI_V1
928
status = get_device_capacity_v1(hba_handle, ep,
929
(char *)&rcap_resp, sizeof(rcap_resp));
931
status = get_device_capacity_v2(hba_handle, lp_info,
932
ep, (char *)&rcap_resp,
935
if (status != HBA_STATUS_OK)
938
if (opt_info->t_flag) {
940
show_short_lun_info_header();
943
show_short_lun_info(ep, inqbuf, &rcap_resp);
944
} else if (opt_info->l_flag)
945
show_full_lun_info(hba_handle, hba_info, lp_info,
946
rp_info, ep, inqbuf, &rcap_resp);
948
#ifdef TEST_REPORT_LUNS
949
if (i == 0) { /* only issue report luns to the first LUN */
950
#ifdef TEST_HBAAPI_V1
951
get_report_luns_data_v1(hba_handle, ep);
953
get_report_luns_data_v2(hba_handle, lp_info, ep);
964
show_port_stats_header(struct opt_info *opt_info)
967
printf("%-7s interval: %-2d Err Inv "
968
"IvTx Link Cntl Input Input Output Output\n",
969
opt_info->ifname, opt_info->n_interval);
970
printf("Seconds TxFrames TxBytes RxFrames RxBytes "
971
"Frms CRC Byte Fail Reqs Requests MBytes "
972
"Requests MBytes\n");
973
printf("------- --------- ------------ --------- -------------- "
974
"---- ---- ---- ---- ---- --------- --------- "
975
"--------- ---------\n");
979
show_port_stats_in_row(HBA_INT64 start_time,
980
HBA_PORTSTATISTICS *port_stats,
981
HBA_FC4STATISTICS *port_fc4stats)
983
printf("%-7lld ", port_stats->SecondsSinceLastReset - start_time);
984
printf("%-9lld ", port_stats->TxFrames);
985
printf("%-12lld ", port_stats->TxWords * FCOE_WORD_TO_BYTE);
986
printf("%-9lld ", port_stats->RxFrames);
987
printf("%-14lld ", port_stats->RxWords * FCOE_WORD_TO_BYTE);
988
printf("%-4lld ", port_stats->ErrorFrames);
989
printf("%-4lld ", port_stats->InvalidCRCCount);
990
printf("%-4lld ", port_stats->InvalidTxWordCount * FCOE_WORD_TO_BYTE);
991
printf("%-4lld ", port_stats->LinkFailureCount);
992
printf("%-4lld ", port_fc4stats->ControlRequests);
993
printf("%-9lld ", port_fc4stats->InputRequests);
994
printf("%-9lld ", port_fc4stats->InputMegabytes);
995
printf("%-9lld ", port_fc4stats->OutputRequests);
996
printf("%-9lld ", port_fc4stats->OutputMegabytes);
1002
display_port_stats(struct opt_info *opt_info)
1006
HBA_HANDLE hba_handle;
1007
HBA_ADAPTERATTRIBUTES hba_attrs;
1008
HBA_PORTATTRIBUTES port_attrs;
1009
HBA_PORTSTATISTICS port_stats;
1010
HBA_FC4STATISTICS port_fc4stats;
1011
HBA_INT64 start_time = 0;
1013
int i = 0, found = 0;
1015
hba_cnt = HBA_GetNumberOfAdapters();
1017
fprintf(stderr, "No FCoE interfaces created.\n");
1021
for (i = 0; i < hba_cnt; i++) {
1022
retval = HBA_GetAdapterName(i, namebuf);
1023
if (retval != HBA_STATUS_OK) {
1024
fprintf(stderr, "Failure of HBA_GetAdapterName: %d\n",
1029
hba_handle = HBA_OpenAdapter(namebuf);
1031
fprintf(stderr, "HBA_OpenAdapter failed\n");
1032
perror("HBA_OpenAdapter");
1036
retval = HBA_GetAdapterAttributes(hba_handle, &hba_attrs);
1037
if (retval != HBA_STATUS_OK) {
1039
"HBA_GetAdapterAttributes failed, retval=%d\n",
1041
perror("HBA_GetAdapterAttributes");
1045
retval = HBA_GetAdapterPortAttributes(
1046
hba_handle, 0, &port_attrs);
1047
if (retval != HBA_STATUS_OK) {
1049
"HBA_GetAdapterPortAttributes failed, "
1050
"status=%d\n", retval);
1054
if (strstr(port_attrs.PortSymbolicName, opt_info->ifname)) {
1061
fprintf(stderr, "Cannot find attributes for %s\n",
1068
unsigned int secs_left;
1070
retval = HBA_GetPortStatistics(hba_handle, 0, &port_stats);
1071
if (retval != HBA_STATUS_OK &&
1072
retval != HBA_STATUS_ERROR_NOT_SUPPORTED) {
1074
"HBA_GetPortStatistics failed, status=%d\n",
1078
if (retval == HBA_STATUS_ERROR_NOT_SUPPORTED) {
1080
"Port Statistics not supported by %s\n",
1086
start_time = port_stats.SecondsSinceLastReset;
1088
retval = HBA_GetFC4Statistics(hba_handle,
1092
if (retval != HBA_STATUS_OK &&
1093
retval != HBA_STATUS_ERROR_NOT_SUPPORTED) {
1094
fprintf(stderr, "HBA_GetFC4Statistics failed, "
1095
"status=%d\n", retval);
1098
if (retval == HBA_STATUS_ERROR_NOT_SUPPORTED) {
1100
"Port FC4 Statistics not supported by %s\n",
1105
show_port_stats_header(opt_info);
1106
show_port_stats_in_row(start_time, &port_stats, &port_fc4stats);
1109
/* wait for the requested time interval in seconds */
1110
secs_left = opt_info->n_interval;
1112
secs_left = sleep(secs_left);
1113
} while (secs_left);
1116
HBA_CloseAdapter(hba_handle);
1120
static struct hba_name_table {
1121
char SerialNumber[64];
1123
} hba_name_table[MAX_HBA_COUNT];
1126
find_hba_index(char *serial_number, int *hba_index)
1130
j = sizeof(hba_name_table[0].SerialNumber) - 1;
1131
for (i = 0; i < MAX_HBA_COUNT; i++) {
1132
if (hba_name_table[i].index == -1) {
1134
hba_name_table[i].index = i;
1135
/* TODO: change to sa_strncpy_safe */
1136
strncpy(hba_name_table[i].SerialNumber,
1139
return 1; /* print hba info */
1141
if (!strncmp(serial_number,
1142
hba_name_table[i].SerialNumber, j)) {
1143
*hba_index = hba_name_table[i].index;
1144
return 0; /* do not print hba info */
1152
display_adapter_info(struct opt_info *opt_info)
1156
HBA_UINT32 lport_cnt_per_hba = 1; /* always one port per hba */
1157
HBA_HANDLE hba_handle;
1158
HBA_ADAPTERATTRIBUTES hba_attrs;
1159
HBA_PORTATTRIBUTES port_attrs;
1165
for (i = 0; i < MAX_HBA_COUNT; i++) {
1166
hba_name_table[i].index = -1;
1167
memset(hba_name_table[i].SerialNumber, 0,
1168
sizeof(hba_name_table[i].SerialNumber));
1171
hba_cnt = HBA_GetNumberOfAdapters();
1173
fprintf(stderr, "No FCoE interfaces created.\n");
1177
for (i = 0; i < hba_cnt; i++) {
1178
retval = HBA_GetAdapterName(i, namebuf);
1179
if (retval != HBA_STATUS_OK) {
1181
"Failure of HBA_GetAdapterName: %d\n", retval);
1185
hba_handle = HBA_OpenAdapter(namebuf);
1187
fprintf(stderr, "HBA_OpenAdapter failed\n");
1188
perror("HBA_OpenAdapter");
1192
retval = HBA_GetAdapterAttributes(hba_handle, &hba_attrs);
1193
if (retval != HBA_STATUS_OK) {
1195
"HBA_GetAdapterAttributes failed, retval=%d\n",
1197
perror("HBA_GetAdapterAttributes");
1201
rc = find_hba_index(hba_attrs.SerialNumber, &hba_index);
1204
"Too many adapters. Maximum %d\n",
1208
show_hba_info(hba_index, &hba_attrs, 0);
1210
for (j = 0; j < lport_cnt_per_hba; j++) {
1211
retval = HBA_GetAdapterPortAttributes(
1212
hba_handle, j, &port_attrs);
1213
if (retval != HBA_STATUS_OK) {
1215
"HBA_GetAdapterPortAttributes failed, "
1216
"j=%d, status=%d\n", j, retval);
1221
if (opt_info->ifname &&
1222
!strstr(port_attrs.PortSymbolicName,
1225
show_port_info(hba_index, lp_index, &hba_attrs,
1228
HBA_CloseAdapter(hba_handle);
1233
display_target_info(struct opt_info *opt_info)
1237
HBA_UINT32 lport_cnt_per_hba = 1; /* always one port per hba */
1238
HBA_HANDLE hba_handle;
1239
HBA_ADAPTERATTRIBUTES hba_attrs;
1240
HBA_PORTATTRIBUTES port_attrs;
1241
HBA_PORTATTRIBUTES rport_attrs;
1248
for (i = 0; i < MAX_HBA_COUNT; i++) {
1249
hba_name_table[i].index = -1;
1250
memset(hba_name_table[i].SerialNumber, 0,
1251
sizeof(hba_name_table[i].SerialNumber));
1254
hba_cnt = HBA_GetNumberOfAdapters();
1256
fprintf(stderr, "No FCoE interfaces created.\n");
1260
for (i = 0; i < hba_cnt; i++) {
1261
retval = HBA_GetAdapterName(i, namebuf);
1262
if (retval != HBA_STATUS_OK) {
1264
"Failure of HBA_GetAdapterName: %d\n", retval);
1268
hba_handle = HBA_OpenAdapter(namebuf);
1270
fprintf(stderr, "HBA_OpenAdapter failed\n");
1271
perror("HBA_OpenAdapter");
1275
retval = HBA_GetAdapterAttributes(hba_handle, &hba_attrs);
1276
if (retval != HBA_STATUS_OK) {
1278
"HBA_GetAdapterAttributes failed, retval=%d\n",
1280
perror("HBA_GetAdapterAttributes");
1284
rc = find_hba_index(hba_attrs.SerialNumber, &hba_index);
1287
"Too many adapters. Maximum %d\n",
1292
for (j = 0; j < lport_cnt_per_hba; j++) {
1293
retval = HBA_GetAdapterPortAttributes(
1294
hba_handle, j, &port_attrs);
1295
if (retval != HBA_STATUS_OK) {
1297
"HBA_GetAdapterPortAttributes failed, "
1298
"j=%d, status=%d\n", j, retval);
1303
if (opt_info->ifname &&
1304
!strstr(port_attrs.PortSymbolicName,
1309
rp_index < port_attrs.NumberofDiscoveredPorts;
1311
retval = HBA_GetDiscoveredPortAttributes(
1312
hba_handle, j, rp_index,
1314
if (retval != HBA_STATUS_OK) {
1316
"HBA_GetDiscoveredPortAttributes "
1317
"failed, j=%d, for rp_index=%d, "
1318
"status=%d\n", j, rp_index, retval);
1323
* If -l option and fcid are specified in the
1324
* command, filter out the targets do not have
1325
* port ID equals to fcid.
1327
if (opt_info->l_flag &&
1328
opt_info->l_fcid_present &&
1329
rport_attrs.PortFcId != opt_info->l_fcid)
1332
show_target_info(hba_index, lp_index,
1333
rp_index, &hba_attrs,
1336
scan_device_map(hba_handle, &hba_attrs,
1337
&port_attrs, &rport_attrs,
1341
HBA_CloseAdapter(hba_handle);