diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-01-18 20:50:25 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-01-18 20:50:25 +0000 |
commit | dd2678d72cfd9050e3d7664da058e00f962dde2e (patch) | |
tree | 41430856d8645c04cdcbe7530091889d5719641a | |
parent | 5b993b0f6927dbf33e76996899b9bc588892961b (diff) |
move atapiscsi to iopools by making the entire ata layer use them too.
this would have been difficult before because the ata completion
paths try to be helfpul by freeing xfers on the adapters behalf,
whch doesn't work in the new world scsi model where the layer that
allocated the thing is responsible for freeing it, and expects to
get it back and maybe use it again. however, deraadt@ added magic
flags for hibernate that im now using to keep ata xfers for the
scsi layers.
committing this now so itll be tested. i cant think of a better time
to handle fallout from diffs like this than hackathons.
discussed with deraadt@
-rw-r--r-- | sys/dev/atapiscsi/atapiscsi.c | 13 | ||||
-rw-r--r-- | sys/dev/ic/wdc.c | 36 | ||||
-rw-r--r-- | sys/dev/ic/wdcvar.h | 3 |
3 files changed, 39 insertions, 13 deletions
diff --git a/sys/dev/atapiscsi/atapiscsi.c b/sys/dev/atapiscsi/atapiscsi.c index 90ed8073600..d9a58c1ee17 100644 --- a/sys/dev/atapiscsi/atapiscsi.c +++ b/sys/dev/atapiscsi/atapiscsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atapiscsi.c,v 1.100 2012/08/08 02:32:11 matthew Exp $ */ +/* $OpenBSD: atapiscsi.c,v 1.101 2014/01/18 20:50:24 dlg Exp $ */ /* * This code is derived from code with the copyright below. @@ -213,6 +213,8 @@ atapiscsi_attach(struct device *parent, struct device *self, void *aux) struct ataparams *id = &drvp->id; struct device *child; + extern struct scsi_iopool wdc_xfer_iopool; + printf("\n"); /* Initialize shared data. */ @@ -232,6 +234,7 @@ atapiscsi_attach(struct device *parent, struct device *self, void *aux) as->sc_adapterlink.luns = 1; as->sc_adapterlink.openings = 1; as->sc_adapterlink.flags = SDEV_ATAPI; + as->sc_adapterlink.pool = &wdc_xfer_iopool; strlcpy(drvp->drive_name, as->sc_dev.dv_xname, sizeof(drvp->drive_name)); @@ -340,13 +343,7 @@ wdc_atapi_send_cmd(struct scsi_xfer *sc_xfer) return; } - xfer = wdc_get_xfer(sc_xfer->flags & SCSI_NOSLEEP - ? WDC_NOSLEEP : WDC_CANSLEEP); - if (xfer == NULL) { - sc_xfer->error = XS_NO_CCB; - scsi_done(sc_xfer); - return; - } + xfer = sc_xfer->io; if (sc_xfer->flags & SCSI_POLL) xfer->c_flags |= C_POLL; xfer->drive = as->drive; diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c index 82c9a49319c..1ac49d3e4d2 100644 --- a/sys/dev/ic/wdc.c +++ b/sys/dev/ic/wdc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wdc.c,v 1.120 2014/01/18 04:24:11 dlg Exp $ */ +/* $OpenBSD: wdc.c,v 1.121 2014/01/18 20:50:24 dlg Exp $ */ /* $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -75,6 +75,9 @@ #include <dev/ic/wdcvar.h> #include <dev/ic/wdcevent.h> +#include <scsi/scsi_all.h> +#include <scsi/scsiconf.h> + #define WDCDELAY 100 /* 100 microseconds */ #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY) #if 0 @@ -83,6 +86,10 @@ #endif /* 0 */ struct pool wdc_xfer_pool; +struct scsi_iopool wdc_xfer_iopool; + +void * wdc_xfer_get(void *); +void wdc_xfer_put(void *, void *); void __wdcerror(struct channel_softc *, char *); int __wdcwait_reset(struct channel_softc *, int); @@ -711,6 +718,8 @@ wdc_alloc_queue(void) pool_init(&wdc_xfer_pool, sizeof(struct wdc_xfer), 0, 0, 0, "wdcxfer", NULL); pool_setipl(&wdc_xfer_pool, IPL_BIO); + scsi_iopool_init(&wdc_xfer_iopool, NULL, + wdc_xfer_get, wdc_xfer_put); inited = 1; } @@ -1914,11 +1923,30 @@ wdc_exec_xfer(struct channel_softc *chp, struct wdc_xfer *xfer) wdcstart(chp); } +void * +wdc_xfer_get(void *null) +{ + return (pool_get(&wdc_xfer_pool, PR_NOWAIT | PR_ZERO)); +} + +void +wdc_scrub_xfer(struct wdc_xfer *xfer) +{ + memset(xfer, 0, sizeof(*xfer)); + xfer->c_flags = C_PRIVATEXFER; +} + +void +wdc_xfer_put(void *null, void *xfer) +{ + pool_put(&wdc_xfer_pool, xfer); +} + struct wdc_xfer * wdc_get_xfer(int flags) { - return (pool_get(&wdc_xfer_pool, PR_ZERO | - ((flags & WDC_NOSLEEP) != 0 ? PR_NOWAIT : PR_WAITOK))); + return (scsi_io_get(&wdc_xfer_iopool, + ISSET(flags, WDC_NOSLEEP) ? SCSI_NOSLEEP : 0)); } void @@ -1937,7 +1965,7 @@ wdc_free_xfer(struct channel_softc *chp, struct wdc_xfer *xfer) TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain); splx(s); - pool_put(&wdc_xfer_pool, xfer); + scsi_io_put(&wdc_xfer_iopool, xfer); } diff --git a/sys/dev/ic/wdcvar.h b/sys/dev/ic/wdcvar.h index 4def34ae0ca..8143ff4810f 100644 --- a/sys/dev/ic/wdcvar.h +++ b/sys/dev/ic/wdcvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wdcvar.h,v 1.52 2011/07/15 16:44:17 deraadt Exp $ */ +/* $OpenBSD: wdcvar.h,v 1.53 2014/01/18 20:50:24 dlg Exp $ */ /* $NetBSD: wdcvar.h,v 1.17 1999/04/11 20:50:29 bouyer Exp $ */ /*- @@ -266,6 +266,7 @@ void wdc_exec_xfer(struct channel_softc *, struct wdc_xfer *); struct wdc_xfer *wdc_get_xfer(int); /* int = WDC_NOSLEEP/CANSLEEP */ #define WDC_CANSLEEP 0x00 #define WDC_NOSLEEP 0x01 +void wdc_scrub_xfer(struct wdc_xfer *); void wdc_free_xfer(struct channel_softc *, struct wdc_xfer *); void wdcstart(struct channel_softc *); int wdcreset(struct channel_softc *, int); |