blob: 2e71aecae206a434fb72501df914f34e90a6b6fb [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <linux/errno.h>
35#include <linux/tty.h>
Alan Cox33f0f882006-01-09 20:54:13 -080036#include <linux/tty_flip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <asm/io.h>
38#include <asm/system.h>
39#include <asm/string.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <asm/uaccess.h>
41
42#include <linux/termios.h>
43#include <linux/serial.h>
44
45#include <linux/generic_serial.h>
46
47#include <linux/delay.h>
48
49#include "linux_compat.h"
50#include "rio_linux.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include "pkt.h"
52#include "daemon.h"
53#include "rio.h"
54#include "riospace.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070055#include "cmdpkt.h"
56#include "map.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070057#include "rup.h"
58#include "port.h"
59#include "riodrvr.h"
60#include "rioinfo.h"
61#include "func.h"
62#include "errors.h"
63#include "pci.h"
64
65#include "parmmap.h"
66#include "unixrup.h"
67#include "board.h"
68#include "host.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070069#include "phb.h"
70#include "link.h"
71#include "cmdblk.h"
72#include "route.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070073#include "cirrus.h"
74#include "rioioctl.h"
75
76
77static void RIOReceive(struct rio_info *, struct Port *);
78
79
Andrew Morton8d8706e2006-01-11 12:17:49 -080080static char *firstchars(char *p, int nch)
Linus Torvalds1da177e2005-04-16 15:20:36 -070081{
Andrew Morton8d8706e2006-01-11 12:17:49 -080082 static char buf[2][128];
83 static int t = 0;
84 t = !t;
85 memcpy(buf[t], p, nch);
86 buf[t][nch] = 0;
87 return buf[t];
Linus Torvalds1da177e2005-04-16 15:20:36 -070088}
89
90
91#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask))
92/* Enable and start the transmission of packets */
Alan Cox00d83a52006-03-24 03:18:28 -080093void RIOTxEnable(char *en)
Linus Torvalds1da177e2005-04-16 15:20:36 -070094{
Andrew Morton8d8706e2006-01-11 12:17:49 -080095 struct Port *PortP;
96 struct rio_info *p;
97 struct tty_struct *tty;
98 int c;
Al Virod886cb52006-05-27 00:08:25 -040099 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800100 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Andrew Morton8d8706e2006-01-11 12:17:49 -0800102 PortP = (struct Port *) en;
103 p = (struct rio_info *) PortP->p;
Alan Coxb5391e22008-07-16 21:55:20 +0100104 tty = PortP->gs.port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106
Andrew Morton8d8706e2006-01-11 12:17:49 -0800107 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 -0700108
Andrew Morton8d8706e2006-01-11 12:17:49 -0800109 if (!PortP->gs.xmit_cnt)
110 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
Andrew Morton8d8706e2006-01-11 12:17:49 -0800113 /* This routine is an order of magnitude simpler than the specialix
114 version. One of the disadvantages is that this version will send
115 an incomplete packet (usually 64 bytes instead of 72) once for
116 every 4k worth of data. Let's just say that this won't influence
117 performance significantly..... */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Andrew Morton8d8706e2006-01-11 12:17:49 -0800119 rio_spin_lock_irqsave(&PortP->portSem, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
Andrew Morton8d8706e2006-01-11 12:17:49 -0800121 while (can_add_transmit(&PacketP, PortP)) {
122 c = PortP->gs.xmit_cnt;
123 if (c > PKT_MAX_DATA_LEN)
124 c = PKT_MAX_DATA_LEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Andrew Morton8d8706e2006-01-11 12:17:49 -0800126 /* Don't copy past the end of the source buffer */
127 if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail)
128 c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
Andrew Morton8d8706e2006-01-11 12:17:49 -0800130 {
131 int t;
132 t = (c > 10) ? 10 : c;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Andrew Morton8d8706e2006-01-11 12:17:49 -0800134 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));
135 }
136 /* If for one reason or another, we can't copy more data,
137 we're done! */
138 if (c == 0)
139 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
Al Virod886cb52006-05-27 00:08:25 -0400141 rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800142 /* udelay (1); */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
Andrew Morton8d8706e2006-01-11 12:17:49 -0800144 writeb(c, &(PacketP->len));
145 if (!(PortP->State & RIO_DELETED)) {
146 add_transmit(PortP);
147 /*
148 ** Count chars tx'd for port statistics reporting
149 */
150 if (PortP->statsGather)
151 PortP->txchars += c;
152 }
153 PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1);
154 PortP->gs.xmit_cnt -= c;
155 }
156
157 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
158
Jiri Slabyb963a842007-02-10 01:44:55 -0800159 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
Alan Coxb5391e22008-07-16 21:55:20 +0100160 tty_wakeup(PortP->gs.port.tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
162}
163
164
165/*
166** RIO Host Service routine. Does all the work traditionally associated with an
167** interrupt.
168*/
Andrew Morton8d8706e2006-01-11 12:17:49 -0800169static int RupIntr;
170static int RxIntr;
171static int TxIntr;
Alan Cox00d83a52006-03-24 03:18:28 -0800172
Jeff Garzikc7bec5a2006-10-06 15:00:58 -0400173void RIOServiceHost(struct rio_info *p, struct Host *HostP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800175 rio_spin_lock(&HostP->HostLock);
176 if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
177 static int t = 0;
178 rio_spin_unlock(&HostP->HostLock);
179 if ((t++ % 200) == 0)
180 rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags);
181 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800183 rio_spin_unlock(&HostP->HostLock);
184
Alan Cox00d83a52006-03-24 03:18:28 -0800185 if (readw(&HostP->ParmMapP->rup_intr)) {
186 writew(0, &HostP->ParmMapP->rup_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800187 p->RIORupCount++;
188 RupIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800189 rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800190 RIOPollHostCommands(p, HostP);
191 }
192
Alan Cox00d83a52006-03-24 03:18:28 -0800193 if (readw(&HostP->ParmMapP->rx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800194 int port;
195
Alan Cox00d83a52006-03-24 03:18:28 -0800196 writew(0, &HostP->ParmMapP->rx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800197 p->RIORxCount++;
198 RxIntr++;
199
Alan Cox00d83a52006-03-24 03:18:28 -0800200 rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800201 /*
202 ** Loop through every port. If the port is mapped into
203 ** the system ( i.e. has /dev/ttyXXXX associated ) then it is
204 ** worth checking. If the port isn't open, grab any packets
205 ** hanging on its receive queue and stuff them on the free
206 ** list; check for commands on the way.
207 */
208 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
209 struct Port *PortP = p->RIOPortp[port];
210 struct tty_struct *ttyP;
Al Virod886cb52006-05-27 00:08:25 -0400211 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800212
213 /*
214 ** not mapped in - most of the RIOPortp[] information
215 ** has not been set up!
216 ** Optimise: ports come in bundles of eight.
217 */
218 if (!PortP->Mapped) {
219 port += 7;
220 continue; /* with the next port */
221 }
222
223 /*
224 ** If the host board isn't THIS host board, check the next one.
225 ** optimise: ports come in bundles of eight.
226 */
227 if (PortP->HostP != HostP) {
228 port += 7;
229 continue;
230 }
231
232 /*
233 ** Let us see - is the port open? If not, then don't service it.
234 */
235 if (!(PortP->PortState & PORT_ISOPEN)) {
236 continue;
237 }
238
239 /*
240 ** find corresponding tty structure. The process of mapping
241 ** the ports puts these here.
242 */
Alan Coxb5391e22008-07-16 21:55:20 +0100243 ttyP = PortP->gs.port.tty;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800244
245 /*
246 ** Lock the port before we begin working on it.
247 */
248 rio_spin_lock(&PortP->portSem);
249
250 /*
251 ** Process received data if there is any.
252 */
253 if (can_remove_receive(&PacketP, PortP))
254 RIOReceive(p, PortP);
255
256 /*
257 ** If there is no data left to be read from the port, and
258 ** it's handshake bit is set, then we must clear the handshake,
259 ** so that that downstream RTA is re-enabled.
260 */
Alan Cox00d83a52006-03-24 03:18:28 -0800261 if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800262 /*
263 ** MAGIC! ( Basically, handshake the RX buffer, so that
264 ** the RTAs upstream can be re-enabled. )
265 */
266 rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n");
Alan Cox00d83a52006-03-24 03:18:28 -0800267 writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800268 }
269 rio_spin_unlock(&PortP->portSem);
270 }
271 }
272
Alan Cox00d83a52006-03-24 03:18:28 -0800273 if (readw(&HostP->ParmMapP->tx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800274 int port;
275
Alan Cox00d83a52006-03-24 03:18:28 -0800276 writew(0, &HostP->ParmMapP->tx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800277
278 p->RIOTxCount++;
279 TxIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800280 rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800281
282 /*
283 ** Loop through every port.
284 ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX
285 ** associated ) then it is worth checking.
286 */
287 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
288 struct Port *PortP = p->RIOPortp[port];
289 struct tty_struct *ttyP;
Al Virod886cb52006-05-27 00:08:25 -0400290 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800291
292 /*
293 ** not mapped in - most of the RIOPortp[] information
294 ** has not been set up!
295 */
296 if (!PortP->Mapped) {
297 port += 7;
298 continue; /* with the next port */
299 }
300
301 /*
302 ** If the host board isn't running, then its data structures
303 ** are no use to us - continue quietly.
304 */
305 if (PortP->HostP != HostP) {
306 port += 7;
307 continue; /* with the next port */
308 }
309
310 /*
311 ** Let us see - is the port open? If not, then don't service it.
312 */
313 if (!(PortP->PortState & PORT_ISOPEN)) {
314 continue;
315 }
316
317 rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
318 /*
319 ** Lock the port before we begin working on it.
320 */
321 rio_spin_lock(&PortP->portSem);
322
323 /*
324 ** If we can't add anything to the transmit queue, then
325 ** we need do none of this processing.
326 */
327 if (!can_add_transmit(&PacketP, PortP)) {
328 rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
329 rio_spin_unlock(&PortP->portSem);
330 continue;
331 }
332
333 /*
334 ** find corresponding tty structure. The process of mapping
335 ** the ports puts these here.
336 */
Alan Coxb5391e22008-07-16 21:55:20 +0100337 ttyP = PortP->gs.port.tty;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800338 /* If ttyP is NULL, the port is getting closed. Forget about it. */
339 if (!ttyP) {
340 rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n");
341 rio_spin_unlock(&PortP->portSem);
342 continue;
343 }
344 /*
345 ** If there is more room available we start up the transmit
346 ** data process again. This can be direct I/O, if the cookmode
347 ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the
348 ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch
349 ** characters via the line discipline. We must always call
350 ** the line discipline,
351 ** so that user input characters can be echoed correctly.
352 **
353 ** ++++ Update +++++
354 ** With the advent of double buffering, we now see if
355 ** TxBufferOut-In is non-zero. If so, then we copy a packet
356 ** to the output place, and set it going. If this empties
357 ** the buffer, then we must issue a wakeup( ) on OUT.
358 ** If it frees space in the buffer then we must issue
359 ** a wakeup( ) on IN.
360 **
361 ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we
362 ** have to send a WFLUSH command down the PHB, to mark the
363 ** end point of a WFLUSH. We also need to clear out any
364 ** data from the double buffer! ( note that WflushFlag is a
365 ** *count* of the number of WFLUSH commands outstanding! )
366 **
367 ** ++++ And there's more!
368 ** If an RTA is powered off, then on again, and rebooted,
369 ** whilst it has ports open, then we need to re-open the ports.
370 ** ( reasonable enough ). We can't do this when we spot the
371 ** re-boot, in interrupt time, because the queue is probably
372 ** full. So, when we come in here, we need to test if any
373 ** ports are in this condition, and re-open the port before
374 ** we try to send any more data to it. Now, the re-booted
375 ** RTA will be discarding packets from the PHB until it
376 ** receives this open packet, but don't worry tooo much
377 ** about that. The one thing that is interesting is the
378 ** combination of this effect and the WFLUSH effect!
379 */
380 /* For now don't handle RTA reboots. -- REW.
381 Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */
382 if (PortP->MagicFlags) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800383 if (PortP->MagicFlags & MAGIC_REBOOT) {
384 /*
385 ** well, the RTA has been rebooted, and there is room
386 ** on its queue to add the open packet that is required.
387 **
388 ** The messy part of this line is trying to decide if
389 ** we need to call the Param function as a tty or as
390 ** a modem.
391 ** DONT USE CLOCAL AS A TEST FOR THIS!
392 **
393 ** If we can't param the port, then move on to the
394 ** next port.
395 */
396 PortP->InUse = NOT_INUSE;
397
398 rio_spin_unlock(&PortP->portSem);
Jiri Slabyd6f63412008-04-30 00:53:57 -0700399 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 -0800400 continue; /* with next port */
Andrew Morton8d8706e2006-01-11 12:17:49 -0800401 rio_spin_lock(&PortP->portSem);
402 PortP->MagicFlags &= ~MAGIC_REBOOT;
403 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404
Andrew Morton8d8706e2006-01-11 12:17:49 -0800405 /*
406 ** As mentioned above, this is a tacky hack to cope
407 ** with WFLUSH
408 */
409 if (PortP->WflushFlag) {
410 rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Andrew Morton8d8706e2006-01-11 12:17:49 -0800412 if (PortP->InUse)
413 rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
414 }
415
416 while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) {
417 int p;
Al Virod886cb52006-05-27 00:08:25 -0400418 struct PktCmd __iomem *PktCmdP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800419
420 rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
421 /*
422 ** make it look just like a WFLUSH command
423 */
Al Virod886cb52006-05-27 00:08:25 -0400424 PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
Andrew Morton8d8706e2006-01-11 12:17:49 -0800425
Jiri Slabyd6f63412008-04-30 00:53:57 -0700426 writeb(RIOC_WFLUSH, &PktCmdP->Command);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800427
Alan Cox00d83a52006-03-24 03:18:28 -0800428 p = PortP->HostPort % (u16) PORTS_PER_RTA;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800429
430 /*
431 ** If second block of ports for 16 port RTA, add 8
432 ** to index 8-15.
433 */
434 if (PortP->SecondBlock)
435 p += PORTS_PER_RTA;
436
Alan Cox00d83a52006-03-24 03:18:28 -0800437 writeb(p, &PktCmdP->PhbNum);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800438
439 /*
440 ** to make debuggery easier
441 */
Alan Cox00d83a52006-03-24 03:18:28 -0800442 writeb('W', &PacketP->data[2]);
443 writeb('F', &PacketP->data[3]);
444 writeb('L', &PacketP->data[4]);
445 writeb('U', &PacketP->data[5]);
446 writeb('S', &PacketP->data[6]);
447 writeb('H', &PacketP->data[7]);
448 writeb(' ', &PacketP->data[8]);
449 writeb('0' + PortP->WflushFlag, &PacketP->data[9]);
450 writeb(' ', &PacketP->data[10]);
451 writeb(' ', &PacketP->data[11]);
452 writeb('\0', &PacketP->data[12]);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800453
454 /*
455 ** its two bytes long!
456 */
Alan Cox00d83a52006-03-24 03:18:28 -0800457 writeb(PKT_CMD_BIT | 2, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800458
459 /*
460 ** queue it!
461 */
462 if (!(PortP->State & RIO_DELETED)) {
463 add_transmit(PortP);
464 /*
465 ** Count chars tx'd for port statistics reporting
466 */
467 if (PortP->statsGather)
468 PortP->txchars += 2;
469 }
470
471 if (--(PortP->WflushFlag) == 0) {
472 PortP->MagicFlags &= ~MAGIC_FLUSH;
473 }
474
475 rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag);
476 }
477 if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) {
478 if (PortP->MagicFlags & MAGIC_FLUSH) {
479 PortP->MagicFlags |= MORE_OUTPUT_EYGOR;
480 } else {
481 if (!can_add_transmit(&PacketP, PortP)) {
482 rio_spin_unlock(&PortP->portSem);
483 continue;
484 }
485 rio_spin_unlock(&PortP->portSem);
486 RIOTxEnable((char *) PortP);
487 rio_spin_lock(&PortP->portSem);
488 PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;
489 }
490 }
491 }
492
493
494 /*
495 ** If we can't add anything to the transmit queue, then
496 ** we need do none of the remaining processing.
497 */
498 if (!can_add_transmit(&PacketP, PortP)) {
499 rio_spin_unlock(&PortP->portSem);
500 continue;
501 }
502
503 rio_spin_unlock(&PortP->portSem);
504 RIOTxEnable((char *) PortP);
505 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507}
508
509/*
Alan Cox00d83a52006-03-24 03:18:28 -0800510** Routine for handling received data for tty drivers
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511*/
Alan Cox00d83a52006-03-24 03:18:28 -0800512static void RIOReceive(struct rio_info *p, struct Port *PortP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800514 struct tty_struct *TtyP;
Alan Cox00d83a52006-03-24 03:18:28 -0800515 unsigned short transCount;
Al Virod886cb52006-05-27 00:08:25 -0400516 struct PKT __iomem *PacketP;
Alan Cox00d83a52006-03-24 03:18:28 -0800517 register unsigned int DataCnt;
Al Virod886cb52006-05-27 00:08:25 -0400518 unsigned char __iomem *ptr;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800519 unsigned char *buf;
520 int copied = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
Andrew Morton8d8706e2006-01-11 12:17:49 -0800522 static int intCount, RxIntCnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523
Andrew Morton8d8706e2006-01-11 12:17:49 -0800524 /*
525 ** The receive data process is to remove packets from the
526 ** PHB until there aren't any more or the current cblock
527 ** is full. When this occurs, there will be some left over
528 ** data in the packet, that we must do something with.
529 ** As we haven't unhooked the packet from the read list
530 ** yet, we can just leave the packet there, having first
531 ** made a note of how far we got. This means that we need
532 ** a pointer per port saying where we start taking the
533 ** data from - this will normally be zero, but when we
534 ** run out of space it will be set to the offset of the
535 ** next byte to copy from the packet data area. The packet
536 ** length field is decremented by the number of bytes that
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200537 ** we successfully removed from the packet. When this reaches
Andrew Morton8d8706e2006-01-11 12:17:49 -0800538 ** zero, we reset the offset pointer to be zero, and free
539 ** the packet from the front of the queue.
540 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541
Andrew Morton8d8706e2006-01-11 12:17:49 -0800542 intCount++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543
Alan Coxb5391e22008-07-16 21:55:20 +0100544 TtyP = PortP->gs.port.tty;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800545 if (!TtyP) {
546 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
547 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800549
550 if (PortP->State & RIO_THROTTLE_RX) {
551 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
552 return;
553 }
554
555 if (PortP->State & RIO_DELETED) {
556 while (can_remove_receive(&PacketP, PortP)) {
557 remove_receive(PortP);
558 put_free_end(PortP->HostP, PacketP);
559 }
560 } else {
561 /*
562 ** loop, just so long as:
563 ** i ) there's some data ( i.e. can_remove_receive )
564 ** ii ) we haven't been blocked
565 ** iii ) there's somewhere to put the data
566 ** iv ) we haven't outstayed our welcome
567 */
568 transCount = 1;
569 while (can_remove_receive(&PacketP, PortP)
570 && transCount) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800571 RxIntCnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572
Andrew Morton8d8706e2006-01-11 12:17:49 -0800573 /*
574 ** check that it is not a command!
575 */
Al Viro92af11c2006-05-27 02:24:14 -0400576 if (readb(&PacketP->len) & PKT_CMD_BIT) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800577 rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
578 /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
Al Viro92af11c2006-05-27 02:24:14 -0400579 rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit));
580 rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port));
581 rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit));
582 rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port));
583 rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len));
584 rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control));
585 rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800586 rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
587 for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
Al Viro92af11c2006-05-27 02:24:14 -0400588 rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800589 remove_receive(PortP);
590 put_free_end(PortP->HostP, PacketP);
591 continue; /* with next packet */
592 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593
Andrew Morton8d8706e2006-01-11 12:17:49 -0800594 /*
595 ** How many characters can we move 'upstream' ?
596 **
597 ** Determine the minimum of the amount of data
598 ** available and the amount of space in which to
599 ** put it.
600 **
601 ** 1. Get the packet length by masking 'len'
602 ** for only the length bits.
603 ** 2. Available space is [buffer size] - [space used]
604 **
605 ** Transfer count is the minimum of packet length
606 ** and available space.
607 */
608
Al Viro92af11c2006-05-27 02:24:14 -0400609 transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800610 rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
611 /*
612 ** To use the following 'kkprintfs' for debugging - change the '#undef'
613 ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
614 ** driver).
615 */
Al Virod886cb52006-05-27 00:08:25 -0400616 ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
Andrew Morton8d8706e2006-01-11 12:17:49 -0800618 tty_prepare_flip_string(TtyP, &buf, transCount);
619 rio_memcpy_fromio(buf, ptr, transCount);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800620 PortP->RxDataStart += transCount;
Al Viro92af11c2006-05-27 02:24:14 -0400621 writeb(readb(&PacketP->len)-transCount, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800622 copied += transCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623
624
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625
Al Viro92af11c2006-05-27 02:24:14 -0400626 if (readb(&PacketP->len) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 /*
Andrew Morton8d8706e2006-01-11 12:17:49 -0800628 ** If we have emptied the packet, then we can
629 ** free it, and reset the start pointer for
630 ** the next packet.
631 */
632 remove_receive(PortP);
633 put_free_end(PortP->HostP, PacketP);
634 PortP->RxDataStart = 0;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800635 }
636 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800638 if (copied) {
639 rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
640 tty_flip_buffer_push(TtyP);
641 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642
Andrew Morton8d8706e2006-01-11 12:17:49 -0800643 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644}
645