Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/pnpbios -catch zeroed descriptors and skip nod...



details:   https://anonhg.NetBSD.org/src/rev/22390fd0f8c8
branches:  trunk
changeset: 480438:22390fd0f8c8
user:      drochner <drochner%NetBSD.org@localhost>
date:      Wed Jan 12 19:24:02 2000 +0000

description:
-catch zeroed descriptors and skip nodes with no valid ressources,
 needed to deal with disabled nodes
-Parse "fixed io descriptors". Their use in nonsense in principle
 because 10-bit decoding is implied. Hope this is not real...
-Tolerate mismatches between node size and actually used space
 as long as the used size is smaller than the buffer size. There
 is at least one broken BIOS which reports node sizes larger than
 the used one, and windows obviously doesn't complain...

diffstat:

 sys/arch/i386/pnpbios/pnpbios.c |  99 +++++++++++++++++++++++++++++++---------
 1 files changed, 77 insertions(+), 22 deletions(-)

diffs (178 lines):

diff -r 9c9829360433 -r 22390fd0f8c8 sys/arch/i386/pnpbios/pnpbios.c
--- a/sys/arch/i386/pnpbios/pnpbios.c   Wed Jan 12 19:19:16 2000 +0000
+++ b/sys/arch/i386/pnpbios/pnpbios.c   Wed Jan 12 19:24:02 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pnpbios.c,v 1.7 1999/12/13 20:12:22 drochner Exp $ */
+/* $NetBSD: pnpbios.c,v 1.8 2000/01/12 19:24:02 drochner Exp $ */
 /*
  * Copyright (c) 1999
  *     Matthias Drochner.  All rights reserved.
@@ -457,8 +457,28 @@
        }
 
        if (p != buf + len) {
-               printf("length mismatch\n");
-               goto dump;
+               printf("%s: length mismatch in node %d: used %d of %d Bytes\n",
+                      sc->sc_dev.dv_xname, idx, p - buf, len);
+               if (p > buf + len) {
+                       /* XXX shouldn't happen - pnp_scan should catch it */
+                       goto dump;
+               }
+               /* Crappy BIOS: Buffer is not fully used. Be generous. */
+       }
+
+       if (r.nummem + r.numio + r.numirq + r.numdma == 0) {
+#ifdef PNPBIOSVERBOSE
+               printf("%s", idstr);
+               if (r.longname)
+                       printf(", %s", r.longname);
+               compatid = s.compatids;
+               while (compatid) {
+                       printf(", %s", compatid->idstr);
+                       compatid = compatid->next;
+               }
+               printf(" at %s index %d disabled\n", sc->sc_dev.dv_xname, idx);
+#endif
+               return;
        }
 
        aa.pbt = 0; /* XXX placeholder */
@@ -511,6 +531,7 @@
 static int pnp_newirq __P((struct pnpresources *, unsigned char *, size_t));
 static int pnp_newdma __P((struct pnpresources *, unsigned char *, size_t));
 static int pnp_newioport __P((struct pnpresources *, unsigned char *, size_t));
+static int pnp_newfixedioport __P((struct pnpresources *, unsigned char *, size_t));
 
 /*
  * small ressource types (beginning with 1)
@@ -527,7 +548,7 @@
        {0, 0, 1}, /* start dep */
        {0, 0, 0}, /* end dep */
        {pnp_newioport, 7, 7}, /* io descriptor */
-       {0, 3, 3}, /* fixed io descriptor */
+       {pnp_newfixedioport, 3, 3}, /* fixed io descriptor */
        {0, -1, -1}, /* reserved */
        {0, -1, -1},
        {0, -1, -1},
@@ -589,13 +610,7 @@
                                        mem->align = 0x10000;
                                mem->len = NEXTBYTE(p) << 8;
                                mem->len |= NEXTBYTE(p) << 16;
-                               SIMPLEQ_INSERT_TAIL(&r->mem, mem, next);
-                               r->nummem++;
-#ifdef PNPBIOSDEBUG
-                               if (mem->len == 0)
-                                       printf("ZERO mem descriptor\n");
-#endif
-                               break;
+                               goto gotmem;
                        case 0x02:
                                if (in_depends)
                                        printf("ID in dep?\n");
@@ -630,13 +645,7 @@
                                mem->len |= NEXTBYTE(p) << 8;
                                mem->len |= NEXTBYTE(p) << 16;
                                mem->len |= NEXTBYTE(p) << 24;
-                               SIMPLEQ_INSERT_TAIL(&r->mem, mem, next);
-                               r->nummem++;
-#ifdef PNPBIOSDEBUG
-                               if (mem->len == 0)
-                                       printf("ZERO mem descriptor\n");
-#endif
-                               break;
+                               goto gotmem;
                        case 0x06: /* 32bit fixed memory descriptor */
                                if (len != 9) {
                                        printf("pnp_scan: bad mem32 desc\n");
@@ -656,12 +665,16 @@
                                mem->len |= NEXTBYTE(p) << 8;
                                mem->len |= NEXTBYTE(p) << 16;
                                mem->len |= NEXTBYTE(p) << 24;
+gotmem:
+                               if (mem->len == 0) { /* disabled */
+#ifdef PNPBIOSDEBUG
+                                       printf("ZERO mem descriptor\n");
+#endif
+                                       free(mem, M_DEVBUF);
+                                       break;
+                               }
                                SIMPLEQ_INSERT_TAIL(&r->mem, mem, next);
                                r->nummem++;
-#ifdef PNPBIOSDEBUG
-                               if (mem->len == 0)
-                                       printf("ZERO mem descriptor\n");
-#endif
                                break;
                        default:
                                printf("ignoring long tag %x\n", type);
@@ -751,6 +764,12 @@
 {
        struct pnp_irq *irq;
 
+       if (buf[0] == 0 && buf[1] == 0) { /* disabled */
+#ifdef PNPBIOSDEBUG
+               printf("ZERO irq descriptor\n");
+#endif
+               return (0);
+       }
        irq = malloc(sizeof(struct pnp_irq), M_DEVBUF, M_NOWAIT);
        irq->mask = buf[0] | (buf[1] << 8);
        if (len > 2)
@@ -770,6 +789,12 @@
 {
        struct pnp_dma *dma;
 
+       if (buf[0] == 0) { /* disabled */
+#ifdef PNPBIOSDEBUG
+               printf("ZERO dma descriptor\n");
+#endif
+               return (0);
+       }
        dma = malloc(sizeof(struct pnp_dma), M_DEVBUF, M_NOWAIT);
        dma->mask = buf[0];
        dma->flags = buf[1];
@@ -786,6 +811,12 @@
 {
        struct pnp_io *io;
 
+       if (buf[6] == 0) { /* disabled */
+#ifdef PNPBIOSDEBUG
+               printf("ZERO io descriptor\n");
+#endif
+               return (0);
+       }
        io = malloc(sizeof(struct pnp_io), M_DEVBUF, M_NOWAIT);
        io->flags = buf[0];
        io->minbase = buf[1] | (buf[2] << 8);
@@ -798,6 +829,30 @@
 }
 
 static int
+pnp_newfixedioport(r, buf, len)
+       struct pnpresources *r;
+       unsigned char *buf;
+       size_t len;
+{
+       struct pnp_io *io;
+
+       if (buf[2] == 0) { /* disabled */
+#ifdef PNPBIOSDEBUG
+               printf("ZERO fixed io descriptor\n");
+#endif
+               return (0);
+       }
+       io = malloc(sizeof(struct pnp_io), M_DEVBUF, M_NOWAIT);
+       io->flags = 1; /* 10 bit decoding */
+       io->minbase = io->maxbase = buf[0] | (buf[1] << 8);
+       io->align = 1;
+       io->len = buf[2];
+       SIMPLEQ_INSERT_TAIL(&r->io, io, next);
+       r->numio++;
+       return (0);
+}
+
+static int
 pnp_compatid(r, buf, len)
        struct pnpresources *r;
        unsigned char *buf;



Home | Main Index | Thread Index | Old Index