]> git.hungrycats.org Git - linux/commitdiff
[PNP]: Resource flags update
authorAdam Belay <ambx1@neo.rr.com>
Sun, 8 Feb 2004 15:28:23 +0000 (15:28 +0000)
committerAdam Belay <ambx1@neo.rr.com>
Sun, 8 Feb 2004 15:28:23 +0000 (15:28 +0000)
This patch reorganizes resource flags to ensure that manual resource
settings are properly recognized.  This fix is necessary for many ALSA
drivers.  It also prevents comparisons between unset resource
structures.  The bug was discovered by Rene Herman
<rene.herman@keyaccess.nl>, who also wrote an initial version of this
patch.  I made further improvements to ensure that the pnp subsystem
was compatible with this initial change.

drivers/pnp/isapnp/core.c
drivers/pnp/manager.c
drivers/pnp/pnpbios/rsparser.c
drivers/pnp/resource.c
include/linux/pnp.h

index b5e3e898f8e56858c3038a04ece6e3818ad3dfc3..453f69c55967dde83abd508def27400b93e93118 100644 (file)
@@ -1039,17 +1039,17 @@ static int isapnp_set_resources(struct pnp_dev *dev, struct pnp_resource_table *
 
        isapnp_cfg_begin(dev->card->number, dev->number);
        dev->active = 1;
-       for (tmp = 0; tmp < PNP_MAX_PORT && res->port_resource[tmp].flags & IORESOURCE_IO; tmp++)
+       for (tmp = 0; tmp < PNP_MAX_PORT && (res->port_resource[tmp].flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO; tmp++)
                isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), res->port_resource[tmp].start);
-       for (tmp = 0; tmp < PNP_MAX_IRQ && res->irq_resource[tmp].flags & IORESOURCE_IRQ; tmp++) {
+       for (tmp = 0; tmp < PNP_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;
                isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
        }
-       for (tmp = 0; tmp < PNP_MAX_DMA && res->dma_resource[tmp].flags & IORESOURCE_DMA; tmp++)
+       for (tmp = 0; tmp < PNP_MAX_DMA && (res->dma_resource[tmp].flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA; tmp++)
                isapnp_write_byte(ISAPNP_CFG_DMA+tmp, res->dma_resource[tmp].start);
-       for (tmp = 0; tmp < PNP_MAX_MEM && res->mem_resource[tmp].flags & IORESOURCE_MEM; tmp++)
+       for (tmp = 0; tmp < PNP_MAX_MEM && (res->mem_resource[tmp].flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM; tmp++)
                isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (res->mem_resource[tmp].start >> 8) & 0xffff);
        /* FIXME: We aren't handling 32bit mems properly here */
        isapnp_activate(dev->number);
index 36b6220a6335d7d3ebdefa443870583c1aa97cb9..bd344233e5e872a308ebcc3df96614a344fe74b4 100644 (file)
@@ -223,25 +223,25 @@ void pnp_init_resource_table(struct pnp_resource_table *table)
                table->irq_resource[idx].name = NULL;
                table->irq_resource[idx].start = -1;
                table->irq_resource[idx].end = -1;
-               table->irq_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
+               table->irq_resource[idx].flags = IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
        }
        for (idx = 0; idx < PNP_MAX_DMA; idx++) {
                table->dma_resource[idx].name = NULL;
                table->dma_resource[idx].start = -1;
                table->dma_resource[idx].end = -1;
-               table->dma_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
+               table->dma_resource[idx].flags = IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
        }
        for (idx = 0; idx < PNP_MAX_PORT; idx++) {
                table->port_resource[idx].name = NULL;
                table->port_resource[idx].start = 0;
                table->port_resource[idx].end = 0;
-               table->port_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
+               table->port_resource[idx].flags = IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
        }
        for (idx = 0; idx < PNP_MAX_MEM; idx++) {
                table->mem_resource[idx].name = NULL;
                table->mem_resource[idx].start = 0;
                table->mem_resource[idx].end = 0;
-               table->mem_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
+               table->mem_resource[idx].flags = IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
        }
 }
 
@@ -258,28 +258,28 @@ static void pnp_clean_resource_table(struct pnp_resource_table * res)
                        continue;
                res->irq_resource[idx].start = -1;
                res->irq_resource[idx].end = -1;
-               res->irq_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
+               res->irq_resource[idx].flags = IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
        }
        for (idx = 0; idx < PNP_MAX_DMA; idx++) {
                if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO))
                        continue;
                res->dma_resource[idx].start = -1;
                res->dma_resource[idx].end = -1;
-               res->dma_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
+               res->dma_resource[idx].flags = IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
        }
        for (idx = 0; idx < PNP_MAX_PORT; idx++) {
                if (!(res->port_resource[idx].flags & IORESOURCE_AUTO))
                        continue;
                res->port_resource[idx].start = 0;
                res->port_resource[idx].end = 0;
-               res->port_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
+               res->port_resource[idx].flags = IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
        }
        for (idx = 0; idx < PNP_MAX_MEM; idx++) {
                if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO))
                        continue;
                res->mem_resource[idx].start = 0;
                res->mem_resource[idx].end = 0;
-               res->mem_resource[idx].flags = IORESOURCE_AUTO | IORESOURCE_UNSET;
+               res->mem_resource[idx].flags = IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
        }
 }
 
@@ -550,7 +550,7 @@ void pnp_resource_change(struct resource *resource, unsigned long start, unsigne
 {
        if (resource == NULL)
                return;
-       resource->flags &= ~IORESOURCE_AUTO;
+       resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
        resource->start = start;
        resource->end = start + size - 1;
 }
index 7af3cb0cecebcd963053b9102481049459170d7f..758d6804f0ff9e4e841ed636ea8ff800d6b33829 100644 (file)
@@ -49,7 +49,7 @@ static void
 pnpbios_parse_allocated_irqresource(struct pnp_resource_table * res, int irq)
 {
        int i = 0;
-       while ((res->irq_resource[i].flags & IORESOURCE_IRQ) && i < PNP_MAX_IRQ) i++;
+       while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_IRQ) i++;
        if (i < PNP_MAX_IRQ) {
                res->irq_resource[i].flags = IORESOURCE_IRQ;  // Also clears _UNSET flag
                if (irq == -1) {
@@ -65,7 +65,7 @@ static void
 pnpbios_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
 {
        int i = 0;
-       while ((res->dma_resource[i].flags & IORESOURCE_DMA) && i < PNP_MAX_DMA) i++;
+       while (!(res->dma_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_DMA) i++;
        if (i < PNP_MAX_DMA) {
                res->dma_resource[i].flags = IORESOURCE_DMA;  // Also clears _UNSET flag
                if (dma == -1) {
@@ -81,7 +81,7 @@ static void
 pnpbios_parse_allocated_ioresource(struct pnp_resource_table * res, int io, int len)
 {
        int i = 0;
-       while ((res->port_resource[i].flags & IORESOURCE_IO) && i < PNP_MAX_PORT) i++;
+       while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_PORT) i++;
        if (i < PNP_MAX_PORT) {
                res->port_resource[i].flags = IORESOURCE_IO;  // Also clears _UNSET flag
                if (len <= 0 || (io + len -1) >= 0x10003) {
@@ -97,7 +97,7 @@ static void
 pnpbios_parse_allocated_memresource(struct pnp_resource_table * res, int mem, int len)
 {
        int i = 0;
-       while ((res->mem_resource[i].flags & IORESOURCE_MEM) && i < PNP_MAX_MEM) i++;
+       while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_MEM) i++;
        if (i < PNP_MAX_MEM) {
                res->mem_resource[i].flags = IORESOURCE_MEM;  // Also clears _UNSET flag
                if (len <= 0) {
index dfe565a82ea8afec6b442d02138a44eead364acb..1c1ab31a619fe8259d090812cd2506c3a311b587 100644 (file)
@@ -241,6 +241,9 @@ void pnp_free_option(struct pnp_option *option)
  (*(enda) >= *(startb) && *(enda) <= *(endb)) || \
  (*(starta) < *(startb) && *(enda) > *(endb)))
 
+#define cannot_compare(flags) \
+((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
+
 int pnp_check_port(struct pnp_dev * dev, int idx)
 {
        int tmp;
@@ -250,7 +253,7 @@ int pnp_check_port(struct pnp_dev * dev, int idx)
        end = &dev->res.port_resource[idx].end;
 
        /* if the resource doesn't exist, don't complain about it */
-       if (dev->res.port_resource[idx].flags & IORESOURCE_UNSET)
+       if (cannot_compare(dev->res.port_resource[idx].flags))
                return 1;
 
        /* check if the resource is already in use, skip if the
@@ -284,7 +287,7 @@ int pnp_check_port(struct pnp_dev * dev, int idx)
                        continue;
                for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
                        if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) {
-                               if (pnp_port_flags(dev, tmp) & IORESOURCE_DISABLED)
+                               if (cannot_compare(tdev->res.port_resource[tmp].flags))
                                        continue;
                                tport = &tdev->res.port_resource[tmp].start;
                                tend = &tdev->res.port_resource[tmp].end;
@@ -306,7 +309,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx)
        end = &dev->res.mem_resource[idx].end;
 
        /* if the resource doesn't exist, don't complain about it */
-       if (dev->res.mem_resource[idx].flags & IORESOURCE_UNSET)
+       if (cannot_compare(dev->res.mem_resource[idx].flags))
                return 1;
 
        /* check if the resource is already in use, skip if the
@@ -340,7 +343,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx)
                        continue;
                for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
                        if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
-                               if (pnp_mem_flags(dev, tmp) & IORESOURCE_DISABLED)
+                               if (cannot_compare(tdev->res.mem_resource[tmp].flags))
                                        continue;
                                taddr = &tdev->res.mem_resource[tmp].start;
                                tend = &tdev->res.mem_resource[tmp].end;
@@ -365,7 +368,7 @@ int pnp_check_irq(struct pnp_dev * dev, int idx)
        unsigned long * irq = &dev->res.irq_resource[idx].start;
 
        /* if the resource doesn't exist, don't complain about it */
-       if (dev->res.irq_resource[idx].flags & IORESOURCE_UNSET)
+       if (cannot_compare(dev->res.irq_resource[idx].flags))
                return 1;
 
        /* check if the resource is valid */
@@ -411,7 +414,7 @@ int pnp_check_irq(struct pnp_dev * dev, int idx)
                        continue;
                for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
                        if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
-                               if (pnp_irq_flags(dev, tmp) & IORESOURCE_DISABLED)
+                               if (cannot_compare(tdev->res.irq_resource[tmp].flags))
                                        continue;
                                if ((tdev->res.irq_resource[tmp].start == *irq))
                                        return 0;
@@ -429,7 +432,7 @@ int pnp_check_dma(struct pnp_dev * dev, int idx)
        unsigned long * dma = &dev->res.dma_resource[idx].start;
 
        /* if the resource doesn't exist, don't complain about it */
-       if (dev->res.dma_resource[idx].flags & IORESOURCE_UNSET)
+       if (cannot_compare(dev->res.dma_resource[idx].flags))
                return 1;
 
        /* check if the resource is valid */
@@ -464,7 +467,7 @@ int pnp_check_dma(struct pnp_dev * dev, int idx)
                        continue;
                for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
                        if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
-                               if (pnp_dma_flags(dev, tmp) & IORESOURCE_DISABLED)
+                               if (cannot_compare(tdev->res.dma_resource[tmp].flags))
                                        continue;
                                if ((tdev->res.dma_resource[tmp].start == *dma))
                                        return 0;
index 1dcef561a2809ea60df73a060d004836792238cc..5aa6df8e1a5a83e3bf9f0354e6f8961c1c296d61 100644 (file)
@@ -33,7 +33,9 @@ struct pnp_dev;
 #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)
+#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)) ==          \
@@ -45,7 +47,9 @@ struct pnp_dev;
 #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)
+#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)) ==           \
@@ -56,11 +60,15 @@ struct pnp_dev;
 
 #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)
+#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)
+#define pnp_dma_valid(dev,bar) \
+       ((pnp_dma_flags((dev),(bar)) & (IORESOURCE_DMA | IORESOURCE_UNSET)) \
+               == IORESOURCE_DMA)
 
 #define PNP_PORT_FLAG_16BITADDR        (1<<0)
 #define PNP_PORT_FLAG_FIXED    (1<<1)