diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2009-10-23 01:02:30 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2009-10-23 01:02:30 +0000 |
commit | 99fa425b37c13e9f732b64afa5c60e4de9bf0ad0 (patch) | |
tree | e5410dc92018c2b14fc013c79f55d8803f740625 /sys | |
parent | c2aca1d2e85d78cb073c1a74abb0109f077fc900 (diff) |
if you're attempting to detach multiple devices (eg, many targets,
many luns, or the entire bus), dont report ENXIO as an error to the
caller. this broke autoconf when it tried to forcefully remove a
bus such as umass and it thought there was a failure.
this introduces a way for scsi hbas to call activate/deactivate on
a device based on its target/lun address via a call to scsi_activate().
they can then schedule the actual detach/attach in a thread later via
scsi_req_probe/detach.
the mpi changes tweak the sas event handling code to use these apis
to properly handle attaches and detaches of disks. event handling
is still disabled till i can make it less chatty.
umass breakage reported by form@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/mpi.c | 48 | ||||
-rw-r--r-- | sys/scsi/mpath.c | 10 | ||||
-rw-r--r-- | sys/scsi/scsiconf.c | 121 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 8 |
4 files changed, 103 insertions, 84 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c index 244928877bc..d77080d8c69 100644 --- a/sys/dev/ic/mpi.c +++ b/sys/dev/ic/mpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpi.c,v 1.114 2009/10/15 12:38:49 dlg Exp $ */ +/* $OpenBSD: mpi.c,v 1.115 2009/10/23 01:02:29 dlg Exp $ */ /* * Copyright (c) 2005, 2006 David Gwynne <dlg@openbsd.org> @@ -140,7 +140,7 @@ void mpi_eventnotify_done(struct mpi_ccb *); void mpi_eventack(struct mpi_softc *, struct mpi_msg_event_reply *); void mpi_eventack_done(struct mpi_ccb *); -void mpi_evt_sas(void *, void *); +void mpi_evt_sas(struct mpi_softc *, struct mpi_rcb *); int mpi_req_cfg_header(struct mpi_softc *, u_int8_t, u_int8_t, u_int32_t, int, void *); @@ -2124,7 +2124,6 @@ mpi_eventnotify_done(struct mpi_ccb *ccb) { struct mpi_softc *sc = ccb->ccb_sc; struct mpi_msg_event_reply *enp = ccb->ccb_rcb->rcb_reply; - int deferred = 0; DNPRINTF(MPI_D_EVT, "%s: mpi_eventnotify_done\n", DEVNAME(sc)); @@ -2154,12 +2153,7 @@ mpi_eventnotify_done(struct mpi_ccb *ccb) if (sc->sc_scsibus == NULL) break; - if (scsi_task(mpi_evt_sas, sc, ccb->ccb_rcb, 0) != 0) { - printf("%s: unable to run SAS device status change\n", - DEVNAME(sc)); - break; - } - deferred = 1; + mpi_evt_sas(sc, ccb->ccb_rcb); break; default: @@ -2168,27 +2162,23 @@ mpi_eventnotify_done(struct mpi_ccb *ccb) break; } - if (!deferred) { - if (enp->ack_required) - mpi_eventack(sc, enp); - mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); - } + if (enp->ack_required) + mpi_eventack(sc, enp); + mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); +#if 0 + /* fc hbas have a bad habit of setting this without meaning it. */ if ((enp->msg_flags & MPI_EVENT_FLAGS_REPLY_KEPT) == 0) { - /* XXX this shouldnt happen till shutdown */ mpi_put_ccb(sc, ccb); } +#endif } void -mpi_evt_sas(void *xsc, void *arg) +mpi_evt_sas(struct mpi_softc *sc, struct mpi_rcb *rcb) { - struct mpi_softc *sc = xsc; - struct mpi_rcb *rcb = arg; - struct mpi_msg_event_reply *enp = rcb->rcb_reply; struct mpi_evt_sas_change *ch; u_int8_t *data; - int s; data = rcb->rcb_reply; data += sizeof(struct mpi_msg_event_reply); @@ -2200,11 +2190,19 @@ mpi_evt_sas(void *xsc, void *arg) switch (ch->reason) { case MPI_EVT_SASCH_REASON_ADDED: case MPI_EVT_SASCH_REASON_NO_PERSIST_ADDED: - scsi_probe_target(sc->sc_scsibus, ch->target); + if (scsi_req_probe(sc->sc_scsibus, ch->target, -1) != 0) { + printf("%s: unable to request attach of %d\n", + DEVNAME(sc), ch->target); + } break; case MPI_EVT_SASCH_REASON_NOT_RESPONDING: - scsi_detach_target(sc->sc_scsibus, ch->target, DETACH_FORCE); + scsi_activate(sc->sc_scsibus, ch->target, -1, DVACT_DEACTIVATE); + if (scsi_req_detach(sc->sc_scsibus, ch->target, -1, + DETACH_FORCE) != 0) { + printf("%s: unable to request detach of %d\n", + DEVNAME(sc), ch->target); + } break; case MPI_EVT_SASCH_REASON_SMART_DATA: @@ -2216,12 +2214,6 @@ mpi_evt_sas(void *xsc, void *arg) "0x%02x\n", DEVNAME(sc), ch->reason); break; } - - s = splbio(); - mpi_push_reply(sc, rcb->rcb_reply_dva); - if (enp->ack_required) - mpi_eventack(sc, enp); - splx(s); } void diff --git a/sys/scsi/mpath.c b/sys/scsi/mpath.c index cbd0a890ca1..7f0a4f64766 100644 --- a/sys/scsi/mpath.c +++ b/sys/scsi/mpath.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpath.c,v 1.6 2009/10/22 11:56:32 dlg Exp $ */ +/* $OpenBSD: mpath.c,v 1.7 2009/10/23 01:02:29 dlg Exp $ */ /* * Copyright (c) 2009 David Gwynne <dlg@openbsd.org> @@ -308,15 +308,15 @@ mpath_path_detach(struct scsi_link *link, int flags) panic("mpath: unable to locate path for detach"); } -int +void mpath_path_activate(struct scsi_link *link) { - return (0); + } -int +void mpath_path_deactivate(struct scsi_link *link) { - return (0); + } diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index 17fe99141ed..431cd0e029c 100644 --- a/sys/scsi/scsiconf.c +++ b/sys/scsi/scsiconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.c,v 1.146 2009/10/22 11:56:32 dlg Exp $ */ +/* $OpenBSD: scsiconf.c,v 1.147 2009/10/23 01:02:29 dlg Exp $ */ /* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */ /* @@ -113,6 +113,10 @@ int scsi_autoconf = SCSI_AUTOCONF; int scsibusprint(void *, const char *); void scsibus_printlink(struct scsi_link *); +void scsi_activate_bus(struct scsibus_softc *, int); +void scsi_activate_target(struct scsibus_softc *, int, int); +void scsi_activate_lun(struct scsibus_softc *, int, int, int); + const u_int8_t version_to_spc [] = { 0, /* 0x00: The device does not claim conformance to any standard. */ 1, /* 0x01: (Obsolete) SCSI-1 in olden times. */ @@ -200,54 +204,79 @@ int scsibusactivate(struct device *dev, int act) { struct scsibus_softc *sc = (struct scsibus_softc *)dev; - struct scsi_link *link; - int i, j; - int rv, ret = 0; - for (i = 0; i < sc->sc_buswidth; i++) { - if (sc->sc_link[i] == NULL) - continue; + scsi_activate(sc, -1, -1, act); - for (j = 0; j < sc->adapter_link->luns; j++) { - link = sc->sc_link[i][j]; - if (link == NULL) - continue; - dev = link->device_softc; + return (0); +} - switch (act) { - case DVACT_ACTIVATE: +void +scsi_activate(struct scsibus_softc *sc, int target, int lun, int act) +{ + if (target == -1 && lun == -1) + scsi_activate_bus(sc, act); + + if (target == -1) + return; + + if (lun == -1) + scsi_activate_target(sc, target, act); + + scsi_activate_lun(sc, target, lun, act); +} + +void +scsi_activate_bus(struct scsibus_softc *sc, int act) +{ + int target; + + for (target = 0; target < sc->sc_buswidth; target++) + scsi_activate_target(sc, target, act); +} + +void +scsi_activate_target(struct scsibus_softc *sc, int target, int act) +{ + int lun; + + for (lun = 0; lun < sc->adapter_link->luns; lun++) + scsi_activate_lun(sc, target, lun, act); +} + +void +scsi_activate_lun(struct scsibus_softc *sc, int target, int lun, int act) +{ + struct scsi_link *link = sc->sc_link[target][lun]; + struct device *dev; + + if (link == NULL) + return; + + dev = link->device_softc; + switch (act) { + case DVACT_ACTIVATE: #if NMPATH > 0 - if (dev == NULL) - rv = mpath_path_activate(link); - else + if (dev == NULL) + mpath_path_activate(link); + else #endif /* NMPATH */ - rv = config_activate(dev); - break; + config_activate(dev); + break; - case DVACT_DEACTIVATE: + case DVACT_DEACTIVATE: #if NMPATH > 0 - if (dev == NULL) - rv = mpath_path_deactivate(link); - else + if (dev == NULL) + mpath_path_deactivate(link); + else #endif /* NMPATH */ - rv = config_deactivate(dev); - break; - default: + config_deactivate(dev); + break; + default: #ifdef DIAGNOSTIC - printf("%s: unsupported act %d\n", - sc->sc_dev.dv_xname, act); + printf("%s: unsupported act %d\n", sc->sc_dev.dv_xname, act); #endif - rv = EOPNOTSUPP; - break; - - } - - if (rv != 0) - ret = rv; - } + break; } - - return (ret); } int @@ -426,24 +455,22 @@ int scsi_detach_bus(struct scsibus_softc *sc, int flags) { struct scsi_link *alink = sc->adapter_link; - int i, err, rv = 0, detached; + int i, err, rv = 0; for (i = 0; i < alink->adapter_buswidth; i++) { err = scsi_detach_target(sc, i, flags); - if (err == 0) - detached = 1; - else + if (err != 0 && err != ENXIO) rv = err; } - return (detached ? rv : ENXIO); + return (rv); } int scsi_detach_target(struct scsibus_softc *sc, int target, int flags) { struct scsi_link *alink = sc->adapter_link; - int i, err, rv = 0, detached = 0; + int i, err, rv = 0; if (target < 0 || target >= alink->adapter_buswidth || target == alink->adapter_target) @@ -457,13 +484,11 @@ scsi_detach_target(struct scsibus_softc *sc, int target, int flags) continue; err = scsi_detach_lun(sc, target, i, flags); - if (err == 0) - detached = 1; - else + if (err != 0 && err != ENXIO) rv = err; } - return (detached ? rv : ENXIO); + return (rv); } int diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index 63cdacecd1b..f3039640b3d 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.h,v 1.104 2009/10/22 11:56:32 dlg Exp $ */ +/* $OpenBSD: scsiconf.h,v 1.105 2009/10/23 01:02:29 dlg Exp $ */ /* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */ /* @@ -571,6 +571,8 @@ int scsi_detach_lun(struct scsibus_softc *, int, int, int); int scsi_req_probe(struct scsibus_softc *, int, int); int scsi_req_detach(struct scsibus_softc *, int, int, int); +void scsi_activate(struct scsibus_softc *, int, int, int); + extern const u_int8_t version_to_spc[]; #define SCSISPC(x)(version_to_spc[(x) & SID_ANSII]) @@ -584,8 +586,8 @@ void scsi_xs_put(struct scsi_xfer *); int mpath_path_attach(struct scsi_link *); int mpath_path_detach(struct scsi_link *, int); -int mpath_path_activate(struct scsi_link *); -int mpath_path_deactivate(struct scsi_link *); +void mpath_path_activate(struct scsi_link *); +void mpath_path_deactivate(struct scsi_link *); #endif /* _KERNEL */ #endif /* SCSI_SCSICONF_H */ |