patch-2.3.99-pre4 linux/drivers/usb/audio.c
Next file: linux/drivers/usb/audio.h
Previous file: linux/drivers/usb/acm.c
Back to the patch index
Back to the overall index
- Lines: 117
- Date:
Mon Mar 27 10:23:21 2000
- Orig file:
v2.3.99-pre3/linux/drivers/usb/audio.c
- Orig date:
Fri Mar 10 16:40:44 2000
diff -u --recursive --new-file v2.3.99-pre3/linux/drivers/usb/audio.c linux/drivers/usb/audio.c
@@ -1395,25 +1395,30 @@
/* --------------------------------------------------------------------- */
-static unsigned int find_format(struct audioformat *afp, unsigned int nr, unsigned int fmt)
+static unsigned int find_format(struct audioformat *afp, unsigned int nr, unsigned int fmt, unsigned int rate)
{
unsigned int i;
- /* first find an exact match */
- for (i = 0; i < nr; i++)
- if (afp[i].format == fmt)
+ /* first find an exact match, taking both format and sample rate into account,
+ but ignore stereo bit */
+ for (i = 0; i < nr; i++) {
+ if (afp[i].format == (fmt & ~AFMT_STEREO) && rate >= afp[i].sratelo && rate <= afp[i].sratehi)
return i;
+ }
+
/* second find a match with the same stereo/mono and 8bit/16bit property */
for (i = 0; i < nr; i++)
if (!AFMT_ISSTEREO(afp[i].format) == !AFMT_ISSTEREO(fmt) &&
- !AFMT_IS16BIT(afp[i].format) == !AFMT_IS16BIT(fmt))
+ !AFMT_IS16BIT(afp[i].format) == !AFMT_IS16BIT(fmt) &&
+ rate >= afp[i].sratelo && rate <= afp[i].sratehi)
return i;
/* third find a match with the same number of channels */
for (i = 0; i < nr; i++)
- if (!AFMT_ISSTEREO(afp[i].format) == !AFMT_ISSTEREO(fmt))
+ if (!AFMT_ISSTEREO(afp[i].format) == !AFMT_ISSTEREO(fmt) &&
+ rate >= afp[i].sratelo && rate <= afp[i].sratehi)
return i;
- /* return anything */
- return 0;
+ /* return failure */
+ return -1;
}
static int set_format_in(struct usb_audiodev *as)
@@ -1432,7 +1437,13 @@
if (u->interface < 0 || u->interface >= config->bNumInterfaces)
return 0;
iface = &config->interface[u->interface];
- fmtnr = find_format(as->fmtin, as->numfmtin, d->format);
+
+ fmtnr = find_format(as->fmtin, as->numfmtin, d->format, d->srate);
+ if (fmtnr < 0) {
+ printk(KERN_ERR "usbaudio: set_format_in(): failed to find desired format/speed combination.\n");
+ return -1;
+ }
+
fmt = as->fmtin + fmtnr;
alts = &iface->altsetting[fmt->altsetting];
u->format = fmt->format;
@@ -1513,7 +1524,13 @@
if (u->interface < 0 || u->interface >= config->bNumInterfaces)
return 0;
iface = &config->interface[u->interface];
- fmtnr = find_format(as->fmtout, as->numfmtout, d->format);
+
+ fmtnr = find_format(as->fmtout, as->numfmtout, d->format, d->srate);
+ if (fmtnr < 0) {
+ printk(KERN_ERR "usbaudio: set_format_out(): failed to find desired format/speed combination.\n");
+ return -1;
+ }
+
fmt = as->fmtout + fmtnr;
u->format = fmt->format;
alts = &iface->altsetting[fmt->altsetting];
@@ -3330,7 +3347,7 @@
struct usb_interface *iface;
unsigned char ifin[USB_MAXINTERFACES], ifout[USB_MAXINTERFACES];
unsigned char *p1;
- unsigned int i, j, numifin = 0, numifout = 0;
+ unsigned int i, j, k, numifin = 0, numifout = 0;
if (!(s = kmalloc(sizeof(struct usb_audio_state), GFP_KERNEL)))
return NULL;
@@ -3377,12 +3394,25 @@
dev->devnum, ctrlif, j);
continue;
}
- if (iface->num_altsetting < 2 ||
- iface->altsetting[0].bNumEndpoints > 0) {
- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u altsetting 0 not zero bandwidth\n",
- dev->devnum, ctrlif);
+ if (iface->num_altsetting == 0) {
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u has no working interface.\n", dev->devnum, ctrlif);
+ continue;
+ }
+ if (iface->num_altsetting == 1) {
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u has only 1 altsetting.\n", dev->devnum, ctrlif);
continue;
}
+ if (iface->altsetting[0].bNumEndpoints > 0) {
+ /* Check all endpoints; should they all have a bandwidth of 0 ? */
+ for (k = 0; k < iface->altsetting[0].bNumEndpoints; k++) {
+ if (iface->altsetting[0].endpoint[k].wMaxPacketSize > 0) {
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u endpoint %d does not have 0 bandwidth at alt[0]\n", dev->devnum, ctrlif, k);
+ break;
+ }
+ }
+ if (k < iface->altsetting[0].bNumEndpoints)
+ continue;
+ }
if (iface->altsetting[1].bNumEndpoints < 1) {
printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no endpoint\n",
dev->devnum, ctrlif, j);
@@ -3418,7 +3448,7 @@
p1 = find_csinterface_descriptor(buffer, buflen, p1, OUTPUT_TERMINAL, ctrlif, -1);
}
- ret:
+ret:
if (list_empty(&s->audiolist) && list_empty(&s->mixerlist)) {
kfree(s);
return NULL;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)