summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2010-07-10 15:27:27 +0000
committermav <mav@FreeBSD.org>2010-07-10 15:27:27 +0000
commite4e2e8edd34de4dc993090a450bec0770bc1b0f3 (patch)
tree7d1de0747923ca56ef50736c93e139c34fa2c79c /sys/dev/ata
parent84fe5497843f77a7b3de4301767abd027ebbed10 (diff)
downloadFreeBSD-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.c8
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
OpenPOWER on IntegriCloud