choose the bAlternateSetting with the closest matching bandwidth,
not the first one we come across that has at least as much as
we need.  the bAlternateSettings aren't guaranteed to be ordered
by increasing bandwidth, and using one with too much bandwidth can
stall the usb pipes.  lets the Ricoh VGP-VCC7 in Vaio VGN-TZ330E 
work at frame sizes other than the largest.

ok?

-- 
[email protected]
SDF Public Access UNIX System - http://sdf.lonestar.org

Index: uvideo.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uvideo.c,v
retrieving revision 1.142
diff -u -p uvideo.c
--- uvideo.c    9 Oct 2010 09:48:03 -0000       1.142
+++ uvideo.c    15 Oct 2010 20:52:06 -0000
@@ -1226,7 +1227,7 @@ uvideo_vs_set_alt(struct uvideo_softc *sc, usbd_interf
        const usb_descriptor_t *desc;
        usb_interface_descriptor_t *id;
        usb_endpoint_descriptor_t *ed;
-       int i;
+       int i, diff, best_diff = INT_MAX;
        usbd_status error;
        uint32_t psize;
 
@@ -1253,19 +1254,25 @@ uvideo_vs_set_alt(struct uvideo_softc *sc, usbd_interf
                /* save endpoint with requested bandwidth */
                psize = UGETW(ed->wMaxPacketSize);
                psize = UE_GET_SIZE(psize) * (1 + UE_GET_TRANS(psize));
-               if (psize >= max_packet_size) {
+               if (psize >= max_packet_size)
+                       diff = psize - max_packet_size;
+               else
+                       goto next;
+               if (diff < best_diff) {
                        sc->sc_vs_cur->endpoint = ed->bEndpointAddress;
                        sc->sc_vs_cur->curalt = id->bAlternateSetting;
                        sc->sc_vs_cur->psize = psize;
-                       DPRINTF(1, "%s: set alternate iface to ", DEVNAME(sc));
-                       DPRINTF(1, "bAlternateSetting=0x%02x\n",
-                           id->bAlternateSetting);
-                       break;
+                       if (diff == 0)
+                               break;
                }
 next:
                desc = usb_desc_iter_next(&iter);
        }
 
+       DPRINTF(1, "%s: set alternate iface to ", DEVNAME(sc));
+       DPRINTF(1, "bAlternateSetting=0x%02x psize=%d max_packet_size=%d\n",
+           sc->sc_vs_cur->curalt, sc->sc_vs_cur->psize, max_packet_size);
+
        /* set alternate video stream interface */
        error = usbd_set_interface(ifaceh, i);
        if (error) {

Reply via email to