Commit 245073f0 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Linus Torvalds

ISAPNP: fix limits of logical device register set

PNP_MAX_MEM and PNP_MAX_PORT are mainly used to size tables of PNP
device resources.  In 2.6.24, we increased their values to accomodate
ACPI devices that have many resources:

                 2.6.23    2.6.24
                 ------    ------
  PNP_MAX_MEM       4         12
  PNP_MAX_PORT      8         40

However, ISAPNP also used these constants as the size of parts of the
logical device register set.  This register set is fixed by hardware,
so increasing the constants meant that we were reading and writing
unintended parts of the register set.

This patch changes ISAPNP to use the correct register set sizes (the
same values we used prior to 2.6.24).
Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a5754337
...@@ -88,6 +88,15 @@ MODULE_LICENSE("GPL"); ...@@ -88,6 +88,15 @@ MODULE_LICENSE("GPL");
#define _LTAG_MEM32RANGE 0x85 #define _LTAG_MEM32RANGE 0x85
#define _LTAG_FIXEDMEM32RANGE 0x86 #define _LTAG_FIXEDMEM32RANGE 0x86
/*
* Sizes of ISAPNP logical device configuration register sets.
* See PNP-ISA-v1.0a.pdf, Appendix A.
*/
#define ISAPNP_MAX_MEM 4
#define ISAPNP_MAX_PORT 8
#define ISAPNP_MAX_IRQ 2
#define ISAPNP_MAX_DMA 2
static unsigned char isapnp_checksum_value; static unsigned char isapnp_checksum_value;
static DEFINE_MUTEX(isapnp_cfg_mutex); static DEFINE_MUTEX(isapnp_cfg_mutex);
static int isapnp_csn_count; static int isapnp_csn_count;
...@@ -945,14 +954,14 @@ static int isapnp_read_resources(struct pnp_dev *dev, ...@@ -945,14 +954,14 @@ static int isapnp_read_resources(struct pnp_dev *dev,
dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE); dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
if (dev->active) { if (dev->active) {
for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) { for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1)); ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
if (!ret) if (!ret)
continue; continue;
res->port_resource[tmp].start = ret; res->port_resource[tmp].start = ret;
res->port_resource[tmp].flags = IORESOURCE_IO; res->port_resource[tmp].flags = IORESOURCE_IO;
} }
for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) { for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
ret = ret =
isapnp_read_word(ISAPNP_CFG_MEM + (tmp << 3)) << 8; isapnp_read_word(ISAPNP_CFG_MEM + (tmp << 3)) << 8;
if (!ret) if (!ret)
...@@ -960,7 +969,7 @@ static int isapnp_read_resources(struct pnp_dev *dev, ...@@ -960,7 +969,7 @@ static int isapnp_read_resources(struct pnp_dev *dev,
res->mem_resource[tmp].start = ret; res->mem_resource[tmp].start = ret;
res->mem_resource[tmp].flags = IORESOURCE_MEM; res->mem_resource[tmp].flags = IORESOURCE_MEM;
} }
for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) { for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
ret = ret =
(isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >>
8); 8);
...@@ -970,7 +979,7 @@ static int isapnp_read_resources(struct pnp_dev *dev, ...@@ -970,7 +979,7 @@ static int isapnp_read_resources(struct pnp_dev *dev,
res->irq_resource[tmp].end = ret; res->irq_resource[tmp].end = ret;
res->irq_resource[tmp].flags = IORESOURCE_IRQ; res->irq_resource[tmp].flags = IORESOURCE_IRQ;
} }
for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) { for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp); ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
if (ret == 4) if (ret == 4)
continue; continue;
...@@ -1002,14 +1011,14 @@ static int isapnp_set_resources(struct pnp_dev *dev, ...@@ -1002,14 +1011,14 @@ static int isapnp_set_resources(struct pnp_dev *dev,
isapnp_cfg_begin(dev->card->number, dev->number); isapnp_cfg_begin(dev->card->number, dev->number);
dev->active = 1; dev->active = 1;
for (tmp = 0; for (tmp = 0;
tmp < PNP_MAX_PORT tmp < ISAPNP_MAX_PORT
&& (res->port_resource[tmp]. && (res->port_resource[tmp].
flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO; flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO;
tmp++) tmp++)
isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
res->port_resource[tmp].start); res->port_resource[tmp].start);
for (tmp = 0; for (tmp = 0;
tmp < PNP_MAX_IRQ tmp < ISAPNP_MAX_IRQ
&& (res->irq_resource[tmp]. && (res->irq_resource[tmp].
flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ; flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ;
tmp++) { tmp++) {
...@@ -1019,14 +1028,14 @@ static int isapnp_set_resources(struct pnp_dev *dev, ...@@ -1019,14 +1028,14 @@ static int isapnp_set_resources(struct pnp_dev *dev,
isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq); isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
} }
for (tmp = 0; for (tmp = 0;
tmp < PNP_MAX_DMA tmp < ISAPNP_MAX_DMA
&& (res->dma_resource[tmp]. && (res->dma_resource[tmp].
flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA; flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA;
tmp++) tmp++)
isapnp_write_byte(ISAPNP_CFG_DMA + tmp, isapnp_write_byte(ISAPNP_CFG_DMA + tmp,
res->dma_resource[tmp].start); res->dma_resource[tmp].start);
for (tmp = 0; for (tmp = 0;
tmp < PNP_MAX_MEM tmp < ISAPNP_MAX_MEM
&& (res->mem_resource[tmp]. && (res->mem_resource[tmp].
flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM; flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM;
tmp++) tmp++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment