This source file includes following definitions.
- stp4020_rd_sockctl
- stp4020_wr_sockctl
- stp4020_rd_winctl
- stp4020_wr_winctl
- stp4020print
- stpattach_common
- stp4020_attach_socket
- stp4020_create_event_thread
- stp4020_event_thread
- stp4020_queue_event
- stp4020_statintr
- stp4020_iointr
- stp4020_calc_speed
- stp4020_map_window
- stp4020_chip_mem_alloc
- stp4020_chip_mem_free
- stp4020_chip_mem_map
- stp4020_chip_mem_unmap
- stp4020_chip_io_alloc
- stp4020_chip_io_free
- stp4020_chip_io_map
- stp4020_chip_io_unmap
- stp4020_chip_socket_enable
- stp4020_chip_socket_disable
- stp4020_chip_intr_establish
- stp4020_chip_intr_disestablish
- stp4020_chip_intr_string
- stp4020_delay
- stp4020_dump_regs
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
37
38
39
40
41
42
43
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/errno.h>
48 #include <sys/extent.h>
49 #include <sys/proc.h>
50 #include <sys/kernel.h>
51 #include <sys/kthread.h>
52 #include <sys/device.h>
53
54 #include <dev/pcmcia/pcmciareg.h>
55 #include <dev/pcmcia/pcmciavar.h>
56 #include <dev/pcmcia/pcmciachip.h>
57
58 #include <machine/bus.h>
59
60 #include <dev/sbus/stp4020reg.h>
61 #include <dev/sbus/stp4020var.h>
62
63
64
65
66
67
68 #define STP_WIN_ATTR 0
69 #define STP_WIN_MEM 1
70 #define STP_WIN_IO 2
71
72 #ifdef STP4020_DEBUG
73 int stp4020_debug = 0;
74 #define DPRINTF(x) do { if (stp4020_debug) printf x; } while(0)
75 #else
76 #define DPRINTF(x)
77 #endif
78
79 int stp4020print(void *, const char *);
80 void stp4020_map_window(struct stp4020_socket *, int, int);
81 void stp4020_calc_speed(int, int, int *, int *);
82
83 struct cfdriver stp_cd = {
84 NULL, "stp", DV_DULL
85 };
86
87 #ifdef STP4020_DEBUG
88 static void stp4020_dump_regs(struct stp4020_socket *);
89 #endif
90
91 static u_int16_t stp4020_rd_sockctl(struct stp4020_socket *, int);
92 static void stp4020_wr_sockctl(struct stp4020_socket *, int, u_int16_t);
93 static u_int16_t stp4020_rd_winctl(struct stp4020_socket *, int, int);
94 static void stp4020_wr_winctl(struct stp4020_socket *, int, int, u_int16_t);
95
96 void stp4020_delay(unsigned int);
97 void stp4020_attach_socket(struct stp4020_socket *, int);
98 void stp4020_create_event_thread(void *);
99 void stp4020_event_thread(void *);
100 void stp4020_queue_event(struct stp4020_softc *, int);
101
102 int stp4020_chip_mem_alloc(pcmcia_chipset_handle_t, bus_size_t,
103 struct pcmcia_mem_handle *);
104 void stp4020_chip_mem_free(pcmcia_chipset_handle_t,
105 struct pcmcia_mem_handle *);
106 int stp4020_chip_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t,
107 bus_size_t, struct pcmcia_mem_handle *, bus_size_t *, int *);
108 void stp4020_chip_mem_unmap(pcmcia_chipset_handle_t, int);
109
110 int stp4020_chip_io_alloc(pcmcia_chipset_handle_t,
111 bus_addr_t, bus_size_t, bus_size_t, struct pcmcia_io_handle *);
112 void stp4020_chip_io_free(pcmcia_chipset_handle_t,
113 struct pcmcia_io_handle *);
114 int stp4020_chip_io_map(pcmcia_chipset_handle_t, int, bus_addr_t,
115 bus_size_t, struct pcmcia_io_handle *, int *);
116 void stp4020_chip_io_unmap(pcmcia_chipset_handle_t, int);
117
118 void stp4020_chip_socket_enable(pcmcia_chipset_handle_t);
119 void stp4020_chip_socket_disable(pcmcia_chipset_handle_t);
120 void *stp4020_chip_intr_establish(pcmcia_chipset_handle_t,
121 struct pcmcia_function *, int, int (*) (void *), void *, char *);
122 void stp4020_chip_intr_disestablish(pcmcia_chipset_handle_t, void *);
123 const char *stp4020_chip_intr_string(pcmcia_chipset_handle_t, void *);
124
125
126 static struct pcmcia_chip_functions stp4020_functions = {
127 stp4020_chip_mem_alloc,
128 stp4020_chip_mem_free,
129 stp4020_chip_mem_map,
130 stp4020_chip_mem_unmap,
131
132 stp4020_chip_io_alloc,
133 stp4020_chip_io_free,
134 stp4020_chip_io_map,
135 stp4020_chip_io_unmap,
136
137 stp4020_chip_intr_establish,
138 stp4020_chip_intr_disestablish,
139 stp4020_chip_intr_string,
140
141 stp4020_chip_socket_enable,
142 stp4020_chip_socket_disable
143 };
144
145
146 static __inline__ u_int16_t
147 stp4020_rd_sockctl(h, idx)
148 struct stp4020_socket *h;
149 int idx;
150 {
151 int o = ((STP4020_SOCKREGS_SIZE * (h->sock)) + idx);
152 return (bus_space_read_2(h->tag, h->regs, o));
153 }
154
155 static __inline__ void
156 stp4020_wr_sockctl(h, idx, v)
157 struct stp4020_socket *h;
158 int idx;
159 u_int16_t v;
160 {
161 int o = (STP4020_SOCKREGS_SIZE * (h->sock)) + idx;
162 bus_space_write_2(h->tag, h->regs, o, v);
163 }
164
165 static __inline__ u_int16_t
166 stp4020_rd_winctl(h, win, idx)
167 struct stp4020_socket *h;
168 int win;
169 int idx;
170 {
171 int o = (STP4020_SOCKREGS_SIZE * (h->sock)) +
172 (STP4020_WINREGS_SIZE * win) + idx;
173 return (bus_space_read_2(h->tag, h->regs, o));
174 }
175
176 static __inline__ void
177 stp4020_wr_winctl(h, win, idx, v)
178 struct stp4020_socket *h;
179 int win;
180 int idx;
181 u_int16_t v;
182 {
183 int o = (STP4020_SOCKREGS_SIZE * (h->sock)) +
184 (STP4020_WINREGS_SIZE * win) + idx;
185 bus_space_write_2(h->tag, h->regs, o, v);
186 }
187
188
189 int
190 stp4020print(aux, busname)
191 void *aux;
192 const char *busname;
193 {
194 struct pcmciabus_attach_args *paa = aux;
195 struct stp4020_socket *h = paa->pch;
196
197 printf(" socket %d", h->sock);
198 return (UNCONF);
199 }
200
201
202
203
204 void
205 stpattach_common(struct stp4020_softc *sc, int clockfreq)
206 {
207 int i, rev;
208
209 rev = stp4020_rd_sockctl(&sc->sc_socks[0], STP4020_ISR1_IDX) &
210 STP4020_ISR1_REV_M;
211 printf(": rev %x\n", rev);
212
213 sc->sc_pct = (pcmcia_chipset_tag_t)&stp4020_functions;
214
215
216
217
218
219 sc->events = 0;
220 kthread_create_deferred(stp4020_create_event_thread, sc);
221
222 for (i = 0; i < STP4020_NSOCK; i++) {
223 struct stp4020_socket *h = &sc->sc_socks[i];
224 h->sock = i;
225 h->sc = sc;
226 #ifdef STP4020_DEBUG
227 if (stp4020_debug)
228 stp4020_dump_regs(h);
229 #endif
230 stp4020_attach_socket(h, clockfreq);
231 }
232 }
233
234 void
235 stp4020_attach_socket(h, speed)
236 struct stp4020_socket *h;
237 int speed;
238 {
239 struct pcmciabus_attach_args paa;
240 int v;
241
242
243 stp4020_map_window(h, STP_WIN_ATTR, speed);
244 stp4020_map_window(h, STP_WIN_MEM, speed);
245 stp4020_map_window(h, STP_WIN_IO, speed);
246
247
248 paa.paa_busname = "pcmcia";
249 paa.pct = (pcmcia_chipset_tag_t)h->sc->sc_pct;
250 paa.pch = (pcmcia_chipset_handle_t)h;
251 paa.iobase = 0;
252 paa.iosize = STP4020_WINDOW_SIZE;
253
254 h->pcmcia = config_found(&h->sc->sc_dev, &paa, stp4020print);
255
256 if (h->pcmcia == NULL)
257 return;
258
259
260
261
262
263
264
265
266
267 stp4020_wr_sockctl(h, STP4020_ICR1_IDX, 0);
268 stp4020_wr_sockctl(h, STP4020_ICR0_IDX, 0);
269 stp4020_wr_sockctl(h, STP4020_ISR1_IDX, 0x3fff);
270 stp4020_wr_sockctl(h, STP4020_ISR0_IDX, 0x3fff);
271
272
273
274
275
276 v = STP4020_ICR0_ALL_STATUS_IE | STP4020_ICR0_SCILVL_SB1;
277 stp4020_wr_sockctl(h, STP4020_ICR0_IDX, v);
278
279
280 v = stp4020_rd_sockctl(h, STP4020_ISR0_IDX);
281 h->sense = v & (STP4020_ISR0_CD1ST | STP4020_ISR0_CD2ST);
282 if (h->sense != 0) {
283 h->flags |= STP4020_SOCKET_BUSY;
284 pcmcia_card_attach(h->pcmcia);
285 }
286 }
287
288
289
290
291
292 void
293 stp4020_create_event_thread(arg)
294 void *arg;
295 {
296 struct stp4020_softc *sc = arg;
297 const char *name = sc->sc_dev.dv_xname;
298
299 if (kthread_create(stp4020_event_thread, sc, &sc->event_thread,
300 "%s", name)) {
301 panic("%s: unable to create event thread", name);
302 }
303 }
304
305
306
307
308 void
309 stp4020_event_thread(arg)
310 void *arg;
311 {
312 struct stp4020_softc *sc = arg;
313 int s, sense;
314 unsigned int socket;
315
316 for (;;) {
317 struct stp4020_socket *h;
318
319 s = splhigh();
320 if ((socket = ffs(sc->events)) == 0) {
321 splx(s);
322 (void)tsleep(&sc->events, PWAIT, "stp4020_ev", 0);
323 continue;
324 }
325 socket--;
326 sc->events &= ~(1 << socket);
327 splx(s);
328
329 if (socket >= STP4020_NSOCK) {
330 #ifdef DEBUG
331 printf("stp4020_event_thread: wayward socket number %d\n",
332 socket);
333 #endif
334 continue;
335 }
336
337 h = &sc->sc_socks[socket];
338
339
340 sense = stp4020_rd_sockctl(h, STP4020_ISR0_IDX) &
341 (STP4020_ISR0_CD1ST | STP4020_ISR0_CD2ST);
342
343 if (sense > h->sense) {
344
345
346
347
348 h->sense = sense;
349 if ((h->flags & STP4020_SOCKET_BUSY) == 0) {
350 h->flags |= STP4020_SOCKET_BUSY;
351 pcmcia_card_attach(h->pcmcia);
352 }
353 } else if (sense < h->sense) {
354
355
356
357
358 h->sense = sense;
359 if (h->flags & STP4020_SOCKET_BUSY) {
360 h->flags &= ~STP4020_SOCKET_BUSY;
361 pcmcia_card_detach(h->pcmcia, DETACH_FORCE);
362 }
363 }
364 }
365 }
366
367 void
368 stp4020_queue_event(sc, sock)
369 struct stp4020_softc *sc;
370 int sock;
371 {
372 int s;
373
374 s = splhigh();
375 sc->events |= (1 << sock);
376 splx(s);
377 wakeup(&sc->events);
378 }
379
380 int
381 stp4020_statintr(arg)
382 void *arg;
383 {
384 struct stp4020_softc *sc = arg;
385 int i, sense, r = 0;
386
387
388
389
390 for (i = 0 ; i < STP4020_NSOCK; i++) {
391 struct stp4020_socket *h;
392 int v;
393
394 h = &sc->sc_socks[i];
395
396
397 v = stp4020_rd_sockctl(h, STP4020_ISR0_IDX);
398 sense = v & (STP4020_ISR0_CD1ST | STP4020_ISR0_CD2ST);
399
400 #ifdef STP4020_DEBUG
401 if (stp4020_debug != 0)
402 printf("stp4020_statintr: ISR0=%b\n",
403 v, STP4020_ISR0_IOBITS);
404 #endif
405
406
407 stp4020_wr_sockctl(h, STP4020_ISR0_IDX,
408 STP4020_ISR0_ALL_STATUS_IRQ);
409
410 if ((v & STP4020_ISR0_CDCHG) != 0) {
411 r = 1;
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426 if (sense != h->sense)
427 stp4020_queue_event(sc, i);
428
429 }
430
431
432 if ((v & STP4020_ISR0_BVD1CHG) != 0) {
433 DPRINTF(("stp4020[%d]: Battery change 1\n",
434 h->sock));
435 r = 1;
436 }
437
438 if ((v & STP4020_ISR0_BVD2CHG) != 0) {
439 DPRINTF(("stp4020[%d]: Battery change 2\n",
440 h->sock));
441 r = 1;
442 }
443
444 if ((v & STP4020_ISR0_RDYCHG) != 0) {
445 DPRINTF(("stp4020[%d]: Ready/Busy change\n",
446 h->sock));
447 r = 1;
448 }
449
450 if ((v & STP4020_ISR0_WPCHG) != 0) {
451 DPRINTF(("stp4020[%d]: Write protect change\n",
452 h->sock));
453 r = 1;
454 }
455
456 if ((v & STP4020_ISR0_PCTO) != 0) {
457 DPRINTF(("stp4020[%d]: Card access timeout\n",
458 h->sock));
459 r = 1;
460 }
461
462 if ((v & STP4020_ISR0_SCINT) != 0) {
463 DPRINTF(("stp4020[%d]: Status change\n",
464 h->sock));
465 r = 1;
466 }
467
468
469
470
471
472 if ((h->flags & STP4020_SOCKET_ENABLING) &&
473 (v & (STP4020_ISR0_WAITST | STP4020_ISR0_PWRON)))
474 r = 1;
475 }
476
477 return (r);
478 }
479
480 int
481 stp4020_iointr(arg)
482 void *arg;
483 {
484 struct stp4020_softc *sc = arg;
485 int i, r = 0;
486
487
488
489
490 for (i = 0 ; i < STP4020_NSOCK; i++) {
491 struct stp4020_socket *h;
492 int v;
493
494 h = &sc->sc_socks[i];
495 v = stp4020_rd_sockctl(h, STP4020_ISR0_IDX);
496
497 if ((v & STP4020_ISR0_IOINT) != 0) {
498
499
500 r = 1;
501
502
503 stp4020_wr_sockctl(h, STP4020_ISR0_IDX, v);
504
505
506 if ((h->flags & STP4020_SOCKET_BUSY) == 0) {
507 printf("stp4020[%d]: spurious interrupt?\n",
508 h->sock);
509 continue;
510 }
511
512 if (h->intrhandler != NULL) {
513
514
515
516
517
518
519 splassert(h->ipl);
520 (*h->intrhandler)(h->intrarg);
521 }
522 }
523
524 }
525
526 return (r);
527 }
528
529
530
531
532
533 void
534 stp4020_calc_speed(int bus_speed, int ns, int *length, int *delay)
535 {
536 int result;
537
538 if (ns < STP4020_MEM_SPEED_MIN)
539 ns = STP4020_MEM_SPEED_MIN;
540 else if (ns > STP4020_MEM_SPEED_MAX)
541 ns = STP4020_MEM_SPEED_MAX;
542 result = ns * (bus_speed / 1000);
543 if (result % 1000000)
544 result = result / 1000000 + 1;
545 else
546 result /= 1000000;
547 *length = result;
548
549
550 *delay = ns <= STP4020_MEM_SPEED_MIN ? 1 : 2;
551 }
552
553 void
554 stp4020_map_window(struct stp4020_socket *h, int win, int speed)
555 {
556 int v, length, delay;
557
558
559
560
561
562
563
564 stp4020_calc_speed(speed, 300, &length, &delay);
565
566
567
568
569
570 v = ((delay << STP4020_WCR0_CMDDLY_S) & STP4020_WCR0_CMDDLY_M) |
571 ((length << STP4020_WCR0_CMDLNG_S) & STP4020_WCR0_CMDLNG_M);
572 switch (win) {
573 case STP_WIN_ATTR:
574 v |= STP4020_WCR0_ASPSEL_AM;
575 break;
576 case STP_WIN_MEM:
577 v |= STP4020_WCR0_ASPSEL_CM;
578 break;
579 case STP_WIN_IO:
580 v |= STP4020_WCR0_ASPSEL_IO;
581 break;
582 }
583 v |= (STP4020_ADDR2PAGE(0) & STP4020_WCR0_BASE_M);
584 stp4020_wr_winctl(h, win, STP4020_WCR0_IDX, v);
585 stp4020_wr_winctl(h, win, STP4020_WCR1_IDX,
586 1 << STP4020_WCR1_WAITREQ_S);
587 }
588
589 int
590 stp4020_chip_mem_alloc(pch, size, pcmhp)
591 pcmcia_chipset_handle_t pch;
592 bus_size_t size;
593 struct pcmcia_mem_handle *pcmhp;
594 {
595 struct stp4020_socket *h = (struct stp4020_socket *)pch;
596
597
598 pcmhp->memt = h->wintag;
599 pcmhp->size = size;
600 pcmhp->addr = 0;
601 pcmhp->mhandle = 0;
602 pcmhp->realsize = size;
603
604 return (0);
605 }
606
607 void
608 stp4020_chip_mem_free(pch, pcmhp)
609 pcmcia_chipset_handle_t pch;
610 struct pcmcia_mem_handle *pcmhp;
611 {
612 }
613
614 int
615 stp4020_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
616 pcmcia_chipset_handle_t pch;
617 int kind;
618 bus_addr_t card_addr;
619 bus_size_t size;
620 struct pcmcia_mem_handle *pcmhp;
621 bus_size_t *offsetp;
622 int *windowp;
623 {
624 struct stp4020_socket *h = (struct stp4020_socket *)pch;
625 int win = (kind & PCMCIA_MEM_ATTR) ? STP_WIN_ATTR : STP_WIN_MEM;
626
627 pcmhp->memt = h->wintag;
628 bus_space_subregion(h->wintag, h->windows[win].winaddr,
629 card_addr, size, &pcmhp->memh);
630 pcmhp->size = size;
631 pcmhp->realsize = STP4020_WINDOW_SIZE - card_addr;
632 *offsetp = 0;
633 *windowp = win;
634
635 return (0);
636 }
637
638 void
639 stp4020_chip_mem_unmap(pch, win)
640 pcmcia_chipset_handle_t pch;
641 int win;
642 {
643 }
644
645 int
646 stp4020_chip_io_alloc(pch, start, size, align, pcihp)
647 pcmcia_chipset_handle_t pch;
648 bus_addr_t start;
649 bus_size_t size;
650 bus_size_t align;
651 struct pcmcia_io_handle *pcihp;
652 {
653 struct stp4020_socket *h = (struct stp4020_socket *)pch;
654
655 pcihp->iot = h->wintag;
656 pcihp->ioh = h->windows[STP_WIN_IO].winaddr;
657 pcihp->size = size;
658 return (0);
659 }
660
661 void
662 stp4020_chip_io_free(pch, pcihp)
663 pcmcia_chipset_handle_t pch;
664 struct pcmcia_io_handle *pcihp;
665 {
666 }
667
668 int
669 stp4020_chip_io_map(pch, width, offset, size, pcihp, windowp)
670 pcmcia_chipset_handle_t pch;
671 int width;
672 bus_addr_t offset;
673 bus_size_t size;
674 struct pcmcia_io_handle *pcihp;
675 int *windowp;
676 {
677 struct stp4020_socket *h = (struct stp4020_socket *)pch;
678
679 pcihp->iot = h->wintag;
680 bus_space_subregion(h->wintag, h->windows[STP_WIN_IO].winaddr,
681 offset, size, &pcihp->ioh);
682 *windowp = 0;
683 return (0);
684 }
685
686 void
687 stp4020_chip_io_unmap(pch, win)
688 pcmcia_chipset_handle_t pch;
689 int win;
690 {
691 }
692
693 void
694 stp4020_chip_socket_enable(pch)
695 pcmcia_chipset_handle_t pch;
696 {
697 struct stp4020_socket *h = (struct stp4020_socket *)pch;
698 int i, v;
699
700 h->flags |= STP4020_SOCKET_ENABLING;
701
702
703
704
705 stp4020_wr_sockctl(h, STP4020_ICR1_IDX, 0);
706
707
708
709
710
711 stp4020_delay((300 + 100) * 1000);
712
713
714 v = STP4020_ICR1_MSTPWR;
715 stp4020_wr_sockctl(h, STP4020_ICR1_IDX, v);
716
717
718
719
720
721
722
723
724 stp4020_delay((100 + 20 + 200) * 1000);
725
726 v |= STP4020_ICR1_PCIFOE | STP4020_ICR1_VPP1_VCC;
727 stp4020_wr_sockctl(h, STP4020_ICR1_IDX, v);
728
729
730
731
732 stp4020_wr_sockctl(h, STP4020_ICR0_IDX,
733 stp4020_rd_sockctl(h, STP4020_ICR0_IDX) | STP4020_ICR0_RESET);
734 delay(20);
735 stp4020_wr_sockctl(h, STP4020_ICR0_IDX,
736 stp4020_rd_sockctl(h, STP4020_ICR0_IDX) & ~STP4020_ICR0_RESET);
737
738
739 stp4020_delay(20000);
740
741
742 for (i = 10000; i > 0; i--) {
743 v = stp4020_rd_sockctl(h, STP4020_ISR0_IDX);
744
745 if ((v & (STP4020_ISR0_CD1ST | STP4020_ISR0_CD2ST)) == 0) {
746 h->flags &= ~STP4020_SOCKET_ENABLING;
747 return;
748 }
749 if ((v & STP4020_ISR0_RDYST) != 0)
750 break;
751 delay(500);
752 }
753 if (i <= 0) {
754 #ifdef STP4020_DEBUG
755 printf("stp4020_chip_socket_enable: not ready: status %b\n",
756 v, STP4020_ISR0_IOBITS);
757 #endif
758 h->flags &= ~STP4020_SOCKET_ENABLING;
759 return;
760 }
761
762 v = stp4020_rd_sockctl(h, STP4020_ICR0_IDX);
763
764
765
766
767
768
769 if (pcmcia_card_gettype(h->pcmcia) == PCMCIA_IFTYPE_IO) {
770 v &= ~(STP4020_ICR0_IOILVL | STP4020_ICR0_IFTYPE);
771 v |= STP4020_ICR0_IFTYPE_IO | STP4020_ICR0_IOIE |
772 STP4020_ICR0_IOILVL_SB0 | STP4020_ICR0_SPKREN;
773 DPRINTF(("%s: configuring card for IO usage\n",
774 h->sc->sc_dev.dv_xname));
775 } else {
776 v &= ~(STP4020_ICR0_IOILVL | STP4020_ICR0_IFTYPE |
777 STP4020_ICR0_SPKREN | STP4020_ICR0_IOIE);
778 v |= STP4020_ICR0_IFTYPE_MEM;
779 DPRINTF(("%s: configuring card for MEM ONLY usage\n",
780 h->sc->sc_dev.dv_xname));
781 }
782 stp4020_wr_sockctl(h, STP4020_ICR0_IDX, v);
783
784 h->flags &= ~STP4020_SOCKET_ENABLING;
785 }
786
787 void
788 stp4020_chip_socket_disable(pch)
789 pcmcia_chipset_handle_t pch;
790 {
791 struct stp4020_socket *h = (struct stp4020_socket *)pch;
792 int v;
793
794
795
796
797 v = stp4020_rd_sockctl(h, STP4020_ICR0_IDX);
798 v &= ~(STP4020_ICR0_IOILVL | STP4020_ICR0_IFTYPE |
799 STP4020_ICR0_SPKREN | STP4020_ICR0_IOIE);
800 stp4020_wr_sockctl(h, STP4020_ICR0_IDX, v);
801
802
803 stp4020_wr_sockctl(h, STP4020_ICR1_IDX, 0);
804
805
806
807
808 stp4020_delay(300 * 1000);
809 }
810
811 void *
812 stp4020_chip_intr_establish(pch, pf, ipl, handler, arg, xname)
813 pcmcia_chipset_handle_t pch;
814 struct pcmcia_function *pf;
815 int ipl;
816 int (*handler) (void *);
817 void *arg;
818 char *xname;
819 {
820 struct stp4020_socket *h = (struct stp4020_socket *)pch;
821
822 h->intrhandler = handler;
823 h->intrarg = arg;
824 h->ipl = ipl;
825 return (h);
826 }
827
828 void
829 stp4020_chip_intr_disestablish(pch, ih)
830 pcmcia_chipset_handle_t pch;
831 void *ih;
832 {
833 struct stp4020_socket *h = (struct stp4020_socket *)pch;
834
835 h->intrhandler = NULL;
836 h->intrarg = NULL;
837 }
838
839 const char *
840 stp4020_chip_intr_string(pch, ih)
841 pcmcia_chipset_handle_t pch;
842 void *ih;
843 {
844 if (ih == NULL)
845 return ("couldn't establish interrupt");
846 else
847 return ("");
848 }
849
850
851
852
853
854 void
855 stp4020_delay(ms)
856 unsigned int ms;
857 {
858 unsigned int ticks;
859
860
861 ticks = (ms * hz) / 1000000;
862
863 if (cold || ticks == 0) {
864 delay(ms);
865 return;
866 }
867
868 #ifdef DEBUG
869 if (ticks > 60 * hz)
870 panic("stp4020: preposterous delay: %u", ticks);
871 #endif
872 tsleep(&ticks, 0, "stp4020_delay", ticks);
873 }
874
875 #ifdef STP4020_DEBUG
876 void
877 stp4020_dump_regs(h)
878 struct stp4020_socket *h;
879 {
880
881
882
883 printf("socket[%d] registers:\n"
884 "\tICR0=%b\n\tICR1=%b\n\tISR0=%b\n\tISR1=%x\n", h->sock,
885 stp4020_rd_sockctl(h, STP4020_ICR0_IDX), STP4020_ICR0_BITS,
886 stp4020_rd_sockctl(h, STP4020_ICR1_IDX), STP4020_ICR1_BITS,
887 stp4020_rd_sockctl(h, STP4020_ISR0_IDX), STP4020_ISR0_IOBITS,
888 stp4020_rd_sockctl(h, STP4020_ISR1_IDX));
889 }
890 #endif