summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorYojiro Uo <yuo@cvs.openbsd.org>2008-12-03 03:28:26 +0000
committerYojiro Uo <yuo@cvs.openbsd.org>2008-12-03 03:28:26 +0000
commit23fcdceb883f7ecd26d0878c32f8f507ba2caf0f (patch)
tree761d334980f4d3b79ef53bdf29f1da46a581e4fa /sys/dev/usb
parentbbd1c0b82a400e1542c8c2d22c5da90dc8bf6cf4 (diff)
fix USB packet size handling of uvideo(4)
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/uvideo.c31
-rw-r--r--sys/dev/usb/uvideo.h9
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;