aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/rio/riointr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/rio/riointr.c')
-rw-r--r--drivers/char/rio/riointr.c1505
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";
88static void RIOReceive(struct rio_info *, struct Port *); 88static void RIOReceive(struct rio_info *, struct Port *);
89 89
90 90
91static char *firstchars (char *p, int nch) 91static 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 */
104void 104void RIOTxEnable(en)
105RIOTxEnable(en) 105char *en;
106char * 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*/
192static int RupIntr; 186static int RupIntr;
193static int RxIntr; 187static int RxIntr;
194static int TxIntr; 188static int TxIntr;
195void 189void RIOServiceHost(p, HostP, From)
196RIOServiceHost(p, HostP, From) 190struct rio_info *p;
197struct rio_info * p;
198struct Host *HostP; 191struct Host *HostP;
199int From; 192int 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*/
554static void 536static void RIOReceive(p, PortP)
555RIOReceive(p, PortP) 537struct rio_info *p;
556struct rio_info * p; 538struct Port *PortP;
557struct 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*/
731int 699int riotproc(p, tp, cmd, port)
732riotproc(p, tp, cmd, port) 700struct rio_info *p;
733struct rio_info * p;
734register struct ttystatics *tp; 701register struct ttystatics *tp;
735int cmd; 702int cmd;
736int port; 703int 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:
836start:
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