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.
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.
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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
36 #include <vendorsmhbaapi.h>
37 #include <sys/types.h>
39 #include <sys/param.h>
52 #include <libdevinfo.h>
54 #include <sys/scsi/generic/commands.h>
55 #include <sys/scsi/impl/commands.h>
56 #include <sys/scsi/impl/sense.h>
57 #include <sys/scsi/generic/inquiry.h>
58 #include <sys/scsi/impl/uscsi.h>
59 #include <sys/varargs.h>
60 #include <sys/varargs.h>
61 #include <libsysevent.h>
67 #define VSL_NUMERIC_VERSION 1
68 #define VSL_STRING_VERSION "Version 1"
69 #define VSL_NAME "Sun T11 SM-HBA Vendor Library for SAS HBAs"
70 #define SMHBA_LIBRARY_VERSION1 VSL_NUMERIC_VERSION
72 /* The /dev links we expose */
73 #define DEV_DISK_DIR "/dev/rdsk"
74 #define DEV_TAPE_DIR "/dev/rmt"
75 #define DEV_ES_DIR "/dev/es"
76 #define DEV_CFG_DIR "/dev/cfg"
77 #define DEVICES_DIR "/devices"
78 #define DEVCTL_SUFFIX ":devctl"
79 #define SCSI_SUFFIX ":scsi"
81 /* To be consistent, when out of memory call this macro routine */
82 #define OUT_OF_MEMORY(routine) \
83 log(LOG_DEBUG, routine, "Out of memory.")
85 #define S_FREE(x) (((x) != NULL) ? (free(x), (x) = NULL) : (void *)0)
87 #define IS_STUB_NODE(s) (di_instance(s) == -1 && \
88 di_nodeid(s) == (DI_PROM_NODEID))
90 /* manf+model+10(char length of UINTMAX)+6(for 2 -'s, NULL & extra 3bytes */
91 #define HANDLE_NAME_LENGTH (64 + 256 + 10 + 6)
92 #define HANDLE_ERROR 0 /* This is an error condition */
94 /* Some timing values */
96 #define BUSY_SLEEP 10000 /* 1/100 second */
97 #define BUSY_RETRY_TIMER 5000000000 /* Retry for 5 seconds */
98 #define STATE_RETRY_TIMER 10000000000 /* Retry for 10 seconds */
99 #define HR_SECOND 1000000000
100 /* How many times to silently retry, before starting to print warnings */
101 #define DEADLOCK_WARNING 10
104 #define REP_LUNS_RSP_SIZE sizeof (rep_luns_rsp_t)+ \
105 (sizeof (lun_list_element_t)*(MAX_LUN - 1))
108 #define SUN_MICROSYSTEMS "Sun Microsystems, Inc."
110 mutex_t all_hbas_lock
;
111 mutex_t open_handles_lock
;
112 mutex_t log_file_lock
;
113 HBA_UINT32 hba_count
;
114 HBA_UINT16 open_handle_index
;
117 /* Internal structures that aren't exposed to clients */
121 struct open_handle
*next
;
125 HBA_UINT32 index
; /* Can be sparse */
126 struct open_handle
*open_handles
;
127 int fd
; /* when open, the FD */
128 /* The libdevinfo HBA path (lacking /devices) */
129 char device_path
[MAXPATHLEN
];
130 char handle_name
[HANDLE_NAME_LENGTH
];
131 SMHBA_ADAPTERATTRIBUTES adapter_attributes
;
135 struct sun_sas_hba
*next
;
136 struct sun_sas_port
*first_port
;
139 struct sun_sas_hba
*global_hba_head
;
141 struct ScsiEntryList
{
142 SMHBA_SCSIENTRY entry
;
143 struct ScsiEntryList
*next
;
150 struct phy_info
*next
;
153 struct sun_sas_port
{
157 /* The libdevinfo HBA path (lacking /devices) */
158 char device_path
[MAXPATHLEN
];
159 SMHBA_PORTATTRIBUTES port_attributes
;
160 struct ScsiEntryList
*scsiInfo
;
163 /* The following are used to track the device map */
165 struct sun_sas_port
*first_attached_port
; /* Only for HBA port */
166 struct phy_info
*first_phy
; /* Only for HBA port */
167 struct sun_sas_port
*next
;
170 typedef struct walkarg
{
175 extern int loadCount
;
177 extern sysevent_handle_t
*gSysEventHandle
;
179 /* External routines */
180 extern HBA_STATUS
SMHBA_RegisterLibrary(PSMHBA_ENTRYPOINTS
);
181 extern HBA_UINT32
Sun_sasGetVendorLibraryAttributes(SMHBA_LIBRARYATTRIBUTES
*);
182 extern HBA_STATUS
Sun_sasGetAdapterAttributes(HBA_HANDLE
,
183 SMHBA_ADAPTERATTRIBUTES
*);
184 extern HBA_UINT32
Sun_sasGetNumberOfAdapters();
185 extern HBA_STATUS
Sun_sasGetAdapterName(HBA_UINT32
, char *);
186 extern HBA_STATUS
Sun_sasGetPortType(HBA_HANDLE
, HBA_UINT32
, HBA_PORTTYPE
*);
187 extern HBA_STATUS
Sun_sasGetAdapterPortAttributes(HBA_HANDLE
, HBA_UINT32
,
188 SMHBA_PORTATTRIBUTES
*);
189 extern HBA_STATUS
Sun_sasGetPortAttributesByWWN(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
190 SMHBA_PORTATTRIBUTES
*);
191 extern HBA_STATUS
Sun_sasGetFCPhyAttributes(HBA_HANDLE
, HBA_UINT32
, HBA_UINT32
,
193 extern HBA_STATUS
Sun_sasGetSASPhyAttributes(HBA_HANDLE
, HBA_UINT32
,
194 HBA_UINT32
, SMHBA_SAS_PHY
*);
195 extern HBA_STATUS
Sun_sasGetProtocolStatistics(HBA_HANDLE
, HBA_UINT32
,
196 HBA_UINT32
, SMHBA_PROTOCOLSTATISTICS
*);
197 extern HBA_STATUS
Sun_sasGetPhyStatistics(HBA_HANDLE
, HBA_UINT32
,
198 HBA_UINT32
, SMHBA_PHYSTATISTICS
*);
199 extern HBA_STATUS
Sun_sasSendSMPPassThru(HBA_HANDLE
, HBA_WWN
, HBA_WWN
, HBA_WWN
,
200 void *, HBA_UINT32
, void *, HBA_UINT32
*);
201 extern HBA_STATUS
Sun_sasGetBindingCapability(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
202 SMHBA_BIND_CAPABILITY
*);
203 extern HBA_STATUS
Sun_sasGetBindingSupport(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
204 SMHBA_BIND_CAPABILITY
*);
205 extern HBA_STATUS
Sun_sasSetBindingSupport(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
206 SMHBA_BIND_CAPABILITY
);
207 extern HBA_STATUS
Sun_sasGetTargetMapping(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
208 SMHBA_TARGETMAPPING
*);
209 extern HBA_STATUS
Sun_sasGetPersistentBinding(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
211 extern HBA_STATUS
Sun_sasSetPersistentBinding(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
212 const SMHBA_BINDING
*);
213 extern HBA_STATUS
Sun_sasRemovePersistentBinding(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
214 const SMHBA_BINDING
*);
215 extern HBA_STATUS
Sun_sasRemoveAllPersistentBindings(HBA_HANDLE
, HBA_WWN
,
217 extern HBA_STATUS
Sun_sasGetLUNStatistics(HBA_HANDLE
, const HBA_SCSIID
*,
218 SMHBA_PROTOCOLSTATISTICS
*);
219 extern HBA_STATUS
Sun_sasRegisterForAdapterAddEvents(void (*)(void *, HBA_WWN
,
220 HBA_UINT32
), void *, HBA_CALLBACKHANDLE
*);
221 extern HBA_STATUS
Sun_sasRegisterForAdapterEvents(void (*)(void *, HBA_WWN
,
222 HBA_UINT32
), void *, HBA_HANDLE
, HBA_CALLBACKHANDLE
*);
223 extern HBA_STATUS
Sun_sasRegisterForAdapterPortEvents(void (*)(void *, HBA_WWN
,
224 HBA_UINT32
, HBA_UINT32
), void *, HBA_HANDLE
, HBA_WWN
, HBA_UINT32
,
225 HBA_CALLBACKHANDLE
*);
226 extern HBA_STATUS
Sun_sasRegisterForAdapterPortStatEvents(void (*)(void *,
227 HBA_WWN
, HBA_UINT32
, HBA_UINT32
), void *, HBA_HANDLE
, HBA_WWN
, HBA_UINT32
,
228 SMHBA_PROTOCOLSTATISTICS
, HBA_UINT32
, HBA_CALLBACKHANDLE
*);
229 extern HBA_STATUS
Sun_sasRegisterForAdapterPhyStatEvents(void (*)(void *,
230 HBA_WWN
, HBA_UINT32
, HBA_UINT32
), void *, HBA_HANDLE
, HBA_WWN
, HBA_UINT32
,
231 SMHBA_PHYSTATISTICS
, HBA_UINT32
, HBA_CALLBACKHANDLE
*);
232 extern HBA_STATUS
Sun_sasRegisterForTargetEvents(void (*)(void *, HBA_WWN
,
233 HBA_WWN
, HBA_WWN
, HBA_UINT32
), void *, HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
234 HBA_WWN
, HBA_CALLBACKHANDLE
*, HBA_UINT32
);
235 extern HBA_STATUS
Sun_sasRegisterForLinkEvents(void (*)(void *, HBA_WWN
,
236 HBA_UINT32
, void *, HBA_UINT32
), void *, void *, HBA_UINT32
, HBA_HANDLE
,
237 HBA_CALLBACKHANDLE
*);
238 extern HBA_STATUS
Sun_sasScsiInquiry(HBA_HANDLE
, HBA_WWN
, HBA_WWN
, HBA_WWN
,
239 SMHBA_SCSILUN
, HBA_UINT8
, HBA_UINT8
, void *, HBA_UINT32
*, HBA_UINT8
*,
240 void *, HBA_UINT32
*);
241 extern HBA_STATUS
Sun_sasScsiReportLUNs(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
242 HBA_WWN
, void *, HBA_UINT32
*, HBA_UINT8
*, void *, HBA_UINT32
*);
243 extern HBA_STATUS
Sun_sasScsiReadCapacity(HBA_HANDLE
, HBA_WWN
, HBA_WWN
, HBA_WWN
,
244 SMHBA_SCSILUN
, void *, HBA_UINT32
*, HBA_UINT8
*, void *, HBA_UINT32
*);
245 extern HBA_UINT32
Sun_sasGetVersion();
246 extern HBA_STATUS
Sun_sasLoadLibrary();
247 extern HBA_STATUS
Sun_sasFreeLibrary();
248 extern HBA_UINT32
Sun_sasGetNumberOfAdapters();
249 extern HBA_UINT32
Sun_sasGetNumberOfPorts(HBA_HANDLE
, HBA_UINT32
*);
250 extern HBA_STATUS
Sun_sasGetAdapterName(HBA_UINT32
, char *);
251 extern HBA_HANDLE
Sun_sasOpenAdapter(char *);
252 extern void Sun_sasCloseAdapter(HBA_HANDLE
);
253 extern HBA_STATUS
Sun_sasGetDiscoveredPortAttributes(HBA_HANDLE
, HBA_UINT32
,
254 HBA_UINT32
, SMHBA_PORTATTRIBUTES
*);
255 extern HBA_STATUS
Sun_sasGetPortAttributesByWWN(HBA_HANDLE
, HBA_WWN
, HBA_WWN
,
256 SMHBA_PORTATTRIBUTES
*);
257 extern void Sun_sasRefreshInformation(HBA_HANDLE
);
258 extern void Sun_sasRefreshAdapterConfiguration(void);
259 extern HBA_STATUS
Sun_sasRemoveCallback(HBA_CALLBACKHANDLE
);
262 /* Internal routines */
263 extern void log(int, const char *, char *, ...);
264 extern u_longlong_t
wwnConversion(uchar_t
*wwn
);
265 extern HBA_STATUS
devtree_attached_devices(di_node_t
, struct sun_sas_port
*);
266 extern HBA_HANDLE
CreateHandle(int);
267 extern int RetrieveIndex(HBA_HANDLE
);
268 extern struct open_handle
*RetrieveOpenHandle(HBA_HANDLE
);
269 extern struct sun_sas_hba
*RetrieveHandle(int);
270 extern struct sun_sas_hba
*ExtractHandle(int);
271 extern struct sun_sas_hba
*Retrieve_Sun_sasHandle(HBA_HANDLE
);
272 extern void lock(mutex_t
*mp
);
273 extern void unlock(mutex_t
*mp
);
274 extern void reportSense(struct scsi_extended_sense
*, const char *);
275 extern HBA_STATUS
verifyAdapter(struct sun_sas_hba
*hba_ptr
);
276 extern HBA_STATUS
devtree_get_all_hbas(di_node_t root
);
277 extern HBA_STATUS
devtree_get_one_hba(di_node_t node
);
278 extern HBA_STATUS
FreeHBA(struct sun_sas_hba
*hba
);
279 extern HBA_WWN
getFirstAdapterPortWWN(HBA_HANDLE handle
);
280 extern HBA_STATUS
getPortStateCounter(char *fpPath
, HBA_UINT32
*stateCount
);
281 extern HBA_STATUS
lookupControllerLink(char *path
, char *link
);
282 extern HBA_STATUS
lookupSMPLink(char *path
, char *link
);
283 extern void convertDevpathToDevlink(PSMHBA_TARGETMAPPING mappings
);
284 extern void fillDomainPortWWN(struct sun_sas_port
*);
285 extern HBA_STATUS
get_phy_info(di_node_t
, struct sun_sas_port
*);
286 extern HBA_STATUS
send_uscsi_cmd(const char *devpath
, struct uscsi_cmd
*ucmd
);
287 extern HBA_STATUS
registerSysevent();
288 extern HBA_STATUS
validateDomainAddress(struct sun_sas_port
*, HBA_WWN
);
294 #endif /* _SUN_SAS_H */