blob: ebc76342712c1485da63b58eb01d83be38e34a4d [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
Jiri Slabyb963a842007-02-10 01:44:55 -0800165 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
166 tty_wakeup(PortP->gs.tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167
168}
169
170
171/*
172** RIO Host Service routine. Does all the work traditionally associated with an
173** interrupt.
174*/
Andrew Morton8d8706e2006-01-11 12:17:49 -0800175static int RupIntr;
176static int RxIntr;
177static int TxIntr;
Alan Cox00d83a52006-03-24 03:18:28 -0800178
Jeff Garzikc7bec5a2006-10-06 15:00:58 -0400179void RIOServiceHost(struct rio_info *p, struct Host *HostP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800181 rio_spin_lock(&HostP->HostLock);
182 if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
183 static int t = 0;
184 rio_spin_unlock(&HostP->HostLock);
185 if ((t++ % 200) == 0)
186 rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags);
187 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800189 rio_spin_unlock(&HostP->HostLock);
190
Alan Cox00d83a52006-03-24 03:18:28 -0800191 if (readw(&HostP->ParmMapP->rup_intr)) {
192 writew(0, &HostP->ParmMapP->rup_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800193 p->RIORupCount++;
194 RupIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800195 rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800196 RIOPollHostCommands(p, HostP);
197 }
198
Alan Cox00d83a52006-03-24 03:18:28 -0800199 if (readw(&HostP->ParmMapP->rx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800200 int port;
201
Alan Cox00d83a52006-03-24 03:18:28 -0800202 writew(0, &HostP->ParmMapP->rx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800203 p->RIORxCount++;
204 RxIntr++;
205
Alan Cox00d83a52006-03-24 03:18:28 -0800206 rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800207 /*
208 ** Loop through every port. If the port is mapped into
209 ** the system ( i.e. has /dev/ttyXXXX associated ) then it is
210 ** worth checking. If the port isn't open, grab any packets
211 ** hanging on its receive queue and stuff them on the free
212 ** list; check for commands on the way.
213 */
214 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
215 struct Port *PortP = p->RIOPortp[port];
216 struct tty_struct *ttyP;
Al Virod886cb52006-05-27 00:08:25 -0400217 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800218
219 /*
220 ** not mapped in - most of the RIOPortp[] information
221 ** has not been set up!
222 ** Optimise: ports come in bundles of eight.
223 */
224 if (!PortP->Mapped) {
225 port += 7;
226 continue; /* with the next port */
227 }
228
229 /*
230 ** If the host board isn't THIS host board, check the next one.
231 ** optimise: ports come in bundles of eight.
232 */
233 if (PortP->HostP != HostP) {
234 port += 7;
235 continue;
236 }
237
238 /*
239 ** Let us see - is the port open? If not, then don't service it.
240 */
241 if (!(PortP->PortState & PORT_ISOPEN)) {
242 continue;
243 }
244
245 /*
246 ** find corresponding tty structure. The process of mapping
247 ** the ports puts these here.
248 */
249 ttyP = PortP->gs.tty;
250
251 /*
252 ** Lock the port before we begin working on it.
253 */
254 rio_spin_lock(&PortP->portSem);
255
256 /*
257 ** Process received data if there is any.
258 */
259 if (can_remove_receive(&PacketP, PortP))
260 RIOReceive(p, PortP);
261
262 /*
263 ** If there is no data left to be read from the port, and
264 ** it's handshake bit is set, then we must clear the handshake,
265 ** so that that downstream RTA is re-enabled.
266 */
Alan Cox00d83a52006-03-24 03:18:28 -0800267 if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800268 /*
269 ** MAGIC! ( Basically, handshake the RX buffer, so that
270 ** the RTAs upstream can be re-enabled. )
271 */
272 rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n");
Alan Cox00d83a52006-03-24 03:18:28 -0800273 writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800274 }
275 rio_spin_unlock(&PortP->portSem);
276 }
277 }
278
Alan Cox00d83a52006-03-24 03:18:28 -0800279 if (readw(&HostP->ParmMapP->tx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800280 int port;
281
Alan Cox00d83a52006-03-24 03:18:28 -0800282 writew(0, &HostP->ParmMapP->tx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800283
284 p->RIOTxCount++;
285 TxIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800286 rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800287
288 /*
289 ** Loop through every port.
290 ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX
291 ** associated ) then it is worth checking.
292 */
293 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
294 struct Port *PortP = p->RIOPortp[port];
295 struct tty_struct *ttyP;
Al Virod886cb52006-05-27 00:08:25 -0400296 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800297
298 /*
299 ** not mapped in - most of the RIOPortp[] information
300 ** has not been set up!
301 */
302 if (!PortP->Mapped) {
303 port += 7;
304 continue; /* with the next port */
305 }
306
307 /*
308 ** If the host board isn't running, then its data structures
309 ** are no use to us - continue quietly.
310 */
311 if (PortP->HostP != HostP) {
312 port += 7;
313 continue; /* with the next port */
314 }
315
316 /*
317 ** Let us see - is the port open? If not, then don't service it.
318 */
319 if (!(PortP->PortState & PORT_ISOPEN)) {
320 continue;
321 }
322
323 rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
324 /*
325 ** Lock the port before we begin working on it.
326 */
327 rio_spin_lock(&PortP->portSem);
328
329 /*
330 ** If we can't add anything to the transmit queue, then
331 ** we need do none of this processing.
332 */
333 if (!can_add_transmit(&PacketP, PortP)) {
334 rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
335 rio_spin_unlock(&PortP->portSem);
336 continue;
337 }
338
339 /*
340 ** find corresponding tty structure. The process of mapping
341 ** the ports puts these here.
342 */
343 ttyP = PortP->gs.tty;
344 /* If ttyP is NULL, the port is getting closed. Forget about it. */
345 if (!ttyP) {
346 rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n");
347 rio_spin_unlock(&PortP->portSem);
348 continue;
349 }
350 /*
351 ** If there is more room available we start up the transmit
352 ** data process again. This can be direct I/O, if the cookmode
353 ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the
354 ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch
355 ** characters via the line discipline. We must always call
356 ** the line discipline,
357 ** so that user input characters can be echoed correctly.
358 **
359 ** ++++ Update +++++
360 ** With the advent of double buffering, we now see if
361 ** TxBufferOut-In is non-zero. If so, then we copy a packet
362 ** to the output place, and set it going. If this empties
363 ** the buffer, then we must issue a wakeup( ) on OUT.
364 ** If it frees space in the buffer then we must issue
365 ** a wakeup( ) on IN.
366 **
367 ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we
368 ** have to send a WFLUSH command down the PHB, to mark the
369 ** end point of a WFLUSH. We also need to clear out any
370 ** data from the double buffer! ( note that WflushFlag is a
371 ** *count* of the number of WFLUSH commands outstanding! )
372 **
373 ** ++++ And there's more!
374 ** If an RTA is powered off, then on again, and rebooted,
375 ** whilst it has ports open, then we need to re-open the ports.
376 ** ( reasonable enough ). We can't do this when we spot the
377 ** re-boot, in interrupt time, because the queue is probably
378 ** full. So, when we come in here, we need to test if any
379 ** ports are in this condition, and re-open the port before
380 ** we try to send any more data to it. Now, the re-booted
381 ** RTA will be discarding packets from the PHB until it
382 ** receives this open packet, but don't worry tooo much
383 ** about that. The one thing that is interesting is the
384 ** combination of this effect and the WFLUSH effect!
385 */
386 /* For now don't handle RTA reboots. -- REW.
387 Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */
388 if (PortP->MagicFlags) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800389 if (PortP->MagicFlags & MAGIC_REBOOT) {
390 /*
391 ** well, the RTA has been rebooted, and there is room
392 ** on its queue to add the open packet that is required.
393 **
394 ** The messy part of this line is trying to decide if
395 ** we need to call the Param function as a tty or as
396 ** a modem.
397 ** DONT USE CLOCAL AS A TEST FOR THIS!
398 **
399 ** If we can't param the port, then move on to the
400 ** next port.
401 */
402 PortP->InUse = NOT_INUSE;
403
404 rio_spin_unlock(&PortP->portSem);
Alan Cox554b7c82006-03-24 03:18:32 -0800405 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 -0800406 continue; /* with next port */
407 }
408 rio_spin_lock(&PortP->portSem);
409 PortP->MagicFlags &= ~MAGIC_REBOOT;
410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Andrew Morton8d8706e2006-01-11 12:17:49 -0800412 /*
413 ** As mentioned above, this is a tacky hack to cope
414 ** with WFLUSH
415 */
416 if (PortP->WflushFlag) {
417 rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Andrew Morton8d8706e2006-01-11 12:17:49 -0800419 if (PortP->InUse)
420 rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
421 }
422
423 while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) {
424 int p;
Al Virod886cb52006-05-27 00:08:25 -0400425 struct PktCmd __iomem *PktCmdP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800426
427 rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
428 /*
429 ** make it look just like a WFLUSH command
430 */
Al Virod886cb52006-05-27 00:08:25 -0400431 PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
Andrew Morton8d8706e2006-01-11 12:17:49 -0800432
Alan Cox00d83a52006-03-24 03:18:28 -0800433 writeb(WFLUSH, &PktCmdP->Command);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800434
Alan Cox00d83a52006-03-24 03:18:28 -0800435 p = PortP->HostPort % (u16) PORTS_PER_RTA;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800436
437 /*
438 ** If second block of ports for 16 port RTA, add 8
439 ** to index 8-15.
440 */
441 if (PortP->SecondBlock)
442 p += PORTS_PER_RTA;
443
Alan Cox00d83a52006-03-24 03:18:28 -0800444 writeb(p, &PktCmdP->PhbNum);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800445
446 /*
447 ** to make debuggery easier
448 */
Alan Cox00d83a52006-03-24 03:18:28 -0800449 writeb('W', &PacketP->data[2]);
450 writeb('F', &PacketP->data[3]);
451 writeb('L', &PacketP->data[4]);
452 writeb('U', &PacketP->data[5]);
453 writeb('S', &PacketP->data[6]);
454 writeb('H', &PacketP->data[7]);
455 writeb(' ', &PacketP->data[8]);
456 writeb('0' + PortP->WflushFlag, &PacketP->data[9]);
457 writeb(' ', &PacketP->data[10]);
458 writeb(' ', &PacketP->data[11]);
459 writeb('\0', &PacketP->data[12]);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800460
461 /*
462 ** its two bytes long!
463 */
Alan Cox00d83a52006-03-24 03:18:28 -0800464 writeb(PKT_CMD_BIT | 2, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800465
466 /*
467 ** queue it!
468 */
469 if (!(PortP->State & RIO_DELETED)) {
470 add_transmit(PortP);
471 /*
472 ** Count chars tx'd for port statistics reporting
473 */
474 if (PortP->statsGather)
475 PortP->txchars += 2;
476 }
477
478 if (--(PortP->WflushFlag) == 0) {
479 PortP->MagicFlags &= ~MAGIC_FLUSH;
480 }
481
482 rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag);
483 }
484 if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) {
485 if (PortP->MagicFlags & MAGIC_FLUSH) {
486 PortP->MagicFlags |= MORE_OUTPUT_EYGOR;
487 } else {
488 if (!can_add_transmit(&PacketP, PortP)) {
489 rio_spin_unlock(&PortP->portSem);
490 continue;
491 }
492 rio_spin_unlock(&PortP->portSem);
493 RIOTxEnable((char *) PortP);
494 rio_spin_lock(&PortP->portSem);
495 PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;
496 }
497 }
498 }
499
500
501 /*
502 ** If we can't add anything to the transmit queue, then
503 ** we need do none of the remaining processing.
504 */
505 if (!can_add_transmit(&PacketP, PortP)) {
506 rio_spin_unlock(&PortP->portSem);
507 continue;
508 }
509
510 rio_spin_unlock(&PortP->portSem);
511 RIOTxEnable((char *) PortP);
512 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514}
515
516/*
Alan Cox00d83a52006-03-24 03:18:28 -0800517** Routine for handling received data for tty drivers
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518*/
Alan Cox00d83a52006-03-24 03:18:28 -0800519static void RIOReceive(struct rio_info *p, struct Port *PortP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800521 struct tty_struct *TtyP;
Alan Cox00d83a52006-03-24 03:18:28 -0800522 unsigned short transCount;
Al Virod886cb52006-05-27 00:08:25 -0400523 struct PKT __iomem *PacketP;
Alan Cox00d83a52006-03-24 03:18:28 -0800524 register unsigned int DataCnt;
Al Virod886cb52006-05-27 00:08:25 -0400525 unsigned char __iomem *ptr;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800526 unsigned char *buf;
527 int copied = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Andrew Morton8d8706e2006-01-11 12:17:49 -0800529 static int intCount, RxIntCnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
Andrew Morton8d8706e2006-01-11 12:17:49 -0800531 /*
532 ** The receive data process is to remove packets from the
533 ** PHB until there aren't any more or the current cblock
534 ** is full. When this occurs, there will be some left over
535 ** data in the packet, that we must do something with.
536 ** As we haven't unhooked the packet from the read list
537 ** yet, we can just leave the packet there, having first
538 ** made a note of how far we got. This means that we need
539 ** a pointer per port saying where we start taking the
540 ** data from - this will normally be zero, but when we
541 ** run out of space it will be set to the offset of the
542 ** next byte to copy from the packet data area. The packet
543 ** length field is decremented by the number of bytes that
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200544 ** we successfully removed from the packet. When this reaches
Andrew Morton8d8706e2006-01-11 12:17:49 -0800545 ** zero, we reset the offset pointer to be zero, and free
546 ** the packet from the front of the queue.
547 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
Andrew Morton8d8706e2006-01-11 12:17:49 -0800549 intCount++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
Andrew Morton8d8706e2006-01-11 12:17:49 -0800551 TtyP = PortP->gs.tty;
552 if (!TtyP) {
553 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
554 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800556
557 if (PortP->State & RIO_THROTTLE_RX) {
558 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
559 return;
560 }
561
562 if (PortP->State & RIO_DELETED) {
563 while (can_remove_receive(&PacketP, PortP)) {
564 remove_receive(PortP);
565 put_free_end(PortP->HostP, PacketP);
566 }
567 } else {
568 /*
569 ** loop, just so long as:
570 ** i ) there's some data ( i.e. can_remove_receive )
571 ** ii ) we haven't been blocked
572 ** iii ) there's somewhere to put the data
573 ** iv ) we haven't outstayed our welcome
574 */
575 transCount = 1;
576 while (can_remove_receive(&PacketP, PortP)
577 && transCount) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800578 RxIntCnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
Andrew Morton8d8706e2006-01-11 12:17:49 -0800580 /*
581 ** check that it is not a command!
582 */
Al Viro92af11c2006-05-27 02:24:14 -0400583 if (readb(&PacketP->len) & PKT_CMD_BIT) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800584 rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
585 /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
Al Viro92af11c2006-05-27 02:24:14 -0400586 rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit));
587 rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port));
588 rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit));
589 rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port));
590 rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len));
591 rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control));
592 rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800593 rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
594 for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
Al Viro92af11c2006-05-27 02:24:14 -0400595 rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800596 remove_receive(PortP);
597 put_free_end(PortP->HostP, PacketP);
598 continue; /* with next packet */
599 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
Andrew Morton8d8706e2006-01-11 12:17:49 -0800601 /*
602 ** How many characters can we move 'upstream' ?
603 **
604 ** Determine the minimum of the amount of data
605 ** available and the amount of space in which to
606 ** put it.
607 **
608 ** 1. Get the packet length by masking 'len'
609 ** for only the length bits.
610 ** 2. Available space is [buffer size] - [space used]
611 **
612 ** Transfer count is the minimum of packet length
613 ** and available space.
614 */
615
Al Viro92af11c2006-05-27 02:24:14 -0400616 transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800617 rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
618 /*
619 ** To use the following 'kkprintfs' for debugging - change the '#undef'
620 ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
621 ** driver).
622 */
Al Virod886cb52006-05-27 00:08:25 -0400623 ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
Andrew Morton8d8706e2006-01-11 12:17:49 -0800625 tty_prepare_flip_string(TtyP, &buf, transCount);
626 rio_memcpy_fromio(buf, ptr, transCount);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800627 PortP->RxDataStart += transCount;
Al Viro92af11c2006-05-27 02:24:14 -0400628 writeb(readb(&PacketP->len)-transCount, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800629 copied += transCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
631
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632
Al Viro92af11c2006-05-27 02:24:14 -0400633 if (readb(&PacketP->len) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 /*
Andrew Morton8d8706e2006-01-11 12:17:49 -0800635 ** If we have emptied the packet, then we can
636 ** free it, and reset the start pointer for
637 ** the next packet.
638 */
639 remove_receive(PortP);
640 put_free_end(PortP->HostP, PacketP);
641 PortP->RxDataStart = 0;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800642 }
643 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800645 if (copied) {
646 rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
647 tty_flip_buffer_push(TtyP);
648 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649
Andrew Morton8d8706e2006-01-11 12:17:49 -0800650 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651}
652