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
Sun_sasGetDiscoveredPortAttributes(HBA_HANDLE handle,HBA_UINT32 port,HBA_UINT32 discoveredport,SMHBA_PORTATTRIBUTES * attributes)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