summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <greg@kroah.com>2002-12-29 22:17:54 -0800
committerGreg Kroah-Hartman <greg@kroah.com>2002-12-29 22:17:54 -0800
commit4513bc2fb92aa9407cea9c9b56053f38c211b6aa (patch)
tree981016921579683c215defead9be6a85a3372d75
parent288bde07965cad1bb83cb8aefa844e801472a5d4 (diff)
parent708d7b682c14fb0c45ec3e917d2e49aca011c5a0 (diff)
Merge kroah.com:/home/linux/linux/BK/bleeding-2.5
into kroah.com:/home/linux/linux/BK/pnp-2.5
-rw-r--r--Documentation/isapnp.txt198
-rw-r--r--drivers/pcmcia/i82365.c26
-rw-r--r--drivers/pnp/card.c14
-rw-r--r--drivers/pnp/core.c3
-rw-r--r--drivers/pnp/driver.c16
-rw-r--r--drivers/pnp/idlist.h3
-rw-r--r--drivers/pnp/interface.c20
-rw-r--r--drivers/pnp/isapnp/Makefile4
-rw-r--r--drivers/pnp/isapnp/compat.c25
-rw-r--r--drivers/pnp/isapnp/core.c58
-rw-r--r--drivers/pnp/isapnp/proc.c1
-rw-r--r--drivers/pnp/pnpbios/core.c27
-rw-r--r--drivers/pnp/resource.c107
-rw-r--r--drivers/serial/8250_pnp.c7
-rw-r--r--include/linux/isapnp.h138
-rw-r--r--include/linux/pci.h19
-rw-r--r--include/linux/pnp.h47
17 files changed, 241 insertions, 472 deletions
diff --git a/Documentation/isapnp.txt b/Documentation/isapnp.txt
index d2f09d3de6a5..400d1b5b523d 100644
--- a/Documentation/isapnp.txt
+++ b/Documentation/isapnp.txt
@@ -4,199 +4,11 @@ ISA Plug & Play support by Jaroslav Kysela <perex@suse.cz>
Interface /proc/isapnp
======================
-Read commands:
---------------
+The interface has been removed. See pnp.txt for more details.
-No comment.
-
-Write commands:
----------------
-
-With the write interface you can activate or modify the configuration of
-ISA Plug & Play devices. It is mainly useful for drivers which have not
-been rewritten to use the ISA Plug & Play kernel support yet.
-
-card <idx> <vendor> - select PnP device by vendor identification
-csn <CSN> - select PnP device by CSN
-dev <idx> <logdev> - select logical device
-auto - run autoconfigure
-activate - activate logical device
-deactivate - deactivate logical device
-port <idx> <value> - set port 0-7 to value
-irq <idx> <value> - set IRQ 0-1 to value
-dma <idx> <value> - set DMA 0-1 to value
-memory <idx> <value> - set memory 0-3 to value
-poke <reg> <value> - poke configuration byte to selected register
-pokew <reg> <value> - poke configuration word to selected register
-poked <reg> <value> - poke configuration dword to selected register
-allow_dma0 <value> - allow dma channel 0 during auto activation: 0=off, 1=on
-
-Explanation:
- - variable <idx> begins with zero
- - variable <CSN> begins with one
- - <vendor> is in the standard format 'ABC1234'
- - <logdev> is in the standard format 'ABC1234'
-
-Example:
-
-cat > /proc/isapnp <<EOF
-card 0 CSC7537
-dev 0 CSC0000
-port 0 0x534
-port 1 0x388
-port 2 0x220
-irq 0 5
-dma 0 1
-dma 1 3
-poke 0x70 9
-activate
-logdev 0 CSC0001
-port 0 0x240
-activate
-EOF
-
-
-Information for developers
+Interface /proc/bus/isapnp
==========================
-Finding a device
-----------------
-
-extern struct pci_bus *isapnp_find_card(unsigned short vendor,
- unsigned short device,
- struct pci_bus *from);
-
-This function finds an ISA PnP card. For the vendor argument, the
-ISAPNP_VENDOR(a,b,c) macro should be used, where a,b,c are characters or
-integers. For the device argument the ISAPNP_DEVICE(x) macro should be
-used, where x is an integer value. Both vendor and device arguments
-can be taken from contents of the /proc/isapnp file.
-
-extern struct pci_dev *isapnp_find_dev(struct pci_bus *card,
- unsigned short vendor,
- unsigned short function,
- struct pci_dev *from);
-
-This function finds an ISA PnP device. If card is NULL, then the global
-search mode is used (all devices are used for the searching). Otherwise
-only devices which belong to the specified card are checked. For the
-function number the ISAPNP_FUNCTION(x) macro can be used; it works
-similarly to the ISAPNP_DEVICE(x) macro.
-
-extern int isapnp_probe_cards(const struct isapnp_card_id *ids,
- int (*probe)(struct pci_bus *card,
- const struct isapnp_card_id *id));
-
-
-This function is a helper for drivers which need to use more than
-one device from an ISA PnP card. The probe callback is called with
-appropriate arguments for each card.
-
-Example for ids parameter initialization:
-
-static struct isapnp_card_id card_ids[] __devinitdata = {
- {
- ISAPNP_CARD_ID('A','D','V', 0x550a),
- devs: {
- ISAPNP_DEVICE_ID('A', 'D', 'V', 0x0010),
- ISAPNP_DEVICE_ID('A', 'D', 'V', 0x0011)
- },
- driver_data: 0x1234,
- },
- {
- ISAPNP_CARD_END,
- }
-};
-ISAPNP_CARD_TABLE(card_ids);
-
-extern int isapnp_probe_devs(const struct isapnp_device_id *ids,
- int (*probe)(struct pci_bus *card,
- const struct isapnp_device_id *id));
-
-
-This function is a helper for drivers which need to use one
-device from an ISA PnP card. The probe callback is called with
-appropriate arguments for each matched device.
-
-Example for ids parameter initialization:
-
-static struct isapnp_device_id device_ids[] __devinitdata = {
- { ISAPNP_DEVICE_SINGLE('E','S','S', 0x0968, 'E','S','S', 0x0968), },
- { ISAPNP_DEVICE_SINGLE_END, }
-};
-MODULE_DEVICE_TABLE(isapnp, device_ids);
-
-
-ISA PnP configuration
-=====================
-
-There are two ways in which the ISA PnP interface can be used.
-
-First way: low-level
---------------------
-
-All ISA PNP configuration registers are accessible via the low-level
-isapnp_(read|write)_(byte|word|dword) functions.
-
-The function isapnp_cfg_begin() must be called before any lowlevel function.
-The function isapnp_cfg_end() must be always called after configuration
-otherwise the access to the ISA PnP configuration functions will be blocked.
-
-Second way: auto-configuration
-------------------------------
-
-This feature gives to the driver the real power of the ISA PnP driver.
-The function dev->prepare() initializes the resource members in the device
-structure. This structure contains all resources set to auto configuration
-values after the initialization. The device driver may modify some resources
-to skip the auto configuration for a given resource.
-
-Once the device structure contains all requested resource values, the function
-dev->activate() must be called to assign free resources to resource members
-with the auto configuration value.
-
-Function dev->activate() does:
- - resources with the auto configuration value are configured
- - the auto configuration is created using ISA PnP resource map
- - the function writes configuration to ISA PnP configuration registers
- - the function returns to the caller actual used resources
-
-When the device driver is removed, function dev->deactivate() has to be
-called to free all assigned resources.
-
-Example (game port initialization)
-==================================
-
-/*** initialization ***/
-
- struct pci_dev *dev;
-
- /* find the first game port, use standard PnP IDs */
- dev = isapnp_find_dev(NULL,
- ISAPNP_VENDOR('P','N','P'),
- ISAPNP_FUNCTION(0xb02f),
- NULL);
- if (!dev)
- return -ENODEV;
- if (dev->active)
- return -EBUSY;
- if (dev->prepare(dev)<0)
- return -EAGAIN;
- if (!(dev->resource[0].flags & IORESOURCE_IO))
- return -ENODEV;
- if (!dev->ro) {
- /* override resource */
- if (user_port != USER_PORT_AUTO_VALUE)
- isapnp_resource_change(&dev->resource[0], user_port, 1);
- }
- if (dev->activate(dev)<0) {
- printk("isapnp configure failed (out of resources?)\n");
- return -ENOMEM;
- }
- user_port = dev->resource[0].start; /* get real port */
-
-/*** deactivation ***/
-
- /* to deactivate use: */
- if (dev)
- dev->deactivate(dev);
+This directory allows access to ISA PnP cards and logical devices.
+The regular files contain the contents of ISA PnP registers for
+a logical device.
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 8c2cd91ad6c3..893561738443 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -814,7 +814,7 @@ static void __init add_pcic(int ns, int type)
#ifdef CONFIG_ISA
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
static struct isapnp_device_id id_table[] __initdata = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
ISAPNP_FUNCTION(0x0e00), (unsigned long) "Intel 82365-Compatible" },
@@ -826,32 +826,28 @@ static struct isapnp_device_id id_table[] __initdata = {
};
MODULE_DEVICE_TABLE(isapnp, id_table);
-static struct pci_dev *i82365_pnpdev;
+static struct pnp_dev *i82365_pnpdev;
#endif
static void __init isa_probe(void)
{
int i, j, sock, k, ns, id;
ioaddr_t port;
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
struct isapnp_device_id *devid;
- struct pci_dev *dev;
+ struct pnp_dev *dev;
for (devid = id_table; devid->vendor; devid++) {
- if ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, NULL))) {
- printk("ISAPNP ");
+ if ((dev = pnp_find_dev(NULL, devid->vendor, devid->function, NULL))) {
+ printk("PNP ");
- if (dev->prepare && dev->prepare(dev) < 0) {
- printk("prepare failed\n");
- break;
- }
-
- if (dev->activate && dev->activate(dev) < 0) {
+ if (pnp_activate_dev(dev, NULL) < 0) {
printk("activate failed\n");
break;
}
- if ((i365_base = pci_resource_start(dev, 0))) {
+ i365_base = pnp_port_start(dev, 0);
+ if (i365_base) {
printk("no resources ?\n");
break;
}
@@ -1644,8 +1640,8 @@ static void __exit exit_i82365(void)
release_region(socket[i].ioaddr, 2);
}
#if defined(CONFIG_ISA) && defined(__ISAPNP__)
- if (i82365_pnpdev && i82365_pnpdev->deactivate)
- i82365_pnpdev->deactivate(i82365_pnpdev);
+ if (i82365_pnpdev)
+ pnp_disable_dev(i82365_pnpdev);
#endif
} /* exit_i82365 */
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index e591e906049d..914c1e2628ee 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -192,6 +192,7 @@ struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id,
{
struct list_head *pos;
struct pnp_dev *dev;
+ struct pnpc_driver *cdrv;
if (!card || !id)
goto done;
if (!from) {
@@ -212,9 +213,16 @@ done:
return NULL;
found:
- if (dev->active == 0)
- if(pnp_activate_dev(dev)<0)
- return NULL;
+ cdrv = to_pnpc_driver(card->dev.driver);
+ if (dev->active == 0) {
+ if (!(cdrv->flags & PNPC_DRIVER_DO_NOT_ACTIVATE)) {
+ if(pnp_activate_dev(dev,NULL)<0)
+ return NULL;
+ }
+ } else {
+ if ((cdrv->flags & PNPC_DRIVER_DO_NOT_ACTIVATE))
+ pnp_disable_dev(dev);
+ }
spin_lock(&pnp_lock);
list_add_tail(&dev->rdev_list, &card->rdevs);
spin_unlock(&pnp_lock);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 7eed8f4f8163..979cccd2a128 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -115,7 +115,8 @@ int __pnp_add_device(struct pnp_dev *dev)
int error = 0;
pnp_name_device(dev);
pnp_fixup_device(dev);
- strcpy(dev->dev.name,dev->name);
+ strncpy(dev->dev.name,dev->name,DEVICE_NAME_SIZE-1);
+ dev->dev.name[DEVICE_NAME_SIZE-1] = '\0';
dev->dev.bus = &pnp_bus_type;
dev->dev.release = &pnp_release_device;
error = device_register(&dev->dev);
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index 8676d7941b00..e954b11ae931 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -66,7 +66,7 @@ static const struct pnp_device_id * match_device(struct pnp_driver *drv, struct
static int pnp_device_probe(struct device *dev)
{
- int error = 0;
+ int error;
struct pnp_driver *pnp_drv;
struct pnp_dev *pnp_dev;
const struct pnp_device_id *dev_id = NULL;
@@ -75,9 +75,17 @@ static int pnp_device_probe(struct device *dev)
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_dev->active == 0) {
+ if (!(pnp_drv->flags & PNP_DRIVER_DO_NOT_ACTIVATE)) {
+ error = pnp_activate_dev(pnp_dev, NULL);
+ if (error < 0)
+ return error;
+ }
+ } else {
+ if ((pnp_drv->flags & PNP_DRIVER_DO_NOT_ACTIVATE))
+ pnp_disable_dev(pnp_dev);
+ }
+ error = 0;
if (pnp_drv->probe && pnp_dev->active) {
dev_id = match_device(pnp_drv, pnp_dev);
if (dev_id != NULL)
diff --git a/drivers/pnp/idlist.h b/drivers/pnp/idlist.h
index c75698a68f5c..aa2272fbd652 100644
--- a/drivers/pnp/idlist.h
+++ b/drivers/pnp/idlist.h
@@ -5,6 +5,7 @@ ID("CSC0003", "Crystal Semiconductor CS423x sound -- MPU401")
ID("IBM3780", "IBM pointing device")
ID("IBM0071", "IBM infrared communications device")
ID("IBM3760", "IBM DSP")
+ID("NSC6001", "National Semiconductor Serial Port with Fast IR")
ID("PNP0000", "AT Interrupt Controller")
ID("PNP0001", "EISA Interrupt Controller")
ID("PNP0002", "MCA Interrupt Controller")
@@ -54,6 +55,7 @@ ID("PNP0602", "Plus Hardcard IIXL/EZ")
ID("PNP0603", "Generic IDE supporting Microsoft Device Bay Specification")
ID("PNP0700", "PC standard floppy disk controller")
ID("PNP0701", "Standard floppy controller supporting MS Device Bay Spec")
+ID("PNP0802", "Microsoft Sound System or Compatible Device (obsolete)")
ID("PNP0900", "VGA Compatible")
ID("PNP0901", "Video Seven VRAM/VRAM II/1024i")
ID("PNP0902", "8514/A Compatible")
@@ -151,7 +153,6 @@ ID("PNP0f1c", "Compaq LTE Trackball PS/2-style Mouse")
ID("PNP0f1d", "Compaq LTE Trackball Serial Mouse")
ID("PNP0f1e", "Microsoft Kids Trackball Mouse")
ID("PNP8001", "Novell/Anthem NE3200")
-ID("PNP0802", "Microsoft Sound System or Compatible Device (obsolete)")
ID("PNP8004", "Compaq NE3200")
ID("PNP8006", "Intel EtherExpress/32")
ID("PNP8008", "HP EtherTwist EISA LAN Adapter/32 (HP27248A)")
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 8746323da744..b7ad96265091 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -295,12 +295,28 @@ pnp_set_current_resources(struct device * dmdev, const char * buf, size_t count,
num_args = sscanf(buf,"%10s %i %10s",command,&depnum,type);
if (!num_args)
goto done;
+ if (!strnicmp(command,"lock",4)) {
+ if (dev->active) {
+ dev->lock_resources = 1;
+ } else {
+ error = -EINVAL;
+ }
+ goto done;
+ }
+ if (!strnicmp(command,"unlock",6)) {
+ if (dev->lock_resources) {
+ dev->lock_resources = 0;
+ } else {
+ error = -EINVAL;
+ }
+ goto done;
+ }
if (!strnicmp(command,"disable",7)) {
error = pnp_disable_dev(dev);
goto done;
}
if (!strnicmp(command,"auto",4)) {
- error = pnp_activate_dev(dev);
+ error = pnp_activate_dev(dev,NULL);
goto done;
}
if (!strnicmp(command,"manual",6)) {
@@ -308,7 +324,7 @@ pnp_set_current_resources(struct device * dmdev, const char * buf, size_t count,
goto done;
if (!strnicmp(type,"static",6))
mode = PNP_STATIC;
- error = pnp_raw_set_dev(dev,depnum,mode);
+ error = pnp_raw_set_dev(dev,depnum,NULL,mode);
goto done;
}
done:
diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile
index 62c36dd5df7e..1539195169db 100644
--- a/drivers/pnp/isapnp/Makefile
+++ b/drivers/pnp/isapnp/Makefile
@@ -2,8 +2,8 @@
# Makefile for the kernel ISAPNP driver.
#
-export-objs := core.o
+export-objs := core.o compat.o
isapnp-proc-$(CONFIG_PROC_FS) = proc.o
-obj-y := core.o $(isapnp-proc-y)
+obj-y := core.o compat.o $(isapnp-proc-y)
diff --git a/drivers/pnp/isapnp/compat.c b/drivers/pnp/isapnp/compat.c
index 862c21feba05..834a4ee8b4a9 100644
--- a/drivers/pnp/isapnp/compat.c
+++ b/drivers/pnp/isapnp/compat.c
@@ -26,21 +26,20 @@ static void pnp_convert_id(char *buf, unsigned short vendor, unsigned short devi
}
struct pnp_card *pnp_find_card(unsigned short vendor,
- unsigned short device,
- struct pnp_card *from)
+ unsigned short device,
+ struct pnp_card *from)
{
char id[7];
char any[7];
struct list_head *list;
pnp_convert_id(id, vendor, device);
pnp_convert_id(any, ISAPNP_ANY_ID, ISAPNP_ANY_ID);
- list = isapnp_cards.next;
- if (from)
- list = from->node.next;
- while (list != &isapnp_cards) {
- struct pnp_card *card = to_pnp_card(list);
- if (compare_pnp_id(&card->ids,id) || (memcmp(id,any,7)==0))
+ list = from ? from->global_list.next : pnp_cards.next;
+
+ while (list != &pnp_cards) {
+ struct pnp_card *card = global_to_pnp_card(list);
+ if (compare_pnp_id(card->id,id) || (memcmp(id,any,7)==0))
return card;
list = list->next;
}
@@ -48,9 +47,9 @@ struct pnp_card *pnp_find_card(unsigned short vendor,
}
struct pnp_dev *pnp_find_dev(struct pnp_card *card,
- unsigned short vendor,
- unsigned short function,
- struct pnp_dev *from)
+ unsigned short vendor,
+ unsigned short function,
+ struct pnp_dev *from)
{
char id[7];
char any[7];
@@ -65,7 +64,7 @@ struct pnp_dev *pnp_find_dev(struct pnp_card *card,
while (list != &pnp_global) {
struct pnp_dev *dev = global_to_pnp_dev(list);
- if (compare_pnp_id(&dev->ids,id) || (memcmp(id,any,7)==0))
+ if (compare_pnp_id(dev->id,id) || (memcmp(id,any,7)==0))
return dev;
list = list->next;
}
@@ -80,7 +79,7 @@ struct pnp_dev *pnp_find_dev(struct pnp_card *card,
}
while (list != &card->devices) {
struct pnp_dev *dev = card_to_pnp_dev(list);
- if (compare_pnp_id(&dev->ids,id))
+ if (compare_pnp_id(dev->id,id))
return dev;
list = list->next;
}
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index b60bea187852..fa683efd00a3 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -42,12 +42,8 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/isapnp.h>
-#include <linux/pnp.h>
#include <asm/io.h>
-LIST_HEAD(isapnp_cards);
-LIST_HEAD(isapnp_devices);
-
#if 0
#define ISAPNP_REGION_OK
#endif
@@ -106,6 +102,8 @@ static int isapnp_detected;
/* some prototypes */
static int isapnp_config_prepare(struct pnp_dev *dev);
+extern struct pnp_protocol isapnp_card_protocol;
+extern struct pnp_protocol isapnp_protocol;
static inline void write_data(unsigned char x)
{
@@ -521,7 +519,7 @@ static void __init isapnp_add_port_resource(struct pnp_dev *dev,
port->max = (tmp[4] << 8) | tmp[3];
port->align = tmp[5];
port->size = tmp[6];
- port->flags = tmp[0] ? ISAPNP_PORT_FLAG_16BITADDR : 0;
+ port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
pnp_add_port_resource(dev,depnum,port);
return;
}
@@ -543,7 +541,7 @@ static void __init isapnp_add_fixed_port_resource(struct pnp_dev *dev,
port->min = port->max = (tmp[1] << 8) | tmp[0];
port->size = tmp[2];
port->align = 0;
- port->flags = ISAPNP_PORT_FLAG_FIXED;
+ port->flags = PNP_PORT_FLAG_FIXED;
pnp_add_port_resource(dev,depnum,port);
return;
}
@@ -631,7 +629,7 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
*/
static int __init isapnp_create_device(struct pnp_card *card,
- unsigned short size)
+ unsigned short size)
{
int number = 0, skip = 0, depnum = 0, dependent = 0, compat = 0;
unsigned char type, tmp[17];
@@ -686,7 +684,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_STARTDEP:
if (size > 1)
goto __skip;
- dependent = 0x100 | ISAPNP_RES_PRIORITY_ACCEPTABLE;
+ dependent = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
if (size > 0) {
isapnp_peek(tmp, size);
dependent = 0x100 | tmp[0];
@@ -891,7 +889,7 @@ static int __init isapnp_build_device_list(void)
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;
- card->protocol = &isapnp_protocol;
+ card->protocol = &isapnp_card_protocol;
pnpc_add_card(card);
}
return 0;
@@ -903,7 +901,12 @@ static int __init isapnp_build_device_list(void)
int isapnp_present(void)
{
- return !list_empty(&isapnp_devices);
+ struct pnp_card *card;
+ pnp_for_each_card(card) {
+ if (card->protocol == &isapnp_card_protocol)
+ return 1;
+ }
+ return 0;
}
int isapnp_cfg_begin(int csn, int logdev)
@@ -947,7 +950,7 @@ static int isapnp_config_prepare(struct pnp_dev *dev)
int idx;
if (dev == NULL)
return -EINVAL;
- if (dev->active || dev->ro)
+ if (dev->active || dev->lock_resources)
return -EBUSY;
for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
dev->irq_resource[idx].name = NULL;
@@ -970,24 +973,11 @@ static int isapnp_config_prepare(struct pnp_dev *dev)
return 0;
}
-void isapnp_resource_change(struct resource *resource,
- unsigned long start,
- unsigned long size)
-{
- if (resource == NULL)
- return;
- resource->flags &= ~IORESOURCE_AUTO;
- resource->start = start;
- resource->end = start + size - 1;
-}
-
/*
* Inititialization.
*/
-EXPORT_SYMBOL(isapnp_cards);
-EXPORT_SYMBOL(isapnp_devices);
EXPORT_SYMBOL(isapnp_present);
EXPORT_SYMBOL(isapnp_cfg_begin);
EXPORT_SYMBOL(isapnp_cfg_end);
@@ -999,7 +989,6 @@ EXPORT_SYMBOL(isapnp_write_word);
EXPORT_SYMBOL(isapnp_write_dword);
EXPORT_SYMBOL(isapnp_wake);
EXPORT_SYMBOL(isapnp_device);
-EXPORT_SYMBOL(isapnp_resource_change);
static int isapnp_get_resources(struct pnp_dev *dev)
{
@@ -1053,8 +1042,15 @@ static int isapnp_disable_resources(struct pnp_dev *dev)
return 0;
}
+struct pnp_protocol isapnp_card_protocol = {
+ .name = "ISA Plug and Play - card",
+ .get = NULL,
+ .set = NULL,
+ .disable = NULL,
+};
+
struct pnp_protocol isapnp_protocol = {
- .name = "ISA Plug and Play",
+ .name = "ISA Plug and Play - device",
.get = isapnp_get_resources,
.set = isapnp_set_resources,
.disable = isapnp_disable_resources,
@@ -1064,6 +1060,7 @@ int __init isapnp_init(void)
{
int cards;
struct pnp_card *card;
+ struct pnp_dev *dev;
if (isapnp_disable) {
isapnp_detected = 0;
@@ -1084,6 +1081,9 @@ int __init isapnp_init(void)
return -EBUSY;
}
+ if(pnp_register_protocol(&isapnp_card_protocol)<0)
+ return -EBUSY;
+
if(pnp_register_protocol(&isapnp_protocol)<0)
return -EBUSY;
@@ -1126,13 +1126,11 @@ int __init isapnp_init(void)
protocol_for_each_card(&isapnp_protocol,card) {
cards++;
if (isapnp_verbose) {
- struct list_head *devlist;
printk(KERN_INFO "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown");
if (isapnp_verbose < 2)
continue;
- for (devlist = card->devices.next; devlist != &card->devices; devlist = devlist->next) {
- struct pci_dev *dev = pci_dev_b(devlist);
- printk(KERN_INFO "isapnp: Device '%s'\n", dev->dev.name[0]?card->name:"Unknown");
+ pnp_card_for_each_dev(card,dev) {
+ printk(KERN_INFO "isapnp: Device '%s'\n", dev->name[0]?dev->name:"Unknown");
}
}
}
diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c
index f3427d078367..2330ee03f808 100644
--- a/drivers/pnp/isapnp/proc.c
+++ b/drivers/pnp/isapnp/proc.c
@@ -28,6 +28,7 @@
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
+extern struct pnp_protocol isapnp_protocol;
static struct proc_dir_entry *isapnp_proc_bus_dir = NULL;
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 2f11e1b5f746..d11383778c18 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -1058,6 +1058,7 @@ static void inline pnpid32_to_pnpid(u32 id, char *str)
static void node_id_data_to_dev(unsigned char *p, struct pnp_bios_node *node, struct pnp_dev *dev)
{
int len;
+ char id[8];
struct pnp_id *dev_id;
if ((char *)p == NULL)
@@ -1083,7 +1084,9 @@ static void node_id_data_to_dev(unsigned char *p, struct pnp_bios_node *node, st
dev_id = pnpbios_kmalloc(sizeof (struct pnp_id), GFP_KERNEL);
if (!dev_id)
return;
- pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24,dev_id->id);
+ memset(dev_id, 0, sizeof(struct pnp_id));
+ pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24,id);
+ memcpy(&dev_id->id, id, 7);
pnp_add_id(dev_id, dev);
break;
}
@@ -1258,7 +1261,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev)
struct pnp_bios_node * node;
/* just in case */
- if(dev->driver)
+ if(pnp_dev_has_driver(dev))
return -EBUSY;
if(!pnp_is_dynamic(dev))
return -EPERM;
@@ -1281,7 +1284,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev, struct pnp_cfg *config, ch
struct pnp_bios_node * node;
/* just in case */
- if(dev->driver)
+ if(pnp_dev_has_driver(dev))
return -EBUSY;
if (flags == PNP_DYNAMIC && !pnp_is_dynamic(dev))
return -EPERM;
@@ -1335,7 +1338,7 @@ static int pnpbios_disable_resources(struct pnp_dev *dev)
if (!config)
return -1;
/* just in case */
- if(dev->driver)
+ if(pnp_dev_has_driver(dev))
return -EBUSY;
if(dev->flags & PNP_NO_DISABLE || !pnp_is_dynamic(dev))
return -EPERM;
@@ -1396,7 +1399,7 @@ static int inline insert_device(struct pnp_dev *dev)
static void __init build_devlist(void)
{
u8 nodenum;
- char id[7];
+ char id[8];
unsigned char *pos;
unsigned int nodes_got = 0;
unsigned int devs = 0;
@@ -1432,14 +1435,15 @@ static void __init build_devlist(void)
break;
memset(dev,0,sizeof(struct pnp_dev));
dev_id = pnpbios_kmalloc(sizeof (struct pnp_id), GFP_KERNEL);
- if (!dev_id)
+ if (!dev_id) {
+ kfree(dev);
break;
+ }
memset(dev_id,0,sizeof(struct pnp_id));
dev->number = thisnodenum;
- memcpy(dev->name,"Unknown Device",13);
- dev->name[14] = '\0';
+ strcpy(dev->name,"Unknown Device");
pnpid32_to_pnpid(node->eisa_id,id);
- memcpy(dev_id->id,id,8);
+ memcpy(dev_id->id,id,7);
pnp_add_id(dev_id, dev);
pos = node_current_resource_data_to_dev(node,dev);
pos = node_possible_resource_data_to_dev(pos,node,dev);
@@ -1448,9 +1452,10 @@ static void __init build_devlist(void)
dev->protocol = &pnpbios_protocol;
- if(insert_device(dev)<0)
+ if(insert_device(dev)<0) {
+ kfree(dev_id);
kfree(dev);
- else
+ } else
devs++;
if (nodenum <= thisnodenum) {
printk(KERN_ERR "PnPBIOS: build_devlist: Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (unsigned int)nodenum, (unsigned int)thisnodenum);
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index d8648efb72b3..d447461caa14 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -588,45 +588,65 @@ static int pnp_generate_dma(struct pnp_cfg *config, int num)
return -ENOENT;
}
-static int pnp_prepare_request(struct pnp_cfg *config)
+int pnp_init_res_cfg(struct pnp_res_cfg *res_config)
{
- struct pnp_dev *dev;
int idx;
- if (!config)
- return -EINVAL;
- dev = &config->request;
- if (dev == NULL)
+
+ if (!res_config)
return -EINVAL;
- if (dev->active || dev->ro)
- return -EBUSY;
for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
- dev->irq_resource[idx].name = NULL;
- dev->irq_resource[idx].start = -1;
- dev->irq_resource[idx].end = -1;
- dev->irq_resource[idx].flags = 0;
+ res_config->irq_resource[idx].start = -1;
+ res_config->irq_resource[idx].end = -1;
+ res_config->irq_resource[idx].flags = 0;
}
for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) {
- dev->dma_resource[idx].name = NULL;
- dev->dma_resource[idx].start = -1;
- dev->dma_resource[idx].end = -1;
- dev->dma_resource[idx].flags = 0;
+ res_config->dma_resource[idx].name = NULL;
+ res_config->dma_resource[idx].start = -1;
+ res_config->dma_resource[idx].end = -1;
+ res_config->dma_resource[idx].flags = 0;
}
for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
- dev->resource[idx].name = NULL;
- dev->resource[idx].start = 0;
- dev->resource[idx].end = 0;
- dev->resource[idx].flags = 0;
+ res_config->resource[idx].name = NULL;
+ res_config->resource[idx].start = 0;
+ res_config->resource[idx].end = 0;
+ res_config->resource[idx].flags = 0;
}
return 0;
}
-static int pnp_generate_request(struct pnp_cfg *config)
+static int pnp_prepare_request(struct pnp_dev *dev, struct pnp_cfg *config, struct pnp_res_cfg *template)
{
- int i;
+ int idx, err;
if (!config)
return -EINVAL;
- if (pnp_prepare_request<0)
- return -ENOENT;
+ if (dev->lock_resources)
+ return -EPERM;
+ if (dev->active)
+ return -EBUSY;
+ err = pnp_init_res_cfg(&config->request);
+ if (err < 0)
+ return err;
+ if (!template)
+ return 0;
+ for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++)
+ if (template->irq_resource[idx].start >= 0)
+ config->request.irq_resource[idx] = template->irq_resource[idx];
+ for (idx = 0; idx < DEVICE_COUNT_DMA; idx++)
+ if (template->dma_resource[idx].start >= 0)
+ config->request.dma_resource[idx] = template->dma_resource[idx];
+ for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++)
+ if (template->resource[idx].start > 0)
+ config->request.resource[idx] = template->resource[idx];
+ return 0;
+}
+
+static int pnp_generate_request(struct pnp_dev *dev, struct pnp_cfg *config, struct pnp_res_cfg *template)
+{
+ int i, err;
+ if (!config)
+ return -EINVAL;
+ if ((err = pnp_prepare_request(dev, config, template))<0)
+ return err;
for (i=0; i<=7; i++)
{
if(pnp_generate_port(config,i)<0)
@@ -745,7 +765,7 @@ static struct pnp_cfg * pnp_generate_config(struct pnp_dev *dev, int depnum)
* finds the best resource configuration and then informs the correct pnp protocol
*/
-int pnp_activate_dev(struct pnp_dev *dev)
+int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template)
{
int depnum, max;
struct pnp_cfg *config;
@@ -754,7 +774,7 @@ int pnp_activate_dev(struct pnp_dev *dev)
max = pnp_get_max_depnum(dev);
if (dev->active)
return -EBUSY;
- if (dev->driver){
+ if (pnp_dev_has_driver(dev)){
printk(KERN_INFO "pnp: Automatic configuration failed because the PnP device '%s' is busy\n", dev->dev.bus_id);
return -EINVAL;
}
@@ -767,7 +787,7 @@ int pnp_activate_dev(struct pnp_dev *dev)
config = pnp_generate_config(dev,depnum);
if (!config)
return -EINVAL;
- if (pnp_generate_request(config)==0)
+ if (pnp_generate_request(dev,config,template)==0)
goto done;
kfree(config);
}
@@ -794,10 +814,12 @@ int pnp_disable_dev(struct pnp_dev *dev)
{
if (!dev)
return -EINVAL;
- if (dev->driver){
+ if (pnp_dev_has_driver(dev)){
printk(KERN_INFO "pnp: Disable failed becuase the PnP device '%s' is busy\n", dev->dev.bus_id);
return -EINVAL;
}
+ if (dev->lock_resources)
+ return -EPERM;
if (!dev->protocol->disable || !dev->active)
return -EINVAL;
pnp_dbg("the device '%s' has been disabled", dev->dev.bus_id);
@@ -812,21 +834,21 @@ 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, struct pnp_res_cfg *template, int mode)
{
struct pnp_cfg *config;
if (!dev)
return -EINVAL;
- config = pnp_generate_config(dev,depnum);
- if (dev->driver){
- printk(KERN_INFO "pnp: Unable to set resources becuase the PnP device '%s' is busy\n", dev->dev.bus_id);
+ if (pnp_dev_has_driver(dev)){
+ printk(KERN_INFO "pnp: Unable to set resources because the PnP device '%s' is busy\n", dev->dev.bus_id);
return -EINVAL;
}
if (!dev->protocol->get || !dev->protocol->set)
return -EINVAL;
+ config = pnp_generate_config(dev,depnum);
if (!config)
return -EINVAL;
- if (pnp_generate_request(config)==0)
+ if (pnp_generate_request(dev,config,template)==0)
goto done;
kfree(config);
printk(KERN_ERR "pnp: Manual configuration failed for device '%s' due to resource conflicts\n", dev->dev.bus_id);
@@ -840,6 +862,23 @@ int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode)
return 0;
}
+/**
+ * pnp_resource_change - change one resource
+ * @resource: pointer to resource to be changed
+ * @start: start of region
+ * @size: size of region
+ *
+ */
+
+void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size)
+{
+ if (resource == NULL)
+ return;
+ resource->flags &= ~IORESOURCE_AUTO;
+ resource->start = start;
+ resource->end = start + size - 1;
+}
+
EXPORT_SYMBOL(pnp_build_resource);
EXPORT_SYMBOL(pnp_find_resources);
EXPORT_SYMBOL(pnp_get_max_depnum);
@@ -848,9 +887,11 @@ EXPORT_SYMBOL(pnp_add_dma_resource);
EXPORT_SYMBOL(pnp_add_port_resource);
EXPORT_SYMBOL(pnp_add_mem_resource);
EXPORT_SYMBOL(pnp_add_mem32_resource);
+EXPORT_SYMBOL(pnp_init_res_cfg);
EXPORT_SYMBOL(pnp_activate_dev);
EXPORT_SYMBOL(pnp_disable_dev);
EXPORT_SYMBOL(pnp_raw_set_dev);
+EXPORT_SYMBOL(pnp_resource_change);
/* format is: allowdma0 */
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index aa599f3385d2..1029a1d126ce 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -360,7 +360,7 @@ static int serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
struct pnp_resources *res = dev->res;
struct pnp_resources *resa;
- if (!(check_name(dev->name) || check_name(dev->card->name)))
+ if (!(check_name(dev->name) || (dev->card && check_name(dev->card->name))))
return -ENODEV;
if (!res)
@@ -385,8 +385,11 @@ 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;
- if (flags & UNKNOWN_DEV)
+ if (flags & UNKNOWN_DEV) {
ret = serial_pnp_guess_board(dev, &flags);
+ if (ret < 0)
+ return ret;
+ }
if (flags & SPCI_FL_NO_SHIRQ)
avoid_irq_share(dev);
memset(&serial_req, 0, sizeof(serial_req));
diff --git a/include/linux/isapnp.h b/include/linux/isapnp.h
index 7008adef1677..3e03c39fbc40 100644
--- a/include/linux/isapnp.h
+++ b/include/linux/isapnp.h
@@ -24,6 +24,7 @@
#include <linux/config.h>
#include <linux/errno.h>
+#include <linux/pnp.h>
/*
* Configuration registers (TODO: change by specification)
@@ -54,79 +55,7 @@
#ifdef __KERNEL__
-#include <linux/pci.h>
-
-#define ISAPNP_PORT_FLAG_16BITADDR (1<<0)
-#define ISAPNP_PORT_FLAG_FIXED (1<<1)
-
-struct isapnp_port {
- unsigned short min; /* min base number */
- unsigned short max; /* max base number */
- unsigned char align; /* align boundary */
- unsigned char size; /* size of range */
- unsigned char flags; /* port flags */
- unsigned char pad; /* pad */
- struct isapnp_resources *res; /* parent */
- struct isapnp_port *next; /* next port */
-};
-
-struct isapnp_irq {
- unsigned short map; /* bitmaks for IRQ lines */
- unsigned char flags; /* IRQ flags */
- unsigned char pad; /* pad */
- struct isapnp_resources *res; /* parent */
- struct isapnp_irq *next; /* next IRQ */
-};
-
-struct isapnp_dma {
- unsigned char map; /* bitmask for DMA channels */
- unsigned char flags; /* DMA flags */
- struct isapnp_resources *res; /* parent */
- struct isapnp_dma *next; /* next port */
-};
-
-struct isapnp_mem {
- unsigned int min; /* min base number */
- unsigned int max; /* max base number */
- unsigned int align; /* align boundary */
- unsigned int size; /* size of range */
- unsigned char flags; /* memory flags */
- unsigned char pad; /* pad */
- struct isapnp_resources *res; /* parent */
- struct isapnp_mem *next; /* next memory resource */
-};
-
-struct isapnp_mem32 {
- /* TODO */
- unsigned char data[17];
- struct isapnp_resources *res; /* parent */
- struct isapnp_mem32 *next; /* next 32-bit memory resource */
-};
-
-struct isapnp_fixup {
- unsigned short vendor; /* matching vendor */
- unsigned short device; /* matching device */
- void (*quirk_function)(struct pci_dev *dev); /* fixup function */
-};
-
-
-#define ISAPNP_RES_PRIORITY_PREFERRED 0
-#define ISAPNP_RES_PRIORITY_ACCEPTABLE 1
-#define ISAPNP_RES_PRIORITY_FUNCTIONAL 2
-#define ISAPNP_RES_PRIORITY_INVALID 65535
-
-struct isapnp_resources {
- unsigned short priority; /* priority */
- unsigned short dependent; /* dependent resources */
- struct isapnp_port *port; /* first port */
- struct isapnp_irq *irq; /* first IRQ */
- struct isapnp_dma *dma; /* first DMA */
- struct isapnp_mem *mem; /* first memory resource */
- struct isapnp_mem32 *mem32; /* first 32-bit memory */
- struct pci_dev *dev; /* parent */
- struct isapnp_resources *alt; /* alternative resource (aka dependent resources) */
- struct isapnp_resources *next; /* next resource */
-};
+#define DEVICE_COUNT_COMPATIBLE 4
#define ISAPNP_ANY_ID 0xffff
#define ISAPNP_CARD_DEVS 8
@@ -162,14 +91,6 @@ struct isapnp_device_id {
unsigned long driver_data; /* data private to the driver */
};
-struct isapnp_driver {
- struct list_head node;
- char *name;
- const struct isapnp_device_id *id_table; /* NULL if wants all devices */
- int (*probe) (struct pci_dev *dev, const struct isapnp_device_id *id); /* New device inserted */
- void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
-};
-
#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
#define __ISAPNP__
@@ -188,7 +109,6 @@ void isapnp_wake(unsigned char csn);
void isapnp_device(unsigned char device);
void isapnp_activate(unsigned char device);
void isapnp_deactivate(unsigned char device);
-void isapnp_fixup_device(struct pci_dev *dev);
void *isapnp_alloc(long size);
#ifdef CONFIG_PROC_FS
@@ -199,40 +119,8 @@ static inline isapnp_proc_init(void) { return 0; }
static inline isapnp_proc_done(void) { return 0; }
#endif
-/* misc */
-void isapnp_resource_change(struct resource *resource,
- unsigned long start,
- unsigned long size);
/* init/main.c */
int isapnp_init(void);
-/* manager */
-static inline struct pci_bus *isapnp_find_card(unsigned short vendor,
- unsigned short device,
- struct pci_bus *from) { return NULL; }
-static inline struct pci_dev *isapnp_find_dev(struct pci_bus *card,
- unsigned short vendor,
- unsigned short function,
- struct pci_dev *from) { return NULL; }
-static inline int isapnp_probe_cards(const struct isapnp_card_id *ids,
- int (*probe)(struct pci_bus *card,
- const struct isapnp_card_id *id)) { return -ENODEV; }
-static inline int isapnp_probe_devs(const struct isapnp_device_id *ids,
- int (*probe)(struct pci_dev *dev,
- const struct isapnp_device_id *id)) { return -ENODEV; }
-static inline int isapnp_activate_dev(struct pci_dev *dev, const char *name) { return -ENODEV; }
-
-static inline int isapnp_register_driver(struct isapnp_driver *drv) { return 0; }
-
-static inline void isapnp_unregister_driver(struct isapnp_driver *drv) { }
-
-extern struct list_head isapnp_cards;
-extern struct list_head isapnp_devices;
-extern struct pnp_protocol isapnp_protocol;
-
-#define isapnp_for_each_card(card) \
- for(card = to_pnp_card(isapnp_cards.next); card != to_pnp_card(&isapnp_cards); card = to_pnp_card(card->node.next))
-#define isapnp_for_each_dev(dev) \
- for(dev = protocol_to_pnp_dev(isapnp_protocol.devices.next); dev != protocol_to_pnp_dev(&isapnp_protocol.devices); dev = protocol_to_pnp_dev(dev->dev_list.next))
#else /* !CONFIG_ISAPNP */
@@ -250,28 +138,6 @@ static inline void isapnp_wake(unsigned char csn) { ; }
static inline void isapnp_device(unsigned char device) { ; }
static inline void isapnp_activate(unsigned char device) { ; }
static inline void isapnp_deactivate(unsigned char device) { ; }
-/* manager */
-static inline struct pci_bus *isapnp_find_card(unsigned short vendor,
- unsigned short device,
- struct pci_bus *from) { return NULL; }
-static inline struct pci_dev *isapnp_find_dev(struct pci_bus *card,
- unsigned short vendor,
- unsigned short function,
- struct pci_dev *from) { return NULL; }
-static inline int isapnp_probe_cards(const struct isapnp_card_id *ids,
- int (*probe)(struct pci_bus *card,
- const struct isapnp_card_id *id)) { return -ENODEV; }
-static inline int isapnp_probe_devs(const struct isapnp_device_id *ids,
- int (*probe)(struct pci_dev *dev,
- const struct isapnp_device_id *id)) { return -ENODEV; }
-static inline void isapnp_resource_change(struct resource *resource,
- unsigned long start,
- unsigned long size) { ; }
-static inline int isapnp_activate_dev(struct pci_dev *dev, const char *name) { return -ENODEV; }
-
-static inline int isapnp_register_driver(struct isapnp_driver *drv) { return 0; }
-
-static inline void isapnp_unregister_driver(struct isapnp_driver *drv) { }
#endif /* CONFIG_ISAPNP */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9d4e269ac1db..553864c6a5fb 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -362,7 +362,7 @@ enum pci_mmap_state {
#define PCI_ANY_ID (~0)
/*
- * The pci_dev structure is used to describe both PCI and ISAPnP devices.
+ * The pci_dev structure is used to describe PCI devices.
*/
struct pci_dev {
struct list_head global_list; /* node in list of all PCI devices */
@@ -410,16 +410,9 @@ struct pci_dev {
struct resource irq_resource[DEVICE_COUNT_IRQ];
char slot_name[8]; /* slot name */
- int active; /* ISAPnP: device is active */
- int ro; /* ISAPnP: read only */
- unsigned short regs; /* ISAPnP: supported registers */
/* These fields are used by common fixups */
- unsigned short transparent:1; /* Transparent PCI bridge */
-
- int (*prepare)(struct pci_dev *dev); /* ISAPnP hooks */
- int (*activate)(struct pci_dev *dev);
- int (*deactivate)(struct pci_dev *dev);
+ unsigned int transparent:1; /* Transparent PCI bridge */
};
#define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
@@ -463,13 +456,7 @@ struct pci_bus {
unsigned char subordinate; /* max number of subordinate buses */
char name[48];
- unsigned short vendor;
- unsigned short device;
- unsigned int serial; /* serial number */
- unsigned char pnpver; /* Plug & Play version */
- unsigned char productver; /* product version */
- unsigned char checksum; /* if zero - checksum passed */
- unsigned char pad1;
+
struct device * dev;
};
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index d666c6a92b9f..7d4e9fd6ae0e 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -26,6 +26,7 @@
struct pnp_resource;
struct pnp_protocol;
struct pnp_id;
+struct pnp_cfg;
struct pnp_card {
char name[80];
@@ -50,11 +51,15 @@ struct pnp_card {
#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 to_pnp_card(n) container_of(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))
+ for((card) = global_to_pnp_card(pnp_cards.next); \
+ (card) != global_to_pnp_card(&pnp_cards); \
+ (card) = global_to_pnp_card((card)->global_list.next))
+#define pnp_card_for_each_dev(card,dev) \
+ for((dev) = card_to_pnp_dev((card)->devices.next); \
+ (dev) != card_to_pnp_dev(&(card)->devices); \
+ (dev) = card_to_pnp_dev((dev)->card_list.next))
static inline void *pnpc_get_drvdata (struct pnp_card *pcard)
{
@@ -79,7 +84,6 @@ static inline void pnpc_set_protodata (struct pnp_card *pcard, void *data)
struct pnp_dev {
char name[80]; /* device name */
int active; /* status of the device */
- int ro; /* read only */
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 */
@@ -93,6 +97,7 @@ struct pnp_dev {
unsigned short regs; /* ISAPnP: supported registers */
struct pnp_resources *res; /* possible resource information */
+ int lock_resources; /* resources are locked */
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];
@@ -112,6 +117,13 @@ struct pnp_dev {
dev != global_to_pnp_dev(&pnp_global); \
dev = global_to_pnp_dev(dev->global_list.next))
+static inline int pnp_dev_has_driver(struct pnp_dev *pdev)
+{
+ if (pdev->driver || (pdev->card && pdev->card->driver))
+ return 1;
+ return 0;
+}
+
static inline void *pnp_get_drvdata (struct pnp_dev *pdev)
{
return dev_get_drvdata(&pdev->dev);
@@ -160,10 +172,13 @@ struct pnp_card_id {
} devs[MAX_DEVICES]; /* logical devices */
};
+#define PNP_DRIVER_DO_NOT_ACTIVATE (1<<0)
+
struct pnp_driver {
struct list_head node;
char *name;
const struct pnp_device_id *id_table;
+ unsigned int flags;
int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
void (*remove) (struct pnp_dev *dev);
struct device_driver driver;
@@ -171,10 +186,13 @@ struct pnp_driver {
#define to_pnp_driver(drv) container_of(drv,struct pnp_driver, driver)
+#define PNPC_DRIVER_DO_NOT_ACTIVATE (1<<0)
+
struct pnpc_driver {
struct list_head node;
char *name;
const struct pnp_card_id *id_table;
+ unsigned int flags;
int (*probe) (struct pnp_card *card, const struct pnp_card_id *card_id);
void (*remove) (struct pnp_card *card);
struct device_driver driver;
@@ -279,6 +297,12 @@ struct pnp_resources {
struct pnp_resources *dep; /* dependent resources */
};
+struct pnp_res_cfg {
+ 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];
+};
+
#define PNP_DYNAMIC 0 /* get or set current resource */
#define PNP_STATIC 1 /* get or set resource for next boot */
@@ -287,7 +311,7 @@ struct pnp_cfg {
struct pnp_irq *irq[2];
struct pnp_dma *dma[2];
struct pnp_mem *mem[4];
- struct pnp_dev request;
+ struct pnp_res_cfg request;
};
@@ -340,9 +364,11 @@ int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_dma *data);
int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_port *data);
int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_mem *data);
int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct pnp_mem32 *data);
-int pnp_activate_dev(struct pnp_dev *dev);
+int pnp_init_res_cfg(struct pnp_res_cfg *template);
+int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template);
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, struct pnp_res_cfg *template, int mode);
+void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size);
/* driver */
int compare_pnp_id(struct pnp_id * pos, const char * id);
@@ -366,9 +392,10 @@ static inline int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct p
static inline int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
static inline int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
static inline int pnp_add_mem32_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_init_res_cfg(struct pnp_res_cfg *template) { return -ENODEV; }
+static inline int pnp_activate_dev(struct pnp_dev *dev, struct pnp_res_cfg *template) { 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, struct pnp_res_cfg *template, int mode) { 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; }