summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/isa/Makefile8
-rw-r--r--sys/dev/isa/devlist2h.awk82
-rw-r--r--sys/dev/isa/isapnp.c948
-rw-r--r--sys/dev/isa/isapnpreg.h59
-rw-r--r--sys/dev/isa/isapnpvar.h21
-rw-r--r--sys/dev/isa/pnpdevs338
-rw-r--r--sys/dev/isa/pnpdevs.h37
7 files changed, 1101 insertions, 392 deletions
diff --git a/sys/dev/isa/Makefile b/sys/dev/isa/Makefile
new file mode 100644
index 00000000000..04044a443c4
--- /dev/null
+++ b/sys/dev/isa/Makefile
@@ -0,0 +1,8 @@
+# $OpenBSD: Makefile,v 1.1 1997/07/12 23:22:00 weingart Exp $
+# $NetBSD: Makefile,v 1.1 1995/06/18 01:07:04 cgd Exp $
+
+AWK= awk
+
+pnpdevs.h: pnpdevs devlist2h.awk
+ /bin/rm -f pnpdevs.h
+ ${AWK} -f devlist2h.awk pnpdevs
diff --git a/sys/dev/isa/devlist2h.awk b/sys/dev/isa/devlist2h.awk
new file mode 100644
index 00000000000..d21fa27c21b
--- /dev/null
+++ b/sys/dev/isa/devlist2h.awk
@@ -0,0 +1,82 @@
+#! /usr/bin/awk -f
+# $NetBSD: devlist2h.awk,v 1.2 1996/01/22 21:08:09 cgd Exp $
+#
+# Copyright (c) 1995, 1996 Christopher G. Demetriou
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by Christopher G. Demetriou.
+# 4. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+BEGIN {
+ nproducts = 0
+ dfile="pnpdevs.h"
+}
+NR == 1 {
+ VERSION = $0
+ gsub("\\$", "", VERSION)
+
+ printf("/*\n") > dfile
+ printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
+ > dfile
+ printf(" *\n") > dfile
+ printf(" * generated from:\n") > dfile
+ printf(" *\t%s\n", VERSION) > dfile
+ printf(" */\n") > dfile
+
+ next
+}
+{
+ if ($1 == "")
+ next
+ if (substr($1,0,1) == "#")
+ next
+ if (substr($2,0,1) == "#")
+ next
+ nproducts++
+ products[nproducts, 1] = $1; # driver name
+ products[nproducts, 2] = $2; # pnp id
+# if ($3 && substr($3,0,1) == "#")
+# products[nproducts, 3] = substr($3, 1);
+# printf("%s %s %s\n", $1, $2, products[nproducts, 3]);
+
+ next
+}
+END {
+ # print out the match tables
+
+ printf("\n") > dfile
+
+ printf("struct pnp_knowndev pnp_knowndevs[] = {\n") > dfile
+ for (i = 1; i <= nproducts; i++) {
+ printf("\t{ \"%s\", \"%s\" },",
+ products[i, 2], products[i, 1]) \
+ > dfile
+ if (products[i, 3])
+ printf("\t/* %s */", products[i, 3]) > dfile
+ printf("\n") > dfile
+ }
+ printf("\t{ NULL, NULL, }\n") > dfile
+ printf("};\n") > dfile
+}
diff --git a/sys/dev/isa/isapnp.c b/sys/dev/isa/isapnp.c
index 7b845341f32..a6fe4cf7ec1 100644
--- a/sys/dev/isa/isapnp.c
+++ b/sys/dev/isa/isapnp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isapnp.c,v 1.9 1996/11/29 22:55:03 niklas Exp $ */
+/* $OpenBSD: isapnp.c,v 1.10 1997/07/12 23:22:01 weingart Exp $ */
/*
* Copyright (c) 1996, Shawn Hsiao <shawn@alpha.secc.fju.edu.tw>
@@ -66,8 +66,9 @@
#include <dev/isa/isavar.h>
-#include "isapnpreg.h"
-#include "isapnpvar.h"
+#include <dev/isa/isapnpreg.h>
+#include <dev/isa/isapnpvar.h>
+#include <dev/isa/pnpdevs.h>
#define SEND(d, r) { bus_space_write_1(sc->iot, sc->addrh, 0, d); \
bus_space_write_1(sc->iot, sc->wdh, 0, r); }
@@ -77,6 +78,15 @@ void isapnpattach __P((struct device *, struct device *, void *));
int isapnpprint __P((void *aux, const char *pnp));
int isapnpsubmatch __P((struct device *parent, void *match, void *aux));
+/* XXX */
+struct emap {
+ int whatever;
+};
+
+void add_extent __P((struct emap *, long, int));
+struct emap *find_emap __P((char *));
+int probe_extent __P((struct emap *, int, int));
+
struct isapnp_softc {
struct device sc_dev;
struct device *parent;
@@ -85,7 +95,6 @@ struct isapnp_softc {
bus_space_handle_t addrh;
bus_space_handle_t wdh;
bus_space_handle_t rdh;
- int rd_offset;
int rd_port;
@@ -100,28 +109,24 @@ struct cfdriver isapnp_cd = {
NULL, "isapnp", DV_DULL, 1
};
-void postisapnpattach __P((struct device *parent,
- struct device *self, void *aux));
-static int isapnpquery __P((struct isapnp_softc *sc,
- u_int32_t dev_id, struct isa_attach_args *ia));
-static void send_Initiation_LFSR __P((struct isapnp_softc *sc));
-static int get_serial __P((struct isapnp_softc *sc, unsigned char *data));
-static int isolation_protocol __P((struct isapnp_softc *sc));
-static void read_config __P((struct isapnp_softc *sc,
- struct cardinfo *card, int csn));
-static int get_resource_info __P((struct isapnp_softc *sc,
- char *buffer, int len));
-static void config_device __P((struct isapnp_softc *sc,
- struct isa_attach_args *data));
-static int find_free_irq __P((int irq_mask));
-static int find_free_drq __P((int drq_mask));
-static int find_free_io __P((struct isapnp_softc *sc, int desc,
- int min_addr, int max_addr, int size,
- int alignment, int range_check));
-static int handle_small_res __P((unsigned char *resinfo,
- int item, int len, struct cardinfo *card));
-static void handle_large_res __P((unsigned char *resinfo,
- int item, int len, struct cardinfo *card));
+int isapnpquery __P((struct isapnp_softc *, u_int32_t,
+ struct isa_attach_args *));
+void send_Initiation_LFSR __P((struct isapnp_softc *));
+int get_serial __P((struct isapnp_softc *, unsigned char *));
+int isolation_protocol __P((struct isapnp_softc *));
+void read_config __P((struct isapnp_softc *, struct cardinfo *, int));
+int get_resource_info __P((struct isapnp_softc *, u_char *, int));
+void config_device __P((struct isapnp_softc *, struct isa_attach_args *));
+int find_free_irq __P((int));
+int find_free_drq __P((int));
+int find_free_io __P((struct isapnp_softc *, int, int, int, int,
+ int, int));
+void postisapnpattach __P((struct device *, struct device *, void *));
+char *searchpnpdevtab __P((char *));
+char *makepnpname __P((u_int32_t));
+void isapnpextent __P((struct isa_attach_args *));
+int handle_small_res __P((unsigned char *, int, int, struct cardinfo *));
+void handle_large_res __P((unsigned char *, int, int, struct cardinfo *));
int
isapnpmatch(parent, match, aux)
@@ -143,10 +148,6 @@ isapnpattach(parent, self, aux)
struct isa_softc *isc = (void *)parent;
struct isapnp_softc *sc = (void *)self;
struct isa_attach_args *ia = aux;
-#ifdef notdef
- struct cardinfo *card;
- int iobase;
-#endif
int num_pnp_devs;
/*
@@ -158,28 +159,75 @@ isapnpattach(parent, self, aux)
sc->parent = parent;
TAILQ_INIT(&sc->q_card);
- /*
- * WRITE_DATA port is located at fixed offset (0x0800)
- * from ADDRESS port,
- * and valid READ_DATA ports are from 0x203 to 0x3ff.
+ /* The bus_space_*() stuff needs to be done differently.
+ * With PNP you want to be able to allocate a region,
+ * but not necessarily map it. Why? The drivers themselves
+ * should really map the bus regions they need. So, which
+ * way should this be done?
+ *
+ * Me thinks to seperate the resource allocation and mapping
+ * of said resources.
*/
- if (bus_space_map(sc->iot, ADDRESS, 1, 0, &(sc->addrh)) ||
- bus_space_map(sc->iot, ADDRESS+0x0800, 1, 0, &(sc->wdh)) ||
- bus_space_map(sc->iot, 0x0200, 0x200, 0, &(sc->rdh)))
- panic("isapnpattach: io mapping failed");
- /* Try various READ_DATA ports from 0x203-0x3ff */
+ /* ADDRESS and WRITE_DATA ports are static */
+ if (bus_space_map(sc->iot, ADDRESS, 1, 0, &(sc->addrh)))
+ panic("isapnpattach: io mapping for ADDRESS port failed");
+ if (bus_space_map(sc->iot, WRITE_DATA, 1, 0, &(sc->wdh)))
+ panic("isapnpattach: io mapping for WRITE_DATA port failed");
+
+ /* Try various READ_DATA ports from 0x203-0x3ff
+ * We try in increments of 16. Note that the rd_port
+ * figure is really port number ((rd_port << 2) | 0x3).
+ */
for (sc->rd_port = 0x80; (sc->rd_port < 0xff); sc->rd_port += 0x10) {
+ int real_port = (sc->rd_port << 2) | 0x3;
+
+ /* Try to map a READ_DATA port */
+ if (bus_space_map(sc->iot, real_port, 1, 0, &(sc->rdh))) {
+#ifdef DEBUG
+ printf("\nisapnpattach: READ_PORT 0x%x failed", real_port);
+#endif
+ continue;
+ }
+
+ /* Try isolation protocol on this port */
num_pnp_devs = isolation_protocol(sc);
- if (num_pnp_devs) {
- printf(": readport 0x%x, %d devices",
- (sc->rd_port << 2) | 0x3, num_pnp_devs);
+ if (num_pnp_devs)
break;
- }
+
+ /* isolation protocol failed for this port */
+ bus_space_unmap(sc->iot, real_port, 1);
}
- if (num_pnp_devs == 0)
- printf(": 0 devices");
- printf("\n");
+ printf(": readport 0x%x, %d devices\n",
+ (sc->rd_port << 2) | 0x3, num_pnp_devs);
+}
+
+char *
+searchpnpdevtab(name)
+ char *name;
+{
+ int i;
+
+ for (i = 0; pnp_knowndevs[i].pnpid; i++)
+ if (strcmp(pnp_knowndevs[i].pnpid, name) == 0)
+ return (pnp_knowndevs[i].driver);
+ return (NULL);
+}
+
+char *
+makepnpname(id)
+ u_int32_t id;
+{
+ static char name[8];
+ u_char info[4];
+
+ bcopy(&id, info, sizeof id);
+ sprintf(name, "%c%c%c%02x%02x",
+ ((info[0] & 0x7c) >> 2) + 64,
+ (((info[0] & 0x03) << 3) | ((info[1] & 0xe0) >> 5)) + 64,
+ (info[1] & 0x1f) + 64,
+ info[2], info[3]);
+ return (name);
}
void
@@ -192,11 +240,15 @@ postisapnpattach(parent, self, aux)
struct isabus_attach_args *iba = aux;
struct cardinfo *card;
struct devinfo *dev;
+ struct device *r;
+#if 0
+ extern char *msgs[];
+#endif
+ void *match;
- for (card = sc->q_card.tqh_first; card;
- card = card->card_link.tqe_next) {
- for (dev = card->q_dev.tqh_first; dev;
- dev = dev->dev_link.tqe_next) {
+ printf("postisapnpattach:\n");
+ for (card = sc->q_card.tqh_first; card; card = card->card_link.tqe_next) {
+ for (dev = card->q_dev.tqh_first; dev; dev = dev->dev_link.tqe_next) {
struct isa_attach_args ia;
bzero(&ia, sizeof(ia));
@@ -206,20 +258,44 @@ postisapnpattach(parent, self, aux)
ia.comp_id = dev->comp_id;
ia.csn = card->csn;
ia.ldn = dev->ldn;
- ia.ia_delayioh = isc->sc_delayioh;
- isapnpquery(sc, ia.id, &ia);
- if (!config_found_sm(self, &ia, isapnpprint,
- isapnpsubmatch)) {
+ if (!isapnpquery(sc, ia.id, &ia)) {
+ printf("isapnpquery failed\n");
+ goto bail;
+ }
+ printf("id %x comp_id %x csn %x ldn %x\n", ia.id,
+ ia.comp_id, ia.csn, ia.ldn);
+ printf("io %x/%x mem %x/%x irq %x drq %x\n",
+ ia.ia_iobase, ia.ia_iosize, ia.ia_maddr,
+ ia.ia_msize, ia.ia_irq, ia.ia_drq);
+ match = config_search(isapnpsubmatch, self, &ia);
+ printf("config search %x\n", match);
+
+ if (match) {
+ r = config_attach(self, match, &ia, NULL);
+ printf("config attach %x\n", r);
+ }
+
+ if (match == NULL || r == NULL) {
+bail:
+#if 0
+ printf(msgs[isapnpprint(&ia, self->dv_xname)]);
+#endif
+#if 1
/*
+ * XXX does this shut down devices we
+ * are using??
* supplied configuration fails,
* disable the device.
*/
SEND(WAKE, ia.csn);
SEND(SET_LDN, ia.ldn);
SEND(ACTIVATE, 0);
+#endif
}
}
+
+ delay(1000*500);
}
}
@@ -229,50 +305,79 @@ isapnpprint(aux, pnp)
const char *pnp;
{
register struct isa_attach_args *ia = aux;
- unsigned char info[4];
- struct emap *io_map, *mem_map, *irq_map, *drq_map;
- io_map = find_emap("io");
- mem_map = find_emap("mem");
- irq_map = find_emap("irq");
- drq_map = find_emap("drq");
-
- bcopy(&ia->id, info, 4);
if (pnp) {
- printf("device <%c%c%c%02x%02x> at %s",
- ((info[0] & 0x7c) >> 2) + 64,
- (((info[0] & 0x03) << 3) |
- ((info[1] & 0xe0) >> 5)) + 64,
- (info[1] & 0x1f) + 64,
- info[2], info[3], pnp);
- }
- if (!pnp) {
+ printf("device ");
+ if (ia->comp_id)
+ printf("<%s> ", makepnpname(ia->comp_id));
+ printf("<%s> at %s", makepnpname(ia->id), pnp);
+ } else {
if (ia->ia_iosize)
printf(" port 0x%x", ia->ia_iobase);
- if (ia->ia_iosize > 1) {
- printf("-0x%x",
- ia->ia_iobase + ia->ia_iosize - 1);
- add_extent(io_map, ia->ia_iobase, ia->ia_iosize);
- }
+ if (ia->ia_iosize > 1)
+ printf("-0x%x", ia->ia_iobase + ia->ia_iosize - 1);
if (ia->ia_msize)
printf(" iomem 0x%x", ia->ia_maddr);
- if (ia->ia_msize > 1) {
- printf("-0x%x",
- ia->ia_maddr + ia->ia_msize - 1);
- add_extent(mem_map, ia->ia_maddr, ia->ia_msize);
- }
- if (ia->ia_irq != IRQUNK) {
+ if (ia->ia_msize > 1)
+ printf("-0x%x", ia->ia_maddr + ia->ia_msize - 1);
+ if (ia->ia_irq != IRQUNK)
printf(" irq %d", ia->ia_irq);
- add_extent(irq_map, ia->ia_irq, 1);
- }
- if (ia->ia_drq != DRQUNK) {
+ if (ia->ia_drq != DRQUNK)
printf(" drq %d", ia->ia_drq);
- add_extent(drq_map, ia->ia_drq, 1);
- }
}
return(UNCONF);
}
+/* XXX */
+/* Always return success */
+int
+probe_extent(ext, s, l)
+ struct emap *ext;
+ int s, l;
+{
+ return(0);
+}
+
+/* XXX */
+/* Return bogus map */
+struct emap *
+find_emap(key)
+ char *key;
+{
+ return(NULL);
+}
+
+/* XXX */
+/* Do nothing at all */
+void
+add_extent(m, base, size)
+ struct emap *m;
+ long base;
+ int size;
+{
+}
+
+void
+isapnpextent(ia)
+ struct isa_attach_args *ia;
+{
+ struct emap *io_map, *mem_map, *irq_map, *drq_map;
+
+ io_map = find_emap("io");
+ mem_map = find_emap("mem");
+ irq_map = find_emap("irq");
+ drq_map = find_emap("drq");
+
+ if (ia->ia_iosize > 0)
+ add_extent(io_map, ia->ia_iobase, ia->ia_iosize);
+ if (ia->ia_msize > 0)
+ add_extent(mem_map, ia->ia_maddr, ia->ia_msize);
+ if (ia->ia_irq != IRQUNK)
+ add_extent(irq_map, ia->ia_irq, 1);
+ if (ia->ia_drq != DRQUNK)
+ add_extent(drq_map, ia->ia_drq, 1);
+}
+
int
isapnpsubmatch(parent, match, aux)
struct device *parent;
@@ -281,14 +386,35 @@ isapnpsubmatch(parent, match, aux)
struct device *dev = match;
struct cfdata *cf = dev->dv_cfdata;
struct isa_attach_args *ia = aux;
- int ret;
+ char *name, *dname;
+ int ret = 0;
- if (cf->cf_pnpid == ia->id ||
- cf->cf_pnpid == ia->comp_id) {
+ /* XXX should check for id/comp_id being 0 */
+ if (cf->cf_pnpid != 0 &&
+ (ia->id == cf->cf_pnpid || ia->comp_id == cf->cf_pnpid)) {
+ printf("isapnpsubmatch going\n");
ret = (*cf->cf_attach->ca_match)(parent, match, aux);
- return (ret);
+ goto done;
}
- return (0);
+
+ if (ia->comp_id) {
+ name = makepnpname(ia->comp_id);
+ dname = searchpnpdevtab(name);
+ if (dname && strcmp(dname, cf->cf_driver->cd_name) == 0) {
+ ret = (*cf->cf_attach->ca_match)(parent, match, aux);
+ goto done;
+ }
+ }
+ name = makepnpname(ia->id);
+ dname = searchpnpdevtab(name);
+ if (dname && strcmp(dname, cf->cf_driver->cd_name) == 0) {
+ printf("match %s\n", dname);
+ ret = (*cf->cf_attach->ca_match)(parent, match, aux);
+ }
+done:
+ if (ret)
+ isapnpextent(ia);
+ return (ret);
}
/*
@@ -304,182 +430,242 @@ isapnpquery(sc, dev_id, ipa)
struct devinfo *dev;
struct confinfo *conf;
struct isa_attach_args *tmp;
-#ifdef notdef
- int irq, drq, iobase, mbase;
+ int c, i, j, fail, success = 0;
+
+ {
+ char resp[10];
+ printf("isapnpquery? ");
+ getsn(resp, sizeof resp);
+ }
+ for (card = sc->q_card.tqh_first; card; card = card->card_link.tqe_next) {
+ for (dev = card->q_dev.tqh_first; dev; dev = dev->dev_link.tqe_next) {
+ if (dev_id != dev->id && dev_id != dev->comp_id)
+ continue;
+ tmp = malloc(sizeof(*tmp), M_DEVBUF, M_WAITOK);
+ bzero(tmp, sizeof(*tmp));
+ SEND(WAKE, card->csn);
+ SEND(SET_LDN, dev->ldn);
+
+ /* Find a usable and acceptable configuration */
+ for (conf = dev->q_conf.tqh_first; conf;
+ conf = conf->conf_link.tqe_next) {
+ /*
+ * BASIC CONFIGURATION
+ */
+ if (conf->prio == BASIC_CONFIGURATION) {
+ for (c=0; c < 2; c++) {
+ ipa->irq[c].num = -1;
+ if (conf->irq[c] == 0)
+ continue;
+#if 0
+ printf("irq %d %d %d\n", c,
+ conf->irq[c]->num,
+ conf->irq[c]->info);
#endif
- int c, i, j, fail, success;
-
- for (card = sc->q_card.tqh_first; card;
- card = card->card_link.tqe_next) {
- for (dev = card->q_dev.tqh_first; dev;
- dev = dev->dev_link.tqe_next) {
- if (dev_id == dev->id ||
- dev_id == dev->comp_id) {
- tmp = malloc(sizeof(struct isa_attach_args), M_DEVBUF, M_WAITOK);
- bzero(tmp, sizeof(struct isa_attach_args));
- SEND(WAKE, card->csn);
- SEND(SET_LDN, dev->ldn);
-
- for (conf = dev->q_conf.tqh_first; conf;
- conf = conf->conf_link.tqe_next) {
- /*
- * BASIC CONFIGURATION
- */
- if (conf->prio == BASIC_CONFIGURATION) {
- if (conf->irq[0]) {
- for (c = 0; conf->irq[c] && c < 2; c++) {
- i = conf->irq[c]->num;
- j = find_free_irq(i);
- if (j) {
- ipa->irq[c].num = j;
- /*
- * if the interrupt can not be configured as
- * low true level-triggered,
- * then set it to high true edge-triggered.
- * XXX needs rework
- */
- if (conf->irq[c]->info & 0x08) {
- ipa->irq[c].type = 0x01;
- }
- else {
- ipa->irq[c].type = 0x10;
- }
- }
- }
- }
- if (conf->dma[0]) {
- for (c = 0; conf->dma[c] && c < 2; c++) {
- i = conf->dma[c]->channel;
- j = find_free_drq(i);
- if (j) {
- ipa->drq[c] = j;
- }
- }
- }
- if (conf->io[0]){
- for (c = 0; conf->io[c] && c < 8; c++) {
- ipa->port[c] = find_free_io(sc, c,
- conf->io[c]->min_base,
- conf->io[c]->max_base,
- conf->io[c]->size,
- conf->io[c]->alignment,
- dev->io_range_check);
- }
- }
- /* XXX mem */
- if (conf->mem[0]) {
- for (c = 0; conf->mem[c] && c < 4; c++) {
- ipa->mem[c].base = conf->mem[c]->min_base;
- ipa->mem[c].range = conf->mem[c]->size;
- }
- }
- }
+ i = conf->irq[c]->num;
+ if (i == 0)
+ continue;
+ j = find_free_irq(i);
+ if (j != 0)
+ continue;
+ ipa->irq[c].num = j;
+
+ /*
+ * XXX if the interrupt cannot
+ * be configured as low true
+ * level-triggered then set it
+ * to high true edge-triggered.
+ */
+ if (conf->irq[c]->info & 0x08)
+ ipa->irq[c].type = 0x01;
+ else
+ ipa->irq[c].type = 0x10;
+ }
+ for (c=0; c < 2; c++) {
+ ipa->drq[c] = -1;
+ if (conf->dma[c] == 0)
+ continue;
+#if 0
+ printf("dma %d %d\n", c,
+ conf->dma[c]->channel);
+#endif
+ i = conf->dma[c]->channel;
+ if (i == 0)
+ continue;
+ j = find_free_drq(i);
+ if (j)
+ ipa->drq[c] = j;
+ }
+ for (c=0; c < 8; c++) {
+ if (conf->io[c] == 0)
+ continue;
+#if 0
+ printf("io %d %d %d %d %d %d\n",
+ c, conf->io[c]->min_base,
+ conf->io[c]->max_base,
+ conf->io[c]->size,
+ conf->io[c]->alignment,
+ dev->io_range_check);
+#endif
+ ipa->port[c] = find_free_io(sc,
+ c, conf->io[c]->min_base,
+ conf->io[c]->max_base,
+ conf->io[c]->size,
+ conf->io[c]->alignment,
+ dev->io_range_check);
+ }
+ for (c=0; c < 4; c++) {
+ if (conf->mem[c] == 0)
+ continue;
+#if 0
+ printf("mem %d %d %d\n", c,
+ conf->mem[c]->min_base,
+ conf->mem[c]->size);
+#endif
+ ipa->mem[c].base =
+ conf->mem[c]->min_base;
+ ipa->mem[c].range =
+ conf->mem[c]->size;
+ }
+ }
- /*
- * DEPENDENT FUNCTION
- */
- fail = 0; success = 1;
- if (conf->irq[0]) {
- for (c = 0; conf->irq[c] && c < 2; c++) {
- i = conf->irq[c]->num;
- j = find_free_irq(i);
- if (j) {
- tmp->irq[c].num = j;
- /*
- * if the interrupt can not be
- * low true level-triggered,
- * then set it to high true edge-triggered.
- * XXX rework
- */
- if (conf->irq[c]->info & 0x08) {
- tmp->irq[c].type = 0x01;
- }
- else {
- tmp->irq[c].type = 0x10;
- }
- }
- else {
- fail = 1;
- success = 0;
- break;
- }
- }
- }
- if (conf->dma[0]) {
- for (c = 0; conf->dma[c] && c < 2; c++) {
- i = conf->dma[c]->channel;
- j = find_free_drq(i);
- if (j) {
- tmp->drq[c] = j;
- }
- else {
- fail = 1;
- success = 0;
- break;
- }
- }
- }
- if (conf->io[0]) {
- for (c = 0; conf->io[c] && c < 8; c++) {
- tmp->port[c] = find_free_io(sc, c,
- conf->io[c]->min_base,
- conf->io[c]->max_base,
- conf->io[c]->size,
- conf->io[c]->alignment,
- dev->io_range_check);
- if (!tmp->port[c]) {
- fail = 1;
- success = 0;
- break;
- }
- }
- }
- if (conf->mem[0]) {
- for (c = 0; conf->mem[c] && c < 4; c++) {
- tmp->mem[c].base = conf->mem[c]->min_base;
- tmp->mem[c].range = conf->mem[c]->size;
-
- if (!tmp->mem[c].base) {
- fail = 1;
- success = 0;
- break;
- }
- }
- }
+ /*
+ * DEPENDENT FUNCTION
+ */
+ fail = 0;
+ success = 1;
+ for (c=0; conf->irq[c] && c < 2; c++) {
+ i = conf->irq[c]->num;
+ tmp->irq[c].num = -1;
+ if (i == 0)
+ continue;
+ j = find_free_irq(i);
+ if (j) {
+ tmp->irq[c].num = j;
+ if (conf->irq[c]->info & 0x08)
+ tmp->irq[c].type = 0x01;
+ else
+ tmp->irq[c].type = 0x10;
+ } else {
+ fail = 1;
+#if 0
+ printf("irq bail\n");
+#endif
+ success = 0;
+ break;
+ }
+ }
+ for (c=0; conf->dma[c] && c < 2; c++) {
+ i = conf->dma[c]->channel;
+ tmp->drq[c] = -1;
+ if (i == 0)
+ continue;
+ j = find_free_drq(i);
+ if (j)
+ tmp->drq[c] = j;
+ else {
+ fail = 1;
+#if 0
+ printf("dma bail\n");
+#endif
+ success = 0;
+ break;
+ }
+ }
- if (fail) {
- continue;
- }
- }
+#if 0
+ printf("ports:");
+#endif
+ for (c=0; conf->io[c] && c < 8; c++) {
+#if 0
+ printf("%x/%x ", conf->io[c]->min_base,
+ conf->io[c]->size);
+#endif
+ if (conf->io[c]->size == 0)
+ continue;
+ tmp->port[c] = find_free_io(sc, c,
+ conf->io[c]->min_base,
+ conf->io[c]->max_base,
+ conf->io[c]->size,
+ conf->io[c]->alignment,
+ dev->io_range_check);
+ if (tmp->port[c] == NULL) {
+ fail = 1;
+#if 0
+ printf("io bail\n");
+#endif
+ success = 0;
+ break;
+ }
+ }
+#if 0
+ printf("\n");
+
+ printf("mem:");
+#endif
+ for (c=0; conf->mem[c] && c < 4; c++) {
+#if 0
+ printf("%x/%x ", conf->mem[c]->min_base,
+ conf->mem[c]->size);
+#endif
+ if (conf->mem[c]->size == 0)
+ continue;
+ tmp->mem[c].base =
+ conf->mem[c]->min_base;
+ tmp->mem[c].range =
+ conf->mem[c]->size;
+ if (tmp->mem[c].base == NULL) {
+ fail = 1;
+#if 0
+ printf("mem bail\n");
+#endif
+ success = 0;
+ break;
+ }
+ }
+#if 0
+ printf("\n");
+#endif
+
+ if (fail) {
+ continue;
+ }
- if (!success) {
- return(0);
- }
+ if (!success) {
+ free(tmp, M_DEVBUF);
+#if 0
+ printf("bailing\n");
+#endif
+ return(0);
+ }
+ }
- for (c = 0; c < 2; c++) {
- if (tmp->irq[c].num) {
- ipa->irq[c].num = tmp->irq[c].num;
- ipa->irq[c].type = tmp->irq[c].type;
- }
- }
- for (c = 0; c < 8; c++) {
- if (tmp->port[c]) {
- ipa->port[c] = tmp->port[c];
- }
- }
- for (c = 0; c < 4; c++) {
- if (tmp->mem[c].base) {
- ipa->mem[c].base = tmp->mem[c].base;
+
+ /* Copy usable configuration */
+ for (c = 0; c < 2; c++) {
+ if (tmp->irq[c].num) {
+ ipa->irq[c].num = tmp->irq[c].num;
+ ipa->irq[c].type = tmp->irq[c].type;
+ }
+ }
+ for (c = 0; c < 8; c++) {
+ if (tmp->port[c])
+ ipa->port[c] = tmp->port[c];
+ }
+ for (c = 0; c < 4; c++) {
+ if (tmp->mem[c].base)
+ ipa->mem[c].base = tmp->mem[c].base;
+ }
+
+ /* Configure device */
+ config_device(sc, ipa);
+ ipa->ia_iobase = ipa->port[0];
+ ipa->ia_iosize = 16; /* XXX */
+ ipa->ia_irq = ipa->irq[0].num;
+ ipa->ia_drq = ipa->drq[0];
+ free(tmp, M_DEVBUF);
+ return(1);
}
- }
- config_device(sc, ipa);
- ipa->ia_iobase = ipa->port[0];
- ipa->ia_irq = ipa->irq[0].num;
- ipa->ia_drq = ipa->drq[0];
- free(tmp, M_DEVBUF);
- return(1);
- }
- }
}
return(0);
}
@@ -488,7 +674,7 @@ isapnpquery(sc, dev_id, ipa)
* Send Initiation LFSR as described in "Plug and Play ISA Specification,
* Intel May 94."
*/
-static void
+void
send_Initiation_LFSR(sc)
struct isapnp_softc *sc;
{
@@ -512,7 +698,7 @@ send_Initiation_LFSR(sc)
/*
* Get the device's serial number. Returns 1 if the serial is valid.
*/
-static int
+int
get_serial(sc, data)
struct isapnp_softc *sc;
unsigned char *data;
@@ -524,15 +710,13 @@ get_serial(sc, data)
bzero(data, sizeof(char) * 9);
- sc->rd_offset = ((sc->rd_port - 0x80) << 2) | 0x3;
for (i = 0; i < 72; i++) {
- bit = bus_space_read_1(iot, rdh, sc->rd_offset) == 0x55;
+ bit = bus_space_read_1(iot, rdh, 0) == 0x55;
delay(250); /* Delay 250 usec */
/* Can't Short Circuit the next evaluation, so 'and' is last */
- bit = (bus_space_read_1(iot, rdh, sc->rd_offset) == 0xaa) &&
- bit;
+ bit = (bus_space_read_1(iot, rdh, 0) == 0xaa) && bit;
delay(250); /* Delay 250 usec */
valid = valid || bit;
@@ -549,30 +733,39 @@ get_serial(sc, data)
return valid;
}
-static int
+int
get_resource_info(sc, buffer, len)
struct isapnp_softc *sc;
- char *buffer;
+ u_char *buffer;
int len;
{
int i, j;
+#if 0
+ printf("gri: ");
+#endif
for (i = 0; i < len; i++) {
bus_space_write_1(sc->iot, sc->addrh, 0, STATUS);
for (j = 0; j < 100; j++) {
- if ((bus_space_read_1(sc->iot, sc->rdh, sc->rd_offset))
- & 0x1)
+ if ((bus_space_read_1(sc->iot, sc->rdh, 0)) & 0x1)
break;
delay(1);
}
if (j == 100) {
- printf("%s: failed to report resource data\n",
+ printf("isapnp: %s failed to report resource data\n",
sc->sc_dev.dv_xname);
return 0;
}
bus_space_write_1(sc->iot, sc->addrh, 0, RESOURCE_DATA);
- buffer[i] = bus_space_read_1(sc->iot, sc->rdh, sc->rd_offset);
+ buffer[i] = bus_space_read_1(sc->iot, sc->rdh, 0);
+
+#if 0
+ printf("%2x ", buffer[i]);
+#endif
}
+#if 0
+ printf("\n");
+#endif
return 1;
}
@@ -585,7 +778,7 @@ get_resource_info(sc, buffer, len)
*
* XXX checksum is ignored now ...
*/
-static int
+int
handle_small_res(resinfo, item, len, card)
unsigned char *resinfo;
int item, len;
@@ -610,7 +803,7 @@ handle_small_res(resinfo, item, len, card)
* if the resource data is not enclosed in a START_DEPEND_FUNC and
* a END_DEPEND_FUNC, it's the basic configuration.
*
- * we simple treat is as a special case.
+ * we simply treat it as a special case.
*/
card->dev->basic = malloc(sizeof(struct confinfo), M_DEVBUF, M_WAITOK);
TAILQ_INSERT_TAIL(&card->dev->q_conf, card->dev->basic, conf_link);
@@ -627,29 +820,29 @@ handle_small_res(resinfo, item, len, card)
card->dev->comp_id = *(u_int32_t *)resinfo;
break;
case IRQ_FORMAT:
- for (i = 0; card->dev->conf->irq[i]; i++) ;
+ for (i = 0; card->dev->conf->irq[i]; i++)
+ ;
card->dev->conf->irq[i] = malloc(sizeof(struct irq_format),
- M_DEVBUF, M_WAITOK);
- card->dev->conf->irq[i]->num = resinfo[0] | resinfo[1] << 8;
- if (len == 3) {
+ M_DEVBUF, M_WAITOK);
+ card->dev->conf->irq[i]->num = resinfo[0] | (resinfo[1] << 8);
+ if (len == 3)
card->dev->conf->irq[i]->info = resinfo[2];
- }
- else {
+ else
card->dev->conf->irq[i]->info = 0;
- }
break;
case DMA_FORMAT:
- for (i = 0; card->dev->conf->dma[i]; i++) ;
+ for (i = 0; card->dev->conf->dma[i]; i++)
+ ;
card->dev->conf->dma[i] = malloc(sizeof(struct dma_format),
- M_DEVBUF, M_WAITOK);
+ M_DEVBUF, M_WAITOK);
card->dev->conf->dma[i]->channel = resinfo[0];
card->dev->conf->dma[i]->info = resinfo[1];
break;
case START_DEPEND_FUNC:
card->dev->conf = malloc(sizeof(struct confinfo),
- M_DEVBUF, M_WAITOK);
+ M_DEVBUF, M_WAITOK);
TAILQ_INSERT_TAIL(&card->dev->q_conf, card->dev->conf,
- conf_link);
+ conf_link);
card->dev->conf->prio = ACCEPTABLE_CONFIGURATION;
bzero(card->dev->conf->irq, 2*sizeof(void *));
bzero(card->dev->conf->dma, 2*sizeof(void *));
@@ -660,19 +853,19 @@ handle_small_res(resinfo, item, len, card)
switch (resinfo[0]) {
case GOOD_CONFIGURATION:
card->dev->conf->prio =
- GOOD_CONFIGURATION;
+ GOOD_CONFIGURATION;
break;
case ACCEPTABLE_CONFIGURATION:
card->dev->conf->prio =
- ACCEPTABLE_CONFIGURATION;
+ ACCEPTABLE_CONFIGURATION;
break;
case SUBOPTIMAL_CONFIGURATION:
card->dev->conf->prio =
- SUBOPTIMAL_CONFIGURATION;
+ SUBOPTIMAL_CONFIGURATION;
break;
default:
card->dev->conf->prio =
- RESERVED_CONFIGURATION;
+ RESERVED_CONFIGURATION;
break;
}
}
@@ -680,28 +873,29 @@ handle_small_res(resinfo, item, len, card)
case END_DEPEND_FUNC:
break;
case IO_PORT_DESC:
- for (i = 0; card->dev->conf->io[i]; i++) ;
+ for (i = 0; card->dev->conf->io[i]; i++)
+ ;
card->dev->conf->io[i] = malloc(sizeof(struct io_descriptor),
- M_DEVBUF, M_WAITOK);
+ M_DEVBUF, M_WAITOK);
card->dev->conf->io[i]->type = 0; /* 0 for normal I/O desc. */
card->dev->conf->io[i]->info = resinfo[0];
card->dev->conf->io[i]->min_base =
- resinfo[1] | resinfo[2] << 8;
+ resinfo[1] | (resinfo[2] << 8);
card->dev->conf->io[i]->max_base =
- resinfo[3] | resinfo[4] << 8;
+ resinfo[3] | (resinfo[4] << 8);
card->dev->conf->io[i]->alignment = resinfo[5];
card->dev->conf->io[i]->size = resinfo[6];
break;
case FIXED_IO_PORT_DESC:
for (i = 0; card->dev->conf->io[i]; i++) ;
card->dev->conf->io[i] = malloc(sizeof(struct io_descriptor),
- M_DEVBUF, M_WAITOK);
+ M_DEVBUF, M_WAITOK);
card->dev->conf->io[i]->type = 1; /* 1 for fixed I/O desc. */
card->dev->conf->io[i]->info = 0;
card->dev->conf->io[i]->min_base =
- resinfo[0] | (resinfo[1] & 0x3) << 8;
+ resinfo[0] | (resinfo[1] & 0x3) << 8;
card->dev->conf->io[i]->max_base =
- card->dev->conf->io[i]->min_base;
+ card->dev->conf->io[i]->min_base;
card->dev->conf->io[i]->alignment = 0;
card->dev->conf->io[i]->size = resinfo[2];
break;
@@ -709,13 +903,16 @@ handle_small_res(resinfo, item, len, card)
/*
* XXX checksum is ignored
*/
+#if 0
+ printf("end of res\n");
+#endif
return(1);
}
return(0);
}
-static void
+void
handle_large_res(resinfo, item, len, card)
unsigned char *resinfo;
int item, len;
@@ -725,33 +922,40 @@ handle_large_res(resinfo, item, len, card)
switch (item) {
case MEMORY_RANGE_DESC:
- for (i = 0; card->dev->conf->mem[i]; i++) ;
+ for (i = 0; card->dev->conf->mem[i]; i++)
+ ;
card->dev->conf->mem[i] = malloc(sizeof(struct mem_descriptor),
- M_DEVBUF, M_WAITOK);
+ M_DEVBUF, M_WAITOK);
card->dev->conf->mem[i]->type = 0; /* 0 for 24bit mem desc. */
card->dev->conf->mem[i]->info = resinfo[0];
card->dev->conf->mem[i]->min_base =
- (resinfo[1] | resinfo[2] << 8) << 8;
+ (resinfo[1] | (resinfo[2] << 8)) << 8;
card->dev->conf->mem[i]->max_base =
- (resinfo[3] | resinfo[4] << 8) << 8;
+ (resinfo[3] | (resinfo[4] << 8)) << 8;
card->dev->conf->mem[i]->alignment =
- (resinfo[5] | resinfo[6] << 8);
+ resinfo[5] | (resinfo[6] << 8);
if (!card->dev->conf->mem[i]->alignment)
- card->dev->conf->mem[i]->alignment = 1 << 16;
+ card->dev->conf->mem[i]->alignment = 1 << 16;
card->dev->conf->mem[i]->size =
- (resinfo[7] | resinfo[8] << 8) << 8;
+ (resinfo[7] | (resinfo[8] << 8)) << 8;
break;
case ID_STRING_ANSI:
if (card->dev) {
- card->dev->id_string =
- (char *)malloc(len+1, M_DEVBUF, M_WAITOK);
+ card->dev->id_string = (char *)malloc(len+1, M_DEVBUF,
+ M_WAITOK);
strncpy(card->dev->id_string, resinfo, len+1);
card->dev->id_string[len] = '\0';
+#if 0
+ printf("ID_STRING_ANSI: %s\n", card->dev->id_string);
+#endif
} else {
- card->id_string =
- (char *)malloc(len+1, M_DEVBUF, M_WAITOK);
+ card->id_string = (char *)malloc(len+1, M_DEVBUF,
+ M_WAITOK);
strncpy(card->id_string, resinfo, len+1);
card->id_string[len] = '\0';
+#if 0
+ printf("ID_STRING_ANSI: %s\n", card->id_string);
+#endif
}
break;
case ID_STRING_UNICODE:
@@ -762,36 +966,39 @@ handle_large_res(resinfo, item, len, card)
break;
case _32BIT_FIXED_LOC_DESC:
break;
+
+ /* XXX - Check how this is defined! Bogus!!! */
case LG_RES_RESERVED:
break;
+ default:
+ break;
}
}
-static void
+void
read_config(sc, card, csn)
struct isapnp_softc *sc;
struct cardinfo *card;
int csn;
{
-#ifdef notdef
- u_char serial[9];
-#endif
u_char tag, *resinfo;
- int i, large_len;
+ u_short large_len;
+ int i;
+#if 0
/*
* set card with csn to Config state
*/
SEND(SET_CSN, csn);
+#endif
/*
- * since we are in the card isolation process, so ther's no reason
+ * since we are in the card isolation process, so theres no reason
* to rewind and skip the first 9 bytes
*/
- /*
- * allow up to 1KB of resource info, should be plenty */
- for (i = 0; i < 1024; i++) {
+ /* allow up to 1KB of resource info, should be plenty */
+ for (i = 0; i < 4096; i++) {
if (!get_resource_info(sc, &tag, 1))
return;
@@ -801,22 +1008,34 @@ read_config(sc, card, csn)
#define L_ITEM (tag & 0x7f)
if (TYPE == 0) {
+#if 0
+ printf("small %d %d\n", S_ITEM, S_LEN);
+#endif
resinfo = malloc(S_LEN, M_TEMP, M_WAITOK);
- if (!get_resource_info(sc, resinfo, S_LEN))
+ if (!get_resource_info(sc, resinfo, S_LEN)) {
+ printf("bail getting small info\n");
return;
+ }
if (handle_small_res(resinfo, S_ITEM, S_LEN, card) == 1)
return;
free(resinfo, M_TEMP);
} else {
large_len = 0;
- if (!get_resource_info(sc, (char *)&large_len, 2))
+ if (!get_resource_info(sc, (char *)&large_len, 2)) {
+ printf("bail getting large info\n");
return;
-
+ }
resinfo = malloc(large_len, M_TEMP, M_WAITOK);
- if (!get_resource_info(sc, resinfo, large_len))
+ if (!get_resource_info(sc, resinfo, large_len)) {
+ printf("bail sadf info\n");
+ free(resinfo, M_TEMP);
return;
+ }
+#if 0
+ printf("large %d %d\n", L_ITEM, large_len);
+#endif
handle_large_res(resinfo, L_ITEM, large_len, card);
free(resinfo, M_TEMP);
}
@@ -828,7 +1047,7 @@ read_config(sc, card, csn)
* should try multiple READ_DATA locations before giving up). Upon exiting,
* all cards are aware that they should use rd_port as the READ_DATA port;
*/
-static int
+int
isolation_protocol(sc)
struct isapnp_softc *sc;
{
@@ -836,10 +1055,23 @@ isolation_protocol(sc)
unsigned char data[9];
/* Reset CSN for All Cards */
+ /* Well, all cards who are *NOT* in Wait for Key state:
+ *
+ * 0x01 - Reset command. (READ_PORT, CSN, PNP state preserved)
+ * 0x02 - Wait for Key. (Everything preserved)
+ * 0x04 - Reset CSN. (Nuke CSN goto wait for key state)
+ *
+ * Use 0x08 for the equivelant to RESET_DRV.
+ */
SEND(CONFIG_CONTROL, 0x05);
+ /* Move all PNP cards from WFK state to sleep state */
send_Initiation_LFSR(sc);
+ /* We should do the following until we do not
+ * find anymore PNP cards, with the max being
+ * 255 cards. This is faster
+ */
for (csn = 1; (csn < MAX_CARDS); csn++) {
/* Wake up cards without a CSN */
SEND(WAKE, 0);
@@ -850,9 +1082,9 @@ isolation_protocol(sc)
if (get_serial(sc, data)) {
struct cardinfo *card;
+ /* Move card into config state */
SEND(SET_CSN, csn);
- card = malloc(sizeof(struct cardinfo),
- M_DEVBUF, M_WAITOK);
+ card = malloc(sizeof(struct cardinfo), M_DEVBUF, M_WAITOK);
bzero(card, sizeof(struct cardinfo));
TAILQ_INSERT_TAIL(&sc->q_card, card, card_link);
bcopy(data, card->serial, 9);
@@ -862,17 +1094,16 @@ isolation_protocol(sc)
* read card's resource data
*/
read_config(sc, card, csn);
- }
- else
+ } else
break;
}
return csn - 1;
}
/*
- * Configure PnP devices, given a set of configuration data
+ * Configure PNP devices, given a set of configuration data
*/
-static void
+void
config_device(sc, data)
struct isapnp_softc *sc;
struct isa_attach_args *data;
@@ -883,17 +1114,18 @@ config_device(sc, data)
return;
}
-#if 0
- printf ("%s: configuring CSN %x (logical device %x)\n",
- sc->sc_dev.dv_xname,
- data->csn,
+#if 1
+ printf ("%s: configuring CSN %x (LDN %x)\n",
+ sc->sc_dev.dv_xname, data->csn,
data->ldn != -1 ? data->ldn : 0);
#endif
+ /* Wake up card, set LDN */
SEND(WAKE, data->csn);
if (data->ldn > 0)
SEND (SET_LDN, data->ldn);
+ /* Config IO */
for (i = 0; i < 8; i++)
if (data->port[i] > 0) {
SEND (IO_CONFIG_BASE + i * 2,
@@ -902,6 +1134,7 @@ config_device(sc, data)
data->port[i] & 0xff);
}
+ /* Config IRQ */
for (i = 0; i < 2; i++)
if (data->irq[i].num > 0) {
SEND (IRQ_CONFIG + i * 2, data->irq[i].num);
@@ -909,11 +1142,13 @@ config_device(sc, data)
SEND (IRQ_CONFIG + i * 2 + 1, data->irq[i].type);
}
+ /* Config DRQ */
for (i = 0; i < 2; i++)
if (data->drq[i] > 0) {
SEND (DRQ_CONFIG + i, data->drq[i]);
}
+ /* Config MEM */
for (i = 0; i < 4; i++)
if (data->mem[i].base > 0) {
SEND (MEM_CONFIG + i * 8,
@@ -935,60 +1170,56 @@ config_device(sc, data)
(data->mem[i].range >> 8) &
0xff);
}
+
+ /* Disable RANGE_CHECK & ACTIVATE logical device */
SEND (IO_RANGE_CHECK, 0);
SEND (ACTIVATE, 1);
}
-static int
+int
find_free_irq(irq_mask)
int irq_mask;
{
- int i, j;
struct emap *irq_map;
+ int i, j;
irq_map = find_emap("irq");
i = irq_mask;
while (1) {
j = ffs(i);
- if (!j) {
+ if (j == 0)
return(0);
- }
- /*
- * irq_mask is starting from 0
- */
- j --;
- if (!probe_extent(irq_map, j, 1)) {
+ j--;
+ if (!probe_extent(irq_map, j, 1))
return(j);
- }
i &= ~(0x1 << j);
}
+
+ return(0);
}
int
find_free_drq(drq_mask)
int drq_mask;
{
- int i, j;
struct emap *drq_map;
+ int i, j;
drq_map = find_emap("drq");
i = drq_mask;
while (1) {
j = ffs(i);
- if (!j) {
+ if (j == 0)
return(0);
- }
- /*
- * drq_mask is starting from 0
- */
- j --;
- if (!probe_extent(drq_map, j, 1)) {
+ j--;
+ if (!probe_extent(drq_map, j, 1))
return(j);
- }
i &= ~(0x1 << j);
}
+
+ return(0);
}
/*
@@ -998,7 +1229,7 @@ find_free_drq(drq_mask)
*
* assume caller has set csn and ldn properly.
*/
-static int
+int
find_free_io(sc, desc, min_addr, max_addr, size, alignment, range_check)
struct isapnp_softc *sc;
int desc, min_addr, max_addr, size, alignment, range_check;
@@ -1035,13 +1266,14 @@ find_free_io(sc, desc, min_addr, max_addr, size, alignment, range_check)
else {
return(0);
}
- }
- else {
+ } else {
+#if 0
+ printf("%x len %x\n", addr, size);
+#endif
io_map = find_emap("io");
addr = min_addr;
- if (!probe_extent(io_map, addr, size)) {
+ if (!probe_extent(io_map, addr, size))
return(addr);
- }
- return(0);
+ return (0);
}
}
diff --git a/sys/dev/isa/isapnpreg.h b/sys/dev/isa/isapnpreg.h
index b93f2beab66..ffff96583ef 100644
--- a/sys/dev/isa/isapnpreg.h
+++ b/sys/dev/isa/isapnpreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isapnpreg.h,v 1.1 1996/08/14 14:36:16 shawn Exp $ */
+/* $OpenBSD: isapnpreg.h,v 1.2 1997/07/12 23:22:01 weingart Exp $ */
/*
* Copyright (c) 1996, Sujal M. Patel
@@ -41,53 +41,60 @@
/* Static ports */
#define ADDRESS 0x279
+#if 0
#define WRITE_DATA 0xa79
+#else
+#define WRITE_DATA (ADDRESS+0x0800)
+#endif
/* PnP Registers. Write to ADDRESS and then use WRITE/READ_DATA */
-#define SET_RD_DATA 0x00
+#define SET_RD_DATA 0x00
#define SERIAL_ISOLATION 0x01
-#define CONFIG_CONTROL 0x02
-#define WAKE 0x03
+#define CONFIG_CONTROL 0x02
+#define WAKE 0x03
#define RESOURCE_DATA 0x04
-#define STATUS 0x05
-#define SET_CSN 0x06
-#define SET_LDN 0x07
-#define ACTIVATE 0x30
+#define STATUS 0x05
+#define SET_CSN 0x06
+#define SET_LDN 0x07
+#define ACTIVATE 0x30
#define IO_RANGE_CHECK 0x31
-#define MEM_CONFIG 0x40
+#define MEM_CONFIG 0x40
#define IO_CONFIG_BASE 0x60
-#define IRQ_CONFIG 0x70
-#define DRQ_CONFIG 0x74
+#define IRQ_CONFIG 0x70
+#define DRQ_CONFIG 0x74
/* Small Resource Item names */
-#define PNP_VERSION 0x1
+#define PNP_VERSION 0x1
#define LOG_DEVICE_ID 0x2
#define COMP_DEVICE_ID 0x3
-#define IRQ_FORMAT 0x4
-#define DMA_FORMAT 0x5
+#define IRQ_FORMAT 0x4
+#define DMA_FORMAT 0x5
#define START_DEPEND_FUNC 0x6
#define END_DEPEND_FUNC 0x7
#define IO_PORT_DESC 0x8
#define FIXED_IO_PORT_DESC 0x9
-#define SM_RES_RESERVED 0xa-0xd
+#define SM_RES_RESERVED1 0xa
+#define SM_RES_RESERVED2 0xb
+#define SM_RES_RESERVED3 0xc
+#define SM_RES_RESERVED4 0xd
#define SM_VENDOR_DEFINED 0xe
-#define END_TAG 0xf
+#define END_TAG 0xf
/* Large Resource Item names */
-#define MEMORY_RANGE_DESC 0x1
-#define ID_STRING_ANSI 0x2
-#define ID_STRING_UNICODE 0x3
-#define LG_VENDOR_DEFINED 0x4
+#define MEMORY_RANGE_DESC 0x1
+#define ID_STRING_ANSI 0x2
+#define ID_STRING_UNICODE 0x3
+#define LG_VENDOR_DEFINED 0x4
#define _32BIT_MEM_RANGE_DESC 0x5
#define _32BIT_FIXED_LOC_DESC 0x6
-#define LG_RES_RESERVED 0x7-0x7f
+#define LG_RES_RESERVED 0x7-0x7f
/* Priority for Resource Group */
-#define BASIC_CONFIGURATION -1
-#define GOOD_CONFIGURATION 0x0
-#define ACCEPTABLE_CONFIGURATION 0x1
-#define SUBOPTIMAL_CONFIGURATION 0x2
-#define RESERVED_CONFIGURATION 0x3
+#define BASIC_CONFIGURATION -1
+#define GOOD_CONFIGURATION 0x0
+#define ACCEPTABLE_CONFIGURATION 0x1
+#define SUBOPTIMAL_CONFIGURATION 0x2
+#define RESERVED_CONFIGURATION 0x3
#endif /* !_DEV_ISA_ISAPNPREG_H_ */
diff --git a/sys/dev/isa/isapnpvar.h b/sys/dev/isa/isapnpvar.h
index 49f5da5f5d0..5458419fc46 100644
--- a/sys/dev/isa/isapnpvar.h
+++ b/sys/dev/isa/isapnpvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isapnpvar.h,v 1.1 1996/08/14 14:36:16 shawn Exp $ */
+/* $OpenBSD: isapnpvar.h,v 1.2 1997/07/12 23:22:02 weingart Exp $ */
/*
* Copyright (c) 1996, Shawn Hsiao <shawn@alpha.secc.fju.edu.tw>
@@ -35,25 +35,25 @@ struct irq_format {
};
struct dma_format {
- int channel; /* DMA channel */
+ int channel; /* DMA channel */
int info; /* DMA type */
};
struct io_descriptor {
int type; /* normal or fixed I/O descriptor */
int info; /* decoding information */
- int min_base; /* minimum base I/O address */
- int max_base; /* maximum base I/O address */
- int alignment; /* alignment for base address */
+ int min_base; /* minimum base I/O address */
+ int max_base; /* maximum base I/O address */
+ int alignment; /* alignment for base address */
int size; /* number of contiguous ports */
};
struct mem_descriptor {
int type; /* 24 or 32bit memory descriptor */
int info; /* misc. memory information */
- int min_base; /* minimum base mem address */
- int max_base; /* maximum base mem address */
- int alignment; /* aligment for base address */
+ int min_base; /* minimum base mem address */
+ int max_base; /* maximum base mem address */
+ int alignment; /* aligment for base address */
int size; /* number of memory range length */
};
@@ -95,4 +95,9 @@ struct cardinfo {
TAILQ_ENTRY(cardinfo) card_link;
};
+struct pnp_knowndev {
+ char *pnpid;
+ char *driver;
+};
+
#endif /* !_DEV_ISA_ISAPNPVAR_H_ */
diff --git a/sys/dev/isa/pnpdevs b/sys/dev/isa/pnpdevs
new file mode 100644
index 00000000000..bef1e5dda18
--- /dev/null
+++ b/sys/dev/isa/pnpdevs
@@ -0,0 +1,338 @@
+#--Interrupt Controllers--
+# PNP0000 #AT Interrupt Controller
+# PNP0001 #EISA Interrupt Controller
+# PNP0002 #MCA Interrupt Controller
+# PNP0003 #APIC
+# PNP0004 #Cyrix SLiC MP interrupt controller
+
+#--Timers--
+# PNP0100 #AT Timer
+# PNP0101 #EISA Timer
+# PNP0102 #MCA Timer
+
+#--DMA--
+# PNP0200 #AT DMA Controller
+# PNP0201 #EISA DMA Controller
+# PNP0202 #MCA DMA Controller
+
+#--Keyboards--
+# PNP0300 #IBM PC/XT keyboard controller (83-key)
+# PNP0301 #IBM PC/AT keyboard controller (86-key)
+# PNP0302 #IBM PC/XT keyboard controller (84-key)
+# PNP0303 #IBM Enhanced (101/102-key, PS/2 mouse support)
+# PNP0304 #Olivetti Keyboard (83-key)
+# PNP0305 #Olivetti Keyboard (102-key)
+# PNP0306 #Olivetti Keyboard (86-key)
+# PNP0307 #Microsoft Windows(R) Keyboard
+# PNP0308 #General Input Device Emulation Interface (GIDEI) legacy
+# PNP0309 #Olivetti Keyboard (A101/102 key)
+# PNP030A #AT&T 302 keyboard
+# PNP030B #Reserved by Microsoft
+# PNP0320 #Japanese 101-key keyboard
+# PNP0321 #Japanese AX keyboard
+# PNP0322 #Japanese 106-key keyboard A01
+# PNP0323 #Japanese 106-key keyboard 002/003
+# PNP0324 #Japanese 106-key keyboard 001
+# PNP0325 #Japanese Toshiba Desktop keyboard
+# PNP0326 #Japanese Toshiba Laptop keyboard
+# PNP0327 #Japanese Toshiba Notebook keyboard
+# PNP0340 #Korean 84-key keyboard
+# PNP0341 #Korean 86-key keyboard
+# PNP0342 #Korean Enhanced keyboard
+# PNP0343 #Korean Enhanced keyboard 101b
+# PNP0343 #Korean Enhanced keyboard 101c
+# PNP0344 #Korean Enhanced keyboard 103
+
+#--Parallel Devices--
+# PNP0400 #Standard LPT printer port
+# PNP0401 #ECP printer port
+
+#--Serial Devices--
+# PNP0500 #Standard PC COM port
+# PNP0501 #16550A-compatible COM port
+# PNP0510 #Generic IRDA-compatible device
+
+#--Disk Controllers--
+# PNP0600 #Generic ESDI/IDE/ATA compatible hard disk controller
+# PNP0601 #Plus Hardcard II
+# PNP0602 #Plus Hardcard IIXL/EZ
+# PNP0603 #Generic IDE supporting Microsoft Device Bay Specification
+# PNP0700 #PC standard floppy disk controller
+# PNP0701 #Standard floppy controller supporting MS Device Bay Spec
+
+#--Compatibility with early device ID list--
+# PNP0802 #Microsoft Sound System compatible device (obsolete, use
+ #PNPB0xx instead)
+#--Display Adapters--
+# PNP0900 #VGA Compatible
+# PNP0901 #Video Seven VRAM/VRAM II/1024i
+# PNP0902 #8514/A Compatible
+# PNP0903 #Trident VGA
+# PNP0904 #Cirrus Logic Laptop VGA
+# PNP0905 #Cirrus Logic VGA
+# PNP0906 #Tseng ET4000
+# PNP0907 #Western Digital VGA
+# PNP0908 #Western Digital Laptop VGA
+# PNP0909 #S3 Inc. 911/924
+# PNP090A #ATI Ultra Pro/Plus (Mach 32)
+# PNP090B #ATI Ultra (Mach 8)
+# PNP090C #XGA Compatible
+# PNP090D #ATI VGA Wonder
+# PNP090E #Weitek P9000 Graphics Adapter
+# PNP090F #Oak Technology VGA
+# PNP0910 #Compaq QVision
+# PNP0911 #XGA/2
+# PNP0912 #Tseng Labs W32/W32i/W32p
+# PNP0913 #S3 Inc. 801/928/964
+# PNP0914 #Cirrus Logic 5429/5434 (memory mapped)
+# PNP0915 #Compaq Advanced VGA (AVGA)
+# PNP0916 #ATI Ultra Pro Turbo (Mach64)
+# PNP0917 #Reserved by Microsoft
+# PNP0918 #Matrox MGA
+# PNP0919 #Compaq QVision 2000
+# PNP091A #Tseng W128
+# PNP0930 #Chips & Technologies Super VGA
+# PNP0931 #Chips & Technologies Accelerator
+# PNP0940 #NCR 77c22e Super VGA
+# PNP0941 #NCR 77c32blt
+# PNP09FF #Plug and Play Monitors (VESA DDC)
+
+#--Peripheral Buses--
+# PNP0A00 #ISA Bus
+# PNP0A01 #EISA Bus
+# PNP0A02 #MCA Bus
+# PNP0A03 #PCI Bus
+# PNP0A04 #VESA/VL Bus
+# PNP0A05 #ACPI Bus
+
+#-- Real Time Clock, BIOS, System board devices--
+# PNP0800 #AT-style speaker sound
+# PNP0B00 #AT Real-Time Clock
+# PNP0C00 #Plug and Play BIOS (only created by the root enumerator)
+# PNP0C01 #System Board
+# PNP0C02 #General ID for reserving resources required by Plug and Play
+ #motherboard registers. (Not specific to a particular device.)
+# PNP0C03 #Plug and Play BIOS Event Notification Interrupt
+# PNP0C04 #Math Coprocessor
+# PNP0C05 #APM BIOS (Version independent)
+# PNP0C06 #Reserved for identification of early Plug and Play
+ #BIOS implementation.
+# PNP0C07 #Reserved for identification of early Plug and Play
+ #BIOS implementation.
+
+#--PCMCIA Controller Chipsets--
+# PNP0E00 #Intel 82365-Compatible PCMCIA Controller
+# PNP0E01 #Cirrus Logic CL-PD6720 PCMCIA Controller
+# PNP0E02 #VLSI VL82C146 PCMCIA Controller
+# PNP0E03 #Intel 82365-compatible CardBus controller
+
+#--Mice--
+# PNP0F00 #Microsoft Bus Mouse
+# PNP0F01 #Microsoft Serial Mouse
+# PNP0F02 #Microsoft InPort Mouse
+# PNP0F03 #Microsoft PS/2-style Mouse
+# PNP0F04 #Mouse Systems Mouse
+# PNP0F05 #Mouse Systems 3-Button Mouse (COM2)
+# PNP0F06 #Genius Mouse (COM1)
+# PNP0F07 #Genius Mouse (COM2)
+# PNP0F08 #Logitech Serial Mouse
+# PNP0F09 #Microsoft BallPoint Serial Mouse
+# PNP0F0A #Microsoft Plug and Play Mouse
+# PNP0F0B #Microsoft Plug and Play BallPoint Mouse
+# PNP0F0C #Microsoft-compatible Serial Mouse
+# PNP0F0D #Microsoft-compatible InPort-compatible Mouse
+# PNP0F0E #Microsoft-compatible PS/2-style Mouse
+# PNP0F0F #Microsoft-compatible Serial BallPoint-compatible Mouse
+# PNP0F10 #Texas Instruments QuickPort Mouse
+# PNP0F11 #Microsoft-compatible Bus Mouse
+# PNP0F12 #Logitech PS/2-style Mouse
+# PNP0F13 #PS/2 Port for PS/2-style Mice
+# PNP0F14 #Microsoft Kids Mouse
+# PNP0F15 #Logitech bus mouse
+# PNP0F16 #Logitech SWIFT device
+# PNP0F17 #Logitech-compatible serial mouse
+# PNP0F18 #Logitech-compatible bus mouse
+# PNP0F19 #Logitech-compatible PS/2-style Mouse
+# PNP0F1A #Logitech-compatible SWIFT Device
+# PNP0F1B #HP Omnibook Mouse
+# PNP0F1C #Compaq LTE Trackball PS/2-style Mouse
+# PNP0F1D #Compaq LTE Trackball Serial Mouse
+# PNP0F1E #Microsoft Kids Trackball Mouse
+# PNP0F1F #Reserved by Microsoft Input Device Group
+# PNP0F20 #Reserved by Microsoft Input Device Group
+# PNP0F21 #Reserved by Microsoft Input Device Group
+# PNP0F22 #Reserved by Microsoft Input Device Group
+# PNP0F23 #Reserved by Microsoft Input Device Group
+# PNP0FFF #Reserved by Microsoft Systems
+
+#***** Network Adapters - PNP8xxx ***********************
+# PNP8001 #Novell/Anthem NE3200
+# PNP8004 #Compaq NE3200
+# PNP8006 #Intel EtherExpress/32
+# PNP8008 #HP EtherTwist EISA LAN Adapter/32 (HP27248A)
+# PNP8065 #Ungermann-Bass NIUps or NIUps/EOTP
+# PNP8072 #DEC (DE211) EtherWorks MC/TP
+# PNP8073 #DEC (DE212) EtherWorks MC/TP_BNC
+# PNP8078 #DCA 10 Mb MCA
+# PNP8074 #HP MC LAN Adapter/16 TP (PC27246)
+# PNP80c9 #IBM Token Ring
+# PNP80ca #IBM Token Ring II
+# PNP80cb #IBM Token Ring II/Short
+# PNP80cc #IBM Token Ring 4/16Mbs
+ed PNP80d3 #Novell/Anthem NE1000
+ed PNP80d4 #Novell/Anthem NE2000
+ed PNP80d5 #NE1000 Compatible
+ed PNP80d6 #NE2000 Compatible
+# PNP80d7 #Novell/Anthem NE1500T
+le PNP80d8 #Novell/Anthem NE2100
+# PNP80dd #SMC ARCNETPC
+# PNP80de #SMC ARCNET PC100, PC200
+# PNP80df #SMC ARCNET PC110, PC210, PC250
+# PNP80e0 #SMC ARCNET PC130/E
+# PNP80e1 #SMC ARCNET PC120, PC220, PC260
+# PNP80e2 #SMC ARCNET PC270/E
+# PNP80e5 #SMC ARCNET PC600W, PC650W
+# PNP80e7 #DEC DEPCA
+# PNP80e8 #DEC (DE100) EtherWorks LC
+# PNP80e9 #DEC (DE200) EtherWorks Turbo
+# PNP80ea #DEC (DE101) EtherWorks LC/TP
+# PNP80eb #DEC (DE201) EtherWorks Turbo/TP
+# PNP80ec #DEC (DE202) EtherWorks Turbo/TP_BNC
+# PNP80ed #DEC (DE102) EtherWorks LC/TP_BNC
+# PNP80ee #DEC EE101 (Built-In)
+# PNP80ef #DECpc 433 WS (Built-In)
+ep PNP80f1 #3Com EtherLink Plus
+ep PNP80f3 #3Com EtherLink II or IITP (8 or 16-bit)
+ep PNP80f4 #3Com TokenLink
+ep PNP80f6 #3Com EtherLink 16
+ep PNP80f7 #3Com EtherLink III
+ep PNP80f8 #3Com Generic Etherlink Plug and Play Device
+# PNP80fb #Thomas Conrad TC6045
+# PNP80fc #Thomas Conrad TC6042
+# PNP80fd #Thomas Conrad TC6142
+# PNP80fe #Thomas Conrad TC6145
+# PNP80ff #Thomas Conrad TC6242
+# PNP8100 #Thomas Conrad TC6245
+# PNP8105 #DCA 10 MB
+# PNP8106 #DCA 10 MB Fiber Optic
+# PNP8107 #DCA 10 MB Twisted Pair
+# PNP8113 #Racal NI6510
+# PNP811C #Ungermann-Bass NIUpc
+# PNP8120 #Ungermann-Bass NIUpc/EOTP
+ed PNP8123 #SMC StarCard PLUS (WD/8003S)
+ed PNP8124 #SMC StarCard PLUS With On Board Hub (WD/8003SH)
+ed PNP8125 #SMC EtherCard PLUS (WD/8003E)
+ed PNP8126 #SMC EtherCard PLUS With Boot ROM Socket (WD/8003EBT)
+ed PNP8127 #SMC EtherCard PLUS With Boot ROM Socket (WD/8003EB)
+ed PNP8128 #SMC EtherCard PLUS TP (WD/8003WT)
+ed PNP812a #SMC EtherCard PLUS 16 With Boot ROM Socket (WD/8013EBT)
+# PNP812d #Intel EtherExpress 16 or 16TP
+# PNP812f #Intel TokenExpress 16/4
+# PNP8130 #Intel TokenExpress MCA 16/4
+# PNP8132 #Intel EtherExpress 16 (MCA)
+# PNP8137 #Artisoft AE-1
+# PNP8138 #Artisoft AE-2 or AE-3
+# PNP8141 #Amplicard AC 210/XT
+# PNP8142 #Amplicard AC 210/AT
+# PNP814b #Everex SpeedLink /PC16 (EV2027)
+# PNP8155 #HP PC LAN Adapter/8 TP (HP27245)
+# PNP8156 #HP PC LAN Adapter/16 TP (HP27247A)
+# PNP8157 #HP PC LAN Adapter/8 TL (HP27250)
+# PNP8158 #HP PC LAN Adapter/16 TP Plus (HP27247B)
+# PNP8159 #HP PC LAN Adapter/16 TL Plus (HP27252)
+# PNP815f #National Semiconductor Ethernode *16AT
+# PNP8160 #National Semiconductor AT/LANTIC EtherNODE 16-AT3
+# PNP816a #NCR Token-Ring 4 Mbs ISA
+# PNP816d #NCR Token-Ring 16/4 Mbs ISA
+# PNP8191 #Olicom 16/4 Token-Ring Adapter
+ed PNP81c3 #SMC EtherCard PLUS Elite (WD/8003EP)
+ed PNP81c4 #SMC EtherCard PLUS 10T (WD/8003W)
+ed PNP81c5 #SMC EtherCard PLUS Elite 16 (WD/8013EP)
+ed PNP81c6 #SMC EtherCard PLUS Elite 16T (WD/8013W)
+ed PNP81c7 #SMC EtherCard PLUS Elite 16 Combo (WD/8013EW or 8013EWC)
+ed PNP81c8 #SMC EtherElite Ultra 16
+# PNP81e4 #Pure Data PDI9025-32 (Token Ring)
+# PNP81e6 #Pure Data PDI508+ (ArcNet)
+# PNP81e7 #Pure Data PDI516+ (ArcNet)
+# PNP81eb #Proteon Token Ring (P1390)
+# PNP81ec #Proteon Token Ring (P1392)
+# PNP81ed #Proteon ISA Token Ring (1340)
+# PNP81ee #Proteon ISA Token Ring (1342)
+# PNP81ef #Proteon ISA Token Ring (1346)
+# PNP81f0 #Proteon ISA Token Ring (1347)
+# PNP81ff #Cabletron E2000 Series DNI
+# PNP8200 #Cabletron E2100 Series DNI
+# PNP8209 #Zenith Data Systems Z-Note
+# PNP820a #Zenith Data Systems NE2000-Compatible
+# PNP8213 #Xircom Pocket Ethernet II
+# PNP8214 #Xircom Pocket Ethernet I
+# PNP821d #RadiSys EXM-10
+# PNP8227 #SMC 3000 Series
+# PNP8228 #SMC 91C2 controller
+# PNP8231 #Advanced Micro Devices AM2100/AM1500T
+# PNP8263 #Tulip NCC-16
+# PNP8277 #Exos 105
+# PNP828A #Intel '595 based Ethernet
+# PNP828B #TI2000-style Token Ring
+le PNP828C #AMD PCNet Family cards
+le PNP828D #AMD PCNet32 (VL version)
+le WUMbeef
+# PNP8294 #IrDA Infrared NDIS driver (Microsoft-supplied)
+# PNP82bd #IBM PCMCIA-NIC
+# PNP82C2 #Xircom CE10
+# PNP82C3 #Xircom CEM2
+# PNP8321 #DEC Ethernet (All Types)
+# PNP8323 #SMC EtherCard (All Types except 8013/A)
+# PNP8324 #ARCNET Compatible
+# PNP8326 #Thomas Conrad (All Arcnet Types)
+# PNP8327 #IBM Token Ring (All Types)
+# PNP8385 #Remote Network Access Driver
+# PNP8387 #RNA Point-to-point Protocol Driver
+# PNP8388 #Reserved for Microsoft Networking components
+
+#***** SCSI, Proprietary CD Adapters - PNPAxxx **********
+# PNPA002 #Future Domain 16-700 compatible controller
+# PNPA003 #Panasonic proprietary CD-ROM adapter (SBPro/SB16)
+# PNPA01B #Trantor 128 SCSI Controller
+# PNPA01D #Trantor T160 SCSI Controller
+# PNPA01E #Trantor T338 Parallel SCSI controller
+# PNPA01F #Trantor T348 Parallel SCSI controller
+# PNPA020 #Trantor Media Vision SCSI controller
+# PNPA022 #Always IN-2000 SCSI controller
+# PNPA02B #Sony proprietary CD-ROM controller
+# PNPA02D #Trantor T13b 8-bit SCSI controller
+# PNPA02F #Trantor T358 Parallel SCSI controller
+# PNPA030 #Mitsumi LU-005 Single Speed CD-ROM controller + drive
+# PNPA031 #Mitsumi FX-001 Single Speed CD-ROM controller + drive
+# PNPA032 #Mitsumi FX-001 Double Speed CD-ROM controller + drive
+
+#***** Sound/Video-capture, multimedia - PNPBxxx ********
+# PNPB000 #Sound Blaster 1.5-compatible sound device
+# PNPB001 #Sound Blaster 2.0-compatible sound device
+# PNPB002 #Sound Blaster Pro-compatible sound device
+# PNPB003 #Sound Blaster 16-compatible sound device
+# PNPB004 #Thunderboard-compatible sound device
+# PNPB005 #Adlib-compatible FM synthesizer device
+# PNPB006 #MPU401 compatible
+# PNPB007 #Microsoft Windows Sound System-compatible sound device
+# PNPB008 #Compaq Business Audio
+# PNPB009 #Plug and Play Microsoft Windows Sound System Device
+# PNPB00A #MediaVision Pro Audio Spectrum
+ #(Trantor SCSI enabled, Thunder Chip Disabled)
+# PNPB00B #MediaVision Pro Audio 3D
+# PNPB00C #MusicQuest MQX-32M
+# PNPB00D #MediaVision Pro Audio Spectrum Basic
+ #(No Trantor SCSI, Thunder Chip Enabled)
+# PNPB00E #MediaVision Pro Audio Spectrum
+ #(Trantor SCSI enabled, Thunder Chip Enabled)
+# PNPB00F #MediaVision Jazz-16 chipset (OEM Versions)
+# PNPB010 #Auravision VxP500 chipset - Orchid Videola
+# PNPB018 #MediaVision Pro Audio Spectrum 8-bit
+# PNPB019 #MediaVision Pro Audio Spectrum Basic
+ #(no Trantor SCSI, Thunder chip Disabled)
+# PNPB020 #Yamaha OPL3-compatible FM synthesizer device
+# PNPB02F #Joystick/Game port
+
+#***** Modems - PNPCxxx-Dxxx****************************
+# PNPC000 #Compaq 14400 Modem (TBD)
+# PNPC001 #Compaq 2400/9600 Modem (TBD)
diff --git a/sys/dev/isa/pnpdevs.h b/sys/dev/isa/pnpdevs.h
new file mode 100644
index 00000000000..21d344fa902
--- /dev/null
+++ b/sys/dev/isa/pnpdevs.h
@@ -0,0 +1,37 @@
+/*
+ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
+ *
+ * generated from:
+ * #--Interrupt Controllers--
+ */
+
+struct pnp_knowndev pnp_knowndevs[] = {
+ { "PNP80d3", "ed" },
+ { "PNP80d4", "ed" },
+ { "PNP80d5", "ed" },
+ { "PNP80d6", "ed" },
+ { "PNP80d8", "le" },
+ { "PNP80f1", "ep" },
+ { "PNP80f3", "ep" },
+ { "PNP80f4", "ep" },
+ { "PNP80f6", "ep" },
+ { "PNP80f7", "ep" },
+ { "PNP80f8", "ep" },
+ { "PNP8123", "ed" },
+ { "PNP8124", "ed" },
+ { "PNP8125", "ed" },
+ { "PNP8126", "ed" },
+ { "PNP8127", "ed" },
+ { "PNP8128", "ed" },
+ { "PNP812a", "ed" },
+ { "PNP81c3", "ed" },
+ { "PNP81c4", "ed" },
+ { "PNP81c5", "ed" },
+ { "PNP81c6", "ed" },
+ { "PNP81c7", "ed" },
+ { "PNP81c8", "ed" },
+ { "PNP828C", "le" },
+ { "PNP828D", "le" },
+ { "WUMbeef", "le" },
+ { NULL, NULL, }
+};