Re: Multi-function PCI devices

Jeff Garzik
2001-04-07T17:47:37Z

Tim Waugh wrote:
>
> On Sat, Apr 07, 2001 at 01:33:25PM +0200, Michael Reinelt wrote:
>
> > Adding PCI entries to both serial.c and parport_pc.c was that easy....
>
> And that's how it should be, IMHO. There needs to be provision for
> more than one driver to be able to talk to any given PCI device.

No, because that gets really ugly. You have to create a shim driver
which allocates resources, and registers subsystems. Only a single PCI
driver like this know best how to locate and allocate resources. You
can wish to hack such into the serial or parallel driver's PCI probe id
lists, but that won't work for this case, and trying to do it any other
way looks suspiciously like a hack :)

You asked in your last message to show you code, here is a short
example. Note that I would love to rip out the SUPERIO code in parport
and make it a separate driver like this short, contrived example. Much
more modular than the existing solution.

static int __devinit foo_init_one (...)
{
u32 tmp;
int rc;
struct serial_port serial;
struct parport parport;

pci_read_config_byte(pdev, 0x40, &tmp);
serial.irq = tmp & 0xFF;
pci_read_config_word(pdev, 0x42, &tmp);
serial.port = tmp & 0xFFFF;

rc = register_serial(&serial);
if (rc < 0)
return rc;

pci_read_config_byte(pdev, 0x40, &tmp);
parport.irq = tmp & 0xFF;
pci_read_config_word(pdev, 0x42, &tmp);
parport.port = tmp & 0xFFFF;

rc = register_parport(&parport);
if (rc < 0)
return rc;

return 0;
}
static void __init foo_init(void) {
return pci_module_init(&foo_driver);
}
static void __exit foo_exit(void) {
pci_unregister_driver(&foo_driver);
}
module_init(foo_init);
module_exit(foo_exit);

--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."