diff options
| author | thorpej <thorpej@NetBSD.org> | 2003-07-19 02:00:18 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2003-07-19 02:00:18 +0000 |
| commit | 5f35784b8a50dfaeacd841ead405cec38018e4e4 (patch) | |
| tree | f772c3f76a63529342994495b316fd9880206141 /sys/dev | |
| parent | ce22377a7e7b6fbc2237cc20a8c76d8ad66673b9 (diff) | |
Add immediate value support for dmoverio transactions.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/dmover/dmover_io.c | 85 | ||||
| -rw-r--r-- | sys/dev/dmover/dmover_io.h | 20 | ||||
| -rw-r--r-- | sys/dev/dmover/dmovervar.h | 9 |
3 files changed, 64 insertions, 50 deletions
diff --git a/sys/dev/dmover/dmover_io.c b/sys/dev/dmover/dmover_io.c index f9611952a8e..df7aaed9c2b 100644 --- a/sys/dev/dmover/dmover_io.c +++ b/sys/dev/dmover/dmover_io.c @@ -1,7 +1,7 @@ -/* $NetBSD: dmover_io.c,v 1.11 2003/06/29 22:30:07 fvdl Exp $ */ +/* $NetBSD: dmover_io.c,v 1.12 2003/07/19 02:00:18 thorpej Exp $ */ /* - * Copyright (c) 2002 Wasabi Systems, Inc. + * Copyright (c) 2002, 2003 Wasabi Systems, Inc. * All rights reserved. * * Written by Jason R. Thorpe for Wasabi Systems, Inc. @@ -55,7 +55,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dmover_io.c,v 1.11 2003/06/29 22:30:07 fvdl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dmover_io.c,v 1.12 2003/07/19 02:00:18 thorpej Exp $"); #include <sys/param.h> #include <sys/queue.h> @@ -147,40 +147,44 @@ dmio_usrreq_init(struct file *fp, struct dmio_usrreq_state *dus, /* XXX How should malloc interact w/ FNONBLOCK? */ - if (req->req_outbuf.dmbuf_iovcnt > IOV_MAX) - return (EINVAL); - len = sizeof(struct iovec) * req->req_outbuf.dmbuf_iovcnt; - if (len == 0) - return (EINVAL); - uio_out->uio_iov = malloc(len, M_TEMP, M_WAITOK); - - error = copyin(req->req_outbuf.dmbuf_iov, uio_out->uio_iov, len); - if (error) { - free(uio_out->uio_iov, M_TEMP); - return (error); - } - - for (j = 0, len = 0; j < req->req_outbuf.dmbuf_iovcnt; j++) { - len += uio_out->uio_iov[j].iov_len; - if (len > SSIZE_MAX) { - free(uio_out->uio_iov, M_TEMP); + if (req->req_outbuf.dmbuf_iovcnt != 0) { + if (req->req_outbuf.dmbuf_iovcnt > IOV_MAX) return (EINVAL); + len = sizeof(struct iovec) * req->req_outbuf.dmbuf_iovcnt; + uio_out->uio_iov = malloc(len, M_TEMP, M_WAITOK); + error = copyin(req->req_outbuf.dmbuf_iov, uio_out->uio_iov, + len); + if (error) { + free(uio_out->uio_iov, M_TEMP); + return (error); } - } - uio_out->uio_iovcnt = req->req_outbuf.dmbuf_iovcnt; - uio_out->uio_resid = len; - uio_out->uio_rw = UIO_READ; - uio_out->uio_segflg = UIO_USERSPACE; - uio_out->uio_procp = curproc; + for (j = 0, len = 0; j < req->req_outbuf.dmbuf_iovcnt; j++) { + len += uio_out->uio_iov[j].iov_len; + if (len > SSIZE_MAX) { + free(uio_out->uio_iov, M_TEMP); + return (EINVAL); + } + } - dreq->dreq_outbuf_type = DMOVER_BUF_UIO; - dreq->dreq_outbuf.dmbuf_uio = uio_out; + uio_out->uio_iovcnt = req->req_outbuf.dmbuf_iovcnt; + uio_out->uio_resid = len; + uio_out->uio_rw = UIO_READ; + uio_out->uio_segflg = UIO_USERSPACE; + uio_out->uio_procp = curproc; + dreq->dreq_outbuf_type = DMOVER_BUF_UIO; + dreq->dreq_outbuf.dmbuf_uio = uio_out; + } else { + uio_out->uio_iov = NULL; + uio_out = NULL; + dreq->dreq_outbuf_type = DMOVER_BUF_NONE; + } + + memcpy(dreq->dreq_immediate, req->req_immediate, + sizeof(dreq->dreq_immediate)); if (dses->dses_ninputs == 0) { - /* No inputs; copy the immediate. */ - memcpy(dreq->dreq_immediate, req->req_immediate, - sizeof(dreq->dreq_immediate)); + /* No inputs; all done. */ return (0); } @@ -214,7 +218,7 @@ dmio_usrreq_init(struct file *fp, struct dmio_usrreq_state *dus, goto bad; } - for (j = 0, len = 0; j < req->req_outbuf.dmbuf_iovcnt; j++) { + for (j = 0, len = 0; j < inbuf.dmbuf_iovcnt; j++) { len += uio_in->uio_iov[j].iov_len; if (len > SSIZE_MAX) { free(uio_in->uio_iov, M_TEMP); @@ -223,7 +227,7 @@ dmio_usrreq_init(struct file *fp, struct dmio_usrreq_state *dus, } } - if (len != uio_out->uio_resid) { + if (uio_out != NULL && len != uio_out->uio_resid) { free(uio_in->uio_iov, M_TEMP); error = EINVAL; goto bad; @@ -248,7 +252,8 @@ dmio_usrreq_init(struct file *fp, struct dmio_usrreq_state *dus, } } free(dus->dus_uio_in, M_TEMP); - free(uio_out->uio_iov, M_TEMP); + if (uio_out != NULL) + free(uio_out->uio_iov, M_TEMP); return (error); } @@ -265,7 +270,8 @@ dmio_usrreq_fini(struct dmio_state *ds, struct dmio_usrreq_state *dus) struct uio *uio_in; int i; - free(uio_out->uio_iov, M_TEMP); + if (uio_out->uio_iov != NULL) + free(uio_out->uio_iov, M_TEMP); if (dses->dses_ninputs == 0) { pool_put(&dmio_usrreq_state_pool, dus); @@ -341,8 +347,13 @@ dmio_read(struct file *fp, off_t *offp, struct uio *uio, dreq = dus->dus_req; resp.resp_id = dus->dus_id; - resp.resp_error = (dreq->dreq_flags & DMOVER_REQ_ERROR) ? - dreq->dreq_error : 0; + if (dreq->dreq_flags & DMOVER_REQ_ERROR) + resp.resp_error = dreq->dreq_error; + else { + resp.resp_error = 0; + memcpy(resp.resp_immediate, dreq->dreq_immediate, + sizeof(resp.resp_immediate)); + } dmio_usrreq_fini(ds, dus); diff --git a/sys/dev/dmover/dmover_io.h b/sys/dev/dmover/dmover_io.h index 6f6c433bac3..76b122f4846 100644 --- a/sys/dev/dmover/dmover_io.h +++ b/sys/dev/dmover/dmover_io.h @@ -1,7 +1,7 @@ -/* $NetBSD: dmover_io.h,v 1.1 2002/08/02 00:30:38 thorpej Exp $ */ +/* $NetBSD: dmover_io.h,v 1.2 2003/07/19 02:00:18 thorpej Exp $ */ /* - * Copyright (c) 2002 Wasabi Systems, Inc. + * Copyright (c) 2002, 2003 Wasabi Systems, Inc. * All rights reserved. * * Written by Jason R. Thorpe for Wasabi Systems, Inc. @@ -55,14 +55,15 @@ struct dmio_usrreq { /* Output buffer. */ dmio_buffer req_outbuf; - /* Input buffer. */ - union { - uint8_t _immediate[8]; - dmio_buffer *_inbuf; - } _req_inbuf_un; + /* + * General purpose immediate value. Can be used as an + * input, output, or both, depending on the function. + * The output is transmitted via the usrresp structure. + */ + uint8_t req_immediate[8]; -#define req_immediate _req_inbuf_un._immediate -#define req_inbuf _req_inbuf_un._inbuf + /* Input buffer. */ + dmio_buffer *req_inbuf; uint32_t req_id; /* request ID; passed in response */ }; @@ -75,6 +76,7 @@ struct dmio_usrreq { struct dmio_usrresp { uint32_t resp_id; /* request ID */ int resp_error; /* error, 0 if success */ + uint8_t resp_immediate[8]; }; /* diff --git a/sys/dev/dmover/dmovervar.h b/sys/dev/dmover/dmovervar.h index 4955aa3ab08..6d5645719e1 100644 --- a/sys/dev/dmover/dmovervar.h +++ b/sys/dev/dmover/dmovervar.h @@ -1,7 +1,7 @@ -/* $NetBSD: dmovervar.h,v 1.5 2003/06/14 19:03:40 thorpej Exp $ */ +/* $NetBSD: dmovervar.h,v 1.6 2003/07/19 02:00:18 thorpej Exp $ */ /* - * Copyright (c) 2002 Wasabi Systems, Inc. + * Copyright (c) 2002, 2003 Wasabi Systems, Inc. * All rights reserved. * * Written by Jason R. Thorpe for Wasabi Systems, Inc. @@ -45,8 +45,9 @@ * Types of buffers the dmover-api can handle. */ typedef enum { - DMOVER_BUF_LINEAR, - DMOVER_BUF_UIO + DMOVER_BUF_NONE = 0, + DMOVER_BUF_LINEAR = 1, + DMOVER_BUF_UIO = 2 } dmover_buffer_type; typedef struct { |
