All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adam Belay <ambx1@neo.rr.com>
To: greg@kroah.com
Cc: linux-kernel@vger.kernel.org,
	Linus Torvalds <torvalds@transmeta.com>,
	Jaroslav Kysela <perex@suse.cz>
Subject: [PATCH] pnp - ISAPnP Updates (5/13)
Date: Mon, 17 Feb 2003 18:23:20 +0000	[thread overview]
Message-ID: <20030217182319.GA31435@neo.rr.com> (raw)

This patch contains many isapnp improvements including true get resource support
which is necessary to get active configs on boot and to ensure a resource set 
was accepted.  It also adds some initial MEM32 support, more work in that area
will come in the near future.

Please apply,
Adam


--- linux-2.5.58/drivers/pnp/isapnp/core.c	Tue Jan 14 05:58:55 2003
+++ a/drivers/pnp/isapnp/core.c	Sun Feb  9 10:42:49 2003
@@ -101,7 +101,6 @@
 
 /* some prototypes */
 
-static int isapnp_config_prepare(struct pnp_dev *dev);
 extern struct pnp_protocol isapnp_protocol;
 
 static inline void write_data(unsigned char x)
@@ -260,7 +259,7 @@
 		 *	We cannot use NE2000 probe spaces for ISAPnP or we
 		 *	will lock up machines.
 		 */
-		if ((rdp < 0x280 || rdp >  0x380) && !check_region(rdp, 1)) 
+		if ((rdp < 0x280 || rdp >  0x380) && !check_region(rdp, 1))
 		{
 			isapnp_rdp = rdp;
 			return 0;
@@ -580,14 +579,18 @@
 						 int depnum, int size)
 {
 	unsigned char tmp[17];
-	struct pnp_mem32 *mem32;
+	struct pnp_mem *mem;
 
 	isapnp_peek(tmp, size);
-	mem32 = isapnp_alloc(sizeof(struct pnp_mem32));
-	if (!mem32)
+	mem = isapnp_alloc(sizeof(struct pnp_mem));
+	if (!mem)
 		return;
-	memcpy(mem32->data, tmp, 17);
-	pnp_add_mem32_resource(dev,depnum,mem32);
+	mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
+	mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
+	mem->align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
+	mem->size = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
+	mem->flags = tmp[0];
+	pnp_add_mem_resource(dev,depnum,mem);
 }
 
 /*
@@ -597,15 +600,18 @@
 static void __init isapnp_add_fixed_mem32_resource(struct pnp_dev *dev,
 						       int depnum, int size)
 {
-	unsigned char tmp[17];
-	struct pnp_mem32 *mem32;
+	unsigned char tmp[9];
+	struct pnp_mem *mem;
 
 	isapnp_peek(tmp, size);
-	mem32 = isapnp_alloc(sizeof(struct pnp_mem32));
-	if (!mem32)
+	mem = isapnp_alloc(sizeof(struct pnp_mem));
+	if (!mem)
 		return;
-	memcpy(mem32->data, tmp, 17);
-	pnp_add_mem32_resource(dev,depnum,mem32);
+	mem->min = mem->max = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
+	mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
+	mem->align = 0;
+	mem->flags = tmp[0];
+	pnp_add_mem_resource(dev,depnum,mem);
 }
 
 /*
@@ -650,7 +656,6 @@
 		switch (type) {
 		case _STAG_LOGDEVID:
 			if (size >= 5 && size <= 6) {
-				isapnp_config_prepare(dev);
 				if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
 					return 1;
 				pnp_build_resource(dev,0);
@@ -723,7 +728,7 @@
 			size = 0;
 			break;
 		case _LTAG_ANSISTR:
-			isapnp_parse_name(dev->name, sizeof(dev->name), &size);
+			isapnp_parse_name(dev->dev.name, sizeof(dev->dev.name), &size);
 			break;
 		case _LTAG_UNICODESTR:
 			/* silently ignore */
@@ -738,7 +743,7 @@
 			size = 0;
 			break;
 		case _LTAG_FIXEDMEM32RANGE:
-			if (size != 17)
+			if (size != 9)
 				goto __skip;
 			isapnp_add_fixed_mem32_resource(dev, depnum, size);
 			size = 0;
@@ -746,7 +751,6 @@
 		case _STAG_END:
 			if (size > 0)
 				isapnp_skip_bytes(size);
-			isapnp_config_prepare(dev);
 			return 1;
 		default:
 			printk(KERN_ERR "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type, dev->number, card->number);
@@ -755,7 +759,6 @@
 	      	if (size > 0)
 		      	isapnp_skip_bytes(size);
 	}
-	isapnp_config_prepare(dev);
 	return 0;
 }
 
@@ -790,7 +793,7 @@
 		case _STAG_VENDOR:
 			break;
 		case _LTAG_ANSISTR:
-			isapnp_parse_name(card->name, sizeof(card->name), &size);
+			isapnp_parse_name(card->dev.name, sizeof(card->dev.name), &size);
 			break;
 		case _LTAG_UNICODESTR:
 			/* silently ignore */
@@ -852,6 +855,64 @@
 	pnpc_add_id(id,card);
 }
 
+
+static int isapnp_parse_current_resources(struct pnp_dev *dev, struct pnp_resource_table * res)
+{
+	int tmp, ret;
+	struct pnp_rule_table rule;
+	if (dev->rule)
+		rule = *dev->rule;
+	else {
+		if (!pnp_generate_rule(dev,1,&rule))
+			return -EINVAL;
+	}
+
+	dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
+	if (dev->active) {
+		for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
+			ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
+			if (!ret)
+				continue;
+			res->port_resource[tmp].start = ret;
+			if (rule.port[tmp])
+				res->port_resource[tmp].end = ret + rule.port[tmp]->size - 1;
+			else
+				res->port_resource[tmp].end = ret + 1; /* all we can do is assume 1 :-( */
+			res->port_resource[tmp].flags = IORESOURCE_IO;
+		}
+		for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
+			ret = isapnp_read_dword(ISAPNP_CFG_MEM + (tmp << 3));
+			if (!ret)
+				continue;
+			res->mem_resource[tmp].start = ret;
+			if (rule.mem[tmp])
+				res->mem_resource[tmp].end = ret + rule.mem[tmp]->size - 1;
+			else
+				res->mem_resource[tmp].end = ret + 1; /* all we can do is assume 1 :-( */
+			res->mem_resource[tmp].flags = IORESOURCE_MEM;
+		}
+		for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
+			ret = (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> 8);
+			if (!ret)
+				continue;
+			res->irq_resource[tmp].start = res->irq_resource[tmp].end = ret;
+			res->irq_resource[tmp].flags = IORESOURCE_IRQ;
+		}
+		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 */
+				res->dma_resource[tmp].start = res->dma_resource[tmp].end = ret;
+				res->dma_resource[tmp].flags = IORESOURCE_DMA;
+			}
+		}
+	}
+	return 0;
+}
+
+
 /*
  *  Build device list for all present ISA PnP devices.
  */
@@ -861,6 +922,7 @@
 	int csn;
 	unsigned char header[9], checksum;
 	struct pnp_card *card;
+	struct pnp_dev *dev;
 
 	isapnp_wait();
 	isapnp_key();
@@ -893,8 +955,17 @@
 			printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);
 		card->checksum = isapnp_checksum_value;
 		card->protocol = &isapnp_protocol;
+
+		/* read the current resource data */
+		card_for_each_dev(card,dev) {
+			isapnp_device(dev->number);
+		pnp_init_resource_table(&dev->res);
+			isapnp_parse_current_resources(dev, &dev->res);
+		}
+
 		pnpc_add_card(card);
 	}
+	isapnp_wait();
 	return 0;
 }
 
@@ -948,39 +1019,6 @@
 	return 0;
 }
 
-static int isapnp_config_prepare(struct pnp_dev *dev)
-{
-	int idx;
-	if (dev == NULL)
-		return -EINVAL;
-	if (dev->active || dev->lock_resources)
-		return -EBUSY;
-	for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
-		dev->irq_resource[idx].name = NULL;
-		dev->irq_resource[idx].start = -1;
-		dev->irq_resource[idx].end = -1;
-		dev->irq_resource[idx].flags = IORESOURCE_IRQ|IORESOURCE_UNSET;
-	}
-	for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) {
-		dev->dma_resource[idx].name = NULL;
-		dev->dma_resource[idx].start = -1;
-		dev->dma_resource[idx].end = -1;
-		dev->dma_resource[idx].flags = IORESOURCE_DMA|IORESOURCE_UNSET;
-	}
-	for (idx = 0; idx < DEVICE_COUNT_IO; idx++) {
-		dev->io_resource[idx].name = NULL;
-		dev->io_resource[idx].start = 0;
-		dev->io_resource[idx].end = 0;
-		dev->io_resource[idx].flags = IORESOURCE_IO|IORESOURCE_UNSET;
-	}
-	for (idx = 0; idx < DEVICE_COUNT_MEM; idx++) {
-		dev->mem_resource[idx].name = NULL;
-		dev->mem_resource[idx].start = 0;
-		dev->mem_resource[idx].end = 0;
-		dev->mem_resource[idx].flags = IORESOURCE_MEM|IORESOURCE_UNSET;
-	}
-	return 0;
-}
 
 /*
  *  Inititialization.
@@ -999,44 +1037,35 @@
 EXPORT_SYMBOL(isapnp_wake);
 EXPORT_SYMBOL(isapnp_device);
 
-static int isapnp_get_resources(struct pnp_dev *dev)
+static int isapnp_get_resources(struct pnp_dev *dev, struct pnp_resource_table * res)
 {
-	/* We don't need to do anything but this, the rest is taken care of */
-	if (pnp_port_valid(dev, 0) == 0 &&
-	    pnp_mem_valid(dev, 0) == 0 &&
-	    pnp_irq_valid(dev, 0) == 0 &&
-	    pnp_dma_valid(dev, 0) == 0)
-		dev->active = 0;
-	else
-		dev->active = 1;
-	return 0;
+	int ret;
+	pnp_init_resource_table(res);
+	isapnp_cfg_begin(dev->card->number, dev->number);
+	ret = isapnp_parse_current_resources(dev, res);
+	isapnp_cfg_end();
+	return ret;
 }
 
-static int isapnp_set_resources(struct pnp_dev *dev, struct pnp_cfg *cfg)
+static int isapnp_set_resources(struct pnp_dev *dev, struct pnp_resource_table * res)
 {
 	int tmp;
-      	isapnp_cfg_begin(dev->card->number, dev->number);
+
+	isapnp_cfg_begin(dev->card->number, dev->number);
 	dev->active = 1;
-	dev->irq_resource[0] = cfg->request.irq_resource[0];
-	dev->irq_resource[1] = cfg->request.irq_resource[1];
-	dev->dma_resource[0] = cfg->request.dma_resource[0];
-	dev->dma_resource[1] = cfg->request.dma_resource[1];
-	for (tmp = 0; tmp < DEVICE_COUNT_IO; tmp++)
-		dev->io_resource[tmp] = cfg->request.io_resource[tmp];
-	for (tmp = 0; tmp < DEVICE_COUNT_MEM; tmp++)
-		dev->mem_resource[tmp] = cfg->request.mem_resource[tmp];
-	for (tmp = 0; tmp < 8 && pnp_port_valid(dev, tmp); tmp++)
-		isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), pnp_port_start(dev, tmp));
-	for (tmp = 0; tmp < 2 && pnp_irq_valid(dev, tmp); tmp++) {
-		int irq = pnp_irq(dev, tmp);
+	for (tmp = 0; tmp < PNP_MAX_PORT && res->port_resource[tmp].flags & IORESOURCE_IO; tmp++)
+		isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), res->port_resource[tmp].start);
+	for (tmp = 0; tmp < PNP_MAX_IRQ && res->irq_resource[tmp].flags & IORESOURCE_IRQ; tmp++) {
+		int irq = res->irq_resource[tmp].start;
 		if (irq == 2)
 			irq = 9;
 		isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
 	}
-	for (tmp = 0; tmp < 2 && pnp_dma_valid(dev, tmp); tmp++)
-		isapnp_write_byte(ISAPNP_CFG_DMA+tmp, pnp_dma(dev, tmp));
-	for (tmp = 0; tmp < 4 && pnp_mem_valid(dev, tmp); tmp++)
-		isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (pnp_mem_start(dev, tmp) >> 8) & 0xffff);
+	for (tmp = 0; tmp < PNP_MAX_DMA && res->dma_resource[tmp].flags & IORESOURCE_DMA; tmp++)
+		isapnp_write_byte(ISAPNP_CFG_DMA+tmp, res->dma_resource[tmp].start);
+	for (tmp = 0; tmp < PNP_MAX_MEM && res->mem_resource[tmp].flags & IORESOURCE_MEM; tmp++)
+		isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (res->mem_resource[tmp].start >> 8) & 0xffff);
+	/* FIXME: We aren't handling 32bit mems properly here */
 	isapnp_activate(dev->number);
 	isapnp_cfg_end();
 	return 0;
@@ -1046,7 +1075,7 @@
 {
 	if (!dev || !dev->active)
 		return -EINVAL;
-      	isapnp_cfg_begin(dev->card->number, dev->number);
+	isapnp_cfg_begin(dev->card->number, dev->number);
 	isapnp_deactivate(dev->number);
 	dev->active = 0;
 	isapnp_cfg_end();
@@ -1127,11 +1156,11 @@
 	protocol_for_each_card(&isapnp_protocol,card) {
 		cards++;
 		if (isapnp_verbose) {
-			printk(KERN_INFO "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown");
+			printk(KERN_INFO "isapnp: Card '%s'\n", card->dev.name[0]?card->dev.name:"Unknown");
 			if (isapnp_verbose < 2)
 				continue;
-			pnp_card_for_each_dev(card,dev) {
-				printk(KERN_INFO "isapnp:   Device '%s'\n", dev->name[0]?dev->name:"Unknown");
+			card_for_each_dev(card,dev) {
+				printk(KERN_INFO "isapnp:   Device '%s'\n", dev->dev.name[0]?dev->dev.name:"Unknown");
 			}
 		}
 	}

                 reply	other threads:[~2003-02-17 23:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030217182319.GA31435@neo.rr.com \
    --to=ambx1@neo.rr.com \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=perex@suse.cz \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.