hi guys,

this makes mpii properly detach devices, which helps a lot if they
have commands in flight. to relevant changes are:

- call the activate(DVACT_DEACTIVATE) function against all the luns
on the target that is going away.
- issue the target reset BEFORE detaching the children devices.
this is needed now tha the midlayer will sleep until all outstanding
commands on a device come back from the adapter before calling the
child devices attach routine.

i have tested this on straight disks, but not on raid volumes. i
need someone to test disk removal behind a raid set before i can
commit it.

assuming testing goes well, can i get oks too?

dlg

Index: mpii.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/mpii.c,v
retrieving revision 1.35
diff -u -p -r1.35 mpii.c
--- mpii.c      23 Aug 2010 00:53:36 -0000      1.35
+++ mpii.c      24 Dec 2010 05:46:34 -0000
@@ -3417,6 +3417,8 @@ mpii_event_sas(struct mpii_softc *sc, st
                        mpii_remove_dev(sc, dev);
                        if (sc->sc_scsibus) {
                                SET(dev->flags, MPII_DF_DETACH);
+                               scsi_activate(sc->sc_scsibus, dev->slot, -1,
+                                   DVACT_DEACTIVATE);
                                if (scsi_task(mpii_event_defer, sc,
                                    dev, 0) != 0)
                                        printf("%s: unable to run device "
@@ -3529,27 +3531,19 @@ mpii_event_defer(void *xsc, void *arg)
        struct mpii_softc       *sc = xsc;
        struct mpii_device      *dev = arg;
 
-       /*
-        * SAS and IR events are delivered separately, so it won't hurt
-        * to wait for a second.
-        */
-       tsleep(sc, PRIBIO, "mpiipause", hz);
-
-       if (!ISSET(dev->flags, MPII_DF_HIDDEN)) {
-               if (ISSET(dev->flags, MPII_DF_ATTACH))
-                       scsi_probe_target(sc->sc_scsibus, dev->slot);
-               else if (ISSET(dev->flags, MPII_DF_DETACH))
-                       scsi_detach_target(sc->sc_scsibus, dev->slot,
-                           DETACH_FORCE);
-       }
-
        if (ISSET(dev->flags, MPII_DF_DETACH)) {
                mpii_sas_remove_device(sc, dev->dev_handle);
+               if (!ISSET(dev->flags, MPII_DF_HIDDEN)) {
+                       scsi_detach_target(sc->sc_scsibus, dev->slot,
+                           DETACH_FORCE);
+               }
                free(dev, M_DEVBUF);
-               return;
-       }
 
-       CLR(dev->flags, MPII_DF_ATTACH);
+       } else if (ISSET(dev->flags, MPII_DF_ATTACH)) {
+               CLR(dev->flags, MPII_DF_ATTACH);
+               if (!ISSET(dev->flags, MPII_DF_HIDDEN))
+                       scsi_probe_target(sc->sc_scsibus, dev->slot);
+       }
 }
 
 void
@@ -4547,9 +4541,12 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
 
        case MPII_IOCSTATUS_BUSY:
        case MPII_IOCSTATUS_INSUFFICIENT_RESOURCES:
+               xs->error = XS_BUSY;
+               break;
+
        case MPII_IOCSTATUS_SCSI_IOC_TERMINATED:
        case MPII_IOCSTATUS_SCSI_TASK_TERMINATED:
-               xs->error = XS_BUSY;
+               xs->error = XS_RESET;
                break;
 
        case MPII_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
@@ -4559,6 +4556,7 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
 
        default:
                xs->error = XS_DRIVER_STUFFUP;
+               break;
        }
 
        if (sie->scsi_state & MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID)

Reply via email to