summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorthorpej <thorpej@NetBSD.org>2003-07-19 02:00:18 +0000
committerthorpej <thorpej@NetBSD.org>2003-07-19 02:00:18 +0000
commit5f35784b8a50dfaeacd841ead405cec38018e4e4 (patch)
treef772c3f76a63529342994495b316fd9880206141 /sys/dev
parentce22377a7e7b6fbc2237cc20a8c76d8ad66673b9 (diff)
Add immediate value support for dmoverio transactions.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/dmover/dmover_io.c85
-rw-r--r--sys/dev/dmover/dmover_io.h20
-rw-r--r--sys/dev/dmover/dmovervar.h9
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 {