Commit 8115f435 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5

into kroah.com:/home/greg/linux/BK/pnp-2.5
parents 7ba78799 cb59aeb2
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/gameport.h> #include <linux/gameport.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/isapnp.h> #include <linux/pnp.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Classic gameport (ISA/PnP) driver"); MODULE_DESCRIPTION("Classic gameport (ISA/PnP) driver");
...@@ -52,7 +52,7 @@ static int ns558_isa_portlist[] = { 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x ...@@ -52,7 +52,7 @@ static int ns558_isa_portlist[] = { 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x
struct ns558 { struct ns558 {
int type; int type;
int size; int size;
struct pci_dev *dev; struct pnp_dev *dev;
struct list_head node; struct list_head node;
struct gameport gameport; struct gameport gameport;
char phys[32]; char phys[32];
...@@ -159,67 +159,55 @@ static void ns558_isa_probe(int io) ...@@ -159,67 +159,55 @@ static void ns558_isa_probe(int io)
list_add(&port->node, &ns558_list); list_add(&port->node, &ns558_list);
} }
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
#define NS558_DEVICE(a,b,c,d)\ static struct pnp_device_id pnp_devids[] = {
.card_vendor = ISAPNP_ANY_ID, card_device: ISAPNP_ANY_ID,\ { .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */
.vendor = ISAPNP_VENDOR(a,b,c), function: ISAPNP_DEVICE(d) { .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */
{ .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */
static struct isapnp_device_id pnp_devids[] = { { .id = "@P@2001", .driver_data = 0 }, /* ALS 120 */
{ NS558_DEVICE('@','P','@',0x0001) }, /* ALS 100 */ { .id = "ASB16fd", .driver_data = 0 }, /* AdLib NSC16 */
{ NS558_DEVICE('@','P','@',0x0020) }, /* ALS 200 */ { .id = "AZT3001", .driver_data = 0 }, /* AZT1008 */
{ NS558_DEVICE('@','P','@',0x1001) }, /* ALS 100+ */ { .id = "CDC0001", .driver_data = 0 }, /* Opl3-SAx */
{ NS558_DEVICE('@','P','@',0x2001) }, /* ALS 120 */ { .id = "CSC0001", .driver_data = 0 }, /* CS4232 */
{ NS558_DEVICE('A','S','B',0x16fd) }, /* AdLib NSC16 */ { .id = "CSC000f", .driver_data = 0 }, /* CS4236 */
{ NS558_DEVICE('A','Z','T',0x3001) }, /* AZT1008 */ { .id = "CSC0101", .driver_data = 0 }, /* CS4327 */
{ NS558_DEVICE('C','D','C',0x0001) }, /* Opl3-SAx */ { .id = "CTL7001", .driver_data = 0 }, /* SB16 */
{ NS558_DEVICE('C','S','C',0x0001) }, /* CS4232 */ { .id = "CTL7002", .driver_data = 0 }, /* AWE64 */
{ NS558_DEVICE('C','S','C',0x000f) }, /* CS4236 */ { .id = "CTL7005", .driver_data = 0 }, /* Vibra16 */
{ NS558_DEVICE('C','S','C',0x0101) }, /* CS4327 */ { .id = "ENS2020", .driver_data = 0 }, /* SoundscapeVIVO */
{ NS558_DEVICE('C','T','L',0x7001) }, /* SB16 */ { .id = "ESS0001", .driver_data = 0 }, /* ES1869 */
{ NS558_DEVICE('C','T','L',0x7002) }, /* AWE64 */ { .id = "ESS0005", .driver_data = 0 }, /* ES1878 */
{ NS558_DEVICE('C','T','L',0x7005) }, /* Vibra16 */ { .id = "ESS6880", .driver_data = 0 }, /* ES688 */
{ NS558_DEVICE('E','N','S',0x2020) }, /* SoundscapeVIVO */ { .id = "IBM0012", .driver_data = 0 }, /* CS4232 */
{ NS558_DEVICE('E','S','S',0x0001) }, /* ES1869 */ { .id = "OPT0001", .driver_data = 0 }, /* OPTi Audio16 */
{ NS558_DEVICE('E','S','S',0x0005) }, /* ES1878 */ { .id = "YMH0006", .driver_data = 0 }, /* Opl3-SA */
{ NS558_DEVICE('E','S','S',0x6880) }, /* ES688 */ { .id = "YMH0022", .driver_data = 0 }, /* Opl3-SAx */
{ NS558_DEVICE('I','B','M',0x0012) }, /* CS4232 */ { .id = "PNPb02f", .driver_data = 0 }, /* Generic */
{ NS558_DEVICE('O','P','T',0x0001) }, /* OPTi Audio16 */ { .id = "", },
{ NS558_DEVICE('Y','M','H',0x0006) }, /* Opl3-SA */
{ NS558_DEVICE('Y','M','H',0x0022) }, /* Opl3-SAx */
{ NS558_DEVICE('P','N','P',0xb02f) }, /* Generic */
{ 0, },
}; };
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_device_id *did)
{ {
int ioport, iolen; int ioport, iolen;
struct ns558 *port; struct ns558 *port;
if (dev->prepare && dev->prepare(dev) < 0)
return;
if (!(dev->resource[0].flags & IORESOURCE_IO)) { if (!(dev->resource[0].flags & IORESOURCE_IO)) {
printk(KERN_WARNING "ns558: No i/o ports on a gameport? Weird\n"); 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); ioport = pnp_port_start(dev,0);
iolen = pci_resource_len(dev, 0); iolen = pnp_port_len(dev,0);
if (!request_region(ioport, iolen, "ns558-pnp")) if (!request_region(ioport, iolen, "ns558-pnp"))
goto deactivate; return -EBUSY;
if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) { if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) {
printk(KERN_ERR "ns558: Memory allocation failed.\n"); printk(KERN_ERR "ns558: Memory allocation failed.\n");
goto deactivate; return -ENOMEM;
} }
memset(port, 0, sizeof(struct ns558)); memset(port, 0, sizeof(struct ns558));
...@@ -231,36 +219,37 @@ static void ns558_pnp_probe(struct pci_dev *dev) ...@@ -231,36 +219,37 @@ static void ns558_pnp_probe(struct pci_dev *dev)
port->gameport.phys = port->phys; port->gameport.phys = port->phys;
port->gameport.name = port->name; port->gameport.name = port->name;
port->gameport.id.bustype = BUS_ISAPNP; port->gameport.id.bustype = BUS_ISAPNP;
port->gameport.id.vendor = dev->vendor;
port->gameport.id.product = dev->device;
port->gameport.id.version = 0x100; 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"); sprintf(port->name, "%s", dev->dev.name[0] ? dev->dev.name : "NS558 PnP Gameport");
gameport_register_port(&port->gameport); gameport_register_port(&port->gameport);
printk(KERN_INFO "gameport: NS558 PnP at isapnp%d.%d io %#x", printk(KERN_INFO "gameport: NS558 PnP at pnp%s io %#x",
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), port->gameport.io); dev->dev.bus_id, port->gameport.io);
if (iolen > 1) printk(" size %d", iolen); if (iolen > 1) printk(" size %d", iolen);
printk(" speed %d kHz\n", port->gameport.speed); printk(" speed %d kHz\n", port->gameport.speed);
list_add_tail(&port->node, &ns558_list); list_add_tail(&port->node, &ns558_list);
return; return 0;
deactivate:
if (dev->deactivate)
dev->deactivate(dev);
} }
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 #endif
int __init ns558_init(void) int __init ns558_init(void)
{ {
int i = 0; int i = 0;
#ifdef __ISAPNP__
struct isapnp_device_id *devid;
struct pci_dev *dev = NULL;
#endif
/* /*
* Probe for ISA ports. * Probe for ISA ports.
...@@ -269,16 +258,7 @@ int __init ns558_init(void) ...@@ -269,16 +258,7 @@ int __init ns558_init(void)
while (ns558_isa_portlist[i]) while (ns558_isa_portlist[i])
ns558_isa_probe(ns558_isa_portlist[i++]); ns558_isa_probe(ns558_isa_portlist[i++]);
/* pnp_register_driver(&ns558_pnp_driver);
* 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
return list_empty(&ns558_list) ? -ENODEV : 0; return list_empty(&ns558_list) ? -ENODEV : 0;
} }
...@@ -290,13 +270,10 @@ void __exit ns558_exit(void) ...@@ -290,13 +270,10 @@ void __exit ns558_exit(void)
gameport_unregister_port(&port->gameport); gameport_unregister_port(&port->gameport);
switch (port->type) { switch (port->type) {
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
case NS558_PNP: case NS558_PNP:
if (port->dev->deactivate)
port->dev->deactivate(port->dev);
/* fall through */ /* fall through */
#endif #endif
case NS558_ISA: case NS558_ISA:
release_region(port->gameport.io, port->size); release_region(port->gameport.io, port->size);
break; break;
...@@ -305,6 +282,7 @@ void __exit ns558_exit(void) ...@@ -305,6 +282,7 @@ void __exit ns558_exit(void)
break; break;
} }
} }
pnp_unregister_driver(&ns558_pnp_driver);
} }
module_init(ns558_init); module_init(ns558_init);
......
...@@ -87,8 +87,8 @@ ...@@ -87,8 +87,8 @@
extern int e100_create_proc_subdir(struct e100_private *, char *); extern int e100_create_proc_subdir(struct e100_private *, char *);
extern void e100_remove_proc_subdir(struct e100_private *, char *); extern void e100_remove_proc_subdir(struct e100_private *, char *);
#else #else
#define e100_create_proc_subdir(X) 0 #define e100_create_proc_subdir(X, Y) 0
#define e100_remove_proc_subdir(X) do {} while(0) #define e100_remove_proc_subdir(X, Y) do {} while(0)
#endif #endif
static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *); static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *);
......
...@@ -2973,7 +2973,7 @@ static int __init parport_pc_init_superio(int autoirq, int autodma) {return 0;} ...@@ -2973,7 +2973,7 @@ static int __init parport_pc_init_superio(int autoirq, int autodma) {return 0;}
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static const struct pnp_id pnp_dev_table[] = { static const struct pnp_device_id pnp_dev_table[] = {
/* Standard LPT Printer Port */ /* Standard LPT Printer Port */
{.id = "PNP0400", .driver_data = 0}, {.id = "PNP0400", .driver_data = 0},
/* ECP Printer Port */ /* ECP Printer Port */
...@@ -2984,7 +2984,6 @@ static const struct pnp_id pnp_dev_table[] = { ...@@ -2984,7 +2984,6 @@ static const struct pnp_id pnp_dev_table[] = {
/* we only need the pnp layer to activate the device, at least for now */ /* we only need the pnp layer to activate the device, at least for now */
static struct pnp_driver parport_pc_pnp_driver = { static struct pnp_driver parport_pc_pnp_driver = {
.name = "parport_pc", .name = "parport_pc",
.card_id_table = NULL,
.id_table = pnp_dev_table, .id_table = pnp_dev_table,
}; };
#else #else
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Plug and Play configuration # Plug and Play configuration
# #
menu "Plug and Play configuration" menu "Plug and Play support"
config PNP config PNP
bool "Plug and Play support" bool "Plug and Play support"
...@@ -30,6 +30,15 @@ config PNP_NAMES ...@@ -30,6 +30,15 @@ config PNP_NAMES
If unsure, say Y. 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 config PNP_DEBUG
bool "PnP Debug Messages" bool "PnP Debug Messages"
depends on PNP depends on PNP
...@@ -42,7 +51,7 @@ comment "Protocols" ...@@ -42,7 +51,7 @@ comment "Protocols"
config ISAPNP config ISAPNP
bool "ISA Plug and Play support (EXPERIMENTAL)" bool "ISA Plug and Play support (EXPERIMENTAL)"
depends on PNP && EXPERIMENTAL depends on PNP && EXPERIMENTAL && PNP_CARD
help help
Say Y here if you would like support for ISA Plug and Play devices. Say Y here if you would like support for ISA Plug and Play devices.
Some information is in <file:Documentation/isapnp.txt>. Some information is in <file:Documentation/isapnp.txt>.
......
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
# Makefile for the Linux Plug-and-Play Support. # 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_PNPBIOS) += pnpbios/
obj-$(CONFIG_ISAPNP) += isapnp/ 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 include $(TOPDIR)/Rules.make
...@@ -4,5 +4,6 @@ extern void *pnp_alloc(long size); ...@@ -4,5 +4,6 @@ extern void *pnp_alloc(long size);
extern int pnp_interface_attach_device(struct pnp_dev *dev); extern int pnp_interface_attach_device(struct pnp_dev *dev);
extern void pnp_name_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_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 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);
/*
* card.c - contains functions for managing groups of PnP devices
*
* Copyright 2002 Adam Belay <ambx1@neo.rr.com>
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#ifdef CONFIG_PNP_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/pnp.h>
#include <linux/init.h>
#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);
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/errno.h>
#include "base.h" #include "base.h"
...@@ -41,7 +42,7 @@ void *pnp_alloc(long size) ...@@ -41,7 +42,7 @@ void *pnp_alloc(long size)
* Ex protocols: ISAPNP, PNPBIOS, etc * Ex protocols: ISAPNP, PNPBIOS, etc
*/ */
int pnp_protocol_register(struct pnp_protocol *protocol) int pnp_register_protocol(struct pnp_protocol *protocol)
{ {
int nodenum; int nodenum;
struct list_head * pos; struct list_head * pos;
...@@ -50,6 +51,7 @@ int pnp_protocol_register(struct pnp_protocol *protocol) ...@@ -50,6 +51,7 @@ int pnp_protocol_register(struct pnp_protocol *protocol)
return -EINVAL; return -EINVAL;
INIT_LIST_HEAD(&protocol->devices); INIT_LIST_HEAD(&protocol->devices);
INIT_LIST_HEAD(&protocol->cards);
nodenum = 0; nodenum = 0;
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
...@@ -76,7 +78,7 @@ int pnp_protocol_register(struct pnp_protocol *protocol) ...@@ -76,7 +78,7 @@ int pnp_protocol_register(struct pnp_protocol *protocol)
* @protocol: pointer to the corresponding pnp_protocol structure * @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); spin_lock(&pnp_lock);
list_del_init(&protocol->protocol_list); list_del_init(&protocol->protocol_list);
...@@ -84,17 +86,19 @@ void pnp_protocol_unregister(struct pnp_protocol *protocol) ...@@ -84,17 +86,19 @@ void pnp_protocol_unregister(struct pnp_protocol *protocol)
device_unregister(&protocol->dev); 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); struct pnp_id * id;
return 0; 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) static void pnp_release_device(struct device *dmdev)
...@@ -106,68 +110,73 @@ static void pnp_release_device(struct device *dmdev) ...@@ -106,68 +110,73 @@ static void pnp_release_device(struct device *dmdev)
kfree(dev); kfree(dev);
} }
/** int __pnp_add_device(struct pnp_dev *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 error = 0; 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_name_device(dev);
pnp_fixup_device(dev); pnp_fixup_device(dev);
strcpy(dev->dev.name,dev->name); strcpy(dev->dev.name,dev->name);
dev->dev.parent = &dev->protocol->dev;
dev->dev.bus = &pnp_bus_type; dev->dev.bus = &pnp_bus_type;
dev->dev.release = &pnp_release_device; dev->dev.release = &pnp_release_device;
error = device_register(&dev->dev); error = device_register(&dev->dev);
if (error == 0){ if (error == 0){
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
list_add_tail(&dev->global_list, &pnp_global); 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); spin_unlock(&pnp_lock);
pnp_interface_attach_device(dev); pnp_interface_attach_device(dev);
} }
return error; 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 * pnp_remove_device - removes a pnp device from the pnp layer
* @dev: pointer to dev to add * @dev: pointer to dev to add
* *
* this function will free all mem used by dev * this function will free all mem used by dev
*/ */
void pnp_remove_device(struct pnp_dev *dev) void pnp_remove_device(struct pnp_dev *dev)
{ {
if (!dev) if (!dev || dev->card)
return; return;
device_unregister(&dev->dev); __pnp_remove_device(dev);
spin_lock(&pnp_lock);
list_del_init(&dev->global_list);
list_del_init(&dev->dev_list);
spin_unlock(&pnp_lock);
} }
static int __init pnp_init(void) 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); return bus_register(&pnp_bus_type);
} }
subsys_initcall(pnp_init); subsys_initcall(pnp_init);
EXPORT_SYMBOL(pnp_protocol_register); EXPORT_SYMBOL(pnp_register_protocol);
EXPORT_SYMBOL(pnp_protocol_unregister); EXPORT_SYMBOL(pnp_unregister_protocol);
EXPORT_SYMBOL(pnp_add_device); EXPORT_SYMBOL(pnp_add_device);
EXPORT_SYMBOL(pnp_remove_device); EXPORT_SYMBOL(pnp_remove_device);
EXPORT_SYMBOL(pnp_init_device);
...@@ -34,46 +34,30 @@ static int compare_func(const char *ida, const char *idb) ...@@ -34,46 +34,30 @@ static int compare_func(const char *ida, const char *idb)
return 1; 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 (!pos || !id || (strlen(id) != 7))
if (!id_list || !id || (strlen(id) != 7))
return 0; return 0;
if (memcmp(id,"ANYDEVS",7)==0) if (memcmp(id,"ANYDEVS",7)==0)
return 1; return 1;
list_for_each(pos,id_list){ while (pos){
struct pnp_id *pnp_id = to_pnp_id(pos); if (memcmp(pos->id,id,3)==0)
if (memcmp(pnp_id->id,id,3)==0) if (compare_func(pos->id,id)==1)
if (compare_func(pnp_id->id,id)==1)
return 1; return 1;
pos = pos->next;
} }
return 0; 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) if (!drv)
return NULL; return NULL;
if (!dev) if (!dev)
return NULL; return NULL;
while (*drv_id->id){ 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; return drv_id;
drv_id++; drv_id++;
} }
...@@ -85,33 +69,24 @@ static int pnp_device_probe(struct device *dev) ...@@ -85,33 +69,24 @@ static int pnp_device_probe(struct device *dev)
int error = 0; int error = 0;
struct pnp_driver *pnp_drv; struct pnp_driver *pnp_drv;
struct pnp_dev *pnp_dev; struct pnp_dev *pnp_dev;
const struct pnp_id *card_id = NULL; const struct pnp_device_id *dev_id = NULL;
const struct pnp_id *dev_id = NULL;
pnp_dev = to_pnp_dev(dev); pnp_dev = to_pnp_dev(dev);
pnp_drv = to_pnp_driver(dev->driver); 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); 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_dev->active == 0)
if(pnp_activate_dev(pnp_dev)<0) if(pnp_activate_dev(pnp_dev)<0)
return -1; return -1;
if (pnp_drv->probe && pnp_dev->active) { 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); dev_id = match_device(pnp_drv, pnp_dev);
if (dev_id != NULL) if (dev_id != NULL)
error = pnp_drv->probe(pnp_dev, card_id, dev_id); error = pnp_drv->probe(pnp_dev, 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){ if (error >= 0){
pnp_dev->driver = pnp_drv; pnp_dev->driver = pnp_drv;
error = 0; error = 0;
} }
}
return error; return error;
} }
...@@ -133,9 +108,6 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv) ...@@ -133,9 +108,6 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv)
{ {
struct pnp_dev * pnp_dev = to_pnp_dev(dev); struct pnp_dev * pnp_dev = to_pnp_dev(dev);
struct pnp_driver * pnp_drv = to_pnp_driver(drv); 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) if (match_device(pnp_drv, pnp_dev) == NULL)
return 0; return 0;
return 1; return 1;
...@@ -174,8 +146,8 @@ int pnp_register_driver(struct pnp_driver *drv) ...@@ -174,8 +146,8 @@ int pnp_register_driver(struct pnp_driver *drv)
void pnp_unregister_driver(struct pnp_driver *drv) void pnp_unregister_driver(struct pnp_driver *drv)
{ {
pnp_dbg("the driver '%s' has been unregistered", drv->name);
driver_unregister(&drv->driver); driver_unregister(&drv->driver);
pnp_dbg("the driver '%s' has been unregistered", drv->name);
} }
/** /**
...@@ -187,25 +159,21 @@ void pnp_unregister_driver(struct pnp_driver *drv) ...@@ -187,25 +159,21 @@ void pnp_unregister_driver(struct pnp_driver *drv)
int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
{ {
struct pnp_id *ptr;
if (!id) if (!id)
return -EINVAL; return -EINVAL;
if (!dev) if (!dev)
return -EINVAL; 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; 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); EXPORT_SYMBOL(pnp_register_driver);
EXPORT_SYMBOL(pnp_unregister_driver); EXPORT_SYMBOL(pnp_unregister_driver);
EXPORT_SYMBOL(pnp_add_id); EXPORT_SYMBOL(pnp_add_id);
...@@ -321,13 +321,13 @@ static DEVICE_ATTR(resources,S_IRUGO | S_IWUSR, ...@@ -321,13 +321,13 @@ static DEVICE_ATTR(resources,S_IRUGO | S_IWUSR,
static ssize_t pnp_show_current_ids(struct device *dmdev, char *buf, size_t count, loff_t off) static ssize_t pnp_show_current_ids(struct device *dmdev, char *buf, size_t count, loff_t off)
{ {
char *str = buf; char *str = buf;
struct list_head * pos;
struct pnp_dev *dev = to_pnp_dev(dmdev); struct pnp_dev *dev = to_pnp_dev(dmdev);
struct pnp_id * pos = dev->id;
if (off) if (off)
return 0; return 0;
list_for_each(pos,&dev->ids) { while (pos) {
struct pnp_id * cur = to_pnp_id(pos); str += sprintf(str,"%s\n", pos->id);
str += sprintf(str,"%s\n", cur->id); pos = pos->next;
} }
return (str - buf); return (str - buf);
} }
......
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
# Makefile for the kernel ISAPNP driver. # Makefile for the kernel ISAPNP driver.
# #
export-objs := core.o compat.o export-objs := core.o
isapnp-proc-$(CONFIG_PROC_FS) = proc.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 include $(TOPDIR)/Rules.make
...@@ -449,13 +449,13 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si ...@@ -449,13 +449,13 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si
dev = isapnp_alloc(sizeof(struct pnp_dev)); dev = isapnp_alloc(sizeof(struct pnp_dev));
if (!dev) if (!dev)
return NULL; return NULL;
pnp_init_device(dev);
dev->number = number; dev->number = number;
isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]); isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]);
dev->regs = tmp[4]; dev->regs = tmp[4];
dev->card = card; dev->card = card;
if (size > 5) if (size > 5)
dev->regs |= tmp[5] << 8; dev->regs |= tmp[5] << 8;
dev->protocol = &isapnp_protocol;
return dev; return dev;
} }
...@@ -640,7 +640,7 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -640,7 +640,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
return 1; return 1;
if (pnp_build_resource(dev, 0) == NULL) if (pnp_build_resource(dev, 0) == NULL)
return 1; return 1;
list_add_tail(&dev->card_list, &card->devices); pnpc_add_device(card,dev);
while (1) { while (1) {
if (isapnp_read_tag(&type, &size)<0) if (isapnp_read_tag(&type, &size)<0)
return 1; return 1;
...@@ -653,7 +653,7 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -653,7 +653,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
if ((dev = isapnp_parse_device(card, size, number++)) == NULL) if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1; return 1;
pnp_build_resource(dev,0); pnp_build_resource(dev,0);
list_add_tail(&dev->card_list, &card->devices); pnpc_add_device(card,dev);
size = 0; size = 0;
skip = 0; skip = 0;
} else { } else {
...@@ -848,7 +848,7 @@ static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor, ...@@ -848,7 +848,7 @@ static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor,
device & 0x0f, device & 0x0f,
(device >> 12) & 0x0f, (device >> 12) & 0x0f,
(device >> 8) & 0x0f); (device >> 8) & 0x0f);
list_add_tail(&id->id_list,&card->ids); pnpc_add_id(id,card);
} }
/* /*
...@@ -879,12 +879,11 @@ static int __init isapnp_build_device_list(void) ...@@ -879,12 +879,11 @@ static int __init isapnp_build_device_list(void)
; ;
else if (checksum == 0x00 || checksum != header[8]) /* not valid CSN */ else if (checksum == 0x00 || checksum != header[8]) /* not valid CSN */
continue; continue;
if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL) if ((card = isapnp_alloc(sizeof(struct pnp_card))) == NULL)
continue; continue;
card->number = csn; card->number = csn;
INIT_LIST_HEAD(&card->devices); 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]); 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]; card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
isapnp_checksum_value = 0x00; isapnp_checksum_value = 0x00;
...@@ -892,8 +891,8 @@ static int __init isapnp_build_device_list(void) ...@@ -892,8 +891,8 @@ static int __init isapnp_build_device_list(void)
if (isapnp_checksum_value != 0x00) if (isapnp_checksum_value != 0x00)
printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value); printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);
card->checksum = isapnp_checksum_value; card->checksum = isapnp_checksum_value;
card->protocol = &isapnp_protocol;
list_add_tail(&card->node, &isapnp_cards); pnpc_add_card(card);
} }
return 0; return 0;
} }
...@@ -1061,25 +1060,6 @@ struct pnp_protocol isapnp_protocol = { ...@@ -1061,25 +1060,6 @@ struct pnp_protocol isapnp_protocol = {
.disable = isapnp_disable_resources, .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 __init isapnp_init(void)
{ {
int cards; int cards;
...@@ -1104,7 +1084,7 @@ int __init isapnp_init(void) ...@@ -1104,7 +1084,7 @@ int __init isapnp_init(void)
return -EBUSY; return -EBUSY;
} }
if(pnp_protocol_register(&isapnp_protocol)<0) if(pnp_register_protocol(&isapnp_protocol)<0)
return -EBUSY; return -EBUSY;
/* /*
...@@ -1143,7 +1123,7 @@ int __init isapnp_init(void) ...@@ -1143,7 +1123,7 @@ int __init isapnp_init(void)
isapnp_build_device_list(); isapnp_build_device_list();
cards = 0; cards = 0;
isapnp_for_each_card(card) { protocol_for_each_card(&isapnp_protocol,card) {
cards++; cards++;
if (isapnp_verbose) { if (isapnp_verbose) {
struct list_head *devlist; struct list_head *devlist;
...@@ -1162,7 +1142,6 @@ int __init isapnp_init(void) ...@@ -1162,7 +1142,6 @@ int __init isapnp_init(void)
printk(KERN_INFO "isapnp: No Plug & Play card found\n"); printk(KERN_INFO "isapnp: No Plug & Play card found\n");
} }
isapnp_init_device_tree();
isapnp_proc_init(); isapnp_proc_init();
return 0; return 0;
} }
......
...@@ -146,7 +146,7 @@ int __init isapnp_proc_init(void) ...@@ -146,7 +146,7 @@ int __init isapnp_proc_init(void)
{ {
struct pnp_dev *dev; struct pnp_dev *dev;
isapnp_proc_bus_dir = proc_mkdir("isapnp", proc_bus); 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); isapnp_proc_attach_device(dev);
} }
return 0; return 0;
......
...@@ -32,7 +32,7 @@ pnp_name_device(struct pnp_dev *dev) ...@@ -32,7 +32,7 @@ pnp_name_device(struct pnp_dev *dev)
int i; int i;
char *name = dev->name; char *name = dev->name;
for(i=0; i<sizeof(pnp_id_eisaid)/sizeof(pnp_id_eisaid[0]); i++){ for(i=0; i<sizeof(pnp_id_eisaid)/sizeof(pnp_id_eisaid[0]); i++){
if (compare_pnp_id(&dev->ids,pnp_id_eisaid[i])){ if (compare_pnp_id(dev->id,pnp_id_eisaid[i])){
sprintf(name, "%s", pnp_id_names[i]); sprintf(name, "%s", pnp_id_names[i]);
return; return;
} }
......
...@@ -1256,6 +1256,12 @@ static int pnpbios_get_resources(struct pnp_dev *dev) ...@@ -1256,6 +1256,12 @@ static int pnpbios_get_resources(struct pnp_dev *dev)
struct pnp_dev_node_info node_info; struct pnp_dev_node_info node_info;
u8 nodenum = dev->number; u8 nodenum = dev->number;
struct pnp_bios_node * node; 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) if (pnp_bios_dev_node_info(&node_info) != 0)
return -ENODEV; return -ENODEV;
node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
...@@ -1273,10 +1279,15 @@ static int pnpbios_set_resources(struct pnp_dev *dev, struct pnp_cfg *config, ch ...@@ -1273,10 +1279,15 @@ static int pnpbios_set_resources(struct pnp_dev *dev, struct pnp_cfg *config, ch
struct pnp_dev_node_info node_info; struct pnp_dev_node_info node_info;
u8 nodenum = dev->number; u8 nodenum = dev->number;
struct pnp_bios_node * node; 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) if (pnp_bios_dev_node_info(&node_info) != 0)
return -ENODEV; return -ENODEV;
node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) if (!node)
return -1; return -1;
if (pnp_bios_get_dev_node(&nodenum, (char )1, node)) if (pnp_bios_get_dev_node(&nodenum, (char )1, node))
...@@ -1323,16 +1334,21 @@ static int pnpbios_disable_resources(struct pnp_dev *dev) ...@@ -1323,16 +1334,21 @@ static int pnpbios_disable_resources(struct pnp_dev *dev)
struct pnp_bios_node * node; struct pnp_bios_node * node;
if (!config) if (!config)
return -1; 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)); memset(config, 0, sizeof(struct pnp_cfg));
if (!dev || !dev->active) if (!dev || !dev->active)
return -EINVAL; return -EINVAL;
for (i=0; i <= 8; i++) for (i=0; i < 8; i++)
config->port[i] = &port; config->port[i] = &port;
for (i=0; i <= 4; i++) for (i=0; i < 4; i++)
config->mem[i] = &mem; config->mem[i] = &mem;
for (i=0; i <= 2; i++) for (i=0; i < 2; i++)
config->irq[i] = &irq; config->irq[i] = &irq;
for (i=0; i <= 2; i++) for (i=0; i < 2; i++)
config->dma[i] = &dma; config->dma[i] = &dma;
dev->active = 0; dev->active = 0;
...@@ -1369,7 +1385,7 @@ static int inline insert_device(struct pnp_dev *dev) ...@@ -1369,7 +1385,7 @@ static int inline insert_device(struct pnp_dev *dev)
struct list_head * pos; struct list_head * pos;
struct pnp_dev * pnp_dev; struct pnp_dev * pnp_dev;
list_for_each (pos, &pnpbios_protocol.devices){ 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) if (dev->number == pnp_dev->number)
return -1; return -1;
} }
...@@ -1402,10 +1418,13 @@ static void __init build_devlist(void) ...@@ -1402,10 +1418,13 @@ static void __init build_devlist(void)
for(nodenum=0; nodenum<0xff; ) { for(nodenum=0; nodenum<0xff; ) {
u8 thisnodenum = nodenum; u8 thisnodenum = nodenum;
/* We build the list from the "boot" config because /* We build the list from the "boot" config because
* asking for the "current" config causes some * we know that the resources couldn't have changed
* BIOSes to crash. * 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; break;
nodes_got++; nodes_got++;
dev = pnpbios_kmalloc(sizeof (struct pnp_dev), GFP_KERNEL); dev = pnpbios_kmalloc(sizeof (struct pnp_dev), GFP_KERNEL);
...@@ -1416,7 +1435,6 @@ static void __init build_devlist(void) ...@@ -1416,7 +1435,6 @@ static void __init build_devlist(void)
if (!dev_id) if (!dev_id)
break; break;
memset(dev_id,0,sizeof(struct pnp_id)); memset(dev_id,0,sizeof(struct pnp_id));
pnp_init_device(dev);
dev->number = thisnodenum; dev->number = thisnodenum;
memcpy(dev->name,"Unknown Device",13); memcpy(dev->name,"Unknown Device",13);
dev->name[14] = '\0'; dev->name[14] = '\0';
...@@ -1426,6 +1444,7 @@ static void __init build_devlist(void) ...@@ -1426,6 +1444,7 @@ static void __init build_devlist(void)
pos = node_current_resource_data_to_dev(node,dev); pos = node_current_resource_data_to_dev(node,dev);
pos = node_possible_resource_data_to_dev(pos,node,dev); pos = node_possible_resource_data_to_dev(pos,node,dev);
node_id_data_to_dev(pos,node,dev); node_id_data_to_dev(pos,node,dev);
dev->flags = node->flags;
dev->protocol = &pnpbios_protocol; dev->protocol = &pnpbios_protocol;
...@@ -1450,10 +1469,7 @@ static void __init build_devlist(void) ...@@ -1450,10 +1469,7 @@ static void __init build_devlist(void)
* *
*/ */
extern int is_sony_vaio_laptop;
static int pnpbios_disabled; /* = 0 */ static int pnpbios_disabled; /* = 0 */
static int dont_reserve_resources; /* = 0 */
int pnpbios_dont_use_current_config; /* = 0 */ int pnpbios_dont_use_current_config; /* = 0 */
#ifndef MODULE #ifndef MODULE
...@@ -1471,8 +1487,6 @@ static int __init pnpbios_setup(char *str) ...@@ -1471,8 +1487,6 @@ static int __init pnpbios_setup(char *str)
str += 3; str += 3;
if (strncmp(str, "curr", 4) == 0) if (strncmp(str, "curr", 4) == 0)
pnpbios_dont_use_current_config = invert; pnpbios_dont_use_current_config = invert;
if (strncmp(str, "res", 3) == 0)
dont_reserve_resources = invert;
str = strchr(str, ','); str = strchr(str, ',');
if (str != NULL) if (str != NULL)
str += strspn(str, ", \t"); str += strspn(str, ", \t");
...@@ -1499,9 +1513,6 @@ int __init pnpbios_init(void) ...@@ -1499,9 +1513,6 @@ int __init pnpbios_init(void)
return -ENODEV; return -ENODEV;
} }
if ( is_sony_vaio_laptop )
pnpbios_dont_use_current_config = 1;
/* /*
* Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
* structure and, if one is found, sets up the selectors and * structure and, if one is found, sets up the selectors and
...@@ -1544,7 +1555,7 @@ int __init pnpbios_init(void) ...@@ -1544,7 +1555,7 @@ int __init pnpbios_init(void)
} }
if (!pnp_bios_present()) if (!pnp_bios_present())
return -ENODEV; return -ENODEV;
pnp_protocol_register(&pnpbios_protocol); pnp_register_protocol(&pnpbios_protocol);
build_devlist(); build_devlist();
/*if ( ! dont_reserve_resources )*/ /*if ( ! dont_reserve_resources )*/
/*reserve_resources();*/ /*reserve_resources();*/
......
...@@ -157,7 +157,7 @@ void pnp_fixup_device(struct pnp_dev *dev) ...@@ -157,7 +157,7 @@ void pnp_fixup_device(struct pnp_dev *dev)
int i = 0; int i = 0;
while (*pnp_fixups[i].id) { 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", pnp_dbg("Calling quirk for %s",
dev->dev.bus_id); dev->dev.bus_id);
pnp_fixups[i].quirk_function(dev); pnp_fixups[i].quirk_function(dev);
......
...@@ -13,12 +13,7 @@ ...@@ -13,12 +13,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/ioport.h> #include <linux/ioport.h>
static const struct pnp_id pnp_card_table[] = { static const struct pnp_device_id pnp_dev_table[] = {
{ "ANYDEVS", 0 },
{ "", 0 }
};
static const struct pnp_id pnp_dev_table[] = {
/* General ID for reserving resources */ /* General ID for reserving resources */
{ "PNP0c02", 0 }, { "PNP0c02", 0 },
/* memory controller */ /* memory controller */
...@@ -101,7 +96,7 @@ static void __init reserve_resources_of_dev( struct pnp_dev *dev ) ...@@ -101,7 +96,7 @@ static void __init reserve_resources_of_dev( struct pnp_dev *dev )
return; 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); reserve_resources_of_dev(dev);
return 0; return 0;
...@@ -109,7 +104,6 @@ static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, ...@@ -109,7 +104,6 @@ static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id,
static struct pnp_driver system_pnp_driver = { static struct pnp_driver system_pnp_driver = {
.name = "system", .name = "system",
.card_id_table = pnp_card_table,
.id_table = pnp_dev_table, .id_table = pnp_dev_table,
.probe = system_pnp_probe, .probe = system_pnp_probe,
.remove = NULL, .remove = NULL,
......
...@@ -33,12 +33,7 @@ ...@@ -33,12 +33,7 @@
#define UNKNOWN_DEV 0x3000 #define UNKNOWN_DEV 0x3000
static const struct pnp_id pnp_card_table[] = { static const struct pnp_device_id pnp_dev_table[] = {
{ "ANYDEVS", 0 },
{ "", 0 }
};
static const struct pnp_id pnp_dev_table[] = {
/* Archtek America Corp. */ /* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */ /* Archtek SmartLink Modem 3334BT Plug & Play */
{ "AAC000F", 0 }, { "AAC000F", 0 },
...@@ -316,6 +311,8 @@ static const struct pnp_id pnp_dev_table[] = { ...@@ -316,6 +311,8 @@ static const struct pnp_id pnp_dev_table[] = {
{ "", 0 } { "", 0 }
}; };
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
static void inline avoid_irq_share(struct pnp_dev *dev) static void inline avoid_irq_share(struct pnp_dev *dev)
{ {
unsigned int map = 0x1FF8; unsigned int map = 0x1FF8;
...@@ -384,7 +381,7 @@ static int serial_pnp_guess_board(struct pnp_dev *dev, int *flags) ...@@ -384,7 +381,7 @@ static int serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
} }
static int 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; struct serial_struct serial_req;
int ret, line, flags = dev_id->driver_data; int ret, line, flags = dev_id->driver_data;
...@@ -393,10 +390,10 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struc ...@@ -393,10 +390,10 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struc
if (flags & SPCI_FL_NO_SHIRQ) if (flags & SPCI_FL_NO_SHIRQ)
avoid_irq_share(dev); avoid_irq_share(dev);
memset(&serial_req, 0, sizeof(serial_req)); memset(&serial_req, 0, sizeof(serial_req));
serial_req.irq = dev->irq_resource[0].start; serial_req.irq = pnp_irq(dev,0);
serial_req.port = pci_resource_start(dev, 0); serial_req.port = pnp_port_start(dev, 0);
if (HIGH_BITS_OFFSET) 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 #ifdef SERIAL_DEBUG_PNP
printk("Setup PNP port: port %x, irq %d, type %d\n", printk("Setup PNP port: port %x, irq %d, type %d\n",
serial_req.port, serial_req.irq, serial_req.io_type); serial_req.port, serial_req.irq, serial_req.io_type);
...@@ -407,7 +404,7 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struc ...@@ -407,7 +404,7 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struc
line = register_serial(&serial_req); line = register_serial(&serial_req);
if (line >= 0) if (line >= 0)
dev->driver_data = (void *)(line + 1); pnp_set_drvdata(dev, (void *)(line + 1));
return line >= 0 ? 0 : -ENODEV; return line >= 0 ? 0 : -ENODEV;
} }
...@@ -419,7 +416,6 @@ static void serial_pnp_remove(struct pnp_dev * dev) ...@@ -419,7 +416,6 @@ static void serial_pnp_remove(struct pnp_dev * dev)
static struct pnp_driver serial_pnp_driver = { static struct pnp_driver serial_pnp_driver = {
.name = "serial", .name = "serial",
.card_id_table = pnp_card_table,
.id_table = pnp_dev_table, .id_table = pnp_dev_table,
.probe = serial_pnp_probe, .probe = serial_pnp_probe,
.remove = serial_pnp_remove, .remove = serial_pnp_remove,
...@@ -442,5 +438,3 @@ EXPORT_NO_SYMBOLS; ...@@ -442,5 +438,3 @@ EXPORT_NO_SYMBOLS;
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver"); MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver");
/* FIXME */
/*MODULE_DEVICE_TABLE(pnpbios, pnp_dev_table);*/
/*
* Linux Plug and Play Support
* Copyright by Adam Belay <ambx1@neo.rr.com>
*
*/
#ifndef _LINUX_PNP_H #ifndef _LINUX_PNP_H
#define _LINUX_PNP_H #define _LINUX_PNP_H
...@@ -5,107 +11,210 @@ ...@@ -5,107 +11,210 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/errno.h>
/* Device Managemnt */ /*
* Device Managemnt
*/
#define DEVICE_COUNT_IRQ 2 #define DEVICE_COUNT_IRQ 2
#define DEVICE_COUNT_DMA 2 #define DEVICE_COUNT_DMA 2
#define DEVICE_COUNT_RESOURCE 12 #define DEVICE_COUNT_RESOURCE 12
#define MAX_DEVICES 8
struct pnp_resource; struct pnp_resource;
struct pnp_protocol; struct pnp_protocol;
struct pnp_id;
struct pnp_card { /* this is for ISAPNP */ struct pnp_card {
struct list_head node; /* node in list of cards */
char name[80]; char name[80];
unsigned char number; /* card number */ 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 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 pnpver; /* Plug & Play version */
unsigned char productver; /* product version */ unsigned char productver; /* product version */
unsigned int serial; /* serial number */ unsigned int serial; /* serial number */
unsigned char checksum; /* if zero - checksum passed */ 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 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 { struct pnp_dev {
char name[80]; /* device name */ char name[80]; /* device name */
int active; /* status of the device */ int active; /* status of the device */
int ro; /* read only */ int ro; /* read only */
struct list_head dev_list; /* node in list of device's protocol */ struct list_head global_list; /* node in global list of devices */
struct list_head global_list; struct list_head protocol_list; /* node in list of device's protocol */
struct list_head card_list; 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_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 char number; /* must be unique */
unsigned short regs; /* ISAPnP: supported registers */ unsigned short regs; /* ISAPnP: supported registers */
struct list_head ids; /* stores all supported dev ids */
struct pnp_resources *res; /* possible resource information */ struct pnp_resources *res; /* possible resource information */
struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
struct resource dma_resource[DEVICE_COUNT_DMA]; struct resource dma_resource[DEVICE_COUNT_DMA];
struct resource irq_resource[DEVICE_COUNT_IRQ]; 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 */ struct device dev; /* Driver Model device interface */
void * driver_data;/* data private to the driver */ int flags; /* used by protocols */
void * protocol_data;
struct proc_dir_entry *procent; /* device entry in /proc/bus/isapnp */ 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 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 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 to_pnp_dev(n) container_of(n, struct pnp_dev, dev)
#define pnp_for_each_dev(dev) \ #define pnp_for_each_dev(dev) \
for(dev = global_to_pnp_dev(pnp_global.next); \ for(dev = global_to_pnp_dev(pnp_global.next); \
dev != global_to_pnp_dev(&pnp_global); \ dev != global_to_pnp_dev(&pnp_global); \
dev = global_to_pnp_dev(dev->global_list.next)) 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 { struct pnp_fixup {
char id[7]; char id[7];
void (*quirk_function)(struct pnp_dev *dev); /* fixup function */ void (*quirk_function)(struct pnp_dev *dev); /* fixup function */
}; };
/* /*
* Linux Plug and Play Support * Driver Management
* Copyright by Adam Belay <ambx1@neo.rr.com>
*
*/ */
/* Driver Management */
struct pnp_id { struct pnp_id {
char id[7];
struct pnp_id * next;
};
struct pnp_device_id {
char id[7]; char id[7];
unsigned long driver_data; /* data private to the driver */ 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 pnp_driver {
struct list_head node; struct list_head node;
char *name; char *name;
const struct pnp_id *card_id_table; const struct pnp_device_id *id_table;
const struct pnp_id *id_table; int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
int (*probe) (struct pnp_dev *dev, const struct pnp_id *card_id,
const struct pnp_id *dev_id);
void (*remove) (struct pnp_dev *dev); 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) #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 */ /*
* Resource Management
*/
#define DEV_IO(dev, index) (dev->resource[index].start) /* Use these instead of directly reading pnp_dev to get resource information */
#define DEV_MEM(dev, index) (dev->resource[index+8].start) #define pnp_port_start(dev,bar) ((dev)->resource[(bar)].start)
#define DEV_IRQ(dev, index) (dev->irq_resource[index].start) #define pnp_port_end(dev,bar) ((dev)->resource[(bar)].end)
#define DEV_DMA(dev, index) (dev->dma_resource[index].start) #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))
#define pnp_irq(dev,bar) ((dev)->irq_resource[(bar)].start)
#define pnp_irq_flags(dev,bar) ((dev)->irq_resource[(bar)].flags)
#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_16BITADDR (1<<0)
#define PNP_PORT_FLAG_FIXED (1<<1) #define PNP_PORT_FLAG_FIXED (1<<1)
...@@ -182,7 +291,9 @@ struct pnp_cfg { ...@@ -182,7 +291,9 @@ struct pnp_cfg {
}; };
/* Protocol Management */ /*
* Protocol Management
*/
struct pnp_protocol { struct pnp_protocol {
struct list_head protocol_list; struct list_head protocol_list;
...@@ -196,18 +307,26 @@ struct pnp_protocol { ...@@ -196,18 +307,26 @@ struct pnp_protocol {
/* used by pnp layer only (look but don't touch) */ /* used by pnp layer only (look but don't touch) */
unsigned char number; /* protocol number*/ unsigned char number; /* protocol number*/
struct device dev; /* link to driver model */ struct device dev; /* link to driver model */
struct list_head cards;
struct list_head devices; struct list_head devices;
}; };
#define to_pnp_protocol(n) list_entry(n, struct pnp_protocol, protocol_list) #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) #if defined(CONFIG_PNP)
/* core */ /* core */
int pnp_protocol_register(struct pnp_protocol *protocol); int pnp_register_protocol(struct pnp_protocol *protocol);
void pnp_protocol_unregister(struct pnp_protocol *protocol); void pnp_unregister_protocol(struct pnp_protocol *protocol);
int pnp_init_device(struct pnp_dev *dev);
int pnp_add_device(struct pnp_dev *dev); int pnp_add_device(struct pnp_dev *dev);
void pnp_remove_device(struct pnp_dev *dev); void pnp_remove_device(struct pnp_dev *dev);
extern struct list_head pnp_global; extern struct list_head pnp_global;
...@@ -226,7 +345,7 @@ int pnp_disable_dev(struct pnp_dev *dev); ...@@ -226,7 +345,7 @@ int pnp_disable_dev(struct pnp_dev *dev);
int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode); int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode);
/* driver */ /* 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_add_id(struct pnp_id *id, struct pnp_dev *dev);
int pnp_register_driver(struct pnp_driver *drv); int pnp_register_driver(struct pnp_driver *drv);
void pnp_unregister_driver(struct pnp_driver *drv); void pnp_unregister_driver(struct pnp_driver *drv);
...@@ -234,8 +353,8 @@ void pnp_unregister_driver(struct pnp_driver *drv); ...@@ -234,8 +353,8 @@ void pnp_unregister_driver(struct pnp_driver *drv);
#else #else
/* just in case anyone decides to call these without PnP Support Enabled */ /* 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 int pnp_register_protocol(struct pnp_protocol *protocol) { return -ENODEV; }
static inline void pnp_protocol_unregister(struct pnp_protocol *protocol) { } 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_init_device(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_add_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) { } static inline void pnp_remove_device(struct pnp_dev *dev) { }
...@@ -250,14 +369,45 @@ static inline int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct ...@@ -250,14 +369,45 @@ static inline int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct
static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; } 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_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 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_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 int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; } static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; }
#endif /* CONFIG_PNP */ #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) #if defined(CONFIG_ISAPNP)
/* compat */ /* compat */
struct pnp_card *pnp_find_card(unsigned short vendor, struct pnp_card *pnp_find_card(unsigned short vendor,
unsigned short device, unsigned short device,
......
...@@ -75,6 +75,19 @@ ...@@ -75,6 +75,19 @@
#define PNPMSG_POWER_OFF 0x41 #define PNPMSG_POWER_OFF 0x41
#define PNPMSG_PNP_OS_ACTIVE 0x42 #define PNPMSG_PNP_OS_ACTIVE 0x42
#define PNPMSG_PNP_OS_INACTIVE 0x43 #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 */ /* 0x8000 through 0xffff are OEM defined */
#pragma pack(1) #pragma pack(1)
......
...@@ -61,16 +61,18 @@ extern struct proc_dir_entry *proc_net_rpc; ...@@ -61,16 +61,18 @@ extern struct proc_dir_entry *proc_net_rpc;
#else #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 void svc_proc_unregister(const char *p) {}
static inline struct proc_dir_entry*svc_proc_register(struct svc_stat *s) 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) {}
return NULL;
} #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
#endif /* _LINUX_SUNRPC_STATS_H */ #endif /* _LINUX_SUNRPC_STATS_H */
...@@ -24,11 +24,7 @@ ...@@ -24,11 +24,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/slab.h> #include <linux/slab.h>
#ifndef LINUX_ISAPNP_H #include <linux/pnp.h>
#include <linux/isapnp.h>
#define isapnp_card pci_bus
#define isapnp_dev pci_dev
#endif
#include <sound/core.h> #include <sound/core.h>
#include <sound/cs4231.h> #include <sound/cs4231.h>
#include <sound/mpu401.h> #include <sound/mpu401.h>
...@@ -51,7 +47,7 @@ MODULE_DEVICES("{{Yamaha,YMF719E-S}," ...@@ -51,7 +47,7 @@ MODULE_DEVICES("{{Yamaha,YMF719E-S},"
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable 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}; static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif #endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0xf86,0x370,0x100 */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0xf86,0x370,0x100 */
...@@ -73,7 +69,7 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC); ...@@ -73,7 +69,7 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(enable, "Enable OPL3-SA soundcard."); MODULE_PARM_DESC(enable, "Enable OPL3-SA soundcard.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
MODULE_PARM(isapnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(isapnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard."); MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
MODULE_PARM_SYNTAX(isapnp, SNDRV_ISAPNP_DESC); MODULE_PARM_SYNTAX(isapnp, SNDRV_ISAPNP_DESC);
...@@ -147,8 +143,8 @@ struct snd_opl3sa2 { ...@@ -147,8 +143,8 @@ struct snd_opl3sa2 {
snd_hwdep_t *synth; snd_hwdep_t *synth;
snd_rawmidi_t *rmidi; snd_rawmidi_t *rmidi;
cs4231_t *cs4231; cs4231_t *cs4231;
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
struct isapnp_dev *dev; struct pnp_dev *dev;
#endif #endif
unsigned char ctlregs[0x20]; unsigned char ctlregs[0x20];
int ymode; /* SL added */ int ymode; /* SL added */
...@@ -163,33 +159,27 @@ struct snd_opl3sa2 { ...@@ -163,33 +159,27 @@ struct snd_opl3sa2 {
static snd_card_t *snd_opl3sa2_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; static snd_card_t *snd_opl3sa2_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
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;
#define ISAPNP_OPL3SA2(_va, _vb, _vc, _device, _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;
ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _function), } \
}
static struct isapnp_card_id snd_opl3sa2_pnpids[] __devinitdata = { static struct pnp_card_id snd_opl3sa2_pnpids[] = {
/* Yamaha YMF719E-S (Genius Sound Maker 3DX) */ /* 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) */ /* 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 */ /* Yamaha OPL3-SA2 */
ISAPNP_OPL3SA2('Y','M','H',0x0800,0x0021), {.id = "YMH0800", .driver_data = 0, devs : { {.id="YMH0021"}, } },
/* NeoMagic MagicWave 3DX */ /* 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) */ /* read control port (w/o spinlock) */
...@@ -634,41 +624,18 @@ static int snd_opl3sa2_pm_callback(struct pm_dev *dev, pm_request_t rqst, void * ...@@ -634,41 +624,18 @@ static int snd_opl3sa2_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
static int __init snd_opl3sa2_isapnp(int dev, opl3sa2_t *chip) static int __init snd_opl3sa2_isapnp(int dev, opl3sa2_t *chip)
{ {
const struct isapnp_card_id *id = snd_opl3sa2_isapnp_id[dev]; const struct pnp_card_id *id = snd_opl3sa2_isapnp_id[dev];
struct isapnp_card *card = snd_opl3sa2_isapnp_cards[dev]; struct pnp_card *card = snd_opl3sa2_isapnp_cards[dev];
struct isapnp_dev *pdev; struct pnp_dev *pdev;
chip->dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL); chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
if (chip->dev->active) {
chip->dev = NULL;
return -EBUSY;
}
/* PnP initialization */
pdev = chip->dev; pdev = chip->dev;
if (pdev->prepare(pdev)<0) if (!pdev){
return -EAGAIN; snd_printdd("isapnp OPL3-SA: a card was found but it did not contain the needed devices\n",);
if (sb_port[dev] != SNDRV_AUTO_PORT) return -ENODEV;
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;
} }
sb_port[dev] = pdev->resource[0].start; sb_port[dev] = pdev->resource[0].start;
wss_port[dev] = pdev->resource[1].start; wss_port[dev] = pdev->resource[1].start;
...@@ -685,19 +652,12 @@ static int __init snd_opl3sa2_isapnp(int dev, opl3sa2_t *chip) ...@@ -685,19 +652,12 @@ static int __init snd_opl3sa2_isapnp(int dev, opl3sa2_t *chip)
return 0; return 0;
} }
static void snd_opl3sa2_deactivate(opl3sa2_t *chip) #endif /* CONFIG_PNP */
{
if (chip->dev) {
chip->dev->deactivate(chip->dev);
chip->dev = NULL;
}
}
#endif /* __ISAPNP__ */
static int snd_opl3sa2_free(opl3sa2_t *chip) static int snd_opl3sa2_free(opl3sa2_t *chip)
{ {
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
snd_opl3sa2_deactivate(chip); chip->dev = NULL;
#endif #endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
if (chip->pm_dev) if (chip->pm_dev)
...@@ -731,7 +691,7 @@ static int __init snd_opl3sa2_probe(int dev) ...@@ -731,7 +691,7 @@ static int __init snd_opl3sa2_probe(int dev)
}; };
int err; int err;
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (!isapnp[dev]) { if (!isapnp[dev]) {
#endif #endif
if (port[dev] == SNDRV_AUTO_PORT) { if (port[dev] == SNDRV_AUTO_PORT) {
...@@ -750,7 +710,7 @@ static int __init snd_opl3sa2_probe(int dev) ...@@ -750,7 +710,7 @@ static int __init snd_opl3sa2_probe(int dev)
snd_printk("specify midi_port\n"); snd_printk("specify midi_port\n");
return -EINVAL; return -EINVAL;
} }
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
} }
#endif #endif
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
...@@ -766,7 +726,7 @@ static int __init snd_opl3sa2_probe(int dev) ...@@ -766,7 +726,7 @@ static int __init snd_opl3sa2_probe(int dev)
chip->irq = -1; chip->irq = -1;
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
goto __error; goto __error;
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (isapnp[dev] && (err = snd_opl3sa2_isapnp(dev, chip)) < 0) if (isapnp[dev] && (err = snd_opl3sa2_isapnp(dev, chip)) < 0)
goto __error; goto __error;
#endif #endif
...@@ -854,9 +814,9 @@ static int __init snd_opl3sa2_probe(int dev) ...@@ -854,9 +814,9 @@ static int __init snd_opl3sa2_probe(int dev)
return err; return err;
} }
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
static int __init snd_opl3sa2_isapnp_detect(struct isapnp_card *card, static int __init snd_opl3sa2_isapnp_detect(struct pnp_card *card,
const struct isapnp_card_id *id) const struct pnp_card_id *id)
{ {
static int dev; static int dev;
int res; int res;
...@@ -874,7 +834,20 @@ static int __init snd_opl3sa2_isapnp_detect(struct isapnp_card *card, ...@@ -874,7 +834,20 @@ static int __init snd_opl3sa2_isapnp_detect(struct isapnp_card *card,
} }
return -ENODEV; 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) static int __init alsa_card_opl3sa2_init(void)
{ {
...@@ -883,15 +856,15 @@ static int __init alsa_card_opl3sa2_init(void) ...@@ -883,15 +856,15 @@ static int __init alsa_card_opl3sa2_init(void)
for (dev = 0; dev < SNDRV_CARDS; dev++) { for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev]) if (!enable[dev])
continue; continue;
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (isapnp[dev]) if (isapnp[dev])
continue; continue;
#endif #endif
if (snd_opl3sa2_probe(dev) >= 0) if (snd_opl3sa2_probe(dev) >= 0)
cards++; cards++;
} }
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
cards += isapnp_probe_cards(snd_opl3sa2_pnpids, snd_opl3sa2_isapnp_detect); cards += pnpc_register_driver(&opl3sa2_pnpc_driver);
#endif #endif
if (!cards) { if (!cards) {
#ifdef MODULE #ifdef MODULE
...@@ -940,7 +913,7 @@ static int __init alsa_card_opl3sa2_setup(char *str) ...@@ -940,7 +913,7 @@ static int __init alsa_card_opl3sa2_setup(char *str)
get_option(&str,&dma1[nr_dev]) == 2 && get_option(&str,&dma1[nr_dev]) == 2 &&
get_option(&str,&dma2[nr_dev]) == 2 && get_option(&str,&dma2[nr_dev]) == 2 &&
get_option(&str,&opl3sa3_ymode[nr_dev]) == 2); get_option(&str,&opl3sa3_ymode[nr_dev]) == 2);
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
if (pnp != INT_MAX) if (pnp != INT_MAX)
isapnp[nr_dev] = pnp; isapnp[nr_dev] = pnp;
#endif #endif
......
...@@ -841,10 +841,9 @@ struct pnp_id pnp_opl3sa2_list[] = { ...@@ -841,10 +841,9 @@ struct pnp_id pnp_opl3sa2_list[] = {
{.id = ""} {.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, static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *dev_id)
const struct pnp_id *dev_id)
{ {
int card = opl3sa2_cards_num; int card = opl3sa2_cards_num;
if (opl3sa2_cards_num == OPL3SA2_CARDS_MAX) if (opl3sa2_cards_num == OPL3SA2_CARDS_MAX)
...@@ -883,7 +882,6 @@ static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *card_id, ...@@ -883,7 +882,6 @@ static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *card_id,
static struct pnp_driver opl3sa2_driver = { static struct pnp_driver opl3sa2_driver = {
.name = "opl3sa2", .name = "opl3sa2",
.card_id_table = NULL,
.id_table = pnp_opl3sa2_list, .id_table = pnp_opl3sa2_list,
.probe = opl3sa2_pnp_probe, .probe = opl3sa2_pnp_probe,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment