summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2014-09-15 12:00:05 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2014-09-15 12:00:05 +0000
commit7eb662dd8f4683e3c765572966de1fa26569d8cd (patch)
tree9aabc561603e15bb8ea0832e69dec0661bd9407e /sys/dev
parent9e6fb0887b2d319c3a96817a536789c7ca236675 (diff)
mark the interrupt handler mpsafe, and drop the kernel lock in the scs_cmd
paths. take it again when going back to other parts of the kernel. tested by and ok kettenis@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/mpi.c41
-rw-r--r--sys/dev/pci/mpi_pci.c4
2 files changed, 28 insertions, 17 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c
index a42503bfa99..e7dcdb7fe34 100644
--- a/sys/dev/ic/mpi.c
+++ b/sys/dev/ic/mpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpi.c,v 1.196 2014/09/14 14:17:24 jsg Exp $ */
+/* $OpenBSD: mpi.c,v 1.197 2014/09/15 12:00:04 dlg Exp $ */
/*
* Copyright (c) 2005, 2006, 2009 David Gwynne <dlg@openbsd.org>
@@ -1310,6 +1310,8 @@ mpi_scsi_cmd(struct scsi_xfer *xs)
DNPRINTF(MPI_D_CMD, "%s: mpi_scsi_cmd\n", DEVNAME(sc));
+ KERNEL_UNLOCK();
+
if (xs->cmdlen > MPI_CDB_LEN) {
DNPRINTF(MPI_D_CMD, "%s: CBD too big %d\n",
DEVNAME(sc), xs->cmdlen);
@@ -1318,8 +1320,7 @@ mpi_scsi_cmd(struct scsi_xfer *xs)
xs->sense.flags = SKEY_ILLEGAL_REQUEST;
xs->sense.add_sense_code = 0x20;
xs->error = XS_SENSE;
- scsi_done(xs);
- return;
+ goto done;
}
ccb = xs->io;
@@ -1371,23 +1372,25 @@ mpi_scsi_cmd(struct scsi_xfer *xs)
htolem32(&io->sense_buf_low_addr, ccb->ccb_cmd_dva +
((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb));
- if (mpi_load_xs(ccb) != 0) {
- xs->error = XS_DRIVER_STUFFUP;
- scsi_done(xs);
- return;
- }
+ if (mpi_load_xs(ccb) != 0)
+ goto stuffup;
timeout_set(&xs->stimeout, mpi_timeout_xs, ccb);
if (xs->flags & SCSI_POLL) {
- if (mpi_poll(sc, ccb, xs->timeout) != 0) {
- xs->error = XS_DRIVER_STUFFUP;
- scsi_done(xs);
- }
- return;
- }
+ if (mpi_poll(sc, ccb, xs->timeout) != 0)
+ goto stuffup;
+ } else
+ mpi_start(sc, ccb);
- mpi_start(sc, ccb);
+ KERNEL_LOCK();
+ return;
+
+stuffup:
+ xs->error = XS_DRIVER_STUFFUP;
+done:
+ KERNEL_LOCK();
+ scsi_done(xs);
}
void
@@ -1414,7 +1417,9 @@ mpi_scsi_cmd_done(struct mpi_ccb *ccb)
if (ccb->ccb_rcb == NULL) {
/* no scsi error, we're ok so drop out early */
xs->status = SCSI_OK;
+ KERNEL_LOCK();
scsi_done(xs);
+ KERNEL_UNLOCK();
return;
}
@@ -2369,14 +2374,18 @@ mpi_evt_sas(struct mpi_softc *sc, struct mpi_rcb *rcb)
switch (ch->reason) {
case MPI_EVT_SASCH_REASON_ADDED:
case MPI_EVT_SASCH_REASON_NO_PERSIST_ADDED:
+ KERNEL_LOCK();
if (scsi_req_probe(sc->sc_scsibus, ch->target, -1) != 0) {
printf("%s: unable to request attach of %d\n",
DEVNAME(sc), ch->target);
}
+ KERNEL_UNLOCK();
break;
case MPI_EVT_SASCH_REASON_NOT_RESPONDING:
+ KERNEL_LOCK();
scsi_activate(sc->sc_scsibus, ch->target, -1, DVACT_DEACTIVATE);
+ KERNEL_UNLOCK();
mtx_enter(&sc->sc_evt_scan_mtx);
SIMPLEQ_INSERT_TAIL(&sc->sc_evt_scan_queue, rcb, rcb_link);
@@ -2450,11 +2459,13 @@ mpi_evt_sas_detach_done(struct mpi_ccb *ccb)
struct mpi_softc *sc = ccb->ccb_sc;
struct mpi_msg_scsi_task_reply *r = ccb->ccb_rcb->rcb_reply;
+ KERNEL_LOCK();
if (scsi_req_detach(sc->sc_scsibus, r->target_id, -1,
DETACH_FORCE) != 0) {
printf("%s: unable to request detach of %d\n",
DEVNAME(sc), r->target_id);
}
+ KERNEL_UNLOCK();
mpi_push_reply(sc, ccb->ccb_rcb);
scsi_io_put(&sc->sc_iopool, ccb);
diff --git a/sys/dev/pci/mpi_pci.c b/sys/dev/pci/mpi_pci.c
index a92a15eac8e..ac017549fe9 100644
--- a/sys/dev/pci/mpi_pci.c
+++ b/sys/dev/pci/mpi_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpi_pci.c,v 1.24 2011/06/09 04:55:44 deraadt Exp $ */
+/* $OpenBSD: mpi_pci.c,v 1.25 2014/09/15 12:00:04 dlg Exp $ */
/*
* Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
@@ -142,7 +142,7 @@ mpi_pci_attach(struct device *parent, struct device *self, void *aux)
goto unmap;
}
intrstr = pci_intr_string(psc->psc_pc, ih);
- psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO,
+ psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO | IPL_MPSAFE,
mpi_intr, sc, sc->sc_dev.dv_xname);
if (psc->psc_ih == NULL) {
printf(": unable to map interrupt%s%s\n",