Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 May 2007 20:19:54 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 120019 for review
Message-ID:  <200705182019.l4IKJs94071021@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=120019

Change 120019 by hselasky@hselasky_mini_itx on 2007/05/18 20:19:29

	Fix isochronous support in the Linux USB compat layer.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.c#2 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.h#2 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.c#2 (text+ko) ====

@@ -64,6 +64,7 @@
 
 static usb_complete_t usb_linux_wait_complete;
 
+static uint16_t usb_max_isoc_frames(struct usb_device *dev);
 static int32_t usb_start_wait_urb(struct urb *urb, uint32_t timeout, uint32_t *p_actlen);
 static const struct usb_device_id * usb_linux_lookup_id(struct usb_driver *udrv, struct usb_attach_arg *uaa);
 static struct usb_driver * usb_linux_get_usb_driver(struct usb_linux_softc *sc);
@@ -347,6 +348,14 @@
 /*------------------------------------------------------------------------*
  * Linux emulation layer
  *------------------------------------------------------------------------*/
+
+static uint16_t
+usb_max_isoc_frames(struct usb_device *dev)
+{
+	return ((usbd_get_speed(dev->bsd_udev) == USB_SPEED_HIGH) ?
+		USB_MAX_HIGH_SPEED_ISOC_FRAMES : USB_MAX_FULL_SPEED_ISOC_FRAMES);
+}
+
 int32_t
 usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 {
@@ -669,6 +678,7 @@
             cfg[0].direction = addr & (UE_DIR_OUT|UE_DIR_IN);
             cfg[0].callback = &usb_linux_isoc_callback;
             cfg[0].bufsize = 0; /* use wMaxPacketSize */
+	    cfg[0].frames = usb_max_isoc_frames(dev);
 
             bcopy(cfg + 0, cfg + 1, sizeof(*cfg));
 
@@ -1189,6 +1199,12 @@
 	    TAILQ_REMOVE(&(uhe->bsd_urb_list), urb, bsd_urb_list);
 	    urb->bsd_urb_list.tqe_prev = NULL;
 
+	    x = usb_max_isoc_frames(urb->dev);
+	    if (urb->number_of_packets > x) {
+	        /* XXX simply truncate the transfer */
+	        urb->number_of_packets = x;
+	    }
+
 	} else {
 
 	    /* already got a transfer (should not happen) */

==== //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.h#2 (text+ko) ====

@@ -49,6 +49,9 @@
 typedef void (usb_complete_t)(struct urb *, struct pt_regs *);
 typedef uint32_t gfp_t;
 
+#define USB_MAX_FULL_SPEED_ISOC_FRAMES (60 * 1)
+#define USB_MAX_HIGH_SPEED_ISOC_FRAMES (60 * 8)
+
 /*
  * Linux compatible USB device drivers put their device information
  * into the "usb_device_id" structure using the "USB_DEVICE()" macro.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705182019.l4IKJs94071021>