static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) { struct pnp_resource *pnp_res; struct resource *res; int i; /* DMA priority: this table is good for i386 */ static unsigned short xtab[8] = { 1, 3, 5, 6, 7, 0, 2, 4 }; pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx); if (!pnp_res) { dev_err(&dev->dev, "too many DMA resources\n"); return; } res = &pnp_res->res; /* check if this resource has been manually set, if so skip */ if (!(res->flags & IORESOURCE_AUTO)) { dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", idx, (int) res->start, res->flags); return; } /* set the initial values */ 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])) { res->start = res->end = xtab[i]; if (pnp_check_dma(dev, res)) { dev_dbg(&dev->dev, " assign dma %d %d\n", idx, (int) res->start); return; } } } #ifdef MAX_DMA_CHANNELS res->start = res->end = MAX_DMA_CHANNELS; #endif res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; dev_dbg(&dev->dev, " disable dma %d\n", idx); }
static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) { unsigned long *start, *end, *flags; int i; /* DMA priority: this table is good for i386 */ static unsigned short xtab[8] = { 1, 3, 5, 6, 7, 0, 2, 4 }; if (!dev || !rule) return -EINVAL; if (idx >= PNP_MAX_DMA) { pnp_err("More than 2 dmas is incompatible with pnp specifications."); /* pretend we were successful so at least the manager won't try again */ return 1; } /* check if this resource has been manually set, if so skip */ if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) return 1; start = &dev->res.dma_resource[idx].start; end = &dev->res.dma_resource[idx].end; flags = &dev->res.dma_resource[idx].flags; /* set the initial values */ *flags |= rule->flags | IORESOURCE_DMA; *flags &= ~IORESOURCE_UNSET; if (!rule->map) { *flags |= IORESOURCE_DISABLED; return 1; /* skip disabled resource requests */ } for (i = 0; i < 8; i++) { if(rule->map & (1<<xtab[i])) { *start = *end = xtab[i]; if(pnp_check_dma(dev, idx)) return 1; } } return 0; }
/** * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table * @dev: pointer to the desired device * @res: pointer to the new resource config * @mode: 0 or PNP_CONFIG_FORCE * * This function can be used by drivers that want to manually set thier resources. */ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res, int mode) { int i; struct pnp_resource_table * bak; if (!dev || !res) return -EINVAL; if (!pnp_can_configure(dev)) return -ENODEV; bak = pnp_alloc(sizeof(struct pnp_resource_table)); if (!bak) return -ENOMEM; *bak = dev->res; down(&pnp_res_mutex); dev->res = *res; if (!(mode & PNP_CONFIG_FORCE)) { for (i = 0; i < PNP_MAX_PORT; i++) { if(!pnp_check_port(dev,i)) goto fail; } for (i = 0; i < PNP_MAX_MEM; i++) { if(!pnp_check_mem(dev,i)) goto fail; } for (i = 0; i < PNP_MAX_IRQ; i++) { if(!pnp_check_irq(dev,i)) goto fail; } for (i = 0; i < PNP_MAX_DMA; i++) { if(!pnp_check_dma(dev,i)) goto fail; } } up(&pnp_res_mutex); kfree(bak); return 0; fail: dev->res = *bak; up(&pnp_res_mutex); kfree(bak); return -EINVAL; }
static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) { resource_size_t *start, *end; unsigned long *flags; int i; /* DMA priority: this table is good for i386 */ static unsigned short xtab[8] = { 1, 3, 5, 6, 7, 0, 2, 4 }; if (idx >= PNP_MAX_DMA) { dev_err(&dev->dev, "too many DMA resources\n"); 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; /* set the initial values */ *flags |= rule->flags | IORESOURCE_DMA; *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)) return; } } #ifdef MAX_DMA_CHANNELS *start = *end = MAX_DMA_CHANNELS; #endif *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; }