diff --git a/sys/dev/disk/nata/atapi-tape.c b/sys/dev/disk/nata/atapi-tape.c --- a/sys/dev/disk/nata/atapi-tape.c +++ b/sys/dev/disk/nata/atapi-tape.c @@ -207,6 +207,16 @@ if (((atadev->unit == ATA_MASTER) && !(ch->devices & ATA_ATAPI_MASTER)) || ((atadev->unit == ATA_SLAVE) && !(ch->devices & ATA_ATAPI_SLAVE))) { + /* The device vanished during channel reset. Previously this only did + * device_set_ivars(NULL)+kfree(), so the later ast_detach dereferenced + * the now-NULL ivars at destroy_dev(stp->cdev1) and panicked. Tear down + * the cdevs/queue/devstat here, mirroring ast_detach, so device_delete_child + * -> ast_detach sees NULL ivars and returns cleanly. See DF-2509. */ + destroy_dev(stp->cdev1); + destroy_dev(stp->cdev2); + ata_fail_requests(dev); + dev_ops_remove_minor(&ast_ops, dkmakeunit(device_get_unit(dev))); + devstat_remove_entry(&stp->stats); device_set_ivars(dev, NULL); kfree(stp, M_AST); return 1;