Commit | Line | Data |
---|---|---|
e72e601b TL |
1 | /* |
2 | * Versatec matrix printer/plotter | |
3 | * dma interface driver | |
4 | */ | |
5 | ||
6 | #include "../h/param.h" | |
7 | #include "../h/dir.h" | |
8 | #include "../h/user.h" | |
9 | #include "../h/userx.h" | |
10 | #include "../h/buf.h" | |
11 | #include "../h/systm.h" | |
12 | #include "../h/uba.h" | |
13 | #include "../h/tty.h" | |
14 | ||
15 | #define VPPRI (PZERO+8) | |
16 | ||
17 | struct vpregs { | |
18 | short plbcr; | |
19 | short fill; | |
20 | short prbcr; | |
21 | unsigned short pbaddr; | |
22 | short plcsr; | |
23 | short plbuf; | |
24 | short prcsr; | |
25 | unsigned short prbuf; | |
26 | }; | |
27 | ||
28 | #define VPADDR ((struct vpregs *)(UBA0_DEV + 0177500)) | |
29 | ||
30 | #define ERROR 0100000 | |
31 | #define DTCINTR 040000 | |
32 | #define DMAACT 020000 | |
33 | #define READY 0200 | |
34 | #define IENABLE 0100 | |
35 | #define TERMCOM 040 | |
36 | #define FFCOM 020 | |
37 | #define EOTCOM 010 | |
38 | #define CLRCOM 04 | |
39 | #define RESET 02 | |
40 | #define SPP 01 | |
41 | ||
42 | struct { | |
43 | int vp_state; | |
44 | int vp_count; | |
45 | struct buf *vp_buf; | |
46 | int vp_bufp; | |
47 | } vp11; | |
48 | ||
49 | #define VISOPEN 01 | |
50 | #define CMNDS 076 | |
51 | #define MODE 0700 | |
52 | #define PRINT 0100 | |
53 | #define PLOT 0200 | |
54 | #define PPLOT 0400 | |
55 | #define VBUSY 01000 | |
56 | ||
57 | vpopen() | |
58 | { | |
59 | ||
60 | if (vp11.vp_state & VISOPEN) { | |
61 | u.u_error = ENXIO; | |
62 | return; | |
63 | } | |
64 | vp11.vp_state = VISOPEN | PRINT | CLRCOM | FFCOM | RESET; | |
65 | vp11.vp_count = 0; | |
66 | vp11.vp_buf = geteblk(); | |
67 | VPADDR->prcsr = IENABLE | DTCINTR; | |
68 | vptimo(); | |
69 | while (vp11.vp_state & CMNDS) { | |
70 | spl4(); | |
71 | if (vperror(READY)) { | |
72 | vpclose(); | |
73 | u.u_error = EIO; | |
74 | return; | |
75 | } | |
76 | vpstart(); | |
77 | spl0(); | |
78 | } | |
79 | } | |
80 | ||
81 | vpwrite() | |
82 | { | |
83 | register int i, e; | |
84 | register int ubainfo; | |
85 | ||
86 | if (u.u_count == 0) | |
87 | return; | |
88 | spl4(); | |
89 | while (vp11.vp_state & VBUSY) | |
90 | sleep((caddr_t) &vp11, VPPRI); | |
91 | vp11.vp_state |= VBUSY; | |
92 | spl0(); | |
93 | ubainfo = uballoc(vp11.vp_buf->b_un.b_addr, 512, 0); | |
94 | vp11.vp_bufp = ubainfo & 0x3ffff; | |
95 | while (i = vp11.vp_count = min(512, u.u_count)) { | |
96 | iomove(vp11.vp_buf->b_addr, i, B_WRITE); | |
97 | spl4(); | |
98 | if (e = vperror(READY)) | |
99 | break; | |
100 | vpstart(); | |
101 | while ((vp11.vp_state&PLOT ? VPADDR->plcsr : VPADDR->prcsr) & DMAACT) | |
102 | sleep((caddr_t) &vp11, VPPRI); | |
103 | if ((vp11.vp_state&MODE) == PPLOT) | |
104 | vp11.vp_state = (vp11.vp_state &~ MODE) | PLOT; | |
105 | spl0(); | |
106 | } | |
107 | ubafree(ubainfo); | |
108 | vp11.vp_state &= ~VBUSY; | |
109 | if (e) | |
110 | u.u_error = EIO; | |
111 | wakeup ((caddr_t) &vp11); | |
112 | } | |
113 | ||
114 | vperror(bit) | |
115 | { | |
116 | register int state, e; | |
117 | ||
118 | state = vp11.vp_state & PLOT; | |
119 | while ((e = (state ? VPADDR->plcsr : VPADDR->prcsr) & (bit|ERROR)) == 0) | |
120 | sleep ((caddr_t) &vp11, VPPRI); | |
121 | return (e & ERROR); | |
122 | } | |
123 | ||
124 | vpstart() | |
125 | { | |
126 | register short bit; | |
127 | ||
128 | if (vp11.vp_count) { | |
129 | VPADDR->pbaddr = vp11.vp_bufp; | |
130 | if (vp11.vp_state & (PRINT|PPLOT)) | |
131 | VPADDR->prbcr = vp11.vp_count; | |
132 | else | |
133 | VPADDR->plbcr = vp11.vp_count; | |
134 | return; | |
135 | } | |
136 | for (bit = 1; bit != 0; bit <<= 1) | |
137 | if (vp11.vp_state&bit&CMNDS) { | |
138 | VPADDR->plcsr |= bit; | |
139 | vp11.vp_state &= ~bit; | |
140 | return; | |
141 | } | |
142 | } | |
143 | ||
144 | vpsgtty(dev, sgbp) | |
145 | register struct sgttyb *sgbp; | |
146 | { | |
147 | register int m; | |
148 | ||
149 | if (sgbp != NULL) { | |
150 | sgbp->sg_flags = vp11.vp_state; | |
151 | return; | |
152 | } | |
153 | m = sgbp->sg_flags; | |
154 | vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS)); | |
155 | spl4(); | |
156 | vperror(READY); | |
157 | if (vp11.vp_state&PPLOT) | |
158 | VPADDR->plcsr |= SPP; | |
159 | else | |
160 | VPADDR->plcsr &= ~SPP; | |
161 | vp11.vp_count = 0; | |
162 | while (CMNDS & vp11.vp_state) { | |
163 | vperror(READY); | |
164 | vpstart(); | |
165 | } | |
166 | spl0(); | |
167 | } | |
168 | ||
169 | vpioctl(dev, cmd, addr, flag) | |
170 | register caddr_t addr; | |
171 | { | |
172 | register int m; | |
173 | ||
174 | switch (cmd) { | |
175 | ||
176 | case ('v'<<8)+0: | |
177 | suword(addr, vp11.vp_state); | |
178 | return; | |
179 | ||
180 | case ('v'<<8)+1: | |
181 | m = fuword(addr); | |
182 | if (m == -1) { | |
183 | u.u_error = EFAULT; | |
184 | return; | |
185 | } | |
186 | vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS)); | |
187 | break; | |
188 | ||
189 | default: | |
190 | u.u_error = ENOTTY; | |
191 | return; | |
192 | } | |
193 | spl4(); | |
194 | vperr(READY); | |
195 | if (vp11.vp_state&PPLOT) | |
196 | VPADDR->plcsr |= SPP; | |
197 | else | |
198 | VPADDR->plcsr &= ~SPP; | |
199 | vp11.vp_count = 0; | |
200 | while (CMNDS & vp11.vp_state) { | |
201 | vperror(READY); | |
202 | vpstart(); | |
203 | } | |
204 | spl0(); | |
205 | } | |
206 | ||
207 | vptimo() | |
208 | { | |
209 | ||
210 | if (vp11.vp_state&VISOPEN) | |
211 | timeout(vptimo, 0, HZ/10); | |
212 | vpintr(0); | |
213 | } | |
214 | ||
215 | vpintr(dev) | |
216 | { | |
217 | ||
218 | wakeup((caddr_t) &vp11); | |
219 | } | |
220 | ||
221 | vpclose() | |
222 | { | |
223 | ||
224 | brelse(vp11.vp_buf); | |
225 | vp11.vp_state = 0; | |
226 | vp11.vp_count = 0; | |
227 | vp11.vp_buf = 0; | |
228 | vp11.vp_bufp = 0; | |
229 | VPADDR->plcsr = 0; | |
230 | } |