On Fri, Dec 24, 2010 at 04:01:19PM +1000, David Gwynne wrote:
> 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
If testing goes well, ok k...@. Alas I don't have any to test.
.... Ken
>
> 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)