Author: mav
Date: Sun Jul 18 07:23:00 2010
New Revision: 210208
URL: http://svn.freebsd.org/changeset/base/210208

Log:
  MFC r209883, r209944:
  Make interrupt handler check that CAM bus initialization completed before
  touching it. It fixes possible panic during controller attach in ATA_CAM
  mode.
  
  While there, slightly improve attach errors handling.

Modified:
  stable/8/sys/dev/ata/ata-all.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/ata/ata-all.c
==============================================================================
--- stable/8/sys/dev/ata/ata-all.c      Sun Jul 18 07:19:23 2010        
(r210207)
+++ stable/8/sys/dev/ata/ata-all.c      Sun Jul 18 07:23:00 2010        
(r210208)
@@ -195,6 +195,7 @@ ata_attach(device_t dev)
     }
     if ((error = bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL,
                                ata_interrupt, ch, &ch->ih))) {
+       bus_release_resource(dev, SYS_RES_IRQ, rid, ch->r_irq);
        device_printf(dev, "unable to setup interrupt\n");
        return error;
     }
@@ -218,8 +219,9 @@ ata_attach(device_t dev)
            device_get_unit(dev), &ch->state_mtx, 1, 0, devq);
        if (ch->sim == NULL) {
                device_printf(dev, "unable to allocate sim\n");
+               cam_simq_free(devq);
                error = ENOMEM;
-               goto err2;
+               goto err1;
        }
        if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) {
                device_printf(dev, "unable to register xpt bus\n");
@@ -239,8 +241,9 @@ err3:
        xpt_bus_deregister(cam_sim_path(ch->sim));
 err2:
        cam_sim_free(ch->sim, /*free_devq*/TRUE);
+       ch->sim = NULL;
 err1:
-       bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
+       bus_release_resource(dev, SYS_RES_IRQ, rid, ch->r_irq);
        mtx_unlock(&ch->state_mtx);
        return (error);
 #endif
@@ -281,6 +284,7 @@ ata_detach(device_t dev)
        xpt_free_path(ch->path);
        xpt_bus_deregister(cam_sim_path(ch->sim));
        cam_sim_free(ch->sim, /*free_devq*/TRUE);
+       ch->sim = NULL;
        mtx_unlock(&ch->state_mtx);
 #endif
 
@@ -307,9 +311,12 @@ ata_conn_event(void *context, int dummy)
        union ccb *ccb;
 
        mtx_lock(&ch->state_mtx);
+       if (ch->sim == NULL) {
+               mtx_unlock(&ch->state_mtx);
+               return;
+       }
        ata_reinit(dev);
-       mtx_unlock(&ch->state_mtx);
-       if ((ccb = xpt_alloc_ccb()) == NULL)
+       if ((ccb = xpt_alloc_ccb_nowait()) == NULL)
                return;
        if (xpt_create_path(&ccb->ccb_h.path, NULL,
            cam_sim_path(ch->sim),
@@ -318,6 +325,7 @@ ata_conn_event(void *context, int dummy)
                return;
        }
        xpt_rescan(ccb);
+       mtx_unlock(&ch->state_mtx);
 #else
        ata_reinit(dev);
 #endif
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to