static void quirk_awe32_resources(struct pnp_dev *dev)
{
	struct pnp_port *port, *port2, *port3;
	struct pnp_option *res = dev->dependent;

	/*
	 * Unfortunately the isapnp_add_port_resource is too tightly bound
	 * into the PnP discovery sequence, and cannot be used. Link in the
	 * two extra ports (at offset 0x400 and 0x800 from the one given) by
	 * hand.
	 */
	for ( ; res ; res = res->next ) {
		port2 = pnp_alloc(sizeof(struct pnp_port));
		if (!port2)
			return;
		port3 = pnp_alloc(sizeof(struct pnp_port));
		if (!port3) {
			kfree(port2);
			return;
		}
		port = res->port;
		memcpy(port2, port, sizeof(struct pnp_port));
		memcpy(port3, port, sizeof(struct pnp_port));
		port->next = port2;
		port2->next = port3;
		port2->min += 0x400;
		port2->max += 0x400;
		port3->min += 0x800;
		port3->max += 0x800;
	}
	printk(KERN_INFO "pnp: AWE32 quirk - adding two ports\n");
}
Esempio n. 2
0
static ssize_t pnp_show_options(struct device *dmdev, struct device_attribute *attr, char *buf)
{
	struct pnp_dev *dev = to_pnp_dev(dmdev);
	struct pnp_option * independent = dev->independent;
	struct pnp_option * dependent = dev->dependent;
	int ret, dep = 1;

	pnp_info_buffer_t *buffer = (pnp_info_buffer_t *)
				 pnp_alloc(sizeof(pnp_info_buffer_t));
	if (!buffer)
		return -ENOMEM;

	buffer->len = PAGE_SIZE;
	buffer->buffer = buf;
	buffer->curr = buffer->buffer;
	if (independent)
		pnp_print_option(buffer, "", independent, 0);

	while (dependent){
		pnp_print_option(buffer, "   ", dependent, dep);
		dependent = dependent->next;
		dep++;
	}
	ret = (buffer->curr - buf);
	kfree(buffer);
	return ret;
}
Esempio n. 3
0
static struct pnp_option * pnp_build_option(int priority)
{
	struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option));

	/* check if pnp_alloc ran out of memory */
	if (!option)
		return NULL;

	option->priority = priority & 0xff;
	/* make sure the priority is valid */
	if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
		option->priority = PNP_RES_PRIORITY_INVALID;

	return option;
}
Esempio n. 4
0
File: quirks.c Progetto: 274914765/C
static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev)
{
    struct pnp_option *head = NULL;
    struct pnp_option *prev = NULL;
    struct pnp_option *res;

    /*
     * Build a functional IRQ-less variant of each MPU option.
     */

    for (res = dev->dependent; res; res = res->next) {
        struct pnp_option *curr;
        struct pnp_port *port;
        struct pnp_port *copy;

        port = res->port;
        if (!port || !res->irq)
            continue;

        copy = pnp_alloc(sizeof *copy);
        if (!copy)
            break;

        copy->min = port->min;
        copy->max = port->max;
        copy->align = port->align;
        copy->size = port->size;
        copy->flags = port->flags;

        curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL);
        if (!curr) {
            kfree(copy);
            break;
        }
        curr->port = copy;

        if (prev)
            prev->next = curr;
        else
            head = curr;
        prev = curr;
    }
    if (head)
        dev_info(&dev->dev, "adding IRQ-less MPU options\n");

    return head;
}
Esempio n. 5
0
File: quirks.c Progetto: 274914765/C
static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
{
    struct pnp_option *res;
    struct pnp_irq *irq;

    /*
     * Distribute the independent IRQ over the dependent options
     */

    res = dev->independent;
    if (!res)
        return;

    irq = res->irq;
    if (!irq || irq->next)
        return;

    res = dev->dependent;
    if (!res)
        return;

    while (1) {
        struct pnp_irq *copy;

        copy = pnp_alloc(sizeof *copy);
        if (!copy)
            break;

        memcpy(copy->map, irq->map, sizeof copy->map);
        copy->flags = irq->flags;

        copy->next = res->irq; /* Yes, this is NULL */
        res->irq = copy;

        if (!res->next)
            break;
        res = res->next;
    }
    kfree(irq);

    res->next = quirk_isapnp_mpu_options(dev);

    res = dev->independent;
    res->irq = NULL;
}
Esempio n. 6
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;
}
Esempio n. 7
0
static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_attribute *attr, char *buf)
{
	struct pnp_dev *dev = to_pnp_dev(dmdev);
	int i, ret;
	pnp_info_buffer_t *buffer;

	if (!dev)
		return -EINVAL;

	buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t));
	if (!buffer)
		return -ENOMEM;
	buffer->len = PAGE_SIZE;
	buffer->buffer = buf;
	buffer->curr = buffer->buffer;

	pnp_printf(buffer,"state = ");
	if (dev->active)
		pnp_printf(buffer,"active\n");
	else
		pnp_printf(buffer,"disabled\n");

	for (i = 0; i < PNP_MAX_PORT; i++) {
		if (pnp_port_valid(dev, i)) {
			pnp_printf(buffer,"io");
			if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED)
				pnp_printf(buffer," disabled\n");
			else
				pnp_printf(buffer," 0x%llx-0x%llx\n",
					(unsigned long long)pnp_port_start(dev, i),
					(unsigned long long)pnp_port_end(dev, i));
		}
	}
	for (i = 0; i < PNP_MAX_MEM; i++) {
		if (pnp_mem_valid(dev, i)) {
			pnp_printf(buffer,"mem");
			if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED)
				pnp_printf(buffer," disabled\n");
			else
				pnp_printf(buffer," 0x%llx-0x%llx\n",
					(unsigned long long)pnp_mem_start(dev, i),
					(unsigned long long)pnp_mem_end(dev, i));
		}
	}
	for (i = 0; i < PNP_MAX_IRQ; i++) {
		if (pnp_irq_valid(dev, i)) {
			pnp_printf(buffer,"irq");
			if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED)
				pnp_printf(buffer," disabled\n");
			else
				pnp_printf(buffer," %lld\n",
					(unsigned long long)pnp_irq(dev, i));
		}
	}
	for (i = 0; i < PNP_MAX_DMA; i++) {
		if (pnp_dma_valid(dev, i)) {
			pnp_printf(buffer,"dma");
			if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED)
				pnp_printf(buffer," disabled\n");
			else
				pnp_printf(buffer," %lld\n",
					(unsigned long long)pnp_dma(dev, i));
		}
	}
	ret = (buffer->curr - buf);
	kfree(buffer);
	return ret;
}