xref: /illumos-gate/usr/src/lib/sun_sas/common/Sun_sasGetDiscoveredPortAttributes.c (revision b6805bf78d2bbbeeaea8909a05623587b42d58b3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include    <sun_sas.h>
28 
29 /*
30  * Retrieves the attributes for a specified port discovered in the network
31  */
32 HBA_STATUS
33 Sun_sasGetDiscoveredPortAttributes(HBA_HANDLE handle,
34 	    HBA_UINT32 port, HBA_UINT32 discoveredport,
35 	    SMHBA_PORTATTRIBUTES *attributes) {
36 	const char		ROUTINE[] =
37 	    "Sun_sasGetDiscoveredPortAttributes";
38 	HBA_STATUS		status;
39 	HBA_STATUS		ret = HBA_STATUS_OK;
40 	struct sun_sas_hba	*hba_ptr;
41 	struct sun_sas_port	*hba_port_ptr, *hba_disco_port;
42 	int			index;
43 
44 	if (attributes == NULL) {
45 	    log(LOG_DEBUG, ROUTINE,
46 		"NULL attributes argument. Handle %08lx, port %d, "
47 		"discovered port %d", handle, port, discoveredport);
48 	    return (HBA_STATUS_ERROR_ARG);
49 	}
50 
51 	lock(&all_hbas_lock);
52 	index = RetrieveIndex(handle);
53 	lock(&open_handles_lock);
54 	hba_ptr = RetrieveHandle(index);
55 	if (hba_ptr == NULL) {
56 	    log(LOG_DEBUG, ROUTINE,
57 		"Invalid handle %08lx.", handle);
58 	    unlock(&open_handles_lock);
59 	    unlock(&all_hbas_lock);
60 	    return (HBA_STATUS_ERROR_INVALID_HANDLE);
61 	}
62 
63 	/* Check for stale data */
64 	status = verifyAdapter(hba_ptr);
65 	if (status != HBA_STATUS_OK) {
66 	    log(LOG_DEBUG, ROUTINE, "Verify Adapter failed");
67 	    unlock(&open_handles_lock);
68 	    unlock(&all_hbas_lock);
69 	    return (status);
70 	}
71 
72 
73 	if (hba_ptr->first_port == NULL) {
74 	    /* This is probably an internal failure of the library */
75 	    if (hba_ptr->device_path) {
76 		log(LOG_DEBUG, ROUTINE,
77 		    "Internal failure:  Adapter %s contains no port data",
78 		    hba_ptr->device_path);
79 	    } else {
80 		log(LOG_DEBUG, ROUTINE,
81 		    "Internal failure:  Adapter at index %d contains no port "
82 		    "data", hba_ptr->index);
83 	    }
84 	    unlock(&open_handles_lock);
85 	    unlock(&all_hbas_lock);
86 	    return (HBA_STATUS_ERROR);
87 	}
88 
89 	for (hba_port_ptr = hba_ptr->first_port;
90 	    hba_port_ptr != NULL; hba_port_ptr = hba_port_ptr->next) {
91 		if (hba_port_ptr->index == port) {
92 			break;
93 		}
94 	}
95 
96 	if (hba_port_ptr == NULL) {
97 		log(LOG_DEBUG, ROUTINE,
98 		    "Invalid port index %d for handle %08lx",
99 		    port, handle);
100 		unlock(&open_handles_lock);
101 		unlock(&all_hbas_lock);
102 		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
103 	}
104 
105 	/* check to make sure there are devices attached to this port */
106 	if (hba_port_ptr->first_attached_port != NULL) {
107 		for (hba_disco_port = hba_port_ptr->first_attached_port;
108 			hba_disco_port != NULL;
109 			hba_disco_port = hba_disco_port->next) {
110 		    if (hba_disco_port->index == discoveredport) {
111 			break;
112 		    }
113 		}
114 		if (hba_disco_port == NULL) {
115 			log(LOG_DEBUG, ROUTINE,
116 			    "Invalid discovered port index %d for hba port "
117 			    "index %d on handle %08lx.",
118 			    discoveredport, port, handle);
119 			ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
120 		} else {
121 		    attributes->PortType =
122 			hba_disco_port->port_attributes.PortType;
123 		    attributes->PortState =
124 			hba_disco_port->port_attributes.PortState;
125 		    (void) strlcpy(attributes->OSDeviceName,
126 			hba_disco_port->port_attributes.OSDeviceName,
127 			sizeof (attributes->OSDeviceName));
128 		    (void) memcpy(attributes->PortSpecificAttribute.SASPort,
129 			hba_disco_port->port_attributes.PortSpecificAttribute.
130 			SASPort, sizeof (struct SMHBA_SAS_Port));
131 		}
132 	} else {
133 		/* No ports, so we can't possibly return anything */
134 		log(LOG_DEBUG, ROUTINE,
135 		    "No discovered port on HBA port index %d for handle %08lx",
136 		    port, handle);
137 		ret = HBA_STATUS_ERROR;
138 	}
139 	unlock(&open_handles_lock);
140 	unlock(&all_hbas_lock);
141 
142 	return (ret);
143 }
144