pcmcia.c revision 1.1.2.10 1 /* $NetBSD: pcmcia.c,v 1.1.2.10 1997/10/14 05:29:32 thorpej Exp $ */
2
3 #define PCMCIADEBUG
4
5 #include <sys/types.h>
6 #include <sys/param.h>
7 #include <sys/systm.h>
8 #include <sys/device.h>
9
10 /* XXX only needed for intr debugging */
11 #include <vm/vm.h>
12
13 #include <dev/pcmcia/pcmciareg.h>
14 #include <dev/pcmcia/pcmciachip.h>
15 #include <dev/pcmcia/pcmciavar.h>
16
17 #ifdef PCMCIADEBUG
18 int pcmcia_debug = 0;
19 #define DPRINTF(arg) if (pcmcia_debug) printf arg
20 #else
21 #define DPRINTF(arg)
22 #endif
23
24 #ifdef PCMCIAVERBOSE
25 int pcmcia_verbose = 1;
26 #else
27 int pcmcia_verbose = 0;
28 #endif
29
30 #ifdef __BROKEN_INDIRECT_CONFIG
31 int pcmcia_match __P((struct device *, void *, void *));
32 int pcmcia_submatch __P((struct device *, void *, void *));
33 #else
34 int pcmcia_match __P((struct device *, struct cfdata *, void *));
35 int pcmcia_submatch __P((struct device *, struct cfdata *, void *));
36 #endif
37 void pcmcia_attach __P((struct device *, struct device *, void *));
38 int pcmcia_print __P((void *, const char *));
39
40 int pcmcia_card_intr __P((void *));
41
42 struct cfdriver pcmcia_cd = {
43 NULL, "pcmcia", DV_DULL
44 };
45
46 struct cfattach pcmcia_ca = {
47 sizeof(struct pcmcia_softc), pcmcia_match, pcmcia_attach
48 };
49
50 int
51 pcmcia_ccr_read(pf, ccr)
52 struct pcmcia_function *pf;
53 int ccr;
54 {
55
56 return (bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh,
57 pf->pf_ccr_offset + ccr));
58 }
59
60 void
61 pcmcia_ccr_write(pf, ccr, val)
62 struct pcmcia_function *pf;
63 int ccr;
64 int val;
65 {
66
67 if ((pf->ccr_mask) & (1 << (ccr / 2))) {
68 bus_space_write_1(pf->pf_ccrt, pf->pf_ccrh,
69 pf->pf_ccr_offset + ccr, val);
70 }
71 }
72
73 int
74 pcmcia_match(parent, match, aux)
75 struct device *parent;
76 #ifdef __BROKEN_INDIRECT_CONFIG
77 void *match;
78 #else
79 struct cfdata *match;
80 #endif
81 void *aux;
82 {
83
84 /* if the autoconfiguration got this far, there's a socket here */
85 return (1);
86 }
87
88 void
89 pcmcia_attach(parent, self, aux)
90 struct device *parent, *self;
91 void *aux;
92 {
93 struct pcmciabus_attach_args *paa =
94 (struct pcmciabus_attach_args *) aux;
95 struct pcmcia_softc *sc = (struct pcmcia_softc *) self;
96
97 printf("\n");
98
99 sc->pct = paa->pct;
100 sc->pch = paa->pch;
101
102 sc->ih = NULL;
103 }
104
105 int
106 pcmcia_card_attach(dev)
107 struct device *dev;
108 {
109 struct pcmcia_softc *sc = (struct pcmcia_softc *) dev;
110 struct pcmcia_function *pf;
111 struct pcmcia_attach_args paa;
112 int attached;
113
114 /*
115 * this is here so that when socket_enable calls gettype, trt happens
116 */
117 sc->card.pf_head.sqh_first = NULL;
118
119 pcmcia_chip_socket_enable(sc->pct, sc->pch);
120
121 pcmcia_read_cis(sc);
122
123 pcmcia_chip_socket_disable(sc->pct, sc->pch);
124
125 /*
126 * bail now if the card has no functions, or if there was an error in
127 * the cis.
128 */
129
130 if (sc->card.error)
131 return (1);
132 if (sc->card.pf_head.sqh_first == NULL)
133 return (1);
134
135 if (pcmcia_verbose)
136 pcmcia_print_cis(sc);
137
138 attached = 0;
139
140 for (pf = sc->card.pf_head.sqh_first; pf != NULL;
141 pf = pf->pf_list.sqe_next) {
142 if (pf->cfe_head.sqh_first == NULL)
143 continue;
144
145 pf->sc = sc;
146 pf->cfe = NULL;
147 pf->ih_fct = NULL;
148 pf->ih_arg = NULL;
149 }
150
151 for (pf = sc->card.pf_head.sqh_first; pf != NULL;
152 pf = pf->pf_list.sqe_next) {
153 if (pf->cfe_head.sqh_first == NULL)
154 continue;
155
156 paa.manufacturer = sc->card.manufacturer;
157 paa.product = sc->card.product;
158 paa.card = &sc->card;
159 paa.pf = pf;
160
161 if (config_found_sm(&sc->dev, &paa, pcmcia_print,
162 pcmcia_submatch)) {
163 attached++;
164
165 DPRINTF(("%s: function %d CCR at %d "
166 "offset %lx: %x %x %x %x, %x %x %x %x, %x\n",
167 sc->dev.dv_xname, pf->number,
168 pf->pf_ccr_window, pf->pf_ccr_offset,
169 pcmcia_ccr_read(pf, 0x00),
170 pcmcia_ccr_read(pf, 0x02), pcmcia_ccr_read(pf, 0x04),
171 pcmcia_ccr_read(pf, 0x06), pcmcia_ccr_read(pf, 0x0A),
172 pcmcia_ccr_read(pf, 0x0C), pcmcia_ccr_read(pf, 0x0E),
173 pcmcia_ccr_read(pf, 0x10), pcmcia_ccr_read(pf, 0x12)));
174 }
175 }
176
177 return (attached ? 0 : 1);
178 }
179
180 void
181 pcmcia_card_detach(dev)
182 struct device *dev;
183 {
184 /* struct pcmcia_softc *sc = (struct pcmcia_softc *) dev; */
185 /* don't do anything yet */
186 }
187
188 int
189 #ifdef __BROKEN_INDIRECT_CONFIG
190 pcmcia_submatch(parent, match, aux)
191 struct device *parent;
192 void *match, *aux;
193 {
194 struct cfdata *cf = match;
195 #else
196 pcmcia_submatch(parent, cf, aux)
197 struct device *parent;
198 struct cfdata *cf;
199 void *aux;
200 {
201 #endif
202 struct pcmcia_attach_args *paa = (struct pcmcia_attach_args *) aux;
203
204 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != paa->pf->number)
205 return (0);
206
207 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
208 }
209
210 int
211 pcmcia_print(arg, pnp)
212 void *arg;
213 const char *pnp;
214 {
215 struct pcmcia_attach_args *pa = (struct pcmcia_attach_args *) arg;
216 struct pcmcia_softc *sc = pa->pf->sc;
217 struct pcmcia_card *card = &sc->card;
218 int i;
219
220 if (pnp) {
221 for (i = 0; i < 4; i++) {
222 if (card->cis1_info[i] == NULL)
223 break;
224 if (i)
225 printf(", ");
226 printf("%s", card->cis1_info[i]);
227 }
228 if (i)
229 printf(" ");
230 printf("(manufacturer 0x%x, product 0x%x)", card->manufacturer,
231 card->product);
232 }
233 printf(" function %d", pa->pf->number);
234
235 return (UNCONF);
236 }
237
238 int
239 pcmcia_card_gettype(dev)
240 struct device *dev;
241 {
242 struct pcmcia_softc *sc = (struct pcmcia_softc *) dev;
243
244 /*
245 * set the iftype to memory if this card has no functions (not yet
246 * probed), or only one function, and that is memory.
247 */
248 if (sc->card.pf_head.sqh_first == NULL ||
249 (sc->card.pf_head.sqh_first != NULL &&
250 sc->card.pf_head.sqh_first->pf_list.sqe_next == NULL &&
251 (sc->card.pf_head.sqh_first->cfe_head.sqh_first->iftype ==
252 PCMCIA_IFTYPE_MEMORY)))
253 return (PCMCIA_IFTYPE_MEMORY);
254 else
255 return (PCMCIA_IFTYPE_IO);
256 }
257
258 /*
259 * Initialize a PCMCIA function. May be called as long as the function is
260 * disabled.
261 */
262 void
263 pcmcia_function_init(pf, cfe)
264 struct pcmcia_function *pf;
265 struct pcmcia_config_entry *cfe;
266 {
267
268 if (pf->pf_flags & PFF_ENABLED)
269 panic("pcmcia_function_init: function is enabled");
270
271 /* Remember which configuration entry we are using. */
272 pf->cfe = cfe;
273 }
274
275 /* Enable a PCMCIA function */
276 int
277 pcmcia_function_enable(pf)
278 struct pcmcia_function *pf;
279 {
280 struct pcmcia_function *tmp;
281 int reg;
282
283 if (pf->cfe == NULL)
284 panic("pcmcia_function_enable: function not initialized");
285
286 if (pf->pf_flags & PFF_ENABLED) {
287 /*
288 * Don't do anything if we're already enabled.
289 */
290 return (0);
291 }
292
293 /*
294 * Increase the reference count on the socket, enabling power, if
295 * necessary.
296 */
297 if (pf->sc->sc_enabled_count++ == 0)
298 pcmcia_chip_socket_enable(pf->sc->pct, pf->sc->pch);
299
300 /*
301 * it's possible for different functions' CCRs to be in the same
302 * underlying page. Check for that.
303 */
304
305 for (tmp = pf->sc->card.pf_head.sqh_first; tmp != NULL;
306 tmp = tmp->pf_list.sqe_next) {
307 if ((tmp->pf_flags & PFF_ENABLED) &&
308 (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) &&
309 ((pf->ccr_base + PCMCIA_CCR_SIZE) <=
310 (tmp->ccr_base - tmp->pf_ccr_offset +
311 tmp->pf_ccr_realsize))) {
312 pf->pf_ccrt = tmp->pf_ccrt;
313 pf->pf_ccrh = tmp->pf_ccrh;
314 pf->pf_ccr_realsize = tmp->pf_ccr_realsize;
315
316 /*
317 * pf->pf_ccr_offset = (tmp->pf_ccr_offset -
318 * tmp->ccr_base) + pf->ccr_base;
319 */
320 pf->pf_ccr_offset =
321 (tmp->pf_ccr_offset + pf->ccr_base) -
322 tmp->ccr_base;
323 pf->pf_ccr_window = tmp->pf_ccr_window;
324 break;
325 }
326 }
327
328 if (tmp == NULL) {
329 if (pcmcia_mem_alloc(pf, PCMCIA_CCR_SIZE, &pf->pf_pcmh))
330 goto bad;
331
332 if (pcmcia_mem_map(pf, PCMCIA_MEM_ATTR, pf->ccr_base,
333 PCMCIA_CCR_SIZE, &pf->pf_pcmh, &pf->pf_ccr_offset,
334 &pf->pf_ccr_window)) {
335 pcmcia_mem_free(pf, &pf->pf_pcmh);
336 goto bad;
337 }
338 }
339 DPRINTF(("%s: function %d CCR at %d offset %lx: "
340 "%x %x %x %x, %x %x %x %x, %x\n",
341 pf->sc->dev.dv_xname, pf->number,
342 pf->pf_ccr_window, pf->pf_ccr_offset,
343 pcmcia_ccr_read(pf, 0x00),
344 pcmcia_ccr_read(pf, 0x02), pcmcia_ccr_read(pf, 0x04),
345 pcmcia_ccr_read(pf, 0x06), pcmcia_ccr_read(pf, 0x0A),
346 pcmcia_ccr_read(pf, 0x0C), pcmcia_ccr_read(pf, 0x0E),
347 pcmcia_ccr_read(pf, 0x10), pcmcia_ccr_read(pf, 0x12)));
348
349 reg = (pf->cfe->number & PCMCIA_CCR_OPTION_CFINDEX);
350 reg |= PCMCIA_CCR_OPTION_LEVIREQ;
351 if (pcmcia_mfc(pf->sc))
352 reg |= PCMCIA_CCR_OPTION_FUNC_ENABLE;
353 pcmcia_ccr_write(pf, PCMCIA_CCR_OPTION, reg);
354
355 reg = 0;
356
357 if ((pf->cfe->flags & PCMCIA_CFE_IO16) == 0)
358 reg |= PCMCIA_CCR_STATUS_IOIS8;
359 if (pf->cfe->flags & PCMCIA_CFE_AUDIO)
360 reg |= PCMCIA_CCR_STATUS_AUDIO;
361 /* Not really needed, since we start with 0. */
362 if (pf->cfe->flags & PCMCIA_CFE_POWERDOWN)
363 reg &= ~PCMCIA_CCR_STATUS_PWRDWN;
364 pcmcia_ccr_write(pf, PCMCIA_CCR_STATUS, reg);
365
366 pcmcia_ccr_write(pf, PCMCIA_CCR_SOCKETCOPY, 0);
367
368 pf->pf_flags |= PFF_ENABLED;
369 return (0);
370
371 bad:
372 /*
373 * Decrement the reference count, and power down the socket, if
374 * necessary.
375 */
376 if (pf->sc->sc_enabled_count-- == 1)
377 pcmcia_chip_socket_disable(pf->sc->pct, pf->sc->pch);
378 return (1);
379 }
380
381 /* Disable PCMCIA function. */
382 void
383 pcmcia_function_disable(pf)
384 struct pcmcia_function *pf;
385 {
386 struct pcmcia_function *tmp;
387 int reg;
388
389 if (pf->cfe == NULL)
390 panic("pcmcia_function_enable: function not initialized");
391
392 if ((pf->pf_flags & PFF_ENABLED) == 0) {
393 /*
394 * Don't do anything if we're already disabled.
395 */
396 return;
397 }
398
399 /* Power down the function if the card supports it. */
400 if (pf->cfe->flags & PCMCIA_CFE_POWERDOWN) {
401 reg = pcmcia_ccr_read(pf, PCMCIA_CCR_STATUS);
402 reg |= PCMCIA_CCR_STATUS_PWRDWN;
403 pcmcia_ccr_write(pf, PCMCIA_CCR_STATUS, reg);
404 }
405
406 /*
407 * it's possible for different functions' CCRs to be in the same
408 * underlying page. Check for that. Note we mark us as disabled
409 * first to avoid matching ourself.
410 */
411
412 pf->pf_flags &= ~PFF_ENABLED;
413 for (tmp = pf->sc->card.pf_head.sqh_first; tmp != NULL;
414 tmp = tmp->pf_list.sqe_next) {
415 if ((tmp->pf_flags & PFF_ENABLED) &&
416 (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) &&
417 ((pf->ccr_base + PCMCIA_CCR_SIZE) <=
418 (tmp->ccr_base - tmp->pf_ccr_offset + tmp->pf_ccr_realsize)))
419 break;
420 }
421
422 /* Not used by anyone else; unmap the CCR. */
423 if (tmp == NULL) {
424 pcmcia_mem_unmap(pf, pf->pf_ccr_window);
425 pcmcia_mem_free(pf, &pf->pf_pcmh);
426 }
427
428 /*
429 * Decrement the reference count, and power down the socket, if
430 * necessary.
431 */
432 if (--pf->sc->sc_enabled_count == 0)
433 pcmcia_chip_socket_disable(pf->sc->pct, pf->sc->pch);
434 }
435
436 int
437 pcmcia_io_map(pf, width, offset, size, pcihp, windowp)
438 struct pcmcia_function *pf;
439 int width;
440 bus_addr_t offset;
441 bus_size_t size;
442 struct pcmcia_io_handle *pcihp;
443 int *windowp;
444 {
445 bus_addr_t ioaddr;
446 int reg;
447
448 if (pcmcia_chip_io_map(pf->sc->pct, pf->sc->pch,
449 width, offset, size, pcihp, windowp))
450 return (1);
451
452 ioaddr = pcihp->addr + offset;
453
454 /*
455 * XXX in the multifunction multi-iospace-per-function case, this
456 * needs to cooperate with io_alloc to make sure that the spaces
457 * don't overlap, and that the ccr's are set correctly
458 */
459
460 if (pcmcia_mfc(pf->sc)) {
461 pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE0, ioaddr & 0xff);
462 pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE1, (ioaddr >> 8) & 0xff);
463 pcmcia_ccr_write(pf, PCMCIA_CCR_IOSIZE, size - 1);
464
465 reg = pcmcia_ccr_read(pf, PCMCIA_CCR_OPTION);
466 reg |= PCMCIA_CCR_OPTION_ADDR_DECODE;
467 pcmcia_ccr_write(pf, PCMCIA_CCR_OPTION, reg);
468 }
469 return (0);
470 }
471
472 void *
473 pcmcia_intr_establish(pf, ipl, ih_fct, ih_arg)
474 struct pcmcia_function *pf;
475 int ipl;
476 int (*ih_fct) __P((void *));
477 void *ih_arg;
478 {
479 void *ret;
480
481 /* behave differently if this is a multifunction card */
482
483 if (pcmcia_mfc(pf->sc)) {
484 int s, ihcnt, hiipl, reg;
485 struct pcmcia_function *pf2;
486
487 /* XXX splraise() use needs to go away! */
488
489 /*
490 * mask all the ipl's which are already used by this card,
491 * and find the highest ipl number (lowest priority)
492 */
493
494 ihcnt = 0;
495 s = 0; /* this is only here to keep the compipler
496 happy */
497 hiipl = 0; /* this is only here to keep the compipler
498 happy */
499
500 for (pf2 = pf->sc->card.pf_head.sqh_first; pf2 != NULL;
501 pf2 = pf2->pf_list.sqe_next) {
502 if (pf2->ih_fct) {
503 if (ihcnt == 0) {
504 s = splraise(pf2->ih_ipl);
505 hiipl = pf2->ih_ipl;
506 ihcnt++;
507 } else {
508 splraise(pf2->ih_ipl);
509 if (pf2->ih_ipl > hiipl)
510 hiipl = pf2->ih_ipl;
511 }
512 }
513 }
514
515 /* set up the handler for the new function */
516
517 pf->ih_fct = ih_fct;
518 pf->ih_arg = ih_arg;
519 pf->ih_ipl = ipl;
520
521 /*
522 * establish the real interrupt, changing the ipl if
523 * necessary
524 */
525
526 if (ihcnt == 0) {
527 #ifdef DIAGNOSTIC
528 if (pf->sc->ih != NULL)
529 panic("card has intr handler, but no function does");
530 #endif
531
532 pf->sc->ih = pcmcia_chip_intr_establish(pf->sc->pct,
533 pf->sc->pch, pf, ipl, pcmcia_card_intr, pf->sc);
534 } else if (ipl > hiipl) {
535 #ifdef DIAGNOSTIC
536 if (pf->sc->ih == NULL)
537 panic("functions have ih, but the card does not");
538 #endif
539
540 pcmcia_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
541 pf->sc->ih);
542 pf->sc->ih = pcmcia_chip_intr_establish(pf->sc->pct,
543 pf->sc->pch, pf, ipl, pcmcia_card_intr, pf->sc);
544 }
545 if (ihcnt)
546 splx(s);
547
548 ret = pf->sc->ih;
549
550 if (ret != NULL) {
551 reg = pcmcia_ccr_read(pf, PCMCIA_CCR_OPTION);
552 reg |= PCMCIA_CCR_OPTION_IREQ_ENABLE;
553 pcmcia_ccr_write(pf, PCMCIA_CCR_OPTION, reg);
554
555 reg = pcmcia_ccr_read(pf, PCMCIA_CCR_STATUS);
556 reg |= PCMCIA_CCR_STATUS_INTRACK;
557 pcmcia_ccr_write(pf, PCMCIA_CCR_STATUS, reg);
558 }
559 } else {
560 ret = pcmcia_chip_intr_establish(pf->sc->pct, pf->sc->pch,
561 pf, ipl, ih_fct, ih_arg);
562 }
563
564 return (ret);
565 }
566
567 void
568 pcmcia_intr_disestablish(pf, ih)
569 struct pcmcia_function *pf;
570 void *ih;
571 {
572
573 /* behave differently if this is a multifunction card */
574
575 if (pcmcia_mfc(pf->sc)) {
576 int s, ihcnt, hiipl;
577 struct pcmcia_function *pf2;
578
579 /*
580 * mask all the ipl's which are already used by this card,
581 * and find the highest ipl number (lowest priority). Skip
582 * the current function.
583 */
584
585 ihcnt = 0;
586 s = 0; /* this is only here to keep the compipler
587 happy */
588 hiipl = 0; /* this is only here to keep the compipler
589 happy */
590
591 for (pf2 = pf->sc->card.pf_head.sqh_first; pf2 != NULL;
592 pf2 = pf2->pf_list.sqe_next) {
593 if (pf2 == pf)
594 continue;
595
596 if (pf2->ih_fct) {
597 if (ihcnt == 0) {
598 s = splraise(pf2->ih_ipl);
599 hiipl = pf2->ih_ipl;
600 ihcnt++;
601 } else {
602 splraise(pf2->ih_ipl);
603 if (pf2->ih_ipl > hiipl)
604 hiipl = pf2->ih_ipl;
605 }
606 }
607 }
608
609 /* null out the handler for this function */
610
611 pf->ih_fct = NULL;
612 pf->ih_arg = NULL;
613
614 /*
615 * if the ih being removed is lower priority than the lowest
616 * priority remaining interrupt, up the priority.
617 */
618
619 #ifdef DIAGNOSTIC
620 if (ihcnt == 0) {
621 panic("can't remove a handler from a card which has none");
622 } else
623 #endif
624 if (ihcnt == 1) {
625 #ifdef DIAGNOSTIC
626 if (pf->sc->ih == NULL)
627 panic("disestablishing last function, but card has no ih");
628 #endif
629 pcmcia_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
630 pf->sc->ih);
631 pf->sc->ih = NULL;
632 } else if (pf->ih_ipl > hiipl) {
633 #ifdef DIAGNOSTIC
634 if (pf->sc->ih == NULL)
635 panic("changing ih ipl, but card has no ih");
636 #endif
637 pcmcia_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
638 pf->sc->ih);
639 pf->sc->ih = pcmcia_chip_intr_establish(pf->sc->pct,
640 pf->sc->pch, pf, hiipl, pcmcia_card_intr, pf->sc);
641 }
642 if (ihcnt)
643 splx(s);
644 } else {
645 pcmcia_chip_intr_disestablish(pf->sc->pct, pf->sc->pch, ih);
646 }
647 }
648
649 int
650 pcmcia_card_intr(arg)
651 void *arg;
652 {
653 struct pcmcia_softc *sc = (struct pcmcia_softc *) arg;
654 struct pcmcia_function *pf;
655 int reg, ret, ret2;
656
657 ret = 0;
658
659 for (pf = sc->card.pf_head.sqh_first; pf != NULL;
660 pf = pf->pf_list.sqe_next) {
661 #if 0
662 printf("%s: intr fct=%d physaddr=%lx cor=%02x csr=%02x pin=%02x",
663 sc->dev.dv_xname, pf->number,
664 pmap_extract(pmap_kernel(),
665 (vm_offset_t) pf->ccrh) + pf->ccr_offset,
666 bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh,
667 pf->pf_ccr_offset + PCMCIA_CCR_OPTION),
668 bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh,
669 pf->pf_ccr_offset + PCMCIA_CCR_STATUS),
670 bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh,
671 pf->pf_ccr_offset + PCMCIA_CCR_PIN));
672 #endif
673 if (pf->ih_fct != NULL &&
674 (pf->ccr_mask & (1 << (PCMCIA_CCR_STATUS / 2)))) {
675 reg = pcmcia_ccr_read(pf, PCMCIA_CCR_STATUS);
676 if (reg & PCMCIA_CCR_STATUS_INTR) {
677 ret2 = (*pf->ih_fct)(pf->ih_arg);
678 if (ret2 != 0 && ret == 0)
679 ret = ret2;
680 reg = pcmcia_ccr_read(pf, PCMCIA_CCR_STATUS);
681 #if 0
682 printf("; csr %02x->%02x",
683 reg, reg & ~PCMCIA_CCR_STATUS_INTR);
684 #endif
685 pcmcia_ccr_write(pf, PCMCIA_CCR_STATUS,
686 reg & ~PCMCIA_CCR_STATUS_INTR);
687 }
688 }
689 #if 0
690 printf("\n");
691 #endif
692 }
693
694 return (ret);
695 }
696