summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2010-04-06 01:12:18 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2010-04-06 01:12:18 +0000
commitcb0eca8a4c3249f7ebc058c5ac85c785b09f589f (patch)
tree46be3e1c69df9b1dec71f16d7327c6f1a2e13f9f /sys/dev/ic
parentc9ba7b34bf0ef30c5f9b25d7ee14c12bb0caa534 (diff)
modify siop to provide an iopool as a way for the midlayer to manage
access to its free ccbs. ok krw@ beck@ marco@ tested by beck@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/siop.c63
-rw-r--r--sys/dev/ic/siopvar.h3
2 files changed, 45 insertions, 21 deletions
diff --git a/sys/dev/ic/siop.c b/sys/dev/ic/siop.c
index be27fc5352a..003ba4ad743 100644
--- a/sys/dev/ic/siop.c
+++ b/sys/dev/ic/siop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: siop.c,v 1.57 2010/03/23 01:57:19 krw Exp $ */
+/* $OpenBSD: siop.c,v 1.58 2010/04/06 01:12:17 dlg Exp $ */
/* $NetBSD: siop.c,v 1.79 2005/11/18 23:10:32 bouyer Exp $ */
/*
@@ -90,6 +90,8 @@ void siop_scsicmd_end(struct siop_cmd *);
void siop_start(struct siop_softc *);
void siop_timeout(void *);
void siop_scsicmd(struct scsi_xfer *);
+void * siop_cmd_get(void *);
+void siop_cmd_put(void *, void *);
#ifdef DUMP_SCRIPT
void siop_dump_script(struct siop_softc *);
#endif
@@ -196,10 +198,12 @@ siop_attach(sc)
TAILQ_INIT(&sc->urgent_list);
TAILQ_INIT(&sc->cmds);
TAILQ_INIT(&sc->lunsw_list);
+ scsi_iopool_init(&sc->iopool, sc, siop_cmd_get, siop_cmd_put);
sc->sc_currschedslot = 0;
sc->sc_c.sc_link.adapter = &siop_adapter;
sc->sc_c.sc_link.device = &siop_dev;
sc->sc_c.sc_link.openings = SIOP_NTAG;
+ sc->sc_c.sc_link.pool = &sc->iopool;
/* Start with one page worth of commands */
siop_morecbd(sc);
@@ -1202,8 +1206,6 @@ siop_scsicmd_end(siop_cmd)
}
out:
siop_lun->lun_flags &= ~SIOP_LUNF_FULL;
- siop_cmd->cmd_c.status = CMDST_FREE;
- TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
#if 0
if (xs->resid != 0)
printf("resid %d datalen %d\n", xs->resid, xs->datalen);
@@ -1356,6 +1358,42 @@ siop_handle_reset(sc)
}
}
+void *
+siop_cmd_get(void *cookie)
+{
+ struct siop_softc *sc = cookie;
+ struct siop_cmd *siop_cmd;
+ int s;
+
+ /* Look if a ccb is available. */
+ s = splbio();
+ siop_cmd = TAILQ_FIRST(&sc->free_list);
+ if (siop_cmd != NULL) {
+ TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
+#ifdef DIAGNOSTIC
+ if (siop_cmd->cmd_c.status != CMDST_FREE)
+ panic("siop_scsicmd: new cmd not free");
+#endif
+ siop_cmd->cmd_c.status = CMDST_READY;
+ }
+ splx(s);
+
+ return (siop_cmd);
+}
+
+void
+siop_cmd_put(void *cookie, void *io)
+{
+ struct siop_softc *sc = cookie;
+ struct siop_cmd *siop_cmd = io;
+ int s;
+
+ s = splbio();
+ siop_cmd->cmd_c.status = CMDST_FREE;
+ TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
+ splx(s);
+}
+
void
siop_scsicmd(xs)
struct scsi_xfer *xs;
@@ -1427,19 +1465,7 @@ siop_scsicmd(xs)
}
}
- /* Looks like we could issue a command, if a ccb is available. */
- siop_cmd = TAILQ_FIRST(&sc->free_list);
- if (siop_cmd == NULL) {
- xs->error = XS_NO_CCB;
- scsi_done(xs);
- splx(s);
- return;
- }
- TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
-#ifdef DIAGNOSTIC
- if (siop_cmd->cmd_c.status != CMDST_FREE)
- panic("siop_scsicmd: new cmd not free");
-#endif
+ siop_cmd = xs->io;
/* Always reset xs->stimeout, lest we timeout_del() with trash */
timeout_set(&xs->stimeout, siop_timeout, siop_cmd);
@@ -1447,7 +1473,6 @@ siop_scsicmd(xs)
siop_cmd->cmd_c.siop_target = sc->sc_c.targets[target];
siop_cmd->cmd_c.xs = xs;
siop_cmd->cmd_c.flags = 0;
- siop_cmd->cmd_c.status = CMDST_READY;
bzero(&siop_cmd->cmd_c.siop_tables->xscmd,
sizeof(siop_cmd->cmd_c.siop_tables->xscmd));
@@ -1465,9 +1490,7 @@ siop_scsicmd(xs)
if (error) {
printf("%s: unable to load data DMA map: %d\n",
sc->sc_c.sc_dev.dv_xname, error);
- siop_cmd->cmd_c.status = CMDST_FREE;
- TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
- xs->error = XS_NO_CCB;
+ xs->error = XS_DRIVER_STUFFUP;
scsi_done(xs);
splx(s);
return;
diff --git a/sys/dev/ic/siopvar.h b/sys/dev/ic/siopvar.h
index 4fa86f57087..e2057e651d3 100644
--- a/sys/dev/ic/siopvar.h
+++ b/sys/dev/ic/siopvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: siopvar.h,v 1.13 2005/11/20 22:32:48 krw Exp $ */
+/* $OpenBSD: siopvar.h,v 1.14 2010/04/06 01:12:17 dlg Exp $ */
/* $NetBSD: siopvar.h,v 1.22 2005/11/18 23:10:32 bouyer Exp $ */
/*
@@ -115,6 +115,7 @@ struct siop_softc {
struct cmd_list free_list; /* cmd descr free list */
struct cmd_list urgent_list; /* high priority cmd descr list */
struct cmd_list ready_list; /* cmd descr ready list */
+ struct scsi_iopool iopool; /* cmd pool */
struct lunsw_list lunsw_list; /* lunsw free list */
u_int32_t script_free_lo; /* free ram offset from sc_scriptaddr */
u_int32_t script_free_hi; /* free ram offset from sc_scriptaddr */