Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/rsm/rsmops.c
+++ new/usr/src/uts/common/io/rsm/rsmops.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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <sys/types.h>
27 27 #include <sys/modctl.h>
28 28 #include <sys/stat.h>
29 29 #include <sys/proc.h>
30 30 #include <sys/ddi.h>
31 31 #include <sys/sunddi.h>
32 32 #include <sys/kmem.h>
33 33 #include <sys/file.h>
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
34 34 #include <sys/rsm/rsm_common.h>
35 35 #include <sys/rsm/rsmpi.h>
36 36 #include <sys/rsm/rsmpi_driver.h>
37 37
38 38 /* lint -w2 */
39 39 static struct modlmisc modlmisc = {
40 40 &mod_miscops, "RSMOPS module",
41 41 };
42 42
43 43 static struct modlinkage modlinkage = {
44 - MODREV_1, (void *)&modlmisc, NULL
44 + MODREV_1, { (void *)&modlmisc, NULL }
45 45 };
46 46
47 47 static kmutex_t rsmops_lock;
48 48
49 49 static rsmops_drv_t *rsmops_drv_head = NULL;
50 50
51 51 static int rsmops_threads_started = 0;
52 52
53 53 int
54 54 _init(void)
55 55 {
56 56 int err;
57 57
58 58 mutex_init(&rsmops_lock, NULL, MUTEX_DEFAULT, NULL);
59 59
60 60 if ((err = mod_install(&modlinkage)) != 0)
61 61 mutex_destroy(&rsmops_lock);
62 62
63 63 return (err);
64 64 }
65 65
66 66 int
67 67 _fini(void)
68 68 {
69 69 int err;
70 70
71 71 mutex_enter(&rsmops_lock);
72 72 if (rsmops_drv_head) {
73 73 /* Somebody is still registered with us - we cannot unload */
74 74 mutex_exit(&rsmops_lock);
75 75 return (EBUSY);
76 76 }
77 77 if (rsmops_threads_started) {
78 78 /*
79 79 * Some threads have been started. We do not have any
80 80 * well-supported way of checking whether they have all
81 81 * exited. For now, fail attempt to unload if we have
82 82 * ever started any threads. This is overkill, but ...
83 83 */
84 84 mutex_exit(&rsmops_lock);
85 85 return (EBUSY);
86 86 }
87 87 mutex_exit(&rsmops_lock);
88 88
89 89 if ((err = mod_remove(&modlinkage)) == 0)
90 90 mutex_destroy(&rsmops_lock);
91 91 return (err);
92 92 }
93 93
94 94 int
95 95 _info(struct modinfo *modinfop)
96 96 {
97 97 return (mod_info(&modlinkage, modinfop));
98 98 }
99 99
100 100 static void
101 101 rsmops_thread_entry(rsmops_drv_t *p_drv)
102 102 {
103 103 /* p_drv->ctrl_cnt has already been increased by the time we get here */
104 104 ASSERT(p_drv->drv.rsm_thread_entry_pt);
105 105
106 106 /* call the driver with the thread */
107 107 (*(p_drv->drv.rsm_thread_entry_pt))(p_drv->drv.drv_name);
108 108
109 109 /* thread has returned */
110 110 mutex_enter(&rsmops_lock);
111 111 p_drv->ctrl_cnt--;
112 112 mutex_exit(&rsmops_lock);
113 113 }
114 114
115 115 /* This is expected to be called from the driver's init function */
116 116 int
117 117 rsm_register_driver(rsmops_registry_t *p_registry)
118 118 {
119 119 rsmops_drv_t **pp_tail;
120 120 rsmops_drv_t *p;
121 121
122 122 if (p_registry->rsm_version > RSM_VERSION) {
123 123 /* The driver is up-rev than me. Fail attempt to register */
124 124 return (RSMERR_BAD_DRIVER_VERSION);
125 125 }
126 126
127 127 /*
128 128 * RSM_VERSION: Since this is the first version, there cannot be any
129 129 * down-rev drivers - this will be an issue in the future
130 130 */
131 131 if (p_registry->rsm_version != RSM_VERSION)
132 132 return (RSMERR_BAD_DRIVER_VERSION);
133 133
134 134 mutex_enter(&rsmops_lock);
135 135 /* First, search that this driver is not already registered */
136 136 pp_tail = &rsmops_drv_head;
137 137 while (*pp_tail) {
138 138 if (strcmp((*pp_tail)->drv.drv_name, p_registry->drv_name)
139 139 == 0) {
140 140 mutex_exit(&rsmops_lock);
141 141 return (RSMERR_DRIVER_NAME_IN_USE);
142 142 }
143 143 pp_tail = &((*pp_tail)->next);
144 144 }
145 145
146 146 p = kmem_alloc(sizeof (rsmops_drv_t), KM_SLEEP);
147 147 p->drv = *p_registry; /* copy entire rsmops_registry_t structure */
148 148 p->next = NULL;
149 149 p->ctrl_cnt = 0;
150 150 p->ctrl_head = NULL;
151 151
152 152 if (p->drv.rsm_thread_entry_pt) {
153 153 /* thread entry point is defined - we need to create a thread */
154 154 extern pri_t minclsyspri;
155 155
156 156 p->ctrl_cnt++; /* bump up the count right now */
157 157 p->thread_id = thread_create(NULL, 0, rsmops_thread_entry,
158 158 p, 0, &p0, TS_RUN, minclsyspri);
159 159 rsmops_threads_started++;
160 160 } else
161 161 p->thread_id = NULL;
162 162
163 163 *pp_tail = p;
164 164 mutex_exit(&rsmops_lock);
165 165 return (RSM_SUCCESS);
166 166 }
167 167
168 168 /*
169 169 * This is expected to be called from the driver's fini function
170 170 * if this function returns EBUSY, the driver is supposed to fail
171 171 * its own fini operation
172 172 */
173 173 int
174 174 rsm_unregister_driver(rsmops_registry_t *p_registry)
175 175 {
176 176 rsmops_drv_t **pp_tail;
177 177 rsmops_drv_t *p;
178 178
179 179 mutex_enter(&rsmops_lock);
180 180
181 181 /* Search for the driver */
182 182 pp_tail = &rsmops_drv_head;
183 183 while (*pp_tail) {
184 184 if (strcmp((*pp_tail)->drv.drv_name, p_registry->drv_name)) {
185 185 pp_tail = &((*pp_tail)->next);
186 186 continue;
187 187 }
188 188 /* check ref count - if somebody is using it, return EBUSY */
189 189 if ((*pp_tail)->ctrl_cnt) {
190 190 mutex_exit(&rsmops_lock);
191 191 return (RSMERR_CTLRS_REGISTERED);
192 192 }
193 193 /* Nobody is using it - we can allow the unregister to happen */
194 194 p = *pp_tail;
195 195
196 196 /* Stomp the guy out of our linked list */
197 197 *pp_tail = (*pp_tail)->next;
198 198
199 199 /* release the memory */
200 200 kmem_free(p, sizeof (rsmops_drv_t));
201 201
202 202 mutex_exit(&rsmops_lock);
203 203 return (RSM_SUCCESS);
204 204 }
205 205
206 206 /* Could not find the guy */
207 207 mutex_exit(&rsmops_lock);
208 208 return (RSMERR_DRIVER_NOT_REGISTERED);
209 209 }
210 210
211 211 /* Should be called holding the rsmops_lock mutex */
212 212 static rsmops_drv_t *
213 213 find_rsmpi_driver(const char *name)
214 214 {
215 215 rsmops_drv_t *p_rsmops_list;
216 216
217 217 ASSERT(MUTEX_HELD(&rsmops_lock));
218 218 /* the name is of the form "sci", "wci" etc */
219 219
220 220 for (p_rsmops_list = rsmops_drv_head; p_rsmops_list != NULL;
221 221 p_rsmops_list = p_rsmops_list->next) {
222 222
223 223 if (strcmp(name, p_rsmops_list->drv.drv_name) == 0) {
224 224 return (p_rsmops_list);
225 225 }
226 226 }
227 227 return (NULL);
228 228 }
229 229
230 230
231 231 /* Should be called holding the rsmops_lock mutex */
232 232 static rsmops_ctrl_t *
233 233 find_rsmpi_controller(const char *name, uint_t number)
234 234 {
235 235 rsmops_drv_t *p_drv;
236 236 rsmops_ctrl_t *p;
237 237
238 238 ASSERT(MUTEX_HELD(&rsmops_lock));
239 239
240 240 if ((p_drv = find_rsmpi_driver(name)) == NULL)
241 241 return (NULL);
242 242
243 243 for (p = p_drv->ctrl_head; p != NULL; p = p->next) {
244 244 ASSERT(p->p_drv == p_drv);
245 245 if (p->number == number)
246 246 return (p);
247 247 }
248 248 return (NULL);
249 249 }
250 250
251 251 /* Should be called holding the rsmops_lock mutex */
252 252 static rsmops_ctrl_t *
253 253 find_rsmpi_controller_handle(rsm_controller_handle_t cntlr_handle)
254 254 {
255 255 rsmops_drv_t *p_drv;
256 256 rsmops_ctrl_t *p;
257 257
258 258 ASSERT(MUTEX_HELD(&rsmops_lock));
259 259
260 260 for (p_drv = rsmops_drv_head; p_drv != NULL; p_drv = p_drv->next) {
261 261 for (p = p_drv->ctrl_head; p != NULL; p = p->next) {
262 262 if (p->handle == cntlr_handle)
263 263 return (p);
264 264 }
265 265 }
266 266
267 267 return (NULL);
268 268 }
269 269
270 270 static vnode_t *
271 271 rsmops_device_open(const char *major_name, const minor_t minor_num);
272 272
273 273 int
274 274 rsm_get_controller(const char *name, uint_t number,
275 275 rsm_controller_object_t *controller, uint_t version)
276 276 {
277 277 rsmops_ctrl_t *p_ctrl;
278 278 rsmops_drv_t *p_drv;
279 279 vnode_t *vp;
280 280 int error;
281 281 int (*rsm_get_controller_handler)
282 282 (const char *name, uint_t number,
283 283 rsm_controller_object_t *pcontroller, uint_t version);
284 284
285 285 mutex_enter(&rsmops_lock);
286 286
287 287 /* check if the controller is already registered */
288 288 if ((p_ctrl = find_rsmpi_controller(name, number)) == NULL) {
289 289 /*
290 290 * controller is not registered. We should try to load it
291 291 * First check if the driver is registered
292 292 */
293 293 if ((p_drv = find_rsmpi_driver(name)) == NULL) {
294 294 /* Cannot find the driver. Try to load him */
295 295 mutex_exit(&rsmops_lock);
296 296 if ((error = modload("drv", (char *)name)) == -1) {
297 297 return (RSMERR_CTLR_NOT_PRESENT);
298 298 }
299 299 mutex_enter(&rsmops_lock);
300 300 if ((p_drv = find_rsmpi_driver(name)) == NULL) {
301 301 mutex_exit(&rsmops_lock);
302 302 /*
303 303 * Cannot find yet - maybe the driver we loaded
304 304 * was not a RSMPI driver at all. We'll just
305 305 * fail this call.
306 306 */
307 307 return (RSMERR_CTLR_NOT_PRESENT);
308 308 }
309 309 }
310 310 ASSERT(p_drv);
311 311 p_ctrl = find_rsmpi_controller(name, number);
312 312 if (p_ctrl == NULL) {
313 313 /*
314 314 * controller is not registered.
315 315 * try to do a VOP_OPEN to force it to get registered
316 316 */
317 317 mutex_exit(&rsmops_lock);
318 318 vp = rsmops_device_open(name, number);
319 319 mutex_enter(&rsmops_lock);
320 320 if (vp != NULL) {
321 321 (void) VOP_CLOSE(vp, FREAD|FWRITE, 0, 0,
322 322 CRED(), NULL);
323 323 VN_RELE(vp);
324 324 }
325 325 p_ctrl = find_rsmpi_controller(name, number);
326 326 if (p_ctrl == NULL) {
327 327 mutex_exit(&rsmops_lock);
328 328 return (RSMERR_CTLR_NOT_PRESENT);
329 329 }
330 330 }
331 331 ASSERT(p_ctrl);
332 332 } else {
333 333 p_drv = p_ctrl->p_drv;
334 334 }
335 335 ASSERT(p_drv);
336 336 ASSERT(p_drv == p_ctrl->p_drv);
337 337
338 338 rsm_get_controller_handler = p_drv->drv.rsm_get_controller_handler;
339 339 /*
340 340 * Increase the refcnt right now, so that attempts to deregister
341 341 * while we are using this entry will fail
342 342 */
343 343 p_ctrl->refcnt++;
344 344 mutex_exit(&rsmops_lock);
345 345
346 346 error = (*rsm_get_controller_handler)(name, number, controller,
347 347 version);
348 348 if (error != RSM_SUCCESS) {
349 349 /* We failed - drop the refcnt back */
350 350 mutex_enter(&rsmops_lock);
351 351 /*
352 352 * Even though we had released the global lock, we can
353 353 * guarantee that p_ctrl is still meaningful (and has not
354 354 * been deregistered, freed whatever) because we were holding
355 355 * refcnt on it. So, it is okay to just use p_ctrl here
356 356 * after re-acquiring the global lock
357 357 */
358 358 p_ctrl->refcnt--;
359 359 mutex_exit(&rsmops_lock);
360 360 } else {
361 361 /*
362 362 * Initialize the controller handle field
363 363 */
364 364 mutex_enter(&rsmops_lock);
365 365 if ((p_ctrl = find_rsmpi_controller(name, number)) == NULL) {
366 366 mutex_exit(&rsmops_lock);
367 367 return (RSMERR_CTLR_NOT_PRESENT);
368 368 }
369 369
370 370 p_ctrl->handle = controller->handle;
371 371 mutex_exit(&rsmops_lock);
372 372 }
373 373 return (error);
374 374 }
375 375
376 376 int
377 377 rsm_release_controller(const char *name, uint_t number,
378 378 rsm_controller_object_t *controller)
379 379 {
380 380 rsmops_ctrl_t *p_ctrl;
381 381 rsmops_drv_t *p_drv;
382 382 int error;
383 383 int (*releaser)(const char *name, uint_t number,
384 384 rsm_controller_object_t *controller);
385 385
386 386 mutex_enter(&rsmops_lock);
387 387
388 388 if ((p_ctrl = find_rsmpi_controller(name, number)) == NULL) {
389 389 mutex_exit(&rsmops_lock);
390 390 return (RSMERR_CTLR_NOT_PRESENT);
391 391 }
392 392 p_drv = find_rsmpi_driver(name);
393 393 ASSERT(p_drv); /* If we found controller, there MUST be a driver */
394 394
395 395 /* Found the appropriate driver. Forward the call to it */
396 396 releaser = p_drv->drv.rsm_release_controller_handler;
397 397 mutex_exit(&rsmops_lock);
398 398
399 399 error = (*releaser)(name, number, controller);
400 400 if (error == RSM_SUCCESS) {
401 401 mutex_enter(&rsmops_lock);
402 402 p_ctrl->refcnt--;
403 403 mutex_exit(&rsmops_lock);
404 404 }
405 405 return (error);
406 406 }
407 407
408 408 /* This is expected to be called from the driver's attach function */
409 409 int
410 410 rsm_register_controller(const char *name, uint_t number,
411 411 rsm_controller_attr_t *attrp)
412 412 {
413 413 rsmops_drv_t *p_drv;
414 414 rsmops_ctrl_t *p_ctrl;
415 415
416 416 if (strlen(name) > MAX_DRVNAME)
417 417 return (RSMERR_NAME_TOO_LONG);
418 418
419 419 mutex_enter(&rsmops_lock);
420 420
421 421 /* Check if the driver is registered with us */
422 422 p_drv = find_rsmpi_driver(name);
423 423 if (p_drv == NULL) {
424 424 /*
425 425 * Hey! Driver is not registered, but we are getting a
426 426 * controller ??
427 427 */
428 428 mutex_exit(&rsmops_lock);
429 429 return (RSMERR_DRIVER_NOT_REGISTERED);
430 430 }
431 431
432 432 /* Check if the controller is already registered with us */
433 433 p_ctrl = find_rsmpi_controller(name, number);
434 434 if (p_ctrl) {
435 435 /* already registered */
436 436 mutex_exit(&rsmops_lock);
437 437 return (RSMERR_CTLR_ALREADY_REGISTERED);
438 438 }
439 439
440 440 /* WAIT: sanity check - verify that the dip matches up to name,number */
441 441
442 442 p_ctrl = kmem_alloc(sizeof (rsmops_ctrl_t), KM_SLEEP);
443 443
444 444 /* bump up controller count on the driver */
445 445 p_drv->ctrl_cnt++;
446 446
447 447 p_ctrl->p_drv = p_drv; /* setup the back pointer */
448 448 p_ctrl->number = number;
449 449 p_ctrl->refcnt = 0;
450 450 p_ctrl->attrp = attrp;
451 451 p_ctrl->handle = NULL;
452 452
453 453 /* Now link to head of list */
454 454 p_ctrl->next = p_drv->ctrl_head;
455 455 p_drv->ctrl_head = p_ctrl;
456 456
457 457 mutex_exit(&rsmops_lock);
458 458
459 459 return (RSM_SUCCESS);
460 460 }
461 461
462 462 /*
463 463 * This is expected to be called from the driver's detach function
464 464 * if this function returns EBUSY, the driver is supposed to fail
465 465 * his own detach operation
466 466 */
467 467 int
468 468 rsm_unregister_controller(const char *name, uint_t number)
469 469 {
470 470 rsmops_drv_t *p_drv;
471 471 rsmops_ctrl_t **p_prev;
472 472 rsmops_ctrl_t *found;
473 473
474 474 mutex_enter(&rsmops_lock);
475 475
476 476 /* Check if the driver is registered with us */
477 477 p_drv = find_rsmpi_driver(name);
478 478 if (p_drv == NULL) {
479 479 /* Hey! Driver is not registered */
480 480 mutex_exit(&rsmops_lock);
481 481 return (RSMERR_DRIVER_NOT_REGISTERED);
482 482 }
483 483
484 484 /* Search for the controller in the list */
485 485 for (p_prev = &p_drv->ctrl_head; *p_prev; p_prev = &((*p_prev)->next)) {
486 486 if ((*p_prev)->number == number) {
487 487 /* Found the controller. Check if it is busy */
488 488 found = *p_prev;
489 489
490 490 if (found->refcnt) {
491 491 /* Controller is busy - handles outstanding */
492 492 mutex_exit(&rsmops_lock);
493 493 return (RSMERR_CTLR_IN_USE);
494 494 }
495 495 /* unlink it out */
496 496 *p_prev = found->next;
497 497 /* bump down controller count on the driver */
498 498 p_drv->ctrl_cnt--;
499 499
500 500 mutex_exit(&rsmops_lock);
501 501 kmem_free(found, sizeof (rsmops_ctrl_t));
502 502 return (RSM_SUCCESS);
503 503 }
504 504 }
505 505 mutex_exit(&rsmops_lock);
506 506 /* Could not find the right controller */
507 507 return (RSMERR_CTLR_NOT_REGISTERED);
508 508 }
509 509
510 510
511 511 /*
512 512 * This opens and closes the appropriate device with minor number -
513 513 * hopefully, it will cause the driver to attach and register a controller
514 514 * with us
515 515 */
516 516 static vnode_t *
517 517 rsmops_device_open(const char *major_name, const minor_t minor_num)
518 518 {
519 519 major_t maj;
520 520 vnode_t *vp;
521 521 int ret;
522 522
523 523 if (minor_num == (minor_t)-1) {
524 524 return (NULL);
525 525 }
526 526
527 527 maj = ddi_name_to_major((char *)major_name);
528 528 if (maj == (major_t)-1) {
529 529 return (NULL);
530 530 }
531 531
532 532 vp = makespecvp(makedevice(maj, minor_num), VCHR);
533 533
534 534 ret = VOP_OPEN(&vp, FREAD|FWRITE, CRED(), NULL);
535 535 if (ret == 0) {
536 536 return (vp);
537 537 } else {
538 538 VN_RELE(vp);
539 539 return (NULL);
540 540 }
541 541 }
542 542
543 543 /*
544 544 * Attributes for controller identified by the handle are returned
545 545 * via *attrp. Modifications of attributes is prohibited by client!
546 546 */
547 547 int
548 548 rsm_get_controller_attr(rsm_controller_handle_t handle,
549 549 rsm_controller_attr_t **attrp)
550 550 {
551 551
552 552 rsmops_ctrl_t *p_ctrl;
553 553
554 554 if (handle == NULL)
555 555 return (RSMERR_BAD_CTLR_HNDL);
556 556
557 557 mutex_enter(&rsmops_lock);
558 558
559 559 /* find controller */
560 560 if ((p_ctrl = find_rsmpi_controller_handle(handle)) == NULL) {
561 561 /* can't supply attributes for invalid controller */
562 562 mutex_exit(&rsmops_lock);
563 563 return (RSMERR_BAD_CTLR_HNDL);
564 564 }
565 565 *attrp = p_ctrl->attrp;
566 566 mutex_exit(&rsmops_lock);
567 567
568 568 return (RSM_SUCCESS);
569 569 }
↓ open down ↓ |
515 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX