svn commit: r220434 - in stable/8: lib/libusb share/man/man9 sys/dev/usb

Hans Petter Selasky hselasky at FreeBSD.org
Fri Apr 8 05:48:52 UTC 2011


Author: hselasky
Date: Fri Apr  8 05:48:51 2011
New Revision: 220434
URL: http://svn.freebsd.org/changeset/base/220434

Log:
  MFC r219100
  - Add support for software pre-scaling of ISOCHRONOUS transfers.
  
  Approved by:	thompsa (mentor)

Modified:
  stable/8/lib/libusb/libusb10.c
  stable/8/lib/libusb/libusb20.3
  stable/8/lib/libusb/libusb20.c
  stable/8/lib/libusb/libusb20.h
  stable/8/lib/libusb/libusb20_int.h
  stable/8/lib/libusb/libusb20_ugen20.c
  stable/8/share/man/man9/usbdi.9
  stable/8/sys/dev/usb/usb_generic.c
  stable/8/sys/dev/usb/usb_ioctl.h
  stable/8/sys/dev/usb/usb_transfer.c
  stable/8/sys/dev/usb/usbdi.h
Directory Properties:
  stable/8/lib/libusb/   (props changed)
  stable/8/lib/libusb/usb.h   (props changed)
  stable/8/share/man/man9/   (props changed)

Modified: stable/8/lib/libusb/libusb10.c
==============================================================================
--- stable/8/lib/libusb/libusb10.c	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/lib/libusb/libusb10.c	Fri Apr  8 05:48:51 2011	(r220434)
@@ -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: stable/8/lib/libusb/libusb20.3
==============================================================================
--- stable/8/lib/libusb/libusb20.3	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/lib/libusb/libusb20.3	Fri Apr  8 05:48:51 2011	(r220434)
@@ -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: stable/8/lib/libusb/libusb20.c
==============================================================================
--- stable/8/lib/libusb/libusb20.c	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/lib/libusb/libusb20.c	Fri Apr  8 05:48:51 2011	(r220434)
@@ -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: stable/8/lib/libusb/libusb20.h
==============================================================================
--- stable/8/lib/libusb/libusb20.h	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/lib/libusb/libusb20.h	Fri Apr  8 05:48:51 2011	(r220434)
@@ -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: stable/8/lib/libusb/libusb20_int.h
==============================================================================
--- stable/8/lib/libusb/libusb20_int.h	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/lib/libusb/libusb20_int.h	Fri Apr  8 05:48:51 2011	(r220434)
@@ -104,7 +104,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: stable/8/lib/libusb/libusb20_ugen20.c
==============================================================================
--- stable/8/lib/libusb/libusb20_ugen20.c	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/lib/libusb/libusb20_ugen20.c	Fri Apr  8 05:48:51 2011	(r220434)
@@ -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: stable/8/share/man/man9/usbdi.9
==============================================================================
--- stable/8/share/man/man9/usbdi.9	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/share/man/man9/usbdi.9	Fri Apr  8 05:48:51 2011	(r220434)
@@ -594,6 +594,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: stable/8/sys/dev/usb/usb_generic.c
==============================================================================
--- stable/8/sys/dev/usb/usb_generic.c	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/sys/dev/usb/usb_generic.c	Fri Apr  8 05:48:51 2011	(r220434)
@@ -1398,6 +1398,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;
 
@@ -1449,6 +1450,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;
@@ -1469,13 +1476,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;
@@ -1517,6 +1526,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: stable/8/sys/dev/usb/usb_ioctl.h
==============================================================================
--- stable/8/sys/dev/usb/usb_ioctl.h	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/sys/dev/usb/usb_ioctl.h	Fri Apr  8 05:48:51 2011	(r220434)
@@ -162,8 +162,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: stable/8/sys/dev/usb/usb_transfer.c
==============================================================================
--- stable/8/sys/dev/usb/usb_transfer.c	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/sys/dev/usb/usb_transfer.c	Fri Apr  8 05:48:51 2011	(r220434)
@@ -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: stable/8/sys/dev/usb/usbdi.h
==============================================================================
--- stable/8/sys/dev/usb/usbdi.h	Thu Apr  7 23:28:28 2011	(r220433)
+++ stable/8/sys/dev/usb/usbdi.h	Fri Apr  8 05:48:51 2011	(r220434)
@@ -194,6 +194,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.
+					 */
 };
 
 /*


More information about the svn-src-stable-8 mailing list