-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...
This commit is contained in:
parent
67fd1bd089
commit
56b8bc14b4
@ -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 @@ pnpbios_attachnode(sc, idx, buf, len)
|
||||
}
|
||||
|
||||
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_compatid __P((struct pnpresources *, unsigned char *, size_t));
|
||||
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 @@ static struct{
|
||||
{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 @@ pnp_scan(bufp, maxlen, r, in_depends)
|
||||
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 @@ pnp_scan(bufp, maxlen, r, in_depends)
|
||||
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 @@ pnp_scan(bufp, maxlen, r, in_depends)
|
||||
mem->len |= NEXTBYTE(p) << 8;
|
||||
mem->len |= NEXTBYTE(p) << 16;
|
||||
mem->len |= NEXTBYTE(p) << 24;
|
||||
SIMPLEQ_INSERT_TAIL(&r->mem, mem, next);
|
||||
r->nummem++;
|
||||
gotmem:
|
||||
if (mem->len == 0) { /* disabled */
|
||||
#ifdef PNPBIOSDEBUG
|
||||
if (mem->len == 0)
|
||||
printf("ZERO mem descriptor\n");
|
||||
#endif
|
||||
free(mem, M_DEVBUF);
|
||||
break;
|
||||
}
|
||||
SIMPLEQ_INSERT_TAIL(&r->mem, mem, next);
|
||||
r->nummem++;
|
||||
break;
|
||||
default:
|
||||
printf("ignoring long tag %x\n", type);
|
||||
@ -751,6 +764,12 @@ pnp_newirq(r, buf, len)
|
||||
{
|
||||
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 @@ pnp_newdma(r, buf, len)
|
||||
{
|
||||
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 @@ pnp_newioport(r, buf, len)
|
||||
{
|
||||
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);
|
||||
@ -797,6 +828,30 @@ pnp_newioport(r, buf, len)
|
||||
return (0);
|
||||
}
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user