Coarsly sort out 32-bit-only, 64-bit-only and ``portable'' MIPS lib/
[linux-2.6/linux-mips.git] / drivers / char / rio / riocmd.c
blobf83f15ca6fe1234faa48b37475ac29ee25c75427
1 /*
2 ** -----------------------------------------------------------------------------
3 **
4 ** Perle Specialix driver for Linux
5 ** ported from the existing SCO driver source
6 **
8 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 ** Module : riocmd.c
25 ** SID : 1.2
26 ** Last Modified : 11/6/98 10:33:41
27 ** Retrieved : 11/6/98 10:33:49
29 ** ident @(#)riocmd.c 1.2
31 ** -----------------------------------------------------------------------------
33 #ifdef SCCS_LABELS
34 static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2";
35 #endif
37 #include <linux/module.h>
38 #include <linux/slab.h>
39 #include <linux/errno.h>
40 #include <linux/tty.h>
41 #include <asm/io.h>
42 #include <asm/system.h>
43 #include <asm/string.h>
44 #include <asm/semaphore.h>
46 #include <linux/termios.h>
47 #include <linux/serial.h>
49 #include <linux/generic_serial.h>
51 #include "linux_compat.h"
52 #include "rio_linux.h"
53 #include "typdef.h"
54 #include "pkt.h"
55 #include "daemon.h"
56 #include "rio.h"
57 #include "riospace.h"
58 #include "top.h"
59 #include "cmdpkt.h"
60 #include "map.h"
61 #include "riotypes.h"
62 #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"
70 #include "parmmap.h"
71 #include "unixrup.h"
72 #include "board.h"
73 #include "host.h"
74 #include "error.h"
75 #include "phb.h"
76 #include "link.h"
77 #include "cmdblk.h"
78 #include "route.h"
79 #include "control.h"
80 #include "cirrus.h"
83 static struct IdentifyRta IdRta;
84 static struct KillNeighbour KillUnit;
86 int
87 RIOFoadRta(HostP, MapP)
88 struct Host * HostP;
89 struct Map * MapP;
91 struct CmdBlk *CmdBlkP;
93 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA\n");
95 CmdBlkP = RIOGetCmdBlk();
97 if ( !CmdBlkP ) {
98 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n");
99 return -ENXIO;
102 CmdBlkP->Packet.dest_unit = MapP->ID;
103 CmdBlkP->Packet.dest_port = BOOT_RUP;
104 CmdBlkP->Packet.src_unit = 0;
105 CmdBlkP->Packet.src_port = BOOT_RUP;
106 CmdBlkP->Packet.len = 0x84;
107 CmdBlkP->Packet.data[0] = IFOAD;
108 CmdBlkP->Packet.data[1] = 0;
109 CmdBlkP->Packet.data[2] = IFOAD_MAGIC & 0xFF;
110 CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF;
112 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
113 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n");
114 return -EIO;
116 return 0;
120 RIOZombieRta(HostP, MapP)
121 struct Host * HostP;
122 struct Map * MapP;
124 struct CmdBlk *CmdBlkP;
126 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA\n");
128 CmdBlkP = RIOGetCmdBlk();
130 if ( !CmdBlkP ) {
131 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n");
132 return -ENXIO;
135 CmdBlkP->Packet.dest_unit = MapP->ID;
136 CmdBlkP->Packet.dest_port = BOOT_RUP;
137 CmdBlkP->Packet.src_unit = 0;
138 CmdBlkP->Packet.src_port = BOOT_RUP;
139 CmdBlkP->Packet.len = 0x84;
140 CmdBlkP->Packet.data[0] = ZOMBIE;
141 CmdBlkP->Packet.data[1] = 0;
142 CmdBlkP->Packet.data[2] = ZOMBIE_MAGIC & 0xFF;
143 CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF;
145 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
146 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n");
147 return -EIO;
149 return 0;
153 RIOCommandRta(p, RtaUnique, func)
154 struct rio_info * p;
155 uint RtaUnique;
156 int (* func)( struct Host *HostP, struct Map *MapP );
158 uint Host;
160 rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func);
162 if ( !RtaUnique )
163 return(0);
165 for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
166 uint Rta;
167 struct Host *HostP = &p->RIOHosts[Host];
169 for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
170 struct Map *MapP = &HostP->Mapping[Rta];
172 if ( MapP->RtaUniqueNum == RtaUnique ) {
173 uint Link;
176 ** now, lets just check we have a route to it...
177 ** IF the routing stuff is working, then one of the
178 ** topology entries for this unit will have a legit
179 ** route *somewhere*. We care not where - if its got
180 ** any connections, we can get to it.
182 for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
183 if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
185 ** Its worth trying the operation...
187 return (*func)( HostP, MapP );
193 return -ENXIO;
198 RIOIdentifyRta(p, arg)
199 struct rio_info * p;
200 caddr_t arg;
202 uint Host;
204 if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) {
205 rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n");
206 p->RIOError.Error = COPYIN_FAILED;
207 return -EFAULT;
210 for ( Host = 0 ; Host < p->RIONumHosts; Host++ ) {
211 uint Rta;
212 struct Host *HostP = &p->RIOHosts[Host];
214 for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
215 struct Map *MapP = &HostP->Mapping[Rta];
217 if ( MapP->RtaUniqueNum == IdRta.RtaUnique ) {
218 uint Link;
220 ** now, lets just check we have a route to it...
221 ** IF the routing stuff is working, then one of the
222 ** topology entries for this unit will have a legit
223 ** route *somewhere*. We care not where - if its got
224 ** any connections, we can get to it.
226 for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
227 if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
229 ** Its worth trying the operation...
231 struct CmdBlk *CmdBlkP;
233 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA\n");
235 CmdBlkP = RIOGetCmdBlk();
237 if ( !CmdBlkP ) {
238 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n");
239 return -ENXIO;
242 CmdBlkP->Packet.dest_unit = MapP->ID;
243 CmdBlkP->Packet.dest_port = BOOT_RUP;
244 CmdBlkP->Packet.src_unit = 0;
245 CmdBlkP->Packet.src_port = BOOT_RUP;
246 CmdBlkP->Packet.len = 0x84;
247 CmdBlkP->Packet.data[0] = IDENTIFY;
248 CmdBlkP->Packet.data[1] = 0;
249 CmdBlkP->Packet.data[2] = IdRta.ID;
251 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
252 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n");
253 return -EIO;
255 return 0;
261 return -ENOENT;
266 RIOKillNeighbour(p, arg)
267 struct rio_info * p;
268 caddr_t arg;
270 uint Host;
271 uint ID;
272 struct Host *HostP;
273 struct CmdBlk *CmdBlkP;
275 rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n");
277 if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) {
278 rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n");
279 p->RIOError.Error = COPYIN_FAILED;
280 return -EFAULT;
283 if ( KillUnit.Link > 3 )
284 return -ENXIO;
286 CmdBlkP = RIOGetCmdBlk();
288 if ( !CmdBlkP ) {
289 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n");
290 return -ENXIO;
293 CmdBlkP->Packet.dest_unit = 0;
294 CmdBlkP->Packet.src_unit = 0;
295 CmdBlkP->Packet.dest_port = BOOT_RUP;
296 CmdBlkP->Packet.src_port = BOOT_RUP;
297 CmdBlkP->Packet.len = 0x84;
298 CmdBlkP->Packet.data[0] = UFOAD;
299 CmdBlkP->Packet.data[1] = KillUnit.Link;
300 CmdBlkP->Packet.data[2] = UFOAD_MAGIC & 0xFF;
301 CmdBlkP->Packet.data[3] = (UFOAD_MAGIC >> 8) & 0xFF;
303 for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
304 ID = 0;
305 HostP = &p->RIOHosts[Host];
307 if ( HostP->UniqueNum == KillUnit.UniqueNum ) {
308 if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link,
309 CmdBlkP) == RIO_FAIL ) {
310 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
311 return -EIO;
313 return 0;
316 for ( ID=0; ID < RTAS_PER_HOST; ID++ ) {
317 if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) {
318 CmdBlkP->Packet.dest_unit = ID+1;
319 if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) {
320 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
321 return -EIO;
323 return 0;
327 RIOFreeCmdBlk( CmdBlkP );
328 return -ENXIO;
332 RIOSuspendBootRta(HostP, ID, Link)
333 struct Host *HostP;
334 int ID;
335 int Link;
337 struct CmdBlk *CmdBlkP;
339 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link);
341 CmdBlkP = RIOGetCmdBlk();
343 if ( !CmdBlkP ) {
344 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n");
345 return -ENXIO;
348 CmdBlkP->Packet.dest_unit = ID;
349 CmdBlkP->Packet.dest_port = BOOT_RUP;
350 CmdBlkP->Packet.src_unit = 0;
351 CmdBlkP->Packet.src_port = BOOT_RUP;
352 CmdBlkP->Packet.len = 0x84;
353 CmdBlkP->Packet.data[0] = IWAIT;
354 CmdBlkP->Packet.data[1] = Link;
355 CmdBlkP->Packet.data[2] = IWAIT_MAGIC & 0xFF;
356 CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF;
358 if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) {
359 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n");
360 return -EIO;
362 return 0;
366 RIOFoadWakeup(p)
367 struct rio_info * p;
369 int port;
370 register struct Port *PortP;
371 unsigned long flags;
373 for ( port=0; port<RIO_PORTS; port++) {
374 PortP = p->RIOPortp[port];
376 rio_spin_lock_irqsave(&PortP->portSem, flags);
377 PortP->Config = 0;
378 PortP->State = 0;
379 PortP->InUse = NOT_INUSE;
380 PortP->PortState = 0;
381 PortP->FlushCmdBodge = 0;
382 PortP->ModemLines = 0;
383 PortP->ModemState = 0;
384 PortP->CookMode = 0;
385 PortP->ParamSem = 0;
386 PortP->Mapped = 0;
387 PortP->WflushFlag = 0;
388 PortP->MagicFlags = 0;
389 PortP->RxDataStart = 0;
390 PortP->TxBufferIn = 0;
391 PortP->TxBufferOut = 0;
392 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
394 return(0);
398 ** Incoming command on the COMMAND_RUP to be processed.
401 RIOCommandRup(p, Rup, HostP, PacketP)
402 struct rio_info * p;
403 uint Rup;
404 struct Host *HostP;
405 PKT *PacketP;
407 struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;
408 struct Port *PortP;
409 struct UnixRup *UnixRupP;
410 ushort SysPort;
411 ushort ReportedModemStatus;
412 ushort rup;
413 ushort subCommand;
414 unsigned long flags;
416 func_enter ();
418 #ifdef CHECK
419 CheckHost( Host );
420 CheckHostP( HostP );
421 CheckPacketP( PacketP );
422 #endif
425 ** 16 port RTA note:
426 ** Command rup packets coming from the RTA will have pkt->data[1] (which
427 ** translates to PktCmdP->PhbNum) set to the host port number for the
428 ** particular unit. To access the correct BaseSysPort for a 16 port RTA,
429 ** we can use PhbNum to get the rup number for the appropriate 8 port
430 ** block (for the first block, this should be equal to 'Rup').
432 rup = RBYTE(PktCmdP->PhbNum) / (ushort)PORTS_PER_RTA;
433 UnixRupP = &HostP->UnixRups[rup];
434 SysPort = UnixRupP->BaseSysPort +
435 (RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);
436 rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);
438 #ifdef CHECK
439 CheckRup( rup );
440 CheckUnixRupP( UnixRupP );
441 #endif
442 if ( UnixRupP->BaseSysPort == NO_PORT ) {
443 rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
444 rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
445 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n",
446 HostP-p->RIOHosts, HostP->Name );
447 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup);
449 if ( Rup >= (ushort)MAX_RUP ) {
450 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n",
451 HostP->Mapping[Rup].Name);
452 } else
453 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n",
454 ('A' + Rup - MAX_RUP), HostP->Name);
456 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n",
457 PacketP->dest_unit, PacketP->dest_port );
458 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n",
459 PacketP->src_unit, PacketP->src_port );
460 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", PacketP->len,PacketP->len );
461 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", PacketP->control, PacketP->control);
462 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", PacketP->csum, PacketP->csum );
463 rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, "
464 "Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command );
465 return TRUE;
468 #ifdef CHECK
469 CheckSysPort( SysPort );
470 #endif
471 PortP = p->RIOPortp[ SysPort ];
472 rio_spin_lock_irqsave(&PortP->portSem, flags);
473 switch( RBYTE(PktCmdP->Command) ) {
474 case BREAK_RECEIVED:
475 rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n");
476 /* If the current line disc. is not multi-threading and
477 the current processor is not the default, reset rup_intr
478 and return FALSE to ensure that the command packet is
479 not freed. */
480 /* Call tmgr HANGUP HERE */
481 /* Fix this later when every thing works !!!! RAMRAJ */
482 gs_got_break (&PortP->gs);
483 break;
485 case COMPLETE:
486 rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n",
487 RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);
488 subCommand = 1;
489 switch (RBYTE(PktCmdP->SubCommand)) {
490 case MEMDUMP :
491 rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n",
492 RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));
493 break;
494 case READ_REGISTER :
495 rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr));
496 p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);
497 break;
498 default :
499 subCommand = 0;
500 break;
502 if (subCommand)
503 break;
504 rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n",
505 RBYTE(PktCmdP->PortStatus),PortP->PortState);
506 if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {
507 rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n");
508 PortP->PortState = RBYTE(PktCmdP->PortStatus);
509 /* What should we do here ...
510 wakeup( &PortP->PortState );
512 } else
513 rio_dprintk (RIO_DEBUG_CMD, "No change\n");
515 /* FALLTHROUGH */
516 case MODEM_STATUS:
518 ** Knock out the tbusy and tstop bits, as these are not relevant
519 ** to the check for modem status change (they're just there because
520 ** it's a convenient place to put them!).
522 ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);
523 if ((PortP->ModemState & MSVR1_HOST) ==
524 (ReportedModemStatus & MSVR1_HOST)) {
525 rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
527 ** Update ModemState just in case tbusy or tstop states have
528 ** changed.
530 PortP->ModemState = ReportedModemStatus;
532 else {
533 rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n",
534 PortP->ModemState, ReportedModemStatus);
535 PortP->ModemState = ReportedModemStatus;
536 #ifdef MODEM_SUPPORT
537 if ( PortP->Mapped ) {
538 /***********************************************************\
539 *************************************************************
540 *** ***
541 *** M O D E M S T A T E C H A N G E ***
542 *** ***
543 *************************************************************
544 \***********************************************************/
546 ** If the device is a modem, then check the modem
547 ** carrier.
549 if (PortP->gs.tty == NULL)
550 break;
551 if (PortP->gs.tty->termios == NULL)
552 break;
554 if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
555 ((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {
557 rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n");
559 ** Is there a carrier?
561 if ( PortP->ModemState & MSVR1_CD ) {
563 ** Has carrier just appeared?
565 if (!(PortP->State & RIO_CARR_ON)) {
566 rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n");
567 PortP->State |= RIO_CARR_ON;
569 ** wakeup anyone in WOPEN
571 if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )
572 wake_up_interruptible (&PortP->gs.open_wait);
573 #ifdef STATS
574 PortP->Stat.ModemOnCnt++;
575 #endif
577 } else {
579 ** Has carrier just dropped?
581 if (PortP->State & RIO_CARR_ON) {
582 if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))
583 tty_hangup (PortP->gs.tty);
584 PortP->State &= ~RIO_CARR_ON;
585 rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n");
586 #ifdef STATS
587 PortP->Stat.ModemOffCnt++;
588 #endif
593 #endif
595 break;
597 default:
598 rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n",
599 RBYTE(PktCmdP->Command),HostP-p->RIOHosts);
600 break;
602 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
604 func_exit ();
606 return TRUE;
609 ** The command mechanism:
610 ** Each rup has a chain of commands associated with it.
611 ** This chain is maintained by routines in this file.
612 ** Periodically we are called and we run a quick check of all the
613 ** active chains to determine if there is a command to be executed,
614 ** and if the rup is ready to accept it.
619 ** Allocate an empty command block.
621 struct CmdBlk *
622 RIOGetCmdBlk()
624 struct CmdBlk *CmdBlkP;
626 CmdBlkP = (struct CmdBlk *)sysbrk(sizeof(struct CmdBlk));
627 if (CmdBlkP)
628 bzero(CmdBlkP, sizeof(struct CmdBlk));
630 return CmdBlkP;
634 ** Return a block to the head of the free list.
636 void
637 RIOFreeCmdBlk(CmdBlkP)
638 struct CmdBlk *CmdBlkP;
640 sysfree((void *)CmdBlkP, sizeof(struct CmdBlk));
644 ** attach a command block to the list of commands to be performed for
645 ** a given rup.
648 RIOQueueCmdBlk(HostP, Rup, CmdBlkP)
649 struct Host *HostP;
650 uint Rup;
651 struct CmdBlk *CmdBlkP;
653 struct CmdBlk **Base;
654 struct UnixRup *UnixRupP;
655 unsigned long flags;
657 #ifdef CHECK
658 CheckHostP( HostP );
659 CheckRup( Rup );
660 CheckCmdBlkP( CmdBlkP );
661 #endif
662 if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {
663 rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup);
664 RIOFreeCmdBlk( CmdBlkP );
665 return RIO_FAIL;
668 UnixRupP = &HostP->UnixRups[Rup];
670 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
673 ** If the RUP is currently inactive, then put the request
674 ** straight on the RUP....
676 if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) &&
677 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&
678 (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)
679 :TRUE)) {
680 rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
681 CmdBlkP->Packet.data[0]);
685 ** Whammy! blat that pack!
687 HostP->Copy( (caddr_t)&CmdBlkP->Packet,
688 RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt ), sizeof(PKT) );
691 ** place command packet on the pending position.
693 UnixRupP->CmdPendingP = CmdBlkP;
696 ** set the command register
698 WWORD(UnixRupP->RupP->txcontrol , TX_PACKET_READY);
700 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
702 return RIO_SUCCESS;
704 rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n");
706 if ( UnixRupP->CmdsWaitingP != NULL)
707 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n");
708 if ( UnixRupP->CmdPendingP != NULL )
709 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n");
710 if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )
711 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n");
713 Base = &UnixRupP->CmdsWaitingP;
715 rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base);
717 while ( *Base ) {
718 rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base));
719 Base = &((*Base)->NextP);
720 rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%x\n",
721 (int)CmdBlkP,(int)Base);
724 rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base);
726 *Base = CmdBlkP;
728 CmdBlkP->NextP = NULL;
730 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
732 return RIO_SUCCESS;
736 ** Here we go - if there is an empty rup, fill it!
737 ** must be called at splrio() or higher.
739 void
740 RIOPollHostCommands(p, HostP)
741 struct rio_info * p;
742 struct Host * HostP;
744 register struct CmdBlk *CmdBlkP;
745 register struct UnixRup *UnixRupP;
746 struct PKT *PacketP;
747 ushort Rup;
748 unsigned long flags;
751 Rup = MAX_RUP+LINKS_PER_UNIT;
753 do { /* do this loop for each RUP */
755 ** locate the rup we are processing & lock it
757 UnixRupP = &HostP->UnixRups[--Rup];
759 spin_lock_irqsave(&UnixRupP->RupLock, flags);
762 ** First check for incoming commands:
764 if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) {
765 int FreeMe;
767 PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt));
769 ShowPacket( DBG_CMD, PacketP );
771 switch ( RBYTE(PacketP->dest_port) ) {
772 case BOOT_RUP:
773 rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n",
774 RBYTE(PacketP->len) & 0x80 ? "Command":"Data",
775 RBYTE(PacketP->data[0]));
776 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
777 FreeMe= RIOBootRup(p, Rup,HostP,PacketP);
778 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
779 break;
781 case COMMAND_RUP:
783 ** Free the RUP lock as loss of carrier causes a
784 ** ttyflush which will (eventually) call another
785 ** routine that uses the RUP lock.
787 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
788 FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
789 if (PacketP->data[5] == MEMDUMP) {
790 rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n",
791 *(ushort *) &(PacketP->data[6]));
792 HostP->Copy( (caddr_t)&(PacketP->data[8]),
793 (caddr_t)p->RIOMemDump, 32 );
795 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
796 break;
798 case ROUTE_RUP:
799 rio_spin_unlock_irqrestore( &UnixRupP->RupLock, flags);
800 FreeMe = RIORouteRup(p, Rup, HostP, PacketP );
801 rio_spin_lock_irqsave( &UnixRupP->RupLock, flags );
802 break;
804 default:
805 rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %d\n", RBYTE(PacketP->dest_port));
806 FreeMe = 1;
807 break;
810 if ( FreeMe ) {
811 rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packet\n");
812 put_free_end(HostP,PacketP);
814 WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE);
816 if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) {
817 rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %d\n",Rup);
818 WWORD(UnixRupP->RupP->handshake,
819 PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
825 ** IF a command was running on the port,
826 ** and it has completed, then tidy it up.
828 if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
829 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
831 ** we are idle.
832 ** there is a command in pending.
833 ** Therefore, this command has finished.
834 ** So, wakeup whoever is waiting for it (and tell them
835 ** what happened).
837 if ( CmdBlkP->Packet.dest_port == BOOT_RUP )
838 rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n",
839 CmdBlkP->Packet.len & 0x80 ? "Command":"Data",
840 CmdBlkP->Packet.data[0]);
842 rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completed\n",(int)CmdBlkP);
845 ** Clear the Rup lock to prevent mutual exclusion.
847 if ( CmdBlkP->PostFuncP ) {
848 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
849 (*CmdBlkP->PostFuncP) (CmdBlkP->PostArg,CmdBlkP);
850 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
854 ** ....clear the pending flag....
856 UnixRupP->CmdPendingP = NULL;
859 ** ....and return the command block to the freelist.
861 RIOFreeCmdBlk( CmdBlkP );
865 ** If there is a command for this rup, and the rup
866 ** is idle, then process the command
868 if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
869 (UnixRupP->CmdPendingP == NULL) &&
870 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
872 ** if the pre-function is non-zero, call it.
873 ** If it returns RIO_FAIL then don't
874 ** send this command yet!
876 #ifdef CHECK
877 CheckCmdBlkP (CmdBlkP);
878 #endif
879 if ( !(CmdBlkP->PreFuncP ?
880 (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) {
881 rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%x\n",(int)CmdBlkP);
883 else {
884 rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%x\n",
885 (int)CmdBlkP, CmdBlkP->Packet.data[0]);
887 ** Whammy! blat that pack!
889 #ifdef CHECK
890 CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt));
891 #endif
892 HostP->Copy( (caddr_t)&CmdBlkP->Packet,
893 RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT));
896 ** remove the command from the rup command queue...
898 UnixRupP->CmdsWaitingP = CmdBlkP->NextP;
901 ** ...and place it on the pending position.
903 UnixRupP->CmdPendingP = CmdBlkP;
906 ** set the command register
908 WWORD(UnixRupP->RupP->txcontrol,TX_PACKET_READY);
911 ** the command block will be freed
912 ** when the command has been processed.
916 spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
917 } while ( Rup );
922 ** Return the length of the named string
925 RIOStrlen(Str)
926 register char *Str;
928 register int len = 0;
930 while ( *Str++ )
931 len++;
932 return len;
936 ** compares s1 to s2 and return 0 if they match.
939 RIOStrCmp(s1, s2)
940 register char *s1;
941 register char *s2;
943 while ( *s1 && *s2 && *s1==*s2 )
944 s1++, s2++;
945 return *s1-*s2;
949 ** compares s1 to s2 for upto n bytes and return 0 if they match.
952 RIOStrnCmp(s1, s2, n)
953 register char *s1;
954 register char *s2;
955 int n;
957 while ( n && *s1 && *s2 && *s1==*s2 )
958 n--, s1++, s2++;
959 return n ? *s1!=*s2 : 0;
963 ** copy up to 'len' bytes from 'from' to 'to'.
965 void
966 RIOStrNCpy(to, from, len)
967 char *to;
968 char *from;
969 int len;
971 while ( len-- && (*to++ = *from++) )
973 to[-1]='\0';
977 RIOWFlushMark(iPortP, CmdBlkP)
978 int iPortP;
979 struct CmdBlk *CmdBlkP;
981 struct Port * PortP = (struct Port *)iPortP;
982 unsigned long flags;
984 rio_spin_lock_irqsave(&PortP->portSem, flags);
985 #ifdef CHECK
986 CheckPortP( PortP );
987 #endif
988 PortP->WflushFlag++;
989 PortP->MagicFlags |= MAGIC_FLUSH;
990 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
991 return RIOUnUse( iPortP, CmdBlkP );
995 RIORFlushEnable(iPortP, CmdBlkP)
996 int iPortP;
997 struct CmdBlk *CmdBlkP;
999 struct Port * PortP = (struct Port *)iPortP;
1000 PKT *PacketP;
1001 unsigned long flags;
1003 rio_spin_lock_irqsave(&PortP->portSem, flags);
1005 while ( can_remove_receive(&PacketP, PortP) ) {
1006 remove_receive(PortP);
1007 ShowPacket(DBG_PROC, PacketP );
1008 put_free_end( PortP->HostP, PacketP );
1011 if ( RWORD(PortP->PhbP->handshake)==PHB_HANDSHAKE_SET ) {
1013 ** MAGIC! (Basically, handshake the RX buffer, so that
1014 ** the RTAs upstream can be re-enabled.)
1016 rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bit\n");
1017 WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
1019 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1020 return RIOUnUse( iPortP, CmdBlkP );
1024 RIOUnUse(iPortP, CmdBlkP)
1025 int iPortP;
1026 struct CmdBlk *CmdBlkP;
1028 struct Port * PortP = (struct Port *)iPortP;
1029 unsigned long flags;
1031 rio_spin_lock_irqsave(&PortP->portSem, flags);
1033 #ifdef CHECK
1034 CheckPortP( PortP );
1035 #endif
1036 rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for port\n");
1038 if (PortP->InUse) {
1039 if ( --PortP->InUse != NOT_INUSE ) {
1040 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1041 return 0;
1045 ** While PortP->InUse is set (i.e. a preemptive command has been sent to
1046 ** the RTA and is awaiting completion), any transmit data is prevented from
1047 ** being transferred from the write queue into the transmit packets
1048 ** (add_transmit) and no furthur transmit interrupt will be sent for that
1049 ** data. The next interrupt will occur up to 500ms later (RIOIntr is called
1050 ** twice a second as a saftey measure). This was the case when kermit was
1051 ** used to send data into a RIO port. After each packet was sent, TCFLSH
1052 ** was called to flush the read queue preemptively. PortP->InUse was
1053 ** incremented, thereby blocking the 6 byte acknowledgement packet
1054 ** transmitted back. This acknowledgment hung around for 500ms before
1055 ** being sent, thus reducing input performance substantially!.
1056 ** When PortP->InUse becomes NOT_INUSE, we must ensure that any data
1057 ** hanging around in the transmit buffer is sent immediately.
1059 WWORD(PortP->HostP->ParmMapP->tx_intr, 1);
1060 /* What to do here ..
1061 wakeup( (caddr_t)&(PortP->InUse) );
1063 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1064 return 0;
1067 void
1068 ShowPacket(Flags, PacketP)
1069 uint Flags;
1070 struct PKT *PacketP;
1076 ** How to use this file:
1078 ** To send a command down a rup, you need to allocate a command block, fill
1079 ** in the packet information, fill in the command number, fill in the pre-
1080 ** and post- functions and arguments, and then add the command block to the
1081 ** queue of command blocks for the port in question. When the port is idle,
1082 ** then the pre-function will be called. If this returns RIO_FAIL then the
1083 ** command will be re-queued and tried again at a later date (probably in one
1084 ** clock tick). If the pre-function returns NOT RIO_FAIL, then the command
1085 ** packet will be queued on the RUP, and the txcontrol field set to the
1086 ** command number. When the txcontrol field has changed from being the
1087 ** command number, then the post-function will be called, with the argument
1088 ** specified earlier, a pointer to the command block, and the value of
1089 ** txcontrol.
1091 ** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer
1092 ** to the command block structure allocated, or NULL if there aren't any.
1093 ** The block will have been zeroed for you.
1095 ** The structure has the following fields:
1097 ** struct CmdBlk
1098 ** {
1099 ** struct CmdBlk *NextP; ** Pointer to next command block **
1100 ** struct PKT Packet; ** A packet, to copy to the rup **
1101 ** int (*PreFuncP)(); ** The func to call to check if OK **
1102 ** int PreArg; ** The arg for the func **
1103 ** int (*PostFuncP)(); ** The func to call when completed **
1104 ** int PostArg; ** The arg for the func **
1105 ** };
1107 ** You need to fill in ALL fields EXCEPT NextP, which is used to link the
1108 ** blocks together either on the free list or on the Rup list.
1110 ** Packet is an actual packet structure to be filled in with the packet
1111 ** information associated with the command. You need to fill in everything,
1112 ** as the command processore doesn't process the command packet in any way.
1114 ** The PreFuncP is called before the packet is enqueued on the host rup.
1115 ** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must
1116 ** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL
1117 ** if the packet is NOT to be queued.
1119 ** The PostFuncP is called when the command has completed. It is called
1120 ** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected
1121 ** to return a value. PostFuncP does NOT need to free the command block,
1122 ** as this happens automatically after PostFuncP returns.
1124 ** Once the command block has been filled in, it is attached to the correct
1125 ** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is
1126 ** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer
1127 ** to it!), and CmdBlkP is the pointer to the command block allocated using
1128 ** RIOGetCmdBlk().