summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_generic.c
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2012-08-12 17:53:06 +0000
committerhselasky <hselasky@FreeBSD.org>2012-08-12 17:53:06 +0000
commitce0da37e7d071995cc8533b668360082f78cb329 (patch)
tree4ef3a2c09abbce548ca79a0652beee2be50d1199 /sys/dev/usb/usb_generic.c
parent0b3ddf87a17ef869513d045700b673f056909ab2 (diff)
downloadFreeBSD-src-ce0da37e7d071995cc8533b668360082f78cb329.zip
FreeBSD-src-ce0da37e7d071995cc8533b668360082f78cb329.tar.gz
Add support for the so-called streams feature of BULK endpoints
in SUPER-speed mode, USB 3.0. This feature has not been tested yet, due to lack of hardware. This feature is useful when implementing protocols like UASP, USB attached SCSI which promises higher USB mass storage throughput. This patch also implements support for hardware processing of endpoints for increased performance. The switching to hardware processing of an endpoint is done via a callback to the USB controller driver. The stream feature is implemented like a variant of a hardware USB protocol. USB controller drivers implementing device mode needs to be updated to implement the new "xfer_stall" USB controller method and remove the "xfer" argument from the "set_stall" method. The API's toward existing USB drivers are preserved. To setup a USB transfer in stream mode, set the "stream_id" field of the USB config structure to the desired value. The maximum number of BULK streams is currently hardcoded and limited to 8 via a define in usb_freebsd.h. All USB drivers should be re-compiled after this change. LibUSB will be updated next week to support streams mode. A new IOCTL to setup BULK streams as already been implemented. The ugen device nodes currently only supports stream ID zero. The FreeBSD version has been bumped. MFC after: 2 weeks
Diffstat (limited to 'sys/dev/usb/usb_generic.c')
-rw-r--r--sys/dev/usb/usb_generic.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
index 5f156b1..8da4119 100644
--- a/sys/dev/usb/usb_generic.c
+++ b/sys/dev/usb/usb_generic.c
@@ -253,6 +253,7 @@ ugen_open_pipe_write(struct usb_fifo *f)
usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
+ usb_config[0].stream_id = 0; /* XXX support more stream ID's */
usb_config[0].direction = UE_DIR_TX;
usb_config[0].interval = USB_DEFAULT_INTERVAL;
usb_config[0].flags.proxy_buffer = 1;
@@ -321,6 +322,7 @@ ugen_open_pipe_read(struct usb_fifo *f)
usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
+ usb_config[0].stream_id = 0; /* XXX support more stream ID's */
usb_config[0].direction = UE_DIR_RX;
usb_config[0].interval = USB_DEFAULT_INTERVAL;
usb_config[0].flags.proxy_buffer = 1;
@@ -1391,6 +1393,7 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
struct usb_fs_start *pstart;
struct usb_fs_stop *pstop;
struct usb_fs_open *popen;
+ struct usb_fs_open_streams *popen_streams;
struct usb_fs_close *pclose;
struct usb_fs_clear_stall_sync *pstall;
void *addr;
@@ -1455,6 +1458,7 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
break;
case USB_FS_OPEN:
+ case USB_FS_OPEN_STREAMS:
if (u.popen->ep_index >= f->fs_ep_max) {
error = EINVAL;
break;
@@ -1506,6 +1510,8 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
usb_config[0].frames = u.popen->max_frames;
usb_config[0].bufsize = u.popen->max_bufsize;
usb_config[0].usb_mode = USB_MODE_DUAL; /* both modes */
+ if (cmd == USB_FS_OPEN_STREAMS)
+ usb_config[0].stream_id = u.popen_streams->stream_id;
if (usb_config[0].type == UE_CONTROL) {
if (f->udev->flags.usb_mode != USB_MODE_HOST) {
OpenPOWER on IntegriCloud