Subject: recent pnpbios lossage
To: None <port-i386@netbsd.org>
From: Johan Danielsson <joda@pdc.kth.se>
List: port-i386
Date: 05/25/2000 12:38:01
The fix for VAIO lossage breaks my TP600 laptop. It gets an error when
trying to get static config data for devie node 11. The following ugly
patch seems to fix this (by ignoring this error).

Another bug in this code is that if getnode fails, idx will never be
updated and it will (most likely) continue to fail, until i == num.

/Johan

--- pnpbios.c	2000/05/11 15:26:23	1.17
+++ pnpbios.c	2000/05/25 10:33:58
@@ -382,50 +387,63 @@
 	 *
 	 * This seems to work conveniently as the indices that cause
 	 * crashes (and it seems to vary from machine to machine) do not
 	 * seem to be for devices that NetBSD's pnpbios supports.
 	 */
 
 	idx = 0;
 	for (i = 0; i < num && idx != 0xff; i++) {
 		int node = idx;
 		int dynidx;
+		int staticconferror = 0;
 
 		DPRINTF(("%s: getting info for index %d\n",
 		    sc->sc_dev.dv_xname, node));
 
 		res = pnpbios_getnode(PNP_CF_DEVCONF_STATIC, &idx, buf, size);
-		if (res) {
+		if (res == PNP_RC_INVALID_HANDLE) {
+		    staticconferror = 1;
+		    goto dodynconf;
+		}
+		else if (res) {
 			printf("%s: index %d error %d "
 			    "getting static configuration\n",
 			    sc->sc_dev.dv_xname, node, res);
 			continue;
 		}
 		dn = (struct pnpdevnode *)buf;
 		if (dn->dn_handle != node)
 			printf("%s: node index mismatch (static): "
 			    "requested %d, got %d\n", sc->sc_dev.dv_xname,
 			    node, dn->dn_handle);
 		if (!pnpbios_attachnode(sc, node, buf, dn->dn_size, 1)) {
 			DPRINTF(("%s index %d: no match from static config\n",
 			    sc->sc_dev.dv_xname, node));
 			continue;
 		}
+	dodynconf:
 		dynidx = node;
 		res = pnpbios_getnode(PNP_CF_DEVCONF_DYNAMIC, &dynidx, buf,
 		    size);
 		if (res) {
 			printf("%s: index %d error %d "
 			    "getting dynamic configuration\n",
 			    sc->sc_dev.dv_xname, node, res);
 			continue;
 		}
+		if (staticconferror) {
+		    printf("%s: failed get static configuration for node %d\n",
+			   sc->sc_dev.dv_xname, idx);
+		    printf("%s: guessing next %d\n",
+			   sc->sc_dev.dv_xname, dynidx);
+		    idx = dynidx; /* XXX totally bogus (but a good guess) */
+		}
 		dn = (struct pnpdevnode *)buf;
 		if (dn->dn_handle != node)
 			printf("%s: node index mismatch (dynamic): "
 			    "requested %d, got %d\n", sc->sc_dev.dv_xname,
 			    node, dn->dn_handle);
 		pnpbios_attachnode(sc, node, buf, dn->dn_size, 0);
 	}
 	if (i != num)
 		printf("%s: got only %d nodes\n", sc->sc_dev.dv_xname, i);
 	if (idx != 0xff)