blob: eeda40c5e189067a547e1db2a5670a6756fc5a74 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : riointr.c
24** SID : 1.2
25** Last Modified : 11/6/98 10:33:44
26** Retrieved : 11/6/98 10:33:49
27**
28** ident @(#)riointr.c 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32#ifdef SCCS_LABELS
33static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2";
34#endif
35
36
37#include <linux/module.h>
38#include <linux/slab.h>
39#include <linux/errno.h>
40#include <linux/tty.h>
Alan Cox33f0f882006-01-09 20:54:13 -080041#include <linux/tty_flip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/io.h>
43#include <asm/system.h>
44#include <asm/string.h>
45#include <asm/semaphore.h>
46#include <asm/uaccess.h>
47
48#include <linux/termios.h>
49#include <linux/serial.h>
50
51#include <linux/generic_serial.h>
52
53#include <linux/delay.h>
54
55#include "linux_compat.h"
56#include "rio_linux.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070057#include "pkt.h"
58#include "daemon.h"
59#include "rio.h"
60#include "riospace.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#include "cmdpkt.h"
62#include "map.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#include "rup.h"
64#include "port.h"
65#include "riodrvr.h"
66#include "rioinfo.h"
67#include "func.h"
68#include "errors.h"
69#include "pci.h"
70
71#include "parmmap.h"
72#include "unixrup.h"
73#include "board.h"
74#include "host.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070075#include "phb.h"
76#include "link.h"
77#include "cmdblk.h"
78#include "route.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070079#include "cirrus.h"
80#include "rioioctl.h"
81
82
83static void RIOReceive(struct rio_info *, struct Port *);
84
85
Andrew Morton8d8706e2006-01-11 12:17:49 -080086static char *firstchars(char *p, int nch)
Linus Torvalds1da177e2005-04-16 15:20:36 -070087{
Andrew Morton8d8706e2006-01-11 12:17:49 -080088 static char buf[2][128];
89 static int t = 0;
90 t = !t;
91 memcpy(buf[t], p, nch);
92 buf[t][nch] = 0;
93 return buf[t];
Linus Torvalds1da177e2005-04-16 15:20:36 -070094}
95
96
97#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask))
98/* Enable and start the transmission of packets */
Alan Cox00d83a52006-03-24 03:18:28 -080099void RIOTxEnable(char *en)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800101 struct Port *PortP;
102 struct rio_info *p;
103 struct tty_struct *tty;
104 int c;
Al Virod886cb52006-05-27 00:08:25 -0400105 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800106 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
Andrew Morton8d8706e2006-01-11 12:17:49 -0800108 PortP = (struct Port *) en;
109 p = (struct rio_info *) PortP->p;
110 tty = PortP->gs.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
112
Andrew Morton8d8706e2006-01-11 12:17:49 -0800113 rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Andrew Morton8d8706e2006-01-11 12:17:49 -0800115 if (!PortP->gs.xmit_cnt)
116 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Andrew Morton8d8706e2006-01-11 12:17:49 -0800119 /* This routine is an order of magnitude simpler than the specialix
120 version. One of the disadvantages is that this version will send
121 an incomplete packet (usually 64 bytes instead of 72) once for
122 every 4k worth of data. Let's just say that this won't influence
123 performance significantly..... */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
Andrew Morton8d8706e2006-01-11 12:17:49 -0800125 rio_spin_lock_irqsave(&PortP->portSem, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
Andrew Morton8d8706e2006-01-11 12:17:49 -0800127 while (can_add_transmit(&PacketP, PortP)) {
128 c = PortP->gs.xmit_cnt;
129 if (c > PKT_MAX_DATA_LEN)
130 c = PKT_MAX_DATA_LEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Andrew Morton8d8706e2006-01-11 12:17:49 -0800132 /* Don't copy past the end of the source buffer */
133 if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail)
134 c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Andrew Morton8d8706e2006-01-11 12:17:49 -0800136 {
137 int t;
138 t = (c > 10) ? 10 : c;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139
Andrew Morton8d8706e2006-01-11 12:17:49 -0800140 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));
141 }
142 /* If for one reason or another, we can't copy more data,
143 we're done! */
144 if (c == 0)
145 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
Al Virod886cb52006-05-27 00:08:25 -0400147 rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800148 /* udelay (1); */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149
Andrew Morton8d8706e2006-01-11 12:17:49 -0800150 writeb(c, &(PacketP->len));
151 if (!(PortP->State & RIO_DELETED)) {
152 add_transmit(PortP);
153 /*
154 ** Count chars tx'd for port statistics reporting
155 */
156 if (PortP->statsGather)
157 PortP->txchars += c;
158 }
159 PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1);
160 PortP->gs.xmit_cnt -= c;
161 }
162
163 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
164
165 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) {
166 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);
167 if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && PortP->gs.tty->ldisc.write_wakeup)
168 (PortP->gs.tty->ldisc.write_wakeup) (PortP->gs.tty);
169 rio_dprintk(RIO_DEBUG_INTR, "(%d/%d)\n", PortP->gs.wakeup_chars, PortP->gs.xmit_cnt);
170 wake_up_interruptible(&PortP->gs.tty->write_wait);
171 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172
173}
174
175
176/*
177** RIO Host Service routine. Does all the work traditionally associated with an
178** interrupt.
179*/
Andrew Morton8d8706e2006-01-11 12:17:49 -0800180static int RupIntr;
181static int RxIntr;
182static int TxIntr;
Alan Cox00d83a52006-03-24 03:18:28 -0800183
Jeff Garzikc7bec5a2006-10-06 15:00:58 -0400184void RIOServiceHost(struct rio_info *p, struct Host *HostP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800186 rio_spin_lock(&HostP->HostLock);
187 if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
188 static int t = 0;
189 rio_spin_unlock(&HostP->HostLock);
190 if ((t++ % 200) == 0)
191 rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags);
192 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800194 rio_spin_unlock(&HostP->HostLock);
195
Alan Cox00d83a52006-03-24 03:18:28 -0800196 if (readw(&HostP->ParmMapP->rup_intr)) {
197 writew(0, &HostP->ParmMapP->rup_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800198 p->RIORupCount++;
199 RupIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800200 rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800201 RIOPollHostCommands(p, HostP);
202 }
203
Alan Cox00d83a52006-03-24 03:18:28 -0800204 if (readw(&HostP->ParmMapP->rx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800205 int port;
206
Alan Cox00d83a52006-03-24 03:18:28 -0800207 writew(0, &HostP->ParmMapP->rx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800208 p->RIORxCount++;
209 RxIntr++;
210
Alan Cox00d83a52006-03-24 03:18:28 -0800211 rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800212 /*
213 ** Loop through every port. If the port is mapped into
214 ** the system ( i.e. has /dev/ttyXXXX associated ) then it is
215 ** worth checking. If the port isn't open, grab any packets
216 ** hanging on its receive queue and stuff them on the free
217 ** list; check for commands on the way.
218 */
219 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
220 struct Port *PortP = p->RIOPortp[port];
221 struct tty_struct *ttyP;
Al Virod886cb52006-05-27 00:08:25 -0400222 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800223
224 /*
225 ** not mapped in - most of the RIOPortp[] information
226 ** has not been set up!
227 ** Optimise: ports come in bundles of eight.
228 */
229 if (!PortP->Mapped) {
230 port += 7;
231 continue; /* with the next port */
232 }
233
234 /*
235 ** If the host board isn't THIS host board, check the next one.
236 ** optimise: ports come in bundles of eight.
237 */
238 if (PortP->HostP != HostP) {
239 port += 7;
240 continue;
241 }
242
243 /*
244 ** Let us see - is the port open? If not, then don't service it.
245 */
246 if (!(PortP->PortState & PORT_ISOPEN)) {
247 continue;
248 }
249
250 /*
251 ** find corresponding tty structure. The process of mapping
252 ** the ports puts these here.
253 */
254 ttyP = PortP->gs.tty;
255
256 /*
257 ** Lock the port before we begin working on it.
258 */
259 rio_spin_lock(&PortP->portSem);
260
261 /*
262 ** Process received data if there is any.
263 */
264 if (can_remove_receive(&PacketP, PortP))
265 RIOReceive(p, PortP);
266
267 /*
268 ** If there is no data left to be read from the port, and
269 ** it's handshake bit is set, then we must clear the handshake,
270 ** so that that downstream RTA is re-enabled.
271 */
Alan Cox00d83a52006-03-24 03:18:28 -0800272 if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800273 /*
274 ** MAGIC! ( Basically, handshake the RX buffer, so that
275 ** the RTAs upstream can be re-enabled. )
276 */
277 rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n");
Alan Cox00d83a52006-03-24 03:18:28 -0800278 writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800279 }
280 rio_spin_unlock(&PortP->portSem);
281 }
282 }
283
Alan Cox00d83a52006-03-24 03:18:28 -0800284 if (readw(&HostP->ParmMapP->tx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800285 int port;
286
Alan Cox00d83a52006-03-24 03:18:28 -0800287 writew(0, &HostP->ParmMapP->tx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800288
289 p->RIOTxCount++;
290 TxIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800291 rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800292
293 /*
294 ** Loop through every port.
295 ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX
296 ** associated ) then it is worth checking.
297 */
298 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
299 struct Port *PortP = p->RIOPortp[port];
300 struct tty_struct *ttyP;
Al Virod886cb52006-05-27 00:08:25 -0400301 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800302
303 /*
304 ** not mapped in - most of the RIOPortp[] information
305 ** has not been set up!
306 */
307 if (!PortP->Mapped) {
308 port += 7;
309 continue; /* with the next port */
310 }
311
312 /*
313 ** If the host board isn't running, then its data structures
314 ** are no use to us - continue quietly.
315 */
316 if (PortP->HostP != HostP) {
317 port += 7;
318 continue; /* with the next port */
319 }
320
321 /*
322 ** Let us see - is the port open? If not, then don't service it.
323 */
324 if (!(PortP->PortState & PORT_ISOPEN)) {
325 continue;
326 }
327
328 rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
329 /*
330 ** Lock the port before we begin working on it.
331 */
332 rio_spin_lock(&PortP->portSem);
333
334 /*
335 ** If we can't add anything to the transmit queue, then
336 ** we need do none of this processing.
337 */
338 if (!can_add_transmit(&PacketP, PortP)) {
339 rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
340 rio_spin_unlock(&PortP->portSem);
341 continue;
342 }
343
344 /*
345 ** find corresponding tty structure. The process of mapping
346 ** the ports puts these here.
347 */
348 ttyP = PortP->gs.tty;
349 /* If ttyP is NULL, the port is getting closed. Forget about it. */
350 if (!ttyP) {
351 rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n");
352 rio_spin_unlock(&PortP->portSem);
353 continue;
354 }
355 /*
356 ** If there is more room available we start up the transmit
357 ** data process again. This can be direct I/O, if the cookmode
358 ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the
359 ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch
360 ** characters via the line discipline. We must always call
361 ** the line discipline,
362 ** so that user input characters can be echoed correctly.
363 **
364 ** ++++ Update +++++
365 ** With the advent of double buffering, we now see if
366 ** TxBufferOut-In is non-zero. If so, then we copy a packet
367 ** to the output place, and set it going. If this empties
368 ** the buffer, then we must issue a wakeup( ) on OUT.
369 ** If it frees space in the buffer then we must issue
370 ** a wakeup( ) on IN.
371 **
372 ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we
373 ** have to send a WFLUSH command down the PHB, to mark the
374 ** end point of a WFLUSH. We also need to clear out any
375 ** data from the double buffer! ( note that WflushFlag is a
376 ** *count* of the number of WFLUSH commands outstanding! )
377 **
378 ** ++++ And there's more!
379 ** If an RTA is powered off, then on again, and rebooted,
380 ** whilst it has ports open, then we need to re-open the ports.
381 ** ( reasonable enough ). We can't do this when we spot the
382 ** re-boot, in interrupt time, because the queue is probably
383 ** full. So, when we come in here, we need to test if any
384 ** ports are in this condition, and re-open the port before
385 ** we try to send any more data to it. Now, the re-booted
386 ** RTA will be discarding packets from the PHB until it
387 ** receives this open packet, but don't worry tooo much
388 ** about that. The one thing that is interesting is the
389 ** combination of this effect and the WFLUSH effect!
390 */
391 /* For now don't handle RTA reboots. -- REW.
392 Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */
393 if (PortP->MagicFlags) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800394 if (PortP->MagicFlags & MAGIC_REBOOT) {
395 /*
396 ** well, the RTA has been rebooted, and there is room
397 ** on its queue to add the open packet that is required.
398 **
399 ** The messy part of this line is trying to decide if
400 ** we need to call the Param function as a tty or as
401 ** a modem.
402 ** DONT USE CLOCAL AS A TEST FOR THIS!
403 **
404 ** If we can't param the port, then move on to the
405 ** next port.
406 */
407 PortP->InUse = NOT_INUSE;
408
409 rio_spin_unlock(&PortP->portSem);
Alan Cox554b7c82006-03-24 03:18:32 -0800410 if (RIOParam(PortP, OPEN, ((PortP->Cor2Copy & (COR2_RTSFLOW | COR2_CTSFLOW)) == (COR2_RTSFLOW | COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800411 continue; /* with next port */
412 }
413 rio_spin_lock(&PortP->portSem);
414 PortP->MagicFlags &= ~MAGIC_REBOOT;
415 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Andrew Morton8d8706e2006-01-11 12:17:49 -0800417 /*
418 ** As mentioned above, this is a tacky hack to cope
419 ** with WFLUSH
420 */
421 if (PortP->WflushFlag) {
422 rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Andrew Morton8d8706e2006-01-11 12:17:49 -0800424 if (PortP->InUse)
425 rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
426 }
427
428 while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) {
429 int p;
Al Virod886cb52006-05-27 00:08:25 -0400430 struct PktCmd __iomem *PktCmdP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800431
432 rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
433 /*
434 ** make it look just like a WFLUSH command
435 */
Al Virod886cb52006-05-27 00:08:25 -0400436 PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
Andrew Morton8d8706e2006-01-11 12:17:49 -0800437
Alan Cox00d83a52006-03-24 03:18:28 -0800438 writeb(WFLUSH, &PktCmdP->Command);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800439
Alan Cox00d83a52006-03-24 03:18:28 -0800440 p = PortP->HostPort % (u16) PORTS_PER_RTA;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800441
442 /*
443 ** If second block of ports for 16 port RTA, add 8
444 ** to index 8-15.
445 */
446 if (PortP->SecondBlock)
447 p += PORTS_PER_RTA;
448
Alan Cox00d83a52006-03-24 03:18:28 -0800449 writeb(p, &PktCmdP->PhbNum);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800450
451 /*
452 ** to make debuggery easier
453 */
Alan Cox00d83a52006-03-24 03:18:28 -0800454 writeb('W', &PacketP->data[2]);
455 writeb('F', &PacketP->data[3]);
456 writeb('L', &PacketP->data[4]);
457 writeb('U', &PacketP->data[5]);
458 writeb('S', &PacketP->data[6]);
459 writeb('H', &PacketP->data[7]);
460 writeb(' ', &PacketP->data[8]);
461 writeb('0' + PortP->WflushFlag, &PacketP->data[9]);
462 writeb(' ', &PacketP->data[10]);
463 writeb(' ', &PacketP->data[11]);
464 writeb('\0', &PacketP->data[12]);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800465
466 /*
467 ** its two bytes long!
468 */
Alan Cox00d83a52006-03-24 03:18:28 -0800469 writeb(PKT_CMD_BIT | 2, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800470
471 /*
472 ** queue it!
473 */
474 if (!(PortP->State & RIO_DELETED)) {
475 add_transmit(PortP);
476 /*
477 ** Count chars tx'd for port statistics reporting
478 */
479 if (PortP->statsGather)
480 PortP->txchars += 2;
481 }
482
483 if (--(PortP->WflushFlag) == 0) {
484 PortP->MagicFlags &= ~MAGIC_FLUSH;
485 }
486
487 rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag);
488 }
489 if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) {
490 if (PortP->MagicFlags & MAGIC_FLUSH) {
491 PortP->MagicFlags |= MORE_OUTPUT_EYGOR;
492 } else {
493 if (!can_add_transmit(&PacketP, PortP)) {
494 rio_spin_unlock(&PortP->portSem);
495 continue;
496 }
497 rio_spin_unlock(&PortP->portSem);
498 RIOTxEnable((char *) PortP);
499 rio_spin_lock(&PortP->portSem);
500 PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;
501 }
502 }
503 }
504
505
506 /*
507 ** If we can't add anything to the transmit queue, then
508 ** we need do none of the remaining processing.
509 */
510 if (!can_add_transmit(&PacketP, PortP)) {
511 rio_spin_unlock(&PortP->portSem);
512 continue;
513 }
514
515 rio_spin_unlock(&PortP->portSem);
516 RIOTxEnable((char *) PortP);
517 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519}
520
521/*
Alan Cox00d83a52006-03-24 03:18:28 -0800522** Routine for handling received data for tty drivers
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523*/
Alan Cox00d83a52006-03-24 03:18:28 -0800524static void RIOReceive(struct rio_info *p, struct Port *PortP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800526 struct tty_struct *TtyP;
Alan Cox00d83a52006-03-24 03:18:28 -0800527 unsigned short transCount;
Al Virod886cb52006-05-27 00:08:25 -0400528 struct PKT __iomem *PacketP;
Alan Cox00d83a52006-03-24 03:18:28 -0800529 register unsigned int DataCnt;
Al Virod886cb52006-05-27 00:08:25 -0400530 unsigned char __iomem *ptr;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800531 unsigned char *buf;
532 int copied = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
Andrew Morton8d8706e2006-01-11 12:17:49 -0800534 static int intCount, RxIntCnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535
Andrew Morton8d8706e2006-01-11 12:17:49 -0800536 /*
537 ** The receive data process is to remove packets from the
538 ** PHB until there aren't any more or the current cblock
539 ** is full. When this occurs, there will be some left over
540 ** data in the packet, that we must do something with.
541 ** As we haven't unhooked the packet from the read list
542 ** yet, we can just leave the packet there, having first
543 ** made a note of how far we got. This means that we need
544 ** a pointer per port saying where we start taking the
545 ** data from - this will normally be zero, but when we
546 ** run out of space it will be set to the offset of the
547 ** next byte to copy from the packet data area. The packet
548 ** length field is decremented by the number of bytes that
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200549 ** we successfully removed from the packet. When this reaches
Andrew Morton8d8706e2006-01-11 12:17:49 -0800550 ** zero, we reset the offset pointer to be zero, and free
551 ** the packet from the front of the queue.
552 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553
Andrew Morton8d8706e2006-01-11 12:17:49 -0800554 intCount++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
Andrew Morton8d8706e2006-01-11 12:17:49 -0800556 TtyP = PortP->gs.tty;
557 if (!TtyP) {
558 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
559 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800561
562 if (PortP->State & RIO_THROTTLE_RX) {
563 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
564 return;
565 }
566
567 if (PortP->State & RIO_DELETED) {
568 while (can_remove_receive(&PacketP, PortP)) {
569 remove_receive(PortP);
570 put_free_end(PortP->HostP, PacketP);
571 }
572 } else {
573 /*
574 ** loop, just so long as:
575 ** i ) there's some data ( i.e. can_remove_receive )
576 ** ii ) we haven't been blocked
577 ** iii ) there's somewhere to put the data
578 ** iv ) we haven't outstayed our welcome
579 */
580 transCount = 1;
581 while (can_remove_receive(&PacketP, PortP)
582 && transCount) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800583 RxIntCnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584
Andrew Morton8d8706e2006-01-11 12:17:49 -0800585 /*
586 ** check that it is not a command!
587 */
Al Viro92af11c2006-05-27 02:24:14 -0400588 if (readb(&PacketP->len) & PKT_CMD_BIT) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800589 rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
590 /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
Al Viro92af11c2006-05-27 02:24:14 -0400591 rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit));
592 rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port));
593 rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit));
594 rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port));
595 rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len));
596 rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control));
597 rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800598 rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
599 for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
Al Viro92af11c2006-05-27 02:24:14 -0400600 rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800601 remove_receive(PortP);
602 put_free_end(PortP->HostP, PacketP);
603 continue; /* with next packet */
604 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
Andrew Morton8d8706e2006-01-11 12:17:49 -0800606 /*
607 ** How many characters can we move 'upstream' ?
608 **
609 ** Determine the minimum of the amount of data
610 ** available and the amount of space in which to
611 ** put it.
612 **
613 ** 1. Get the packet length by masking 'len'
614 ** for only the length bits.
615 ** 2. Available space is [buffer size] - [space used]
616 **
617 ** Transfer count is the minimum of packet length
618 ** and available space.
619 */
620
Al Viro92af11c2006-05-27 02:24:14 -0400621 transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800622 rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
623 /*
624 ** To use the following 'kkprintfs' for debugging - change the '#undef'
625 ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
626 ** driver).
627 */
Al Virod886cb52006-05-27 00:08:25 -0400628 ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629
Andrew Morton8d8706e2006-01-11 12:17:49 -0800630 tty_prepare_flip_string(TtyP, &buf, transCount);
631 rio_memcpy_fromio(buf, ptr, transCount);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800632 PortP->RxDataStart += transCount;
Al Viro92af11c2006-05-27 02:24:14 -0400633 writeb(readb(&PacketP->len)-transCount, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800634 copied += transCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635
636
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637
Al Viro92af11c2006-05-27 02:24:14 -0400638 if (readb(&PacketP->len) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 /*
Andrew Morton8d8706e2006-01-11 12:17:49 -0800640 ** If we have emptied the packet, then we can
641 ** free it, and reset the start pointer for
642 ** the next packet.
643 */
644 remove_receive(PortP);
645 put_free_end(PortP->HostP, PacketP);
646 PortP->RxDataStart = 0;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800647 }
648 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800650 if (copied) {
651 rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
652 tty_flip_buffer_push(TtyP);
653 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654
Andrew Morton8d8706e2006-01-11 12:17:49 -0800655 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656}
657