summaryrefslogtreecommitdiffstats
path: root/sys/isa/pnpparse.c
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1999-10-14 21:03:03 +0000
committerdfr <dfr@FreeBSD.org>1999-10-14 21:03:03 +0000
commitf7cfef8ecf037d19a81279dcc4e946b79fc3837b (patch)
tree9cfc808248748600189af9b09481a97025b4b8ce /sys/isa/pnpparse.c
parentcdedefff3d29174f78d8e07698cec803b5553099 (diff)
downloadFreeBSD-src-f7cfef8ecf037d19a81279dcc4e946b79fc3837b.zip
FreeBSD-src-f7cfef8ecf037d19a81279dcc4e946b79fc3837b.tar.gz
* Add some verbose logging to the PnP parser and fix a couple of bugs.
* Move pnp_eisaformat() to pnp.c, declared in <isa/pnpvar.h>. * Turn the pnpbios code into an enumerator for the isa bus. This allows all devices known to the bios to be probed automatically. Currently the pnpbios code is dependant on the PNPBIOS option. As the code is tested more and when more drivers are converted this will be made the default. I have PnP changes in the wings for fdc, atkbd, psm, pcaudio, and joy. Sio already works with pnpbios.
Diffstat (limited to 'sys/isa/pnpparse.c')
-rw-r--r--sys/isa/pnpparse.c199
1 files changed, 166 insertions, 33 deletions
diff --git a/sys/isa/pnpparse.c b/sys/isa/pnpparse.c
index 766869d..e513662 100644
--- a/sys/isa/pnpparse.c
+++ b/sys/isa/pnpparse.c
@@ -35,6 +35,9 @@
#include <isa/pnpreg.h>
#include <isa/pnpvar.h>
+#define I16(p) ((p)[0] + ((p)[1] << 8))
+#define I32(p) (I16(p) + (I16(p+2) << 16))
+
/*
* Parse resource data for Logical Devices.
*
@@ -48,13 +51,14 @@ pnp_parse_resources(device_t dev, u_char *resources, int len)
device_t parent = device_get_parent(dev);
u_char tag, *resp, *resinfo;
int large_len, scanning = len;
- u_int32_t compat_id;
+ u_int32_t id, compat_id;
struct isa_config logdev, alt;
struct isa_config *config;
int priority = 0;
int seenalt = 0;
char buf[100];
+ id = isa_get_logicalid(dev);
bzero(&logdev, sizeof logdev);
bzero(&alt, sizeof alt);
config = &logdev;
@@ -84,17 +88,27 @@ pnp_parse_resources(device_t dev, u_char *resources, int len)
break;
case PNP_TAG_IRQ_FORMAT:
+ if (bootverbose) {
+ printf("%s: adding irq mask %#04x\n",
+ pnp_eisaformat(id),
+ I16(resinfo));
+ }
if (config->ic_nirq == ISA_NIRQ) {
device_printf(parent, "too many irqs");
scanning = 0;
break;
}
config->ic_irqmask[config->ic_nirq] =
- resinfo[0] + (resinfo[1]<<8);
+ I16(resinfo);
config->ic_nirq++;
break;
case PNP_TAG_DMA_FORMAT:
+ if (bootverbose) {
+ printf("%s: adding dma mask %#02x\n",
+ pnp_eisaformat(id),
+ resinfo[0]);
+ }
if (config->ic_ndrq == ISA_NDRQ) {
device_printf(parent, "too many drqs");
scanning = 0;
@@ -106,6 +120,10 @@ pnp_parse_resources(device_t dev, u_char *resources, int len)
break;
case PNP_TAG_START_DEPENDANT:
+ if (bootverbose) {
+ printf("%s: start dependant\n",
+ pnp_eisaformat(id));
+ }
if (config == &alt) {
ISA_ADD_CONFIG(parent, dev,
priority, config);
@@ -128,47 +146,80 @@ pnp_parse_resources(device_t dev, u_char *resources, int len)
break;
case PNP_TAG_END_DEPENDANT:
+ if (bootverbose) {
+ printf("%s: end dependant\n",
+ pnp_eisaformat(id));
+ }
ISA_ADD_CONFIG(parent, dev, priority, config);
config = &logdev;
seenalt = 1;
break;
case PNP_TAG_IO_RANGE:
+ if (bootverbose) {
+ printf("%s: adding io range "
+ "%#x-%#x, size=%#x, "
+ "align=%#x\n",
+ pnp_eisaformat(id),
+ I16(resinfo + 1),
+ I16(resinfo + 3) + resinfo[6]-1,
+ resinfo[6],
+ resinfo[5]);
+ }
if (config->ic_nport == ISA_NPORT) {
device_printf(parent, "too many ports");
scanning = 0;
break;
}
config->ic_port[config->ic_nport].ir_start =
- resinfo[1] + (resinfo[2]<<8);
+ I16(resinfo + 1);
config->ic_port[config->ic_nport].ir_end =
- resinfo[3] + (resinfo[4]<<8)
- + resinfo[6] - 1;
- config->ic_port[config->ic_nport].ir_size
- =
+ I16(resinfo + 3) + resinfo[6] - 1;
+ config->ic_port[config->ic_nport].ir_size =
resinfo[6];
+ if (resinfo[5] == 0) {
+ /* Make sure align is at least one */
+ resinfo[5] = 1;
+ }
config->ic_port[config->ic_nport].ir_align =
resinfo[5];
config->ic_nport++;
break;
case PNP_TAG_IO_FIXED:
+ if (bootverbose) {
+ printf("%s: adding io range "
+ "%#x-%#x, size=%#x, "
+ "align=%#x\n",
+ pnp_eisaformat(id),
+ I16(resinfo),
+ I16(resinfo) + resinfo[2] - 1,
+ resinfo[2],
+ 1);
+ }
if (config->ic_nport == ISA_NPORT) {
device_printf(parent, "too many ports");
scanning = 0;
break;
}
config->ic_port[config->ic_nport].ir_start =
- resinfo[0] + (resinfo[1]<<8);
+ I16(resinfo);
config->ic_port[config->ic_nport].ir_end =
- resinfo[0] + (resinfo[1]<<8)
- + resinfo[2] - 1;
+ I16(resinfo) + resinfo[2] - 1;
config->ic_port[config->ic_nport].ir_size
= resinfo[2];
config->ic_port[config->ic_nport].ir_align = 1;
config->ic_nport++;
break;
+ case PNP_TAG_END:
+ if (bootverbose) {
+ printf("%s: start dependant\n",
+ pnp_eisaformat(id));
+ }
+ scanning = 0;
+ break;
+
default:
/* Skip this resource */
device_printf(parent, "unexpected tag %d\n",
@@ -181,7 +232,7 @@ pnp_parse_resources(device_t dev, u_char *resources, int len)
scanning = 0;
continue;
}
- large_len = resp[0] + (resp[1] << 8);
+ large_len = I16(resp);
resp += 2;
scanning -= 2;
@@ -193,7 +244,8 @@ pnp_parse_resources(device_t dev, u_char *resources, int len)
resp += large_len;
scanning -= large_len;
- if (PNP_LRES_NUM(tag) == PNP_TAG_ID_ANSI) {
+ switch (PNP_LRES_NUM(tag)) {
+ case PNP_TAG_ID_ANSI:
if (large_len > sizeof(buf) - 1)
large_len = sizeof(buf) - 1;
bcopy(resinfo, buf, large_len);
@@ -205,32 +257,113 @@ pnp_parse_resources(device_t dev, u_char *resources, int len)
large_len--;
buf[large_len] = '\0';
device_set_desc_copy(dev, buf);
- continue;
- }
+ break;
+
+ case PNP_TAG_MEMORY_RANGE:
+ if (bootverbose) {
+ printf("%s: adding memory range "
+ "%#x-%#x, size=%#x, "
+ "align=%#x\n",
+ pnp_eisaformat(id),
+ I16(resinfo + 1)<<8,
+ (I16(resinfo + 3)<<8)
+ + I16(resinfo + 7) - 1,
+ I16(resinfo + 7),
+ I16(resinfo + 5));
+ }
- if (PNP_LRES_NUM(tag) != PNP_TAG_MEMORY_RANGE) {
- /* skip */
- continue;
- }
+ if (config->ic_nmem == ISA_NMEM) {
+ device_printf(parent, "too many memory ranges");
+ scanning = 0;
+ break;
+ }
- if (config->ic_nmem == ISA_NMEM) {
- device_printf(parent, "too many memory ranges");
- scanning = 0;
+ config->ic_mem[config->ic_nmem].ir_start =
+ I16(resinfo + 1)<<8;
+ config->ic_mem[config->ic_nmem].ir_end =
+ (I16(resinfo + 3)<<8)
+ + I16(resinfo + 7) - 1;
+ config->ic_mem[config->ic_nmem].ir_size =
+ I16(resinfo + 7);
+ config->ic_mem[config->ic_nmem].ir_align =
+ I16(resinfo + 5);
+ if (!config->ic_mem[config->ic_nmem].ir_align)
+ config->ic_mem[config->ic_nmem]
+ .ir_align = 0x10000;
+ config->ic_nmem++;
break;
- }
- config->ic_mem[config->ic_nmem].ir_start =
- (resinfo[4]<<8) + (resinfo[5]<<16);
- config->ic_mem[config->ic_nmem].ir_end =
- (resinfo[6]<<8) + (resinfo[7]<<16);
- config->ic_mem[config->ic_nmem].ir_size =
- (resinfo[10]<<8) + (resinfo[11]<<16);
- config->ic_mem[config->ic_nmem].ir_align =
- resinfo[8] + (resinfo[9]<<8);
- if (!config->ic_mem[config->ic_nmem].ir_align)
+ case PNP_TAG_MEMORY32_RANGE:
+ if (bootverbose) {
+ printf("%s: adding memory range "
+ "%#x-%#x, size=%#x, "
+ "align=%#x\n",
+ pnp_eisaformat(id),
+ I32(resinfo + 1),
+ I32(resinfo + 5)
+ + I32(resinfo + 13) - 1,
+ I32(resinfo + 13),
+ I32(resinfo + 9));
+ }
+
+ if (config->ic_nmem == ISA_NMEM) {
+ device_printf(parent, "too many memory ranges");
+ scanning = 0;
+ break;
+ }
+
+ config->ic_mem[config->ic_nmem].ir_start =
+ I32(resinfo + 1);
+ config->ic_mem[config->ic_nmem].ir_end =
+ I32(resinfo + 5)
+ + I32(resinfo + 13) - 1;
+ config->ic_mem[config->ic_nmem].ir_size =
+ I32(resinfo + 13);
config->ic_mem[config->ic_nmem].ir_align =
- 0x10000;
- config->ic_nmem++;
+ I32(resinfo + 9);
+ config->ic_nmem++;
+ break;
+
+ case PNP_TAG_MEMORY32_FIXED:
+ if (I32(resinfo + 5) == 0) {
+ if (bootverbose) {
+ printf("%s: skipping empty range\n",
+ pnp_eisaformat(id));
+ }
+ continue;
+ }
+ if (bootverbose) {
+ printf("%s: adding memory range "
+ "%#x-%#x, size=%#x\n",
+ pnp_eisaformat(id),
+ I32(resinfo + 1),
+ I32(resinfo + 1)
+ + I32(resinfo + 5) - 1,
+ I32(resinfo + 5));
+ }
+
+ if (config->ic_nmem == ISA_NMEM) {
+ device_printf(parent, "too many memory ranges");
+ scanning = 0;
+ break;
+ }
+
+ config->ic_mem[config->ic_nmem].ir_start =
+ I32(resinfo + 1);
+ config->ic_mem[config->ic_nmem].ir_end =
+ I32(resinfo + 1)
+ + I32(resinfo + 5) - 1;
+ config->ic_mem[config->ic_nmem].ir_size =
+ I32(resinfo + 5);
+ config->ic_mem[config->ic_nmem].ir_align = 1;
+ config->ic_nmem++;
+ break;
+
+ default:
+ /* Skip this resource */
+ device_printf(parent, "unexpected tag %d\n",
+ PNP_SRES_NUM(tag));
+ }
}
}
OpenPOWER on IntegriCloud