diff options
author | Yojiro Uo <yuo@cvs.openbsd.org> | 2008-12-03 03:28:26 +0000 |
---|---|---|
committer | Yojiro Uo <yuo@cvs.openbsd.org> | 2008-12-03 03:28:26 +0000 |
commit | 23fcdceb883f7ecd26d0878c32f8f507ba2caf0f (patch) | |
tree | 761d334980f4d3b79ef53bdf29f1da46a581e4fa /sys/dev/usb | |
parent | bbd1c0b82a400e1542c8c2d22c5da90dc8bf6cf4 (diff) |
fix USB packet size handling of uvideo(4)
Diffstat (limited to 'sys/dev/usb')
-rw-r--r-- | sys/dev/usb/uvideo.c | 31 | ||||
-rw-r--r-- | sys/dev/usb/uvideo.h | 9 |
2 files changed, 24 insertions, 16 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c index 601af344414..f52cb405e04 100644 --- a/sys/dev/usb/uvideo.c +++ b/sys/dev/usb/uvideo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.c,v 1.93 2008/11/30 15:20:33 mglocker Exp $ */ +/* $OpenBSD: uvideo.c,v 1.94 2008/12/03 03:28:25 yuo Exp $ */ /* * Copyright (c) 2008 Robert Nagy <robert@openbsd.org> @@ -1009,12 +1009,12 @@ uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, struct usb_attach_arg *uaa, goto next; /* save endpoint with largest bandwidth */ - if (UGETW(ed->wMaxPacketSize) > vs->max_packet_size) { + if (UGETW(ed->wMaxPacketSize) > vs->psize) { vs->ifaceh = uaa->ifaces[iface]; vs->endpoint = ed->bEndpointAddress; vs->numalts = numalts; vs->curalt = id->bAlternateSetting; - vs->max_packet_size = UGETW(ed->wMaxPacketSize); + vs->psize = UGETW(ed->wMaxPacketSize); vs->iface = iface; } next: @@ -1041,6 +1041,7 @@ uvideo_vs_set_alt(struct uvideo_softc *sc, usbd_interface_handle ifaceh, usb_endpoint_descriptor_t *ed; int i; usbd_status error; + uint32_t psize; i = 0; usb_desc_iter_init(sc->sc_udev, &iter); @@ -1063,10 +1064,12 @@ uvideo_vs_set_alt(struct uvideo_softc *sc, usbd_interface_handle ifaceh, i++; /* save endpoint with requested bandwidth */ - if (UGETW(ed->wMaxPacketSize) >= max_packet_size) { + psize = UGETW(ed->wMaxPacketSize); + psize = UE_GET_SIZE(psize) * (1 + UE_GET_TRANS(psize)); + if (psize == max_packet_size) { sc->sc_vs_cur->endpoint = ed->bEndpointAddress; sc->sc_vs_cur->curalt = id->bAlternateSetting; - sc->sc_vs_cur->max_packet_size = max_packet_size; + sc->sc_vs_cur->psize = psize; DPRINTF(1, "%s: set alternate iface to ", DEVNAME(sc)); DPRINTF(1, "bAlternateSetting=0x%02x\n", id->bAlternateSetting); @@ -1384,7 +1387,7 @@ uvideo_vs_alloc_isoc(struct uvideo_softc *sc) return (USBD_NOMEM); } - size = sc->sc_vs_cur->max_packet_size * sc->sc_nframes; + size = sc->sc_vs_cur->psize * sc->sc_nframes; sc->sc_vs_cur->ixfer[i].buf = usbd_alloc_buffer(sc->sc_vs_cur->ixfer[i].xfer, size); @@ -1468,6 +1471,7 @@ uvideo_vs_open(struct uvideo_softc *sc) { usb_endpoint_descriptor_t *ed; usbd_status error; + uint32_t dwMaxVideoFrameSize; DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__); @@ -1497,7 +1501,7 @@ uvideo_vs_open(struct uvideo_softc *sc) ed->bEndpointAddress, sc->sc_vs_cur->endpoint, UGETW(ed->wMaxPacketSize), - sc->sc_vs_cur->max_packet_size); + sc->sc_vs_cur->psize); error = usbd_open_pipe( sc->sc_vs_cur->ifaceh, @@ -1513,11 +1517,12 @@ uvideo_vs_open(struct uvideo_softc *sc) /* calculate optimal isoc xfer size */ if (strncmp(sc->sc_udev->bus->bdev.dv_xname, "ohci", 4) == 0) { /* ohci workaround */ - sc->sc_nframes = 6400 / - sc->sc_vs_cur->max_packet_size; + sc->sc_nframes = 6400 / sc->sc_vs_cur->psize; } else { - sc->sc_nframes = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize) / - sc->sc_vs_cur->max_packet_size; + dwMaxVideoFrameSize = + UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize); + sc->sc_nframes = (dwMaxVideoFrameSize + sc->sc_vs_cur->psize - + 1) / sc->sc_vs_cur->psize; } if (sc->sc_nframes > UVIDEO_NFRAMES_MAX) sc->sc_nframes = UVIDEO_NFRAMES_MAX; @@ -1650,7 +1655,7 @@ uvideo_vs_start_isoc_ixfer(struct uvideo_softc *sc, return; for (i = 0; i < sc->sc_nframes; i++) - ixfer->size[i] = sc->sc_vs_cur->max_packet_size; + ixfer->size[i] = sc->sc_vs_cur->psize; usbd_setup_isoc_xfer( ixfer->xfer, @@ -1692,7 +1697,7 @@ uvideo_vs_cb(usbd_xfer_handle xfer, usbd_private_handle priv, goto skip; for (i = 0; i < sc->sc_nframes; i++) { - frame = ixfer->buf + (i * sc->sc_vs_cur->max_packet_size); + frame = ixfer->buf + (i * sc->sc_vs_cur->psize); frame_size = ixfer->size[i]; if (frame_size == 0) diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h index f92d1737ec6..10781553d49 100644 --- a/sys/dev/usb/uvideo.h +++ b/sys/dev/usb/uvideo.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.h,v 1.35 2008/11/30 15:20:33 mglocker Exp $ */ +/* $OpenBSD: uvideo.h,v 1.36 2008/12/03 03:28:25 yuo Exp $ */ /* * Copyright (c) 2007 Robert Nagy <robert@openbsd.org> @@ -304,6 +304,9 @@ struct usb_video_probe_commit { 0x4e, 0x56, 0x31, 0x32, 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } +#define UVIDEO_FORMAT_GUID_UYVY { \ + 0x55, 0x59, 0x56, 0x59, 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } /* * USB Video Payload MJPEG */ @@ -425,7 +428,7 @@ struct uvideo_format_desc { } u; } __packed; -#define UVIDEO_NFRAMES_MAX 640 +#define UVIDEO_NFRAMES_MAX 40 struct uvideo_isoc_xfer { struct uvideo_softc *sc; usbd_xfer_handle xfer; @@ -447,7 +450,7 @@ struct uvideo_vs_iface { usbd_pipe_handle pipeh; int numalts; int curalt; - uint32_t max_packet_size; + uint32_t psize; int iface; int bulk_endpoint; int bulk_running; |