Print this page
3217 cfgadm should spell "adaptors" correctly
Reviewed by: Alexander Eremin <alexander.r.eremin@gmail.com>
Reviewed by: David Hoeppner <0xffea@gmail.com>
Reviewed by: Gary Mills <gary_mills@fastmail.fm>
Reviewed by: Eric Schrock <Eric.Schrock@delphix.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/sun_sas/common/sun_sas.c
+++ new/usr/src/lib/sun_sas/common/sun_sas.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27
28 28 #include <sys/byteorder.h>
29 29 #include <sun_sas.h>
30 30
31 31 /*
32 32 * creates a handle each time Sun_sas_OpenAdapter() is called.
33 33 *
34 34 * a open_handle_struct was created to keep track of which handles are currently
35 35 * open. This prevents a user from using an old handle that corresponds to
36 36 * an hba that has already been closed.
37 37 */
38 38 HBA_HANDLE
39 39 CreateHandle(int adapterIndex)
40 40 {
41 41 const char ROUTINE[] = "CreateHandle";
42 42 struct open_handle *new_open_handle;
43 43 HBA_UINT32 new_handle_index;
44 44 HBA_UINT8 max_handle_wrap = 0;
45 45
46 46 if (global_hba_head == NULL) {
47 47 log(LOG_DEBUG, ROUTINE,
48 48 "an error as occurred. global_hba_head is "
49 49 "NULL. Library may not be loaded yet.");
50 50 return (HANDLE_ERROR);
51 51 }
52 52
53 53 while (RetrieveIndex(open_handle_index) != -1) {
54 54 open_handle_index = open_handle_index + 1;
55 55 if (open_handle_index == 0) {
56 56 /*
57 57 * If open_handle_index wraps back to zero again,
58 58 * that means all handles are currently in use.
59 59 * Spec only allows for 16 bits of handles
60 60 */
61 61 if (max_handle_wrap == 1) {
62 62 log(LOG_DEBUG, ROUTINE,
63 63 "Max number of handles reached.");
64 64 return (HANDLE_ERROR);
65 65 }
66 66 open_handle_index = 1;
67 67 max_handle_wrap = 1;
68 68 }
69 69 }
70 70
71 71 new_handle_index = open_handle_index;
72 72 if ((new_open_handle = (struct open_handle *)calloc(1,
73 73 sizeof (struct open_handle))) == NULL) {
74 74 OUT_OF_MEMORY(ROUTINE);
75 75 return (HANDLE_ERROR);
76 76 }
77 77 (void) memset(new_open_handle, 0, sizeof (struct open_handle));
78 78 new_open_handle->adapterIndex = adapterIndex;
79 79 new_open_handle->handle = new_handle_index;
80 80
81 81 lock(&open_handles_lock);
82 82
83 83 /* add new open handle struct to the open_handles list */
84 84 if (global_hba_head->open_handles == NULL) {
85 85 global_hba_head->open_handles = new_open_handle;
86 86 } else {
87 87 new_open_handle->next = global_hba_head->open_handles;
88 88 global_hba_head->open_handles = new_open_handle;
89 89 }
90 90
91 91 unlock(&open_handles_lock);
92 92 open_handle_index = open_handle_index + 1;
93 93 if (open_handle_index == 0) {
94 94 open_handle_index = 1;
95 95 }
96 96
97 97 return (new_handle_index);
98 98 }
99 99
100 100 /*
101 101 * given a handle, returns the adapterIndex number.
102 102 *
103 103 * This functions checkes to see if the given handle corresponds to an open
104 104 * HBA. If it does, the adapterIndex is returned.
105 105 */
106 106 int
107 107 RetrieveIndex(HBA_HANDLE handle)
108 108 {
109 109
110 110 struct open_handle *open_handle_ptr;
111 111
112 112 lock(&open_handles_lock);
113 113
114 114 open_handle_ptr = RetrieveOpenHandle(handle);
115 115
116 116 unlock(&open_handles_lock);
117 117 if (open_handle_ptr == NULL) {
118 118 return (-1);
119 119 }
120 120
121 121 return (open_handle_ptr->adapterIndex);
122 122 }
123 123 /*
124 124 * Given a handle, returns the open_handle structure
125 125 * The routine assumes that the open_handles_lock has already
↓ open down ↓ |
125 lines elided |
↑ open up ↑ |
126 126 * been taken.
127 127 */
128 128 struct open_handle *
129 129 RetrieveOpenHandle(HBA_HANDLE handle)
130 130 {
131 131
132 132 const char ROUTINE[] = "RetrieveOpenHandle";
133 133 struct open_handle *open_handle_ptr = NULL;
134 134
135 135 if (global_hba_head == NULL) {
136 - log(LOG_DEBUG, ROUTINE, "No adpater is found.");
136 + log(LOG_DEBUG, ROUTINE, "No adapter is found.");
137 137 return (NULL);
138 138 }
139 139
140 140 for (open_handle_ptr = global_hba_head->open_handles;
141 141 open_handle_ptr != NULL;
142 142 open_handle_ptr = open_handle_ptr->next) {
143 143 if (open_handle_ptr->handle == handle) {
144 144 break;
145 145 }
146 146 }
147 147
148 148 return (open_handle_ptr);
149 149 }
150 150
151 151 /*
152 152 * Given an adapterIndex, this functions returns a pointer to the handle
153 153 * structure. This handle structure holds the hba's information
154 154 * Caller must take all_hbas_lock first.
155 155 */
156 156 struct sun_sas_hba *
157 157 RetrieveHandle(int index)
158 158 {
159 159 struct sun_sas_hba *hba_ptr = NULL;
160 160
161 161 for (hba_ptr = global_hba_head; hba_ptr != NULL;
162 162 hba_ptr = hba_ptr->next) {
163 163 if (hba_ptr->index == index)
164 164 break;
165 165 }
166 166
167 167 return (hba_ptr);
168 168 }
169 169
170 170 /*
171 171 * Given an adapterIndex, this functions returns a pointer to the handle
172 172 * structure and extracts it from the global list.
173 173 *
174 174 * all_hbas_lock must be taken already.
175 175 */
176 176 struct sun_sas_hba *
177 177 ExtractHandle(int index)
178 178 {
179 179 struct sun_sas_hba *last = NULL;
180 180 struct sun_sas_hba *hba_ptr = NULL;
181 181
182 182 for (hba_ptr = global_hba_head;
183 183 hba_ptr != NULL;
184 184 last = hba_ptr, hba_ptr = hba_ptr->next) {
185 185 if (hba_ptr->index == index) {
186 186 if (last) {
187 187 last->next = hba_ptr->next;
188 188 } else {
189 189 /* Hmm, must be the head of the list. */
190 190 global_hba_head = hba_ptr->next;
191 191 }
192 192 hba_ptr->next = NULL; /* Zap it to be safe */
193 193 break;
194 194 }
195 195 }
196 196
197 197 return (hba_ptr);
198 198 }
199 199
200 200
201 201 /*
202 202 * Given an handle, this functions returns a pointer to the handle structure
203 203 * for that hba
204 204 *
205 205 * Caller must take all_hbas_lock first.
206 206 */
207 207 struct sun_sas_hba *
208 208 Retrieve_Sun_sasHandle(HBA_HANDLE handle)
209 209 {
210 210 const char ROUTINE[] = "Retrieve_Sun_sasHandle";
211 211 struct sun_sas_hba *handle_struct = NULL;
212 212 int index;
213 213
214 214 /* Retrieve fp device path from handle */
215 215 index = RetrieveIndex(handle);
216 216 if (index == -1) {
217 217 log(LOG_DEBUG, ROUTINE,
218 218 "handle could not be found.");
219 219 return (handle_struct);
220 220 }
221 221 lock(&open_handles_lock);
222 222 handle_struct = RetrieveHandle(index);
223 223 if (handle_struct == NULL) {
224 224 log(LOG_DEBUG, ROUTINE,
225 225 "could not find index in the handle list.");
226 226 unlock(&open_handles_lock);
227 227 return (handle_struct);
228 228 }
229 229 unlock(&open_handles_lock);
230 230
231 231 return (handle_struct);
232 232 }
233 233
234 234 /*
235 235 * Take a mutex lock. The routine will try, and if it fails,
236 236 * it will loop for a while and retry. If it fails many times,
237 237 * it will start writing to the log file.
238 238 */
239 239 void
240 240 lock(mutex_t *mp)
241 241 {
242 242 int status;
243 243 int loop = 0;
244 244 const char ROUTINE[] = "lock";
245 245
246 246 do {
247 247 loop++;
248 248 status = mutex_trylock(mp);
249 249 switch (status) {
250 250 case 0:
251 251 break;
252 252 case EFAULT:
253 253 log(LOG_DEBUG, ROUTINE,
254 254 "Lock failed: fault 0x%x", mp);
255 255 break;
256 256 case EINVAL:
257 257 log(LOG_DEBUG, ROUTINE,
258 258 "Lock failed: invalid 0x%x", mp);
259 259 break;
260 260 case EBUSY:
261 261 if (loop > DEADLOCK_WARNING) {
262 262 log(LOG_DEBUG, ROUTINE,
263 263 "Lock busy, possible deadlock:0x%x",
264 264 mp);
265 265 }
266 266 break;
267 267 case EOWNERDEAD:
268 268 log(LOG_DEBUG, ROUTINE,
269 269 "Lock failed: owner dead 0x%x",
270 270 mp);
271 271 break;
272 272 case ELOCKUNMAPPED:
273 273 log(LOG_DEBUG, ROUTINE,
274 274 "Lock failed: unmapped 0x%x",
275 275 mp);
276 276 break;
277 277 case ENOTRECOVERABLE:
278 278 log(LOG_DEBUG, ROUTINE,
279 279 "Lock failed: not recoverable 0x%x", mp);
280 280 default:
281 281 if (loop > DEADLOCK_WARNING) {
282 282 log(LOG_DEBUG, ROUTINE,
283 283 "Lock failed: %s 0x%x",
284 284 strerror(status), mp);
285 285 break;
286 286 }
287 287 }
288 288
289 289 if (status) {
290 290 (void) sleep(LOCK_SLEEP);
291 291 }
292 292
293 293 } while (status);
294 294 }
295 295
296 296 /*
297 297 * Unlock a mutex lock.
298 298 */
299 299 void
300 300 unlock(mutex_t *mp)
301 301 {
302 302 (void) mutex_unlock(mp);
303 303 }
304 304
305 305
306 306 /*
307 307 * Get the Port WWN of the first adapter port. This routine
308 308 * is used by the old V1 interfaces so that they can call
309 309 * the new V2 interfaces and exhibit the same behavior.
310 310 * In the event of error the WWN will be zero.
311 311 *
312 312 * This function will transition to PAA state but it will not
313 313 * verfiy whether data is stale or not
314 314 */
315 315 HBA_WWN
316 316 getFirstAdapterPortWWN(HBA_HANDLE handle)
317 317 {
318 318 const char ROUTINE[] = "getFirstAdapterPortWWN";
319 319 HBA_WWN pwwn = {0, 0, 0, 0, 0, 0, 0, 0};
320 320 struct sun_sas_hba *hba_ptr = NULL;
321 321 int index = 0;
322 322 HBA_STATUS status;
323 323
324 324 lock(&all_hbas_lock);
325 325 index = RetrieveIndex(handle);
326 326 lock(&open_handles_lock);
327 327 hba_ptr = RetrieveHandle(index);
328 328 if (hba_ptr == NULL) {
329 329 log(LOG_DEBUG, ROUTINE, "Invalid handle %08lx", handle);
330 330 unlock(&open_handles_lock);
331 331 unlock(&all_hbas_lock);
332 332 return (pwwn); /* zero WWN */
333 333 }
334 334
335 335 /* Check for stale data */
336 336 status = verifyAdapter(hba_ptr);
337 337 if (status != HBA_STATUS_OK) {
338 338 log(LOG_DEBUG, ROUTINE, "Verify adapter failed");
339 339 unlock(&open_handles_lock);
340 340 unlock(&all_hbas_lock);
341 341 return (pwwn);
342 342 }
343 343
344 344 if (hba_ptr->first_port == NULL) {
345 345 /* This is probably an internal failure of the library */
346 346 if (hba_ptr->device_path) {
347 347 log(LOG_DEBUG, ROUTINE,
348 348 "Internal failure: Adapter %s contains no "
349 349 "port data", hba_ptr->device_path);
350 350 } else {
351 351 log(LOG_DEBUG, ROUTINE,
352 352 "Internal failure: Adapter at index %d contains "
353 353 " no support data", hba_ptr->index);
354 354 }
355 355 unlock(&open_handles_lock);
356 356 unlock(&all_hbas_lock);
357 357 return (pwwn); /* zero WWN */
358 358 }
359 359 /* Set the WWN now and return it */
360 360 pwwn = hba_ptr->first_port->port_attributes.PortSpecificAttribute.\
361 361 SASPort->LocalSASAddress;
362 362 unlock(&open_handles_lock);
363 363 unlock(&all_hbas_lock);
364 364
365 365 return (pwwn);
366 366 }
367 367
368 368 u_longlong_t
369 369 wwnConversion(uchar_t *wwn)
370 370 {
371 371 u_longlong_t tmp;
372 372 (void) memcpy(&tmp, wwn, sizeof (u_longlong_t));
373 373 tmp = ntohll(tmp);
374 374 return (tmp);
375 375 }
376 376
377 377 /*
378 378 * Using ioctl to send uscsi command out
379 379 */
380 380 HBA_STATUS
381 381 send_uscsi_cmd(const char *devpath, struct uscsi_cmd *ucmd)
382 382 {
383 383 const char ROUTINE[] = "send_uscsi_cmd";
384 384 int fd;
385 385 HBA_STATUS ret;
386 386
387 387 /* set default timeout to 200 */
388 388 ucmd->uscsi_timeout = 200;
389 389
390 390 /* reset errno. */
391 391 errno = 0;
392 392 if ((fd = open(devpath, O_RDONLY | O_NDELAY)) == -1) {
393 393 log(LOG_DEBUG, ROUTINE,
394 394 "open devpath %s failed: %s", devpath, strerror(errno));
395 395 return (HBA_STATUS_ERROR);
396 396 }
397 397
398 398 if (ioctl(fd, USCSICMD, ucmd) == -1) {
399 399 if (errno == EBUSY) {
400 400 ret = HBA_STATUS_ERROR_BUSY;
401 401 } else if (errno == EAGAIN) {
402 402 ret = HBA_STATUS_ERROR_TRY_AGAIN;
403 403 } else {
404 404 ret = HBA_STATUS_ERROR;
405 405 }
406 406 log(LOG_DEBUG, ROUTINE,
407 407 "ioctl send uscsi to devpath: %s failed: %s",
408 408 devpath, strerror(errno));
409 409 (void) close(fd);
410 410 return (ret);
411 411 }
412 412
413 413 (void) close(fd);
414 414
415 415 return (HBA_STATUS_OK);
416 416 }
417 417
418 418 /*
419 419 * Check whether the given Domain Address is valid.
420 420 */
421 421 HBA_STATUS
422 422 validateDomainAddress(struct sun_sas_port *hba_port_ptr, HBA_WWN DomainAddr)
423 423 {
424 424 if (hba_port_ptr->first_phy != NULL &&
425 425 wwnConversion(hba_port_ptr->first_phy->
426 426 phy.domainPortWWN.wwn) ==
427 427 wwnConversion(DomainAddr.wwn)) {
428 428 return (HBA_STATUS_OK);
429 429 }
430 430 return (HBA_STATUS_ERROR);
431 431 }
↓ open down ↓ |
285 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX