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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include <printAttrs.h>
29 static SAS_STATE hbastatus_string
[] = {
30 HBA_STATUS_OK
, "Okay",
31 HBA_STATUS_ERROR
, "Error",
32 HBA_STATUS_ERROR_NOT_SUPPORTED
, "Not Supported",
33 HBA_STATUS_ERROR_INVALID_HANDLE
, "Invalid Handle",
34 HBA_STATUS_ERROR_ARG
, "Argument Error",
35 HBA_STATUS_ERROR_ILLEGAL_WWN
, "Illegal WWN",
36 HBA_STATUS_ERROR_ILLEGAL_INDEX
, "Illegal Index",
37 HBA_STATUS_ERROR_MORE_DATA
, "Not Enough Buffer for Data",
38 HBA_STATUS_ERROR_STALE_DATA
, "Stale Data",
39 HBA_STATUS_SCSI_CHECK_CONDITION
, "SCSI Check Condition",
40 HBA_STATUS_ERROR_BUSY
, "Busy",
41 HBA_STATUS_ERROR_TRY_AGAIN
, "Try Again",
42 HBA_STATUS_ERROR_UNAVAILABLE
, "Unavailable",
43 HBA_STATUS_ERROR_ELS_REJECT
, "ELS Reject",
44 HBA_STATUS_ERROR_INVALID_LUN
, "Invalid LUN",
45 HBA_STATUS_ERROR_INCOMPATIBLE
, "Request Incompatible",
46 HBA_STATUS_ERROR_AMBIGUOUS_WWN
, "Ambiguous WWN",
47 HBA_STATUS_ERROR_LOCAL_BUS
, "Local Bus Error",
48 HBA_STATUS_ERROR_LOCAL_TARGET
, "Local Target Error",
49 HBA_STATUS_ERROR_LOCAL_LUN
, "Local LUN Error",
50 HBA_STATUS_ERROR_LOCAL_SCSIID_BOUND
, "Local SCSIID Bound",
51 HBA_STATUS_ERROR_TARGET_FCID
, "Target FCID Error",
52 HBA_STATUS_ERROR_TARGET_NODE_WWN
, "Target Node WWN Error",
53 HBA_STATUS_ERROR_TARGET_PORT_WWN
, "Target Port WWN Error",
54 HBA_STATUS_ERROR_TARGET_LUN
, "Target LUN Error",
55 HBA_STATUS_ERROR_TARGET_LUID
, "Target LUID Error",
56 HBA_STATUS_ERROR_NO_SUCH_BINDING
, "No Such Binding",
57 HBA_STATUS_ERROR_NOT_A_TARGET
, "Not a Target",
58 HBA_STATUS_ERROR_UNSUPPORTED_FC4
, "Unsupported FC4",
59 HBA_STATUS_ERROR_INCAPABLE
, "Incapable",
60 HBA_STATUS_ERROR_TARGET_BUSY
, "Target Busy",
61 HBA_STATUS_ERROR_NOT_LOADED
, "Not Loaded",
62 HBA_STATUS_ERROR_ALREADY_LOADED
, "Alreday Loaded",
63 HBA_STATUS_ERROR_ILLEGAL_FCID
, "Illegal FCID",
64 HBA_STATUS_ERROR_NOT_ASCSIDEVICE
, "Not a SCSI Device",
65 HBA_STATUS_ERROR_INVALID_PROTOCOL_TYPE
, "Invalid Protocol Type",
66 HBA_STATUS_ERROR_BAD_EVENT_TYPE
, "Bad Event Type",
70 SAS_STATE porttype_string
[] = {
71 HBA_PORTTYPE_UNKNOWN
, "UNKNOWN",
72 HBA_PORTTYPE_OTHER
, "OTHER",
73 HBA_PORTTYPE_NOTPRESENT
, "NOT Present",
74 HBA_PORTTYPE_SASDEVICE
, "SAS Device",
75 HBA_PORTTYPE_SATADEVICE
, "SATA Device",
76 HBA_PORTTYPE_SASEXPANDER
, "SAS Expander",
80 SAS_STATE portstate_string
[] = {
81 HBA_PORTSTATE_UNKNOWN
, "unknown",
82 HBA_PORTSTATE_ONLINE
, "online",
83 HBA_PORTSTATE_OFFLINE
, "offline",
84 HBA_PORTSTATE_BYPASSED
, "bypassed",
85 HBA_PORTSTATE_DIAGNOSTICS
, "diagnostics",
86 HBA_PORTSTATE_LINKDOWN
, "link Down",
87 HBA_PORTSTATE_ERROR
, "port Error",
88 HBA_PORTSTATE_LOOPBACK
, "loopback",
89 HBA_PORTSTATE_DEGRADED
, "degraded",
93 static SAS_STATE phystate_string
[] = {
94 HBA_SASSTATE_UNKNOWN
, "unknown",
95 HBA_SASSTATE_DISABLED
, "disabled",
96 HBA_SASSTATE_FAILED
, "failed",
97 HBA_SASSTATE_SATASPINUP
, "sata-spinup",
98 HBA_SASSTATE_SATAPORTSEL
, "sata-portselector",
99 HBA_SASSPEED_1_5GBIT
, "1.5Gbit",
100 HBA_SASSPEED_3GBIT
, "3Gbit",
101 HBA_SASSPEED_6GBIT
, "6Gbit",
102 HBA_SASSPEED_12GBIT
, "12Gbit",
106 static SAS_STATE dtype_string
[] = {
107 DTYPE_DIRECT
, "Disk Device",
108 DTYPE_SEQUENTIAL
, "Tape Device",
109 DTYPE_PRINTER
, "Printer Device",
110 DTYPE_PROCESSOR
, "Processor Device",
111 DTYPE_WORM
, "WORM Device",
112 DTYPE_RODIRECT
, "CD/DVD Device",
113 DTYPE_SCANNER
, "Scanner Device",
114 DTYPE_OPTICAL
, "Optical Memory Device",
115 DTYPE_CHANGER
, "Medium Changer Device",
116 DTYPE_COMM
, "Communications Device",
117 DTYPE_ARRAY_CTRL
, "Storage Array Controller Device",
118 DTYPE_ESI
, "Enclosure Services Device",
119 DTYPE_RBC
, "Simplified Direct-access Device",
120 DTYPE_OCRW
, "Optical Card Reader/Writer Device",
121 DTYPE_BCC
, "Bridge Controller Commands",
122 DTYPE_OSD
, "Object-based Storage Device",
123 DTYPE_ADC
, "Automation/Drive Interface",
124 DTYPE_WELLKNOWN
, "Well Known Logical Unit",
125 DTYPE_UNKNOWN
, "Unknown Device",
129 static char *getPhyStateString(HBA_UINT32 key
, phystat_type phyt
);
132 getIndentSpaces(int number
)
135 /* the maximum indent with terminator '\0' */
136 static char ret
[MAXINDENT
+1];
138 if (number
> MAXINDENT
)
141 for (i
= 0; i
< number
; i
++) {
149 getStateString(HBA_UINT32 key
, SAS_STATE
*stat_string
)
152 while (stat_string
->key
!= -1) {
153 if (stat_string
->key
== key
) {
154 return ((char *)stat_string
->value
);
158 (void *) sprintf(ret
, "Undefined value (%d)", key
);
163 getPhyStateString(HBA_UINT32 key
, phystat_type phyt
)
165 int i
= 0, len
= 0, match
= 0;
166 HBA_UINT32 physpeed
[] = {
167 HBA_SASSPEED_1_5GBIT
,
173 len
= sizeof (physpeed
) / sizeof (HBA_UINT32
);
174 for (i
= 0; i
< len
; i
++) {
175 if (key
== physpeed
[i
]) {
182 if (phyt
== PHY_STATE
)
185 return (getStateString(key
, phystate_string
));
187 if (phyt
== PHY_STATE
)
188 return (getStateString(key
, phystate_string
));
190 return ("not available");
195 getHBAStatus(HBA_STATUS key
)
197 return (getStateString(key
, hbastatus_string
));
201 * return device type description
204 * dType - Device type returned from Standard INQUIRY
206 * char string description for device type
209 getDTypeString(uchar_t dType
)
211 return (getStateString((dType
& DTYPE_MASK
), dtype_string
));
215 wwnConversion(uchar_t
*wwn
)
218 (void *) memcpy(&tmp
, wwn
, sizeof (uint64_t));
219 return (ntohll(tmp
));
223 * prints out HBA information
226 printHBAInfo(SMHBA_ADAPTERATTRIBUTES
*attrs
, int pflag
, int numberOfPorts
,
227 const char *adapterName
)
230 (void *) fprintf(stdout
, "%s %s\n", "HBA Name:", adapterName
);
232 if (pflag
& PRINT_VERBOSE
) {
233 (void *) fprintf(stdout
, "%s%s %s\n",
234 getIndentSpaces(4), "Manufacturer:",
235 attrs
->Manufacturer
[0] == 0?
236 "not available":attrs
->Manufacturer
);
237 (void *) fprintf(stdout
, "%s%s %s\n",
238 getIndentSpaces(4), "Model: ",
239 attrs
->Model
[0] == 0? "not available":attrs
->Model
);
240 (void *) fprintf(stdout
, "%s%s %s\n",
243 attrs
->FirmwareVersion
[0] == 0? "not available":
244 attrs
->FirmwareVersion
);
245 (void *) fprintf(stdout
, "%s%s %s\n",
247 "FCode/BIOS Version:",
248 attrs
->OptionROMVersion
[0] == 0? "not available":
249 attrs
->OptionROMVersion
);
250 (void *) fprintf(stdout
, "%s%s %s\n",
253 attrs
->SerialNumber
[0] == 0? "not available":
254 attrs
->SerialNumber
);
255 (void *) fprintf(stdout
, "%s%s %s\n",
258 attrs
->DriverName
[0] == 0? "not available":
260 (void *) fprintf(stdout
, "%s%s %s\n",
263 attrs
->DriverVersion
[0] == 0? "not available":
264 attrs
->DriverVersion
);
265 (void *) fprintf(stdout
, "%s%s %d\n",
267 "Number of HBA Ports:",
273 * prints out all the HBA port information
276 printHBAPortInfo(SMHBA_PORTATTRIBUTES
*port
,
277 SMHBA_ADAPTERATTRIBUTES
*attrs
, int pflag
) {
279 if ((port
== NULL
) || (attrs
== NULL
)) {
283 (void *) fprintf(stdout
, "%s%s %s\n",
288 if (!(pflag
& PRINT_VERBOSE
)) {
292 if (port
->PortType
!= HBA_PORTTYPE_SASDEVICE
)
295 (void *) fprintf(stdout
, "%s%s %s\n",
298 getStateString(port
->PortType
, porttype_string
));
299 (void *) fprintf(stdout
, "%s%s %s\n",
302 getStateString(port
->PortState
, portstate_string
));
304 (void *) fprintf(stdout
, "%s%s %016llx\n",
306 "Local SAS Address:",
307 wwnConversion(port
->PortSpecificAttribute
.SASPort
->\
308 LocalSASAddress
.wwn
));
310 (void *) fprintf(stdout
, "%s%s %016llx\n",
312 "Attached SAS Address:",
313 wwnConversion(port
->PortSpecificAttribute
.SASPort
->\
314 AttachedSASAddress
.wwn
));
316 (void *) fprintf(stdout
, "%s%s %d\n",
319 port
->PortSpecificAttribute
.SASPort
->NumberofPhys
);
323 printHBAPortPhyInfo(SMHBA_SAS_PHY
*phyinfo
)
328 (void *) fprintf(stdout
, "%s%s %u\n",
331 phyinfo
->PhyIdentifier
);
333 (void *) fprintf(stdout
, "%s%s %s\n",
336 getPhyStateString(phyinfo
->NegotiatedLinkRate
, PHY_STATE
));
337 (void *) fprintf(stdout
, "%s%s %s/%s\n",
339 "HardwareLinkRate(Min/Max):",
340 getPhyStateString(phyinfo
->HardwareMinLinkRate
, PHY_SPEED
),
341 getPhyStateString(phyinfo
->HardwareMaxLinkRate
, PHY_SPEED
));
342 (void *) fprintf(stdout
, "%s%s %s/%s\n",
344 "ProgrammedLinkRate(Min/Max):",
345 getPhyStateString(phyinfo
->ProgrammedMinLinkRate
, PHY_SPEED
),
346 getPhyStateString(phyinfo
->ProgrammedMaxLinkRate
, PHY_SPEED
));
347 (void *) fprintf(stdout
, "%s%s %s\n",
349 "NegotiatedLinkRate:",
350 getPhyStateString(phyinfo
->NegotiatedLinkRate
, PHY_SPEED
));
354 printHBAPortPhyStatistics(SMHBA_SASPHYSTATISTICS
*phystat
)
359 (void *) fprintf(stdout
, "%s%s\n",
361 "Link Error Statistics:");
362 (void *) fprintf(stdout
, "%s%s %llu\n",
365 phystat
->InvalidDwordCount
);
366 (void *) fprintf(stdout
, "%s%s %llu\n",
368 "Running Disparity Error:",
369 phystat
->RunningDisparityErrorCount
);
370 (void *) fprintf(stdout
, "%s%s %llu\n",
372 "Loss of Dword Sync:",
373 phystat
->LossofDwordSyncCount
);
374 (void *) fprintf(stdout
, "%s%s %llu\n",
377 phystat
->PhyResetProblemCount
);
381 * print the OS device name for the logical-unit object
384 * devListWalk - OS device path info
385 * verbose - boolean indicating whether to display additional info
389 * >0 - we met issues.
392 printTargetPortInfo(targetPortList_t
*TPListWalk
, int pflag
)
394 targetPortConfig_t
*configList
;
395 targetPortMappingData_t
*mapList
;
399 (void *) fprintf(stdout
, "Target Port SAS Address: %016llx\n",
400 wwnConversion(TPListWalk
->sasattr
.LocalSASAddress
.wwn
));
401 if ((pflag
& PRINT_VERBOSE
) || (pflag
& PRINT_TARGET_SCSI
)) {
402 (void *) fprintf(stdout
, "%sType: %s\n", getIndentSpaces(4),
403 getStateString(TPListWalk
->targetattr
.PortType
,
405 for (configList
= TPListWalk
->configEntry
;
406 configList
!= NULL
; configList
= configList
->next
) {
407 (void *) fprintf(stdout
, "%sHBA Port Name: %s\n",
408 getIndentSpaces(4), configList
->hbaPortName
);
409 if (wwnConversion(configList
->expanderSASAddr
.wwn
) !=
411 if (configList
->expanderValid
) {
412 (void *) fprintf(stdout
,
413 "%sExpander Device SAS Address:"
416 wwnConversion(configList
->
417 expanderSASAddr
.wwn
));
419 (void *) fprintf(stdout
,
420 "%sExpander Device SAS Address:"
421 " %016llx (Failed to Validate"
424 wwnConversion(configList
->
425 expanderSASAddr
.wwn
));
429 if (configList
->expanderValid
) {
430 (void *) fprintf(stdout
,
431 "%sExpander Device SAS Address: %s",
433 "None (direct attached)");
435 (void *) fprintf(stdout
,
436 "%sExpander Device SAS Address: %s",
438 "None (Failed to Get"
442 (void *) fprintf(stdout
, "\n");
443 if (pflag
& PRINT_TARGET_SCSI
) {
445 if (configList
->reportLUNsFailed
) {
446 (void *) fprintf(stdout
,
448 gettext("Error: Failed to get "
449 "ReportLun Data on"),
450 wwnConversion(TPListWalk
->
451 sasattr
.LocalSASAddress
.wwn
));
456 for (mapList
= configList
->map
;
457 mapList
!= NULL
; mapList
= mapList
->next
) {
458 (void *) fprintf(stdout
, "%sLUN : %d\n",
461 if (mapList
->mappingExist
) {
462 (void *) fprintf(stdout
,
463 "%sOS Device Name : %s\n",
465 (mapList
->osDeviceName
[0] ==
466 '\0') ? "Not avaialble" :
467 mapList
->osDeviceName
);
469 (void *) fprintf(stdout
,
470 "%sOS Device Name : %s\n",
471 getIndentSpaces(14), "No "
472 "matching OS Device "
476 /* indentation changed here */
477 if (mapList
->inquiryFailed
) {
478 (void *) fprintf(stdout
, "%s %s LUN %d\n",
479 gettext("Error: Failed to get Inquiry Data on"),
480 mapList
->osDeviceName
, mapList
->osLUN
);
483 (void *) fprintf(stdout
, "%sVendor: ",
484 getIndentSpaces(14));
485 for (count
= sizeof (mapList
->inq_vid
), i
= 0;
487 if (isprint(mapList
->inq_vid
[i
]))
488 (void *) fprintf(stdout
, "%c",
489 mapList
->inq_vid
[i
]);
492 (void *) fprintf(stdout
, "\n%sProduct: ",
493 getIndentSpaces(14));
494 for (count
= sizeof (mapList
->inq_pid
), i
= 0;
496 if (isprint(mapList
->inq_pid
[i
]))
497 (void *) fprintf(stdout
, "%c",
498 mapList
->inq_pid
[i
]);
501 (void *) fprintf(stdout
, "\n%sDevice Type: %s\n",
503 getDTypeString(mapList
->inq_dtype
));
505 /* indentation changed back */
514 * print the OS device name for the logical-unit object
517 * devListWalk - OS device path info
518 * verbose - boolean indicating whether to display additional info
522 * >0 - we met issues.
525 printOSDeviceNameInfo(discoveredDevice
*devListWalk
, boolean_t verbose
)
528 tgtPortWWNList
*tgtWWNList
;
532 (void *) fprintf(stdout
, "OS Device Name: %s\n",
533 devListWalk
->OSDeviceName
);
534 if (verbose
== B_TRUE
) {
535 for (portElem
= devListWalk
->HBAPortList
;
536 portElem
!= NULL
; portElem
= portElem
->next
) {
537 (void *) fprintf(stdout
, "%sHBA Port Name: ",
539 (void *) fprintf(stdout
, "%s", portElem
->portName
);
540 for (tgtWWNList
= portElem
->tgtPortWWN
;
541 tgtWWNList
!= NULL
; tgtWWNList
= tgtWWNList
->next
) {
542 (void *) fprintf(stdout
,
543 "\n%sTarget Port SAS Address: ",
545 (void *) fprintf(stdout
, "%016llx",
546 wwnConversion(tgtWWNList
->portWWN
.wwn
));
547 (void *) fprintf(stdout
, "\n%sLUN: %u",
549 tgtWWNList
->scsiOSLun
);
551 (void *) fprintf(stdout
, "\n");
554 if (devListWalk
->inquiryFailed
) {
555 (void *) fprintf(stdout
, "%s %s\n",
556 gettext("Error: Failed to get Inquiry data "
557 "on device"), devListWalk
->OSDeviceName
);
560 (void *) fprintf(stdout
, "%sVendor: ",
562 for (count
= sizeof (devListWalk
->VID
), i
= 0;
564 if (isprint(devListWalk
->VID
[i
]))
565 (void *) fprintf(stdout
, "%c",
566 devListWalk
->VID
[i
]);
569 (void *) fprintf(stdout
, "\n%sProduct: ",
571 for (count
= sizeof (devListWalk
->PID
), i
= 0;
573 if (isprint(devListWalk
->PID
[i
]))
574 (void *) fprintf(stdout
, "%c",
575 devListWalk
->PID
[i
]);
578 (void *) fprintf(stdout
, "\n%sDevice Type: %s\n",
580 getDTypeString(devListWalk
->dType
));