fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Extracted from the old scsi.h file */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Structure to handle the inq. page 0x80 serial number */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern char *dtype[];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern const int OPTION_P;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint find_supported_inq_page(HBA_HANDLE handle, HBA_WWN hwwn, HBA_WWN pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The routines within this file operate against the T11
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * HBA API interface. In some cases, proprietary Sun driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * interface are also called to add additional information
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * above what the standard library supports.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte printf(MSGSTR(2423, "UNKNOWN ERROR TYPE %d"), status);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "\nERROR: No Fibre Channel Adapters found.\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns non-zero on failure (aka, HBA_STATUS_ERROR_*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Will handle retries if applicable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetAdapterAttrs(HBA_HANDLE handle, char *name, HBA_ADAPTERATTRIBUTES *attrs) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte HBA_STATUS status = HBA_STATUS_ERROR_TRY_AGAIN; /* force first pass */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop as long as we have a retryable error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status == HBA_STATUS_ERROR_BUSY) && count++ < MAX_RETRIES) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterAttributes(handle, attrs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We encountered a non-retryable error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "\nERROR: Unable to retrieve adapter port details (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns non-zero on failure (aka, HBA_STATUS_ERROR_*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Will handle retries if applicable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetAdapterPortAttrs(HBA_HANDLE handle, char *name, int portIndex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte HBA_STATUS status = HBA_STATUS_ERROR_TRY_AGAIN; /* force first pass */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop as long as we have a retryable error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status == HBA_STATUS_ERROR_BUSY) && count++ < MAX_RETRIES) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterPortAttributes(handle, portIndex, attrs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The odds of this occuring are very slim, but possible. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we hit a stale data scenario,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we'll just tell the user to try again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We encountered a non-retryable error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "\nERROR: Unable to retrieve adapter port details (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns non-zero on failure (aka, HBA_STATUS_ERROR_*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Will handle retries if applicable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn FortegetDiscPortAttrs(HBA_HANDLE handle, char *name, int portIndex, int discIndex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte HBA_STATUS status = HBA_STATUS_ERROR_TRY_AGAIN; /* force first pass */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop as long as we have a retryable error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status == HBA_STATUS_ERROR_BUSY) && count++ < MAX_RETRIES) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetDiscoveredPortAttributes(handle, portIndex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The odds of this occuring are very slim, but possible. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we hit a stale data scenario, we'll just tell the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * user to try again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We encountered a non-retryable error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "\nERROR: Unable to retrieve target port details (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (adapterIndex = 0; adapterIndex < count; adapterIndex ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterName(adapterIndex, (char *)&name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Just skip it, maybe it was DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Just skip it, maybe it was DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This should never happen, we'll just skip the adapter */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (portIndex = 0; portIndex < hbaAttrs.NumberOfPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Internal routines/structure to deal with a path list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so we can ensure uniqueness
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid add_path(struct path_entry *head, struct path_entry *cur) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (tmp = head; tmp->next != NULL; tmp = tmp->next) { }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct path_entry *is_duplicate_path(struct path_entry *head, char *path) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp(tmp->path, path, sizeof (tmp->path)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < 16; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* We take a wild guess for our first get target mappings call */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefetch_mappings(HBA_HANDLE handle, HBA_WWN pwwn, HBA_FCPTARGETMAPPINGV2 **map) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte HBA_STATUS status = HBA_STATUS_ERROR_TRY_AGAIN; /* force first pass */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop as long as we have a retryable error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status == HBA_STATUS_ERROR_MORE_DATA) && loop++ < MAX_RETRIES) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetFcpTargetMappingV2(handle, pwwn, *map);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (status == HBA_STATUS_ERROR_MORE_DATA) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We encountered a non-retryable error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "\nERROR: Unable to retrieve SCSI device paths "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "(HBA Port WWN %016llx)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns the index of the first match, or -1 if no match
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortematch_mappings(char *compare, HBA_FCPTARGETMAPPINGV2 *map) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Convert the paths to phsyical paths */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte physical = get_slash_devices_from_osDevName(compare,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mapIndex = 0; mapIndex < map->NumberOfEntries; mapIndex ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns non-zero on failure (aka HBA_STATUS_ERROR_*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ERROR: Unable to load HBA API library: "));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t inquirySize = sizeof (inq), senseSize = sizeof (sense);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBAs */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (adapterIndex = 0; adapterIndex < count; adapterIndex ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterName(adapterIndex, (char *)&name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Should not happen, just skip it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBA Ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (portIndex = 0; portIndex < hbaAttrs.NumberOfPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fetch_mappings(handle, portAttrs.PortWWN, &map)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all target Mapping entries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mapIndex = 0; mapIndex < map->NumberOfEntries;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct path_entry));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (map->entry[mapIndex].ScsiId.OSDeviceName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (map->entry[mapIndex].ScsiId.OSDeviceName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte printf(MSGSTR(2098, "\nFound Fibre Channel device(s):\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Reserved"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unknown"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte printf(MSGSTR(31, "Logical Path:%s"), tmp->path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We probably shouldn't be using a g_fc interface here */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t inquirySize = sizeof (inq), senseSize = sizeof (sense);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (path_index = 0; argv[path_index] != NULL; path_index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sscanf(argv[path_index], "%016llx", &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stderr, MSGSTR(112, "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Convert the paths to phsyical paths */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte physical = get_slash_devices_from_osDevName(argv[path_index],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBAs */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (adapterIndex = 0; adapterIndex < count; adapterIndex ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterName(adapterIndex, (char *)&name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Should never happen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBA Ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (portIndex = 0; portIndex < hbaAttrs.NumberOfPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fetch_mappings(handle, portAttrs.PortWWN, &map)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mapIndex = 0; mapIndex < map->NumberOfEntries;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call the inquiry cmd on page 0x80 only if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the vendor supports page 0x80
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unavailable",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unsupported",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we are adding serial number information
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from 0x80. If length is less than 39,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then we want to increase length to 52 to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reflect the fact that we have serial number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Error: I/O failure communicating with %s "),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stderr, MSGSTR(112, "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count, adapterIndex, portIndex, mapIndex, discIndex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t inquirySize = sizeof (inq), senseSize = sizeof (sense);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (path_index = 0; argv[path_index] != NULL; path_index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sscanf(argv[path_index], "%016llx", &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stderr, MSGSTR(112, "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBAs */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (adapterIndex = 0; adapterIndex < count && !done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterName(adapterIndex, (char *)&name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Should never happen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBA Ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (portIndex = 0; portIndex < hbaAttrs.NumberOfPorts && !done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fetch_mappings(handle, portAttrs.PortWWN, &map)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mapIndex = match_mappings(argv[path_index], map);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Pos Port_ID Hard_Addr Port WWN"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Node WWN Type\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Move on to the next target */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices are not all required to respond to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Scsi Inquiry calls sent to LUN 0. We must
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fisrt issue a ReportLUN and then send the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SCSI Inquiry call to the first LUN Returned
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from the ReportLUN call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (unsigned long)raw_luns;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in case we are unable to retrieve report
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LUN data, we will blindly try sending the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * INQUIRY to lun 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now dump this HBA's stats */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stderr, MSGSTR(112, "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (path_index = 0; argv[path_index] != NULL; path_index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sscanf(argv[path_index], "%016llx", &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stderr, MSGSTR(112, "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBAs */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (adapterIndex = 0; adapterIndex < count; adapterIndex ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterName(adapterIndex, (char *)&name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Should never happen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBA Ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (portIndex = 0; portIndex < hbaAttrs.NumberOfPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fetch_mappings(handle, portAttrs.PortWWN, &map)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (matched || match_mappings(argv[path_index], map) >= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " sync loss signal loss sequence err"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " invalid word CRC\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%x\t%-12d%-12d%-14d%-15d%-15d%-12d\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%x\t%-12u%-12u%-14u%-15u%-15u%-12u\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now dump this HBA's stats */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%x\t%-12d%-12d%-14d%-15d%-15d%-12d\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%x\t%-12u%-12u%-14u%-15u%-15u%-12u\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stderr, MSGSTR(112, "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " cleared by a reset, only power cycles.\n"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "These counts must be compared"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " to previously read counts.\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Points to another lun_tracking instance with the same map->LUID */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Points to next lun_tracking with a different map->LUID */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *phys_path = get_slash_devices_from_osDevName(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Only proceed if we are an mpxio path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (phys_path == NULL || strstr(phys_path, VHCI_COMPONENT) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* First get the controller path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sprintf(temppath, "/dev/cfg/c%d", entry.ScsiId.ScsiBusNumber);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((count = readlink(temppath, buf, sizeof (buf)))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now skip over the leading "../.." */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now chop off the trailing ":xxx" portion if present */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retval = get_scsi_vhci_pathinfo(phys_path, &ioc, &pathcnt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < pathcnt; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strstr(devPath, ioc.ret_buf[i].device.ret_phci)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This could break someday if MPxIO changes devaddr */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retval = nvlist_unpack(ioc.ret_buf[i].ret_prop.buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "UNKNOWN PROB");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lun->info.pathInfoState = ioc.ret_buf[i].ret_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free everything we alloced */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Utility routine to add new entries to the list (ignores dups) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteadd_lun_path(struct lun_tracking *head, HBA_FCPSCSIENTRYV2 *map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (tmp = head; tmp != NULL; tmp = tmp->next_lun) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (HBA_LUID)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Ensure this isn't a duplicate */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (memcmp(&cmp->map, map, sizeof (cmp->map)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (memcmp(&cmp->map, map, sizeof (cmp->map)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We have a new entry to add */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmp->next_path = (struct lun_tracking *)calloc(1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct lun_tracking));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Append a new LUN at the end of the list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (tmp = head; tmp->next_lun != NULL; tmp = tmp->next_lun) {}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct lun_tracking));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefchba_display_config(char **argv, int option_t_input, int argc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t inquirySize = sizeof (inq), senseSize = sizeof (sense);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (path_index = 0; argv[path_index] != NULL; path_index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sscanf(argv[path_index], "%016llx", &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stderr, MSGSTR(112, "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Convert the paths to phsyical paths */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte physical = get_slash_devices_from_osDevName(argv[path_index],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We have to loop twice to ensure we don't miss any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * extra paths for other targets in a multi-target device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* First check WWN/path comparisons */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (adapterIndex = 0; adapterIndex < count; adapterIndex ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterName(adapterIndex, (char *)&name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Should never happen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBA Ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (portIndex = 0; portIndex < hbaAttrs.NumberOfPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fetch_mappings(handle, portAttrs.PortWWN, &map)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mapIndex = 0; mapIndex < map->NumberOfEntries;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct lun_tracking));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memcpy(&head->hba_pwwn, &portAttrs.PortWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (matched) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now do it again and look for matching LUIDs (aka GUIDs) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (adapterIndex = 0; adapterIndex < count; adapterIndex ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_GetAdapterName(adapterIndex, (char *)&name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* May have been DR'd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Should never happen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all HBA Ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (portIndex = 0; portIndex < hbaAttrs.NumberOfPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fetch_mappings(handle, portAttrs.PortWWN, &map)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mapIndex = 0; mapIndex < map->NumberOfEntries;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (HBA_LUID)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct lun_tracking));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memcpy(&head->hba_pwwn, &portAttrs.PortWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (matched) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stderr, MSGSTR(112, "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Just bomb out instead of going on */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now display all the LUNs that we found that matched */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Change behavior if this is an MPxIO device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* continue to next online path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Error: Failed to get handle for %s "),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* continue to next path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Error: I/O failure communicating with %s "),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "DEVICE PROPERTIES for disk: %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "DEVICE PROPERTIES for tape: %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "DEVICE PROPERTIES for: %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte print_chars(inq.inq_vid, sizeof (inq.inq_vid), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stdout, MSGSTR(2115, "\n Product ID:\t\t"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte print_chars(inq.inq_pid, sizeof (inq.inq_pid), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte print_chars(inq.inq_revision, sizeof (inq.inq_revision), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call the inquiry cmd on page 0x80 only if the vendor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * supports page 0x80.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((find_supported_inq_page(handle, first_time->hba_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((inq.inq_dtype & DTYPE_MASK) == DTYPE_DIRECT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Read capacity wont work on standby paths, so try till OK */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* continue to next online path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* continue to next path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (status == HBA_STATUS_SCSI_CHECK_CONDITION &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * retry for check-condition state when unit attention
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * condition has been established
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Make sure we don't display garbage */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unformatted capacity:\t%6.3f MBytes"), lunMbytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get mode page information for FC device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * do not do mode sense if this is a tape device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode sense will rewind the tape
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((inq.inq_dtype & DTYPE_MASK) != DTYPE_SEQUENTIAL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (get_mode_page(first_time->map.ScsiId.OSDeviceName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (offset < (ntohs(mode_header_ptr->length) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Write Cache:\t\t"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Enabled\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Read Cache:\t\t"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Enabled\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Minimum prefetch:\t0x%x\n"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Maximum prefetch:\t0x%x\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct mode_page);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stdout, " %s\t\t", MSGSTR(35, "Device Type:"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((inq.inq_dtype & DTYPE_MASK) < 0x1f) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* dtype of 0x1f is returned */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now display all paths to this LUN */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Display the controller information */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fprintf(stdout, MSGSTR(2303, " Controller \t%s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Device Address\t\t%016llx,%x\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Host controller port WWN\t%016llx\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle expert-mode hotplug commands
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return 0 iff all is okay
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefchba_hotplug_e(int todo, char **argv, int verbose_flag, int force_flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Convert the paths to phsyical paths */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte path_phys = get_slash_devices_from_osDevName(argv[0],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Error: Invalid pathname (%s)"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "phys path = \"%s\"\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* acquire rights to hack on device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Error: can't acquire \"%s\": %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* all done now -- release device */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns non zero if we should use FC-HBA.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For x86, luxadm uses FC-HBA.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns non-zero if we should skip the HBA at index "i"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) HBA_GetVendorLibraryAttributes(i, &lib_attrs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function to determine if the given page is supported by vendor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefind_supported_inq_page(HBA_HANDLE handle, HBA_WWN hwwn, HBA_WWN pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte status = HBA_ScsiInquiryV2(handle, hwwn, pwwn, lun, 1, 0x00,