#include #include #include #include #include int rtl8139_maj=-1, rtl8139_min=0; // RX and TX descriptor structures typedef struct rtl8139_dev_s { unsigned addr, inter; struct pci_device *device; struct inode *node; struct rtl8139_dev_s *next, *prev; } rtl8139dev_t; volatile rtl8139dev_t *cards; rtl8139dev_t *create_new_device(unsigned addr, struct pci_device *device) { rtl8139dev_t *d = (rtl8139dev_t *)kmalloc(sizeof(rtl8139dev_t)); d->addr = addr; d->device = device; rtl8139dev_t *t = (rtl8139dev_t *)cards; cards = d; d->next = t; if(t) t->prev=d; return d; } void delete_device(rtl8139dev_t *d) { if(d->prev) d->prev->next = d->next; if(d->next) d->next->prev = d->prev; if(d == cards) cards = d->next; kfree(d); } int rtl8139_init(rtl8139dev_t *dev) { return 0; } int rtl8139_int(registers_t *regs) { return 0; } int rtl8139_load_device_pci(struct pci_device *device) { int addr; char ret=0; if(!(addr = pci_get_base_address(device))) { device->flags |= PCI_ERROR; return 1; } rtl8139dev_t *dev = create_new_device(addr, device); printk(1, "[rtl8139]: Initiating rtl8139 controller (%x.%x.%x)...\n", device->bus, device->dev, device->func); if(rtl8139_init(dev)) ret++; if(ret){ printk(1, "[rtl8139]: Device error when trying to initialize\n"); device->flags |= PCI_ERROR; return -1; } struct inode *i = dfs_cn("rtl8139", S_IFCHR, rtl8139_maj, rtl8139_min++); dev->node = i; printk(1, "[rtl8139]: Success!\n"); device->flags |= PCI_ENGAGED; device->flags |= PCI_DRIVEN; dev->inter = device->pcs->interrupt_line; register_interrupt_handler(dev->inter, (isr_t)&rtl8139_int); return 0; } int rtl8139_unload_device_pci(rtl8139dev_t *dev) { if(!dev) return 0; struct pci_device *device = dev->device; printk(1, "[rtl8139]: Unloading device (%x.%x.%x)\n", device->bus, device->dev, device->func); device->flags &= ~PCI_ENGAGED; device->flags &= ~PCI_DRIVEN; iremove_force(dev->node); unregister_interrupt_handler(dev->inter, (isr_t)&rtl8139_int); delete_device(dev); return 0; } int rtl8139_rw_main(int rw, int min, char *buf, int count) { return 0; } int ioctl_rtl8139(int min, int cmd, int arg) { return 0; } int module_install() { rtl8139_min=0; cards=0; rtl8139_maj = set_availablecd(rtl8139_rw_main, ioctl_rtl8139); int i=0; printk(1, "[rtl8139]: Scanning PCI bus...\n"); while(1) { struct pci_device *dev = pci_locate_devices(0x10ec, 0x8139, i); if(!dev) break; rtl8139_load_device_pci(dev); i++; } return 0; } int module_deps(char *b) { write_deps(b, "pci,ethernet,:"); return CONFIG_VERSION_NUMBER; } int module_exit() { printk(1, "[rtl8139]: Shutting down all cards...\n"); while(cards) /* this call updates 'cards' within it. */ rtl8139_unload_device_pci((rtl8139dev_t *)cards); unregister_char_device(rtl8139_maj); return 0; }