ChangeSet 1.837.4.1, 2002/12/05 23:31:21-06:00, ambx1@neo.rr.com [PATCH] Linux PnP Support V0.93 - 2.5.50 Attached is a patch, that updates the 2.5.50 to the latest pnp version. It includes all 9 of the previously submitted patches. Highlights are as follows: -PnP BIOS fixes -Several new macros -PnP Card Services -Various bug fixes -more drivers converted to the new APIs diff -Nru a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c --- a/drivers/input/gameport/ns558.c Fri Dec 6 10:38:41 2002 +++ b/drivers/input/gameport/ns558.c Fri Dec 6 10:38:41 2002 @@ -37,7 +37,7 @@ #include #include #include -#include +#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Classic gameport (ISA/PnP) driver"); @@ -52,7 +52,7 @@ struct ns558 { int type; int size; - struct pci_dev *dev; + struct pnp_dev *dev; struct list_head node; struct gameport gameport; char phys[32]; @@ -159,67 +159,55 @@ list_add(&port->node, &ns558_list); } -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP -#define NS558_DEVICE(a,b,c,d)\ - .card_vendor = ISAPNP_ANY_ID, card_device: ISAPNP_ANY_ID,\ - .vendor = ISAPNP_VENDOR(a,b,c), function: ISAPNP_DEVICE(d) - -static struct isapnp_device_id pnp_devids[] = { - { NS558_DEVICE('@','P','@',0x0001) }, /* ALS 100 */ - { NS558_DEVICE('@','P','@',0x0020) }, /* ALS 200 */ - { NS558_DEVICE('@','P','@',0x1001) }, /* ALS 100+ */ - { NS558_DEVICE('@','P','@',0x2001) }, /* ALS 120 */ - { NS558_DEVICE('A','S','B',0x16fd) }, /* AdLib NSC16 */ - { NS558_DEVICE('A','Z','T',0x3001) }, /* AZT1008 */ - { NS558_DEVICE('C','D','C',0x0001) }, /* Opl3-SAx */ - { NS558_DEVICE('C','S','C',0x0001) }, /* CS4232 */ - { NS558_DEVICE('C','S','C',0x000f) }, /* CS4236 */ - { NS558_DEVICE('C','S','C',0x0101) }, /* CS4327 */ - { NS558_DEVICE('C','T','L',0x7001) }, /* SB16 */ - { NS558_DEVICE('C','T','L',0x7002) }, /* AWE64 */ - { NS558_DEVICE('C','T','L',0x7005) }, /* Vibra16 */ - { NS558_DEVICE('E','N','S',0x2020) }, /* SoundscapeVIVO */ - { NS558_DEVICE('E','S','S',0x0001) }, /* ES1869 */ - { NS558_DEVICE('E','S','S',0x0005) }, /* ES1878 */ - { NS558_DEVICE('E','S','S',0x6880) }, /* ES688 */ - { NS558_DEVICE('I','B','M',0x0012) }, /* CS4232 */ - { NS558_DEVICE('O','P','T',0x0001) }, /* OPTi Audio16 */ - { NS558_DEVICE('Y','M','H',0x0006) }, /* Opl3-SA */ - { NS558_DEVICE('Y','M','H',0x0022) }, /* Opl3-SAx */ - { NS558_DEVICE('P','N','P',0xb02f) }, /* Generic */ - { 0, }, +static struct pnp_id pnp_devids[] = { + { .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */ + { .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */ + { .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */ + { .id = "@P@2001", .driver_data = 0 }, /* ALS 120 */ + { .id = "ASB16fd", .driver_data = 0 }, /* AdLib NSC16 */ + { .id = "AZT3001", .driver_data = 0 }, /* AZT1008 */ + { .id = "CDC0001", .driver_data = 0 }, /* Opl3-SAx */ + { .id = "CSC0001", .driver_data = 0 }, /* CS4232 */ + { .id = "CSC000f", .driver_data = 0 }, /* CS4236 */ + { .id = "CSC0101", .driver_data = 0 }, /* CS4327 */ + { .id = "CTL7001", .driver_data = 0 }, /* SB16 */ + { .id = "CTL7002", .driver_data = 0 }, /* AWE64 */ + { .id = "CTL7005", .driver_data = 0 }, /* Vibra16 */ + { .id = "ENS2020", .driver_data = 0 }, /* SoundscapeVIVO */ + { .id = "ESS0001", .driver_data = 0 }, /* ES1869 */ + { .id = "ESS0005", .driver_data = 0 }, /* ES1878 */ + { .id = "ESS6880", .driver_data = 0 }, /* ES688 */ + { .id = "IBM0012", .driver_data = 0 }, /* CS4232 */ + { .id = "OPT0001", .driver_data = 0 }, /* OPTi Audio16 */ + { .id = "YMH0006", .driver_data = 0 }, /* Opl3-SA */ + { .id = "YMH0022", .driver_data = 0 }, /* Opl3-SAx */ + { .id = "PNPb02f", .driver_data = 0 }, /* Generic */ + { .id = "", }, }; -MODULE_DEVICE_TABLE(isapnp, pnp_devids); +MODULE_DEVICE_TABLE(pnp, pnp_devids); -static void ns558_pnp_probe(struct pci_dev *dev) +static int ns558_pnp_probe(struct pnp_dev *dev, const struct pnp_id *cid, const struct pnp_id *did) { int ioport, iolen; struct ns558 *port; - if (dev->prepare && dev->prepare(dev) < 0) - return; - if (!(dev->resource[0].flags & IORESOURCE_IO)) { printk(KERN_WARNING "ns558: No i/o ports on a gameport? Weird\n"); - return; + return -ENODEV; } - if (dev->activate && dev->activate(dev) < 0) { - printk(KERN_ERR "ns558: PnP resource allocation failed\n"); - return; - } - - ioport = pci_resource_start(dev, 0); - iolen = pci_resource_len(dev, 0); + ioport = pnp_port_start(dev,0); + iolen = pnp_port_len(dev,0); if (!request_region(ioport, iolen, "ns558-pnp")) - goto deactivate; + return -EBUSY; if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) { printk(KERN_ERR "ns558: Memory allocation failed.\n"); - goto deactivate; + return -ENOMEM; } memset(port, 0, sizeof(struct ns558)); @@ -231,54 +219,46 @@ port->gameport.phys = port->phys; port->gameport.name = port->name; port->gameport.id.bustype = BUS_ISAPNP; - port->gameport.id.vendor = dev->vendor; - port->gameport.id.product = dev->device; port->gameport.id.version = 0x100; - sprintf(port->phys, "isapnp%d.%d/gameport0", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + sprintf(port->phys, "pnp%s/gameport0", dev->dev.bus_id); sprintf(port->name, "%s", dev->dev.name[0] ? dev->dev.name : "NS558 PnP Gameport"); gameport_register_port(&port->gameport); - printk(KERN_INFO "gameport: NS558 PnP at isapnp%d.%d io %#x", - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), port->gameport.io); + printk(KERN_INFO "gameport: NS558 PnP at pnp%s io %#x", + dev->dev.bus_id, port->gameport.io); if (iolen > 1) printk(" size %d", iolen); printk(" speed %d kHz\n", port->gameport.speed); list_add_tail(&port->node, &ns558_list); - return; - -deactivate: - if (dev->deactivate) - dev->deactivate(dev); + return 0; } + +static struct pnp_driver ns558_pnp_driver = { + .name = "ns558", + .id_table = pnp_devids, + .probe = ns558_pnp_probe, +}; + +#else + +static const struct pnp_driver ns558_pnp_driver; + #endif int __init ns558_init(void) { int i = 0; -#ifdef __ISAPNP__ - struct isapnp_device_id *devid; - struct pci_dev *dev = NULL; -#endif /* * Probe for ISA ports. */ - while (ns558_isa_portlist[i]) + while (ns558_isa_portlist[i]) ns558_isa_probe(ns558_isa_portlist[i++]); -/* - * Probe for PnP ports. - */ - -#ifdef __ISAPNP__ - for (devid = pnp_devids; devid->vendor; devid++) - while ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, dev))) - ns558_pnp_probe(dev); -#endif - + pnp_register_driver(&ns558_pnp_driver); return list_empty(&ns558_list) ? -ENODEV : 0; } @@ -290,13 +270,10 @@ gameport_unregister_port(&port->gameport); switch (port->type) { -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP case NS558_PNP: - if (port->dev->deactivate) - port->dev->deactivate(port->dev); /* fall through */ #endif - case NS558_ISA: release_region(port->gameport.io, port->size); break; @@ -305,6 +282,7 @@ break; } } + pnp_unregister_driver(&ns558_pnp_driver); } module_init(ns558_init); diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c --- a/drivers/net/e100/e100_main.c Fri Dec 6 10:38:41 2002 +++ b/drivers/net/e100/e100_main.c Fri Dec 6 10:38:41 2002 @@ -87,8 +87,8 @@ extern int e100_create_proc_subdir(struct e100_private *, char *); extern void e100_remove_proc_subdir(struct e100_private *, char *); #else -#define e100_create_proc_subdir(X) 0 -#define e100_remove_proc_subdir(X) do {} while(0) +#define e100_create_proc_subdir(X, Y) 0 +#define e100_remove_proc_subdir(X, Y) do {} while(0) #endif static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *); diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c --- a/drivers/parport/parport_pc.c Fri Dec 6 10:38:41 2002 +++ b/drivers/parport/parport_pc.c Fri Dec 6 10:38:41 2002 @@ -2973,7 +2973,7 @@ #endif /* CONFIG_PCI */ #ifdef CONFIG_PNP -static const struct pnp_id pnp_dev_table[] = { +static const struct pnp_device_id pnp_dev_table[] = { /* Standard LPT Printer Port */ {.id = "PNP0400", .driver_data = 0}, /* ECP Printer Port */ @@ -2984,7 +2984,6 @@ /* we only need the pnp layer to activate the device, at least for now */ static struct pnp_driver parport_pc_pnp_driver = { .name = "parport_pc", - .card_id_table = NULL, .id_table = pnp_dev_table, }; #else diff -Nru a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig --- a/drivers/pnp/Kconfig Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/Kconfig Fri Dec 6 10:38:41 2002 @@ -2,7 +2,7 @@ # Plug and Play configuration # -menu "Plug and Play configuration" +menu "Plug and Play support" config PNP bool "Plug and Play support" @@ -30,11 +30,20 @@ If unsure, say Y. +config PNP_CARD + bool "Plug and Play card services" + depends on PNP + help + Select Y if you want the PnP Layer to manage cards. Cards are groups + of PnP devices. Some drivers, especially PnP sound card drivers, use + these cards. If you want to use the protocol ISAPNP you will need to + say Y here. + config PNP_DEBUG bool "PnP Debug Messages" depends on PNP help - Say Y if you want the Plug and Play Layer to print debug messages. + Say Y if you want the Plug and Play Layer to print debug messages. This is useful if you are developing a PnP driver or troubleshooting. comment "Protocols" @@ -42,7 +51,7 @@ config ISAPNP bool "ISA Plug and Play support (EXPERIMENTAL)" - depends on PNP && EXPERIMENTAL + depends on PNP && EXPERIMENTAL && PNP_CARD help Say Y here if you would like support for ISA Plug and Play devices. Some information is in . diff -Nru a/drivers/pnp/Makefile b/drivers/pnp/Makefile --- a/drivers/pnp/Makefile Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/Makefile Fri Dec 6 10:38:41 2002 @@ -2,11 +2,13 @@ # Makefile for the Linux Plug-and-Play Support. # -obj-y := core.o driver.o resource.o interface.o quirks.o names.o system.o +pnp-card-$(CONFIG_PNP_CARD) = card.o + +obj-y := core.o driver.o resource.o interface.o quirks.o names.o system.o $(pnp-card-y) obj-$(CONFIG_PNPBIOS) += pnpbios/ obj-$(CONFIG_ISAPNP) += isapnp/ -export-objs := core.o driver.o resource.o +export-objs := core.o driver.o resource.o $(pnp-card-y) include $(TOPDIR)/Rules.make diff -Nru a/drivers/pnp/base.h b/drivers/pnp/base.h --- a/drivers/pnp/base.h Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/base.h Fri Dec 6 10:38:41 2002 @@ -4,5 +4,6 @@ extern int pnp_interface_attach_device(struct pnp_dev *dev); extern void pnp_name_device(struct pnp_dev *dev); extern void pnp_fixup_device(struct pnp_dev *dev); -extern void pnp_free_ids(struct pnp_dev *dev); extern void pnp_free_resources(struct pnp_resources *resources); +extern int __pnp_add_device(struct pnp_dev *dev); +extern void __pnp_remove_device(struct pnp_dev *dev); diff -Nru a/drivers/pnp/card.c b/drivers/pnp/card.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/pnp/card.c Fri Dec 6 10:38:41 2002 @@ -0,0 +1,342 @@ +/* + * card.c - contains functions for managing groups of PnP devices + * + * Copyright 2002 Adam Belay + * + */ + +#include +#include +#include + +#ifdef CONFIG_PNP_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif + +#include +#include +#include "base.h" + + +LIST_HEAD(pnp_cards); + +static const struct pnp_card_id * match_card(struct pnpc_driver *drv, struct pnp_card *card) +{ + const struct pnp_card_id *drv_id = drv->id_table; + while (*drv_id->id){ + if (compare_pnp_id(card->id,drv_id->id)) + return drv_id; + drv_id++; + } + return NULL; +} + +static int card_bus_match(struct device *dev, struct device_driver *drv) +{ + struct pnp_card * card = to_pnp_card(dev); + struct pnpc_driver * pnp_drv = to_pnpc_driver(drv); + if (match_card(pnp_drv, card) == NULL) + return 0; + return 1; +} + +struct bus_type pnpc_bus_type = { + name: "pnp_card", + match: card_bus_match, +}; + + +/** + * pnpc_add_id - adds an EISA id to the specified card + * @id: pointer to a pnp_id structure + * @card: pointer to the desired card + * + */ + +int pnpc_add_id(struct pnp_id *id, struct pnp_card *card) +{ + struct pnp_id *ptr; + if (!id) + return -EINVAL; + if (!card) + return -EINVAL; + ptr = card->id; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = id; + else + card->id = id; + return 0; +} + +static void pnpc_free_ids(struct pnp_card *card) +{ + struct pnp_id * id; + struct pnp_id *next; + if (!card) + return; + id = card->id; + while (id) { + next = id->next; + kfree(id); + id = next; + } +} + +static void pnp_release_card(struct device *dmdev) +{ + struct pnp_card * card = to_pnp_card(dmdev); + pnpc_free_ids(card); + kfree(card); +} + +/** + * pnpc_add_card - adds a PnP card to the PnP Layer + * @card: pointer to the card to add + */ + +int pnpc_add_card(struct pnp_card *card) +{ + int error = 0; + if (!card || !card->protocol) + return -EINVAL; + sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number, card->number); + INIT_LIST_HEAD(&card->rdevs); + strcpy(card->dev.name,card->name); + card->dev.parent = &card->protocol->dev; + card->dev.bus = &pnpc_bus_type; + card->dev.release = &pnp_release_card; + error = device_register(&card->dev); + if (error == 0){ + struct list_head *pos; + spin_lock(&pnp_lock); + list_add_tail(&card->global_list, &pnp_cards); + list_add_tail(&card->protocol_list, &card->protocol->cards); + spin_unlock(&pnp_lock); + list_for_each(pos,&card->devices){ + struct pnp_dev *dev = card_to_pnp_dev(pos); + __pnp_add_device(dev); + } + } + return error; +} + +/** + * pnpc_remove_card - removes a PnP card from the PnP Layer + * @card: pointer to the card to remove + */ + +void pnpc_remove_card(struct pnp_card *card) +{ + struct list_head *pos; + if (!card) + return; + device_unregister(&card->dev); + spin_lock(&pnp_lock); + list_del_init(&card->global_list); + list_del_init(&card->protocol_list); + spin_unlock(&pnp_lock); + list_for_each(pos,&card->devices){ + struct pnp_dev *dev = card_to_pnp_dev(pos); + __pnp_remove_device(dev); + } +} + +/** + * pnpc_add_device - adds a device to the specified card + * @card: pointer to the card to add to + * @dev: pointer to the device to add + */ + +int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev) +{ + if (!dev || !dev->protocol || !card) + return -EINVAL; + dev->dev.parent = &card->dev; + sprintf(dev->dev.bus_id, "%02x:%02x.%02x", dev->protocol->number, card->number,dev->number); + spin_lock(&pnp_lock); + dev->card = card; + list_add_tail(&dev->card_list, &card->devices); + spin_unlock(&pnp_lock); + return 0; +} + +/** + * pnpc_remove_device- removes a device from the specified card + * @card: pointer to the card to remove from + * @dev: pointer to the device to remove + */ + +void pnpc_remove_device(struct pnp_dev *dev) +{ + spin_lock(&pnp_lock); + dev->card = NULL; + list_del_init(&dev->card_list); + spin_unlock(&pnp_lock); + __pnp_remove_device(dev); +} + +/** + * pnp_request_card_device - Searches for a PnP device under the specified card + * @card: pointer to the card to search under, cannot be NULL + * @id: pointer to a PnP ID structure that explains the rules for finding the device + * @from: Starting place to search from. If NULL it will start from the begining. + * + * Will activate the device + */ + +struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from) +{ + struct list_head *pos; + struct pnp_dev *dev; + if (!card || !id) + goto done; + if (!from) { + pos = card->devices.next; + } else { + if (from->card != card) + goto done; + pos = from->card_list.next; + } + while (pos != &card->devices) { + dev = card_to_pnp_dev(pos); + if (compare_pnp_id(dev->id,id)) + goto found; + pos = pos->next; + } + +done: + return NULL; + +found: + if (dev->active == 0) + if(pnp_activate_dev(dev)<0) + return NULL; + spin_lock(&pnp_lock); + list_add_tail(&dev->rdev_list, &card->rdevs); + spin_unlock(&pnp_lock); + return dev; +} + +/** + * pnp_release_card_device - call this when the driver no longer needs the device + * @dev: pointer to the PnP device stucture + * + * Will disable the device + */ + +void pnp_release_card_device(struct pnp_dev *dev) +{ + spin_lock(&pnp_lock); + list_del_init(&dev->rdev_list); + spin_unlock(&pnp_lock); + pnp_disable_dev(dev); +} + +static void pnpc_recover_devices(struct pnp_card *card) +{ + struct list_head *pos; + list_for_each(pos,&card->rdevs){ + struct pnp_dev *dev = list_entry(pos, struct pnp_dev, rdev_list); + pnp_release_card_device(dev); + } +} + +static int pnpc_card_probe(struct device *dev) +{ + int error = 0; + struct pnpc_driver *drv = to_pnpc_driver(dev->driver); + struct pnp_card *card = to_pnp_card(dev); + const struct pnp_card_id *card_id = NULL; + + pnp_dbg("pnp: match found with the PnP card '%s' and the driver '%s'", dev->bus_id,drv->name); + + if (drv->probe) { + card_id = match_card(drv, card); + if (card_id != NULL) + error = drv->probe(card, card_id); + if (error >= 0){ + card->driver = drv; + error = 0; + } else + pnpc_recover_devices(card); + } + return error; +} + +static int pnpc_card_remove(struct device *dev) +{ + struct pnp_card * card = to_pnp_card(dev); + struct pnpc_driver * drv = card->driver; + + if (drv) { + if (drv->remove) + drv->remove(card); + card->driver = NULL; + } + pnpc_recover_devices(card); + return 0; +} + +/** + * pnpc_register_driver - registers a PnP card driver with the PnP Layer + * @cdrv: pointer to the driver to register + */ + +int pnpc_register_driver(struct pnpc_driver * drv) +{ + int count; + struct list_head *pos; + + drv->driver.name = drv->name; + drv->driver.bus = &pnpc_bus_type; + drv->driver.probe = pnpc_card_probe; + drv->driver.remove = pnpc_card_remove; + + pnp_dbg("the card driver '%s' has been registered", drv->name); + + count = driver_register(&drv->driver); + + /* get the number of initial matches */ + if (count >= 0){ + count = 0; + list_for_each(pos,&drv->driver.devices){ + count++; + } + } + return count; +} + +/** + * pnpc_unregister_driver - unregisters a PnP card driver from the PnP Layer + * @cdrv: pointer to the driver to unregister + * + * Automatically disables requested devices + */ + +void pnpc_unregister_driver(struct pnpc_driver *drv) +{ + driver_unregister(&drv->driver); + pnp_dbg("the card driver '%s' has been unregistered", drv->name); +} + +static int __init pnp_card_init(void) +{ + printk(KERN_INFO "pnp: Enabling Plug and Play Card Services.\n"); + return bus_register(&pnpc_bus_type); +} + +subsys_initcall(pnp_card_init); + +EXPORT_SYMBOL(pnpc_add_card); +EXPORT_SYMBOL(pnpc_remove_card); +EXPORT_SYMBOL(pnpc_add_device); +EXPORT_SYMBOL(pnpc_remove_device); +EXPORT_SYMBOL(pnp_request_card_device); +EXPORT_SYMBOL(pnp_release_card_device); +EXPORT_SYMBOL(pnpc_register_driver); +EXPORT_SYMBOL(pnpc_unregister_driver); +EXPORT_SYMBOL(pnpc_add_id); diff -Nru a/drivers/pnp/core.c b/drivers/pnp/core.c --- a/drivers/pnp/core.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/core.c Fri Dec 6 10:38:41 2002 @@ -13,6 +13,7 @@ #include #include #include +#include #include "base.h" @@ -41,7 +42,7 @@ * Ex protocols: ISAPNP, PNPBIOS, etc */ -int pnp_protocol_register(struct pnp_protocol *protocol) +int pnp_register_protocol(struct pnp_protocol *protocol) { int nodenum; struct list_head * pos; @@ -50,6 +51,7 @@ return -EINVAL; INIT_LIST_HEAD(&protocol->devices); + INIT_LIST_HEAD(&protocol->cards); nodenum = 0; spin_lock(&pnp_lock); @@ -76,7 +78,7 @@ * @protocol: pointer to the corresponding pnp_protocol structure * */ -void pnp_protocol_unregister(struct pnp_protocol *protocol) +void pnp_unregister_protocol(struct pnp_protocol *protocol) { spin_lock(&pnp_lock); list_del_init(&protocol->protocol_list); @@ -84,17 +86,19 @@ device_unregister(&protocol->dev); } -/** - * pnp_init_device - pnp protocols should call this before adding a PnP device - * @dev: pointer to dev to init - * - * for now it only inits dev->ids, more later? - */ -int pnp_init_device(struct pnp_dev *dev) +static void pnp_free_ids(struct pnp_dev *dev) { - INIT_LIST_HEAD(&dev->ids); - return 0; + struct pnp_id * id; + struct pnp_id * next; + if (!dev) + return; + id = dev->id; + while (id) { + next = id->next; + kfree(id); + id = next; + } } static void pnp_release_device(struct device *dmdev) @@ -106,68 +110,73 @@ kfree(dev); } -/** - * pnp_add_device - adds a pnp device to the pnp layer - * @dev: pointer to dev to add - * - * adds to driver model, name database, fixups, interface, etc. - */ - -int pnp_add_device(struct pnp_dev *dev) +int __pnp_add_device(struct pnp_dev *dev) { int error = 0; - if (!dev || !dev->protocol) - return -EINVAL; - if (dev->card) - sprintf(dev->dev.bus_id, "%02x:%02x.%02x", dev->protocol->number, - dev->card->number,dev->number); - else - sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number, - dev->number); pnp_name_device(dev); pnp_fixup_device(dev); strcpy(dev->dev.name,dev->name); - dev->dev.parent = &dev->protocol->dev; dev->dev.bus = &pnp_bus_type; dev->dev.release = &pnp_release_device; error = device_register(&dev->dev); if (error == 0){ spin_lock(&pnp_lock); list_add_tail(&dev->global_list, &pnp_global); - list_add_tail(&dev->dev_list, &dev->protocol->devices); + list_add_tail(&dev->protocol_list, &dev->protocol->devices); spin_unlock(&pnp_lock); pnp_interface_attach_device(dev); } return error; } +/* + * pnp_add_device - adds a pnp device to the pnp layer + * @dev: pointer to dev to add + * + * adds to driver model, name database, fixups, interface, etc. + */ + +int pnp_add_device(struct pnp_dev *dev) +{ + if (!dev || !dev->protocol || dev->card) + return -EINVAL; + dev->dev.parent = &dev->protocol->dev; + sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number, dev->number); + return __pnp_add_device(dev); +} + +void __pnp_remove_device(struct pnp_dev *dev) +{ + spin_lock(&pnp_lock); + list_del_init(&dev->global_list); + list_del_init(&dev->protocol_list); + spin_unlock(&pnp_lock); + device_unregister(&dev->dev); +} + /** * pnp_remove_device - removes a pnp device from the pnp layer * @dev: pointer to dev to add * * this function will free all mem used by dev */ + void pnp_remove_device(struct pnp_dev *dev) { - if (!dev) + if (!dev || dev->card) return; - device_unregister(&dev->dev); - spin_lock(&pnp_lock); - list_del_init(&dev->global_list); - list_del_init(&dev->dev_list); - spin_unlock(&pnp_lock); + __pnp_remove_device(dev); } static int __init pnp_init(void) { - printk(KERN_INFO "Linux Plug and Play Support v0.9 (c) Adam Belay\n"); + printk(KERN_INFO "Linux Plug and Play Support v0.93 (c) Adam Belay\n"); return bus_register(&pnp_bus_type); } subsys_initcall(pnp_init); -EXPORT_SYMBOL(pnp_protocol_register); -EXPORT_SYMBOL(pnp_protocol_unregister); +EXPORT_SYMBOL(pnp_register_protocol); +EXPORT_SYMBOL(pnp_unregister_protocol); EXPORT_SYMBOL(pnp_add_device); EXPORT_SYMBOL(pnp_remove_device); -EXPORT_SYMBOL(pnp_init_device); diff -Nru a/drivers/pnp/driver.c b/drivers/pnp/driver.c --- a/drivers/pnp/driver.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/driver.c Fri Dec 6 10:38:41 2002 @@ -34,46 +34,30 @@ return 1; } -int compare_pnp_id(struct list_head *id_list, const char *id) +int compare_pnp_id(struct pnp_id *pos, const char *id) { - struct list_head *pos; - if (!id_list || !id || (strlen(id) != 7)) + if (!pos || !id || (strlen(id) != 7)) return 0; if (memcmp(id,"ANYDEVS",7)==0) return 1; - list_for_each(pos,id_list){ - struct pnp_id *pnp_id = to_pnp_id(pos); - if (memcmp(pnp_id->id,id,3)==0) - if (compare_func(pnp_id->id,id)==1) + while (pos){ + if (memcmp(pos->id,id,3)==0) + if (compare_func(pos->id,id)==1) return 1; + pos = pos->next; } return 0; } -static const struct pnp_id * match_card(struct pnp_driver *drv, struct pnp_card *card) +static const struct pnp_device_id * match_device(struct pnp_driver *drv, struct pnp_dev *dev) { - const struct pnp_id *drv_card_id = drv->card_id_table; - if (!drv) - return NULL; - if (!card) - return NULL; - while (*drv_card_id->id){ - if (compare_pnp_id(&card->ids,drv_card_id->id)) - return drv_card_id; - drv_card_id++; - } - return NULL; -} - -static const struct pnp_id * match_device(struct pnp_driver *drv, struct pnp_dev *dev) -{ - const struct pnp_id *drv_id = drv->id_table; + const struct pnp_device_id *drv_id = drv->id_table; if (!drv) return NULL; if (!dev) return NULL; while (*drv_id->id){ - if (compare_pnp_id(&dev->ids,drv_id->id)) + if (compare_pnp_id(dev->id,drv_id->id)) return drv_id; drv_id++; } @@ -85,32 +69,23 @@ int error = 0; struct pnp_driver *pnp_drv; struct pnp_dev *pnp_dev; - const struct pnp_id *card_id = NULL; - const struct pnp_id *dev_id = NULL; + const struct pnp_device_id *dev_id = NULL; pnp_dev = to_pnp_dev(dev); pnp_drv = to_pnp_driver(dev->driver); + pnp_dbg("pnp: match found with the PnP device '%s' and the driver '%s'", dev->bus_id,pnp_drv->name); if (pnp_dev->active == 0) if(pnp_activate_dev(pnp_dev)<0) return -1; if (pnp_drv->probe && pnp_dev->active) { - if (pnp_dev->card && pnp_drv->card_id_table){ - card_id = match_card(pnp_drv, pnp_dev->card); - if (card_id != NULL) - dev_id = match_device(pnp_drv, pnp_dev); - if (dev_id != NULL) - error = pnp_drv->probe(pnp_dev, card_id, dev_id); - } - else{ - dev_id = match_device(pnp_drv, pnp_dev); - if (dev_id != NULL) - error = pnp_drv->probe(pnp_dev, card_id, dev_id); - } - if (error >= 0){ - pnp_dev->driver = pnp_drv; - error = 0; - } + dev_id = match_device(pnp_drv, pnp_dev); + if (dev_id != NULL) + error = pnp_drv->probe(pnp_dev, dev_id); + } + if (error >= 0){ + pnp_dev->driver = pnp_drv; + error = 0; } return error; } @@ -133,9 +108,6 @@ { struct pnp_dev * pnp_dev = to_pnp_dev(dev); struct pnp_driver * pnp_drv = to_pnp_driver(drv); - if (pnp_dev->card && pnp_drv->card_id_table - && match_card(pnp_drv, pnp_dev->card) == NULL) - return 0; if (match_device(pnp_drv, pnp_dev) == NULL) return 0; return 1; @@ -174,8 +146,8 @@ void pnp_unregister_driver(struct pnp_driver *drv) { - pnp_dbg("the driver '%s' has been unregistered", drv->name); driver_unregister(&drv->driver); + pnp_dbg("the driver '%s' has been unregistered", drv->name); } /** @@ -187,23 +159,19 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { + struct pnp_id *ptr; if (!id) return -EINVAL; if (!dev) return -EINVAL; - list_add_tail(&id->id_list,&dev->ids); + ptr = dev->id; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = id; + else + dev->id = id; return 0; -} - -void pnp_free_ids(struct pnp_dev *dev) -{ - struct list_head *pos; - if (!dev) - return; - list_for_each(pos,&dev->ids){ - struct pnp_id *pnp_id = to_pnp_id(pos); - kfree(pnp_id); - } } EXPORT_SYMBOL(pnp_register_driver); diff -Nru a/drivers/pnp/interface.c b/drivers/pnp/interface.c --- a/drivers/pnp/interface.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/interface.c Fri Dec 6 10:38:41 2002 @@ -321,13 +321,13 @@ static ssize_t pnp_show_current_ids(struct device *dmdev, char *buf, size_t count, loff_t off) { char *str = buf; - struct list_head * pos; struct pnp_dev *dev = to_pnp_dev(dmdev); + struct pnp_id * pos = dev->id; if (off) return 0; - list_for_each(pos,&dev->ids) { - struct pnp_id * cur = to_pnp_id(pos); - str += sprintf(str,"%s\n", cur->id); + while (pos) { + str += sprintf(str,"%s\n", pos->id); + pos = pos->next; } return (str - buf); } diff -Nru a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile --- a/drivers/pnp/isapnp/Makefile Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/isapnp/Makefile Fri Dec 6 10:38:41 2002 @@ -2,10 +2,10 @@ # Makefile for the kernel ISAPNP driver. # -export-objs := core.o compat.o +export-objs := core.o isapnp-proc-$(CONFIG_PROC_FS) = proc.o -obj-y := core.o compat.o $(isapnp-proc-y) +obj-y := core.o $(isapnp-proc-y) include $(TOPDIR)/Rules.make diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c --- a/drivers/pnp/isapnp/core.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/isapnp/core.c Fri Dec 6 10:38:41 2002 @@ -449,13 +449,13 @@ dev = isapnp_alloc(sizeof(struct pnp_dev)); if (!dev) return NULL; - pnp_init_device(dev); dev->number = number; isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]); dev->regs = tmp[4]; dev->card = card; if (size > 5) dev->regs |= tmp[5] << 8; + dev->protocol = &isapnp_protocol; return dev; } @@ -640,7 +640,7 @@ return 1; if (pnp_build_resource(dev, 0) == NULL) return 1; - list_add_tail(&dev->card_list, &card->devices); + pnpc_add_device(card,dev); while (1) { if (isapnp_read_tag(&type, &size)<0) return 1; @@ -653,7 +653,7 @@ if ((dev = isapnp_parse_device(card, size, number++)) == NULL) return 1; pnp_build_resource(dev,0); - list_add_tail(&dev->card_list, &card->devices); + pnpc_add_device(card,dev); size = 0; skip = 0; } else { @@ -848,7 +848,7 @@ device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f); - list_add_tail(&id->id_list,&card->ids); + pnpc_add_id(id,card); } /* @@ -879,12 +879,11 @@ ; else if (checksum == 0x00 || checksum != header[8]) /* not valid CSN */ continue; - if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL) + if ((card = isapnp_alloc(sizeof(struct pnp_card))) == NULL) continue; card->number = csn; INIT_LIST_HEAD(&card->devices); - INIT_LIST_HEAD(&card->ids); isapnp_parse_card_id(card, (header[1] << 8) | header[0], (header[3] << 8) | header[2]); card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4]; isapnp_checksum_value = 0x00; @@ -892,8 +891,8 @@ if (isapnp_checksum_value != 0x00) printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value); card->checksum = isapnp_checksum_value; - - list_add_tail(&card->node, &isapnp_cards); + card->protocol = &isapnp_protocol; + pnpc_add_card(card); } return 0; } @@ -1061,25 +1060,6 @@ .disable = isapnp_disable_resources, }; -static inline int isapnp_init_device_tree(void) -{ - - struct pnp_card *card; - - isapnp_for_each_card(card) { - struct list_head *devlist; - for (devlist = card->devices.next; devlist != &card->devices; devlist = devlist->next) { - struct pnp_dev *dev = card_to_pnp_dev(devlist); - snprintf(dev->dev.name, sizeof(dev->dev.name), "%s", dev->name); - dev->card = card; - dev->protocol = &isapnp_protocol; - pnp_add_device(dev); - } - } - - return 0; -} - int __init isapnp_init(void) { int cards; @@ -1104,7 +1084,7 @@ return -EBUSY; } - if(pnp_protocol_register(&isapnp_protocol)<0) + if(pnp_register_protocol(&isapnp_protocol)<0) return -EBUSY; /* @@ -1143,7 +1123,7 @@ isapnp_build_device_list(); cards = 0; - isapnp_for_each_card(card) { + protocol_for_each_card(&isapnp_protocol,card) { cards++; if (isapnp_verbose) { struct list_head *devlist; @@ -1162,7 +1142,6 @@ printk(KERN_INFO "isapnp: No Plug & Play card found\n"); } - isapnp_init_device_tree(); isapnp_proc_init(); return 0; } diff -Nru a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c --- a/drivers/pnp/isapnp/proc.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/isapnp/proc.c Fri Dec 6 10:38:41 2002 @@ -146,7 +146,7 @@ { struct pnp_dev *dev; isapnp_proc_bus_dir = proc_mkdir("isapnp", proc_bus); - isapnp_for_each_dev(dev) { + protocol_for_each_dev(&isapnp_protocol,dev) { isapnp_proc_attach_device(dev); } return 0; diff -Nru a/drivers/pnp/names.c b/drivers/pnp/names.c --- a/drivers/pnp/names.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/names.c Fri Dec 6 10:38:41 2002 @@ -32,7 +32,7 @@ int i; char *name = dev->name; for(i=0; iids,pnp_id_eisaid[i])){ + if (compare_pnp_id(dev->id,pnp_id_eisaid[i])){ sprintf(name, "%s", pnp_id_names[i]); return; } diff -Nru a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c --- a/drivers/pnp/pnpbios/core.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/pnpbios/core.c Fri Dec 6 10:38:41 2002 @@ -1256,6 +1256,12 @@ struct pnp_dev_node_info node_info; u8 nodenum = dev->number; struct pnp_bios_node * node; + + /* just in case */ + if(dev->driver) + return -EBUSY; + if(!pnp_is_dynamic(dev)) + return -EPERM; if (pnp_bios_dev_node_info(&node_info) != 0) return -ENODEV; node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); @@ -1273,10 +1279,15 @@ struct pnp_dev_node_info node_info; u8 nodenum = dev->number; struct pnp_bios_node * node; - node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); + /* just in case */ + if(dev->driver) + return -EBUSY; + if (flags == PNP_DYNAMIC && !pnp_is_dynamic(dev)) + return -EPERM; if (pnp_bios_dev_node_info(&node_info) != 0) return -ENODEV; + node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); if (!node) return -1; if (pnp_bios_get_dev_node(&nodenum, (char )1, node)) @@ -1323,16 +1334,21 @@ struct pnp_bios_node * node; if (!config) return -1; + /* just in case */ + if(dev->driver) + return -EBUSY; + if(dev->flags & PNP_NO_DISABLE || !pnp_is_dynamic(dev)) + return -EPERM; memset(config, 0, sizeof(struct pnp_cfg)); if (!dev || !dev->active) return -EINVAL; - for (i=0; i <= 8; i++) + for (i=0; i < 8; i++) config->port[i] = &port; - for (i=0; i <= 4; i++) + for (i=0; i < 4; i++) config->mem[i] = &mem; - for (i=0; i <= 2; i++) + for (i=0; i < 2; i++) config->irq[i] = &irq; - for (i=0; i <= 2; i++) + for (i=0; i < 2; i++) config->dma[i] = &dma; dev->active = 0; @@ -1369,7 +1385,7 @@ struct list_head * pos; struct pnp_dev * pnp_dev; list_for_each (pos, &pnpbios_protocol.devices){ - pnp_dev = list_entry(pos, struct pnp_dev, dev_list); + pnp_dev = list_entry(pos, struct pnp_dev, protocol_list); if (dev->number == pnp_dev->number) return -1; } @@ -1402,10 +1418,13 @@ for(nodenum=0; nodenum<0xff; ) { u8 thisnodenum = nodenum; /* We build the list from the "boot" config because - * asking for the "current" config causes some - * BIOSes to crash. + * we know that the resources couldn't have changed + * at this stage. Furthermore some buggy PnP BIOSes + * will crash if we request the "current" config + * from devices that are can only be static such as + * those controlled by the "system" driver. */ - if (pnp_bios_get_dev_node(&nodenum, (char )0 , node)) + if (pnp_bios_get_dev_node(&nodenum, (char )1, node)) break; nodes_got++; dev = pnpbios_kmalloc(sizeof (struct pnp_dev), GFP_KERNEL); @@ -1416,7 +1435,6 @@ if (!dev_id) break; memset(dev_id,0,sizeof(struct pnp_id)); - pnp_init_device(dev); dev->number = thisnodenum; memcpy(dev->name,"Unknown Device",13); dev->name[14] = '\0'; @@ -1426,6 +1444,7 @@ pos = node_current_resource_data_to_dev(node,dev); pos = node_possible_resource_data_to_dev(pos,node,dev); node_id_data_to_dev(pos,node,dev); + dev->flags = node->flags; dev->protocol = &pnpbios_protocol; @@ -1450,10 +1469,7 @@ * */ -extern int is_sony_vaio_laptop; - static int pnpbios_disabled; /* = 0 */ -static int dont_reserve_resources; /* = 0 */ int pnpbios_dont_use_current_config; /* = 0 */ #ifndef MODULE @@ -1471,8 +1487,6 @@ str += 3; if (strncmp(str, "curr", 4) == 0) pnpbios_dont_use_current_config = invert; - if (strncmp(str, "res", 3) == 0) - dont_reserve_resources = invert; str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); @@ -1499,9 +1513,6 @@ return -ENODEV; } - if ( is_sony_vaio_laptop ) - pnpbios_dont_use_current_config = 1; - /* * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS * structure and, if one is found, sets up the selectors and @@ -1544,7 +1555,7 @@ } if (!pnp_bios_present()) return -ENODEV; - pnp_protocol_register(&pnpbios_protocol); + pnp_register_protocol(&pnpbios_protocol); build_devlist(); /*if ( ! dont_reserve_resources )*/ /*reserve_resources();*/ diff -Nru a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c --- a/drivers/pnp/quirks.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/quirks.c Fri Dec 6 10:38:41 2002 @@ -157,7 +157,7 @@ int i = 0; while (*pnp_fixups[i].id) { - if (compare_pnp_id(&dev->ids,pnp_fixups[i].id)) { + if (compare_pnp_id(dev->id,pnp_fixups[i].id)) { pnp_dbg("Calling quirk for %s", dev->dev.bus_id); pnp_fixups[i].quirk_function(dev); diff -Nru a/drivers/pnp/system.c b/drivers/pnp/system.c --- a/drivers/pnp/system.c Fri Dec 6 10:38:41 2002 +++ b/drivers/pnp/system.c Fri Dec 6 10:38:41 2002 @@ -13,12 +13,7 @@ #include #include -static const struct pnp_id pnp_card_table[] = { - { "ANYDEVS", 0 }, - { "", 0 } -}; - -static const struct pnp_id pnp_dev_table[] = { +static const struct pnp_device_id pnp_dev_table[] = { /* General ID for reserving resources */ { "PNP0c02", 0 }, /* memory controller */ @@ -101,7 +96,7 @@ return; } -static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id) +static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) { reserve_resources_of_dev(dev); return 0; @@ -109,7 +104,6 @@ static struct pnp_driver system_pnp_driver = { .name = "system", - .card_id_table = pnp_card_table, .id_table = pnp_dev_table, .probe = system_pnp_probe, .remove = NULL, diff -Nru a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c --- a/drivers/serial/8250_pnp.c Fri Dec 6 10:38:41 2002 +++ b/drivers/serial/8250_pnp.c Fri Dec 6 10:38:41 2002 @@ -33,12 +33,7 @@ #define UNKNOWN_DEV 0x3000 -static const struct pnp_id pnp_card_table[] = { - { "ANYDEVS", 0 }, - { "", 0 } -}; - -static const struct pnp_id pnp_dev_table[] = { +static const struct pnp_device_id pnp_dev_table[] = { /* Archtek America Corp. */ /* Archtek SmartLink Modem 3334BT Plug & Play */ { "AAC000F", 0 }, @@ -316,6 +311,8 @@ { "", 0 } }; +MODULE_DEVICE_TABLE(pnp, pnp_dev_table); + static void inline avoid_irq_share(struct pnp_dev *dev) { unsigned int map = 0x1FF8; @@ -384,7 +381,7 @@ } static int -serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id) +serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) { struct serial_struct serial_req; int ret, line, flags = dev_id->driver_data; @@ -393,10 +390,10 @@ if (flags & SPCI_FL_NO_SHIRQ) avoid_irq_share(dev); memset(&serial_req, 0, sizeof(serial_req)); - serial_req.irq = dev->irq_resource[0].start; - serial_req.port = pci_resource_start(dev, 0); + serial_req.irq = pnp_irq(dev,0); + serial_req.port = pnp_port_start(dev, 0); if (HIGH_BITS_OFFSET) - serial_req.port = dev->resource[0].start >> HIGH_BITS_OFFSET; + serial_req.port = pnp_port_start(dev, 0) >> HIGH_BITS_OFFSET; #ifdef SERIAL_DEBUG_PNP printk("Setup PNP port: port %x, irq %d, type %d\n", serial_req.port, serial_req.irq, serial_req.io_type); @@ -407,7 +404,7 @@ line = register_serial(&serial_req); if (line >= 0) - dev->driver_data = (void *)(line + 1); + pnp_set_drvdata(dev, (void *)(line + 1)); return line >= 0 ? 0 : -ENODEV; } @@ -419,7 +416,6 @@ static struct pnp_driver serial_pnp_driver = { .name = "serial", - .card_id_table = pnp_card_table, .id_table = pnp_dev_table, .probe = serial_pnp_probe, .remove = serial_pnp_remove, @@ -442,5 +438,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver"); -/* FIXME */ -/*MODULE_DEVICE_TABLE(pnpbios, pnp_dev_table);*/ diff -Nru a/include/linux/pnp.h b/include/linux/pnp.h --- a/include/linux/pnp.h Fri Dec 6 10:38:41 2002 +++ b/include/linux/pnp.h Fri Dec 6 10:38:41 2002 @@ -1,3 +1,9 @@ +/* + * Linux Plug and Play Support + * Copyright by Adam Belay + * + */ + #ifndef _LINUX_PNP_H #define _LINUX_PNP_H @@ -7,108 +13,210 @@ #include -/* Device Managemnt */ +/* + * Device Managemnt + */ #define DEVICE_COUNT_IRQ 2 #define DEVICE_COUNT_DMA 2 #define DEVICE_COUNT_RESOURCE 12 +#define MAX_DEVICES 8 struct pnp_resource; struct pnp_protocol; +struct pnp_id; -struct pnp_card { /* this is for ISAPNP */ - struct list_head node; /* node in list of cards */ +struct pnp_card { char name[80]; unsigned char number; /* card number */ - struct list_head ids; /* stores all supported dev ids */ + struct list_head global_list; /* node in global list of cards */ + struct list_head protocol_list; /* node in protocol's list of cards */ struct list_head devices; /* devices attached to the card */ + struct pnp_protocol * protocol; + struct pnp_id * id; /* contains supported EISA IDs*/ + unsigned char pnpver; /* Plug & Play version */ unsigned char productver; /* product version */ unsigned int serial; /* serial number */ unsigned char checksum; /* if zero - checksum passed */ + void * protocol_data; /* Used to store protocol specific data */ + + struct pnpc_driver * driver; /* pointer to the driver bound to this device */ + struct list_head rdevs; /* a list of devices requested by the card driver */ struct proc_dir_entry *procdir; /* directory entry in /proc/bus/isapnp */ + struct device dev; /* Driver Model device interface */ }; -#define to_pnp_card(n) list_entry(n, struct pnp_card, node) +#define global_to_pnp_card(n) list_entry(n, struct pnp_card, global_list) +#define protocol_to_pnp_card(n) list_entry(n, struct pnp_card, protocol_list) +#define to_pnp_card(n) list_entry(n, struct pnp_card, dev) +#define pnp_for_each_card(card) \ + for(dev = global_to_pnp_card(pnp_cards.next); \ + dev != global_to_pnp_card(&cards); \ + dev = global_to_pnp_card(card>global_list.next)) + +static inline void *pnpc_get_drvdata (struct pnp_card *pcard) +{ + return dev_get_drvdata(&pcard->dev); +} + +static inline void pnpc_set_drvdata (struct pnp_card *pcard, void *data) +{ + dev_set_drvdata(&pcard->dev, data); +} + +static inline void *pnpc_get_protodata (struct pnp_card *pcard) +{ + return pcard->protocol_data; +} + +static inline void pnpc_set_protodata (struct pnp_card *pcard, void *data) +{ + pcard->protocol_data = data; +} struct pnp_dev { char name[80]; /* device name */ int active; /* status of the device */ int ro; /* read only */ - struct list_head dev_list; /* node in list of device's protocol */ - struct list_head global_list; - struct list_head card_list; + struct list_head global_list; /* node in global list of devices */ + struct list_head protocol_list; /* node in list of device's protocol */ + struct list_head card_list; /* node in card's list of devices */ + struct list_head rdev_list; /* node in cards list of requested devices */ struct pnp_protocol * protocol; - struct pnp_card *card; + struct pnp_card * card; + struct pnp_id * id; /* contains supported EISA IDs*/ + void * protocol_data; /* Used to store protocol specific data */ unsigned char number; /* must be unique */ unsigned short regs; /* ISAPnP: supported registers */ - struct list_head ids; /* stores all supported dev ids */ + struct pnp_resources *res; /* possible resource information */ struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ struct resource dma_resource[DEVICE_COUNT_DMA]; struct resource irq_resource[DEVICE_COUNT_IRQ]; - struct pnp_driver * driver; /* which driver has allocated this device */ + struct pnp_driver * driver; /* pointer to the driver bound to this device */ struct device dev; /* Driver Model device interface */ - void * driver_data;/* data private to the driver */ - void * protocol_data; + int flags; /* used by protocols */ struct proc_dir_entry *procent; /* device entry in /proc/bus/isapnp */ }; #define global_to_pnp_dev(n) list_entry(n, struct pnp_dev, global_list) #define card_to_pnp_dev(n) list_entry(n, struct pnp_dev, card_list) -#define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, dev_list) +#define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, protocol_list) #define to_pnp_dev(n) container_of(n, struct pnp_dev, dev) #define pnp_for_each_dev(dev) \ for(dev = global_to_pnp_dev(pnp_global.next); \ dev != global_to_pnp_dev(&pnp_global); \ dev = global_to_pnp_dev(dev->global_list.next)) +static inline void *pnp_get_drvdata (struct pnp_dev *pdev) +{ + return dev_get_drvdata(&pdev->dev); +} + +static inline void pnp_set_drvdata (struct pnp_dev *pdev, void *data) +{ + dev_set_drvdata(&pdev->dev, data); +} + +static inline void *pnp_get_protodata (struct pnp_dev *pdev) +{ + return pdev->protocol_data; +} + +static inline void pnp_set_protodata (struct pnp_dev *pdev, void *data) +{ + pdev->protocol_data = data; +} + struct pnp_fixup { char id[7]; void (*quirk_function)(struct pnp_dev *dev); /* fixup function */ }; + /* - * Linux Plug and Play Support - * Copyright by Adam Belay - * + * Driver Management */ -/* Driver Management */ - struct pnp_id { char id[7]; + struct pnp_id * next; +}; + +struct pnp_device_id { + char id[7]; unsigned long driver_data; /* data private to the driver */ - struct list_head id_list; /* node in card's or device's list */ }; -#define to_pnp_id(n) list_entry(n, struct pnp_id, id_list) +struct pnp_card_id { + char id[7]; + unsigned long driver_data; /* data private to the driver */ + struct { + char id[7]; + } devs[MAX_DEVICES]; /* logical devices */ +}; struct pnp_driver { struct list_head node; char *name; - const struct pnp_id *card_id_table; - const struct pnp_id *id_table; - int (*probe) (struct pnp_dev *dev, const struct pnp_id *card_id, - const struct pnp_id *dev_id); + const struct pnp_device_id *id_table; + int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id); void (*remove) (struct pnp_dev *dev); - struct device_driver driver; + struct device_driver driver; }; #define to_pnp_driver(drv) container_of(drv,struct pnp_driver, driver) +struct pnpc_driver { + struct list_head node; + char *name; + const struct pnp_card_id *id_table; + int (*probe) (struct pnp_card *card, const struct pnp_card_id *card_id); + void (*remove) (struct pnp_card *card); + struct device_driver driver; +}; + +#define to_pnpc_driver(drv) container_of(drv,struct pnpc_driver, driver) + + +/* + * Resource Management + */ + +/* Use these instead of directly reading pnp_dev to get resource information */ +#define pnp_port_start(dev,bar) ((dev)->resource[(bar)].start) +#define pnp_port_end(dev,bar) ((dev)->resource[(bar)].end) +#define pnp_port_flags(dev,bar) ((dev)->resource[(bar)].flags) +#define pnp_port_len(dev,bar) \ + ((pnp_port_start((dev),(bar)) == 0 && \ + pnp_port_end((dev),(bar)) == \ + pnp_port_start((dev),(bar))) ? 0 : \ + \ + (pnp_port_end((dev),(bar)) - \ + pnp_port_start((dev),(bar)) + 1)) + +#define pnp_mem_start(dev,bar) ((dev)->resource[(bar+8)].start) +#define pnp_mem_end(dev,bar) ((dev)->resource[(bar+8)].end) +#define pnp_mem_flags(dev,bar) ((dev)->resource[(bar+8)].flags) +#define pnp_mem_len(dev,bar) \ + ((pnp_mem_start((dev),(bar)) == 0 && \ + pnp_mem_end((dev),(bar)) == \ + pnp_mem_start((dev),(bar))) ? 0 : \ + \ + (pnp_mem_end((dev),(bar)) - \ + pnp_mem_start((dev),(bar)) + 1)) -/* Resource Management */ +#define pnp_irq(dev,bar) ((dev)->irq_resource[(bar)].start) +#define pnp_irq_flags(dev,bar) ((dev)->irq_resource[(bar)].flags) -#define DEV_IO(dev, index) (dev->resource[index].start) -#define DEV_MEM(dev, index) (dev->resource[index+8].start) -#define DEV_IRQ(dev, index) (dev->irq_resource[index].start) -#define DEV_DMA(dev, index) (dev->dma_resource[index].start) +#define pnp_dma(dev,bar) ((dev)->dma_resource[(bar)].start) +#define pnp_dma_flags(dev,bar) ((dev)->dma_resource[(bar)].flags) #define PNP_PORT_FLAG_16BITADDR (1<<0) -#define PNP_PORT_FLAG_FIXED (1<<1) +#define PNP_PORT_FLAG_FIXED (1<<1) struct pnp_port { unsigned short min; /* min base number */ @@ -182,7 +290,9 @@ }; -/* Protocol Management */ +/* + * Protocol Management + */ struct pnp_protocol { struct list_head protocol_list; @@ -196,18 +306,26 @@ /* used by pnp layer only (look but don't touch) */ unsigned char number; /* protocol number*/ struct device dev; /* link to driver model */ + struct list_head cards; struct list_head devices; }; #define to_pnp_protocol(n) list_entry(n, struct pnp_protocol, protocol_list) +#define protocol_for_each_card(protocol,card) \ + for((card) = protocol_to_pnp_card((protocol)->cards.next); \ + (card) != protocol_to_pnp_card(&(protocol)->cards); \ + (card) = protocol_to_pnp_card((card)->protocol_list.next)) +#define protocol_for_each_dev(protocol,dev) \ + for((dev) = protocol_to_pnp_dev((protocol)->devices.next); \ + (dev) != protocol_to_pnp_dev(&(protocol)->devices); \ + (dev) = protocol_to_pnp_dev((dev)->protocol_list.next)) #if defined(CONFIG_PNP) /* core */ -int pnp_protocol_register(struct pnp_protocol *protocol); -void pnp_protocol_unregister(struct pnp_protocol *protocol); -int pnp_init_device(struct pnp_dev *dev); +int pnp_register_protocol(struct pnp_protocol *protocol); +void pnp_unregister_protocol(struct pnp_protocol *protocol); int pnp_add_device(struct pnp_dev *dev); void pnp_remove_device(struct pnp_dev *dev); extern struct list_head pnp_global; @@ -226,7 +344,7 @@ int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode); /* driver */ -int compare_pnp_id(struct list_head * id_list, const char * id); +int compare_pnp_id(struct pnp_id * pos, const char * id); int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev); int pnp_register_driver(struct pnp_driver *drv); void pnp_unregister_driver(struct pnp_driver *drv); @@ -234,8 +352,8 @@ #else /* just in case anyone decides to call these without PnP Support Enabled */ -static inline int pnp_protocol_register(struct pnp_protocol *protocol) { return -ENODEV; } -static inline void pnp_protocol_unregister(struct pnp_protocol *protocol) { } +static inline int pnp_register_protocol(struct pnp_protocol *protocol) { return -ENODEV; } +static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { } static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; } static inline void pnp_remove_device(struct pnp_dev *dev) { } @@ -250,14 +368,45 @@ static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode) { return -ENODEV; } -static inline int compare_pnp_id(struct list_head * id_list, char * id) { return -ENODEV; } +static inline int compare_pnp_id(struct list_head * id_list, const char * id) { return -ENODEV; } static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; } static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; } #endif /* CONFIG_PNP */ + +#if defined(CONFIG_PNP_CARD) + +/* card */ +int pnpc_add_card(struct pnp_card *card); +void pnpc_remove_card(struct pnp_card *card); +int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev); +void pnpc_remove_device(struct pnp_dev *dev); +struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from); +void pnp_release_card_device(struct pnp_dev *dev); +int pnpc_register_driver(struct pnpc_driver * drv); +void pnpc_unregister_driver(struct pnpc_driver *drv); +int pnpc_add_id(struct pnp_id *id, struct pnp_card *card); +extern struct list_head pnp_cards; + +#else + +static inline int pnpc_add_card(struct pnp_card *card) { return -ENODEV; } +static inline void pnpc_remove_card(struct pnp_card *card) { ; } +static inline int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev) { return -ENODEV; } +static inline void pnpc_remove_device(struct pnp_dev *dev) { ; } +static inline struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from) { return NULL; } +static inline void pnp_release_card_device(struct pnp_dev *dev) { ; } +static inline int pnpc_register_driver(struct pnpc_driver *drv) { return -ENODEV; } +static inline void pnpc_unregister_driver(struct pnpc_driver *drv) { ; } +static inline int pnpc_add_id(struct pnp_id *id, struct pnp_card *card) { return -ENODEV; } + +#endif /* CONFIG_PNP_CARD */ + + #if defined(CONFIG_ISAPNP) + /* compat */ struct pnp_card *pnp_find_card(unsigned short vendor, unsigned short device, diff -Nru a/include/linux/pnpbios.h b/include/linux/pnpbios.h --- a/include/linux/pnpbios.h Fri Dec 6 10:38:41 2002 +++ b/include/linux/pnpbios.h Fri Dec 6 10:38:41 2002 @@ -75,6 +75,19 @@ #define PNPMSG_POWER_OFF 0x41 #define PNPMSG_PNP_OS_ACTIVE 0x42 #define PNPMSG_PNP_OS_INACTIVE 0x43 +/* + * Plug and Play BIOS flags + */ +#define PNP_NO_DISABLE 0x0001 +#define PNP_NO_CONFIG 0x0002 +#define PNP_OUTPUT 0x0004 +#define PNP_INPUT 0x0008 +#define PNP_BOOTABLE 0x0010 +#define PNP_DOCK 0x0020 +#define PNP_REMOVABLE 0x0040 +#define pnp_is_static(x) (x->flags & 0x0100) == 0x0000 +#define pnp_is_dynamic(x) x->flags & 0x0080 + /* 0x8000 through 0xffff are OEM defined */ #pragma pack(1) diff -Nru a/include/linux/sunrpc/stats.h b/include/linux/sunrpc/stats.h --- a/include/linux/sunrpc/stats.h Fri Dec 6 10:38:41 2002 +++ b/include/linux/sunrpc/stats.h Fri Dec 6 10:38:41 2002 @@ -61,16 +61,18 @@ #else +static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; } +static inline void rpc_proc_unregister(const char *p) {} +static inline int rpc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f) { return 0; } +static inline void rpc_proc_zero(struct rpc_program *p) {} + +static inline struct proc_dir_entry *svc_proc_register(struct svc_stat *s) { return NULL; } static inline void svc_proc_unregister(const char *p) {} -static inline struct proc_dir_entry*svc_proc_register(struct svc_stat *s) -{ - return NULL; -} +static inline int svc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f) { return 0; } +static inline void svc_proc_zero(struct svc_program *p) {} + +#define proc_net_rpc NULL -static inline int svc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f) -{ - return 0; -} #endif #endif /* _LINUX_SUNRPC_STATS_H */ diff -Nru a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c --- a/sound/isa/opl3sa2.c Fri Dec 6 10:38:41 2002 +++ b/sound/isa/opl3sa2.c Fri Dec 6 10:38:41 2002 @@ -24,11 +24,7 @@ #include #include #include -#ifndef LINUX_ISAPNP_H -#include -#define isapnp_card pci_bus -#define isapnp_dev pci_dev -#endif +#include #include #include #include @@ -51,7 +47,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0xf86,0x370,0x100 */ @@ -73,7 +69,7 @@ MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(enable, "Enable OPL3-SA soundcard."); MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP MODULE_PARM(isapnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard."); MODULE_PARM_SYNTAX(isapnp, SNDRV_ISAPNP_DESC); @@ -147,8 +143,8 @@ snd_hwdep_t *synth; snd_rawmidi_t *rmidi; cs4231_t *cs4231; -#ifdef __ISAPNP__ - struct isapnp_dev *dev; +#ifdef CONFIG_PNP + struct pnp_dev *dev; #endif unsigned char ctlregs[0x20]; int ymode; /* SL added */ @@ -163,33 +159,27 @@ static snd_card_t *snd_opl3sa2_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; -#ifdef __ISAPNP__ - -static struct isapnp_card *snd_opl3sa2_isapnp_cards[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PTR; -static const struct isapnp_card_id *snd_opl3sa2_isapnp_id[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PTR; +#ifdef CONFIG_PNP -#define ISAPNP_OPL3SA2(_va, _vb, _vc, _device, _function) \ - { \ - ISAPNP_CARD_ID(_va, _vb, _vc, _device), \ - devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _function), } \ - } +static struct pnp_card *snd_opl3sa2_isapnp_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; +static const struct pnp_card_id *snd_opl3sa2_isapnp_id[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; -static struct isapnp_card_id snd_opl3sa2_pnpids[] __devinitdata = { +static struct pnp_card_id snd_opl3sa2_pnpids[] = { /* Yamaha YMF719E-S (Genius Sound Maker 3DX) */ - ISAPNP_OPL3SA2('Y','M','H',0x0020,0x0021), + {.id = "YMH0020", .driver_data = 0, devs : { {.id="YMH0021"}, } }, /* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */ - ISAPNP_OPL3SA2('Y','M','H',0x0030,0x0021), + {.id = "YMH0030", .driver_data = 0, devs : { {.id="YMH0021"}, } }, /* Yamaha OPL3-SA2 */ - ISAPNP_OPL3SA2('Y','M','H',0x0800,0x0021), + {.id = "YMH0800", .driver_data = 0, devs : { {.id="YMH0021"}, } }, /* NeoMagic MagicWave 3DX */ - ISAPNP_OPL3SA2('N','M','X',0x2200,0x2210), + {.id = "NMX2200", .driver_data = 0, devs : { {.id="NMX2210"}, } }, /* --- */ - { ISAPNP_CARD_END, } /* end */ + {.id = "", } /* end */ }; -ISAPNP_CARD_TABLE(snd_opl3sa2_pnpids); +/*PNP_CARD_TABLE(snd_opl3sa2_pnpids);*/ -#endif /* __ISAPNP__ */ +#endif /* CONFIG_PNP */ /* read control port (w/o spinlock) */ @@ -634,41 +624,18 @@ #endif /* CONFIG_PM */ -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP static int __init snd_opl3sa2_isapnp(int dev, opl3sa2_t *chip) { - const struct isapnp_card_id *id = snd_opl3sa2_isapnp_id[dev]; - struct isapnp_card *card = snd_opl3sa2_isapnp_cards[dev]; - struct isapnp_dev *pdev; - - chip->dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL); - if (chip->dev->active) { - chip->dev = NULL; - return -EBUSY; - } - /* PnP initialization */ + const struct pnp_card_id *id = snd_opl3sa2_isapnp_id[dev]; + struct pnp_card *card = snd_opl3sa2_isapnp_cards[dev]; + struct pnp_dev *pdev; + + chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL); pdev = chip->dev; - if (pdev->prepare(pdev)<0) - return -EAGAIN; - if (sb_port[dev] != SNDRV_AUTO_PORT) - isapnp_resource_change(&pdev->resource[0], sb_port[dev], 16); - if (wss_port[dev] != SNDRV_AUTO_PORT) - isapnp_resource_change(&pdev->resource[1], wss_port[dev], 8); - if (fm_port[dev] != SNDRV_AUTO_PORT) - isapnp_resource_change(&pdev->resource[2], fm_port[dev], 4); - if (midi_port[dev] != SNDRV_AUTO_PORT) - isapnp_resource_change(&pdev->resource[3], midi_port[dev], 2); - if (port[dev] != SNDRV_AUTO_PORT) - isapnp_resource_change(&pdev->resource[4], port[dev], 2); - if (dma1[dev] != SNDRV_AUTO_DMA) - isapnp_resource_change(&pdev->dma_resource[0], dma1[dev], 1); - if (dma2[dev] != SNDRV_AUTO_DMA) - isapnp_resource_change(&pdev->dma_resource[1], dma2[dev], 1); - if (irq[dev] != SNDRV_AUTO_IRQ) - isapnp_resource_change(&pdev->irq_resource[0], irq[dev], 1); - if (pdev->activate(pdev)<0) { - snd_printk("isapnp configure failure (out of resources?)\n"); - return -EBUSY; + if (!pdev){ + snd_printdd("isapnp OPL3-SA: a card was found but it did not contain the needed devices\n",); + return -ENODEV; } sb_port[dev] = pdev->resource[0].start; wss_port[dev] = pdev->resource[1].start; @@ -685,19 +652,12 @@ return 0; } -static void snd_opl3sa2_deactivate(opl3sa2_t *chip) -{ - if (chip->dev) { - chip->dev->deactivate(chip->dev); - chip->dev = NULL; - } -} -#endif /* __ISAPNP__ */ +#endif /* CONFIG_PNP */ static int snd_opl3sa2_free(opl3sa2_t *chip) { -#ifdef __ISAPNP__ - snd_opl3sa2_deactivate(chip); +#ifdef CONFIG_PNP + chip->dev = NULL; #endif #ifdef CONFIG_PM if (chip->pm_dev) @@ -731,7 +691,7 @@ }; int err; -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP if (!isapnp[dev]) { #endif if (port[dev] == SNDRV_AUTO_PORT) { @@ -750,7 +710,7 @@ snd_printk("specify midi_port\n"); return -EINVAL; } -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP } #endif card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); @@ -766,7 +726,7 @@ chip->irq = -1; if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) goto __error; -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP if (isapnp[dev] && (err = snd_opl3sa2_isapnp(dev, chip)) < 0) goto __error; #endif @@ -854,9 +814,9 @@ return err; } -#ifdef __ISAPNP__ -static int __init snd_opl3sa2_isapnp_detect(struct isapnp_card *card, - const struct isapnp_card_id *id) +#ifdef CONFIG_PNP +static int __init snd_opl3sa2_isapnp_detect(struct pnp_card *card, + const struct pnp_card_id *id) { static int dev; int res; @@ -874,7 +834,20 @@ } return -ENODEV; } -#endif /* __ISAPNP__ */ + +static void snd_opl3sa2_isapnp_remove(struct pnp_card * card) +{ +/* FIXME */ +} + +static struct pnpc_driver opl3sa2_pnpc_driver = { + .name = "opl3sa2", + .id_table = snd_opl3sa2_pnpids, + .probe = snd_opl3sa2_isapnp_detect, + .remove = snd_opl3sa2_isapnp_remove, +}; + +#endif /* CONFIG_PNP */ static int __init alsa_card_opl3sa2_init(void) { @@ -883,15 +856,15 @@ for (dev = 0; dev < SNDRV_CARDS; dev++) { if (!enable[dev]) continue; -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP if (isapnp[dev]) continue; #endif if (snd_opl3sa2_probe(dev) >= 0) cards++; } -#ifdef __ISAPNP__ - cards += isapnp_probe_cards(snd_opl3sa2_pnpids, snd_opl3sa2_isapnp_detect); +#ifdef CONFIG_PNP + cards += pnpc_register_driver(&opl3sa2_pnpc_driver); #endif if (!cards) { #ifdef MODULE @@ -940,7 +913,7 @@ get_option(&str,&dma1[nr_dev]) == 2 && get_option(&str,&dma2[nr_dev]) == 2 && get_option(&str,&opl3sa3_ymode[nr_dev]) == 2); -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP if (pnp != INT_MAX) isapnp[nr_dev] = pnp; #endif diff -Nru a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c --- a/sound/oss/opl3sa2.c Fri Dec 6 10:38:41 2002 +++ b/sound/oss/opl3sa2.c Fri Dec 6 10:38:41 2002 @@ -841,10 +841,9 @@ {.id = ""} }; -/*MODULE_DEVICE_TABLE(isapnp, isapnp_opl3sa2_list);*/ +MODULE_DEVICE_TABLE(pnp, pnp_opl3sa2_list); -static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *card_id, - const struct pnp_id *dev_id) +static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *dev_id) { int card = opl3sa2_cards_num; if (opl3sa2_cards_num == OPL3SA2_CARDS_MAX) @@ -883,7 +882,6 @@ static struct pnp_driver opl3sa2_driver = { .name = "opl3sa2", - .card_id_table = NULL, .id_table = pnp_opl3sa2_list, .probe = opl3sa2_pnp_probe, };