summaryrefslogtreecommitdiffstats
path: root/sys/boot/common/pnp.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1998-10-21 20:07:05 +0000
committermsmith <msmith@FreeBSD.org>1998-10-21 20:07:05 +0000
commit880061ca43c5eb7110f8b122628b447b5df729e9 (patch)
treec03d04e81f549d7c5f9fdd53d289b5ef2e77e1e7 /sys/boot/common/pnp.c
parenta9435964cae6bb08cf72cd42f4f2e90b5721bbcb (diff)
downloadFreeBSD-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.c148
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);
}
OpenPOWER on IntegriCloud