scsi_xfers have a thing in them for letting adapters store them on
lists via a LIST_ENTRY. turns out most adapters want SIMPLEQ type
operations, so they end up doing things by hand. LIST_ENTRYs and
SIMPLEQ_ENTRYs are the same size, so this is effectively just a
code simplification.
id appreciate it if a gdt user could test this for me. isp seems
to be fine so far.
ok?
Index: scsi/scsiconf.h
===================================================================
RCS file: /cvs/src/sys/scsi/scsiconf.h,v
retrieving revision 1.150
diff -u -p -r1.150 scsiconf.h
--- scsi/scsiconf.h 1 Jul 2012 01:41:13 -0000 1.150
+++ scsi/scsiconf.h 4 Feb 2013 04:24:40 -0000
@@ -390,7 +390,7 @@ struct scsi_attach_args {
* (via the scsi_link structure)
*/
struct scsi_xfer {
- LIST_ENTRY(scsi_xfer) free_list;
+ SIMPLEQ_ENTRY(scsi_xfer) xfer_list;
int flags;
struct scsi_link *sc_link; /* all about our device and adapter */
int retries; /* the number of times to retry */
@@ -414,6 +414,7 @@ struct scsi_xfer {
void *io; /* adapter io resource */
};
+SIMPLEQ_HEAD(scsi_xfer_list, scsi_xfer);
/*
* Per-request Flag values
Index: dev/ic/gdt_common.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/gdt_common.c,v
retrieving revision 1.61
diff -u -p -r1.61 gdt_common.c
--- dev/ic/gdt_common.c 15 Aug 2012 02:38:14 -0000 1.61
+++ dev/ic/gdt_common.c 4 Feb 2013 04:24:40 -0000
@@ -129,7 +129,7 @@ gdt_attach(struct gdt_softc *sc)
TAILQ_INIT(&sc->sc_free_ccb);
TAILQ_INIT(&sc->sc_ccbq);
TAILQ_INIT(&sc->sc_ucmdq);
- LIST_INIT(&sc->sc_queue);
+ SIMPLEQ_INIT(&sc->sc_queue);
mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
scsi_iopool_init(&sc->sc_iopool, sc, gdt_ccb_alloc, gdt_ccb_free);
@@ -517,14 +517,10 @@ gdt_eval_mapping(u_int32_t size, int *cy
void
gdt_enqueue(struct gdt_softc *sc, struct scsi_xfer *xs, int infront)
{
- if (infront || LIST_FIRST(&sc->sc_queue) == NULL) {
- if (LIST_FIRST(&sc->sc_queue) == NULL)
- sc->sc_queuelast = xs;
- LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
- return;
- }
- LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
- sc->sc_queuelast = xs;
+ if (infront)
+ SIMPLEQ_INSERT_HEAD(&sc->sc_queue, xs, xfer_list);
+ else
+ SIMPLEQ_INSERT_TAIL(&sc->sc_queue, xs, xfer_list);
}
/*
@@ -535,13 +531,9 @@ gdt_dequeue(struct gdt_softc *sc)
{
struct scsi_xfer *xs;
- xs = LIST_FIRST(&sc->sc_queue);
- if (xs == NULL)
- return (NULL);
- LIST_REMOVE(xs, free_list);
-
- if (LIST_FIRST(&sc->sc_queue) == NULL)
- sc->sc_queuelast = NULL;
+ xs = SIMPLEQ_FIRST(&sc->sc_queue);
+ if (xs != NULL)
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, xfer_list);
return (xs);
}
@@ -584,7 +576,7 @@ gdt_scsi_cmd(struct scsi_xfer *xs)
}
/* Don't double enqueue if we came from gdt_chain. */
- if (xs != LIST_FIRST(&sc->sc_queue))
+ if (xs != SIMPLEQ_FIRST(&sc->sc_queue))
gdt_enqueue(sc, xs, 0);
while ((xs = gdt_dequeue(sc)) != NULL) {
@@ -1307,8 +1299,8 @@ gdt_chain(struct gdt_softc *sc)
{
GDT_DPRINTF(GDT_D_INTR, ("gdt_chain(%p) ", sc));
- if (LIST_FIRST(&sc->sc_queue))
- gdt_scsi_cmd(LIST_FIRST(&sc->sc_queue));
+ if (!SIMPLEQ_EMPTY(&sc->sc_queue))
+ gdt_scsi_cmd(SIMPLEQ_FIRST(&sc->sc_queue));
}
void
Index: dev/ic/gdtvar.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/gdtvar.h,v
retrieving revision 1.21
diff -u -p -r1.21 gdtvar.h
--- dev/ic/gdtvar.h 15 Aug 2012 02:38:14 -0000 1.21
+++ dev/ic/gdtvar.h 4 Feb 2013 04:24:40 -0000
@@ -131,8 +131,7 @@ struct gdt_softc {
struct gdt_ccb sc_ccbs[GDT_MAXCMDS];
TAILQ_HEAD(, gdt_ccb) sc_free_ccb, sc_ccbq;
TAILQ_HEAD(, gdt_ucmd) sc_ucmdq;
- LIST_HEAD(, scsi_xfer) sc_queue;
- struct scsi_xfer *sc_queuelast;
+ struct scsi_xfer_list sc_queue;
struct mutex sc_ccb_mtx;
struct scsi_iopool sc_iopool;
Index: dev/ic/isp_openbsd.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/isp_openbsd.c,v
retrieving revision 1.47
diff -u -p -r1.47 isp_openbsd.c
--- dev/ic/isp_openbsd.c 22 Oct 2011 19:34:06 -0000 1.47
+++ dev/ic/isp_openbsd.c 4 Feb 2013 04:24:40 -0000
@@ -103,7 +103,7 @@ isp_attach(struct ispsoftc *isp)
* We only manage a single wait queues for dual bus controllers.
* This is arguably broken.
*/
- isp->isp_osinfo.wqf = isp->isp_osinfo.wqt = NULL;
+ SIMPLEQ_INIT(&isp->isp_osinfo.wq);
lptr->adapter_softc = isp;
lptr->adapter = &isp->isp_osinfo._adapter;
@@ -276,13 +276,7 @@ ispcmd_slow(XS_T *xs)
void
isp_add2_blocked_queue(struct ispsoftc *isp, XS_T *xs)
{
- if (isp->isp_osinfo.wqf != NULL) {
- isp->isp_osinfo.wqt->free_list.le_next = xs;
- } else {
- isp->isp_osinfo.wqf = xs;
- }
- isp->isp_osinfo.wqt = xs;
- xs->free_list.le_next = NULL;
+ SIMPLEQ_INSERT_TAIL(&isp->isp_osinfo.wq, xs, xfer_list);
}
int
@@ -665,53 +659,41 @@ void
isp_trestart(void *arg)
{
struct ispsoftc *isp = arg;
- struct scsi_xfer *list;
+ struct scsi_xfer *xs;
+ struct scsi_xfer_list list;
ISP_LOCK(isp);
isp->isp_osinfo.rtpend = 0;
- list = isp->isp_osinfo.wqf;
- if (isp->isp_osinfo.blocked == 0 && list != NULL) {
- int nrestarted = 0;
-
- isp->isp_osinfo.wqf = NULL;
- ISP_UNLOCK(isp);
- do {
- struct scsi_xfer *xs = list;
- list = xs->free_list.le_next;
- xs->free_list.le_next = NULL;
- isp_requeue(xs);
- if (isp->isp_osinfo.wqf == NULL)
- nrestarted++;
- } while (list != NULL);
-#ifndef SMALL_KERNEL
- isp_prt(isp, ISP_LOGDEBUG0, "requeued %d commands", nrestarted);
-#endif
- } else {
+ if (isp->isp_osinfo.blocked) {
ISP_UNLOCK(isp);
+ return;
+ }
+
+ list = isp->isp_osinfo.wq;
+ SIMPLEQ_INIT(&isp->isp_osinfo.wq);
+ ISP_UNLOCK(isp);
+
+ while ((xs = SIMPLEQ_FIRST(&list)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&list, xfer_list);
+ isp_requeue(xs);
}
}
void
isp_restart(struct ispsoftc *isp)
{
- struct scsi_xfer *list;
+ struct scsi_xfer *xs;
+ struct scsi_xfer_list list;
- list = isp->isp_osinfo.wqf;
- if (isp->isp_osinfo.blocked == 0 && list != NULL) {
- int nrestarted = 0;
-
- isp->isp_osinfo.wqf = NULL;
- do {
- struct scsi_xfer *xs = list;
- list = xs->free_list.le_next;
- xs->free_list.le_next = NULL;
- isp_requeue(xs);
- if (isp->isp_osinfo.wqf == NULL)
- nrestarted++;
- } while (list != NULL);
-#ifndef SMALL_KERNEL
- isp_prt(isp, ISP_LOGDEBUG0, "requeued %d commands", nrestarted);
-#endif
+ if (isp->isp_osinfo.blocked)
+ return;
+
+ list = isp->isp_osinfo.wq;
+ SIMPLEQ_INIT(&isp->isp_osinfo.wq);
+
+ while ((xs = SIMPLEQ_FIRST(&list)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&list, xfer_list);
+ isp_requeue(xs);
}
}
Index: dev/ic/isp_openbsd.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/isp_openbsd.h,v
retrieving revision 1.34
diff -u -p -r1.34 isp_openbsd.h
--- dev/ic/isp_openbsd.h 6 Mar 2011 16:59:42 -0000 1.34
+++ dev/ic/isp_openbsd.h 4 Feb 2013 04:24:40 -0000
@@ -103,7 +103,7 @@ struct isposinfo {
u_int16_t _discovered[2];
} un;
#define discovered un._discovered
- struct scsi_xfer *wqf, *wqt;
+ struct scsi_xfer_list wq;
struct timeout rqt;
};
#define MUST_POLL(isp) \