xref: /illumos-gate/usr/src/cmd/fcinfo/fcinfo-list.c (revision 2a8164df)
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
retrieveAttrs(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_ADAPTERATTRIBUTES * attrs,HBA_PORTATTRIBUTES * port,int * portIndex)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
getTargetMapping(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_FCPTARGETMAPPINGV2 ** mapping)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
handleRemotePort(HBA_HANDLE handle,HBA_WWN portWWN,HBA_WWN remotePortWWN,HBA_PORTATTRIBUTES * discPort)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
printLinkStat(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_WWN destWWN)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
printHBANPIVPortInfo(HBA_HANDLE handle,int portindex)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
processHBA(HBA_HANDLE handle,HBA_ADAPTERATTRIBUTES attrs,int portIndex,HBA_PORTATTRIBUTES port,HBA_FCPTARGETMAPPINGV2 * map,int resourceType,int flags,int mode)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
processRemotePort(HBA_HANDLE handle,HBA_WWN portWWN,HBA_FCPTARGETMAPPINGV2 * map,int wwnCount,char ** wwn_argv,int flags)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
handleScsiTarget(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_WWN scsiTargetWWN,HBA_FCPTARGETMAPPINGV2 * map)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
fc_util_list_remoteport(int wwnCount,char ** wwn_argv,cmdOptions_t * options)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
fc_util_list_hbaport(int wwnCount,char ** wwn_argv,cmdOptions_t * options)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
searchDevice(discoveredDevice ** devList,HBA_FCPSCSIENTRYV2 entry,HBA_WWN initiatorPortWWN,HBA_HANDLE handle,boolean_t verbose)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
fc_util_list_logicalunit(int luCount,char ** luArgv,cmdOptions_t * options)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 "
132963c17d01SRaghuram Prahlada 				    "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