1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <linux/module.h>
34#include <linux/slab.h>
35#include <linux/errno.h>
36#include <linux/tty.h>
37#include <linux/tty_flip.h>
38#include <asm/io.h>
39#include <asm/system.h>
40#include <asm/string.h>
41#include <asm/uaccess.h>
42
43#include <linux/termios.h>
44#include <linux/serial.h>
45
46#include <linux/generic_serial.h>
47
48#include <linux/delay.h>
49
50#include "linux_compat.h"
51#include "rio_linux.h"
52#include "pkt.h"
53#include "daemon.h"
54#include "rio.h"
55#include "riospace.h"
56#include "cmdpkt.h"
57#include "map.h"
58#include "rup.h"
59#include "port.h"
60#include "riodrvr.h"
61#include "rioinfo.h"
62#include "func.h"
63#include "errors.h"
64#include "pci.h"
65
66#include "parmmap.h"
67#include "unixrup.h"
68#include "board.h"
69#include "host.h"
70#include "phb.h"
71#include "link.h"
72#include "cmdblk.h"
73#include "route.h"
74#include "cirrus.h"
75#include "rioioctl.h"
76
77
78static void RIOReceive(struct rio_info *, struct Port *);
79
80
81static char *firstchars(char *p, int nch)
82{
83 static char buf[2][128];
84 static int t = 0;
85 t = !t;
86 memcpy(buf[t], p, nch);
87 buf[t][nch] = 0;
88 return buf[t];
89}
90
91
92#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask))
93
94void RIOTxEnable(char *en)
95{
96 struct Port *PortP;
97 struct rio_info *p;
98 struct tty_struct *tty;
99 int c;
100 struct PKT __iomem *PacketP;
101 unsigned long flags;
102
103 PortP = (struct Port *) en;
104 p = (struct rio_info *) PortP->p;
105 tty = PortP->gs.port.tty;
106
107
108 rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt);
109
110 if (!PortP->gs.xmit_cnt)
111 return;
112
113
114
115
116
117
118
119
120 rio_spin_lock_irqsave(&PortP->portSem, flags);
121
122 while (can_add_transmit(&PacketP, PortP)) {
123 c = PortP->gs.xmit_cnt;
124 if (c > PKT_MAX_DATA_LEN)
125 c = PKT_MAX_DATA_LEN;
126
127
128 if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail)
129 c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail;
130
131 {
132 int t;
133 t = (c > 10) ? 10 : c;
134
135 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));
136 }
137
138
139 if (c == 0)
140 break;
141
142 rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
143
144
145 writeb(c, &(PacketP->len));
146 if (!(PortP->State & RIO_DELETED)) {
147 add_transmit(PortP);
148
149
150
151 if (PortP->statsGather)
152 PortP->txchars += c;
153 }
154 PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1);
155 PortP->gs.xmit_cnt -= c;
156 }
157
158 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
159
160 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
161 tty_wakeup(PortP->gs.port.tty);
162
163}
164
165
166
167
168
169
170static int RupIntr;
171static int RxIntr;
172static int TxIntr;
173
174void RIOServiceHost(struct rio_info *p, struct Host *HostP)
175{
176 rio_spin_lock(&HostP->HostLock);
177 if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
178 static int t = 0;
179 rio_spin_unlock(&HostP->HostLock);
180 if ((t++ % 200) == 0)
181 rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags);
182 return;
183 }
184 rio_spin_unlock(&HostP->HostLock);
185
186 if (readw(&HostP->ParmMapP->rup_intr)) {
187 writew(0, &HostP->ParmMapP->rup_intr);
188 p->RIORupCount++;
189 RupIntr++;
190 rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts);
191 RIOPollHostCommands(p, HostP);
192 }
193
194 if (readw(&HostP->ParmMapP->rx_intr)) {
195 int port;
196
197 writew(0, &HostP->ParmMapP->rx_intr);
198 p->RIORxCount++;
199 RxIntr++;
200
201 rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts);
202
203
204
205
206
207
208
209 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
210 struct Port *PortP = p->RIOPortp[port];
211 struct tty_struct *ttyP;
212 struct PKT __iomem *PacketP;
213
214
215
216
217
218
219 if (!PortP->Mapped) {
220 port += 7;
221 continue;
222 }
223
224
225
226
227
228 if (PortP->HostP != HostP) {
229 port += 7;
230 continue;
231 }
232
233
234
235
236 if (!(PortP->PortState & PORT_ISOPEN)) {
237 continue;
238 }
239
240
241
242
243
244 ttyP = PortP->gs.port.tty;
245
246
247
248
249 rio_spin_lock(&PortP->portSem);
250
251
252
253
254 if (can_remove_receive(&PacketP, PortP))
255 RIOReceive(p, PortP);
256
257
258
259
260
261
262 if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) {
263
264
265
266
267 rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n");
268 writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
269 }
270 rio_spin_unlock(&PortP->portSem);
271 }
272 }
273
274 if (readw(&HostP->ParmMapP->tx_intr)) {
275 int port;
276
277 writew(0, &HostP->ParmMapP->tx_intr);
278
279 p->RIOTxCount++;
280 TxIntr++;
281 rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts);
282
283
284
285
286
287
288 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
289 struct Port *PortP = p->RIOPortp[port];
290 struct tty_struct *ttyP;
291 struct PKT __iomem *PacketP;
292
293
294
295
296
297 if (!PortP->Mapped) {
298 port += 7;
299 continue;
300 }
301
302
303
304
305
306 if (PortP->HostP != HostP) {
307 port += 7;
308 continue;
309 }
310
311
312
313
314 if (!(PortP->PortState & PORT_ISOPEN)) {
315 continue;
316 }
317
318 rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
319
320
321
322 rio_spin_lock(&PortP->portSem);
323
324
325
326
327
328 if (!can_add_transmit(&PacketP, PortP)) {
329 rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
330 rio_spin_unlock(&PortP->portSem);
331 continue;
332 }
333
334
335
336
337
338 ttyP = PortP->gs.port.tty;
339
340 if (!ttyP) {
341 rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n");
342 rio_spin_unlock(&PortP->portSem);
343 continue;
344 }
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383 if (PortP->MagicFlags) {
384 if (PortP->MagicFlags & MAGIC_REBOOT) {
385
386
387
388
389
390
391
392
393
394
395
396
397 PortP->InUse = NOT_INUSE;
398
399 rio_spin_unlock(&PortP->portSem);
400 if (RIOParam(PortP, RIOC_OPEN, ((PortP->Cor2Copy & (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) == (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL)
401 continue;
402 rio_spin_lock(&PortP->portSem);
403 PortP->MagicFlags &= ~MAGIC_REBOOT;
404 }
405
406
407
408
409
410 if (PortP->WflushFlag) {
411 rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
412
413 if (PortP->InUse)
414 rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
415 }
416
417 while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) {
418 int p;
419 struct PktCmd __iomem *PktCmdP;
420
421 rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
422
423
424
425 PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
426
427 writeb(RIOC_WFLUSH, &PktCmdP->Command);
428
429 p = PortP->HostPort % (u16) PORTS_PER_RTA;
430
431
432
433
434
435 if (PortP->SecondBlock)
436 p += PORTS_PER_RTA;
437
438 writeb(p, &PktCmdP->PhbNum);
439
440
441
442
443 writeb('W', &PacketP->data[2]);
444 writeb('F', &PacketP->data[3]);
445 writeb('L', &PacketP->data[4]);
446 writeb('U', &PacketP->data[5]);
447 writeb('S', &PacketP->data[6]);
448 writeb('H', &PacketP->data[7]);
449 writeb(' ', &PacketP->data[8]);
450 writeb('0' + PortP->WflushFlag, &PacketP->data[9]);
451 writeb(' ', &PacketP->data[10]);
452 writeb(' ', &PacketP->data[11]);
453 writeb('\0', &PacketP->data[12]);
454
455
456
457
458 writeb(PKT_CMD_BIT | 2, &PacketP->len);
459
460
461
462
463 if (!(PortP->State & RIO_DELETED)) {
464 add_transmit(PortP);
465
466
467
468 if (PortP->statsGather)
469 PortP->txchars += 2;
470 }
471
472 if (--(PortP->WflushFlag) == 0) {
473 PortP->MagicFlags &= ~MAGIC_FLUSH;
474 }
475
476 rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag);
477 }
478 if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) {
479 if (PortP->MagicFlags & MAGIC_FLUSH) {
480 PortP->MagicFlags |= MORE_OUTPUT_EYGOR;
481 } else {
482 if (!can_add_transmit(&PacketP, PortP)) {
483 rio_spin_unlock(&PortP->portSem);
484 continue;
485 }
486 rio_spin_unlock(&PortP->portSem);
487 RIOTxEnable((char *) PortP);
488 rio_spin_lock(&PortP->portSem);
489 PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;
490 }
491 }
492 }
493
494
495
496
497
498
499 if (!can_add_transmit(&PacketP, PortP)) {
500 rio_spin_unlock(&PortP->portSem);
501 continue;
502 }
503
504 rio_spin_unlock(&PortP->portSem);
505 RIOTxEnable((char *) PortP);
506 }
507 }
508}
509
510
511
512
513static void RIOReceive(struct rio_info *p, struct Port *PortP)
514{
515 struct tty_struct *TtyP;
516 unsigned short transCount;
517 struct PKT __iomem *PacketP;
518 register unsigned int DataCnt;
519 unsigned char __iomem *ptr;
520 unsigned char *buf;
521 int copied = 0;
522
523 static int intCount, RxIntCnt;
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543 intCount++;
544
545 TtyP = PortP->gs.port.tty;
546 if (!TtyP) {
547 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
548 return;
549 }
550
551 if (PortP->State & RIO_THROTTLE_RX) {
552 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
553 return;
554 }
555
556 if (PortP->State & RIO_DELETED) {
557 while (can_remove_receive(&PacketP, PortP)) {
558 remove_receive(PortP);
559 put_free_end(PortP->HostP, PacketP);
560 }
561 } else {
562
563
564
565
566
567
568
569 transCount = 1;
570 while (can_remove_receive(&PacketP, PortP)
571 && transCount) {
572 RxIntCnt++;
573
574
575
576
577 if (readb(&PacketP->len) & PKT_CMD_BIT) {
578 rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
579
580 rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit));
581 rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port));
582 rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit));
583 rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port));
584 rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len));
585 rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control));
586 rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum));
587 rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
588 for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
589 rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
590 remove_receive(PortP);
591 put_free_end(PortP->HostP, PacketP);
592 continue;
593 }
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610 transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
611 rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
612
613
614
615
616
617 ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
618
619 tty_prepare_flip_string(TtyP, &buf, transCount);
620 rio_memcpy_fromio(buf, ptr, transCount);
621 PortP->RxDataStart += transCount;
622 writeb(readb(&PacketP->len)-transCount, &PacketP->len);
623 copied += transCount;
624
625
626
627 if (readb(&PacketP->len) == 0) {
628
629
630
631
632
633 remove_receive(PortP);
634 put_free_end(PortP->HostP, PacketP);
635 PortP->RxDataStart = 0;
636 }
637 }
638 }
639 if (copied) {
640 rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
641 tty_flip_buffer_push(TtyP);
642 }
643
644 return;
645}
646
647