PNP cleanup, v5
Subsystems (4)
cover PNP cleanup, v5
I'm trying to stabilize something so we can get it into -mm, so this only addresses Rene's comments on v4.
As a reminder, if anybody tests this and sees problems, the dmesg log with CONFIG_PNP_DEBUG enabled would be a great help to me.
Changes between v4 and v5:
- moved #ifdef DEBUG inside dbg_pnp_show_resources()
- removed cast of flags to int; print the long directly
- changed printk "0x%x" to "%#x"
- set "type" in pnp_clean_resource_table()
- fix return type of pnp_{port,mem,irq,dma}_flags()
- new patch converts pnp_assign_*() and /sys interfaces to pnp_get_resource()
- added Rene's acks
Changes between v3 and v4:
- changed pnp_check_port(), etc., to take resource instead of index
- added some decoder/encoder/assign debug output (under CONFIG_PNP_DEBUG)
- fixed some ISAPNP register index bisectability problems
- removed the list-based resource management (will work on that separately)
Changes between v2 and v3:
- several updates from Rene Herman's review:
- tweak EISA ID conversion and keep high-order bit for ISAPNP
- fix pnp_add_card_id() so bisection works better
- fix some "x <= 0" tests when x is unsigned
- make resource accessors inlines, not #defines
- fix pnp_{port,mem,irq,dma}_valid() return int, not resource_size_t
- fold isapnp_read_resources() back into isapnp_get_resources()
- factored out pnp_init_resource() from pnp_{init,clean}_resource_table()
- initialize generic pnp_dev fields earlier, to help dev_printk
- add pnp_resource to hold ISAPNP register index
- convert to resource management from table to list (finally)
- remove pnp_dev->regs (only set by ISAPNP, never used)
- in /sys/.../resources, don't sort resources by type
Changes between first post and v2:
- export pnp_get_resource()
- fix EISA ID conversion and make a common function for ISAPNP/PNPBIOS
- fix typos in pnp_check_{port,mem,etc} that made resource assign fail
- the following fixes should precede this series (they're in -mm already):
- parport_pc: wrap PNP probe code in CONFIG_PNP
- radio-cadet: wrap PNP probe code in CONFIG_PNP
- smsc-ircc2: wrap PNP probe code in CONFIG_PNP
- nsc-ircc: wrap PNP probe code in CONFIG_PNP
Bjorn
PATCH 1/55 PNP: turn on -DDEBUG when CONFIG_PNP_DEBUG is set
Turn on -DDEBUG in CFLAGS when CONFIG_PNP_DEBUG=y. This makes dev_dbg() do what you expect.
drivers/pnp/isapnp/Makefile +4 -0
@@ -5,3 +5,7 @@ isapnp-proc-$(CONFIG_PROC_FS) = proc.o obj-y := core.o compat.o $(isapnp-proc-y) + +ifeq ($(CONFIG_PNP_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif
drivers/pnp/pnpacpi/Makefile +4 -0
@@ -3,3 +3,7 @@ # obj-y := core.o rsparser.o + +ifeq ($(CONFIG_PNP_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif
drivers/pnp/pnpbios/Makefile +4 -0
@@ -5,3 +5,7 @@ pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) + +ifeq ($(CONFIG_PNP_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif
PATCH 2/55 ISAPNP: move config register addresses out of isapnp.h
In reply to Bjorn HelgaasThese are used only in drivers/pnp/isapnp/core.c, so no need to expose them to the world.
drivers/pnp/isapnp/core.c +8 -0
@@ -88,6 +88,14 @@#define _LTAG_MEM32RANGE 0x85#define _LTAG_FIXEDMEM32RANGE 0x86 +/* Logical device control and configuration registers */ + +#define ISAPNP_CFG_ACTIVATE 0x30/* byte */ +#define ISAPNP_CFG_MEM 0x40/* 4 * dword */ +#define ISAPNP_CFG_PORT 0x60/* 8 * word */ +#define ISAPNP_CFG_IRQ 0x70/* 2 * word */ +#define ISAPNP_CFG_DMA 0x74/* 2 * byte */ +/* * Sizes of ISAPNP logical device configuration register sets. * See PNP-ISA-v1.0a.pdf, Appendix A.
include/linux/isapnp.h +0 -10
@@ -26,16 +26,6 @@#include <linux/pnp.h> /* -* Configuration registers (TODO: change by specification) -*/ - -#define ISAPNP_CFG_ACTIVATE 0x30/* byte */ -#define ISAPNP_CFG_MEM 0x40/* 4 * dword */ -#define ISAPNP_CFG_PORT 0x60/* 8 * word */ -#define ISAPNP_CFG_IRQ 0x70/* 2 * word */ -#define ISAPNP_CFG_DMA 0x74/* 2 * byte */ - -/* * */
PATCH 3/55 PNPACPI: continue after _CRS and _PRS errors
In reply to Bjorn HelgaasKeep going and register the device even if we have trouble parsing _CRS or _PRS. A parsing problem might mean we ignore some resources the device is using, or we might not be able to change its resources. But we should still take note of anything we *could* parse correctly.
Also remove reference to dev_id because I plan to remove it soon.
drivers/pnp/pnpacpi/core.c +2 -6
@@ -213,8 +213,7 @@ &dev->res);if (ACPI_FAILURE (status) && (status !=AE_NOT_FOUND )) {pnp_err ("PnPACPI: METHOD_NAME__CRS failure for %s" , - dev_id->id); - goto err1; +acpi_device_hid (device)); } }
@@ -223,8 +222,7 @@ dev);if (ACPI_FAILURE (status) && (status !=AE_NOT_FOUND )) {pnp_err ("PnPACPI: METHOD_NAME__PRS failure for %s" , - dev_id->id); - goto err1; +acpi_device_hid (device)); } }
@@ -252,8 +250,6 @@ num++;return AE_OK ; -err1: -kfree (dev_id); err:kfree (dev);return -EINVAL ;
PATCH 4/55 PNP: make pnp_add_id() internal to PNP core
In reply to Bjorn Helgaaspnp_add_id() doesn't need to be exposed outside the PNP core, so move the declaration to an internal header file.
include/linux/pnp.h +0 -2
@@ -403,7 +403,6 @@/* protocol helpers */ int pnp_is_active (struct pnp_dev *dev);int compare_pnp_id (struct pnp_id *pos,const char *id); -int pnp_add_id (struct pnp_id *id,struct pnp_dev *dev);int pnp_register_driver (struct pnp_driver *drv);void pnp_unregister_driver (struct pnp_driver *drv);
@@ -450,7 +449,6 @@/* protocol helpers */ static inline int pnp_is_active (struct pnp_dev *dev) {return 0 ; }static inline int compare_pnp_id (struct pnp_id *pos,const char *id) {return -ENODEV ; } -static inline int pnp_add_id (struct pnp_id *id,struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_register_driver (struct pnp_driver *drv) {return -ENODEV ; }static inline void pnp_unregister_driver (struct pnp_driver *drv) { }
drivers/pnp/base.h +1 -0
@@ -1,5 +1,6 @@extern spinlock_t pnp_lock;void *pnp_alloc (long size); +int pnp_add_id (struct pnp_id *id,struct pnp_dev *dev);int pnp_interface_attach_device (struct pnp_dev *dev);void pnp_fixup_device (struct pnp_dev *dev);void pnp_free_option (struct pnp_option *option);
drivers/pnp/pnpacpi/core.c +1 -0
@@ -25,6 +25,7 @@#include <acpi/acpi_bus.h> #include <acpi/actypes.h> +#include "../base.h" #include "pnpacpi.h" static int num =0 ;
drivers/pnp/pnpbios/core.c +1 -0
@@ -69,6 +69,7 @@#include <asm/system.h> #include <asm/byteorder.h> +#include "../base.h" #include "pnpbios.h" /*
PATCH 5/55 PNP: change pnp_add_id() to allocate its own pnp_id structures
In reply to Bjorn HelgaasThis moves some of the pnp_id knowledge out of the backends and into the PNP core.
--- drivers/pnp/base.h | 2 +- drivers/pnp/driver.c | 28 +++++++++++++++++++++------- drivers/pnp/isapnp/core.c | 24 +++++++++++------------- drivers/pnp/pnpacpi/core.c | 27 +++------------------------ drivers/pnp/pnpbios/core.c | 10 +--------- drivers/pnp/pnpbios/rsparser.c | 7 +------ 6 files changed, 38 insertions(+), 60 deletions(-)
drivers/pnp/base.h +1 -1
@@ -1,6 +1,6 @@extern spinlock_t pnp_lock;void *pnp_alloc (long size); -int pnp_add_id (struct pnp_id *id,struct pnp_dev *dev); +struct pnp_id *pnp_add_id (struct pnp_dev *dev,char *id);int pnp_interface_attach_device (struct pnp_dev *dev);void pnp_fixup_device (struct pnp_dev *dev);void pnp_free_option (struct pnp_option *option);
drivers/pnp/driver.c +21 -7
@@ -226,22 +226,36 @@/** * pnp_add_id - adds an EISA id to the specified device -* @id: pointer to a pnp_id structure * @dev: pointer to the desired device +* @id: pointer to an EISA id string */ -int pnp_add_id (struct pnp_id *id,struct pnp_dev *dev) +struct pnp_id *pnp_add_id (struct pnp_dev *dev,char *id) { -struct pnp_id *ptr; +struct pnp_id *dev_id, *ptr; - id->next =NULL ; + dev_id =kzalloc (sizeof (struct pnp_id ),GFP_KERNEL ); +if (!dev_id) +return NULL ; + + dev_id->id[0 ] = id[0 ]; + dev_id->id[1 ] = id[1 ]; + dev_id->id[2 ] = id[2 ]; + dev_id->id[3 ] =tolower (id[3 ]); + dev_id->id[4 ] =tolower (id[4 ]); + dev_id->id[5 ] =tolower (id[5 ]); + dev_id->id[6 ] =tolower (id[6 ]); + dev_id->id[7 ] ='\0' ; + + dev_id->next =NULL ; ptr = dev->id;while (ptr && ptr->next) ptr = ptr->next;if (ptr) - ptr->next = id; + ptr->next = dev_id;else - dev->id = id; -return 0 ; + dev->id = dev_id; + +return dev_id; }EXPORT_SYMBOL (pnp_register_driver);
drivers/pnp/isapnp/core.c +6 -8
@@ -44,6 +44,8 @@#include <linux/mutex.h> #include <asm/io.h> +#include "../base.h" +#if 0 #define ISAPNP_REGION_OK #endif
@@ -401,20 +403,16 @@static void isapnp_parse_id (struct pnp_dev *dev,unsigned short vendor,unsigned short device) { -struct pnp_id *id; +char id[8 ]; -if (!dev) -return ; - id =kzalloc (sizeof (struct pnp_id ),GFP_KERNEL ); -if (!id) -return ; -sprintf (id->id,"%c%c%c%x%x%x%x" , +sprintf (id,"%c%c%c%x%x%x%x" ,'A' + ((vendor >>2 ) &0x3f ) -1 ,'A' + (((vendor &3 ) <<3 ) | ((vendor >>13 ) &7 )) -1 ,'A' + ((vendor >>8 ) &0x1f ) -1 , (device >>4 ) &0x0f , device &0x0f , (device >>12 ) &0x0f , (device >>8 ) &0x0f ); -pnp_add_id (id, dev); + +pnp_add_id (dev, id); }/*
drivers/pnp/pnpacpi/core.c +2 -23
@@ -73,18 +73,6 @@return 1 ; } -static void __init pnpidacpi_to_pnpid (char *id,char *str) -{ - str[0 ] = id[0 ]; - str[1 ] = id[1 ]; - str[2 ] = id[2 ]; - str[3 ] =tolower (id[3 ]); - str[4 ] =tolower (id[4 ]); - str[5 ] =tolower (id[5 ]); - str[6 ] =tolower (id[6 ]); - str[7 ] ='\0' ; -} -static int pnpacpi_get_resources (struct pnp_dev *dev,struct pnp_resource_table *res) {
@@ -201,12 +189,9 @@ dev->number = num; -/* set the initial values for the PnP device */ - dev_id =kzalloc (sizeof (struct pnp_id ),GFP_KERNEL ); + dev_id =pnp_add_id (dev,acpi_device_hid (device));if (!dev_id) goto err; -pnpidacpi_to_pnpid (acpi_device_hid (device), dev_id->id); -pnp_add_id (dev_id, dev);if (dev->active) {/* parse allocated resource */
@@ -227,7 +212,6 @@ } } -/* parse compatible ids */ if (device->flags.compatible_ids) {struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;int i;
@@ -235,12 +219,7 @@for (i =0 ; i < cid_list->count; i++) {if (!ispnpidacpi (cid_list->id[i].value))continue ; - dev_id =kzalloc (sizeof (struct pnp_id ),GFP_KERNEL ); -if (!dev_id) -continue ; - -pnpidacpi_to_pnpid (cid_list->id[i].value, dev_id->id); -pnp_add_id (dev_id, dev); +pnp_add_id (dev, cid_list->id[i].value); } }
drivers/pnp/pnpbios/core.c +2 -4
@@ -332,16 +332,14 @@if (!dev)return -1 ; - dev_id =kzalloc (sizeof (struct pnp_id ),GFP_KERNEL ); +pnpid32_to_pnpid (node->eisa_id, id); + dev_id =pnp_add_id (dev, id);if (!dev_id) {kfree (dev);return -1 ; } dev->number = node->handle; -pnpid32_to_pnpid (node->eisa_id, id); -memcpy (dev_id->id, id,7 ); -pnp_add_id (dev_id, dev);pnpbios_parse_data_stream (dev, node); dev->active =pnp_is_active (dev); dev->flags = node->flags;
drivers/pnp/pnpbios/rsparser.c +4 -5
@@ -16,6 +16,7 @@ }#endif /* CONFIG_PCI */ +#include "../base.h" #include "pnpbios.h" /* standard resource tags */
@@ -548,13 +549,11 @@case SMALL_TAG_COMPATDEVID :/* compatible ID */ if (len !=4 ) goto len_err; - dev_id =kzalloc (sizeof (struct pnp_id ),GFP_KERNEL ); -if (!dev_id) -return NULL ;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); + dev_id =pnp_add_id (dev, id); +if (!dev_id) +return NULL ;break ;case SMALL_TAG_END :
PATCH 6/55 PNP: add pnp_eisa_id_to_string()
In reply to Bjorn HelgaasConverting the EISA ID to a string is messy and error-prone, and we might as well use the same code for ISAPNP and PNPBIOS.
PNPACPI uses the conversion done by the ACPI core with acpi_ex_eisa_id_to_string().
--- drivers/pnp/base.h | 2 ++ drivers/pnp/isapnp/core.c | 32 +++++++++++--------------------- drivers/pnp/pnpbios/core.c | 2 +- drivers/pnp/pnpbios/rsparser.c | 26 +++----------------------- drivers/pnp/support.c | 26 ++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 45 deletions(-)
drivers/pnp/base.h +2 -0
@@ -1,5 +1,7 @@extern spinlock_t pnp_lock;void *pnp_alloc (long size); +#define PNP_EISA_ID_MASK 0x7fffffff +void pnp_eisa_id_to_string (u32 id,char *str);struct pnp_id *pnp_add_id (struct pnp_dev *dev,char *id);int pnp_interface_attach_device (struct pnp_dev *dev);void pnp_fixup_device (struct pnp_dev *dev);
drivers/pnp/isapnp/core.c +11 -21
@@ -398,24 +398,6 @@ }/* -* Parse EISA id. -*/ -static void isapnp_parse_id (struct pnp_dev *dev,unsigned short vendor, -unsigned short device) -{ -char id[8 ]; - -sprintf (id,"%c%c%c%x%x%x%x" , -'A' + ((vendor >>2 ) &0x3f ) -1 , -'A' + (((vendor &3 ) <<3 ) | ((vendor >>13 ) &7 )) -1 , -'A' + ((vendor >>8 ) &0x1f ) -1 , - (device >>4 ) &0x0f , - device &0x0f , (device >>12 ) &0x0f , (device >>8 ) &0x0f ); - -pnp_add_id (dev, id); -} - -/* * Parse logical device tag. */ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
@@ -423,13 +405,17 @@ {unsigned char tmp[6 ];struct pnp_dev *dev; +u32 eisa_id; +char id[8 ];isapnp_peek (tmp, size); dev =kzalloc (sizeof (struct pnp_dev ),GFP_KERNEL );if (!dev)return NULL ; dev->number = number; -isapnp_parse_id (dev, (tmp[1 ] <<8 ) | tmp[0 ], (tmp[3 ] <<8 ) | tmp[2 ]); + eisa_id = tmp[0 ] | tmp[1 ] <<8 | tmp[2 ] <<16 | tmp[3 ] <<24 ; +pnp_eisa_id_to_string (eisa_id, id); +pnp_add_id (dev, id); dev->regs = tmp[4 ]; dev->card = card;if (size >5 )
@@ -619,6 +605,8 @@unsigned char type, tmp[17 ];struct pnp_option *option;struct pnp_dev *dev; +u32 eisa_id; +char id[8 ];if ((dev =isapnp_parse_device (card, size, number++)) ==NULL )return 1 ;
@@ -658,8 +646,10 @@case _STAG_COMPATDEVID:if (size ==4 && compat <DEVICE_COUNT_COMPATIBLE ) {isapnp_peek (tmp,4 ); -isapnp_parse_id (dev, (tmp[1 ] <<8 ) | tmp[0 ], - (tmp[3 ] <<8 ) | tmp[2 ]); + eisa_id = tmp[0 ] | tmp[1 ] <<8 | + tmp[2 ] <<16 | tmp[3 ] <<24 ; +pnp_eisa_id_to_string (eisa_id, id); +pnp_add_id (dev, id); compat++; size =0 ; }
drivers/pnp/pnpbios/core.c +1 -1
@@ -332,7 +332,7 @@if (!dev)return -1 ; -pnpid32_to_pnpid (node->eisa_id, id); +pnp_eisa_id_to_string (node->eisa_id &PNP_EISA_ID_MASK , id); dev_id =pnp_add_id (dev, id);if (!dev_id) {kfree (dev);
drivers/pnp/pnpbios/rsparser.c +3 -23
@@ -494,32 +494,12 @@* Compatible Device IDs */ -#define HEX (id,a) hex[((id)>>a) & 15] -#define CHAR (id,a) (0x40 + (((id)>>a) & 31)) - -void pnpid32_to_pnpid (u32 id,char *str) -{ -const char *hex ="0123456789abcdef" ; - - id =be32_to_cpu (id); - str[0 ] =CHAR (id,26 ); - str[1 ] =CHAR (id,21 ); - str[2 ] =CHAR (id,16 ); - str[3 ] =HEX (id,12 ); - str[4 ] =HEX (id,8 ); - str[5 ] =HEX (id,4 ); - str[6 ] =HEX (id,0 ); - str[7 ] ='\0' ; -} - -#undef CHAR -#undef HEX -static unsigned char *pnpbios_parse_compatible_ids (unsigned char *p,unsigned char *end,struct pnp_dev *dev) {int len, tag; +u32 eisa_id;char id[8 ];struct pnp_id *dev_id;
@@ -549,8 +529,8 @@case SMALL_TAG_COMPATDEVID :/* compatible ID */ if (len !=4 ) goto len_err; -pnpid32_to_pnpid (p[1 ] | p[2 ] <<8 | p[3 ] <<16 | p[4 ] << -24 , id); + eisa_id = p[1 ] | p[2 ] <<8 | p[3 ] <<16 | p[4 ] <<24 ; +pnp_eisa_id_to_string (eisa_id &PNP_EISA_ID_MASK , id); dev_id =pnp_add_id (dev, id);if (!dev_id)return NULL ;
drivers/pnp/support.c +26 -0
@@ -25,3 +25,29 @@ }EXPORT_SYMBOL (pnp_is_active); + +/* +* Functionally similar to acpi_ex_eisa_id_to_string(), but that's +* buried in the ACPI CA, and we can't depend on it being present. +*/ +void pnp_eisa_id_to_string (u32 id,char *str) +{ + id =be32_to_cpu (id); + +/* +* According to the specs, the first three characters are five-bit +* compressed ASCII, and the left-over high order bit should be zero. +* However, the Linux ISAPNP code historically used six bits for the +* first character, and there seem to be IDs that depend on that, +* e.g., "nEC8241" in the Linux 8250_pnp serial driver and the +* FreeBSD sys/pc98/cbus/sio_cbus.c driver. +*/ + str[0 ] ='A' + ((id >>26 ) &0x3f ) -1 ; + str[1 ] ='A' + ((id >>21 ) &0x1f ) -1 ; + str[2 ] ='A' + ((id >>16 ) &0x1f ) -1 ; + str[3 ] =hex_asc ((id >>12 ) &0xf ); + str[4 ] =hex_asc ((id >>8 ) &0xf ); + str[5 ] =hex_asc ((id >>4 ) &0xf ); + str[6 ] =hex_asc ((id >>0 ) &0xf ); + str[7 ] ='\0' ; +}
PATCH 7/55 PNP: add pnp_alloc_dev()
In reply to Bjorn HelgaasAdd pnp_alloc_dev() to allocate a struct pnp_dev and fill in the protocol, instance number, and initial PNP ID. Now it is always valid to use dev_printk() on any pnp_dev pointer.
--- drivers/pnp/base.h | 1 + drivers/pnp/core.c | 38 +++++++++++++++++++++++++++++++------- drivers/pnp/isapnp/core.c | 11 +++++------ drivers/pnp/pnpacpi/core.c | 19 +++---------------- drivers/pnp/pnpbios/core.c | 13 ++----------- 5 files changed, 42 insertions(+), 40 deletions(-)
drivers/pnp/base.h +1 -0
@@ -2,6 +2,7 @@void *pnp_alloc (long size);#define PNP_EISA_ID_MASK 0x7fffffffvoid pnp_eisa_id_to_string (u32 id,char *str); +struct pnp_dev *pnp_alloc_dev (struct pnp_protocol *,int id,char *pnpid);struct pnp_id *pnp_add_id (struct pnp_dev *dev,char *id);int pnp_interface_attach_device (struct pnp_dev *dev);void pnp_fixup_device (struct pnp_dev *dev);
drivers/pnp/core.c +31 -7
@@ -109,15 +109,42 @@kfree (dev); } -int __pnp_add_device (struct pnp_dev *dev) +struct pnp_dev *pnp_alloc_dev (struct pnp_protocol *protocol,int id,char *pnpid) { -int ret; +struct pnp_dev *dev; +struct pnp_id *dev_id; -pnp_fixup_device (dev); + dev =kzalloc (sizeof (struct pnp_dev ),GFP_KERNEL ); +if (!dev) +return NULL ; + + dev->protocol = protocol; + dev->number = id; + dev->dma_mask =DMA_24BIT_MASK ; + + dev->dev.parent = &dev->protocol->dev; dev->dev.bus = &pnp_bus_type; dev->dev.dma_mask = &dev->dma_mask; - dev->dma_mask = dev->dev.coherent_dma_mask =DMA_24BIT_MASK ; + dev->dev.coherent_dma_mask = dev->dma_mask; dev->dev.release = &pnp_release_device; + +sprintf (dev->dev.bus_id,"%02x:%02x" , dev->protocol->number, + dev->number); + + dev_id =pnp_add_id (dev, pnpid); +if (!dev_id) { +kfree (dev); +return NULL ; + } + +return dev; +} + +int __pnp_add_device (struct pnp_dev *dev) +{ +int ret; + +pnp_fixup_device (dev); dev->status =PNP_READY ;spin_lock (&pnp_lock);list_add_tail (&dev->global_list, &pnp_global);
@@ -145,9 +172,6 @@if (dev->card)return -EINVAL ; - dev->dev.parent = &dev->protocol->dev; -sprintf (dev->dev.bus_id,"%02x:%02x" , dev->protocol->number, - dev->number); ret =__pnp_add_device (dev);if (ret)return ret;
drivers/pnp/isapnp/core.c +5 -6
@@ -409,18 +409,17 @@char id[8 ];isapnp_peek (tmp, size); - dev =kzalloc (sizeof (struct pnp_dev ),GFP_KERNEL ); -if (!dev) -return NULL ; - dev->number = number; eisa_id = tmp[0 ] | tmp[1 ] <<8 | tmp[2 ] <<16 | tmp[3 ] <<24 ;pnp_eisa_id_to_string (eisa_id, id); -pnp_add_id (dev, id); + + dev =pnp_alloc_dev (&isapnp_protocol, number, id); +if (!dev) +return NULL ; + dev->regs = tmp[4 ]; dev->card = card;if (size >5 ) dev->regs |= tmp[5 ] <<8 ; - dev->protocol = &isapnp_protocol; dev->capabilities |=PNP_CONFIGURABLE ; dev->capabilities |=PNP_READ ; dev->capabilities |=PNP_WRITE ;
drivers/pnp/pnpacpi/core.c +3 -16
@@ -152,7 +152,6 @@ {acpi_handle temp =NULL ;acpi_status status; -struct pnp_id *dev_id;struct pnp_dev *dev; status =acpi_get_handle (device->handle,"_CRS" , &temp);
@@ -160,11 +159,10 @@ is_exclusive_device(device))return 0 ; - dev =kzalloc (sizeof (struct pnp_dev ),GFP_KERNEL ); -if (!dev) { -pnp_err ("Out of memory" ); + dev =pnp_alloc_dev (&pnpacpi_protocol, num,acpi_device_hid (device)); +if (!dev)return -ENOMEM ; - } + dev->data = device->handle;/* .enabled means the device can decode the resources */ dev->active = device->status.enabled;
@@ -180,19 +178,11 @@if (ACPI_SUCCESS (status)) dev->capabilities |=PNP_DISABLE ; - dev->protocol = &pnpacpi_protocol; -if (strlen (acpi_device_name (device)))strncpy (dev->name,acpi_device_name (device),sizeof (dev->name));else strncpy (dev->name,acpi_device_bid (device),sizeof (dev->name)); - dev->number = num; - - dev_id =pnp_add_id (dev,acpi_device_hid (device)); -if (!dev_id) - goto err; -if (dev->active) {/* parse allocated resource */ status = pnpacpi_parse_allocated_resource(device->handle,
@@ -230,9 +220,6 @@ num++;return AE_OK ; -err: -kfree (dev); -return -EINVAL ; } static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
drivers/pnp/pnpbios/core.c +2 -11
@@ -318,7 +318,6 @@ {struct list_head *pos;struct pnp_dev *dev; -struct pnp_id *dev_id;char id[8 ];/* check if the device is already added */
@@ -328,18 +327,11 @@return -1 ; } - dev =kzalloc (sizeof (struct pnp_dev ),GFP_KERNEL ); -if (!dev) -return -1 ; -pnp_eisa_id_to_string (node->eisa_id &PNP_EISA_ID_MASK , id); - dev_id =pnp_add_id (dev, id); -if (!dev_id) { -kfree (dev); + dev =pnp_alloc_dev (&pnpbios_protocol, node->handle, id); +if (!dev)return -1 ; - } - dev->number = node->handle;pnpbios_parse_data_stream (dev, node); dev->active =pnp_is_active (dev); dev->flags = node->flags;
@@ -352,7 +344,6 @@ dev->capabilities |=PNP_WRITE ;if (dev->flags &PNPBIOS_REMOVABLE ) dev->capabilities |=PNP_REMOVABLE ; - dev->protocol = &pnpbios_protocol;/* clear out the damaged flags */ if (!dev->active)
PATCH 8/55 PNP: make pnp_add_card_id() internal to PNP core
In reply to Bjorn Helgaaspnp_add_card_id() doesn't need to be exposed outside the PNP core, so move the declaration to an internal header file.
drivers/pnp/base.h +1 -0
@@ -4,6 +4,7 @@void pnp_eisa_id_to_string (u32 id,char *str);struct pnp_dev *pnp_alloc_dev (struct pnp_protocol *,int id,char *pnpid);struct pnp_id *pnp_add_id (struct pnp_dev *dev,char *id); +int pnp_add_card_id (struct pnp_id *id,struct pnp_card *card);int pnp_interface_attach_device (struct pnp_dev *dev);void pnp_fixup_device (struct pnp_dev *dev);void pnp_free_option (struct pnp_option *option);
include/linux/pnp.h +0 -2
@@ -371,7 +371,6 @@void pnp_remove_card (struct pnp_card *card);int pnp_add_card_device (struct pnp_card *card,struct pnp_dev *dev);void pnp_remove_card_device (struct pnp_dev *dev); -int pnp_add_card_id (struct pnp_id *id,struct pnp_card *card);struct pnp_dev *pnp_request_card_device (struct pnp_card_link *clink,const char *id,struct pnp_dev *from);void pnp_release_card_device (struct pnp_dev *dev);
@@ -423,7 +422,6 @@static inline void pnp_remove_card (struct pnp_card *card) { }static inline int pnp_add_card_device (struct pnp_card *card,struct pnp_dev *dev) {return -ENODEV ; }static inline void pnp_remove_card_device (struct pnp_dev *dev) { } -static inline int pnp_add_card_id (struct pnp_id *id,struct pnp_card *card) {return -ENODEV ; }static inline struct pnp_dev *pnp_request_card_device (struct pnp_card_link *clink,const char *id,struct pnp_dev *from) {return NULL ; }static inline void pnp_release_card_device (struct pnp_dev *dev) { }static inline int pnp_register_card_driver (struct pnp_card_driver *drv) {return -ENODEV ; }
PATCH 9/55 PNP: change pnp_add_card_id() to allocate its own pnp_id structures
In reply to Bjorn HelgaasThis moves some of the pnp_id knowledge out of the backends and into the PNP core.
drivers/pnp/base.h +1 -1
@@ -4,7 +4,7 @@void pnp_eisa_id_to_string (u32 id,char *str);struct pnp_dev *pnp_alloc_dev (struct pnp_protocol *,int id,char *pnpid);struct pnp_id *pnp_add_id (struct pnp_dev *dev,char *id); -int pnp_add_card_id (struct pnp_id *id,struct pnp_card *card); +struct pnp_id *pnp_add_card_id (struct pnp_card *card,char *id);int pnp_interface_attach_device (struct pnp_dev *dev);void pnp_fixup_device (struct pnp_dev *dev);void pnp_free_option (struct pnp_option *option);
drivers/pnp/card.c +21 -6
@@ -5,6 +5,7 @@*/ #include <linux/module.h> +#include <linux/ctype.h> #include <linux/slab.h> #include <linux/pnp.h> #include "base.h"
@@ -100,19 +101,33 @@* @id: pointer to a pnp_id structure * @card: pointer to the desired card */ -int pnp_add_card_id (struct pnp_id *id,struct pnp_card *card) +struct pnp_id *pnp_add_card_id (struct pnp_card *card,char *id) { -struct pnp_id *ptr; +struct pnp_id *dev_id, *ptr; - id->next =NULL ; + dev_id =kzalloc (sizeof (struct pnp_id ),GFP_KERNEL ); +if (!dev_id) +return NULL ; + + dev_id->id[0 ] = id[0 ]; + dev_id->id[1 ] = id[1 ]; + dev_id->id[2 ] = id[2 ]; + dev_id->id[3 ] =tolower (id[3 ]); + dev_id->id[4 ] =tolower (id[4 ]); + dev_id->id[5 ] =tolower (id[5 ]); + dev_id->id[6 ] =tolower (id[6 ]); + dev_id->id[7 ] ='\0' ; + + dev_id->next =NULL ; ptr = card->id;while (ptr && ptr->next) ptr = ptr->next;if (ptr) - ptr->next = id; + ptr->next = dev_id;else - card->id = id; -return 0 ; + card->id = dev_id; + +return dev_id; }static void pnp_free_card_ids (struct pnp_card *card)
drivers/pnp/isapnp/core.c +11 -10
@@ -822,17 +822,18 @@static void isapnp_parse_card_id (struct pnp_card *card,unsigned short vendor,unsigned short device) { -struct pnp_id *id =kzalloc (sizeof (struct pnp_id ),GFP_KERNEL ); +char id[8 ]; -if (!id) -return ; -sprintf (id->id,"%c%c%c%x%x%x%x" , -'A' + ((vendor >>2 ) &0x3f ) -1 , -'A' + (((vendor &3 ) <<3 ) | ((vendor >>13 ) &7 )) -1 , -'A' + ((vendor >>8 ) &0x1f ) -1 , - (device >>4 ) &0x0f , - device &0x0f , (device >>12 ) &0x0f , (device >>8 ) &0x0f ); -pnp_add_card_id (id, card); + id[0 ] ='A' + ((vendor >>2 ) &0x3f ) -1 ; + id[1 ] ='A' + (((vendor &3 ) <<3 ) | ((vendor >>13 ) &7 )) -1 ; + id[2 ] ='A' + ((vendor >>8 ) &0x1f ) -1 ; + id[3 ] =hex_asc ((device >>4 ) &0x0f ); + id[4 ] =hex_asc (device &0x0f ); + id[5 ] =hex_asc ((device >>12 ) &0x0f ); + id[6 ] =hex_asc ((device >>8 ) &0x0f ); + id[7 ] ='\0' ; + +pnp_add_card_id (card, id); }/*
PATCH 10/55 ISAPNP: pull pnp_add_card_id() out of isapnp_parse_card_id()
In reply to Bjorn HelgaasSplit the pnp_add_card_id() part from the PNPID conversion part so we can move the initial add_id() into the pnp_card allocation.
This makes the PNPID conversion generic so we can use the same one for both devices and cards.
drivers/pnp/isapnp/core.c +6 -22
@@ -817,26 +817,6 @@ }/* -* Parse EISA id for ISA PnP card. -*/ -static void isapnp_parse_card_id (struct pnp_card *card,unsigned short vendor, -unsigned short device) -{ -char id[8 ]; - - id[0 ] ='A' + ((vendor >>2 ) &0x3f ) -1 ; - id[1 ] ='A' + (((vendor &3 ) <<3 ) | ((vendor >>13 ) &7 )) -1 ; - id[2 ] ='A' + ((vendor >>8 ) &0x1f ) -1 ; - id[3 ] =hex_asc ((device >>4 ) &0x0f ); - id[4 ] =hex_asc (device &0x0f ); - id[5 ] =hex_asc ((device >>12 ) &0x0f ); - id[6 ] =hex_asc ((device >>8 ) &0x0f ); - id[7 ] ='\0' ; - -pnp_add_card_id (card, id); -} - -/* * Build device list for all present ISA PnP devices. */ static int __init isapnp_build_device_list (void )
@@ -844,6 +824,8 @@int csn;unsigned char header[9 ], checksum;struct pnp_card *card; +u32 eisa_id; +char id[8 ];isapnp_wait ();isapnp_key ();
@@ -864,8 +846,10 @@ card->number = csn;INIT_LIST_HEAD (&card->devices); -isapnp_parse_card_id (card, (header[1 ] <<8 ) | header[0 ], - (header[3 ] <<8 ) | header[2 ]); + eisa_id = header[0 ] | header[1 ] <<8 | + header[2 ] <<16 | header[3 ] <<24 ; +pnp_eisa_id_to_string (eisa_id, id); +pnp_add_card_id (card, id); card->serial = (header[7 ] <<24 ) | (header[6 ] <<16 ) | (header[5 ] <<8 ) | header[4 ];
PATCH 11/55 PNP: add pnp_alloc_card()
In reply to Bjorn HelgaasAdd pnp_alloc_card() to allocate a struct pnp_card and fill in the protocol, instance number, and initial PNP ID. Now it is always valid to use dev_printk() on any pnp_card pointer.
--- drivers/pnp/base.h | 1 + drivers/pnp/card.c | 28 +++++++++++++++++++++++++--- drivers/pnp/isapnp/core.c | 11 ++++------- 3 files changed, 30 insertions(+), 10 deletions(-)
drivers/pnp/base.h +1 -0
@@ -3,6 +3,7 @@#define PNP_EISA_ID_MASK 0x7fffffffvoid pnp_eisa_id_to_string (u32 id,char *str);struct pnp_dev *pnp_alloc_dev (struct pnp_protocol *,int id,char *pnpid); +struct pnp_card *pnp_alloc_card (struct pnp_protocol *,int id,char *pnpid);struct pnp_id *pnp_add_id (struct pnp_dev *dev,char *id);struct pnp_id *pnp_add_card_id (struct pnp_card *card,char *id);int pnp_interface_attach_device (struct pnp_dev *dev);
drivers/pnp/card.c +25 -3
@@ -151,6 +151,31 @@kfree (card); } +struct pnp_card *pnp_alloc_card (struct pnp_protocol *protocol,int id,char *pnpid) +{ +struct pnp_card *card; +struct pnp_id *dev_id; + + card =kzalloc (sizeof (struct pnp_card ),GFP_KERNEL ); +if (!card) +return NULL ; + + card->protocol = protocol; + card->number = id; + + card->dev.parent = &card->protocol->dev; +sprintf (card->dev.bus_id,"%02x:%02x" , card->protocol->number, + card->number); + + dev_id =pnp_add_card_id (card, pnpid); +if (!dev_id) { +kfree (card); +return NULL ; + } + +return card; +} +static ssize_t pnp_show_card_name (struct device *dmdev,struct device_attribute *attr,char *buf) {
@@ -206,9 +231,6 @@int error;struct list_head *pos, *temp; -sprintf (card->dev.bus_id,"%02x:%02x" , card->protocol->number, - card->number); - card->dev.parent = &card->protocol->dev; card->dev.bus =NULL ; card->dev.release = &pnp_release_card; error =device_register (&card->dev);
drivers/pnp/isapnp/core.c +5 -8
@@ -840,16 +840,14 @@ header[5], header[6], header[7], header[8]);printk (KERN_DEBUG "checksum = 0x%x\n" , checksum);#endif -if ((card = -kzalloc (sizeof (struct pnp_card ),GFP_KERNEL )) ==NULL ) -continue ; - - card->number = csn; -INIT_LIST_HEAD (&card->devices); eisa_id = header[0 ] | header[1 ] <<8 | header[2 ] <<16 | header[3 ] <<24 ;pnp_eisa_id_to_string (eisa_id, id); -pnp_add_card_id (card, id); + card =pnp_alloc_card (&isapnp_protocol, csn, id); +if (!card) +continue ; + +INIT_LIST_HEAD (&card->devices); card->serial = (header[7 ] <<24 ) | (header[6 ] <<16 ) | (header[5 ] <<8 ) | header[4 ];
@@ -860,7 +858,6 @@"isapnp: checksum for device %i is not valid (0x%x)\n" , csn, isapnp_checksum_value); card->checksum = isapnp_checksum_value; - card->protocol = &isapnp_protocol;pnp_add_card (card); }
PATCH 12/55 PNPACPI: pnpacpi_encode_ext_irq() wrongly set "irq" instead of "extended_irq"
In reply to Bjorn Helgaaspnpacpi_encode_ext_irq() should set resource->data.extended_irq, not resource->data.irq.
This has been wrong since at least 2.6.12. I haven't seen any bug reports, but it's clearly incorrect.
drivers/pnp/pnpacpi/rsparser.c +2 -2
@@ -820,9 +820,9 @@ resource->data.extended_irq.triggering = triggering; resource->data.extended_irq.polarity = polarity;if (triggering ==ACPI_EDGE_SENSITIVE ) - resource->data.irq.sharable =ACPI_EXCLUSIVE ; + resource->data.extended_irq.sharable =ACPI_EXCLUSIVE ;else - resource->data.irq.sharable =ACPI_SHARED ; + resource->data.extended_irq.sharable =ACPI_SHARED ; resource->data.extended_irq.interrupt_count =1 ; resource->data.extended_irq.interrupts[0 ] = p->start; }
PATCH 13/55 PNPACPI: use temporaries to reduce repetition
In reply to Bjorn HelgaasNo functional change, just fewer words and fewer chances for transcription errors.
drivers/pnp/pnpacpi/rsparser.c +103 -73
@@ -280,6 +280,14 @@ void *data) {struct pnp_resource_table *res_table = data; +struct acpi_resource_irq *irq; +struct acpi_resource_dma *dma; +struct acpi_resource_io *io; +struct acpi_resource_fixed_io *fixed_io; +struct acpi_resource_memory24 *memory24; +struct acpi_resource_memory32 *memory32; +struct acpi_resource_fixed_memory32 *fixed_memory32; +struct acpi_resource_extended_irq *extended_irq;int i;switch (res->type) {
@@ -288,29 +296,32 @@* Per spec, only one interrupt per descriptor is allowed in * _CRS, but some firmware violates this, so parse them all. */ -for (i =0 ; i < res->data.irq.interrupt_count; i++) { + irq = &res->data.irq; +for (i =0 ; i < irq->interrupt_count; i++) {pnpacpi_parse_allocated_irqresource (res_table, - res->data.irq.interrupts[i], - res->data.irq.triggering, - res->data.irq.polarity, - res->data.irq.sharable); + irq->interrupts[i], + irq->triggering, + irq->polarity, + irq->sharable); }break ;case ACPI_RESOURCE_TYPE_DMA : -if (res->data.dma.channel_count >0 ) + dma = &res->data.dma; +if (dma->channel_count >0 )pnpacpi_parse_allocated_dmaresource (res_table, - res->data.dma.channels[0 ], - res->data.dma.type, - res->data.dma.bus_master, - res->data.dma.transfer); + dma->channels[0 ], + dma->type, + dma->bus_master, + dma->transfer);break ;case ACPI_RESOURCE_TYPE_IO : + io = &res->data.io;pnpacpi_parse_allocated_ioresource (res_table, - res->data.io.minimum, - res->data.io.address_length, - res->data.io.io_decode); + io->minimum, + io->address_length, + io->io_decode);break ;case ACPI_RESOURCE_TYPE_START_DEPENDENT :
@@ -318,9 +329,10 @@break ;case ACPI_RESOURCE_TYPE_FIXED_IO : + fixed_io = &res->data.fixed_io;pnpacpi_parse_allocated_ioresource (res_table, - res->data.fixed_io.address, - res->data.fixed_io.address_length, + fixed_io->address, + fixed_io->address_length,ACPI_DECODE_10 );break ;
@@ -331,22 +343,25 @@break ;case ACPI_RESOURCE_TYPE_MEMORY24 : + memory24 = &res->data.memory24;pnpacpi_parse_allocated_memresource (res_table, - res->data.memory24.minimum, - res->data.memory24.address_length, - res->data.memory24.write_protect); + memory24->minimum, + memory24->address_length, + memory24->write_protect);break ;case ACPI_RESOURCE_TYPE_MEMORY32 : + memory32 = &res->data.memory32;pnpacpi_parse_allocated_memresource (res_table, - res->data.memory32.minimum, - res->data.memory32.address_length, - res->data.memory32.write_protect); + memory32->minimum, + memory32->address_length, + memory32->write_protect);break ;case ACPI_RESOURCE_TYPE_FIXED_MEMORY32 : + fixed_memory32 = &res->data.fixed_memory32;pnpacpi_parse_allocated_memresource (res_table, - res->data.fixed_memory32.address, - res->data.fixed_memory32.address_length, - res->data.fixed_memory32.write_protect); + fixed_memory32->address, + fixed_memory32->address_length, + fixed_memory32->write_protect);break ;case ACPI_RESOURCE_TYPE_ADDRESS16 :case ACPI_RESOURCE_TYPE_ADDRESS32 :
@@ -360,15 +375,16 @@break ;case ACPI_RESOURCE_TYPE_EXTENDED_IRQ : -if (res->data.extended_irq.producer_consumer ==ACPI_PRODUCER ) + extended_irq = &res->data.extended_irq; +if (extended_irq->producer_consumer ==ACPI_PRODUCER )return AE_OK ; -for (i =0 ; i < res->data.extended_irq.interrupt_count; i++) { +for (i =0 ; i < extended_irq->interrupt_count; i++) {pnpacpi_parse_allocated_irqresource (res_table, - res->data.extended_irq.interrupts[i], - res->data.extended_irq.triggering, - res->data.extended_irq.polarity, - res->data.extended_irq.sharable); + extended_irq->interrupts[i], + extended_irq->triggering, + extended_irq->polarity, + extended_irq->sharable); }break ;
@@ -797,122 +813,136 @@static void pnpacpi_encode_irq (struct acpi_resource *resource,struct resource *p) { +struct acpi_resource_irq *irq = &resource->data.irq;int triggering, polarity;decode_irq_flags (p->flags &IORESOURCE_BITS , &triggering, &polarity); - resource->data.irq.triggering = triggering; - resource->data.irq.polarity = polarity; + irq->triggering = triggering; + irq->polarity = polarity;if (triggering ==ACPI_EDGE_SENSITIVE ) - resource->data.irq.sharable =ACPI_EXCLUSIVE ; + irq->sharable =ACPI_EXCLUSIVE ;else - resource->data.irq.sharable =ACPI_SHARED ; - resource->data.irq.interrupt_count =1 ; - resource->data.irq.interrupts[0 ] = p->start; + irq->sharable =ACPI_SHARED ; + irq->interrupt_count =1 ; + irq->interrupts[0 ] = p->start; }static void pnpacpi_encode_ext_irq (struct acpi_resource *resource,struct resource *p) { +struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;int triggering, polarity;decode_irq_flags (p->flags &IORESOURCE_BITS , &triggering, &polarity); - resource->data.extended_irq.producer_consumer =ACPI_CONSUMER ; - resource->data.extended_irq.triggering = triggering; - resource->data.extended_irq.polarity = polarity; + extended_irq->producer_consumer =ACPI_CONSUMER ; + extended_irq->triggering = triggering; + extended_irq->polarity = polarity;if (triggering ==ACPI_EDGE_SENSITIVE ) - resource->data.extended_irq.sharable =ACPI_EXCLUSIVE ; + extended_irq->sharable =ACPI_EXCLUSIVE ;else - resource->data.extended_irq.sharable =ACPI_SHARED ; - resource->data.extended_irq.interrupt_count =1 ; - resource->data.extended_irq.interrupts[0 ] = p->start; + extended_irq->sharable =ACPI_SHARED ; + extended_irq->interrupt_count =1 ; + extended_irq->interrupts[0 ] = p->start; }static void pnpacpi_encode_dma (struct acpi_resource *resource,struct resource *p) { +struct acpi_resource_dma *dma = &resource->data.dma; +/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ switch (p->flags &IORESOURCE_DMA_SPEED_MASK ) {case IORESOURCE_DMA_TYPEA : - resource->data.dma.type =ACPI_TYPE_A ; + dma->type =ACPI_TYPE_A ;break ;case IORESOURCE_DMA_TYPEB : - resource->data.dma.type =ACPI_TYPE_B ; + dma->type =ACPI_TYPE_B ;break ;case IORESOURCE_DMA_TYPEF : - resource->data.dma.type =ACPI_TYPE_F ; + dma->type =ACPI_TYPE_F ;break ;default : - resource->data.dma.type =ACPI_COMPATIBILITY ; + dma->type =ACPI_COMPATIBILITY ; }switch (p->flags &IORESOURCE_DMA_TYPE_MASK ) {case IORESOURCE_DMA_8BIT : - resource->data.dma.transfer =ACPI_TRANSFER_8 ; + dma->transfer =ACPI_TRANSFER_8 ;break ;case IORESOURCE_DMA_8AND16BIT : - resource->data.dma.transfer =ACPI_TRANSFER_8_16 ; + dma->transfer =ACPI_TRANSFER_8_16 ;break ;default : - resource->data.dma.transfer =ACPI_TRANSFER_16 ; + dma->transfer =ACPI_TRANSFER_16 ; } - resource->data.dma.bus_master = !!(p->flags &IORESOURCE_DMA_MASTER ); - resource->data.dma.channel_count =1 ; - resource->data.dma.channels[0 ] = p->start; + dma->bus_master = !!(p->flags &IORESOURCE_DMA_MASTER ); + dma->channel_count =1 ; + dma->channels[0 ] = p->start; }static void pnpacpi_encode_io (struct acpi_resource *resource,struct resource *p) { +struct acpi_resource_io *io = &resource->data.io; +/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ - resource->data.io.io_decode = (p->flags &PNP_PORT_FLAG_16BITADDR ) ? + io->io_decode = (p->flags &PNP_PORT_FLAG_16BITADDR ) ?ACPI_DECODE_16 :ACPI_DECODE_10 ; - resource->data.io.minimum = p->start; - resource->data.io.maximum = p->end; - resource->data.io.alignment =0 ;/* Correct? */ - resource->data.io.address_length = p->end - p->start +1 ; + io->minimum = p->start; + io->maximum = p->end; + io->alignment =0 ;/* Correct? */ + io->address_length = p->end - p->start +1 ; }static void pnpacpi_encode_fixed_io (struct acpi_resource *resource,struct resource *p) { - resource->data.fixed_io.address = p->start; - resource->data.fixed_io.address_length = p->end - p->start +1 ; +struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io; + + fixed_io->address = p->start; + fixed_io->address_length = p->end - p->start +1 ; }static void pnpacpi_encode_mem24 (struct acpi_resource *resource,struct resource *p) { +struct acpi_resource_memory24 *memory24 = &resource->data.memory24; +/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ - resource->data.memory24.write_protect = + memory24->write_protect = (p->flags &IORESOURCE_MEM_WRITEABLE ) ?ACPI_READ_WRITE_MEMORY :ACPI_READ_ONLY_MEMORY ; - resource->data.memory24.minimum = p->start; - resource->data.memory24.maximum = p->end; - resource->data.memory24.alignment =0 ; - resource->data.memory24.address_length = p->end - p->start +1 ; + memory24->minimum = p->start; + memory24->maximum = p->end; + memory24->alignment =0 ; + memory24->address_length = p->end - p->start +1 ; }static void pnpacpi_encode_mem32 (struct acpi_resource *resource,struct resource *p) { - resource->data.memory32.write_protect = +struct acpi_resource_memory32 *memory32 = &resource->data.memory32; + + memory32->write_protect = (p->flags &IORESOURCE_MEM_WRITEABLE ) ?ACPI_READ_WRITE_MEMORY :ACPI_READ_ONLY_MEMORY ; - resource->data.memory32.minimum = p->start; - resource->data.memory32.maximum = p->end; - resource->data.memory32.alignment =0 ; - resource->data.memory32.address_length = p->end - p->start +1 ; + memory32->minimum = p->start; + memory32->maximum = p->end; + memory32->alignment =0 ; + memory32->address_length = p->end - p->start +1 ; }static void pnpacpi_encode_fixed_mem32 (struct acpi_resource *resource,struct resource *p) { - resource->data.fixed_memory32.write_protect = +struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32; + + fixed_memory32->write_protect = (p->flags &IORESOURCE_MEM_WRITEABLE ) ?ACPI_READ_WRITE_MEMORY :ACPI_READ_ONLY_MEMORY ; - resource->data.fixed_memory32.address = p->start; - resource->data.fixed_memory32.address_length = p->end - p->start +1 ; + fixed_memory32->address = p->start; + fixed_memory32->address_length = p->end - p->start +1 ; } int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
PATCH 14/55 PNPACPI: hoist dma_flags() out of pnpacpi_parse_allocated_dmaresource()
In reply to Bjorn HelgaasHoist dma_flags() out of pnpacpi_parse_allocated_dmaresource() into its caller. This makes pnpacpi_parse_allocated_dmaresource() more similar to pnpbios_parse_allocated_dmaresource().
drivers/pnp/pnpacpi/rsparser.c +4 -7
@@ -169,8 +169,7 @@ }static void pnpacpi_parse_allocated_dmaresource (struct pnp_resource_table *res, -u32 dma,int type, -int bus_master,int transfer) +u32 dma,int flags) {int i =0 ;static unsigned char warned;
@@ -180,8 +179,7 @@ i++;if (i <PNP_MAX_DMA ) { res->dma_resource[i].flags =IORESOURCE_DMA ;// Also clears _UNSET flag - res->dma_resource[i].flags |= -dma_flags (type, bus_master, transfer); + res->dma_resource[i].flags |= flags;if (dma ==-1 ) { res->dma_resource[i].flags |=IORESOURCE_DISABLED ;return ;
@@ -311,9 +309,8 @@if (dma->channel_count >0 )pnpacpi_parse_allocated_dmaresource (res_table, dma->channels[0 ], - dma->type, - dma->bus_master, - dma->transfer); +dma_flags (dma->type, dma->bus_master, + dma->transfer));break ;case ACPI_RESOURCE_TYPE_IO :
PATCH 15/55 PNPACPI: extend irq_flags() to set IORESOURCE_IRQ_SHAREABLE when appropriate
In reply to Bjorn HelgaasThis simplifies IRQ resource parsing slightly by computing all the IORESOURCE_IRQ_* flags at the same time.
This also keeps track of shareability information when parsing options from _PRS. Previously we ignored shareability in _PRS.
drivers/pnp/pnpacpi/rsparser.c +15 -11
@@ -32,19 +32,26 @@/* * Allocated Resources */ -static int irq_flags (int triggering,int polarity) +static int irq_flags (int triggering,int polarity,int shareable) { +int flags; +if (triggering ==ACPI_LEVEL_SENSITIVE ) {if (polarity ==ACPI_ACTIVE_LOW ) -return IORESOURCE_IRQ_LOWLEVEL ; + flags =IORESOURCE_IRQ_LOWLEVEL ;else -return IORESOURCE_IRQ_HIGHLEVEL ; + flags =IORESOURCE_IRQ_HIGHLEVEL ; }else {if (polarity ==ACPI_ACTIVE_LOW ) -return IORESOURCE_IRQ_LOWEDGE ; + flags =IORESOURCE_IRQ_LOWEDGE ;else -return IORESOURCE_IRQ_HIGHEDGE ; + flags =IORESOURCE_IRQ_HIGHEDGE ; } + +if (shareable) + flags |=IORESOURCE_IRQ_SHAREABLE ; + +return flags; }static void decode_irq_flags (int flag,int *triggering,int *polarity)
@@ -110,16 +117,13 @@ } res->irq_resource[i].flags =IORESOURCE_IRQ ;// Also clears _UNSET flag - res->irq_resource[i].flags |=irq_flags (triggering, polarity); + res->irq_resource[i].flags |=irq_flags (triggering, polarity, shareable); irq =acpi_register_gsi (gsi, triggering, polarity);if (irq <0 ) { res->irq_resource[i].flags |=IORESOURCE_DISABLED ;return ; } -if (shareable) - res->irq_resource[i].flags |=IORESOURCE_IRQ_SHAREABLE ; - res->irq_resource[i].start = irq; res->irq_resource[i].end = irq;pcibios_penalize_isa_irq (irq,1 );
@@ -441,7 +445,7 @@for (i =0 ; i < p->interrupt_count; i++)if (p->interrupts[i])__set_bit (p->interrupts[i], irq->map); - irq->flags =irq_flags (p->triggering, p->polarity); + irq->flags =irq_flags (p->triggering, p->polarity, p->sharable);pnp_register_irq_resource (option, irq); }
@@ -461,7 +465,7 @@for (i =0 ; i < p->interrupt_count; i++)if (p->interrupts[i])__set_bit (p->interrupts[i], irq->map); - irq->flags =irq_flags (p->triggering, p->polarity); + irq->flags =irq_flags (p->triggering, p->polarity, p->sharable);pnp_register_irq_resource (option, irq); }
PATCH 16/55 PNPACPI: pass pnp_dev instead of acpi_handle
In reply to Bjorn HelgaasPass the pnp_dev pointer when possible instead of the acpi_handle. This allows better error messages and reduces the chance of error in the caller.
drivers/pnp/pnpacpi/core.c +2 -2
@@ -88,10 +88,10 @@ {acpi_handle handle = dev->data;struct acpi_buffer buffer; -int ret =0 ; +int ret;acpi_status status; - ret =pnpacpi_build_resource_template (handle, &buffer); + ret =pnpacpi_build_resource_template (dev, &buffer);if (ret)return ret; ret =pnpacpi_encode_resources (res, &buffer);
drivers/pnp/pnpacpi/pnpacpi.h +1 -1
@@ -8,5 +8,5 @@acpi_status pnpacpi_parse_allocated_resource (acpi_handle ,struct pnp_resource_table *);acpi_status pnpacpi_parse_resource_option_data (acpi_handle ,struct pnp_dev *);int pnpacpi_encode_resources (struct pnp_resource_table *,struct acpi_buffer *); -int pnpacpi_build_resource_template (acpi_handle ,struct acpi_buffer *); +int pnpacpi_build_resource_template (struct pnp_dev *,struct acpi_buffer *);#endif
drivers/pnp/pnpacpi/rsparser.c +2 -1
@@ -777,9 +777,10 @@return AE_OK ; } -int pnpacpi_build_resource_template (acpi_handle handle, +int pnpacpi_build_resource_template (struct pnp_dev *dev,struct acpi_buffer *buffer) { +acpi_handle handle = dev->data;struct acpi_resource *resource;int res_cnt =0 ;acpi_status status;
PATCH 17/55 PNP: add debug output to option registration
In reply to Bjorn HelgaasAdd debug output to resource option registration functions (enabled by CONFIG_PNP_DEBUG). This uses dev_printk, so I had to add pnp_dev arguments at the same time.
--- drivers/pnp/isapnp/core.c | 49 +++++++++++++++++------------ drivers/pnp/pnpacpi/rsparser.c | 67 +++++++++++++++++++++++------------------ drivers/pnp/pnpbios/rsparser.c | 53 ++++++++++++++++++-------------- drivers/pnp/resource.c | 34 ++++++++++++++++++-- include/linux/pnp.h | 11 ++++-- 5 files changed, 134 insertions(+), 80 deletions(-)
drivers/pnp/resource.c +30 -4
@@ -53,6 +53,8 @@if (dev->independent)dev_err (&dev->dev,"independent resource already registered\n" ); dev->independent = option; + +dev_dbg (&dev->dev,"new independent option\n" );return option; }
@@ -70,12 +72,18 @@ parent->next = option; }else dev->dependent = option; + +dev_dbg (&dev->dev,"new dependent option (priority %#x)\n" , priority);return option; } -int pnp_register_irq_resource (struct pnp_option *option,struct pnp_irq *data) +int pnp_register_irq_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_irq *data) {struct pnp_irq *ptr; +#ifdef DEBUG +char buf[PNP_IRQ_NR ];/* hex-encoded, so this is overkill but safe */ +#endif ptr = option->irq;while (ptr && ptr->next)
@@ -94,10 +102,17 @@ pcibios_penalize_isa_irq(i, 0); }#endif + +#ifdef DEBUG +bitmap_scnprintf (buf,sizeof (buf), data->map,PNP_IRQ_NR ); +dev_dbg (&dev->dev," irq bitmask %s flags %#x\n" , buf, + data->flags); +#endif return 0 ; } -int pnp_register_dma_resource (struct pnp_option *option,struct pnp_dma *data) +int pnp_register_dma_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_dma *data) {struct pnp_dma *ptr;
@@ -109,10 +124,13 @@else option->dma = data; +dev_dbg (&dev->dev," dma bitmask %#x flags %#x\n" , data->map, + data->flags);return 0 ; } -int pnp_register_port_resource (struct pnp_option *option,struct pnp_port *data) +int pnp_register_port_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_port *data) {struct pnp_port *ptr;
@@ -124,10 +142,14 @@else option->port = data; +dev_dbg (&dev->dev," io " +"min %#x max %#x align %d size %d flags %#x\n" , + data->min, data->max, data->align, data->size, data->flags);return 0 ; } -int pnp_register_mem_resource (struct pnp_option *option,struct pnp_mem *data) +int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_mem *data) {struct pnp_mem *ptr;
@@ -138,6 +160,10 @@ ptr->next = data; else option->mem = data; + +dev_dbg (&dev->dev," mem " +"min %#x max %#x align %d size %d flags %#x\n" , + data->min, data->max, data->align, data->size, data->flags);return 0 ; }
include/linux/pnp.h +11 -8
@@ -382,11 +382,14 @@struct pnp_option *pnp_register_independent_option (struct pnp_dev *dev);struct pnp_option *pnp_register_dependent_option (struct pnp_dev *dev,int priority); -int pnp_register_irq_resource (struct pnp_option *option,struct pnp_irq *data); -int pnp_register_dma_resource (struct pnp_option *option,struct pnp_dma *data); -int pnp_register_port_resource (struct pnp_option *option, +int pnp_register_irq_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_irq *data); +int pnp_register_dma_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_dma *data); +int pnp_register_port_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_port *data); -int pnp_register_mem_resource (struct pnp_option *option,struct pnp_mem *data); +int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_mem *data);void pnp_init_resource_table (struct pnp_resource_table *table);int pnp_manual_config_dev (struct pnp_dev *dev,struct pnp_resource_table *res,int mode);
@@ -430,10 +433,10 @@/* resource management */ static inline struct pnp_option *pnp_register_independent_option (struct pnp_dev *dev) {return NULL ; }static inline struct pnp_option *pnp_register_dependent_option (struct pnp_dev *dev,int priority) {return NULL ; } -static inline int pnp_register_irq_resource (struct pnp_option *option,struct pnp_irq *data) {return -ENODEV ; } -static inline int pnp_register_dma_resource (struct pnp_option *option,struct pnp_dma *data) {return -ENODEV ; } -static inline int pnp_register_port_resource (struct pnp_option *option,struct pnp_port *data) {return -ENODEV ; } -static inline int pnp_register_mem_resource (struct pnp_option *option,struct pnp_mem *data) {return -ENODEV ; } +static inline int pnp_register_irq_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_irq *data) {return -ENODEV ; } +static inline int pnp_register_dma_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_dma *data) {return -ENODEV ; } +static inline int pnp_register_port_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_port *data) {return -ENODEV ; } +static inline int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_mem *data) {return -ENODEV ; }static inline void pnp_init_resource_table (struct pnp_resource_table *table) { }static inline int pnp_manual_config_dev (struct pnp_dev *dev,struct pnp_resource_table *res,int mode) {return -ENODEV ; }static inline int pnp_auto_config_dev (struct pnp_dev *dev) {return -ENODEV ; }
drivers/pnp/isapnp/core.c +29 -21
171 lines not on this page · raw message
drivers/pnp/pnpbios/rsparser.c +31 -23
157 lines not on this page · raw message
drivers/pnp/pnpacpi/rsparser.c +40 -28
195 lines not on this page · raw message
PATCH 18/55 PNP: remove pnp_resource_table from internal get/set interfaces
In reply to Bjorn HelgaasWhen we call protocol->get() and protocol->set() methods, we currently supply pointers to both the pnp_dev and the pnp_resource_table even though the pnp_resource_table should always be the one associated with the pnp_dev.
This removes the pnp_resource_table arguments to make it clear that these methods only operate on the specified pnp_dev.
--- include/linux/pnp.h | 4 ++-- drivers/pnp/interface.c | 2 +- drivers/pnp/manager.c | 2 +- drivers/pnp/isapnp/core.c | 11 +++++------ drivers/pnp/pnpacpi/core.c | 8 +++----- drivers/pnp/pnpbios/core.c | 10 ++++------ 6 files changed, 16 insertions(+), 21 deletions(-)
include/linux/pnp.h +2 -2
@@ -328,8 +328,8 @@char *name;/* resource control functions */ -int (*get) (struct pnp_dev *dev,struct pnp_resource_table *res); -int (*set) (struct pnp_dev *dev,struct pnp_resource_table *res); +int (*get) (struct pnp_dev *dev); +int (*set) (struct pnp_dev *dev);int (*disable) (struct pnp_dev *dev);/* protocol specific suspend/resume */
drivers/pnp/interface.c +1 -1
@@ -364,7 +364,7 @@if (!strnicmp (buf,"get" ,3 )) {mutex_lock (&pnp_res_mutex);if (pnp_can_read (dev)) - dev->protocol->get (dev, &dev->res); + dev->protocol->get (dev);mutex_unlock (&pnp_res_mutex); goto done; }
drivers/pnp/manager.c +1 -1
@@ -473,7 +473,7 @@return -EINVAL ; } -if (dev->protocol->set (dev, &dev->res) <0 ) { +if (dev->protocol->set (dev) <0 ) {dev_err (&dev->dev,"activation failed\n" );return -EIO ; }
drivers/pnp/isapnp/core.c +5 -6
@@ -976,21 +976,20 @@return 0 ; } -static int isapnp_get_resources (struct pnp_dev *dev, -struct pnp_resource_table *res) +static int isapnp_get_resources (struct pnp_dev *dev) {int ret; -pnp_init_resource_table (res); +pnp_init_resource_table (&dev->res);isapnp_cfg_begin (dev->card->number, dev->number); - ret =isapnp_read_resources (dev, res); + ret =isapnp_read_resources (dev, &dev->res);isapnp_cfg_end ();return ret; } -static int isapnp_set_resources (struct pnp_dev *dev, -struct pnp_resource_table *res) +static int isapnp_set_resources (struct pnp_dev *dev) { +struct pnp_resource_table *res = &dev->res;int tmp;isapnp_cfg_begin (dev->card->number, dev->number);
drivers/pnp/pnpacpi/core.c +3 -5
@@ -73,8 +73,7 @@return 1 ; } -static int pnpacpi_get_resources (struct pnp_dev *dev, -struct pnp_resource_table *res) +static int pnpacpi_get_resources (struct pnp_dev *dev) {acpi_status status;
@@ -83,8 +82,7 @@return ACPI_FAILURE (status) ? -ENODEV :0 ; } -static int pnpacpi_set_resources (struct pnp_dev *dev, -struct pnp_resource_table *res) +static int pnpacpi_set_resources (struct pnp_dev *dev) {acpi_handle handle = dev->data;struct acpi_buffer buffer;
@@ -94,7 +92,7 @@ ret =pnpacpi_build_resource_template (dev, &buffer);if (ret)return ret; - ret =pnpacpi_encode_resources (res, &buffer); + ret =pnpacpi_encode_resources (&dev->res, &buffer);if (ret) {kfree (buffer.pointer);return ret;
drivers/pnp/pnpbios/core.c +4 -6
@@ -204,8 +204,7 @@#endif /* CONFIG_HOTPLUG */ -static int pnpbios_get_resources (struct pnp_dev *dev, -struct pnp_resource_table *res) +static int pnpbios_get_resources (struct pnp_dev *dev) {u8 nodenum = dev->number;struct pnp_bios_node *node;
@@ -220,14 +219,13 @@kfree (node);return -ENODEV ; } -pnpbios_read_resources_from_node (res, node); +pnpbios_read_resources_from_node (&dev->res, node); dev->active =pnp_is_active (dev);kfree (node);return 0 ; } -static int pnpbios_set_resources (struct pnp_dev *dev, -struct pnp_resource_table *res) +static int pnpbios_set_resources (struct pnp_dev *dev) {u8 nodenum = dev->number;struct pnp_bios_node *node;
@@ -243,7 +241,7 @@kfree (node);return -ENODEV ; } -if (pnpbios_write_resources_to_node (res, node) <0 ) { +if (pnpbios_write_resources_to_node (&dev->res, node) <0 ) {kfree (node);return -1 ; }
PATCH 19/55 PNP: remove more pnp_resource_table arguments
In reply to Bjorn HelgaasStop passing around struct pnp_resource_table pointers. In most cases, the caller doesn't need to know how the resources are stored inside the struct pnp_dev.
--- drivers/pnp/isapnp/core.c | 6 ++-- drivers/pnp/pnpacpi/core.c | 11 ++----- drivers/pnp/pnpacpi/pnpacpi.h | 6 ++-- drivers/pnp/pnpacpi/rsparser.c | 55 +++++++++++++++++++++----------------- drivers/pnp/pnpbios/core.c | 4 +- drivers/pnp/pnpbios/pnpbios.h | 4 +- drivers/pnp/pnpbios/rsparser.c | 58 ++++++++++++++++++++--------------------- 7 files changed, 73 insertions(+), 71 deletions(-)
drivers/pnp/isapnp/core.c +3 -3
@@ -932,9 +932,9 @@EXPORT_SYMBOL (isapnp_cfg_end);EXPORT_SYMBOL (isapnp_write_byte); -static int isapnp_read_resources (struct pnp_dev *dev, -struct pnp_resource_table *res) +static int isapnp_read_resources (struct pnp_dev *dev) { +struct pnp_resource_table *res = &dev->res;int tmp, ret; dev->active =isapnp_read_byte (ISAPNP_CFG_ACTIVATE );
@@ -982,7 +982,7 @@pnp_init_resource_table (&dev->res);isapnp_cfg_begin (dev->card->number, dev->number); - ret =isapnp_read_resources (dev, &dev->res); + ret =isapnp_read_resources (dev);isapnp_cfg_end ();return ret; }
drivers/pnp/pnpacpi/core.c +4 -7
@@ -77,8 +77,7 @@ {acpi_status status; - status =pnpacpi_parse_allocated_resource ((acpi_handle ) dev->data, - &dev->res); + status =pnpacpi_parse_allocated_resource (dev);return ACPI_FAILURE (status) ? -ENODEV :0 ; }
@@ -92,7 +91,7 @@ ret =pnpacpi_build_resource_template (dev, &buffer);if (ret)return ret; - ret =pnpacpi_encode_resources (&dev->res, &buffer); + ret =pnpacpi_encode_resources (dev, &buffer);if (ret) {kfree (buffer.pointer);return ret;
@@ -183,8 +182,7 @@if (dev->active) {/* parse allocated resource */ - status =pnpacpi_parse_allocated_resource (device->handle, - &dev->res); + status =pnpacpi_parse_allocated_resource (dev);if (ACPI_FAILURE (status) && (status !=AE_NOT_FOUND )) {pnp_err ("PnPACPI: METHOD_NAME__CRS failure for %s" ,acpi_device_hid (device));
@@ -192,8 +190,7 @@ }if (dev->capabilities &PNP_CONFIGURABLE ) { - status =pnpacpi_parse_resource_option_data (device->handle, - dev); + status =pnpacpi_parse_resource_option_data (dev);if (ACPI_FAILURE (status) && (status !=AE_NOT_FOUND )) {pnp_err ("PnPACPI: METHOD_NAME__PRS failure for %s" ,acpi_device_hid (device));
drivers/pnp/pnpacpi/pnpacpi.h +3 -3
@@ -5,8 +5,8 @@#include <linux/acpi.h> #include <linux/pnp.h> -acpi_status pnpacpi_parse_allocated_resource (acpi_handle ,struct pnp_resource_table *); -acpi_status pnpacpi_parse_resource_option_data (acpi_handle ,struct pnp_dev *); -int pnpacpi_encode_resources (struct pnp_resource_table *,struct acpi_buffer *); +acpi_status pnpacpi_parse_allocated_resource (struct pnp_dev *); +acpi_status pnpacpi_parse_resource_option_data (struct pnp_dev *); +int pnpacpi_encode_resources (struct pnp_dev *,struct acpi_buffer *);int pnpacpi_build_resource_template (struct pnp_dev *,struct acpi_buffer *);#endif
drivers/pnp/pnpacpi/rsparser.c +30 -25
188 lines not on this page · raw message
drivers/pnp/pnpbios/core.c +2 -2
@@ -219,7 +219,7 @@kfree (node);return -ENODEV ; } -pnpbios_read_resources_from_node (&dev->res, node); +pnpbios_read_resources_from_node (dev, node); dev->active =pnp_is_active (dev);kfree (node);return 0 ;
@@ -241,7 +241,7 @@kfree (node);return -ENODEV ; } -if (pnpbios_write_resources_to_node (&dev->res, node) <0 ) { +if (pnpbios_write_resources_to_node (dev, node) <0 ) {kfree (node);return -1 ; }
drivers/pnp/pnpbios/pnpbios.h +2 -2
@@ -28,8 +28,8 @@extern int pnpbios_dont_use_current_config;extern int pnpbios_parse_data_stream (struct pnp_dev *dev,struct pnp_bios_node * node); -extern int pnpbios_read_resources_from_node (struct pnp_resource_table *res,struct pnp_bios_node * node); -extern int pnpbios_write_resources_to_node (struct pnp_resource_table *res,struct pnp_bios_node * node); +extern int pnpbios_read_resources_from_node (struct pnp_dev *dev,struct pnp_bios_node *node); +extern int pnpbios_write_resources_to_node (struct pnp_dev *dev,struct pnp_bios_node *node);extern void pnpid32_to_pnpid (u32 id,char *str);extern void pnpbios_print_status (const char * module,u16 status);
drivers/pnp/pnpbios/rsparser.c +29 -29
176 lines not on this page · raw message
PATCH 20/55 PNP: add debug output to encoders
In reply to Bjorn HelgaasAdd debug output to encoders (enabled by CONFIG_PNP_DEBUG). This uses dev_printk, so I had to add pnp_dev arguments at the same time.
--- drivers/pnp/isapnp/core.c | 2 drivers/pnp/pnpacpi/core.c | 2 drivers/pnp/pnpacpi/rsparser.c | 90 +++++++++++++++++++++++++++++------------ drivers/pnp/pnpbios/core.c | 2 drivers/pnp/pnpbios/rsparser.c | 58 ++++++++++++++++++++------ 5 files changed, 114 insertions(+), 40 deletions(-)
drivers/pnp/isapnp/core.c +15 -3
@@ -980,6 +980,7 @@ {int ret; +dev_dbg (&dev->dev,"get resources\n" );pnp_init_resource_table (&dev->res);isapnp_cfg_begin (dev->card->number, dev->number); ret =isapnp_read_resources (dev);
@@ -992,15 +993,19 @@struct pnp_resource_table *res = &dev->res;int tmp; +dev_dbg (&dev->dev,"set resources\n" );isapnp_cfg_begin (dev->card->number, dev->number); dev->active =1 ;for (tmp =0 ; tmp <ISAPNP_MAX_PORT && (res->port_resource[tmp]. flags & (IORESOURCE_IO |IORESOURCE_UNSET )) ==IORESOURCE_IO ; - tmp++) + tmp++) { +dev_dbg (&dev->dev," set io %d to %#llx\n" , + tmp, (unsigned long long ) res->port_resource[tmp].start);isapnp_write_word (ISAPNP_CFG_PORT + (tmp <<1 ), res->port_resource[tmp].start); + } for (tmp = 0; tmp < ISAPNP_MAX_IRQ && (res->irq_resource[tmp].
@@ -1009,22 +1014,29 @@int irq = res->irq_resource[tmp].start;if (irq ==2 ) irq =9 ; +dev_dbg (&dev->dev," set irq %d to %d\n" , tmp, irq);isapnp_write_byte (ISAPNP_CFG_IRQ + (tmp <<1 ), irq); }for (tmp =0 ; tmp <ISAPNP_MAX_DMA && (res->dma_resource[tmp]. flags & (IORESOURCE_DMA |IORESOURCE_UNSET )) ==IORESOURCE_DMA ; - tmp++) + tmp++) { +dev_dbg (&dev->dev," set dma %d to %lld\n" , + tmp, (unsigned long long ) res->dma_resource[tmp].start);isapnp_write_byte (ISAPNP_CFG_DMA + tmp, res->dma_resource[tmp].start); + }for (tmp =0 ; tmp <ISAPNP_MAX_MEM && (res->mem_resource[tmp]. flags & (IORESOURCE_MEM |IORESOURCE_UNSET )) ==IORESOURCE_MEM ; - tmp++) + tmp++) { +dev_dbg (&dev->dev," set mem %d to %#llx\n" , + tmp, (unsigned long long ) res->mem_resource[tmp].start);isapnp_write_word (ISAPNP_CFG_MEM + (tmp <<3 ), (res->mem_resource[tmp].start >>8 ) &0xffff ); + }/* FIXME: We aren't handling 32bit mems properly here */ isapnp_activate (dev->number);isapnp_cfg_end ();
drivers/pnp/pnpacpi/core.c +2 -0
@@ -77,6 +77,7 @@ {acpi_status status; +dev_dbg (&dev->dev,"get resources\n" ); status =pnpacpi_parse_allocated_resource (dev);return ACPI_FAILURE (status) ? -ENODEV :0 ; }
@@ -88,6 +89,7 @@int ret;acpi_status status; +dev_dbg (&dev->dev,"set resources\n" ); ret =pnpacpi_build_resource_template (dev, &buffer);if (ret)return ret;
drivers/pnp/pnpacpi/rsparser.c +64 -26
216 lines not on this page · raw message
drivers/pnp/pnpbios/core.c +2 -0
@@ -212,6 +212,7 @@if (!pnpbios_is_dynamic (dev))return -EPERM ; +dev_dbg (&dev->dev,"get resources\n" ); node =kzalloc (node_info.max_node_size,GFP_KERNEL );if (!node)return -1 ;
@@ -234,6 +235,7 @@if (!pnpbios_is_dynamic (dev))return -EPERM ; +dev_dbg (&dev->dev,"set resources\n" ); node =kzalloc (node_info.max_node_size,GFP_KERNEL );if (!node)return -1 ;
drivers/pnp/pnpbios/rsparser.c +44 -14
171 lines not on this page · raw message
PATCH 21/55 PNP: add debug when assigning PNP resources
In reply to Bjorn HelgaasThis patch adds code to dump PNP resources before and after assigning resources and before writing them to the device.
This is enabled by CONFIG_PNP_DEBUG=y.
drivers/pnp/base.h +2 -0
@@ -16,3 +16,5 @@int pnp_check_mem (struct pnp_dev * dev,int idx);int pnp_check_irq (struct pnp_dev * dev,int idx);int pnp_check_dma (struct pnp_dev * dev,int idx); + +void dbg_pnp_show_resources (struct pnp_dev *dev,char *desc);
drivers/pnp/support.c +37 -0
@@ -51,3 +51,40 @@ str[6 ] =hex_asc ((id >>0 ) &0xf ); str[7 ] ='\0' ; } + +void dbg_pnp_show_resources (struct pnp_dev *dev,char *desc) +{ +#ifdef DEBUG +struct resource *res; +int i; + +dev_dbg (&dev->dev,"current resources: %s\n" , desc); + +for (i =0 ; i <PNP_MAX_IRQ ; i++) { + res = &dev->res.irq_resource[i]; +if (!(res->flags &IORESOURCE_UNSET )) +dev_dbg (&dev->dev," irq %lld flags %#lx\n" , + (unsigned long long ) res->start, res->flags); + } +for (i =0 ; i <PNP_MAX_DMA ; i++) { + res = &dev->res.dma_resource[i]; +if (!(res->flags &IORESOURCE_UNSET )) +dev_dbg (&dev->dev," dma %lld flags %#lx\n" , + (unsigned long long ) res->start, res->flags); + } +for (i =0 ; i <PNP_MAX_PORT ; i++) { + res = &dev->res.port_resource[i]; +if (!(res->flags &IORESOURCE_UNSET )) +dev_dbg (&dev->dev," io %#llx-%#llx flags %#lx\n" , + (unsigned long long ) res->start, + (unsigned long long ) res->end, res->flags); + } +for (i =0 ; i <PNP_MAX_MEM ; i++) { + res = &dev->res.mem_resource[i]; +if (!(res->flags &IORESOURCE_UNSET )) +dev_dbg (&dev->dev," mem %#llx-%#llx flags %#lx\n" , + (unsigned long long ) res->start, + (unsigned long long ) res->end, res->flags); + } +#endif +}
drivers/pnp/manager.c +61 -20
214 lines not on this page · raw message
PATCH 22/55 PNP: add pnp_init_resources(struct pnp_dev *) interface
In reply to Bjorn HelgaasAdd pnp_init_resources(struct pnp_dev *) to replace pnp_init_resource_table(), which takes a pointer to the pnp_resource_table itself. Passing only the pnp_dev * reduces the possibility for error in the caller and removes the pnp_resource_table implementation detail from the interface.
Even though pnp_init_resource_table() is exported, I did not export pnp_init_resources() because it is used only by the PNP core.
--- drivers/pnp/interface.c | 6 +++--- drivers/pnp/isapnp/core.c | 4 ++-- drivers/pnp/manager.c | 5 +++++ drivers/pnp/pnpacpi/core.c | 2 +- drivers/pnp/pnpacpi/rsparser.c | 3 +-- drivers/pnp/pnpbios/core.c | 2 +- drivers/pnp/pnpbios/rsparser.c | 3 +-- include/linux/pnp.h | 2 ++ 8 files changed, 16 insertions(+), 11 deletions(-)
include/linux/pnp.h +2 -0
@@ -391,6 +391,7 @@int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_mem *data);void pnp_init_resource_table (struct pnp_resource_table *table); +void pnp_init_resources (struct pnp_dev *dev);int pnp_manual_config_dev (struct pnp_dev *dev,struct pnp_resource_table *res,int mode);int pnp_auto_config_dev (struct pnp_dev *dev);
@@ -438,6 +439,7 @@static inline int pnp_register_port_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_port *data) {return -ENODEV ; }static inline int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_mem *data) {return -ENODEV ; }static inline void pnp_init_resource_table (struct pnp_resource_table *table) { } +static inline void pnp_init_resources (struct pnp_dev *dev) { }static inline int pnp_manual_config_dev (struct pnp_dev *dev,struct pnp_resource_table *res,int mode) {return -ENODEV ; }static inline int pnp_auto_config_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_validate_config (struct pnp_dev *dev) {return -ENODEV ; }
drivers/pnp/manager.c +5 -0
@@ -272,6 +272,11 @@ } } +void pnp_init_resources (struct pnp_dev *dev) +{ +pnp_init_resource_table (&dev->res); +} +/** * pnp_clean_resources - clears resources that were not manually set * @res: the resources to clean
drivers/pnp/interface.c +3 -3
@@ -351,14 +351,14 @@if (!strnicmp (buf,"auto" ,4 )) {if (dev->active) goto done; -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev); retval =pnp_auto_config_dev (dev); goto done; }if (!strnicmp (buf,"clear" ,5 )) {if (dev->active) goto done; -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev); goto done; }if (!strnicmp (buf,"get" ,3 )) {
@@ -373,7 +373,7 @@if (dev->active) goto done; buf +=3 ; -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev);mutex_lock (&pnp_res_mutex);while (1 ) {while (isspace (*buf))
drivers/pnp/isapnp/core.c +2 -2
@@ -424,7 +424,7 @@ dev->capabilities |=PNP_READ ; dev->capabilities |=PNP_WRITE ; dev->capabilities |=PNP_DISABLE ; -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev);return dev; }
@@ -981,7 +981,7 @@int ret;dev_dbg (&dev->dev,"get resources\n" ); -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev);isapnp_cfg_begin (dev->card->number, dev->number); ret =isapnp_read_resources (dev);isapnp_cfg_end ();
drivers/pnp/pnpacpi/core.c +1 -1
@@ -212,7 +212,7 @@/* clear out the damaged flags */ if (!dev->active) -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev);pnp_add_device (dev); num++;
drivers/pnp/pnpbios/core.c +1 -1
@@ -347,7 +347,7 @@/* clear out the damaged flags */ if (!dev->active) -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev);pnp_add_device (dev);pnpbios_interface_attach_device (node);
drivers/pnp/pnpacpi/rsparser.c +1 -2
@@ -410,8 +410,7 @@dev_dbg (&dev->dev,"parse allocated resources\n" ); -/* Blank the resource table values */ -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev);return acpi_walk_resources (handle,METHOD_NAME__CRS , pnpacpi_allocated_resource, dev);
drivers/pnp/pnpbios/rsparser.c +1 -2
@@ -145,8 +145,7 @@dev_dbg (&dev->dev,"parse allocated resources\n" ); -/* Blank the resource table values */ -pnp_init_resource_table (&dev->res); +pnp_init_resources (dev);while ((char *)p < (char *)end) {
PATCH 23/55 PNP: remove pnp_resource_table from internal pnp_clean_resource_table interface
In reply to Bjorn HelgaasThis changes pnp_clean_resource_table() to take a pnp_dev pointer rather than a pnp_resource_table pointer. This reduces the visibility of pnp_resource_table and removes an opportunity for error in the caller.
drivers/pnp/manager.c +5 -4
@@ -281,8 +281,9 @@* pnp_clean_resources - clears resources that were not manually set * @res: the resources to clean */ -static void pnp_clean_resource_table (struct pnp_resource_table *res) +static void pnp_clean_resource_table (struct pnp_dev *dev) { +struct pnp_resource_table *res = &dev->res;int idx;for (idx =0 ; idx <PNP_MAX_IRQ ; idx++) {
@@ -339,7 +340,7 @@dbg_pnp_show_resources (dev,"before pnp_assign_resources" );mutex_lock (&pnp_res_mutex); -pnp_clean_resource_table (&dev->res);/* start with a fresh slate */ +pnp_clean_resource_table (dev);if (dev->independent) {dev_dbg (&dev->dev,"assigning independent options\n" ); port = dev->independent->port;
@@ -415,7 +416,7 @@return 1 ; fail: -pnp_clean_resource_table (&dev->res); +pnp_clean_resource_table (dev);mutex_unlock (&pnp_res_mutex);dbg_pnp_show_resources (dev,"after pnp_assign_resources (failed)" );return 0 ;
@@ -595,7 +596,7 @@/* release the resources so that other devices can use them */ mutex_lock (&pnp_res_mutex); -pnp_clean_resource_table (&dev->res); +pnp_clean_resource_table (dev);mutex_unlock (&pnp_res_mutex);return 0 ;
PATCH 24/55 PNP: remove unused interfaces using pnp_resource_table
In reply to Bjorn HelgaasRene Herman <[email protected]> recently removed the only in-tree driver uses of:
pnp_init_resource_table()
pnp_manual_config_dev()
pnp_resource_change()
in this change:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=109c53f840e551d6e99ecfd8b0131a968332c89f
These are no longer used in the PNP core either, so we can just remove them completely.
It's possible that there are out-of-tree drivers that use these interfaces. They should be changed to either (1) use PNP quirks to work around broken hardware or firmware, or (2) use the sysfs interfaces to control resource usage from userspace.
--- drivers/pnp/manager.c | 78 +------------------------------------------------- include/linux/pnp.h | 9 ----- 2 files changed, 3 insertions(+), 84 deletions(-)
include/linux/pnp.h +0 -8
@@ -390,18 +390,13 @@ struct pnp_port *data);int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_mem *data); -void pnp_init_resource_table (struct pnp_resource_table *table);void pnp_init_resources (struct pnp_dev *dev); -int pnp_manual_config_dev (struct pnp_dev *dev,struct pnp_resource_table *res, -int mode);int pnp_auto_config_dev (struct pnp_dev *dev);int pnp_validate_config (struct pnp_dev *dev);int pnp_start_dev (struct pnp_dev *dev);int pnp_stop_dev (struct pnp_dev *dev);int pnp_activate_dev (struct pnp_dev *dev);int pnp_disable_dev (struct pnp_dev *dev); -void pnp_resource_change (struct resource *resource,resource_size_t start, -resource_size_t size);/* protocol helpers */ int pnp_is_active (struct pnp_dev *dev);
@@ -438,16 +433,13 @@static inline int pnp_register_dma_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_dma *data) {return -ENODEV ; }static inline int pnp_register_port_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_port *data) {return -ENODEV ; }static inline int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_mem *data) {return -ENODEV ; } -static inline void pnp_init_resource_table (struct pnp_resource_table *table) { }static inline void pnp_init_resources (struct pnp_dev *dev) { } -static inline int pnp_manual_config_dev (struct pnp_dev *dev,struct pnp_resource_table *res,int mode) {return -ENODEV ; }static inline int pnp_auto_config_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_validate_config (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_start_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_stop_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_activate_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_disable_dev (struct pnp_dev *dev) {return -ENODEV ; } -static inline void pnp_resource_change (struct resource *resource,resource_size_t start,resource_size_t size) { }/* protocol helpers */ static inline int pnp_is_active (struct pnp_dev *dev) {return 0 ; }
drivers/pnp/manager.c +2 -76
104 lines not on this page · raw message
PATCH 25/55 PNP: use dev_printk when possible
In reply to Bjorn HelgaasUse dev_printk() when possible for more informative error messages.
--- drivers/pnp/isapnp/core.c | 38 ++++++++++++++++++-------------------- drivers/pnp/pnpacpi/rsparser.c | 20 ++++++++++++-------- drivers/pnp/pnpbios/rsparser.c | 36 ++++++++++++++---------------------- 3 files changed, 44 insertions(+), 50 deletions(-)
drivers/pnp/isapnp/core.c +17 -20
@@ -737,9 +737,8 @@isapnp_skip_bytes (size);return 1 ;default : -printk (KERN_ERR -"isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n" , - type, dev->number, card->number); +dev_err (&dev->dev,"unknown tag %#x (card %i), " +"ignored\n" , type, card->number); } __skip:if (size >0 )
@@ -792,9 +791,8 @@isapnp_skip_bytes (size);return ;default : -printk (KERN_ERR -"isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n" , - type, card->number); +dev_err (&card->dev,"unknown tag %#x, ignored\n" , + type); } __skip:if (size >0 )
@@ -841,13 +839,6 @@isapnp_wake (csn);isapnp_peek (header,9 ); checksum =isapnp_checksum (header); -#if 0 -printk (KERN_DEBUG -"vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" , - header[0 ], header[1 ], header[2 ], header[3 ], header[4 ], - header[5 ], header[6 ], header[7 ], header[8 ]); -printk (KERN_DEBUG "checksum = 0x%x\n" , checksum); -#endif eisa_id = header[0 ] | header[1 ] <<8 | header[2 ] <<16 | header[3 ] <<24 ;pnp_eisa_id_to_string (eisa_id, id);
@@ -855,6 +846,13 @@if (!card)continue ; +#if 0 +dev_info (&card->dev, +"vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" , + header[0 ], header[1 ], header[2 ], header[3 ], header[4 ], + header[5 ], header[6 ], header[7 ], header[8 ]); +dev_info (&card->dev,"checksum = %#x\n" , checksum); +#endif INIT_LIST_HEAD (&card->devices); card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
@@ -862,9 +860,8 @@ isapnp_checksum_value =0x00 ;isapnp_parse_resource_map (card);if (isapnp_checksum_value !=0x00 ) -printk (KERN_ERR -"isapnp: checksum for device %i is not valid (0x%x)\n" , - csn, isapnp_checksum_value); +dev_err (&card->dev,"invalid checksum %#x\n" , + isapnp_checksum_value); card->checksum = isapnp_checksum_value;pnp_add_card (card);
@@ -1134,13 +1131,13 @@protocol_for_each_card (&isapnp_protocol, card) { cards++;if (isapnp_verbose) { -printk (KERN_INFO "isapnp: Card '%s'\n" , - card->name[0 ] ? card->name :"Unknown" ); +dev_info (&card->dev,"card '%s'\n" , + card->name[0 ] ? card->name :"unknown" );if (isapnp_verbose <2 )continue ;card_for_each_dev (card, dev) { -printk (KERN_INFO "isapnp: Device '%s'\n" , - dev->name[0 ] ? dev->name :"Unknown" ); +dev_info (&card->dev,"device '%s'\n" , + dev->name[0 ] ? dev->name :"unknown" ); } } }
drivers/pnp/pnpacpi/rsparser.c +12 -8
@@ -110,7 +110,7 @@ p = p ?ACPI_ACTIVE_LOW :ACPI_ACTIVE_HIGH ;if (triggering != t || polarity != p) { -pnp_warn ("IRQ %d override to %s, %s" , +dev_warn (&dev->dev,"IRQ %d override to %s, %s\n" , gsi, t ?"edge" :"level" , p ?"low" :"high" ); triggering = t; polarity = p;
@@ -263,7 +263,7 @@ status =acpi_resource_to_address64 (res, p);if (!ACPI_SUCCESS (status)) { -pnp_warn ("PnPACPI: failed to convert resource type %d" , +dev_warn (&dev->dev,"failed to convert resource type %d\n" , res->type);return ; }
@@ -397,7 +397,8 @@break ;default : -pnp_warn ("PnPACPI: unknown resource type %d" , res->type); +dev_warn (&dev->dev,"unknown resource type %d in _CRS\n" , + res->type);return AE_ERROR ; }
@@ -674,7 +675,8 @@case ACPI_RESOURCE_TYPE_END_DEPENDENT :/*only one EndDependentFn is allowed */ if (!parse_data->option_independent) { -pnp_warn ("PnPACPI: more than one EndDependentFn" ); +dev_warn (&dev->dev,"more than one EndDependentFn " +"in _PRS\n" );return AE_ERROR ; } parse_data->option = parse_data->option_independent;
@@ -726,7 +728,8 @@break ;default : -pnp_warn ("PnPACPI: unknown resource type %d" , res->type); +dev_warn (&dev->dev,"unknown resource type %d in _PRS\n" , + res->type);return AE_ERROR ; }
@@ -808,7 +811,7 @@ status =acpi_walk_resources (handle,METHOD_NAME__CRS , pnpacpi_count_resources, &res_cnt);if (ACPI_FAILURE (status)) { -pnp_err ("Evaluate _CRS failed" ); +dev_err (&dev->dev,"can't evaluate _CRS\n" );return -EINVAL ; }if (!res_cnt)
@@ -823,7 +826,7 @@ pnpacpi_type_resources, &resource);if (ACPI_FAILURE (status)) {kfree (buffer->pointer); -pnp_err ("Evaluate _CRS failed" ); +dev_err (&dev->dev,"can't evaluate _CRS\n" );return -EINVAL ; }/* resource will pointer the end resource now */
@@ -1074,7 +1077,8 @@case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 :case ACPI_RESOURCE_TYPE_GENERIC_REGISTER :default :/* other type */ -pnp_warn ("unknown resource type %d" , resource->type); +dev_warn (&dev->dev,"can't encode unknown resource " +"type %d\n" , resource->type);return -EINVAL ; } resource++;
drivers/pnp/pnpbios/rsparser.c +14 -22
@@ -241,9 +241,8 @@default :/* an unkown tag */ len_err: -printk (KERN_ERR -"PnPBIOS: Unknown tag '0x%x', length '%d'.\n" , - tag, len); +dev_err (&dev->dev,"unknown tag %#x length %d\n" , + tag, len);break ; }
@@ -254,8 +253,7 @@ p += len +1 ; } -printk (KERN_ERR -"PnPBIOS: Resource structure does not contain an end tag.\n" ); +dev_err (&dev->dev,"no end tag in resource structure\n" );return NULL ; }
@@ -471,8 +469,8 @@if (len !=0 ) goto len_err;if (option_independent == option) -printk (KERN_WARNING -"PnPBIOS: Missing SMALL_TAG_STARTDEP tag\n" ); +dev_warn (&dev->dev,"missing " +"SMALL_TAG_STARTDEP tag\n" ); option = option_independent;dev_dbg (&dev->dev,"end dependent options\n" );break ;
@@ -482,9 +480,8 @@default :/* an unkown tag */ len_err: -printk (KERN_ERR -"PnPBIOS: Unknown tag '0x%x', length '%d'.\n" , - tag, len); +dev_err (&dev->dev,"unknown tag %#x length %d\n" , + tag, len);break ; }
@@ -495,8 +492,7 @@ p += len +1 ; } -printk (KERN_ERR -"PnPBIOS: Resource structure does not contain an end tag.\n" ); +dev_err (&dev->dev,"no end tag in resource structure\n" );return NULL ; }
@@ -554,9 +550,8 @@default :/* an unkown tag */ len_err: -printk (KERN_ERR -"PnPBIOS: Unknown tag '0x%x', length '%d'.\n" , - tag, len); +dev_err (&dev->dev,"unknown tag %#x length %d\n" , + tag, len);break ; }
@@ -567,8 +562,7 @@ p += len +1 ; } -printk (KERN_ERR -"PnPBIOS: Resource structure does not contain an end tag.\n" ); +dev_err (&dev->dev,"no end tag in resource structure\n" );return NULL ; }
@@ -774,9 +768,8 @@default :/* an unkown tag */ len_err: -printk (KERN_ERR -"PnPBIOS: Unknown tag '0x%x', length '%d'.\n" , - tag, len); +dev_err (&dev->dev,"unknown tag %#x length %d\n" , + tag, len);break ; }
@@ -787,8 +780,7 @@ p += len +1 ; } -printk (KERN_ERR -"PnPBIOS: Resource structure does not contain an end tag.\n" ); +dev_err (&dev->dev,"no end tag in resource structure\n" );return NULL ; }
PATCH 26/55 PNP: factor pnp_init_resource_table() and pnp_clean_resource_table()
In reply to Bjorn HelgaasMove the common part of pnp_init_resource_table() and pnp_clean_resource_table() into a new pnp_init_resource(). This reduces a little code duplication and will be useful later to initialize an individual resource.
--- drivers/pnp/base.h | 2 + drivers/pnp/manager.c | 90 ++++++++++++++++++++++++-------------------------- 2 files changed, 46 insertions(+), 46 deletions(-)
drivers/pnp/base.h +2 -0
@@ -18,3 +18,5 @@int pnp_check_dma (struct pnp_dev * dev,int idx);void dbg_pnp_show_resources (struct pnp_dev *dev,char *desc); + +void pnp_init_resource (struct resource *res);
drivers/pnp/manager.c +52 -46
134 lines not on this page · raw message
PATCH 27/55 PNP: add pnp_get_resource() interface
In reply to Bjorn HelgaasThis adds a pnp_get_resource() that works the same way as platform_get_resource(). This will enable us to consolidate many pnp_resource_table references in one place, which will make it easier to make the table dynamic.
--- drivers/pnp/resource.c | 27 +++++++++++++++++++++++++++ include/linux/pnp.h | 1 + 2 files changed, 28 insertions(+)
include/linux/pnp.h +1 -0
@@ -25,6 +25,7 @@/* * Resource Management */ +struct resource *pnp_get_resource (struct pnp_dev *,unsigned int ,unsigned int );/* Use these instead of directly reading pnp_dev to get resource information */ #define pnp_port_start (dev,bar) ((dev)->res.port_resource[(bar)].start)
drivers/pnp/resource.c +27 -0
@@ -487,6 +487,33 @@#endif } +struct resource *pnp_get_resource (struct pnp_dev *dev, +unsigned int type,unsigned int num) +{ +struct pnp_resource_table *res = &dev->res; + +switch (type) { +case IORESOURCE_IO : +if (num >=PNP_MAX_PORT ) +return NULL ; +return &res->port_resource[num]; +case IORESOURCE_MEM : +if (num >=PNP_MAX_MEM ) +return NULL ; +return &res->mem_resource[num]; +case IORESOURCE_IRQ : +if (num >=PNP_MAX_IRQ ) +return NULL ; +return &res->irq_resource[num]; +case IORESOURCE_DMA : +if (num >=PNP_MAX_DMA ) +return NULL ; +return &res->dma_resource[num]; + } +return NULL ; +} +EXPORT_SYMBOL (pnp_get_resource); +/* format is: pnp_reserve_irq=irq1[,irq2] .... */ static int __init pnp_setup_reserve_irq (char *str) {
PATCH 28/55 PNP: remove pnp_mem_flags() as an lvalue
In reply to Bjorn HelgaasA future change will change pnp_mem_flags() from a "#define that simplifies to an lvalue" to "an inline function that returns the flags value."
drivers/pnp/quirks.c +3 -1
@@ -117,6 +117,7 @@static void quirk_system_pci_resources (struct pnp_dev *dev) {struct pci_dev *pdev =NULL ; +struct resource *res;resource_size_t pnp_start, pnp_end, pci_start, pci_end;int i, j;
@@ -176,7 +177,8 @@pci_name (pdev), i, (unsigned long long ) pci_start, (unsigned long long) pci_end); -pnp_mem_flags (dev, j) =0 ; + res =pnp_get_resource (dev,IORESOURCE_MEM , j); + res->flags =0 ; } } }
PATCH 29/55 PNP: convert resource accessors to use pnp_get_resource(), not pnp_resource_table
In reply to Bjorn HelgaasThis removes more direct references to pnp_resource_table.
--- include/linux/pnp.h | 148 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 108 insertions(+), 40 deletions(-)
include/linux/pnp.h +105 -40
@@ -27,46 +27,111 @@*/ struct resource *pnp_get_resource (struct pnp_dev *,unsigned int ,unsigned int ); -/* Use these instead of directly reading pnp_dev to get resource information */ -#define pnp_port_start (dev,bar) ((dev)->res.port_resource[(bar)].start) -#define pnp_port_end (dev,bar) ((dev)->res.port_resource[(bar)].end) -#define pnp_port_flags (dev,bar) ((dev)->res.port_resource[(bar)].flags) -#define pnp_port_valid (dev,bar) \ - ((pnp_port_flags((dev),(bar)) & (IORESOURCE_IO | IORESOURCE_UNSET)) \ - == IORESOURCE_IO) -#define pnp_port_len (dev,bar) \ - ((pnp_port_start((dev),(bar)) == 0 && \ - pnp_port_end((dev),(bar)) == \ - pnp_port_start((dev),(bar))) ? 0 : \ - \ - (pnp_port_end((dev),(bar)) - \ - pnp_port_start((dev),(bar)) + 1)) - -#define pnp_mem_start (dev,bar) ((dev)->res.mem_resource[(bar)].start) -#define pnp_mem_end (dev,bar) ((dev)->res.mem_resource[(bar)].end) -#define pnp_mem_flags (dev,bar) ((dev)->res.mem_resource[(bar)].flags) -#define pnp_mem_valid (dev,bar) \ - ((pnp_mem_flags((dev),(bar)) & (IORESOURCE_MEM | IORESOURCE_UNSET)) \ - == IORESOURCE_MEM) -#define pnp_mem_len (dev,bar) \ - ((pnp_mem_start((dev),(bar)) == 0 && \ - pnp_mem_end((dev),(bar)) == \ - pnp_mem_start((dev),(bar))) ? 0 : \ - \ - (pnp_mem_end((dev),(bar)) - \ - pnp_mem_start((dev),(bar)) + 1)) - -#define pnp_irq (dev,bar) ((dev)->res.irq_resource[(bar)].start) -#define pnp_irq_flags (dev,bar) ((dev)->res.irq_resource[(bar)].flags) -#define pnp_irq_valid (dev,bar) \ - ((pnp_irq_flags((dev),(bar)) & (IORESOURCE_IRQ | IORESOURCE_UNSET)) \ - == IORESOURCE_IRQ) - -#define pnp_dma (dev,bar) ((dev)->res.dma_resource[(bar)].start) -#define pnp_dma_flags (dev,bar) ((dev)->res.dma_resource[(bar)].flags) -#define pnp_dma_valid (dev,bar) \ - ((pnp_dma_flags((dev),(bar)) & (IORESOURCE_DMA | IORESOURCE_UNSET)) \ - == IORESOURCE_DMA) +static inline int pnp_resource_valid (struct resource *res) +{ +if (res && !(res->flags &IORESOURCE_UNSET )) +return 1 ; +return 0 ; +} + +static inline resource_size_t pnp_resource_len (struct resource *res) +{ +if (res->start ==0 && res->end ==0 ) +return 0 ; +return res->end - res->start +1 ; +} + + +static inline resource_size_t pnp_port_start (struct pnp_dev *dev, +unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_IO , bar)->start; +} + +static inline resource_size_t pnp_port_end (struct pnp_dev *dev, +unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_IO , bar)->end; +} + +static inline unsigned long pnp_port_flags (struct pnp_dev *dev, +unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_IO , bar)->flags; +} + +static inline int pnp_port_valid (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_resource_valid (pnp_get_resource (dev,IORESOURCE_IO , bar)); +} + +static inline resource_size_t pnp_port_len (struct pnp_dev *dev, +unsigned int bar) +{ +return pnp_resource_len (pnp_get_resource (dev,IORESOURCE_IO , bar)); +} + + +static inline resource_size_t pnp_mem_start (struct pnp_dev *dev, +unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_MEM , bar)->start; +} + +static inline resource_size_t pnp_mem_end (struct pnp_dev *dev, +unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_MEM , bar)->end; +} + +static inline unsigned long pnp_mem_flags (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_MEM , bar)->flags; +} + +static inline int pnp_mem_valid (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_resource_valid (pnp_get_resource (dev,IORESOURCE_MEM , bar)); +} + +static inline resource_size_t pnp_mem_len (struct pnp_dev *dev, +unsigned int bar) +{ +return pnp_resource_len (pnp_get_resource (dev,IORESOURCE_MEM , bar)); +} + + +static inline resource_size_t pnp_irq (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_IRQ , bar)->start; +} + +static inline unsigned long pnp_irq_flags (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_IRQ , bar)->flags; +} + +static inline int pnp_irq_valid (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_resource_valid (pnp_get_resource (dev,IORESOURCE_IRQ , bar)); +} + + +static inline resource_size_t pnp_dma (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_DMA , bar)->start; +} + +static inline unsigned long pnp_dma_flags (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_get_resource (dev,IORESOURCE_DMA , bar)->flags; +} + +static inline int pnp_dma_valid (struct pnp_dev *dev,unsigned int bar) +{ +return pnp_resource_valid (pnp_get_resource (dev,IORESOURCE_DMA , bar)); +} +#define PNP_PORT_FLAG_16BITADDR (1<<0)#define PNP_PORT_FLAG_FIXED (1<<1)
PATCH 30/55 PNP: use conventional "i" for loop indices
In reply to Bjorn HelgaasCosmetic only: just use "i" instead of "tmp".
drivers/pnp/resource.c +46 -46
@@ -241,7 +241,7 @@int pnp_check_port (struct pnp_dev *dev,int idx) { -int tmp; +int i;struct pnp_dev *tdev;resource_size_t *port, *end, *tport, *tend;
@@ -260,18 +260,18 @@ }/* check if the resource is reserved */ -for (tmp =0 ; tmp <8 ; tmp++) { -int rport = pnp_reserve_io[tmp <<1 ]; -int rend = pnp_reserve_io[(tmp <<1 ) +1 ] + rport -1 ; +for (i =0 ; i <8 ; i++) { +int rport = pnp_reserve_io[i <<1 ]; +int rend = pnp_reserve_io[(i <<1 ) +1 ] + rport -1 ;if (ranged_conflict (port, end, &rport, &rend))return 0 ; }/* check for internal conflicts */ -for (tmp =0 ; tmp <PNP_MAX_PORT && tmp != idx; tmp++) { -if (dev->res.port_resource[tmp].flags &IORESOURCE_IO ) { - tport = &dev->res.port_resource[tmp].start; - tend = &dev->res.port_resource[tmp].end; +for (i =0 ; i <PNP_MAX_PORT && i != idx; i++) { +if (dev->res.port_resource[i].flags &IORESOURCE_IO ) { + tport = &dev->res.port_resource[i].start; + tend = &dev->res.port_resource[i].end;if (ranged_conflict (port, end, tport, tend))return 0 ; }
@@ -281,13 +281,13 @@pnp_for_each_dev (tdev) {if (tdev == dev)continue ; -for (tmp =0 ; tmp <PNP_MAX_PORT ; tmp++) { -if (tdev->res.port_resource[tmp].flags &IORESOURCE_IO ) { +for (i =0 ; i <PNP_MAX_PORT ; i++) { +if (tdev->res.port_resource[i].flags &IORESOURCE_IO ) {if (cannot_compare - (tdev->res.port_resource[tmp].flags)) + (tdev->res.port_resource[i].flags))continue ; - tport = &tdev->res.port_resource[tmp].start; - tend = &tdev->res.port_resource[tmp].end; + tport = &tdev->res.port_resource[i].start; + tend = &tdev->res.port_resource[i].end;if (ranged_conflict (port, end, tport, tend))return 0 ; }
@@ -299,7 +299,7 @@int pnp_check_mem (struct pnp_dev *dev,int idx) { -int tmp; +int i;struct pnp_dev *tdev;resource_size_t *addr, *end, *taddr, *tend;
@@ -318,18 +318,18 @@ }/* check if the resource is reserved */ -for (tmp =0 ; tmp <8 ; tmp++) { -int raddr = pnp_reserve_mem[tmp <<1 ]; -int rend = pnp_reserve_mem[(tmp <<1 ) +1 ] + raddr -1 ; +for (i =0 ; i <8 ; i++) { +int raddr = pnp_reserve_mem[i <<1 ]; +int rend = pnp_reserve_mem[(i <<1 ) +1 ] + raddr -1 ;if (ranged_conflict (addr, end, &raddr, &rend))return 0 ; }/* check for internal conflicts */ -for (tmp =0 ; tmp <PNP_MAX_MEM && tmp != idx; tmp++) { -if (dev->res.mem_resource[tmp].flags &IORESOURCE_MEM ) { - taddr = &dev->res.mem_resource[tmp].start; - tend = &dev->res.mem_resource[tmp].end; +for (i =0 ; i <PNP_MAX_MEM && i != idx; i++) { +if (dev->res.mem_resource[i].flags &IORESOURCE_MEM ) { + taddr = &dev->res.mem_resource[i].start; + tend = &dev->res.mem_resource[i].end;if (ranged_conflict (addr, end, taddr, tend))return 0 ; }
@@ -339,13 +339,13 @@pnp_for_each_dev (tdev) {if (tdev == dev)continue ; -for (tmp =0 ; tmp <PNP_MAX_MEM ; tmp++) { -if (tdev->res.mem_resource[tmp].flags &IORESOURCE_MEM ) { +for (i =0 ; i <PNP_MAX_MEM ; i++) { +if (tdev->res.mem_resource[i].flags &IORESOURCE_MEM ) {if (cannot_compare - (tdev->res.mem_resource[tmp].flags)) + (tdev->res.mem_resource[i].flags))continue ; - taddr = &tdev->res.mem_resource[tmp].start; - tend = &tdev->res.mem_resource[tmp].end; + taddr = &tdev->res.mem_resource[i].start; + tend = &tdev->res.mem_resource[i].end;if (ranged_conflict (addr, end, taddr, tend))return 0 ; }
@@ -362,7 +362,7 @@int pnp_check_irq (struct pnp_dev *dev,int idx) { -int tmp; +int i;struct pnp_dev *tdev;resource_size_t *irq = &dev->res.irq_resource[idx].start;
@@ -375,15 +375,15 @@return 0 ;/* check if the resource is reserved */ -for (tmp =0 ; tmp <16 ; tmp++) { -if (pnp_reserve_irq[tmp] == *irq) +for (i =0 ; i <16 ; i++) { +if (pnp_reserve_irq[i] == *irq)return 0 ; }/* check for internal conflicts */ -for (tmp =0 ; tmp <PNP_MAX_IRQ && tmp != idx; tmp++) { -if (dev->res.irq_resource[tmp].flags &IORESOURCE_IRQ ) { -if (dev->res.irq_resource[tmp].start == *irq) +for (i =0 ; i <PNP_MAX_IRQ && i != idx; i++) { +if (dev->res.irq_resource[i].flags &IORESOURCE_IRQ ) { +if (dev->res.irq_resource[i].start == *irq)return 0 ; } }
@@ -414,12 +414,12 @@pnp_for_each_dev (tdev) {if (tdev == dev)continue ; -for (tmp =0 ; tmp <PNP_MAX_IRQ ; tmp++) { -if (tdev->res.irq_resource[tmp].flags &IORESOURCE_IRQ ) { +for (i =0 ; i <PNP_MAX_IRQ ; i++) { +if (tdev->res.irq_resource[i].flags &IORESOURCE_IRQ ) {if (cannot_compare - (tdev->res.irq_resource[tmp].flags)) + (tdev->res.irq_resource[i].flags))continue ; -if ((tdev->res.irq_resource[tmp].start == *irq)) +if ((tdev->res.irq_resource[i].start == *irq))return 0 ; } }
@@ -431,7 +431,7 @@int pnp_check_dma (struct pnp_dev *dev,int idx) {#ifndef CONFIG_IA64 -int tmp; +int i;struct pnp_dev *tdev;resource_size_t *dma = &dev->res.dma_resource[idx].start;
@@ -444,15 +444,15 @@return 0 ;/* check if the resource is reserved */ -for (tmp =0 ; tmp <8 ; tmp++) { -if (pnp_reserve_dma[tmp] == *dma) +for (i =0 ; i <8 ; i++) { +if (pnp_reserve_dma[i] == *dma)return 0 ; }/* check for internal conflicts */ -for (tmp =0 ; tmp <PNP_MAX_DMA && tmp != idx; tmp++) { -if (dev->res.dma_resource[tmp].flags &IORESOURCE_DMA ) { -if (dev->res.dma_resource[tmp].start == *dma) +for (i =0 ; i <PNP_MAX_DMA && i != idx; i++) { +if (dev->res.dma_resource[i].flags &IORESOURCE_DMA ) { +if (dev->res.dma_resource[i].start == *dma)return 0 ; } }
@@ -469,12 +469,12 @@pnp_for_each_dev (tdev) {if (tdev == dev)continue ; -for (tmp =0 ; tmp <PNP_MAX_DMA ; tmp++) { -if (tdev->res.dma_resource[tmp].flags &IORESOURCE_DMA ) { +for (i =0 ; i <PNP_MAX_DMA ; i++) { +if (tdev->res.dma_resource[i].flags &IORESOURCE_DMA ) {if (cannot_compare - (tdev->res.dma_resource[tmp].flags)) + (tdev->res.dma_resource[i].flags))continue ; -if ((tdev->res.dma_resource[tmp].start == *dma)) +if ((tdev->res.dma_resource[i].start == *dma))return 0 ; } }
PATCH 31/55 PNP: reduce redundancy in pnp_assign_port() and others
In reply to Bjorn HelgaasUse a temporary "res" pointer to replace repeated lookups in the pnp resource tables.
--- drivers/pnp/manager.c | 108 ++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 60 deletions(-)
drivers/pnp/manager.c +56 -67
@@ -19,8 +19,7 @@static int pnp_assign_port (struct pnp_dev *dev,struct pnp_port *rule,int idx) { -resource_size_t *start, *end; -unsigned long *flags; +struct resource *res;if (idx >=PNP_MAX_PORT ) {dev_err (&dev->dev,"too many I/O port resources\n" );
@@ -28,49 +27,46 @@return 1 ; } - start = &dev->res.port_resource[idx].start; - end = &dev->res.port_resource[idx].end; - flags = &dev->res.port_resource[idx].flags; + res = &dev->res.port_resource[idx];/* check if this resource has been manually set, if so skip */ -if (!(dev->res.port_resource[idx].flags &IORESOURCE_AUTO )) { +if (!(res->flags &IORESOURCE_AUTO )) {dev_dbg (&dev->dev," io %d already set to %#llx-%#llx " -"flags %#lx\n" , idx, (unsigned long long ) *start, - (unsigned long long ) *end, *flags); +"flags %#lx\n" , idx, (unsigned long long ) res->start, + (unsigned long long ) res->end, res->flags);return 1 ; }/* set the initial values */ - *flags |= rule->flags |IORESOURCE_IO ; - *flags &= ~IORESOURCE_UNSET ; + res->flags |= rule->flags |IORESOURCE_IO ; + res->flags &= ~IORESOURCE_UNSET ;if (!rule->size) { - *flags |=IORESOURCE_DISABLED ; + res->flags |=IORESOURCE_DISABLED ;dev_dbg (&dev->dev," io %d disabled\n" , idx);return 1 ;/* skip disabled resource requests */ } - *start = rule->min; - *end = *start + rule->size -1 ; + res->start = rule->min; + res->end = res->start + rule->size -1 ;/* run through until pnp_check_port is happy */ while (!pnp_check_port (dev, idx)) { - *start += rule->align; - *end = *start + rule->size -1 ; -if (*start > rule->max || !rule->align) { + res->start += rule->align; + res->end = res->start + rule->size -1 ; +if (res->start > rule->max || !rule->align) {dev_dbg (&dev->dev," couldn't assign io %d\n" , idx);return 0 ; } }dev_dbg (&dev->dev," assign io %d %#llx-%#llx\n" , idx, - (unsigned long long ) *start, (unsigned long long ) *end); + (unsigned long long ) res->start, (unsigned long long ) res->end);return 1 ; }static int pnp_assign_mem (struct pnp_dev *dev,struct pnp_mem *rule,int idx) { -resource_size_t *start, *end; -unsigned long *flags; +struct resource *res;if (idx >=PNP_MAX_MEM ) {dev_err (&dev->dev,"too many memory resources\n" );
@@ -78,59 +74,56 @@return 1 ; } - start = &dev->res.mem_resource[idx].start; - end = &dev->res.mem_resource[idx].end; - flags = &dev->res.mem_resource[idx].flags; + res = &dev->res.mem_resource[idx];/* check if this resource has been manually set, if so skip */ -if (!(dev->res.mem_resource[idx].flags &IORESOURCE_AUTO )) { +if (!(res->flags &IORESOURCE_AUTO )) {dev_dbg (&dev->dev," mem %d already set to %#llx-%#llx " -"flags %#lx\n" , idx, (unsigned long long ) *start, - (unsigned long long ) *end, *flags); +"flags %#lx\n" , idx, (unsigned long long ) res->start, + (unsigned long long ) res->end, res->flags);return 1 ; }/* set the initial values */ - *flags |= rule->flags |IORESOURCE_MEM ; - *flags &= ~IORESOURCE_UNSET ; + res->flags |= rule->flags |IORESOURCE_MEM ; + res->flags &= ~IORESOURCE_UNSET ;/* convert pnp flags to standard Linux flags */ if (!(rule->flags &IORESOURCE_MEM_WRITEABLE )) - *flags |=IORESOURCE_READONLY ; + res->flags |=IORESOURCE_READONLY ;if (rule->flags &IORESOURCE_MEM_CACHEABLE ) - *flags |=IORESOURCE_CACHEABLE ; + res->flags |=IORESOURCE_CACHEABLE ;if (rule->flags &IORESOURCE_MEM_RANGELENGTH ) - *flags |=IORESOURCE_RANGELENGTH ; + res->flags |=IORESOURCE_RANGELENGTH ;if (rule->flags &IORESOURCE_MEM_SHADOWABLE ) - *flags |=IORESOURCE_SHADOWABLE ; + res->flags |=IORESOURCE_SHADOWABLE ;if (!rule->size) { - *flags |=IORESOURCE_DISABLED ; + res->flags |=IORESOURCE_DISABLED ;dev_dbg (&dev->dev," mem %d disabled\n" , idx);return 1 ;/* skip disabled resource requests */ } - *start = rule->min; - *end = *start + rule->size -1 ; + res->start = rule->min; + res->end = res->start + rule->size -1 ;/* run through until pnp_check_mem is happy */ while (!pnp_check_mem (dev, idx)) { - *start += rule->align; - *end = *start + rule->size -1 ; -if (*start > rule->max || !rule->align) { + res->start += rule->align; + res->end = res->start + rule->size -1 ; +if (res->start > rule->max || !rule->align) {dev_dbg (&dev->dev," couldn't assign mem %d\n" , idx);return 0 ; } }dev_dbg (&dev->dev," assign mem %d %#llx-%#llx\n" , idx, - (unsigned long long ) *start, (unsigned long long ) *end); + (unsigned long long ) res->start, (unsigned long long ) res->end);return 1 ; }static int pnp_assign_irq (struct pnp_dev *dev,struct pnp_irq *rule,int idx) { -resource_size_t *start, *end; -unsigned long *flags; +struct resource *res;int i;/* IRQ priority: this table is good for i386 */
@@ -144,40 +137,39 @@return 1 ; } - start = &dev->res.irq_resource[idx].start; - end = &dev->res.irq_resource[idx].end; - flags = &dev->res.irq_resource[idx].flags; + res = &dev->res.irq_resource[idx];/* check if this resource has been manually set, if so skip */ -if (!(dev->res.irq_resource[idx].flags &IORESOURCE_AUTO )) { +if (!(res->flags &IORESOURCE_AUTO )) {dev_dbg (&dev->dev," irq %d already set to %d flags %#lx\n" , - idx, (int ) *start, *flags); + idx, (int ) res->start, res->flags);return 1 ; }/* set the initial values */ - *flags |= rule->flags |IORESOURCE_IRQ ; - *flags &= ~IORESOURCE_UNSET ; + res->flags |= rule->flags |IORESOURCE_IRQ ; + res->flags &= ~IORESOURCE_UNSET ;if (bitmap_empty (rule->map,PNP_IRQ_NR )) { - *flags |=IORESOURCE_DISABLED ; + res->flags |=IORESOURCE_DISABLED ;dev_dbg (&dev->dev," irq %d disabled\n" , idx);return 1 ;/* skip disabled resource requests */ }/* TBD: need check for >16 IRQ */ - *start =find_next_bit (rule->map,PNP_IRQ_NR ,16 ); -if (*start <PNP_IRQ_NR ) { - *end = *start; -dev_dbg (&dev->dev," assign irq %d %d\n" , idx, (int ) *start); + res->start =find_next_bit (rule->map,PNP_IRQ_NR ,16 ); +if (res->start <PNP_IRQ_NR ) { + res->end = res->start; +dev_dbg (&dev->dev," assign irq %d %d\n" , idx, + (int ) res->start);return 1 ; }for (i =0 ; i <16 ; i++) {if (test_bit (xtab[i], rule->map)) { - *start = *end = xtab[i]; + res->start = res->end = xtab[i];if (pnp_check_irq (dev, idx)) {dev_dbg (&dev->dev," assign irq %d %d\n" , idx, - (int ) *start); + (int ) res->start);return 1 ; } }
@@ -188,8 +180,7 @@static void pnp_assign_dma (struct pnp_dev *dev,struct pnp_dma *rule,int idx) { -resource_size_t *start, *end; -unsigned long *flags; +struct resource *res;int i;/* DMA priority: this table is good for i386 */
@@ -202,35 +193,33 @@return ; } - start = &dev->res.dma_resource[idx].start; - end = &dev->res.dma_resource[idx].end; - flags = &dev->res.dma_resource[idx].flags; + res = &dev->res.dma_resource[idx];/* check if this resource has been manually set, if so skip */ -if (!(dev->res.dma_resource[idx].flags &IORESOURCE_AUTO )) { +if (!(res->flags &IORESOURCE_AUTO )) {dev_dbg (&dev->dev," dma %d already set to %d flags %#lx\n" , - idx, (int ) *start, *flags); + idx, (int ) res->start, res->flags);return ; }/* set the initial values */ - *flags |= rule->flags |IORESOURCE_DMA ; - *flags &= ~IORESOURCE_UNSET ; + res->flags |= rule->flags |IORESOURCE_DMA ; + res->flags &= ~IORESOURCE_UNSET ;for (i =0 ; i <8 ; i++) {if (rule->map & (1 << xtab[i])) { - *start = *end = xtab[i]; + res->start = res->end = xtab[i];if (pnp_check_dma (dev, idx)) {dev_dbg (&dev->dev," assign dma %d %d\n" , idx, - (int ) *start); + (int ) res->start);return ; } } }#ifdef MAX_DMA_CHANNELS - *start = *end =MAX_DMA_CHANNELS ; + res->start = res->end =MAX_DMA_CHANNELS ;#endif - *flags |=IORESOURCE_UNSET |IORESOURCE_DISABLED ; + res->flags |=IORESOURCE_UNSET |IORESOURCE_DISABLED ;dev_dbg (&dev->dev," disable dma %d\n" , idx); }
PATCH 32/55 PNP: reduce redundancy in pnp_check_port() and others
In reply to Bjorn HelgaasUse a temporary "res" pointer to replace repeated lookups in the pnp resource tables.
drivers/pnp/resource.c +54 -38
@@ -243,13 +243,15 @@ {int i;struct pnp_dev *tdev; +struct resource *res, *tres;resource_size_t *port, *end, *tport, *tend; - port = &dev->res.port_resource[idx].start; - end = &dev->res.port_resource[idx].end; + res = &dev->res.port_resource[idx]; + port = &res->start; + end = &res->end;/* if the resource doesn't exist, don't complain about it */ -if (cannot_compare (dev->res.port_resource[idx].flags)) +if (cannot_compare (res->flags))return 1 ;/* check if the resource is already in use, skip if the
@@ -269,9 +271,10 @@/* check for internal conflicts */ for (i =0 ; i <PNP_MAX_PORT && i != idx; i++) { -if (dev->res.port_resource[i].flags &IORESOURCE_IO ) { - tport = &dev->res.port_resource[i].start; - tend = &dev->res.port_resource[i].end; + tres = &dev->res.port_resource[i]; +if (tres->flags &IORESOURCE_IO ) { + tport = &tres->start; + tend = &tres->end;if (ranged_conflict (port, end, tport, tend))return 0 ; }
@@ -282,12 +285,12 @@if (tdev == dev)continue ;for (i =0 ; i <PNP_MAX_PORT ; i++) { -if (tdev->res.port_resource[i].flags &IORESOURCE_IO ) { -if (cannot_compare - (tdev->res.port_resource[i].flags)) + tres = &tdev->res.port_resource[i]; +if (tres->flags &IORESOURCE_IO ) { +if (cannot_compare (tres->flags))continue ; - tport = &tdev->res.port_resource[i].start; - tend = &tdev->res.port_resource[i].end; + tport = &tres->start; + tend = &tres->end;if (ranged_conflict (port, end, tport, tend))return 0 ; }
@@ -301,13 +304,15 @@ {int i;struct pnp_dev *tdev; +struct resource *res, *tres;resource_size_t *addr, *end, *taddr, *tend; - addr = &dev->res.mem_resource[idx].start; - end = &dev->res.mem_resource[idx].end; + res = &dev->res.mem_resource[idx]; + addr = &res->start; + end = &res->end;/* if the resource doesn't exist, don't complain about it */ -if (cannot_compare (dev->res.mem_resource[idx].flags)) +if (cannot_compare (res->flags))return 1 ;/* check if the resource is already in use, skip if the
@@ -327,9 +332,10 @@/* check for internal conflicts */ for (i =0 ; i <PNP_MAX_MEM && i != idx; i++) { -if (dev->res.mem_resource[i].flags &IORESOURCE_MEM ) { - taddr = &dev->res.mem_resource[i].start; - tend = &dev->res.mem_resource[i].end; + tres = &dev->res.mem_resource[i]; +if (tres->flags &IORESOURCE_MEM ) { + taddr = &tres->start; + tend = &tres->end;if (ranged_conflict (addr, end, taddr, tend))return 0 ; }
@@ -340,12 +346,12 @@if (tdev == dev)continue ;for (i =0 ; i <PNP_MAX_MEM ; i++) { -if (tdev->res.mem_resource[i].flags &IORESOURCE_MEM ) { -if (cannot_compare - (tdev->res.mem_resource[i].flags)) + tres = &tdev->res.mem_resource[i]; +if (tres->flags &IORESOURCE_MEM ) { +if (cannot_compare (tres->flags))continue ; - taddr = &tdev->res.mem_resource[i].start; - tend = &tdev->res.mem_resource[i].end; + taddr = &tres->start; + tend = &tres->end;if (ranged_conflict (addr, end, taddr, tend))return 0 ; }
@@ -364,10 +370,14 @@ {int i;struct pnp_dev *tdev; -resource_size_t *irq = &dev->res.irq_resource[idx].start; +struct resource *res, *tres; +resource_size_t *irq; + + res = &dev->res.irq_resource[idx]; + irq = &res->start;/* if the resource doesn't exist, don't complain about it */ -if (cannot_compare (dev->res.irq_resource[idx].flags)) +if (cannot_compare (res->flags))return 1 ;/* check if the resource is valid */
@@ -382,8 +392,9 @@/* check for internal conflicts */ for (i =0 ; i <PNP_MAX_IRQ && i != idx; i++) { -if (dev->res.irq_resource[i].flags &IORESOURCE_IRQ ) { -if (dev->res.irq_resource[i].start == *irq) + tres = &dev->res.irq_resource[i]; +if (tres->flags &IORESOURCE_IRQ ) { +if (tres->start == *irq)return 0 ; } }
@@ -415,11 +426,11 @@if (tdev == dev)continue ;for (i =0 ; i <PNP_MAX_IRQ ; i++) { -if (tdev->res.irq_resource[i].flags &IORESOURCE_IRQ ) { -if (cannot_compare - (tdev->res.irq_resource[i].flags)) + tres = &tdev->res.irq_resource[i]; +if (tres->flags &IORESOURCE_IRQ ) { +if (cannot_compare (tres->flags))continue ; -if ((tdev->res.irq_resource[i].start == *irq)) +if (tres->start == *irq)return 0 ; } }
@@ -433,10 +444,14 @@#ifndef CONFIG_IA64 int i;struct pnp_dev *tdev; -resource_size_t *dma = &dev->res.dma_resource[idx].start; +struct resource *res, *tres; +resource_size_t *dma; + + res = &dev->res.dma_resource[idx]; + dma = &res->start;/* if the resource doesn't exist, don't complain about it */ -if (cannot_compare (dev->res.dma_resource[idx].flags)) +if (cannot_compare (res->flags))return 1 ;/* check if the resource is valid */
@@ -451,8 +466,9 @@/* check for internal conflicts */ for (i =0 ; i <PNP_MAX_DMA && i != idx; i++) { -if (dev->res.dma_resource[i].flags &IORESOURCE_DMA ) { -if (dev->res.dma_resource[i].start == *dma) + tres = &dev->res.dma_resource[i]; +if (tres->flags &IORESOURCE_DMA ) { +if (tres->start == *dma)return 0 ; } }
@@ -470,11 +486,11 @@if (tdev == dev)continue ;for (i =0 ; i <PNP_MAX_DMA ; i++) { -if (tdev->res.dma_resource[i].flags &IORESOURCE_DMA ) { -if (cannot_compare - (tdev->res.dma_resource[i].flags)) + tres = &tdev->res.dma_resource[i]; +if (tres->flags &IORESOURCE_DMA ) { +if (cannot_compare (tres->flags))continue ; -if ((tdev->res.dma_resource[i].start == *dma)) +if (tres->start == *dma)return 0 ; } }
PATCH 33/55 PNP: reduce redundancy in pnp_set_current_resources()
In reply to Bjorn HelgaasUse a temporary "res" pointer to replace repeated lookups in the pnp resource tables.
drivers/pnp/interface.c +17 -24
@@ -323,6 +323,7 @@ const char *ubuf, size_t count) {struct pnp_dev *dev =to_pnp_dev (dmdev); +struct resource *res;char *buf = (void *)ubuf;int retval =0 ;
@@ -382,21 +383,18 @@ buf +=2 ;while (isspace (*buf)) ++buf; - dev->res.port_resource[nport].start = -simple_strtoul (buf, &buf,0 ); + res = &dev->res.port_resource[nport]; + res->start =simple_strtoul (buf, &buf,0 );while (isspace (*buf)) ++buf;if (*buf =='-' ) { buf +=1 ;while (isspace (*buf)) ++buf; - dev->res.port_resource[nport].end = -simple_strtoul (buf, &buf,0 ); + res->end =simple_strtoul (buf, &buf,0 ); }else - dev->res.port_resource[nport].end = - dev->res.port_resource[nport].start; - dev->res.port_resource[nport].flags = -IORESOURCE_IO ; + res->end = res->start; + res->flags =IORESOURCE_IO ; nport++;if (nport >=PNP_MAX_PORT )break ;
@@ -406,21 +404,18 @@ buf +=3 ;while (isspace (*buf)) ++buf; - dev->res.mem_resource[nmem].start = -simple_strtoul (buf, &buf,0 ); + res = &dev->res.mem_resource[nmem]; + res->start =simple_strtoul (buf, &buf,0 );while (isspace (*buf)) ++buf;if (*buf =='-' ) { buf +=1 ;while (isspace (*buf)) ++buf; - dev->res.mem_resource[nmem].end = -simple_strtoul (buf, &buf,0 ); + res->end =simple_strtoul (buf, &buf,0 ); }else - dev->res.mem_resource[nmem].end = - dev->res.mem_resource[nmem].start; - dev->res.mem_resource[nmem].flags = -IORESOURCE_MEM ; + res->end = res->start; + res->flags =IORESOURCE_MEM ; nmem++;if (nmem >=PNP_MAX_MEM )break ;
@@ -430,11 +425,10 @@ buf +=3 ;while (isspace (*buf)) ++buf; - dev->res.irq_resource[nirq].start = - dev->res.irq_resource[nirq].end = + res = &dev->res.irq_resource[nirq]; + res->start = res->end =simple_strtoul (buf, &buf,0 ); - dev->res.irq_resource[nirq].flags = -IORESOURCE_IRQ ; + res->flags =IORESOURCE_IRQ ; nirq++;if (nirq >=PNP_MAX_IRQ )break ;
@@ -444,11 +438,10 @@ buf +=3 ;while (isspace (*buf)) ++buf; - dev->res.dma_resource[ndma].start = - dev->res.dma_resource[ndma].end = + res = &dev->res.dma_resource[ndma]; + res->start = res->end =simple_strtoul (buf, &buf,0 ); - dev->res.dma_resource[ndma].flags = -IORESOURCE_DMA ; + res->flags =IORESOURCE_DMA ; ndma++;if (ndma >=PNP_MAX_DMA )break ;
PATCH 34/55 PNP: check for conflicts with all resources, not just earlier ones
In reply to Bjorn HelgaasThis patch removes a use of "idx" in pnp_check_port() and similar functions, in preparation for replacing idx with a pointer to the resource itself.
I split this out because it changes the behavior slightly: we used to check for conflicts only with earlier resources, e.g., we checked resource 2 against resources 0 and 1 but not against 3, 4, etc. Now we will check against all resources except 2.
Since resources are assigned in ascending order, the old behavior was probably safe, but I don't like to depend on that ordering.
drivers/pnp/resource.c +8 -8
@@ -270,9 +270,9 @@ }/* check for internal conflicts */ -for (i =0 ; i <PNP_MAX_PORT && i != idx; i++) { +for (i =0 ; i <PNP_MAX_PORT ; i++) { tres = &dev->res.port_resource[i]; -if (tres->flags &IORESOURCE_IO ) { +if (tres != res && tres->flags &IORESOURCE_IO ) { tport = &tres->start; tend = &tres->end;if (ranged_conflict (port, end, tport, tend))
@@ -331,9 +331,9 @@ }/* check for internal conflicts */ -for (i =0 ; i <PNP_MAX_MEM && i != idx; i++) { +for (i =0 ; i <PNP_MAX_MEM ; i++) { tres = &dev->res.mem_resource[i]; -if (tres->flags &IORESOURCE_MEM ) { +if (tres != res && tres->flags &IORESOURCE_MEM ) { taddr = &tres->start; tend = &tres->end;if (ranged_conflict (addr, end, taddr, tend))
@@ -391,9 +391,9 @@ }/* check for internal conflicts */ -for (i =0 ; i <PNP_MAX_IRQ && i != idx; i++) { +for (i =0 ; i <PNP_MAX_IRQ ; i++) { tres = &dev->res.irq_resource[i]; -if (tres->flags &IORESOURCE_IRQ ) { +if (tres != res && tres->flags &IORESOURCE_IRQ ) {if (tres->start == *irq)return 0 ; }
@@ -465,9 +465,9 @@ }/* check for internal conflicts */ -for (i =0 ; i <PNP_MAX_DMA && i != idx; i++) { +for (i =0 ; i <PNP_MAX_DMA ; i++) { tres = &dev->res.dma_resource[i]; -if (tres->flags &IORESOURCE_DMA ) { +if (tres != res && tres->flags &IORESOURCE_DMA ) {if (tres->start == *dma)return 0 ; }
PATCH 35/55 PNP: pass resources, not indexes, to pnp_check_port(), et al
In reply to Bjorn HelgaasThe caller already has the struct resource pointer, so no need for pnp_check_port(), pnp_check_mem(), etc., to look it up again.
drivers/pnp/base.h +4 -4
@@ -12,10 +12,10 @@int __pnp_add_device (struct pnp_dev *dev);void __pnp_remove_device (struct pnp_dev *dev); -int pnp_check_port (struct pnp_dev * dev,int idx); -int pnp_check_mem (struct pnp_dev * dev,int idx); -int pnp_check_irq (struct pnp_dev * dev,int idx); -int pnp_check_dma (struct pnp_dev * dev,int idx); +int pnp_check_port (struct pnp_dev *dev,struct resource *res); +int pnp_check_mem (struct pnp_dev *dev,struct resource *res); +int pnp_check_irq (struct pnp_dev *dev,struct resource *res); +int pnp_check_dma (struct pnp_dev *dev,struct resource *res);void dbg_pnp_show_resources (struct pnp_dev *dev,char *desc);
drivers/pnp/manager.c +4 -4
@@ -51,7 +51,7 @@ res->end = res->start + rule->size -1 ;/* run through until pnp_check_port is happy */ -while (!pnp_check_port (dev, idx)) { +while (!pnp_check_port (dev, res)) { res->start += rule->align; res->end = res->start + rule->size -1 ;if (res->start > rule->max || !rule->align) {
@@ -108,7 +108,7 @@ res->end = res->start + rule->size -1 ;/* run through until pnp_check_mem is happy */ -while (!pnp_check_mem (dev, idx)) { +while (!pnp_check_mem (dev, res)) { res->start += rule->align; res->end = res->start + rule->size -1 ;if (res->start > rule->max || !rule->align) {
@@ -167,7 +167,7 @@for (i =0 ; i <16 ; i++) {if (test_bit (xtab[i], rule->map)) { res->start = res->end = xtab[i]; -if (pnp_check_irq (dev, idx)) { +if (pnp_check_irq (dev, res)) {dev_dbg (&dev->dev," assign irq %d %d\n" , idx, (int ) res->start);return 1 ;
@@ -209,7 +209,7 @@for (i =0 ; i <8 ; i++) {if (rule->map & (1 << xtab[i])) { res->start = res->end = xtab[i]; -if (pnp_check_dma (dev, idx)) { +if (pnp_check_dma (dev, res)) {dev_dbg (&dev->dev," assign dma %d %d\n" , idx, (int ) res->start);return ;
drivers/pnp/resource.c +8 -12
@@ -239,14 +239,13 @@#define cannot_compare (flags) \ ((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) -int pnp_check_port (struct pnp_dev *dev,int idx) +int pnp_check_port (struct pnp_dev *dev,struct resource *res) {int i;struct pnp_dev *tdev; -struct resource *res, *tres; +struct resource *tres;resource_size_t *port, *end, *tport, *tend; - res = &dev->res.port_resource[idx]; port = &res->start; end = &res->end;
@@ -300,14 +299,13 @@return 1 ; } -int pnp_check_mem (struct pnp_dev *dev,int idx) +int pnp_check_mem (struct pnp_dev *dev,struct resource *res) {int i;struct pnp_dev *tdev; -struct resource *res, *tres; +struct resource *tres;resource_size_t *addr, *end, *taddr, *tend; - res = &dev->res.mem_resource[idx]; addr = &res->start; end = &res->end;
@@ -366,14 +364,13 @@return IRQ_HANDLED ; } -int pnp_check_irq (struct pnp_dev *dev,int idx) +int pnp_check_irq (struct pnp_dev *dev,struct resource *res) {int i;struct pnp_dev *tdev; -struct resource *res, *tres; +struct resource *tres;resource_size_t *irq; - res = &dev->res.irq_resource[idx]; irq = &res->start;/* if the resource doesn't exist, don't complain about it */
@@ -439,15 +436,14 @@return 1 ; } -int pnp_check_dma (struct pnp_dev *dev,int idx) +int pnp_check_dma (struct pnp_dev *dev,struct resource *res) {#ifndef CONFIG_IA64 int i;struct pnp_dev *tdev; -struct resource *res, *tres; +struct resource *tres;resource_size_t *dma; - res = &dev->res.dma_resource[idx]; dma = &res->start;/* if the resource doesn't exist, don't complain about it */
PATCH 36/55 PNP: convert resource checks to use pnp_get_resource(), not pnp_resource_table
In reply to Bjorn HelgaasThis removes more direct references to pnp_resource_table.
--- drivers/pnp/resource.c | 96 +++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 38 deletions(-)
drivers/pnp/resource.c +16 -16
@@ -270,8 +270,8 @@/* check for internal conflicts */ for (i =0 ; i <PNP_MAX_PORT ; i++) { - tres = &dev->res.port_resource[i]; -if (tres != res && tres->flags &IORESOURCE_IO ) { + tres =pnp_get_resource (dev,IORESOURCE_IO , i); +if (tres && tres != res && tres->flags &IORESOURCE_IO ) { tport = &tres->start; tend = &tres->end;if (ranged_conflict (port, end, tport, tend))
@@ -284,8 +284,8 @@if (tdev == dev)continue ;for (i =0 ; i <PNP_MAX_PORT ; i++) { - tres = &tdev->res.port_resource[i]; -if (tres->flags &IORESOURCE_IO ) { + tres =pnp_get_resource (tdev,IORESOURCE_IO , i); +if (tres && tres->flags &IORESOURCE_IO ) {if (cannot_compare (tres->flags))continue ; tport = &tres->start;
@@ -330,8 +330,8 @@/* check for internal conflicts */ for (i =0 ; i <PNP_MAX_MEM ; i++) { - tres = &dev->res.mem_resource[i]; -if (tres != res && tres->flags &IORESOURCE_MEM ) { + tres =pnp_get_resource (dev,IORESOURCE_MEM , i); +if (tres && tres != res && tres->flags &IORESOURCE_MEM ) { taddr = &tres->start; tend = &tres->end;if (ranged_conflict (addr, end, taddr, tend))
@@ -344,8 +344,8 @@if (tdev == dev)continue ;for (i =0 ; i <PNP_MAX_MEM ; i++) { - tres = &tdev->res.mem_resource[i]; -if (tres->flags &IORESOURCE_MEM ) { + tres =pnp_get_resource (tdev,IORESOURCE_MEM , i); +if (tres && tres->flags &IORESOURCE_MEM ) {if (cannot_compare (tres->flags))continue ; taddr = &tres->start;
@@ -389,8 +389,8 @@/* check for internal conflicts */ for (i =0 ; i <PNP_MAX_IRQ ; i++) { - tres = &dev->res.irq_resource[i]; -if (tres != res && tres->flags &IORESOURCE_IRQ ) { + tres =pnp_get_resource (dev,IORESOURCE_IRQ , i); +if (tres && tres != res && tres->flags &IORESOURCE_IRQ ) {if (tres->start == *irq)return 0 ; }
@@ -423,8 +423,8 @@if (tdev == dev)continue ;for (i =0 ; i <PNP_MAX_IRQ ; i++) { - tres = &tdev->res.irq_resource[i]; -if (tres->flags &IORESOURCE_IRQ ) { + tres =pnp_get_resource (tdev,IORESOURCE_IRQ , i); +if (tres && tres->flags &IORESOURCE_IRQ ) {if (cannot_compare (tres->flags))continue ;if (tres->start == *irq)
@@ -462,8 +462,8 @@/* check for internal conflicts */ for (i =0 ; i <PNP_MAX_DMA ; i++) { - tres = &dev->res.dma_resource[i]; -if (tres != res && tres->flags &IORESOURCE_DMA ) { + tres =pnp_get_resource (dev,IORESOURCE_DMA , i); +if (tres && tres != res && tres->flags &IORESOURCE_DMA ) {if (tres->start == *dma)return 0 ; }
@@ -482,8 +482,8 @@if (tdev == dev)continue ;for (i =0 ; i <PNP_MAX_DMA ; i++) { - tres = &tdev->res.dma_resource[i]; -if (tres->flags &IORESOURCE_DMA ) { + tres =pnp_get_resource (tdev,IORESOURCE_DMA , i); +if (tres && tres->flags &IORESOURCE_DMA ) {if (cannot_compare (tres->flags))continue ;if (tres->start == *dma)
PATCH 37/55 PNP: convert encoders to use pnp_get_resource(), not pnp_resource_table
In reply to Bjorn HelgaasThis removes more direct references to pnp_resource_table. This path is used when telling a device what resources it should use.
This doesn't convert ISAPNP because ISA needs to know the config register index in addition to the resource itself.
drivers/pnp/pnpacpi/rsparser.c +8 -11
@@ -1014,7 +1014,6 @@int pnpacpi_encode_resources (struct pnp_dev *dev,struct acpi_buffer *buffer) { -struct pnp_resource_table *res_table = &dev->res;int i =0 ;/* pnpacpi_build_resource_template allocates extra mem */ int res_cnt = (buffer->length -1 ) /sizeof (struct acpi_resource ) -1 ;
@@ -1026,45 +1025,43 @@switch (resource->type) {case ACPI_RESOURCE_TYPE_IRQ :pnpacpi_encode_irq (dev, resource, - &res_table->irq_resource[irq]); +pnp_get_resource (dev,IORESOURCE_IRQ , irq)); irq++;break ;case ACPI_RESOURCE_TYPE_DMA :pnpacpi_encode_dma (dev, resource, - &res_table->dma_resource[dma]); +pnp_get_resource (dev,IORESOURCE_DMA , dma)); dma++;break ;case ACPI_RESOURCE_TYPE_IO :pnpacpi_encode_io (dev, resource, - &res_table->port_resource[port]); +pnp_get_resource (dev,IORESOURCE_IO , port)); port++;break ;case ACPI_RESOURCE_TYPE_FIXED_IO :pnpacpi_encode_fixed_io (dev, resource, - &res_table-> - port_resource[port]); +pnp_get_resource (dev,IORESOURCE_IO , port)); port++;break ;case ACPI_RESOURCE_TYPE_MEMORY24 :pnpacpi_encode_mem24 (dev, resource, - &res_table->mem_resource[mem]); +pnp_get_resource (dev,IORESOURCE_MEM , mem)); mem++;break ;case ACPI_RESOURCE_TYPE_MEMORY32 :pnpacpi_encode_mem32 (dev, resource, - &res_table->mem_resource[mem]); +pnp_get_resource (dev,IORESOURCE_MEM , mem)); mem++;break ;case ACPI_RESOURCE_TYPE_FIXED_MEMORY32 :pnpacpi_encode_fixed_mem32 (dev, resource, - &res_table-> - mem_resource[mem]); +pnp_get_resource (dev,IORESOURCE_MEM , mem)); mem++;break ;case ACPI_RESOURCE_TYPE_EXTENDED_IRQ :pnpacpi_encode_ext_irq (dev, resource, - &res_table->irq_resource[irq]); +pnp_get_resource (dev,IORESOURCE_IRQ , irq)); irq++;break ;case ACPI_RESOURCE_TYPE_START_DEPENDENT :
drivers/pnp/pnpbios/rsparser.c +14 -8
@@ -688,7 +688,6 @@unsigned char *p, unsigned char *end) { - struct pnp_resource_table *res = &dev->res; unsigned int len, tag;int port =0 , irq =0 , dma =0 , mem =0 ;
@@ -711,42 +710,48 @@case LARGE_TAG_MEM :if (len !=9 ) goto len_err; -pnpbios_encode_mem (dev, p, &res->mem_resource[mem]); +pnpbios_encode_mem (dev, p, +pnp_get_resource (dev,IORESOURCE_MEM , mem)); mem++;break ;case LARGE_TAG_MEM32 :if (len !=17 ) goto len_err; -pnpbios_encode_mem32 (dev, p, &res->mem_resource[mem]); +pnpbios_encode_mem32 (dev, p, +pnp_get_resource (dev,IORESOURCE_MEM , mem)); mem++;break ;case LARGE_TAG_FIXEDMEM32 :if (len !=9 ) goto len_err; -pnpbios_encode_fixed_mem32 (dev, p, &res->mem_resource[mem]); +pnpbios_encode_fixed_mem32 (dev, p, +pnp_get_resource (dev,IORESOURCE_MEM , mem)); mem++;break ;case SMALL_TAG_IRQ :if (len <2 || len >3 ) goto len_err; -pnpbios_encode_irq (dev, p, &res->irq_resource[irq]); +pnpbios_encode_irq (dev, p, +pnp_get_resource (dev,IORESOURCE_IRQ , irq)); irq++;break ;case SMALL_TAG_DMA :if (len !=2 ) goto len_err; -pnpbios_encode_dma (dev, p, &res->dma_resource[dma]); +pnpbios_encode_dma (dev, p, +pnp_get_resource (dev,IORESOURCE_DMA , dma)); dma++;break ;case SMALL_TAG_PORT :if (len !=7 ) goto len_err; -pnpbios_encode_port (dev, p, &res->port_resource[port]); +pnpbios_encode_port (dev, p, +pnp_get_resource (dev,IORESOURCE_IO , port)); port++;break ;
@@ -757,7 +762,8 @@case SMALL_TAG_FIXEDPORT :if (len !=3 ) goto len_err; -pnpbios_encode_fixed_port (dev, p, &res->port_resource[port]); +pnpbios_encode_fixed_port (dev, p, +pnp_get_resource (dev,IORESOURCE_IO , port)); port++;break ;
PATCH 38/55 PNP: convert assign, interface to use pnp_get_resource(), not pnp_resource_table
In reply to Bjorn HelgaasThis removes more direct references to pnp_resource_table from the pnp_assign_resources() path and the /sys user interface path.
drivers/pnp/manager.c +8 -12
@@ -21,14 +21,13 @@ {struct resource *res; -if (idx >=PNP_MAX_PORT ) { + res =pnp_get_resource (dev,IORESOURCE_IO , idx); +if (!res) {dev_err (&dev->dev,"too many I/O port resources\n" );/* pretend we were successful so at least the manager won't try again */ return 1 ; } - res = &dev->res.port_resource[idx]; -/* check if this resource has been manually set, if so skip */ if (!(res->flags &IORESOURCE_AUTO )) { dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
@@ -68,14 +67,13 @@ {struct resource *res; -if (idx >=PNP_MAX_MEM ) { + res =pnp_get_resource (dev,IORESOURCE_MEM , idx); +if (!res) {dev_err (&dev->dev,"too many memory resources\n" );/* pretend we were successful so at least the manager won't try again */ return 1 ; } - res = &dev->res.mem_resource[idx]; -/* check if this resource has been manually set, if so skip */ if (!(res->flags &IORESOURCE_AUTO )) { dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
@@ -131,14 +129,13 @@5 ,10 ,11 ,12 ,9 ,14 ,15 ,7 ,3 ,4 ,13 ,0 ,1 ,6 ,8 ,2 }; -if (idx >=PNP_MAX_IRQ ) { + res =pnp_get_resource (dev,IORESOURCE_IRQ , idx); +if (!res) {dev_err (&dev->dev,"too many IRQ resources\n" );/* pretend we were successful so at least the manager won't try again */ return 1 ; } - res = &dev->res.irq_resource[idx]; -/* check if this resource has been manually set, if so skip */ if (!(res->flags &IORESOURCE_AUTO )) { dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
@@ -188,13 +185,12 @@1 ,3 ,5 ,6 ,7 ,0 ,2 ,4 }; -if (idx >=PNP_MAX_DMA ) { + res =pnp_get_resource (dev,IORESOURCE_DMA , idx); +if (!res) {dev_err (&dev->dev,"too many DMA resources\n" );return ; } - res = &dev->res.dma_resource[idx]; -/* check if this resource has been manually set, if so skip */ if (!(res->flags &IORESOURCE_AUTO )) { dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
drivers/pnp/interface.c +16 -12
@@ -383,7 +383,10 @@ buf +=2 ;while (isspace (*buf)) ++buf; - res = &dev->res.port_resource[nport]; + res =pnp_get_resource (dev,IORESOURCE_IO , + nport); +if (!res) +break ; res->start =simple_strtoul (buf, &buf,0 );while (isspace (*buf)) ++buf;
@@ -396,15 +399,16 @@ res->end = res->start; res->flags =IORESOURCE_IO ; nport++; -if (nport >=PNP_MAX_PORT ) -break ;continue ; }if (!strnicmp (buf,"mem" ,3 )) { buf +=3 ;while (isspace (*buf)) ++buf; - res = &dev->res.mem_resource[nmem]; + res =pnp_get_resource (dev,IORESOURCE_MEM , + nmem); +if (!res) +break ; res->start =simple_strtoul (buf, &buf,0 );while (isspace (*buf)) ++buf;
@@ -417,34 +421,34 @@ res->end = res->start; res->flags =IORESOURCE_MEM ; nmem++; -if (nmem >=PNP_MAX_MEM ) -break ;continue ; }if (!strnicmp (buf,"irq" ,3 )) { buf +=3 ;while (isspace (*buf)) ++buf; - res = &dev->res.irq_resource[nirq]; + res =pnp_get_resource (dev,IORESOURCE_IRQ , + nirq); +if (!res) +break ; res->start = res->end =simple_strtoul (buf, &buf,0 ); res->flags =IORESOURCE_IRQ ; nirq++; -if (nirq >=PNP_MAX_IRQ ) -break ;continue ; }if (!strnicmp (buf,"dma" ,3 )) { buf +=3 ;while (isspace (*buf)) ++buf; - res = &dev->res.dma_resource[ndma]; + res =pnp_get_resource (dev,IORESOURCE_DMA , + ndma); +if (!res) +break ; res->start = res->end =simple_strtoul (buf, &buf,0 ); res->flags =IORESOURCE_DMA ; ndma++; -if (ndma >=PNP_MAX_DMA ) -break ;continue ; }break ;
drivers/pnp/support.c +8 -8
@@ -61,27 +61,27 @@dev_dbg (&dev->dev,"current resources: %s\n" , desc);for (i =0 ; i <PNP_MAX_IRQ ; i++) { - res = &dev->res.irq_resource[i]; -if (!(res->flags &IORESOURCE_UNSET )) + res =pnp_get_resource (dev,IORESOURCE_IRQ , i); +if (res && !(res->flags &IORESOURCE_UNSET ))dev_dbg (&dev->dev," irq %lld flags %#lx\n" , (unsigned long long ) res->start, res->flags); }for (i =0 ; i <PNP_MAX_DMA ; i++) { - res = &dev->res.dma_resource[i]; -if (!(res->flags &IORESOURCE_UNSET )) + res =pnp_get_resource (dev,IORESOURCE_DMA , i); +if (res && !(res->flags &IORESOURCE_UNSET ))dev_dbg (&dev->dev," dma %lld flags %#lx\n" , (unsigned long long ) res->start, res->flags); }for (i =0 ; i <PNP_MAX_PORT ; i++) { - res = &dev->res.port_resource[i]; -if (!(res->flags &IORESOURCE_UNSET )) + res =pnp_get_resource (dev,IORESOURCE_IO , i); +if (res && !(res->flags &IORESOURCE_UNSET ))dev_dbg (&dev->dev," io %#llx-%#llx flags %#lx\n" , (unsigned long long ) res->start, (unsigned long long ) res->end, res->flags); }for (i =0 ; i <PNP_MAX_MEM ; i++) { - res = &dev->res.mem_resource[i]; -if (!(res->flags &IORESOURCE_UNSET )) + res =pnp_get_resource (dev,IORESOURCE_MEM , i); +if (res && !(res->flags &IORESOURCE_UNSET ))dev_dbg (&dev->dev," mem %#llx-%#llx flags %#lx\n" , (unsigned long long ) res->start, (unsigned long long ) res->end, res->flags);
PATCH 39/55 PNP: remove PNP_MAX_* uses
In reply to Bjorn HelgaasRemove some PNP_MAX_* uses. The pnp_resource_table isn't dynamic yet, but with pnp_get_resource(), we can start moving away from the table size constants.
--- drivers/pnp/interface.c | 43 ++++++++++++++++++------------------ drivers/pnp/quirks.c | 13 ++++++----- drivers/pnp/resource.c | 56 +++++++++++++++++++++++++++--------------------- drivers/pnp/system.c | 21 ++++++++---------- 4 files changed, 70 insertions(+), 63 deletions(-)
drivers/pnp/interface.c +19 -22
@@ -248,6 +248,7 @@ char *buf) {struct pnp_dev *dev =to_pnp_dev (dmdev); +struct resource *res;int i, ret;pnp_info_buffer_t *buffer;
@@ -267,50 +268,46 @@else pnp_printf (buffer,"disabled\n" ); -for (i =0 ; i <PNP_MAX_PORT ; i++) { -if (pnp_port_valid (dev, i)) { +for (i =0 ; (res =pnp_get_resource (dev,IORESOURCE_IO , i)); i++) { +if (pnp_resource_valid (res)) {pnp_printf (buffer,"io" ); -if (pnp_port_flags (dev, i) &IORESOURCE_DISABLED ) +if (res->flags &IORESOURCE_DISABLED )pnp_printf (buffer," disabled\n" );else pnp_printf (buffer," 0x%llx-0x%llx\n" , - (unsigned long long ) -pnp_port_start (dev, i), - (unsigned long long )pnp_port_end (dev, - i)); + (unsigned long long ) res->start, + (unsigned long long ) res->end); } } -for (i =0 ; i <PNP_MAX_MEM ; i++) { -if (pnp_mem_valid (dev, i)) { +for (i =0 ; (res =pnp_get_resource (dev,IORESOURCE_MEM , i)); i++) { +if (pnp_resource_valid (res)) {pnp_printf (buffer,"mem" ); -if (pnp_mem_flags (dev, i) &IORESOURCE_DISABLED ) +if (res->flags &IORESOURCE_DISABLED )pnp_printf (buffer," disabled\n" );else pnp_printf (buffer," 0x%llx-0x%llx\n" , - (unsigned long long ) -pnp_mem_start (dev, i), - (unsigned long long )pnp_mem_end (dev, - i)); + (unsigned long long ) res->start, + (unsigned long long ) res->end); } } -for (i =0 ; i <PNP_MAX_IRQ ; i++) { -if (pnp_irq_valid (dev, i)) { +for (i =0 ; (res =pnp_get_resource (dev,IORESOURCE_IRQ , i)); i++) { +if (pnp_resource_valid (res)) {pnp_printf (buffer,"irq" ); -if (pnp_irq_flags (dev, i) &IORESOURCE_DISABLED ) +if (res->flags &IORESOURCE_DISABLED )pnp_printf (buffer," disabled\n" );else pnp_printf (buffer," %lld\n" , - (unsigned long long )pnp_irq (dev, i)); + (unsigned long long ) res->start); } } -for (i =0 ; i <PNP_MAX_DMA ; i++) { -if (pnp_dma_valid (dev, i)) { +for (i =0 ; (res =pnp_get_resource (dev,IORESOURCE_DMA , i)); i++) { +if (pnp_resource_valid (res)) {pnp_printf (buffer,"dma" ); -if (pnp_dma_flags (dev, i) &IORESOURCE_DISABLED ) +if (res->flags &IORESOURCE_DISABLED )pnp_printf (buffer," disabled\n" );else pnp_printf (buffer," %lld\n" , - (unsigned long long )pnp_dma (dev, i)); + (unsigned long long ) res->start); } } ret = (buffer->curr - buf);
drivers/pnp/quirks.c +7 -6
@@ -138,13 +138,15 @@ pci_start =pci_resource_start (pdev, i); pci_end =pci_resource_end (pdev, i); -for (j =0 ; j <PNP_MAX_MEM ; j++) { -if (!pnp_mem_valid (dev, j) || -pnp_mem_len (dev, j) ==0 ) +for (j =0 ; + (res =pnp_get_resource (dev,IORESOURCE_MEM , j)); + j++) { +if (res->flags &IORESOURCE_UNSET || + (res->start ==0 && res->end ==0 ))continue ; - pnp_start =pnp_mem_start (dev, j); - pnp_end =pnp_mem_end (dev, j); + pnp_start = res->start; + pnp_end = res->end;/* * If the PNP region doesn't overlap the PCI
@@ -177,7 +179,6 @@pci_name (pdev), i, (unsigned long long ) pci_start, (unsigned long long) pci_end); - res =pnp_get_resource (dev,IORESOURCE_MEM , j); res->flags =0 ; } }
drivers/pnp/resource.c +24 -24
96 lines not on this page · raw message
drivers/pnp/system.c +10 -11
@@ -56,14 +56,15 @@static void reserve_resources_of_dev (struct pnp_dev *dev) { +struct resource *res;int i; -for (i =0 ; i <PNP_MAX_PORT ; i++) { -if (!pnp_port_valid (dev, i)) +for (i =0 ; (res =pnp_get_resource (dev,IORESOURCE_IO , i)); i++) { +if (res->flags &IORESOURCE_UNSET )continue ; -if (pnp_port_start (dev, i) ==0 ) +if (res->start ==0 )continue ;/* disabled */ -if (pnp_port_start (dev, i) <0x100 ) +if (res->start <0x100 )/* * Below 0x100 is only standard PC hardware * (pics, kbd, timer, dma, ...)
@@ -73,19 +74,17 @@* So, do nothing */ continue ; -if (pnp_port_end (dev, i) <pnp_port_start (dev, i)) +if (res->end < res->start)continue ;/* invalid */ -reserve_range (dev,pnp_port_start (dev, i), -pnp_port_end (dev, i),1 ); +reserve_range (dev, res->start, res->end,1 ); } -for (i =0 ; i <PNP_MAX_MEM ; i++) { -if (!pnp_mem_valid (dev, i)) +for (i =0 ; (res =pnp_get_resource (dev,IORESOURCE_MEM , i)); i++) { +if (res->flags &IORESOURCE_UNSET )continue ; -reserve_range (dev,pnp_mem_start (dev, i), -pnp_mem_end (dev, i),0 ); +reserve_range (dev, res->start, res->end,0 ); } }
PATCH 40/55 rtc: dont reference pnp_resource_table directly
In reply to Bjorn Helgaaspnp_resource_table is going away soon, so use the more generic public interfaces instead.
drivers/rtc/rtc-cmos.c +4 -3
@@ -854,11 +854,12 @@* don't define the IRQ. It should always be safe to * hardcode it in these cases */ -return cmos_do_probe (&pnp->dev, &pnp->res.port_resource[0 ],8 ); +return cmos_do_probe (&pnp->dev, +pnp_get_resource (pnp,IORESOURCE_IO ,0 ),8 ); else return cmos_do_probe(&pnp->dev, - &pnp->res.port_resource[0 ], - pnp->res.irq_resource[0 ].start); +pnp_get_resource (pnp,IORESOURCE_IO ,0 ), +pnp_irq (pnp,0 )); } static void __exit cmos_pnp_remove(struct pnp_dev *pnp)
PATCH 41/55 PNP: make pnp_resource_table private to PNP core
In reply to Bjorn HelgaasThere are no remaining references to the PNP_MAX_* constants or the pnp_resource_table structure outside of the PNP core. Make them private to the PNP core.
--- drivers/pnp/base.h | 12 ++++++++++++ drivers/pnp/core.c | 8 ++++++++ drivers/pnp/isapnp/core.c | 4 ++-- drivers/pnp/manager.c | 16 ++++++++-------- drivers/pnp/pnpacpi/rsparser.c | 10 ++++++---- drivers/pnp/pnpbios/rsparser.c | 8 ++++---- drivers/pnp/resource.c | 2 +- include/linux/pnp.h | 14 ++------------ 8 files changed, 43 insertions(+), 31 deletions(-)
include/linux/pnp.h +2 -12
@@ -13,14 +13,11 @@#include <linux/errno.h> #include <linux/mod_devicetable.h> -#define PNP_MAX_PORT 40 -#define PNP_MAX_MEM 24 -#define PNP_MAX_IRQ 2 -#define PNP_MAX_DMA 2#define PNP_NAME_LEN 50struct pnp_protocol ;struct pnp_dev ; +struct pnp_resource_table ;/* * Resource Management
@@ -184,13 +181,6 @@struct pnp_option *next;/* used to chain dependent resources */ }; -struct pnp_resource_table { -struct resource port_resource[PNP_MAX_PORT ]; -struct resource mem_resource[PNP_MAX_MEM ]; -struct resource dma_resource[PNP_MAX_DMA ]; -struct resource irq_resource[PNP_MAX_IRQ ]; -}; -/* * Device Management */
@@ -260,7 +250,7 @@int capabilities;struct pnp_option *independent;struct pnp_option *dependent; -struct pnp_resource_table res; +struct pnp_resource_table *res;char name[PNP_NAME_LEN ];/* contains a human-readable name */ unsigned short regs;/* ISAPnP: supported registers */
drivers/pnp/base.h +12 -0
@@ -20,3 +20,15 @@void dbg_pnp_show_resources (struct pnp_dev *dev,char *desc);void pnp_init_resource (struct resource *res); + +#define PNP_MAX_PORT 40 +#define PNP_MAX_MEM 24 +#define PNP_MAX_IRQ 2 +#define PNP_MAX_DMA 2 + +struct pnp_resource_table { +struct resource port_resource[PNP_MAX_PORT ]; +struct resource mem_resource[PNP_MAX_MEM ]; +struct resource dma_resource[PNP_MAX_DMA ]; +struct resource irq_resource[PNP_MAX_IRQ ]; +};
drivers/pnp/core.c +8 -0
@@ -106,6 +106,7 @@pnp_free_option (dev->independent);pnp_free_option (dev->dependent);pnp_free_ids (dev); +kfree (dev->res);kfree (dev); }
@@ -118,6 +119,12 @@if (!dev)return NULL ; + dev->res =kzalloc (sizeof (struct pnp_resource_table ),GFP_KERNEL ); +if (!dev->res) { +kfree (dev); +return NULL ; + } + dev->protocol = protocol; dev->number = id; dev->dma_mask =DMA_24BIT_MASK ;
@@ -133,6 +140,7 @@ dev_id =pnp_add_id (dev, pnpid);if (!dev_id) { +kfree (dev->res);kfree (dev);return NULL ; }
drivers/pnp/isapnp/core.c +2 -2
@@ -931,7 +931,7 @@static int isapnp_read_resources (struct pnp_dev *dev) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;int tmp, ret; dev->active =isapnp_read_byte (ISAPNP_CFG_ACTIVATE );
@@ -987,7 +987,7 @@static int isapnp_set_resources (struct pnp_dev *dev) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;int tmp;dev_dbg (&dev->dev,"set resources\n" );
drivers/pnp/pnpacpi/rsparser.c +6 -4
@@ -21,6 +21,8 @@#include <linux/kernel.h> #include <linux/acpi.h> #include <linux/pci.h> +#include <linux/pnp.h> +#include "../base.h" #include "pnpacpi.h" #ifdef CONFIG_IA64
@@ -80,7 +82,7 @@ u32 gsi, int triggering, int polarity, int shareable) { - struct pnp_resource_table *res = &dev->res; + struct pnp_resource_table *res = dev->res;int i =0 ;int irq;int p, t;
@@ -176,7 +178,7 @@static void pnpacpi_parse_allocated_dmaresource (struct pnp_dev *dev,u32 dma,int flags) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;int i =0 ;static unsigned char warned;
@@ -202,7 +204,7 @@static void pnpacpi_parse_allocated_ioresource (struct pnp_dev *dev,u64 io,u64 len,int io_decode) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;int i =0 ;static unsigned char warned;
@@ -230,7 +232,7 @@ u64 mem, u64 len, int write_protect) { - struct pnp_resource_table *res = &dev->res; + struct pnp_resource_table *res = dev->res;int i =0 ;static unsigned char warned;
drivers/pnp/pnpbios/rsparser.c +4 -4
@@ -56,7 +56,7 @@static void pnpbios_parse_allocated_irqresource (struct pnp_dev *dev,int irq) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;int i =0 ; while (!(res->irq_resource[i].flags & IORESOURCE_UNSET)
@@ -76,7 +76,7 @@static void pnpbios_parse_allocated_dmaresource (struct pnp_dev *dev,int dma) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;int i =0 ; while (i < PNP_MAX_DMA &&
@@ -96,7 +96,7 @@static void pnpbios_parse_allocated_ioresource (struct pnp_dev *dev,int io,int len) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;int i =0 ; while (!(res->port_resource[i].flags & IORESOURCE_UNSET)
@@ -116,7 +116,7 @@static void pnpbios_parse_allocated_memresource (struct pnp_dev *dev,int mem,int len) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;int i =0 ; while (!(res->mem_resource[i].flags & IORESOURCE_UNSET)
drivers/pnp/resource.c +1 -1
@@ -502,7 +502,7 @@struct resource *pnp_get_resource (struct pnp_dev *dev,unsigned int type,unsigned int num) { -struct pnp_resource_table *res = &dev->res; +struct pnp_resource_table *res = dev->res;switch (type) {case IORESOURCE_IO :
drivers/pnp/manager.c +8 -8
@@ -247,22 +247,22 @@int idx;for (idx =0 ; idx <PNP_MAX_IRQ ; idx++) { - res = &dev->res.irq_resource[idx]; + res = &dev->res->irq_resource[idx]; res->flags =IORESOURCE_IRQ ;pnp_init_resource (res); }for (idx =0 ; idx <PNP_MAX_DMA ; idx++) { - res = &dev->res.dma_resource[idx]; + res = &dev->res->dma_resource[idx]; res->flags =IORESOURCE_DMA ;pnp_init_resource (res); }for (idx =0 ; idx <PNP_MAX_PORT ; idx++) { - res = &dev->res.port_resource[idx]; + res = &dev->res->port_resource[idx]; res->flags =IORESOURCE_IO ;pnp_init_resource (res); }for (idx =0 ; idx <PNP_MAX_MEM ; idx++) { - res = &dev->res.mem_resource[idx]; + res = &dev->res->mem_resource[idx]; res->flags =IORESOURCE_MEM ;pnp_init_resource (res); }
@@ -278,28 +278,28 @@int idx;for (idx =0 ; idx <PNP_MAX_IRQ ; idx++) { - res = &dev->res.irq_resource[idx]; + res = &dev->res->irq_resource[idx];if (res->flags &IORESOURCE_AUTO ) { res->flags =IORESOURCE_IRQ ;pnp_init_resource (res); } }for (idx =0 ; idx <PNP_MAX_DMA ; idx++) { - res = &dev->res.dma_resource[idx]; + res = &dev->res->dma_resource[idx];if (res->flags &IORESOURCE_AUTO ) { res->flags =IORESOURCE_DMA ;pnp_init_resource (res); } }for (idx =0 ; idx <PNP_MAX_PORT ; idx++) { - res = &dev->res.port_resource[idx]; + res = &dev->res->port_resource[idx];if (res->flags &IORESOURCE_AUTO ) { res->flags =IORESOURCE_IO ;pnp_init_resource (res); } }for (idx =0 ; idx <PNP_MAX_MEM ; idx++) { - res = &dev->res.mem_resource[idx]; + res = &dev->res->mem_resource[idx];if (res->flags &IORESOURCE_AUTO ) { res->flags =IORESOURCE_MEM ;pnp_init_resource (res);
PATCH 42/55 PNP: remove pnp_resource_table references from resource decoders
In reply to Bjorn HelgaasThis removes a few more references to the pnp_resource_table. No functional change.
--- drivers/pnp/isapnp/core.c | 87 ++++++++++++++++++++-------------------- drivers/pnp/pnpacpi/rsparser.c | 88 ++++++++++++++++++++++------------------- drivers/pnp/pnpbios/rsparser.c | 82 +++++++++++++++++++++----------------- 3 files changed, 138 insertions(+), 119 deletions(-)
drivers/pnp/isapnp/core.c +49 -52
@@ -931,7 +931,7 @@static int isapnp_read_resources (struct pnp_dev *dev) { -struct pnp_resource_table *res = dev->res; +struct resource *res;int tmp, ret; dev->active =isapnp_read_byte (ISAPNP_CFG_ACTIVATE );
@@ -940,16 +940,18 @@ ret =isapnp_read_word (ISAPNP_CFG_PORT + (tmp <<1 ));if (!ret)continue ; - res->port_resource[tmp].start = ret; - res->port_resource[tmp].flags =IORESOURCE_IO ; + res =pnp_get_resource (dev,IORESOURCE_IO , tmp); + res->start = ret; + res->flags =IORESOURCE_IO ; }for (tmp =0 ; tmp <ISAPNP_MAX_MEM ; tmp++) { ret =isapnp_read_word (ISAPNP_CFG_MEM + (tmp <<3 )) <<8 ;if (!ret)continue ; - res->mem_resource[tmp].start = ret; - res->mem_resource[tmp].flags =IORESOURCE_MEM ; + res =pnp_get_resource (dev,IORESOURCE_MEM , tmp); + res->start = ret; + res->flags =IORESOURCE_MEM ; }for (tmp =0 ; tmp <ISAPNP_MAX_IRQ ; tmp++) { ret =
@@ -957,17 +959,17 @@ 8);if (!ret)continue ; - res->irq_resource[tmp].start = - res->irq_resource[tmp].end = ret; - res->irq_resource[tmp].flags =IORESOURCE_IRQ ; + res =pnp_get_resource (dev,IORESOURCE_IRQ , tmp); + res->start = res->end = ret; + res->flags =IORESOURCE_IRQ ; }for (tmp =0 ; tmp <ISAPNP_MAX_DMA ; tmp++) { ret =isapnp_read_byte (ISAPNP_CFG_DMA + tmp);if (ret ==4 )continue ; - res->dma_resource[tmp].start = - res->dma_resource[tmp].end = ret; - res->dma_resource[tmp].flags =IORESOURCE_DMA ; + res =pnp_get_resource (dev,IORESOURCE_DMA , tmp); + res->start = res->end = ret; + res->flags =IORESOURCE_DMA ; } }return 0 ;
@@ -987,52 +989,47 @@static int isapnp_set_resources (struct pnp_dev *dev) { -struct pnp_resource_table *res = dev->res; +struct resource *res;int tmp;dev_dbg (&dev->dev,"set resources\n" );isapnp_cfg_begin (dev->card->number, dev->number); dev->active =1 ; -for (tmp =0 ; - tmp <ISAPNP_MAX_PORT - && (res->port_resource[tmp]. - flags & (IORESOURCE_IO |IORESOURCE_UNSET )) ==IORESOURCE_IO ; - tmp++) { -dev_dbg (&dev->dev," set io %d to %#llx\n" , - tmp, (unsigned long long ) res->port_resource[tmp].start); -isapnp_write_word (ISAPNP_CFG_PORT + (tmp <<1 ), - res->port_resource[tmp].start); - } -for (tmp =0 ; - tmp <ISAPNP_MAX_IRQ - && (res->irq_resource[tmp]. - flags & (IORESOURCE_IRQ |IORESOURCE_UNSET )) ==IORESOURCE_IRQ ; - tmp++) { -int irq = res->irq_resource[tmp].start; -if (irq ==2 ) - irq =9 ; -dev_dbg (&dev->dev," set irq %d to %d\n" , tmp, irq); -isapnp_write_byte (ISAPNP_CFG_IRQ + (tmp <<1 ), irq); - } -for (tmp =0 ; - tmp <ISAPNP_MAX_DMA - && (res->dma_resource[tmp]. - flags & (IORESOURCE_DMA |IORESOURCE_UNSET )) ==IORESOURCE_DMA ; - tmp++) { -dev_dbg (&dev->dev," set dma %d to %lld\n" , - tmp, (unsigned long long ) res->dma_resource[tmp].start); -isapnp_write_byte (ISAPNP_CFG_DMA + tmp, - res->dma_resource[tmp].start); - } -for (tmp =0 ; - tmp <ISAPNP_MAX_MEM - && (res->mem_resource[tmp]. - flags & (IORESOURCE_MEM |IORESOURCE_UNSET )) ==IORESOURCE_MEM ; - tmp++) { -dev_dbg (&dev->dev," set mem %d to %#llx\n" , - tmp, (unsigned long long ) res->mem_resource[tmp].start); -isapnp_write_word (ISAPNP_CFG_MEM + (tmp <<3 ), - (res->mem_resource[tmp].start >>8 ) &0xffff ); +for (tmp =0 ; tmp <ISAPNP_MAX_PORT ; tmp++) { + res =pnp_get_resource (dev,IORESOURCE_IO , tmp); +if (pnp_resource_valid (res)) { +dev_dbg (&dev->dev," set io %d to %#llx\n" , + tmp, (unsigned long long ) res->start); +isapnp_write_word (ISAPNP_CFG_PORT + (tmp <<1 ), + res->start); + } + } +for (tmp =0 ; tmp <ISAPNP_MAX_IRQ ; tmp++) { + res =pnp_get_resource (dev,IORESOURCE_IRQ , tmp); +if (pnp_resource_valid (res)) { +int irq = res->start; +if (irq ==2 ) + irq =9 ; +dev_dbg (&dev->dev," set irq %d to %d\n" , tmp, irq); +isapnp_write_byte (ISAPNP_CFG_IRQ + (tmp <<1 ), irq); + } + } +for (tmp =0 ; tmp <ISAPNP_MAX_DMA ; tmp++) { + res =pnp_get_resource (dev,IORESOURCE_DMA , tmp); +if (pnp_resource_valid (res)) { +dev_dbg (&dev->dev," set dma %d to %lld\n" , + tmp, (unsigned long long ) res->start); +isapnp_write_byte (ISAPNP_CFG_DMA + tmp, res->start); + } + } +for (tmp =0 ; tmp <ISAPNP_MAX_MEM ; tmp++) { + res =pnp_get_resource (dev,IORESOURCE_MEM , tmp); +if (pnp_resource_valid (res)) { +dev_dbg (&dev->dev," set mem %d to %#llx\n" , + tmp, (unsigned long long ) res->start); +isapnp_write_word (ISAPNP_CFG_MEM + (tmp <<3 ), + (res->start >>8 ) &0xffff ); + } }/* FIXME: We aren't handling 32bit mems properly here */ isapnp_activate (dev->number);
drivers/pnp/pnpacpi/rsparser.c +48 -40
150 lines not on this page · raw message
drivers/pnp/pnpbios/rsparser.c +46 -36
126 lines not on this page · raw message
PATCH 43/55 PNP: add struct pnp_resource
In reply to Bjorn HelgaasThis patch adds a "struct pnp_resource". This currently contains only a struct resource, but we will soon need additional PNP-specific information.
--- drivers/pnp/base.h | 12 ++++++++---- drivers/pnp/interface.c | 1 + drivers/pnp/manager.c | 20 ++++++++++++-------- drivers/pnp/resource.c | 8 ++++---- 4 files changed, 25 insertions(+), 16 deletions(-)
drivers/pnp/base.h +8 -4
@@ -26,9 +26,13 @@#define PNP_MAX_IRQ 2#define PNP_MAX_DMA 2 +struct pnp_resource { +struct resource res; +}; +struct pnp_resource_table { -struct resource port_resource[PNP_MAX_PORT ]; -struct resource mem_resource[PNP_MAX_MEM ]; -struct resource dma_resource[PNP_MAX_DMA ]; -struct resource irq_resource[PNP_MAX_IRQ ]; +struct pnp_resource port[PNP_MAX_PORT ]; +struct pnp_resource mem[PNP_MAX_MEM ]; +struct pnp_resource dma[PNP_MAX_DMA ]; +struct pnp_resource irq[PNP_MAX_IRQ ]; };
drivers/pnp/resource.c +4 -4
@@ -508,19 +508,19 @@case IORESOURCE_IO :if (num >=PNP_MAX_PORT )return NULL ; -return &res->port_resource[num]; +return &res->port[num].res;case IORESOURCE_MEM :if (num >=PNP_MAX_MEM )return NULL ; -return &res->mem_resource[num]; +return &res->mem[num].res;case IORESOURCE_IRQ :if (num >=PNP_MAX_IRQ )return NULL ; -return &res->irq_resource[num]; +return &res->irq[num].res;case IORESOURCE_DMA :if (num >=PNP_MAX_DMA )return NULL ; -return &res->dma_resource[num]; +return &res->dma[num].res; }return NULL ; }
drivers/pnp/manager.c +8 -8
@@ -247,22 +247,22 @@int idx;for (idx =0 ; idx <PNP_MAX_IRQ ; idx++) { - res = &dev->res->irq_resource[idx]; + res = &dev->res->irq[idx].res; res->flags =IORESOURCE_IRQ ;pnp_init_resource (res); }for (idx =0 ; idx <PNP_MAX_DMA ; idx++) { - res = &dev->res->dma_resource[idx]; + res = &dev->res->dma[idx].res; res->flags =IORESOURCE_DMA ;pnp_init_resource (res); }for (idx =0 ; idx <PNP_MAX_PORT ; idx++) { - res = &dev->res->port_resource[idx]; + res = &dev->res->port[idx].res; res->flags =IORESOURCE_IO ;pnp_init_resource (res); }for (idx =0 ; idx <PNP_MAX_MEM ; idx++) { - res = &dev->res->mem_resource[idx]; + res = &dev->res->mem[idx].res; res->flags =IORESOURCE_MEM ;pnp_init_resource (res); }
@@ -278,28 +278,28 @@int idx;for (idx =0 ; idx <PNP_MAX_IRQ ; idx++) { - res = &dev->res->irq_resource[idx]; + res = &dev->res->irq[idx].res;if (res->flags &IORESOURCE_AUTO ) { res->flags =IORESOURCE_IRQ ;pnp_init_resource (res); } }for (idx =0 ; idx <PNP_MAX_DMA ; idx++) { - res = &dev->res->dma_resource[idx]; + res = &dev->res->dma[idx].res;if (res->flags &IORESOURCE_AUTO ) { res->flags =IORESOURCE_DMA ;pnp_init_resource (res); } }for (idx =0 ; idx <PNP_MAX_PORT ; idx++) { - res = &dev->res->port_resource[idx]; + res = &dev->res->port[idx].res;if (res->flags &IORESOURCE_AUTO ) { res->flags =IORESOURCE_IO ;pnp_init_resource (res); } }for (idx =0 ; idx <PNP_MAX_MEM ; idx++) { - res = &dev->res->mem_resource[idx]; + res = &dev->res->mem[idx].res;if (res->flags &IORESOURCE_AUTO ) { res->flags =IORESOURCE_MEM ;pnp_init_resource (res);
PATCH 44/55 PNP: add pnp_get_pnp_resource()
In reply to Bjorn HelgaasIn some places, we need to get the struct pnp_resource, not just the struct resource, because ISAPNP needs to store the register index in the pnp_resource.
I don't like pnp_get_pnp_resource() and hope that it is temporary, but we need it for a little while.
--- drivers/pnp/base.h | 3 +++ drivers/pnp/resource.c | 24 ++++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-)
drivers/pnp/base.h +3 -0
@@ -21,6 +21,9 @@void pnp_init_resource (struct resource *res); +struct pnp_resource *pnp_get_pnp_resource (struct pnp_dev *dev, +unsigned int type,unsigned int num); +#define PNP_MAX_PORT 40#define PNP_MAX_MEM 24#define PNP_MAX_IRQ 2
drivers/pnp/resource.c +18 -6
@@ -499,8 +499,8 @@#endif } -struct resource *pnp_get_resource (struct pnp_dev *dev, -unsigned int type,unsigned int num) +struct pnp_resource *pnp_get_pnp_resource (struct pnp_dev *dev, +unsigned int type,unsigned int num) {struct pnp_resource_table *res = dev->res;
@@ -508,22 +508,34 @@case IORESOURCE_IO :if (num >=PNP_MAX_PORT )return NULL ; -return &res->port[num].res; +return &res->port[num];case IORESOURCE_MEM :if (num >=PNP_MAX_MEM )return NULL ; -return &res->mem[num].res; +return &res->mem[num];case IORESOURCE_IRQ :if (num >=PNP_MAX_IRQ )return NULL ; -return &res->irq[num].res; +return &res->irq[num];case IORESOURCE_DMA :if (num >=PNP_MAX_DMA )return NULL ; -return &res->dma[num].res; +return &res->dma[num]; }return NULL ; } + +struct resource *pnp_get_resource (struct pnp_dev *dev, +unsigned int type,unsigned int num) +{ +struct pnp_resource *pnp_res; + + pnp_res =pnp_get_pnp_resource (dev, type, num); +if (pnp_res) +return &pnp_res->res; + +return NULL ; +}EXPORT_SYMBOL (pnp_get_resource);/* format is: pnp_reserve_irq=irq1[,irq2] .... */
PATCH 45/55 PNP: add pnp_resource index for ISAPNP
In reply to Bjorn HelgaasSave the ISAPNP config register index in the struct pnp_resource.
We need this because it is important to write ISAPNP configuration back to the same registers we read it from. For example, if we read valid regions from memory descriptors 0, 1, and 3, we'd better write them back to the same registers, without compressing them to descriptors 0, 1, and 2.
This was previously guaranteed by using the index into the pnp_resource_table array as the ISAPNP config register index. However, I am removing those fixed-size arrays, so we need to save the ISAPNP register index elsewhere.
--- drivers/pnp/base.h | 1 drivers/pnp/interface.c | 33 +++++++++++++++--------- drivers/pnp/isapnp/core.c | 63 +++++++++++++++++++++++++++++++++------------- drivers/pnp/manager.c | 32 +++++++++++++++++------ 4 files changed, 92 insertions(+), 37 deletions(-)
drivers/pnp/base.h +1 -0
@@ -31,6 +31,7 @@struct pnp_resource {struct resource res; +unsigned int index;/* ISAPNP config register index */ };struct pnp_resource_table {
drivers/pnp/isapnp/core.c +46 -17
125 lines not on this page · raw message
drivers/pnp/interface.c +21 -12
@@ -320,6 +320,7 @@ const char *ubuf, size_t count) {struct pnp_dev *dev =to_pnp_dev (dmdev); +struct pnp_resource *pnp_res;struct resource *res;char *buf = (void *)ubuf;int retval =0 ;
@@ -380,10 +381,12 @@ buf +=2 ;while (isspace (*buf)) ++buf; - res =pnp_get_resource (dev,IORESOURCE_IO , - nport); -if (!res) + pnp_res =pnp_get_pnp_resource (dev, +IORESOURCE_IO , nport); +if (!pnp_res)break ; + pnp_res->index = nport; + res = &pnp_res->res; res->start =simple_strtoul (buf, &buf,0 );while (isspace (*buf)) ++buf;
@@ -402,10 +405,12 @@ buf +=3 ;while (isspace (*buf)) ++buf; - res =pnp_get_resource (dev,IORESOURCE_MEM , - nmem); -if (!res) + pnp_res =pnp_get_pnp_resource (dev, +IORESOURCE_MEM , nmem); +if (!pnp_res)break ; + pnp_res->index = nmem; + res = &pnp_res->res; res->start =simple_strtoul (buf, &buf,0 );while (isspace (*buf)) ++buf;
@@ -424,10 +429,12 @@ buf +=3 ;while (isspace (*buf)) ++buf; - res =pnp_get_resource (dev,IORESOURCE_IRQ , - nirq); -if (!res) + pnp_res =pnp_get_pnp_resource (dev, +IORESOURCE_IRQ , nirq); +if (!pnp_res)break ; + pnp_res->index = nirq; + res = &pnp_res->res; res->start = res->end =simple_strtoul (buf, &buf,0 ); res->flags =IORESOURCE_IRQ ;
@@ -438,10 +445,12 @@ buf +=3 ;while (isspace (*buf)) ++buf; - res =pnp_get_resource (dev,IORESOURCE_DMA , - ndma); -if (!res) + pnp_res =pnp_get_pnp_resource (dev, +IORESOURCE_DMA , ndma); +if (!pnp_res)break ; + pnp_res->index = ndma; + res = &pnp_res->res; res->start = res->end =simple_strtoul (buf, &buf,0 ); res->flags =IORESOURCE_DMA ;
drivers/pnp/manager.c +24 -8
@@ -19,15 +19,18 @@static int pnp_assign_port (struct pnp_dev *dev,struct pnp_port *rule,int idx) { +struct pnp_resource *pnp_res;struct resource *res; - res =pnp_get_resource (dev,IORESOURCE_IO , idx); -if (!res) { + pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_IO , idx); +if (!pnp_res) {dev_err (&dev->dev,"too many I/O port resources\n" );/* pretend we were successful so at least the manager won't try again */ return 1 ; } + res = &pnp_res->res; +/* check if this resource has been manually set, if so skip */ if (!(res->flags &IORESOURCE_AUTO )) { dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
@@ -37,6 +40,7 @@ }/* set the initial values */ + pnp_res->index = idx; res->flags |= rule->flags |IORESOURCE_IO ; res->flags &= ~IORESOURCE_UNSET ;
@@ -65,15 +69,18 @@static int pnp_assign_mem (struct pnp_dev *dev,struct pnp_mem *rule,int idx) { +struct pnp_resource *pnp_res;struct resource *res; - res =pnp_get_resource (dev,IORESOURCE_MEM , idx); -if (!res) { + pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_MEM , idx); +if (!pnp_res) {dev_err (&dev->dev,"too many memory resources\n" );/* pretend we were successful so at least the manager won't try again */ return 1 ; } + res = &pnp_res->res; +/* check if this resource has been manually set, if so skip */ if (!(res->flags &IORESOURCE_AUTO )) { dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
@@ -83,6 +90,7 @@ }/* set the initial values */ + pnp_res->index = idx; res->flags |= rule->flags |IORESOURCE_MEM ; res->flags &= ~IORESOURCE_UNSET ;
@@ -121,6 +129,7 @@static int pnp_assign_irq (struct pnp_dev *dev,struct pnp_irq *rule,int idx) { +struct pnp_resource *pnp_res;struct resource *res;int i;
@@ -129,13 +138,15 @@5 ,10 ,11 ,12 ,9 ,14 ,15 ,7 ,3 ,4 ,13 ,0 ,1 ,6 ,8 ,2 }; - res =pnp_get_resource (dev,IORESOURCE_IRQ , idx); -if (!res) { + pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_IRQ , idx); +if (!pnp_res) {dev_err (&dev->dev,"too many IRQ resources\n" );/* pretend we were successful so at least the manager won't try again */ return 1 ; } + res = &pnp_res->res; +/* check if this resource has been manually set, if so skip */ if (!(res->flags &IORESOURCE_AUTO )) { dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
@@ -144,6 +155,7 @@ }/* set the initial values */ + pnp_res->index = idx; res->flags |= rule->flags |IORESOURCE_IRQ ; res->flags &= ~IORESOURCE_UNSET ;
@@ -177,6 +189,7 @@static void pnp_assign_dma (struct pnp_dev *dev,struct pnp_dma *rule,int idx) { +struct pnp_resource *pnp_res;struct resource *res;int i;
@@ -185,12 +198,14 @@1 ,3 ,5 ,6 ,7 ,0 ,2 ,4 }; - res =pnp_get_resource (dev,IORESOURCE_DMA , idx); -if (!res) { + pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_DMA , idx); +if (!pnp_res) {dev_err (&dev->dev,"too many DMA resources\n" );return ; } + res = &pnp_res->res; +/* check if this resource has been manually set, if so skip */ if (!(res->flags &IORESOURCE_AUTO )) { dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
@@ -199,6 +214,7 @@ }/* set the initial values */ + pnp_res->index = idx; res->flags |= rule->flags |IORESOURCE_DMA ; res->flags &= ~IORESOURCE_UNSET ;
PATCH 46/55 PNP: add pnp_new_resource() to find a new unset pnp_resource
In reply to Bjorn HelgaasThis encapsulates the code to locate a new pnp_resource of the desired type. Currently this uses the pnp_resource_table, but it will soon change to find a resource in a linked list.
drivers/pnp/resource.c +38 -0
@@ -538,6 +538,44 @@ }EXPORT_SYMBOL (pnp_get_resource); +static struct pnp_resource *pnp_new_resource (struct pnp_dev *dev,int type) +{ +struct pnp_resource *pnp_res; +int i; + +switch (type) { +case IORESOURCE_IO : +for (i =0 ; i <PNP_MAX_PORT ; i++) { + pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_IO , i); +if (pnp_res && !pnp_resource_valid (&pnp_res->res)) +return pnp_res; + } +break ; +case IORESOURCE_MEM : +for (i =0 ; i <PNP_MAX_MEM ; i++) { + pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_MEM , i); +if (pnp_res && !pnp_resource_valid (&pnp_res->res)) +return pnp_res; + } +break ; +case IORESOURCE_IRQ : +for (i =0 ; i <PNP_MAX_IRQ ; i++) { + pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_IRQ , i); +if (pnp_res && !pnp_resource_valid (&pnp_res->res)) +return pnp_res; + } +break ; +case IORESOURCE_DMA : +for (i =0 ; i <PNP_MAX_DMA ; i++) { + pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_DMA , i); +if (pnp_res && !pnp_resource_valid (&pnp_res->res)) +return pnp_res; + } +break ; + } +return NULL ; +} +/* format is: pnp_reserve_irq=irq1[,irq2] .... */ static int __init pnp_setup_reserve_irq (char *str) {
PATCH 47/55 PNP: make generic pnp_add_irq_resource()
In reply to Bjorn HelgaasAdd a pnp_add_irq_resource() that can be used by all the PNP backends. This consolidates a little more pnp_resource_table knowledge into one place.
--- drivers/pnp/base.h | 3 +++ drivers/pnp/interface.c | 14 +++++--------- drivers/pnp/isapnp/core.c | 8 +++----- drivers/pnp/pnpacpi/rsparser.c | 31 +++++++------------------------ drivers/pnp/pnpbios/rsparser.c | 31 +++++++------------------------ drivers/pnp/resource.c | 26 ++++++++++++++++++++++++++ 6 files changed, 51 insertions(+), 62 deletions(-)
drivers/pnp/base.h +3 -0
@@ -40,3 +40,6 @@struct pnp_resource dma[PNP_MAX_DMA ];struct pnp_resource irq[PNP_MAX_IRQ ]; }; + +struct pnp_resource *pnp_add_irq_resource (struct pnp_dev *dev,int irq, +int flags);
drivers/pnp/resource.c +26 -0
@@ -576,6 +576,32 @@return NULL ; } +struct pnp_resource *pnp_add_irq_resource (struct pnp_dev *dev,int irq, +int flags) +{ +struct pnp_resource *pnp_res; +struct resource *res; +static unsigned char warned; + + pnp_res =pnp_new_resource (dev,IORESOURCE_IRQ ); +if (!pnp_res) { +if (!warned) { +dev_err (&dev->dev,"can't add resource for IRQ %d\n" , + irq); + warned =1 ; + } +return NULL ; + } + + res = &pnp_res->res; + res->flags =IORESOURCE_IRQ | flags; + res->start = irq; + res->end = irq; + +dev_dbg (&dev->dev," add irq %d flags %#x\n" , irq, flags); +return pnp_res; +} +/* format is: pnp_reserve_irq=irq1[,irq2] .... */ static int __init pnp_setup_reserve_irq (char *str) {
drivers/pnp/interface.c +5 -10
@@ -324,6 +324,7 @@struct resource *res;char *buf = (void *)ubuf;int retval =0 ; +resource_size_t start;if (dev->status &PNP_ATTACHED ) { retval = -EBUSY ;
@@ -429,16 +430,10 @@ buf +=3 ;while (isspace (*buf)) ++buf; - pnp_res =pnp_get_pnp_resource (dev, -IORESOURCE_IRQ , nirq); -if (!pnp_res) -break ; - pnp_res->index = nirq; - res = &pnp_res->res; - res->start = res->end = -simple_strtoul (buf, &buf,0 ); - res->flags =IORESOURCE_IRQ ; - nirq++; + start =simple_strtoul (buf, &buf,0 ); + pnp_res =pnp_add_irq_resource (dev, start,0 ); +if (pnp_res) + nirq++;continue ; }if (!strnicmp (buf,"dma" ,3 )) {
drivers/pnp/isapnp/core.c +3 -6
@@ -965,12 +965,9 @@ 8);if (!ret)continue ; - pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_IRQ , - tmp); - pnp_res->index = tmp; - res = &pnp_res->res; - res->start = res->end = ret; - res->flags =IORESOURCE_IRQ ; + pnp_res =pnp_add_irq_resource (dev, ret,0 ); +if (pnp_res) + pnp_res->index = tmp; }for (tmp =0 ; tmp <ISAPNP_MAX_DMA ; tmp++) { ret =isapnp_read_byte (ISAPNP_CFG_DMA + tmp);
drivers/pnp/pnpacpi/rsparser.c +7 -26
@@ -82,28 +82,12 @@ u32 gsi, int triggering, int polarity, int shareable) { - struct resource *res; -int i; -int irq; + int irq, flags;int p, t; -static unsigned char warned;if (!valid_IRQ (gsi))return ; -for (i =0 ; i <PNP_MAX_IRQ ; i++) { - res =pnp_get_resource (dev,IORESOURCE_IRQ , i); -if (!pnp_resource_valid (res)) -break ; - } -if (i >=PNP_MAX_IRQ ) { -if (!warned) { -printk (KERN_WARNING "pnpacpi: exceeded the max number" -" of IRQ resources: %d\n" ,PNP_MAX_IRQ ); - warned =1 ; - } -return ; - }/* * in IO-APIC mode, use overrided attribute. Two reasons: * 1. BIOS bug in DSDT
@@ -121,17 +105,14 @@ } } - res->flags =IORESOURCE_IRQ ;// Also clears _UNSET flag - res->flags |=irq_flags (triggering, polarity, shareable); + flags =irq_flags (triggering, polarity, shareable); irq =acpi_register_gsi (gsi, triggering, polarity); -if (irq <0 ) { - res->flags |=IORESOURCE_DISABLED ; -return ; - } +if (irq >=0 ) +pcibios_penalize_isa_irq (irq,1 ); +else + flags |=IORESOURCE_DISABLED ; - res->start = irq; - res->end = irq; -pcibios_penalize_isa_irq (irq,1 ); +pnp_add_irq_resource (dev, irq, flags); }static int dma_flags (int type,int bus_master,int transfer)
drivers/pnp/pnpbios/rsparser.c +7 -24
@@ -54,28 +54,6 @@* Allocated Resources */ -static void pnpbios_parse_allocated_irqresource (struct pnp_dev *dev,int irq) -{ -struct resource *res; -int i; - -for (i =0 ; i <PNP_MAX_IRQ ; i++) { - res =pnp_get_resource (dev,IORESOURCE_IRQ , i); -if (!pnp_resource_valid (res)) -break ; - } - -if (i <PNP_MAX_IRQ ) { - res->flags =IORESOURCE_IRQ ;// Also clears _UNSET flag -if (irq ==-1 ) { - res->flags |=IORESOURCE_DISABLED ; -return ; - } - res->start = res->end = (unsigned long )irq; -pcibios_penalize_isa_irq (irq,1 ); - } -} -static void pnpbios_parse_allocated_dmaresource (struct pnp_dev *dev,int dma) {struct resource *res;
@@ -148,7 +126,7 @@ unsigned char *end) {unsigned int len, tag; -int io, size, mask, i; +int io, size, mask, i, flags;if (!p)return NULL ;
@@ -205,12 +183,17 @@case SMALL_TAG_IRQ :if (len <2 || len >3 ) goto len_err; + flags =0 ; io =-1 ; mask = p[1 ] + p[2 ] *256 ;for (i =0 ; i <16 ; i++, mask = mask >>1 )if (mask &0x01 ) io = i; -pnpbios_parse_allocated_irqresource (dev, io); +if (io !=-1 ) +pcibios_penalize_isa_irq (io,1 ); +else + flags =IORESOURCE_DISABLED ; +pnp_add_irq_resource (dev, io, flags);break ;case SMALL_TAG_DMA :
PATCH 48/55 PNP: make generic pnp_add_dma_resource()
In reply to Bjorn HelgaasAdd a pnp_add_dma_resource() that can be used by all the PNP backends. This consolidates a little more pnp_resource_table knowledge into one place.
--- drivers/pnp/base.h | 2 + drivers/pnp/interface.c | 14 +++---------- drivers/pnp/isapnp/core.c | 9 ++------ drivers/pnp/pnpacpi/rsparser.c | 42 +++++++---------------------------------- drivers/pnp/pnpbios/rsparser.c | 26 +++---------------------- drivers/pnp/resource.c | 26 +++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 72 deletions(-)
drivers/pnp/base.h +2 -0
@@ -43,3 +43,5 @@struct pnp_resource *pnp_add_irq_resource (struct pnp_dev *dev,int irq,int flags); +struct pnp_resource *pnp_add_dma_resource (struct pnp_dev *dev,int dma, +int flags);
drivers/pnp/resource.c +26 -0
@@ -602,6 +602,32 @@return pnp_res; } +struct pnp_resource *pnp_add_dma_resource (struct pnp_dev *dev,int dma, +int flags) +{ +struct pnp_resource *pnp_res; +struct resource *res; +static unsigned char warned; + + pnp_res =pnp_new_resource (dev,IORESOURCE_DMA ); +if (!pnp_res) { +if (!warned) { +dev_err (&dev->dev,"can't add resource for DMA %d\n" , + dma); + warned =1 ; + } +return NULL ; + } + + res = &pnp_res->res; + res->flags =IORESOURCE_DMA | flags; + res->start = dma; + res->end = dma; + +dev_dbg (&dev->dev," add dma %d flags %#x\n" , dma, flags); +return pnp_res; +} +/* format is: pnp_reserve_irq=irq1[,irq2] .... */ static int __init pnp_setup_reserve_irq (char *str) {
drivers/pnp/interface.c +4 -10
@@ -440,16 +440,10 @@ buf +=3 ;while (isspace (*buf)) ++buf; - pnp_res =pnp_get_pnp_resource (dev, -IORESOURCE_DMA , ndma); -if (!pnp_res) -break ; - pnp_res->index = ndma; - res = &pnp_res->res; - res->start = res->end = -simple_strtoul (buf, &buf,0 ); - res->flags =IORESOURCE_DMA ; - ndma++; + start =simple_strtoul (buf, &buf,0 ); + pnp_res =pnp_add_dma_resource (dev, start,0 ); +if (pnp_res) + pnp_res->index = ndma++;continue ; }break ;
drivers/pnp/isapnp/core.c +3 -6
@@ -973,12 +973,9 @@ ret =isapnp_read_byte (ISAPNP_CFG_DMA + tmp);if (ret ==4 )continue ; - pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_DMA , - tmp); - pnp_res->index = tmp; - res = &pnp_res->res; - res->start = res->end = ret; - res->flags =IORESOURCE_DMA ; + pnp_res =pnp_add_dma_resource (dev, ret,0 ); +if (pnp_res) + pnp_res->index = tmp; } }return 0 ;
drivers/pnp/pnpacpi/rsparser.c +8 -34
60 lines not on this page · raw message
drivers/pnp/pnpbios/rsparser.c +4 -22
@@ -54,27 +54,6 @@* Allocated Resources */ -static void pnpbios_parse_allocated_dmaresource (struct pnp_dev *dev,int dma) -{ -struct resource *res; -int i; - -for (i =0 ; i <PNP_MAX_DMA ; i++) { - res =pnp_get_resource (dev,IORESOURCE_DMA , i); -if (!pnp_resource_valid (res)) -break ; - } - -if (i <PNP_MAX_DMA ) { - res->flags =IORESOURCE_DMA ;// Also clears _UNSET flag -if (dma ==-1 ) { - res->flags |=IORESOURCE_DISABLED ; -return ; - } - res->start = res->end = (unsigned long )dma; - } -} -static void pnpbios_parse_allocated_ioresource (struct pnp_dev *dev,int io,int len) {
@@ -199,12 +178,15 @@case SMALL_TAG_DMA :if (len !=2 ) goto len_err; + flags =0 ; io =-1 ; mask = p[1 ];for (i =0 ; i <8 ; i++, mask = mask >>1 )if (mask &0x01 ) io = i; -pnpbios_parse_allocated_dmaresource (dev, io); +if (io ==-1 ) + flags =IORESOURCE_DISABLED ; +pnp_add_dma_resource (dev, io, flags);break ;case SMALL_TAG_PORT :
PATCH 49/55 PNP: make generic pnp_add_io_resource()
In reply to Bjorn HelgaasAdd a pnp_add_io_resource() that can be used by all the PNP backends. This consolidates a little more pnp_resource_table knowledge into one place.
--- drivers/pnp/base.h | 3 +++ drivers/pnp/interface.c | 20 ++++++++------------ drivers/pnp/isapnp/core.c | 8 +++----- drivers/pnp/pnpacpi/rsparser.c | 35 ++++++++++------------------------- drivers/pnp/pnpbios/rsparser.c | 23 ++++++----------------- drivers/pnp/resource.c | 29 +++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 59 deletions(-)
drivers/pnp/base.h +3 -0
@@ -45,3 +45,6 @@ int flags);struct pnp_resource *pnp_add_dma_resource (struct pnp_dev *dev,int dma,int flags); +struct pnp_resource *pnp_add_io_resource (struct pnp_dev *dev, +resource_size_t start, +resource_size_t end,int flags);
drivers/pnp/interface.c +8 -12
@@ -324,7 +324,7 @@struct resource *res;char *buf = (void *)ubuf;int retval =0 ; -resource_size_t start; +resource_size_t start, end;if (dev->status &PNP_ATTACHED ) { retval = -EBUSY ;
@@ -382,24 +382,20 @@ buf +=2 ;while (isspace (*buf)) ++buf; - pnp_res =pnp_get_pnp_resource (dev, -IORESOURCE_IO , nport); -if (!pnp_res) -break ; - pnp_res->index = nport; - res = &pnp_res->res; - res->start =simple_strtoul (buf, &buf,0 ); + start =simple_strtoul (buf, &buf,0 );while (isspace (*buf)) ++buf;if (*buf =='-' ) { buf +=1 ;while (isspace (*buf)) ++buf; - res->end =simple_strtoul (buf, &buf,0 ); + end =simple_strtoul (buf, &buf,0 ); }else - res->end = res->start; - res->flags =IORESOURCE_IO ; - nport++; + end = start; + pnp_res =pnp_add_io_resource (dev, start, end, +0 ); +if (pnp_res) + pnp_res->index = nport++;continue ; }if (!strnicmp (buf,"mem" ,3 )) {
drivers/pnp/isapnp/core.c +3 -5
@@ -941,11 +941,9 @@ ret =isapnp_read_word (ISAPNP_CFG_PORT + (tmp <<1 ));if (!ret)continue ; - pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_IO , tmp); - pnp_res->index = tmp; - res = &pnp_res->res; - res->start = ret; - res->flags =IORESOURCE_IO ; + pnp_res =pnp_add_io_resource (dev, ret, ret,0 ); +if (pnp_res) + pnp_res->index = tmp; }for (tmp =0 ; tmp <ISAPNP_MAX_MEM ; tmp++) { ret =
drivers/pnp/pnpacpi/rsparser.c +10 -25
@@ -158,33 +158,18 @@return flags; } -static void pnpacpi_parse_allocated_ioresource (struct pnp_dev *dev, -u64 io,u64 len,int io_decode) +static void pnpacpi_parse_allocated_ioresource (struct pnp_dev *dev,u64 start, +u64 len,int io_decode) { -struct resource *res; -int i; -static unsigned char warned; +int flags =0 ; +u64 end = start + len -1 ; -for (i =0 ; i <PNP_MAX_PORT ; i++) { - res =pnp_get_resource (dev,IORESOURCE_IO , i); -if (!pnp_resource_valid (res)) -break ; - } -if (i <PNP_MAX_PORT ) { - res->flags =IORESOURCE_IO ;// Also clears _UNSET flag -if (io_decode ==ACPI_DECODE_16 ) - res->flags |=PNP_PORT_FLAG_16BITADDR ; -if (len <=0 || (io + len -1 ) >=0x10003 ) { - res->flags |=IORESOURCE_DISABLED ; -return ; - } - res->start = io; - res->end = io + len -1 ; - }else if (!warned) { -printk (KERN_WARNING "pnpacpi: exceeded the max number of IO " -"resources: %d \n" ,PNP_MAX_PORT ); - warned =1 ; - } +if (io_decode ==ACPI_DECODE_16 ) + flags |=PNP_PORT_FLAG_16BITADDR ; +if (len ==0 || end >=0x10003 ) + flags |=IORESOURCE_DISABLED ; + +pnp_add_io_resource (dev, start, end, flags); } static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
drivers/pnp/pnpbios/rsparser.c +6 -17
@@ -55,26 +55,15 @@*/ static void pnpbios_parse_allocated_ioresource (struct pnp_dev *dev, -int io,int len) +int start,int len) { -struct resource *res; -int i; +int flags =0 ; +int end = start + len -1 ; -for (i =0 ; i <PNP_MAX_PORT ; i++) { - res =pnp_get_resource (dev,IORESOURCE_IO , i); -if (!pnp_resource_valid (res)) -break ; - } +if (len <=0 || end >=0x10003 ) + flags |=IORESOURCE_DISABLED ; -if (i <PNP_MAX_PORT ) { - res->flags =IORESOURCE_IO ;// Also clears _UNSET flag -if (len <=0 || (io + len -1 ) >=0x10003 ) { - res->flags |=IORESOURCE_DISABLED ; -return ; - } - res->start = (unsigned long )io; - res->end = (unsigned long )(io + len -1 ); - } +pnp_add_io_resource (dev, start, end, flags); } static void pnpbios_parse_allocated_memresource(struct pnp_dev *dev,
drivers/pnp/resource.c +29 -0
@@ -628,6 +628,35 @@return pnp_res; } +struct pnp_resource *pnp_add_io_resource (struct pnp_dev *dev, +resource_size_t start, +resource_size_t end,int flags) +{ +struct pnp_resource *pnp_res; +struct resource *res; +static unsigned char warned; + + pnp_res =pnp_new_resource (dev,IORESOURCE_IO ); +if (!pnp_res) { +if (!warned) { +dev_err (&dev->dev,"can't add resource for IO " +"%#llx-%#llx\n" ,(unsigned long long ) start, + (unsigned long long ) end); + warned =1 ; + } +return NULL ; + } + + res = &pnp_res->res; + res->flags =IORESOURCE_IO | flags; + res->start = start; + res->end = end; + +dev_dbg (&dev->dev," add io %#llx-%#llx flags %#x\n" , + (unsigned long long ) start, (unsigned long long ) end, flags); +return pnp_res; +} +/* format is: pnp_reserve_irq=irq1[,irq2] .... */ static int __init pnp_setup_reserve_irq (char *str) {
PATCH 50/55 PNP: make generic pnp_add_mem_resource()
In reply to Bjorn HelgaasAdd a pnp_add_mem_resource() that can be used by all the PNP backends. This consolidates a little more pnp_resource_table knowledge into one place.
--- drivers/pnp/base.h | 3 +++ drivers/pnp/interface.c | 19 +++++++------------ drivers/pnp/isapnp/core.c | 10 +++------- drivers/pnp/pnpacpi/rsparser.c | 30 +++++++----------------------- drivers/pnp/pnpbios/rsparser.c | 21 +++++---------------- drivers/pnp/resource.c | 29 +++++++++++++++++++++++++++++ 6 files changed, 54 insertions(+), 58 deletions(-)
drivers/pnp/base.h +3 -0
@@ -48,3 +48,6 @@struct pnp_resource *pnp_add_io_resource (struct pnp_dev *dev,resource_size_t start,resource_size_t end,int flags); +struct pnp_resource *pnp_add_mem_resource (struct pnp_dev *dev, +resource_size_t start, +resource_size_t end,int flags);
drivers/pnp/resource.c +29 -0
@@ -657,6 +657,35 @@return pnp_res; } +struct pnp_resource *pnp_add_mem_resource (struct pnp_dev *dev, +resource_size_t start, +resource_size_t end,int flags) +{ +struct pnp_resource *pnp_res; +struct resource *res; +static unsigned char warned; + + pnp_res =pnp_new_resource (dev,IORESOURCE_MEM ); +if (!pnp_res) { +if (!warned) { +dev_err (&dev->dev,"can't add resource for MEM " +"%#llx-%#llx\n" ,(unsigned long long ) start, + (unsigned long long ) end); + warned =1 ; + } +return NULL ; + } + + res = &pnp_res->res; + res->flags =IORESOURCE_MEM | flags; + res->start = start; + res->end = end; + +dev_dbg (&dev->dev," add mem %#llx-%#llx flags %#x\n" , + (unsigned long long ) start, (unsigned long long ) end, flags); +return pnp_res; +} +/* format is: pnp_reserve_irq=irq1[,irq2] .... */ static int __init pnp_setup_reserve_irq (char *str) {
drivers/pnp/interface.c +7 -12
@@ -321,7 +321,6 @@ {struct pnp_dev *dev =to_pnp_dev (dmdev);struct pnp_resource *pnp_res; -struct resource *res;char *buf = (void *)ubuf;int retval =0 ;resource_size_t start, end;
@@ -402,24 +401,20 @@ buf +=3 ;while (isspace (*buf)) ++buf; - pnp_res =pnp_get_pnp_resource (dev, -IORESOURCE_MEM , nmem); -if (!pnp_res) -break ; - pnp_res->index = nmem; - res = &pnp_res->res; - res->start =simple_strtoul (buf, &buf,0 ); + start =simple_strtoul (buf, &buf,0 );while (isspace (*buf)) ++buf;if (*buf =='-' ) { buf +=1 ;while (isspace (*buf)) ++buf; - res->end =simple_strtoul (buf, &buf,0 ); + end =simple_strtoul (buf, &buf,0 ); }else - res->end = res->start; - res->flags =IORESOURCE_MEM ; - nmem++; + end = start; + pnp_res =pnp_add_mem_resource (dev, start, end, +0 ); +if (pnp_res) + pnp_res->index = nmem++;continue ; }if (!strnicmp (buf,"irq" ,3 )) {
drivers/pnp/isapnp/core.c +3 -7
@@ -932,7 +932,6 @@static int isapnp_read_resources (struct pnp_dev *dev) {struct pnp_resource *pnp_res; -struct resource *res;int tmp, ret; dev->active =isapnp_read_byte (ISAPNP_CFG_ACTIVATE );
@@ -950,12 +949,9 @@isapnp_read_word (ISAPNP_CFG_MEM + (tmp <<3 )) <<8 ;if (!ret)continue ; - pnp_res =pnp_get_pnp_resource (dev,IORESOURCE_MEM , - tmp); - pnp_res->index = tmp; - res = &pnp_res->res; - res->start = ret; - res->flags =IORESOURCE_MEM ; + pnp_res =pnp_add_mem_resource (dev, ret, ret,0 ); +if (pnp_res) + pnp_res->index = tmp; }for (tmp =0 ; tmp <ISAPNP_MAX_IRQ ; tmp++) { ret =
drivers/pnp/pnpacpi/rsparser.c +8 -24
@@ -173,34 +173,18 @@ }static void pnpacpi_parse_allocated_memresource (struct pnp_dev *dev, -u64 mem,u64 len, +u64 start,u64 len,int write_protect) { -struct resource *res; -int i; -static unsigned char warned; +int flags =0 ; +u64 end = start + len -1 ; -for (i =0 ; i <PNP_MAX_MEM ; i++) { - res =pnp_get_resource (dev,IORESOURCE_MEM , i); -if (!pnp_resource_valid (res)) -break ; - } -if (i <PNP_MAX_MEM ) { - res->flags =IORESOURCE_MEM ;// Also clears _UNSET flag -if (len <=0 ) { - res->flags |=IORESOURCE_DISABLED ; -return ; - } -if (write_protect ==ACPI_READ_WRITE_MEMORY ) - res->flags |=IORESOURCE_MEM_WRITEABLE ; +if (len ==0 ) + flags |=IORESOURCE_DISABLED ; +if (write_protect ==ACPI_READ_WRITE_MEMORY ) + flags |=IORESOURCE_MEM_WRITEABLE ; - res->start = mem; - res->end = mem + len -1 ; - }else if (!warned) { -printk (KERN_WARNING "pnpacpi: exceeded the max number of mem " -"resources: %d\n" ,PNP_MAX_MEM ); - warned =1 ; - } +pnp_add_mem_resource (dev, start, end, flags); } static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
drivers/pnp/pnpbios/rsparser.c +6 -17
@@ -67,26 +67,15 @@ }static void pnpbios_parse_allocated_memresource (struct pnp_dev *dev, -int mem,int len) +int start,int len) { -struct resource *res; -int i; +int flags =0 ; +int end = start + len -1 ; -for (i =0 ; i <PNP_MAX_MEM ; i++) { - res =pnp_get_resource (dev,IORESOURCE_MEM , i); -if (!pnp_resource_valid (res)) -break ; - } +if (len <=0 ) + flags |=IORESOURCE_DISABLED ; -if (i <PNP_MAX_MEM ) { - res->flags =IORESOURCE_MEM ;// Also clears _UNSET flag -if (len <=0 ) { - res->flags |=IORESOURCE_DISABLED ; -return ; - } - res->start = (unsigned long )mem; - res->end = (unsigned long )(mem + len -1 ); - } +pnp_add_mem_resource (dev, start, end, flags); } static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
PATCH 51/55 ISAPNP: fold isapnp_read_resources() back into isapnp_get_resources()
In reply to Bjorn Helgaasisapnp_get_resources() does very little besides call isapnp_read_resources(), so just fold them back together.
Based on a patch by Rene Herman <[email protected]>
drivers/pnp/isapnp/core.c +29 -37
@@ -929,62 +929,54 @@EXPORT_SYMBOL (isapnp_cfg_end);EXPORT_SYMBOL (isapnp_write_byte); -static int isapnp_read_resources (struct pnp_dev *dev) +static int isapnp_get_resources (struct pnp_dev *dev) {struct pnp_resource *pnp_res; -int tmp, ret; +int i, ret; +dev_dbg (&dev->dev,"get resources\n" ); +pnp_init_resources (dev); +isapnp_cfg_begin (dev->card->number, dev->number); dev->active =isapnp_read_byte (ISAPNP_CFG_ACTIVATE ); -if (dev->active) { -for (tmp =0 ; tmp <ISAPNP_MAX_PORT ; tmp++) { - ret =isapnp_read_word (ISAPNP_CFG_PORT + (tmp <<1 )); -if (!ret) -continue ; +if (!dev->active) + goto __end; + +for (i =0 ; i <ISAPNP_MAX_PORT ; i++) { + ret =isapnp_read_word (ISAPNP_CFG_PORT + (i <<1 )); +if (ret) { pnp_res =pnp_add_io_resource (dev, ret, ret,0 );if (pnp_res) - pnp_res->index = tmp; + pnp_res->index = i; } -for (tmp =0 ; tmp <ISAPNP_MAX_MEM ; tmp++) { - ret = -isapnp_read_word (ISAPNP_CFG_MEM + (tmp <<3 )) <<8 ; -if (!ret) -continue ; + } +for (i =0 ; i <ISAPNP_MAX_MEM ; i++) { + ret =isapnp_read_word (ISAPNP_CFG_MEM + (i <<3 )) <<8 ; +if (ret) { pnp_res =pnp_add_mem_resource (dev, ret, ret,0 );if (pnp_res) - pnp_res->index = tmp; + pnp_res->index = i; } -for (tmp =0 ; tmp <ISAPNP_MAX_IRQ ; tmp++) { - ret = - (isapnp_read_word (ISAPNP_CFG_IRQ + (tmp <<1 )) >> -8 ); -if (!ret) -continue ; + } +for (i =0 ; i <ISAPNP_MAX_IRQ ; i++) { + ret =isapnp_read_word (ISAPNP_CFG_IRQ + (i <<1 )) >>8 ; +if (ret) { pnp_res =pnp_add_irq_resource (dev, ret,0 );if (pnp_res) - pnp_res->index = tmp; + pnp_res->index = i; } -for (tmp =0 ; tmp <ISAPNP_MAX_DMA ; tmp++) { - ret =isapnp_read_byte (ISAPNP_CFG_DMA + tmp); -if (ret ==4 ) -continue ; + } +for (i =0 ; i <ISAPNP_MAX_DMA ; i++) { + ret =isapnp_read_byte (ISAPNP_CFG_DMA + i); +if (ret !=4 ) { pnp_res =pnp_add_dma_resource (dev, ret,0 );if (pnp_res) - pnp_res->index = tmp; + pnp_res->index = i; } } -return 0 ; -} -static int isapnp_get_resources (struct pnp_dev *dev) -{ -int ret; - -dev_dbg (&dev->dev,"get resources\n" ); -pnp_init_resources (dev); -isapnp_cfg_begin (dev->card->number, dev->number); - ret =isapnp_read_resources (dev); +__end:isapnp_cfg_end (); -return ret; +return 0 ; }static int isapnp_set_resources (struct pnp_dev *dev)
PATCH 52/55 PNPACPI: move _CRS/_PRS warnings closer to the action
In reply to Bjorn HelgaasMove warnings about _CRS and _PRS problems to the place where we actually make the ACPI calls. Then we don't have to pass around acpi_status values any more than necessary.
drivers/pnp/pnpacpi/pnpacpi.h +2 -2
@@ -5,8 +5,8 @@#include <linux/acpi.h> #include <linux/pnp.h> -acpi_status pnpacpi_parse_allocated_resource (struct pnp_dev *); -acpi_status pnpacpi_parse_resource_option_data (struct pnp_dev *); +int pnpacpi_parse_allocated_resource (struct pnp_dev *); +int pnpacpi_parse_resource_option_data (struct pnp_dev *);int pnpacpi_encode_resources (struct pnp_dev *,struct acpi_buffer *);int pnpacpi_build_resource_template (struct pnp_dev *,struct acpi_buffer *);#endif
drivers/pnp/pnpacpi/core.c +5 -19
@@ -75,11 +75,8 @@static int pnpacpi_get_resources (struct pnp_dev *dev) { -acpi_status status; -dev_dbg (&dev->dev,"get resources\n" ); - status =pnpacpi_parse_allocated_resource (dev); -return ACPI_FAILURE (status) ? -ENODEV :0 ; +return pnpacpi_parse_allocated_resource (dev); }static int pnpacpi_set_resources (struct pnp_dev *dev)
@@ -182,22 +179,11 @@else strncpy (dev->name,acpi_device_bid (device),sizeof (dev->name)); -if (dev->active) { -/* parse allocated resource */ - status =pnpacpi_parse_allocated_resource (dev); -if (ACPI_FAILURE (status) && (status !=AE_NOT_FOUND )) { -pnp_err ("PnPACPI: METHOD_NAME__CRS failure for %s" , -acpi_device_hid (device)); - } - } +if (dev->active) +pnpacpi_parse_allocated_resource (dev); -if (dev->capabilities &PNP_CONFIGURABLE ) { - status =pnpacpi_parse_resource_option_data (dev); -if (ACPI_FAILURE (status) && (status !=AE_NOT_FOUND )) { -pnp_err ("PnPACPI: METHOD_NAME__PRS failure for %s" , -acpi_device_hid (device)); - } - } +if (dev->capabilities &PNP_CONFIGURABLE ) +pnpacpi_parse_resource_option_data (dev);if (device->flags.compatible_ids) {struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
drivers/pnp/pnpacpi/rsparser.c +22 -8
@@ -339,16 +339,24 @@return AE_OK ; } -acpi_status pnpacpi_parse_allocated_resource (struct pnp_dev *dev) +int pnpacpi_parse_allocated_resource (struct pnp_dev *dev) {acpi_handle handle = dev->data; +acpi_status status;dev_dbg (&dev->dev,"parse allocated resources\n" );pnp_init_resources (dev); -return acpi_walk_resources (handle,METHOD_NAME__CRS , - pnpacpi_allocated_resource, dev); + status =acpi_walk_resources (handle,METHOD_NAME__CRS , + pnpacpi_allocated_resource, dev); + +if (ACPI_FAILURE (status)) { +if (status !=AE_NOT_FOUND ) +dev_err (&dev->dev,"can't evaluate _CRS: %d" , status); +return -EPERM ; + } +return 0 ; } static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
@@ -670,7 +678,7 @@return AE_OK ; } -acpi_status __init pnpacpi_parse_resource_option_data (struct pnp_dev *dev) +int __init pnpacpi_parse_resource_option_data (struct pnp_dev *dev) {acpi_handle handle = dev->data;acpi_status status;
@@ -680,13 +688,19 @@ parse_data.option =pnp_register_independent_option (dev);if (!parse_data.option) -return AE_ERROR ; +return -ENOMEM ; + parse_data.option_independent = parse_data.option; parse_data.dev = dev; status =acpi_walk_resources (handle,METHOD_NAME__PRS , pnpacpi_option_resource, &parse_data); -return status; +if (ACPI_FAILURE (status)) { +if (status !=AE_NOT_FOUND ) +dev_err (&dev->dev,"can't evaluate _PRS: %d" , status); +return -EPERM ; + } +return 0 ; }static int pnpacpi_supported_resource (struct acpi_resource *res)
@@ -745,7 +759,7 @@ status =acpi_walk_resources (handle,METHOD_NAME__CRS , pnpacpi_count_resources, &res_cnt);if (ACPI_FAILURE (status)) { -dev_err (&dev->dev,"can't evaluate _CRS\n" ); +dev_err (&dev->dev,"can't evaluate _CRS: %d\n" , status);return -EINVAL ; }if (!res_cnt)
@@ -760,7 +774,7 @@ pnpacpi_type_resources, &resource);if (ACPI_FAILURE (status)) {kfree (buffer->pointer); -dev_err (&dev->dev,"can't evaluate _CRS\n" ); +dev_err (&dev->dev,"can't evaluate _CRS: %d\n" , status);return -EINVAL ; }/* resource will pointer the end resource now */
PATCH 53/55 PNP: make interfaces private to the PNP core
In reply to Bjorn HelgaasThe interfaces for registering protocols, devices, cards, and resource options should only be used inside the PNP core.
--- drivers/pnp/base.h | 24 +++++++++++++++++++++++- include/linux/pnp.h | 34 ---------------------------------- 2 files changed, 23 insertions(+), 35 deletions(-)
include/linux/pnp.h +0 -36
@@ -414,19 +414,12 @@#if defined(CONFIG_PNP )/* device management */ -int pnp_register_protocol (struct pnp_protocol *protocol); -void pnp_unregister_protocol (struct pnp_protocol *protocol); -int pnp_add_device (struct pnp_dev *dev);int pnp_device_attach (struct pnp_dev *pnp_dev);void pnp_device_detach (struct pnp_dev *pnp_dev);extern struct list_head pnp_global;extern int pnp_platform_devices;/* multidevice card support */ -int pnp_add_card (struct pnp_card *card); -void pnp_remove_card (struct pnp_card *card); -int pnp_add_card_device (struct pnp_card *card,struct pnp_dev *dev); -void pnp_remove_card_device (struct pnp_dev *dev);struct pnp_dev *pnp_request_card_device (struct pnp_card_link *clink,const char *id,struct pnp_dev *from);void pnp_release_card_device (struct pnp_dev *dev);
@@ -435,20 +428,7 @@extern struct list_head pnp_cards;/* resource management */ -struct pnp_option *pnp_register_independent_option (struct pnp_dev *dev); -struct pnp_option *pnp_register_dependent_option (struct pnp_dev *dev, -int priority); -int pnp_register_irq_resource (struct pnp_dev *dev,struct pnp_option *option, -struct pnp_irq *data); -int pnp_register_dma_resource (struct pnp_dev *dev,struct pnp_option *option, -struct pnp_dma *data); -int pnp_register_port_resource (struct pnp_dev *dev,struct pnp_option *option, -struct pnp_port *data); -int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option, -struct pnp_mem *data); -void pnp_init_resources (struct pnp_dev *dev);int pnp_auto_config_dev (struct pnp_dev *dev); -int pnp_validate_config (struct pnp_dev *dev);int pnp_start_dev (struct pnp_dev *dev);int pnp_stop_dev (struct pnp_dev *dev);int pnp_activate_dev (struct pnp_dev *dev);
@@ -463,35 +443,19 @@#else /* device management */ -static inline int pnp_register_protocol (struct pnp_protocol *protocol) {return -ENODEV ; } -static inline void pnp_unregister_protocol (struct pnp_protocol *protocol) { } -static inline int pnp_init_device (struct pnp_dev *dev) {return -ENODEV ; } -static inline int pnp_add_device (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_device_attach (struct pnp_dev *pnp_dev) {return -ENODEV ; }static inline void pnp_device_detach (struct pnp_dev *pnp_dev) { }#define pnp_platform_devices 0/* multidevice card support */ -static inline int pnp_add_card (struct pnp_card *card) {return -ENODEV ; } -static inline void pnp_remove_card (struct pnp_card *card) { } -static inline int pnp_add_card_device (struct pnp_card *card,struct pnp_dev *dev) {return -ENODEV ; } -static inline void pnp_remove_card_device (struct pnp_dev *dev) { }static inline struct pnp_dev *pnp_request_card_device (struct pnp_card_link *clink,const char *id,struct pnp_dev *from) {return NULL ; }static inline void pnp_release_card_device (struct pnp_dev *dev) { }static inline int pnp_register_card_driver (struct pnp_card_driver *drv) {return -ENODEV ; }static inline void pnp_unregister_card_driver (struct pnp_card_driver *drv) { }/* resource management */ -static inline struct pnp_option *pnp_register_independent_option (struct pnp_dev *dev) {return NULL ; } -static inline struct pnp_option *pnp_register_dependent_option (struct pnp_dev *dev,int priority) {return NULL ; } -static inline int pnp_register_irq_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_irq *data) {return -ENODEV ; } -static inline int pnp_register_dma_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_dma *data) {return -ENODEV ; } -static inline int pnp_register_port_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_port *data) {return -ENODEV ; } -static inline int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option,struct pnp_mem *data) {return -ENODEV ; } -static inline void pnp_init_resources (struct pnp_dev *dev) { }static inline int pnp_auto_config_dev (struct pnp_dev *dev) {return -ENODEV ; } -static inline int pnp_validate_config (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_start_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_stop_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_activate_dev (struct pnp_dev *dev) {return -ENODEV ; }
drivers/pnp/base.h +26 -1
@@ -1,12 +1,37 @@extern spinlock_t pnp_lock;void *pnp_alloc (long size); + +int pnp_register_protocol (struct pnp_protocol *protocol); +void pnp_unregister_protocol (struct pnp_protocol *protocol); +#define PNP_EISA_ID_MASK 0x7fffffffvoid pnp_eisa_id_to_string (u32 id,char *str);struct pnp_dev *pnp_alloc_dev (struct pnp_protocol *,int id,char *pnpid);struct pnp_card *pnp_alloc_card (struct pnp_protocol *,int id,char *pnpid); + +int pnp_add_device (struct pnp_dev *dev);struct pnp_id *pnp_add_id (struct pnp_dev *dev,char *id); -struct pnp_id *pnp_add_card_id (struct pnp_card *card,char *id);int pnp_interface_attach_device (struct pnp_dev *dev); + +int pnp_add_card (struct pnp_card *card); +struct pnp_id *pnp_add_card_id (struct pnp_card *card,char *id); +void pnp_remove_card (struct pnp_card *card); +int pnp_add_card_device (struct pnp_card *card,struct pnp_dev *dev); +void pnp_remove_card_device (struct pnp_dev *dev); + +struct pnp_option *pnp_register_independent_option (struct pnp_dev *dev); +struct pnp_option *pnp_register_dependent_option (struct pnp_dev *dev, +int priority); +int pnp_register_irq_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_irq *data); +int pnp_register_dma_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_dma *data); +int pnp_register_port_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_port *data); +int pnp_register_mem_resource (struct pnp_dev *dev,struct pnp_option *option, +struct pnp_mem *data); +void pnp_init_resources (struct pnp_dev *dev); +void pnp_fixup_device (struct pnp_dev *dev);void pnp_free_option (struct pnp_option *option);int __pnp_add_device (struct pnp_dev *dev);
PATCH 54/55 ISAPNP: remove unused pnp_dev->regs field
In reply to Bjorn HelgaasThe "regs" field in struct pnp_dev is set but never read, so remove it.
drivers/pnp/isapnp/core.c +0 -3
@@ -416,10 +416,7 @@if (!dev)return NULL ; - dev->regs = tmp[4 ]; dev->card = card; -if (size >5 ) - dev->regs |= tmp[5 ] <<8 ; dev->capabilities |=PNP_CONFIGURABLE ; dev->capabilities |=PNP_READ ; dev->capabilities |=PNP_WRITE ;
include/linux/pnp.h +0 -1
@@ -253,7 +253,6 @@struct pnp_resource_table *res;char name[PNP_NAME_LEN ];/* contains a human-readable name */ -unsigned short regs;/* ISAPnP: supported registers */ int flags;/* used by protocols */ struct proc_dir_entry *procent;/* device entry in /proc/bus/isapnp */ void *data;
PATCH 55/55 PNPBIOS: remove include/linux/pnpbios.h
In reply to Bjorn HelgaasThe contents of include/linux/pnpbios.h are used only inside the PNPBIOS backend, so this file doesn't need to be visible outside PNP.
This patch moves the contents into an existing PNPBIOS-specific file, drivers/pnp/pnpbios/pnpbios.h.
--- drivers/pnp/pnpbios/bioscalls.c | 1 drivers/pnp/pnpbios/core.c | 1 drivers/pnp/pnpbios/pnpbios.h | 136 ++++++++++++++++++++++++++++++++++++ drivers/pnp/pnpbios/proc.c | 2 drivers/pnp/pnpbios/rsparser.c | 1 include/linux/pnpbios.h | 151 ---------------------------------------- 6 files changed, 137 insertions(+), 155 deletions(-)
drivers/pnp/pnpbios/bioscalls.c +0 -1
@@ -7,7 +7,6 @@#include <linux/init.h> #include <linux/linkage.h> #include <linux/kernel.h> -#include <linux/pnpbios.h> #include <linux/device.h> #include <linux/pnp.h> #include <linux/mm.h>
drivers/pnp/pnpbios/core.c +0 -1
@@ -50,7 +50,6 @@#include <linux/init.h> #include <linux/linkage.h> #include <linux/kernel.h> -#include <linux/pnpbios.h> #include <linux/device.h> #include <linux/pnp.h> #include <linux/mm.h>
drivers/pnp/pnpbios/pnpbios.h +136 -0
142 lines not on this page · raw message
drivers/pnp/pnpbios/proc.c +1 -1
@@ -23,7 +23,7 @@#include <linux/slab.h> #include <linux/types.h> #include <linux/proc_fs.h> -#include <linux/pnpbios.h> +#include <linux/pnp.h> #include <linux/init.h> #include <asm/uaccess.h>
drivers/pnp/pnpbios/rsparser.c +0 -1
@@ -4,7 +4,6 @@#include <linux/ctype.h> #include <linux/pnp.h> -#include <linux/pnpbios.h> #include <linux/string.h> #include <linux/slab.h>
include/linux/pnpbios.h deleted +0 -151
151 lines not on this page · raw message
Len Brown
reviewerBjorn,
I'm running this version on my primary development machine, and I've pulled it into the acpi tree a few minutes ago.
thanks,
-Len
Quoted 54 lines · Bjorn Helgaas
I'm trying to stabilize something so we can get it into -mm, so this only addresses Rene's comments on v4.
As a reminder, if anybody tests this and sees problems, the dmesg log with
CONFIG_PNP_DEBUGenabled would be a great help to me.Changes between v4 and v5:
- moved #ifdef DEBUG inside
dbg_pnp_show_resources()
- removed cast of flags to int; print the long directly
- changed printk "0x%x" to "%#x"
- set "type" inpnp_clean_resource_table()
- fix return type of pnp_{port,mem,irq,dma}_flags()
- new patch converts pnp_assign_*() and /sys interfaces topnp_get_resource()
- added Rene's acksChanges between v3 and v4:
- changed
pnp_check_port(), etc., to take resource instead of index
- added some decoder/encoder/assign debug output (underCONFIG_PNP_DEBUG)
- fixed some ISAPNP register index bisectability problems
- removed the list-based resource management (will work on that separately)Changes between v2 and v3:
- several updates from Rene Herman's review:
- tweak EISA ID conversion and keep high-order bit for ISAPNP
- fixpnp_add_card_id()so bisection works better
- fix some "x <= 0" tests when x is unsigned
- make resource accessors inlines, not #defines
- fix pnp_{port,mem,irq,dma}_valid() return int, notresource_size_t
- foldisapnp_read_resources()back intoisapnp_get_resources()
- factored outpnp_init_resource()from pnp_{init,clean}_resource_table()
- initialize genericpnp_devfields earlier, to helpdev_printk
- addpnp_resourceto hold ISAPNP register index
- convert to resource management from table to list (finally)
- removepnp_dev->regs(only set by ISAPNP, never used)
- in/sys/.../resources, don't sort resources by typeChanges between first post and v2:
- export
pnp_get_resource()
- fix EISA ID conversion and make a common function for ISAPNP/PNPBIOS
- fix typos in pnp_check_{port,mem,etc} that made resource assign fail- the following fixes should precede this series (they're in -mm already):
-parport_pc: wrap PNP probe code inCONFIG_PNP
- radio-cadet: wrap PNP probe code inCONFIG_PNP
- smsc-ircc2: wrap PNP probe code inCONFIG_PNP
- nsc-ircc: wrap PNP probe code inCONFIG_PNPBjorn