From 334f2cf5a8a3d24ac5671425fc59d08923312b6b Mon Sep 17 00:00:00 2001 From: jakemsr Date: Mon, 19 Jul 2010 05:50:37 +0000 Subject: [PATCH] add a quirk to allow attaching devices which claim to have a vendor defined interface class, but are audio class compliant enough to be supported by this driver. the E-MU 0202 USB is such a device. this gets it attaching, but needs some forthcoming commits to make it usable. --- sys/dev/usb/uaudio.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 70c15788c45..120f0382430 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uaudio.c,v 1.75 2010/07/19 05:08:37 jakemsr Exp $ */ +/* $OpenBSD: uaudio.c,v 1.76 2010/07/19 05:50:37 jakemsr Exp $ */ /* $NetBSD: uaudio.c,v 1.90 2004/10/29 17:12:53 kent Exp $ */ /* @@ -157,6 +157,7 @@ struct chan { #define UAUDIO_FLAG_NO_FRAC 0x0002 /* don't use fractional samples */ #define UAUDIO_FLAG_NO_XU 0x0004 /* has broken extension unit */ #define UAUDIO_FLAG_BAD_ADC 0x0008 /* bad audio spec version number */ +#define UAUDIO_FLAG_VENDOR_CLASS 0x0010 /* claims vendor class but works */ struct uaudio_devs { struct usb_devno uv_dev; @@ -166,6 +167,8 @@ struct uaudio_devs { UAUDIO_FLAG_BAD_ADC } , { { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495 }, UAUDIO_FLAG_BAD_AUDIO }, + { { USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_EMU0202 }, + UAUDIO_FLAG_VENDOR_CLASS }, { { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502 }, UAUDIO_FLAG_NO_XU | UAUDIO_FLAG_BAD_ADC }, { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBDLX }, @@ -255,7 +258,7 @@ usbd_status uaudio_process_as void uaudio_add_alt(struct uaudio_softc *, const struct as_info *); const usb_interface_descriptor_t *uaudio_find_iface - (const char *, int, int *, int); + (const char *, int, int *, int, int); void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *); char *uaudio_id_name @@ -426,6 +429,12 @@ uaudio_match(struct device *parent, void *match, void *aux) !(flags & UAUDIO_FLAG_BAD_AUDIO)) return (UMATCH_VENDOR_PRODUCT_CONF_IFACE); + /* additional quirk devices which we want to attach */ + if ((flags & UAUDIO_FLAG_VENDOR_CLASS) && + id->bInterfaceClass == UICLASS_VENDOR && + id->bInterfaceSubClass == UISUBCLASS_AUDIOCONTROL) + return (UMATCH_VENDOR_PRODUCT_CONF_IFACE); + return (UMATCH_NONE); } @@ -626,7 +635,7 @@ uaudio_query_encoding(void *addr, struct audio_encoding *fp) } const usb_interface_descriptor_t * -uaudio_find_iface(const char *buf, int size, int *offsp, int subtype) +uaudio_find_iface(const char *buf, int size, int *offsp, int subtype, int flags) { const usb_interface_descriptor_t *d; @@ -634,8 +643,10 @@ uaudio_find_iface(const char *buf, int size, int *offsp, int subtype) d = (const void *)(buf + *offsp); *offsp += d->bLength; if (d->bDescriptorType == UDESC_INTERFACE && - d->bInterfaceClass == UICLASS_AUDIO && - d->bInterfaceSubClass == subtype) + d->bInterfaceSubClass == subtype && + (d->bInterfaceClass == UICLASS_AUDIO || + (d->bInterfaceClass == UICLASS_VENDOR && + (flags & UAUDIO_FLAG_VENDOR_CLASS)))) return (d); } return (NULL); @@ -1768,7 +1779,8 @@ uaudio_identify_as(struct uaudio_softc *sc, /* Locate the AudioStreaming interface descriptor. */ offs = 0; - id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM); + id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM, + sc->sc_quirks); if (id == NULL) return (USBD_INVAL); @@ -1794,7 +1806,8 @@ uaudio_identify_as(struct uaudio_softc *sc, sc->sc_dev.dv_xname, id->bNumEndpoints); break; } - id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM); + id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM, + sc->sc_quirks); if (id == NULL) break; } @@ -1828,7 +1841,8 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc /* Locate the AudioControl interface descriptor. */ offs = 0; - id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL); + id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL, + sc->sc_quirks); if (id == NULL) return (USBD_INVAL); if (offs + sizeof *acdp > size) -- 2.20.1