From: Bjorn Helgaas Date: Mon, 28 Apr 2008 22:34:08 +0000 (-0600) Subject: PNP: add debug when assigning PNP resources X-Git-Tag: v2.6.26-rc1~101^2^2~34 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=81b5c75f0ed22a93c3da00650d0898eec56e1d62;p=linux-2.6 PNP: add debug when assigning PNP resources This 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. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index a83cdcfee1..0c5cb1d58c 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -16,3 +16,5 @@ 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); + +void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 6a1f0b0b24..945c620171 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -28,20 +28,25 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) return 1; } - /* check if this resource has been manually set, if so skip */ - if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO)) - return 1; - start = &dev->res.port_resource[idx].start; end = &dev->res.port_resource[idx].end; flags = &dev->res.port_resource[idx].flags; + /* check if this resource has been manually set, if so skip */ + if (!(dev->res.port_resource[idx].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); + return 1; + } + /* set the initial values */ *flags |= rule->flags | IORESOURCE_IO; *flags &= ~IORESOURCE_UNSET; if (!rule->size) { *flags |= IORESOURCE_DISABLED; + dev_dbg(&dev->dev, " io %d disabled\n", idx); return 1; /* skip disabled resource requests */ } @@ -52,9 +57,13 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) while (!pnp_check_port(dev, idx)) { *start += rule->align; *end = *start + rule->size - 1; - if (*start > rule->max || !rule->align) + if (*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); return 1; } @@ -69,14 +78,18 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) return 1; } - /* check if this resource has been manually set, if so skip */ - if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO)) - return 1; - start = &dev->res.mem_resource[idx].start; end = &dev->res.mem_resource[idx].end; flags = &dev->res.mem_resource[idx].flags; + /* check if this resource has been manually set, if so skip */ + if (!(dev->res.mem_resource[idx].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); + return 1; + } + /* set the initial values */ *flags |= rule->flags | IORESOURCE_MEM; *flags &= ~IORESOURCE_UNSET; @@ -93,6 +106,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) if (!rule->size) { *flags |= IORESOURCE_DISABLED; + dev_dbg(&dev->dev, " mem %d disabled\n", idx); return 1; /* skip disabled resource requests */ } @@ -103,9 +117,13 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) while (!pnp_check_mem(dev, idx)) { *start += rule->align; *end = *start + rule->size - 1; - if (*start > rule->max || !rule->align) + if (*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); return 1; } @@ -126,20 +144,24 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) return 1; } - /* check if this resource has been manually set, if so skip */ - if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO)) - return 1; - start = &dev->res.irq_resource[idx].start; end = &dev->res.irq_resource[idx].end; flags = &dev->res.irq_resource[idx].flags; + /* check if this resource has been manually set, if so skip */ + if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO)) { + dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", + idx, (int) *start, *flags); + return 1; + } + /* set the initial values */ *flags |= rule->flags | IORESOURCE_IRQ; *flags &= ~IORESOURCE_UNSET; if (bitmap_empty(rule->map, PNP_IRQ_NR)) { *flags |= IORESOURCE_DISABLED; + dev_dbg(&dev->dev, " irq %d disabled\n", idx); return 1; /* skip disabled resource requests */ } @@ -147,15 +169,20 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) *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); return 1; } for (i = 0; i < 16; i++) { if (test_bit(xtab[i], rule->map)) { *start = *end = xtab[i]; - if (pnp_check_irq(dev, idx)) + if (pnp_check_irq(dev, idx)) { + dev_dbg(&dev->dev, " assign irq %d %d\n", idx, + (int) *start); return 1; + } } } + dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); return 0; } @@ -175,14 +202,17 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) return; } - /* check if this resource has been manually set, if so skip */ - if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) - return; - start = &dev->res.dma_resource[idx].start; end = &dev->res.dma_resource[idx].end; flags = &dev->res.dma_resource[idx].flags; + /* check if this resource has been manually set, if so skip */ + if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) { + dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", + idx, (int) *start, *flags); + return; + } + /* set the initial values */ *flags |= rule->flags | IORESOURCE_DMA; *flags &= ~IORESOURCE_UNSET; @@ -190,14 +220,18 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) for (i = 0; i < 8; i++) { if (rule->map & (1 << xtab[i])) { *start = *end = xtab[i]; - if (pnp_check_dma(dev, idx)) + if (pnp_check_dma(dev, idx)) { + dev_dbg(&dev->dev, " assign dma %d %d\n", idx, + (int) *start); return; + } } } #ifdef MAX_DMA_CHANNELS *start = *end = MAX_DMA_CHANNELS; #endif *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; + dev_dbg(&dev->dev, " disable dma %d\n", idx); } /** @@ -298,9 +332,11 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) if (!pnp_can_configure(dev)) return -ENODEV; + 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 */ if (dev->independent) { + dev_dbg(&dev->dev, "assigning independent options\n"); port = dev->independent->port; mem = dev->independent->mem; irq = dev->independent->irq; @@ -333,6 +369,8 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) if (depnum) { struct pnp_option *dep; int i; + + dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum); for (i = 1, dep = dev->dependent; i < depnum; i++, dep = dep->next) if (!dep) @@ -368,11 +406,13 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) goto fail; mutex_unlock(&pnp_res_mutex); + dbg_pnp_show_resources(dev, "after pnp_assign_resources"); return 1; fail: pnp_clean_resource_table(&dev->res); mutex_unlock(&pnp_res_mutex); + dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)"); return 0; } @@ -473,6 +513,7 @@ int pnp_start_dev(struct pnp_dev *dev) return -EINVAL; } + dbg_pnp_show_resources(dev, "pnp_start_dev"); if (dev->protocol->set(dev) < 0) { dev_err(&dev->dev, "activation failed\n"); return -EIO; diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index e848b794e3..3aeb154e27 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c @@ -51,3 +51,40 @@ void pnp_eisa_id_to_string(u32 id, char *str) 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 +}