Commit bb9d6284 authored by Adam Belay's avatar Adam Belay

PnP Bug Fixes

parent 18876b41
...@@ -107,9 +107,6 @@ static int pnp_device_probe(struct device *dev) ...@@ -107,9 +107,6 @@ static int pnp_device_probe(struct device *dev)
if (error < 0) if (error < 0)
return error; return error;
} }
} else {
if ((pnp_drv->flags & PNP_DRIVER_DO_NOT_ACTIVATE))
pnp_disable_dev(pnp_dev);
} }
error = 0; error = 0;
if (pnp_drv->probe && pnp_dev->active) { if (pnp_drv->probe && pnp_dev->active) {
......
...@@ -229,6 +229,13 @@ static ssize_t pnp_show_possible_resources(struct device *dmdev, char *buf) ...@@ -229,6 +229,13 @@ static ssize_t pnp_show_possible_resources(struct device *dmdev, char *buf)
static DEVICE_ATTR(possible,S_IRUGO,pnp_show_possible_resources,NULL); static DEVICE_ATTR(possible,S_IRUGO,pnp_show_possible_resources,NULL);
static void pnp_print_conflict_node(pnp_info_buffer_t *buffer, struct pnp_dev * dev)
{
if (!dev)
return;
pnp_printf(buffer, "'%s'.\n", dev->dev.bus_id);
}
static void pnp_print_conflict_desc(pnp_info_buffer_t *buffer, int conflict) static void pnp_print_conflict_desc(pnp_info_buffer_t *buffer, int conflict)
{ {
if (!conflict) if (!conflict)
...@@ -236,31 +243,31 @@ static void pnp_print_conflict_desc(pnp_info_buffer_t *buffer, int conflict) ...@@ -236,31 +243,31 @@ static void pnp_print_conflict_desc(pnp_info_buffer_t *buffer, int conflict)
pnp_printf(buffer, " Conflict Detected: %2x - ", conflict); pnp_printf(buffer, " Conflict Detected: %2x - ", conflict);
switch (conflict) { switch (conflict) {
case CONFLICT_TYPE_RESERVED: case CONFLICT_TYPE_RESERVED:
pnp_printf(buffer, "This resource was manually reserved.\n"); pnp_printf(buffer, "manually reserved.\n");
break; break;
case CONFLICT_TYPE_IN_USE: case CONFLICT_TYPE_IN_USE:
pnp_printf(buffer, "This resource resource is currently in use.\n"); pnp_printf(buffer, "currently in use.\n");
break; break;
case CONFLICT_TYPE_PCI: case CONFLICT_TYPE_PCI:
pnp_printf(buffer, "This resource conflicts with a PCI device.\n"); pnp_printf(buffer, "PCI device.\n");
break; break;
case CONFLICT_TYPE_INVALID: case CONFLICT_TYPE_INVALID:
pnp_printf(buffer, "This resource is invalid.\n"); pnp_printf(buffer, "invalid.\n");
break; break;
case CONFLICT_TYPE_INTERNAL: case CONFLICT_TYPE_INTERNAL:
pnp_printf(buffer, "This resource conflicts with another resource on this device.\n"); pnp_printf(buffer, "another resource on this device.\n");
break; break;
case CONFLICT_TYPE_PNP_WARM: case CONFLICT_TYPE_PNP_WARM:
pnp_printf(buffer, "This resource conflicts with the active PnP device "); pnp_printf(buffer, "active PnP device ");
break; break;
case CONFLICT_TYPE_PNP_COLD: case CONFLICT_TYPE_PNP_COLD:
pnp_printf(buffer, "This resource conflicts with the resources that PnP plans to assign to the device "); pnp_printf(buffer, "disabled PnP device ");
break; break;
default: default:
pnp_printf(buffer, "Unknown conflict.\n"); pnp_printf(buffer, "Unknown conflict.\n");
...@@ -268,16 +275,9 @@ static void pnp_print_conflict_desc(pnp_info_buffer_t *buffer, int conflict) ...@@ -268,16 +275,9 @@ static void pnp_print_conflict_desc(pnp_info_buffer_t *buffer, int conflict)
} }
} }
static void pnp_print_conflict_node(pnp_info_buffer_t *buffer, struct pnp_dev * dev)
{
if (!dev)
return;
pnp_printf(buffer, "%s.\n", dev->dev.bus_id);
}
static void pnp_print_conflict(pnp_info_buffer_t *buffer, struct pnp_dev * dev, int idx, int type) static void pnp_print_conflict(pnp_info_buffer_t *buffer, struct pnp_dev * dev, int idx, int type)
{ {
struct pnp_dev * cdev, * wdev; struct pnp_dev * cdev, * wdev = NULL;
int conflict; int conflict;
switch (type) { switch (type) {
case IORESOURCE_IO: case IORESOURCE_IO:
...@@ -310,6 +310,8 @@ static void pnp_print_conflict(pnp_info_buffer_t *buffer, struct pnp_dev * dev, ...@@ -310,6 +310,8 @@ static void pnp_print_conflict(pnp_info_buffer_t *buffer, struct pnp_dev * dev,
pnp_print_conflict_desc(buffer, conflict); pnp_print_conflict_desc(buffer, conflict);
if (wdev)
pnp_print_conflict_node(buffer, wdev);
if (cdev) { if (cdev) {
pnp_print_conflict_desc(buffer, CONFLICT_TYPE_PNP_COLD); pnp_print_conflict_desc(buffer, CONFLICT_TYPE_PNP_COLD);
...@@ -392,16 +394,43 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count ...@@ -392,16 +394,43 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
retval = pnp_activate_dev(dev); retval = pnp_activate_dev(dev);
goto done; goto done;
} }
if (!strnicmp(buf,"reset",5)) {
if (!dev->active)
goto done;
retval = pnp_disable_dev(dev);
if (retval)
goto done;
retval = pnp_activate_dev(dev);
goto done;
}
if (!strnicmp(buf,"auto-config",11)) { if (!strnicmp(buf,"auto-config",11)) {
if (dev->active) if (dev->active)
goto done; goto done;
retval = pnp_auto_config_dev(dev); retval = pnp_auto_config_dev(dev);
goto done; goto done;
} }
if (!strnicmp(buf,"clear-config",12)) {
if (dev->active)
goto done;
spin_lock(&pnp_lock);
dev->config_mode = PNP_CONFIG_MANUAL;
pnp_init_resource_table(&dev->res);
if (dev->rule)
dev->rule->depnum = 0;
spin_unlock(&pnp_lock);
goto done;
}
if (!strnicmp(buf,"resolve",7)) { if (!strnicmp(buf,"resolve",7)) {
retval = pnp_resolve_conflicts(dev); retval = pnp_resolve_conflicts(dev);
goto done; goto done;
} }
if (!strnicmp(buf,"get",3)) {
spin_lock(&pnp_lock);
if (pnp_can_read(dev))
dev->protocol->get(dev, &dev->res);
spin_unlock(&pnp_lock);
goto done;
}
if (!strnicmp(buf,"set",3)) { if (!strnicmp(buf,"set",3)) {
if (dev->active) if (dev->active)
goto done; goto done;
......
...@@ -765,7 +765,7 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -765,7 +765,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
/* /*
* Parse resource map for ISA PnP card. * Parse resource map for ISA PnP card.
*/ */
static void __init isapnp_parse_resource_map(struct pnp_card *card) static void __init isapnp_parse_resource_map(struct pnp_card *card)
{ {
unsigned char type, tmp[17]; unsigned char type, tmp[17];
...@@ -822,7 +822,7 @@ static unsigned char __init isapnp_checksum(unsigned char *data) ...@@ -822,7 +822,7 @@ static unsigned char __init isapnp_checksum(unsigned char *data)
{ {
int i, j; int i, j;
unsigned char checksum = 0x6a, bit, b; unsigned char checksum = 0x6a, bit, b;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
b = data[i]; b = data[i];
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
...@@ -900,7 +900,6 @@ static int isapnp_parse_current_resources(struct pnp_dev *dev, struct pnp_resour ...@@ -900,7 +900,6 @@ static int isapnp_parse_current_resources(struct pnp_dev *dev, struct pnp_resour
} }
for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) { for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp); ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
pnp_info("dma %d", tmp);
if (ret == 4) if (ret == 4)
continue; continue;
if (rule.dma[tmp]) { /* some isapnp systems forget to set this to 4 so we have to check */ if (rule.dma[tmp]) { /* some isapnp systems forget to set this to 4 so we have to check */
...@@ -1174,7 +1173,7 @@ int __init isapnp_init(void) ...@@ -1174,7 +1173,7 @@ int __init isapnp_init(void)
return 0; return 0;
} }
subsys_initcall(isapnp_init); device_initcall(isapnp_init);
/* format is: noisapnp */ /* format is: noisapnp */
......
/* /*
* manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices * manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
* *
* Copyright 2002 Adam Belay <ambx1@neo.rr.com> * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
* *
*/ */
...@@ -27,31 +27,31 @@ int pnp_max_moves = 4; ...@@ -27,31 +27,31 @@ int pnp_max_moves = 4;
static int pnp_next_port(struct pnp_dev * dev, int idx) static int pnp_next_port(struct pnp_dev * dev, int idx)
{ {
struct pnp_port *port; struct pnp_port *port;
unsigned long *value1, *value2, *value3; unsigned long *start, *end, *flags;
if (!dev || idx < 0 || idx >= PNP_MAX_PORT) if (!dev || idx < 0 || idx >= PNP_MAX_PORT)
return 0; return 0;
port = dev->rule->port[idx]; port = dev->rule->port[idx];
if (!port) if (!port)
return 1; return 1;
value1 = &dev->res.port_resource[idx].start; start = &dev->res.port_resource[idx].start;
value2 = &dev->res.port_resource[idx].end; end = &dev->res.port_resource[idx].end;
value3 = &dev->res.port_resource[idx].flags; flags = &dev->res.port_resource[idx].flags;
/* set the initial values if this is the first time */ /* set the initial values if this is the first time */
if (*value1 == 0) { if (*start == 0) {
*value1 = port->min; *start = port->min;
*value2 = *value1 + port->size -1; *end = *start + port->size - 1;
*value3 = port->flags | IORESOURCE_IO; *flags = port->flags | IORESOURCE_IO;
if (!pnp_check_port(dev, idx)) if (!pnp_check_port(dev, idx))
return 1; return 1;
} }
/* run through until pnp_check_port is happy */ /* run through until pnp_check_port is happy */
do { do {
*value1 += port->align; *start += port->align;
*value2 = *value1 + port->size - 1; *end = *start + port->size - 1;
if (*value1 > port->max || !port->align) if (*start > port->max || !port->align)
return 0; return 0;
} while (pnp_check_port(dev, idx)); } while (pnp_check_port(dev, idx));
return 1; return 1;
...@@ -60,39 +60,39 @@ static int pnp_next_port(struct pnp_dev * dev, int idx) ...@@ -60,39 +60,39 @@ static int pnp_next_port(struct pnp_dev * dev, int idx)
static int pnp_next_mem(struct pnp_dev * dev, int idx) static int pnp_next_mem(struct pnp_dev * dev, int idx)
{ {
struct pnp_mem *mem; struct pnp_mem *mem;
unsigned long *value1, *value2, *value3; unsigned long *start, *end, *flags;
if (!dev || idx < 0 || idx >= PNP_MAX_MEM) if (!dev || idx < 0 || idx >= PNP_MAX_MEM)
return 0; return 0;
mem = dev->rule->mem[idx]; mem = dev->rule->mem[idx];
if (!mem) if (!mem)
return 1; return 1;
value1 = &dev->res.mem_resource[idx].start; start = &dev->res.mem_resource[idx].start;
value2 = &dev->res.mem_resource[idx].end; end = &dev->res.mem_resource[idx].end;
value3 = &dev->res.mem_resource[idx].flags; flags = &dev->res.mem_resource[idx].flags;
/* set the initial values if this is the first time */ /* set the initial values if this is the first time */
if (*value1 == 0) { if (*start == 0) {
*value1 = mem->min; *start = mem->min;
*value2 = *value1 + mem->size -1; *end = *start + mem->size -1;
*value3 = mem->flags | IORESOURCE_MEM; *flags = mem->flags | IORESOURCE_MEM;
if (!(mem->flags & IORESOURCE_MEM_WRITEABLE)) if (!(mem->flags & IORESOURCE_MEM_WRITEABLE))
*value3 |= IORESOURCE_READONLY; *flags |= IORESOURCE_READONLY;
if (mem->flags & IORESOURCE_MEM_CACHEABLE) if (mem->flags & IORESOURCE_MEM_CACHEABLE)
*value3 |= IORESOURCE_CACHEABLE; *flags |= IORESOURCE_CACHEABLE;
if (mem->flags & IORESOURCE_MEM_RANGELENGTH) if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
*value3 |= IORESOURCE_RANGELENGTH; *flags |= IORESOURCE_RANGELENGTH;
if (mem->flags & IORESOURCE_MEM_SHADOWABLE) if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
*value3 |= IORESOURCE_SHADOWABLE; *flags |= IORESOURCE_SHADOWABLE;
if (!pnp_check_mem(dev, idx)) if (!pnp_check_mem(dev, idx))
return 1; return 1;
} }
/* run through until pnp_check_mem is happy */ /* run through until pnp_check_mem is happy */
do { do {
*value1 += mem->align; *start += mem->align;
*value2 = *value1 + mem->size - 1; *end = *start + mem->size - 1;
if (*value1 > mem->max || !mem->align) if (*start > mem->max || !mem->align)
return 0; return 0;
} while (pnp_check_mem(dev, idx)); } while (pnp_check_mem(dev, idx));
return 1; return 1;
...@@ -101,7 +101,7 @@ static int pnp_next_mem(struct pnp_dev * dev, int idx) ...@@ -101,7 +101,7 @@ static int pnp_next_mem(struct pnp_dev * dev, int idx)
static int pnp_next_irq(struct pnp_dev * dev, int idx) static int pnp_next_irq(struct pnp_dev * dev, int idx)
{ {
struct pnp_irq *irq; struct pnp_irq *irq;
unsigned long *value1, *value2, *value3; unsigned long *start, *end, *flags;
int i, mask; int i, mask;
if (!dev || idx < 0 || idx >= PNP_MAX_IRQ) if (!dev || idx < 0 || idx >= PNP_MAX_IRQ)
return 0; return 0;
...@@ -109,23 +109,23 @@ static int pnp_next_irq(struct pnp_dev * dev, int idx) ...@@ -109,23 +109,23 @@ static int pnp_next_irq(struct pnp_dev * dev, int idx)
if (!irq) if (!irq)
return 1; return 1;
value1 = &dev->res.irq_resource[idx].start; start = &dev->res.irq_resource[idx].start;
value2 = &dev->res.irq_resource[idx].end; end = &dev->res.irq_resource[idx].end;
value3 = &dev->res.irq_resource[idx].flags; flags = &dev->res.irq_resource[idx].flags;
/* set the initial values if this is the first time */ /* set the initial values if this is the first time */
if (*value1 == -1) { if (*start == -1) {
*value1 = *value2 = 0; *start = *end = 0;
*value3 = irq->flags | IORESOURCE_IRQ; *flags = irq->flags | IORESOURCE_IRQ;
if (!pnp_check_irq(dev, idx)) if (!pnp_check_irq(dev, idx))
return 1; return 1;
} }
mask = irq->map; mask = irq->map;
for (i = *value1 + 1; i < 16; i++) for (i = *start + 1; i < 16; i++)
{ {
if(mask>>i & 0x01) { if(mask>>i & 0x01) {
*value1 = *value2 = i; *start = *end = i;
if(!pnp_check_irq(dev, idx)) if(!pnp_check_irq(dev, idx))
return 1; return 1;
} }
...@@ -136,8 +136,7 @@ static int pnp_next_irq(struct pnp_dev * dev, int idx) ...@@ -136,8 +136,7 @@ static int pnp_next_irq(struct pnp_dev * dev, int idx)
static int pnp_next_dma(struct pnp_dev * dev, int idx) static int pnp_next_dma(struct pnp_dev * dev, int idx)
{ {
struct pnp_dma *dma; struct pnp_dma *dma;
struct resource backup; unsigned long *start, *end, *flags;
unsigned long *value1, *value2, *value3;
int i, mask; int i, mask;
if (!dev || idx < 0 || idx >= PNP_MAX_DMA) if (!dev || idx < 0 || idx >= PNP_MAX_DMA)
return -EINVAL; return -EINVAL;
...@@ -145,46 +144,52 @@ static int pnp_next_dma(struct pnp_dev * dev, int idx) ...@@ -145,46 +144,52 @@ static int pnp_next_dma(struct pnp_dev * dev, int idx)
if (!dma) if (!dma)
return 1; return 1;
value1 = &dev->res.dma_resource[idx].start; start = &dev->res.dma_resource[idx].start;
value2 = &dev->res.dma_resource[idx].end; end = &dev->res.dma_resource[idx].end;
value3 = &dev->res.dma_resource[idx].flags; flags = &dev->res.dma_resource[idx].flags;
*value3 = dma->flags | IORESOURCE_DMA;
backup = dev->res.dma_resource[idx];
/* set the initial values if this is the first time */ /* set the initial values if this is the first time */
if (*value1 == -1) { if (*start == -1) {
*value1 = *value2 = 0; *start = *end = 0;
*value3 = dma->flags | IORESOURCE_DMA; *flags = dma->flags | IORESOURCE_DMA;
if (!pnp_check_dma(dev, idx)) if (!pnp_check_dma(dev, idx))
return 1; return 1;
} }
mask = dma->map; mask = dma->map;
for (i = *value1 + 1; i < 8; i++) for (i = *start + 1; i < 8; i++)
{ {
if(mask>>i & 0x01) { if(mask>>i & 0x01) {
*value1 = *value2 = i; *start = *end = i;
if(!pnp_check_dma(dev, idx)) if(!pnp_check_dma(dev, idx))
return 1; return 1;
} }
} }
dev->res.dma_resource[idx] = backup;
return 0; return 0;
} }
static int pnp_next_rule(struct pnp_dev *dev) static int pnp_next_rule(struct pnp_dev *dev)
{ {
int depnum = dev->rule->depnum; int depnum = dev->rule->depnum;
int max = pnp_get_max_depnum(dev); int max = pnp_get_max_depnum(dev);
int priority = PNP_RES_PRIORITY_PREFERRED; int priority = PNP_RES_PRIORITY_PREFERRED;
if (depnum < 0)
return 0;
if (max == 0) {
if (pnp_generate_rule(dev, 0, dev->rule)) {
dev->rule->depnum = -1;
return 1;
}
}
if(depnum > 0) { if(depnum > 0) {
struct pnp_resources * res = pnp_find_resources(dev, depnum); struct pnp_resources * res = pnp_find_resources(dev, depnum);
priority = res->priority; priority = res->priority;
} }
for (; priority <= PNP_RES_PRIORITY_FUNCTIONAL; priority++, depnum=0) { for (; priority <= PNP_RES_PRIORITY_FUNCTIONAL; priority++, depnum = 0) {
depnum += 1; depnum += 1;
for (; depnum <= max; depnum++) { for (; depnum <= max; depnum++) {
struct pnp_resources * res = pnp_find_resources(dev, depnum); struct pnp_resources * res = pnp_find_resources(dev, depnum);
...@@ -251,6 +256,7 @@ static void pnp_commit_changes(struct pnp_change * parent, struct pnp_change * c ...@@ -251,6 +256,7 @@ static void pnp_commit_changes(struct pnp_change * parent, struct pnp_change * c
if (!list_empty(&change->changes)) if (!list_empty(&change->changes))
list_splice_init(&change->changes, &parent->changes); list_splice_init(&change->changes, &parent->changes);
} }
static int pnp_next_config(struct pnp_dev * dev, int move, struct pnp_change * parent); static int pnp_next_config(struct pnp_dev * dev, int move, struct pnp_change * parent);
static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * parent, struct pnp_change * change) static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * parent, struct pnp_change * change)
...@@ -259,7 +265,8 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * ...@@ -259,7 +265,8 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change *
struct pnp_dev * cdev; struct pnp_dev * cdev;
for (i = 0; i < PNP_MAX_PORT; i++) { for (i = 0; i < PNP_MAX_PORT; i++) {
if (dev->res.port_resource[i].start == 0 || pnp_check_port_conflicts(dev,i,SEARCH_WARM)) { if (dev->res.port_resource[i].start == 0
|| pnp_check_port_conflicts(dev,i,SEARCH_WARM)) {
if (!pnp_next_port(dev,i)) if (!pnp_next_port(dev,i))
return 0; return 0;
} }
...@@ -274,7 +281,8 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * ...@@ -274,7 +281,8 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change *
pnp_commit_changes(parent, change); pnp_commit_changes(parent, change);
} }
for (i = 0; i < PNP_MAX_MEM; i++) { for (i = 0; i < PNP_MAX_MEM; i++) {
if (dev->res.mem_resource[i].start == 0 || pnp_check_mem_conflicts(dev,i,SEARCH_WARM)) { if (dev->res.mem_resource[i].start == 0
|| pnp_check_mem_conflicts(dev,i,SEARCH_WARM)) {
if (!pnp_next_mem(dev,i)) if (!pnp_next_mem(dev,i))
return 0; return 0;
} }
...@@ -289,7 +297,8 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * ...@@ -289,7 +297,8 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change *
pnp_commit_changes(parent, change); pnp_commit_changes(parent, change);
} }
for (i = 0; i < PNP_MAX_IRQ; i++) { for (i = 0; i < PNP_MAX_IRQ; i++) {
if (dev->res.irq_resource[i].start == -1 || pnp_check_irq_conflicts(dev,i,SEARCH_WARM)) { if (dev->res.irq_resource[i].start == -1
|| pnp_check_irq_conflicts(dev,i,SEARCH_WARM)) {
if (!pnp_next_irq(dev,i)) if (!pnp_next_irq(dev,i))
return 0; return 0;
} }
...@@ -304,7 +313,8 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * ...@@ -304,7 +313,8 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change *
pnp_commit_changes(parent, change); pnp_commit_changes(parent, change);
} }
for (i = 0; i < PNP_MAX_DMA; i++) { for (i = 0; i < PNP_MAX_DMA; i++) {
if (dev->res.dma_resource[i].start == -1 || pnp_check_dma_conflicts(dev,i,SEARCH_WARM)) { if (dev->res.dma_resource[i].start == -1
|| pnp_check_dma_conflicts(dev,i,SEARCH_WARM)) {
if (!pnp_next_dma(dev,i)) if (!pnp_next_dma(dev,i))
return 0; return 0;
} }
...@@ -323,12 +333,13 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * ...@@ -323,12 +333,13 @@ static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change *
static int pnp_next_config(struct pnp_dev * dev, int move, struct pnp_change * parent) static int pnp_next_config(struct pnp_dev * dev, int move, struct pnp_change * parent)
{ {
struct pnp_change * change = pnp_add_change(parent,dev); struct pnp_change * change;
move--; move--;
if (!dev->rule)
return 0;
change = pnp_add_change(parent,dev);
if (!change) if (!change)
return 0; return 0;
if (!dev->rule)
goto fail;
if (!pnp_can_configure(dev)) if (!pnp_can_configure(dev))
goto fail; goto fail;
if (!dev->rule->depnum) { if (!dev->rule->depnum) {
...@@ -431,8 +442,6 @@ static int pnp_simple_config(struct pnp_dev * dev) ...@@ -431,8 +442,6 @@ static int pnp_simple_config(struct pnp_dev * dev)
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
return 1; return 1;
} }
dev->rule->depnum = 0;
pnp_init_resource_table(&dev->res);
if (!dev->rule) { if (!dev->rule) {
dev->rule = pnp_alloc(sizeof(struct pnp_rule_table)); dev->rule = pnp_alloc(sizeof(struct pnp_rule_table));
if (!dev->rule) { if (!dev->rule) {
...@@ -440,6 +449,8 @@ static int pnp_simple_config(struct pnp_dev * dev) ...@@ -440,6 +449,8 @@ static int pnp_simple_config(struct pnp_dev * dev)
return -ENOMEM; return -ENOMEM;
} }
} }
dev->rule->depnum = 0;
pnp_init_resource_table(&dev->res);
while (pnp_next_rule(dev)) { while (pnp_next_rule(dev)) {
for (i = 0; i < PNP_MAX_PORT; i++) { for (i = 0; i < PNP_MAX_PORT; i++) {
if (!pnp_next_port(dev,i)) if (!pnp_next_port(dev,i))
......
...@@ -33,7 +33,7 @@ pnp_name_device(struct pnp_dev *dev) ...@@ -33,7 +33,7 @@ pnp_name_device(struct pnp_dev *dev)
char *name = dev->dev.name; char *name = dev->dev.name;
for(i=0; i<sizeof(pnp_id_eisaid)/sizeof(pnp_id_eisaid[0]); i++){ for(i=0; i<sizeof(pnp_id_eisaid)/sizeof(pnp_id_eisaid[0]); i++){
if (compare_pnp_id(dev->id,pnp_id_eisaid[i])){ if (compare_pnp_id(dev->id,pnp_id_eisaid[i])){
sprintf(name, "%s", pnp_id_names[i]); snprintf(name, DEVICE_NAME_SIZE, "%s", pnp_id_names[i]);
return; return;
} }
} }
......
...@@ -146,9 +146,9 @@ static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; ...@@ -146,9 +146,9 @@ static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
/* /*
* At some point we want to use this stack frame pointer to unwind * At some point we want to use this stack frame pointer to unwind
* after PnP BIOS oopses. * after PnP BIOS oopses.
*/ */
u32 pnp_bios_fault_esp; u32 pnp_bios_fault_esp;
u32 pnp_bios_fault_eip; u32 pnp_bios_fault_eip;
u32 pnp_bios_is_utter_crap = 0; u32 pnp_bios_is_utter_crap = 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* resource.c - Contains functions for registering and analyzing resource information * resource.c - Contains functions for registering and analyzing resource information
* *
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz> * based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz>
* Copyright 2002 Adam Belay <ambx1@neo.rr.com> * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
* *
*/ */
...@@ -598,7 +598,7 @@ int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table * ...@@ -598,7 +598,7 @@ int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table *
struct pnp_irq * irq; struct pnp_irq * irq;
struct pnp_dma * dma; struct pnp_dma * dma;
if (depnum <= 0 || !rule) if (depnum < 0 || !rule)
return -EINVAL; return -EINVAL;
/* independent */ /* independent */
...@@ -631,6 +631,8 @@ int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table * ...@@ -631,6 +631,8 @@ int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table *
} }
/* dependent */ /* dependent */
if (depnum == 0)
return 1;
res = pnp_find_resources(dev, depnum); res = pnp_find_resources(dev, depnum);
if (!res) if (!res)
return -ENODEV; return -ENODEV;
...@@ -680,7 +682,6 @@ EXPORT_SYMBOL(pnp_add_irq_resource); ...@@ -680,7 +682,6 @@ EXPORT_SYMBOL(pnp_add_irq_resource);
EXPORT_SYMBOL(pnp_add_dma_resource); EXPORT_SYMBOL(pnp_add_dma_resource);
EXPORT_SYMBOL(pnp_add_port_resource); EXPORT_SYMBOL(pnp_add_port_resource);
EXPORT_SYMBOL(pnp_add_mem_resource); EXPORT_SYMBOL(pnp_add_mem_resource);
EXPORT_SYMBOL(pnp_add_mem32_resource);
EXPORT_SYMBOL(pnp_init_resource_table); EXPORT_SYMBOL(pnp_init_resource_table);
EXPORT_SYMBOL(pnp_generate_rule); EXPORT_SYMBOL(pnp_generate_rule);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define LARGE_TAG_ANSISTR 0x02 #define LARGE_TAG_ANSISTR 0x02
#define LARGE_TAG_UNICODESTR 0x03 #define LARGE_TAG_UNICODESTR 0x03
#define LARGE_TAG_VENDOR 0x04 #define LARGE_TAG_VENDOR 0x04
#define LARGE_TAG_MEM32 0x05 #define LARGE_TAG_MEM32 0x05
#define LARGE_TAG_FIXEDMEM32 0x06 #define LARGE_TAG_FIXEDMEM32 0x06
...@@ -143,6 +143,11 @@ unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * e ...@@ -143,6 +143,11 @@ unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * e
/* ignore this for now */ /* ignore this for now */
break; break;
} }
case LARGE_TAG_VENDOR:
{
/* do nothing */
break;
}
case LARGE_TAG_MEM32: case LARGE_TAG_MEM32:
{ {
int io = *(int *) &p[4]; int io = *(int *) &p[4];
...@@ -206,6 +211,11 @@ unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * e ...@@ -206,6 +211,11 @@ unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * e
current_ioresource(res, io, size); current_ioresource(res, io, size);
break; break;
} }
case SMALL_TAG_VENDOR:
{
/* do nothing */
break;
}
case SMALL_TAG_FIXEDPORT: case SMALL_TAG_FIXEDPORT:
{ {
int io = p[1] + p[2] * 256; int io = p[1] + p[2] * 256;
......
...@@ -93,6 +93,7 @@ static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *de ...@@ -93,6 +93,7 @@ static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *de
static struct pnp_driver system_pnp_driver = { static struct pnp_driver system_pnp_driver = {
.name = "system", .name = "system",
.flags = PNP_DRIVER_DO_NOT_ACTIVATE,
.id_table = pnp_dev_table, .id_table = pnp_dev_table,
.probe = system_pnp_probe, .probe = system_pnp_probe,
.remove = NULL, .remove = NULL,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment