summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2006-01-02 01:24:19 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2006-01-02 01:24:19 +0000
commit19c2190d65b50ccbcb1385e2ef74f7e2f1c6c92d (patch)
tree470cc08cd4e9d1773ac540a5b50d693440bccb27 /sys/dev/usb
parent650d8360f968a821468bb81158dd1744b0318479 (diff)
recognize sync-pipe audio stream; disabled for now. from kent@netbsd.org
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/uaudio.c80
1 files changed, 72 insertions, 8 deletions
diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c
index 3964a3e6c1a..b496f8fdebf 100644
--- a/sys/dev/usb/uaudio.c
+++ b/sys/dev/usb/uaudio.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uaudio.c,v 1.28 2006/01/02 00:26:48 fgsch Exp $ */
-/* $NetBSD: uaudio.c,v 1.79 2004/10/03 06:01:09 kent Exp $ */
+/* $OpenBSD: uaudio.c,v 1.29 2006/01/02 01:24:18 fgsch Exp $ */
+/* $NetBSD: uaudio.c,v 1.80 2004/10/16 18:08:50 kent Exp $ */
/*
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -71,6 +71,8 @@
#include <dev/usb/uaudioreg.h>
+/* #define UAUDIO_DEBUG */
+/* #define UAUDIO_MULTIPLE_ENDPOINTS */
#ifdef UAUDIO_DEBUG
#define DPRINTF(x) do { if (uaudiodebug) logprintf x; } while (0)
#define DPRINTFN(n,x) do { if (uaudiodebug>(n)) logprintf x; } while (0)
@@ -115,6 +117,7 @@ struct as_info {
usbd_interface_handle ifaceh;
const usb_interface_descriptor_t *idesc;
const usb_endpoint_descriptor_audio_t *edesc;
+ const usb_endpoint_descriptor_audio_t *edesc1;
const struct usb_audio_streaming_type1_descriptor *asf1desc;
int sc_busy; /* currently used */
};
@@ -1114,9 +1117,10 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
const struct usb_audio_streaming_interface_descriptor *asid;
const struct usb_audio_streaming_type1_descriptor *asf1d;
const usb_endpoint_descriptor_audio_t *ed;
+ const usb_endpoint_descriptor_audio_t *epdesc1;
const struct usb_audio_streaming_endpoint_descriptor *sed;
int format, chan, prec, enc;
- int dir, type;
+ int dir, type, sync;
struct as_info ai;
const char *format_str;
@@ -1147,7 +1151,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
ed = (const void *)(buf + offs);
if (ed->bDescriptorType != UDESC_ENDPOINT)
return (USBD_INVAL);
- DPRINTF(("uaudio_process_as: endpoint bLength=%d bDescriptorType=%d "
+ DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
"bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
"bInterval=%d bRefresh=%d bSynchAddress=%d\n",
ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
@@ -1166,25 +1170,80 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
type = UE_ISO_ASYNC;
/* We can't handle endpoints that need a sync pipe yet. */
+ sync = FALSE;
if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
+ sync = TRUE;
+#ifndef UAUDIO_MULTIPLE_ENDPOINTS
printf("%s: ignored input endpoint of type adaptive\n",
USBDEVNAME(sc->sc_dev));
return (USBD_NORMAL_COMPLETION);
+#endif
}
if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
+ sync = TRUE;
+#ifndef UAUDIO_MULTIPLE_ENDPOINTS
printf("%s: ignored output endpoint of type async\n",
USBDEVNAME(sc->sc_dev));
return (USBD_NORMAL_COMPLETION);
+#endif
}
sed = (const void *)(buf + offs);
if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
sed->bDescriptorSubtype != AS_GENERAL)
return (USBD_INVAL);
+ DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
offs += sed->bLength;
if (offs > size)
return (USBD_INVAL);
+ if (sync && id->bNumEndpoints <= 1) {
+ printf("%s: a sync-pipe endpoint but no other endpoint\n",
+ USBDEVNAME(sc->sc_dev));
+ return USBD_INVAL;
+ }
+ if (!sync && id->bNumEndpoints > 1) {
+ printf("%s: non sync-pipe endpoint but multiple endpoints\n",
+ USBDEVNAME(sc->sc_dev));
+ return USBD_INVAL;
+ }
+ epdesc1 = NULL;
+ if (id->bNumEndpoints > 1) {
+ epdesc1 = (const void*)(buf + offs);
+ if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
+ return USBD_INVAL;
+ DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
+ "bDescriptorType=%d bEndpointAddress=%d "
+ "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
+ "bRefresh=%d bSynchAddress=%d\n",
+ epdesc1->bLength, epdesc1->bDescriptorType,
+ epdesc1->bEndpointAddress, epdesc1->bmAttributes,
+ UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
+ epdesc1->bRefresh, epdesc1->bSynchAddress));
+ offs += epdesc1->bLength;
+ if (offs > size)
+ return USBD_INVAL;
+ if (epdesc1->bSynchAddress != 0) {
+ printf("%s: invalid endpoint: bSynchAddress=0\n",
+ USBDEVNAME(sc->sc_dev));
+ return USBD_INVAL;
+ }
+ if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
+ printf("%s: invalid endpoint: bmAttributes=0x%x\n",
+ USBDEVNAME(sc->sc_dev), epdesc1->bmAttributes);
+ return USBD_INVAL;
+ }
+ if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
+ printf("%s: invalid endpoint addresses: "
+ "ep[0]->bSynchAddress=0x%x "
+ "ep[1]->bEndpointAddress=0x%x\n",
+ USBDEVNAME(sc->sc_dev), ed->bSynchAddress,
+ epdesc1->bEndpointAddress);
+ return USBD_INVAL;
+ }
+ /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
+ }
+
format = UGETW(asid->wFormatTag);
chan = asf1d->bNrChannels;
prec = asf1d->bBitResolution;
@@ -1220,6 +1279,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
sc->sc_altflags |= HAS_MULAW;
format_str = "mulaw";
break;
+ case UA_FMT_IEEE_FLOAT:
default:
printf("%s: ignored setting with format %d\n",
USBDEVNAME(sc->sc_dev), format);
@@ -1244,6 +1304,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
ai.attributes = sed->bmAttributes;
ai.idesc = id;
ai.edesc = ed;
+ ai.edesc1 = epdesc1;
ai.asf1desc = asf1d;
ai.sc_busy = 0;
uaudio_add_alt(sc, &ai);
@@ -1278,8 +1339,8 @@ uaudio_identify_as(struct uaudio_softc *sc,
/* Loop through all the alternate settings. */
while (offs <= size) {
- DPRINTFN(2, ("uaudio_identify: interface %d\n",
- id->bInterfaceNumber));
+ DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
+ id->bInterfaceNumber, offs));
switch (id->bNumEndpoints) {
case 0:
DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
@@ -1287,6 +1348,9 @@ uaudio_identify_as(struct uaudio_softc *sc,
sc->sc_nullalt = id->bAlternateSetting;
break;
case 1:
+#ifdef UAUDIO_MULTIPLE_ENDPOINTS
+ case 2:
+#endif
uaudio_process_as(sc, buf, &offs, size, id);
break;
default:
@@ -2323,13 +2387,13 @@ uaudio_match_alt_sub(int nalts, const struct as_info *alts,
if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
continue;
if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
- DPRINTFN(2,("uaudio_match_alt_sub: cont %d-%d\n",
+ DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n",
UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
return i;
} else {
for (j = 0; j < a1d->bSamFreqType; j++) {
- DPRINTFN(2,("uaudio_match_alt_sub: disc #%d: %d\n",
+ DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n",
j, UA_GETSAMP(a1d, j)));
/* XXX allow for some slack */
if (UA_GETSAMP(a1d, j) == rate)