patch-2.3.25 linux/drivers/usb/audio.c
Next file: linux/drivers/usb/cpia.c
Previous file: linux/drivers/usb/acm.c
Back to the patch index
Back to the overall index
- Lines: 986
- Date:
Sun Oct 31 15:01:59 1999
- Orig file:
v2.3.24/linux/drivers/usb/audio.c
- Orig date:
Mon Oct 11 15:38:15 1999
diff -u --recursive --new-file v2.3.24/linux/drivers/usb/audio.c linux/drivers/usb/audio.c
@@ -33,6 +33,22 @@
* wants to use an Asynch out pipe. usb_audio_state now basically
* only contains lists of mixer and wave devices. We can therefore
* now have multiple mixer/wave devices per USB device.
+ * 1999-10-31: Thomas Sailer
+ * Audio can now be unloaded if it is not in use by any mixer
+ * or dsp client (formerly you had to disconnect the audio devices
+ * from the USB port)
+ * Finally, about three months after ordering, my "Maxxtro SPK222"
+ * speakers arrived, isn't disdata a great mail order company 8-)
+ * Parse class specific endpoint descriptor of the audiostreaming
+ * interfaces and take the endpoint attributes from there.
+ * Unbelievably, the Philips USB DAC has a sampling rate range
+ * of over a decade, yet does not support the sampling rate control!
+ * No wonder it sounds so bad, has very audible sampling rate
+ * conversion distortion. Don't try to listen to it using
+ * decent headphones!
+ * "Let's make things better" -> but please Philips start with your
+ * own stuff!!!!
+ *
*
*/
@@ -182,6 +198,7 @@
unsigned int sratelo;
unsigned int sratehi;
unsigned char altsetting;
+ unsigned char attributes;
};
struct dmabuf {
@@ -542,11 +559,24 @@
i = u->flags;
spin_unlock_irqrestore(&as->lock, flags);
while (i & (FLG_ID0RUNNING|FLG_ID1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) {
+ set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
+ if (signal_pending(current)) {
+ if (i & FLG_ID0RUNNING)
+ usb_kill_isoc(u->dataiso[0]);
+ if (i & FLG_ID1RUNNING)
+ usb_kill_isoc(u->dataiso[1]);
+ if (i & FLG_SYNC0RUNNING)
+ usb_kill_isoc(u->synciso[0]);
+ if (i & FLG_SYNC1RUNNING)
+ usb_kill_isoc(u->synciso[1]);
+ break;
+ }
spin_lock_irqsave(&as->lock, flags);
i = u->flags;
spin_unlock_irqrestore(&as->lock, flags);
}
+ set_current_state(TASK_RUNNING);
if (u->dataiso[0])
usb_free_isoc(u->dataiso[0]);
if (u->dataiso[1])
@@ -801,6 +831,7 @@
printk(KERN_DEBUG "usbin_completed: killing id\n");
usb_kill_isoc(id);
printk(KERN_DEBUG "usbin_completed: id killed\n");
+ wake_up(&u->dma.wait);
}
spin_unlock_irqrestore(&as->lock, flags);
return 0;
@@ -873,6 +904,7 @@
printk(KERN_DEBUG "usbin_sync_completed: killing id\n");
usb_kill_isoc(id);
printk(KERN_DEBUG "usbin_sync_completed: id killed\n");
+ wake_up(&u->dma.wait);
}
spin_unlock_irqrestore(&as->lock, flags);
return 0;
@@ -1005,12 +1037,25 @@
spin_unlock_irqrestore(&as->lock, flags);
printk(KERN_DEBUG "usb_audio: usbout_stop (2) flags 0x%04x\n", i);
while (i & (FLG_ID0RUNNING|FLG_ID1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) {
+ set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
+ if (signal_pending(current)) {
+ if (i & FLG_ID0RUNNING)
+ usb_kill_isoc(u->dataiso[0]);
+ if (i & FLG_ID1RUNNING)
+ usb_kill_isoc(u->dataiso[1]);
+ if (i & FLG_SYNC0RUNNING)
+ usb_kill_isoc(u->synciso[0]);
+ if (i & FLG_SYNC1RUNNING)
+ usb_kill_isoc(u->synciso[1]);
+ break;
+ }
spin_lock_irqsave(&as->lock, flags);
i = u->flags;
spin_unlock_irqrestore(&as->lock, flags);
printk(KERN_DEBUG "usb_audio: usbout_stop (3) flags 0x%04x\n", i);
}
+ set_current_state(TASK_RUNNING);
if (u->dataiso[0])
usb_free_isoc(u->dataiso[0]);
if (u->dataiso[1])
@@ -1272,6 +1317,7 @@
printk(KERN_DEBUG "usbout_completed: killing id\n");
usb_kill_isoc(id);
printk(KERN_DEBUG "usbout_completed: id killed\n");
+ wake_up(&u->dma.wait);
}
spin_unlock_irqrestore(&as->lock, flags);
return 0;
@@ -1347,6 +1393,7 @@
printk(KERN_DEBUG "usbout_sync_completed: killing id\n");
usb_kill_isoc(id);
printk(KERN_DEBUG "usbout_sync_completed: id killed\n");
+ wake_up(&u->dma.wait);
}
spin_unlock_irqrestore(&as->lock, flags);
return 0;
@@ -1500,6 +1547,7 @@
struct audioformat *fmt;
unsigned int fmtnr, ep;
unsigned char data[3];
+ int ret;
if (u->interface < 0 || u->interface >= config->bNumInterfaces)
return 0;
@@ -1515,7 +1563,7 @@
alts->endpoint[1].bmAttributes != 0x01 ||
alts->endpoint[1].bSynchAddress != 0 ||
alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress & 0x7f)) {
- printk(KERN_ERR "usb_audio: device %d interface %d altsetting %d invalid synch pipe\n",
+ printk(KERN_ERR "usbaudio: device %d interface %d altsetting %d invalid synch pipe\n",
dev->devnum, u->interface, fmt->altsetting);
return -1;
}
@@ -1533,25 +1581,38 @@
}
if (fmt->sratelo == fmt->sratehi)
return 0;
- data[0] = d->srate;
- data[1] = d->srate >> 8;
- data[2] = d->srate >> 16;
ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN);
- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
- SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) {
- printk(KERN_ERR "usbaudio: failure to set input sampling frequency device %d endpoint 0x%x to %u\n",
- dev->devnum, ep, d->srate);
- return -1;
+ /* if endpoint has pitch control, enable it */
+ if (fmt->attributes & 0x02) {
+ data[0] = 1;
+ if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
+ PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) {
+ printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n",
+ ret, dev->devnum, u->interface, ep, d->srate);
+ return -1;
+ }
}
- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
- SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) {
- printk(KERN_ERR "usbaudio: failure to get input sampling frequency device %d endpoint 0x%x\n",
- dev->devnum, ep);
- return -1;
+ /* if endpoint has sampling rate control, set it */
+ if (fmt->attributes & 0x01) {
+ data[0] = d->srate;
+ data[1] = d->srate >> 8;
+ data[2] = d->srate >> 16;
+ if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
+ SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
+ printk(KERN_ERR "usbaudio: failure (error %d) to set input sampling frequency device %d interface %u endpoint 0x%x to %u\n",
+ ret, dev->devnum, u->interface, ep, d->srate);
+ return -1;
+ }
+ if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
+ SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
+ printk(KERN_ERR "usbaudio: failure (error %d) to get input sampling frequency device %d interface %u endpoint 0x%x\n",
+ ret, dev->devnum, u->interface, ep);
+ return -1;
+ }
+ printk(KERN_DEBUG "usbaudio: set_format_in: device %d interface %d altsetting %d srate req: %u real %u\n",
+ dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16));
+ d->srate = data[0] | (data[1] << 8) | (data[2] << 16);
}
- printk(KERN_DEBUG "usb_audio: set_format_in: device %d interface %d altsetting %d srate req: %u real %u\n",
- dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16));
- d->srate = data[0] | (data[1] << 8) | (data[2] << 16);
return 0;
}
@@ -1566,6 +1627,7 @@
struct audioformat *fmt;
unsigned int fmtnr, ep;
unsigned char data[3];
+ int ret;
if (u->interface < 0 || u->interface >= config->bNumInterfaces)
return 0;
@@ -1581,7 +1643,7 @@
alts->endpoint[1].bmAttributes != 0x01 ||
alts->endpoint[1].bSynchAddress != 0 ||
alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress | 0x80)) {
- printk(KERN_ERR "usb_audio: device %d interface %d altsetting %d invalid synch pipe\n",
+ printk(KERN_ERR "usbaudio: device %d interface %d altsetting %d invalid synch pipe\n",
dev->devnum, u->interface, fmt->altsetting);
return -1;
}
@@ -1599,25 +1661,38 @@
}
if (fmt->sratelo == fmt->sratehi)
return 0;
- data[0] = d->srate;
- data[1] = d->srate >> 8;
- data[2] = d->srate >> 16;
ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN);
- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
- SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) {
- printk(KERN_ERR "usbaudio: failure to set output sampling frequency device %d endpoint 0x%x to %u\n",
- dev->devnum, ep, d->srate);
- return -1;
+ /* if endpoint has pitch control, enable it */
+ if (fmt->attributes & 0x02) {
+ data[0] = 1;
+ if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
+ PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) {
+ printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n",
+ ret, dev->devnum, u->interface, ep, d->srate);
+ return -1;
+ }
}
- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
- SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) {
- printk(KERN_ERR "usbaudio: failure to get output sampling frequency device %d endpoint 0x%x\n",
- dev->devnum, ep);
- return -1;
+ /* if endpoint has sampling rate control, set it */
+ if (fmt->attributes & 0x01) {
+ data[0] = d->srate;
+ data[1] = d->srate >> 8;
+ data[2] = d->srate >> 16;
+ if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
+ SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
+ printk(KERN_ERR "usbaudio: failure (error %d) to set output sampling frequency device %d interface %u endpoint 0x%x to %u\n",
+ ret, dev->devnum, u->interface, ep, d->srate);
+ return -1;
+ }
+ if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
+ SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
+ printk(KERN_ERR "usbaudio: failure (error %d) to get output sampling frequency device %d interface %u endpoint 0x%x\n",
+ ret, dev->devnum, u->interface, ep);
+ return -1;
+ }
+ printk(KERN_DEBUG "usbaudio: set_format_out: device %d interface %d altsetting %d srate req: %u real %u\n",
+ dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16));
+ d->srate = data[0] | (data[1] << 8) | (data[2] << 16);
}
- printk(KERN_DEBUG "usb_audio: set_format_out: device %d interface %d altsetting %d srate req: %u real %u\n",
- dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16));
- d->srate = data[0] | (data[1] << 8) | (data[2] << 16);
return 0;
}
@@ -1736,7 +1811,7 @@
return 0;
err:
- printk(KERN_ERR "usb_audio: mixer request device %u if %u unit %u ch %u selector %u failed\n",
+ printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n",
dev->devnum, ms->iface, ch->unitid, ch->chnum, ch->selector);
return -1;
}
@@ -1775,7 +1850,6 @@
kfree(ms);
}
kfree(s);
- MOD_DEC_USE_COUNT;
}
extern inline int prog_dmabuf_in(struct usb_audiodev *as)
@@ -1825,6 +1899,7 @@
}
file->private_data = ms;
s->count++;
+ MOD_INC_USE_COUNT;
up(&open_sem);
return 0;
}
@@ -1836,6 +1911,7 @@
down(&open_sem);
release(s);
+ MOD_DEC_USE_COUNT;
return 0;
}
@@ -1952,10 +2028,10 @@
if (as->usbout.dma.mapped || !as->usbout.dma.ready)
return 0;
- __set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&as->usbout.dma.wait, &wait);
for (;;) {
- spin_lock_irqsave(&as->lock, flags);
+ __set_current_state(TASK_INTERRUPTIBLE);
+ spin_lock_irqsave(&as->lock, flags);
count = as->usbout.dma.count;
spin_unlock_irqrestore(&as->lock, flags);
if (count <= 0)
@@ -1969,8 +2045,10 @@
}
tmo = 3 * HZ * count / as->usbout.dma.srate;
tmo >>= AFMT_BYTESSHIFT(as->usbout.dma.format);
- if (!schedule_timeout(tmo + 1))
+ if (!schedule_timeout(tmo + 1)) {
printk(KERN_DEBUG "usbaudio: dma timed out??\n");
+ break;
+ }
}
remove_wait_queue(&as->usbout.dma.wait, &wait);
set_current_state(TASK_RUNNING);
@@ -1998,12 +2076,14 @@
return ret;
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
- __set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&as->usbin.dma.wait, &wait);
while (count > 0) {
spin_lock_irqsave(&as->lock, flags);
ptr = as->usbin.dma.rdptr;
cnt = as->usbin.dma.count;
+ /* set task state early to avoid wakeup races */
+ if (cnt <= 0)
+ __set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irqrestore(&as->lock, flags);
if (cnt > count)
cnt = count;
@@ -2060,9 +2140,13 @@
return ret;
if (!access_ok(VERIFY_READ, buffer, count))
return -EFAULT;
- __set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&as->usbout.dma.wait, &wait);
while (count > 0) {
+#if 0
+ printk(KERN_DEBUG "usb_audio_write: count %u dma: count %u rdptr %u wrptr %u dmasize %u fragsize %u flags 0x%02x taskst 0x%x\n",
+ count, as->usbout.dma.count, as->usbout.dma.rdptr, as->usbout.dma.wrptr, as->usbout.dma.dmasize, as->usbout.dma.fragsize,
+ as->usbout.flags, current->state);
+#endif
spin_lock_irqsave(&as->lock, flags);
if (as->usbout.dma.count < 0) {
as->usbout.dma.count = 0;
@@ -2070,6 +2154,9 @@
}
ptr = as->usbout.dma.wrptr;
cnt = as->usbout.dma.dmasize - as->usbout.dma.count;
+ /* set task state early to avoid wakeup races */
+ if (cnt <= 0)
+ __set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irqrestore(&as->lock, flags);
if (cnt > count)
cnt = count;
@@ -2160,7 +2247,7 @@
db = &as->usbin.dma;
} else
return -EINVAL;
- if (vma->vm_offset != 0)
+ if (vma->vm_pgoff != 0)
return -EINVAL;
return dmabuf_mmap(db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot);
}
@@ -2469,6 +2556,7 @@
file->private_data = as;
as->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
s->count++;
+ MOD_INC_USE_COUNT;
up(&open_sem);
return 0;
}
@@ -2498,6 +2586,7 @@
as->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
release(s);
wake_up(&open_wait);
+ MOD_DEC_USE_COUNT;
return 0;
}
@@ -2532,14 +2621,16 @@
* zero bandwidth (idle) config and one or more live one pers interface.
*/
-static int usb_audio_probe(struct usb_device *dev);
-static void usb_audio_disconnect(struct usb_device *dev);
+static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum);
+static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
static struct usb_driver usb_audio_driver = {
"audio",
usb_audio_probe,
usb_audio_disconnect,
- { NULL, NULL }
+ /*{ NULL, NULL }, */ LIST_HEAD_INIT(usb_audio_driver.driver_list),
+ NULL,
+ 0
};
@@ -2620,7 +2711,7 @@
struct usb_interface_descriptor *alts;
struct usb_interface *iface;
struct audioformat *fp;
- unsigned char *fmt;
+ unsigned char *fmt, *csep;
unsigned int i, j, k, format;
if (!(as = kmalloc(sizeof(struct usb_audiodev), GFP_KERNEL)))
@@ -2640,44 +2731,50 @@
if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2)
continue;
if (alts->bNumEndpoints < 1) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u does not have an endpoint\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n",
dev->devnum, asifin, i);
continue;
}
if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 ||
!(alts->endpoint[0].bEndpointAddress & 0x80)) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u first endpoint not isochronous in\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous in\n",
dev->devnum, asifin, i);
continue;
}
fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifin, i);
if (!fmt) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
dev->devnum, asifin, i);
continue;
}
if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u format not supported\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u format not supported\n",
dev->devnum, asifin, i);
continue;
}
format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8);
fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifin, i);
if (!fmt) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
dev->devnum, asifin, i);
continue;
}
if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n",
dev->devnum, asifin, i);
continue;
}
if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n",
dev->devnum, asifin, i, fmt[4], fmt[5]);
continue;
}
+ csep = find_descriptor(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, asifin, i);
+ if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) {
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u no or invalid class specific endpoint descriptor\n",
+ dev->devnum, asifin, i);
+ continue;
+ }
if (as->numfmtin >= MAXFORMATS)
continue;
fp = &as->fmtin[as->numfmtin++];
@@ -2697,8 +2794,9 @@
if (k < fp->sratelo)
fp->sratelo = k;
}
- printk(KERN_INFO "usb_audio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u\n",
- dev->devnum, asifin, i, fp->format, fp->sratelo, fp->sratehi);
+ fp->attributes = csep[3];
+ printk(KERN_INFO "usbaudio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u attributes 0x%02x\n",
+ dev->devnum, asifin, i, fp->format, fp->sratelo, fp->sratehi, fp->attributes);
}
}
/* search for output formats */
@@ -2709,44 +2807,50 @@
if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2)
continue;
if (alts->bNumEndpoints < 1) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u does not have an endpoint\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n",
dev->devnum, asifout, i);
continue;
}
if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 ||
(alts->endpoint[0].bEndpointAddress & 0x80)) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u first endpoint not isochronous out\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous out\n",
dev->devnum, asifout, i);
continue;
}
fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifout, i);
if (!fmt) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
dev->devnum, asifout, i);
continue;
}
if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u format not supported\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u format not supported\n",
dev->devnum, asifout, i);
continue;
}
format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8);
fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifout, i);
if (!fmt) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
dev->devnum, asifout, i);
continue;
}
if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n",
dev->devnum, asifout, i);
continue;
}
if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) {
- printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n",
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n",
dev->devnum, asifout, i, fmt[4], fmt[5]);
continue;
}
+ csep = find_descriptor(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, asifout, i);
+ if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) {
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u no or invalid class specific endpoint descriptor\n",
+ dev->devnum, asifout, i);
+ continue;
+ }
if (as->numfmtout >= MAXFORMATS)
continue;
fp = &as->fmtout[as->numfmtout++];
@@ -2766,8 +2870,9 @@
if (k < fp->sratelo)
fp->sratelo = k;
}
- printk(KERN_INFO "usb_audio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u\n",
- dev->devnum, asifout, i, fp->format, fp->sratelo, fp->sratehi);
+ fp->attributes = csep[3];
+ printk(KERN_INFO "usbaudio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u attributes 0x%02x\n",
+ dev->devnum, asifout, i, fp->format, fp->sratelo, fp->sratehi, fp->attributes);
}
}
if (as->numfmtin == 0 && as->numfmtout == 0) {
@@ -2775,7 +2880,7 @@
return;
}
if ((as->dev_audio = register_sound_dsp(&usb_audio_fops, -1)) < 0) {
- printk(KERN_ERR "usb_audio: cannot register dsp\n");
+ printk(KERN_ERR "usbaudio: cannot register dsp\n");
kfree(as);
return;
}
@@ -2803,11 +2908,11 @@
struct mixerchannel *c;
if (nr >= SOUND_MIXER_NRDEVICES) {
- printk(KERN_ERR "usb_audio: invalid OSS mixer channel %u\n", nr);
+ printk(KERN_ERR "usbaudio: invalid OSS mixer channel %u\n", nr);
return NULL;
}
if (!(state->mixchmask & (1 << nr))) {
- printk(KERN_WARNING "usb_audio: OSS mixer channel %u already in use\n", nr);
+ printk(KERN_WARNING "usbaudio: OSS mixer channel %u already in use\n", nr);
return NULL;
}
c = &state->mixch[state->nrmixch++];
@@ -2973,7 +3078,7 @@
return;
err:
- printk(KERN_ERR "usb_audio: mixer request device %u if %u unit %u ch %u selector %u failed\n",
+ printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n",
dev->devnum, state->ctrlif, ch->unitid, ch->chnum, ch->selector);
if (state->nrmixch)
state->nrmixch--;
@@ -3009,11 +3114,11 @@
unsigned int i;
if (!mixer[4]) {
- printk(KERN_ERR "usb_audio: unit %u invalid MIXER_UNIT descriptor\n", mixer[3]);
+ printk(KERN_ERR "usbaudio: unit %u invalid MIXER_UNIT descriptor\n", mixer[3]);
return;
}
if (mixer[4] > SOUND_MIXER_NRDEVICES) {
- printk(KERN_ERR "usb_audio: mixer unit %u: too many input pins\n", mixer[3]);
+ printk(KERN_ERR "usbaudio: mixer unit %u: too many input pins\n", mixer[3]);
return;
}
chidx[0] = 0;
@@ -3027,7 +3132,7 @@
bmapsize = (nroutch * chidx[mixer[4]] + 7) >> 3;
bmap += bmapsize - 1;
if (mixer[0] < 10+mixer[4]+bmapsize) {
- printk(KERN_ERR "usb_audio: unit %u invalid MIXER_UNIT descriptor (bitmap too small)\n", mixer[3]);
+ printk(KERN_ERR "usbaudio: unit %u invalid MIXER_UNIT descriptor (bitmap too small)\n", mixer[3]);
return;
}
for (i = 0; i < mixer[4]; i++) {
@@ -3066,7 +3171,7 @@
unsigned int chnum, i;
if (!selector[4]) {
- printk(KERN_ERR "usb_audio: unit %u invalid SELECTOR_UNIT descriptor\n", selector[3]);
+ printk(KERN_ERR "usbaudio: unit %u invalid SELECTOR_UNIT descriptor\n", selector[3]);
return;
}
usb_audio_recurseunit(state, selector[5]);
@@ -3074,7 +3179,7 @@
for (i = 1; i < selector[4]; i++) {
usb_audio_recurseunit(state, selector[5+i]);
if (chnum != state->nrchannels) {
- printk(KERN_ERR "usb_audio: selector unit %u: input pins with varying channel numbers\n", selector[3]);
+ printk(KERN_ERR "usbaudio: selector unit %u: input pins with varying channel numbers\n", selector[3]);
state->termtype = 0;
state->chconfig = 0;
state->nrchannels = 0;
@@ -3100,18 +3205,20 @@
static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr)
{
+ struct usb_device *dev = state->s->usbdev;
struct mixerchannel *ch;
unsigned short chftr, mchftr;
+ unsigned char data[1];
usb_audio_recurseunit(state, ftr[4]);
if (state->nrchannels == 0) {
- printk(KERN_ERR "usb_audio: feature unit %u source has no channels\n", ftr[3]);
+ printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]);
return;
}
if (state->nrchannels > 2)
- printk(KERN_WARNING "usb_audio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]);
+ printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]);
if (ftr[0] < 7+ftr[5]*(1+state->nrchannels)) {
- printk(KERN_ERR "usb_audio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]);
+ printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]);
return;
}
mchftr = ftr[6];
@@ -3149,7 +3256,7 @@
prepmixch(state);
}
} else if (mchftr & 4) {
- ch = getmixchannel(state, getvolchannel(state));
+ ch = getmixchannel(state, SOUND_MIXER_BASS);
if (ch) {
ch->unitid = ftr[3];
ch->selector = BASS_CONTROL;
@@ -3169,7 +3276,7 @@
prepmixch(state);
}
} else if (mchftr & 16) {
- ch = getmixchannel(state, getvolchannel(state));
+ ch = getmixchannel(state, SOUND_MIXER_TREBLE);
if (ch) {
ch->unitid = ftr[3];
ch->selector = TREBLE_CONTROL;
@@ -3178,6 +3285,14 @@
prepmixch(state);
}
}
+ /* if there are mute controls, unmute them */
+ if ((chftr & 1) || (mchftr & 1)) {
+ printk(KERN_DEBUG "usbaudio: unmuting feature unit %u interface %u\n", ftr[3], state->ctrlif);
+ data[0] = 0;
+ if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
+ (MUTE_CONTROL << 8) | 0xff, state->ctrlif | (ftr[3] << 8), data, 1, HZ) < 0)
+ printk(KERN_WARNING "usbaudio: failure to unmute feature unit %u interface %u\n", ftr[3], state->ctrlif);
+ }
}
static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid)
@@ -3186,12 +3301,12 @@
unsigned int i, j;
if (test_and_set_bit(unitid, &state->unitbitmap)) {
- printk(KERN_ERR "usb_audio: mixer path recursion detected, unit %d!\n", unitid);
+ printk(KERN_ERR "usbaudio: mixer path recursion detected, unit %d!\n", unitid);
return;
}
p1 = find_audiocontrol_unit(state->buffer, state->buflen, NULL, unitid, state->ctrlif);
if (!p1) {
- printk(KERN_ERR "usb_audio: unit %d not found!\n", unitid);
+ printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid);
return;
}
state->nrchannels = 0;
@@ -3200,7 +3315,7 @@
switch (p1[2]) {
case INPUT_TERMINAL:
if (p1[0] < 12) {
- printk(KERN_ERR "usb_audio: unit %u: invalid INPUT_TERMINAL descriptor\n", unitid);
+ printk(KERN_ERR "usbaudio: unit %u: invalid INPUT_TERMINAL descriptor\n", unitid);
return;
}
state->nrchannels = p1[7];
@@ -3210,7 +3325,7 @@
case MIXER_UNIT:
if (p1[0] < 10 || p1[0] < 10+p1[4]) {
- printk(KERN_ERR "usb_audio: unit %u: invalid MIXER_UNIT descriptor\n", unitid);
+ printk(KERN_ERR "usbaudio: unit %u: invalid MIXER_UNIT descriptor\n", unitid);
return;
}
usb_audio_mixerunit(state, p1);
@@ -3218,7 +3333,7 @@
case SELECTOR_UNIT:
if (p1[0] < 6 || p1[0] < 6+p1[4]) {
- printk(KERN_ERR "usb_audio: unit %u: invalid SELECTOR_UNIT descriptor\n", unitid);
+ printk(KERN_ERR "usbaudio: unit %u: invalid SELECTOR_UNIT descriptor\n", unitid);
return;
}
usb_audio_selectorunit(state, p1);
@@ -3226,7 +3341,7 @@
case FEATURE_UNIT:
if (p1[0] < 7 || p1[0] < 7+p1[5]) {
- printk(KERN_ERR "usb_audio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid);
+ printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid);
return;
}
usb_audio_featureunit(state, p1);
@@ -3234,7 +3349,7 @@
case PROCESSING_UNIT:
if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]] || p1[0] < 13+p1[6]+p1[11+p1[6]]+p1[13+p1[6]+p1[11+p1[6]]]) {
- printk(KERN_ERR "usb_audio: unit %u: invalid PROCESSING_UNIT descriptor\n", unitid);
+ printk(KERN_ERR "usbaudio: unit %u: invalid PROCESSING_UNIT descriptor\n", unitid);
return;
}
usb_audio_processingunit(state, p1);
@@ -3242,7 +3357,7 @@
case EXTENSION_UNIT:
if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]]) {
- printk(KERN_ERR "usb_audio: unit %u: invalid EXTENSION_UNIT descriptor\n", unitid);
+ printk(KERN_ERR "usbaudio: unit %u: invalid EXTENSION_UNIT descriptor\n", unitid);
return;
}
for (j = i = 0; i < p1[6]; i++) {
@@ -3258,7 +3373,7 @@
return;
default:
- printk(KERN_ERR "usb_audio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
+ printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
return;
}
}
@@ -3276,11 +3391,11 @@
state.buflen = buflen;
state.ctrlif = ctrlif;
set_bit(oterm[3], &state.unitbitmap); /* mark terminal ID as visited */
- printk(KERN_INFO "usb_audio: constructing mixer for Terminal %u type 0x%04x\n",
+ printk(KERN_INFO "usbaudio: constructing mixer for Terminal %u type 0x%04x\n",
oterm[3], oterm[4] | (oterm[5] << 8));
usb_audio_recurseunit(&state, oterm[7]);
if (!state.nrmixch) {
- printk(KERN_INFO "usb_audio: no mixer controls found for Terminal %u\n", oterm[3]);
+ printk(KERN_INFO "usbaudio: no mixer controls found for Terminal %u\n", oterm[3]);
return;
}
if (!(ms = kmalloc(sizeof(struct usb_mixerdev)+state.nrmixch*sizeof(struct mixerchannel), GFP_KERNEL)))
@@ -3291,14 +3406,14 @@
ms->iface = ctrlif;
ms->numch = state.nrmixch;
if ((ms->dev_mixer = register_sound_mixer(&usb_mixer_fops, -1)) < 0) {
- printk(KERN_ERR "usb_audio: cannot register mixer\n");
+ printk(KERN_ERR "usbaudio: cannot register mixer\n");
kfree(ms);
return;
}
list_add_tail(&ms->list, &s->mixerlist);
}
-static int usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif)
+static void * usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif)
{
struct usb_audio_state *s;
struct usb_config_descriptor *config = dev->actconfig;
@@ -3308,7 +3423,7 @@
unsigned int i, j, numifin = 0, numifout = 0;
if (!(s = kmalloc(sizeof(struct usb_audio_state), GFP_KERNEL)))
- return -1;
+ return NULL;
memset(s, 0, sizeof(struct usb_audio_state));
INIT_LIST_HEAD(&s->audiolist);
INIT_LIST_HEAD(&s->mixerlist);
@@ -3316,63 +3431,67 @@
s->count = 1;
/* find audiocontrol interface */
if (!(p1 = find_csinterface_descriptor(buffer, buflen, NULL, HEADER, ctrlif, -1))) {
- printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u no HEADER found\n",
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u no HEADER found\n",
dev->devnum, ctrlif);
goto ret;
}
if (p1[0] < 8 + p1[7]) {
- printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u HEADER error\n",
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u HEADER error\n",
dev->devnum, ctrlif);
goto ret;
}
if (!p1[7])
- printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u has no AudioStreaming and MidiStreaming interfaces\n",
+ printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u has no AudioStreaming and MidiStreaming interfaces\n",
dev->devnum, ctrlif);
for (i = 0; i < p1[7]; i++) {
j = p1[8+i];
if (j >= config->bNumInterfaces) {
- printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u does not exist\n",
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u does not exist\n",
dev->devnum, ctrlif, j);
continue;
}
iface = &config->interface[j];
if (iface->altsetting[0].bInterfaceClass != USB_CLASS_AUDIO) {
- printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u is not an AudioClass interface\n",
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u is not an AudioClass interface\n",
dev->devnum, ctrlif, j);
continue;
}
if (iface->altsetting[0].bInterfaceSubClass == 3) {
- printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u interface %u MIDIStreaming not supported\n",
+ printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u interface %u MIDIStreaming not supported\n",
dev->devnum, ctrlif, j);
continue;
}
if (iface->altsetting[0].bInterfaceSubClass != 2) {
- printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u invalid AudioClass subtype\n",
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u invalid AudioClass subtype\n",
dev->devnum, ctrlif, j);
continue;
}
if (iface->num_altsetting < 2 ||
iface->altsetting[0].bNumEndpoints > 0) {
- printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u altsetting 0 not zero bandwidth\n",
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u altsetting 0 not zero bandwidth\n",
dev->devnum, ctrlif);
continue;
}
if (iface->altsetting[1].bNumEndpoints < 1) {
- printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u has no endpoint\n",
+ printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no endpoint\n",
dev->devnum, ctrlif, j);
continue;
}
/* note: this requires the data endpoint to be ep0 and the optional sync
ep to be ep1, which seems to be the case */
if (iface->altsetting[1].endpoint[0].bEndpointAddress & USB_DIR_IN) {
- if (numifin < USB_MAXINTERFACES)
+ if (numifin < USB_MAXINTERFACES) {
ifin[numifin++] = j;
+ usb_driver_claim_interface(&usb_audio_driver, iface, s);
+ }
} else {
- if (numifout < USB_MAXINTERFACES)
+ if (numifout < USB_MAXINTERFACES) {
ifout[numifout++] = j;
+ usb_driver_claim_interface(&usb_audio_driver, iface, s);
+ }
}
}
- printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u has %u input and %u output AudioStreaming interfaces\n",
+ printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u has %u input and %u output AudioStreaming interfaces\n",
dev->devnum, ctrlif, numifin, numifout);
for (i = 0; i < numifin && i < numifout; i++)
usb_audio_parsestreaming(s, buffer, buflen, ifin[i], ifout[i]);
@@ -3391,20 +3510,18 @@
ret:
if (list_empty(&s->audiolist) && list_empty(&s->mixerlist)) {
kfree(s);
- return -1;
+ return NULL;
}
/* everything successful */
- dev->private = s;
down(&open_sem);
list_add_tail(&s->audiodev, &audiodevs);
up(&open_sem);
- MOD_INC_USE_COUNT;
- return 0;
+ return s;
}
/* we only care for the currently active configuration */
-static int usb_audio_probe(struct usb_device *dev)
+static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum)
{
struct usb_config_descriptor *config = dev->actconfig;
unsigned char *buffer;
@@ -3416,40 +3533,36 @@
if (config->interface[i].altsetting[0].bInterfaceClass == USB_CLASS_AUDIO &&
config->interface[i].altsetting[0].bInterfaceSubClass == 1) /* audiocontrol interface found */
goto audioctrlfound;
- printk(KERN_DEBUG "usb_audio: vendor id 0x%04x, product id 0x%04x contains no AudioControl interface\n",
+ printk(KERN_DEBUG "usbaudio: vendor id 0x%04x, product id 0x%04x contains no AudioControl interface\n",
dev->descriptor.idVendor, dev->descriptor.idProduct);
- return -1;
+ return NULL;
audioctrlfound:
/* find which configuration number is active */
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
if (dev->config+i == config)
goto configfound;
- printk(KERN_ERR "usb_audio: cannot find active configuration number of device %d\n", dev->devnum);
- return -1;
+ printk(KERN_ERR "usbaudio: cannot find active configuration number of device %d\n", dev->devnum);
+ return NULL;
configfound:
- if (usb_set_configuration(dev, config->bConfigurationValue) < 0) {
- printk(KERN_ERR "usb_audio: set_configuration failed (ConfigValue 0x%x)\n", config->bConfigurationValue);
- return -1;
- }
ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8);
if (ret) {
- printk(KERN_ERR "usb_audio: cannot get first 8 bytes of config descriptor %d of device %d\n", i, dev->devnum);
- return -1;
+ printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d\n", i, dev->devnum);
+ return NULL;
}
if (buf[1] != USB_DT_CONFIG || buf[0] < 9) {
- printk(KERN_ERR "usb_audio: invalid config descriptor %d of device %d\n", i, dev->devnum);
- return -1;
+ printk(KERN_ERR "usbaudio: invalid config descriptor %d of device %d\n", i, dev->devnum);
+ return NULL;
}
buflen = buf[2] | (buf[3] << 8);
if (!(buffer = kmalloc(buflen, GFP_KERNEL)))
- return -1;
+ return NULL;
ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buffer, buflen);
if (ret) {
kfree(buffer);
- printk(KERN_ERR "usb_audio: cannot get config descriptor %d of device %d\n", i, dev->devnum);
- return -1;
+ printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d\n", i, dev->devnum);
+ return NULL;
}
/* find first audio control interface; we currently cannot handle more than one */
for (i = 0; i < config->bNumInterfaces; i++) {
@@ -3457,18 +3570,17 @@
config->interface[i].altsetting[0].bInterfaceSubClass != 1)
continue;
/* audiocontrol interface found */
- if (!usb_audio_parsecontrol(dev, buffer, buflen, i))
- return 0;
+ return usb_audio_parsecontrol(dev, buffer, buflen, i);
}
- return -1;
+ return NULL;
}
/* a revoke facility would make things simpler */
-static void usb_audio_disconnect(struct usb_device *dev)
+static void usb_audio_disconnect(struct usb_device *dev, void *ptr)
{
- struct usb_audio_state *s = (struct usb_audio_state *)dev->private;
+ struct usb_audio_state *s = (struct usb_audio_state *)ptr;
struct list_head *list;
struct usb_audiodev *as;
struct usb_mixerdev *ms;
@@ -3496,7 +3608,6 @@
#endif
release(s);
wake_up(&open_wait);
- dev->private = NULL;
}
int usb_audio_init(void)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)