1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte /* 22*2a8164dfSZhong Wang * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23fcf3ce44SJohn Forte * Use is subject to license terms. 24fcf3ce44SJohn Forte */ 25fcf3ce44SJohn Forte 26fcf3ce44SJohn Forte 27fcf3ce44SJohn Forte #include "fcinfo.h" 28fcf3ce44SJohn Forte #include <libintl.h> 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte struct lun { 31fcf3ce44SJohn Forte uchar_t val[8]; 32fcf3ce44SJohn Forte }; 33fcf3ce44SJohn Forte 34fcf3ce44SJohn Forte typedef enum { 35fcf3ce44SJohn Forte HBA_PORT, 36fcf3ce44SJohn Forte REMOTE_PORT, 37fcf3ce44SJohn Forte LOGICAL_UNIT 38fcf3ce44SJohn Forte } resource_type; 39fcf3ce44SJohn Forte 40fcf3ce44SJohn Forte typedef struct rep_luns_rsp { 41fcf3ce44SJohn Forte uint32_t length; 42fcf3ce44SJohn Forte uint32_t rsrvd; 43fcf3ce44SJohn Forte struct lun lun[1]; 44fcf3ce44SJohn Forte } rep_luns_rsp_t; 45fcf3ce44SJohn Forte 46fcf3ce44SJohn Forte static int getTargetMapping(HBA_HANDLE, HBA_WWN myhbaPortWWN, 47fcf3ce44SJohn Forte HBA_FCPTARGETMAPPINGV2 **mapping); 48fcf3ce44SJohn Forte static int processHBA(HBA_HANDLE handle, HBA_ADAPTERATTRIBUTES attrs, 49fcf3ce44SJohn Forte int portIndex, HBA_PORTATTRIBUTES port, HBA_FCPTARGETMAPPINGV2 *map, 50fcf3ce44SJohn Forte int resourceType, int flags, int mode); 51fcf3ce44SJohn Forte static void processRemotePort(HBA_HANDLE handle, HBA_WWN portWWN, 52fcf3ce44SJohn Forte HBA_FCPTARGETMAPPINGV2 *map, int wwnCount, char **wwn_argv, int flags); 53fcf3ce44SJohn Forte static void handleRemotePort(HBA_HANDLE handle, HBA_WWN portWWN, 54fcf3ce44SJohn Forte HBA_WWN myRemotePortWWN, HBA_PORTATTRIBUTES *discPort); 55fcf3ce44SJohn Forte static void printLinkStat(HBA_HANDLE handle, HBA_WWN hbaportWWN, 56fcf3ce44SJohn Forte HBA_WWN destWWN); 57fcf3ce44SJohn Forte static void handleScsiTarget(HBA_HANDLE handle, HBA_WWN hbaPortWWN, 58fcf3ce44SJohn Forte HBA_WWN scsiTargetWWN, HBA_FCPTARGETMAPPINGV2 *map); 59fcf3ce44SJohn Forte static int retrieveAttrs(HBA_HANDLE handle, HBA_WWN hbaPortWWN, 60fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES *attrs, HBA_PORTATTRIBUTES *port, int *portIndex); 61fcf3ce44SJohn Forte static void searchDevice(discoveredDevice **devList, HBA_FCPSCSIENTRYV2 entry, 62fcf3ce44SJohn Forte HBA_WWN initiatorPortWWN, HBA_HANDLE handle, boolean_t verbose); 63fcf3ce44SJohn Forte 64fcf3ce44SJohn Forte /* 65fcf3ce44SJohn Forte * This function retrieve the adapater attributes, port attributes, and 66fcf3ce44SJohn Forte * portIndex for the given handle and hba port WWN. 67fcf3ce44SJohn Forte * 68fcf3ce44SJohn Forte * Arguments: 69fcf3ce44SJohn Forte * handle an HBA_HANDLE to a adapter 70fcf3ce44SJohn Forte * hbaPortWWN WWN of the port on the adapter to which to retrieve 71fcf3ce44SJohn Forte * HBA_PORTATTRIBUTES from 72fcf3ce44SJohn Forte * attrs pointer to a HBA_ADAPTERATTRIBUTES structure. Upon 73fcf3ce44SJohn Forte * successful completion, this structure will be filled in 74fcf3ce44SJohn Forte * port pointer to a HBA_PORTATTRIBUTES structure. Upon successful 75fcf3ce44SJohn Forte * completion, this structure will be fill in 76fcf3ce44SJohn Forte * portIndex the Index count of the port on the adapter that is 77fcf3ce44SJohn Forte * associated with the WWN. 78fcf3ce44SJohn Forte * 79fcf3ce44SJohn Forte * Returns 80fcf3ce44SJohn Forte * 0 successfully retrieve all information 81fcf3ce44SJohn Forte * >0 otherwise 82fcf3ce44SJohn Forte */ 83fcf3ce44SJohn Forte static int 84fcf3ce44SJohn Forte retrieveAttrs(HBA_HANDLE handle, HBA_WWN hbaPortWWN, 85fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES *attrs, HBA_PORTATTRIBUTES *port, int *portIndex) 86fcf3ce44SJohn Forte { 87fcf3ce44SJohn Forte HBA_STATUS status; 88fcf3ce44SJohn Forte int portCtr; 89fcf3ce44SJohn Forte int times; 90fcf3ce44SJohn Forte 91fcf3ce44SJohn Forte /* argument checking */ 92fcf3ce44SJohn Forte if (attrs == NULL || port == NULL || portIndex == NULL) { 93fcf3ce44SJohn Forte fprintf(stderr, gettext("Error: Invalid arguments to " 94fcf3ce44SJohn Forte "retreiveAttrs\n")); 95fcf3ce44SJohn Forte return (1); 96fcf3ce44SJohn Forte } 97fcf3ce44SJohn Forte 98fcf3ce44SJohn Forte /* retrieve Adapter attributes */ 99fcf3ce44SJohn Forte memset(attrs, 0, sizeof (HBA_ADAPTERATTRIBUTES)); 100fcf3ce44SJohn Forte status = HBA_GetAdapterAttributes(handle, attrs); 101fcf3ce44SJohn Forte times = 0; 102fcf3ce44SJohn Forte while ((status == HBA_STATUS_ERROR_TRY_AGAIN || 103fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) && 104fcf3ce44SJohn Forte times++ < HBA_MAX_RETRIES) { 105fcf3ce44SJohn Forte (void) sleep(1); 106fcf3ce44SJohn Forte status = HBA_GetAdapterAttributes(handle, attrs); 107fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) { 108fcf3ce44SJohn Forte break; 109fcf3ce44SJohn Forte } 110fcf3ce44SJohn Forte } 111fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 112fcf3ce44SJohn Forte fprintf(stderr, gettext("Failed to get adapter " 113fcf3ce44SJohn Forte "attributes handle(%d) Reason: "), handle); 114fcf3ce44SJohn Forte printStatus(status); 115fcf3ce44SJohn Forte fprintf(stderr, "\n"); 116fcf3ce44SJohn Forte return (1); 117fcf3ce44SJohn Forte } 118fcf3ce44SJohn Forte 119fcf3ce44SJohn Forte /* 120fcf3ce44SJohn Forte * find the corresponding port on the adapter and retrieve 121fcf3ce44SJohn Forte * port attributes as well as the port index 122fcf3ce44SJohn Forte */ 123fcf3ce44SJohn Forte memset(port, 0, sizeof (HBA_PORTATTRIBUTES)); 124fcf3ce44SJohn Forte for (portCtr = 0; portCtr < attrs->NumberOfPorts; portCtr++) { 125fcf3ce44SJohn Forte if ((status = HBA_GetAdapterPortAttributes(handle, 126fcf3ce44SJohn Forte portCtr, port)) != HBA_STATUS_OK) { 127fcf3ce44SJohn Forte fprintf(stderr, 128fcf3ce44SJohn Forte gettext("Error: Failed to get port (%d) " 129fcf3ce44SJohn Forte "attributes reason: "), portCtr); 130fcf3ce44SJohn Forte printStatus(status); 131fcf3ce44SJohn Forte fprintf(stderr, "\n"); 132fcf3ce44SJohn Forte return (1); 133fcf3ce44SJohn Forte } 134fcf3ce44SJohn Forte if (memcmp(hbaPortWWN.wwn, port->PortWWN.wwn, 135fcf3ce44SJohn Forte sizeof (port->PortWWN.wwn)) == 0) { 136fcf3ce44SJohn Forte break; 137fcf3ce44SJohn Forte } 138fcf3ce44SJohn Forte } 139fcf3ce44SJohn Forte if (portCtr >= attrs->NumberOfPorts) { 140fcf3ce44SJohn Forte /* 141fcf3ce44SJohn Forte * not able to find corresponding port WWN 142fcf3ce44SJohn Forte * returning an error 143fcf3ce44SJohn Forte */ 144fcf3ce44SJohn Forte *portIndex = 0; 145fcf3ce44SJohn Forte return (1); 146fcf3ce44SJohn Forte } 147fcf3ce44SJohn Forte *portIndex = portCtr; 148fcf3ce44SJohn Forte return (0); 149fcf3ce44SJohn Forte } 150fcf3ce44SJohn Forte 151fcf3ce44SJohn Forte /* 152fcf3ce44SJohn Forte * This function retrieves target mapping information for the HBA port WWN. 153fcf3ce44SJohn Forte * This function will allocate space for the mapping structure which the caller 154fcf3ce44SJohn Forte * must free when they are finished 155fcf3ce44SJohn Forte * 156fcf3ce44SJohn Forte * Arguments: 157fcf3ce44SJohn Forte * handle - a handle to a HBA that we will be processing 158fcf3ce44SJohn Forte * hbaPortWWN - the port WWN for the HBA port to retrieve the mappings for 159fcf3ce44SJohn Forte * mapping - a pointer to a pointer for the target mapping structure 160fcf3ce44SJohn Forte * Upon successful completion of this function, *mapping will contain 161fcf3ce44SJohn Forte * the target mapping information 162fcf3ce44SJohn Forte * 163fcf3ce44SJohn Forte * returns: 164fcf3ce44SJohn Forte * 0 if successful 165fcf3ce44SJohn Forte * 1 otherwise 166fcf3ce44SJohn Forte */ 167fcf3ce44SJohn Forte static int 168fcf3ce44SJohn Forte getTargetMapping(HBA_HANDLE handle, HBA_WWN hbaPortWWN, 169fcf3ce44SJohn Forte HBA_FCPTARGETMAPPINGV2 **mapping) 170fcf3ce44SJohn Forte { 171fcf3ce44SJohn Forte HBA_FCPTARGETMAPPINGV2 *map; 172fcf3ce44SJohn Forte HBA_STATUS status; 173fcf3ce44SJohn Forte int count; 174fcf3ce44SJohn Forte 175fcf3ce44SJohn Forte /* argument sanity checking */ 176fcf3ce44SJohn Forte if (mapping == NULL) { 177fcf3ce44SJohn Forte fprintf(stderr, gettext("Internal Error: mapping is NULL")); 178fcf3ce44SJohn Forte return (1); 179fcf3ce44SJohn Forte } 180fcf3ce44SJohn Forte *mapping = NULL; 181fcf3ce44SJohn Forte if ((map = calloc(1, sizeof (HBA_FCPTARGETMAPPINGV2))) == NULL) { 182fcf3ce44SJohn Forte fprintf(stderr, 183fcf3ce44SJohn Forte gettext("Internal Error: Unable to calloc map")); 184fcf3ce44SJohn Forte return (1); 185fcf3ce44SJohn Forte } 186fcf3ce44SJohn Forte status = HBA_GetFcpTargetMappingV2(handle, hbaPortWWN, map); 187fcf3ce44SJohn Forte count = map->NumberOfEntries; 188fcf3ce44SJohn Forte if (status == HBA_STATUS_ERROR_MORE_DATA) { 189fcf3ce44SJohn Forte free(map); 190fcf3ce44SJohn Forte if ((map = calloc(1, (sizeof (HBA_FCPSCSIENTRYV2)*(count-1)) + 191fcf3ce44SJohn Forte sizeof (HBA_FCPTARGETMAPPINGV2))) == NULL) { 192fcf3ce44SJohn Forte fprintf(stderr, 193fcf3ce44SJohn Forte gettext("Unable to calloc map of size: %d"), count); 194fcf3ce44SJohn Forte return (1); 195fcf3ce44SJohn Forte } 196fcf3ce44SJohn Forte map->NumberOfEntries = count; 197fcf3ce44SJohn Forte status = HBA_GetFcpTargetMappingV2(handle, hbaPortWWN, map); 198fcf3ce44SJohn Forte } 199fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 200fcf3ce44SJohn Forte fprintf(stderr, 201fcf3ce44SJohn Forte gettext("Error: Unable to get Target Mapping\n")); 202fcf3ce44SJohn Forte printStatus(status); 203fcf3ce44SJohn Forte fprintf(stderr, "\n"); 204fcf3ce44SJohn Forte free(map); 205fcf3ce44SJohn Forte return (1); 206fcf3ce44SJohn Forte } 207fcf3ce44SJohn Forte *mapping = map; 208fcf3ce44SJohn Forte return (0); 209fcf3ce44SJohn Forte } 210fcf3ce44SJohn Forte 211fcf3ce44SJohn Forte /* 212fcf3ce44SJohn Forte * This function handles the remoteport object. It will issue a report lun 213fcf3ce44SJohn Forte * to determine whether it is a scsi-target and then print the information. 214fcf3ce44SJohn Forte * 215fcf3ce44SJohn Forte * Arguments: 216fcf3ce44SJohn Forte * handle - a handle to a HBA that we will be processing 217fcf3ce44SJohn Forte * portWWN - the port WWN for the HBA port we will be issuing the SCSI 218fcf3ce44SJohn Forte * ReportLUNS through 219fcf3ce44SJohn Forte * remotePortWWN - the port WWN we will be issuing the report lun call to 220fcf3ce44SJohn Forte * discPort - PORTATTRIBUTES structure for the remotePortWWN 221fcf3ce44SJohn Forte */ 222fcf3ce44SJohn Forte static void 223fcf3ce44SJohn Forte handleRemotePort(HBA_HANDLE handle, HBA_WWN portWWN, HBA_WWN remotePortWWN, 224fcf3ce44SJohn Forte HBA_PORTATTRIBUTES *discPort) 225fcf3ce44SJohn Forte { 226fcf3ce44SJohn Forte HBA_STATUS status; 227fcf3ce44SJohn Forte int scsiTargetType; 228fcf3ce44SJohn Forte uchar_t raw_luns[LUN_LENGTH]; 229fcf3ce44SJohn Forte HBA_UINT32 responseSize = LUN_LENGTH; 230fcf3ce44SJohn Forte struct scsi_extended_sense sense; 231fcf3ce44SJohn Forte HBA_UINT32 senseSize = sizeof (struct scsi_extended_sense); 232fcf3ce44SJohn Forte HBA_UINT8 rep_luns_status; 233fcf3ce44SJohn Forte 234fcf3ce44SJohn Forte /* argument checking */ 235fcf3ce44SJohn Forte if (discPort == NULL) { 236fcf3ce44SJohn Forte return; 237fcf3ce44SJohn Forte } 238fcf3ce44SJohn Forte 239fcf3ce44SJohn Forte memset(raw_luns, 0, sizeof (raw_luns)); 240fcf3ce44SJohn Forte /* going to issue a report lun to check if this is a scsi-target */ 241fcf3ce44SJohn Forte status = HBA_ScsiReportLUNsV2(handle, portWWN, remotePortWWN, 242fcf3ce44SJohn Forte (void *)raw_luns, &responseSize, &rep_luns_status, 243fcf3ce44SJohn Forte (void *)&sense, &senseSize); 244fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) { 245fcf3ce44SJohn Forte scsiTargetType = SCSI_TARGET_TYPE_YES; 246fcf3ce44SJohn Forte } else if (status == HBA_STATUS_ERROR_NOT_A_TARGET) { 247fcf3ce44SJohn Forte scsiTargetType = SCSI_TARGET_TYPE_NO; 248fcf3ce44SJohn Forte } else { 249fcf3ce44SJohn Forte scsiTargetType = SCSI_TARGET_TYPE_UNKNOWN; 250fcf3ce44SJohn Forte } 251fcf3ce44SJohn Forte printDiscoPortInfo(discPort, scsiTargetType); 252fcf3ce44SJohn Forte } 253fcf3ce44SJohn Forte 254fcf3ce44SJohn Forte /* 255fcf3ce44SJohn Forte * This function will issue the RLS and print out the port statistics for 256fcf3ce44SJohn Forte * the given destWWN 257fcf3ce44SJohn Forte * 258fcf3ce44SJohn Forte * Arguments 259fcf3ce44SJohn Forte * handle - a handle to a HBA that we will be processing 260fcf3ce44SJohn Forte * hbaPortWWN - the hba port WWN through which the RLS will be sent 261fcf3ce44SJohn Forte * destWWN - the remote port to which the RLS will be sent 262fcf3ce44SJohn Forte */ 263fcf3ce44SJohn Forte static void 264fcf3ce44SJohn Forte printLinkStat(HBA_HANDLE handle, HBA_WWN hbaPortWWN, HBA_WWN destWWN) 265fcf3ce44SJohn Forte { 266fcf3ce44SJohn Forte HBA_STATUS status; 267fcf3ce44SJohn Forte fc_rls_acc_t rls_payload; 268fcf3ce44SJohn Forte uint32_t rls_payload_size; 269fcf3ce44SJohn Forte 270fcf3ce44SJohn Forte memset(&rls_payload, 0, sizeof (rls_payload)); 271fcf3ce44SJohn Forte rls_payload_size = sizeof (rls_payload); 272fcf3ce44SJohn Forte status = HBA_SendRLS(handle, hbaPortWWN, destWWN, 273fcf3ce44SJohn Forte &rls_payload, &rls_payload_size); 274fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 275fcf3ce44SJohn Forte fprintf(stderr, gettext("Error: SendRLS failed for %016llx\n"), 276fcf3ce44SJohn Forte wwnConversion(destWWN.wwn)); 277fcf3ce44SJohn Forte } else { 278fcf3ce44SJohn Forte printPortStat(&rls_payload); 279fcf3ce44SJohn Forte } 280fcf3ce44SJohn Forte } 281fcf3ce44SJohn Forte 282fcf3ce44SJohn Forte int 283fcf3ce44SJohn Forte printHBANPIVPortInfo(HBA_HANDLE handle, int portindex) 284fcf3ce44SJohn Forte { 285fcf3ce44SJohn Forte HBA_PORTNPIVATTRIBUTES portattrs; 286fcf3ce44SJohn Forte HBA_NPIVATTRIBUTES npivattrs; 287fcf3ce44SJohn Forte HBA_STATUS status; 288fcf3ce44SJohn Forte int index; 289fcf3ce44SJohn Forte int times = 0; 290fcf3ce44SJohn Forte 291fcf3ce44SJohn Forte status = Sun_HBA_GetPortNPIVAttributes(handle, portindex, &portattrs); 292fcf3ce44SJohn Forte while (status == HBA_STATUS_ERROR_TRY_AGAIN || 293fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) { 294fcf3ce44SJohn Forte (void) sleep(1); 295fcf3ce44SJohn Forte status = Sun_HBA_GetPortNPIVAttributes( 296fcf3ce44SJohn Forte handle, portindex, &portattrs); 297fcf3ce44SJohn Forte if (times++ > HBA_MAX_RETRIES) { 298fcf3ce44SJohn Forte break; 299fcf3ce44SJohn Forte } 300fcf3ce44SJohn Forte } 301fcf3ce44SJohn Forte 302fcf3ce44SJohn Forte if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) { 303fcf3ce44SJohn Forte fprintf(stdout, gettext("\tNPIV Not Supported\n")); 304fcf3ce44SJohn Forte return (0); 305fcf3ce44SJohn Forte } 306fcf3ce44SJohn Forte 307fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 308fcf3ce44SJohn Forte fprintf(stderr, 309fcf3ce44SJohn Forte gettext("Error: Failed to get port (%d) " 310fcf3ce44SJohn Forte "npiv attributes reason: "), portindex); 311fcf3ce44SJohn Forte printStatus(status); 312fcf3ce44SJohn Forte fprintf(stderr, "\n"); 313fcf3ce44SJohn Forte return (1); 314fcf3ce44SJohn Forte } 315fcf3ce44SJohn Forte if (portattrs.MaxNumberOfNPIVPorts) { 316fcf3ce44SJohn Forte fprintf(stdout, gettext("\tMax NPIV Ports: %d\n"), 317fcf3ce44SJohn Forte portattrs.MaxNumberOfNPIVPorts); 318fcf3ce44SJohn Forte } else { 319fcf3ce44SJohn Forte fprintf(stdout, gettext("\tNPIV Not Supported\n")); 320fcf3ce44SJohn Forte return (0); 321fcf3ce44SJohn Forte } 322fcf3ce44SJohn Forte fprintf(stdout, gettext("\tNPIV port list:\n")); 323fcf3ce44SJohn Forte for (index = 0; index < portattrs.NumberOfNPIVPorts; index++) { 324fcf3ce44SJohn Forte int times = 0; 325fcf3ce44SJohn Forte status = Sun_HBA_GetNPIVPortInfo(handle, 326fcf3ce44SJohn Forte portindex, index, &npivattrs); 327fcf3ce44SJohn Forte while (status == HBA_STATUS_ERROR_TRY_AGAIN || 328fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) { 329fcf3ce44SJohn Forte (void) sleep(1); 330fcf3ce44SJohn Forte status = Sun_HBA_GetNPIVPortInfo(handle, 331fcf3ce44SJohn Forte portindex, index, &npivattrs); 332fcf3ce44SJohn Forte if (times++ > HBA_MAX_RETRIES) { 333fcf3ce44SJohn Forte break; 334fcf3ce44SJohn Forte } 335fcf3ce44SJohn Forte } 336fcf3ce44SJohn Forte 337fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 338fcf3ce44SJohn Forte fprintf(stderr, 339fcf3ce44SJohn Forte gettext("Error: Failed to get npiv port (%d) " 340fcf3ce44SJohn Forte "attributes reason: "), index); 341fcf3ce44SJohn Forte printStatus(status); 342fcf3ce44SJohn Forte fprintf(stderr, "\n"); 343fcf3ce44SJohn Forte return (1); 344fcf3ce44SJohn Forte } else { 345fcf3ce44SJohn Forte fprintf(stdout, 346fcf3ce44SJohn Forte gettext("\t Virtual Port%d:\n"), index+1); 347fcf3ce44SJohn Forte fprintf(stdout, gettext("\t\tNode WWN: %016llx\n"), 348fcf3ce44SJohn Forte wwnConversion(npivattrs.NodeWWN.wwn)); 349fcf3ce44SJohn Forte fprintf(stdout, gettext("\t\tPort WWN: %016llx\n"), 350fcf3ce44SJohn Forte wwnConversion(npivattrs.PortWWN.wwn)); 351fcf3ce44SJohn Forte } 352fcf3ce44SJohn Forte } 353fcf3ce44SJohn Forte return (0); 354fcf3ce44SJohn Forte } 355fcf3ce44SJohn Forte 356fcf3ce44SJohn Forte /* 357fcf3ce44SJohn Forte * This function will process hba port, remote port and scsi-target information 358fcf3ce44SJohn Forte * for the given handle. 359fcf3ce44SJohn Forte * 360fcf3ce44SJohn Forte * Arguments: 361fcf3ce44SJohn Forte * handle - a handle to a HBA that we will be processing 362fcf3ce44SJohn Forte * resourceType - resourceType flag 363fcf3ce44SJohn Forte * possible values include: HBA_PORT, REMOTE_PORT 364fcf3ce44SJohn Forte * flags - represents options passed in by the user 365fcf3ce44SJohn Forte * 366fcf3ce44SJohn Forte * Return Value: 367fcf3ce44SJohn Forte * 0 sucessfully processed handle 368fcf3ce44SJohn Forte * 1 error has occured 369fcf3ce44SJohn Forte */ 370fcf3ce44SJohn Forte static int 371fcf3ce44SJohn Forte processHBA(HBA_HANDLE handle, HBA_ADAPTERATTRIBUTES attrs, int portIndex, 372fcf3ce44SJohn Forte HBA_PORTATTRIBUTES port, HBA_FCPTARGETMAPPINGV2 *map, 373fcf3ce44SJohn Forte int resourceType, int flags, int mode) 374fcf3ce44SJohn Forte { 375fcf3ce44SJohn Forte HBA_PORTATTRIBUTES discPort; 376fcf3ce44SJohn Forte HBA_STATUS status; 377fcf3ce44SJohn Forte int discPortCount; 378fcf3ce44SJohn Forte 379fcf3ce44SJohn Forte if (resourceType == HBA_PORT) { 380*2a8164dfSZhong Wang if ((flags & PRINT_FCOE) == PRINT_FCOE && 381*2a8164dfSZhong Wang attrs.VendorSpecificID != 0xFC0E) { 382*2a8164dfSZhong Wang return (0); 383*2a8164dfSZhong Wang } 384fcf3ce44SJohn Forte printHBAPortInfo(&port, &attrs, mode); 385fcf3ce44SJohn Forte if ((flags & PRINT_LINKSTAT) == PRINT_LINKSTAT) { 386fcf3ce44SJohn Forte printLinkStat(handle, port.PortWWN, port.PortWWN); 387fcf3ce44SJohn Forte } 388fcf3ce44SJohn Forte return (0); 389fcf3ce44SJohn Forte } 390fcf3ce44SJohn Forte /* 391fcf3ce44SJohn Forte * process each of the remote targets from this hba port 392fcf3ce44SJohn Forte */ 393fcf3ce44SJohn Forte for (discPortCount = 0; 394fcf3ce44SJohn Forte discPortCount < port.NumberofDiscoveredPorts; 395fcf3ce44SJohn Forte discPortCount++) { 396fcf3ce44SJohn Forte status = HBA_GetDiscoveredPortAttributes(handle, 397fcf3ce44SJohn Forte portIndex, discPortCount, &discPort); 398fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 399fcf3ce44SJohn Forte fprintf(stderr, 400fcf3ce44SJohn Forte gettext("Failed to get discovered port (%d)" 401fcf3ce44SJohn Forte " attributes reason :"), discPortCount); 402fcf3ce44SJohn Forte printStatus(status); 403fcf3ce44SJohn Forte fprintf(stderr, "\n"); 404fcf3ce44SJohn Forte continue; 405fcf3ce44SJohn Forte } 406fcf3ce44SJohn Forte if (resourceType == REMOTE_PORT) { 407fcf3ce44SJohn Forte handleRemotePort(handle, port.PortWWN, discPort.PortWWN, 408fcf3ce44SJohn Forte &discPort); 409fcf3ce44SJohn Forte if ((flags & PRINT_LINKSTAT) == PRINT_LINKSTAT) { 410fcf3ce44SJohn Forte printLinkStat(handle, port.PortWWN, 411fcf3ce44SJohn Forte discPort.PortWWN); 412fcf3ce44SJohn Forte } 413fcf3ce44SJohn Forte if ((flags & PRINT_SCSI_TARGET) == PRINT_SCSI_TARGET) { 414fcf3ce44SJohn Forte handleScsiTarget(handle, port.PortWWN, 415fcf3ce44SJohn Forte discPort.PortWWN, map); 416fcf3ce44SJohn Forte } 417fcf3ce44SJohn Forte } 418fcf3ce44SJohn Forte } 419fcf3ce44SJohn Forte return (0); 420fcf3ce44SJohn Forte } 421fcf3ce44SJohn Forte 422fcf3ce44SJohn Forte /* 423fcf3ce44SJohn Forte * This function will process remote port information for the given handle. 424fcf3ce44SJohn Forte * 425fcf3ce44SJohn Forte * Arguments: 426fcf3ce44SJohn Forte * handle - a handle to a HBA that we will be processing 427fcf3ce44SJohn Forte * portWWN - the port WWN for the HBA port we will be issuing the SCSI 428fcf3ce44SJohn Forte * ReportLUNS through 429fcf3ce44SJohn Forte * wwnCount - the number of wwns in wwn_argv 430fcf3ce44SJohn Forte * wwn_argv - argument vector of WWNs 431fcf3ce44SJohn Forte */ 432fcf3ce44SJohn Forte static void 433fcf3ce44SJohn Forte processRemotePort(HBA_HANDLE handle, HBA_WWN portWWN, 434fcf3ce44SJohn Forte HBA_FCPTARGETMAPPINGV2 *map, int wwnCount, char **wwn_argv, int flags) 435fcf3ce44SJohn Forte { 436fcf3ce44SJohn Forte int remote_wwn_counter; 437fcf3ce44SJohn Forte uint64_t remotePortWWN; 438fcf3ce44SJohn Forte HBA_WWN myremotePortWWN; 439fcf3ce44SJohn Forte HBA_PORTATTRIBUTES discPort; 440fcf3ce44SJohn Forte HBA_STATUS status; 441fcf3ce44SJohn Forte 442fcf3ce44SJohn Forte for (remote_wwn_counter = 0; 443fcf3ce44SJohn Forte remote_wwn_counter < wwnCount; 444fcf3ce44SJohn Forte remote_wwn_counter++) { 445fcf3ce44SJohn Forte int times = 0; 446fcf3ce44SJohn Forte sscanf(wwn_argv[remote_wwn_counter], "%016llx", 447fcf3ce44SJohn Forte &remotePortWWN); 448fcf3ce44SJohn Forte remotePortWWN = htonll(remotePortWWN); 449fcf3ce44SJohn Forte memcpy(myremotePortWWN.wwn, &remotePortWWN, 450fcf3ce44SJohn Forte sizeof (remotePortWWN)); 451fcf3ce44SJohn Forte memset(&discPort, 0, sizeof (discPort)); 452fcf3ce44SJohn Forte status = HBA_GetPortAttributesByWWN(handle, myremotePortWWN, 453fcf3ce44SJohn Forte &discPort); 454fcf3ce44SJohn Forte while (status == HBA_STATUS_ERROR_TRY_AGAIN || 455fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) { 456fcf3ce44SJohn Forte (void) sleep(1); 457fcf3ce44SJohn Forte status = HBA_GetPortAttributesByWWN(handle, 458fcf3ce44SJohn Forte myremotePortWWN, &discPort); 459fcf3ce44SJohn Forte if (times++ > HBA_MAX_RETRIES) { 460fcf3ce44SJohn Forte break; 461fcf3ce44SJohn Forte } 462fcf3ce44SJohn Forte } 463fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 464fcf3ce44SJohn Forte fprintf(stderr, gettext("HBA_GetPortAttributesByWWN " 465fcf3ce44SJohn Forte "failed: reason: ")); 466fcf3ce44SJohn Forte printStatus(status); 467fcf3ce44SJohn Forte fprintf(stderr, "\n"); 468fcf3ce44SJohn Forte continue; 469fcf3ce44SJohn Forte } 470fcf3ce44SJohn Forte handleRemotePort(handle, portWWN, myremotePortWWN, &discPort); 471fcf3ce44SJohn Forte if ((flags & PRINT_LINKSTAT) == PRINT_LINKSTAT) { 472fcf3ce44SJohn Forte printLinkStat(handle, portWWN, myremotePortWWN); 473fcf3ce44SJohn Forte } 474fcf3ce44SJohn Forte if ((flags & PRINT_SCSI_TARGET) == PRINT_SCSI_TARGET) { 475fcf3ce44SJohn Forte handleScsiTarget(handle, portWWN, 476fcf3ce44SJohn Forte myremotePortWWN, map); 477fcf3ce44SJohn Forte } 478fcf3ce44SJohn Forte } 479fcf3ce44SJohn Forte } 480fcf3ce44SJohn Forte 481fcf3ce44SJohn Forte /* 482fcf3ce44SJohn Forte * This function handles printing Scsi target information for remote ports 483fcf3ce44SJohn Forte * 484fcf3ce44SJohn Forte * Arguments: 485fcf3ce44SJohn Forte * handle - a handle to a HBA that we will be processing 486fcf3ce44SJohn Forte * hbaPortWWN - the port WWN for the HBA port through which the SCSI call 487fcf3ce44SJohn Forte * is being sent 488fcf3ce44SJohn Forte * scsiTargetWWN - target port WWN of the remote target the SCSI call is 489fcf3ce44SJohn Forte * being sent to 490fcf3ce44SJohn Forte * map - a pointer to the target mapping structure for the given HBA port 491fcf3ce44SJohn Forte */ 492fcf3ce44SJohn Forte static void 493fcf3ce44SJohn Forte handleScsiTarget(HBA_HANDLE handle, HBA_WWN hbaPortWWN, HBA_WWN scsiTargetWWN, 494fcf3ce44SJohn Forte HBA_FCPTARGETMAPPINGV2 *map) 495fcf3ce44SJohn Forte { 496fcf3ce44SJohn Forte HBA_STATUS status; 497fcf3ce44SJohn Forte struct scsi_inquiry inq; 498fcf3ce44SJohn Forte struct scsi_extended_sense sense; 499fcf3ce44SJohn Forte HBA_UINT32 responseSize, senseSize = 0; 500fcf3ce44SJohn Forte HBA_UINT8 inq_status; 501fcf3ce44SJohn Forte uchar_t raw_luns[DEFAULT_LUN_LENGTH], *lun_string; 502fcf3ce44SJohn Forte HBA_UINT8 rep_luns_status; 503fcf3ce44SJohn Forte rep_luns_rsp_t *lun_resp; 504fcf3ce44SJohn Forte uint64_t fcLUN; 505fcf3ce44SJohn Forte int lunNum, numberOfLun, lunCount, count; 506fcf3ce44SJohn Forte uint32_t lunlength, tmp_lunlength; 507fcf3ce44SJohn Forte 508fcf3ce44SJohn Forte responseSize = DEFAULT_LUN_LENGTH; 509fcf3ce44SJohn Forte senseSize = sizeof (struct scsi_extended_sense); 510fcf3ce44SJohn Forte memset(&sense, 0, sizeof (sense)); 511fcf3ce44SJohn Forte status = HBA_ScsiReportLUNsV2(handle, hbaPortWWN, 512fcf3ce44SJohn Forte scsiTargetWWN, (void *)raw_luns, &responseSize, 513fcf3ce44SJohn Forte &rep_luns_status, (void *)&sense, &senseSize); 514fcf3ce44SJohn Forte /* 515fcf3ce44SJohn Forte * if HBA_STATUS_ERROR_NOT_A_TARGET is return, we can assume this is 516fcf3ce44SJohn Forte * a remote HBA and move on 517fcf3ce44SJohn Forte */ 518fcf3ce44SJohn Forte if (status == HBA_STATUS_ERROR_NOT_A_TARGET) { 519fcf3ce44SJohn Forte return; 520fcf3ce44SJohn Forte } else if (status != HBA_STATUS_OK) { 521fcf3ce44SJohn Forte fprintf(stderr, gettext("Error has occured. " 522fcf3ce44SJohn Forte "HBA_ScsiReportLUNsV2 failed. reason ")); 523fcf3ce44SJohn Forte printStatus(status); 524fcf3ce44SJohn Forte fprintf(stderr, "\n"); 525fcf3ce44SJohn Forte return; 526fcf3ce44SJohn Forte } 527fcf3ce44SJohn Forte lun_resp = (rep_luns_rsp_t *)raw_luns; 528fcf3ce44SJohn Forte memcpy(&tmp_lunlength, &(lun_resp->length), sizeof (tmp_lunlength)); 529fcf3ce44SJohn Forte lunlength = htonl(tmp_lunlength); 530fcf3ce44SJohn Forte memcpy(&numberOfLun, &lunlength, sizeof (numberOfLun)); 531fcf3ce44SJohn Forte for (lunCount = 0; lunCount < (numberOfLun / 8); lunCount++) { 532fcf3ce44SJohn Forte /* 533fcf3ce44SJohn Forte * now issue standard inquiry to get Vendor 534fcf3ce44SJohn Forte * and product information 535fcf3ce44SJohn Forte */ 536fcf3ce44SJohn Forte responseSize = sizeof (struct scsi_inquiry); 537fcf3ce44SJohn Forte senseSize = sizeof (struct scsi_extended_sense); 538fcf3ce44SJohn Forte memset(&inq, 0, sizeof (struct scsi_inquiry)); 539fcf3ce44SJohn Forte memset(&sense, 0, sizeof (sense)); 540fcf3ce44SJohn Forte fcLUN = ntohll(wwnConversion(lun_resp->lun[lunCount].val)); 541fcf3ce44SJohn Forte status = HBA_ScsiInquiryV2( 542fcf3ce44SJohn Forte handle, 543fcf3ce44SJohn Forte hbaPortWWN, 544fcf3ce44SJohn Forte scsiTargetWWN, 545fcf3ce44SJohn Forte fcLUN, 546fcf3ce44SJohn Forte 0, /* EVPD */ 547fcf3ce44SJohn Forte 0, 548fcf3ce44SJohn Forte &inq, &responseSize, 549fcf3ce44SJohn Forte &inq_status, 550fcf3ce44SJohn Forte &sense, &senseSize); 551fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 552fcf3ce44SJohn Forte fprintf(stderr, gettext("Not able to issue Inquiry.\n")); 553fcf3ce44SJohn Forte printStatus(status); 554fcf3ce44SJohn Forte fprintf(stderr, "\n"); 555fcf3ce44SJohn Forte strcpy(inq.inq_vid, "Unknown"); 556fcf3ce44SJohn Forte strcpy(inq.inq_pid, "Unknown"); 557fcf3ce44SJohn Forte } 558fcf3ce44SJohn Forte if (map != NULL) { 559fcf3ce44SJohn Forte for (count = 0; count < map->NumberOfEntries; count++) { 560fcf3ce44SJohn Forte if ((memcmp(map->entry[count].FcpId.PortWWN.wwn, 561fcf3ce44SJohn Forte scsiTargetWWN.wwn, 562fcf3ce44SJohn Forte sizeof (scsiTargetWWN.wwn)) 563fcf3ce44SJohn Forte == 0) && 564fcf3ce44SJohn Forte (memcmp(&(map->entry[count].FcpId.FcpLun), 565fcf3ce44SJohn Forte &fcLUN, sizeof (fcLUN)) == 0)) { 566fcf3ce44SJohn Forte printLUNInfo(&inq, 567fcf3ce44SJohn Forte map->entry[count].ScsiId.ScsiOSLun, 568fcf3ce44SJohn Forte map->entry[count].ScsiId.OSDeviceName); 569fcf3ce44SJohn Forte break; 570fcf3ce44SJohn Forte } 571fcf3ce44SJohn Forte } 572fcf3ce44SJohn Forte if (count == map->NumberOfEntries) { 573fcf3ce44SJohn Forte lun_string = lun_resp->lun[lunCount].val; 574fcf3ce44SJohn Forte lunNum = ((lun_string[0] & 0x3F) << 8) | 575fcf3ce44SJohn Forte lun_string[1]; 576fcf3ce44SJohn Forte printLUNInfo(&inq, lunNum, "Unknown"); 577fcf3ce44SJohn Forte } 578fcf3ce44SJohn Forte } else { 579fcf3ce44SJohn Forte /* Not able to get any target mapping information */ 580fcf3ce44SJohn Forte lun_string = lun_resp->lun[lunCount].val; 581fcf3ce44SJohn Forte lunNum = ((lun_string[0] & 0x3F) << 8) | 582fcf3ce44SJohn Forte lun_string[1]; 583fcf3ce44SJohn Forte printLUNInfo(&inq, lunNum, "Unknown"); 584fcf3ce44SJohn Forte } 585fcf3ce44SJohn Forte } 586fcf3ce44SJohn Forte } 587fcf3ce44SJohn Forte 588fcf3ce44SJohn Forte /* 589fcf3ce44SJohn Forte * function to handle the list remoteport command 590fcf3ce44SJohn Forte * 591fcf3ce44SJohn Forte * Arguments: 592fcf3ce44SJohn Forte * wwnCount - the number of wwns in wwn_argv 593fcf3ce44SJohn Forte * if wwnCount == 0, then print information on all 594fcf3ce44SJohn Forte * remote ports. wwn_argv will not be used in this case 595fcf3ce44SJohn Forte * if wwnCount > 0, then print information for the WWNs 596fcf3ce44SJohn Forte * given in wwn_argv 597fcf3ce44SJohn Forte * wwn_argv - argument vector of WWNs 598fcf3ce44SJohn Forte * options - any options specified by the caller 599fcf3ce44SJohn Forte * 600fcf3ce44SJohn Forte * returns: 601fcf3ce44SJohn Forte * 0 if successful 602fcf3ce44SJohn Forte * 1 otherwise 603fcf3ce44SJohn Forte */ 604fcf3ce44SJohn Forte int 605fcf3ce44SJohn Forte fc_util_list_remoteport(int wwnCount, char **wwn_argv, cmdOptions_t *options) 606fcf3ce44SJohn Forte { 607fcf3ce44SJohn Forte HBA_STATUS status; 608fcf3ce44SJohn Forte HBA_FCPTARGETMAPPINGV2 *map = NULL; 609fcf3ce44SJohn Forte HBA_PORTATTRIBUTES port; 610fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attrs; 611fcf3ce44SJohn Forte HBA_HANDLE handle; 612fcf3ce44SJohn Forte uint64_t hbaPortWWN; 613fcf3ce44SJohn Forte HBA_WWN myhbaPortWWN; 614fcf3ce44SJohn Forte int processHBA_flags = 0, portCount = 0; 615fcf3ce44SJohn Forte int mode; 616fcf3ce44SJohn Forte 617fcf3ce44SJohn Forte /* grab the hba port wwn from the -p option */ 618fcf3ce44SJohn Forte for (; options->optval; options++) { 619fcf3ce44SJohn Forte if (options->optval == 'p') { 620fcf3ce44SJohn Forte sscanf(options->optarg, "%016llx", 621fcf3ce44SJohn Forte &hbaPortWWN); 622fcf3ce44SJohn Forte } else if (options->optval == 's') { 623fcf3ce44SJohn Forte processHBA_flags |= PRINT_SCSI_TARGET; 624fcf3ce44SJohn Forte } else if (options->optval == 'l') { 625fcf3ce44SJohn Forte processHBA_flags |= PRINT_LINKSTAT; 626fcf3ce44SJohn Forte } else { 627fcf3ce44SJohn Forte fprintf(stderr, gettext("Error: Illegal option: %c.\n"), 628fcf3ce44SJohn Forte options->optval); 629fcf3ce44SJohn Forte return (1); 630fcf3ce44SJohn Forte } 631fcf3ce44SJohn Forte } 632fcf3ce44SJohn Forte /* 633fcf3ce44SJohn Forte * -h option was not specified, this should not happen either. 634fcf3ce44SJohn Forte * cmdparse should catch this problem, but checking anyways 635fcf3ce44SJohn Forte */ 636fcf3ce44SJohn Forte if (hbaPortWWN == 0) { 637fcf3ce44SJohn Forte fprintf(stderr, 638fcf3ce44SJohn Forte gettext("Error: -p option was not specified.\n")); 639fcf3ce44SJohn Forte return (1); 640fcf3ce44SJohn Forte } 641fcf3ce44SJohn Forte if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) { 642fcf3ce44SJohn Forte fprintf(stderr, 643fcf3ce44SJohn Forte gettext("Failed to load FC-HBA common library\n")); 644fcf3ce44SJohn Forte printStatus(status); 645fcf3ce44SJohn Forte fprintf(stderr, "\n"); 646fcf3ce44SJohn Forte return (1); 647fcf3ce44SJohn Forte } 648fcf3ce44SJohn Forte hbaPortWWN = htonll(hbaPortWWN); 649fcf3ce44SJohn Forte memcpy(myhbaPortWWN.wwn, &hbaPortWWN, sizeof (hbaPortWWN)); 650fcf3ce44SJohn Forte if ((status = HBA_OpenAdapterByWWN(&handle, myhbaPortWWN)) 651fcf3ce44SJohn Forte != HBA_STATUS_OK) { 652fcf3ce44SJohn Forte status = Sun_HBA_OpenTgtAdapterByWWN(&handle, myhbaPortWWN); 653fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 654fcf3ce44SJohn Forte fprintf(stderr, 655fcf3ce44SJohn Forte gettext("Error: Failed to open adapter port. Reason ")); 656fcf3ce44SJohn Forte printStatus(status); 657fcf3ce44SJohn Forte fprintf(stderr, "\n"); 658fcf3ce44SJohn Forte HBA_FreeLibrary(); 659fcf3ce44SJohn Forte return (1); 660fcf3ce44SJohn Forte } else { 661fcf3ce44SJohn Forte if ((processHBA_flags & PRINT_SCSI_TARGET) == 662fcf3ce44SJohn Forte PRINT_SCSI_TARGET) { 663fcf3ce44SJohn Forte fprintf(stderr, gettext( 664fcf3ce44SJohn Forte "Error: Unsupported option for target mode: %c.\n"), 665fcf3ce44SJohn Forte 's'); 666fcf3ce44SJohn Forte HBA_FreeLibrary(); 667fcf3ce44SJohn Forte return (1); 668fcf3ce44SJohn Forte } 669fcf3ce44SJohn Forte mode = TARGET_MODE; 670fcf3ce44SJohn Forte } 671fcf3ce44SJohn Forte } else { 672fcf3ce44SJohn Forte mode = INITIATOR_MODE; 673fcf3ce44SJohn Forte } 674fcf3ce44SJohn Forte 675fcf3ce44SJohn Forte if ((processHBA_flags & PRINT_SCSI_TARGET) == PRINT_SCSI_TARGET) { 676fcf3ce44SJohn Forte getTargetMapping(handle, myhbaPortWWN, &map); 677fcf3ce44SJohn Forte } 678fcf3ce44SJohn Forte if (wwnCount == 0) { 679fcf3ce44SJohn Forte /* get adapater attributes for the given handle */ 680fcf3ce44SJohn Forte memset(&attrs, 0, sizeof (attrs)); 681fcf3ce44SJohn Forte memset(&port, 0, sizeof (port)); 682fcf3ce44SJohn Forte if (retrieveAttrs(handle, myhbaPortWWN, &attrs, &port, 683fcf3ce44SJohn Forte &portCount) != 0) { 684fcf3ce44SJohn Forte if (map != NULL) { 685fcf3ce44SJohn Forte free(map); 686fcf3ce44SJohn Forte } 687fcf3ce44SJohn Forte HBA_CloseAdapter(handle); 688fcf3ce44SJohn Forte HBA_FreeLibrary(); 689fcf3ce44SJohn Forte return (1); 690fcf3ce44SJohn Forte } 691fcf3ce44SJohn Forte processHBA(handle, attrs, portCount, port, map, REMOTE_PORT, 692fcf3ce44SJohn Forte processHBA_flags, mode); 693fcf3ce44SJohn Forte } else { 694fcf3ce44SJohn Forte processRemotePort(handle, myhbaPortWWN, map, wwnCount, 695fcf3ce44SJohn Forte wwn_argv, processHBA_flags); 696fcf3ce44SJohn Forte } 697fcf3ce44SJohn Forte if (map != NULL) { 698fcf3ce44SJohn Forte free(map); 699fcf3ce44SJohn Forte } 700fcf3ce44SJohn Forte HBA_CloseAdapter(handle); 701fcf3ce44SJohn Forte HBA_FreeLibrary(); 702fcf3ce44SJohn Forte return (0); 703fcf3ce44SJohn Forte } 704fcf3ce44SJohn Forte 705fcf3ce44SJohn Forte /* 706fcf3ce44SJohn Forte * process the hbaport object 707fcf3ce44SJohn Forte * 708fcf3ce44SJohn Forte * Arguments: 709fcf3ce44SJohn Forte * wwnCount - count of the number of WWNs in wwn_argv 710fcf3ce44SJohn Forte * if wwnCount > 0, then we will only print information for 711fcf3ce44SJohn Forte * the hba ports listed in wwn_argv 712fcf3ce44SJohn Forte * if wwnCount == 0, then we will print information on all hba ports 713fcf3ce44SJohn Forte * wwn_argv - argument array of hba port WWNs 714fcf3ce44SJohn Forte * options - any options specified by the caller 715fcf3ce44SJohn Forte * 716fcf3ce44SJohn Forte * returns: 717fcf3ce44SJohn Forte * 0 if successful 718fcf3ce44SJohn Forte * 1 otherwise 719fcf3ce44SJohn Forte */ 720fcf3ce44SJohn Forte int 721fcf3ce44SJohn Forte fc_util_list_hbaport(int wwnCount, char **wwn_argv, cmdOptions_t *options) 722fcf3ce44SJohn Forte { 723fcf3ce44SJohn Forte int port_wwn_counter, numAdapters = 0, numTgtAdapters = 0, i; 724fcf3ce44SJohn Forte HBA_STATUS status; 725fcf3ce44SJohn Forte char adapterName[256]; 726fcf3ce44SJohn Forte HBA_HANDLE handle; 727fcf3ce44SJohn Forte uint64_t hbaWWN; 728fcf3ce44SJohn Forte HBA_WWN myWWN; 729fcf3ce44SJohn Forte int processHBA_flags = 0; 730fcf3ce44SJohn Forte HBA_PORTATTRIBUTES port; 731fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attrs; 732fcf3ce44SJohn Forte int portIndex = 0, err_cnt = 0; 733fcf3ce44SJohn Forte int mode; 734fcf3ce44SJohn Forte 735fcf3ce44SJohn Forte /* process each of the options */ 736fcf3ce44SJohn Forte for (; options->optval; options++) { 737fcf3ce44SJohn Forte if (options->optval == 'l') { 738fcf3ce44SJohn Forte processHBA_flags |= PRINT_LINKSTAT; 739fcf3ce44SJohn Forte } else if (options->optval == 'i') { 740fcf3ce44SJohn Forte processHBA_flags |= PRINT_INITIATOR; 741fcf3ce44SJohn Forte } else if (options->optval == 't') { 742fcf3ce44SJohn Forte processHBA_flags |= PRINT_TARGET; 743*2a8164dfSZhong Wang } else if (options->optval == 'e') { 744*2a8164dfSZhong Wang processHBA_flags |= PRINT_FCOE; 745fcf3ce44SJohn Forte } 746fcf3ce44SJohn Forte } 747fcf3ce44SJohn Forte 748fcf3ce44SJohn Forte /* 749fcf3ce44SJohn Forte * Print both initiator and target if no initiator/target flag 750fcf3ce44SJohn Forte * specified. 751fcf3ce44SJohn Forte */ 752fcf3ce44SJohn Forte if (((processHBA_flags & PRINT_INITIATOR) == 0) && 753fcf3ce44SJohn Forte ((processHBA_flags & PRINT_TARGET) == 0)) { 754fcf3ce44SJohn Forte processHBA_flags |= PRINT_INITIATOR | PRINT_TARGET; 755fcf3ce44SJohn Forte } 756fcf3ce44SJohn Forte 757fcf3ce44SJohn Forte if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) { 758fcf3ce44SJohn Forte fprintf(stderr, 759fcf3ce44SJohn Forte gettext("Failed to load FC-HBA common library\n")); 760fcf3ce44SJohn Forte printStatus(status); 761fcf3ce44SJohn Forte fprintf(stderr, "\n"); 762fcf3ce44SJohn Forte return (1); 763fcf3ce44SJohn Forte } 764fcf3ce44SJohn Forte if (wwnCount > 0) { 765fcf3ce44SJohn Forte /* list only ports given in wwn_argv */ 766fcf3ce44SJohn Forte for (port_wwn_counter = 0; 767fcf3ce44SJohn Forte port_wwn_counter < wwnCount; 768fcf3ce44SJohn Forte port_wwn_counter++) { 769fcf3ce44SJohn Forte sscanf(wwn_argv[port_wwn_counter], "%016llx", &hbaWWN); 770fcf3ce44SJohn Forte hbaWWN = htonll(hbaWWN); 771fcf3ce44SJohn Forte memcpy(myWWN.wwn, &hbaWWN, sizeof (hbaWWN)); 772fcf3ce44SJohn Forte /* first check to see if it is an initiator port. */ 773fcf3ce44SJohn Forte if ((processHBA_flags & PRINT_INITIATOR) == 774fcf3ce44SJohn Forte PRINT_INITIATOR) { 775fcf3ce44SJohn Forte int times = 0; 776fcf3ce44SJohn Forte status = HBA_OpenAdapterByWWN(&handle, myWWN); 777fcf3ce44SJohn Forte while (status == HBA_STATUS_ERROR_TRY_AGAIN || 778fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) { 779fcf3ce44SJohn Forte (void) sleep(1); 780fcf3ce44SJohn Forte status = HBA_OpenAdapterByWWN(&handle, myWWN); 781fcf3ce44SJohn Forte if (times++ > HBA_MAX_RETRIES) { 782fcf3ce44SJohn Forte break; 783fcf3ce44SJohn Forte } 784fcf3ce44SJohn Forte } 785fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 786fcf3ce44SJohn Forte /* now see if it is a target mode FC port */ 787fcf3ce44SJohn Forte if ((processHBA_flags & PRINT_TARGET) == 788fcf3ce44SJohn Forte PRINT_TARGET) { 789fcf3ce44SJohn Forte status = 790fcf3ce44SJohn Forte Sun_HBA_OpenTgtAdapterByWWN(&handle, myWWN); 791fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 792fcf3ce44SJohn Forte fprintf(stderr, 793fcf3ce44SJohn Forte gettext( 794fcf3ce44SJohn Forte "Error: HBA port %s: not found\n"), 795fcf3ce44SJohn Forte wwn_argv[port_wwn_counter]); 796fcf3ce44SJohn Forte err_cnt++; 797fcf3ce44SJohn Forte continue; 798fcf3ce44SJohn Forte } else { 799fcf3ce44SJohn Forte /* set the port mode. */ 800fcf3ce44SJohn Forte mode = TARGET_MODE; 801fcf3ce44SJohn Forte } 802fcf3ce44SJohn Forte } else { 803fcf3ce44SJohn Forte fprintf(stderr, 804fcf3ce44SJohn Forte gettext( 805fcf3ce44SJohn Forte "Error: HBA port %s: not found\n"), 806fcf3ce44SJohn Forte wwn_argv[port_wwn_counter]); 807fcf3ce44SJohn Forte err_cnt++; 808fcf3ce44SJohn Forte continue; 809fcf3ce44SJohn Forte } 810fcf3ce44SJohn Forte } else { 811fcf3ce44SJohn Forte /* set the port mode. */ 812fcf3ce44SJohn Forte mode = INITIATOR_MODE; 813fcf3ce44SJohn Forte } 814fcf3ce44SJohn Forte /* try target mode discovery if print target is set. */ 815fcf3ce44SJohn Forte } else if ((processHBA_flags & PRINT_TARGET) == 816fcf3ce44SJohn Forte PRINT_TARGET) { 817fcf3ce44SJohn Forte status = 818fcf3ce44SJohn Forte Sun_HBA_OpenTgtAdapterByWWN(&handle, myWWN); 819fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 820fcf3ce44SJohn Forte fprintf(stderr, gettext( 821fcf3ce44SJohn Forte "Error: HBA port %s: not found\n"), 822fcf3ce44SJohn Forte wwn_argv[port_wwn_counter]); 823fcf3ce44SJohn Forte err_cnt++; 824fcf3ce44SJohn Forte continue; 825fcf3ce44SJohn Forte } else { 826fcf3ce44SJohn Forte /* set the port mode. */ 827fcf3ce44SJohn Forte mode = TARGET_MODE; 828fcf3ce44SJohn Forte } 829fcf3ce44SJohn Forte } else { 830fcf3ce44SJohn Forte /* should not get here. */ 831fcf3ce44SJohn Forte fprintf(stderr, gettext( 832fcf3ce44SJohn Forte "Error: HBA port %s: not found\n"), 833fcf3ce44SJohn Forte wwn_argv[port_wwn_counter]); 834fcf3ce44SJohn Forte err_cnt++; 835fcf3ce44SJohn Forte continue; 836fcf3ce44SJohn Forte } 837fcf3ce44SJohn Forte memset(&attrs, 0, sizeof (attrs)); 838fcf3ce44SJohn Forte memset(&port, 0, sizeof (port)); 839fcf3ce44SJohn Forte if (retrieveAttrs(handle, myWWN, &attrs, &port, 840fcf3ce44SJohn Forte &portIndex) != 0) { 841fcf3ce44SJohn Forte HBA_CloseAdapter(handle); 842fcf3ce44SJohn Forte continue; 843fcf3ce44SJohn Forte } 844fcf3ce44SJohn Forte processHBA(handle, attrs, portIndex, port, NULL, 845fcf3ce44SJohn Forte HBA_PORT, processHBA_flags, mode); 846*2a8164dfSZhong Wang if ((processHBA_flags & PRINT_FCOE) != PRINT_FCOE && 847*2a8164dfSZhong Wang attrs.VendorSpecificID != 0xFC0E && 848*2a8164dfSZhong Wang printHBANPIVPortInfo(handle, portIndex) != 0) { 849fcf3ce44SJohn Forte err_cnt++; 850fcf3ce44SJohn Forte } 851fcf3ce44SJohn Forte HBA_CloseAdapter(handle); 852fcf3ce44SJohn Forte } 853fcf3ce44SJohn Forte } else { 854fcf3ce44SJohn Forte /* 855fcf3ce44SJohn Forte * if PRINT_INITIATOR is specified, get the list of initiator 856fcf3ce44SJohn Forte * mod port. 857fcf3ce44SJohn Forte */ 858fcf3ce44SJohn Forte if ((processHBA_flags & PRINT_INITIATOR) == PRINT_INITIATOR) { 859fcf3ce44SJohn Forte numAdapters = HBA_GetNumberOfAdapters(); 860fcf3ce44SJohn Forte if ((numAdapters == 0) && 861fcf3ce44SJohn Forte ((processHBA_flags & ~PRINT_INITIATOR) == 0)) { 862fcf3ce44SJohn Forte fprintf(stdout, gettext("No Adapters Found.\n")); 863fcf3ce44SJohn Forte } 864fcf3ce44SJohn Forte for (i = 0; i < numAdapters; i++) { 865fcf3ce44SJohn Forte int times = 0; 866fcf3ce44SJohn Forte status = HBA_GetAdapterName(i, adapterName); 867fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 868fcf3ce44SJohn Forte fprintf(stderr, gettext( 869fcf3ce44SJohn Forte "failed to get adapter %d. Reason: "), i); 870fcf3ce44SJohn Forte printStatus(status); 871fcf3ce44SJohn Forte fprintf(stderr, "\n"); 872fcf3ce44SJohn Forte continue; 873fcf3ce44SJohn Forte } 874fcf3ce44SJohn Forte if ((handle = HBA_OpenAdapter(adapterName)) == 0) { 875fcf3ce44SJohn Forte fprintf(stderr, gettext( 876fcf3ce44SJohn Forte "Failed to open adapter %s.\n"), 877fcf3ce44SJohn Forte adapterName); 878fcf3ce44SJohn Forte continue; 879fcf3ce44SJohn Forte } 880fcf3ce44SJohn Forte /* get adapater attributes for the given handle */ 881fcf3ce44SJohn Forte memset(&attrs, 0, sizeof (attrs)); 882fcf3ce44SJohn Forte status = 883fcf3ce44SJohn Forte Sun_HBA_NPIVGetAdapterAttributes(handle, 884fcf3ce44SJohn Forte &attrs); 885fcf3ce44SJohn Forte while ((status == HBA_STATUS_ERROR_TRY_AGAIN || 886fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) && 887fcf3ce44SJohn Forte times++ < HBA_MAX_RETRIES) { 888fcf3ce44SJohn Forte (void) sleep(1); 889fcf3ce44SJohn Forte status = 890fcf3ce44SJohn Forte Sun_HBA_NPIVGetAdapterAttributes(handle, 891fcf3ce44SJohn Forte &attrs); 892fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) { 893fcf3ce44SJohn Forte break; 894fcf3ce44SJohn Forte } 895fcf3ce44SJohn Forte } 896fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 897fcf3ce44SJohn Forte fprintf(stderr, 898fcf3ce44SJohn Forte gettext("Failed to get adapter attributes " 899fcf3ce44SJohn Forte "handle(%d) Reason: "), handle); 900fcf3ce44SJohn Forte printStatus(status); 901fcf3ce44SJohn Forte fprintf(stderr, "\n"); 90263c17d01SRaghuram Prahlada HBA_CloseAdapter(handle); 903fcf3ce44SJohn Forte continue; 904fcf3ce44SJohn Forte } 905fcf3ce44SJohn Forte 906fcf3ce44SJohn Forte /* process each port on the given adatpter */ 907fcf3ce44SJohn Forte for (portIndex = 0; 908fcf3ce44SJohn Forte portIndex < attrs.NumberOfPorts; 909fcf3ce44SJohn Forte portIndex++) { 910fcf3ce44SJohn Forte memset(&port, 0, sizeof (port)); 911fcf3ce44SJohn Forte if ((status = HBA_GetAdapterPortAttributes( 912fcf3ce44SJohn Forte handle, portIndex, &port)) 913fcf3ce44SJohn Forte != HBA_STATUS_OK) { 914fcf3ce44SJohn Forte /* 915fcf3ce44SJohn Forte * not able to get port attributes. 916fcf3ce44SJohn Forte * print out error * message and move 917fcf3ce44SJohn Forte * on to the next port 918fcf3ce44SJohn Forte */ 919fcf3ce44SJohn Forte fprintf(stderr, 920fcf3ce44SJohn Forte gettext("Error: Failed to get port " 921fcf3ce44SJohn Forte "(%d) attributes reason: "), 922fcf3ce44SJohn Forte portIndex); 923fcf3ce44SJohn Forte printStatus(status); 924fcf3ce44SJohn Forte fprintf(stderr, "\n"); 925fcf3ce44SJohn Forte continue; 926fcf3ce44SJohn Forte } 927fcf3ce44SJohn Forte processHBA(handle, attrs, portIndex, port, 928fcf3ce44SJohn Forte NULL, HBA_PORT, processHBA_flags, 929fcf3ce44SJohn Forte INITIATOR_MODE); 930*2a8164dfSZhong Wang if ((processHBA_flags & PRINT_FCOE) != 931*2a8164dfSZhong Wang PRINT_FCOE && 932*2a8164dfSZhong Wang attrs.VendorSpecificID != 0xFC0E && 933*2a8164dfSZhong Wang printHBANPIVPortInfo(handle, 934*2a8164dfSZhong Wang portIndex) != 0) { 935fcf3ce44SJohn Forte err_cnt++; 936fcf3ce44SJohn Forte } 937fcf3ce44SJohn Forte } 938fcf3ce44SJohn Forte HBA_CloseAdapter(handle); 939fcf3ce44SJohn Forte } 940fcf3ce44SJohn Forte } 941fcf3ce44SJohn Forte 942fcf3ce44SJohn Forte /* 943fcf3ce44SJohn Forte * Get the info on the target mode FC port if PRINT_TARGET 944fcf3ce44SJohn Forte * is specified. 945fcf3ce44SJohn Forte */ 946fcf3ce44SJohn Forte if ((processHBA_flags & PRINT_TARGET) == PRINT_TARGET) { 947fcf3ce44SJohn Forte numTgtAdapters = Sun_HBA_GetNumberOfTgtAdapters(); 948fcf3ce44SJohn Forte if (numTgtAdapters == 0 && numAdapters == 0) { 949fcf3ce44SJohn Forte fprintf(stdout, 950fcf3ce44SJohn Forte gettext("No Adapters Found.\n")); 951fcf3ce44SJohn Forte } 952fcf3ce44SJohn Forte for (i = 0; i < numTgtAdapters; i++) { 953fcf3ce44SJohn Forte status = Sun_HBA_GetTgtAdapterName(i, adapterName); 954fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 955fcf3ce44SJohn Forte fprintf(stderr, gettext( 956fcf3ce44SJohn Forte "failed to get adapter %d. Reason: "), i); 957fcf3ce44SJohn Forte printStatus(status); 958fcf3ce44SJohn Forte fprintf(stderr, "\n"); 959fcf3ce44SJohn Forte continue; 960fcf3ce44SJohn Forte } 961fcf3ce44SJohn Forte if ((handle = Sun_HBA_OpenTgtAdapter(adapterName)) 962fcf3ce44SJohn Forte == 0) { 963fcf3ce44SJohn Forte fprintf(stderr, gettext( 964fcf3ce44SJohn Forte "Failed to open adapter %s.\n"), adapterName); 965fcf3ce44SJohn Forte continue; 966fcf3ce44SJohn Forte } 967fcf3ce44SJohn Forte /* get adapater attributes for the given handle */ 968fcf3ce44SJohn Forte memset(&attrs, 0, sizeof (attrs)); 969fcf3ce44SJohn Forte if ((status = HBA_GetAdapterAttributes(handle, &attrs)) 970fcf3ce44SJohn Forte != HBA_STATUS_OK) { 971fcf3ce44SJohn Forte fprintf(stderr, 972fcf3ce44SJohn Forte gettext("Failed to get target mode adapter" 973fcf3ce44SJohn Forte "attributes handle(%d) Reason: "), 974fcf3ce44SJohn Forte handle); 975fcf3ce44SJohn Forte printStatus(status); 976fcf3ce44SJohn Forte fprintf(stderr, "\n"); 977fcf3ce44SJohn Forte continue; 978fcf3ce44SJohn Forte } 979fcf3ce44SJohn Forte 980fcf3ce44SJohn Forte /* process each port on the given adatpter */ 981fcf3ce44SJohn Forte for (portIndex = 0; 982fcf3ce44SJohn Forte portIndex < attrs.NumberOfPorts; 983fcf3ce44SJohn Forte portIndex++) { 984fcf3ce44SJohn Forte memset(&port, 0, sizeof (port)); 985fcf3ce44SJohn Forte if ((status = HBA_GetAdapterPortAttributes( 986fcf3ce44SJohn Forte handle, portIndex, &port)) 987fcf3ce44SJohn Forte != HBA_STATUS_OK) { 988fcf3ce44SJohn Forte /* 989fcf3ce44SJohn Forte * not able to get port attributes. 990fcf3ce44SJohn Forte * print out error * message and move 991fcf3ce44SJohn Forte * on to the next port 992fcf3ce44SJohn Forte */ 993fcf3ce44SJohn Forte fprintf(stderr, 994fcf3ce44SJohn Forte gettext("Error: Failed to get port " 995fcf3ce44SJohn Forte "(%d) attributes reason: "), 996fcf3ce44SJohn Forte portIndex); 997fcf3ce44SJohn Forte printStatus(status); 998fcf3ce44SJohn Forte fprintf(stderr, "\n"); 999fcf3ce44SJohn Forte continue; 1000fcf3ce44SJohn Forte } 1001fcf3ce44SJohn Forte processHBA(handle, attrs, portIndex, port, 1002fcf3ce44SJohn Forte NULL, HBA_PORT, processHBA_flags, 1003fcf3ce44SJohn Forte TARGET_MODE); 1004fcf3ce44SJohn Forte } 1005fcf3ce44SJohn Forte HBA_CloseAdapter(handle); 1006fcf3ce44SJohn Forte } 1007fcf3ce44SJohn Forte } 1008fcf3ce44SJohn Forte } 1009fcf3ce44SJohn Forte 1010fcf3ce44SJohn Forte HBA_FreeLibrary(); 1011fcf3ce44SJohn Forte 1012fcf3ce44SJohn Forte /* 1013fcf3ce44SJohn Forte * print additional error msg for partial failure when more than 1014fcf3ce44SJohn Forte * one wwn is specified. 1015fcf3ce44SJohn Forte */ 1016fcf3ce44SJohn Forte if (err_cnt != 0) { 1017fcf3ce44SJohn Forte if (wwnCount > 1) { 1018fcf3ce44SJohn Forte if (err_cnt == wwnCount) { 1019fcf3ce44SJohn Forte fprintf(stderr, gettext( 1020fcf3ce44SJohn Forte "Error: All specified HBA ports are not found\n")); 1021fcf3ce44SJohn Forte } else { 1022fcf3ce44SJohn Forte fprintf(stderr, gettext( 1023fcf3ce44SJohn Forte "Error: Some of specified HBA ports are not found\n")); 1024fcf3ce44SJohn Forte } 1025fcf3ce44SJohn Forte } 1026fcf3ce44SJohn Forte return (1); 1027fcf3ce44SJohn Forte } 1028fcf3ce44SJohn Forte 1029fcf3ce44SJohn Forte return (0); 1030fcf3ce44SJohn Forte } 1031fcf3ce44SJohn Forte 1032fcf3ce44SJohn Forte /* 1033fcf3ce44SJohn Forte * Search the existing device list 1034fcf3ce44SJohn Forte * 1035fcf3ce44SJohn Forte * Take one of two actions: 1036fcf3ce44SJohn Forte * 1037fcf3ce44SJohn Forte * Add an entry if an entry doesn't exist 1038fcf3ce44SJohn Forte * Add WWN data to it if an entry does exist 1039fcf3ce44SJohn Forte * 1040fcf3ce44SJohn Forte * Arguments: 1041fcf3ce44SJohn Forte * devList - OS device path list 1042fcf3ce44SJohn Forte * map - target mapping data 1043fcf3ce44SJohn Forte * index - index into target mapping data 1044fcf3ce44SJohn Forte * initiatorPortWWN - HBA port WWN 1045fcf3ce44SJohn Forte * verbose - boolean indicating whether to get additional data 1046fcf3ce44SJohn Forte * 1047fcf3ce44SJohn Forte * returns: 1048fcf3ce44SJohn Forte * none 1049fcf3ce44SJohn Forte */ 1050fcf3ce44SJohn Forte static void 1051fcf3ce44SJohn Forte searchDevice(discoveredDevice **devList, HBA_FCPSCSIENTRYV2 entry, 1052fcf3ce44SJohn Forte HBA_WWN initiatorPortWWN, HBA_HANDLE handle, boolean_t verbose) 1053fcf3ce44SJohn Forte { 1054fcf3ce44SJohn Forte discoveredDevice *discoveredDevList, *newDevice; 1055fcf3ce44SJohn Forte portWWNList *WWNList, *newWWN; 1056fcf3ce44SJohn Forte tgtPortWWNList *newTgtWWN; 1057fcf3ce44SJohn Forte boolean_t foundDevice = B_FALSE, foundWWN; 1058fcf3ce44SJohn Forte struct scsi_inquiry inq; 1059fcf3ce44SJohn Forte struct scsi_extended_sense sense; 1060fcf3ce44SJohn Forte HBA_UINT32 responseSize, senseSize = 0; 1061fcf3ce44SJohn Forte HBA_UINT8 inq_status; 1062fcf3ce44SJohn Forte HBA_STATUS status; 1063fcf3ce44SJohn Forte 1064fcf3ce44SJohn Forte for (discoveredDevList = *devList; discoveredDevList != NULL; 1065fcf3ce44SJohn Forte discoveredDevList = discoveredDevList->next) { 1066fcf3ce44SJohn Forte if (strcmp(entry.ScsiId.OSDeviceName, 1067fcf3ce44SJohn Forte discoveredDevList->OSDeviceName) == 0) { 1068fcf3ce44SJohn Forte /* 1069fcf3ce44SJohn Forte * if only device names are requested, 1070fcf3ce44SJohn Forte * no reason to go any further 1071fcf3ce44SJohn Forte */ 1072fcf3ce44SJohn Forte if (verbose == B_FALSE) { 1073fcf3ce44SJohn Forte return; 1074fcf3ce44SJohn Forte } 1075fcf3ce44SJohn Forte foundDevice = B_TRUE; 1076fcf3ce44SJohn Forte break; 1077fcf3ce44SJohn Forte } 1078fcf3ce44SJohn Forte } 1079fcf3ce44SJohn Forte if (foundDevice == B_TRUE) { 1080fcf3ce44SJohn Forte /* add initiator Port WWN if it doesn't exist */ 1081fcf3ce44SJohn Forte for (WWNList = discoveredDevList->HBAPortWWN, 1082fcf3ce44SJohn Forte foundWWN = B_FALSE; WWNList != NULL; 1083fcf3ce44SJohn Forte WWNList = WWNList->next) { 1084fcf3ce44SJohn Forte if (memcmp((void *)&(WWNList->portWWN), 1085fcf3ce44SJohn Forte (void *)&initiatorPortWWN, 1086fcf3ce44SJohn Forte sizeof (HBA_WWN)) == 0) { 1087fcf3ce44SJohn Forte foundWWN = B_TRUE; 1088fcf3ce44SJohn Forte break; 1089fcf3ce44SJohn Forte } 1090fcf3ce44SJohn Forte } 1091fcf3ce44SJohn Forte if (discoveredDevList->inqSuccess == B_FALSE) { 1092fcf3ce44SJohn Forte responseSize = sizeof (struct scsi_inquiry); 1093fcf3ce44SJohn Forte senseSize = sizeof (struct scsi_extended_sense); 1094fcf3ce44SJohn Forte memset(&inq, 0, sizeof (struct scsi_inquiry)); 1095fcf3ce44SJohn Forte memset(&sense, 0, sizeof (sense)); 1096fcf3ce44SJohn Forte status = HBA_ScsiInquiryV2( 1097fcf3ce44SJohn Forte handle, 1098fcf3ce44SJohn Forte initiatorPortWWN, 1099fcf3ce44SJohn Forte entry.FcpId.PortWWN, 1100fcf3ce44SJohn Forte entry.FcpId.FcpLun, 1101fcf3ce44SJohn Forte 0, /* CDB Byte 1 */ 1102fcf3ce44SJohn Forte 0, /* CDB Byte 2 */ 1103fcf3ce44SJohn Forte &inq, &responseSize, 1104fcf3ce44SJohn Forte &inq_status, 1105fcf3ce44SJohn Forte &sense, &senseSize); 1106fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) { 1107fcf3ce44SJohn Forte memcpy(discoveredDevList->VID, inq.inq_vid, 1108fcf3ce44SJohn Forte sizeof (discoveredDevList->VID)); 1109fcf3ce44SJohn Forte memcpy(discoveredDevList->PID, inq.inq_pid, 1110fcf3ce44SJohn Forte sizeof (discoveredDevList->PID)); 1111fcf3ce44SJohn Forte discoveredDevList->dType = inq.inq_dtype; 1112fcf3ce44SJohn Forte discoveredDevList->inqSuccess = B_TRUE; 1113fcf3ce44SJohn Forte } 1114fcf3ce44SJohn Forte } 1115fcf3ce44SJohn Forte 1116fcf3ce44SJohn Forte if (foundWWN == B_FALSE) { 1117fcf3ce44SJohn Forte newWWN = (portWWNList *)calloc(1, sizeof (portWWNList)); 1118fcf3ce44SJohn Forte if (newWWN == NULL) { 1119fcf3ce44SJohn Forte perror("Out of memory"); 1120fcf3ce44SJohn Forte exit(1); 1121fcf3ce44SJohn Forte } 1122fcf3ce44SJohn Forte 1123fcf3ce44SJohn Forte /* insert at head */ 1124fcf3ce44SJohn Forte newWWN->next = discoveredDevList->HBAPortWWN; 1125fcf3ce44SJohn Forte discoveredDevList->HBAPortWWN = newWWN; 1126fcf3ce44SJohn Forte memcpy((void *)&(newWWN->portWWN), 1127fcf3ce44SJohn Forte (void *)&initiatorPortWWN, 1128fcf3ce44SJohn Forte sizeof (newWWN->portWWN)); 1129fcf3ce44SJohn Forte /* add Target Port */ 1130fcf3ce44SJohn Forte newWWN->tgtPortWWN = (tgtPortWWNList *)calloc(1, 1131fcf3ce44SJohn Forte sizeof (tgtPortWWNList)); 1132fcf3ce44SJohn Forte if (newWWN->tgtPortWWN == NULL) { 1133fcf3ce44SJohn Forte perror("Out of memory"); 1134fcf3ce44SJohn Forte exit(1); 1135fcf3ce44SJohn Forte } 1136fcf3ce44SJohn Forte 1137fcf3ce44SJohn Forte memcpy((void *)&(newWWN->tgtPortWWN->portWWN), 1138fcf3ce44SJohn Forte (void *)&(entry.FcpId.PortWWN), 1139fcf3ce44SJohn Forte sizeof (newWWN->tgtPortWWN->portWWN)); 1140fcf3ce44SJohn Forte /* Set LUN data */ 1141fcf3ce44SJohn Forte newWWN->tgtPortWWN->scsiOSLun = entry.ScsiId.ScsiOSLun; 1142fcf3ce44SJohn Forte } else { /* add it to existing */ 1143fcf3ce44SJohn Forte newTgtWWN = (tgtPortWWNList *)calloc(1, 1144fcf3ce44SJohn Forte sizeof (tgtPortWWNList)); 1145fcf3ce44SJohn Forte if (newTgtWWN == NULL) { 1146fcf3ce44SJohn Forte perror("Out of memory"); 1147fcf3ce44SJohn Forte exit(1); 1148fcf3ce44SJohn Forte } 1149fcf3ce44SJohn Forte /* insert at head */ 1150fcf3ce44SJohn Forte newTgtWWN->next = WWNList->tgtPortWWN; 1151fcf3ce44SJohn Forte WWNList->tgtPortWWN = newTgtWWN; 1152fcf3ce44SJohn Forte memcpy((void *)&(newTgtWWN->portWWN), 1153fcf3ce44SJohn Forte (void *)&(entry.FcpId.PortWWN), 1154fcf3ce44SJohn Forte sizeof (newTgtWWN->portWWN)); 1155fcf3ce44SJohn Forte /* Set LUN data */ 1156fcf3ce44SJohn Forte newTgtWWN->scsiOSLun = entry.ScsiId.ScsiOSLun; 1157fcf3ce44SJohn Forte } 1158fcf3ce44SJohn Forte } else { /* add new entry */ 1159fcf3ce44SJohn Forte newDevice = (discoveredDevice *)calloc(1, 1160fcf3ce44SJohn Forte sizeof (discoveredDevice)); 1161fcf3ce44SJohn Forte if (newDevice == NULL) { 1162fcf3ce44SJohn Forte perror("Out of memory"); 1163fcf3ce44SJohn Forte exit(1); 1164fcf3ce44SJohn Forte } 1165fcf3ce44SJohn Forte newDevice->next = *devList; /* insert at head */ 1166fcf3ce44SJohn Forte *devList = newDevice; /* set new head */ 1167fcf3ce44SJohn Forte 1168fcf3ce44SJohn Forte /* Copy device name */ 1169fcf3ce44SJohn Forte strncpy(newDevice->OSDeviceName, entry.ScsiId.OSDeviceName, 1170fcf3ce44SJohn Forte sizeof (newDevice->OSDeviceName) - 1); 1171fcf3ce44SJohn Forte 1172fcf3ce44SJohn Forte /* 1173fcf3ce44SJohn Forte * if only device names are requested, 1174fcf3ce44SJohn Forte * no reason to go any further 1175fcf3ce44SJohn Forte */ 1176fcf3ce44SJohn Forte if (verbose == B_FALSE) { 1177fcf3ce44SJohn Forte return; 1178fcf3ce44SJohn Forte } 1179fcf3ce44SJohn Forte 1180fcf3ce44SJohn Forte /* 1181fcf3ce44SJohn Forte * copy WWN data 1182fcf3ce44SJohn Forte */ 1183fcf3ce44SJohn Forte newDevice->HBAPortWWN = (portWWNList *)calloc(1, 1184fcf3ce44SJohn Forte sizeof (portWWNList)); 1185fcf3ce44SJohn Forte if (newDevice->HBAPortWWN == NULL) { 1186fcf3ce44SJohn Forte perror("Out of memory"); 1187fcf3ce44SJohn Forte exit(1); 1188fcf3ce44SJohn Forte } 1189fcf3ce44SJohn Forte memcpy((void *)&(newDevice->HBAPortWWN->portWWN), 1190fcf3ce44SJohn Forte (void *)&initiatorPortWWN, sizeof (newWWN->portWWN)); 1191fcf3ce44SJohn Forte 1192fcf3ce44SJohn Forte newDevice->HBAPortWWN->tgtPortWWN = 1193fcf3ce44SJohn Forte (tgtPortWWNList *)calloc(1, sizeof (tgtPortWWNList)); 1194fcf3ce44SJohn Forte if (newDevice->HBAPortWWN->tgtPortWWN == NULL) { 1195fcf3ce44SJohn Forte perror("Out of memory"); 1196fcf3ce44SJohn Forte exit(1); 1197fcf3ce44SJohn Forte } 1198fcf3ce44SJohn Forte 1199fcf3ce44SJohn Forte memcpy((void *)&(newDevice->HBAPortWWN->tgtPortWWN->portWWN), 1200fcf3ce44SJohn Forte (void *)&(entry.FcpId.PortWWN), 1201fcf3ce44SJohn Forte sizeof (newDevice->HBAPortWWN->tgtPortWWN->portWWN)); 1202fcf3ce44SJohn Forte 1203fcf3ce44SJohn Forte /* Set LUN data */ 1204fcf3ce44SJohn Forte newDevice->HBAPortWWN->tgtPortWWN->scsiOSLun = 1205fcf3ce44SJohn Forte entry.ScsiId.ScsiOSLun; 1206fcf3ce44SJohn Forte 1207fcf3ce44SJohn Forte responseSize = sizeof (struct scsi_inquiry); 1208fcf3ce44SJohn Forte senseSize = sizeof (struct scsi_extended_sense); 1209fcf3ce44SJohn Forte memset(&inq, 0, sizeof (struct scsi_inquiry)); 1210fcf3ce44SJohn Forte memset(&sense, 0, sizeof (sense)); 1211fcf3ce44SJohn Forte status = HBA_ScsiInquiryV2( 1212fcf3ce44SJohn Forte handle, 1213fcf3ce44SJohn Forte initiatorPortWWN, 1214fcf3ce44SJohn Forte entry.FcpId.PortWWN, 1215fcf3ce44SJohn Forte entry.FcpId.FcpLun, 1216fcf3ce44SJohn Forte 0, /* CDB Byte 1 */ 1217fcf3ce44SJohn Forte 0, /* CDB Byte 2 */ 1218fcf3ce44SJohn Forte &inq, &responseSize, 1219fcf3ce44SJohn Forte &inq_status, 1220fcf3ce44SJohn Forte &sense, &senseSize); 1221fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 1222fcf3ce44SJohn Forte /* initialize VID/PID/dType as "Unknown" */ 1223fcf3ce44SJohn Forte strcpy(newDevice->VID, "Unknown"); 1224fcf3ce44SJohn Forte strcpy(newDevice->PID, "Unknown"); 1225fcf3ce44SJohn Forte newDevice->dType = DTYPE_UNKNOWN; 1226fcf3ce44SJohn Forte /* initialize inq status */ 1227fcf3ce44SJohn Forte newDevice->inqSuccess = B_FALSE; 1228fcf3ce44SJohn Forte } else { 1229fcf3ce44SJohn Forte memcpy(newDevice->VID, inq.inq_vid, 1230fcf3ce44SJohn Forte sizeof (newDevice->VID)); 1231fcf3ce44SJohn Forte memcpy(newDevice->PID, inq.inq_pid, 1232fcf3ce44SJohn Forte sizeof (newDevice->PID)); 1233fcf3ce44SJohn Forte newDevice->dType = inq.inq_dtype; 1234fcf3ce44SJohn Forte /* initialize inq status */ 1235fcf3ce44SJohn Forte newDevice->inqSuccess = B_TRUE; 1236fcf3ce44SJohn Forte } 1237fcf3ce44SJohn Forte } 1238fcf3ce44SJohn Forte } 1239fcf3ce44SJohn Forte 1240fcf3ce44SJohn Forte 1241fcf3ce44SJohn Forte /* 1242fcf3ce44SJohn Forte * process the logical-unit object 1243fcf3ce44SJohn Forte * 1244fcf3ce44SJohn Forte * Arguments: 1245fcf3ce44SJohn Forte * luCount - count of the number of device paths in paths_argv 1246fcf3ce44SJohn Forte * if pathCount > 0, then we will only print information for 1247fcf3ce44SJohn Forte * the device paths listed in paths_argv 1248fcf3ce44SJohn Forte * if pathCount == 0, then we will print information on all device 1249fcf3ce44SJohn Forte * paths 1250fcf3ce44SJohn Forte * luArgv - argument array of device paths 1251fcf3ce44SJohn Forte * options - any options specified by the caller 1252fcf3ce44SJohn Forte * 1253fcf3ce44SJohn Forte * returns: 1254fcf3ce44SJohn Forte * 0 if successful 1255fcf3ce44SJohn Forte * > 0 otherwise 1256fcf3ce44SJohn Forte */ 1257fcf3ce44SJohn Forte int 1258fcf3ce44SJohn Forte fc_util_list_logicalunit(int luCount, char **luArgv, cmdOptions_t *options) 1259fcf3ce44SJohn Forte { 1260fcf3ce44SJohn Forte int pathCtr, numAdapters, i, count; 1261fcf3ce44SJohn Forte HBA_STATUS status; 1262fcf3ce44SJohn Forte char adapterName[256]; 1263fcf3ce44SJohn Forte HBA_HANDLE handle; 1264fcf3ce44SJohn Forte HBA_PORTATTRIBUTES port; 1265fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attrs; 1266fcf3ce44SJohn Forte int portIndex = 0; 1267fcf3ce44SJohn Forte int ret = 0; 1268fcf3ce44SJohn Forte boolean_t verbose = B_FALSE; 1269fcf3ce44SJohn Forte HBA_FCPTARGETMAPPINGV2 *map = NULL; 1270fcf3ce44SJohn Forte discoveredDevice *devListWalk, *devList = NULL; 1271fcf3ce44SJohn Forte boolean_t pathFound; 1272fcf3ce44SJohn Forte 1273fcf3ce44SJohn Forte /* process each of the options */ 1274fcf3ce44SJohn Forte for (; options->optval; options++) { 1275fcf3ce44SJohn Forte if (options->optval == 'v') { 1276fcf3ce44SJohn Forte verbose = B_TRUE; 1277fcf3ce44SJohn Forte } 1278fcf3ce44SJohn Forte } 1279fcf3ce44SJohn Forte 1280fcf3ce44SJohn Forte if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) { 1281fcf3ce44SJohn Forte fprintf(stderr, 1282fcf3ce44SJohn Forte gettext("Failed to load FC-HBA common library\n")); 1283fcf3ce44SJohn Forte printStatus(status); 1284fcf3ce44SJohn Forte fprintf(stderr, "\n"); 1285fcf3ce44SJohn Forte return (1); 1286fcf3ce44SJohn Forte } 1287fcf3ce44SJohn Forte /* 1288fcf3ce44SJohn Forte * Retrieve all device paths. We'll need to traverse the list 1289fcf3ce44SJohn Forte * until we find the input paths or all paths if none were given. We 1290fcf3ce44SJohn Forte * cannot print as we go since there can be duplicate paths returned 1291fcf3ce44SJohn Forte */ 1292fcf3ce44SJohn Forte numAdapters = HBA_GetNumberOfAdapters(); 1293fcf3ce44SJohn Forte if (numAdapters == 0) { 1294fcf3ce44SJohn Forte return (0); 1295fcf3ce44SJohn Forte } 1296fcf3ce44SJohn Forte for (i = 0; i < numAdapters; i++) { 1297fcf3ce44SJohn Forte int times; 1298fcf3ce44SJohn Forte status = HBA_GetAdapterName(i, adapterName); 1299fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 1300fcf3ce44SJohn Forte fprintf(stderr, gettext( 1301fcf3ce44SJohn Forte "Failed to get adapter %d. Reason: "), i); 1302fcf3ce44SJohn Forte printStatus(status); 1303fcf3ce44SJohn Forte fprintf(stderr, "\n"); 1304fcf3ce44SJohn Forte ret++; 1305fcf3ce44SJohn Forte continue; 1306fcf3ce44SJohn Forte } 1307fcf3ce44SJohn Forte if ((handle = HBA_OpenAdapter(adapterName)) == 0) { 1308fcf3ce44SJohn Forte fprintf(stderr, gettext("Failed to open adapter %s\n"), 1309fcf3ce44SJohn Forte adapterName); 1310fcf3ce44SJohn Forte ret++; 1311fcf3ce44SJohn Forte continue; 1312fcf3ce44SJohn Forte } 1313fcf3ce44SJohn Forte /* get adapter attributes for the given handle */ 1314fcf3ce44SJohn Forte memset(&attrs, 0, sizeof (attrs)); 1315fcf3ce44SJohn Forte times = 0; 1316fcf3ce44SJohn Forte status = HBA_GetAdapterAttributes(handle, &attrs); 1317fcf3ce44SJohn Forte while ((status == HBA_STATUS_ERROR_TRY_AGAIN || 1318fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) && 1319fcf3ce44SJohn Forte times++ < HBA_MAX_RETRIES) { 1320fcf3ce44SJohn Forte (void) sleep(1); 1321fcf3ce44SJohn Forte status = HBA_GetAdapterAttributes(handle, &attrs); 1322fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) { 1323fcf3ce44SJohn Forte break; 1324fcf3ce44SJohn Forte } 1325fcf3ce44SJohn Forte } 1326fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) { 1327fcf3ce44SJohn Forte fprintf(stderr, 1328fcf3ce44SJohn Forte gettext("Failed to get adapter attributes " 1329fcf3ce44SJohn Forte "handle(%d) Reason: "), handle); 1330fcf3ce44SJohn Forte printStatus(status); 1331fcf3ce44SJohn Forte fprintf(stderr, "\n"); 1332fcf3ce44SJohn Forte ret++; 133363c17d01SRaghuram Prahlada HBA_CloseAdapter(handle); 1334fcf3ce44SJohn Forte continue; 1335fcf3ce44SJohn Forte } 1336fcf3ce44SJohn Forte 1337fcf3ce44SJohn Forte /* process each port on adapter */ 1338fcf3ce44SJohn Forte for (portIndex = 0; portIndex < attrs.NumberOfPorts; 1339fcf3ce44SJohn Forte portIndex++) { 1340fcf3ce44SJohn Forte memset(&port, 0, sizeof (port)); 1341fcf3ce44SJohn Forte if ((status = HBA_GetAdapterPortAttributes(handle, 1342fcf3ce44SJohn Forte portIndex, &port)) != HBA_STATUS_OK) { 1343fcf3ce44SJohn Forte /* 1344fcf3ce44SJohn Forte * not able to get port attributes. 1345fcf3ce44SJohn Forte * print out error message and move 1346fcf3ce44SJohn Forte * on to the next port 1347fcf3ce44SJohn Forte */ 1348fcf3ce44SJohn Forte fprintf(stderr, gettext("Failed to get port " 1349fcf3ce44SJohn Forte "(%d) attributes reason: "), 1350fcf3ce44SJohn Forte portIndex); 1351fcf3ce44SJohn Forte printStatus(status); 1352fcf3ce44SJohn Forte fprintf(stderr, "\n"); 1353fcf3ce44SJohn Forte ret++; 1354fcf3ce44SJohn Forte continue; 1355fcf3ce44SJohn Forte } 1356fcf3ce44SJohn Forte 1357fcf3ce44SJohn Forte /* get OS Device Paths */ 1358fcf3ce44SJohn Forte getTargetMapping(handle, port.PortWWN, &map); 1359fcf3ce44SJohn Forte if (map != NULL) { 1360fcf3ce44SJohn Forte for (count = 0; count < map->NumberOfEntries; 1361fcf3ce44SJohn Forte count++) { 1362fcf3ce44SJohn Forte searchDevice(&devList, 1363fcf3ce44SJohn Forte map->entry[count], port.PortWWN, 1364fcf3ce44SJohn Forte handle, verbose); 1365fcf3ce44SJohn Forte } 1366fcf3ce44SJohn Forte } 1367fcf3ce44SJohn Forte } 1368fcf3ce44SJohn Forte HBA_CloseAdapter(handle); 1369fcf3ce44SJohn Forte } 1370fcf3ce44SJohn Forte HBA_FreeLibrary(); 1371fcf3ce44SJohn Forte 1372fcf3ce44SJohn Forte if (luCount == 0) { 1373fcf3ce44SJohn Forte /* list all paths */ 1374fcf3ce44SJohn Forte for (devListWalk = devList; devListWalk != NULL; 1375fcf3ce44SJohn Forte devListWalk = devListWalk->next) { 1376fcf3ce44SJohn Forte printOSDeviceNameInfo(devListWalk, verbose); 1377fcf3ce44SJohn Forte } 1378fcf3ce44SJohn Forte } else { 1379fcf3ce44SJohn Forte /* 1380fcf3ce44SJohn Forte * list any paths not found first 1381fcf3ce44SJohn Forte * this gives the user cleaner output 1382fcf3ce44SJohn Forte */ 1383fcf3ce44SJohn Forte for (pathCtr = 0; pathCtr < luCount; pathCtr++) { 1384fcf3ce44SJohn Forte for (devListWalk = devList, pathFound = B_FALSE; 1385fcf3ce44SJohn Forte devListWalk != NULL; 1386fcf3ce44SJohn Forte devListWalk = devListWalk->next) { 1387fcf3ce44SJohn Forte if (strcmp(devListWalk->OSDeviceName, 1388fcf3ce44SJohn Forte luArgv[pathCtr]) == 0) { 1389fcf3ce44SJohn Forte pathFound = B_TRUE; 1390fcf3ce44SJohn Forte } 1391fcf3ce44SJohn Forte } 1392fcf3ce44SJohn Forte if (pathFound == B_FALSE) { 1393fcf3ce44SJohn Forte fprintf(stderr, "%s: no such path\n", 1394fcf3ce44SJohn Forte luArgv[pathCtr]); 1395fcf3ce44SJohn Forte ret++; 1396fcf3ce44SJohn Forte } 1397fcf3ce44SJohn Forte } 1398fcf3ce44SJohn Forte /* list all paths requested in order requested */ 1399fcf3ce44SJohn Forte for (pathCtr = 0; pathCtr < luCount; pathCtr++) { 1400fcf3ce44SJohn Forte for (devListWalk = devList; devListWalk != NULL; 1401fcf3ce44SJohn Forte devListWalk = devListWalk->next) { 1402fcf3ce44SJohn Forte if (strcmp(devListWalk->OSDeviceName, 1403fcf3ce44SJohn Forte luArgv[pathCtr]) == 0) { 1404fcf3ce44SJohn Forte printOSDeviceNameInfo(devListWalk, 1405fcf3ce44SJohn Forte verbose); 1406fcf3ce44SJohn Forte } 1407fcf3ce44SJohn Forte } 1408fcf3ce44SJohn Forte } 1409fcf3ce44SJohn Forte } 1410fcf3ce44SJohn Forte return (ret); 1411fcf3ce44SJohn Forte } 1412