aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/usb/usb_generic.c
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2011-02-28 17:23:15 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2011-02-28 17:23:15 +0000
commit1c49736857cfe0b562e2f1e100ab2307e882a9e6 (patch)
tree47ed63016899826a83fbbc10b56bb53c1b6d65cd /sys/dev/usb/usb_generic.c
parent898899d9ddbd15925a9d3c6b1da0d426dbc6351b (diff)
downloadsrc-1c49736857cfe0b562e2f1e100ab2307e882a9e6.tar.gz
src-1c49736857cfe0b562e2f1e100ab2307e882a9e6.zip
- Add support for software pre-scaling of ISOCHRONOUS transfers.
MFC after: 14 days Approved by: thompsa (mentor)
Notes
Notes: svn path=/head/; revision=219100
Diffstat (limited to 'sys/dev/usb/usb_generic.c')
-rw-r--r--sys/dev/usb/usb_generic.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
index da9b1d8ac055..8f197531bc46 100644
--- a/sys/dev/usb/usb_generic.c
+++ b/sys/dev/usb/usb_generic.c
@@ -1397,6 +1397,7 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
uint8_t iface_index;
uint8_t isread;
uint8_t ep_index;
+ uint8_t pre_scale;
u.addr = addr;
@@ -1448,6 +1449,12 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
if (u.popen->max_bufsize > USB_FS_MAX_BUFSIZE) {
u.popen->max_bufsize = USB_FS_MAX_BUFSIZE;
}
+ if (u.popen->max_frames & USB_FS_MAX_FRAMES_PRE_SCALE) {
+ pre_scale = 1;
+ u.popen->max_frames &= ~USB_FS_MAX_FRAMES_PRE_SCALE;
+ } else {
+ pre_scale = 0;
+ }
if (u.popen->max_frames > USB_FS_MAX_FRAMES) {
u.popen->max_frames = USB_FS_MAX_FRAMES;
break;
@@ -1468,13 +1475,15 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
}
iface_index = ep->iface_index;
- bzero(usb_config, sizeof(usb_config));
+ memset(usb_config, 0, sizeof(usb_config));
usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
usb_config[0].direction = ed->bEndpointAddress & (UE_DIR_OUT | UE_DIR_IN);
usb_config[0].interval = USB_DEFAULT_INTERVAL;
usb_config[0].flags.proxy_buffer = 1;
+ if (pre_scale != 0)
+ usb_config[0].flags.pre_scale_frames = 1;
usb_config[0].callback = &ugen_ctrl_fs_callback;
usb_config[0].timeout = 0; /* no timeout */
usb_config[0].frames = u.popen->max_frames;
@@ -1516,6 +1525,10 @@ ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
f->fs_xfer[u.popen->ep_index]->max_frame_size;
u.popen->max_bufsize =
f->fs_xfer[u.popen->ep_index]->max_data_length;
+ /* update number of frames */
+ u.popen->max_frames =
+ f->fs_xfer[u.popen->ep_index]->nframes;
+ /* store index of endpoint */
f->fs_xfer[u.popen->ep_index]->priv_fifo =
((uint8_t *)0) + u.popen->ep_index;
} else {