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 * Copyright 2019 Joyent, Inc.
28 */
29 #include <sun_sas.h>
30
31 /*
32 * Retrieves the attributes for a specified port of an adapter
33 */
34 HBA_STATUS
Sun_sasGetAdapterPortAttributes(HBA_HANDLE handle,HBA_UINT32 port,PSMHBA_PORTATTRIBUTES attributes)35 Sun_sasGetAdapterPortAttributes(HBA_HANDLE handle, HBA_UINT32 port,
36 PSMHBA_PORTATTRIBUTES attributes)
37 {
38 const char ROUTINE[] = "Sun_sasGetAdapterPortAttributes";
39 HBA_STATUS status;
40 struct sun_sas_hba *hba_ptr;
41 struct sun_sas_port *hba_port_ptr;
42 int index;
43
44 /* Validate the arguments */
45 if ((attributes == NULL) ||
46 (attributes->PortSpecificAttribute.SASPort == NULL)) {
47 log(LOG_DEBUG, ROUTINE, "NULL attributes");
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, "Invalid handle %08lx", handle);
57 unlock(&open_handles_lock);
58 unlock(&all_hbas_lock);
59 return (HBA_STATUS_ERROR_INVALID_HANDLE);
60 }
61
62 /* Check for stale data */
63 status = verifyAdapter(hba_ptr);
64 if (status != HBA_STATUS_OK) {
65 log(LOG_DEBUG, ROUTINE, "Verify Adapter failed");
66 unlock(&open_handles_lock);
67 unlock(&all_hbas_lock);
68 return (status);
69 }
70
71 if (hba_ptr->first_port == NULL) {
72 /* This is probably an internal failure of the library */
73 if (hba_ptr->device_path[0] != '\0') {
74 log(LOG_DEBUG, ROUTINE, "Internal failure: Adapter "
75 "%s contains no port data", hba_ptr->device_path);
76 } else {
77 log(LOG_DEBUG, ROUTINE, "Internal failure: Adapter at"
78 " index %d contains no port data", hba_ptr->index);
79 }
80 unlock(&open_handles_lock);
81 unlock(&all_hbas_lock);
82 return (HBA_STATUS_ERROR);
83 }
84 for (hba_port_ptr = hba_ptr->first_port;
85 hba_port_ptr != NULL; hba_port_ptr = hba_port_ptr->next) {
86 if (hba_port_ptr->index == port) {
87 break;
88 }
89 }
90 if (hba_port_ptr == NULL || hba_port_ptr->index != port) {
91 log(LOG_DEBUG, ROUTINE,
92 "Invalid port index %d for handle %08lx.",
93 port, handle);
94 unlock(&open_handles_lock);
95 unlock(&all_hbas_lock);
96 return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
97 }
98
99 attributes->PortType = hba_port_ptr->port_attributes.PortType;
100 attributes->PortState = hba_port_ptr->port_attributes.PortState;
101 (void) strlcpy(attributes->OSDeviceName,
102 hba_port_ptr->port_attributes.OSDeviceName,
103 sizeof (attributes->OSDeviceName));
104 (void) memcpy(attributes->PortSpecificAttribute.SASPort,
105 hba_port_ptr->port_attributes.PortSpecificAttribute.SASPort,
106 sizeof (struct SMHBA_SAS_Port));
107
108 unlock(&open_handles_lock);
109 unlock(&all_hbas_lock);
110
111 return (HBA_STATUS_OK);
112 }
113