4 * $FreeBSD: src/sys/boot/common/pnp.c,v 1.16 2003/08/25 23:30:41 obrien Exp $
8 * "Plug and Play" functionality.
10 * We use the PnP enumerators to obtain identifiers for installed hardware,
11 * and the contents of a database to determine modules to be loaded to support
17 #include <bootstrap.h>
19 struct pnpinfo_stql pnp_devices
;
20 static int pnp_devices_initted
= 0;
22 static void pnp_discard(void);
25 * Perform complete enumeration sweep
28 COMMAND_SET(pnpscan
, "pnpscan", "scan for PnP devices", pnp_scan
);
31 pnp_scan(int argc
, char *argv
[])
38 if (pnp_devices_initted
== 0) {
39 STAILQ_INIT(&pnp_devices
);
40 pnp_devices_initted
= 1;
46 while ((ch
= getopt(argc
, argv
, "v")) != -1) {
53 /* getopt has already reported an error */
58 /* forget anything we think we knew */
61 /* iterate over all of the handlers */
62 for (hdlr
= 0; pnphandlers
[hdlr
] != NULL
; hdlr
++) {
64 printf("Probing %s...\n", pnphandlers
[hdlr
]->pp_name
);
65 pnphandlers
[hdlr
]->pp_enumerate();
69 pager_output("PNP scan summary:\n");
70 STAILQ_FOREACH(pi
, &pnp_devices
, pi_link
) {
71 pager_output(STAILQ_FIRST(&pi
->pi_ident
)->id_ident
); /* first ident should be canonical */
72 if (pi
->pi_desc
!= NULL
) {
74 pager_output(pi
->pi_desc
);
84 * Throw away anything we think we know about PnP devices.
91 while (STAILQ_FIRST(&pnp_devices
) != NULL
) {
92 pi
= STAILQ_FIRST(&pnp_devices
);
93 STAILQ_REMOVE_HEAD(&pnp_devices
, pi_link
);
99 * Add a unique identifier to (pi)
102 pnp_addident(struct pnpinfo
*pi
, char *ident
)
106 STAILQ_FOREACH(id
, &pi
->pi_ident
, id_link
)
107 if (!strcmp(id
->id_ident
, ident
))
108 return; /* already have this one */
110 id
= malloc(sizeof(struct pnpident
));
111 id
->id_ident
= strdup(ident
);
112 STAILQ_INSERT_TAIL(&pi
->pi_ident
, id
, id_link
);
116 * Allocate a new pnpinfo struct
123 pi
= malloc(sizeof(struct pnpinfo
));
124 bzero(pi
, sizeof(struct pnpinfo
));
125 STAILQ_INIT(&pi
->pi_ident
);
130 * Release storage held by a pnpinfo struct
133 pnp_freeinfo(struct pnpinfo
*pi
)
137 while (!STAILQ_EMPTY(&pi
->pi_ident
)) {
138 id
= STAILQ_FIRST(&pi
->pi_ident
);
139 STAILQ_REMOVE_HEAD(&pi
->pi_ident
, id_link
);
153 * Add a new pnpinfo struct to the list.
156 pnp_addinfo(struct pnpinfo
*pi
)
158 STAILQ_INSERT_TAIL(&pnp_devices
, pi
, pi_link
);
163 * Format an EISA id as a string in standard ISA PnP format, AAAIIRR
164 * where 'AAA' is the EISA vendor ID, II is the product ID and RR the revision ID.
167 pnp_eisaformat(u_int8_t
*data
)
169 static char idbuf
[8];
170 const char hextoascii
[] = "0123456789abcdef";
172 idbuf
[0] = '@' + ((data
[0] & 0x7c) >> 2);
173 idbuf
[1] = '@' + (((data
[0] & 0x3) << 3) + ((data
[1] & 0xe0) >> 5));
174 idbuf
[2] = '@' + (data
[1] & 0x1f);
175 idbuf
[3] = hextoascii
[(data
[2] >> 4)];
176 idbuf
[4] = hextoascii
[(data
[2] & 0xf)];
177 idbuf
[5] = hextoascii
[(data
[3] >> 4)];
178 idbuf
[6] = hextoascii
[(data
[3] & 0xf)];