blob: ea21686c69a43293b41664546b134932e3837ca9 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <asm/uaccess.h>
46
47#include <linux/termios.h>
48#include <linux/serial.h>
49
50#include <linux/generic_serial.h>
51
52#include <linux/delay.h>
53
54#include "linux_compat.h"
55#include "rio_linux.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070056#include "pkt.h"
57#include "daemon.h"
58#include "rio.h"
59#include "riospace.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070060#include "cmdpkt.h"
61#include "map.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070062#include "rup.h"
63#include "port.h"
64#include "riodrvr.h"
65#include "rioinfo.h"
66#include "func.h"
67#include "errors.h"
68#include "pci.h"
69
70#include "parmmap.h"
71#include "unixrup.h"
72#include "board.h"
73#include "host.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070074#include "phb.h"
75#include "link.h"
76#include "cmdblk.h"
77#include "route.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070078#include "cirrus.h"
79#include "rioioctl.h"
80
81
82static void RIOReceive(struct rio_info *, struct Port *);
83
84
Andrew Morton8d8706e2006-01-11 12:17:49 -080085static char *firstchars(char *p, int nch)
Linus Torvalds1da177e2005-04-16 15:20:36 -070086{
Andrew Morton8d8706e2006-01-11 12:17:49 -080087 static char buf[2][128];
88 static int t = 0;
89 t = !t;
90 memcpy(buf[t], p, nch);
91 buf[t][nch] = 0;
92 return buf[t];
Linus Torvalds1da177e2005-04-16 15:20:36 -070093}
94
95
96#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask))
97/* Enable and start the transmission of packets */
Alan Cox00d83a52006-03-24 03:18:28 -080098void RIOTxEnable(char *en)
Linus Torvalds1da177e2005-04-16 15:20:36 -070099{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800100 struct Port *PortP;
101 struct rio_info *p;
102 struct tty_struct *tty;
103 int c;
Al Virod886cb52006-05-27 00:08:25 -0400104 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800105 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
Andrew Morton8d8706e2006-01-11 12:17:49 -0800107 PortP = (struct Port *) en;
108 p = (struct rio_info *) PortP->p;
109 tty = PortP->gs.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111
Andrew Morton8d8706e2006-01-11 12:17:49 -0800112 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 -0700113
Andrew Morton8d8706e2006-01-11 12:17:49 -0800114 if (!PortP->gs.xmit_cnt)
115 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
Andrew Morton8d8706e2006-01-11 12:17:49 -0800118 /* This routine is an order of magnitude simpler than the specialix
119 version. One of the disadvantages is that this version will send
120 an incomplete packet (usually 64 bytes instead of 72) once for
121 every 4k worth of data. Let's just say that this won't influence
122 performance significantly..... */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
Andrew Morton8d8706e2006-01-11 12:17:49 -0800124 rio_spin_lock_irqsave(&PortP->portSem, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Andrew Morton8d8706e2006-01-11 12:17:49 -0800126 while (can_add_transmit(&PacketP, PortP)) {
127 c = PortP->gs.xmit_cnt;
128 if (c > PKT_MAX_DATA_LEN)
129 c = PKT_MAX_DATA_LEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Andrew Morton8d8706e2006-01-11 12:17:49 -0800131 /* Don't copy past the end of the source buffer */
132 if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail)
133 c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134
Andrew Morton8d8706e2006-01-11 12:17:49 -0800135 {
136 int t;
137 t = (c > 10) ? 10 : c;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Andrew Morton8d8706e2006-01-11 12:17:49 -0800139 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));
140 }
141 /* If for one reason or another, we can't copy more data,
142 we're done! */
143 if (c == 0)
144 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
Al Virod886cb52006-05-27 00:08:25 -0400146 rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800147 /* udelay (1); */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
Andrew Morton8d8706e2006-01-11 12:17:49 -0800149 writeb(c, &(PacketP->len));
150 if (!(PortP->State & RIO_DELETED)) {
151 add_transmit(PortP);
152 /*
153 ** Count chars tx'd for port statistics reporting
154 */
155 if (PortP->statsGather)
156 PortP->txchars += c;
157 }
158 PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1);
159 PortP->gs.xmit_cnt -= c;
160 }
161
162 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
163
Jiri Slabyb963a842007-02-10 01:44:55 -0800164 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
165 tty_wakeup(PortP->gs.tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
167}
168
169
170/*
171** RIO Host Service routine. Does all the work traditionally associated with an
172** interrupt.
173*/
Andrew Morton8d8706e2006-01-11 12:17:49 -0800174static int RupIntr;
175static int RxIntr;
176static int TxIntr;
Alan Cox00d83a52006-03-24 03:18:28 -0800177
Jeff Garzikc7bec5a2006-10-06 15:00:58 -0400178void RIOServiceHost(struct rio_info *p, struct Host *HostP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800180 rio_spin_lock(&HostP->HostLock);
181 if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
182 static int t = 0;
183 rio_spin_unlock(&HostP->HostLock);
184 if ((t++ % 200) == 0)
185 rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags);
186 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800188 rio_spin_unlock(&HostP->HostLock);
189
Alan Cox00d83a52006-03-24 03:18:28 -0800190 if (readw(&HostP->ParmMapP->rup_intr)) {
191 writew(0, &HostP->ParmMapP->rup_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800192 p->RIORupCount++;
193 RupIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800194 rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800195 RIOPollHostCommands(p, HostP);
196 }
197
Alan Cox00d83a52006-03-24 03:18:28 -0800198 if (readw(&HostP->ParmMapP->rx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800199 int port;
200
Alan Cox00d83a52006-03-24 03:18:28 -0800201 writew(0, &HostP->ParmMapP->rx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800202 p->RIORxCount++;
203 RxIntr++;
204
Alan Cox00d83a52006-03-24 03:18:28 -0800205 rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800206 /*
207 ** Loop through every port. If the port is mapped into
208 ** the system ( i.e. has /dev/ttyXXXX associated ) then it is
209 ** worth checking. If the port isn't open, grab any packets
210 ** hanging on its receive queue and stuff them on the free
211 ** list; check for commands on the way.
212 */
213 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
214 struct Port *PortP = p->RIOPortp[port];
215 struct tty_struct *ttyP;
Al Virod886cb52006-05-27 00:08:25 -0400216 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800217
218 /*
219 ** not mapped in - most of the RIOPortp[] information
220 ** has not been set up!
221 ** Optimise: ports come in bundles of eight.
222 */
223 if (!PortP->Mapped) {
224 port += 7;
225 continue; /* with the next port */
226 }
227
228 /*
229 ** If the host board isn't THIS host board, check the next one.
230 ** optimise: ports come in bundles of eight.
231 */
232 if (PortP->HostP != HostP) {
233 port += 7;
234 continue;
235 }
236
237 /*
238 ** Let us see - is the port open? If not, then don't service it.
239 */
240 if (!(PortP->PortState & PORT_ISOPEN)) {
241 continue;
242 }
243
244 /*
245 ** find corresponding tty structure. The process of mapping
246 ** the ports puts these here.
247 */
248 ttyP = PortP->gs.tty;
249
250 /*
251 ** Lock the port before we begin working on it.
252 */
253 rio_spin_lock(&PortP->portSem);
254
255 /*
256 ** Process received data if there is any.
257 */
258 if (can_remove_receive(&PacketP, PortP))
259 RIOReceive(p, PortP);
260
261 /*
262 ** If there is no data left to be read from the port, and
263 ** it's handshake bit is set, then we must clear the handshake,
264 ** so that that downstream RTA is re-enabled.
265 */
Alan Cox00d83a52006-03-24 03:18:28 -0800266 if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800267 /*
268 ** MAGIC! ( Basically, handshake the RX buffer, so that
269 ** the RTAs upstream can be re-enabled. )
270 */
271 rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n");
Alan Cox00d83a52006-03-24 03:18:28 -0800272 writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800273 }
274 rio_spin_unlock(&PortP->portSem);
275 }
276 }
277
Alan Cox00d83a52006-03-24 03:18:28 -0800278 if (readw(&HostP->ParmMapP->tx_intr)) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800279 int port;
280
Alan Cox00d83a52006-03-24 03:18:28 -0800281 writew(0, &HostP->ParmMapP->tx_intr);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800282
283 p->RIOTxCount++;
284 TxIntr++;
Alan Cox00d83a52006-03-24 03:18:28 -0800285 rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800286
287 /*
288 ** Loop through every port.
289 ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX
290 ** associated ) then it is worth checking.
291 */
292 for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
293 struct Port *PortP = p->RIOPortp[port];
294 struct tty_struct *ttyP;
Al Virod886cb52006-05-27 00:08:25 -0400295 struct PKT __iomem *PacketP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800296
297 /*
298 ** not mapped in - most of the RIOPortp[] information
299 ** has not been set up!
300 */
301 if (!PortP->Mapped) {
302 port += 7;
303 continue; /* with the next port */
304 }
305
306 /*
307 ** If the host board isn't running, then its data structures
308 ** are no use to us - continue quietly.
309 */
310 if (PortP->HostP != HostP) {
311 port += 7;
312 continue; /* with the next port */
313 }
314
315 /*
316 ** Let us see - is the port open? If not, then don't service it.
317 */
318 if (!(PortP->PortState & PORT_ISOPEN)) {
319 continue;
320 }
321
322 rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
323 /*
324 ** Lock the port before we begin working on it.
325 */
326 rio_spin_lock(&PortP->portSem);
327
328 /*
329 ** If we can't add anything to the transmit queue, then
330 ** we need do none of this processing.
331 */
332 if (!can_add_transmit(&PacketP, PortP)) {
333 rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
334 rio_spin_unlock(&PortP->portSem);
335 continue;
336 }
337
338 /*
339 ** find corresponding tty structure. The process of mapping
340 ** the ports puts these here.
341 */
342 ttyP = PortP->gs.tty;
343 /* If ttyP is NULL, the port is getting closed. Forget about it. */
344 if (!ttyP) {
345 rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n");
346 rio_spin_unlock(&PortP->portSem);
347 continue;
348 }
349 /*
350 ** If there is more room available we start up the transmit
351 ** data process again. This can be direct I/O, if the cookmode
352 ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the
353 ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch
354 ** characters via the line discipline. We must always call
355 ** the line discipline,
356 ** so that user input characters can be echoed correctly.
357 **
358 ** ++++ Update +++++
359 ** With the advent of double buffering, we now see if
360 ** TxBufferOut-In is non-zero. If so, then we copy a packet
361 ** to the output place, and set it going. If this empties
362 ** the buffer, then we must issue a wakeup( ) on OUT.
363 ** If it frees space in the buffer then we must issue
364 ** a wakeup( ) on IN.
365 **
366 ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we
367 ** have to send a WFLUSH command down the PHB, to mark the
368 ** end point of a WFLUSH. We also need to clear out any
369 ** data from the double buffer! ( note that WflushFlag is a
370 ** *count* of the number of WFLUSH commands outstanding! )
371 **
372 ** ++++ And there's more!
373 ** If an RTA is powered off, then on again, and rebooted,
374 ** whilst it has ports open, then we need to re-open the ports.
375 ** ( reasonable enough ). We can't do this when we spot the
376 ** re-boot, in interrupt time, because the queue is probably
377 ** full. So, when we come in here, we need to test if any
378 ** ports are in this condition, and re-open the port before
379 ** we try to send any more data to it. Now, the re-booted
380 ** RTA will be discarding packets from the PHB until it
381 ** receives this open packet, but don't worry tooo much
382 ** about that. The one thing that is interesting is the
383 ** combination of this effect and the WFLUSH effect!
384 */
385 /* For now don't handle RTA reboots. -- REW.
386 Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */
387 if (PortP->MagicFlags) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800388 if (PortP->MagicFlags & MAGIC_REBOOT) {
389 /*
390 ** well, the RTA has been rebooted, and there is room
391 ** on its queue to add the open packet that is required.
392 **
393 ** The messy part of this line is trying to decide if
394 ** we need to call the Param function as a tty or as
395 ** a modem.
396 ** DONT USE CLOCAL AS A TEST FOR THIS!
397 **
398 ** If we can't param the port, then move on to the
399 ** next port.
400 */
401 PortP->InUse = NOT_INUSE;
402
403 rio_spin_unlock(&PortP->portSem);
Jiri Slabyd6f63412008-04-30 00:53:57 -0700404 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 -0800405 continue; /* with next port */
Andrew Morton8d8706e2006-01-11 12:17:49 -0800406 rio_spin_lock(&PortP->portSem);
407 PortP->MagicFlags &= ~MAGIC_REBOOT;
408 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Andrew Morton8d8706e2006-01-11 12:17:49 -0800410 /*
411 ** As mentioned above, this is a tacky hack to cope
412 ** with WFLUSH
413 */
414 if (PortP->WflushFlag) {
415 rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Andrew Morton8d8706e2006-01-11 12:17:49 -0800417 if (PortP->InUse)
418 rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
419 }
420
421 while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) {
422 int p;
Al Virod886cb52006-05-27 00:08:25 -0400423 struct PktCmd __iomem *PktCmdP;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800424
425 rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
426 /*
427 ** make it look just like a WFLUSH command
428 */
Al Virod886cb52006-05-27 00:08:25 -0400429 PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
Andrew Morton8d8706e2006-01-11 12:17:49 -0800430
Jiri Slabyd6f63412008-04-30 00:53:57 -0700431 writeb(RIOC_WFLUSH, &PktCmdP->Command);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800432
Alan Cox00d83a52006-03-24 03:18:28 -0800433 p = PortP->HostPort % (u16) PORTS_PER_RTA;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800434
435 /*
436 ** If second block of ports for 16 port RTA, add 8
437 ** to index 8-15.
438 */
439 if (PortP->SecondBlock)
440 p += PORTS_PER_RTA;
441
Alan Cox00d83a52006-03-24 03:18:28 -0800442 writeb(p, &PktCmdP->PhbNum);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800443
444 /*
445 ** to make debuggery easier
446 */
Alan Cox00d83a52006-03-24 03:18:28 -0800447 writeb('W', &PacketP->data[2]);
448 writeb('F', &PacketP->data[3]);
449 writeb('L', &PacketP->data[4]);
450 writeb('U', &PacketP->data[5]);
451 writeb('S', &PacketP->data[6]);
452 writeb('H', &PacketP->data[7]);
453 writeb(' ', &PacketP->data[8]);
454 writeb('0' + PortP->WflushFlag, &PacketP->data[9]);
455 writeb(' ', &PacketP->data[10]);
456 writeb(' ', &PacketP->data[11]);
457 writeb('\0', &PacketP->data[12]);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800458
459 /*
460 ** its two bytes long!
461 */
Alan Cox00d83a52006-03-24 03:18:28 -0800462 writeb(PKT_CMD_BIT | 2, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800463
464 /*
465 ** queue it!
466 */
467 if (!(PortP->State & RIO_DELETED)) {
468 add_transmit(PortP);
469 /*
470 ** Count chars tx'd for port statistics reporting
471 */
472 if (PortP->statsGather)
473 PortP->txchars += 2;
474 }
475
476 if (--(PortP->WflushFlag) == 0) {
477 PortP->MagicFlags &= ~MAGIC_FLUSH;
478 }
479
480 rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag);
481 }
482 if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) {
483 if (PortP->MagicFlags & MAGIC_FLUSH) {
484 PortP->MagicFlags |= MORE_OUTPUT_EYGOR;
485 } else {
486 if (!can_add_transmit(&PacketP, PortP)) {
487 rio_spin_unlock(&PortP->portSem);
488 continue;
489 }
490 rio_spin_unlock(&PortP->portSem);
491 RIOTxEnable((char *) PortP);
492 rio_spin_lock(&PortP->portSem);
493 PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;
494 }
495 }
496 }
497
498
499 /*
500 ** If we can't add anything to the transmit queue, then
501 ** we need do none of the remaining processing.
502 */
503 if (!can_add_transmit(&PacketP, PortP)) {
504 rio_spin_unlock(&PortP->portSem);
505 continue;
506 }
507
508 rio_spin_unlock(&PortP->portSem);
509 RIOTxEnable((char *) PortP);
510 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512}
513
514/*
Alan Cox00d83a52006-03-24 03:18:28 -0800515** Routine for handling received data for tty drivers
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516*/
Alan Cox00d83a52006-03-24 03:18:28 -0800517static void RIOReceive(struct rio_info *p, struct Port *PortP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518{
Andrew Morton8d8706e2006-01-11 12:17:49 -0800519 struct tty_struct *TtyP;
Alan Cox00d83a52006-03-24 03:18:28 -0800520 unsigned short transCount;
Al Virod886cb52006-05-27 00:08:25 -0400521 struct PKT __iomem *PacketP;
Alan Cox00d83a52006-03-24 03:18:28 -0800522 register unsigned int DataCnt;
Al Virod886cb52006-05-27 00:08:25 -0400523 unsigned char __iomem *ptr;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800524 unsigned char *buf;
525 int copied = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
Andrew Morton8d8706e2006-01-11 12:17:49 -0800527 static int intCount, RxIntCnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Andrew Morton8d8706e2006-01-11 12:17:49 -0800529 /*
530 ** The receive data process is to remove packets from the
531 ** PHB until there aren't any more or the current cblock
532 ** is full. When this occurs, there will be some left over
533 ** data in the packet, that we must do something with.
534 ** As we haven't unhooked the packet from the read list
535 ** yet, we can just leave the packet there, having first
536 ** made a note of how far we got. This means that we need
537 ** a pointer per port saying where we start taking the
538 ** data from - this will normally be zero, but when we
539 ** run out of space it will be set to the offset of the
540 ** next byte to copy from the packet data area. The packet
541 ** length field is decremented by the number of bytes that
Andreas Mohrd6e05ed2006-06-26 18:35:02 +0200542 ** we successfully removed from the packet. When this reaches
Andrew Morton8d8706e2006-01-11 12:17:49 -0800543 ** zero, we reset the offset pointer to be zero, and free
544 ** the packet from the front of the queue.
545 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
Andrew Morton8d8706e2006-01-11 12:17:49 -0800547 intCount++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
Andrew Morton8d8706e2006-01-11 12:17:49 -0800549 TtyP = PortP->gs.tty;
550 if (!TtyP) {
551 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
552 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800554
555 if (PortP->State & RIO_THROTTLE_RX) {
556 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
557 return;
558 }
559
560 if (PortP->State & RIO_DELETED) {
561 while (can_remove_receive(&PacketP, PortP)) {
562 remove_receive(PortP);
563 put_free_end(PortP->HostP, PacketP);
564 }
565 } else {
566 /*
567 ** loop, just so long as:
568 ** i ) there's some data ( i.e. can_remove_receive )
569 ** ii ) we haven't been blocked
570 ** iii ) there's somewhere to put the data
571 ** iv ) we haven't outstayed our welcome
572 */
573 transCount = 1;
574 while (can_remove_receive(&PacketP, PortP)
575 && transCount) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800576 RxIntCnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577
Andrew Morton8d8706e2006-01-11 12:17:49 -0800578 /*
579 ** check that it is not a command!
580 */
Al Viro92af11c2006-05-27 02:24:14 -0400581 if (readb(&PacketP->len) & PKT_CMD_BIT) {
Andrew Morton8d8706e2006-01-11 12:17:49 -0800582 rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
583 /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
Al Viro92af11c2006-05-27 02:24:14 -0400584 rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit));
585 rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port));
586 rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit));
587 rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port));
588 rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len));
589 rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control));
590 rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800591 rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
592 for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
Al Viro92af11c2006-05-27 02:24:14 -0400593 rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
Andrew Morton8d8706e2006-01-11 12:17:49 -0800594 remove_receive(PortP);
595 put_free_end(PortP->HostP, PacketP);
596 continue; /* with next packet */
597 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
Andrew Morton8d8706e2006-01-11 12:17:49 -0800599 /*
600 ** How many characters can we move 'upstream' ?
601 **
602 ** Determine the minimum of the amount of data
603 ** available and the amount of space in which to
604 ** put it.
605 **
606 ** 1. Get the packet length by masking 'len'
607 ** for only the length bits.
608 ** 2. Available space is [buffer size] - [space used]
609 **
610 ** Transfer count is the minimum of packet length
611 ** and available space.
612 */
613
Al Viro92af11c2006-05-27 02:24:14 -0400614 transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800615 rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
616 /*
617 ** To use the following 'kkprintfs' for debugging - change the '#undef'
618 ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
619 ** driver).
620 */
Al Virod886cb52006-05-27 00:08:25 -0400621 ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Andrew Morton8d8706e2006-01-11 12:17:49 -0800623 tty_prepare_flip_string(TtyP, &buf, transCount);
624 rio_memcpy_fromio(buf, ptr, transCount);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800625 PortP->RxDataStart += transCount;
Al Viro92af11c2006-05-27 02:24:14 -0400626 writeb(readb(&PacketP->len)-transCount, &PacketP->len);
Andrew Morton8d8706e2006-01-11 12:17:49 -0800627 copied += transCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628
629
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
Al Viro92af11c2006-05-27 02:24:14 -0400631 if (readb(&PacketP->len) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 /*
Andrew Morton8d8706e2006-01-11 12:17:49 -0800633 ** If we have emptied the packet, then we can
634 ** free it, and reset the start pointer for
635 ** the next packet.
636 */
637 remove_receive(PortP);
638 put_free_end(PortP->HostP, PacketP);
639 PortP->RxDataStart = 0;
Andrew Morton8d8706e2006-01-11 12:17:49 -0800640 }
641 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 }
Andrew Morton8d8706e2006-01-11 12:17:49 -0800643 if (copied) {
644 rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
645 tty_flip_buffer_push(TtyP);
646 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Andrew Morton8d8706e2006-01-11 12:17:49 -0800648 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649}
650