| 1306 | } |
| 1307 | |
| 1308 | int |
| 1309 | clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up, |
| 1310 | struct cdev **dp, int extra) |
| 1311 | { |
| 1312 | struct clonedevs *cd; |
| 1313 | struct cdev *dev, *ndev, *dl, *de; |
| 1314 | struct make_dev_args args; |
| 1315 | int unit, low, u; |
| 1316 | |
| 1317 | KASSERT(*cdp != NULL, |
| 1318 | ("clone_setup() not called in driver \"%s\"", csw->d_name)); |
| 1319 | KASSERT(!(extra & CLONE_UNITMASK), |
| 1320 | ("Illegal extra bits (0x%x) in clone_create", extra)); |
| 1321 | KASSERT(*up <= CLONE_UNITMASK, |
| 1322 | ("Too high unit (0x%x) in clone_create", *up)); |
| 1323 | KASSERT(csw->d_flags & D_NEEDMINOR, |
| 1324 | ("clone_create() on cdevsw without minor numbers")); |
| 1325 | |
| 1326 | /* |
| 1327 | * Search the list for a lot of things in one go: |
| 1328 | * A preexisting match is returned immediately. |
| 1329 | * The lowest free unit number if we are passed -1, and the place |
| 1330 | * in the list where we should insert that new element. |
| 1331 | * The place to insert a specified unit number, if applicable |
| 1332 | * the end of the list. |
| 1333 | */ |
| 1334 | unit = *up; |
| 1335 | ndev = devfs_alloc(MAKEDEV_WAITOK); |
| 1336 | dev_lock(); |
| 1337 | prep_cdevsw(csw, MAKEDEV_WAITOK); |
| 1338 | low = extra; |
| 1339 | de = dl = NULL; |
| 1340 | cd = *cdp; |
| 1341 | LIST_FOREACH(dev, &cd->head, si_clone) { |
| 1342 | KASSERT(dev->si_flags & SI_CLONELIST, |
| 1343 | ("Dev %p(%s) should be on clonelist", dev, dev->si_name)); |
| 1344 | u = dev2unit(dev); |
| 1345 | if (u == (unit | extra)) { |
| 1346 | *dp = dev; |
| 1347 | dev_unlock(); |
| 1348 | devfs_free(ndev); |
| 1349 | return (0); |
| 1350 | } |
| 1351 | if (unit == -1 && u == low) { |
| 1352 | low++; |
| 1353 | de = dev; |
| 1354 | continue; |
| 1355 | } else if (u < (unit | extra)) { |
| 1356 | de = dev; |
| 1357 | continue; |
| 1358 | } else if (u > (unit | extra)) { |
| 1359 | dl = dev; |
| 1360 | break; |
| 1361 | } |
| 1362 | } |
| 1363 | if (unit == -1) |
| 1364 | unit = low & CLONE_UNITMASK; |
| 1365 | make_dev_args_init(&args); |
no test coverage detected