This source file includes following definitions.
- acpidock_match
- acpidock_attach
- acpidock_status
- acpidock_docklock
- acpidock_dockctl
- acpidock_eject
- acpidock_notify
- acpidock_foundejd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 #include <sys/malloc.h>
22 #include <sys/sensors.h>
23
24 #include <machine/bus.h>
25
26 #include <dev/acpi/acpireg.h>
27 #include <dev/acpi/acpivar.h>
28 #include <dev/acpi/acpidev.h>
29 #include <dev/acpi/amltypes.h>
30 #include <dev/acpi/dsdt.h>
31
32 struct aml_nodelist {
33 struct aml_node *node;
34 TAILQ_ENTRY(aml_nodelist) entries;
35 };
36
37 int acpidock_match(struct device *, void *, void *);
38 void acpidock_attach(struct device *, struct device *, void *);
39
40 struct cfattach acpidock_ca = {
41 sizeof(struct acpidock_softc), acpidock_match, acpidock_attach
42 };
43
44 struct cfdriver acpidock_cd = {
45 NULL, "acpidock", DV_DULL
46 };
47
48
49 int acpidock_docklock(struct acpidock_softc *, int);
50 int acpidock_dockctl(struct acpidock_softc *, int);
51 int acpidock_eject(struct acpidock_softc *, struct aml_node *);
52 int acpidock_notify(struct aml_node *, int, void *);
53 int acpidock_status(struct acpidock_softc *);
54
55 void acpidock_foundejd(struct aml_node *, void *);
56
57 int
58 acpidock_match(struct device *parent, void *match, void *aux)
59 {
60 struct acpi_attach_args *aaa = aux;
61 struct cfdata *cf = match;
62
63
64 if (aaa->aaa_name == NULL ||
65 strcmp(aaa->aaa_name, cf->cf_driver->cd_name) != 0 ||
66 aaa->aaa_table != NULL)
67 return (0);
68
69 return (1);
70 }
71
72 void
73 acpidock_attach(struct device *parent, struct device *self, void *aux)
74 {
75 struct acpidock_softc *sc = (struct acpidock_softc *)self;
76 struct acpi_attach_args *aa = aux;
77 extern struct aml_node aml_root;
78
79 sc->sc_acpi = (struct acpi_softc *)parent;
80 sc->sc_devnode = aa->aaa_node->child;
81
82 printf(": %s", sc->sc_devnode->parent->name);
83
84 acpidock_status(sc);
85 if (sc->sc_docked == ACPIDOCK_STATUS_DOCKED) {
86 acpidock_docklock(sc, 1);
87 acpidock_dockctl(sc, 1);
88 } else {
89 acpidock_dockctl(sc, 0);
90 acpidock_docklock(sc, 0);
91 }
92
93 acpidock_status(sc);
94 printf(":%s docked (%d)\n",
95 sc->sc_docked == ACPIDOCK_STATUS_DOCKED ? "" : " not",
96 sc->sc_sta);
97
98 strlcpy(sc->sc_sensdev.xname, DEVNAME(sc),
99 sizeof(sc->sc_sensdev.xname));
100 if (sc->sc_docked)
101 strlcpy(sc->sc_sens.desc, "docked",
102 sizeof(sc->sc_sens.desc));
103 else
104 strlcpy(sc->sc_sens.desc, "not docked",
105 sizeof(sc->sc_sens.desc));
106
107 sc->sc_sens.type = SENSOR_INDICATOR;
108 sc->sc_sens.value = sc->sc_docked == ACPIDOCK_STATUS_DOCKED;
109 sensor_attach(&sc->sc_sensdev, &sc->sc_sens);
110 sensordev_install(&sc->sc_sensdev);
111
112 TAILQ_INIT(&sc->sc_deps_h);
113 aml_find_node(aml_root.child, "_EJD", acpidock_foundejd, sc);
114
115 aml_register_notify(sc->sc_devnode->parent, aa->aaa_dev,
116 acpidock_notify, sc, ACPIDEV_NOPOLL);
117
118 }
119
120 int
121 acpidock_status(struct acpidock_softc *sc)
122 {
123 struct aml_value res;
124 int rv;
125
126 if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL,
127 &res) != 0)
128 rv = 0;
129 else
130 rv = 1;
131
132 sc->sc_sta = aml_val2int(&res);
133
134 sc->sc_docked = sc->sc_sta & STA_PRESENT;
135
136 aml_freevalue(&res);
137
138 return (rv);
139 }
140
141 int
142 acpidock_docklock(struct acpidock_softc *sc, int lock)
143 {
144 struct aml_value cmd;
145 struct aml_value res;
146 int rv;
147
148 memset(&cmd, 0, sizeof cmd);
149 cmd.v_integer = lock;
150 cmd.type = AML_OBJTYPE_INTEGER;
151 if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_LCK", 1, &cmd,
152 &res) != 0) {
153 dnprintf(20, "%s: _LCK %d failed\n", DEVNAME(sc), lock);
154
155 rv = 0;
156 } else {
157 dnprintf(20, "%s: _LCK %d successful\n", DEVNAME(sc), lock);
158
159 rv = 1;
160 }
161
162 aml_freevalue(&res);
163
164 return rv;
165 }
166
167 int
168 acpidock_dockctl(struct acpidock_softc *sc, int dock)
169 {
170 struct aml_value cmd;
171 struct aml_value res;
172 int rv;
173
174 memset(&cmd, 0, sizeof cmd);
175 cmd.v_integer = dock;
176 cmd.type = AML_OBJTYPE_INTEGER;
177 if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_DCK", 1, &cmd,
178 &res) != 0) {
179
180 dnprintf(15, "%s: _DCK %d failed\n", DEVNAME(sc), dock);
181
182 rv = 0;
183 } else {
184 dnprintf(15, "%s: _DCK %d successful\n", DEVNAME(sc), dock);
185
186 rv = 1;
187 }
188
189 aml_freevalue(&res);
190
191 return rv;
192 }
193
194 int
195 acpidock_eject(struct acpidock_softc *sc, struct aml_node *node)
196 {
197 struct aml_value cmd;
198 struct aml_value res;
199 int rv;
200
201 memset(&cmd, 0, sizeof cmd);
202 cmd.v_integer = 1;
203 cmd.type = AML_OBJTYPE_INTEGER;
204 if (aml_evalname(sc->sc_acpi, node, "_EJ0", 1, &cmd,
205 &res) != 0) {
206
207 dnprintf(15, "%s: _EJ0 failed\n", DEVNAME(sc));
208
209 rv = 0;
210 } else {
211 dnprintf(15, "%s: _EJ0 successful\n", DEVNAME(sc));
212
213 rv = 1;
214 }
215
216 aml_freevalue(&res);
217
218 return rv;
219 }
220
221 int
222 acpidock_notify(struct aml_node *node, int notify_type, void *arg)
223 {
224 struct acpidock_softc *sc = arg;
225
226 dnprintf(5, "%s: acpidock_notify: notify %d\n", DEVNAME(sc),
227 notify_type);
228
229 switch (notify_type) {
230 case ACPIDOCK_EVENT_INSERT:
231 printf("%s: dock", DEVNAME(sc));
232 acpidock_docklock(sc, 1);
233 acpidock_dockctl(sc, 1);
234
235 break;
236 case ACPIDOCK_EVENT_EJECT: {
237 struct aml_nodelist *n;
238
239 TAILQ_FOREACH(n, &sc->sc_deps_h, entries)
240 acpidock_eject(sc, n->node);
241
242 acpidock_dockctl(sc, 0);
243 acpidock_docklock(sc, 0);
244
245
246 acpidock_eject(sc, sc->sc_devnode);
247
248 printf("%s: undock", DEVNAME(sc));
249
250 break;
251 }
252 }
253
254 acpidock_status(sc);
255 sc->sc_sens.value = sc->sc_docked == ACPIDOCK_STATUS_DOCKED;
256 if (sc->sc_docked)
257 strlcpy(sc->sc_sens.desc, "docked",
258 sizeof(sc->sc_sens.desc));
259 else
260 strlcpy(sc->sc_sens.desc, "not docked",
261 sizeof(sc->sc_sens.desc));
262
263 printf(": status %s\n",
264 sc->sc_docked == ACPIDOCK_STATUS_DOCKED ? "docked" : "undocked");
265
266 return (0);
267 }
268
269 void
270 acpidock_foundejd(struct aml_node *node, void *arg)
271 {
272 struct acpidock_softc *sc = (struct acpidock_softc *)arg;
273 struct aml_value res;
274
275 dnprintf(15, "%s: %s", DEVNAME(sc), node->parent->name);
276
277 if (aml_evalnode(sc->sc_acpi, node, 0, NULL, &res) == -1) {
278 printf(": error\n");
279 } else {
280 struct aml_nodelist *n;
281
282
283 dnprintf(10, "%s: %s depends on %s\n", DEVNAME(sc),
284 node->parent->name, res.v_string);
285
286
287
288 n = malloc(sizeof(struct aml_nodelist), M_DEVBUF, M_WAITOK);
289 n->node = node->parent;
290
291 TAILQ_INSERT_TAIL(&sc->sc_deps_h, n, entries);
292 }
293
294 aml_freevalue(&res);
295 }