This source file includes following definitions.
- cardslotmatch
- cardslotattach
- cardslot_cb_print
- cardslot_16_submatch
- cardslot_16_print
- create_slot_manager
- cardslot_event_throw
- cardslot_event_thread
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/device.h>
39 #include <sys/malloc.h>
40 #include <sys/kernel.h>
41 #include <sys/syslog.h>
42 #include <sys/kthread.h>
43
44 #include <machine/bus.h>
45
46 #include <dev/cardbus/cardslotvar.h>
47 #include <dev/cardbus/cardbusvar.h>
48 #include <dev/pcmcia/pcmciavar.h>
49 #include <dev/pcmcia/pcmciachip.h>
50 #include <dev/ic/i82365var.h>
51
52 #if defined CARDSLOT_DEBUG
53 #define STATIC
54 #define DPRINTF(a) printf a
55 #else
56 #define STATIC static
57 #define DPRINTF(a)
58 #endif
59
60 STATIC void cardslotattach(struct device *, struct device *, void *);
61
62 STATIC int cardslotmatch(struct device *, void *, void *);
63 static void create_slot_manager(void *);
64 static void cardslot_event_thread(void *arg);
65
66 STATIC int cardslot_cb_print(void *aux, const char *pcic);
67 static int cardslot_16_print(void *, const char *);
68 static int cardslot_16_submatch(struct device *, void *,void *);
69
70 struct cfattach cardslot_ca = {
71 sizeof(struct cardslot_softc), cardslotmatch, cardslotattach
72 };
73
74 struct cfdriver cardslot_cd = {
75 NULL, "cardslot", DV_DULL
76 };
77
78 STATIC int
79 cardslotmatch(struct device *parent, void *match, void *aux)
80 {
81 struct cardslot_attach_args *caa = aux;
82
83 if (caa->caa_cb_attach == NULL && caa->caa_16_attach == NULL) {
84
85 return (0);
86 }
87
88 return (1);
89 }
90
91 STATIC void
92 cardslotattach(struct device *parent, struct device *self, void *aux)
93 {
94 struct cardslot_softc *sc = (struct cardslot_softc *)self;
95 struct cardslot_attach_args *caa = aux;
96
97 struct cbslot_attach_args *cba = caa->caa_cb_attach;
98 struct pcmciabus_attach_args *pa = caa->caa_16_attach;
99
100 struct cardbus_softc *csc;
101 struct pcmcia_softc *psc;
102
103 sc->sc_slot = sc->sc_dev.dv_unit;
104 sc->sc_cb_softc = NULL;
105 sc->sc_16_softc = NULL;
106 SIMPLEQ_INIT(&sc->sc_events);
107 sc->sc_th_enable = 0;
108
109 printf(" slot %d flags %x\n", sc->sc_slot,
110 sc->sc_dev.dv_cfdata->cf_flags);
111
112 DPRINTF(("%s attaching CardBus bus...\n", sc->sc_dev.dv_xname));
113 if (cba != NULL) {
114 if ((csc = (void *)config_found(self, cba,
115 cardslot_cb_print)) != NULL) {
116
117 DPRINTF(("cardslotattach: found cardbus on %s\n",
118 sc->sc_dev.dv_xname));
119 sc->sc_cb_softc = csc;
120 }
121 }
122
123 if (pa != NULL) {
124 if ((psc = (void *)config_found_sm(self, pa, cardslot_16_print,
125 cardslot_16_submatch)) != NULL) {
126
127 DPRINTF(("cardslotattach: found 16-bit pcmcia bus\n"));
128 sc->sc_16_softc = psc;
129
130
131
132 caa->caa_ph->pcmcia = (struct device *)psc;
133 }
134 }
135
136 if (csc != NULL || psc != NULL)
137 kthread_create_deferred(create_slot_manager, (void *)sc);
138
139 if (csc && (csc->sc_cf->cardbus_ctrl)(csc->sc_cc, CARDBUS_CD)) {
140 DPRINTF(("cardslotattach: CardBus card found\n"));
141
142 cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_CB);
143 }
144
145 if (psc && (psc->pct->card_detect)(psc->pch)) {
146 DPRINTF(("cardbusattach: 16-bit card found\n"));
147
148 cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_16);
149 }
150 }
151
152 STATIC int
153 cardslot_cb_print(void *aux, const char *pnp)
154 {
155 struct cbslot_attach_args *cba = aux;
156
157 if (pnp)
158 printf("cardbus at %s subordinate bus %d", pnp, cba->cba_bus);
159
160 return (UNCONF);
161 }
162
163 static int
164 cardslot_16_submatch(struct device *parent, void *match, void *aux)
165 {
166 struct cfdata *cf = match;
167
168 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
169 return (0);
170
171 if (cf->cf_loc[0] == -1)
172 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
173
174 return (0);
175 }
176
177 static int
178 cardslot_16_print(void *arg, const char *pnp)
179 {
180 if (pnp)
181 printf("pcmciabus at %s", pnp);
182
183 return (UNCONF);
184 }
185
186 static void
187 create_slot_manager(void *arg)
188 {
189 struct cardslot_softc *sc = (struct cardslot_softc *)arg;
190
191 sc->sc_th_enable = 1;
192
193 if (kthread_create(cardslot_event_thread, sc, &sc->sc_event_thread,
194 "%s", sc->sc_dev.dv_xname)) {
195 printf("%s: unable to create event thread for slot %d\n",
196 sc->sc_dev.dv_xname, sc->sc_slot);
197 panic("create_slot_manager");
198 }
199 }
200
201
202
203
204
205
206
207 void
208 cardslot_event_throw(struct cardslot_softc *sc, int ev)
209 {
210 struct cardslot_event *ce;
211
212 DPRINTF(("cardslot_event_throw: an event %s comes\n",
213 ev == CARDSLOT_EVENT_INSERTION_CB ? "CardBus Card inserted" :
214 ev == CARDSLOT_EVENT_INSERTION_16 ? "16-bit Card inserted" :
215 ev == CARDSLOT_EVENT_REMOVAL_CB ? "CardBus Card removed" :
216 ev == CARDSLOT_EVENT_REMOVAL_16 ? "16-bit Card removed" : "???"));
217
218 if ((ce = (struct cardslot_event *)malloc(sizeof(struct cardslot_event),
219 M_TEMP, M_NOWAIT)) == NULL) {
220 panic("cardslot_event");
221 }
222
223 ce->ce_type = ev;
224
225 {
226 int s = spltty();
227 SIMPLEQ_INSERT_TAIL(&sc->sc_events, ce, ce_q);
228 splx(s);
229 }
230
231 wakeup(&sc->sc_events);
232 }
233
234
235
236
237
238
239
240
241 static void
242 cardslot_event_thread(void *arg)
243 {
244 struct cardslot_softc *sc = arg;
245 struct cardslot_event *ce;
246 int s;
247 static int antonym_ev[4] = {
248 CARDSLOT_EVENT_REMOVAL_16, CARDSLOT_EVENT_INSERTION_16,
249 CARDSLOT_EVENT_REMOVAL_CB, CARDSLOT_EVENT_INSERTION_CB
250 };
251
252 while (sc->sc_th_enable) {
253 s = spltty();
254 if ((ce = SIMPLEQ_FIRST(&sc->sc_events)) == NULL) {
255 splx(s);
256 (void) tsleep(&sc->sc_events, PWAIT, "cardslotev", 0);
257 continue;
258 }
259 SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q);
260 splx(s);
261
262 if (IS_CARDSLOT_INSERT_REMOVE_EV(ce->ce_type)) {
263
264 s = spltty();
265 while (1) {
266 struct cardslot_event *ce1, *ce2;
267
268 if ((ce1 = SIMPLEQ_FIRST(&sc->sc_events)) ==
269 NULL)
270 break;
271 if (ce1->ce_type != antonym_ev[ce->ce_type])
272 break;
273 if ((ce2 = SIMPLEQ_NEXT(ce1, ce_q)) == NULL)
274 break;
275 if (ce2->ce_type == ce->ce_type) {
276 SIMPLEQ_REMOVE_HEAD(&sc->sc_events,
277 ce_q);
278 free(ce1, M_TEMP);
279 SIMPLEQ_REMOVE_HEAD(&sc->sc_events,
280 ce_q);
281 free(ce2, M_TEMP);
282 }
283 }
284 splx(s);
285 }
286
287 switch (ce->ce_type) {
288 case CARDSLOT_EVENT_INSERTION_CB:
289 if ((CARDSLOT_CARDTYPE(sc->sc_status) ==
290 CARDSLOT_STATUS_CARD_CB) ||
291 (CARDSLOT_CARDTYPE(sc->sc_status) ==
292 CARDSLOT_STATUS_CARD_16)) {
293 if (CARDSLOT_WORK(sc->sc_status) ==
294 CARDSLOT_STATUS_WORKING) {
295
296
297
298 break;
299 }
300 }
301
302 if (sc->sc_cb_softc) {
303 CARDSLOT_SET_CARDTYPE(sc->sc_status,
304 CARDSLOT_STATUS_CARD_CB);
305 if (cardbus_attach_card(sc->sc_cb_softc) > 0) {
306
307 CARDSLOT_SET_WORK(sc->sc_status,
308 CARDSLOT_STATUS_WORKING);
309 } else {
310
311
312
313 CARDSLOT_SET_WORK(sc->sc_status,
314 CARDSLOT_STATUS_NOTWORK);
315 }
316 } else {
317 panic("no cardbus on %s", sc->sc_dev.dv_xname);
318 }
319
320 break;
321
322 case CARDSLOT_EVENT_INSERTION_16:
323 if ((CARDSLOT_CARDTYPE(sc->sc_status) ==
324 CARDSLOT_STATUS_CARD_CB) ||
325 (CARDSLOT_CARDTYPE(sc->sc_status) ==
326 CARDSLOT_STATUS_CARD_16)) {
327 if (CARDSLOT_WORK(sc->sc_status) ==
328 CARDSLOT_STATUS_WORKING) {
329
330
331
332 break;
333 }
334 }
335 if (sc->sc_16_softc) {
336 CARDSLOT_SET_CARDTYPE(sc->sc_status,
337 CARDSLOT_STATUS_CARD_16);
338 if (pcmcia_card_attach(
339 (struct device *)sc->sc_16_softc)) {
340
341 CARDSLOT_SET_WORK(sc->sc_status,
342 CARDSLOT_STATUS_NOTWORK);
343 } else {
344
345 CARDSLOT_SET_WORK(sc->sc_status,
346 CARDSLOT_STATUS_WORKING);
347 }
348 } else {
349 panic("no 16-bit pcmcia on %s",
350 sc->sc_dev.dv_xname);
351 }
352
353 break;
354
355 case CARDSLOT_EVENT_REMOVAL_CB:
356 if (CARDSLOT_CARDTYPE(sc->sc_status) ==
357 CARDSLOT_STATUS_CARD_CB) {
358
359 if (CARDSLOT_WORK(sc->sc_status) ==
360 CARDSLOT_STATUS_WORKING) {
361 cardbus_detach_card(sc->sc_cb_softc);
362 CARDSLOT_SET_WORK(sc->sc_status,
363 CARDSLOT_STATUS_NOTWORK);
364 CARDSLOT_SET_WORK(sc->sc_status,
365 CARDSLOT_STATUS_CARD_NONE);
366 }
367 CARDSLOT_SET_CARDTYPE(sc->sc_status,
368 CARDSLOT_STATUS_CARD_NONE);
369 } else if (CARDSLOT_CARDTYPE(sc->sc_status) !=
370 CARDSLOT_STATUS_CARD_16) {
371
372 CARDSLOT_SET_CARDTYPE(sc->sc_status,
373 CARDSLOT_STATUS_CARD_NONE);
374 }
375 CARDSLOT_SET_WORK(sc->sc_status,
376 CARDSLOT_STATUS_NOTWORK);
377 break;
378
379 case CARDSLOT_EVENT_REMOVAL_16:
380 DPRINTF(("%s: removal event\n", sc->sc_dev.dv_xname));
381 if (CARDSLOT_CARDTYPE(sc->sc_status) !=
382 CARDSLOT_STATUS_CARD_16) {
383
384 break;
385 }
386 if ((sc->sc_16_softc != NULL) &&
387 (CARDSLOT_WORK(sc->sc_status) ==
388 CARDSLOT_STATUS_WORKING)) {
389 struct pcmcia_softc *psc = sc->sc_16_softc;
390
391 pcmcia_card_deactivate((struct device *)psc);
392 pcmcia_chip_socket_disable(psc->pct, psc->pch);
393 pcmcia_card_detach((struct device *)psc,
394 DETACH_FORCE);
395 }
396 CARDSLOT_SET_CARDTYPE(sc->sc_status,
397 CARDSLOT_STATUS_CARD_NONE);
398 CARDSLOT_SET_WORK(sc->sc_status,
399 CARDSLOT_STATUS_NOTWORK);
400 break;
401
402 default:
403 panic("cardslot_event_thread: unknown event %d",
404 ce->ce_type);
405 }
406 free(ce, M_TEMP);
407 }
408
409 sc->sc_event_thread = NULL;
410
411
412 wakeup(sc);
413
414 kthread_exit(0);
415 }