ast.c revision 1.4 1 /*
2 * Multi-port serial card interrupt demuxing support.
3 * Roland McGrath 3/20/94
4 * The author disclaims copyright and places this file in the public domain.
5 *
6 * Modified by: Charles Hannum, 3/22/94
7 *
8 * $Id: ast.c,v 1.4 1994/03/23 03:55:24 cgd Exp $
9 */
10
11 #include "ast.h"
12
13 #include <sys/types.h>
14 #include <sys/device.h>
15
16 #include <machine/pio.h>
17 #include <i386/isa/isa_device.h>
18
19 int astprobe __P((struct isa_device *));
20 int astattach __P((struct isa_device *));
21
22 struct isa_driver astdriver = {
23 astprobe, astattach, "ast"
24 };
25
26 struct ast_softc {
27 struct device sc_dev;
28 u_short sc_iobase;
29 int sc_alive; /* Mask of slave units attached. */
30 int sc_slaves[8]; /* com device unit numbers. XXX - softc ptrs */
31 } ast_softc[NAST];
32
33 int
34 astprobe(dev)
35 struct isa_device *dev;
36 {
37
38 /*
39 * Do the normal com probe for the first UART and assume
40 * its presence means there is a multiport board there.
41 * XXX needs more robustness.
42 */
43 return comprobe1(dev->id_iobase);
44 }
45
46 int
47 astattach(dev)
48 struct isa_device *dev;
49 {
50 struct ast_softc *sc = &ast_softc[dev->id_unit];
51 u_short iobase = dev->id_iobase;
52 unsigned int x;
53
54 /* XXX HACK */
55 sprintf(sc->sc_dev.dv_xname, "%s%d", astdriver.name, dev->id_unit);
56 sc->sc_dev.dv_unit = dev->id_unit;
57
58 sc->sc_iobase = iobase;
59
60 /*
61 * Enable the master interrupt.
62 */
63 outb(iobase | 0x1f, 0x80);
64 x = inb(iobase | 0x1f);
65 /*
66 * My guess is this bitmask tells you how many ports are there.
67 * I only have a 4-port board to try (returns 0xf). --roland
68 *
69 * It's also not clear that it would be correct to rely on this, since
70 * there might be an interrupt pending on one of the ports, and thus
71 * its bit wouldn't be set. I think the AST protocol simply does not
72 * support more than 4 ports. - mycroft
73 */
74 printf("%s: 0x%x\n", sc->sc_dev.dv_xname, x);
75 }
76
77 void
78 astslave(dev)
79 struct isa_device *dev;
80 {
81 struct ast_softc *sc = &ast_softc[dev->id_parent->id_unit];
82
83 sc->sc_slaves[dev->id_physid] = dev->id_unit;
84 sc->sc_alive |= 1 << dev->id_physid;
85 }
86
87 int
88 astintr(unit)
89 int unit;
90 {
91 struct ast_softc *sc = &ast_softc[unit];
92 u_short iobase = sc->sc_iobase;
93 int alive = sc->sc_alive;
94 int bits;
95
96 bits = inb(iobase | 0x1f) & alive;
97 if (bits == alive)
98 return 0;
99
100 do {
101 #define TRY(n) \
102 if ((bits & (1 << (n))) == 0) \
103 comintr(sc->sc_slaves[n]); /* XXX softc ptr */
104 TRY(0);
105 TRY(1);
106 TRY(2);
107 TRY(3);
108 #ifdef notdef
109 TRY(4);
110 TRY(5);
111 TRY(6);
112 TRY(7);
113 #endif
114 bits = inb(iobase | 0x1f) & alive;
115 } while (bits != alive);
116
117 return 1;
118 }
119