/* * lostirq.c * Copyright (C) 2000 Media Lab. Inc. * * Sometimes, BIOS does not set IRQ route for devices like USB. * This driver can change irq for PCI devices. * Usage: insmod lostirq pcidev=bus,device,func irq=dd * You can confirm this assigned irq using "lspci -v" command. * * v0.1 Feb. 15 JST 2000 Media Lab. Inc. */ #define MODULE #define __KERNEL__ #include #include #include static int pcidev[3] = {-1,-1,-1 }; static int irq=-1; MODULE_PARM(pcidev, "1-" __MODULE_STRING(3) "i"); MODULE_PARM(irq, "i"); int init_module(void) { int pci_index = 0; /* struct pci_dev *dev = pci_devices; */ struct pci_dev *dev; unsigned char pci_bus, pci_device_fn; int devfn = (pcidev[1] << 3) + pcidev[2]; int bus = pcidev[0]; if (pcidev[0] == -1 || pcidev[1] == -1 || pcidev[2] == -1 || irq == -1) { printk(KERN_ERR "lostirq: need args pcidev=bus,dev,func irq=dd\n"); return 1; } /* printk("lostirq: start bus=%x devfn=%x irq=%d\n",bus,devfn,irq); */ for(dev = pci_dev_g(pci_devices.next); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.next)) { /* printk("index:%d vendor:%x device:%x devfn:%x irq:%d\n", pci_index,dev->vendor,dev->device,dev->devfn,dev->irq); */ if (bus == dev->bus->number && devfn == dev->devfn) { printk("lostirq: found device bus=%x device=%x func=%x set irq=%d\n", bus,devfn>>3,devfn&0x7,irq); dev->irq = irq; pci_write_config_byte( dev , PCI_INTERRUPT_LINE , irq ); } } return(0); } void cleanup_module(void) { printk("lostirq: end\n"); }