X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fpnp%2Fmanager.c;h=bea0914ff947a337dcf45d2a58bf7b6fc0f38644;hb=97bff0953dd45a633fa69e1a650d612f5610a60b;hp=d407c07b5b9d372031bee70a3ce6d351d1d06387;hpb=2cd1393098073426256cb4543c897f8c340d0b93;p=linux-2.6 diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index d407c07b5b..bea0914ff9 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -19,118 +19,118 @@ DEFINE_MUTEX(pnp_res_mutex); static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) { - resource_size_t *start, *end; - unsigned long *flags; + struct pnp_resource *pnp_res; + struct resource *res; - if (idx >= PNP_MAX_PORT) { + 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; } - start = &dev->res.port_resource[idx].start; - end = &dev->res.port_resource[idx].end; - flags = &dev->res.port_resource[idx].flags; + res = &pnp_res->res; /* 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; + pnp_res->index = idx; + 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) { + while (!pnp_check_port(dev, res)) { + 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 pnp_resource *pnp_res; + struct resource *res; - if (idx >= PNP_MAX_MEM) { + 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; } - start = &dev->res.mem_resource[idx].start; - end = &dev->res.mem_resource[idx].end; - flags = &dev->res.mem_resource[idx].flags; + res = &pnp_res->res; /* 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; + pnp_res->index = idx; + 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) { + while (!pnp_check_mem(dev, res)) { + 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 pnp_resource *pnp_res; + struct resource *res; int i; /* IRQ priority: this table is good for i386 */ @@ -138,46 +138,47 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 }; - if (idx >= PNP_MAX_IRQ) { + 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; } - start = &dev->res.irq_resource[idx].start; - end = &dev->res.irq_resource[idx].end; - flags = &dev->res.irq_resource[idx].flags; + res = &pnp_res->res; /* 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; + pnp_res->index = idx; + 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]; - if (pnp_check_irq(dev, idx)) { + res->start = res->end = xtab[i]; + if (pnp_check_irq(dev, res)) { dev_dbg(&dev->dev, " assign irq %d %d\n", idx, - (int) *start); + (int) res->start); return 1; } } @@ -188,8 +189,8 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) { - resource_size_t *start, *end; - unsigned long *flags; + struct pnp_resource *pnp_res; + struct resource *res; int i; /* DMA priority: this table is good for i386 */ @@ -197,79 +198,89 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 1, 3, 5, 6, 7, 0, 2, 4 }; - if (idx >= PNP_MAX_DMA) { + pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx); + if (!pnp_res) { dev_err(&dev->dev, "too many DMA resources\n"); return; } - start = &dev->res.dma_resource[idx].start; - end = &dev->res.dma_resource[idx].end; - flags = &dev->res.dma_resource[idx].flags; + res = &pnp_res->res; /* 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; + pnp_res->index = idx; + 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]; - if (pnp_check_dma(dev, idx)) { + res->start = res->end = xtab[i]; + if (pnp_check_dma(dev, res)) { 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); } +void pnp_init_resource(struct resource *res) +{ + unsigned long type; + + type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM | + IORESOURCE_IRQ | IORESOURCE_DMA); + + res->name = NULL; + res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET; + if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) { + res->start = -1; + res->end = -1; + } else { + res->start = 0; + res->end = 0; + } +} + /** * pnp_init_resources - Resets a resource table to default values. * @table: pointer to the desired resource table */ void pnp_init_resources(struct pnp_dev *dev) { - struct pnp_resource_table *table = &dev->res; + struct resource *res; int idx; for (idx = 0; idx < PNP_MAX_IRQ; idx++) { - table->irq_resource[idx].name = NULL; - table->irq_resource[idx].start = -1; - table->irq_resource[idx].end = -1; - table->irq_resource[idx].flags = - IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET; + res = &dev->res->irq[idx].res; + res->flags = IORESOURCE_IRQ; + pnp_init_resource(res); } 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_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET; + res = &dev->res->dma[idx].res; + res->flags = IORESOURCE_DMA; + pnp_init_resource(res); } 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_IO | IORESOURCE_AUTO | IORESOURCE_UNSET; + res = &dev->res->port[idx].res; + res->flags = IORESOURCE_IO; + pnp_init_resource(res); } 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_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET; + res = &dev->res->mem[idx].res; + res->flags = IORESOURCE_MEM; + pnp_init_resource(res); } } @@ -279,40 +290,36 @@ void pnp_init_resources(struct pnp_dev *dev) */ static void pnp_clean_resource_table(struct pnp_dev *dev) { - struct pnp_resource_table *res = &dev->res; + struct resource *res; int idx; for (idx = 0; idx < PNP_MAX_IRQ; idx++) { - if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO)) - continue; - res->irq_resource[idx].start = -1; - res->irq_resource[idx].end = -1; - res->irq_resource[idx].flags = - IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET; + 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++) { - 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_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET; + 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++) { - 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_IO | IORESOURCE_AUTO | IORESOURCE_UNSET; + 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++) { - 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_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET; + res = &dev->res->mem[idx].res; + if (res->flags & IORESOURCE_AUTO) { + res->flags = IORESOURCE_MEM; + pnp_init_resource(res); + } } }