diff options
Diffstat (limited to 'drivers/char/rio/riointr.c')
-rw-r--r-- | drivers/char/rio/riointr.c | 1505 |
1 files changed, 731 insertions, 774 deletions
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c index ddda9c14e059..34d8787557a1 100644 --- a/drivers/char/rio/riointr.c +++ b/drivers/char/rio/riointr.c | |||
@@ -88,99 +88,93 @@ static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2"; | |||
88 | static void RIOReceive(struct rio_info *, struct Port *); | 88 | static void RIOReceive(struct rio_info *, struct Port *); |
89 | 89 | ||
90 | 90 | ||
91 | static char *firstchars (char *p, int nch) | 91 | static char *firstchars(char *p, int nch) |
92 | { | 92 | { |
93 | static char buf[2][128]; | 93 | static char buf[2][128]; |
94 | static int t=0; | 94 | static int t = 0; |
95 | t = ! t; | 95 | t = !t; |
96 | memcpy (buf[t], p, nch); | 96 | memcpy(buf[t], p, nch); |
97 | buf[t][nch] = 0; | 97 | buf[t][nch] = 0; |
98 | return buf[t]; | 98 | return buf[t]; |
99 | } | 99 | } |
100 | 100 | ||
101 | 101 | ||
102 | #define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask)) | 102 | #define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask)) |
103 | /* Enable and start the transmission of packets */ | 103 | /* Enable and start the transmission of packets */ |
104 | void | 104 | void RIOTxEnable(en) |
105 | RIOTxEnable(en) | 105 | char *en; |
106 | char * en; | ||
107 | { | 106 | { |
108 | struct Port * PortP; | 107 | struct Port *PortP; |
109 | struct rio_info *p; | 108 | struct rio_info *p; |
110 | struct tty_struct* tty; | 109 | struct tty_struct *tty; |
111 | int c; | 110 | int c; |
112 | struct PKT * PacketP; | 111 | struct PKT *PacketP; |
113 | unsigned long flags; | 112 | unsigned long flags; |
114 | 113 | ||
115 | PortP = (struct Port *)en; | 114 | PortP = (struct Port *) en; |
116 | p = (struct rio_info *)PortP->p; | 115 | p = (struct rio_info *) PortP->p; |
117 | tty = PortP->gs.tty; | 116 | tty = PortP->gs.tty; |
118 | 117 | ||
119 | 118 | ||
120 | rio_dprintk (RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", | 119 | rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt); |
121 | PortP->PortNum, PortP->gs.xmit_cnt); | 120 | |
122 | 121 | if (!PortP->gs.xmit_cnt) | |
123 | if (!PortP->gs.xmit_cnt) return; | 122 | return; |
124 | 123 | ||
125 | 124 | ||
126 | /* This routine is an order of magnitude simpler than the specialix | 125 | /* This routine is an order of magnitude simpler than the specialix |
127 | version. One of the disadvantages is that this version will send | 126 | version. One of the disadvantages is that this version will send |
128 | an incomplete packet (usually 64 bytes instead of 72) once for | 127 | an incomplete packet (usually 64 bytes instead of 72) once for |
129 | every 4k worth of data. Let's just say that this won't influence | 128 | every 4k worth of data. Let's just say that this won't influence |
130 | performance significantly..... */ | 129 | performance significantly..... */ |
131 | 130 | ||
132 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 131 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
133 | 132 | ||
134 | while (can_add_transmit( &PacketP, PortP )) { | 133 | while (can_add_transmit(&PacketP, PortP)) { |
135 | c = PortP->gs.xmit_cnt; | 134 | c = PortP->gs.xmit_cnt; |
136 | if (c > PKT_MAX_DATA_LEN) c = PKT_MAX_DATA_LEN; | 135 | if (c > PKT_MAX_DATA_LEN) |
137 | 136 | c = PKT_MAX_DATA_LEN; | |
138 | /* Don't copy past the end of the source buffer */ | 137 | |
139 | if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail) | 138 | /* Don't copy past the end of the source buffer */ |
140 | c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail; | 139 | if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail) |
141 | 140 | c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail; | |
142 | { int t; | 141 | |
143 | t = (c > 10)?10:c; | 142 | { |
144 | 143 | int t; | |
145 | rio_dprintk (RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", | 144 | t = (c > 10) ? 10 : c; |
146 | PortP->PortNum, c, | 145 | |
147 | firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail , t), | 146 | rio_dprintk(RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", PortP->PortNum, c, firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail, t), firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail + c - t, t)); |
148 | firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail + c-t, t)); | 147 | } |
149 | } | 148 | /* If for one reason or another, we can't copy more data, |
150 | /* If for one reason or another, we can't copy more data, | 149 | we're done! */ |
151 | we're done! */ | 150 | if (c == 0) |
152 | if (c == 0) break; | 151 | break; |
153 | 152 | ||
154 | rio_memcpy_toio (PortP->HostP->Caddr, (caddr_t)PacketP->data, | 153 | rio_memcpy_toio(PortP->HostP->Caddr, (caddr_t) PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c); |
155 | PortP->gs.xmit_buf + PortP->gs.xmit_tail, c); | 154 | /* udelay (1); */ |
156 | /* udelay (1); */ | 155 | |
157 | 156 | writeb(c, &(PacketP->len)); | |
158 | writeb (c, &(PacketP->len)); | 157 | if (!(PortP->State & RIO_DELETED)) { |
159 | if (!( PortP->State & RIO_DELETED ) ) { | 158 | add_transmit(PortP); |
160 | add_transmit ( PortP ); | 159 | /* |
161 | /* | 160 | ** Count chars tx'd for port statistics reporting |
162 | ** Count chars tx'd for port statistics reporting | 161 | */ |
163 | */ | 162 | if (PortP->statsGather) |
164 | if ( PortP->statsGather ) | 163 | PortP->txchars += c; |
165 | PortP->txchars += c; | 164 | } |
166 | } | 165 | PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1); |
167 | PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE-1); | 166 | PortP->gs.xmit_cnt -= c; |
168 | PortP->gs.xmit_cnt -= c; | 167 | } |
169 | } | 168 | |
170 | 169 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | |
171 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 170 | |
172 | 171 | if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) { | |
173 | if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2*PKT_MAX_DATA_LEN)) { | 172 | rio_dprintk(RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....", (int) (PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)), PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); |
174 | rio_dprintk (RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....", | 173 | if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && PortP->gs.tty->ldisc.write_wakeup) |
175 | (int)(PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)), | 174 | (PortP->gs.tty->ldisc.write_wakeup) (PortP->gs.tty); |
176 | PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); | 175 | rio_dprintk(RIO_DEBUG_INTR, "(%d/%d)\n", PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); |
177 | if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | 176 | wake_up_interruptible(&PortP->gs.tty->write_wait); |
178 | PortP->gs.tty->ldisc.write_wakeup) | 177 | } |
179 | (PortP->gs.tty->ldisc.write_wakeup)(PortP->gs.tty); | ||
180 | rio_dprintk (RIO_DEBUG_INTR, "(%d/%d)\n", | ||
181 | PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); | ||
182 | wake_up_interruptible(&PortP->gs.tty->write_wait); | ||
183 | } | ||
184 | 178 | ||
185 | } | 179 | } |
186 | 180 | ||
@@ -189,361 +183,349 @@ char * en; | |||
189 | ** RIO Host Service routine. Does all the work traditionally associated with an | 183 | ** RIO Host Service routine. Does all the work traditionally associated with an |
190 | ** interrupt. | 184 | ** interrupt. |
191 | */ | 185 | */ |
192 | static int RupIntr; | 186 | static int RupIntr; |
193 | static int RxIntr; | 187 | static int RxIntr; |
194 | static int TxIntr; | 188 | static int TxIntr; |
195 | void | 189 | void RIOServiceHost(p, HostP, From) |
196 | RIOServiceHost(p, HostP, From) | 190 | struct rio_info *p; |
197 | struct rio_info * p; | ||
198 | struct Host *HostP; | 191 | struct Host *HostP; |
199 | int From; | 192 | int From; |
200 | { | 193 | { |
201 | rio_spin_lock (&HostP->HostLock); | 194 | rio_spin_lock(&HostP->HostLock); |
202 | if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) { | 195 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { |
203 | static int t =0; | 196 | static int t = 0; |
204 | rio_spin_unlock (&HostP->HostLock); | 197 | rio_spin_unlock(&HostP->HostLock); |
205 | if ((t++ % 200) == 0) | 198 | if ((t++ % 200) == 0) |
206 | rio_dprintk (RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int)HostP->Flags); | 199 | rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags); |
207 | return; | 200 | return; |
208 | } | 201 | } |
209 | rio_spin_unlock (&HostP->HostLock); | 202 | rio_spin_unlock(&HostP->HostLock); |
210 | 203 | ||
211 | if ( RWORD( HostP->ParmMapP->rup_intr ) ) { | 204 | if (RWORD(HostP->ParmMapP->rup_intr)) { |
212 | WWORD( HostP->ParmMapP->rup_intr , 0 ); | 205 | WWORD(HostP->ParmMapP->rup_intr, 0); |
213 | p->RIORupCount++; | 206 | p->RIORupCount++; |
214 | RupIntr++; | 207 | RupIntr++; |
215 | rio_dprintk (RIO_DEBUG_INTR, "rio: RUP interrupt on host %d\n", HostP-p->RIOHosts); | 208 | rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %d\n", HostP - p->RIOHosts); |
216 | RIOPollHostCommands(p, HostP ); | 209 | RIOPollHostCommands(p, HostP); |
217 | } | 210 | } |
218 | 211 | ||
219 | if ( RWORD( HostP->ParmMapP->rx_intr ) ) { | 212 | if (RWORD(HostP->ParmMapP->rx_intr)) { |
220 | int port; | 213 | int port; |
221 | 214 | ||
222 | WWORD( HostP->ParmMapP->rx_intr , 0 ); | 215 | WWORD(HostP->ParmMapP->rx_intr, 0); |
223 | p->RIORxCount++; | 216 | p->RIORxCount++; |
224 | RxIntr++; | 217 | RxIntr++; |
225 | 218 | ||
226 | rio_dprintk (RIO_DEBUG_INTR, "rio: RX interrupt on host %d\n", HostP-p->RIOHosts); | 219 | rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %d\n", HostP - p->RIOHosts); |
227 | /* | 220 | /* |
228 | ** Loop through every port. If the port is mapped into | 221 | ** Loop through every port. If the port is mapped into |
229 | ** the system ( i.e. has /dev/ttyXXXX associated ) then it is | 222 | ** the system ( i.e. has /dev/ttyXXXX associated ) then it is |
230 | ** worth checking. If the port isn't open, grab any packets | 223 | ** worth checking. If the port isn't open, grab any packets |
231 | ** hanging on its receive queue and stuff them on the free | 224 | ** hanging on its receive queue and stuff them on the free |
232 | ** list; check for commands on the way. | 225 | ** list; check for commands on the way. |
233 | */ | 226 | */ |
234 | for ( port=p->RIOFirstPortsBooted; | 227 | for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { |
235 | port<p->RIOLastPortsBooted+PORTS_PER_RTA; port++ ) { | 228 | struct Port *PortP = p->RIOPortp[port]; |
236 | struct Port *PortP = p->RIOPortp[port]; | 229 | struct tty_struct *ttyP; |
237 | struct tty_struct *ttyP; | 230 | struct PKT *PacketP; |
238 | struct PKT *PacketP; | 231 | |
239 | 232 | /* | |
240 | /* | 233 | ** not mapped in - most of the RIOPortp[] information |
241 | ** not mapped in - most of the RIOPortp[] information | 234 | ** has not been set up! |
242 | ** has not been set up! | 235 | ** Optimise: ports come in bundles of eight. |
243 | ** Optimise: ports come in bundles of eight. | 236 | */ |
244 | */ | 237 | if (!PortP->Mapped) { |
245 | if ( !PortP->Mapped ) { | 238 | port += 7; |
246 | port += 7; | 239 | continue; /* with the next port */ |
247 | continue; /* with the next port */ | 240 | } |
248 | } | 241 | |
249 | 242 | /* | |
250 | /* | 243 | ** If the host board isn't THIS host board, check the next one. |
251 | ** If the host board isn't THIS host board, check the next one. | 244 | ** optimise: ports come in bundles of eight. |
252 | ** optimise: ports come in bundles of eight. | 245 | */ |
253 | */ | 246 | if (PortP->HostP != HostP) { |
254 | if ( PortP->HostP != HostP ) { | 247 | port += 7; |
255 | port += 7; | 248 | continue; |
256 | continue; | 249 | } |
257 | } | 250 | |
258 | 251 | /* | |
259 | /* | 252 | ** Let us see - is the port open? If not, then don't service it. |
260 | ** Let us see - is the port open? If not, then don't service it. | 253 | */ |
261 | */ | 254 | if (!(PortP->PortState & PORT_ISOPEN)) { |
262 | if ( !( PortP->PortState & PORT_ISOPEN ) ) { | 255 | continue; |
263 | continue; | 256 | } |
264 | } | 257 | |
265 | 258 | /* | |
266 | /* | 259 | ** find corresponding tty structure. The process of mapping |
267 | ** find corresponding tty structure. The process of mapping | 260 | ** the ports puts these here. |
268 | ** the ports puts these here. | 261 | */ |
269 | */ | 262 | ttyP = PortP->gs.tty; |
270 | ttyP = PortP->gs.tty; | 263 | |
271 | 264 | /* | |
272 | /* | 265 | ** Lock the port before we begin working on it. |
273 | ** Lock the port before we begin working on it. | 266 | */ |
274 | */ | 267 | rio_spin_lock(&PortP->portSem); |
275 | rio_spin_lock(&PortP->portSem); | 268 | |
276 | 269 | /* | |
277 | /* | 270 | ** Process received data if there is any. |
278 | ** Process received data if there is any. | 271 | */ |
279 | */ | 272 | if (can_remove_receive(&PacketP, PortP)) |
280 | if ( can_remove_receive( &PacketP, PortP ) ) | 273 | RIOReceive(p, PortP); |
281 | RIOReceive(p, PortP); | 274 | |
282 | 275 | /* | |
283 | /* | 276 | ** If there is no data left to be read from the port, and |
284 | ** If there is no data left to be read from the port, and | 277 | ** it's handshake bit is set, then we must clear the handshake, |
285 | ** it's handshake bit is set, then we must clear the handshake, | 278 | ** so that that downstream RTA is re-enabled. |
286 | ** so that that downstream RTA is re-enabled. | 279 | */ |
287 | */ | 280 | if (!can_remove_receive(&PacketP, PortP) && (RWORD(PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) { |
288 | if ( !can_remove_receive( &PacketP, PortP ) && | ||
289 | ( RWORD( PortP->PhbP->handshake )==PHB_HANDSHAKE_SET ) ) { | ||
290 | /* | 281 | /* |
291 | ** MAGIC! ( Basically, handshake the RX buffer, so that | 282 | ** MAGIC! ( Basically, handshake the RX buffer, so that |
292 | ** the RTAs upstream can be re-enabled. ) | 283 | ** the RTAs upstream can be re-enabled. ) |
293 | */ | 284 | */ |
294 | rio_dprintk (RIO_DEBUG_INTR, "Set RX handshake bit\n"); | 285 | rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n"); |
295 | WWORD( PortP->PhbP->handshake, | 286 | WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET); |
296 | PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET ); | 287 | } |
297 | } | 288 | rio_spin_unlock(&PortP->portSem); |
298 | rio_spin_unlock(&PortP->portSem); | 289 | } |
299 | } | ||
300 | } | ||
301 | |||
302 | if ( RWORD( HostP->ParmMapP->tx_intr ) ) { | ||
303 | int port; | ||
304 | |||
305 | WWORD( HostP->ParmMapP->tx_intr , 0); | ||
306 | |||
307 | p->RIOTxCount++; | ||
308 | TxIntr++; | ||
309 | rio_dprintk (RIO_DEBUG_INTR, "rio: TX interrupt on host %d\n", HostP-p->RIOHosts); | ||
310 | |||
311 | /* | ||
312 | ** Loop through every port. | ||
313 | ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX | ||
314 | ** associated ) then it is worth checking. | ||
315 | */ | ||
316 | for ( port=p->RIOFirstPortsBooted; | ||
317 | port<p->RIOLastPortsBooted+PORTS_PER_RTA; port++ ) { | ||
318 | struct Port *PortP = p->RIOPortp[port]; | ||
319 | struct tty_struct *ttyP; | ||
320 | struct PKT *PacketP; | ||
321 | |||
322 | /* | ||
323 | ** not mapped in - most of the RIOPortp[] information | ||
324 | ** has not been set up! | ||
325 | */ | ||
326 | if ( !PortP->Mapped ) { | ||
327 | port += 7; | ||
328 | continue; /* with the next port */ | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | ** If the host board isn't running, then its data structures | ||
333 | ** are no use to us - continue quietly. | ||
334 | */ | ||
335 | if ( PortP->HostP != HostP ) { | ||
336 | port += 7; | ||
337 | continue; /* with the next port */ | ||
338 | } | ||
339 | |||
340 | /* | ||
341 | ** Let us see - is the port open? If not, then don't service it. | ||
342 | */ | ||
343 | if ( !( PortP->PortState & PORT_ISOPEN ) ) { | ||
344 | continue; | ||
345 | } | ||
346 | |||
347 | rio_dprintk (RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port); | ||
348 | /* | ||
349 | ** Lock the port before we begin working on it. | ||
350 | */ | ||
351 | rio_spin_lock(&PortP->portSem); | ||
352 | |||
353 | /* | ||
354 | ** If we can't add anything to the transmit queue, then | ||
355 | ** we need do none of this processing. | ||
356 | */ | ||
357 | if ( !can_add_transmit( &PacketP, PortP ) ) { | ||
358 | rio_dprintk (RIO_DEBUG_INTR, "Can't add to port, so skipping.\n"); | ||
359 | rio_spin_unlock(&PortP->portSem); | ||
360 | continue; | ||
361 | } | ||
362 | |||
363 | /* | ||
364 | ** find corresponding tty structure. The process of mapping | ||
365 | ** the ports puts these here. | ||
366 | */ | ||
367 | ttyP = PortP->gs.tty; | ||
368 | /* If ttyP is NULL, the port is getting closed. Forget about it. */ | ||
369 | if (!ttyP) { | ||
370 | rio_dprintk (RIO_DEBUG_INTR, "no tty, so skipping.\n"); | ||
371 | rio_spin_unlock(&PortP->portSem); | ||
372 | continue; | ||
373 | } | ||
374 | /* | ||
375 | ** If there is more room available we start up the transmit | ||
376 | ** data process again. This can be direct I/O, if the cookmode | ||
377 | ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the | ||
378 | ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch | ||
379 | ** characters via the line discipline. We must always call | ||
380 | ** the line discipline, | ||
381 | ** so that user input characters can be echoed correctly. | ||
382 | ** | ||
383 | ** ++++ Update +++++ | ||
384 | ** With the advent of double buffering, we now see if | ||
385 | ** TxBufferOut-In is non-zero. If so, then we copy a packet | ||
386 | ** to the output place, and set it going. If this empties | ||
387 | ** the buffer, then we must issue a wakeup( ) on OUT. | ||
388 | ** If it frees space in the buffer then we must issue | ||
389 | ** a wakeup( ) on IN. | ||
390 | ** | ||
391 | ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we | ||
392 | ** have to send a WFLUSH command down the PHB, to mark the | ||
393 | ** end point of a WFLUSH. We also need to clear out any | ||
394 | ** data from the double buffer! ( note that WflushFlag is a | ||
395 | ** *count* of the number of WFLUSH commands outstanding! ) | ||
396 | ** | ||
397 | ** ++++ And there's more! | ||
398 | ** If an RTA is powered off, then on again, and rebooted, | ||
399 | ** whilst it has ports open, then we need to re-open the ports. | ||
400 | ** ( reasonable enough ). We can't do this when we spot the | ||
401 | ** re-boot, in interrupt time, because the queue is probably | ||
402 | ** full. So, when we come in here, we need to test if any | ||
403 | ** ports are in this condition, and re-open the port before | ||
404 | ** we try to send any more data to it. Now, the re-booted | ||
405 | ** RTA will be discarding packets from the PHB until it | ||
406 | ** receives this open packet, but don't worry tooo much | ||
407 | ** about that. The one thing that is interesting is the | ||
408 | ** combination of this effect and the WFLUSH effect! | ||
409 | */ | ||
410 | /* For now don't handle RTA reboots. -- REW. | ||
411 | Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */ | ||
412 | if ( PortP->MagicFlags ) { | ||
413 | #if 1 | ||
414 | if ( PortP->MagicFlags & MAGIC_REBOOT ) { | ||
415 | /* | ||
416 | ** well, the RTA has been rebooted, and there is room | ||
417 | ** on its queue to add the open packet that is required. | ||
418 | ** | ||
419 | ** The messy part of this line is trying to decide if | ||
420 | ** we need to call the Param function as a tty or as | ||
421 | ** a modem. | ||
422 | ** DONT USE CLOCAL AS A TEST FOR THIS! | ||
423 | ** | ||
424 | ** If we can't param the port, then move on to the | ||
425 | ** next port. | ||
426 | */ | ||
427 | PortP->InUse = NOT_INUSE; | ||
428 | |||
429 | rio_spin_unlock(&PortP->portSem); | ||
430 | if ( RIOParam(PortP, OPEN, ((PortP->Cor2Copy & | ||
431 | (COR2_RTSFLOW|COR2_CTSFLOW ) )== | ||
432 | (COR2_RTSFLOW|COR2_CTSFLOW ) ) ? | ||
433 | TRUE : FALSE, DONT_SLEEP ) == RIO_FAIL ) { | ||
434 | continue; /* with next port */ | ||
435 | } | ||
436 | rio_spin_lock(&PortP->portSem); | ||
437 | PortP->MagicFlags &= ~MAGIC_REBOOT; | ||
438 | } | 290 | } |
291 | |||
292 | if (RWORD(HostP->ParmMapP->tx_intr)) { | ||
293 | int port; | ||
294 | |||
295 | WWORD(HostP->ParmMapP->tx_intr, 0); | ||
296 | |||
297 | p->RIOTxCount++; | ||
298 | TxIntr++; | ||
299 | rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %d\n", HostP - p->RIOHosts); | ||
300 | |||
301 | /* | ||
302 | ** Loop through every port. | ||
303 | ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX | ||
304 | ** associated ) then it is worth checking. | ||
305 | */ | ||
306 | for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { | ||
307 | struct Port *PortP = p->RIOPortp[port]; | ||
308 | struct tty_struct *ttyP; | ||
309 | struct PKT *PacketP; | ||
310 | |||
311 | /* | ||
312 | ** not mapped in - most of the RIOPortp[] information | ||
313 | ** has not been set up! | ||
314 | */ | ||
315 | if (!PortP->Mapped) { | ||
316 | port += 7; | ||
317 | continue; /* with the next port */ | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | ** If the host board isn't running, then its data structures | ||
322 | ** are no use to us - continue quietly. | ||
323 | */ | ||
324 | if (PortP->HostP != HostP) { | ||
325 | port += 7; | ||
326 | continue; /* with the next port */ | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | ** Let us see - is the port open? If not, then don't service it. | ||
331 | */ | ||
332 | if (!(PortP->PortState & PORT_ISOPEN)) { | ||
333 | continue; | ||
334 | } | ||
335 | |||
336 | rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port); | ||
337 | /* | ||
338 | ** Lock the port before we begin working on it. | ||
339 | */ | ||
340 | rio_spin_lock(&PortP->portSem); | ||
341 | |||
342 | /* | ||
343 | ** If we can't add anything to the transmit queue, then | ||
344 | ** we need do none of this processing. | ||
345 | */ | ||
346 | if (!can_add_transmit(&PacketP, PortP)) { | ||
347 | rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n"); | ||
348 | rio_spin_unlock(&PortP->portSem); | ||
349 | continue; | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | ** find corresponding tty structure. The process of mapping | ||
354 | ** the ports puts these here. | ||
355 | */ | ||
356 | ttyP = PortP->gs.tty; | ||
357 | /* If ttyP is NULL, the port is getting closed. Forget about it. */ | ||
358 | if (!ttyP) { | ||
359 | rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n"); | ||
360 | rio_spin_unlock(&PortP->portSem); | ||
361 | continue; | ||
362 | } | ||
363 | /* | ||
364 | ** If there is more room available we start up the transmit | ||
365 | ** data process again. This can be direct I/O, if the cookmode | ||
366 | ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the | ||
367 | ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch | ||
368 | ** characters via the line discipline. We must always call | ||
369 | ** the line discipline, | ||
370 | ** so that user input characters can be echoed correctly. | ||
371 | ** | ||
372 | ** ++++ Update +++++ | ||
373 | ** With the advent of double buffering, we now see if | ||
374 | ** TxBufferOut-In is non-zero. If so, then we copy a packet | ||
375 | ** to the output place, and set it going. If this empties | ||
376 | ** the buffer, then we must issue a wakeup( ) on OUT. | ||
377 | ** If it frees space in the buffer then we must issue | ||
378 | ** a wakeup( ) on IN. | ||
379 | ** | ||
380 | ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we | ||
381 | ** have to send a WFLUSH command down the PHB, to mark the | ||
382 | ** end point of a WFLUSH. We also need to clear out any | ||
383 | ** data from the double buffer! ( note that WflushFlag is a | ||
384 | ** *count* of the number of WFLUSH commands outstanding! ) | ||
385 | ** | ||
386 | ** ++++ And there's more! | ||
387 | ** If an RTA is powered off, then on again, and rebooted, | ||
388 | ** whilst it has ports open, then we need to re-open the ports. | ||
389 | ** ( reasonable enough ). We can't do this when we spot the | ||
390 | ** re-boot, in interrupt time, because the queue is probably | ||
391 | ** full. So, when we come in here, we need to test if any | ||
392 | ** ports are in this condition, and re-open the port before | ||
393 | ** we try to send any more data to it. Now, the re-booted | ||
394 | ** RTA will be discarding packets from the PHB until it | ||
395 | ** receives this open packet, but don't worry tooo much | ||
396 | ** about that. The one thing that is interesting is the | ||
397 | ** combination of this effect and the WFLUSH effect! | ||
398 | */ | ||
399 | /* For now don't handle RTA reboots. -- REW. | ||
400 | Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */ | ||
401 | if (PortP->MagicFlags) { | ||
402 | #if 1 | ||
403 | if (PortP->MagicFlags & MAGIC_REBOOT) { | ||
404 | /* | ||
405 | ** well, the RTA has been rebooted, and there is room | ||
406 | ** on its queue to add the open packet that is required. | ||
407 | ** | ||
408 | ** The messy part of this line is trying to decide if | ||
409 | ** we need to call the Param function as a tty or as | ||
410 | ** a modem. | ||
411 | ** DONT USE CLOCAL AS A TEST FOR THIS! | ||
412 | ** | ||
413 | ** If we can't param the port, then move on to the | ||
414 | ** next port. | ||
415 | */ | ||
416 | PortP->InUse = NOT_INUSE; | ||
417 | |||
418 | rio_spin_unlock(&PortP->portSem); | ||
419 | if (RIOParam(PortP, OPEN, ((PortP->Cor2Copy & (COR2_RTSFLOW | COR2_CTSFLOW)) == (COR2_RTSFLOW | COR2_CTSFLOW)) ? TRUE : FALSE, DONT_SLEEP) == RIO_FAIL) { | ||
420 | continue; /* with next port */ | ||
421 | } | ||
422 | rio_spin_lock(&PortP->portSem); | ||
423 | PortP->MagicFlags &= ~MAGIC_REBOOT; | ||
424 | } | ||
439 | #endif | 425 | #endif |
440 | 426 | ||
441 | /* | 427 | /* |
442 | ** As mentioned above, this is a tacky hack to cope | 428 | ** As mentioned above, this is a tacky hack to cope |
443 | ** with WFLUSH | 429 | ** with WFLUSH |
444 | */ | 430 | */ |
445 | if ( PortP->WflushFlag ) { | 431 | if (PortP->WflushFlag) { |
446 | rio_dprintk (RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n"); | 432 | rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n"); |
447 | 433 | ||
448 | if ( PortP->InUse ) | 434 | if (PortP->InUse) |
449 | rio_dprintk (RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n"); | 435 | rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n"); |
450 | } | 436 | } |
451 | 437 | ||
452 | while ( PortP->WflushFlag && | 438 | while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) { |
453 | can_add_transmit( &PacketP, PortP ) && | 439 | int p; |
454 | ( PortP->InUse == NOT_INUSE ) ) { | 440 | struct PktCmd *PktCmdP; |
455 | int p; | 441 | |
456 | struct PktCmd *PktCmdP; | 442 | rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n"); |
457 | 443 | /* | |
458 | rio_dprintk (RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n"); | 444 | ** make it look just like a WFLUSH command |
459 | /* | 445 | */ |
460 | ** make it look just like a WFLUSH command | 446 | PktCmdP = (struct PktCmd *) &PacketP->data[0]; |
461 | */ | 447 | |
462 | PktCmdP = ( struct PktCmd * )&PacketP->data[0]; | 448 | WBYTE(PktCmdP->Command, WFLUSH); |
463 | 449 | ||
464 | WBYTE( PktCmdP->Command , WFLUSH ); | 450 | p = PortP->HostPort % (ushort) PORTS_PER_RTA; |
465 | 451 | ||
466 | p = PortP->HostPort % ( ushort )PORTS_PER_RTA; | 452 | /* |
467 | 453 | ** If second block of ports for 16 port RTA, add 8 | |
468 | /* | 454 | ** to index 8-15. |
469 | ** If second block of ports for 16 port RTA, add 8 | 455 | */ |
470 | ** to index 8-15. | 456 | if (PortP->SecondBlock) |
471 | */ | 457 | p += PORTS_PER_RTA; |
472 | if ( PortP->SecondBlock ) | 458 | |
473 | p += PORTS_PER_RTA; | 459 | WBYTE(PktCmdP->PhbNum, p); |
474 | 460 | ||
475 | WBYTE( PktCmdP->PhbNum, p ); | 461 | /* |
476 | 462 | ** to make debuggery easier | |
477 | /* | 463 | */ |
478 | ** to make debuggery easier | 464 | WBYTE(PacketP->data[2], 'W'); |
479 | */ | 465 | WBYTE(PacketP->data[3], 'F'); |
480 | WBYTE( PacketP->data[ 2], 'W' ); | 466 | WBYTE(PacketP->data[4], 'L'); |
481 | WBYTE( PacketP->data[ 3], 'F' ); | 467 | WBYTE(PacketP->data[5], 'U'); |
482 | WBYTE( PacketP->data[ 4], 'L' ); | 468 | WBYTE(PacketP->data[6], 'S'); |
483 | WBYTE( PacketP->data[ 5], 'U' ); | 469 | WBYTE(PacketP->data[7], 'H'); |
484 | WBYTE( PacketP->data[ 6], 'S' ); | 470 | WBYTE(PacketP->data[8], ' '); |
485 | WBYTE( PacketP->data[ 7], 'H' ); | 471 | WBYTE(PacketP->data[9], '0' + PortP->WflushFlag); |
486 | WBYTE( PacketP->data[ 8], ' ' ); | 472 | WBYTE(PacketP->data[10], ' '); |
487 | WBYTE( PacketP->data[ 9], '0'+PortP->WflushFlag ); | 473 | WBYTE(PacketP->data[11], ' '); |
488 | WBYTE( PacketP->data[10], ' ' ); | 474 | WBYTE(PacketP->data[12], '\0'); |
489 | WBYTE( PacketP->data[11], ' ' ); | 475 | |
490 | WBYTE( PacketP->data[12], '\0' ); | 476 | /* |
491 | 477 | ** its two bytes long! | |
492 | /* | 478 | */ |
493 | ** its two bytes long! | 479 | WBYTE(PacketP->len, PKT_CMD_BIT | 2); |
494 | */ | 480 | |
495 | WBYTE( PacketP->len , PKT_CMD_BIT | 2 ); | 481 | /* |
496 | 482 | ** queue it! | |
497 | /* | 483 | */ |
498 | ** queue it! | 484 | if (!(PortP->State & RIO_DELETED)) { |
499 | */ | 485 | add_transmit(PortP); |
500 | if ( !( PortP->State & RIO_DELETED ) ) { | 486 | /* |
501 | add_transmit( PortP ); | 487 | ** Count chars tx'd for port statistics reporting |
502 | /* | 488 | */ |
503 | ** Count chars tx'd for port statistics reporting | 489 | if (PortP->statsGather) |
504 | */ | 490 | PortP->txchars += 2; |
505 | if ( PortP->statsGather ) | 491 | } |
506 | PortP->txchars += 2; | 492 | |
507 | } | 493 | if (--(PortP->WflushFlag) == 0) { |
508 | 494 | PortP->MagicFlags &= ~MAGIC_FLUSH; | |
509 | if ( --( PortP->WflushFlag ) == 0 ) { | 495 | } |
510 | PortP->MagicFlags &= ~MAGIC_FLUSH; | 496 | |
511 | } | 497 | rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag); |
512 | 498 | } | |
513 | rio_dprintk (RIO_DEBUG_INTR, "Wflush count now stands at %d\n", | 499 | if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) { |
514 | PortP->WflushFlag); | 500 | if (PortP->MagicFlags & MAGIC_FLUSH) { |
515 | } | 501 | PortP->MagicFlags |= MORE_OUTPUT_EYGOR; |
516 | if ( PortP->MagicFlags & MORE_OUTPUT_EYGOR ) { | 502 | } else { |
517 | if ( PortP->MagicFlags & MAGIC_FLUSH ) { | 503 | if (!can_add_transmit(&PacketP, PortP)) { |
518 | PortP->MagicFlags |= MORE_OUTPUT_EYGOR; | 504 | rio_spin_unlock(&PortP->portSem); |
519 | } | 505 | continue; |
520 | else { | 506 | } |
521 | if ( !can_add_transmit( &PacketP, PortP ) ) { | 507 | rio_spin_unlock(&PortP->portSem); |
522 | rio_spin_unlock(&PortP->portSem); | 508 | RIOTxEnable((char *) PortP); |
523 | continue; | 509 | rio_spin_lock(&PortP->portSem); |
524 | } | 510 | PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR; |
525 | rio_spin_unlock(&PortP->portSem); | 511 | } |
526 | RIOTxEnable((char *)PortP); | 512 | } |
527 | rio_spin_lock(&PortP->portSem); | 513 | } |
528 | PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR; | 514 | |
529 | } | 515 | |
516 | /* | ||
517 | ** If we can't add anything to the transmit queue, then | ||
518 | ** we need do none of the remaining processing. | ||
519 | */ | ||
520 | if (!can_add_transmit(&PacketP, PortP)) { | ||
521 | rio_spin_unlock(&PortP->portSem); | ||
522 | continue; | ||
523 | } | ||
524 | |||
525 | rio_spin_unlock(&PortP->portSem); | ||
526 | RIOTxEnable((char *) PortP); | ||
527 | } | ||
530 | } | 528 | } |
531 | } | ||
532 | |||
533 | |||
534 | /* | ||
535 | ** If we can't add anything to the transmit queue, then | ||
536 | ** we need do none of the remaining processing. | ||
537 | */ | ||
538 | if (!can_add_transmit( &PacketP, PortP ) ) { | ||
539 | rio_spin_unlock(&PortP->portSem); | ||
540 | continue; | ||
541 | } | ||
542 | |||
543 | rio_spin_unlock(&PortP->portSem); | ||
544 | RIOTxEnable((char *)PortP); | ||
545 | } | ||
546 | } | ||
547 | } | 529 | } |
548 | 530 | ||
549 | /* | 531 | /* |
@@ -551,176 +533,162 @@ int From; | |||
551 | ** NB: Called with the tty locked. The spl from the lockb( ) is passed. | 533 | ** NB: Called with the tty locked. The spl from the lockb( ) is passed. |
552 | ** we return the ttySpl level that we re-locked at. | 534 | ** we return the ttySpl level that we re-locked at. |
553 | */ | 535 | */ |
554 | static void | 536 | static void RIOReceive(p, PortP) |
555 | RIOReceive(p, PortP) | 537 | struct rio_info *p; |
556 | struct rio_info * p; | 538 | struct Port *PortP; |
557 | struct Port * PortP; | ||
558 | { | 539 | { |
559 | struct tty_struct *TtyP; | 540 | struct tty_struct *TtyP; |
560 | register ushort transCount; | 541 | register ushort transCount; |
561 | struct PKT *PacketP; | 542 | struct PKT *PacketP; |
562 | register uint DataCnt; | 543 | register uint DataCnt; |
563 | uchar * ptr; | 544 | uchar *ptr; |
564 | unsigned char *buf; | 545 | unsigned char *buf; |
565 | int copied =0; | 546 | int copied = 0; |
566 | 547 | ||
567 | static int intCount, RxIntCnt; | 548 | static int intCount, RxIntCnt; |
568 | 549 | ||
569 | /* | 550 | /* |
570 | ** The receive data process is to remove packets from the | 551 | ** The receive data process is to remove packets from the |
571 | ** PHB until there aren't any more or the current cblock | 552 | ** PHB until there aren't any more or the current cblock |
572 | ** is full. When this occurs, there will be some left over | 553 | ** is full. When this occurs, there will be some left over |
573 | ** data in the packet, that we must do something with. | 554 | ** data in the packet, that we must do something with. |
574 | ** As we haven't unhooked the packet from the read list | 555 | ** As we haven't unhooked the packet from the read list |
575 | ** yet, we can just leave the packet there, having first | 556 | ** yet, we can just leave the packet there, having first |
576 | ** made a note of how far we got. This means that we need | 557 | ** made a note of how far we got. This means that we need |
577 | ** a pointer per port saying where we start taking the | 558 | ** a pointer per port saying where we start taking the |
578 | ** data from - this will normally be zero, but when we | 559 | ** data from - this will normally be zero, but when we |
579 | ** run out of space it will be set to the offset of the | 560 | ** run out of space it will be set to the offset of the |
580 | ** next byte to copy from the packet data area. The packet | 561 | ** next byte to copy from the packet data area. The packet |
581 | ** length field is decremented by the number of bytes that | 562 | ** length field is decremented by the number of bytes that |
582 | ** we succesfully removed from the packet. When this reaches | 563 | ** we succesfully removed from the packet. When this reaches |
583 | ** zero, we reset the offset pointer to be zero, and free | 564 | ** zero, we reset the offset pointer to be zero, and free |
584 | ** the packet from the front of the queue. | 565 | ** the packet from the front of the queue. |
585 | */ | 566 | */ |
586 | 567 | ||
587 | intCount++; | 568 | intCount++; |
588 | 569 | ||
589 | TtyP = PortP->gs.tty; | 570 | TtyP = PortP->gs.tty; |
590 | if (!TtyP) { | 571 | if (!TtyP) { |
591 | rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: tty is null. \n"); | 572 | rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n"); |
592 | return; | 573 | return; |
593 | } | ||
594 | |||
595 | if (PortP->State & RIO_THROTTLE_RX) { | ||
596 | rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n"); | ||
597 | return; | ||
598 | } | ||
599 | |||
600 | if ( PortP->State & RIO_DELETED ) | ||
601 | { | ||
602 | while ( can_remove_receive( &PacketP, PortP ) ) | ||
603 | { | ||
604 | remove_receive( PortP ); | ||
605 | put_free_end( PortP->HostP, PacketP ); | ||
606 | } | 574 | } |
607 | } | 575 | |
608 | else | 576 | if (PortP->State & RIO_THROTTLE_RX) { |
609 | { | 577 | rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n"); |
610 | /* | 578 | return; |
611 | ** loop, just so long as: | 579 | } |
612 | ** i ) there's some data ( i.e. can_remove_receive ) | 580 | |
613 | ** ii ) we haven't been blocked | 581 | if (PortP->State & RIO_DELETED) { |
614 | ** iii ) there's somewhere to put the data | 582 | while (can_remove_receive(&PacketP, PortP)) { |
615 | ** iv ) we haven't outstayed our welcome | 583 | remove_receive(PortP); |
616 | */ | 584 | put_free_end(PortP->HostP, PacketP); |
617 | transCount = 1; | 585 | } |
618 | while ( can_remove_receive(&PacketP, PortP) | 586 | } else { |
619 | && transCount) | 587 | /* |
620 | { | 588 | ** loop, just so long as: |
589 | ** i ) there's some data ( i.e. can_remove_receive ) | ||
590 | ** ii ) we haven't been blocked | ||
591 | ** iii ) there's somewhere to put the data | ||
592 | ** iv ) we haven't outstayed our welcome | ||
593 | */ | ||
594 | transCount = 1; | ||
595 | while (can_remove_receive(&PacketP, PortP) | ||
596 | && transCount) { | ||
621 | #ifdef STATS | 597 | #ifdef STATS |
622 | PortP->Stat.RxIntCnt++; | 598 | PortP->Stat.RxIntCnt++; |
623 | #endif /* STATS */ | 599 | #endif /* STATS */ |
624 | RxIntCnt++; | 600 | RxIntCnt++; |
625 | 601 | ||
626 | /* | 602 | /* |
627 | ** check that it is not a command! | 603 | ** check that it is not a command! |
628 | */ | 604 | */ |
629 | if ( PacketP->len & PKT_CMD_BIT ) { | 605 | if (PacketP->len & PKT_CMD_BIT) { |
630 | rio_dprintk (RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n"); | 606 | rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n"); |
631 | /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */ | 607 | /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */ |
632 | rio_dprintk (RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit); | 608 | rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit); |
633 | rio_dprintk (RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port); | 609 | rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port); |
634 | rio_dprintk (RIO_DEBUG_INTR, " src_unit = %d\n", PacketP->src_unit); | 610 | rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", PacketP->src_unit); |
635 | rio_dprintk (RIO_DEBUG_INTR, " src_port = %d\n", PacketP->src_port); | 611 | rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", PacketP->src_port); |
636 | rio_dprintk (RIO_DEBUG_INTR, " len = %d\n", PacketP->len); | 612 | rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", PacketP->len); |
637 | rio_dprintk (RIO_DEBUG_INTR, " control = %d\n", PacketP->control); | 613 | rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", PacketP->control); |
638 | rio_dprintk (RIO_DEBUG_INTR, " csum = %d\n", PacketP->csum); | 614 | rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", PacketP->csum); |
639 | rio_dprintk (RIO_DEBUG_INTR, " data bytes: "); | 615 | rio_dprintk(RIO_DEBUG_INTR, " data bytes: "); |
640 | for ( DataCnt=0; DataCnt<PKT_MAX_DATA_LEN; DataCnt++ ) | 616 | for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++) |
641 | rio_dprintk (RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]); | 617 | rio_dprintk(RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]); |
642 | remove_receive( PortP ); | 618 | remove_receive(PortP); |
643 | put_free_end( PortP->HostP, PacketP ); | 619 | put_free_end(PortP->HostP, PacketP); |
644 | continue; /* with next packet */ | 620 | continue; /* with next packet */ |
645 | } | 621 | } |
646 | 622 | ||
647 | /* | 623 | /* |
648 | ** How many characters can we move 'upstream' ? | 624 | ** How many characters can we move 'upstream' ? |
649 | ** | 625 | ** |
650 | ** Determine the minimum of the amount of data | 626 | ** Determine the minimum of the amount of data |
651 | ** available and the amount of space in which to | 627 | ** available and the amount of space in which to |
652 | ** put it. | 628 | ** put it. |
653 | ** | 629 | ** |
654 | ** 1. Get the packet length by masking 'len' | 630 | ** 1. Get the packet length by masking 'len' |
655 | ** for only the length bits. | 631 | ** for only the length bits. |
656 | ** 2. Available space is [buffer size] - [space used] | 632 | ** 2. Available space is [buffer size] - [space used] |
657 | ** | 633 | ** |
658 | ** Transfer count is the minimum of packet length | 634 | ** Transfer count is the minimum of packet length |
659 | ** and available space. | 635 | ** and available space. |
660 | */ | 636 | */ |
661 | 637 | ||
662 | transCount = tty_buffer_request_room(TtyP, PacketP->len & PKT_LEN_MASK); | 638 | transCount = tty_buffer_request_room(TtyP, PacketP->len & PKT_LEN_MASK); |
663 | rio_dprintk (RIO_DEBUG_REC, "port %d: Copy %d bytes\n", | 639 | rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount); |
664 | PortP->PortNum, transCount); | 640 | /* |
665 | /* | 641 | ** To use the following 'kkprintfs' for debugging - change the '#undef' |
666 | ** To use the following 'kkprintfs' for debugging - change the '#undef' | 642 | ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the |
667 | ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the | 643 | ** driver). |
668 | ** driver). | 644 | */ |
669 | */ | ||
670 | #undef ___DEBUG_IT___ | 645 | #undef ___DEBUG_IT___ |
671 | #ifdef ___DEBUG_IT___ | 646 | #ifdef ___DEBUG_IT___ |
672 | kkprintf("I:%d R:%d P:%d Q:%d C:%d F:%x ", | 647 | kkprintf("I:%d R:%d P:%d Q:%d C:%d F:%x ", intCount, RxIntCnt, PortP->PortNum, TtyP->rxqueue.count, transCount, TtyP->flags); |
673 | intCount, | ||
674 | RxIntCnt, | ||
675 | PortP->PortNum, | ||
676 | TtyP->rxqueue.count, | ||
677 | transCount, | ||
678 | TtyP->flags ); | ||
679 | #endif | 648 | #endif |
680 | ptr = (uchar *) PacketP->data + PortP->RxDataStart; | 649 | ptr = (uchar *) PacketP->data + PortP->RxDataStart; |
681 | 650 | ||
682 | tty_prepare_flip_string(TtyP, &buf, transCount); | 651 | tty_prepare_flip_string(TtyP, &buf, transCount); |
683 | rio_memcpy_fromio (buf, ptr, transCount); | 652 | rio_memcpy_fromio(buf, ptr, transCount); |
684 | #ifdef STATS | 653 | #ifdef STATS |
685 | /* | 654 | /* |
686 | ** keep a count for statistical purposes | 655 | ** keep a count for statistical purposes |
687 | */ | 656 | */ |
688 | PortP->Stat.RxCharCnt += transCount; | 657 | PortP->Stat.RxCharCnt += transCount; |
689 | #endif | 658 | #endif |
690 | PortP->RxDataStart += transCount; | 659 | PortP->RxDataStart += transCount; |
691 | PacketP->len -= transCount; | 660 | PacketP->len -= transCount; |
692 | copied += transCount; | 661 | copied += transCount; |
693 | 662 | ||
694 | 663 | ||
695 | #ifdef ___DEBUG_IT___ | 664 | #ifdef ___DEBUG_IT___ |
696 | kkprintf("T:%d L:%d\n", DataCnt, PacketP->len ); | 665 | kkprintf("T:%d L:%d\n", DataCnt, PacketP->len); |
697 | #endif | 666 | #endif |
698 | 667 | ||
699 | if ( PacketP->len == 0 ) | 668 | if (PacketP->len == 0) { |
700 | { | ||
701 | /* | 669 | /* |
702 | ** If we have emptied the packet, then we can | 670 | ** If we have emptied the packet, then we can |
703 | ** free it, and reset the start pointer for | 671 | ** free it, and reset the start pointer for |
704 | ** the next packet. | 672 | ** the next packet. |
705 | */ | 673 | */ |
706 | remove_receive( PortP ); | 674 | remove_receive(PortP); |
707 | put_free_end( PortP->HostP, PacketP ); | 675 | put_free_end(PortP->HostP, PacketP); |
708 | PortP->RxDataStart = 0; | 676 | PortP->RxDataStart = 0; |
709 | #ifdef STATS | 677 | #ifdef STATS |
710 | /* | 678 | /* |
711 | ** more lies ( oops, I mean statistics ) | 679 | ** more lies ( oops, I mean statistics ) |
712 | */ | 680 | */ |
713 | PortP->Stat.RxPktCnt++; | 681 | PortP->Stat.RxPktCnt++; |
714 | #endif /* STATS */ | 682 | #endif /* STATS */ |
715 | } | 683 | } |
684 | } | ||
685 | } | ||
686 | if (copied) { | ||
687 | rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied); | ||
688 | tty_flip_buffer_push(TtyP); | ||
716 | } | 689 | } |
717 | } | ||
718 | if (copied) { | ||
719 | rio_dprintk (RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied); | ||
720 | tty_flip_buffer_push (TtyP); | ||
721 | } | ||
722 | 690 | ||
723 | return; | 691 | return; |
724 | } | 692 | } |
725 | 693 | ||
726 | #ifdef FUTURE_RELEASE | 694 | #ifdef FUTURE_RELEASE |
@@ -728,221 +696,210 @@ struct Port * PortP; | |||
728 | ** The proc routine called by the line discipline to do the work for it. | 696 | ** The proc routine called by the line discipline to do the work for it. |
729 | ** The proc routine works hand in hand with the interrupt routine. | 697 | ** The proc routine works hand in hand with the interrupt routine. |
730 | */ | 698 | */ |
731 | int | 699 | int riotproc(p, tp, cmd, port) |
732 | riotproc(p, tp, cmd, port) | 700 | struct rio_info *p; |
733 | struct rio_info * p; | ||
734 | register struct ttystatics *tp; | 701 | register struct ttystatics *tp; |
735 | int cmd; | 702 | int cmd; |
736 | int port; | 703 | int port; |
737 | { | 704 | { |
738 | register struct Port *PortP; | 705 | register struct Port *PortP; |
739 | int SysPort; | 706 | int SysPort; |
740 | struct PKT *PacketP; | 707 | struct PKT *PacketP; |
741 | 708 | ||
742 | SysPort = port; /* Believe me, it works. */ | 709 | SysPort = port; /* Believe me, it works. */ |
743 | 710 | ||
744 | if ( SysPort < 0 || SysPort >= RIO_PORTS ) { | 711 | if (SysPort < 0 || SysPort >= RIO_PORTS) { |
745 | rio_dprintk (RIO_DEBUG_INTR, "Illegal port %d derived from TTY in riotproc()\n",SysPort); | 712 | rio_dprintk(RIO_DEBUG_INTR, "Illegal port %d derived from TTY in riotproc()\n", SysPort); |
746 | return 0; | 713 | return 0; |
747 | } | 714 | } |
748 | PortP = p->RIOPortp[SysPort]; | 715 | PortP = p->RIOPortp[SysPort]; |
749 | 716 | ||
750 | if ((uint)PortP->PhbP < (uint)PortP->Caddr || | 717 | if ((uint) PortP->PhbP < (uint) PortP->Caddr || (uint) PortP->PhbP >= (uint) PortP->Caddr + SIXTY_FOUR_K) { |
751 | (uint)PortP->PhbP >= (uint)PortP->Caddr+SIXTY_FOUR_K ) { | 718 | rio_dprintk(RIO_DEBUG_INTR, "RIO: NULL or BAD PhbP on sys port %d in proc routine\n", SysPort); |
752 | rio_dprintk (RIO_DEBUG_INTR, "RIO: NULL or BAD PhbP on sys port %d in proc routine\n", | 719 | rio_dprintk(RIO_DEBUG_INTR, " PortP = 0x%x\n", PortP); |
753 | SysPort); | 720 | rio_dprintk(RIO_DEBUG_INTR, " PortP->PhbP = 0x%x\n", PortP->PhbP); |
754 | rio_dprintk (RIO_DEBUG_INTR, " PortP = 0x%x\n",PortP); | 721 | rio_dprintk(RIO_DEBUG_INTR, " PortP->Caddr = 0x%x\n", PortP->PhbP); |
755 | rio_dprintk (RIO_DEBUG_INTR, " PortP->PhbP = 0x%x\n",PortP->PhbP); | 722 | rio_dprintk(RIO_DEBUG_INTR, " PortP->HostPort = 0x%x\n", PortP->HostPort); |
756 | rio_dprintk (RIO_DEBUG_INTR, " PortP->Caddr = 0x%x\n",PortP->PhbP); | ||
757 | rio_dprintk (RIO_DEBUG_INTR, " PortP->HostPort = 0x%x\n",PortP->HostPort); | ||
758 | return 0; | 723 | return 0; |
759 | } | 724 | } |
760 | 725 | ||
761 | switch(cmd) { | 726 | switch (cmd) { |
762 | case T_WFLUSH: | 727 | case T_WFLUSH: |
763 | rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH\n"); | 728 | rio_dprintk(RIO_DEBUG_INTR, "T_WFLUSH\n"); |
729 | /* | ||
730 | ** Because of the spooky way the RIO works, we don't need | ||
731 | ** to issue a flush command on any of the SET*F commands, | ||
732 | ** as that causes trouble with getty and login, which issue | ||
733 | ** these commands to incur a READ flush, and rely on the fact | ||
734 | ** that the line discipline does a wait for drain for them. | ||
735 | ** As the rio doesn't wait for drain, the write flush would | ||
736 | ** destroy the Password: prompt. This isn't very friendly, so | ||
737 | ** here we only issue a WFLUSH command if we are in the interrupt | ||
738 | ** routine, or we aren't executing a SET*F command. | ||
739 | */ | ||
740 | if (PortP->HostP->InIntr || !PortP->FlushCmdBodge) { | ||
764 | /* | 741 | /* |
765 | ** Because of the spooky way the RIO works, we don't need | 742 | ** form a wflush packet - 1 byte long, no data |
766 | ** to issue a flush command on any of the SET*F commands, | 743 | */ |
767 | ** as that causes trouble with getty and login, which issue | 744 | if (PortP->State & RIO_DELETED) { |
768 | ** these commands to incur a READ flush, and rely on the fact | 745 | rio_dprintk(RIO_DEBUG_INTR, "WFLUSH on deleted RTA\n"); |
769 | ** that the line discipline does a wait for drain for them. | 746 | } else { |
770 | ** As the rio doesn't wait for drain, the write flush would | 747 | if (RIOPreemptiveCmd(p, PortP, WFLUSH) == RIO_FAIL) { |
771 | ** destroy the Password: prompt. This isn't very friendly, so | 748 | rio_dprintk(RIO_DEBUG_INTR, "T_WFLUSH Command failed\n"); |
772 | ** here we only issue a WFLUSH command if we are in the interrupt | 749 | } else |
773 | ** routine, or we aren't executing a SET*F command. | 750 | rio_dprintk(RIO_DEBUG_INTR, "T_WFLUSH Command\n"); |
774 | */ | ||
775 | if ( PortP->HostP->InIntr || !PortP->FlushCmdBodge ) { | ||
776 | /* | ||
777 | ** form a wflush packet - 1 byte long, no data | ||
778 | */ | ||
779 | if ( PortP->State & RIO_DELETED ) { | ||
780 | rio_dprintk (RIO_DEBUG_INTR, "WFLUSH on deleted RTA\n"); | ||
781 | } | ||
782 | else { | ||
783 | if ( RIOPreemptiveCmd(p, PortP, WFLUSH ) == RIO_FAIL ) { | ||
784 | rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command failed\n"); | ||
785 | } | ||
786 | else | ||
787 | rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command\n"); | ||
788 | } | ||
789 | /* | ||
790 | ** WFLUSH operation - flush the data! | ||
791 | */ | ||
792 | PortP->TxBufferIn = PortP->TxBufferOut = 0; | ||
793 | } | ||
794 | else { | ||
795 | rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command ignored\n"); | ||
796 | } | 751 | } |
797 | /* | 752 | /* |
798 | ** sort out the line discipline | 753 | ** WFLUSH operation - flush the data! |
799 | */ | 754 | */ |
800 | if (PortP->CookMode == COOK_WELL) | 755 | PortP->TxBufferIn = PortP->TxBufferOut = 0; |
801 | goto start; | 756 | } else { |
802 | break; | 757 | rio_dprintk(RIO_DEBUG_INTR, "T_WFLUSH Command ignored\n"); |
803 | 758 | } | |
804 | case T_RESUME: | 759 | /* |
805 | rio_dprintk (RIO_DEBUG_INTR, "T_RESUME\n"); | 760 | ** sort out the line discipline |
806 | /* | 761 | */ |
807 | ** send pre-emptive resume packet | 762 | if (PortP->CookMode == COOK_WELL) |
808 | */ | 763 | goto start; |
809 | if ( PortP->State & RIO_DELETED ) { | 764 | break; |
810 | rio_dprintk (RIO_DEBUG_INTR, "RESUME on deleted RTA\n"); | 765 | |
766 | case T_RESUME: | ||
767 | rio_dprintk(RIO_DEBUG_INTR, "T_RESUME\n"); | ||
768 | /* | ||
769 | ** send pre-emptive resume packet | ||
770 | */ | ||
771 | if (PortP->State & RIO_DELETED) { | ||
772 | rio_dprintk(RIO_DEBUG_INTR, "RESUME on deleted RTA\n"); | ||
773 | } else { | ||
774 | if (RIOPreemptiveCmd(p, PortP, RESUME) == RIO_FAIL) { | ||
775 | rio_dprintk(RIO_DEBUG_INTR, "T_RESUME Command failed\n"); | ||
811 | } | 776 | } |
812 | else { | 777 | } |
813 | if ( RIOPreemptiveCmd(p, PortP, RESUME ) == RIO_FAIL ) { | 778 | /* |
814 | rio_dprintk (RIO_DEBUG_INTR, "T_RESUME Command failed\n"); | 779 | ** and re-start the sender software! |
815 | } | 780 | */ |
781 | if (PortP->CookMode == COOK_WELL) | ||
782 | goto start; | ||
783 | break; | ||
784 | |||
785 | case T_TIME: | ||
786 | rio_dprintk(RIO_DEBUG_INTR, "T_TIME\n"); | ||
787 | /* | ||
788 | ** T_TIME is called when xDLY is set in oflags and | ||
789 | ** the line discipline timeout has expired. It's | ||
790 | ** function in life is to clear the TIMEOUT flag | ||
791 | ** and to re-start output to the port. | ||
792 | */ | ||
793 | /* | ||
794 | ** Fall through and re-start output | ||
795 | */ | ||
796 | case T_OUTPUT: | ||
797 | start: | ||
798 | if (PortP->MagicFlags & MAGIC_FLUSH) { | ||
799 | PortP->MagicFlags |= MORE_OUTPUT_EYGOR; | ||
800 | return 0; | ||
801 | } | ||
802 | RIOTxEnable((char *) PortP); | ||
803 | PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR; | ||
804 | /*rio_dprint(RIO_DEBUG_INTR, PortP,DBG_PROC,"T_OUTPUT finished\n"); */ | ||
805 | break; | ||
806 | |||
807 | case T_SUSPEND: | ||
808 | rio_dprintk(RIO_DEBUG_INTR, "T_SUSPEND\n"); | ||
809 | /* | ||
810 | ** send a suspend pre-emptive packet. | ||
811 | */ | ||
812 | if (PortP->State & RIO_DELETED) { | ||
813 | rio_dprintk(RIO_DEBUG_INTR, "SUSPEND deleted RTA\n"); | ||
814 | } else { | ||
815 | if (RIOPreemptiveCmd(p, PortP, SUSPEND) == RIO_FAIL) { | ||
816 | rio_dprintk(RIO_DEBUG_INTR, "T_SUSPEND Command failed\n"); | ||
816 | } | 817 | } |
817 | /* | 818 | } |
818 | ** and re-start the sender software! | 819 | /* |
819 | */ | 820 | ** done! |
820 | if (PortP->CookMode == COOK_WELL) | 821 | */ |
821 | goto start; | 822 | break; |
822 | break; | 823 | |
823 | 824 | case T_BLOCK: | |
824 | case T_TIME: | 825 | rio_dprintk(RIO_DEBUG_INTR, "T_BLOCK\n"); |
825 | rio_dprintk (RIO_DEBUG_INTR, "T_TIME\n"); | 826 | break; |
826 | /* | 827 | |
827 | ** T_TIME is called when xDLY is set in oflags and | 828 | case T_RFLUSH: |
828 | ** the line discipline timeout has expired. It's | 829 | rio_dprintk(RIO_DEBUG_INTR, "T_RFLUSH\n"); |
829 | ** function in life is to clear the TIMEOUT flag | 830 | if (PortP->State & RIO_DELETED) { |
830 | ** and to re-start output to the port. | 831 | rio_dprintk(RIO_DEBUG_INTR, "RFLUSH on deleted RTA\n"); |
831 | */ | 832 | PortP->RxDataStart = 0; |
832 | /* | 833 | } else { |
833 | ** Fall through and re-start output | 834 | if (RIOPreemptiveCmd(p, PortP, RFLUSH) == RIO_FAIL) { |
834 | */ | 835 | rio_dprintk(RIO_DEBUG_INTR, "T_RFLUSH Command failed\n"); |
835 | case T_OUTPUT: | ||
836 | start: | ||
837 | if ( PortP->MagicFlags & MAGIC_FLUSH ) { | ||
838 | PortP->MagicFlags |= MORE_OUTPUT_EYGOR; | ||
839 | return 0; | 836 | return 0; |
840 | } | 837 | } |
841 | RIOTxEnable((char *)PortP); | 838 | PortP->RxDataStart = 0; |
842 | PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR; | 839 | while (can_remove_receive(&PacketP, PortP)) { |
843 | /*rio_dprint(RIO_DEBUG_INTR, PortP,DBG_PROC,"T_OUTPUT finished\n");*/ | 840 | remove_receive(PortP); |
844 | break; | 841 | ShowPacket(DBG_PROC, PacketP); |
845 | 842 | put_free_end(PortP->HostP, PacketP); | |
846 | case T_SUSPEND: | ||
847 | rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND\n"); | ||
848 | /* | ||
849 | ** send a suspend pre-emptive packet. | ||
850 | */ | ||
851 | if ( PortP->State & RIO_DELETED ) { | ||
852 | rio_dprintk (RIO_DEBUG_INTR, "SUSPEND deleted RTA\n"); | ||
853 | } | ||
854 | else { | ||
855 | if ( RIOPreemptiveCmd(p, PortP, SUSPEND ) == RIO_FAIL ) { | ||
856 | rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND Command failed\n"); | ||
857 | } | ||
858 | } | 843 | } |
859 | /* | 844 | if (PortP->PhbP->handshake == PHB_HANDSHAKE_SET) { |
860 | ** done! | 845 | /* |
861 | */ | 846 | ** MAGIC! |
862 | break; | 847 | */ |
863 | 848 | rio_dprintk(RIO_DEBUG_INTR, "Set receive handshake bit\n"); | |
864 | case T_BLOCK: | 849 | PortP->PhbP->handshake |= PHB_HANDSHAKE_RESET; |
865 | rio_dprintk (RIO_DEBUG_INTR, "T_BLOCK\n"); | ||
866 | break; | ||
867 | |||
868 | case T_RFLUSH: | ||
869 | rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH\n"); | ||
870 | if ( PortP->State & RIO_DELETED ) { | ||
871 | rio_dprintk (RIO_DEBUG_INTR, "RFLUSH on deleted RTA\n"); | ||
872 | PortP->RxDataStart = 0; | ||
873 | } | ||
874 | else { | ||
875 | if ( RIOPreemptiveCmd( p, PortP, RFLUSH ) == RIO_FAIL ) { | ||
876 | rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH Command failed\n"); | ||
877 | return 0; | ||
878 | } | ||
879 | PortP->RxDataStart = 0; | ||
880 | while ( can_remove_receive(&PacketP, PortP) ) { | ||
881 | remove_receive(PortP); | ||
882 | ShowPacket(DBG_PROC, PacketP ); | ||
883 | put_free_end(PortP->HostP, PacketP ); | ||
884 | } | ||
885 | if ( PortP->PhbP->handshake == PHB_HANDSHAKE_SET ) { | ||
886 | /* | ||
887 | ** MAGIC! | ||
888 | */ | ||
889 | rio_dprintk (RIO_DEBUG_INTR, "Set receive handshake bit\n"); | ||
890 | PortP->PhbP->handshake |= PHB_HANDSHAKE_RESET; | ||
891 | } | ||
892 | } | ||
893 | break; | ||
894 | /* FALLTHROUGH */ | ||
895 | case T_UNBLOCK: | ||
896 | rio_dprintk (RIO_DEBUG_INTR, "T_UNBLOCK\n"); | ||
897 | /* | ||
898 | ** If there is any data to receive set a timeout to service it. | ||
899 | */ | ||
900 | RIOReceive(p, PortP); | ||
901 | break; | ||
902 | |||
903 | case T_BREAK: | ||
904 | rio_dprintk (RIO_DEBUG_INTR, "T_BREAK\n"); | ||
905 | /* | ||
906 | ** Send a break command. For Sys V | ||
907 | ** this is a timed break, so we | ||
908 | ** send a SBREAK[time] packet | ||
909 | */ | ||
910 | /* | ||
911 | ** Build a BREAK command | ||
912 | */ | ||
913 | if ( PortP->State & RIO_DELETED ) { | ||
914 | rio_dprintk (RIO_DEBUG_INTR, "BREAK on deleted RTA\n"); | ||
915 | } | 850 | } |
916 | else { | 851 | } |
917 | if (RIOShortCommand(PortP,SBREAK,2, | 852 | break; |
918 | p->RIOConf.BreakInterval)==RIO_FAIL) { | 853 | /* FALLTHROUGH */ |
919 | rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); | 854 | case T_UNBLOCK: |
920 | } | 855 | rio_dprintk(RIO_DEBUG_INTR, "T_UNBLOCK\n"); |
856 | /* | ||
857 | ** If there is any data to receive set a timeout to service it. | ||
858 | */ | ||
859 | RIOReceive(p, PortP); | ||
860 | break; | ||
861 | |||
862 | case T_BREAK: | ||
863 | rio_dprintk(RIO_DEBUG_INTR, "T_BREAK\n"); | ||
864 | /* | ||
865 | ** Send a break command. For Sys V | ||
866 | ** this is a timed break, so we | ||
867 | ** send a SBREAK[time] packet | ||
868 | */ | ||
869 | /* | ||
870 | ** Build a BREAK command | ||
871 | */ | ||
872 | if (PortP->State & RIO_DELETED) { | ||
873 | rio_dprintk(RIO_DEBUG_INTR, "BREAK on deleted RTA\n"); | ||
874 | } else { | ||
875 | if (RIOShortCommand(PortP, SBREAK, 2, p->RIOConf.BreakInterval) == RIO_FAIL) { | ||
876 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); | ||
921 | } | 877 | } |
922 | 878 | } | |
923 | /* | 879 | |
924 | ** done! | 880 | /* |
925 | */ | 881 | ** done! |
926 | break; | 882 | */ |
927 | 883 | break; | |
928 | case T_INPUT: | 884 | |
929 | rio_dprintk (RIO_DEBUG_INTR, "Proc T_INPUT called - I don't know what to do!\n"); | 885 | case T_INPUT: |
930 | break; | 886 | rio_dprintk(RIO_DEBUG_INTR, "Proc T_INPUT called - I don't know what to do!\n"); |
931 | case T_PARM: | 887 | break; |
932 | rio_dprintk (RIO_DEBUG_INTR, "Proc T_PARM called - I don't know what to do!\n"); | 888 | case T_PARM: |
933 | break; | 889 | rio_dprintk(RIO_DEBUG_INTR, "Proc T_PARM called - I don't know what to do!\n"); |
934 | 890 | break; | |
935 | case T_SWTCH: | 891 | |
936 | rio_dprintk (RIO_DEBUG_INTR, "Proc T_SWTCH called - I don't know what to do!\n"); | 892 | case T_SWTCH: |
937 | break; | 893 | rio_dprintk(RIO_DEBUG_INTR, "Proc T_SWTCH called - I don't know what to do!\n"); |
938 | 894 | break; | |
939 | default: | 895 | |
940 | rio_dprintk (RIO_DEBUG_INTR, "Proc UNKNOWN command %d\n",cmd); | 896 | default: |
897 | rio_dprintk(RIO_DEBUG_INTR, "Proc UNKNOWN command %d\n", cmd); | ||
941 | } | 898 | } |
942 | /* | 899 | /* |
943 | ** T_OUTPUT returns without passing through this point! | 900 | ** T_OUTPUT returns without passing through this point! |
944 | */ | 901 | */ |
945 | /*rio_dprint(RIO_DEBUG_INTR, PortP,DBG_PROC,"riotproc done\n");*/ | 902 | /*rio_dprint(RIO_DEBUG_INTR, PortP,DBG_PROC,"riotproc done\n"); */ |
946 | return(0); | 903 | return (0); |
947 | } | 904 | } |
948 | #endif | 905 | #endif |