1 /*- 2 * Copyright (c) 1999-2002 Poul-Henning Kamp 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/kernel.h> 32 #include <sys/systm.h> 33 #include <sys/bio.h> 34 #include <sys/lock.h> 35 #include <sys/mutex.h> 36 #include <sys/sysctl.h> 37 #include <sys/module.h> 38 #include <sys/malloc.h> 39 #include <sys/conf.h> 40 #include <sys/vnode.h> 41 #include <sys/queue.h> 42 #include <sys/poll.h> 43 #include <sys/ctype.h> 44 #include <sys/tty.h> 45 #include <machine/stdarg.h> 46 47 static MALLOC_DEFINE(M_DEVT, "cdev", "cdev storage"); 48 49 /* Built at compile time from sys/conf/majors */ 50 extern unsigned char reserved_majors[256]; 51 52 /* 53 * This is the number of hash-buckets. Experiments with 'real-life' 54 * dev_t's show that a prime halfway between two powers of two works 55 * best. 56 */ 57 #define DEVT_HASH 83 58 59 static LIST_HEAD(, cdev) dev_hash[DEVT_HASH]; 60 61 static struct mtx devmtx; 62 static void freedev(struct cdev *dev); 63 static struct cdev *newdev(int x, int y, struct cdev *); 64 static void destroy_devl(struct cdev *dev); 65 66 void 67 dev_lock(void) 68 { 69 if (!mtx_initialized(&devmtx)) 70 mtx_init(&devmtx, "cdev", NULL, MTX_DEF); 71 mtx_lock(&devmtx); 72 } 73 74 void 75 dev_unlock(void) 76 { 77 78 mtx_unlock(&devmtx); 79 } 80 81 void 82 dev_ref(struct cdev *dev) 83 { 84 85 mtx_assert(&devmtx, MA_OWNED); 86 dev->si_refcount++; 87 } 88 89 void 90 dev_rel(struct cdev *dev) 91 { 92 int flag = 0; 93 94 mtx_assert(&devmtx, MA_NOTOWNED); 95 dev_lock(); 96 dev->si_refcount--; 97 KASSERT(dev->si_refcount >= 0, 98 ("dev_rel(%s) gave negative count", devtoname(dev))); 99 if (dev->si_usecount == 0 && 100 (dev->si_flags & SI_CHEAPCLONE) && (dev->si_flags & SI_NAMED)) 101 if (dev->si_devsw == NULL && dev->si_refcount == 0) { 102 LIST_REMOVE(dev, si_list); 103 flag = 1; 104 } 105 dev_unlock(); 106 if (flag) 107 freedev(dev); 108 } 109 110 struct cdevsw * 111 dev_refthread(struct cdev *dev) 112 { 113 struct cdevsw *csw; 114 115 mtx_assert(&devmtx, MA_NOTOWNED); 116 dev_lock(); 117 csw = dev->si_devsw; 118 if (csw != NULL) 119 dev->si_threadcount++; 120 dev_unlock(); 121 return (csw); 122 } 123 124 void 125 dev_relthread(struct cdev *dev) 126 { 127 128 mtx_assert(&devmtx, MA_NOTOWNED); 129 dev_lock(); 130 dev->si_threadcount--; 131 dev_unlock(); 132 } 133 134 int 135 nullop(void) 136 { 137 138 return (0); 139 } 140 141 int 142 eopnotsupp(void) 143 { 144 145 return (EOPNOTSUPP); 146 } 147 148 static int 149 enxio(void) 150 { 151 return (ENXIO); 152 } 153 154 static int 155 enodev(void) 156 { 157 return (ENODEV); 158 } 159 160 /* Define a dead_cdevsw for use when devices leave unexpectedly. */ 161 162 #define dead_open (d_open_t *)enxio 163 #define dead_close (d_close_t *)enxio 164 #define dead_read (d_read_t *)enxio 165 #define dead_write (d_write_t *)enxio 166 #define dead_ioctl (d_ioctl_t *)enxio 167 #define dead_poll (d_poll_t *)enodev 168 #define dead_mmap (d_mmap_t *)enodev 169 170 static void 171 dead_strategy(struct bio *bp) 172 { 173 174 biofinish(bp, NULL, ENXIO); 175 } 176 177 #define dead_dump (dumper_t *)enxio 178 #define dead_kqfilter (d_kqfilter_t *)enxio 179 180 static struct cdevsw dead_cdevsw = { 181 .d_version = D_VERSION, 182 .d_flags = D_NEEDGIANT, /* XXX: does dead_strategy need this ? */ 183 .d_open = dead_open, 184 .d_close = dead_close, 185 .d_read = dead_read, 186 .d_write = dead_write, 187 .d_ioctl = dead_ioctl, 188 .d_poll = dead_poll, 189 .d_mmap = dead_mmap, 190 .d_strategy = dead_strategy, 191 .d_name = "dead", 192 .d_maj = 255, 193 .d_dump = dead_dump, 194 .d_kqfilter = dead_kqfilter 195 }; 196 197 /* Default methods if driver does not specify method */ 198 199 #define null_open (d_open_t *)nullop 200 #define null_close (d_close_t *)nullop 201 #define no_read (d_read_t *)enodev 202 #define no_write (d_write_t *)enodev 203 #define no_ioctl (d_ioctl_t *)enodev 204 #define no_mmap (d_mmap_t *)enodev 205 #define no_kqfilter (d_kqfilter_t *)enodev 206 207 static void 208 no_strategy(struct bio *bp) 209 { 210 211 biofinish(bp, NULL, ENODEV); 212 } 213 214 static int 215 no_poll(struct cdev *dev __unused, int events, struct thread *td __unused) 216 { 217 /* 218 * Return true for read/write. If the user asked for something 219 * special, return POLLNVAL, so that clients have a way of 220 * determining reliably whether or not the extended 221 * functionality is present without hard-coding knowledge 222 * of specific filesystem implementations. 223 * Stay in sync with vop_nopoll(). 224 */ 225 if (events & ~POLLSTANDARD) 226 return (POLLNVAL); 227 228 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 229 } 230 231 #define no_dump (dumper_t *)enodev 232 233 /* 234 * struct cdev * and u_dev_t primitives 235 */ 236 237 int 238 major(struct cdev *x) 239 { 240 if (x == NULL) 241 return NODEV; 242 return((x->si_udev >> 8) & 0xff); 243 } 244 245 int 246 minor(struct cdev *x) 247 { 248 if (x == NULL) 249 return NODEV; 250 return(x->si_udev & MAXMINOR); 251 } 252 253 int 254 dev2unit(struct cdev *x) 255 { 256 257 if (x == NULL) 258 return NODEV; 259 return (minor2unit(minor(x))); 260 } 261 262 int 263 minor2unit(int _minor) 264 { 265 266 KASSERT((_minor & ~MAXMINOR) == 0, ("Illegal minor %x", _minor)); 267 return ((_minor & 0xff) | (_minor >> 8)); 268 } 269 270 int 271 unit2minor(int unit) 272 { 273 274 KASSERT(unit <= 0xffffff, ("Invalid unit (%d) in unit2minor", unit)); 275 return ((unit & 0xff) | ((unit << 8) & ~0xffff)); 276 } 277 278 static struct cdev * 279 allocdev(void) 280 { 281 struct cdev *si; 282 283 si = malloc(sizeof *si, M_DEVT, M_USE_RESERVE | M_ZERO | M_WAITOK); 284 si->si_name = si->__si_namebuf; 285 LIST_INIT(&si->si_children); 286 LIST_INIT(&si->si_alist); 287 return (si); 288 } 289 290 static struct cdev * 291 newdev(int x, int y, struct cdev *si) 292 { 293 struct cdev *si2; 294 dev_t udev; 295 int hash; 296 297 mtx_assert(&devmtx, MA_OWNED); 298 if (x == umajor(NODEV) && y == uminor(NODEV)) 299 panic("newdev of NODEV"); 300 udev = (x << 8) | y; 301 hash = udev % DEVT_HASH; 302 LIST_FOREACH(si2, &dev_hash[hash], si_hash) { 303 if (si2->si_udev == udev) { 304 freedev(si); 305 return (si2); 306 } 307 } 308 si->si_udev = udev; 309 LIST_INSERT_HEAD(&dev_hash[hash], si, si_hash); 310 return (si); 311 } 312 313 static void 314 freedev(struct cdev *dev) 315 { 316 317 free(dev, M_DEVT); 318 } 319 320 dev_t 321 dev2udev(struct cdev *x) 322 { 323 if (x == NULL) 324 return (NODEV); 325 return (x->si_udev); 326 } 327 328 struct cdev * 329 findcdev(dev_t udev) 330 { 331 struct cdev *si; 332 int hash; 333 334 mtx_assert(&devmtx, MA_NOTOWNED); 335 if (udev == NODEV) 336 return (NULL); 337 dev_lock(); 338 hash = udev % DEVT_HASH; 339 LIST_FOREACH(si, &dev_hash[hash], si_hash) { 340 if (si->si_udev == udev) 341 break; 342 } 343 dev_unlock(); 344 return (si); 345 } 346 347 int 348 uminor(dev_t dev) 349 { 350 return (dev & MAXMINOR); 351 } 352 353 int 354 umajor(dev_t dev) 355 { 356 return ((dev & ~MAXMINOR) >> 8); 357 } 358 359 static void 360 find_major(struct cdevsw *devsw) 361 { 362 int i; 363 364 if (devsw->d_maj != MAJOR_AUTO) { 365 printf("NOTICE: Ignoring d_maj hint from driver \"%s\", %s", 366 devsw->d_name, "driver should be updated/fixed\n"); 367 devsw->d_maj = MAJOR_AUTO; 368 } 369 for (i = NUMCDEVSW - 1; i > 0; i--) 370 if (reserved_majors[i] != i) 371 break; 372 KASSERT(i > 0, ("Out of major numbers (%s)", devsw->d_name)); 373 devsw->d_maj = i; 374 reserved_majors[i] = i; 375 devsw->d_flags |= D_ALLOCMAJ; 376 } 377 378 static void 379 fini_cdevsw(struct cdevsw *devsw) 380 { 381 if (devsw->d_flags & D_ALLOCMAJ) { 382 reserved_majors[devsw->d_maj] = 0; 383 devsw->d_maj = MAJOR_AUTO; 384 devsw->d_flags &= ~D_ALLOCMAJ; 385 } 386 devsw->d_flags &= ~D_INIT; 387 } 388 389 static void 390 prep_cdevsw(struct cdevsw *devsw) 391 { 392 393 dev_lock(); 394 395 if (devsw->d_version != D_VERSION_00) { 396 printf( 397 "WARNING: Device driver \"%s\" has wrong version %s\n", 398 devsw->d_name, "and is disabled. Recompile KLD module."); 399 devsw->d_open = dead_open; 400 devsw->d_close = dead_close; 401 devsw->d_read = dead_read; 402 devsw->d_write = dead_write; 403 devsw->d_ioctl = dead_ioctl; 404 devsw->d_poll = dead_poll; 405 devsw->d_mmap = dead_mmap; 406 devsw->d_strategy = dead_strategy; 407 devsw->d_dump = dead_dump; 408 devsw->d_kqfilter = dead_kqfilter; 409 } 410 411 if (devsw->d_flags & D_TTY) { 412 if (devsw->d_ioctl == NULL) devsw->d_ioctl = ttyioctl; 413 if (devsw->d_read == NULL) devsw->d_read = ttyread; 414 if (devsw->d_write == NULL) devsw->d_write = ttywrite; 415 if (devsw->d_kqfilter == NULL) devsw->d_kqfilter = ttykqfilter; 416 if (devsw->d_poll == NULL) devsw->d_poll = ttypoll; 417 } 418 419 if (devsw->d_open == NULL) devsw->d_open = null_open; 420 if (devsw->d_close == NULL) devsw->d_close = null_close; 421 if (devsw->d_read == NULL) devsw->d_read = no_read; 422 if (devsw->d_write == NULL) devsw->d_write = no_write; 423 if (devsw->d_ioctl == NULL) devsw->d_ioctl = no_ioctl; 424 if (devsw->d_poll == NULL) devsw->d_poll = no_poll; 425 if (devsw->d_mmap == NULL) devsw->d_mmap = no_mmap; 426 if (devsw->d_strategy == NULL) devsw->d_strategy = no_strategy; 427 if (devsw->d_dump == NULL) devsw->d_dump = no_dump; 428 if (devsw->d_kqfilter == NULL) devsw->d_kqfilter = no_kqfilter; 429 430 LIST_INIT(&devsw->d_devs); 431 432 devsw->d_flags |= D_INIT; 433 434 if (!(devsw->d_flags & D_ALLOCMAJ)) 435 find_major(devsw); 436 dev_unlock(); 437 } 438 439 struct cdev * 440 make_dev(struct cdevsw *devsw, int minornr, uid_t uid, gid_t gid, int perms, const char *fmt, ...) 441 { 442 struct cdev *dev; 443 va_list ap; 444 int i; 445 446 KASSERT((minornr & ~MAXMINOR) == 0, 447 ("Invalid minor (0x%x) in make_dev", minornr)); 448 449 if (!(devsw->d_flags & D_INIT)) 450 prep_cdevsw(devsw); 451 dev = allocdev(); 452 dev_lock(); 453 dev = newdev(devsw->d_maj, minornr, dev); 454 if (dev->si_flags & SI_CHEAPCLONE && 455 dev->si_flags & SI_NAMED && 456 dev->si_devsw == devsw) { 457 /* 458 * This is allowed as it removes races and generally 459 * simplifies cloning devices. 460 * XXX: still ?? 461 */ 462 dev_unlock(); 463 return (dev); 464 } 465 KASSERT(!(dev->si_flags & SI_NAMED), 466 ("make_dev() by driver %s on pre-existing device (maj=%d, min=%d, name=%s)", 467 devsw->d_name, major(dev), minor(dev), devtoname(dev))); 468 469 va_start(ap, fmt); 470 i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap); 471 if (i > (sizeof dev->__si_namebuf - 1)) { 472 printf("WARNING: Device name truncated! (%s)\n", 473 dev->__si_namebuf); 474 } 475 va_end(ap); 476 477 dev->si_devsw = devsw; 478 dev->si_uid = uid; 479 dev->si_gid = gid; 480 dev->si_mode = perms; 481 dev->si_flags |= SI_NAMED; 482 483 LIST_INSERT_HEAD(&devsw->d_devs, dev, si_list); 484 devfs_create(dev); 485 dev_unlock(); 486 return (dev); 487 } 488 489 int 490 dev_named(struct cdev *pdev, const char *name) 491 { 492 struct cdev *cdev; 493 494 if (strcmp(devtoname(pdev), name) == 0) 495 return (1); 496 LIST_FOREACH(cdev, &pdev->si_children, si_siblings) 497 if (strcmp(devtoname(cdev), name) == 0) 498 return (1); 499 return (0); 500 } 501 502 void 503 dev_depends(struct cdev *pdev, struct cdev *cdev) 504 { 505 506 dev_lock(); 507 cdev->si_parent = pdev; 508 cdev->si_flags |= SI_CHILD; 509 LIST_INSERT_HEAD(&pdev->si_children, cdev, si_siblings); 510 dev_unlock(); 511 } 512 513 struct cdev * 514 make_dev_alias(struct cdev *pdev, const char *fmt, ...) 515 { 516 struct cdev *dev; 517 va_list ap; 518 int i; 519 520 dev = allocdev(); 521 dev_lock(); 522 dev->si_flags |= SI_ALIAS; 523 dev->si_flags |= SI_NAMED; 524 va_start(ap, fmt); 525 i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap); 526 if (i > (sizeof dev->__si_namebuf - 1)) { 527 printf("WARNING: Device name truncated! (%s)\n", 528 dev->__si_namebuf); 529 } 530 va_end(ap); 531 532 devfs_create(dev); 533 dev_unlock(); 534 dev_depends(pdev, dev); 535 return (dev); 536 } 537 538 static void 539 destroy_devl(struct cdev *dev) 540 { 541 struct cdevsw *csw; 542 543 mtx_assert(&devmtx, MA_OWNED); 544 KASSERT(dev->si_flags & SI_NAMED, 545 ("WARNING: Driver mistake: destroy_dev on %d/%d\n", 546 major(dev), minor(dev))); 547 548 devfs_destroy(dev); 549 550 /* Remove name marking */ 551 dev->si_flags &= ~SI_NAMED; 552 553 /* If we are a child, remove us from the parents list */ 554 if (dev->si_flags & SI_CHILD) { 555 LIST_REMOVE(dev, si_siblings); 556 dev->si_flags &= ~SI_CHILD; 557 } 558 559 /* Kill our children */ 560 while (!LIST_EMPTY(&dev->si_children)) 561 destroy_devl(LIST_FIRST(&dev->si_children)); 562 563 /* Remove from clone list */ 564 if (dev->si_flags & SI_CLONELIST) { 565 LIST_REMOVE(dev, si_clone); 566 dev->si_flags &= ~SI_CLONELIST; 567 } 568 569 csw = dev->si_devsw; 570 dev->si_devsw = NULL; /* already NULL for SI_ALIAS */ 571 while (csw != NULL && csw->d_purge != NULL && dev->si_threadcount) { 572 printf("Purging %lu threads from %s\n", 573 dev->si_threadcount, devtoname(dev)); 574 csw->d_purge(dev); 575 msleep(csw, &devmtx, PRIBIO, "devprg", hz/10); 576 } 577 if (csw != NULL && csw->d_purge != NULL) 578 printf("All threads purged from %s\n", devtoname(dev)); 579 580 dev->si_drv1 = 0; 581 dev->si_drv2 = 0; 582 bzero(&dev->__si_u, sizeof(dev->__si_u)); 583 584 if (!(dev->si_flags & SI_ALIAS)) { 585 /* Remove from cdevsw list */ 586 LIST_REMOVE(dev, si_list); 587 588 /* If cdevsw has no struct cdev *'s, clean it */ 589 if (LIST_EMPTY(&csw->d_devs)) 590 fini_cdevsw(csw); 591 592 LIST_REMOVE(dev, si_hash); 593 } 594 dev->si_flags &= ~SI_ALIAS; 595 596 if (dev->si_refcount > 0) { 597 LIST_INSERT_HEAD(&dead_cdevsw.d_devs, dev, si_list); 598 } else { 599 freedev(dev); 600 } 601 } 602 603 void 604 destroy_dev(struct cdev *dev) 605 { 606 607 dev_lock(); 608 destroy_devl(dev); 609 dev_unlock(); 610 } 611 612 const char * 613 devtoname(struct cdev *dev) 614 { 615 char *p; 616 struct cdevsw *csw; 617 int mynor; 618 619 if (dev->si_name[0] == '#' || dev->si_name[0] == '\0') { 620 p = dev->si_name; 621 sprintf(p, "#%d", major(dev)); 622 p += strlen(p); 623 csw = dev_refthread(dev); 624 if (csw != NULL) { 625 sprintf(p, "(%s)", csw->d_name); 626 dev_relthread(dev); 627 } 628 p += strlen(p); 629 mynor = minor(dev); 630 if (mynor < 0 || mynor > 255) 631 sprintf(p, "/%#x", (u_int)mynor); 632 else 633 sprintf(p, "/%d", mynor); 634 } 635 return (dev->si_name); 636 } 637 638 int 639 dev_stdclone(char *name, char **namep, const char *stem, int *unit) 640 { 641 int u, i; 642 643 i = strlen(stem); 644 if (bcmp(stem, name, i) != 0) 645 return (0); 646 if (!isdigit(name[i])) 647 return (0); 648 u = 0; 649 if (name[i] == '0' && isdigit(name[i+1])) 650 return (0); 651 while (isdigit(name[i])) { 652 u *= 10; 653 u += name[i++] - '0'; 654 } 655 if (u > 0xffffff) 656 return (0); 657 *unit = u; 658 if (namep) 659 *namep = &name[i]; 660 if (name[i]) 661 return (2); 662 return (1); 663 } 664 665 /* 666 * Helper functions for cloning device drivers. 667 * 668 * The objective here is to make it unnecessary for the device drivers to 669 * use rman or similar to manage their unit number space. Due to the way 670 * we do "on-demand" devices, using rman or other "private" methods 671 * will be very tricky to lock down properly once we lock down this file. 672 * 673 * Instead we give the drivers these routines which puts the struct cdev *'s 674 * that are to be managed on their own list, and gives the driver the ability 675 * to ask for the first free unit number or a given specified unit number. 676 * 677 * In addition these routines support paired devices (pty, nmdm and similar) 678 * by respecting a number of "flag" bits in the minor number. 679 * 680 */ 681 682 struct clonedevs { 683 LIST_HEAD(,cdev) head; 684 }; 685 686 void 687 clone_setup(struct clonedevs **cdp) 688 { 689 690 *cdp = malloc(sizeof **cdp, M_DEVBUF, M_WAITOK | M_ZERO); 691 LIST_INIT(&(*cdp)->head); 692 } 693 694 int 695 clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up, struct cdev **dp, u_int extra) 696 { 697 struct clonedevs *cd; 698 struct cdev *dev, *ndev, *dl, *de; 699 int unit, low, u; 700 701 KASSERT(*cdp != NULL, 702 ("clone_setup() not called in driver \"%s\"", csw->d_name)); 703 KASSERT(!(extra & CLONE_UNITMASK), 704 ("Illegal extra bits (0x%x) in clone_create", extra)); 705 KASSERT(*up <= CLONE_UNITMASK, 706 ("Too high unit (0x%x) in clone_create", *up)); 707 708 if (!(csw->d_flags & D_INIT)) 709 prep_cdevsw(csw); 710 711 /* 712 * Search the list for a lot of things in one go: 713 * A preexisting match is returned immediately. 714 * The lowest free unit number if we are passed -1, and the place 715 * in the list where we should insert that new element. 716 * The place to insert a specified unit number, if applicable 717 * the end of the list. 718 */ 719 unit = *up; 720 ndev = allocdev(); 721 dev_lock(); 722 low = extra; 723 de = dl = NULL; 724 cd = *cdp; 725 LIST_FOREACH(dev, &cd->head, si_clone) { 726 KASSERT(dev->si_flags & SI_CLONELIST, 727 ("Dev %p(%s) should be on clonelist", dev, dev->si_name)); 728 u = dev2unit(dev); 729 if (u == (unit | extra)) { 730 *dp = dev; 731 freedev(ndev); 732 dev_unlock(); 733 return (0); 734 } 735 if (unit == -1 && u == low) { 736 low++; 737 de = dev; 738 continue; 739 } 740 if (u > (unit | extra)) { 741 dl = dev; 742 break; 743 } 744 } 745 if (unit == -1) 746 unit = low & CLONE_UNITMASK; 747 dev = newdev(csw->d_maj, unit2minor(unit | extra), ndev); 748 if (dev->si_flags & SI_CLONELIST) { 749 printf("dev %p (%s) is on clonelist\n", dev, dev->si_name); 750 printf("unit=%d\n", unit); 751 LIST_FOREACH(dev, &cd->head, si_clone) { 752 printf("\t%p %s\n", dev, dev->si_name); 753 } 754 panic("foo"); 755 } 756 KASSERT(!(dev->si_flags & SI_CLONELIST), 757 ("Dev %p(%s) should not be on clonelist", dev, dev->si_name)); 758 if (dl != NULL) 759 LIST_INSERT_BEFORE(dl, dev, si_clone); 760 else if (de != NULL) 761 LIST_INSERT_AFTER(de, dev, si_clone); 762 else 763 LIST_INSERT_HEAD(&cd->head, dev, si_clone); 764 dev->si_flags |= SI_CLONELIST; 765 *up = unit; 766 dev_unlock(); 767 return (1); 768 } 769 770 /* 771 * Kill everything still on the list. The driver should already have 772 * disposed of any softc hung of the struct cdev *'s at this time. 773 */ 774 void 775 clone_cleanup(struct clonedevs **cdp) 776 { 777 struct cdev *dev, *tdev; 778 struct clonedevs *cd; 779 780 cd = *cdp; 781 if (cd == NULL) 782 return; 783 dev_lock(); 784 LIST_FOREACH_SAFE(dev, &cd->head, si_clone, tdev) { 785 KASSERT(dev->si_flags & SI_CLONELIST, 786 ("Dev %p(%s) should be on clonelist", dev, dev->si_name)); 787 KASSERT(dev->si_flags & SI_NAMED, 788 ("Driver has goofed in cloning underways udev %x", dev->si_udev)); 789 destroy_devl(dev); 790 } 791 dev_unlock(); 792 free(cd, M_DEVBUF); 793 *cdp = NULL; 794 } 795 796 /* 797 * Helper sysctl for devname(3). We're given a struct cdev * and return 798 * the name, if any, registered by the device driver. 799 */ 800 static int 801 sysctl_devname(SYSCTL_HANDLER_ARGS) 802 { 803 int error; 804 dev_t ud; 805 struct cdev *dev; 806 807 error = SYSCTL_IN(req, &ud, sizeof (ud)); 808 if (error) 809 return (error); 810 if (ud == NODEV) 811 return(EINVAL); 812 dev = findcdev(ud); 813 if (dev == NULL) 814 error = ENOENT; 815 else 816 error = SYSCTL_OUT(req, dev->si_name, strlen(dev->si_name) + 1); 817 return (error); 818 } 819 820 SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY, 821 NULL, 0, sysctl_devname, "", "devname(3) handler"); 822