9 * "Plug and Play" functionality.
11 * We use the PnP enumerators to obtain identifiers for installed hardware,
12 * and the contents of a database to determine modules to be loaded to support
18 #include <bootstrap.h>
21 static struct pnpinfo_stql pnp_devices
;
22 static int pnp_devices_initted
= 0;
24 static void pnp_discard(void);
27 * Perform complete enumeration sweep
30 COMMAND_SET(pnpscan
, "pnpscan", "scan for PnP devices", pnp_scan
);
33 pnp_scan(int argc
, char *argv
[])
40 if (pnp_devices_initted
== 0) {
41 STAILQ_INIT(&pnp_devices
);
42 pnp_devices_initted
= 1;
48 while ((ch
= getopt(argc
, argv
, "v")) != -1) {
55 /* getopt has already reported an error */
60 /* forget anything we think we knew */
63 /* iterate over all of the handlers */
64 for (hdlr
= 0; pnphandlers
[hdlr
] != NULL
; hdlr
++) {
66 printf("Probing %s...\n", pnphandlers
[hdlr
]->pp_name
);
67 pnphandlers
[hdlr
]->pp_enumerate();
71 pager_output("PNP scan summary:\n");
72 STAILQ_FOREACH(pi
, &pnp_devices
, pi_link
) {
73 pager_output(STAILQ_FIRST(&pi
->pi_ident
)->id_ident
); /* first ident should be canonical */
74 if (pi
->pi_desc
!= NULL
) {
76 pager_output(pi
->pi_desc
);
86 * Throw away anything we think we know about PnP devices.
93 while (STAILQ_FIRST(&pnp_devices
) != NULL
) {
94 pi
= STAILQ_FIRST(&pnp_devices
);
95 STAILQ_REMOVE_HEAD(&pnp_devices
, pi_link
);
101 * Add a unique identifier to (pi)
104 pnp_addident(struct pnpinfo
*pi
, char *ident
)
108 STAILQ_FOREACH(id
, &pi
->pi_ident
, id_link
)
109 if (!strcmp(id
->id_ident
, ident
))
110 return; /* already have this one */
112 id
= malloc(sizeof(struct pnpident
));
113 id
->id_ident
= strdup(ident
);
114 STAILQ_INSERT_TAIL(&pi
->pi_ident
, id
, id_link
);
118 * Allocate a new pnpinfo struct
125 pi
= malloc(sizeof(struct pnpinfo
));
126 bzero(pi
, sizeof(struct pnpinfo
));
127 STAILQ_INIT(&pi
->pi_ident
);
132 * Release storage held by a pnpinfo struct
135 pnp_freeinfo(struct pnpinfo
*pi
)
139 while (!STAILQ_EMPTY(&pi
->pi_ident
)) {
140 id
= STAILQ_FIRST(&pi
->pi_ident
);
141 STAILQ_REMOVE_HEAD(&pi
->pi_ident
, id_link
);
155 * Add a new pnpinfo struct to the list.
158 pnp_addinfo(struct pnpinfo
*pi
)
160 STAILQ_INSERT_TAIL(&pnp_devices
, pi
, pi_link
);
165 * Format an EISA id as a string in standard ISA PnP format, AAAIIRR
166 * where 'AAA' is the EISA vendor ID, II is the product ID and RR the revision ID.
169 pnp_eisaformat(u_int8_t
*data
)
171 static char idbuf
[8];
172 const char hextoascii
[] = "0123456789abcdef";
174 idbuf
[0] = '@' + ((data
[0] & 0x7c) >> 2);
175 idbuf
[1] = '@' + (((data
[0] & 0x3) << 3) + ((data
[1] & 0xe0) >> 5));
176 idbuf
[2] = '@' + (data
[1] & 0x1f);
177 idbuf
[3] = hextoascii
[(data
[2] >> 4)];
178 idbuf
[4] = hextoascii
[(data
[2] & 0xf)];
179 idbuf
[5] = hextoascii
[(data
[3] >> 4)];
180 idbuf
[6] = hextoascii
[(data
[3] & 0xf)];
186 ficlPnpdevices(ficlVm
*pVM
)
188 static int pnp_devices_initted
= 0;
190 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 0, 1);
192 if (!pnp_devices_initted
) {
193 STAILQ_INIT(&pnp_devices
);
194 pnp_devices_initted
= 1;
197 ficlStackPushPointer(ficlVmGetDataStack(pVM
), &pnp_devices
);
201 ficlPnphandlers(ficlVm
*pVM
)
203 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 0, 1);
205 ficlStackPushPointer(ficlVmGetDataStack(pVM
), pnphandlers
);
209 * Glue function to add the appropriate forth words to access pnp BIOS
213 ficlCompilePnp(ficlSystem
*pSys
)
215 ficlDictionary
*dp
= ficlSystemGetDictionary(pSys
);
217 FICL_SYSTEM_ASSERT(pSys
, dp
);
219 ficlDictionarySetPrimitive(dp
, "pnpdevices", ficlPnpdevices
,
221 ficlDictionarySetPrimitive(dp
, "pnphandlers", ficlPnphandlers
,
225 FICL_COMPILE_SET(ficlCompilePnp
);