svn commit: r209883 - head/sys/dev/ata

Alexander Motin mav at FreeBSD.org
Sat Jul 10 15:27:28 UTC 2010


Author: mav
Date: Sat Jul 10 15:27:27 2010
New Revision: 209883
URL: http://svn.freebsd.org/changeset/base/209883

Log:
  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.

Modified:
  head/sys/dev/ata/ata-all.c

Modified: head/sys/dev/ata/ata-all.c
==============================================================================
--- head/sys/dev/ata/ata-all.c	Sat Jul 10 15:16:35 2010	(r209882)
+++ head/sys/dev/ata/ata-all.c	Sat Jul 10 15:27:27 2010	(r209883)
@@ -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


More information about the svn-src-head mailing list