summaryrefslogtreecommitdiff
path: root/usr/src/cmd/sasinfo/printAttrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/sasinfo/printAttrs.c')
-rw-r--r--usr/src/cmd/sasinfo/printAttrs.c582
1 files changed, 582 insertions, 0 deletions
diff --git a/usr/src/cmd/sasinfo/printAttrs.c b/usr/src/cmd/sasinfo/printAttrs.c
new file mode 100644
index 0000000000..ae66526d59
--- /dev/null
+++ b/usr/src/cmd/sasinfo/printAttrs.c
@@ -0,0 +1,582 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <ctype.h>
+#include <printAttrs.h>
+
+static SAS_STATE hbastatus_string[] = {
+ HBA_STATUS_OK, "Okay",
+ HBA_STATUS_ERROR, "Error",
+ HBA_STATUS_ERROR_NOT_SUPPORTED, "Not Supported",
+ HBA_STATUS_ERROR_INVALID_HANDLE, "Invalid Handle",
+ HBA_STATUS_ERROR_ARG, "Argument Error",
+ HBA_STATUS_ERROR_ILLEGAL_WWN, "Illegal WWN",
+ HBA_STATUS_ERROR_ILLEGAL_INDEX, "Illegal Index",
+ HBA_STATUS_ERROR_MORE_DATA, "Not Enough Buffer for Data",
+ HBA_STATUS_ERROR_STALE_DATA, "Stale Data",
+ HBA_STATUS_SCSI_CHECK_CONDITION, "SCSI Check Condition",
+ HBA_STATUS_ERROR_BUSY, "Busy",
+ HBA_STATUS_ERROR_TRY_AGAIN, "Try Again",
+ HBA_STATUS_ERROR_UNAVAILABLE, "Unavailable",
+ HBA_STATUS_ERROR_ELS_REJECT, "ELS Reject",
+ HBA_STATUS_ERROR_INVALID_LUN, "Invalid LUN",
+ HBA_STATUS_ERROR_INCOMPATIBLE, "Request Incompatible",
+ HBA_STATUS_ERROR_AMBIGUOUS_WWN, "Ambiguous WWN",
+ HBA_STATUS_ERROR_LOCAL_BUS, "Local Bus Error",
+ HBA_STATUS_ERROR_LOCAL_TARGET, "Local Target Error",
+ HBA_STATUS_ERROR_LOCAL_LUN, "Local LUN Error",
+ HBA_STATUS_ERROR_LOCAL_SCSIID_BOUND, "Local SCSIID Bound",
+ HBA_STATUS_ERROR_TARGET_FCID, "Target FCID Error",
+ HBA_STATUS_ERROR_TARGET_NODE_WWN, "Target Node WWN Error",
+ HBA_STATUS_ERROR_TARGET_PORT_WWN, "Target Port WWN Error",
+ HBA_STATUS_ERROR_TARGET_LUN, "Target LUN Error",
+ HBA_STATUS_ERROR_TARGET_LUID, "Target LUID Error",
+ HBA_STATUS_ERROR_NO_SUCH_BINDING, "No Such Binding",
+ HBA_STATUS_ERROR_NOT_A_TARGET, "Not a Target",
+ HBA_STATUS_ERROR_UNSUPPORTED_FC4, "Unsupported FC4",
+ HBA_STATUS_ERROR_INCAPABLE, "Incapable",
+ HBA_STATUS_ERROR_TARGET_BUSY, "Target Busy",
+ HBA_STATUS_ERROR_NOT_LOADED, "Not Loaded",
+ HBA_STATUS_ERROR_ALREADY_LOADED, "Alreday Loaded",
+ HBA_STATUS_ERROR_ILLEGAL_FCID, "Illegal FCID",
+ HBA_STATUS_ERROR_NOT_ASCSIDEVICE, "Not a SCSI Device",
+ HBA_STATUS_ERROR_INVALID_PROTOCOL_TYPE, "Invalid Protocol Type",
+ HBA_STATUS_ERROR_BAD_EVENT_TYPE, "Bad Event Type",
+ -1, NULL
+};
+
+SAS_STATE porttype_string[] = {
+ HBA_PORTTYPE_UNKNOWN, "UNKNOWN",
+ HBA_PORTTYPE_OTHER, "OTHER",
+ HBA_PORTTYPE_NOTPRESENT, "NOT Present",
+ HBA_PORTTYPE_SASDEVICE, "SAS Device",
+ HBA_PORTTYPE_SATADEVICE, "SATA Device",
+ HBA_PORTTYPE_SASEXPANDER, "SAS Expander",
+ -1, NULL,
+};
+
+SAS_STATE portstate_string[] = {
+ HBA_PORTSTATE_UNKNOWN, "unknown",
+ HBA_PORTSTATE_ONLINE, "online",
+ HBA_PORTSTATE_OFFLINE, "offline",
+ HBA_PORTSTATE_BYPASSED, "bypassed",
+ HBA_PORTSTATE_DIAGNOSTICS, "diagnostics",
+ HBA_PORTSTATE_LINKDOWN, "link Down",
+ HBA_PORTSTATE_ERROR, "port Error",
+ HBA_PORTSTATE_LOOPBACK, "loopback",
+ HBA_PORTSTATE_DEGRADED, "degraded",
+ -1, NULL,
+};
+
+static SAS_STATE phystate_string[] = {
+ HBA_SASSTATE_UNKNOWN, "unknown",
+ HBA_SASSTATE_DISABLED, "disabled",
+ HBA_SASSTATE_FAILED, "failed",
+ HBA_SASSTATE_SATASPINUP, "sata-spinup",
+ HBA_SASSTATE_SATAPORTSEL, "sata-portselector",
+ HBA_SASSPEED_1_5GBIT, "1.5Gbit",
+ HBA_SASSPEED_3GBIT, "3Gbit",
+ HBA_SASSPEED_6GBIT, "6Gbit",
+ -1, NULL,
+};
+
+static SAS_STATE dtype_string[] = {
+ DTYPE_DIRECT, "Disk Device",
+ DTYPE_SEQUENTIAL, "Tape Device",
+ DTYPE_PRINTER, "Printer Device",
+ DTYPE_PROCESSOR, "Processor Device",
+ DTYPE_WORM, "WORM Device",
+ DTYPE_RODIRECT, "CD/DVD Device",
+ DTYPE_SCANNER, "Scanner Device",
+ DTYPE_OPTICAL, "Optical Memory Device",
+ DTYPE_CHANGER, "Medium Changer Device",
+ DTYPE_COMM, "Communications Device",
+ DTYPE_ARRAY_CTRL, "Storage Array Controller Device",
+ DTYPE_ESI, "Enclosure Services Device",
+ DTYPE_RBC, "Simplified Direct-access Device",
+ DTYPE_OCRW, "Optical Card Reader/Writer Device",
+ DTYPE_BCC, "Bridge Controller Commands",
+ DTYPE_OSD, "Object-based Storage Device",
+ DTYPE_ADC, "Automation/Drive Interface",
+ DTYPE_WELLKNOWN, "Well Known Logical Unit",
+ DTYPE_UNKNOWN, "Unknown Device",
+ -1, NULL
+};
+
+static char *getPhyStateString(HBA_UINT32 key, phystat_type phyt);
+
+char *
+getIndentSpaces(int number)
+{
+ int i = 0;
+ /* the maximum indent with terminator '\0' */
+ static char ret[MAXINDENT+1];
+
+ if (number > MAXINDENT)
+ number = MAXINDENT;
+
+ for (i = 0; i < number; i++) {
+ ret[i] = ' ';
+ }
+ ret[i] = '\0';
+ return (ret);
+}
+
+char *
+getStateString(HBA_UINT32 key, SAS_STATE *stat_string)
+{
+ static char ret[64];
+ while (stat_string->key != -1) {
+ if (stat_string->key == key) {
+ return ((char *)stat_string->value);
+ }
+ stat_string++;
+ }
+ (void *) sprintf(ret, "Undefined value (%d)", key);
+ return (ret);
+}
+
+static char *
+getPhyStateString(HBA_UINT32 key, phystat_type phyt)
+{
+ int i = 0, len = 0, match = 0;
+ HBA_UINT32 physpeed[] = {
+ HBA_SASSPEED_1_5GBIT,
+ HBA_SASSPEED_3GBIT,
+ HBA_SASSPEED_6GBIT
+ };
+
+ len = sizeof (physpeed) / sizeof (HBA_UINT32);
+ for (i = 0; i < len; i++) {
+ if (key == physpeed[i]) {
+ match = 1;
+ break;
+ }
+ }
+
+ if (match == 1) {
+ if (phyt == PHY_STATE)
+ return ("enabled");
+ else
+ return (getStateString(key, phystate_string));
+ } else {
+ if (phyt == PHY_STATE)
+ return (getStateString(key, phystate_string));
+ else
+ return ("not available");
+ }
+}
+
+char *
+getHBAStatus(HBA_STATUS key)
+{
+ return (getStateString(key, hbastatus_string));
+}
+
+/*
+ * return device type description
+ *
+ * Arguments:
+ * dType - Device type returned from Standard INQUIRY
+ * Returns:
+ * char string description for device type
+ */
+char *
+getDTypeString(uchar_t dType)
+{
+ return (getStateString((dType & DTYPE_MASK), dtype_string));
+}
+
+uint64_t
+wwnConversion(uchar_t *wwn)
+{
+ uint64_t tmp;
+ (void *) memcpy(&tmp, wwn, sizeof (uint64_t));
+ return (ntohll(tmp));
+}
+
+/*
+ * prints out HBA information
+ */
+void
+printHBAInfo(SMHBA_ADAPTERATTRIBUTES *attrs, int pflag, int numberOfPorts,
+ const char *adapterName)
+{
+
+ (void *) fprintf(stdout, "%s %s\n", "HBA Name:", adapterName);
+
+ if (pflag & PRINT_VERBOSE) {
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4), "Manufacturer:",
+ attrs->Manufacturer[0] == 0?
+ "not available":attrs->Manufacturer);
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4), "Model: ",
+ attrs->Model[0] == 0? "not available":attrs->Model);
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4),
+ "Firmware Version:",
+ attrs->FirmwareVersion[0] == 0? "not available":
+ attrs->FirmwareVersion);
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4),
+ "FCode/BIOS Version:",
+ attrs->OptionROMVersion[0] == 0? "not available":
+ attrs->OptionROMVersion);
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4),
+ "Serial Number:",
+ attrs->SerialNumber[0] == 0? "not available":
+ attrs->SerialNumber);
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4),
+ "Driver Name:",
+ attrs->DriverName[0] == 0? "not available":
+ attrs->DriverName);
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4),
+ "Driver Version:",
+ attrs->DriverVersion[0] == 0? "not available":
+ attrs->DriverVersion);
+ (void *) fprintf(stdout, "%s%s %d\n",
+ getIndentSpaces(4),
+ "Number of HBA Ports:",
+ numberOfPorts);
+ }
+}
+
+/*
+ * prints out all the HBA port information
+ */
+void
+printHBAPortInfo(SMHBA_PORTATTRIBUTES *port,
+ SMHBA_ADAPTERATTRIBUTES *attrs, int pflag) {
+
+ if ((port == NULL) || (attrs == NULL)) {
+ return;
+ }
+
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(2),
+ "HBA Port Name:",
+ port->OSDeviceName);
+
+ if (!(pflag & PRINT_VERBOSE)) {
+ return;
+ }
+
+ if (port->PortType != HBA_PORTTYPE_SASDEVICE)
+ return;
+
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4),
+ "Type:",
+ getStateString(port->PortType, porttype_string));
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(4),
+ "State:",
+ getStateString(port->PortState, portstate_string));
+
+ (void *) fprintf(stdout, "%s%s %016llx\n",
+ getIndentSpaces(4),
+ "Local SAS Address:",
+ wwnConversion(port->PortSpecificAttribute.SASPort->\
+ LocalSASAddress.wwn));
+
+ (void *) fprintf(stdout, "%s%s %016llx\n",
+ getIndentSpaces(4),
+ "Attached SAS Address:",
+ wwnConversion(port->PortSpecificAttribute.SASPort->\
+ AttachedSASAddress.wwn));
+
+ (void *) fprintf(stdout, "%s%s %d\n",
+ getIndentSpaces(4),
+ "Number of Phys:",
+ port->PortSpecificAttribute.SASPort->NumberofPhys);
+}
+
+void
+printHBAPortPhyInfo(SMHBA_SAS_PHY *phyinfo)
+{
+ if (phyinfo == NULL)
+ return;
+
+ (void *) fprintf(stdout, "%s%s %u\n",
+ getIndentSpaces(6),
+ "Identifier:",
+ phyinfo->PhyIdentifier);
+
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(8),
+ "State: ",
+ getPhyStateString(phyinfo->NegotiatedLinkRate, PHY_STATE));
+ (void *) fprintf(stdout, "%s%s %s/%s\n",
+ getIndentSpaces(8),
+ "HardwareLinkRate(Min/Max):",
+ getPhyStateString(phyinfo->HardwareMinLinkRate, PHY_SPEED),
+ getPhyStateString(phyinfo->HardwareMaxLinkRate, PHY_SPEED));
+ (void *) fprintf(stdout, "%s%s %s/%s\n",
+ getIndentSpaces(8),
+ "ProgrammedLinkRate(Min/Max):",
+ getPhyStateString(phyinfo->ProgrammedMinLinkRate, PHY_SPEED),
+ getPhyStateString(phyinfo->ProgrammedMaxLinkRate, PHY_SPEED));
+ (void *) fprintf(stdout, "%s%s %s\n",
+ getIndentSpaces(8),
+ "NegotiatedLinkRate:",
+ getPhyStateString(phyinfo->NegotiatedLinkRate, PHY_SPEED));
+}
+
+void
+printHBAPortPhyStatistics(SMHBA_SASPHYSTATISTICS *phystat)
+{
+ if (phystat == NULL)
+ return;
+
+ (void *) fprintf(stdout, "%s%s\n",
+ getIndentSpaces(8),
+ "Link Error Statistics:");
+ (void *) fprintf(stdout, "%s%s %llu\n",
+ getIndentSpaces(12),
+ "Invalid Dword:",
+ phystat->InvalidDwordCount);
+ (void *) fprintf(stdout, "%s%s %llu\n",
+ getIndentSpaces(12),
+ "Running Disparity Error:",
+ phystat->RunningDisparityErrorCount);
+ (void *) fprintf(stdout, "%s%s %llu\n",
+ getIndentSpaces(12),
+ "Loss of Dword Sync:",
+ phystat->LossofDwordSyncCount);
+ (void *) fprintf(stdout, "%s%s %llu\n",
+ getIndentSpaces(12),
+ "Reset Problem:",
+ phystat->PhyResetProblemCount);
+}
+
+/*
+ * print the OS device name for the logical-unit object
+ *
+ * Arguments:
+ * devListWalk - OS device path info
+ * verbose - boolean indicating whether to display additional info
+ *
+ * returns:
+ * 0 - we're good.
+ * >0 - we met issues.
+ */
+int
+printTargetPortInfo(targetPortList_t *TPListWalk, int pflag)
+{
+ targetPortConfig_t *configList;
+ targetPortMappingData_t *mapList;
+ int count, i;
+ int ret = 0;
+
+ (void *) fprintf(stdout, "Target Port SAS Address: %016llx\n",
+ wwnConversion(TPListWalk->sasattr.LocalSASAddress.wwn));
+ if ((pflag & PRINT_VERBOSE) || (pflag & PRINT_TARGET_SCSI)) {
+ (void *) fprintf(stdout, "%sType: %s\n", getIndentSpaces(4),
+ getStateString(TPListWalk->targetattr.PortType,
+ porttype_string));
+ for (configList = TPListWalk->configEntry;
+ configList != NULL; configList = configList->next) {
+ (void *) fprintf(stdout, "%sHBA Port Name: %s\n",
+ getIndentSpaces(4), configList->hbaPortName);
+ if (wwnConversion(configList->expanderSASAddr.wwn) !=
+ 0) {
+ if (configList->expanderValid) {
+ (void *) fprintf(stdout,
+ "%sExpander Device SAS Address:"
+ " %016llx",
+ getIndentSpaces(8),
+ wwnConversion(configList->
+ expanderSASAddr.wwn));
+ } else {
+ (void *) fprintf(stdout,
+ "%sExpander Device SAS Address:"
+ " %016llx (Failed to Validate"
+ " Attached Port.)",
+ getIndentSpaces(8),
+ wwnConversion(configList->
+ expanderSASAddr.wwn));
+ ret++;
+ }
+ } else {
+ if (configList->expanderValid) {
+ (void *) fprintf(stdout,
+ "%sExpander Device SAS Address: %s",
+ getIndentSpaces(8),
+ "None (direct attached)");
+ } else {
+ (void *) fprintf(stdout,
+ "%sExpander Device SAS Address: %s",
+ getIndentSpaces(8),
+ "None (Failed to Get"
+ " Attached Port)");
+ }
+ }
+ (void *) fprintf(stdout, "\n");
+ if (pflag & PRINT_TARGET_SCSI) {
+
+ if (configList->reportLUNsFailed) {
+ (void *) fprintf(stdout,
+ "%s %016llx\n",
+ gettext("Error: Failed to get "
+ "ReportLun Data on"),
+ wwnConversion(TPListWalk->
+ sasattr.LocalSASAddress.wwn));
+ ret++;
+ continue;
+ }
+
+ for (mapList = configList->map;
+ mapList != NULL; mapList = mapList->next) {
+ (void *) fprintf(stdout, "%sLUN : %d\n",
+ getIndentSpaces(12),
+ mapList->osLUN);
+ if (mapList->mappingExist) {
+ (void *) fprintf(stdout,
+ "%sOS Device Name : %s\n",
+ getIndentSpaces(14),
+ (mapList->osDeviceName[0] ==
+ '\0') ? "Not avaialble" :
+ mapList->osDeviceName);
+ } else {
+ (void *) fprintf(stdout,
+ "%sOS Device Name : %s\n",
+ getIndentSpaces(14), "No "
+ "matching OS Device "
+ "found.");
+ ret++;
+ }
+ /* indentation changed here */
+ if (mapList->inquiryFailed) {
+ (void *) fprintf(stdout, "%s %s LUN %d\n",
+ gettext("Error: Failed to get Inquiry Data on"),
+ mapList->osDeviceName, mapList->osLUN);
+ ret++;
+ } else {
+ (void *) fprintf(stdout, "%sVendor: ",
+ getIndentSpaces(14));
+ for (count = sizeof (mapList->inq_vid), i = 0;
+ i < count; i++) {
+ if (isprint(mapList->inq_vid[i]))
+ (void *) fprintf(stdout, "%c",
+ mapList->inq_vid[i]);
+ }
+
+ (void *) fprintf(stdout, "\n%sProduct: ",
+ getIndentSpaces(14));
+ for (count = sizeof (mapList->inq_pid), i = 0;
+ i < count; i++) {
+ if (isprint(mapList->inq_pid[i]))
+ (void *) fprintf(stdout, "%c",
+ mapList->inq_pid[i]);
+ }
+
+ (void *) fprintf(stdout, "\n%sDevice Type: %s\n",
+ getIndentSpaces(14),
+ getDTypeString(mapList->inq_dtype));
+ }
+ /* indentation changed back */
+ }
+ }
+ }
+ }
+ return (ret);
+}
+
+/*
+ * print the OS device name for the logical-unit object
+ *
+ * Arguments:
+ * devListWalk - OS device path info
+ * verbose - boolean indicating whether to display additional info
+ *
+ * returns:
+ * 0 - we're good.
+ * >0 - we met issues.
+ */
+int
+printOSDeviceNameInfo(discoveredDevice *devListWalk, boolean_t verbose)
+{
+ portList *portElem;
+ tgtPortWWNList *tgtWWNList;
+ int i, count;
+ int ret = 0;
+
+ (void *) fprintf(stdout, "OS Device Name: %s\n",
+ devListWalk->OSDeviceName);
+ if (verbose == B_TRUE) {
+ for (portElem = devListWalk->HBAPortList;
+ portElem != NULL; portElem = portElem->next) {
+ (void *) fprintf(stdout, "%sHBA Port Name: ",
+ getIndentSpaces(4));
+ (void *) fprintf(stdout, "%s", portElem->portName);
+ for (tgtWWNList = portElem->tgtPortWWN;
+ tgtWWNList != NULL; tgtWWNList = tgtWWNList->next) {
+ (void *) fprintf(stdout,
+ "\n%sTarget Port SAS Address: ",
+ getIndentSpaces(8));
+ (void *) fprintf(stdout, "%016llx",
+ wwnConversion(tgtWWNList->portWWN.wwn));
+ (void *) fprintf(stdout, "\n%sLUN: %u",
+ getIndentSpaces(12),
+ tgtWWNList->scsiOSLun);
+ }
+ (void *) fprintf(stdout, "\n");
+ }
+
+ if (devListWalk->inquiryFailed) {
+ (void *) fprintf(stdout, "%s %s\n",
+ gettext("Error: Failed to get Inquiry data "
+ "on device"), devListWalk->OSDeviceName);
+ ret++;
+ } else {
+ (void *) fprintf(stdout, "%sVendor: ",
+ getIndentSpaces(4));
+ for (count = sizeof (devListWalk->VID), i = 0;
+ i < count; i++) {
+ if (isprint(devListWalk->VID[i]))
+ (void *) fprintf(stdout, "%c",
+ devListWalk->VID[i]);
+ }
+
+ (void *) fprintf(stdout, "\n%sProduct: ",
+ getIndentSpaces(4));
+ for (count = sizeof (devListWalk->PID), i = 0;
+ i < count; i++) {
+ if (isprint(devListWalk->PID[i]))
+ (void *) fprintf(stdout, "%c",
+ devListWalk->PID[i]);
+ }
+
+ (void *) fprintf(stdout, "\n%sDevice Type: %s\n",
+ getIndentSpaces(4),
+ getDTypeString(devListWalk->dType));
+ }
+ }
+ return (ret);
+}