~ubuntu-branches/ubuntu/wily/fcoe-utils/wily

« back to all changes in this revision

Viewing changes to fcoeadm_display.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2010-02-16 14:46:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100216144623-n6gqxpxc5nvonv9f
Tags: upstream-1.0.9
ImportĀ upstreamĀ versionĀ 1.0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright(c) 2009 Intel Corporation. All rights reserved.
 
3
 *
 
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.
 
7
 *
 
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
 
11
 * more details.
 
12
 *
 
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.
 
16
 *
 
17
 * Maintained at www.Open-FCoE.org
 
18
 */
 
19
 
 
20
#include "fcoeadm.h"
 
21
 
 
22
/* #define TEST_HBAAPI_V1 */
 
23
#ifdef TEST_HBAAPI_V1
 
24
  #define HBA_FCP_SCSI_ENTRY     HBA_FCPSCSIENTRY
 
25
  #define HBA_FCP_TARGET_MAPPING HBA_FCPTARGETMAPPING
 
26
#else
 
27
  #define HBA_FCP_SCSI_ENTRY     HBA_FCPSCSIENTRYV2
 
28
  #define HBA_FCP_TARGET_MAPPING HBA_FCPTARGETMAPPINGV2
 
29
#endif
 
30
/* #define TEST_REPORT_LUNS */
 
31
/* #define TEST_READ_CAP_V1 */
 
32
/* #define TEST_DEV_SERIAL_NO */
 
33
 
 
34
/* Maximum number of HBA the display routines support */
 
35
#define MAX_HBA_COUNT      128
 
36
 
 
37
/* Define FC4 Type */
 
38
#define FC_TYPE_FCP        0x08 /* SCSI FCP */
 
39
 
 
40
/* Constant defined in fcoe_def.h of fcoe driver */
 
41
#define FCOE_WORD_TO_BYTE  4
 
42
 
 
43
/* Minimum byte size of the received inquiry data */
 
44
#define MIN_INQ_DATA_SIZE       36
 
45
 
 
46
struct sa_nameval {
 
47
        char        *nv_name;
 
48
        u_int32_t   nv_val;
 
49
};
 
50
 
 
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 },
 
62
        { NULL, 0 }
 
63
};
 
64
 
 
65
/*
 
66
 * table of /sys port speed strings to HBA-API values.
 
67
 */
 
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 },
 
74
        { NULL, 0 }
 
75
};
 
76
 
 
77
/** sa_enum_decode(buf, len, tp, val)
 
78
 *
 
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.
 
84
 */
 
85
static const char *
 
86
sa_enum_decode(char *buf, size_t len,
 
87
                const struct sa_nameval *tp, u_int32_t val)
 
88
{
 
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);
 
93
                        break;
 
94
                }
 
95
        }
 
96
        return buf;
 
97
}
 
98
 
 
99
static void
 
100
sa_dump_wwn(void *Data, int Length, int Break)
 
101
{
 
102
        unsigned char *pc = (unsigned char *)Data;
 
103
        int i;
 
104
 
 
105
        for (i = 1; i <= Length; i++) {
 
106
                printf("%02X", (int)*pc++);
 
107
                if ((Break != 0) && (!(i % Break)))
 
108
                        printf("     ");
 
109
        }
 
110
}
 
111
 
 
112
/*
 
113
 * Make a printable NUL-terminated copy of the string.
 
114
 * The source buffer might not be NUL-terminated.
 
115
 */
 
116
static char *
 
117
sa_strncpy_safe(char *dest, size_t len, const char *src, size_t src_len)
 
118
{
 
119
        char *dp = dest;
 
120
        const char *sp = src;
 
121
 
 
122
        while (len-- > 1 && src_len-- > 0 && *sp != '\0') {
 
123
                *dp++ = isprint(*sp) ? *sp : (isspace(*sp) ? ' ' : '.');
 
124
                sp++;
 
125
        }
 
126
        *dp = '\0';
 
127
 
 
128
        /*
 
129
         * Take off trailing blanks.
 
130
         */
 
131
        while (--dp >= dest && isspace(*dp))
 
132
                *dp = '\0';
 
133
 
 
134
        return dest;
 
135
}
 
136
 
 
137
/*
 
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.
 
143
 */
 
144
static int
 
145
sa_sys_read_line(const char *dir, const char *file, char *buf, size_t len)
 
146
{
 
147
        FILE *fp;
 
148
        char file_name[256];
 
149
        char *cp;
 
150
        int rc = 0;
 
151
 
 
152
        snprintf(file_name, sizeof(file_name), "%s/%s", dir, file);
 
153
        fp = fopen(file_name, "r");
 
154
        if (fp == NULL)
 
155
                rc = -1;
 
156
        else {
 
157
                cp = fgets(buf, len, fp);
 
158
                if (cp == NULL) {
 
159
                        fprintf(stderr, "read error or empty file %s,"
 
160
                                " errno=0x%x\n", file_name, errno);
 
161
                        rc = -1;
 
162
                } else {
 
163
 
 
164
                        /*
 
165
                         * Trim off trailing newline or other white space.
 
166
                         */
 
167
                        cp = buf + strlen(buf);
 
168
                        while (--cp >= buf && isspace(*cp))
 
169
                                *cp = '\0';
 
170
                }
 
171
                fclose(fp);
 
172
        }
 
173
        return rc;
 
174
}
 
175
 
 
176
static int
 
177
sa_sys_read_u32(const char *dir, const char *file, u_int32_t *vp)
 
178
{
 
179
        char buf[256];
 
180
        int rc;
 
181
        u_int32_t val;
 
182
        char *endptr;
 
183
 
 
184
        rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
 
185
        if (rc == 0) {
 
186
                val = strtoul(buf, &endptr, 0);
 
187
                if (*endptr != '\0') {
 
188
                        fprintf(stderr,
 
189
                                "parse error. file %s/%s line '%s'\n",
 
190
                                dir, file, buf);
 
191
                        rc = -1;
 
192
                } else
 
193
                        *vp = val;
 
194
        }
 
195
        return rc;
 
196
}
 
197
 
 
198
static void show_wwn(unsigned char *pWwn)
 
199
{
 
200
        sa_dump_wwn(pWwn, 8, 0);
 
201
}
 
202
 
 
203
static void
 
204
show_hba_info(int hba_index, HBA_ADAPTERATTRIBUTES *hba_info, int flags)
 
205
{
 
206
        printf("\n");
 
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);
 
215
}
 
216
 
 
217
static void
 
218
show_port_info(int hba_index, int lp_index,
 
219
                HBA_ADAPTERATTRIBUTES *hba_info,
 
220
                HBA_PORTATTRIBUTES *lp_info)
 
221
{
 
222
        char buf[256];
 
223
        int len = sizeof(buf);
 
224
 
 
225
        printf("\n    Port #%d\n", lp_index);
 
226
 
 
227
        printf("        Symbolic Name:     %s\n",
 
228
                                        lp_info->PortSymbolicName);
 
229
 
 
230
        printf("        OS Device Name:    %s\n",
 
231
                                        lp_info->OSDeviceName);
 
232
 
 
233
        printf("        Node Name:         0x");
 
234
                                        show_wwn(lp_info->NodeWWN.wwn);
 
235
                                        printf("    \n");
 
236
 
 
237
        printf("        Port Name:         0x");
 
238
                                        show_wwn(lp_info->PortWWN.wwn);
 
239
                                        printf("    \n");
 
240
 
 
241
        printf("        FabricName:        0x");
 
242
                                        show_wwn(lp_info->FabricName.wwn);
 
243
                                        printf("    \n");
 
244
 
 
245
        sa_enum_decode(buf, len, port_speeds, lp_info->PortSpeed);
 
246
        printf("        Speed:             %s\n", buf);
 
247
 
 
248
        sa_enum_decode(buf, len, port_speeds, lp_info->PortSupportedSpeed);
 
249
        printf("        Supported Speed:   %s\n", buf);
 
250
 
 
251
        printf("        MaxFrameSize:      %d\n",
 
252
                                        lp_info->PortMaxFrameSize);
 
253
 
 
254
        printf("        FC-ID (Port ID):   0x%06X\n",
 
255
                                        lp_info->PortFcId);
 
256
 
 
257
        sa_enum_decode(buf, sizeof(buf), port_states, lp_info->PortState);
 
258
        printf("        State:             %s\n", buf);
 
259
 
 
260
        /* TODO: Display PortSupportedFc4Types and PortActiveFc4Types */
 
261
}
 
262
 
 
263
static void
 
264
show_target_info(int hba_index, int lp_index, int rp_index,
 
265
                HBA_ADAPTERATTRIBUTES *hba_info,
 
266
                HBA_PORTATTRIBUTES *rp_info)
 
267
{
 
268
        char buf[256];
 
269
        u_int32_t tgt_id;
 
270
        int rc;
 
271
 
 
272
        printf("Target #%d @ %s\n",
 
273
                                rp_index, hba_info->NodeSymbolicName + 5);
 
274
 
 
275
        rc = sa_sys_read_line(rp_info->OSDeviceName, "roles", buf, sizeof(buf));
 
276
        printf("    Roles:            %s\n", buf);
 
277
 
 
278
        printf("    Node Name:        0x");
 
279
                                show_wwn(rp_info->NodeWWN.wwn);
 
280
                                printf("    \n");
 
281
 
 
282
        printf("    Port Name:        0x");
 
283
                                show_wwn(rp_info->PortWWN.wwn);
 
284
                                printf("    \n");
 
285
 
 
286
        rc = sa_sys_read_u32(rp_info->OSDeviceName, "scsi_target_id", &tgt_id);
 
287
        if (tgt_id != -1)
 
288
                printf("    Target ID:        %d\n", tgt_id);
 
289
 
 
290
        printf("    MaxFrameSize:     %d\n", rp_info->PortMaxFrameSize);
 
291
 
 
292
        printf("    OS Device Name:   %s\n",
 
293
                                strrchr(rp_info->OSDeviceName, '/') + 1);
 
294
 
 
295
        printf("    FC-ID (Port ID):  0x%06X\n", rp_info->PortFcId);
 
296
 
 
297
        sa_enum_decode(buf, sizeof(buf), port_states, rp_info->PortState);
 
298
        printf("    State:            %s\n", buf);
 
299
 
 
300
        printf("    \n");
 
301
}
 
302
 
 
303
static void
 
304
show_sense_data(char *dev, char *sense, int slen)
 
305
{
 
306
        printf("%s", dev);
 
307
        if (slen >= 3)
 
308
                printf("    Sense Key=0x%02x", sense[2]);
 
309
        if (slen >= 13)
 
310
                printf(" ASC=0x%02x", sense[12]);
 
311
        if (slen >= 14)
 
312
                printf(" ASCQ=0x%02x\n", sense[13]);
 
313
        printf("\n");
 
314
}
 
315
 
 
316
#ifdef TEST_HBAAPI_V1
 
317
static HBA_STATUS
 
318
get_inquiry_data_v1(HBA_HANDLE hba_handle,
 
319
                    HBA_FCPSCSIENTRY *ep,
 
320
                    char *inqbuf, size_t inqlen)
 
321
{
 
322
        char sense[128];
 
323
        HBA_UINT32 rlen;
 
324
        HBA_UINT32 slen;
 
325
        HBA_STATUS status;
 
326
 
 
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,
 
332
                                     ep->FcpId.PortWWN,
 
333
                                     ep->FcpId.FcpLun,
 
334
                                     0,
 
335
                                     0,
 
336
                                     inqbuf,
 
337
                                     rlen,
 
338
                                     sense,
 
339
                                     slen);
 
340
        if ((status != HBA_STATUS_OK) ||
 
341
            (rlen < MIN_INQ_DATA_SIZE)) {
 
342
                fprintf(stderr,
 
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;
 
348
        }
 
349
        return HBA_STATUS_OK;
 
350
}
 
351
#else
 
352
static HBA_STATUS
 
353
get_inquiry_data_v2(HBA_HANDLE hba_handle,
 
354
                    HBA_PORTATTRIBUTES *lp_info,
 
355
                    HBA_FCPSCSIENTRYV2 *ep,
 
356
                    char *inqbuf, size_t inqlen)
 
357
{
 
358
        char sense[128];
 
359
        HBA_UINT32 rlen;
 
360
        HBA_UINT32 slen;
 
361
        HBA_STATUS status;
 
362
        HBA_UINT8 sstat;
 
363
 
 
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,
 
370
                                   lp_info->PortWWN,
 
371
                                   ep->FcpId.PortWWN,
 
372
                                   ep->FcpId.FcpLun,
 
373
                                   0,
 
374
                                   0,
 
375
                                   inqbuf,
 
376
                                   &rlen,
 
377
                                   &sstat,
 
378
                                   sense,
 
379
                                   &slen);
 
380
        if ((status != HBA_STATUS_OK) ||
 
381
            (sstat != SCSI_ST_GOOD) ||
 
382
            (rlen < MIN_INQ_DATA_SIZE)) {
 
383
                fprintf(stderr,
 
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;
 
390
        }
 
391
        return HBA_STATUS_OK;
 
392
}
 
393
#endif
 
394
 
 
395
#ifdef TEST_HBAAPI_V1
 
396
static HBA_STATUS
 
397
get_device_capacity_v1(HBA_HANDLE hba_handle,
 
398
                    HBA_FCPSCSIENTRY *ep,
 
399
                    char *buf, size_t len)
 
400
{
 
401
        char sense[128];
 
402
        HBA_UINT32 rlen;
 
403
        HBA_UINT32 slen;
 
404
        HBA_STATUS status;
 
405
        int retry_count = 10;
 
406
 
 
407
        while (retry_count--) {
 
408
                memset(buf, 0, len);
 
409
                memset(sense, 0, sizeof(sense));
 
410
                rlen = (HBA_UINT32)len;
 
411
                slen = (HBA_UINT32)sizeof(sense);
 
412
                status = HBA_SendReadCapacity(hba_handle,
 
413
                                              ep->FcpId.PortWWN,
 
414
                                              ep->FcpId.FcpLun,
 
415
                                              buf,
 
416
                                              rlen,
 
417
                                              sense,
 
418
                                              slen);
 
419
                if (status == HBA_STATUS_OK)
 
420
                        return HBA_STATUS_OK;
 
421
                if (sense[2] == 0x06)
 
422
                        continue;
 
423
                fprintf(stderr,
 
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;
 
429
        }
 
430
        /* retry count exhausted */
 
431
        return HBA_STATUS_ERROR;
 
432
}
 
433
#else
 
434
static HBA_STATUS
 
435
get_device_capacity_v2(HBA_HANDLE hba_handle,
 
436
                    HBA_PORTATTRIBUTES *lp_info,
 
437
                    HBA_FCPSCSIENTRYV2 *ep,
 
438
                    char *buf, size_t len)
 
439
{
 
440
        char sense[128];
 
441
        HBA_UINT32 rlen;
 
442
        HBA_UINT32 slen;
 
443
        HBA_STATUS status;
 
444
        HBA_UINT8 sstat;
 
445
        int retry_count = 10;
 
446
 
 
447
        while (retry_count--) {
 
448
                memset(buf, 0, len);
 
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,
 
454
                                                lp_info->PortWWN,
 
455
                                                ep->FcpId.PortWWN,
 
456
                                                ep->FcpId.FcpLun,
 
457
                                                buf,
 
458
                                                &rlen,
 
459
                                                &sstat,
 
460
                                                sense,
 
461
                                                &slen);
 
462
                if ((status == HBA_STATUS_OK) && (sstat == SCSI_ST_GOOD))
 
463
                        return HBA_STATUS_OK;
 
464
                if ((sstat == SCSI_ST_CHECK) && (sense[2] == 0x06))
 
465
                        continue;
 
466
                fprintf(stderr,
 
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;
 
473
        }
 
474
        /* retry count exhausted */
 
475
        return HBA_STATUS_ERROR;
 
476
}
 
477
#endif
 
478
 
 
479
#ifdef TEST_DEV_SERIAL_NO
 
480
static HBA_STATUS
 
481
get_device_serial_number(HBA_HANDLE hba_handle,
 
482
                         HBA_FCPSCSIENTRYV2 *ep,
 
483
                         char *buf, size_t buflen)
 
484
{
 
485
        struct scsi_inquiry_unit_sn *unit_sn;
 
486
        char rspbuf[256];
 
487
        char sense[128];
 
488
        HBA_UINT32 rlen;
 
489
        HBA_UINT32 slen;
 
490
        HBA_STATUS status;
 
491
 
 
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,
 
497
                                     ep->FcpId.PortWWN,
 
498
                                     ep->FcpId.FcpLun,
 
499
                                     SCSI_INQF_EVPD,
 
500
                                     SCSI_INQP_UNIT_SN,
 
501
                                     rspbuf,
 
502
                                     rlen,
 
503
                                     sense,
 
504
                                     slen);
 
505
        if (status != HBA_STATUS_OK) {
 
506
                fprintf(stderr,
 
507
                        "%s: inquiry page 0x80 failed, status=0x%x\n",
 
508
                        __func__, status);
 
509
                show_sense_data(ep->ScsiId.OSDeviceName, sense, slen);
 
510
                return HBA_STATUS_ERROR;
 
511
        }
 
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;
 
517
}
 
518
#endif
 
519
 
 
520
#ifdef TEST_REPORT_LUNS
 
521
static void
 
522
show_report_luns_data(char *rspbuf)
 
523
{
 
524
        struct scsi_report_luns_resp *rp;
 
525
        int list_len;
 
526
        net64_t *lp;
 
527
        u_int64_t lun_id;
 
528
 
 
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));
 
532
 
 
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));
 
537
                else
 
538
                        printf("\tLUN %lx\n", (u_int64_t)lun_id);
 
539
        }
 
540
}
 
541
 
 
542
static HBA_STATUS
 
543
get_report_luns_data_v1(HBA_HANDLE hba_handle, HBA_FCPSCSIENTRYV2 *ep)
 
544
{
 
545
        HBA_STATUS status;
 
546
        char rspbuf[512 * sizeof(u_int64_t)]; /* max 512 luns */
 
547
        char sense[128];
 
548
        HBA_UINT32 rlen;
 
549
        HBA_UINT32 slen;
 
550
        int retry_count = 10;
 
551
 
 
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,
 
558
                                             ep->FcpId.PortWWN,
 
559
                                             rspbuf,
 
560
                                             rlen,
 
561
                                             sense,
 
562
                                             slen);
 
563
                if (status == HBA_STATUS_OK) {
 
564
                        show_report_luns_data(rspbuf);
 
565
                        return HBA_STATUS_OK;
 
566
                }
 
567
                if (sense[2] == 0x06)
 
568
                        continue;
 
569
                fprintf(stderr,
 
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;
 
575
        }
 
576
        /* retry count exhausted */
 
577
        return HBA_STATUS_ERROR;
 
578
}
 
579
 
 
580
static HBA_STATUS
 
581
get_report_luns_data_v2(HBA_HANDLE hba_handle,
 
582
                       HBA_PORTATTRIBUTES *lp_info,
 
583
                       HBA_FCPSCSIENTRYV2 *ep)
 
584
{
 
585
        HBA_STATUS status;
 
586
        char rspbuf[512 * sizeof(u_int64_t)]; /* max 512 luns */
 
587
        char sense[128];
 
588
        HBA_UINT32 rlen;
 
589
        HBA_UINT32 slen;
 
590
        HBA_UINT8 sstat;
 
591
        int retry_count = 10;
 
592
 
 
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,
 
600
                                              lp_info->PortWWN,
 
601
                                              ep->FcpId.PortWWN,
 
602
                                              rspbuf,
 
603
                                              &rlen,
 
604
                                              &sstat,
 
605
                                              sense,
 
606
                                              &slen);
 
607
                if ((status == HBA_STATUS_OK) && (sstat == SCSI_ST_GOOD)) {
 
608
                        show_report_luns_data(rspbuf);
 
609
                        return HBA_STATUS_OK;
 
610
                }
 
611
                if ((sstat == SCSI_ST_CHECK) && (sense[2] == 0x06))
 
612
                        continue;
 
613
                fprintf(stderr,
 
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;
 
620
        }
 
621
        /* retry count exhausted */
 
622
        return HBA_STATUS_ERROR;
 
623
}
 
624
#endif
 
625
 
 
626
static void
 
627
show_short_lun_info_header(void)
 
628
{
 
629
        printf("    LUN ID  Device Name   Capacity   "
 
630
                "Block Size  Description\n");
 
631
        printf("    ------  -----------  ----------  ----------  "
 
632
                "----------------------------\n");
 
633
}
 
634
 
 
635
static void
 
636
show_short_lun_info(HBA_FCP_SCSI_ENTRY *ep, char *inqbuf,
 
637
                    struct scsi_rcap10_resp *rcap_resp)
 
638
{
 
639
        struct scsi_inquiry_std *inq = (struct scsi_inquiry_std *)inqbuf;
 
640
        char vendor[10];
 
641
        char model[20];
 
642
        char capstr[32];
 
643
        char rev[16];
 
644
        u_int64_t cap;
 
645
        double cap_abbr;
 
646
        char *abbr;
 
647
 
 
648
        memset(vendor, 0, sizeof(vendor));
 
649
        memset(model, 0, sizeof(model));
 
650
        memset(capstr, 0, sizeof(capstr));
 
651
        memset(rev, 0, sizeof(rev));
 
652
 
 
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);
 
657
        abbr = "MB";
 
658
        if (cap_abbr >= 1024) {
 
659
                cap_abbr /= 1024.0;
 
660
                abbr = "GB";
 
661
        }
 
662
        if (cap_abbr >= 1024) {
 
663
                cap_abbr /= 1024.0;
 
664
                abbr = "TB";
 
665
        }
 
666
        if (cap_abbr >= 1024) {
 
667
                cap_abbr /= 1024.0;
 
668
                abbr = "PB";
 
669
        }
 
670
        snprintf(capstr, sizeof(capstr), "%0.2f %s", cap_abbr, abbr);
 
671
 
 
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));
 
679
 
 
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),
 
684
                vendor, model, rev);
 
685
}
 
686
 
 
687
static void
 
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,
 
693
                   char *inqbuf,
 
694
                   struct scsi_rcap10_resp *rcap_resp)
 
695
{
 
696
        struct scsi_inquiry_std *inq = (struct scsi_inquiry_std *)inqbuf;
 
697
        char vendor[10];
 
698
        char model[20];
 
699
        char capstr[32];
 
700
        char rev[16];
 
701
        double cap_abbr;
 
702
        char *abbr;
 
703
        u_int64_t cap;
 
704
        u_int32_t tgt_id;
 
705
        u_int8_t pqual;
 
706
#ifdef TEST_DEV_SERIAL_NO
 
707
        HBA_STATUS status;
 
708
        char serial_number[32];
 
709
#endif
 
710
 
 
711
        memset(vendor, 0, sizeof(vendor));
 
712
        memset(model, 0, sizeof(model));
 
713
        memset(capstr, 0, sizeof(capstr));
 
714
        memset(rev, 0, sizeof(rev));
 
715
 
 
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));
 
723
 
 
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);
 
728
        abbr = "MB";
 
729
        if (cap_abbr >= 1024) {
 
730
                cap_abbr /= 1024.0;
 
731
                abbr = "GB";
 
732
        }
 
733
        if (cap_abbr >= 1024) {
 
734
                cap_abbr /= 1024.0;
 
735
                abbr = "TB";
 
736
        }
 
737
        if (cap_abbr >= 1024) {
 
738
                cap_abbr /= 1024.0;
 
739
                abbr = "PB";
 
740
        }
 
741
        snprintf(capstr, sizeof(capstr), "%0.2f %s", cap_abbr, abbr);
 
742
 
 
743
        /* Get SCSI target ID */
 
744
        sa_sys_read_u32(rp_info->OSDeviceName,
 
745
                        "scsi_target_id", &tgt_id);
 
746
 
 
747
        /* Show lun info */
 
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",
 
752
                                        vendor, model, rev);
 
753
        printf("        Ethernet Port FCID: 0x%06X\n",
 
754
                                        lp_info->PortFcId);
 
755
        printf("        Target FCID:        0x%06X\n",
 
756
                                        rp_info->PortFcId);
 
757
        if (tgt_id == -1)
 
758
                printf("        Target ID:          (None)\n");
 
759
        else
 
760
                printf("        Target ID:          %u\n", tgt_id);
 
761
        printf("        LUN ID:             %d\n",
 
762
                                        ep->ScsiId.ScsiOSLun);
 
763
 
 
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)
 
775
                printf("        Status:             "
 
776
                        "Not capable of attachment\n");
 
777
 
 
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);
 
784
#endif
 
785
 
 
786
        printf("\n");
 
787
}
 
788
 
 
789
/* Compare two LUN mappings for qsort */
 
790
static int
 
791
lun_compare(const void *arg1, const void *arg2)
 
792
{
 
793
        const HBA_FCP_SCSI_ENTRY *e1 = arg1;
 
794
        const HBA_FCP_SCSI_ENTRY *e2 = arg2;
 
795
        int diff;
 
796
 
 
797
        diff = e2->FcpId.FcId - e1->FcpId.FcId;
 
798
        if (diff == 0)
 
799
                diff = e1->ScsiId.ScsiOSLun - e2->ScsiId.ScsiOSLun;
 
800
 
 
801
        return diff;
 
802
}
 
803
 
 
804
static HBA_STATUS
 
805
get_device_map(HBA_HANDLE hba_handle, HBA_PORTATTRIBUTES *lp_info,
 
806
               HBA_FCP_TARGET_MAPPING **tgtmap, u_int32_t *lun_count)
 
807
{
 
808
        HBA_STATUS status;
 
809
        HBA_FCP_TARGET_MAPPING *map = NULL;
 
810
        HBA_FCP_SCSI_ENTRY *ep;
 
811
        u_int32_t limit;
 
812
        u_int32_t i;
 
813
 
 
814
#define LUN_COUNT_START     8       /* number of LUNs to start with */
 
815
#define LUN_COUNT_INCR      4       /* excess to allocate */
 
816
 
 
817
        /*
 
818
         * Get buffer large enough to retrieve all the mappings.
 
819
         * If they don't fit, increase the size of the buffer and retry.
 
820
         */
 
821
        *lun_count = 0;
 
822
        limit = LUN_COUNT_START;
 
823
        for (;;) {
 
824
                i = (limit - 1) * sizeof(*ep) +  sizeof(*map);
 
825
                map = malloc(i);
 
826
                if (map == NULL) {
 
827
                        fprintf(stderr, "%s: malloc failed\n", __func__);
 
828
                        return HBA_STATUS_ERROR;
 
829
                }
 
830
                memset((char *)map, 0, i);
 
831
                map->NumberOfEntries = limit;
 
832
#ifdef TEST_HBAAPI_V1
 
833
                status = HBA_GetFcpTargetMapping(hba_handle, map);
 
834
#else
 
835
                status = HBA_GetFcpTargetMappingV2(
 
836
                                hba_handle, lp_info->PortWWN, map);
 
837
#endif
 
838
                if (map->NumberOfEntries > limit) {
 
839
                        limit = map->NumberOfEntries + LUN_COUNT_INCR;
 
840
                        free(map);
 
841
                        continue;
 
842
                }
 
843
                if (status != HBA_STATUS_OK) {
 
844
                        fprintf(stderr,
 
845
                                "%s: HBA_GetFcpTargetMappingV2 failed\n",
 
846
                                __func__);
 
847
                        free(map);
 
848
                        return HBA_STATUS_ERROR;
 
849
                }
 
850
                break;
 
851
        }
 
852
 
 
853
        if (map == NULL) {
 
854
                fprintf(stderr, "%s: map == NULL\n", __func__);
 
855
                return HBA_STATUS_ERROR;
 
856
        }
 
857
 
 
858
        if (map->NumberOfEntries > limit) {
 
859
                fprintf(stderr, "%s: map->NumberOfEntries=%d too big\n",
 
860
                        __func__, map->NumberOfEntries);
 
861
                return HBA_STATUS_ERROR;
 
862
        }
 
863
 
 
864
        ep = map->entry;
 
865
        limit = map->NumberOfEntries;
 
866
 
 
867
        /* Sort the response by LUN number */
 
868
        qsort(ep, limit, sizeof(*ep), lun_compare);
 
869
 
 
870
        *lun_count = limit;
 
871
        *tgtmap = map;
 
872
        return HBA_STATUS_OK;
 
873
}
 
874
 
 
875
static void
 
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)
 
881
{
 
882
        HBA_STATUS status;
 
883
        HBA_FCP_TARGET_MAPPING *map = NULL;
 
884
        u_int32_t limit;
 
885
        HBA_FCP_SCSI_ENTRY *ep;
 
886
        u_int32_t i;
 
887
        char *dev;
 
888
        char inqbuf[256];
 
889
        struct scsi_rcap10_resp rcap_resp;
 
890
        int lun_count = 0;
 
891
        int print_header = 0;
 
892
 
 
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__);
 
896
                return;
 
897
        }
 
898
 
 
899
        ep = map->entry;
 
900
        for (i = 0; i < limit; i++, ep++) {
 
901
                if (ep->FcpId.FcId != rp_info->PortFcId)
 
902
                        continue;
 
903
 
 
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)
 
908
                        continue;
 
909
 
 
910
                dev = ep->ScsiId.OSDeviceName;
 
911
                if (strstr(dev, "/dev/") == dev)
 
912
                        dev += 5;
 
913
 
 
914
                /* Issue standard inquiry */
 
915
#ifdef TEST_HBAAPI_V1
 
916
                status = get_inquiry_data_v1(hba_handle, ep,
 
917
                                        inqbuf, sizeof(inqbuf));
 
918
#else
 
919
                status = get_inquiry_data_v2(hba_handle, lp_info,
 
920
                                        ep, inqbuf, sizeof(inqbuf));
 
921
#endif
 
922
                if (status != HBA_STATUS_OK)
 
923
                        continue;
 
924
                lun_count++;
 
925
 
 
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));
 
930
#else
 
931
                status = get_device_capacity_v2(hba_handle, lp_info,
 
932
                                        ep, (char *)&rcap_resp,
 
933
                                        sizeof(rcap_resp));
 
934
#endif
 
935
                if (status != HBA_STATUS_OK)
 
936
                        continue;
 
937
 
 
938
                if (opt_info->t_flag) {
 
939
                        if (!print_header) {
 
940
                                show_short_lun_info_header();
 
941
                                print_header = 1;
 
942
                        }
 
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);
 
947
 
 
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);
 
952
 #else
 
953
                        get_report_luns_data_v2(hba_handle, lp_info, ep);
 
954
 #endif
 
955
                }
 
956
#endif
 
957
        }
 
958
 
 
959
        free(map);
 
960
        printf("\n");
 
961
}
 
962
 
 
963
static void
 
964
show_port_stats_header(struct opt_info *opt_info)
 
965
{
 
966
        printf("\n");
 
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");
 
976
}
 
977
 
 
978
static void
 
979
show_port_stats_in_row(HBA_INT64 start_time,
 
980
                       HBA_PORTSTATISTICS *port_stats,
 
981
                       HBA_FC4STATISTICS *port_fc4stats)
 
982
{
 
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);
 
997
        printf("\n");
 
998
}
 
999
 
 
1000
 
 
1001
void
 
1002
display_port_stats(struct opt_info *opt_info)
 
1003
{
 
1004
        HBA_STATUS retval;
 
1005
        HBA_UINT32 hba_cnt;
 
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;
 
1012
        char namebuf[1028];
 
1013
        int i = 0, found = 0;
 
1014
 
 
1015
        hba_cnt = HBA_GetNumberOfAdapters();
 
1016
        if (!hba_cnt) {
 
1017
                fprintf(stderr, "No FCoE interfaces created.\n");
 
1018
                return;
 
1019
        }
 
1020
 
 
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",
 
1025
                                retval);
 
1026
                        continue;
 
1027
                }
 
1028
 
 
1029
                hba_handle = HBA_OpenAdapter(namebuf);
 
1030
                if (!hba_handle) {
 
1031
                        fprintf(stderr, "HBA_OpenAdapter failed\n");
 
1032
                        perror("HBA_OpenAdapter");
 
1033
                        continue;
 
1034
                }
 
1035
 
 
1036
                retval = HBA_GetAdapterAttributes(hba_handle, &hba_attrs);
 
1037
                if (retval != HBA_STATUS_OK) {
 
1038
                        fprintf(stderr,
 
1039
                                "HBA_GetAdapterAttributes failed, retval=%d\n",
 
1040
                                retval);
 
1041
                        perror("HBA_GetAdapterAttributes");
 
1042
                        continue;
 
1043
                }
 
1044
 
 
1045
                retval = HBA_GetAdapterPortAttributes(
 
1046
                                        hba_handle, 0, &port_attrs);
 
1047
                if (retval != HBA_STATUS_OK) {
 
1048
                        fprintf(stderr,
 
1049
                                "HBA_GetAdapterPortAttributes failed, "
 
1050
                                "status=%d\n", retval);
 
1051
                        continue;
 
1052
                }
 
1053
 
 
1054
                if (strstr(port_attrs.PortSymbolicName, opt_info->ifname)) {
 
1055
                        found = 1;
 
1056
                        break;
 
1057
                }
 
1058
        }
 
1059
 
 
1060
        if (!found) {
 
1061
                fprintf(stderr, "Cannot find attributes for %s\n",
 
1062
                        opt_info->ifname);
 
1063
                return;
 
1064
        }
 
1065
 
 
1066
        i = 0;
 
1067
        while (1) {
 
1068
                unsigned int secs_left;
 
1069
 
 
1070
                retval = HBA_GetPortStatistics(hba_handle, 0, &port_stats);
 
1071
                if (retval != HBA_STATUS_OK &&
 
1072
                    retval != HBA_STATUS_ERROR_NOT_SUPPORTED) {
 
1073
                        fprintf(stderr,
 
1074
                                "HBA_GetPortStatistics failed, status=%d\n",
 
1075
                                retval);
 
1076
                        break;
 
1077
                }
 
1078
                if (retval == HBA_STATUS_ERROR_NOT_SUPPORTED) {
 
1079
                        fprintf(stderr,
 
1080
                                "Port Statistics not supported by %s\n",
 
1081
                                opt_info->ifname);
 
1082
                        break;
 
1083
                }
 
1084
 
 
1085
                if (!start_time)
 
1086
                        start_time = port_stats.SecondsSinceLastReset;
 
1087
 
 
1088
                retval = HBA_GetFC4Statistics(hba_handle,
 
1089
                                              port_attrs.PortWWN,
 
1090
                                              FC_TYPE_FCP,
 
1091
                                              &port_fc4stats);
 
1092
                if (retval != HBA_STATUS_OK &&
 
1093
                    retval != HBA_STATUS_ERROR_NOT_SUPPORTED) {
 
1094
                        fprintf(stderr, "HBA_GetFC4Statistics failed, "
 
1095
                                 "status=%d\n", retval);
 
1096
                        break;
 
1097
                }
 
1098
                if (retval == HBA_STATUS_ERROR_NOT_SUPPORTED) {
 
1099
                        fprintf(stderr,
 
1100
                                "Port FC4 Statistics not supported by %s\n",
 
1101
                                opt_info->ifname);
 
1102
                        break;
 
1103
                }
 
1104
                if (!(i % 52))
 
1105
                        show_port_stats_header(opt_info);
 
1106
                show_port_stats_in_row(start_time, &port_stats, &port_fc4stats);
 
1107
                i++;
 
1108
 
 
1109
                /* wait for the requested time interval in seconds */
 
1110
                secs_left = opt_info->n_interval;
 
1111
                do {
 
1112
                        secs_left = sleep(secs_left);
 
1113
                } while (secs_left);
 
1114
        }
 
1115
 
 
1116
        HBA_CloseAdapter(hba_handle);
 
1117
        return;
 
1118
}
 
1119
 
 
1120
static struct hba_name_table {
 
1121
        char  SerialNumber[64];
 
1122
        int   index;
 
1123
} hba_name_table[MAX_HBA_COUNT];
 
1124
 
 
1125
static int
 
1126
find_hba_index(char *serial_number, int *hba_index)
 
1127
{
 
1128
        int i, j;
 
1129
 
 
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) {
 
1133
                        /* not found */
 
1134
                        hba_name_table[i].index = i;
 
1135
                        /* TODO: change to sa_strncpy_safe */
 
1136
                        strncpy(hba_name_table[i].SerialNumber,
 
1137
                                serial_number, j);
 
1138
                        *hba_index = i;
 
1139
                        return 1;    /* print hba info */
 
1140
                }
 
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 */
 
1145
                }
 
1146
        }
 
1147
        /* table full */
 
1148
        return -1;
 
1149
}
 
1150
 
 
1151
void
 
1152
display_adapter_info(struct opt_info *opt_info)
 
1153
{
 
1154
        HBA_STATUS retval;
 
1155
        HBA_UINT32 hba_cnt;
 
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;
 
1160
        char namebuf[1028];
 
1161
        int i, j, rc;
 
1162
        int hba_index = -1;
 
1163
        int lp_index = -1;
 
1164
 
 
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));
 
1169
        }
 
1170
 
 
1171
        hba_cnt = HBA_GetNumberOfAdapters();
 
1172
        if (!hba_cnt) {
 
1173
                fprintf(stderr, "No FCoE interfaces created.\n");
 
1174
                return;
 
1175
        }
 
1176
 
 
1177
        for (i = 0; i < hba_cnt; i++) {
 
1178
                retval = HBA_GetAdapterName(i, namebuf);
 
1179
                if (retval != HBA_STATUS_OK) {
 
1180
                        fprintf(stderr,
 
1181
                                "Failure of HBA_GetAdapterName: %d\n", retval);
 
1182
                        continue;
 
1183
                }
 
1184
 
 
1185
                hba_handle = HBA_OpenAdapter(namebuf);
 
1186
                if (!hba_handle) {
 
1187
                        fprintf(stderr, "HBA_OpenAdapter failed\n");
 
1188
                        perror("HBA_OpenAdapter");
 
1189
                        continue;
 
1190
                }
 
1191
 
 
1192
                retval = HBA_GetAdapterAttributes(hba_handle, &hba_attrs);
 
1193
                if (retval != HBA_STATUS_OK) {
 
1194
                        fprintf(stderr,
 
1195
                                "HBA_GetAdapterAttributes failed, retval=%d\n",
 
1196
                                retval);
 
1197
                        perror("HBA_GetAdapterAttributes");
 
1198
                        continue;
 
1199
                }
 
1200
 
 
1201
                rc = find_hba_index(hba_attrs.SerialNumber, &hba_index);
 
1202
                if (rc == -1) {
 
1203
                        fprintf(stderr,
 
1204
                                "Too many adapters. Maximum %d\n",
 
1205
                                MAX_HBA_COUNT);
 
1206
                        return;
 
1207
                } else if (rc == 1)
 
1208
                        show_hba_info(hba_index, &hba_attrs, 0);
 
1209
 
 
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) {
 
1214
                                fprintf(stderr,
 
1215
                                        "HBA_GetAdapterPortAttributes failed, "
 
1216
                                        "j=%d, status=%d\n", j, retval);
 
1217
                                continue;
 
1218
                        }
 
1219
 
 
1220
                        lp_index++;
 
1221
                        if (opt_info->ifname &&
 
1222
                            !strstr(port_attrs.PortSymbolicName,
 
1223
                                        opt_info->ifname))
 
1224
                                continue;
 
1225
                        show_port_info(hba_index, lp_index, &hba_attrs,
 
1226
                                        &port_attrs);
 
1227
                }
 
1228
                HBA_CloseAdapter(hba_handle);
 
1229
        }
 
1230
}
 
1231
 
 
1232
void
 
1233
display_target_info(struct opt_info *opt_info)
 
1234
{
 
1235
        HBA_STATUS retval;
 
1236
        HBA_UINT32 hba_cnt;
 
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;
 
1242
        char namebuf[1028];
 
1243
        int i, j, rc;
 
1244
        int hba_index = -1;
 
1245
        int lp_index = -1;
 
1246
        int rp_index = -1;
 
1247
 
 
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));
 
1252
        }
 
1253
 
 
1254
        hba_cnt = HBA_GetNumberOfAdapters();
 
1255
        if (!hba_cnt) {
 
1256
                fprintf(stderr, "No FCoE interfaces created.\n");
 
1257
                return;
 
1258
        }
 
1259
 
 
1260
        for (i = 0; i < hba_cnt; i++) {
 
1261
                retval = HBA_GetAdapterName(i, namebuf);
 
1262
                if (retval != HBA_STATUS_OK) {
 
1263
                        fprintf(stderr,
 
1264
                                "Failure of HBA_GetAdapterName: %d\n", retval);
 
1265
                        continue;
 
1266
                }
 
1267
 
 
1268
                hba_handle = HBA_OpenAdapter(namebuf);
 
1269
                if (!hba_handle) {
 
1270
                        fprintf(stderr, "HBA_OpenAdapter failed\n");
 
1271
                        perror("HBA_OpenAdapter");
 
1272
                        continue;
 
1273
                }
 
1274
 
 
1275
                retval = HBA_GetAdapterAttributes(hba_handle, &hba_attrs);
 
1276
                if (retval != HBA_STATUS_OK) {
 
1277
                        fprintf(stderr,
 
1278
                                "HBA_GetAdapterAttributes failed, retval=%d\n",
 
1279
                                retval);
 
1280
                        perror("HBA_GetAdapterAttributes");
 
1281
                        continue;
 
1282
                }
 
1283
 
 
1284
                rc = find_hba_index(hba_attrs.SerialNumber, &hba_index);
 
1285
                if (rc == -1) {
 
1286
                        fprintf(stderr,
 
1287
                                "Too many adapters. Maximum %d\n",
 
1288
                                MAX_HBA_COUNT);
 
1289
                        return;
 
1290
                }
 
1291
 
 
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) {
 
1296
                                fprintf(stderr,
 
1297
                                        "HBA_GetAdapterPortAttributes failed, "
 
1298
                                        "j=%d, status=%d\n", j, retval);
 
1299
                                continue;
 
1300
                        }
 
1301
 
 
1302
                        lp_index++;
 
1303
                        if (opt_info->ifname &&
 
1304
                            !strstr(port_attrs.PortSymbolicName,
 
1305
                                        opt_info->ifname))
 
1306
                                continue;
 
1307
 
 
1308
                        for (rp_index = 0;
 
1309
                             rp_index < port_attrs.NumberofDiscoveredPorts;
 
1310
                             rp_index++) {
 
1311
                                retval = HBA_GetDiscoveredPortAttributes(
 
1312
                                                hba_handle, j, rp_index,
 
1313
                                                &rport_attrs);
 
1314
                                if (retval != HBA_STATUS_OK) {
 
1315
                                        fprintf(stderr,
 
1316
                                        "HBA_GetDiscoveredPortAttributes "
 
1317
                                        "failed, j=%d, for rp_index=%d, "
 
1318
                                        "status=%d\n", j, rp_index, retval);
 
1319
                                        continue;
 
1320
                                }
 
1321
 
 
1322
                                /*
 
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.
 
1326
                                 */
 
1327
                                if (opt_info->l_flag &&
 
1328
                                    opt_info->l_fcid_present &&
 
1329
                                    rport_attrs.PortFcId != opt_info->l_fcid)
 
1330
                                        continue;
 
1331
 
 
1332
                                show_target_info(hba_index, lp_index,
 
1333
                                                 rp_index, &hba_attrs,
 
1334
                                                 &rport_attrs);
 
1335
 
 
1336
                                scan_device_map(hba_handle, &hba_attrs,
 
1337
                                                &port_attrs, &rport_attrs,
 
1338
                                                opt_info);
 
1339
                        }
 
1340
                }
 
1341
                HBA_CloseAdapter(hba_handle);
 
1342
        }
 
1343
}