diff options
author | msmith <msmith@FreeBSD.org> | 1998-10-21 20:07:05 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 1998-10-21 20:07:05 +0000 |
commit | 880061ca43c5eb7110f8b122628b447b5df729e9 (patch) | |
tree | c03d04e81f549d7c5f9fdd53d289b5ef2e77e1e7 /sys/boot/common/pnp.c | |
parent | a9435964cae6bb08cf72cd42f4f2e90b5721bbcb (diff) | |
download | FreeBSD-src-880061ca43c5eb7110f8b122628b447b5df729e9.zip FreeBSD-src-880061ca43c5eb7110f8b122628b447b5df729e9.tar.gz |
Make ISA PnP work. This successfully enumerates as many ISA devices as I
can fit into my test machine.
- Move to using STAILQs rather than ad-hoc singly-linked lists.
- Use a mostly procedural interface to the PnP information. This
improves data-hiding.
Implement a new linker-set technique (currently on i386 only but should work
on Alpha as well). This is a good candidate for replacing the current
gensetdefs cruft completely.
Diffstat (limited to 'sys/boot/common/pnp.c')
-rw-r--r-- | sys/boot/common/pnp.c | 148 |
1 files changed, 110 insertions, 38 deletions
diff --git a/sys/boot/common/pnp.c b/sys/boot/common/pnp.c index 4a8ee48..128bb22 100644 --- a/sys/boot/common/pnp.c +++ b/sys/boot/common/pnp.c @@ -13,9 +13,10 @@ #include <string.h> #include <bootstrap.h> -static struct pnpinfo *pnp_devices = NULL; +STAILQ_HEAD(,pnpinfo) pnp_devices; +static int pnp_devices_initted = 0; -static void pnp_discard(struct pnpinfo **list); +static void pnp_discard(void); static int pnp_readconf(char *path); static int pnp_scankernel(void); @@ -28,15 +29,55 @@ COMMAND_SET(pnpscan, "pnpscan", "scan for PnP devices", pnp_scan); int pnp_scan(int argc, char *argv[]) { + struct pnpinfo *pi; int hdlr; + int verbose; + int ch; + + if (pnp_devices_initted == 0) { + STAILQ_INIT(&pnp_devices); + pnp_devices_initted = 1; + } + + verbose = 0; + optind = 1; + while ((ch = getopt(argc, argv, "v")) != -1) { + switch(ch) { + case 'v': + verbose = 1; + break; + case '?': + default: + /* getopt has already reported an error */ + return(CMD_OK); + } + } /* forget anything we think we knew */ - pnp_discard(&pnp_devices); + pnp_discard(); + + if (verbose) + pager_open(); /* iterate over all of the handlers */ for (hdlr = 0; pnphandlers[hdlr] != NULL; hdlr++) { - printf("Probing bus '%s'...\n", pnphandlers[hdlr]->pp_name); - pnphandlers[hdlr]->pp_enumerate(&pnp_devices); + if (verbose) { + pager_output("Probing "); + pager_output(pnphandlers[hdlr]->pp_name); + pager_output("...\n"); + } + pnphandlers[hdlr]->pp_enumerate(); + } + if (verbose) { + for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) { + pager_output(pi->pi_ident.stqh_first->id_ident); /* first ident should be canonical */ + if (pi->pi_desc != NULL) { + pager_output(" : "); + pager_output(pi->pi_desc); + pager_output("\n"); + } + } + pager_close(); } return(CMD_OK); } @@ -51,7 +92,7 @@ pnp_reload(char *fname) char *modfname; /* find anything? */ - if (pnp_devices != NULL) { + if (pnp_devices.stqh_first != NULL) { /* check for kernel, assign modules handled by static drivers there */ if (pnp_scankernel()) { @@ -70,13 +111,13 @@ pnp_reload(char *fname) } /* try to load any modules that have been nominated */ - for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) { + for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) { /* Already loaded? */ if ((pi->pi_module != NULL) && (mod_findmodule(pi->pi_module, NULL) == NULL)) { modfname = malloc(strlen(pi->pi_module + 3)); sprintf(modfname, "%s.ko", pi->pi_module); /* XXX implicit knowledge of KLD module filenames */ if (mod_load(pi->pi_module, pi->pi_argc, pi->pi_argv)) - printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident->id_ident); + printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident.stqh_first->id_ident); free(modfname); } } @@ -88,24 +129,14 @@ pnp_reload(char *fname) * Throw away anything we think we know about PnP devices on (list) */ static void -pnp_discard(struct pnpinfo **list) +pnp_discard(void) { struct pnpinfo *pi; - struct pnpident *id; - - while (*list != NULL) { - pi = *list; - *list = (*list)->pi_next; - while (pi->pi_ident) { - id = pi->pi_ident; - pi->pi_ident = pi->pi_ident->id_next; - free(id); - } - if (pi->pi_module) - free(pi->pi_module); - if (pi->pi_argv) - free(pi->pi_argv); - free(pi); + + while (pnp_devices.stqh_first != NULL) { + pi = pnp_devices.stqh_first; + STAILQ_REMOVE_HEAD(&pnp_devices, pi_link); + pnp_freeinfo(pi); } } @@ -226,14 +257,14 @@ pnp_readconf(char *path) * assigned. * XXX no revision parse/test here yet. */ - for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) { + for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) { /* no driver assigned, bus matches OK */ if ((pi->pi_module == NULL) && !strcmp(pi->pi_handler->pp_name, currbus)) { /* scan idents, take first match */ - for (id = pi->pi_ident; id != NULL; id = id->id_next) + for (id = pi->pi_ident.stqh_first; id != NULL; id = id->id_link.stqe_next) if (!strcmp(id->id_ident, ident)) break; @@ -267,19 +298,60 @@ pnp_scankernel(void) void pnp_addident(struct pnpinfo *pi, char *ident) { - struct pnpident *id, **idp; + struct pnpident *id; + + for (id = pi->pi_ident.stqh_first; id != NULL; id = id->id_link.stqe_next) + if (!strcmp(id->id_ident, ident)) + return; /* already have this one */ + + id = malloc(sizeof(struct pnpident)); + id->id_ident = strdup(ident); + STAILQ_INSERT_TAIL(&pi->pi_ident, id, id_link); +} + +/* + * Allocate a new pnpinfo struct + */ +struct pnpinfo * +pnp_allocinfo(void) +{ + struct pnpinfo *pi; - if (pi->pi_ident == NULL) { - idp = &(pi->pi_ident); - } else { - for (id = pi->pi_ident; id->id_next != NULL; id = id->id_next) - if (!strcmp(id->id_ident, ident)) - return; /* already have this one */ - ; - idp = &(id->id_next); + pi = malloc(sizeof(struct pnpinfo)); + bzero(pi, sizeof(struct pnpinfo)); + STAILQ_INIT(&pi->pi_ident); + return(pi); +} + +/* + * Release storage held by a pnpinfo struct + */ +void +pnp_freeinfo(struct pnpinfo *pi) +{ + struct pnpident *id; + + while (pi->pi_ident.stqh_first != NULL) { + id = pi->pi_ident.stqh_first; + STAILQ_REMOVE_HEAD(&pi->pi_ident, id_link); + free(id->id_ident); + free(id); } - *idp = malloc(sizeof(struct pnpident)); - (*idp)->id_next = NULL; - (*idp)->id_ident = strdup(ident); + if (pi->pi_desc) + free(pi->pi_desc); + if (pi->pi_module) + free(pi->pi_module); + if (pi->pi_argv) + free(pi->pi_argv); + free(pi); +} + +/* + * Add a new pnpinfo struct to the list. + */ +void +pnp_addinfo(struct pnpinfo *pi) +{ + STAILQ_INSERT_TAIL(&pnp_devices, pi, pi_link); } |