Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/rump/dev/wip/librumpusbhc * support async transfers
details: https://anonhg.NetBSD.org/src/rev/23be1a1c8a2c
branches: trunk
changeset: 747909:23be1a1c8a2c
user: pooka <pooka%NetBSD.org@localhost>
date: Mon Oct 05 13:00:37 2009 +0000
description:
* support async transfers
* make it possible to abort transfers
(these are all cheap hacks, but make things work)
diffstat:
sys/rump/dev/wip/librumpusbhc/Makefile | 4 +-
sys/rump/dev/wip/librumpusbhc/rumpusbhc.c | 111 ++++++++++++++++++++++-------
2 files changed, 87 insertions(+), 28 deletions(-)
diffs (226 lines):
diff -r 1f94b03a8cd1 -r 23be1a1c8a2c sys/rump/dev/wip/librumpusbhc/Makefile
--- a/sys/rump/dev/wip/librumpusbhc/Makefile Mon Oct 05 12:53:37 2009 +0000
+++ b/sys/rump/dev/wip/librumpusbhc/Makefile Mon Oct 05 13:00:37 2009 +0000
@@ -1,9 +1,11 @@
-# $NetBSD: Makefile,v 1.1 2009/10/02 15:35:46 pooka Exp $
+# $NetBSD: Makefile,v 1.2 2009/10/05 13:00:37 pooka Exp $
#
LIB= rumpdev_usbhc
SRCS= rumpusbhc.c
+CPPFLAGS+= -I${RUMPTOP}/librump/rumpkern
+
.include <bsd.lib.mk>
.include <bsd.klinks.mk>
diff -r 1f94b03a8cd1 -r 23be1a1c8a2c sys/rump/dev/wip/librumpusbhc/rumpusbhc.c
--- a/sys/rump/dev/wip/librumpusbhc/rumpusbhc.c Mon Oct 05 12:53:37 2009 +0000
+++ b/sys/rump/dev/wip/librumpusbhc/rumpusbhc.c Mon Oct 05 13:00:37 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpusbhc.c,v 1.5 2009/10/04 17:46:58 pooka Exp $ */
+/* $NetBSD: rumpusbhc.c,v 1.6 2009/10/05 13:00:37 pooka Exp $ */
/*
* Copyright (c) 2009 Antti Kantee. All Rights Reserved.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpusbhc.c,v 1.5 2009/10/04 17:46:58 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpusbhc.c,v 1.6 2009/10/05 13:00:37 pooka Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -69,6 +69,8 @@
#include <sys/device.h>
#include <sys/fcntl.h>
#include <sys/kmem.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -78,6 +80,7 @@
#include <rump/rumpuser.h>
+#include "rump_private.h"
#include "rump_dev_private.h"
#define UGEN_NEPTS 16
@@ -119,12 +122,20 @@
DVUNIT_ANY
};
+struct rusb_xfer {
+ struct usbd_xfer rusb_xfer;
+ int rusb_status; /* now this is a cheap trick */
+};
+#define RUSB(x) ((struct rusb_xfer *)x)
+
/* probe ugen0 through ugen3 */
struct cfdata rumpusbhc_cfdata[] = {
+#if 0
{ "rumpusbhc", "rumpusbhc", 0, FSTATE_NOTFOUND, NULL, 0, &rumpusbhcpar},
{ "rumpusbhc", "rumpusbhc", 1, FSTATE_NOTFOUND, NULL, 0, &rumpusbhcpar},
+ { "rumpusbhc", "rumpusbhc", 3, FSTATE_NOTFOUND, NULL, 0, &rumpusbhcpar},
+#endif
{ "rumpusbhc", "rumpusbhc", 2, FSTATE_NOTFOUND, NULL, 0, &rumpusbhcpar},
- { "rumpusbhc", "rumpusbhc", 3, FSTATE_NOTFOUND, NULL, 0, &rumpusbhcpar},
};
#define UGENDEV_BASESTR "/dev/ugen"
@@ -465,10 +476,6 @@
case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
printf("clear feature UNIMPL\n");
- break;
-
- case C(0xfe, UT_READ_CLASS_INTERFACE):
- /* XXX: what is this? */
totlen = 0;
break;
@@ -480,6 +487,7 @@
case C(0x06, UT_WRITE_VENDOR_DEVICE):
case C(0x07, UT_READ_VENDOR_DEVICE):
case C(0x09, UT_READ_VENDOR_DEVICE):
+ case C(0xfe, UT_READ_CLASS_INTERFACE):
{
struct usb_ctl_request ucr;
@@ -631,44 +639,87 @@
len = xfer->length;
buf = KERNADDR(&xfer->dmabuf, 0);
- if (isread) {
- n = rumpuser_read(sc->sc_ugenfd[endpt], buf, len, &error);
- if (n != len)
- n = 0;
- } else {
- n = rumpuser_write(sc->sc_ugenfd[endpt], buf, len, &error);
- if (n != len)
- panic("short write");
+ while (RUSB(xfer)->rusb_status == 0) {
+ if (isread) {
+ n = rumpuser_read(sc->sc_ugenfd[endpt],
+ buf, len, &error);
+ if (n == len)
+ break;
+ if (error != EAGAIN) {
+ n = 0;
+ break;
+ }
+ } else {
+ n = rumpuser_write(sc->sc_ugenfd[endpt],
+ buf, len, &error);
+ if (n == len)
+ break;
+ else
+ panic("short write");
+ }
}
- xfer->actlen = n;
- xfer->status = USBD_NORMAL_COMPLETION;
+ if (RUSB(xfer)->rusb_status == 0) {
+ xfer->actlen = n;
+ xfer->status = USBD_NORMAL_COMPLETION;
+ } else {
+ xfer->status = USBD_CANCELLED;
+ RUSB(xfer)->rusb_status = 2;
+ }
usb_transfer_complete(xfer);
return (USBD_IN_PROGRESS);
}
+static void
+doxfer_kth(void *arg)
+{
+ usbd_xfer_handle xfer = arg;
+
+ rumpusb_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
+ kthread_exit(0);
+}
+
static usbd_status
rumpusb_device_bulk_transfer(usbd_xfer_handle xfer)
{
usbd_status err;
- /* XXX: lie about supporting async transfers */
- if ((xfer->flags & USBD_SYNCHRONOUS) == 0) {
- printf("rumpusbhc does not support async transfers. LIAR!\n");
+ if (!rump_threads) {
+ /* XXX: lie about supporting async transfers */
+ if ((xfer->flags & USBD_SYNCHRONOUS) == 0) {
+ printf("non-threaded rump does not support "
+ "async transfers.\n");
+ return USBD_IN_PROGRESS;
+ }
+
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return err;
+
+ return rumpusb_device_bulk_start(
+ SIMPLEQ_FIRST(&xfer->pipe->queue));
+ } else {
+ /* biglocked */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return err;
+ kthread_create(PRI_NONE, 0, NULL, doxfer_kth, xfer, NULL,
+ "rusbhcxf");
+
return USBD_IN_PROGRESS;
}
-
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- return (rumpusb_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
+/* wait for transfer to abort. yea, this is cheesy (from a spray can) */
static void
rumpusb_device_bulk_abort(usbd_xfer_handle xfer)
{
+ struct rusb_xfer *rx = RUSB(xfer);
+ rx->rusb_status = 1;
+ while (rx->rusb_status < 2) {
+ kpause("jopo", false, hz/10, NULL);
+ }
}
static void
@@ -708,7 +759,7 @@
u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
char buf[UGENDEV_BUFSIZE];
int endpt, oflags, error;
- int fd;
+ int fd, val;
sc->sc_port_status = UPS_CURRENT_CONNECT_STATUS
| UPS_PORT_ENABLED | UPS_PORT_POWER | UPS_HIGH_SPEED;
@@ -755,6 +806,10 @@
fd = rumpuser_open(buf, oflags, &error);
if (fd == -1)
return USBD_INVAL; /* XXX: no mapping */
+ val = 100;
+ if (rumpuser_ioctl(fd, USB_SET_TIMEOUT, &val,
+ &error) == -1)
+ panic("timeout set failed");
sc->sc_ugenfd[endpt] = fd;
sc->sc_fdmodes[endpt] = oflags;
break;
@@ -885,4 +940,6 @@
/* whoah, like extreme XXX, bro */
rhscintr();
+ if (!rump_threads)
+ config_pending_decr();
}
Home |
Main Index |
Thread Index |
Old Index