Jay Miller wrote:
Thanks Ty, that's exactly what we're looking for. The de-allocation wouldn't be an issue as we would be re-programming on the reboot anyway.
Did you use the proc_pci_attach_device() mechanism?
Cheers,
Jay Miller 781-229-7812x117 Actuality Systems, Inc. jmiller@actuality-systems.com
-----Original Message----- From: tyson@irobot.com [mailto:tyson@irobot.com] Sent: Wednesday, October 06, 2004 1:52 PM To: Jay Miller Cc: Ronald G. Minnich; YhLu; linuxbios@clustermatic.org Subject: Re: Adding a PCI device that doesn't exist (yet)
Hopping in mid-thread here so I may have the context wrong:
I have succeeded at programming the FPGA to create a PCI device after the boot process. I was then able to have the device driver add the device to the pci device table and get resources allocated for it and get it paired up with the alread loaded device driver.
I did not figure out how to de-allocate/de-register such that I could cleanely re-program the FPGA without a re-boot.
Is this relevant?
Cheers! Ty
It is only a specific variation of this device that needed this code so it is hacked in by conditionally including the header file below into a .c file. Crufty code organization, but now you know.
This was made to work by having user level initialization scripts program the FPGA before loading the device driver. The first thing that the device driver did in its init function was call the function below. This is working code as it sits. The things like "PCI_VENDOR_ID_IROBOT" are our own local hacks and defines. Things like "list_for_each_safe() come from the kernel headers. I think that <linux/pci.h> was all I needed for this part of the code but it might be dependent on others as well.
I'd be happy to attempt to answer specific questions, but I think everything needed is here. I figured this out thought a lot of grepping and "use the source Luke!".
Cheers! Ty
=================================================================== /* * neolink2.h */
#define PCI_FNBUS 0 #define PCI_FNSLOT 16 #define PCI_FNFUNC 0
static int __init neolink2_init(void) { struct list_head *list, *list_tmp; struct pci_bus *bus; struct pci_dev dev, *dev1;
if (pci_find_device(PCI_VENDOR_ID_IROBOT, PCI_DEVICE_ID_IROBOT_FN2A, NULL)) { printk("%6d:%s:%s() - Device is already initialized\n", __LINE__, __FILE__, __FUNCTION__); return 0; }
list_for_each_safe(list, list_tmp, &pci_root_buses) { bus = pci_bus_b(list); if (bus->number == PCI_FNBUS) { memset(&dev, 0, sizeof(dev)); dev.bus = bus; dev.sysdata = bus->sysdata; dev.devfn = PCI_DEVFN(PCI_FNSLOT, PCI_FNFUNC); dev1 = pci_scan_slot(&dev); if (!dev1) { printk("%6d:%s:%s() - No device found\n", __LINE__, __FILE__, __FUNCTION__); return -ENODEV; } else { printk("%6d:%s:%s() - Found device %s\n", __LINE__, __FILE__, __FUNCTION__, dev1->name);
pci_set_power_state(dev1, 0); pci_assign_resource(dev1, 0); pci_enable_device(dev1); // pci_announce_device_to_drivers(dev1); return 0; } break; } }
printk("%6d:%s:%s() - Bus %d found\n", __LINE__, __FILE__, __FUNCTION__, PCI_FNBUS);
return -ENODEV; } =====================================================================