Various Fixes and Improved Error Checking (3/4)
Subsystems (2)
RFC PATCH 1/1 Various Fixes and Improved Error Checking (3/4)
This patch fixes many bugs that were discovered while testing the previous two patches. It also checks to see if the resources requested and the resources set actually match.
drivers/pnp/driver.c +1 -1
@@ -95,7 +95,7 @@ pnp_dev =to_pnp_dev (dev); pnp_drv =to_pnp_driver (dev->driver); -pnp_dbg ("pnp: match found with the PnP device '%s' and the driver '%s'" , dev->bus_id,pnp_drv->name); +pnp_dbg ("match found with the PnP device '%s' and the driver '%s'" , dev->bus_id,pnp_drv->name); error =pnp_device_attach (pnp_dev);if (error <0 )
drivers/pnp/isapnp/core.c +11 -10
@@ -969,7 +969,7 @@EXPORT_SYMBOL (isapnp_wake);EXPORT_SYMBOL (isapnp_device); -static int isapnp_get_resources (struct pnp_dev *dev) +static int isapnp_get_resources (struct pnp_dev *dev,struct pnp_resource_table * res) {/* We don't need to do anything but this, the rest is taken care of */ if (pnp_port_valid(dev, 0) == 0 &&
@@ -979,27 +979,28 @@ dev->active =0 ; else dev->active = 1; + *res = dev->res;return 0 ; } -static int isapnp_set_resources (struct pnp_dev *dev) +static int isapnp_set_resources (struct pnp_dev *dev,struct pnp_resource_table * res) {int tmp;isapnp_cfg_begin (dev->card->number, dev->number); dev->active =1 ; -for (tmp =0 ; tmp <8 &&pnp_port_valid (dev, tmp); tmp++) -isapnp_write_word (ISAPNP_CFG_PORT +(tmp<<1 ),pnp_port_start (dev, tmp)); -for (tmp =0 ; tmp <2 &&pnp_irq_valid (dev, tmp); tmp++) { -int irq =pnp_irq (dev, tmp); +for (tmp =0 ; tmp <8 && res->port_resource[tmp].flags &IORESOURCE_IO ; tmp++) +isapnp_write_word (ISAPNP_CFG_PORT +(tmp<<1 ), res->port_resource[tmp].start); +for (tmp =0 ; tmp <2 && res->irq_resource[tmp].flags &IORESOURCE_IRQ ; tmp++) { +int irq = res->irq_resource[tmp].start;if (irq ==2 ) irq =9 ;isapnp_write_byte (ISAPNP_CFG_IRQ +(tmp<<1 ), irq); } -for (tmp =0 ; tmp <2 &&pnp_dma_valid (dev, tmp); tmp++) -isapnp_write_byte (ISAPNP_CFG_DMA +tmp,pnp_dma (dev, tmp)); -for (tmp =0 ; tmp <4 &&pnp_mem_valid (dev, tmp); tmp++) -isapnp_write_word (ISAPNP_CFG_MEM +(tmp<<2 ), (pnp_mem_start (dev, tmp) >>8 ) &0xffff ); +for (tmp =0 ; tmp <2 && res->dma_resource[tmp].flags &IORESOURCE_DMA ; tmp++) +isapnp_write_byte (ISAPNP_CFG_DMA +tmp, res->dma_resource[tmp].start); +for (tmp =0 ; tmp <4 && res->mem_resource[tmp].flags &IORESOURCE_MEM ; tmp++) +isapnp_write_word (ISAPNP_CFG_MEM +(tmp<<2 ), (res->mem_resource[tmp].start >>8 ) &0xffff );isapnp_activate (dev->number);isapnp_cfg_end ();return 0 ;
drivers/pnp/pnpbios/core.c +25 -19
99 lines not on this page · raw message
drivers/pnp/resource.c +70 -30
178 lines not on this page · raw message
drivers/pnp/support.c +48 -42
206 lines not on this page · raw message
include/linux/pnp.h +8 -9
@@ -156,7 +156,6 @@struct pnp_resources {unsigned short priority;/* priority */ -unsigned short dependent;/* dependent resources */ struct pnp_port *port;/* first port */ struct pnp_irq *irq;/* first IRQ */ struct pnp_dma *dma;/* first DMA */
@@ -333,8 +332,8 @@char * name;/* resource control functions */ -int (*get)(struct pnp_dev *dev); -int (*set)(struct pnp_dev *dev); +int (*get)(struct pnp_dev *dev,struct pnp_resource_table *res); +int (*set)(struct pnp_dev *dev,struct pnp_resource_table *res);int (*disable)(struct pnp_dev *dev);/* used by pnp layer only (look but don't touch) */
@@ -387,9 +386,9 @@/* support */ int pnp_is_active (struct pnp_dev * dev); -unsigned char *pnp_parse_current_resources (unsigned char * p,unsigned char * end,struct pnp_dev *dev); -unsigned char *pnp_parse_possible_resources (unsigned char * p,unsigned char * end,struct pnp_dev *dev); -unsigned char *pnp_write_resources (unsigned char * p,unsigned char * end,struct pnp_dev *dev); +unsigned char *pnp_parse_current_resources (unsigned char * p,unsigned char * end,struct pnp_resource_table * res); +unsigned char *pnp_parse_possible_resources (unsigned char * p,unsigned char * end,struct pnp_dev * dev); +unsigned char *pnp_write_resources (unsigned char * p,unsigned char * end,struct pnp_resource_table * res);#else
@@ -425,9 +424,9 @@/* support */ static inline int pnp_is_active(struct pnp_dev * dev) { return -ENODEV; ) -static inline unsigned char *pnp_parse_current_resources (unsigned char * p,unsigned char * end,struct pnp_dev *dev) {return NULL ; } -static inline unsigned char *pnp_parse_possible_resources (unsigned char * p,unsigned char * end,struct pnp_dev *dev) {return NULL ; } -static inline unsigned char * pnp_write_resources(unsigned char * p, unsigned char * end, struct pnp_dev *dev) { return NULL; ) +static inline unsigned char *pnp_parse_current_resources (unsigned char * p,unsigned char * end,struct pnp_resource_table * res) {return NULL ; } +static inline unsigned char *pnp_parse_possible_resources (unsigned char * p,unsigned char * end,struct pnp_dev * dev) {return NULL ; } +static inline unsigned char * pnp_write_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res) { return NULL; ) #endif /* CONFIG_PNP */
Jaroslav Kysela
maintainerdrivers/pnp/isapnp/core.c line 995
Quoted 8 lines · Adam Belay
drivers/pnp/isapnp/core.c +4
-4-for (tmp =0 ; tmp <8 &&pnp_port_valid (dev, tmp); tmp++) -isapnp_write_word (ISAPNP_CFG_PORT +(tmp<<1 ),pnp_port_start (dev, tmp)); -for (tmp =0 ; tmp <2 &&pnp_irq_valid (dev, tmp); tmp++) { -int irq =pnp_irq (dev, tmp); +for (tmp =0 ; tmp <8 && res->port_resource[tmp].flags &IORESOURCE_IO ; tmp++) +isapnp_write_word (ISAPNP_CFG_PORT +(tmp<<1 ), res->port_resource[tmp].start); +for (tmp =0 ; tmp <2 && res->irq_resource[tmp].flags &IORESOURCE_IRQ ; tmp++) { +int irq = res->irq_resource[tmp].start;
Why you remove pnp_*_valid() checks? They are more robust. There is also check for UNSET flag.
Jaroslav
-----
Jaroslav Kysela <[email protected]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs