10 * "Plug and Play" functionality.
12 * We use the PnP enumerators to obtain identifiers for installed hardware,
13 * and the contents of a database to determine modules to be loaded to support
19 #include <bootstrap.h>
24 static struct pnpinfo_stql pnp_devices;
25 static int pnp_devices_initted = 0;
27 static void pnp_discard(void);
30 * Perform complete enumeration sweep
33 COMMAND_SET(pnpscan, "pnpscan", "scan for PnP devices", pnp_scan);
36 pnp_scan(int argc, char *argv[])
43 if (pnp_devices_initted == 0) {
44 STAILQ_INIT(&pnp_devices);
45 pnp_devices_initted = 1;
51 while ((ch = getopt(argc, argv, "v")) != -1) {
58 /* getopt has already reported an error */
63 /* forget anything we think we knew */
66 /* iterate over all of the handlers */
67 for (hdlr = 0; pnphandlers[hdlr] != NULL; hdlr++) {
69 printf("Probing %s...\n", pnphandlers[hdlr]->pp_name);
70 pnphandlers[hdlr]->pp_enumerate();
74 if (pager_output("PNP scan summary:\n"))
76 STAILQ_FOREACH(pi, &pnp_devices, pi_link) {
77 pager_output(STAILQ_FIRST(&pi->pi_ident)->id_ident); /* first ident should be canonical */
78 if (pi->pi_desc != NULL) {
80 pager_output(pi->pi_desc);
82 if (pager_output("\n"))
92 * Throw away anything we think we know about PnP devices.
99 while (STAILQ_FIRST(&pnp_devices) != NULL) {
100 pi = STAILQ_FIRST(&pnp_devices);
101 STAILQ_REMOVE_HEAD(&pnp_devices, pi_link);
107 * Add a unique identifier to (pi)
110 pnp_addident(struct pnpinfo *pi, char *ident)
114 STAILQ_FOREACH(id, &pi->pi_ident, id_link)
115 if (!strcmp(id->id_ident, ident))
116 return; /* already have this one */
118 id = malloc(sizeof(struct pnpident));
119 id->id_ident = strdup(ident);
120 STAILQ_INSERT_TAIL(&pi->pi_ident, id, id_link);
124 * Allocate a new pnpinfo struct
131 pi = malloc(sizeof(struct pnpinfo));
132 bzero(pi, sizeof(struct pnpinfo));
133 STAILQ_INIT(&pi->pi_ident);
138 * Release storage held by a pnpinfo struct
141 pnp_freeinfo(struct pnpinfo *pi)
145 while (!STAILQ_EMPTY(&pi->pi_ident)) {
146 id = STAILQ_FIRST(&pi->pi_ident);
147 STAILQ_REMOVE_HEAD(&pi->pi_ident, id_link);
161 * Add a new pnpinfo struct to the list.
164 pnp_addinfo(struct pnpinfo *pi)
166 STAILQ_INSERT_TAIL(&pnp_devices, pi, pi_link);
171 * Format an EISA id as a string in standard ISA PnP format, AAAIIRR
172 * where 'AAA' is the EISA vendor ID, II is the product ID and RR the revision ID.
175 pnp_eisaformat(u_int8_t *data)
177 static char idbuf[8];
178 const char hextoascii[] = "0123456789abcdef";
180 idbuf[0] = '@' + ((data[0] & 0x7c) >> 2);
181 idbuf[1] = '@' + (((data[0] & 0x3) << 3) + ((data[1] & 0xe0) >> 5));
182 idbuf[2] = '@' + (data[1] & 0x1f);
183 idbuf[3] = hextoascii[(data[2] >> 4)];
184 idbuf[4] = hextoascii[(data[2] & 0xf)];
185 idbuf[5] = hextoascii[(data[3] >> 4)];
186 idbuf[6] = hextoascii[(data[3] & 0xf)];
193 ficlPnpdevices(FICL_VM *pVM)
195 static int pnp_devices_initted = 0;
197 vmCheckStack(pVM, 0, 1);
200 if(!pnp_devices_initted) {
201 STAILQ_INIT(&pnp_devices);
202 pnp_devices_initted = 1;
205 stackPushPtr(pVM->pStack, &pnp_devices);
211 ficlPnphandlers(FICL_VM *pVM)
214 vmCheckStack(pVM, 0, 1);
217 stackPushPtr(pVM->pStack, pnphandlers);
223 * Glue function to add the appropriate forth words to access pnp BIOS
226 static void ficlCompilePnp(FICL_SYSTEM *pSys)
228 FICL_DICT *dp = pSys->dp;
231 dictAppendWord(dp, "pnpdevices",ficlPnpdevices, FW_DEFAULT);
232 dictAppendWord(dp, "pnphandlers",ficlPnphandlers, FW_DEFAULT);
235 FICL_COMPILE_SET(ficlCompilePnp);