Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/common/pnp.c
34677 views
1
/*
2
* mjs copyright
3
*
4
*/
5
6
/*
7
* "Plug and Play" functionality.
8
*
9
* We use the PnP enumerators to obtain identifiers for installed hardware,
10
* and the contents of a database to determine modules to be loaded to support
11
* such hardware.
12
*/
13
14
#include <stand.h>
15
#include <string.h>
16
#include <bootstrap.h>
17
18
static struct pnpinfo_stql pnp_devices;
19
static int pnp_devices_initted = 0;
20
21
static void pnp_discard(void);
22
23
/*
24
* Perform complete enumeration sweep
25
*/
26
27
COMMAND_SET(pnpscan, "pnpscan", "scan for PnP devices", pnp_scan);
28
29
static int
30
pnp_scan(int argc, char *argv[])
31
{
32
struct pnpinfo *pi;
33
int hdlr;
34
int verbose;
35
int ch;
36
37
if (pnp_devices_initted == 0) {
38
STAILQ_INIT(&pnp_devices);
39
pnp_devices_initted = 1;
40
}
41
42
verbose = 0;
43
optind = 1;
44
optreset = 1;
45
while ((ch = getopt(argc, argv, "v")) != -1) {
46
switch(ch) {
47
case 'v':
48
verbose = 1;
49
break;
50
case '?':
51
default:
52
/* getopt has already reported an error */
53
return(CMD_OK);
54
}
55
}
56
57
/* forget anything we think we knew */
58
pnp_discard();
59
60
/* iterate over all of the handlers */
61
for (hdlr = 0; pnphandlers[hdlr] != NULL; hdlr++) {
62
if (verbose)
63
printf("Probing %s...\n", pnphandlers[hdlr]->pp_name);
64
pnphandlers[hdlr]->pp_enumerate();
65
}
66
if (verbose) {
67
pager_open();
68
if (pager_output("PNP scan summary:\n"))
69
goto out;
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) {
73
pager_output(" : ");
74
pager_output(pi->pi_desc);
75
}
76
if (pager_output("\n"))
77
break;
78
}
79
out:
80
pager_close();
81
}
82
return(CMD_OK);
83
}
84
85
/*
86
* Throw away anything we think we know about PnP devices.
87
*/
88
static void
89
pnp_discard(void)
90
{
91
struct pnpinfo *pi;
92
93
while (STAILQ_FIRST(&pnp_devices) != NULL) {
94
pi = STAILQ_FIRST(&pnp_devices);
95
STAILQ_REMOVE_HEAD(&pnp_devices, pi_link);
96
pnp_freeinfo(pi);
97
}
98
}
99
100
/*
101
* Add a unique identifier to (pi)
102
*/
103
void
104
pnp_addident(struct pnpinfo *pi, char *ident)
105
{
106
struct pnpident *id;
107
108
STAILQ_FOREACH(id, &pi->pi_ident, id_link)
109
if (!strcmp(id->id_ident, ident))
110
return; /* already have this one */
111
112
id = malloc(sizeof(struct pnpident));
113
id->id_ident = strdup(ident);
114
STAILQ_INSERT_TAIL(&pi->pi_ident, id, id_link);
115
}
116
117
/*
118
* Allocate a new pnpinfo struct
119
*/
120
struct pnpinfo *
121
pnp_allocinfo(void)
122
{
123
struct pnpinfo *pi;
124
125
pi = malloc(sizeof(struct pnpinfo));
126
bzero(pi, sizeof(struct pnpinfo));
127
STAILQ_INIT(&pi->pi_ident);
128
return(pi);
129
}
130
131
/*
132
* Release storage held by a pnpinfo struct
133
*/
134
void
135
pnp_freeinfo(struct pnpinfo *pi)
136
{
137
struct pnpident *id;
138
139
while (!STAILQ_EMPTY(&pi->pi_ident)) {
140
id = STAILQ_FIRST(&pi->pi_ident);
141
STAILQ_REMOVE_HEAD(&pi->pi_ident, id_link);
142
free(id->id_ident);
143
free(id);
144
}
145
if (pi->pi_desc)
146
free(pi->pi_desc);
147
if (pi->pi_module)
148
free(pi->pi_module);
149
if (pi->pi_argv)
150
free(pi->pi_argv);
151
free(pi);
152
}
153
154
/*
155
* Add a new pnpinfo struct to the list.
156
*/
157
void
158
pnp_addinfo(struct pnpinfo *pi)
159
{
160
STAILQ_INSERT_TAIL(&pnp_devices, pi, pi_link);
161
}
162
163
164
/*
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.
167
*/
168
char *
169
pnp_eisaformat(uint8_t *data)
170
{
171
static char idbuf[8];
172
const char hextoascii[] = "0123456789abcdef";
173
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)];
181
idbuf[7] = 0;
182
return(idbuf);
183
}
184
185