From owner-svn-src-all@FreeBSD.ORG Mon Feb 28 17:23:16 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3B71B1065672; Mon, 28 Feb 2011 17:23:16 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 282128FC1B; Mon, 28 Feb 2011 17:23:16 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p1SHNGoj046644; Mon, 28 Feb 2011 17:23:16 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p1SHNFLD046632; Mon, 28 Feb 2011 17:23:15 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201102281723.p1SHNFLD046632@svn.freebsd.org> From: Hans Petter Selasky Date: Mon, 28 Feb 2011 17:23:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r219100 - in head: lib/libusb share/man/man9 sys/dev/usb X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Feb 2011 17:23:16 -0000 Author: hselasky Date: Mon Feb 28 17:23:15 2011 New Revision: 219100 URL: http://svn.freebsd.org/changeset/base/219100 Log: - Add support for software pre-scaling of ISOCHRONOUS transfers. MFC after: 14 days Approved by: thompsa (mentor) Modified: head/lib/libusb/libusb10.c head/lib/libusb/libusb20.3 head/lib/libusb/libusb20.c head/lib/libusb/libusb20.h head/lib/libusb/libusb20_int.h head/lib/libusb/libusb20_ugen20.c head/share/man/man9/usbdi.9 head/sys/dev/usb/usb_generic.c head/sys/dev/usb/usb_ioctl.h head/sys/dev/usb/usb_transfer.c head/sys/dev/usb/usbdi.h Modified: head/lib/libusb/libusb10.c ============================================================================== --- head/lib/libusb/libusb10.c Mon Feb 28 16:39:15 2011 (r219099) +++ head/lib/libusb/libusb10.c Mon Feb 28 17:23:15 2011 (r219100) @@ -51,7 +51,6 @@ struct libusb_context *usbi_default_cont /* Prototypes */ static struct libusb20_transfer *libusb10_get_transfer(struct libusb20_device *, uint8_t, uint8_t); -static int libusb10_get_maxframe(struct libusb20_device *, libusb_transfer *); static int libusb10_get_buffsize(struct libusb20_device *, libusb_transfer *); static int libusb10_convert_error(uint8_t status); static void libusb10_complete_transfer(struct libusb20_transfer *, struct libusb_super_transfer *, int); @@ -810,25 +809,14 @@ libusb_free_transfer(struct libusb_trans free(sxfer); } -static int +static uint32_t libusb10_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer) { - int ret; - int usb_speed; - - usb_speed = libusb20_dev_get_speed(pdev); + uint32_t ret; switch (xfer->type) { case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: - switch (usb_speed) { - case LIBUSB20_SPEED_LOW: - case LIBUSB20_SPEED_FULL: - ret = 60 * 1; - break; - default: - ret = 60 * 8; - break; - } + ret = 60 | LIBUSB20_MAX_FRAME_PRE_SCALE; /* 60ms */ break; case LIBUSB_TRANSFER_TYPE_CONTROL: ret = 2; Modified: head/lib/libusb/libusb20.3 ============================================================================== --- head/lib/libusb/libusb20.3 Mon Feb 28 16:39:15 2011 (r219099) +++ head/lib/libusb/libusb20.3 Mon Feb 28 17:23:15 2011 (r219100) @@ -261,6 +261,16 @@ The actual buffer size can be greater th and is returned by .Fn libusb20_tr_get_max_total_length . . +If +.Fa max_frame_count +is OR'ed with LIBUSB20_MAX_FRAME_PRE_SCALE the remaining part of the +argument is converted from milliseconds into the actual number of +frames rounded up, when this function returns. +This flag is only valid for ISOCHRONOUS transfers and has no effect +for other transfer types. +The actual number of frames setup is found by calling +.Fn libusb20_tr_get_max_frames . +. This function returns zero upon success. . Non-zero return values indicate a LIBUSB20_ERROR value. Modified: head/lib/libusb/libusb20.c ============================================================================== --- head/lib/libusb/libusb20.c Mon Feb 28 16:39:15 2011 (r219099) +++ head/lib/libusb/libusb20.c Mon Feb 28 17:23:15 2011 (r219100) @@ -156,14 +156,20 @@ libusb20_tr_open(struct libusb20_transfe uint32_t MaxFrameCount, uint8_t ep_no) { uint32_t size; + uint8_t pre_scale; int error; - if (xfer->is_opened) { + if (xfer->is_opened) return (LIBUSB20_ERROR_BUSY); + if (MaxFrameCount & LIBUSB20_MAX_FRAME_PRE_SCALE) { + MaxFrameCount &= ~LIBUSB20_MAX_FRAME_PRE_SCALE; + pre_scale = 1; + } else { + pre_scale = 0; } - if (MaxFrameCount == 0) { + if (MaxFrameCount == 0) return (LIBUSB20_ERROR_INVALID_PARAM); - } + xfer->maxFrames = MaxFrameCount; size = MaxFrameCount * sizeof(xfer->pLength[0]); @@ -182,7 +188,7 @@ libusb20_tr_open(struct libusb20_transfe memset(xfer->ppBuffer, 0, size); error = xfer->pdev->methods->tr_open(xfer, MaxBufSize, - MaxFrameCount, ep_no); + MaxFrameCount, ep_no, pre_scale); if (error) { free(xfer->ppBuffer); Modified: head/lib/libusb/libusb20.h ============================================================================== --- head/lib/libusb/libusb20.h Mon Feb 28 16:39:15 2011 (r219099) +++ head/lib/libusb/libusb20.h Mon Feb 28 17:23:15 2011 (r219100) @@ -197,8 +197,9 @@ struct libusb20_quirk { char quirkname[64 - 12]; }; -/* USB transfer operations */ +#define LIBUSB20_MAX_FRAME_PRE_SCALE (1U << 31) +/* USB transfer operations */ int libusb20_tr_close(struct libusb20_transfer *xfer); int libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t max_buf_size, uint32_t max_frame_count, uint8_t ep_no); struct libusb20_transfer *libusb20_tr_get_pointer(struct libusb20_device *pdev, uint16_t tr_index); Modified: head/lib/libusb/libusb20_int.h ============================================================================== --- head/lib/libusb/libusb20_int.h Mon Feb 28 16:39:15 2011 (r219099) +++ head/lib/libusb/libusb20_int.h Mon Feb 28 17:23:15 2011 (r219100) @@ -110,7 +110,7 @@ typedef int (libusb20_set_config_index_t typedef int (libusb20_check_connected_t)(struct libusb20_device *pdev); /* USB transfer specific */ -typedef int (libusb20_tr_open_t)(struct libusb20_transfer *xfer, uint32_t MaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no); +typedef int (libusb20_tr_open_t)(struct libusb20_transfer *xfer, uint32_t MaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no, uint8_t pre_scale); typedef int (libusb20_tr_close_t)(struct libusb20_transfer *xfer); typedef int (libusb20_tr_clear_stall_sync_t)(struct libusb20_transfer *xfer); typedef void (libusb20_tr_submit_t)(struct libusb20_transfer *xfer); Modified: head/lib/libusb/libusb20_ugen20.c ============================================================================== --- head/lib/libusb/libusb20_ugen20.c Mon Feb 28 16:39:15 2011 (r219099) +++ head/lib/libusb/libusb20_ugen20.c Mon Feb 28 17:23:15 2011 (r219100) @@ -736,11 +736,14 @@ ugen20_process(struct libusb20_device *p static int ugen20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize, - uint32_t MaxFrameCount, uint8_t ep_no) + uint32_t MaxFrameCount, uint8_t ep_no, uint8_t pre_scale) { struct usb_fs_open temp; struct usb_fs_endpoint *fsep; + if (pre_scale) + MaxFrameCount |= USB_FS_MAX_FRAMES_PRE_SCALE; + memset(&temp, 0, sizeof(temp)); fsep = xfer->pdev->privBeData; Modified: head/share/man/man9/usbdi.9 ============================================================================== --- head/share/man/man9/usbdi.9 Mon Feb 28 16:39:15 2011 (r219099) +++ head/share/man/man9/usbdi.9 Mon Feb 28 17:23:15 2011 (r219100) @@ -593,6 +593,10 @@ use the "usbd_xfer_set_stall()" and "usb functions! This flag is automatically cleared after that the stall or clear stall has been executed. . +.It pre_scale_frames +If this flag is set the number of frames specified is assumed to give the buffering time in milliseconds instead of frames. +During transfer setup the frames field is pre scaled with the corresponding value for the endpoint and rounded to the nearest number of frames greater than zero. +This option only has effect for ISOCHRONOUS transfers. .El .Pp .Fa bufsize Modified: head/sys/dev/usb/usb_generic.c ============================================================================== --- head/sys/dev/usb/usb_generic.c Mon Feb 28 16:39:15 2011 (r219099) +++ head/sys/dev/usb/usb_generic.c Mon Feb 28 17:23:15 2011 (r219100) @@ -1397,6 +1397,7 @@ ugen_ioctl(struct usb_fifo *f, u_long cm 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 cm 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 cm } 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 cm 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 { Modified: head/sys/dev/usb/usb_ioctl.h ============================================================================== --- head/sys/dev/usb/usb_ioctl.h Mon Feb 28 16:39:15 2011 (r219099) +++ head/sys/dev/usb/usb_ioctl.h Mon Feb 28 17:23:15 2011 (r219100) @@ -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; Modified: head/sys/dev/usb/usb_transfer.c ============================================================================== --- head/sys/dev/usb/usb_transfer.c Mon Feb 28 16:39:15 2011 (r219099) +++ head/sys/dev/usb/usb_transfer.c Mon Feb 28 17:23:15 2011 (r219100) @@ -471,6 +471,8 @@ usbd_transfer_setup_sub(struct usb_setup 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; } Modified: head/sys/dev/usb/usbdi.h ============================================================================== --- head/sys/dev/usb/usbdi.h Mon Feb 28 16:39:15 2011 (r219099) +++ head/sys/dev/usb/usbdi.h Mon Feb 28 17:23:15 2011 (r219100) @@ -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. + */ }; /*