blob: 71f87600907ce04f1da12bb7d3279650a19c2857 [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*/
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33#include <linux/module.h>
34#include <linux/slab.h>
35#include <linux/errno.h>
36#include <linux/tty.h>
Alan Cox33f0f882006-01-09 20:54:13 -080037#include <linux/tty_flip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <asm/io.h>
39#include <asm/system.h>
40#include <asm/string.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#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"
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#include "pkt.h"
53#include "daemon.h"
54#include "rio.h"
55#include "riospace.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070056#include "cmdpkt.h"
57#include "map.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070058#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"
Linus Torvalds1da177e2005-04-16 15:20:36 -070070#include "phb.h"
71#include "link.h"
72#include "cmdblk.h"
73#include "route.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070074#include "cirrus.h"
75#include "rioioctl.h"
76
77
78static void RIOReceive(struct rio_info *, struct Port *);
79
80
Andrew Morton8d8706e2006-01-11 12:17:49 -080081static char *firstchars(char *p, int nch)
Linus Torvalds1da177e2005-04-16 15:20:36 -070082{
Andrew Morton8d8706e2006-01-11 12:17:49 -080083 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];
Linus Torvalds1da177e2005-04-16 15:20:36 -070089}
90
91
92#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask))
93/* Enable and start the transmission of packets */
Alan Cox00d83a52006-03-24 03:18:28 -080094void RIOTxEnable(char *en)
Linus Torvalds1da177e2005-04-16 15:20:36 -070095{
Andrew Morton8d8706e2006-01-11 12:17:49 -080096 struct Port *PortP;
97 struct rio_info *p;
98 struct tty_struct *tty;
99 int c;
Al Virod886cb52006-05-27 00:08:25 -0400100 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800101 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Andrew Morton8d8706e2006-01-11 12:17:49 -0800103 PortP = (struct Port *) en;
104 p = (struct rio_info *) PortP->p;
Alan Coxb5391e22008-07-16 21:55:20 +0100105 tty = PortP->gs.port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
107
Andrew Morton8d8706e2006-01-11 12:17:49 -0800108 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 -0700109
Andrew Morton8d8706e2006-01-11 12:17:49 -0800110 if (!PortP->gs.xmit_cnt)
111 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
Andrew Morton8d8706e2006-01-11 12:17:49 -0800114 /* This routine is an order of magnitude simpler than the specialix
115 version. One of the disadvantages is that this version will send
116 an incomplete packet (usually 64 bytes instead of 72) once for
117 every 4k worth of data. Let's just say that this won't influence
118 performance significantly..... */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119
Andrew Morton8d8706e2006-01-11 12:17:49 -0800120 rio_spin_lock_irqsave(&PortP->portSem, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Andrew Morton8d8706e2006-01-11 12:17:49 -0800122 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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
Andrew Morton8d8706e2006-01-11 12:17:49 -0800127 /* Don't copy past the end of the source buffer */
128 if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail)
129 c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Andrew Morton8d8706e2006-01-11 12:17:49 -0800131 {
132 int t;
133 t = (c > 10) ? 10 : c;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134
Andrew Morton8d8706e2006-01-11 12:17:49 -0800135 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 /* If for one reason or another, we can't copy more data,
138 we're done! */
139 if (c == 0)
140 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
Al Virod886cb52006-05-27 00:08:25 -0400142 rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800143 /* udelay (1); */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144
Andrew Morton8d8706e2006-01-11 12:17:49 -0800145 writeb(c, &(PacketP->len));
146 if (!(PortP->State & RIO_DELETED)) {
147 add_transmit(PortP);
148 /*
149 ** Count chars tx'd for port statistics reporting
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
Jiri Slabyb963a842007-02-10 01:44:55 -0800160 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
Alan Coxb5391e22008-07-16 21:55:20 +0100161 tty_wakeup(PortP->gs.port.tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162
163}
164
165
166/*
167** RIO Host Service routine. Does all the work traditionally associated with an
168** interrupt.
169*/
Andrew Morton8d8706e2006-01-11 12:17:49 -0800170static int RupIntr;
171static int RxIntr;
172static int TxIntr;
Alan Cox00d83a52006-03-24 03:18:28 -0800173
Jeff Garzikc7bec5a2006-10-06 15:00:58 -0400174void RIOServiceHost(struct rio_info *p, struct Host *HostP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800176 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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800184 rio_spin_unlock(&HostP->HostLock);
185
Alan Cox00d83a52006-03-24 03:18:28 -0800186 if (readw(&HostP->ParmMapP->rup_intr)) {
187 writew(0, &HostP->ParmMapP->rup_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800188 p->RIORupCount++;
189 RupIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800190 rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800191 RIOPollHostCommands(p, HostP);
192 }
193
Alan Cox00d83a52006-03-24 03:18:28 -0800194 if (readw(&HostP->ParmMapP->rx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800195 int port;
196
Alan Cox00d83a52006-03-24 03:18:28 -0800197 writew(0, &HostP->ParmMapP->rx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800198 p->RIORxCount++;
199 RxIntr++;
200
Alan Cox00d83a52006-03-24 03:18:28 -0800201 rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800202 /*
203 ** Loop through every port. If the port is mapped into
204 ** the system ( i.e. has /dev/ttyXXXX associated ) then it is
205 ** worth checking. If the port isn't open, grab any packets
206 ** hanging on its receive queue and stuff them on the free
207 ** list; check for commands on the way.
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;
Al Virod886cb52006-05-27 00:08:25 -0400212 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800213
214 /*
215 ** not mapped in - most of the RIOPortp[] information
216 ** has not been set up!
217 ** Optimise: ports come in bundles of eight.
218 */
219 if (!PortP->Mapped) {
220 port += 7;
221 continue; /* with the next port */
222 }
223
224 /*
225 ** If the host board isn't THIS host board, check the next one.
226 ** optimise: ports come in bundles of eight.
227 */
228 if (PortP->HostP != HostP) {
229 port += 7;
230 continue;
231 }
232
233 /*
234 ** Let us see - is the port open? If not, then don't service it.
235 */
236 if (!(PortP->PortState & PORT_ISOPEN)) {
237 continue;
238 }
239
240 /*
241 ** find corresponding tty structure. The process of mapping
242 ** the ports puts these here.
243 */
Alan Coxb5391e22008-07-16 21:55:20 +0100244 ttyP = PortP->gs.port.tty;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800245
246 /*
247 ** Lock the port before we begin working on it.
248 */
249 rio_spin_lock(&PortP->portSem);
250
251 /*
252 ** Process received data if there is any.
253 */
254 if (can_remove_receive(&PacketP, PortP))
255 RIOReceive(p, PortP);
256
257 /*
258 ** If there is no data left to be read from the port, and
259 ** it's handshake bit is set, then we must clear the handshake,
260 ** so that that downstream RTA is re-enabled.
261 */
Alan Cox00d83a52006-03-24 03:18:28 -0800262 if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800263 /*
264 ** MAGIC! ( Basically, handshake the RX buffer, so that
265 ** the RTAs upstream can be re-enabled. )
266 */
267 rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n");
Alan Cox00d83a52006-03-24 03:18:28 -0800268 writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800269 }
270 rio_spin_unlock(&PortP->portSem);
271 }
272 }
273
Alan Cox00d83a52006-03-24 03:18:28 -0800274 if (readw(&HostP->ParmMapP->tx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800275 int port;
276
Alan Cox00d83a52006-03-24 03:18:28 -0800277 writew(0, &HostP->ParmMapP->tx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800278
279 p->RIOTxCount++;
280 TxIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800281 rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800282
283 /*
284 ** Loop through every port.
285 ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX
286 ** associated ) then it is worth checking.
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;
Al Virod886cb52006-05-27 00:08:25 -0400291 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800292
293 /*
294 ** not mapped in - most of the RIOPortp[] information
295 ** has not been set up!
296 */
297 if (!PortP->Mapped) {
298 port += 7;
299 continue; /* with the next port */
300 }
301
302 /*
303 ** If the host board isn't running, then its data structures
304 ** are no use to us - continue quietly.
305 */
306 if (PortP->HostP != HostP) {
307 port += 7;
308 continue; /* with the next port */
309 }
310
311 /*
312 ** Let us see - is the port open? If not, then don't service it.
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 ** Lock the port before we begin working on it.
321 */
322 rio_spin_lock(&PortP->portSem);
323
324 /*
325 ** If we can't add anything to the transmit queue, then
326 ** we need do none of this processing.
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 ** find corresponding tty structure. The process of mapping
336 ** the ports puts these here.
337 */
Alan Coxb5391e22008-07-16 21:55:20 +0100338 ttyP = PortP->gs.port.tty;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800339 /* If ttyP is NULL, the port is getting closed. Forget about it. */
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 ** If there is more room available we start up the transmit
347 ** data process again. This can be direct I/O, if the cookmode
348 ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the
349 ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch
350 ** characters via the line discipline. We must always call
351 ** the line discipline,
352 ** so that user input characters can be echoed correctly.
353 **
354 ** ++++ Update +++++
355 ** With the advent of double buffering, we now see if
356 ** TxBufferOut-In is non-zero. If so, then we copy a packet
357 ** to the output place, and set it going. If this empties
358 ** the buffer, then we must issue a wakeup( ) on OUT.
359 ** If it frees space in the buffer then we must issue
360 ** a wakeup( ) on IN.
361 **
362 ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we
363 ** have to send a WFLUSH command down the PHB, to mark the
364 ** end point of a WFLUSH. We also need to clear out any
365 ** data from the double buffer! ( note that WflushFlag is a
366 ** *count* of the number of WFLUSH commands outstanding! )
367 **
368 ** ++++ And there's more!
369 ** If an RTA is powered off, then on again, and rebooted,
370 ** whilst it has ports open, then we need to re-open the ports.
371 ** ( reasonable enough ). We can't do this when we spot the
372 ** re-boot, in interrupt time, because the queue is probably
373 ** full. So, when we come in here, we need to test if any
374 ** ports are in this condition, and re-open the port before
375 ** we try to send any more data to it. Now, the re-booted
376 ** RTA will be discarding packets from the PHB until it
377 ** receives this open packet, but don't worry tooo much
378 ** about that. The one thing that is interesting is the
379 ** combination of this effect and the WFLUSH effect!
380 */
381 /* For now don't handle RTA reboots. -- REW.
382 Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */
383 if (PortP->MagicFlags) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800384 if (PortP->MagicFlags & MAGIC_REBOOT) {
385 /*
386 ** well, the RTA has been rebooted, and there is room
387 ** on its queue to add the open packet that is required.
388 **
389 ** The messy part of this line is trying to decide if
390 ** we need to call the Param function as a tty or as
391 ** a modem.
392 ** DONT USE CLOCAL AS A TEST FOR THIS!
393 **
394 ** If we can't param the port, then move on to the
395 ** next port.
396 */
397 PortP->InUse = NOT_INUSE;
398
399 rio_spin_unlock(&PortP->portSem);
Jiri Slabyd6f63412008-04-30 00:53:57 -0700400 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)
Andrew Morton8d8706e2006-01-11 12:17:49 -0800401 continue; /* with next port */
Andrew Morton8d8706e2006-01-11 12:17:49 -0800402 rio_spin_lock(&PortP->portSem);
403 PortP->MagicFlags &= ~MAGIC_REBOOT;
404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Andrew Morton8d8706e2006-01-11 12:17:49 -0800406 /*
407 ** As mentioned above, this is a tacky hack to cope
408 ** with WFLUSH
409 */
410 if (PortP->WflushFlag) {
411 rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Andrew Morton8d8706e2006-01-11 12:17:49 -0800413 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;
Al Virod886cb52006-05-27 00:08:25 -0400419 struct PktCmd __iomem *PktCmdP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800420
421 rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
422 /*
423 ** make it look just like a WFLUSH command
424 */
Al Virod886cb52006-05-27 00:08:25 -0400425 PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
Andrew Morton8d8706e2006-01-11 12:17:49 -0800426
Jiri Slabyd6f63412008-04-30 00:53:57 -0700427 writeb(RIOC_WFLUSH, &PktCmdP->Command);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800428
Alan Cox00d83a52006-03-24 03:18:28 -0800429 p = PortP->HostPort % (u16) PORTS_PER_RTA;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800430
431 /*
432 ** If second block of ports for 16 port RTA, add 8
433 ** to index 8-15.
434 */
435 if (PortP->SecondBlock)
436 p += PORTS_PER_RTA;
437
Alan Cox00d83a52006-03-24 03:18:28 -0800438 writeb(p, &PktCmdP->PhbNum);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800439
440 /*
441 ** to make debuggery easier
442 */
Alan Cox00d83a52006-03-24 03:18:28 -0800443 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]);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800454
455 /*
456 ** its two bytes long!
457 */
Alan Cox00d83a52006-03-24 03:18:28 -0800458 writeb(PKT_CMD_BIT | 2, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800459
460 /*
461 ** queue it!
462 */
463 if (!(PortP->State & RIO_DELETED)) {
464 add_transmit(PortP);
465 /*
466 ** Count chars tx'd for port statistics reporting
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 ** If we can't add anything to the transmit queue, then
497 ** we need do none of the remaining processing.
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 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508}
509
510/*
Alan Cox00d83a52006-03-24 03:18:28 -0800511** Routine for handling received data for tty drivers
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512*/
Alan Cox00d83a52006-03-24 03:18:28 -0800513static void RIOReceive(struct rio_info *p, struct Port *PortP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800515 struct tty_struct *TtyP;
Alan Cox00d83a52006-03-24 03:18:28 -0800516 unsigned short transCount;
Al Virod886cb52006-05-27 00:08:25 -0400517 struct PKT __iomem *PacketP;
Alan Cox00d83a52006-03-24 03:18:28 -0800518 register unsigned int DataCnt;
Al Virod886cb52006-05-27 00:08:25 -0400519 unsigned char __iomem *ptr;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800520 unsigned char *buf;
521 int copied = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
Andrew Morton8d8706e2006-01-11 12:17:49 -0800523 static int intCount, RxIntCnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
Andrew Morton8d8706e2006-01-11 12:17:49 -0800525 /*
526 ** The receive data process is to remove packets from the
527 ** PHB until there aren't any more or the current cblock
528 ** is full. When this occurs, there will be some left over
529 ** data in the packet, that we must do something with.
530 ** As we haven't unhooked the packet from the read list
531 ** yet, we can just leave the packet there, having first
532 ** made a note of how far we got. This means that we need
533 ** a pointer per port saying where we start taking the
534 ** data from - this will normally be zero, but when we
535 ** run out of space it will be set to the offset of the
536 ** next byte to copy from the packet data area. The packet
537 ** length field is decremented by the number of bytes that
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200538 ** we successfully removed from the packet. When this reaches
Andrew Morton8d8706e2006-01-11 12:17:49 -0800539 ** zero, we reset the offset pointer to be zero, and free
540 ** the packet from the front of the queue.
541 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
Andrew Morton8d8706e2006-01-11 12:17:49 -0800543 intCount++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
Alan Coxb5391e22008-07-16 21:55:20 +0100545 TtyP = PortP->gs.port.tty;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800546 if (!TtyP) {
547 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
548 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800550
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 ** loop, just so long as:
564 ** i ) there's some data ( i.e. can_remove_receive )
565 ** ii ) we haven't been blocked
566 ** iii ) there's somewhere to put the data
567 ** iv ) we haven't outstayed our welcome
568 */
569 transCount = 1;
570 while (can_remove_receive(&PacketP, PortP)
571 && transCount) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800572 RxIntCnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
Andrew Morton8d8706e2006-01-11 12:17:49 -0800574 /*
575 ** check that it is not a command!
576 */
Al Viro92af11c2006-05-27 02:24:14 -0400577 if (readb(&PacketP->len) & PKT_CMD_BIT) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800578 rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
579 /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
Al Viro92af11c2006-05-27 02:24:14 -0400580 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));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800587 rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
588 for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
Al Viro92af11c2006-05-27 02:24:14 -0400589 rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800590 remove_receive(PortP);
591 put_free_end(PortP->HostP, PacketP);
592 continue; /* with next packet */
593 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594
Andrew Morton8d8706e2006-01-11 12:17:49 -0800595 /*
596 ** How many characters can we move 'upstream' ?
597 **
598 ** Determine the minimum of the amount of data
599 ** available and the amount of space in which to
600 ** put it.
601 **
602 ** 1. Get the packet length by masking 'len'
603 ** for only the length bits.
604 ** 2. Available space is [buffer size] - [space used]
605 **
606 ** Transfer count is the minimum of packet length
607 ** and available space.
608 */
609
Al Viro92af11c2006-05-27 02:24:14 -0400610 transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800611 rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
612 /*
613 ** To use the following 'kkprintfs' for debugging - change the '#undef'
614 ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
615 ** driver).
616 */
Al Virod886cb52006-05-27 00:08:25 -0400617 ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618
Andrew Morton8d8706e2006-01-11 12:17:49 -0800619 tty_prepare_flip_string(TtyP, &buf, transCount);
620 rio_memcpy_fromio(buf, ptr, transCount);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800621 PortP->RxDataStart += transCount;
Al Viro92af11c2006-05-27 02:24:14 -0400622 writeb(readb(&PacketP->len)-transCount, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800623 copied += transCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
625
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626
Al Viro92af11c2006-05-27 02:24:14 -0400627 if (readb(&PacketP->len) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 /*
Andrew Morton8d8706e2006-01-11 12:17:49 -0800629 ** If we have emptied the packet, then we can
630 ** free it, and reset the start pointer for
631 ** the next packet.
632 */
633 remove_receive(PortP);
634 put_free_end(PortP->HostP, PacketP);
635 PortP->RxDataStart = 0;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800636 }
637 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800639 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 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643
Andrew Morton8d8706e2006-01-11 12:17:49 -0800644 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645}
646