[PATCH] PnP Bug Fixes (12/13)

From: Adam Belay (ambx1@neo.rr.com)
Date: Mon Feb 17 2003 - 13:25:37 EST


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/



This archive was generated by hypermail 2b29 : Sun Feb 23 2003 - 22:00:20 EST