Patchworkβ Patch to superiotool - add basic indexing of devices detected at IO ports

login
register
about
Submitter Frantisek Rysanek
Date 2011-01-29 13:59:47
Message ID <4D442B63.26606.150F3F1E@Frantisek.Rysanek.post.cz>
Download mbox | patch
Permalink /patch/2581/
State New
Headers show

Comments

Frantisek Rysanek - 2011-01-29 13:59:47
Dear gentlemen,

sorry for a noob question... noone has responded to my suggested 
patch - is there something more I can do?
I can see on the mailing list that the admins are busy doing other 
things, and I understand they are volunteers, so I'd hate to sound 
abusive :-)

I guess the patch may look long, but it's mostly the same one-liners 
over and over in all the vendor-specific files. And it's so simple 
conceptually, that it shouldn't cause any trouble.
I've spent an enjoyable evening coding the patch and I'd like to have 
it merged, for the benefit of others...

Thanks for your time and attention :-)

Frank Rysanek

-----------
On 10 Jan 2011 at 8:49, Frantisek.Rysanek@post.cz wrote:

This patch adds a simple table of SuperIO chips already detected in 
the system. This allows superiotool to properly avoid scanning the 
same IO port again by another vendor-specific probe, after some 
device has already been found on that particular port.

The table of chips detected contains entries that, apart from the IO 
port known to be "inhabited", also relate the port to a particular 
"chip entry" (struct superio_registers*).
There's no immediate use for this, but in the future it could 
facilitate further functionality enhancements, such as
- separation of the "dump" function from the "detect" function
- write support (with validity checking of the desired LDN/CR)

As suggested by Mr. Hendricks, the vendor-specific probe functions 
now return a result code, indicating that a particular chip was found
and which one that was, or that none was detected.

The simple "framework" is headquartered in superiotool.c, with some 
necessary mods to superiotool.h. All the existing "vendor-specific" C 

files have been adapted to make use of this "framework".

Apart from this addition, the patch scraps some previous attempts at 
the same functionality, and moves some table definitions from 
superiotool.h to superiotool.c, where they seem to belong.

Signed-off-by: Frank Rysanek <Frantisek.Rysanek@post.cz>
---

Tested on my AEC-6811 with two Winbond SuperIO chips.
Note that the Winbond probe comes last in the "sequence of vendors", 
so my test is not entirely significant :-)

I've tried the recommended method of deriving the patch via 
"svn diff". The resulting patch however fails to apply cleanly (hunk 
failed...).
But if I try the bare "diff -Naur", the resulting patch *does* apply 
just fine. Go figure... 
Attached you'll find the manual diff that works for me.
The following section of this message contains a file attachment
prepared for transmission using the Internet MIME message format.
If you are using Pegasus Mail, or any other MIME-compliant system,
you should be able to save it or view it from within your mailer.
If you cannot, please ask your system administrator for assistance.

   ---- File information -----------
     File:  device_counting.diff
     Date:  9 Jan 2011, 22:25
     Size:  20401 bytes.
     Type:  Unknown

Patch

diff -Naur --exclude='\.*' superiotool.old/ali.c superiotool/ali.c
--- superiotool.old/ali.c	2010-11-25 12:48:17.000000000 +0100
+++ superiotool/ali.c	2011-01-09 21:38:39.000000000 +0100
@@ -69,7 +69,7 @@ 
 	OUTB(0xbb, port);
 }
 
-void probe_idregs_ali(uint16_t port)
+const struct superio_registers* probe_idregs_ali(uint16_t port)
 {
 	uint16_t id;
 	uint8_t rev;
@@ -88,16 +88,17 @@ 
 		if (verbose)
 			printf(NOTFOUND "id=0x%04x, rev=0x%02x\n", id, rev);
 		exit_conf_mode_ali(port);
-		return;
+		return NULL;
 	}
 
 	printf("Found ALi %s (id=0x%04x, rev=0x%02x) at 0x%x\n",
 	       get_superio_name(reg_table, id), id, rev, port);
-	chip_found = 1;
 
 	dump_superio("ALi", reg_table, port, id, LDN_SEL);
 
 	exit_conf_mode_ali(port);
+
+	return get_superio_regs_entry(reg_table, id);
 }
 
 void print_ali_chips(void)
diff -Naur --exclude='\.*' superiotool.old/fintek.c superiotool/fintek.c
--- superiotool.old/fintek.c	2010-12-28 10:10:04.000000000 +0100
+++ superiotool/fintek.c	2011-01-09 21:39:24.000000000 +0100
@@ -283,7 +283,7 @@ 
 	{EOT}
 };
 
-void probe_idregs_fintek(uint16_t port)
+const struct superio_registers* probe_idregs_fintek(uint16_t port)
 {
 	uint16_t vid, did;
 
@@ -301,20 +301,21 @@ 
 		if (verbose)
 			printf(NOTFOUND "vid=0x%04x, id=0x%04x\n", vid, did);
 		exit_conf_mode_winbond_fintek_ite_8787(port);
-		return;
+		return NULL;
 	}
 
 	printf("Found Fintek %s (vid=0x%04x, id=0x%04x) at 0x%x\n",
 	       get_superio_name(reg_table, did), vid, did, port);
-	chip_found = 1;
 
 	dump_superio("Fintek", reg_table, port, did, LDN_SEL);
 
 	exit_conf_mode_winbond_fintek_ite_8787(port);
+
+	return get_superio_regs_entry(reg_table, did);
 }
 
 
-void probe_idregs_fintek_alternative(uint16_t port)
+const struct superio_registers* probe_idregs_fintek_alternative(uint16_t port)
 {
 	uint16_t vid, did;
 
@@ -332,16 +333,17 @@ 
 		if (verbose)
 			printf(NOTFOUND "vid=0x%04x, id=0x%04x\n", vid, did);
 		exit_conf_mode_fintek_7777(port);
-		return;
+		return NULL;
 	}
 
 	printf("Found Fintek %s (vid=0x%04x, id=0x%04x) at 0x%x\n",
 	       get_superio_name(reg_table, did), vid, did, port);
-	chip_found = 1;
 
 	dump_superio("Fintek", reg_table, port, did, LDN_SEL);
 
 	exit_conf_mode_fintek_7777(port);
+
+	return get_superio_regs_entry(reg_table, did);
 }
 
 void print_fintek_chips(void)
diff -Naur --exclude='\.*' superiotool.old/ite.c superiotool/ite.c
--- superiotool.old/ite.c	2011-01-03 21:06:37.000000000 +0100
+++ superiotool/ite.c	2011-01-09 21:53:48.000000000 +0100
@@ -800,9 +800,7 @@ 
 	regwrite(port, 0x02, 0x02);
 }
 
-static int chip_found_at_port;
-
-static void probe_idregs_ite_helper(const char *init, uint16_t port)
+static const struct superio_registers* probe_idregs_ite_helper(const char *init, uint16_t port)
 {
 	uint16_t id, chipver, ecport;
 
@@ -815,13 +813,11 @@ 
 	if (superio_unknown(reg_table, id)) {
 		if (verbose)
 			printf(NOTFOUND "id=0x%04x, rev=0x%01x\n", id, chipver);
-		return;
+		return NULL;
 	}
 
 	printf("Found ITE %s (id=0x%04x, rev=0x%01x) at 0x%x\n",
 	       get_superio_name(reg_table, id), id, chipver, port);
-	chip_found = 1;
-	chip_found_at_port = 1;
 
 	dump_superio("ITE", reg_table, port, id, LDN_SEL);
 
@@ -838,48 +834,52 @@ 
 		printf("Environment controller (0x%04x)\n", ecport);
 		dump_superio("ITE-EC", ec_table, ecport, id, LDN_SEL);
 	}
+
+	return get_superio_regs_entry(reg_table, id);
 }
 
-void probe_idregs_ite(uint16_t port)
+const struct superio_registers* probe_idregs_ite(uint16_t port)
 {
-	chip_found_at_port = 0;
-
+	const struct superio_registers* retval = NULL;
+   
 	if (port == 0x3f0 || port == 0x3bd || port == 0x370) {
 		enter_conf_mode_ite_legacy(port, initkey_it8661f);
-		probe_idregs_ite_helper("(init=legacy/it8661f) ", port);
+		retval = probe_idregs_ite_helper("(init=legacy/it8661f) ", port);
 		exit_conf_mode_ite(port);
-		if (chip_found_at_port) return;
+		if (retval != NULL) return retval;
 
 		enter_conf_mode_ite_legacy(port, initkey_it8671f);
-		probe_idregs_ite_helper("(init=legacy/it8671f) ", port);
+		retval = probe_idregs_ite_helper("(init=legacy/it8671f) ", port);
 		exit_conf_mode_ite(port);
-		if (chip_found_at_port) return;
+		if (retval != NULL) return retval;
 	} else {
 		enter_conf_mode_ite(port);
-		probe_idregs_ite_helper("(init=standard) ", port);
+		retval = probe_idregs_ite_helper("(init=standard) ", port);
 		exit_conf_mode_ite(port);
-		if (chip_found_at_port) return;
+		if (retval != NULL) return retval;
 
 		enter_conf_mode_ite_it8502e(port);
-		probe_idregs_ite_helper("(init=it8502e) ", port);
+		retval = probe_idregs_ite_helper("(init=it8502e) ", port);
 		exit_conf_mode_ite(port);
-		if (chip_found_at_port) return;
+		if (retval != NULL) return retval;
 
 		enter_conf_mode_ite_it8761e(port);
-		probe_idregs_ite_helper("(init=it8761e) ", port);
+		retval = probe_idregs_ite_helper("(init=it8761e) ", port);
 		exit_conf_mode_ite(port);
-		if (chip_found_at_port) return;
+		if (retval != NULL) return retval;
 
 		enter_conf_mode_ite_it8228e(port);
-		probe_idregs_ite_helper("(init=it8228e) ", port);
+		retval = probe_idregs_ite_helper("(init=it8228e) ", port);
 		exit_conf_mode_ite(port);
-		if (chip_found_at_port) return;
+		if (retval != NULL) return retval;
 
 		enter_conf_mode_winbond_fintek_ite_8787(port);
-		probe_idregs_ite_helper("(init=0x87,0x87) ", port);
+		retval = probe_idregs_ite_helper("(init=0x87,0x87) ", port);
 		exit_conf_mode_winbond_fintek_ite_8787(port);
-		if (chip_found_at_port) return;
+		if (retval != NULL) return retval;
 	}
+
+	return NULL;
 }
 
 void print_ite_chips(void)
diff -Naur --exclude='\.*' superiotool.old/nsc.c superiotool/nsc.c
--- superiotool.old/nsc.c	2010-11-25 12:48:17.000000000 +0100
+++ superiotool/nsc.c	2011-01-09 21:48:19.000000000 +0100
@@ -548,7 +548,7 @@ 
 	{EOT}
 };
 
-void probe_idregs_nsc(uint16_t port)
+const struct superio_registers* probe_idregs_nsc(uint16_t port)
 {
 	uint8_t id, rev;
 	uint16_t magic;
@@ -560,7 +560,7 @@ 
 		if (verbose)
 			printf(NOTFOUND "port=0x%02x, port+1=0x%02x\n",
 			       INB(port), INB(port + 1));
-		return;
+		return NULL;
 	}
 	id = INB(port + 1);
 
@@ -584,16 +584,17 @@ 
 	if (superio_unknown(reg_table, magic)) {
 		if (verbose)
 			printf(NOTFOUND "sid=0x%02x, srid=0x%02x\n", id, rev);
-		return;
+		return NULL;
 	}
 
 	printf("Found %s %s (sid=0x%02x, srid=0x%02x) at 0x%x\n",
 	       magic == 0x8f1 ? "Winbond" : "NSC",
 	       get_superio_name(reg_table, magic), id, rev, port);
-	chip_found = 1;
 
 	dump_superio(magic == 0x8f1 ? "Winbond" : "NSC",
 		     reg_table, port, magic, LDN_SEL);
+
+	return get_superio_regs_entry(reg_table, magic);
 }
 
 void print_nsc_chips(void)
diff -Naur --exclude='\.*' superiotool.old/nuvoton.c superiotool/nuvoton.c
--- superiotool.old/nuvoton.c	2011-01-03 21:04:17.000000000 +0100
+++ superiotool/nuvoton.c	2011-01-09 21:49:37.000000000 +0100
@@ -69,7 +69,7 @@ 
 	{EOT}
 };
 
-void probe_idregs_nuvoton(uint16_t port)
+const struct superio_registers* probe_idregs_nuvoton(uint16_t port)
 {
 	uint8_t sid, srid;
 	uint8_t chip_id = 0, chip_rev = 0;
@@ -93,14 +93,15 @@ 
 			printf(NOTFOUND
 			       "sid=0x%02x, id=0x%02x, rev=0x%02x\n", sid,
 			       chip_id, chip_rev);
-		return;
+		return NULL;
 	}
 
 	printf("Found Nuvoton %s (id=0x%02x, rev=0x%02x) at 0x%x\n",
 	       get_superio_name(reg_table, sid), chip_id, chip_rev, port);
-	chip_found = 1;
 
 	dump_superio("Nuvoton", reg_table, port, sid, LDN_SEL);
+
+	return get_superio_regs_entry(reg_table, sid);
 }
 
 void print_nuvoton_chips(void)
diff -Naur --exclude='\.*' superiotool.old/smsc.c superiotool/smsc.c
--- superiotool.old/smsc.c	2010-11-25 12:48:17.000000000 +0100
+++ superiotool/smsc.c	2011-01-09 22:08:06.000000000 +0100
@@ -761,7 +761,7 @@ 
 	OUTB(0xaa, port);
 }
 
-static void probe_idregs_smsc_helper(uint16_t port, uint8_t idreg,
+static const struct superio_registers* probe_idregs_smsc_helper(uint16_t port, uint8_t idreg,
 				     uint8_t revreg)
 {
 	uint8_t id, rev;
@@ -780,13 +780,12 @@ 
 		if (verbose)
 			printf(NOTFOUND "id=0x%02x, rev=0x%02x\n", id, rev);
 		exit_conf_mode_smsc(port);
-		return;
+		return NULL;
 	}
 
 	printf("Found %s %s (id=0x%02x, rev=0x%02x) at 0x%x\n",
 	       (id == 0x77 ? "ASUS" : "SMSC"), get_superio_name(reg_table, id),
 	       id, rev, port);
-	chip_found = 1;
 
 	dump_superio((id == 0x77 ? "ASUS" : "SMSC"), reg_table, port, id,
 		     LDN_SEL);
@@ -806,12 +805,21 @@ 
 	}
 
 	exit_conf_mode_smsc(port);
+
+	return get_superio_regs_entry(reg_table, id);
 }
 
-void probe_idregs_smsc(uint16_t port)
+const struct superio_registers* probe_idregs_smsc(uint16_t port)
 {
-	probe_idregs_smsc_helper(port, DEVICE_ID_REG, DEVICE_REV_REG);
-	probe_idregs_smsc_helper(port, DEVICE_ID_REG_OLD, DEVICE_REV_REG_OLD);
+	const struct superio_registers* retval = NULL;
+	
+	retval = probe_idregs_smsc_helper(port, DEVICE_ID_REG, DEVICE_REV_REG);
+	if (retval != NULL) return retval;
+	
+	retval = probe_idregs_smsc_helper(port, DEVICE_ID_REG_OLD, DEVICE_REV_REG_OLD);
+	if (retval != NULL) return retval;
+
+	return NULL;
 }
 
 void print_smsc_chips(void)
diff -Naur --exclude='\.*' superiotool.old/superiotool.c superiotool/superiotool.c
--- superiotool.old/superiotool.c	2011-01-03 21:15:12.000000000 +0100
+++ superiotool/superiotool.c	2011-01-09 22:07:22.000000000 +0100
@@ -28,6 +28,67 @@ 
 #include <unistd.h>
 #endif
 
+#define MAX_CHIPS_FOUND 10
+
+/** Table of which config ports to probe for each Super I/O family. */
+static const struct {
+	const struct superio_registers* (*probe_idregs) (uint16_t port);
+	int ports[MAXNUMPORTS]; /* Signed, as we need EOT. */
+} superio_ports_table[] = {
+	{probe_idregs_ali,	{0x3f0, 0x370, EOT}},
+	{probe_idregs_fintek,	{0x2e, 0x4e, EOT}},
+	{probe_idregs_fintek_alternative,	{0x2e, 0x4e, EOT}},
+	/* Only use 0x370 for ITE, but 0x3f0 or 0x3bd would also be valid. */
+	{probe_idregs_ite,	{0x25e, 0x2e, 0x4e, 0x370, EOT}},
+	{probe_idregs_nsc,	{0x2e, 0x4e, 0x15c, EOT}},
+	/* I/O pairs on Nuvoton EC chips can be configured by firmware in
+	 * addition to the following hardware strapping options. */
+	{probe_idregs_nuvoton, {0x164e, 0x2e, EOT}},
+	{probe_idregs_smsc,	{0x2e, 0x4e, 0x162e, 0x164e, 0x3f0, 0x370, EOT}},
+	{probe_idregs_winbond,	{0x2e, 0x4e, 0x3f0, 0x370, 0x250, EOT}},
+#ifdef PCI_SUPPORT
+	{probe_idregs_via,	{0x3f0, EOT}},
+#endif
+};
+
+/** Table of functions to print out supported Super I/O chips. */
+static const struct {
+	void (*print_list) (void);
+} vendor_print_functions[] = {
+	{print_ali_chips},
+	{print_fintek_chips},
+	{print_ite_chips},
+	{print_nsc_chips},
+	{print_nuvoton_chips},
+	{print_smsc_chips},
+	{print_winbond_chips},
+#ifdef PCI_SUPPORT
+	{print_via_chips},
+#endif
+};
+
+struct chip_found {
+	int16_t port;
+	const struct superio_registers* dev;
+};
+
+struct chip_found chips_found[MAX_CHIPS_FOUND]; 
+int num_chips_found = 0;
+
+/* if something's been detected on the port, return 1. Otherwise, return 0 = chip free. */
+static int port_already_inhabited(int port)
+{
+ int i;	
+
+	for (i=0; i < num_chips_found; i++) {
+		if (chips_found[i].port == port)
+			return 1;
+	}
+
+	return 0;
+}
+
+
 /* Command line options. */
 int dump = 0, verbose = 0, extra_dump = 0;
 
@@ -93,6 +154,24 @@ 
 	return "<unknown>";
 }
 
+const struct superio_registers* get_superio_regs_entry(const struct superio_registers reg_table[],
+			     uint16_t id)
+{
+	int i;
+
+	for (i = 0; /* Nothing */; i++) {
+		if (reg_table[i].superio_id == EOT)
+			break;
+
+		if ((uint16_t)reg_table[i].superio_id != id)
+			continue;
+
+		return &reg_table[i];
+	}
+
+	return NULL;
+}
+
 static void dump_regs(const struct superio_registers reg_table[],
 		      int i, int j, uint16_t port, uint8_t ldn_sel)
 {
@@ -305,14 +384,24 @@ 
 #endif
 
 	for (i = 0; i < ARRAY_SIZE(superio_ports_table); i++) {
-		for (j = 0; superio_ports_table[i].ports[j] != EOT; j++)
-                {
-			superio_ports_table[i].probe_idregs(
-				superio_ports_table[i].ports[j]);
+		for (j = 0; superio_ports_table[i].ports[j] != EOT; j++) {
+		  const struct superio_registers* dev_found = NULL;
+		  int port = superio_ports_table[i].ports[j];
+                 
+			if (! port_already_inhabited(port)) {
+				dev_found = superio_ports_table[i].probe_idregs(port);
+				if (dev_found != NULL) {
+					chips_found[num_chips_found].port = port;
+					chips_found[num_chips_found].dev = dev_found;
+					num_chips_found++;
+				} /* else no device found on this port by this 
+                                     vendor's probe - try another one */
+			} /* else some device has already been 
+                            detected here - try another port */
                 }
 	}
 
-	if (!chip_found)
+	if (num_chips_found == 0)
 		printf("No Super I/O found\n");
 
 #if defined(__FreeBSD__)
diff -Naur --exclude='\.*' superiotool.old/superiotool.h superiotool/superiotool.h
--- superiotool.old/superiotool.h	2010-11-25 12:48:17.000000000 +0100
+++ superiotool/superiotool.h	2011-01-09 21:32:07.000000000 +0100
@@ -142,8 +142,6 @@ 
 /* Command line parameters. */
 extern int dump, verbose, extra_dump;
 
-extern int chip_found;
-
 struct superio_registers {
 	int32_t superio_id;		/* Signed, as we need EOT. */
 	const char *name;		/* Super I/O name */
@@ -171,6 +169,8 @@ 
 int superio_unknown(const struct superio_registers reg_table[], uint16_t id);
 const char *get_superio_name(const struct superio_registers reg_table[],
 			     uint16_t id);
+const struct superio_registers* get_superio_regs_entry(const struct superio_registers reg_table[],
+			     uint16_t id);
 void dump_superio(const char *name, const struct superio_registers reg_table[],
 		  uint16_t port, uint16_t id, uint8_t ldn_sel);
 void dump_io(uint16_t iobase, uint16_t length);
@@ -179,75 +179,38 @@ 
 			const struct superio_registers reg_table[]);
 
 /* ali.c */
-void probe_idregs_ali(uint16_t port);
+const struct superio_registers* probe_idregs_ali(uint16_t port);
 void print_ali_chips(void);
 
 /* fintek.c */
-void probe_idregs_fintek(uint16_t port);
-void probe_idregs_fintek_alternative(uint16_t port);
+const struct superio_registers* probe_idregs_fintek(uint16_t port);
+const struct superio_registers* probe_idregs_fintek_alternative(uint16_t port);
 void print_fintek_chips(void);
 
 /* ite.c */
-void probe_idregs_ite(uint16_t port);
+const struct superio_registers* probe_idregs_ite(uint16_t port);
 void print_ite_chips(void);
 
 /* nsc.c */
-void probe_idregs_nsc(uint16_t port);
+const struct superio_registers* probe_idregs_nsc(uint16_t port);
 void print_nsc_chips(void);
 
 /* nuvoton.c */
-void probe_idregs_nuvoton(uint16_t port);
+const struct superio_registers* probe_idregs_nuvoton(uint16_t port);
 void print_nuvoton_chips(void);
 
 /* smsc.c */
-void probe_idregs_smsc(uint16_t port);
+const struct superio_registers* probe_idregs_smsc(uint16_t port);
 void print_smsc_chips(void);
 
 /* winbond.c */
-void probe_idregs_winbond(uint16_t port);
+const struct superio_registers* probe_idregs_winbond(uint16_t port);
 void print_winbond_chips(void);
 
 /* via.c */
 #ifdef PCI_SUPPORT
-void probe_idregs_via(uint16_t port);
+const struct superio_registers* probe_idregs_via(uint16_t port);
 void print_via_chips(void);
 #endif
 
-/** Table of which config ports to probe for each Super I/O family. */
-static const struct {
-	void (*probe_idregs) (uint16_t port);
-	int ports[MAXNUMPORTS]; /* Signed, as we need EOT. */
-} superio_ports_table[] = {
-	{probe_idregs_ali,	{0x3f0, 0x370, EOT}},
-	{probe_idregs_fintek,	{0x2e, 0x4e, EOT}},
-	{probe_idregs_fintek_alternative,	{0x2e, 0x4e, EOT}},
-	/* Only use 0x370 for ITE, but 0x3f0 or 0x3bd would also be valid. */
-	{probe_idregs_ite,	{0x25e, 0x2e, 0x4e, 0x370, EOT}},
-	{probe_idregs_nsc,	{0x2e, 0x4e, 0x15c, EOT}},
-	/* I/O pairs on Nuvoton EC chips can be configured by firmware in
-	 * addition to the following hardware strapping options. */
-	{probe_idregs_nuvoton, {0x164e, 0x2e, EOT}},
-	{probe_idregs_smsc,	{0x2e, 0x4e, 0x162e, 0x164e, 0x3f0, 0x370, EOT}},
-	{probe_idregs_winbond,	{0x2e, 0x4e, 0x3f0, 0x370, 0x250, EOT}},
-#ifdef PCI_SUPPORT
-	{probe_idregs_via,	{0x3f0, EOT}},
-#endif
-};
-
-/** Table of functions to print out supported Super I/O chips. */
-static const struct {
-	void (*print_list) (void);
-} vendor_print_functions[] = {
-	{print_ali_chips},
-	{print_fintek_chips},
-	{print_ite_chips},
-	{print_nsc_chips},
-	{print_nuvoton_chips},
-	{print_smsc_chips},
-	{print_winbond_chips},
-#ifdef PCI_SUPPORT
-	{print_via_chips},
-#endif
-};
-
 #endif
diff -Naur --exclude='\.*' superiotool.old/via.c superiotool/via.c
--- superiotool.old/via.c	2010-11-25 12:48:17.000000000 +0100
+++ superiotool/via.c	2011-01-09 22:04:52.000000000 +0100
@@ -73,7 +73,7 @@ 
 	pci_write_byte(dev, 0x85, vt82c686_conf);
 }
 
-void probe_idregs_via(uint16_t port)
+const struct superio_registers* probe_idregs_via(uint16_t port)
 {
 	uint16_t id;
 	uint8_t rev;
@@ -81,7 +81,7 @@ 
 	probing_for("VIA", "", port);
 
 	if (enter_conf_mode_via_vt82c686())
-		return;
+		return NULL;
 
 	id = regval(port, DEVICE_ID_VT82C686_REG);
 	rev = regval(port, DEVICE_REV_VT82C686_REG);
@@ -90,14 +90,15 @@ 
 		if (verbose)
 			printf(NOTFOUND "id=0x%04x, rev=0x%02x\n", id, rev);
 		exit_conf_mode_via_vt82c686();
-		return;
+		return NULL;
 	}
 
 	printf("Found VIA %s (id=0x%04x, rev=0x%02x) at 0x%x\n",
 	       get_superio_name(reg_table, id), id, rev, port);
-	chip_found = 1;
 
 	exit_conf_mode_via_vt82c686();
+
+	return get_superio_regs_entry(reg_table, id);
 }
 
 void print_via_chips(void)
diff -Naur --exclude='\.*' superiotool.old/winbond.c superiotool/winbond.c
--- superiotool.old/winbond.c	2011-01-03 21:06:37.000000000 +0100
+++ superiotool/winbond.c	2011-01-09 22:09:13.000000000 +0100
@@ -625,9 +625,7 @@ 
 	OUTB(0x86, port);
 }
 
-static int chip_found_at_port;
-
-static void probe_idregs_winbond_helper(const char *init, uint16_t port)
+static const struct superio_registers* probe_idregs_winbond_helper(const char *init, uint16_t port)
 {
 	uint16_t id, hwmport;
 	uint8_t devid, rev, olddevid;
@@ -654,7 +652,7 @@ 
 		if (verbose)
 			printf(NOTFOUND "id/oldid=0x%02x/0x%02x, rev=0x%02x\n",
 			       devid, olddevid, rev);
-		return;
+		return NULL;
 	}
 
 	if (olddevid >= 0x0a && olddevid <= 0x0d)
@@ -663,8 +661,6 @@ 
 	else
 		printf("Found Winbond %s (id=0x%02x, rev=0x%02x) at 0x%x\n",
 		       get_superio_name(reg_table, id), devid, rev, port);
-	chip_found = 1;
-	chip_found_at_port = 1;
 
 	dump_superio("Winbond", reg_table, port, id, LDN_SEL);
 
@@ -673,7 +669,8 @@ 
 
 		if ((regval(port, 0x30) & (1 << 0)) != (1 << 0)) {
 			printf("Hardware Monitor disabled or does not exist.\n");
-			return;
+			/* Yet the SuperIO chip is valid, so return a positive result! */
+			return get_superio_regs_entry(reg_table, id);
 		}
 
 		/* Get HWM base address (stored in LDN 0xb, index 0x60/0x61). */
@@ -687,31 +684,35 @@ 
 		dump_superio("Winbond-HWM", hwm_table, hwmport, id,
 			     WINBOND_HWM_SEL);
 	}
+
+	return get_superio_regs_entry(reg_table, id);
 }
 
-void probe_idregs_winbond(uint16_t port)
+const struct superio_registers* probe_idregs_winbond(uint16_t port)
 {
-	chip_found_at_port = 0;
-
+	const struct superio_registers* retval = NULL;
+   
 	enter_conf_mode_winbond_88(port);
-	probe_idregs_winbond_helper("(init=0x88) ", port);
+	retval = probe_idregs_winbond_helper("(init=0x88) ", port);
 	exit_conf_mode_winbond_fintek_ite_8787(port);
-	if (chip_found_at_port) return;
+	if (retval != NULL) return retval;
 
 	enter_conf_mode_winbond_89(port);
-	probe_idregs_winbond_helper("(init=0x89) ", port);
+	retval = probe_idregs_winbond_helper("(init=0x89) ", port);
 	exit_conf_mode_winbond_fintek_ite_8787(port);
-	if (chip_found_at_port) return;
+	if (retval != NULL) return retval;
 
 	enter_conf_mode_winbond_86(port);
-	probe_idregs_winbond_helper("(init=0x86,0x86) ", port);
+	retval = probe_idregs_winbond_helper("(init=0x86,0x86) ", port);
 	exit_conf_mode_winbond_fintek_ite_8787(port);
-	if (chip_found_at_port) return;
+	if (retval != NULL) return retval;
 
 	enter_conf_mode_winbond_fintek_ite_8787(port);
-	probe_idregs_winbond_helper("(init=0x87,0x87) ", port);
+	retval = probe_idregs_winbond_helper("(init=0x87,0x87) ", port);
 	exit_conf_mode_winbond_fintek_ite_8787(port);
-	if (chip_found_at_port) return;
+	if (retval != NULL) return retval;
+
+        return(NULL);
 }
 
 void print_winbond_chips(void)