diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/usb_generic.c | 15 | ||||
-rw-r--r-- | sys/dev/usb/usb_ioctl.h | 5 | ||||
-rw-r--r-- | sys/dev/usb/usb_transfer.c | 2 | ||||
-rw-r--r-- | sys/dev/usb/usbdi.h | 10 |
4 files changed, 29 insertions, 3 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 { diff --git a/sys/dev/usb/usb_ioctl.h b/sys/dev/usb/usb_ioctl.h index 8fe55e18bd2a..452de94a7ab4 100644 --- a/sys/dev/usb/usb_ioctl.h +++ b/sys/dev/usb/usb_ioctl.h @@ -183,8 +183,9 @@ struct usb_fs_uninit { struct usb_fs_open { #define USB_FS_MAX_BUFSIZE (1 << 18) uint32_t max_bufsize; -#define USB_FS_MAX_FRAMES (1 << 12) - uint32_t max_frames; +#define USB_FS_MAX_FRAMES (1U << 12) +#define USB_FS_MAX_FRAMES_PRE_SCALE (1U << 31) /* for ISOCHRONOUS transfers */ + uint32_t max_frames; /* read and write */ uint16_t max_packet_length; /* read only */ uint8_t dev_index; /* currently unused */ uint8_t ep_index; diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index 3a77c36d9b48..8dd9d1d27ac6 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -471,6 +471,8 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) xfer->fps_shift--; if (xfer->fps_shift > 3) xfer->fps_shift = 3; + if (xfer->flags.pre_scale_frames != 0) + xfer->nframes <<= (3 - xfer->fps_shift); break; } diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 6d4a911b0d13..b88a65557aac 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -195,6 +195,16 @@ struct usb_xfer_flags { uint8_t stall_pipe:1; /* set if the endpoint belonging to * this USB transfer should be stalled * before starting this transfer! */ + uint8_t pre_scale_frames:1; /* "usb_config->frames" is + * assumed to give the + * buffering time in + * milliseconds and is + * converted into the nearest + * number of frames when the + * USB transfer is setup. This + * option only has effect for + * ISOCHRONOUS transfers. + */ }; /* |