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",
105 static SAS_STATE dtype_string
[] = {
106 DTYPE_DIRECT
, "Disk Device",
107 DTYPE_SEQUENTIAL
, "Tape Device",
108 DTYPE_PRINTER
, "Printer Device",
109 DTYPE_PROCESSOR
, "Processor Device",
110 DTYPE_WORM
, "WORM Device",
111 DTYPE_RODIRECT
, "CD/DVD Device",
112 DTYPE_SCANNER
, "Scanner Device",
113 DTYPE_OPTICAL
, "Optical Memory Device",
114 DTYPE_CHANGER
, "Medium Changer Device",
115 DTYPE_COMM
, "Communications Device",
116 DTYPE_ARRAY_CTRL
, "Storage Array Controller Device",
117 DTYPE_ESI
, "Enclosure Services Device",
118 DTYPE_RBC
, "Simplified Direct-access Device",
119 DTYPE_OCRW
, "Optical Card Reader/Writer Device",
120 DTYPE_BCC
, "Bridge Controller Commands",
121 DTYPE_OSD
, "Object-based Storage Device",
122 DTYPE_ADC
, "Automation/Drive Interface",
123 DTYPE_WELLKNOWN
, "Well Known Logical Unit",
124 DTYPE_UNKNOWN
, "Unknown Device",
128 static char *getPhyStateString(HBA_UINT32 key
, phystat_type phyt
);
131 getIndentSpaces(int number
)
134 /* the maximum indent with terminator '\0' */
135 static char ret
[MAXINDENT
+1];
137 if (number
> MAXINDENT
)
140 for (i
= 0; i
< number
; i
++) {
148 getStateString(HBA_UINT32 key
, SAS_STATE
*stat_string
)
151 while (stat_string
->key
!= -1) {
152 if (stat_string
->key
== key
) {
153 return ((char *)stat_string
->value
);
157 (void *) sprintf(ret
, "Undefined value (%d)", key
);
162 getPhyStateString(HBA_UINT32 key
, phystat_type phyt
)
164 int i
= 0, len
= 0, match
= 0;
165 HBA_UINT32 physpeed
[] = {
166 HBA_SASSPEED_1_5GBIT
,
171 len
= sizeof (physpeed
) / sizeof (HBA_UINT32
);
172 for (i
= 0; i
< len
; i
++) {
173 if (key
== physpeed
[i
]) {
180 if (phyt
== PHY_STATE
)
183 return (getStateString(key
, phystate_string
));
185 if (phyt
== PHY_STATE
)
186 return (getStateString(key
, phystate_string
));
188 return ("not available");
193 getHBAStatus(HBA_STATUS key
)
195 return (getStateString(key
, hbastatus_string
));
199 * return device type description
202 * dType - Device type returned from Standard INQUIRY
204 * char string description for device type
207 getDTypeString(uchar_t dType
)
209 return (getStateString((dType
& DTYPE_MASK
), dtype_string
));
213 wwnConversion(uchar_t
*wwn
)
216 (void *) memcpy(&tmp
, wwn
, sizeof (uint64_t));
217 return (ntohll(tmp
));
221 * prints out HBA information
224 printHBAInfo(SMHBA_ADAPTERATTRIBUTES
*attrs
, int pflag
, int numberOfPorts
,
225 const char *adapterName
)
228 (void *) fprintf(stdout
, "%s %s\n", "HBA Name:", adapterName
);
230 if (pflag
& PRINT_VERBOSE
) {
231 (void *) fprintf(stdout
, "%s%s %s\n",
232 getIndentSpaces(4), "Manufacturer:",
233 attrs
->Manufacturer
[0] == 0?
234 "not available":attrs
->Manufacturer
);
235 (void *) fprintf(stdout
, "%s%s %s\n",
236 getIndentSpaces(4), "Model: ",
237 attrs
->Model
[0] == 0? "not available":attrs
->Model
);
238 (void *) fprintf(stdout
, "%s%s %s\n",
241 attrs
->FirmwareVersion
[0] == 0? "not available":
242 attrs
->FirmwareVersion
);
243 (void *) fprintf(stdout
, "%s%s %s\n",
245 "FCode/BIOS Version:",
246 attrs
->OptionROMVersion
[0] == 0? "not available":
247 attrs
->OptionROMVersion
);
248 (void *) fprintf(stdout
, "%s%s %s\n",
251 attrs
->SerialNumber
[0] == 0? "not available":
252 attrs
->SerialNumber
);
253 (void *) fprintf(stdout
, "%s%s %s\n",
256 attrs
->DriverName
[0] == 0? "not available":
258 (void *) fprintf(stdout
, "%s%s %s\n",
261 attrs
->DriverVersion
[0] == 0? "not available":
262 attrs
->DriverVersion
);
263 (void *) fprintf(stdout
, "%s%s %d\n",
265 "Number of HBA Ports:",
271 * prints out all the HBA port information
274 printHBAPortInfo(SMHBA_PORTATTRIBUTES
*port
,
275 SMHBA_ADAPTERATTRIBUTES
*attrs
, int pflag
) {
277 if ((port
== NULL
) || (attrs
== NULL
)) {
281 (void *) fprintf(stdout
, "%s%s %s\n",
286 if (!(pflag
& PRINT_VERBOSE
)) {
290 if (port
->PortType
!= HBA_PORTTYPE_SASDEVICE
)
293 (void *) fprintf(stdout
, "%s%s %s\n",
296 getStateString(port
->PortType
, porttype_string
));
297 (void *) fprintf(stdout
, "%s%s %s\n",
300 getStateString(port
->PortState
, portstate_string
));
302 (void *) fprintf(stdout
, "%s%s %016llx\n",
304 "Local SAS Address:",
305 wwnConversion(port
->PortSpecificAttribute
.SASPort
->\
306 LocalSASAddress
.wwn
));
308 (void *) fprintf(stdout
, "%s%s %016llx\n",
310 "Attached SAS Address:",
311 wwnConversion(port
->PortSpecificAttribute
.SASPort
->\
312 AttachedSASAddress
.wwn
));
314 (void *) fprintf(stdout
, "%s%s %d\n",
317 port
->PortSpecificAttribute
.SASPort
->NumberofPhys
);
321 printHBAPortPhyInfo(SMHBA_SAS_PHY
*phyinfo
)
326 (void *) fprintf(stdout
, "%s%s %u\n",
329 phyinfo
->PhyIdentifier
);
331 (void *) fprintf(stdout
, "%s%s %s\n",
334 getPhyStateString(phyinfo
->NegotiatedLinkRate
, PHY_STATE
));
335 (void *) fprintf(stdout
, "%s%s %s/%s\n",
337 "HardwareLinkRate(Min/Max):",
338 getPhyStateString(phyinfo
->HardwareMinLinkRate
, PHY_SPEED
),
339 getPhyStateString(phyinfo
->HardwareMaxLinkRate
, PHY_SPEED
));
340 (void *) fprintf(stdout
, "%s%s %s/%s\n",
342 "ProgrammedLinkRate(Min/Max):",
343 getPhyStateString(phyinfo
->ProgrammedMinLinkRate
, PHY_SPEED
),
344 getPhyStateString(phyinfo
->ProgrammedMaxLinkRate
, PHY_SPEED
));
345 (void *) fprintf(stdout
, "%s%s %s\n",
347 "NegotiatedLinkRate:",
348 getPhyStateString(phyinfo
->NegotiatedLinkRate
, PHY_SPEED
));
352 printHBAPortPhyStatistics(SMHBA_SASPHYSTATISTICS
*phystat
)
357 (void *) fprintf(stdout
, "%s%s\n",
359 "Link Error Statistics:");
360 (void *) fprintf(stdout
, "%s%s %llu\n",
363 phystat
->InvalidDwordCount
);
364 (void *) fprintf(stdout
, "%s%s %llu\n",
366 "Running Disparity Error:",
367 phystat
->RunningDisparityErrorCount
);
368 (void *) fprintf(stdout
, "%s%s %llu\n",
370 "Loss of Dword Sync:",
371 phystat
->LossofDwordSyncCount
);
372 (void *) fprintf(stdout
, "%s%s %llu\n",
375 phystat
->PhyResetProblemCount
);
379 * print the OS device name for the logical-unit object
382 * devListWalk - OS device path info
383 * verbose - boolean indicating whether to display additional info
387 * >0 - we met issues.
390 printTargetPortInfo(targetPortList_t
*TPListWalk
, int pflag
)
392 targetPortConfig_t
*configList
;
393 targetPortMappingData_t
*mapList
;
397 (void *) fprintf(stdout
, "Target Port SAS Address: %016llx\n",
398 wwnConversion(TPListWalk
->sasattr
.LocalSASAddress
.wwn
));
399 if ((pflag
& PRINT_VERBOSE
) || (pflag
& PRINT_TARGET_SCSI
)) {
400 (void *) fprintf(stdout
, "%sType: %s\n", getIndentSpaces(4),
401 getStateString(TPListWalk
->targetattr
.PortType
,
403 for (configList
= TPListWalk
->configEntry
;
404 configList
!= NULL
; configList
= configList
->next
) {
405 (void *) fprintf(stdout
, "%sHBA Port Name: %s\n",
406 getIndentSpaces(4), configList
->hbaPortName
);
407 if (wwnConversion(configList
->expanderSASAddr
.wwn
) !=
409 if (configList
->expanderValid
) {
410 (void *) fprintf(stdout
,
411 "%sExpander Device SAS Address:"
414 wwnConversion(configList
->
415 expanderSASAddr
.wwn
));
417 (void *) fprintf(stdout
,
418 "%sExpander Device SAS Address:"
419 " %016llx (Failed to Validate"
422 wwnConversion(configList
->
423 expanderSASAddr
.wwn
));
427 if (configList
->expanderValid
) {
428 (void *) fprintf(stdout
,
429 "%sExpander Device SAS Address: %s",
431 "None (direct attached)");
433 (void *) fprintf(stdout
,
434 "%sExpander Device SAS Address: %s",
436 "None (Failed to Get"
440 (void *) fprintf(stdout
, "\n");
441 if (pflag
& PRINT_TARGET_SCSI
) {
443 if (configList
->reportLUNsFailed
) {
444 (void *) fprintf(stdout
,
446 gettext("Error: Failed to get "
447 "ReportLun Data on"),
448 wwnConversion(TPListWalk
->
449 sasattr
.LocalSASAddress
.wwn
));
454 for (mapList
= configList
->map
;
455 mapList
!= NULL
; mapList
= mapList
->next
) {
456 (void *) fprintf(stdout
, "%sLUN : %d\n",
459 if (mapList
->mappingExist
) {
460 (void *) fprintf(stdout
,
461 "%sOS Device Name : %s\n",
463 (mapList
->osDeviceName
[0] ==
464 '\0') ? "Not avaialble" :
465 mapList
->osDeviceName
);
467 (void *) fprintf(stdout
,
468 "%sOS Device Name : %s\n",
469 getIndentSpaces(14), "No "
470 "matching OS Device "
474 /* indentation changed here */
475 if (mapList
->inquiryFailed
) {
476 (void *) fprintf(stdout
, "%s %s LUN %d\n",
477 gettext("Error: Failed to get Inquiry Data on"),
478 mapList
->osDeviceName
, mapList
->osLUN
);
481 (void *) fprintf(stdout
, "%sVendor: ",
482 getIndentSpaces(14));
483 for (count
= sizeof (mapList
->inq_vid
), i
= 0;
485 if (isprint(mapList
->inq_vid
[i
]))
486 (void *) fprintf(stdout
, "%c",
487 mapList
->inq_vid
[i
]);
490 (void *) fprintf(stdout
, "\n%sProduct: ",
491 getIndentSpaces(14));
492 for (count
= sizeof (mapList
->inq_pid
), i
= 0;
494 if (isprint(mapList
->inq_pid
[i
]))
495 (void *) fprintf(stdout
, "%c",
496 mapList
->inq_pid
[i
]);
499 (void *) fprintf(stdout
, "\n%sDevice Type: %s\n",
501 getDTypeString(mapList
->inq_dtype
));
503 /* indentation changed back */
512 * print the OS device name for the logical-unit object
515 * devListWalk - OS device path info
516 * verbose - boolean indicating whether to display additional info
520 * >0 - we met issues.
523 printOSDeviceNameInfo(discoveredDevice
*devListWalk
, boolean_t verbose
)
526 tgtPortWWNList
*tgtWWNList
;
530 (void *) fprintf(stdout
, "OS Device Name: %s\n",
531 devListWalk
->OSDeviceName
);
532 if (verbose
== B_TRUE
) {
533 for (portElem
= devListWalk
->HBAPortList
;
534 portElem
!= NULL
; portElem
= portElem
->next
) {
535 (void *) fprintf(stdout
, "%sHBA Port Name: ",
537 (void *) fprintf(stdout
, "%s", portElem
->portName
);
538 for (tgtWWNList
= portElem
->tgtPortWWN
;
539 tgtWWNList
!= NULL
; tgtWWNList
= tgtWWNList
->next
) {
540 (void *) fprintf(stdout
,
541 "\n%sTarget Port SAS Address: ",
543 (void *) fprintf(stdout
, "%016llx",
544 wwnConversion(tgtWWNList
->portWWN
.wwn
));
545 (void *) fprintf(stdout
, "\n%sLUN: %u",
547 tgtWWNList
->scsiOSLun
);
549 (void *) fprintf(stdout
, "\n");
552 if (devListWalk
->inquiryFailed
) {
553 (void *) fprintf(stdout
, "%s %s\n",
554 gettext("Error: Failed to get Inquiry data "
555 "on device"), devListWalk
->OSDeviceName
);
558 (void *) fprintf(stdout
, "%sVendor: ",
560 for (count
= sizeof (devListWalk
->VID
), i
= 0;
562 if (isprint(devListWalk
->VID
[i
]))
563 (void *) fprintf(stdout
, "%c",
564 devListWalk
->VID
[i
]);
567 (void *) fprintf(stdout
, "\n%sProduct: ",
569 for (count
= sizeof (devListWalk
->PID
), i
= 0;
571 if (isprint(devListWalk
->PID
[i
]))
572 (void *) fprintf(stdout
, "%c",
573 devListWalk
->PID
[i
]);
576 (void *) fprintf(stdout
, "\n%sDevice Type: %s\n",
578 getDTypeString(devListWalk
->dType
));