patch-2.3.15 linux/drivers/pnp/isapnp.c

Next file: linux/drivers/pnp/isapnp_proc.c
Previous file: linux/drivers/pci/quirks.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.14/linux/drivers/pnp/isapnp.c linux/drivers/pnp/isapnp.c
@@ -506,7 +506,7 @@
 	if (size > 2)
 		irq->flags = tmp[2];
 	else
-		irq->flags = DEVICE_IRQ_FLAG_HIGHEDGE;
+		irq->flags = IORESOURCE_IRQ_HIGHEDGE;
 	irq->res = *res;
 	ptr = (*res)->irq;
 	while (ptr && ptr->next)
@@ -540,9 +540,7 @@
 		}
 	}
 	dma->map = tmp[0];
-	dma->type = tmp[1] & 3;
-	dma->flags = (tmp[1] >> 2) & 7;
-	dma->speed = (tmp[1] >> 6) & 3;
+	dma->flags = tmp[1];
 	dma->res = *res;
 	ptr = (*res)->dma;
 	while (ptr && ptr->next)
@@ -652,9 +650,7 @@
 	mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
 	mem->align = (tmp[6] << 8) | tmp[5];
 	mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
-	mem->flags = tmp[0] & 7;
-	mem->flags |= (tmp[0] >> 2) & 0x18;
-	mem->type = (tmp[0] >> 3) & 3;
+	mem->flags = tmp[0];
 	mem->res = *res;
 	ptr = (*res)->mem;
 	while (ptr && ptr->next)
@@ -1199,6 +1195,37 @@
 	return NULL;
 }
 
+static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma)
+{
+	return dma->flags | IORESOURCE_DMA | IORESOURCE_AUTO;
+}
+
+static unsigned int isapnp_mem_resource_flags(struct isapnp_mem *mem)
+{
+	unsigned int result;
+
+	result = mem->flags | IORESOURCE_MEM | IORESOURCE_AUTO;
+	if (!(mem->flags & IORESOURCE_MEM_WRITEABLE))
+		result |= IORESOURCE_READONLY;
+	if (mem->flags & IORESOURCE_MEM_CACHEABLE)
+		result |= IORESOURCE_CACHEABLE;
+	if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
+		result |= IORESOURCE_RANGELENGTH;
+	if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
+		result |= IORESOURCE_SHADOWABLE;
+	return result;
+}
+
+static unsigned int isapnp_irq_resource_flags(struct isapnp_irq *irq)
+{
+	return irq->flags | IORESOURCE_IRQ | IORESOURCE_AUTO;
+}
+
+static unsigned int isapnp_port_resource_flags(struct isapnp_port *port)
+{
+	return port->flags | IORESOURCE_IO | IORESOURCE_AUTO;
+}
+
 static int isapnp_config_prepare(struct pci_dev *dev)
 {
 	struct isapnp_resources *res, *resa;
@@ -1216,47 +1243,41 @@
 		return -EINVAL;
 	if (dev->active || dev->ro)
 		return -EBUSY;
-	dev->irq = dev->irq2 = DEVICE_IRQ_NOTSET;
-	dev->irq_flags = dev->irq2_flags = 0;
+	for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
+		dev->irq_resource[idx].name = NULL;
+		dev->irq_resource[idx].start = 0;
+		dev->irq_resource[idx].end = 0;
+		dev->irq_resource[idx].flags = 0;
+	}
 	for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) {
-		dev->dma[idx] = DEVICE_DMA_NOTSET;
-		dev->dma_type[idx] = DEVICE_DMA_TYPE_8AND16BIT;
-		dev->dma_flags[idx] = 0;
-		dev->dma_speed[idx] = DEVICE_DMA_SPEED_COMPATIBLE;
+		dev->dma_resource[idx].name = NULL;
+		dev->dma_resource[idx].start = 0;
+		dev->dma_resource[idx].end = 0;
+		dev->dma_resource[idx].flags = 0;
 	}
 	for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
 		dev->resource[idx].name = NULL;
-		dev->resource[idx].start = DEVICE_IO_NOTSET;
+		dev->resource[idx].start = 0;
 		dev->resource[idx].end = 0;
-		dev->resource[idx].fixed = 0;
-		dev->resource[idx].bits = 12;
-		dev->resource[idx].hw_flags = 0;
-		dev->resource[idx].type = DEVICE_IO_TYPE_8AND16BIT;
+		dev->resource[idx].flags = 0;
 	}
 	port_count = irq_count = dma_count = mem_count = 0;
 	for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
 		port_count1 = irq_count1 = dma_count1 = mem_count1 = 0;
 		for (resa = res; resa; resa = resa->alt) {
 			for (port = resa->port, idx = 0; port; port = port->next, idx++) {
-				if (dev->resource[port_count + idx].start == DEVICE_IO_NOTSET) {
-					dev->resource[port_count + idx].start = DEVICE_IO_AUTO;
+				if (dev->resource[port_count + idx].flags == 0) {
+					dev->resource[port_count + idx].flags = isapnp_port_resource_flags(port);
 					dev->resource[port_count + idx].end = port->size;
-					dev->resource[port_count + idx].bits = port->flags & ISAPNP_PORT_FLAG_16BITADDR ? 16 : 12;
-					dev->resource[port_count + idx].fixed = port->flags & ISAPNP_PORT_FLAG_FIXED ? 1 : 0;
 				}
 			}
 			if (port_count1 < idx)
 				port_count1 = idx;
 			for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) {
-				if (irq_count + idx == 0) {
-					if (dev->irq == DEVICE_IRQ_NOTSET) {
-						dev->irq = DEVICE_IRQ_AUTO;
-						dev->irq_flags = irq->flags;
-					}
-				} else if (irq_count + idx == 1) {
-					if (dev->irq2 == DEVICE_IRQ_NOTSET) {
-						dev->irq2 = DEVICE_IRQ_AUTO;
-						dev->irq2_flags = irq->flags;
+				int count = irq_count + idx;
+				if (count < DEVICE_COUNT_IRQ) {
+					if (dev->irq_resource[count].flags == 0) {
+						dev->irq_resource[count].flags = isapnp_irq_resource_flags(irq);
 					}
 				}
 				
@@ -1264,22 +1285,14 @@
 			if (irq_count1 < idx)
 				irq_count1 = idx;
 			for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++)
-				if (dev->dma[idx] == DEVICE_DMA_NOTSET) {
-					dev->dma[idx] = DEVICE_DMA_AUTO;
-					dev->dma_type[idx] = dma->type;
-					dev->dma_flags[idx] = dma->flags;
-					dev->dma_speed[idx] = dma->speed;
+				if (dev->dma_resource[idx].flags == 0) {
+					dev->dma_resource[idx].flags = isapnp_dma_resource_flags(dma);
 				}
 			if (dma_count1 < idx)
 				dma_count1 = idx;
 			for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++)
-				if (dev->resource[mem_count + idx + 8].start == DEVICE_IO_AUTO) {
-					dev->resource[mem_count + idx].start = DEVICE_IO_AUTO;
-					dev->resource[mem_count + idx].end = mem->size;
-					dev->resource[mem_count + idx].bits = 24;
-					dev->resource[mem_count + idx].fixed = 0;
-					dev->resource[mem_count + idx].hw_flags = mem->flags;
-					dev->resource[mem_count + idx].type = mem->type;
+				if (dev->resource[mem_count + idx + 8].flags == 0) {
+					dev->resource[mem_count + idx + 8].flags = isapnp_mem_resource_flags(mem);
 				}
 			if (mem_count1 < idx)
 				mem_count1 = idx;
@@ -1315,7 +1328,7 @@
 		return -EINVAL;
 	/* process port settings */
 	for (tmp = 0; tmp < 8; tmp++) {
-		if (cfg->request->resource[tmp].start != DEVICE_IO_AUTO)
+		if (!(cfg->request->resource[tmp].flags & IORESOURCE_AUTO))
 			continue;		/* don't touch */
 		port = cfg->port[tmp];
 		if (!port) {
@@ -1331,21 +1344,16 @@
 				for (tmp1 = tmp; tmp1 > 0 && port; tmp1--)
 					port = port->next;
 				cfg->port[tmp] = port;
-				cfg->result.resource[tmp].start = DEVICE_IO_AUTO;
 				if (!port)
 					return -ENOENT;
+				cfg->result.resource[tmp].flags = isapnp_port_resource_flags(port);
 			}
 		}
 	}
 	/* process irq settings */
 	for (tmp = 0; tmp < 2; tmp++) {
-		if (tmp == 0) {
-			if (cfg->request->irq != DEVICE_IRQ_AUTO)
-				continue;		/* don't touch */
-		} else {
-			if (cfg->request->irq2 != DEVICE_IRQ_AUTO)
-				continue;		/* don't touch */
-		}
+		if (!(cfg->request->irq_resource[tmp].flags & IORESOURCE_AUTO))
+			continue;		/* don't touch */
 		irq = cfg->irq[tmp];
 		if (!irq) {
 			cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp);
@@ -1360,19 +1368,15 @@
 				for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--)
 					irq = irq->next;
 				cfg->irq[tmp] = irq;
-				if (tmp == 0) {
-					cfg->result.irq = DEVICE_IRQ_AUTO;
-				} else {
-					cfg->result.irq2 = DEVICE_IRQ_AUTO;
-				}
 				if (!irq)
 					return -ENOENT;
+				cfg->result.irq_resource[tmp].flags = isapnp_irq_resource_flags(irq);
 			}
 		}
 	}
 	/* process dma settings */
 	for (tmp = 0; tmp < 2; tmp++) {
-		if (cfg->request->dma[tmp] != DEVICE_DMA_AUTO)
+		if (!(cfg->request->dma_resource[tmp].flags & IORESOURCE_AUTO))
 			continue;		/* don't touch */
 		dma = cfg->dma[tmp];
 		if (!dma) {
@@ -1388,15 +1392,15 @@
 				for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--)
 					dma = dma->next;
 				cfg->dma[tmp] = dma;
-				cfg->result.dma[tmp] = DEVICE_DMA_AUTO;
 				if (!dma)
 					return -ENOENT;
+				cfg->result.dma_resource[tmp].flags = isapnp_dma_resource_flags(dma);
 			}
 		}
 	}
 	/* process memory settings */
 	for (tmp = 0; tmp < 4; tmp++) {
-		if (cfg->request->resource[tmp + 8].start != DEVICE_IO_AUTO)
+		if (!(cfg->request->resource[tmp + 8].flags & IORESOURCE_AUTO))
 			continue;		/* don't touch */
 		mem = cfg->mem[tmp];
 		if (!mem) {
@@ -1412,9 +1416,9 @@
 				for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--)
 					mem = mem->next;
 				cfg->mem[tmp] = mem;
-				cfg->result.resource[tmp + 8].start = DEVICE_IO_AUTO;
 				if (!mem)
 					return -ENOENT;
+				cfg->result.resource[tmp + 8].flags = isapnp_mem_resource_flags(mem);
 			}
 		}
 	}
@@ -1440,7 +1444,7 @@
 	for (dev = isapnp_devices; dev; dev = dev->next) {
 		if (dev->active) {
 			for (tmp = 0; tmp < 8; tmp++) {
-				if (dev->resource[tmp].start != DEVICE_IO_NOTSET) {
+				if (dev->resource[tmp].flags) {
 					rport = dev->resource[tmp].start;
 					rsize = (dev->resource[tmp].end - rport) + 1;
 					if (port >= rport && port < rport + rsize)
@@ -1452,18 +1456,20 @@
 		}
 	}
 	for (i = 0; i < 8; i++) {
+		unsigned int flags;
 		if (i == idx)
 			continue;
-		tmp = cfg->request->resource[i].start;
-		if (tmp == DEVICE_IO_NOTSET)
+		flags = cfg->request->resource[i].flags;
+		if (!flags)
 			continue;
-		if (tmp == DEVICE_IO_AUTO) {		/* auto */
+		tmp = cfg->request->resource[i].start;
+		if (flags & IORESOURCE_AUTO) {		/* auto */
 			xport = cfg->port[i];
 			if (!xport)
 				return 1;
-			tmp = cfg->result.resource[i].start;
-			if (tmp == DEVICE_IO_AUTO)
+			if (cfg->result.resource[i].flags & IORESOURCE_AUTO)
 				continue;
+			tmp = cfg->result.resource[i].start;
 			if (tmp + xport->size >= port && tmp <= port + xport->size)
 				return 1;
 			continue;
@@ -1482,25 +1488,30 @@
 static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx)
 {
 	int err;
-	unsigned long *value;
+	unsigned long *value1, *value2;
 	struct isapnp_port *port;
 
 	if (!cfg || idx < 0 || idx > 7)
 		return -EINVAL;
-	if (cfg->result.resource[idx].start != DEVICE_IO_AUTO) /* don't touch */
+	if (!(cfg->result.resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
 		return 0;
       __again:
       	port = cfg->port[idx];
       	if (!port)
       		return -EINVAL;
-      	value = &cfg->result.resource[idx].start;
-	if (*value == DEVICE_IO_AUTO) {
-		if (!isapnp_check_port(cfg, *value = port->min, port->size, idx))
+      	value1 = &cfg->result.resource[idx].start;
+      	value2 = &cfg->result.resource[idx].end;
+	if (cfg->result.resource[idx].flags & IORESOURCE_AUTO) {
+		cfg->result.resource[idx].flags &= ~IORESOURCE_AUTO;
+		*value1 = port->min;
+		*value2 = port->min + port->size - 1;
+		if (!isapnp_check_port(cfg, *value1, port->size, idx))
 			return 0;
 	}
 	do {
-		*value += port->align;
-		if (*value > port->max || !port->align) {
+		*value1 += port->align;
+		*value2 = *value1 + port->size - 1;
+		if (*value1 > port->max || !port->align) {
 			if (port->res && port->res->alt) {
 				if ((err = isapnp_alternative_switch(cfg, port->res, port->res->alt))<0)
 					return err;
@@ -1508,7 +1519,7 @@
 			}
 			return -ENOENT;
 		}
-	} while (isapnp_check_port(cfg, *value, port->size, idx));
+	} while (isapnp_check_port(cfg, *value1, port->size, idx));
 	return 0;
 }
 
@@ -1529,65 +1540,57 @@
 	}
 	for (dev = isapnp_devices; dev; dev = dev->next) {
 		if (dev->active) {
-			if (dev->irq == irq || dev->irq2 == irq)
+			if (dev->irq_resource[0].start == irq ||
+			    dev->irq_resource[1].start == irq)
 				return 1;
 		}
 	}
 	if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL))
 		return 1;
 	free_irq(irq, NULL);
-	if (idx != 0) {
-		if (cfg->result.irq != DEVICE_IRQ_AUTO &&
-		    cfg->result.irq != DEVICE_IRQ_NOTSET)
-			if (cfg->result.irq == irq)
-				return 1;
-	}
-	if (idx != 1) {
-		if (cfg->result.irq2 != DEVICE_IRQ_AUTO &&
-		    cfg->result.irq2 != DEVICE_IRQ_NOTSET)
-			if (cfg->result.irq2 == irq)
-				return 1;
+	for (i = 0; i < DEVICE_COUNT_IRQ; i++) {
+		if (i == idx)
+			continue;
+		if (!cfg->result.irq_resource[i].flags)
+			continue;
+		if (cfg->result.irq_resource[i].flags & IORESOURCE_AUTO)
+			continue;
+		if (cfg->result.irq_resource[i].start == irq)
+			return 1;
 	}
 	return 0;
 }
 
 static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx)
 {
-	/* IRQ priority: table is good for i386 */
+	/* IRQ priority: this table is good for i386 */
 	static unsigned short xtab[16] = {
 		5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
 	};
 	int err, i;
-	unsigned int *value;
+	unsigned long *value1, *value2;
 	struct isapnp_irq *irq;
 
 	if (!cfg || idx < 0 || idx > 1)
 		return -EINVAL;
-	if (idx == 0) {
-		if (cfg->result.irq != DEVICE_IRQ_AUTO) /* don't touch */
-			return 0;
-	} else {
-		if (cfg->result.irq2 != DEVICE_IRQ_AUTO) /* don't touch */
-			return 0;
-	}
+	if (!(cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO))
+		return 0;
       __again:
       	irq = cfg->irq[idx];
       	if (!irq)
       		return -EINVAL;
-      	if (idx == 0) {
-	      	value = &cfg->result.irq;
-	} else {
-		value = &cfg->result.irq2;
-	}
-	if (*value == DEVICE_IRQ_AUTO) {
+      	value1 = &cfg->result.irq_resource[idx].start;
+      	value2 = &cfg->result.irq_resource[idx].end;
+	if (cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO) {
 		for (i = 0; i < 16 && !(irq->map & (1<<xtab[i])); i++);
 		if (i >= 16)
 			return -ENOENT;
-		if (!isapnp_check_interrupt(cfg, *value = xtab[i], idx))
+		cfg->result.irq_resource[idx].flags &= ~IORESOURCE_AUTO;
+		if (!isapnp_check_interrupt(cfg, *value1 = *value2 = xtab[i], idx))
 			return 0;
 	}
 	do {
-		for (i = 0; i < 16 && xtab[i] != *value; i++);
+		for (i = 0; i < 16 && xtab[i] != *value1; i++);
 		for (i++; i < 16 && !(irq->map & (1<<xtab[i])); i++);
 		if (i >= 16) {
 			if (irq->res && irq->res->alt) {
@@ -1597,9 +1600,9 @@
 			}
 			return -ENOENT;
 		} else {
-			*value = xtab[i];
+			*value1 = *value2 = xtab[i];
 		}
-	} while (isapnp_check_interrupt(cfg, *value, idx));
+	} while (isapnp_check_interrupt(cfg, *value1, idx));
 	return 0;
 }
 
@@ -1616,7 +1619,7 @@
 	}
 	for (dev = isapnp_devices; dev; dev = dev->next) {
 		if (dev->active) {
-			if (dev->dma[0] == dma || dev->dma[1] == dma)
+			if (dev->dma_resource[0].start == dma || dev->dma_resource[1].start == dma)
 				return 1;
 		}
 	}
@@ -1626,10 +1629,10 @@
 	for (i = 0; i < 2; i++) {
 		if (i == idx)
 			continue;
-		if (cfg->result.dma[i] == DEVICE_DMA_NOTSET ||
-		    cfg->result.dma[i] == DEVICE_DMA_AUTO)
+		if (!cfg->result.dma_resource[i].flags ||
+		    (cfg->result.dma_resource[i].flags & IORESOURCE_AUTO))
 			continue;
-		if (cfg->result.dma[i] == dma)
+		if (cfg->result.dma_resource[i].start == dma)
 			return 1;
 	}
 	return 0;
@@ -1638,27 +1641,29 @@
 static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
 {
 	int err, i;
-	unsigned char *value;
+	unsigned long *value1, *value2;
 	struct isapnp_dma *dma;
 
 	if (!cfg || idx < 0 || idx > 1)
 		return -EINVAL;
-	if (cfg->result.dma[idx] != DEVICE_DMA_AUTO)	/* don't touch */
+	if (!(cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO))	/* don't touch */
 		return 0;
       __again:
       	dma = cfg->dma[idx];
       	if (!dma)
       		return -EINVAL;
-      	value = &cfg->result.dma[idx];
-	if (*value == DEVICE_DMA_AUTO) {
+      	value1 = &cfg->result.dma_resource[idx].start;
+      	value2 = &cfg->result.dma_resource[idx].end;
+	if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
 		for (i = 0; i < 8 && !(dma->map & (1<<i)); i++);
 		if (i >= 8)
 			return -ENOENT;
-		if (!isapnp_check_dma(cfg, *value = i, idx))
+		cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;
+		if (!isapnp_check_dma(cfg, *value1 = *value2 = i, idx))
 			return 0;
 	}
 	do {
-		for (i = *value + 1; i < 8 && !(dma->map & (1<<i)); i++);
+		for (i = *value1 + 1; i < 8 && !(dma->map & (1<<i)); i++);
 		if (i >= 8) {
 			if (dma->res && dma->res->alt) {
 				if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)
@@ -1667,9 +1672,9 @@
 			}
 			return -ENOENT;
 		} else {
-			*value = i;
+			*value1 = *value2 = i;
 		}
-	} while (isapnp_check_dma(cfg, *value, idx));
+	} while (isapnp_check_dma(cfg, *value1, idx));
 	return 0;
 }
 
@@ -1693,7 +1698,7 @@
 	for (dev = isapnp_devices; dev; dev = dev->next) {
 		if (dev->active) {
 			for (tmp = 0; tmp < 4; tmp++) {
-				if (dev->resource[tmp].start != DEVICE_IO_NOTSET) {
+				if (dev->resource[tmp].flags) {
 					raddr = dev->resource[tmp + 8].start;
 					rsize = (dev->resource[tmp + 8].end - raddr) + 1;
 					if (addr >= raddr && addr < raddr + rsize)
@@ -1705,17 +1710,17 @@
 		}
 	}
 	for (i = 0; i < 4; i++) {
+		unsigned int flags = cfg->request->resource[i + 8].flags;
 		if (i == idx)
 			continue;
-		tmp = cfg->request->resource[i + 8].start;
-		if (tmp == DEVICE_IO_NOTSET)
+		if (!flags)
 			continue;
-		if (tmp == DEVICE_IO_AUTO) {		/* auto */
+		tmp = cfg->result.resource[i + 8].start;
+		if (flags & IORESOURCE_AUTO) {		/* auto */
 			xmem = cfg->mem[i];
 			if (!xmem)
 				return 1;
-			tmp = cfg->result.resource[i + 8].start;
-			if (tmp == DEVICE_IO_AUTO)
+			if (cfg->result.resource[i + 8].flags & IORESOURCE_AUTO)
 				continue;
 			if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
 				return 1;
@@ -1735,26 +1740,30 @@
 static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx)
 {
 	int err;
-	unsigned long *value;
+	unsigned long *value1, *value2;
 	struct isapnp_mem *mem;
 
 	if (!cfg || idx < 0 || idx > 3)
 		return -EINVAL;
-	if (cfg->result.resource[idx + 8].start != DEVICE_IO_AUTO) /* don't touch */
+	if (!(cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO)) /* don't touch */
 		return 0;
       __again:
       	mem = cfg->mem[idx];
       	if (!mem)
       		return -EINVAL;
-      	value = &cfg->result.resource[idx].start;
-	if (*value == DEVICE_IO_AUTO) {
-		*value = mem->min;
-		if (!isapnp_check_mem(cfg, *value, mem->size, idx))
+      	value1 = &cfg->result.resource[idx].start;
+      	value2 = &cfg->result.resource[idx].end;
+	if (cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO) {
+		cfg->result.resource[idx + 8].flags &= ~IORESOURCE_AUTO;
+		*value1 = mem->min;
+		*value2 = mem->min + mem->size - 1;
+		if (!isapnp_check_mem(cfg, *value1, mem->size, idx))
 			return 0;
 	}
 	do {
-		*value += mem->align;
-		if (*value >= 8 || !mem->align) {
+		*value1 += mem->align;
+		*value2 = *value1 + mem->size - 1;
+		if (*value1 >= 8 || !mem->align) {
 			if (mem->res && mem->res->alt) {
 				if ((err = isapnp_alternative_switch(cfg, mem->res, mem->res->alt))<0)
 					return err;
@@ -1762,7 +1771,7 @@
 			}
 			return -ENOENT;
 		}
-	} while (isapnp_check_mem(cfg, *value, mem->size, idx));
+	} while (isapnp_check_mem(cfg, *value1, mem->size, idx));
 	return 0;
 }
 
@@ -1771,17 +1780,16 @@
 	int tmp;
 	
 	for (tmp = 0; tmp < 8; tmp++)
-		if (cfg->result.resource[tmp].start == DEVICE_IO_AUTO)
+		if (cfg->result.resource[tmp].flags & IORESOURCE_AUTO)
+			return -EAGAIN;
+	for (tmp = 0; tmp < 2; tmp++)
+		if (cfg->result.irq_resource[tmp].flags & IORESOURCE_AUTO)
 			return -EAGAIN;
-	if (cfg->result.irq == DEVICE_IRQ_AUTO)
-		return -EAGAIN;
-	if (cfg->result.irq2 == DEVICE_IRQ_AUTO)
-		return -EAGAIN;
 	for (tmp = 0; tmp < 2; tmp++)
-		if (cfg->result.dma[tmp] == DEVICE_DMA_AUTO)
+		if (cfg->result.dma_resource[tmp].flags & IORESOURCE_AUTO)
 			return -EAGAIN;
 	for (tmp = 0; tmp < 4; tmp++)
-		if (cfg->result.resource[tmp + 1].start == DEVICE_IO_AUTO)
+		if (cfg->result.resource[tmp + 8].flags & IORESOURCE_AUTO)
 			return -EAGAIN;
 	return 0;
 }
@@ -1800,19 +1808,19 @@
 	memcpy(&cfg.result, dev, sizeof(struct pci_dev));
 	/* check if all values are set, otherwise try auto-configuration */
 	for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) {
-		if (dev->resource[tmp].start == DEVICE_IO_AUTO)
+		if (dev->resource[tmp].flags & IORESOURCE_AUTO)
+			fauto++;
+	}
+	for (tmp = 0; !fauto && tmp < 2; tmp++) {
+		if (dev->irq_resource[tmp].flags & IORESOURCE_AUTO)
 			fauto++;
 	}
-	if (dev->irq == DEVICE_IRQ_AUTO)
-		fauto++;
-	if (dev->irq2 == DEVICE_IRQ_AUTO)
-		fauto++;
 	for (tmp = 0; !fauto && tmp < 2; tmp++) {
-		if (dev->dma[tmp] == DEVICE_DMA_AUTO)
+		if (dev->dma_resource[tmp].flags & IORESOURCE_AUTO)
 			fauto++;
 	}
 	for (tmp = 0; !fauto && tmp < 4; tmp++) {
-		if (dev->resource[tmp + 8].start == DEVICE_IO_AUTO)
+		if (dev->resource[tmp + 8].flags & IORESOURCE_AUTO)
 			fauto++;
 	}
 	if (!fauto)
@@ -1823,19 +1831,16 @@
 	/* find first valid configuration */
 	fauto = 0;
 	do {
-		for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].start != DEVICE_IO_NOTSET; tmp++)
+		for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].flags; tmp++)
 			if ((err = isapnp_valid_port(&cfg, tmp))<0)
 				return err;
-		if (cfg.result.irq != DEVICE_IRQ_NOTSET)
-			if ((err = isapnp_valid_irq(&cfg, 0))<0)
-				return err;
-		if (cfg.result.irq2 != DEVICE_IRQ_NOTSET)
-			if ((err = isapnp_valid_irq(&cfg, 1))<0)
+		for (tmp = 0; tmp < 2 && cfg.result.irq_resource[tmp].flags; tmp++)
+			if ((err = isapnp_valid_irq(&cfg, tmp))<0)
 				return err;
-		for (tmp = 0; tmp < 2 && tmp < cfg.result.dma[tmp] != DEVICE_DMA_NOTSET; tmp++)
+		for (tmp = 0; tmp < 2 && cfg.result.dma_resource[tmp].flags; tmp++)
 			if ((err = isapnp_valid_dma(&cfg, tmp))<0)
 				return err;
-		for (tmp = 0; tmp < 4 && tmp < cfg.result.resource[tmp + 8].start != DEVICE_IO_NOTSET; tmp++)
+		for (tmp = 0; tmp < 4 && cfg.result.resource[tmp + 8].flags; tmp++)
 			if ((err = isapnp_valid_mem(&cfg, tmp))<0)
 				return err;
 	} while (isapnp_check_valid(&cfg)<0 && fauto++ < 20);
@@ -1845,31 +1850,24 @@
       	/* we have valid configuration, try configure hardware */
       	isapnp_cfg_begin(dev->bus->number, dev->devfn);
 	dev->active = 1;
-	dev->irq = cfg.result.irq;
-	dev->irq2 = cfg.result.irq2;
-	dev->dma[0] = cfg.result.dma[0];
-	dev->dma[1] = cfg.result.dma[1];
+	dev->irq_resource[0] = cfg.result.irq_resource[0];
+	dev->irq_resource[1] = cfg.result.irq_resource[1];
+	dev->dma_resource[0] = cfg.result.dma_resource[0];
+	dev->dma_resource[1] = cfg.result.dma_resource[1];
 	for (tmp = 0; tmp < 12; tmp++) {
-		dev->resource[tmp].start = cfg.result.resource[tmp].start;
-		if (cfg.result.resource[tmp].start != DEVICE_IO_NOTSET &&
-		    cfg.result.resource[tmp].end != DEVICE_IO_AUTO)
-			dev->resource[tmp].end += cfg.result.resource[tmp].start;
+		dev->resource[tmp] = cfg.result.resource[tmp];
 	}	
-	for (tmp = 0; tmp < 8 && dev->resource[tmp].start != DEVICE_IO_NOTSET; tmp++)
+	for (tmp = 0; tmp < 8 && dev->resource[tmp].flags; tmp++)
 		isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start);
-	if (dev->irq != DEVICE_IRQ_NOTSET) {
-		if (dev->irq == 2)
-			dev->irq = 9;
-		isapnp_write_byte(ISAPNP_CFG_IRQ+(0<<1), dev->irq);
-	}
-	if (dev->irq2 != DEVICE_IRQ_NOTSET) {
-		if (dev->irq2 == 2)
-			dev->irq2 = 9;
-		isapnp_write_byte(ISAPNP_CFG_IRQ+(1<<1), dev->irq2);
-	}
-	for (tmp = 0; tmp < 2 && dev->dma[tmp] != DEVICE_DMA_NOTSET; tmp++)
-		isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma[tmp]);
-	for (tmp = 0; tmp < 4 && dev->resource[tmp].start != DEVICE_IO_NOTSET; tmp++)
+	for (tmp = 0; tmp < 2 && dev->irq_resource[tmp].flags; tmp++) {
+		int irq = dev->irq_resource[tmp].start;
+		if (irq == 2)
+			irq = 9;
+		isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
+	}
+	for (tmp = 0; tmp < 2 && dev->dma_resource[tmp].flags; tmp++)
+		isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma_resource[tmp].start);
+	for (tmp = 0; tmp < 4 && dev->resource[tmp+8].flags; tmp++)
 		isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff);
 	isapnp_activate(dev->devfn);
 	isapnp_cfg_end();
@@ -1882,11 +1880,22 @@
 		return -EINVAL;
       	isapnp_cfg_begin(dev->bus->number, dev->devfn);
 	isapnp_deactivate(dev->devfn);
-	dev->activate = 0;
+	dev->active = 0;
 	isapnp_cfg_end();
 	return 0;
 }
 
+void isapnp_resource_change(struct resource *resource,
+			    unsigned long start,
+			    unsigned long size)
+{
+	if (resource == NULL)
+		return;
+	resource->flags &= ~IORESOURCE_AUTO;
+	resource->start = start;
+	resource->end = start + size - 1;
+}
+
 /*
  *  Inititialization.
  */
@@ -1971,7 +1980,7 @@
 	struct pci_dev *next;
 
 	while (dev) {
-		next = dev->next;
+		next = dev->sibling;
 		isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0);
 		kfree(dev);
 		dev = next;
@@ -2067,6 +2076,7 @@
 EXPORT_SYMBOL(isapnp_deactivate);
 EXPORT_SYMBOL(isapnp_find_card);
 EXPORT_SYMBOL(isapnp_find_dev);
+EXPORT_SYMBOL(isapnp_resource_change);
 
 int __init isapnp_init(void)
 {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)