Example #1
0
/**
 * pnp_auto_config_dev - automatically assigns resources to a device
 * @dev: pointer to the desired device
 *
 */
int pnp_auto_config_dev(struct pnp_dev *dev)
{
	struct pnp_option *dep;
	int i = 1;

	if(!dev)
		return -EINVAL;

	if(!pnp_can_configure(dev)) {
		pnp_info("Device %s does not support resource configuration.", dev->dev.bus_id);
		return -ENODEV;
	}

	if (!dev->dependent) {
		if (pnp_assign_resources(dev, 0))
			return 0;
	} else {
		dep = dev->dependent;
		do {
			if (pnp_assign_resources(dev, i))
				return 0;
			dep = dep->next;
			i++;
		} while (dep);
	}

	pnp_err("Unable to assign resources to device %s.", dev->dev.bus_id);
	return -EBUSY;
}
Example #2
0
/**
 * pnp_auto_config_dev - automatically assigns resources to a device
 * @dev: pointer to the desired device
 */
int pnp_auto_config_dev(struct pnp_dev *dev)
{
	struct pnp_option *dep;
	int i = 1;

	if (!pnp_can_configure(dev)) {
		dev_dbg(&dev->dev, "configuration not supported\n");
		return -ENODEV;
	}

	if (!dev->dependent) {
		if (pnp_assign_resources(dev, 0))
			return 0;
	} else {
		dep = dev->dependent;
		do {
			if (pnp_assign_resources(dev, i))
				return 0;
			dep = dep->next;
			i++;
		} while (dep);
	}

	dev_err(&dev->dev, "unable to assign resources\n");
	return -EBUSY;
}
Example #3
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;
}
Example #4
0
/**
 * pnp_assign_resources - assigns resources to the device based on the specified dependent number
 * @dev: pointer to the desired device
 * @depnum: the dependent function number
 *
 * Only set depnum to 0 if the device does not have dependent options.
 */
static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
{
	struct pnp_port *port;
	struct pnp_mem *mem;
	struct pnp_irq *irq;
	struct pnp_dma *dma;
	int nport = 0, nmem = 0, nirq = 0, ndma = 0;

	if (!pnp_can_configure(dev))
		return -ENODEV;

	down(&pnp_res_mutex);
	pnp_clean_resource_table(&dev->res); /* start with a fresh slate */
	if (dev->independent) {
		port = dev->independent->port;
		mem = dev->independent->mem;
		irq = dev->independent->irq;
		dma = dev->independent->dma;
		while (port) {
			if (!pnp_assign_port(dev, port, nport))
				goto fail;
			nport++;
			port = port->next;
		}
		while (mem) {
			if (!pnp_assign_mem(dev, mem, nmem))
				goto fail;
			nmem++;
			mem = mem->next;
		}
		while (irq) {
			if (!pnp_assign_irq(dev, irq, nirq))
				goto fail;
			nirq++;
			irq = irq->next;
		}
		while (dma) {
			if (!pnp_assign_dma(dev, dma, ndma))
				goto fail;
			ndma++;
			dma = dma->next;
		}
	}

	if (depnum) {
		struct pnp_option *dep;
		int i;
		for (i=1,dep=dev->dependent; i<depnum; i++, dep=dep->next)
			if(!dep)
				goto fail;
		port =dep->port;
		mem = dep->mem;
		irq = dep->irq;
		dma = dep->dma;
		while (port) {
			if (!pnp_assign_port(dev, port, nport))
				goto fail;
			nport++;
			port = port->next;
		}
		while (mem) {
			if (!pnp_assign_mem(dev, mem, nmem))
				goto fail;
			nmem++;
			mem = mem->next;
		}
		while (irq) {
			if (!pnp_assign_irq(dev, irq, nirq))
				goto fail;
			nirq++;
			irq = irq->next;
		}
		while (dma) {
			if (!pnp_assign_dma(dev, dma, ndma))
				goto fail;
			ndma++;
			dma = dma->next;
		}
	} else if (dev->dependent)
		goto fail;

	up(&pnp_res_mutex);
	return 1;

fail:
	pnp_clean_resource_table(&dev->res);
	up(&pnp_res_mutex);
	return 0;
}
Example #5
0
/**
 * pnp_assign_resources - assigns resources to the device based on the specified dependent number
 * @dev: pointer to the desired device
 * @depnum: the dependent function number
 *
 * Only set depnum to 0 if the device does not have dependent options.
 */
static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
{
    struct pnp_port *port;
    struct pnp_mem *mem;
    struct pnp_irq *irq;
    struct pnp_dma *dma;
    int nport = 0, nmem = 0, nirq = 0, ndma = 0;

    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);
    if (dev->independent) {
        dev_dbg(&dev->dev, "assigning independent options\n");
        port = dev->independent->port;
        mem = dev->independent->mem;
        irq = dev->independent->irq;
        dma = dev->independent->dma;
        while (port) {
            if (!pnp_assign_port(dev, port, nport))
                goto fail;
            nport++;
            port = port->next;
        }
        while (mem) {
            if (!pnp_assign_mem(dev, mem, nmem))
                goto fail;
            nmem++;
            mem = mem->next;
        }
        while (irq) {
            if (!pnp_assign_irq(dev, irq, nirq))
                goto fail;
            nirq++;
            irq = irq->next;
        }
        while (dma) {
            pnp_assign_dma(dev, dma, ndma);
            ndma++;
            dma = dma->next;
        }
    }

    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)
                goto fail;
        port = dep->port;
        mem = dep->mem;
        irq = dep->irq;
        dma = dep->dma;
        while (port) {
            if (!pnp_assign_port(dev, port, nport))
                goto fail;
            nport++;
            port = port->next;
        }
        while (mem) {
            if (!pnp_assign_mem(dev, mem, nmem))
                goto fail;
            nmem++;
            mem = mem->next;
        }
        while (irq) {
            if (!pnp_assign_irq(dev, irq, nirq))
                goto fail;
            nirq++;
            irq = irq->next;
        }
        while (dma) {
            pnp_assign_dma(dev, dma, ndma);
            ndma++;
            dma = dma->next;
        }
    } else if (dev->dependent)
        goto fail;

    mutex_unlock(&pnp_res_mutex);
    dbg_pnp_show_resources(dev, "after pnp_assign_resources");
    return 1;

fail:
    pnp_clean_resource_table(dev);
    mutex_unlock(&pnp_res_mutex);
    dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
    return 0;
}