| 565 | } |
| 566 | |
| 567 | static struct cdev * |
| 568 | newdev(struct make_dev_args *args, struct cdev *si) |
| 569 | { |
| 570 | struct cdev *si2; |
| 571 | struct cdevsw *csw; |
| 572 | |
| 573 | dev_lock_assert_locked(); |
| 574 | csw = args->mda_devsw; |
| 575 | si2 = NULL; |
| 576 | if (csw->d_flags & D_NEEDMINOR) { |
| 577 | /* We may want to return an existing device */ |
| 578 | LIST_FOREACH(si2, &csw->d_devs, si_list) { |
| 579 | if (dev2unit(si2) == args->mda_unit) { |
| 580 | dev_free_devlocked(si); |
| 581 | si = si2; |
| 582 | break; |
| 583 | } |
| 584 | } |
| 585 | |
| 586 | /* |
| 587 | * If we're returning an existing device, we should make sure |
| 588 | * it isn't already initialized. This would have been caught |
| 589 | * in consumers anyways, but it's good to catch such a case |
| 590 | * early. We still need to complete initialization of the |
| 591 | * device, and we'll use whatever make_dev_args were passed in |
| 592 | * to do so. |
| 593 | */ |
| 594 | KASSERT(si2 == NULL || (si2->si_flags & SI_NAMED) == 0, |
| 595 | ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)", |
| 596 | args->mda_devsw->d_name, dev2unit(si2), devtoname(si2))); |
| 597 | } |
| 598 | si->si_drv0 = args->mda_unit; |
| 599 | si->si_drv1 = args->mda_si_drv1; |
| 600 | si->si_drv2 = args->mda_si_drv2; |
| 601 | /* Only push to csw->d_devs if it's not a cloned device. */ |
| 602 | if (si2 == NULL) { |
| 603 | si->si_devsw = csw; |
| 604 | LIST_INSERT_HEAD(&csw->d_devs, si, si_list); |
| 605 | } else { |
| 606 | KASSERT(si->si_devsw == csw, |
| 607 | ("%s: inconsistent devsw between clone_create() and make_dev()", |
| 608 | __func__)); |
| 609 | } |
| 610 | return (si); |
| 611 | } |
| 612 | |
| 613 | static void |
| 614 | fini_cdevsw(struct cdevsw *devsw) |
no test coverage detected