17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM /*
22*9087SZhong.Wang@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237836SJohn.Forte@Sun.COM * Use is subject to license terms.
247836SJohn.Forte@Sun.COM */
257836SJohn.Forte@Sun.COM
267836SJohn.Forte@Sun.COM
277836SJohn.Forte@Sun.COM #include "fcinfo.h"
287836SJohn.Forte@Sun.COM #include <libintl.h>
297836SJohn.Forte@Sun.COM
307836SJohn.Forte@Sun.COM struct lun {
317836SJohn.Forte@Sun.COM uchar_t val[8];
327836SJohn.Forte@Sun.COM };
337836SJohn.Forte@Sun.COM
347836SJohn.Forte@Sun.COM typedef enum {
357836SJohn.Forte@Sun.COM HBA_PORT,
367836SJohn.Forte@Sun.COM REMOTE_PORT,
377836SJohn.Forte@Sun.COM LOGICAL_UNIT
387836SJohn.Forte@Sun.COM } resource_type;
397836SJohn.Forte@Sun.COM
407836SJohn.Forte@Sun.COM typedef struct rep_luns_rsp {
417836SJohn.Forte@Sun.COM uint32_t length;
427836SJohn.Forte@Sun.COM uint32_t rsrvd;
437836SJohn.Forte@Sun.COM struct lun lun[1];
447836SJohn.Forte@Sun.COM } rep_luns_rsp_t;
457836SJohn.Forte@Sun.COM
467836SJohn.Forte@Sun.COM static int getTargetMapping(HBA_HANDLE, HBA_WWN myhbaPortWWN,
477836SJohn.Forte@Sun.COM HBA_FCPTARGETMAPPINGV2 **mapping);
487836SJohn.Forte@Sun.COM static int processHBA(HBA_HANDLE handle, HBA_ADAPTERATTRIBUTES attrs,
497836SJohn.Forte@Sun.COM int portIndex, HBA_PORTATTRIBUTES port, HBA_FCPTARGETMAPPINGV2 *map,
507836SJohn.Forte@Sun.COM int resourceType, int flags, int mode);
517836SJohn.Forte@Sun.COM static void processRemotePort(HBA_HANDLE handle, HBA_WWN portWWN,
527836SJohn.Forte@Sun.COM HBA_FCPTARGETMAPPINGV2 *map, int wwnCount, char **wwn_argv, int flags);
537836SJohn.Forte@Sun.COM static void handleRemotePort(HBA_HANDLE handle, HBA_WWN portWWN,
547836SJohn.Forte@Sun.COM HBA_WWN myRemotePortWWN, HBA_PORTATTRIBUTES *discPort);
557836SJohn.Forte@Sun.COM static void printLinkStat(HBA_HANDLE handle, HBA_WWN hbaportWWN,
567836SJohn.Forte@Sun.COM HBA_WWN destWWN);
577836SJohn.Forte@Sun.COM static void handleScsiTarget(HBA_HANDLE handle, HBA_WWN hbaPortWWN,
587836SJohn.Forte@Sun.COM HBA_WWN scsiTargetWWN, HBA_FCPTARGETMAPPINGV2 *map);
597836SJohn.Forte@Sun.COM static int retrieveAttrs(HBA_HANDLE handle, HBA_WWN hbaPortWWN,
607836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES *attrs, HBA_PORTATTRIBUTES *port, int *portIndex);
617836SJohn.Forte@Sun.COM static void searchDevice(discoveredDevice **devList, HBA_FCPSCSIENTRYV2 entry,
627836SJohn.Forte@Sun.COM HBA_WWN initiatorPortWWN, HBA_HANDLE handle, boolean_t verbose);
637836SJohn.Forte@Sun.COM
647836SJohn.Forte@Sun.COM /*
657836SJohn.Forte@Sun.COM * This function retrieve the adapater attributes, port attributes, and
667836SJohn.Forte@Sun.COM * portIndex for the given handle and hba port WWN.
677836SJohn.Forte@Sun.COM *
687836SJohn.Forte@Sun.COM * Arguments:
697836SJohn.Forte@Sun.COM * handle an HBA_HANDLE to a adapter
707836SJohn.Forte@Sun.COM * hbaPortWWN WWN of the port on the adapter to which to retrieve
717836SJohn.Forte@Sun.COM * HBA_PORTATTRIBUTES from
727836SJohn.Forte@Sun.COM * attrs pointer to a HBA_ADAPTERATTRIBUTES structure. Upon
737836SJohn.Forte@Sun.COM * successful completion, this structure will be filled in
747836SJohn.Forte@Sun.COM * port pointer to a HBA_PORTATTRIBUTES structure. Upon successful
757836SJohn.Forte@Sun.COM * completion, this structure will be fill in
767836SJohn.Forte@Sun.COM * portIndex the Index count of the port on the adapter that is
777836SJohn.Forte@Sun.COM * associated with the WWN.
787836SJohn.Forte@Sun.COM *
797836SJohn.Forte@Sun.COM * Returns
807836SJohn.Forte@Sun.COM * 0 successfully retrieve all information
817836SJohn.Forte@Sun.COM * >0 otherwise
827836SJohn.Forte@Sun.COM */
837836SJohn.Forte@Sun.COM static int
retrieveAttrs(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_ADAPTERATTRIBUTES * attrs,HBA_PORTATTRIBUTES * port,int * portIndex)847836SJohn.Forte@Sun.COM retrieveAttrs(HBA_HANDLE handle, HBA_WWN hbaPortWWN,
857836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES *attrs, HBA_PORTATTRIBUTES *port, int *portIndex)
867836SJohn.Forte@Sun.COM {
877836SJohn.Forte@Sun.COM HBA_STATUS status;
887836SJohn.Forte@Sun.COM int portCtr;
897836SJohn.Forte@Sun.COM int times;
907836SJohn.Forte@Sun.COM
917836SJohn.Forte@Sun.COM /* argument checking */
927836SJohn.Forte@Sun.COM if (attrs == NULL || port == NULL || portIndex == NULL) {
937836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Error: Invalid arguments to "
947836SJohn.Forte@Sun.COM "retreiveAttrs\n"));
957836SJohn.Forte@Sun.COM return (1);
967836SJohn.Forte@Sun.COM }
977836SJohn.Forte@Sun.COM
987836SJohn.Forte@Sun.COM /* retrieve Adapter attributes */
997836SJohn.Forte@Sun.COM memset(attrs, 0, sizeof (HBA_ADAPTERATTRIBUTES));
1007836SJohn.Forte@Sun.COM status = HBA_GetAdapterAttributes(handle, attrs);
1017836SJohn.Forte@Sun.COM times = 0;
1027836SJohn.Forte@Sun.COM while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
1037836SJohn.Forte@Sun.COM status == HBA_STATUS_ERROR_BUSY) &&
1047836SJohn.Forte@Sun.COM times++ < HBA_MAX_RETRIES) {
1057836SJohn.Forte@Sun.COM (void) sleep(1);
1067836SJohn.Forte@Sun.COM status = HBA_GetAdapterAttributes(handle, attrs);
1077836SJohn.Forte@Sun.COM if (status == HBA_STATUS_OK) {
1087836SJohn.Forte@Sun.COM break;
1097836SJohn.Forte@Sun.COM }
1107836SJohn.Forte@Sun.COM }
1117836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
1127836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Failed to get adapter "
1137836SJohn.Forte@Sun.COM "attributes handle(%d) Reason: "), handle);
1147836SJohn.Forte@Sun.COM printStatus(status);
1157836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
1167836SJohn.Forte@Sun.COM return (1);
1177836SJohn.Forte@Sun.COM }
1187836SJohn.Forte@Sun.COM
1197836SJohn.Forte@Sun.COM /*
1207836SJohn.Forte@Sun.COM * find the corresponding port on the adapter and retrieve
1217836SJohn.Forte@Sun.COM * port attributes as well as the port index
1227836SJohn.Forte@Sun.COM */
1237836SJohn.Forte@Sun.COM memset(port, 0, sizeof (HBA_PORTATTRIBUTES));
1247836SJohn.Forte@Sun.COM for (portCtr = 0; portCtr < attrs->NumberOfPorts; portCtr++) {
1257836SJohn.Forte@Sun.COM if ((status = HBA_GetAdapterPortAttributes(handle,
1267836SJohn.Forte@Sun.COM portCtr, port)) != HBA_STATUS_OK) {
1277836SJohn.Forte@Sun.COM fprintf(stderr,
1287836SJohn.Forte@Sun.COM gettext("Error: Failed to get port (%d) "
1297836SJohn.Forte@Sun.COM "attributes reason: "), portCtr);
1307836SJohn.Forte@Sun.COM printStatus(status);
1317836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
1327836SJohn.Forte@Sun.COM return (1);
1337836SJohn.Forte@Sun.COM }
1347836SJohn.Forte@Sun.COM if (memcmp(hbaPortWWN.wwn, port->PortWWN.wwn,
1357836SJohn.Forte@Sun.COM sizeof (port->PortWWN.wwn)) == 0) {
1367836SJohn.Forte@Sun.COM break;
1377836SJohn.Forte@Sun.COM }
1387836SJohn.Forte@Sun.COM }
1397836SJohn.Forte@Sun.COM if (portCtr >= attrs->NumberOfPorts) {
1407836SJohn.Forte@Sun.COM /*
1417836SJohn.Forte@Sun.COM * not able to find corresponding port WWN
1427836SJohn.Forte@Sun.COM * returning an error
1437836SJohn.Forte@Sun.COM */
1447836SJohn.Forte@Sun.COM *portIndex = 0;
1457836SJohn.Forte@Sun.COM return (1);
1467836SJohn.Forte@Sun.COM }
1477836SJohn.Forte@Sun.COM *portIndex = portCtr;
1487836SJohn.Forte@Sun.COM return (0);
1497836SJohn.Forte@Sun.COM }
1507836SJohn.Forte@Sun.COM
1517836SJohn.Forte@Sun.COM /*
1527836SJohn.Forte@Sun.COM * This function retrieves target mapping information for the HBA port WWN.
1537836SJohn.Forte@Sun.COM * This function will allocate space for the mapping structure which the caller
1547836SJohn.Forte@Sun.COM * must free when they are finished
1557836SJohn.Forte@Sun.COM *
1567836SJohn.Forte@Sun.COM * Arguments:
1577836SJohn.Forte@Sun.COM * handle - a handle to a HBA that we will be processing
1587836SJohn.Forte@Sun.COM * hbaPortWWN - the port WWN for the HBA port to retrieve the mappings for
1597836SJohn.Forte@Sun.COM * mapping - a pointer to a pointer for the target mapping structure
1607836SJohn.Forte@Sun.COM * Upon successful completion of this function, *mapping will contain
1617836SJohn.Forte@Sun.COM * the target mapping information
1627836SJohn.Forte@Sun.COM *
1637836SJohn.Forte@Sun.COM * returns:
1647836SJohn.Forte@Sun.COM * 0 if successful
1657836SJohn.Forte@Sun.COM * 1 otherwise
1667836SJohn.Forte@Sun.COM */
1677836SJohn.Forte@Sun.COM static int
getTargetMapping(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_FCPTARGETMAPPINGV2 ** mapping)1687836SJohn.Forte@Sun.COM getTargetMapping(HBA_HANDLE handle, HBA_WWN hbaPortWWN,
1697836SJohn.Forte@Sun.COM HBA_FCPTARGETMAPPINGV2 **mapping)
1707836SJohn.Forte@Sun.COM {
1717836SJohn.Forte@Sun.COM HBA_FCPTARGETMAPPINGV2 *map;
1727836SJohn.Forte@Sun.COM HBA_STATUS status;
1737836SJohn.Forte@Sun.COM int count;
1747836SJohn.Forte@Sun.COM
1757836SJohn.Forte@Sun.COM /* argument sanity checking */
1767836SJohn.Forte@Sun.COM if (mapping == NULL) {
1777836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Internal Error: mapping is NULL"));
1787836SJohn.Forte@Sun.COM return (1);
1797836SJohn.Forte@Sun.COM }
1807836SJohn.Forte@Sun.COM *mapping = NULL;
1817836SJohn.Forte@Sun.COM if ((map = calloc(1, sizeof (HBA_FCPTARGETMAPPINGV2))) == NULL) {
1827836SJohn.Forte@Sun.COM fprintf(stderr,
1837836SJohn.Forte@Sun.COM gettext("Internal Error: Unable to calloc map"));
1847836SJohn.Forte@Sun.COM return (1);
1857836SJohn.Forte@Sun.COM }
1867836SJohn.Forte@Sun.COM status = HBA_GetFcpTargetMappingV2(handle, hbaPortWWN, map);
1877836SJohn.Forte@Sun.COM count = map->NumberOfEntries;
1887836SJohn.Forte@Sun.COM if (status == HBA_STATUS_ERROR_MORE_DATA) {
1897836SJohn.Forte@Sun.COM free(map);
1907836SJohn.Forte@Sun.COM if ((map = calloc(1, (sizeof (HBA_FCPSCSIENTRYV2)*(count-1)) +
1917836SJohn.Forte@Sun.COM sizeof (HBA_FCPTARGETMAPPINGV2))) == NULL) {
1927836SJohn.Forte@Sun.COM fprintf(stderr,
1937836SJohn.Forte@Sun.COM gettext("Unable to calloc map of size: %d"), count);
1947836SJohn.Forte@Sun.COM return (1);
1957836SJohn.Forte@Sun.COM }
1967836SJohn.Forte@Sun.COM map->NumberOfEntries = count;
1977836SJohn.Forte@Sun.COM status = HBA_GetFcpTargetMappingV2(handle, hbaPortWWN, map);
1987836SJohn.Forte@Sun.COM }
1997836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
2007836SJohn.Forte@Sun.COM fprintf(stderr,
2017836SJohn.Forte@Sun.COM gettext("Error: Unable to get Target Mapping\n"));
2027836SJohn.Forte@Sun.COM printStatus(status);
2037836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
2047836SJohn.Forte@Sun.COM free(map);
2057836SJohn.Forte@Sun.COM return (1);
2067836SJohn.Forte@Sun.COM }
2077836SJohn.Forte@Sun.COM *mapping = map;
2087836SJohn.Forte@Sun.COM return (0);
2097836SJohn.Forte@Sun.COM }
2107836SJohn.Forte@Sun.COM
2117836SJohn.Forte@Sun.COM /*
2127836SJohn.Forte@Sun.COM * This function handles the remoteport object. It will issue a report lun
2137836SJohn.Forte@Sun.COM * to determine whether it is a scsi-target and then print the information.
2147836SJohn.Forte@Sun.COM *
2157836SJohn.Forte@Sun.COM * Arguments:
2167836SJohn.Forte@Sun.COM * handle - a handle to a HBA that we will be processing
2177836SJohn.Forte@Sun.COM * portWWN - the port WWN for the HBA port we will be issuing the SCSI
2187836SJohn.Forte@Sun.COM * ReportLUNS through
2197836SJohn.Forte@Sun.COM * remotePortWWN - the port WWN we will be issuing the report lun call to
2207836SJohn.Forte@Sun.COM * discPort - PORTATTRIBUTES structure for the remotePortWWN
2217836SJohn.Forte@Sun.COM */
2227836SJohn.Forte@Sun.COM static void
handleRemotePort(HBA_HANDLE handle,HBA_WWN portWWN,HBA_WWN remotePortWWN,HBA_PORTATTRIBUTES * discPort)2237836SJohn.Forte@Sun.COM handleRemotePort(HBA_HANDLE handle, HBA_WWN portWWN, HBA_WWN remotePortWWN,
2247836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES *discPort)
2257836SJohn.Forte@Sun.COM {
2267836SJohn.Forte@Sun.COM HBA_STATUS status;
2277836SJohn.Forte@Sun.COM int scsiTargetType;
2287836SJohn.Forte@Sun.COM uchar_t raw_luns[LUN_LENGTH];
2297836SJohn.Forte@Sun.COM HBA_UINT32 responseSize = LUN_LENGTH;
2307836SJohn.Forte@Sun.COM struct scsi_extended_sense sense;
2317836SJohn.Forte@Sun.COM HBA_UINT32 senseSize = sizeof (struct scsi_extended_sense);
2327836SJohn.Forte@Sun.COM HBA_UINT8 rep_luns_status;
2337836SJohn.Forte@Sun.COM
2347836SJohn.Forte@Sun.COM /* argument checking */
2357836SJohn.Forte@Sun.COM if (discPort == NULL) {
2367836SJohn.Forte@Sun.COM return;
2377836SJohn.Forte@Sun.COM }
2387836SJohn.Forte@Sun.COM
2397836SJohn.Forte@Sun.COM memset(raw_luns, 0, sizeof (raw_luns));
2407836SJohn.Forte@Sun.COM /* going to issue a report lun to check if this is a scsi-target */
2417836SJohn.Forte@Sun.COM status = HBA_ScsiReportLUNsV2(handle, portWWN, remotePortWWN,
2427836SJohn.Forte@Sun.COM (void *)raw_luns, &responseSize, &rep_luns_status,
2437836SJohn.Forte@Sun.COM (void *)&sense, &senseSize);
2447836SJohn.Forte@Sun.COM if (status == HBA_STATUS_OK) {
2457836SJohn.Forte@Sun.COM scsiTargetType = SCSI_TARGET_TYPE_YES;
2467836SJohn.Forte@Sun.COM } else if (status == HBA_STATUS_ERROR_NOT_A_TARGET) {
2477836SJohn.Forte@Sun.COM scsiTargetType = SCSI_TARGET_TYPE_NO;
2487836SJohn.Forte@Sun.COM } else {
2497836SJohn.Forte@Sun.COM scsiTargetType = SCSI_TARGET_TYPE_UNKNOWN;
2507836SJohn.Forte@Sun.COM }
2517836SJohn.Forte@Sun.COM printDiscoPortInfo(discPort, scsiTargetType);
2527836SJohn.Forte@Sun.COM }
2537836SJohn.Forte@Sun.COM
2547836SJohn.Forte@Sun.COM /*
2557836SJohn.Forte@Sun.COM * This function will issue the RLS and print out the port statistics for
2567836SJohn.Forte@Sun.COM * the given destWWN
2577836SJohn.Forte@Sun.COM *
2587836SJohn.Forte@Sun.COM * Arguments
2597836SJohn.Forte@Sun.COM * handle - a handle to a HBA that we will be processing
2607836SJohn.Forte@Sun.COM * hbaPortWWN - the hba port WWN through which the RLS will be sent
2617836SJohn.Forte@Sun.COM * destWWN - the remote port to which the RLS will be sent
2627836SJohn.Forte@Sun.COM */
2637836SJohn.Forte@Sun.COM static void
printLinkStat(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_WWN destWWN)2647836SJohn.Forte@Sun.COM printLinkStat(HBA_HANDLE handle, HBA_WWN hbaPortWWN, HBA_WWN destWWN)
2657836SJohn.Forte@Sun.COM {
2667836SJohn.Forte@Sun.COM HBA_STATUS status;
2677836SJohn.Forte@Sun.COM fc_rls_acc_t rls_payload;
2687836SJohn.Forte@Sun.COM uint32_t rls_payload_size;
2697836SJohn.Forte@Sun.COM
2707836SJohn.Forte@Sun.COM memset(&rls_payload, 0, sizeof (rls_payload));
2717836SJohn.Forte@Sun.COM rls_payload_size = sizeof (rls_payload);
2727836SJohn.Forte@Sun.COM status = HBA_SendRLS(handle, hbaPortWWN, destWWN,
2737836SJohn.Forte@Sun.COM &rls_payload, &rls_payload_size);
2747836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
2757836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Error: SendRLS failed for %016llx\n"),
2767836SJohn.Forte@Sun.COM wwnConversion(destWWN.wwn));
2777836SJohn.Forte@Sun.COM } else {
2787836SJohn.Forte@Sun.COM printPortStat(&rls_payload);
2797836SJohn.Forte@Sun.COM }
2807836SJohn.Forte@Sun.COM }
2817836SJohn.Forte@Sun.COM
2827836SJohn.Forte@Sun.COM int
printHBANPIVPortInfo(HBA_HANDLE handle,int portindex)2837836SJohn.Forte@Sun.COM printHBANPIVPortInfo(HBA_HANDLE handle, int portindex)
2847836SJohn.Forte@Sun.COM {
2857836SJohn.Forte@Sun.COM HBA_PORTNPIVATTRIBUTES portattrs;
2867836SJohn.Forte@Sun.COM HBA_NPIVATTRIBUTES npivattrs;
2877836SJohn.Forte@Sun.COM HBA_STATUS status;
2887836SJohn.Forte@Sun.COM int index;
2897836SJohn.Forte@Sun.COM int times = 0;
2907836SJohn.Forte@Sun.COM
2917836SJohn.Forte@Sun.COM status = Sun_HBA_GetPortNPIVAttributes(handle, portindex, &portattrs);
2927836SJohn.Forte@Sun.COM while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
2937836SJohn.Forte@Sun.COM status == HBA_STATUS_ERROR_BUSY) {
2947836SJohn.Forte@Sun.COM (void) sleep(1);
2957836SJohn.Forte@Sun.COM status = Sun_HBA_GetPortNPIVAttributes(
2967836SJohn.Forte@Sun.COM handle, portindex, &portattrs);
2977836SJohn.Forte@Sun.COM if (times++ > HBA_MAX_RETRIES) {
2987836SJohn.Forte@Sun.COM break;
2997836SJohn.Forte@Sun.COM }
3007836SJohn.Forte@Sun.COM }
3017836SJohn.Forte@Sun.COM
3027836SJohn.Forte@Sun.COM if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
3037836SJohn.Forte@Sun.COM fprintf(stdout, gettext("\tNPIV Not Supported\n"));
3047836SJohn.Forte@Sun.COM return (0);
3057836SJohn.Forte@Sun.COM }
3067836SJohn.Forte@Sun.COM
3077836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
3087836SJohn.Forte@Sun.COM fprintf(stderr,
3097836SJohn.Forte@Sun.COM gettext("Error: Failed to get port (%d) "
3107836SJohn.Forte@Sun.COM "npiv attributes reason: "), portindex);
3117836SJohn.Forte@Sun.COM printStatus(status);
3127836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
3137836SJohn.Forte@Sun.COM return (1);
3147836SJohn.Forte@Sun.COM }
3157836SJohn.Forte@Sun.COM if (portattrs.MaxNumberOfNPIVPorts) {
3167836SJohn.Forte@Sun.COM fprintf(stdout, gettext("\tMax NPIV Ports: %d\n"),
3177836SJohn.Forte@Sun.COM portattrs.MaxNumberOfNPIVPorts);
3187836SJohn.Forte@Sun.COM } else {
3197836SJohn.Forte@Sun.COM fprintf(stdout, gettext("\tNPIV Not Supported\n"));
3207836SJohn.Forte@Sun.COM return (0);
3217836SJohn.Forte@Sun.COM }
3227836SJohn.Forte@Sun.COM fprintf(stdout, gettext("\tNPIV port list:\n"));
3237836SJohn.Forte@Sun.COM for (index = 0; index < portattrs.NumberOfNPIVPorts; index++) {
3247836SJohn.Forte@Sun.COM int times = 0;
3257836SJohn.Forte@Sun.COM status = Sun_HBA_GetNPIVPortInfo(handle,
3267836SJohn.Forte@Sun.COM portindex, index, &npivattrs);
3277836SJohn.Forte@Sun.COM while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
3287836SJohn.Forte@Sun.COM status == HBA_STATUS_ERROR_BUSY) {
3297836SJohn.Forte@Sun.COM (void) sleep(1);
3307836SJohn.Forte@Sun.COM status = Sun_HBA_GetNPIVPortInfo(handle,
3317836SJohn.Forte@Sun.COM portindex, index, &npivattrs);
3327836SJohn.Forte@Sun.COM if (times++ > HBA_MAX_RETRIES) {
3337836SJohn.Forte@Sun.COM break;
3347836SJohn.Forte@Sun.COM }
3357836SJohn.Forte@Sun.COM }
3367836SJohn.Forte@Sun.COM
3377836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
3387836SJohn.Forte@Sun.COM fprintf(stderr,
3397836SJohn.Forte@Sun.COM gettext("Error: Failed to get npiv port (%d) "
3407836SJohn.Forte@Sun.COM "attributes reason: "), index);
3417836SJohn.Forte@Sun.COM printStatus(status);
3427836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
3437836SJohn.Forte@Sun.COM return (1);
3447836SJohn.Forte@Sun.COM } else {
3457836SJohn.Forte@Sun.COM fprintf(stdout,
3467836SJohn.Forte@Sun.COM gettext("\t Virtual Port%d:\n"), index+1);
3477836SJohn.Forte@Sun.COM fprintf(stdout, gettext("\t\tNode WWN: %016llx\n"),
3487836SJohn.Forte@Sun.COM wwnConversion(npivattrs.NodeWWN.wwn));
3497836SJohn.Forte@Sun.COM fprintf(stdout, gettext("\t\tPort WWN: %016llx\n"),
3507836SJohn.Forte@Sun.COM wwnConversion(npivattrs.PortWWN.wwn));
3517836SJohn.Forte@Sun.COM }
3527836SJohn.Forte@Sun.COM }
3537836SJohn.Forte@Sun.COM return (0);
3547836SJohn.Forte@Sun.COM }
3557836SJohn.Forte@Sun.COM
3567836SJohn.Forte@Sun.COM /*
3577836SJohn.Forte@Sun.COM * This function will process hba port, remote port and scsi-target information
3587836SJohn.Forte@Sun.COM * for the given handle.
3597836SJohn.Forte@Sun.COM *
3607836SJohn.Forte@Sun.COM * Arguments:
3617836SJohn.Forte@Sun.COM * handle - a handle to a HBA that we will be processing
3627836SJohn.Forte@Sun.COM * resourceType - resourceType flag
3637836SJohn.Forte@Sun.COM * possible values include: HBA_PORT, REMOTE_PORT
3647836SJohn.Forte@Sun.COM * flags - represents options passed in by the user
3657836SJohn.Forte@Sun.COM *
3667836SJohn.Forte@Sun.COM * Return Value:
3677836SJohn.Forte@Sun.COM * 0 sucessfully processed handle
3687836SJohn.Forte@Sun.COM * 1 error has occured
3697836SJohn.Forte@Sun.COM */
3707836SJohn.Forte@Sun.COM static int
processHBA(HBA_HANDLE handle,HBA_ADAPTERATTRIBUTES attrs,int portIndex,HBA_PORTATTRIBUTES port,HBA_FCPTARGETMAPPINGV2 * map,int resourceType,int flags,int mode)3717836SJohn.Forte@Sun.COM processHBA(HBA_HANDLE handle, HBA_ADAPTERATTRIBUTES attrs, int portIndex,
3727836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES port, HBA_FCPTARGETMAPPINGV2 *map,
3737836SJohn.Forte@Sun.COM int resourceType, int flags, int mode)
3747836SJohn.Forte@Sun.COM {
3757836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES discPort;
3767836SJohn.Forte@Sun.COM HBA_STATUS status;
3777836SJohn.Forte@Sun.COM int discPortCount;
3787836SJohn.Forte@Sun.COM
3797836SJohn.Forte@Sun.COM if (resourceType == HBA_PORT) {
380*9087SZhong.Wang@Sun.COM if ((flags & PRINT_FCOE) == PRINT_FCOE &&
381*9087SZhong.Wang@Sun.COM attrs.VendorSpecificID != 0xFC0E) {
382*9087SZhong.Wang@Sun.COM return (0);
383*9087SZhong.Wang@Sun.COM }
3847836SJohn.Forte@Sun.COM printHBAPortInfo(&port, &attrs, mode);
3857836SJohn.Forte@Sun.COM if ((flags & PRINT_LINKSTAT) == PRINT_LINKSTAT) {
3867836SJohn.Forte@Sun.COM printLinkStat(handle, port.PortWWN, port.PortWWN);
3877836SJohn.Forte@Sun.COM }
3887836SJohn.Forte@Sun.COM return (0);
3897836SJohn.Forte@Sun.COM }
3907836SJohn.Forte@Sun.COM /*
3917836SJohn.Forte@Sun.COM * process each of the remote targets from this hba port
3927836SJohn.Forte@Sun.COM */
3937836SJohn.Forte@Sun.COM for (discPortCount = 0;
3947836SJohn.Forte@Sun.COM discPortCount < port.NumberofDiscoveredPorts;
3957836SJohn.Forte@Sun.COM discPortCount++) {
3967836SJohn.Forte@Sun.COM status = HBA_GetDiscoveredPortAttributes(handle,
3977836SJohn.Forte@Sun.COM portIndex, discPortCount, &discPort);
3987836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
3997836SJohn.Forte@Sun.COM fprintf(stderr,
4007836SJohn.Forte@Sun.COM gettext("Failed to get discovered port (%d)"
4017836SJohn.Forte@Sun.COM " attributes reason :"), discPortCount);
4027836SJohn.Forte@Sun.COM printStatus(status);
4037836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
4047836SJohn.Forte@Sun.COM continue;
4057836SJohn.Forte@Sun.COM }
4067836SJohn.Forte@Sun.COM if (resourceType == REMOTE_PORT) {
4077836SJohn.Forte@Sun.COM handleRemotePort(handle, port.PortWWN, discPort.PortWWN,
4087836SJohn.Forte@Sun.COM &discPort);
4097836SJohn.Forte@Sun.COM if ((flags & PRINT_LINKSTAT) == PRINT_LINKSTAT) {
4107836SJohn.Forte@Sun.COM printLinkStat(handle, port.PortWWN,
4117836SJohn.Forte@Sun.COM discPort.PortWWN);
4127836SJohn.Forte@Sun.COM }
4137836SJohn.Forte@Sun.COM if ((flags & PRINT_SCSI_TARGET) == PRINT_SCSI_TARGET) {
4147836SJohn.Forte@Sun.COM handleScsiTarget(handle, port.PortWWN,
4157836SJohn.Forte@Sun.COM discPort.PortWWN, map);
4167836SJohn.Forte@Sun.COM }
4177836SJohn.Forte@Sun.COM }
4187836SJohn.Forte@Sun.COM }
4197836SJohn.Forte@Sun.COM return (0);
4207836SJohn.Forte@Sun.COM }
4217836SJohn.Forte@Sun.COM
4227836SJohn.Forte@Sun.COM /*
4237836SJohn.Forte@Sun.COM * This function will process remote port information for the given handle.
4247836SJohn.Forte@Sun.COM *
4257836SJohn.Forte@Sun.COM * Arguments:
4267836SJohn.Forte@Sun.COM * handle - a handle to a HBA that we will be processing
4277836SJohn.Forte@Sun.COM * portWWN - the port WWN for the HBA port we will be issuing the SCSI
4287836SJohn.Forte@Sun.COM * ReportLUNS through
4297836SJohn.Forte@Sun.COM * wwnCount - the number of wwns in wwn_argv
4307836SJohn.Forte@Sun.COM * wwn_argv - argument vector of WWNs
4317836SJohn.Forte@Sun.COM */
4327836SJohn.Forte@Sun.COM static void
processRemotePort(HBA_HANDLE handle,HBA_WWN portWWN,HBA_FCPTARGETMAPPINGV2 * map,int wwnCount,char ** wwn_argv,int flags)4337836SJohn.Forte@Sun.COM processRemotePort(HBA_HANDLE handle, HBA_WWN portWWN,
4347836SJohn.Forte@Sun.COM HBA_FCPTARGETMAPPINGV2 *map, int wwnCount, char **wwn_argv, int flags)
4357836SJohn.Forte@Sun.COM {
4367836SJohn.Forte@Sun.COM int remote_wwn_counter;
4377836SJohn.Forte@Sun.COM uint64_t remotePortWWN;
4387836SJohn.Forte@Sun.COM HBA_WWN myremotePortWWN;
4397836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES discPort;
4407836SJohn.Forte@Sun.COM HBA_STATUS status;
4417836SJohn.Forte@Sun.COM
4427836SJohn.Forte@Sun.COM for (remote_wwn_counter = 0;
4437836SJohn.Forte@Sun.COM remote_wwn_counter < wwnCount;
4447836SJohn.Forte@Sun.COM remote_wwn_counter++) {
4457836SJohn.Forte@Sun.COM int times = 0;
4467836SJohn.Forte@Sun.COM sscanf(wwn_argv[remote_wwn_counter], "%016llx",
4477836SJohn.Forte@Sun.COM &remotePortWWN);
4487836SJohn.Forte@Sun.COM remotePortWWN = htonll(remotePortWWN);
4497836SJohn.Forte@Sun.COM memcpy(myremotePortWWN.wwn, &remotePortWWN,
4507836SJohn.Forte@Sun.COM sizeof (remotePortWWN));
4517836SJohn.Forte@Sun.COM memset(&discPort, 0, sizeof (discPort));
4527836SJohn.Forte@Sun.COM status = HBA_GetPortAttributesByWWN(handle, myremotePortWWN,
4537836SJohn.Forte@Sun.COM &discPort);
4547836SJohn.Forte@Sun.COM while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
4557836SJohn.Forte@Sun.COM status == HBA_STATUS_ERROR_BUSY) {
4567836SJohn.Forte@Sun.COM (void) sleep(1);
4577836SJohn.Forte@Sun.COM status = HBA_GetPortAttributesByWWN(handle,
4587836SJohn.Forte@Sun.COM myremotePortWWN, &discPort);
4597836SJohn.Forte@Sun.COM if (times++ > HBA_MAX_RETRIES) {
4607836SJohn.Forte@Sun.COM break;
4617836SJohn.Forte@Sun.COM }
4627836SJohn.Forte@Sun.COM }
4637836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
4647836SJohn.Forte@Sun.COM fprintf(stderr, gettext("HBA_GetPortAttributesByWWN "
4657836SJohn.Forte@Sun.COM "failed: reason: "));
4667836SJohn.Forte@Sun.COM printStatus(status);
4677836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
4687836SJohn.Forte@Sun.COM continue;
4697836SJohn.Forte@Sun.COM }
4707836SJohn.Forte@Sun.COM handleRemotePort(handle, portWWN, myremotePortWWN, &discPort);
4717836SJohn.Forte@Sun.COM if ((flags & PRINT_LINKSTAT) == PRINT_LINKSTAT) {
4727836SJohn.Forte@Sun.COM printLinkStat(handle, portWWN, myremotePortWWN);
4737836SJohn.Forte@Sun.COM }
4747836SJohn.Forte@Sun.COM if ((flags & PRINT_SCSI_TARGET) == PRINT_SCSI_TARGET) {
4757836SJohn.Forte@Sun.COM handleScsiTarget(handle, portWWN,
4767836SJohn.Forte@Sun.COM myremotePortWWN, map);
4777836SJohn.Forte@Sun.COM }
4787836SJohn.Forte@Sun.COM }
4797836SJohn.Forte@Sun.COM }
4807836SJohn.Forte@Sun.COM
4817836SJohn.Forte@Sun.COM /*
4827836SJohn.Forte@Sun.COM * This function handles printing Scsi target information for remote ports
4837836SJohn.Forte@Sun.COM *
4847836SJohn.Forte@Sun.COM * Arguments:
4857836SJohn.Forte@Sun.COM * handle - a handle to a HBA that we will be processing
4867836SJohn.Forte@Sun.COM * hbaPortWWN - the port WWN for the HBA port through which the SCSI call
4877836SJohn.Forte@Sun.COM * is being sent
4887836SJohn.Forte@Sun.COM * scsiTargetWWN - target port WWN of the remote target the SCSI call is
4897836SJohn.Forte@Sun.COM * being sent to
4907836SJohn.Forte@Sun.COM * map - a pointer to the target mapping structure for the given HBA port
4917836SJohn.Forte@Sun.COM */
4927836SJohn.Forte@Sun.COM static void
handleScsiTarget(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_WWN scsiTargetWWN,HBA_FCPTARGETMAPPINGV2 * map)4937836SJohn.Forte@Sun.COM handleScsiTarget(HBA_HANDLE handle, HBA_WWN hbaPortWWN, HBA_WWN scsiTargetWWN,
4947836SJohn.Forte@Sun.COM HBA_FCPTARGETMAPPINGV2 *map)
4957836SJohn.Forte@Sun.COM {
4967836SJohn.Forte@Sun.COM HBA_STATUS status;
4977836SJohn.Forte@Sun.COM struct scsi_inquiry inq;
4987836SJohn.Forte@Sun.COM struct scsi_extended_sense sense;
4997836SJohn.Forte@Sun.COM HBA_UINT32 responseSize, senseSize = 0;
5007836SJohn.Forte@Sun.COM HBA_UINT8 inq_status;
5017836SJohn.Forte@Sun.COM uchar_t raw_luns[DEFAULT_LUN_LENGTH], *lun_string;
5027836SJohn.Forte@Sun.COM HBA_UINT8 rep_luns_status;
5037836SJohn.Forte@Sun.COM rep_luns_rsp_t *lun_resp;
5047836SJohn.Forte@Sun.COM uint64_t fcLUN;
5057836SJohn.Forte@Sun.COM int lunNum, numberOfLun, lunCount, count;
5067836SJohn.Forte@Sun.COM uint32_t lunlength, tmp_lunlength;
5077836SJohn.Forte@Sun.COM
5087836SJohn.Forte@Sun.COM responseSize = DEFAULT_LUN_LENGTH;
5097836SJohn.Forte@Sun.COM senseSize = sizeof (struct scsi_extended_sense);
5107836SJohn.Forte@Sun.COM memset(&sense, 0, sizeof (sense));
5117836SJohn.Forte@Sun.COM status = HBA_ScsiReportLUNsV2(handle, hbaPortWWN,
5127836SJohn.Forte@Sun.COM scsiTargetWWN, (void *)raw_luns, &responseSize,
5137836SJohn.Forte@Sun.COM &rep_luns_status, (void *)&sense, &senseSize);
5147836SJohn.Forte@Sun.COM /*
5157836SJohn.Forte@Sun.COM * if HBA_STATUS_ERROR_NOT_A_TARGET is return, we can assume this is
5167836SJohn.Forte@Sun.COM * a remote HBA and move on
5177836SJohn.Forte@Sun.COM */
5187836SJohn.Forte@Sun.COM if (status == HBA_STATUS_ERROR_NOT_A_TARGET) {
5197836SJohn.Forte@Sun.COM return;
5207836SJohn.Forte@Sun.COM } else if (status != HBA_STATUS_OK) {
5217836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Error has occured. "
5227836SJohn.Forte@Sun.COM "HBA_ScsiReportLUNsV2 failed. reason "));
5237836SJohn.Forte@Sun.COM printStatus(status);
5247836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
5257836SJohn.Forte@Sun.COM return;
5267836SJohn.Forte@Sun.COM }
5277836SJohn.Forte@Sun.COM lun_resp = (rep_luns_rsp_t *)raw_luns;
5287836SJohn.Forte@Sun.COM memcpy(&tmp_lunlength, &(lun_resp->length), sizeof (tmp_lunlength));
5297836SJohn.Forte@Sun.COM lunlength = htonl(tmp_lunlength);
5307836SJohn.Forte@Sun.COM memcpy(&numberOfLun, &lunlength, sizeof (numberOfLun));
5317836SJohn.Forte@Sun.COM for (lunCount = 0; lunCount < (numberOfLun / 8); lunCount++) {
5327836SJohn.Forte@Sun.COM /*
5337836SJohn.Forte@Sun.COM * now issue standard inquiry to get Vendor
5347836SJohn.Forte@Sun.COM * and product information
5357836SJohn.Forte@Sun.COM */
5367836SJohn.Forte@Sun.COM responseSize = sizeof (struct scsi_inquiry);
5377836SJohn.Forte@Sun.COM senseSize = sizeof (struct scsi_extended_sense);
5387836SJohn.Forte@Sun.COM memset(&inq, 0, sizeof (struct scsi_inquiry));
5397836SJohn.Forte@Sun.COM memset(&sense, 0, sizeof (sense));
5407836SJohn.Forte@Sun.COM fcLUN = ntohll(wwnConversion(lun_resp->lun[lunCount].val));
5417836SJohn.Forte@Sun.COM status = HBA_ScsiInquiryV2(
5427836SJohn.Forte@Sun.COM handle,
5437836SJohn.Forte@Sun.COM hbaPortWWN,
5447836SJohn.Forte@Sun.COM scsiTargetWWN,
5457836SJohn.Forte@Sun.COM fcLUN,
5467836SJohn.Forte@Sun.COM 0, /* EVPD */
5477836SJohn.Forte@Sun.COM 0,
5487836SJohn.Forte@Sun.COM &inq, &responseSize,
5497836SJohn.Forte@Sun.COM &inq_status,
5507836SJohn.Forte@Sun.COM &sense, &senseSize);
5517836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
5527836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Not able to issue Inquiry.\n"));
5537836SJohn.Forte@Sun.COM printStatus(status);
5547836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
5557836SJohn.Forte@Sun.COM strcpy(inq.inq_vid, "Unknown");
5567836SJohn.Forte@Sun.COM strcpy(inq.inq_pid, "Unknown");
5577836SJohn.Forte@Sun.COM }
5587836SJohn.Forte@Sun.COM if (map != NULL) {
5597836SJohn.Forte@Sun.COM for (count = 0; count < map->NumberOfEntries; count++) {
5607836SJohn.Forte@Sun.COM if ((memcmp(map->entry[count].FcpId.PortWWN.wwn,
5617836SJohn.Forte@Sun.COM scsiTargetWWN.wwn,
5627836SJohn.Forte@Sun.COM sizeof (scsiTargetWWN.wwn))
5637836SJohn.Forte@Sun.COM == 0) &&
5647836SJohn.Forte@Sun.COM (memcmp(&(map->entry[count].FcpId.FcpLun),
5657836SJohn.Forte@Sun.COM &fcLUN, sizeof (fcLUN)) == 0)) {
5667836SJohn.Forte@Sun.COM printLUNInfo(&inq,
5677836SJohn.Forte@Sun.COM map->entry[count].ScsiId.ScsiOSLun,
5687836SJohn.Forte@Sun.COM map->entry[count].ScsiId.OSDeviceName);
5697836SJohn.Forte@Sun.COM break;
5707836SJohn.Forte@Sun.COM }
5717836SJohn.Forte@Sun.COM }
5727836SJohn.Forte@Sun.COM if (count == map->NumberOfEntries) {
5737836SJohn.Forte@Sun.COM lun_string = lun_resp->lun[lunCount].val;
5747836SJohn.Forte@Sun.COM lunNum = ((lun_string[0] & 0x3F) << 8) |
5757836SJohn.Forte@Sun.COM lun_string[1];
5767836SJohn.Forte@Sun.COM printLUNInfo(&inq, lunNum, "Unknown");
5777836SJohn.Forte@Sun.COM }
5787836SJohn.Forte@Sun.COM } else {
5797836SJohn.Forte@Sun.COM /* Not able to get any target mapping information */
5807836SJohn.Forte@Sun.COM lun_string = lun_resp->lun[lunCount].val;
5817836SJohn.Forte@Sun.COM lunNum = ((lun_string[0] & 0x3F) << 8) |
5827836SJohn.Forte@Sun.COM lun_string[1];
5837836SJohn.Forte@Sun.COM printLUNInfo(&inq, lunNum, "Unknown");
5847836SJohn.Forte@Sun.COM }
5857836SJohn.Forte@Sun.COM }
5867836SJohn.Forte@Sun.COM }
5877836SJohn.Forte@Sun.COM
5887836SJohn.Forte@Sun.COM /*
5897836SJohn.Forte@Sun.COM * function to handle the list remoteport command
5907836SJohn.Forte@Sun.COM *
5917836SJohn.Forte@Sun.COM * Arguments:
5927836SJohn.Forte@Sun.COM * wwnCount - the number of wwns in wwn_argv
5937836SJohn.Forte@Sun.COM * if wwnCount == 0, then print information on all
5947836SJohn.Forte@Sun.COM * remote ports. wwn_argv will not be used in this case
5957836SJohn.Forte@Sun.COM * if wwnCount > 0, then print information for the WWNs
5967836SJohn.Forte@Sun.COM * given in wwn_argv
5977836SJohn.Forte@Sun.COM * wwn_argv - argument vector of WWNs
5987836SJohn.Forte@Sun.COM * options - any options specified by the caller
5997836SJohn.Forte@Sun.COM *
6007836SJohn.Forte@Sun.COM * returns:
6017836SJohn.Forte@Sun.COM * 0 if successful
6027836SJohn.Forte@Sun.COM * 1 otherwise
6037836SJohn.Forte@Sun.COM */
6047836SJohn.Forte@Sun.COM int
fc_util_list_remoteport(int wwnCount,char ** wwn_argv,cmdOptions_t * options)6057836SJohn.Forte@Sun.COM fc_util_list_remoteport(int wwnCount, char **wwn_argv, cmdOptions_t *options)
6067836SJohn.Forte@Sun.COM {
6077836SJohn.Forte@Sun.COM HBA_STATUS status;
6087836SJohn.Forte@Sun.COM HBA_FCPTARGETMAPPINGV2 *map = NULL;
6097836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES port;
6107836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES attrs;
6117836SJohn.Forte@Sun.COM HBA_HANDLE handle;
6127836SJohn.Forte@Sun.COM uint64_t hbaPortWWN;
6137836SJohn.Forte@Sun.COM HBA_WWN myhbaPortWWN;
6147836SJohn.Forte@Sun.COM int processHBA_flags = 0, portCount = 0;
6157836SJohn.Forte@Sun.COM int mode;
6167836SJohn.Forte@Sun.COM
6177836SJohn.Forte@Sun.COM /* grab the hba port wwn from the -p option */
6187836SJohn.Forte@Sun.COM for (; options->optval; options++) {
6197836SJohn.Forte@Sun.COM if (options->optval == 'p') {
6207836SJohn.Forte@Sun.COM sscanf(options->optarg, "%016llx",
6217836SJohn.Forte@Sun.COM &hbaPortWWN);
6227836SJohn.Forte@Sun.COM } else if (options->optval == 's') {
6237836SJohn.Forte@Sun.COM processHBA_flags |= PRINT_SCSI_TARGET;
6247836SJohn.Forte@Sun.COM } else if (options->optval == 'l') {
6257836SJohn.Forte@Sun.COM processHBA_flags |= PRINT_LINKSTAT;
6267836SJohn.Forte@Sun.COM } else {
6277836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Error: Illegal option: %c.\n"),
6287836SJohn.Forte@Sun.COM options->optval);
6297836SJohn.Forte@Sun.COM return (1);
6307836SJohn.Forte@Sun.COM }
6317836SJohn.Forte@Sun.COM }
6327836SJohn.Forte@Sun.COM /*
6337836SJohn.Forte@Sun.COM * -h option was not specified, this should not happen either.
6347836SJohn.Forte@Sun.COM * cmdparse should catch this problem, but checking anyways
6357836SJohn.Forte@Sun.COM */
6367836SJohn.Forte@Sun.COM if (hbaPortWWN == 0) {
6377836SJohn.Forte@Sun.COM fprintf(stderr,
6387836SJohn.Forte@Sun.COM gettext("Error: -p option was not specified.\n"));
6397836SJohn.Forte@Sun.COM return (1);
6407836SJohn.Forte@Sun.COM }
6417836SJohn.Forte@Sun.COM if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
6427836SJohn.Forte@Sun.COM fprintf(stderr,
6437836SJohn.Forte@Sun.COM gettext("Failed to load FC-HBA common library\n"));
6447836SJohn.Forte@Sun.COM printStatus(status);
6457836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
6467836SJohn.Forte@Sun.COM return (1);
6477836SJohn.Forte@Sun.COM }
6487836SJohn.Forte@Sun.COM hbaPortWWN = htonll(hbaPortWWN);
6497836SJohn.Forte@Sun.COM memcpy(myhbaPortWWN.wwn, &hbaPortWWN, sizeof (hbaPortWWN));
6507836SJohn.Forte@Sun.COM if ((status = HBA_OpenAdapterByWWN(&handle, myhbaPortWWN))
6517836SJohn.Forte@Sun.COM != HBA_STATUS_OK) {
6527836SJohn.Forte@Sun.COM status = Sun_HBA_OpenTgtAdapterByWWN(&handle, myhbaPortWWN);
6537836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
6547836SJohn.Forte@Sun.COM fprintf(stderr,
6557836SJohn.Forte@Sun.COM gettext("Error: Failed to open adapter port. Reason "));
6567836SJohn.Forte@Sun.COM printStatus(status);
6577836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
6587836SJohn.Forte@Sun.COM HBA_FreeLibrary();
6597836SJohn.Forte@Sun.COM return (1);
6607836SJohn.Forte@Sun.COM } else {
6617836SJohn.Forte@Sun.COM if ((processHBA_flags & PRINT_SCSI_TARGET) ==
6627836SJohn.Forte@Sun.COM PRINT_SCSI_TARGET) {
6637836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
6647836SJohn.Forte@Sun.COM "Error: Unsupported option for target mode: %c.\n"),
6657836SJohn.Forte@Sun.COM 's');
6667836SJohn.Forte@Sun.COM HBA_FreeLibrary();
6677836SJohn.Forte@Sun.COM return (1);
6687836SJohn.Forte@Sun.COM }
6697836SJohn.Forte@Sun.COM mode = TARGET_MODE;
6707836SJohn.Forte@Sun.COM }
6717836SJohn.Forte@Sun.COM } else {
6727836SJohn.Forte@Sun.COM mode = INITIATOR_MODE;
6737836SJohn.Forte@Sun.COM }
6747836SJohn.Forte@Sun.COM
6757836SJohn.Forte@Sun.COM if ((processHBA_flags & PRINT_SCSI_TARGET) == PRINT_SCSI_TARGET) {
6767836SJohn.Forte@Sun.COM getTargetMapping(handle, myhbaPortWWN, &map);
6777836SJohn.Forte@Sun.COM }
6787836SJohn.Forte@Sun.COM if (wwnCount == 0) {
6797836SJohn.Forte@Sun.COM /* get adapater attributes for the given handle */
6807836SJohn.Forte@Sun.COM memset(&attrs, 0, sizeof (attrs));
6817836SJohn.Forte@Sun.COM memset(&port, 0, sizeof (port));
6827836SJohn.Forte@Sun.COM if (retrieveAttrs(handle, myhbaPortWWN, &attrs, &port,
6837836SJohn.Forte@Sun.COM &portCount) != 0) {
6847836SJohn.Forte@Sun.COM if (map != NULL) {
6857836SJohn.Forte@Sun.COM free(map);
6867836SJohn.Forte@Sun.COM }
6877836SJohn.Forte@Sun.COM HBA_CloseAdapter(handle);
6887836SJohn.Forte@Sun.COM HBA_FreeLibrary();
6897836SJohn.Forte@Sun.COM return (1);
6907836SJohn.Forte@Sun.COM }
6917836SJohn.Forte@Sun.COM processHBA(handle, attrs, portCount, port, map, REMOTE_PORT,
6927836SJohn.Forte@Sun.COM processHBA_flags, mode);
6937836SJohn.Forte@Sun.COM } else {
6947836SJohn.Forte@Sun.COM processRemotePort(handle, myhbaPortWWN, map, wwnCount,
6957836SJohn.Forte@Sun.COM wwn_argv, processHBA_flags);
6967836SJohn.Forte@Sun.COM }
6977836SJohn.Forte@Sun.COM if (map != NULL) {
6987836SJohn.Forte@Sun.COM free(map);
6997836SJohn.Forte@Sun.COM }
7007836SJohn.Forte@Sun.COM HBA_CloseAdapter(handle);
7017836SJohn.Forte@Sun.COM HBA_FreeLibrary();
7027836SJohn.Forte@Sun.COM return (0);
7037836SJohn.Forte@Sun.COM }
7047836SJohn.Forte@Sun.COM
7057836SJohn.Forte@Sun.COM /*
7067836SJohn.Forte@Sun.COM * process the hbaport object
7077836SJohn.Forte@Sun.COM *
7087836SJohn.Forte@Sun.COM * Arguments:
7097836SJohn.Forte@Sun.COM * wwnCount - count of the number of WWNs in wwn_argv
7107836SJohn.Forte@Sun.COM * if wwnCount > 0, then we will only print information for
7117836SJohn.Forte@Sun.COM * the hba ports listed in wwn_argv
7127836SJohn.Forte@Sun.COM * if wwnCount == 0, then we will print information on all hba ports
7137836SJohn.Forte@Sun.COM * wwn_argv - argument array of hba port WWNs
7147836SJohn.Forte@Sun.COM * options - any options specified by the caller
7157836SJohn.Forte@Sun.COM *
7167836SJohn.Forte@Sun.COM * returns:
7177836SJohn.Forte@Sun.COM * 0 if successful
7187836SJohn.Forte@Sun.COM * 1 otherwise
7197836SJohn.Forte@Sun.COM */
7207836SJohn.Forte@Sun.COM int
fc_util_list_hbaport(int wwnCount,char ** wwn_argv,cmdOptions_t * options)7217836SJohn.Forte@Sun.COM fc_util_list_hbaport(int wwnCount, char **wwn_argv, cmdOptions_t *options)
7227836SJohn.Forte@Sun.COM {
7237836SJohn.Forte@Sun.COM int port_wwn_counter, numAdapters = 0, numTgtAdapters = 0, i;
7247836SJohn.Forte@Sun.COM HBA_STATUS status;
7257836SJohn.Forte@Sun.COM char adapterName[256];
7267836SJohn.Forte@Sun.COM HBA_HANDLE handle;
7277836SJohn.Forte@Sun.COM uint64_t hbaWWN;
7287836SJohn.Forte@Sun.COM HBA_WWN myWWN;
7297836SJohn.Forte@Sun.COM int processHBA_flags = 0;
7307836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES port;
7317836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES attrs;
7327836SJohn.Forte@Sun.COM int portIndex = 0, err_cnt = 0;
7337836SJohn.Forte@Sun.COM int mode;
7347836SJohn.Forte@Sun.COM
7357836SJohn.Forte@Sun.COM /* process each of the options */
7367836SJohn.Forte@Sun.COM for (; options->optval; options++) {
7377836SJohn.Forte@Sun.COM if (options->optval == 'l') {
7387836SJohn.Forte@Sun.COM processHBA_flags |= PRINT_LINKSTAT;
7397836SJohn.Forte@Sun.COM } else if (options->optval == 'i') {
7407836SJohn.Forte@Sun.COM processHBA_flags |= PRINT_INITIATOR;
7417836SJohn.Forte@Sun.COM } else if (options->optval == 't') {
7427836SJohn.Forte@Sun.COM processHBA_flags |= PRINT_TARGET;
743*9087SZhong.Wang@Sun.COM } else if (options->optval == 'e') {
744*9087SZhong.Wang@Sun.COM processHBA_flags |= PRINT_FCOE;
7457836SJohn.Forte@Sun.COM }
7467836SJohn.Forte@Sun.COM }
7477836SJohn.Forte@Sun.COM
7487836SJohn.Forte@Sun.COM /*
7497836SJohn.Forte@Sun.COM * Print both initiator and target if no initiator/target flag
7507836SJohn.Forte@Sun.COM * specified.
7517836SJohn.Forte@Sun.COM */
7527836SJohn.Forte@Sun.COM if (((processHBA_flags & PRINT_INITIATOR) == 0) &&
7537836SJohn.Forte@Sun.COM ((processHBA_flags & PRINT_TARGET) == 0)) {
7547836SJohn.Forte@Sun.COM processHBA_flags |= PRINT_INITIATOR | PRINT_TARGET;
7557836SJohn.Forte@Sun.COM }
7567836SJohn.Forte@Sun.COM
7577836SJohn.Forte@Sun.COM if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
7587836SJohn.Forte@Sun.COM fprintf(stderr,
7597836SJohn.Forte@Sun.COM gettext("Failed to load FC-HBA common library\n"));
7607836SJohn.Forte@Sun.COM printStatus(status);
7617836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
7627836SJohn.Forte@Sun.COM return (1);
7637836SJohn.Forte@Sun.COM }
7647836SJohn.Forte@Sun.COM if (wwnCount > 0) {
7657836SJohn.Forte@Sun.COM /* list only ports given in wwn_argv */
7667836SJohn.Forte@Sun.COM for (port_wwn_counter = 0;
7677836SJohn.Forte@Sun.COM port_wwn_counter < wwnCount;
7687836SJohn.Forte@Sun.COM port_wwn_counter++) {
7697836SJohn.Forte@Sun.COM sscanf(wwn_argv[port_wwn_counter], "%016llx", &hbaWWN);
7707836SJohn.Forte@Sun.COM hbaWWN = htonll(hbaWWN);
7717836SJohn.Forte@Sun.COM memcpy(myWWN.wwn, &hbaWWN, sizeof (hbaWWN));
7727836SJohn.Forte@Sun.COM /* first check to see if it is an initiator port. */
7737836SJohn.Forte@Sun.COM if ((processHBA_flags & PRINT_INITIATOR) ==
7747836SJohn.Forte@Sun.COM PRINT_INITIATOR) {
7757836SJohn.Forte@Sun.COM int times = 0;
7767836SJohn.Forte@Sun.COM status = HBA_OpenAdapterByWWN(&handle, myWWN);
7777836SJohn.Forte@Sun.COM while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
7787836SJohn.Forte@Sun.COM status == HBA_STATUS_ERROR_BUSY) {
7797836SJohn.Forte@Sun.COM (void) sleep(1);
7807836SJohn.Forte@Sun.COM status = HBA_OpenAdapterByWWN(&handle, myWWN);
7817836SJohn.Forte@Sun.COM if (times++ > HBA_MAX_RETRIES) {
7827836SJohn.Forte@Sun.COM break;
7837836SJohn.Forte@Sun.COM }
7847836SJohn.Forte@Sun.COM }
7857836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
7867836SJohn.Forte@Sun.COM /* now see if it is a target mode FC port */
7877836SJohn.Forte@Sun.COM if ((processHBA_flags & PRINT_TARGET) ==
7887836SJohn.Forte@Sun.COM PRINT_TARGET) {
7897836SJohn.Forte@Sun.COM status =
7907836SJohn.Forte@Sun.COM Sun_HBA_OpenTgtAdapterByWWN(&handle, myWWN);
7917836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
7927836SJohn.Forte@Sun.COM fprintf(stderr,
7937836SJohn.Forte@Sun.COM gettext(
7947836SJohn.Forte@Sun.COM "Error: HBA port %s: not found\n"),
7957836SJohn.Forte@Sun.COM wwn_argv[port_wwn_counter]);
7967836SJohn.Forte@Sun.COM err_cnt++;
7977836SJohn.Forte@Sun.COM continue;
7987836SJohn.Forte@Sun.COM } else {
7997836SJohn.Forte@Sun.COM /* set the port mode. */
8007836SJohn.Forte@Sun.COM mode = TARGET_MODE;
8017836SJohn.Forte@Sun.COM }
8027836SJohn.Forte@Sun.COM } else {
8037836SJohn.Forte@Sun.COM fprintf(stderr,
8047836SJohn.Forte@Sun.COM gettext(
8057836SJohn.Forte@Sun.COM "Error: HBA port %s: not found\n"),
8067836SJohn.Forte@Sun.COM wwn_argv[port_wwn_counter]);
8077836SJohn.Forte@Sun.COM err_cnt++;
8087836SJohn.Forte@Sun.COM continue;
8097836SJohn.Forte@Sun.COM }
8107836SJohn.Forte@Sun.COM } else {
8117836SJohn.Forte@Sun.COM /* set the port mode. */
8127836SJohn.Forte@Sun.COM mode = INITIATOR_MODE;
8137836SJohn.Forte@Sun.COM }
8147836SJohn.Forte@Sun.COM /* try target mode discovery if print target is set. */
8157836SJohn.Forte@Sun.COM } else if ((processHBA_flags & PRINT_TARGET) ==
8167836SJohn.Forte@Sun.COM PRINT_TARGET) {
8177836SJohn.Forte@Sun.COM status =
8187836SJohn.Forte@Sun.COM Sun_HBA_OpenTgtAdapterByWWN(&handle, myWWN);
8197836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
8207836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
8217836SJohn.Forte@Sun.COM "Error: HBA port %s: not found\n"),
8227836SJohn.Forte@Sun.COM wwn_argv[port_wwn_counter]);
8237836SJohn.Forte@Sun.COM err_cnt++;
8247836SJohn.Forte@Sun.COM continue;
8257836SJohn.Forte@Sun.COM } else {
8267836SJohn.Forte@Sun.COM /* set the port mode. */
8277836SJohn.Forte@Sun.COM mode = TARGET_MODE;
8287836SJohn.Forte@Sun.COM }
8297836SJohn.Forte@Sun.COM } else {
8307836SJohn.Forte@Sun.COM /* should not get here. */
8317836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
8327836SJohn.Forte@Sun.COM "Error: HBA port %s: not found\n"),
8337836SJohn.Forte@Sun.COM wwn_argv[port_wwn_counter]);
8347836SJohn.Forte@Sun.COM err_cnt++;
8357836SJohn.Forte@Sun.COM continue;
8367836SJohn.Forte@Sun.COM }
8377836SJohn.Forte@Sun.COM memset(&attrs, 0, sizeof (attrs));
8387836SJohn.Forte@Sun.COM memset(&port, 0, sizeof (port));
8397836SJohn.Forte@Sun.COM if (retrieveAttrs(handle, myWWN, &attrs, &port,
8407836SJohn.Forte@Sun.COM &portIndex) != 0) {
8417836SJohn.Forte@Sun.COM HBA_CloseAdapter(handle);
8427836SJohn.Forte@Sun.COM continue;
8437836SJohn.Forte@Sun.COM }
8447836SJohn.Forte@Sun.COM processHBA(handle, attrs, portIndex, port, NULL,
8457836SJohn.Forte@Sun.COM HBA_PORT, processHBA_flags, mode);
846*9087SZhong.Wang@Sun.COM if ((processHBA_flags & PRINT_FCOE) != PRINT_FCOE &&
847*9087SZhong.Wang@Sun.COM attrs.VendorSpecificID != 0xFC0E &&
848*9087SZhong.Wang@Sun.COM printHBANPIVPortInfo(handle, portIndex) != 0) {
8497836SJohn.Forte@Sun.COM err_cnt++;
8507836SJohn.Forte@Sun.COM }
8517836SJohn.Forte@Sun.COM HBA_CloseAdapter(handle);
8527836SJohn.Forte@Sun.COM }
8537836SJohn.Forte@Sun.COM } else {
8547836SJohn.Forte@Sun.COM /*
8557836SJohn.Forte@Sun.COM * if PRINT_INITIATOR is specified, get the list of initiator
8567836SJohn.Forte@Sun.COM * mod port.
8577836SJohn.Forte@Sun.COM */
8587836SJohn.Forte@Sun.COM if ((processHBA_flags & PRINT_INITIATOR) == PRINT_INITIATOR) {
8597836SJohn.Forte@Sun.COM numAdapters = HBA_GetNumberOfAdapters();
8607836SJohn.Forte@Sun.COM if ((numAdapters == 0) &&
8617836SJohn.Forte@Sun.COM ((processHBA_flags & ~PRINT_INITIATOR) == 0)) {
8627836SJohn.Forte@Sun.COM fprintf(stdout, gettext("No Adapters Found.\n"));
8637836SJohn.Forte@Sun.COM }
8647836SJohn.Forte@Sun.COM for (i = 0; i < numAdapters; i++) {
8657836SJohn.Forte@Sun.COM int times = 0;
8667836SJohn.Forte@Sun.COM status = HBA_GetAdapterName(i, adapterName);
8677836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
8687836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
8697836SJohn.Forte@Sun.COM "failed to get adapter %d. Reason: "), i);
8707836SJohn.Forte@Sun.COM printStatus(status);
8717836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
8727836SJohn.Forte@Sun.COM continue;
8737836SJohn.Forte@Sun.COM }
8747836SJohn.Forte@Sun.COM if ((handle = HBA_OpenAdapter(adapterName)) == 0) {
8757836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
8767836SJohn.Forte@Sun.COM "Failed to open adapter %s.\n"),
8777836SJohn.Forte@Sun.COM adapterName);
8787836SJohn.Forte@Sun.COM continue;
8797836SJohn.Forte@Sun.COM }
8807836SJohn.Forte@Sun.COM /* get adapater attributes for the given handle */
8817836SJohn.Forte@Sun.COM memset(&attrs, 0, sizeof (attrs));
8827836SJohn.Forte@Sun.COM status =
8837836SJohn.Forte@Sun.COM Sun_HBA_NPIVGetAdapterAttributes(handle,
8847836SJohn.Forte@Sun.COM &attrs);
8857836SJohn.Forte@Sun.COM while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
8867836SJohn.Forte@Sun.COM status == HBA_STATUS_ERROR_BUSY) &&
8877836SJohn.Forte@Sun.COM times++ < HBA_MAX_RETRIES) {
8887836SJohn.Forte@Sun.COM (void) sleep(1);
8897836SJohn.Forte@Sun.COM status =
8907836SJohn.Forte@Sun.COM Sun_HBA_NPIVGetAdapterAttributes(handle,
8917836SJohn.Forte@Sun.COM &attrs);
8927836SJohn.Forte@Sun.COM if (status == HBA_STATUS_OK) {
8937836SJohn.Forte@Sun.COM break;
8947836SJohn.Forte@Sun.COM }
8957836SJohn.Forte@Sun.COM }
8967836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
8977836SJohn.Forte@Sun.COM fprintf(stderr,
8987836SJohn.Forte@Sun.COM gettext("Failed to get adapter attributes "
8997836SJohn.Forte@Sun.COM "handle(%d) Reason: "), handle);
9007836SJohn.Forte@Sun.COM printStatus(status);
9017836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
9028507SRaghuram.Prahlada@Sun.COM HBA_CloseAdapter(handle);
9037836SJohn.Forte@Sun.COM continue;
9047836SJohn.Forte@Sun.COM }
9057836SJohn.Forte@Sun.COM
9067836SJohn.Forte@Sun.COM /* process each port on the given adatpter */
9077836SJohn.Forte@Sun.COM for (portIndex = 0;
9087836SJohn.Forte@Sun.COM portIndex < attrs.NumberOfPorts;
9097836SJohn.Forte@Sun.COM portIndex++) {
9107836SJohn.Forte@Sun.COM memset(&port, 0, sizeof (port));
9117836SJohn.Forte@Sun.COM if ((status = HBA_GetAdapterPortAttributes(
9127836SJohn.Forte@Sun.COM handle, portIndex, &port))
9137836SJohn.Forte@Sun.COM != HBA_STATUS_OK) {
9147836SJohn.Forte@Sun.COM /*
9157836SJohn.Forte@Sun.COM * not able to get port attributes.
9167836SJohn.Forte@Sun.COM * print out error * message and move
9177836SJohn.Forte@Sun.COM * on to the next port
9187836SJohn.Forte@Sun.COM */
9197836SJohn.Forte@Sun.COM fprintf(stderr,
9207836SJohn.Forte@Sun.COM gettext("Error: Failed to get port "
9217836SJohn.Forte@Sun.COM "(%d) attributes reason: "),
9227836SJohn.Forte@Sun.COM portIndex);
9237836SJohn.Forte@Sun.COM printStatus(status);
9247836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
9257836SJohn.Forte@Sun.COM continue;
9267836SJohn.Forte@Sun.COM }
9277836SJohn.Forte@Sun.COM processHBA(handle, attrs, portIndex, port,
9287836SJohn.Forte@Sun.COM NULL, HBA_PORT, processHBA_flags,
9297836SJohn.Forte@Sun.COM INITIATOR_MODE);
930*9087SZhong.Wang@Sun.COM if ((processHBA_flags & PRINT_FCOE) !=
931*9087SZhong.Wang@Sun.COM PRINT_FCOE &&
932*9087SZhong.Wang@Sun.COM attrs.VendorSpecificID != 0xFC0E &&
933*9087SZhong.Wang@Sun.COM printHBANPIVPortInfo(handle,
934*9087SZhong.Wang@Sun.COM portIndex) != 0) {
9357836SJohn.Forte@Sun.COM err_cnt++;
9367836SJohn.Forte@Sun.COM }
9377836SJohn.Forte@Sun.COM }
9387836SJohn.Forte@Sun.COM HBA_CloseAdapter(handle);
9397836SJohn.Forte@Sun.COM }
9407836SJohn.Forte@Sun.COM }
9417836SJohn.Forte@Sun.COM
9427836SJohn.Forte@Sun.COM /*
9437836SJohn.Forte@Sun.COM * Get the info on the target mode FC port if PRINT_TARGET
9447836SJohn.Forte@Sun.COM * is specified.
9457836SJohn.Forte@Sun.COM */
9467836SJohn.Forte@Sun.COM if ((processHBA_flags & PRINT_TARGET) == PRINT_TARGET) {
9477836SJohn.Forte@Sun.COM numTgtAdapters = Sun_HBA_GetNumberOfTgtAdapters();
9487836SJohn.Forte@Sun.COM if (numTgtAdapters == 0 && numAdapters == 0) {
9497836SJohn.Forte@Sun.COM fprintf(stdout,
9507836SJohn.Forte@Sun.COM gettext("No Adapters Found.\n"));
9517836SJohn.Forte@Sun.COM }
9527836SJohn.Forte@Sun.COM for (i = 0; i < numTgtAdapters; i++) {
9537836SJohn.Forte@Sun.COM status = Sun_HBA_GetTgtAdapterName(i, adapterName);
9547836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
9557836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
9567836SJohn.Forte@Sun.COM "failed to get adapter %d. Reason: "), i);
9577836SJohn.Forte@Sun.COM printStatus(status);
9587836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
9597836SJohn.Forte@Sun.COM continue;
9607836SJohn.Forte@Sun.COM }
9617836SJohn.Forte@Sun.COM if ((handle = Sun_HBA_OpenTgtAdapter(adapterName))
9627836SJohn.Forte@Sun.COM == 0) {
9637836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
9647836SJohn.Forte@Sun.COM "Failed to open adapter %s.\n"), adapterName);
9657836SJohn.Forte@Sun.COM continue;
9667836SJohn.Forte@Sun.COM }
9677836SJohn.Forte@Sun.COM /* get adapater attributes for the given handle */
9687836SJohn.Forte@Sun.COM memset(&attrs, 0, sizeof (attrs));
9697836SJohn.Forte@Sun.COM if ((status = HBA_GetAdapterAttributes(handle, &attrs))
9707836SJohn.Forte@Sun.COM != HBA_STATUS_OK) {
9717836SJohn.Forte@Sun.COM fprintf(stderr,
9727836SJohn.Forte@Sun.COM gettext("Failed to get target mode adapter"
9737836SJohn.Forte@Sun.COM "attributes handle(%d) Reason: "),
9747836SJohn.Forte@Sun.COM handle);
9757836SJohn.Forte@Sun.COM printStatus(status);
9767836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
9777836SJohn.Forte@Sun.COM continue;
9787836SJohn.Forte@Sun.COM }
9797836SJohn.Forte@Sun.COM
9807836SJohn.Forte@Sun.COM /* process each port on the given adatpter */
9817836SJohn.Forte@Sun.COM for (portIndex = 0;
9827836SJohn.Forte@Sun.COM portIndex < attrs.NumberOfPorts;
9837836SJohn.Forte@Sun.COM portIndex++) {
9847836SJohn.Forte@Sun.COM memset(&port, 0, sizeof (port));
9857836SJohn.Forte@Sun.COM if ((status = HBA_GetAdapterPortAttributes(
9867836SJohn.Forte@Sun.COM handle, portIndex, &port))
9877836SJohn.Forte@Sun.COM != HBA_STATUS_OK) {
9887836SJohn.Forte@Sun.COM /*
9897836SJohn.Forte@Sun.COM * not able to get port attributes.
9907836SJohn.Forte@Sun.COM * print out error * message and move
9917836SJohn.Forte@Sun.COM * on to the next port
9927836SJohn.Forte@Sun.COM */
9937836SJohn.Forte@Sun.COM fprintf(stderr,
9947836SJohn.Forte@Sun.COM gettext("Error: Failed to get port "
9957836SJohn.Forte@Sun.COM "(%d) attributes reason: "),
9967836SJohn.Forte@Sun.COM portIndex);
9977836SJohn.Forte@Sun.COM printStatus(status);
9987836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
9997836SJohn.Forte@Sun.COM continue;
10007836SJohn.Forte@Sun.COM }
10017836SJohn.Forte@Sun.COM processHBA(handle, attrs, portIndex, port,
10027836SJohn.Forte@Sun.COM NULL, HBA_PORT, processHBA_flags,
10037836SJohn.Forte@Sun.COM TARGET_MODE);
10047836SJohn.Forte@Sun.COM }
10057836SJohn.Forte@Sun.COM HBA_CloseAdapter(handle);
10067836SJohn.Forte@Sun.COM }
10077836SJohn.Forte@Sun.COM }
10087836SJohn.Forte@Sun.COM }
10097836SJohn.Forte@Sun.COM
10107836SJohn.Forte@Sun.COM HBA_FreeLibrary();
10117836SJohn.Forte@Sun.COM
10127836SJohn.Forte@Sun.COM /*
10137836SJohn.Forte@Sun.COM * print additional error msg for partial failure when more than
10147836SJohn.Forte@Sun.COM * one wwn is specified.
10157836SJohn.Forte@Sun.COM */
10167836SJohn.Forte@Sun.COM if (err_cnt != 0) {
10177836SJohn.Forte@Sun.COM if (wwnCount > 1) {
10187836SJohn.Forte@Sun.COM if (err_cnt == wwnCount) {
10197836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
10207836SJohn.Forte@Sun.COM "Error: All specified HBA ports are not found\n"));
10217836SJohn.Forte@Sun.COM } else {
10227836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
10237836SJohn.Forte@Sun.COM "Error: Some of specified HBA ports are not found\n"));
10247836SJohn.Forte@Sun.COM }
10257836SJohn.Forte@Sun.COM }
10267836SJohn.Forte@Sun.COM return (1);
10277836SJohn.Forte@Sun.COM }
10287836SJohn.Forte@Sun.COM
10297836SJohn.Forte@Sun.COM return (0);
10307836SJohn.Forte@Sun.COM }
10317836SJohn.Forte@Sun.COM
10327836SJohn.Forte@Sun.COM /*
10337836SJohn.Forte@Sun.COM * Search the existing device list
10347836SJohn.Forte@Sun.COM *
10357836SJohn.Forte@Sun.COM * Take one of two actions:
10367836SJohn.Forte@Sun.COM *
10377836SJohn.Forte@Sun.COM * Add an entry if an entry doesn't exist
10387836SJohn.Forte@Sun.COM * Add WWN data to it if an entry does exist
10397836SJohn.Forte@Sun.COM *
10407836SJohn.Forte@Sun.COM * Arguments:
10417836SJohn.Forte@Sun.COM * devList - OS device path list
10427836SJohn.Forte@Sun.COM * map - target mapping data
10437836SJohn.Forte@Sun.COM * index - index into target mapping data
10447836SJohn.Forte@Sun.COM * initiatorPortWWN - HBA port WWN
10457836SJohn.Forte@Sun.COM * verbose - boolean indicating whether to get additional data
10467836SJohn.Forte@Sun.COM *
10477836SJohn.Forte@Sun.COM * returns:
10487836SJohn.Forte@Sun.COM * none
10497836SJohn.Forte@Sun.COM */
10507836SJohn.Forte@Sun.COM static void
searchDevice(discoveredDevice ** devList,HBA_FCPSCSIENTRYV2 entry,HBA_WWN initiatorPortWWN,HBA_HANDLE handle,boolean_t verbose)10517836SJohn.Forte@Sun.COM searchDevice(discoveredDevice **devList, HBA_FCPSCSIENTRYV2 entry,
10527836SJohn.Forte@Sun.COM HBA_WWN initiatorPortWWN, HBA_HANDLE handle, boolean_t verbose)
10537836SJohn.Forte@Sun.COM {
10547836SJohn.Forte@Sun.COM discoveredDevice *discoveredDevList, *newDevice;
10557836SJohn.Forte@Sun.COM portWWNList *WWNList, *newWWN;
10567836SJohn.Forte@Sun.COM tgtPortWWNList *newTgtWWN;
10577836SJohn.Forte@Sun.COM boolean_t foundDevice = B_FALSE, foundWWN;
10587836SJohn.Forte@Sun.COM struct scsi_inquiry inq;
10597836SJohn.Forte@Sun.COM struct scsi_extended_sense sense;
10607836SJohn.Forte@Sun.COM HBA_UINT32 responseSize, senseSize = 0;
10617836SJohn.Forte@Sun.COM HBA_UINT8 inq_status;
10627836SJohn.Forte@Sun.COM HBA_STATUS status;
10637836SJohn.Forte@Sun.COM
10647836SJohn.Forte@Sun.COM for (discoveredDevList = *devList; discoveredDevList != NULL;
10657836SJohn.Forte@Sun.COM discoveredDevList = discoveredDevList->next) {
10667836SJohn.Forte@Sun.COM if (strcmp(entry.ScsiId.OSDeviceName,
10677836SJohn.Forte@Sun.COM discoveredDevList->OSDeviceName) == 0) {
10687836SJohn.Forte@Sun.COM /*
10697836SJohn.Forte@Sun.COM * if only device names are requested,
10707836SJohn.Forte@Sun.COM * no reason to go any further
10717836SJohn.Forte@Sun.COM */
10727836SJohn.Forte@Sun.COM if (verbose == B_FALSE) {
10737836SJohn.Forte@Sun.COM return;
10747836SJohn.Forte@Sun.COM }
10757836SJohn.Forte@Sun.COM foundDevice = B_TRUE;
10767836SJohn.Forte@Sun.COM break;
10777836SJohn.Forte@Sun.COM }
10787836SJohn.Forte@Sun.COM }
10797836SJohn.Forte@Sun.COM if (foundDevice == B_TRUE) {
10807836SJohn.Forte@Sun.COM /* add initiator Port WWN if it doesn't exist */
10817836SJohn.Forte@Sun.COM for (WWNList = discoveredDevList->HBAPortWWN,
10827836SJohn.Forte@Sun.COM foundWWN = B_FALSE; WWNList != NULL;
10837836SJohn.Forte@Sun.COM WWNList = WWNList->next) {
10847836SJohn.Forte@Sun.COM if (memcmp((void *)&(WWNList->portWWN),
10857836SJohn.Forte@Sun.COM (void *)&initiatorPortWWN,
10867836SJohn.Forte@Sun.COM sizeof (HBA_WWN)) == 0) {
10877836SJohn.Forte@Sun.COM foundWWN = B_TRUE;
10887836SJohn.Forte@Sun.COM break;
10897836SJohn.Forte@Sun.COM }
10907836SJohn.Forte@Sun.COM }
10917836SJohn.Forte@Sun.COM if (discoveredDevList->inqSuccess == B_FALSE) {
10927836SJohn.Forte@Sun.COM responseSize = sizeof (struct scsi_inquiry);
10937836SJohn.Forte@Sun.COM senseSize = sizeof (struct scsi_extended_sense);
10947836SJohn.Forte@Sun.COM memset(&inq, 0, sizeof (struct scsi_inquiry));
10957836SJohn.Forte@Sun.COM memset(&sense, 0, sizeof (sense));
10967836SJohn.Forte@Sun.COM status = HBA_ScsiInquiryV2(
10977836SJohn.Forte@Sun.COM handle,
10987836SJohn.Forte@Sun.COM initiatorPortWWN,
10997836SJohn.Forte@Sun.COM entry.FcpId.PortWWN,
11007836SJohn.Forte@Sun.COM entry.FcpId.FcpLun,
11017836SJohn.Forte@Sun.COM 0, /* CDB Byte 1 */
11027836SJohn.Forte@Sun.COM 0, /* CDB Byte 2 */
11037836SJohn.Forte@Sun.COM &inq, &responseSize,
11047836SJohn.Forte@Sun.COM &inq_status,
11057836SJohn.Forte@Sun.COM &sense, &senseSize);
11067836SJohn.Forte@Sun.COM if (status == HBA_STATUS_OK) {
11077836SJohn.Forte@Sun.COM memcpy(discoveredDevList->VID, inq.inq_vid,
11087836SJohn.Forte@Sun.COM sizeof (discoveredDevList->VID));
11097836SJohn.Forte@Sun.COM memcpy(discoveredDevList->PID, inq.inq_pid,
11107836SJohn.Forte@Sun.COM sizeof (discoveredDevList->PID));
11117836SJohn.Forte@Sun.COM discoveredDevList->dType = inq.inq_dtype;
11127836SJohn.Forte@Sun.COM discoveredDevList->inqSuccess = B_TRUE;
11137836SJohn.Forte@Sun.COM }
11147836SJohn.Forte@Sun.COM }
11157836SJohn.Forte@Sun.COM
11167836SJohn.Forte@Sun.COM if (foundWWN == B_FALSE) {
11177836SJohn.Forte@Sun.COM newWWN = (portWWNList *)calloc(1, sizeof (portWWNList));
11187836SJohn.Forte@Sun.COM if (newWWN == NULL) {
11197836SJohn.Forte@Sun.COM perror("Out of memory");
11207836SJohn.Forte@Sun.COM exit(1);
11217836SJohn.Forte@Sun.COM }
11227836SJohn.Forte@Sun.COM
11237836SJohn.Forte@Sun.COM /* insert at head */
11247836SJohn.Forte@Sun.COM newWWN->next = discoveredDevList->HBAPortWWN;
11257836SJohn.Forte@Sun.COM discoveredDevList->HBAPortWWN = newWWN;
11267836SJohn.Forte@Sun.COM memcpy((void *)&(newWWN->portWWN),
11277836SJohn.Forte@Sun.COM (void *)&initiatorPortWWN,
11287836SJohn.Forte@Sun.COM sizeof (newWWN->portWWN));
11297836SJohn.Forte@Sun.COM /* add Target Port */
11307836SJohn.Forte@Sun.COM newWWN->tgtPortWWN = (tgtPortWWNList *)calloc(1,
11317836SJohn.Forte@Sun.COM sizeof (tgtPortWWNList));
11327836SJohn.Forte@Sun.COM if (newWWN->tgtPortWWN == NULL) {
11337836SJohn.Forte@Sun.COM perror("Out of memory");
11347836SJohn.Forte@Sun.COM exit(1);
11357836SJohn.Forte@Sun.COM }
11367836SJohn.Forte@Sun.COM
11377836SJohn.Forte@Sun.COM memcpy((void *)&(newWWN->tgtPortWWN->portWWN),
11387836SJohn.Forte@Sun.COM (void *)&(entry.FcpId.PortWWN),
11397836SJohn.Forte@Sun.COM sizeof (newWWN->tgtPortWWN->portWWN));
11407836SJohn.Forte@Sun.COM /* Set LUN data */
11417836SJohn.Forte@Sun.COM newWWN->tgtPortWWN->scsiOSLun = entry.ScsiId.ScsiOSLun;
11427836SJohn.Forte@Sun.COM } else { /* add it to existing */
11437836SJohn.Forte@Sun.COM newTgtWWN = (tgtPortWWNList *)calloc(1,
11447836SJohn.Forte@Sun.COM sizeof (tgtPortWWNList));
11457836SJohn.Forte@Sun.COM if (newTgtWWN == NULL) {
11467836SJohn.Forte@Sun.COM perror("Out of memory");
11477836SJohn.Forte@Sun.COM exit(1);
11487836SJohn.Forte@Sun.COM }
11497836SJohn.Forte@Sun.COM /* insert at head */
11507836SJohn.Forte@Sun.COM newTgtWWN->next = WWNList->tgtPortWWN;
11517836SJohn.Forte@Sun.COM WWNList->tgtPortWWN = newTgtWWN;
11527836SJohn.Forte@Sun.COM memcpy((void *)&(newTgtWWN->portWWN),
11537836SJohn.Forte@Sun.COM (void *)&(entry.FcpId.PortWWN),
11547836SJohn.Forte@Sun.COM sizeof (newTgtWWN->portWWN));
11557836SJohn.Forte@Sun.COM /* Set LUN data */
11567836SJohn.Forte@Sun.COM newTgtWWN->scsiOSLun = entry.ScsiId.ScsiOSLun;
11577836SJohn.Forte@Sun.COM }
11587836SJohn.Forte@Sun.COM } else { /* add new entry */
11597836SJohn.Forte@Sun.COM newDevice = (discoveredDevice *)calloc(1,
11607836SJohn.Forte@Sun.COM sizeof (discoveredDevice));
11617836SJohn.Forte@Sun.COM if (newDevice == NULL) {
11627836SJohn.Forte@Sun.COM perror("Out of memory");
11637836SJohn.Forte@Sun.COM exit(1);
11647836SJohn.Forte@Sun.COM }
11657836SJohn.Forte@Sun.COM newDevice->next = *devList; /* insert at head */
11667836SJohn.Forte@Sun.COM *devList = newDevice; /* set new head */
11677836SJohn.Forte@Sun.COM
11687836SJohn.Forte@Sun.COM /* Copy device name */
11697836SJohn.Forte@Sun.COM strncpy(newDevice->OSDeviceName, entry.ScsiId.OSDeviceName,
11707836SJohn.Forte@Sun.COM sizeof (newDevice->OSDeviceName) - 1);
11717836SJohn.Forte@Sun.COM
11727836SJohn.Forte@Sun.COM /*
11737836SJohn.Forte@Sun.COM * if only device names are requested,
11747836SJohn.Forte@Sun.COM * no reason to go any further
11757836SJohn.Forte@Sun.COM */
11767836SJohn.Forte@Sun.COM if (verbose == B_FALSE) {
11777836SJohn.Forte@Sun.COM return;
11787836SJohn.Forte@Sun.COM }
11797836SJohn.Forte@Sun.COM
11807836SJohn.Forte@Sun.COM /*
11817836SJohn.Forte@Sun.COM * copy WWN data
11827836SJohn.Forte@Sun.COM */
11837836SJohn.Forte@Sun.COM newDevice->HBAPortWWN = (portWWNList *)calloc(1,
11847836SJohn.Forte@Sun.COM sizeof (portWWNList));
11857836SJohn.Forte@Sun.COM if (newDevice->HBAPortWWN == NULL) {
11867836SJohn.Forte@Sun.COM perror("Out of memory");
11877836SJohn.Forte@Sun.COM exit(1);
11887836SJohn.Forte@Sun.COM }
11897836SJohn.Forte@Sun.COM memcpy((void *)&(newDevice->HBAPortWWN->portWWN),
11907836SJohn.Forte@Sun.COM (void *)&initiatorPortWWN, sizeof (newWWN->portWWN));
11917836SJohn.Forte@Sun.COM
11927836SJohn.Forte@Sun.COM newDevice->HBAPortWWN->tgtPortWWN =
11937836SJohn.Forte@Sun.COM (tgtPortWWNList *)calloc(1, sizeof (tgtPortWWNList));
11947836SJohn.Forte@Sun.COM if (newDevice->HBAPortWWN->tgtPortWWN == NULL) {
11957836SJohn.Forte@Sun.COM perror("Out of memory");
11967836SJohn.Forte@Sun.COM exit(1);
11977836SJohn.Forte@Sun.COM }
11987836SJohn.Forte@Sun.COM
11997836SJohn.Forte@Sun.COM memcpy((void *)&(newDevice->HBAPortWWN->tgtPortWWN->portWWN),
12007836SJohn.Forte@Sun.COM (void *)&(entry.FcpId.PortWWN),
12017836SJohn.Forte@Sun.COM sizeof (newDevice->HBAPortWWN->tgtPortWWN->portWWN));
12027836SJohn.Forte@Sun.COM
12037836SJohn.Forte@Sun.COM /* Set LUN data */
12047836SJohn.Forte@Sun.COM newDevice->HBAPortWWN->tgtPortWWN->scsiOSLun =
12057836SJohn.Forte@Sun.COM entry.ScsiId.ScsiOSLun;
12067836SJohn.Forte@Sun.COM
12077836SJohn.Forte@Sun.COM responseSize = sizeof (struct scsi_inquiry);
12087836SJohn.Forte@Sun.COM senseSize = sizeof (struct scsi_extended_sense);
12097836SJohn.Forte@Sun.COM memset(&inq, 0, sizeof (struct scsi_inquiry));
12107836SJohn.Forte@Sun.COM memset(&sense, 0, sizeof (sense));
12117836SJohn.Forte@Sun.COM status = HBA_ScsiInquiryV2(
12127836SJohn.Forte@Sun.COM handle,
12137836SJohn.Forte@Sun.COM initiatorPortWWN,
12147836SJohn.Forte@Sun.COM entry.FcpId.PortWWN,
12157836SJohn.Forte@Sun.COM entry.FcpId.FcpLun,
12167836SJohn.Forte@Sun.COM 0, /* CDB Byte 1 */
12177836SJohn.Forte@Sun.COM 0, /* CDB Byte 2 */
12187836SJohn.Forte@Sun.COM &inq, &responseSize,
12197836SJohn.Forte@Sun.COM &inq_status,
12207836SJohn.Forte@Sun.COM &sense, &senseSize);
12217836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
12227836SJohn.Forte@Sun.COM /* initialize VID/PID/dType as "Unknown" */
12237836SJohn.Forte@Sun.COM strcpy(newDevice->VID, "Unknown");
12247836SJohn.Forte@Sun.COM strcpy(newDevice->PID, "Unknown");
12257836SJohn.Forte@Sun.COM newDevice->dType = DTYPE_UNKNOWN;
12267836SJohn.Forte@Sun.COM /* initialize inq status */
12277836SJohn.Forte@Sun.COM newDevice->inqSuccess = B_FALSE;
12287836SJohn.Forte@Sun.COM } else {
12297836SJohn.Forte@Sun.COM memcpy(newDevice->VID, inq.inq_vid,
12307836SJohn.Forte@Sun.COM sizeof (newDevice->VID));
12317836SJohn.Forte@Sun.COM memcpy(newDevice->PID, inq.inq_pid,
12327836SJohn.Forte@Sun.COM sizeof (newDevice->PID));
12337836SJohn.Forte@Sun.COM newDevice->dType = inq.inq_dtype;
12347836SJohn.Forte@Sun.COM /* initialize inq status */
12357836SJohn.Forte@Sun.COM newDevice->inqSuccess = B_TRUE;
12367836SJohn.Forte@Sun.COM }
12377836SJohn.Forte@Sun.COM }
12387836SJohn.Forte@Sun.COM }
12397836SJohn.Forte@Sun.COM
12407836SJohn.Forte@Sun.COM
12417836SJohn.Forte@Sun.COM /*
12427836SJohn.Forte@Sun.COM * process the logical-unit object
12437836SJohn.Forte@Sun.COM *
12447836SJohn.Forte@Sun.COM * Arguments:
12457836SJohn.Forte@Sun.COM * luCount - count of the number of device paths in paths_argv
12467836SJohn.Forte@Sun.COM * if pathCount > 0, then we will only print information for
12477836SJohn.Forte@Sun.COM * the device paths listed in paths_argv
12487836SJohn.Forte@Sun.COM * if pathCount == 0, then we will print information on all device
12497836SJohn.Forte@Sun.COM * paths
12507836SJohn.Forte@Sun.COM * luArgv - argument array of device paths
12517836SJohn.Forte@Sun.COM * options - any options specified by the caller
12527836SJohn.Forte@Sun.COM *
12537836SJohn.Forte@Sun.COM * returns:
12547836SJohn.Forte@Sun.COM * 0 if successful
12557836SJohn.Forte@Sun.COM * > 0 otherwise
12567836SJohn.Forte@Sun.COM */
12577836SJohn.Forte@Sun.COM int
fc_util_list_logicalunit(int luCount,char ** luArgv,cmdOptions_t * options)12587836SJohn.Forte@Sun.COM fc_util_list_logicalunit(int luCount, char **luArgv, cmdOptions_t *options)
12597836SJohn.Forte@Sun.COM {
12607836SJohn.Forte@Sun.COM int pathCtr, numAdapters, i, count;
12617836SJohn.Forte@Sun.COM HBA_STATUS status;
12627836SJohn.Forte@Sun.COM char adapterName[256];
12637836SJohn.Forte@Sun.COM HBA_HANDLE handle;
12647836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES port;
12657836SJohn.Forte@Sun.COM HBA_ADAPTERATTRIBUTES attrs;
12667836SJohn.Forte@Sun.COM int portIndex = 0;
12677836SJohn.Forte@Sun.COM int ret = 0;
12687836SJohn.Forte@Sun.COM boolean_t verbose = B_FALSE;
12697836SJohn.Forte@Sun.COM HBA_FCPTARGETMAPPINGV2 *map = NULL;
12707836SJohn.Forte@Sun.COM discoveredDevice *devListWalk, *devList = NULL;
12717836SJohn.Forte@Sun.COM boolean_t pathFound;
12727836SJohn.Forte@Sun.COM
12737836SJohn.Forte@Sun.COM /* process each of the options */
12747836SJohn.Forte@Sun.COM for (; options->optval; options++) {
12757836SJohn.Forte@Sun.COM if (options->optval == 'v') {
12767836SJohn.Forte@Sun.COM verbose = B_TRUE;
12777836SJohn.Forte@Sun.COM }
12787836SJohn.Forte@Sun.COM }
12797836SJohn.Forte@Sun.COM
12807836SJohn.Forte@Sun.COM if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
12817836SJohn.Forte@Sun.COM fprintf(stderr,
12827836SJohn.Forte@Sun.COM gettext("Failed to load FC-HBA common library\n"));
12837836SJohn.Forte@Sun.COM printStatus(status);
12847836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
12857836SJohn.Forte@Sun.COM return (1);
12867836SJohn.Forte@Sun.COM }
12877836SJohn.Forte@Sun.COM /*
12887836SJohn.Forte@Sun.COM * Retrieve all device paths. We'll need to traverse the list
12897836SJohn.Forte@Sun.COM * until we find the input paths or all paths if none were given. We
12907836SJohn.Forte@Sun.COM * cannot print as we go since there can be duplicate paths returned
12917836SJohn.Forte@Sun.COM */
12927836SJohn.Forte@Sun.COM numAdapters = HBA_GetNumberOfAdapters();
12937836SJohn.Forte@Sun.COM if (numAdapters == 0) {
12947836SJohn.Forte@Sun.COM return (0);
12957836SJohn.Forte@Sun.COM }
12967836SJohn.Forte@Sun.COM for (i = 0; i < numAdapters; i++) {
12977836SJohn.Forte@Sun.COM int times;
12987836SJohn.Forte@Sun.COM status = HBA_GetAdapterName(i, adapterName);
12997836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
13007836SJohn.Forte@Sun.COM fprintf(stderr, gettext(
13017836SJohn.Forte@Sun.COM "Failed to get adapter %d. Reason: "), i);
13027836SJohn.Forte@Sun.COM printStatus(status);
13037836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
13047836SJohn.Forte@Sun.COM ret++;
13057836SJohn.Forte@Sun.COM continue;
13067836SJohn.Forte@Sun.COM }
13077836SJohn.Forte@Sun.COM if ((handle = HBA_OpenAdapter(adapterName)) == 0) {
13087836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Failed to open adapter %s\n"),
13097836SJohn.Forte@Sun.COM adapterName);
13107836SJohn.Forte@Sun.COM ret++;
13117836SJohn.Forte@Sun.COM continue;
13127836SJohn.Forte@Sun.COM }
13137836SJohn.Forte@Sun.COM /* get adapter attributes for the given handle */
13147836SJohn.Forte@Sun.COM memset(&attrs, 0, sizeof (attrs));
13157836SJohn.Forte@Sun.COM times = 0;
13167836SJohn.Forte@Sun.COM status = HBA_GetAdapterAttributes(handle, &attrs);
13177836SJohn.Forte@Sun.COM while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
13187836SJohn.Forte@Sun.COM status == HBA_STATUS_ERROR_BUSY) &&
13197836SJohn.Forte@Sun.COM times++ < HBA_MAX_RETRIES) {
13207836SJohn.Forte@Sun.COM (void) sleep(1);
13217836SJohn.Forte@Sun.COM status = HBA_GetAdapterAttributes(handle, &attrs);
13227836SJohn.Forte@Sun.COM if (status == HBA_STATUS_OK) {
13237836SJohn.Forte@Sun.COM break;
13247836SJohn.Forte@Sun.COM }
13257836SJohn.Forte@Sun.COM }
13267836SJohn.Forte@Sun.COM if (status != HBA_STATUS_OK) {
13277836SJohn.Forte@Sun.COM fprintf(stderr,
13287836SJohn.Forte@Sun.COM gettext("Failed to get adapter attributes "
13298507SRaghuram.Prahlada@Sun.COM "handle(%d) Reason: "), handle);
13307836SJohn.Forte@Sun.COM printStatus(status);
13317836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
13327836SJohn.Forte@Sun.COM ret++;
13338507SRaghuram.Prahlada@Sun.COM HBA_CloseAdapter(handle);
13347836SJohn.Forte@Sun.COM continue;
13357836SJohn.Forte@Sun.COM }
13367836SJohn.Forte@Sun.COM
13377836SJohn.Forte@Sun.COM /* process each port on adapter */
13387836SJohn.Forte@Sun.COM for (portIndex = 0; portIndex < attrs.NumberOfPorts;
13397836SJohn.Forte@Sun.COM portIndex++) {
13407836SJohn.Forte@Sun.COM memset(&port, 0, sizeof (port));
13417836SJohn.Forte@Sun.COM if ((status = HBA_GetAdapterPortAttributes(handle,
13427836SJohn.Forte@Sun.COM portIndex, &port)) != HBA_STATUS_OK) {
13437836SJohn.Forte@Sun.COM /*
13447836SJohn.Forte@Sun.COM * not able to get port attributes.
13457836SJohn.Forte@Sun.COM * print out error message and move
13467836SJohn.Forte@Sun.COM * on to the next port
13477836SJohn.Forte@Sun.COM */
13487836SJohn.Forte@Sun.COM fprintf(stderr, gettext("Failed to get port "
13497836SJohn.Forte@Sun.COM "(%d) attributes reason: "),
13507836SJohn.Forte@Sun.COM portIndex);
13517836SJohn.Forte@Sun.COM printStatus(status);
13527836SJohn.Forte@Sun.COM fprintf(stderr, "\n");
13537836SJohn.Forte@Sun.COM ret++;
13547836SJohn.Forte@Sun.COM continue;
13557836SJohn.Forte@Sun.COM }
13567836SJohn.Forte@Sun.COM
13577836SJohn.Forte@Sun.COM /* get OS Device Paths */
13587836SJohn.Forte@Sun.COM getTargetMapping(handle, port.PortWWN, &map);
13597836SJohn.Forte@Sun.COM if (map != NULL) {
13607836SJohn.Forte@Sun.COM for (count = 0; count < map->NumberOfEntries;
13617836SJohn.Forte@Sun.COM count++) {
13627836SJohn.Forte@Sun.COM searchDevice(&devList,
13637836SJohn.Forte@Sun.COM map->entry[count], port.PortWWN,
13647836SJohn.Forte@Sun.COM handle, verbose);
13657836SJohn.Forte@Sun.COM }
13667836SJohn.Forte@Sun.COM }
13677836SJohn.Forte@Sun.COM }
13687836SJohn.Forte@Sun.COM HBA_CloseAdapter(handle);
13697836SJohn.Forte@Sun.COM }
13707836SJohn.Forte@Sun.COM HBA_FreeLibrary();
13717836SJohn.Forte@Sun.COM
13727836SJohn.Forte@Sun.COM if (luCount == 0) {
13737836SJohn.Forte@Sun.COM /* list all paths */
13747836SJohn.Forte@Sun.COM for (devListWalk = devList; devListWalk != NULL;
13757836SJohn.Forte@Sun.COM devListWalk = devListWalk->next) {
13767836SJohn.Forte@Sun.COM printOSDeviceNameInfo(devListWalk, verbose);
13777836SJohn.Forte@Sun.COM }
13787836SJohn.Forte@Sun.COM } else {
13797836SJohn.Forte@Sun.COM /*
13807836SJohn.Forte@Sun.COM * list any paths not found first
13817836SJohn.Forte@Sun.COM * this gives the user cleaner output
13827836SJohn.Forte@Sun.COM */
13837836SJohn.Forte@Sun.COM for (pathCtr = 0; pathCtr < luCount; pathCtr++) {
13847836SJohn.Forte@Sun.COM for (devListWalk = devList, pathFound = B_FALSE;
13857836SJohn.Forte@Sun.COM devListWalk != NULL;
13867836SJohn.Forte@Sun.COM devListWalk = devListWalk->next) {
13877836SJohn.Forte@Sun.COM if (strcmp(devListWalk->OSDeviceName,
13887836SJohn.Forte@Sun.COM luArgv[pathCtr]) == 0) {
13897836SJohn.Forte@Sun.COM pathFound = B_TRUE;
13907836SJohn.Forte@Sun.COM }
13917836SJohn.Forte@Sun.COM }
13927836SJohn.Forte@Sun.COM if (pathFound == B_FALSE) {
13937836SJohn.Forte@Sun.COM fprintf(stderr, "%s: no such path\n",
13947836SJohn.Forte@Sun.COM luArgv[pathCtr]);
13957836SJohn.Forte@Sun.COM ret++;
13967836SJohn.Forte@Sun.COM }
13977836SJohn.Forte@Sun.COM }
13987836SJohn.Forte@Sun.COM /* list all paths requested in order requested */
13997836SJohn.Forte@Sun.COM for (pathCtr = 0; pathCtr < luCount; pathCtr++) {
14007836SJohn.Forte@Sun.COM for (devListWalk = devList; devListWalk != NULL;
14017836SJohn.Forte@Sun.COM devListWalk = devListWalk->next) {
14027836SJohn.Forte@Sun.COM if (strcmp(devListWalk->OSDeviceName,
14037836SJohn.Forte@Sun.COM luArgv[pathCtr]) == 0) {
14047836SJohn.Forte@Sun.COM printOSDeviceNameInfo(devListWalk,
14057836SJohn.Forte@Sun.COM verbose);
14067836SJohn.Forte@Sun.COM }
14077836SJohn.Forte@Sun.COM }
14087836SJohn.Forte@Sun.COM }
14097836SJohn.Forte@Sun.COM }
14107836SJohn.Forte@Sun.COM return (ret);
14117836SJohn.Forte@Sun.COM }
1412