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) {
