diff options
| author | Greg Kroah-Hartman <greg@kroah.com> | 2002-12-29 22:17:54 -0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <greg@kroah.com> | 2002-12-29 22:17:54 -0800 |
| commit | 4513bc2fb92aa9407cea9c9b56053f38c211b6aa (patch) | |
| tree | 981016921579683c215defead9be6a85a3372d75 | |
| parent | 288bde07965cad1bb83cb8aefa844e801472a5d4 (diff) | |
| parent | 708d7b682c14fb0c45ec3e917d2e49aca011c5a0 (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.txt | 198 | ||||
| -rw-r--r-- | drivers/pcmcia/i82365.c | 26 | ||||
| -rw-r--r-- | drivers/pnp/card.c | 14 | ||||
| -rw-r--r-- | drivers/pnp/core.c | 3 | ||||
| -rw-r--r-- | drivers/pnp/driver.c | 16 | ||||
| -rw-r--r-- | drivers/pnp/idlist.h | 3 | ||||
| -rw-r--r-- | drivers/pnp/interface.c | 20 | ||||
| -rw-r--r-- | drivers/pnp/isapnp/Makefile | 4 | ||||
| -rw-r--r-- | drivers/pnp/isapnp/compat.c | 25 | ||||
| -rw-r--r-- | drivers/pnp/isapnp/core.c | 58 | ||||
| -rw-r--r-- | drivers/pnp/isapnp/proc.c | 1 | ||||
| -rw-r--r-- | drivers/pnp/pnpbios/core.c | 27 | ||||
| -rw-r--r-- | drivers/pnp/resource.c | 107 | ||||
| -rw-r--r-- | drivers/serial/8250_pnp.c | 7 | ||||
| -rw-r--r-- | include/linux/isapnp.h | 138 | ||||
| -rw-r--r-- | include/linux/pci.h | 19 | ||||
| -rw-r--r-- | include/linux/pnp.h | 47 |
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; } |
