Messages in this thread Patch in this message |  | | Date | Mon, 17 Feb 2003 18:25:37 +0000 | From | Adam Belay <> | Subject | [PATCH] PnP Bug Fixes (12/13) |
| |
This patch contains numerous bugfixes discovered by myself and Shawn Starr.
Please apply,
Adam
diff -urN a/drivers/pnp/driver.c b/drivers/pnp/driver.c --- a/drivers/pnp/driver.c Sat Feb 15 22:53:38 2003 +++ b/drivers/pnp/driver.c Sun Feb 16 20:29:08 2003 @@ -107,9 +107,6 @@ if (error < 0) return error; } - } else { - if ((pnp_drv->flags & PNP_DRIVER_DO_NOT_ACTIVATE)) - pnp_disable_dev(pnp_dev); } error = 0; if (pnp_drv->probe && pnp_dev->active) { diff -urN a/drivers/pnp/interface.c b/drivers/pnp/interface.c --- a/drivers/pnp/interface.c Sat Feb 15 23:26:41 2003 +++ b/drivers/pnp/interface.c Sun Feb 16 20:29:08 2003 @@ -229,6 +229,13 @@ 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) { if (!conflict) @@ -236,31 +243,31 @@ pnp_printf(buffer, " Conflict Detected: %2x - ", conflict); switch (conflict) { case CONFLICT_TYPE_RESERVED: - pnp_printf(buffer, "This resource was manually reserved.\n"); + pnp_printf(buffer, "manually reserved.\n"); break; case CONFLICT_TYPE_IN_USE: - pnp_printf(buffer, "This resource resource is currently in use.\n"); + pnp_printf(buffer, "currently in use.\n"); break; case CONFLICT_TYPE_PCI: - pnp_printf(buffer, "This resource conflicts with a PCI device.\n"); + pnp_printf(buffer, "PCI device.\n"); break; case CONFLICT_TYPE_INVALID: - pnp_printf(buffer, "This resource is invalid.\n"); + pnp_printf(buffer, "invalid.\n"); break; 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; case CONFLICT_TYPE_PNP_WARM: - pnp_printf(buffer, "This resource conflicts with the active PnP device "); + pnp_printf(buffer, "active PnP device "); break; 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; default: pnp_printf(buffer, "Unknown conflict.\n"); @@ -268,16 +275,9 @@ } } -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) { - struct pnp_dev * cdev, * wdev; + struct pnp_dev * cdev, * wdev = NULL; int conflict; switch (type) { case IORESOURCE_IO: @@ -310,6 +310,8 @@ pnp_print_conflict_desc(buffer, conflict); + if (wdev) + pnp_print_conflict_node(buffer, wdev); if (cdev) { pnp_print_conflict_desc(buffer, CONFLICT_TYPE_PNP_COLD); @@ -392,14 +394,41 @@ retval = pnp_activate_dev(dev); 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 (dev->active) goto done; retval = pnp_auto_config_dev(dev); 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)) { retval = pnp_resolve_conflicts(dev); + 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)) { diff -urN a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c --- a/drivers/pnp/isapnp/core.c Sat Feb 15 23:26:41 2003 +++ b/drivers/pnp/isapnp/core.c Sun Feb 16 20:29:09 2003 @@ -765,7 +765,7 @@ /* * Parse resource map for ISA PnP card. */ - + static void __init isapnp_parse_resource_map(struct pnp_card *card) { unsigned char type, tmp[17]; @@ -822,7 +822,7 @@ { int i, j; unsigned char checksum = 0x6a, bit, b; - + for (i = 0; i < 8; i++) { b = data[i]; for (j = 0; j < 8; j++) { @@ -900,7 +900,6 @@ } for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) { ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp); - pnp_info("dma %d", tmp); if (ret == 4) continue; if (rule.dma[tmp]) { /* some isapnp systems forget to set this to 4 so we have to check */ @@ -1174,7 +1173,7 @@ return 0; } -subsys_initcall(isapnp_init); +device_initcall(isapnp_init); /* format is: noisapnp */ diff -urN a/drivers/pnp/manager.c b/drivers/pnp/manager.c --- a/drivers/pnp/manager.c Sat Feb 15 23:26:41 2003 +++ b/drivers/pnp/manager.c Sun Feb 16 20:29:09 2003 @@ -1,7 +1,7 @@ /* * 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 @@ static int pnp_next_port(struct pnp_dev * dev, int idx) { struct pnp_port *port; - unsigned long *value1, *value2, *value3; + unsigned long *start, *end, *flags; if (!dev || idx < 0 || idx >= PNP_MAX_PORT) return 0; port = dev->rule->port[idx]; if (!port) return 1; - value1 = &dev->res.port_resource[idx].start; - value2 = &dev->res.port_resource[idx].end; - value3 = &dev->res.port_resource[idx].flags; + start = &dev->res.port_resource[idx].start; + end = &dev->res.port_resource[idx].end; + flags = &dev->res.port_resource[idx].flags; /* set the initial values if this is the first time */ - if (*value1 == 0) { - *value1 = port->min; - *value2 = *value1 + port->size -1; - *value3 = port->flags | IORESOURCE_IO; + if (*start == 0) { + *start = port->min; + *end = *start + port->size - 1; + *flags = port->flags | IORESOURCE_IO; if (!pnp_check_port(dev, idx)) return 1; } /* run through until pnp_check_port is happy */ do { - *value1 += port->align; - *value2 = *value1 + port->size - 1; - if (*value1 > port->max || !port->align) + *start += port->align; + *end = *start + port->size - 1; + if (*start > port->max || !port->align) return 0; } while (pnp_check_port(dev, idx)); return 1; @@ -60,39 +60,39 @@ static int pnp_next_mem(struct pnp_dev * dev, int idx) { struct pnp_mem *mem; - unsigned long *value1, *value2, *value3; + unsigned long *start, *end, *flags; if (!dev || idx < 0 || idx >= PNP_MAX_MEM) return 0; mem = dev->rule->mem[idx]; if (!mem) return 1; - value1 = &dev->res.mem_resource[idx].start; - value2 = &dev->res.mem_resource[idx].end; - value3 = &dev->res.mem_resource[idx].flags; + start = &dev->res.mem_resource[idx].start; + end = &dev->res.mem_resource[idx].end; + flags = &dev->res.mem_resource[idx].flags; /* set the initial values if this is the first time */ - if (*value1 == 0) { - *value1 = mem->min; - *value2 = *value1 + mem->size -1; - *value3 = mem->flags | IORESOURCE_MEM; + if (*start == 0) { + *start = mem->min; + *end = *start + mem->size -1; + *flags = mem->flags | IORESOURCE_MEM; if (!(mem->flags & IORESOURCE_MEM_WRITEABLE)) - *value3 |= IORESOURCE_READONLY; + *flags |= IORESOURCE_READONLY; if (mem->flags & IORESOURCE_MEM_CACHEABLE) - *value3 |= IORESOURCE_CACHEABLE; + *flags |= IORESOURCE_CACHEABLE; if (mem->flags & IORESOURCE_MEM_RANGELENGTH) - *value3 |= IORESOURCE_RANGELENGTH; + *flags |= IORESOURCE_RANGELENGTH; if (mem->flags & IORESOURCE_MEM_SHADOWABLE) - *value3 |= IORESOURCE_SHADOWABLE; + *flags |= IORESOURCE_SHADOWABLE; if (!pnp_check_mem(dev, idx)) return 1; } /* run through until pnp_check_mem is happy */ do { - *value1 += mem->align; - *value2 = *value1 + mem->size - 1; - if (*value1 > mem->max || !mem->align) + *start += mem->align; + *end = *start + mem->size - 1; + if (*start > mem->max || !mem->align) return 0; } while (pnp_check_mem(dev, idx)); return 1; @@ -101,7 +101,7 @@ static int pnp_next_irq(struct pnp_dev * dev, int idx) { struct pnp_irq *irq; - unsigned long *value1, *value2, *value3; + unsigned long *start, *end, *flags; int i, mask; if (!dev || idx < 0 || idx >= PNP_MAX_IRQ) return 0; @@ -109,23 +109,23 @@ if (!irq) return 1; - value1 = &dev->res.irq_resource[idx].start; - value2 = &dev->res.irq_resource[idx].end; - value3 = &dev->res.irq_resource[idx].flags; + start = &dev->res.irq_resource[idx].start; + end = &dev->res.irq_resource[idx].end; + flags = &dev->res.irq_resource[idx].flags; /* set the initial values if this is the first time */ - if (*value1 == -1) { - *value1 = *value2 = 0; - *value3 = irq->flags | IORESOURCE_IRQ; + if (*start == -1) { + *start = *end = 0; + *flags = irq->flags | IORESOURCE_IRQ; if (!pnp_check_irq(dev, idx)) return 1; } mask = irq->map; - for (i = *value1 + 1; i < 16; i++) + for (i = *start + 1; i < 16; i++) { if(mask>>i & 0x01) { - *value1 = *value2 = i; + *start = *end = i; if(!pnp_check_irq(dev, idx)) return 1; } @@ -136,8 +136,7 @@ static int pnp_next_dma(struct pnp_dev * dev, int idx) { struct pnp_dma *dma; - struct resource backup; - unsigned long *value1, *value2, *value3; + unsigned long *start, *end, *flags; int i, mask; if (!dev || idx < 0 || idx >= PNP_MAX_DMA) return -EINVAL; @@ -145,46 +144,52 @@ if (!dma) return 1; - value1 = &dev->res.dma_resource[idx].start; - value2 = &dev->res.dma_resource[idx].end; - value3 = &dev->res.dma_resource[idx].flags; - *value3 = dma->flags | IORESOURCE_DMA; - backup = dev->res.dma_resource[idx]; + 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 if this is the first time */ - if (*value1 == -1) { - *value1 = *value2 = 0; - *value3 = dma->flags | IORESOURCE_DMA; + if (*start == -1) { + *start = *end = 0; + *flags = dma->flags | IORESOURCE_DMA; if (!pnp_check_dma(dev, idx)) return 1; } mask = dma->map; - for (i = *value1 + 1; i < 8; i++) + for (i = *start + 1; i < 8; i++) { if(mask>>i & 0x01) { - *value1 = *value2 = i; + *start = *end = i; if(!pnp_check_dma(dev, idx)) return 1; } } - dev->res.dma_resource[idx] = backup; return 0; } - static int pnp_next_rule(struct pnp_dev *dev) { int depnum = dev->rule->depnum; int max = pnp_get_max_depnum(dev); 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) { struct pnp_resources * res = pnp_find_resources(dev, depnum); priority = res->priority; } - for (; priority <= PNP_RES_PRIORITY_FUNCTIONAL; priority++, depnum=0) { + for (; priority <= PNP_RES_PRIORITY_FUNCTIONAL; priority++, depnum = 0) { depnum += 1; for (; depnum <= max; depnum++) { struct pnp_resources * res = pnp_find_resources(dev, depnum); @@ -251,6 +256,7 @@ if (!list_empty(&change->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_request(struct pnp_dev * dev, int move, struct pnp_change * parent, struct pnp_change * change) @@ -259,7 +265,8 @@ struct pnp_dev * cdev; 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)) return 0; } @@ -274,7 +281,8 @@ pnp_commit_changes(parent, change); } 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)) return 0; } @@ -289,7 +297,8 @@ pnp_commit_changes(parent, change); } 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)) return 0; } @@ -304,7 +313,8 @@ pnp_commit_changes(parent, change); } 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)) return 0; } @@ -323,12 +333,13 @@ 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--; + if (!dev->rule) + return 0; + change = pnp_add_change(parent,dev); if (!change) return 0; - if (!dev->rule) - goto fail; if (!pnp_can_configure(dev)) goto fail; if (!dev->rule->depnum) { @@ -431,8 +442,6 @@ spin_unlock(&pnp_lock); return 1; } - dev->rule->depnum = 0; - pnp_init_resource_table(&dev->res); if (!dev->rule) { dev->rule = pnp_alloc(sizeof(struct pnp_rule_table)); if (!dev->rule) { @@ -440,6 +449,8 @@ return -ENOMEM; } } + dev->rule->depnum = 0; + pnp_init_resource_table(&dev->res); while (pnp_next_rule(dev)) { for (i = 0; i < PNP_MAX_PORT; i++) { if (!pnp_next_port(dev,i)) diff -urN a/drivers/pnp/names.c b/drivers/pnp/names.c --- a/drivers/pnp/names.c Sat Feb 15 22:53:38 2003 +++ b/drivers/pnp/names.c Sun Feb 16 20:31:36 2003 @@ -33,7 +33,7 @@ char *name = dev->dev.name; for(i=0; i<sizeof(pnp_id_eisaid)/sizeof(pnp_id_eisaid[0]); 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; } } diff -urN a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c --- a/drivers/pnp/pnpbios/core.c Sat Feb 15 23:26:41 2003 +++ b/drivers/pnp/pnpbios/core.c Sun Feb 16 20:29:09 2003 @@ -146,9 +146,9 @@ /* * 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_eip; u32 pnp_bios_is_utter_crap = 0; diff -urN a/drivers/pnp/resource.c b/drivers/pnp/resource.c --- a/drivers/pnp/resource.c Sat Feb 15 23:26:41 2003 +++ b/drivers/pnp/resource.c Sun Feb 16 20:29:09 2003 @@ -2,7 +2,7 @@ * resource.c - Contains functions for registering and analyzing resource information * * 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 @@ struct pnp_irq * irq; struct pnp_dma * dma; - if (depnum <= 0 || !rule) + if (depnum < 0 || !rule) return -EINVAL; /* independent */ @@ -631,6 +631,8 @@ } /* dependent */ + if (depnum == 0) + return 1; res = pnp_find_resources(dev, depnum); if (!res) return -ENODEV; @@ -680,7 +682,6 @@ EXPORT_SYMBOL(pnp_add_dma_resource); EXPORT_SYMBOL(pnp_add_port_resource); EXPORT_SYMBOL(pnp_add_mem_resource); -EXPORT_SYMBOL(pnp_add_mem32_resource); EXPORT_SYMBOL(pnp_init_resource_table); EXPORT_SYMBOL(pnp_generate_rule); diff -urN a/drivers/pnp/support.c b/drivers/pnp/support.c --- a/drivers/pnp/support.c Sat Feb 15 23:26:41 2003 +++ b/drivers/pnp/support.c Sun Feb 16 20:30:49 2003 @@ -36,7 +36,7 @@ #define LARGE_TAG_ANSISTR 0x02 #define LARGE_TAG_UNICODESTR 0x03 #define LARGE_TAG_VENDOR 0x04 -#define LARGE_TAG_MEM32 0x05 +#define LARGE_TAG_MEM32 0x05 #define LARGE_TAG_FIXEDMEM32 0x06 @@ -143,6 +143,11 @@ /* ignore this for now */ break; } + case LARGE_TAG_VENDOR: + { + /* do nothing */ + break; + } case LARGE_TAG_MEM32: { int io = *(int *) &p[4]; @@ -204,6 +209,11 @@ if (len != 7) goto sm_err; current_ioresource(res, io, size); + break; + } + case SMALL_TAG_VENDOR: + { + /* do nothing */ break; } case SMALL_TAG_FIXEDPORT: diff -urN a/drivers/pnp/system.c b/drivers/pnp/system.c --- a/drivers/pnp/system.c Sat Feb 15 23:26:41 2003 +++ b/drivers/pnp/system.c Sun Feb 16 20:29:09 2003 @@ -93,6 +93,7 @@ static struct pnp_driver system_pnp_driver = { .name = "system", + .flags = PNP_DRIVER_DO_NOT_ACTIVATE, .id_table = pnp_dev_table, .probe = system_pnp_probe, .remove = NULL, - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |