一个UAC设备插入到Ubuntu 14.04电脑上dmesg中打印的信息如下:
[ 2367.490491] usb 3-3.2: new full-speed USB device number 9 using xhci_hcd
[ 2367.580010] usb 3-3.2: New USB device found, idVendor=0d8c, idProduct=0132
[ 2367.580018] usb 3-3.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2367.580023] usb 3-3.2: Product: USB PnP Audio Device
[ 2367.580027] usb 3-3.2: Manufacturer: C-Media Electronics Inc.
[ 2367.581679] input: C-Media Electronics Inc. USB PnP Audio Device as /devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.2/3-3.2:1.2/0003:0D8C:0132.0004/input/input18
[ 2367.581999] hid-generic 0003:0D8C:0132.0004: input,hidraw3: USB HID v1.11 Device [C-Media Electronics Inc. USB PnP Audio Device] on usb-0000:00:14.0-3.2/input2
[ 2367.913280] usbcore: registered new interface driver snd-usb-audio
这里可以看到其驱动程序为snd-usb-audio,依据这个关键词在内核中查找到如下内容:
tony@tony-E431:~/linux-3.4.y$grep "registered new interface driver" ./ -rn
Binary file ./vmlinux.o matches
Binary file ./.tmp_vmlinux1 matches
Binary file ./.tmp_vmlinux2 matches
Binary file ./drivers/built-in.o matches
Binary file ./drivers/usb/built-in.o matches
Binary file ./drivers/usb/core/built-in.o matches
./drivers/usb/core/driver.c:865: pr_info("%s: registered new interface driver %s\n",
Binary file ./drivers/usb/core/driver.o matches
Binary file ./drivers/usb/core/usbcore.o matches
Binary file ./arch/arm/boot/Image matches
Binary file ./vmlinux matches
tony@tony-E431:~/linux-3.4.y$
以及
// file: linux-3.4.y/sound/usb/card.c
/* * entry point for linux usb interface */
static struct usb_driver usb_audio_driver = {
.name = "snd-usb-audio",
.probe = usb_audio_probe,
.disconnect = usb_audio_disconnect,
.suspend = usb_audio_suspend,
.resume = usb_audio_resume,
.id_table = usb_audio_ids,
.supports_autosuspend = 1,
};
根据probe方法snd_usb_audio_probe调用了snd_usb_apply_boot_quirk和snd_card_register,查到了
// linux-3.4.y/sound/usb/card.c
/* * new 2.5 USB kernel API */
static int usb_audio_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct snd_usb_audio *chip;
chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
if (chip) {
usb_set_intfdata(intf, chip);
return 0;
} else
return -EIO;
}
// linux-3.4.y/sound/usb/quirks.c
int snd_usb_apply_boot_quirk(struct usb_device *dev,
struct usb_interface *intf,
const struct snd_usb_audio_quirk *quirk)
{
u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
switch (id) {
case USB_ID(0x041e, 0x3000):
/* SB Extigy needs special boot-up sequence */
/* if more models come, this will go to the quirk list. */
return snd_usb_extigy_boot_quirk(dev, intf);
case USB_ID(0x041e, 0x3020):
/* SB Audigy 2 NX needs its own boot-up magic, too */
return snd_usb_audigy2nx_boot_quirk(dev);
case USB_ID(0x10f5, 0x0200):
/* C-Media CM106 / Turt