summaryrefslogtreecommitdiff
path: root/sys/dev/pci/mpii.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2010-12-29 03:48:31 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2010-12-29 03:48:31 +0000
commit1dc8ea7c455d8d778b6ba59a7ba7fe85cef5aa6b (patch)
tree3fb8b2450a4c847432ac8b20404ed736691243f9 /sys/dev/pci/mpii.c
parent6b22b2f2165e7747604e85544495cd234bc6978c (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.c36
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)