--- a/sys/dev/misc/gpio/gpio.c +++ b/sys/dev/misc/gpio/gpio.c @@ -70,6 +70,7 @@ struct gpio_driver { char *name; struct devfs_bitmap unit_bitmap; + int refs; LIST_ENTRY(gpio_driver) link; }; @@ -554,6 +555,7 @@ continue; master_unit = devfs_clone_bitmap_get(&gpd->unit_bitmap, 0); + gpd->refs++; break; } if (master_unit == -1) { @@ -561,6 +563,7 @@ M_TEMP, M_WAITOK | M_ZERO); gpd->name = kstrdup(gp->driver_name, M_TEMP); devfs_clone_bitmap_init(&gpd->unit_bitmap); + gpd->refs = 1; master_unit = devfs_clone_bitmap_get(&gpd->unit_bitmap, 0); LIST_INSERT_HEAD(&gpio_driverlist, gpd, link); } @@ -600,6 +603,8 @@ } destroy_dev(gp->master_dev); + devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(gpio), + minor(gp->master_dev)); lockmgr(&gpio_lock, LK_EXCLUSIVE); LIST_FOREACH(gpd, &gpio_driverlist, link) { @@ -607,7 +612,11 @@ continue; devfs_clone_bitmap_put(&gpd->unit_bitmap, gp->driver_unit); - LIST_REMOVE(gpd, link); + if (--gpd->refs == 0) { + LIST_REMOVE(gpd, link); + kfree(gpd->name, M_TEMP); + kfree(gpd, M_TEMP); + } break; } lockmgr(&gpio_lock, LK_RELEASE);