diff --git a/sys/dev/disk/nata/atapi-cam.c b/sys/dev/disk/nata/atapi-cam.c --- a/sys/dev/disk/nata/atapi-cam.c +++ b/sys/dev/disk/nata/atapi-cam.c @@ -881,6 +881,14 @@ struct atapi_hcb *hcb; if (scp != NULL) { + /* Abort any ATA requests still in flight for this atapi_cam device + * BEFORE freeing the hcbs. atapi_action() submits requests via the + * asynchronous ata_queue_request() with request->driver = hcb; without + * this drain, a request completing after detach invokes atapi_cb() which + * dereferences the already-freed hcb (and the lockuninit'd state_lock). + * See DF-2500. */ + ata_fail_requests(scp->dev); + lockmgr(&scp->state_lock, LK_EXCLUSIVE); TAILQ_FOREACH(hcb, &scp->pending_hcbs, chain) { free_hcb_and_ccb_done(hcb, CAM_UNREC_HBA_ERROR);