diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2010-12-29 03:48:31 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2010-12-29 03:48:31 +0000 |
commit | 1dc8ea7c455d8d778b6ba59a7ba7fe85cef5aa6b (patch) | |
tree | 3fb8b2450a4c847432ac8b20404ed736691243f9 /sys/dev/pci/mpii.c | |
parent | 6b22b2f2165e7747604e85544495cd234bc6978c (diff) |
make 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 as soon as possible.
- 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.
tested on straight disks and on disks in enclosures.
ok and moral support from krw@
Diffstat (limited to 'sys/dev/pci/mpii.c')
-rw-r--r-- | sys/dev/pci/mpii.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/sys/dev/pci/mpii.c b/sys/dev/pci/mpii.c index eac0110e01d..92abdf11edb 100644 --- a/sys/dev/pci/mpii.c +++ b/sys/dev/pci/mpii.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpii.c,v 1.35 2010/08/23 00:53:36 dlg Exp $ */ +/* $OpenBSD: mpii.c,v 1.36 2010/12/29 03:48:30 dlg Exp $ */ /* * Copyright (c) 2010 Mike Belopuhov <mkb@crypt.org.ru> * Copyright (c) 2009 James Giannoules @@ -3417,6 +3417,8 @@ mpii_event_sas(struct mpii_softc *sc, struct mpii_msg_event_reply *enp) 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) |