diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2011-03-17 21:30:25 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2011-03-17 21:30:25 +0000 |
commit | b71b15e5f1c171efa42d93994e43a18433eadf69 (patch) | |
tree | 2221cea7c6302adf6d3059fcf4823dc937a4a178 /sys/scsi/st.c | |
parent | 81343b1aa9521c707413b624b863c29672abff6f (diff) |
use dma_alloc/dma_free instead of malloc to allocate buffers which need
to be in the right address space.
help from matthew and krw
Diffstat (limited to 'sys/scsi/st.c')
-rw-r--r-- | sys/scsi/st.c | 126 |
1 files changed, 67 insertions, 59 deletions
diff --git a/sys/scsi/st.c b/sys/scsi/st.c index f5323b61eb0..7f81323ee77 100644 --- a/sys/scsi/st.c +++ b/sys/scsi/st.c @@ -1,4 +1,4 @@ -/* $OpenBSD: st.c,v 1.116 2010/12/24 02:45:33 krw Exp $ */ +/* $OpenBSD: st.c,v 1.117 2011/03/17 21:30:24 deraadt Exp $ */ /* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */ /* @@ -62,7 +62,7 @@ #include <sys/errno.h> #include <sys/ioctl.h> #include <sys/stat.h> -#include <sys/malloc.h> +#include <sys/pool.h> #include <sys/buf.h> #include <sys/proc.h> #include <sys/mtio.h> @@ -1409,21 +1409,28 @@ st_read(struct st_softc *st, char *buf, int size, int flags) int st_read_block_limits(struct st_softc *st, int flags) { - struct scsi_block_limits_data block_limits; + struct scsi_block_limits_data *block_limits = NULL; struct scsi_block_limits *cmd; struct scsi_link *sc_link = st->sc_link; struct scsi_xfer *xs; - int error; + int error = 0; if ((sc_link->flags & SDEV_MEDIA_LOADED)) return (0); - xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN); - if (xs == NULL) + block_limits = dma_alloc(sizeof(*block_limits), PR_NOWAIT); + if (block_limits == NULL) return (ENOMEM); + + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN); + if (xs == NULL) { + error = ENOMEM; + goto done; + } + xs->cmdlen = sizeof(*cmd); - xs->data = (void *)&block_limits; - xs->datalen = sizeof(block_limits); + xs->data = (void *)block_limits; + xs->datalen = sizeof(*block_limits); xs->timeout = ST_CTL_TIME; cmd = (struct scsi_block_limits *)xs->cmd; @@ -1433,12 +1440,15 @@ st_read_block_limits(struct st_softc *st, int flags) scsi_xs_put(xs); if (error == 0) { - st->blkmin = _2btol(block_limits.min_length); - st->blkmax = _3btol(block_limits.max_length); + st->blkmin = _2btol(block_limits->min_length); + st->blkmax = _3btol(block_limits->max_length); SC_DEBUG(sc_link, SDEV_DB3, ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax)); } +done: + if (block_limits) + dma_free(block_limits, sizeof(*block_limits)); return (error); } @@ -1455,15 +1465,15 @@ st_read_block_limits(struct st_softc *st, int flags) int st_mode_sense(struct st_softc *st, int flags) { - union scsi_mode_sense_buf *data; + union scsi_mode_sense_buf *data = NULL; struct scsi_link *sc_link = st->sc_link; u_int64_t block_count; u_int32_t density, block_size; u_char *page0 = NULL; u_int8_t dev_spec; - int error, big; + int error = 0, big; - data = malloc(sizeof(*data), M_TEMP, M_NOWAIT); + data = dma_alloc(sizeof(*data), PR_NOWAIT); if (data == NULL) return (ENOMEM); @@ -1472,10 +1482,8 @@ st_mode_sense(struct st_softc *st, int flags) */ error = scsi_do_mode_sense(sc_link, 0, data, (void **)&page0, &density, &block_count, &block_size, 1, flags | SCSI_SILENT, &big); - if (error != 0) { - free(data, M_TEMP); - return (error); - } + if (error != 0) + goto done; /* It is valid for no page0 to be available. */ @@ -1502,8 +1510,10 @@ st_mode_sense(struct st_softc *st, int flags) sc_link->flags |= SDEV_MEDIA_LOADED; - free(data, M_TEMP); - return (0); +done: + if (data) + dma_free(data, sizeof(*data)); + return (error); } /* @@ -1513,19 +1523,21 @@ st_mode_sense(struct st_softc *st, int flags) int st_mode_select(struct st_softc *st, int flags) { - union scsi_mode_sense_buf *inbuf, *outbuf; + union scsi_mode_sense_buf *inbuf = NULL, *outbuf = NULL; struct scsi_blk_desc general; struct scsi_link *sc_link = st->sc_link; u_int8_t *page0 = NULL; - int error, big, page0_size; + int error = 0, big, page0_size; - inbuf = malloc(sizeof(*inbuf), M_TEMP, M_NOWAIT); - if (inbuf == NULL) - return (ENOMEM); - outbuf = malloc(sizeof(*outbuf), M_TEMP, M_NOWAIT | M_ZERO); + inbuf = dma_alloc(sizeof(*inbuf), PR_NOWAIT); + if (inbuf == NULL) { + error = ENOMEM; + goto done; + } + outbuf = dma_alloc(sizeof(*outbuf), PR_NOWAIT | PR_ZERO); if (outbuf == NULL) { - free(inbuf, M_TEMP); - return (ENOMEM); + error = ENOMEM; + goto done; } /* @@ -1537,15 +1549,13 @@ st_mode_select(struct st_softc *st, int flags) SC_DEBUG(sc_link, SDEV_DB3, ("not setting density 0x%x blksize 0x%x\n", st->density, st->blksize)); - free(inbuf, M_TEMP); - free(outbuf, M_TEMP); - return (0); + error = 0; + goto done; } if (sc_link->flags & SDEV_ATAPI) { - free(inbuf, M_TEMP); - free(outbuf, M_TEMP); - return (0); + error = 0; + goto done; } bzero(&general, sizeof(general)); @@ -1559,11 +1569,8 @@ st_mode_select(struct st_softc *st, int flags) */ error = scsi_do_mode_sense(sc_link, 0, inbuf, (void **)&page0, NULL, NULL, NULL, 1, flags | SCSI_SILENT, &big); - if (error != 0) { - free(inbuf, M_TEMP); - free(outbuf, M_TEMP); - return (error); - } + if (error != 0) + goto done; if (page0 == NULL) { page0_size = 0; @@ -1596,9 +1603,7 @@ st_mode_select(struct st_softc *st, int flags) &general, sizeof(general)); error = scsi_mode_select(st->sc_link, 0, &outbuf->hdr, flags, ST_CTL_TIME); - free(inbuf, M_TEMP); - free(outbuf, M_TEMP); - return (error); + goto done; } /* MODE SENSE (10) header was returned, so use MODE SELECT (10). */ @@ -1612,8 +1617,11 @@ st_mode_select(struct st_softc *st, int flags) error = scsi_mode_select_big(st->sc_link, 0, &outbuf->hdr_big, flags, ST_CTL_TIME); - free(inbuf, M_TEMP); - free(outbuf, M_TEMP); +done: + if (inbuf) + dma_free(inbuf, sizeof(*inbuf)); + if (outbuf) + dma_free(outbuf, sizeof(*outbuf)); return (error); } @@ -2108,16 +2116,18 @@ st_interpret_sense(struct scsi_xfer *xs) int st_touch_tape(struct st_softc *st) { - char *buf; - int readsize; - int error; - - buf = malloc(1024, M_TEMP, M_NOWAIT); - if (!buf) - return ENOMEM; + char *buf = NULL; + int readsize, maxblksize = 1024; + int error = 0; if ((error = st_mode_sense(st, 0)) != 0) - goto bad; + goto done; + buf = dma_alloc(maxblksize, PR_NOWAIT); + if (!buf) { + error = ENOMEM; + goto done; + } + st->blksize = 1024; do { switch (st->blksize) { @@ -2131,16 +2141,14 @@ st_touch_tape(struct st_softc *st) st->flags &= ~ST_FIXEDBLOCKS; } if ((error = st_mode_select(st, 0)) != 0) - goto bad; + goto done; st_read(st, buf, readsize, SCSI_SILENT); /* XXX */ - if ((error = st_rewind(st, 0, 0)) != 0) { -bad: free(buf, M_TEMP); - return error; - } + if ((error = st_rewind(st, 0, 0)) != 0) + goto done; } while (readsize != 1 && readsize > st->blksize); - - free(buf, M_TEMP); - return 0; +done: + dma_free(buf, maxblksize); + return (error); } int |