#include #include #include static LIST_HEAD(cx878_pci_list); static DEFINE_MUTEX(cx878_pci_list_lock); struct pci_cx878_data { int cx878_counter; int id; struct list_head cx878_list; }; // Pinnacle PCTVSAT, Avermedia AverTV DVB-T 771 and 761, TT 1.6 DVB-S FF, TwinHan DST and clones, all other bt8xx-based DVB cards equally static struct pci_device_id pci_cx878_ids[]={ { 0x109e, 0x036e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, // function 0, video controller (I2C bus) { 0x109e, 0x0878, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, // function 1, audio controller (RISC DMA engine) {} }; static int __devinit pci_cx878_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { struct list_head *list = NULL; struct pci_cx878_data *h = NULL, *dev = NULL; int id; id = (pdev->bus->number<<8) | PCI_SLOT(pdev->devfn); printk("ID: %04x\n",id); mutex_lock(&cx878_pci_list_lock); list_for_each(list, &cx878_pci_list) { h = list_entry(list, struct pci_cx878_data, cx878_list); if (h->id == id) dev=h; } if (h != NULL) { dev->cx878_counter++; printk("found cx878 list (ID: %04x)! : %d\n",dev->id,dev->cx878_counter); } else { h=kmalloc(sizeof(struct pci_cx878_data), GFP_KERNEL); h->cx878_counter=5; h->id=id; list_add_tail(&h->cx878_list, &cx878_pci_list); printk("no list available initializing new one (id: %04x): %d\n",h->id, h->cx878_counter); } mutex_unlock(&cx878_pci_list_lock); return 0; } static struct pci_driver driver = { .name = "cx878", .id_table = pci_cx878_ids, .probe = pci_cx878_probe, }; static int __init pci_driver_init(void) { printk("=============== LOADING MODULE ===============\n"); return pci_register_driver(&driver); } static void __exit pci_driver_exit(void) { pci_unregister_driver(&driver); } module_init(pci_driver_init); module_exit(pci_driver_exit);