diff options
author | mav <mav@FreeBSD.org> | 2010-07-10 15:27:27 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2010-07-10 15:27:27 +0000 |
commit | e4e2e8edd34de4dc993090a450bec0770bc1b0f3 (patch) | |
tree | 7d1de0747923ca56ef50736c93e139c34fa2c79c /sys/dev/ata | |
parent | 84fe5497843f77a7b3de4301767abd027ebbed10 (diff) | |
download | FreeBSD-src-e4e2e8edd34de4dc993090a450bec0770bc1b0f3.zip FreeBSD-src-e4e2e8edd34de4dc993090a450bec0770bc1b0f3.tar.gz |
On attach, grab channel lock before setting up interrupt. This fixes crash
in ATA_CAM mode if phy connect event arrive before CAM bus initialization
completed.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r-- | sys/dev/ata/ata-all.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index e9f1082..ac94e8e 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -185,27 +185,29 @@ ata_attach(device_t dev) if (ch->dma.alloc) ch->dma.alloc(dev); + mtx_lock(&ch->state_mtx); /* setup interrupt delivery */ rid = ATA_IRQ_RID; ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (!ch->r_irq) { device_printf(dev, "unable to allocate interrupt\n"); + mtx_unlock(&ch->state_mtx); return ENXIO; } if ((error = bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL, ata_interrupt, ch, &ch->ih))) { device_printf(dev, "unable to setup interrupt\n"); - return error; + goto err1; } #ifndef ATA_CAM + mtx_unlock(&ch->state_mtx); /* probe and attach devices on this channel unless we are in early boot */ if (!ata_delayed_attach) ata_identify(dev); return (0); #else - mtx_lock(&ch->state_mtx); /* Create the device queue for our SIM. */ devq = cam_simq_alloc(1); if (devq == NULL) { @@ -239,11 +241,11 @@ err3: xpt_bus_deregister(cam_sim_path(ch->sim)); err2: cam_sim_free(ch->sim, /*free_devq*/TRUE); +#endif err1: bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); mtx_unlock(&ch->state_mtx); return (error); -#endif } int |