/*
** -----------------------------------------------------------------------------
**
**  Perle Specialix driver for Linux
**  ported from the existing SCO driver source
**
 *
 *  (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
**	Module		: riocmd.c
**	SID		: 1.2
**	Last Modified	: 11/6/98 10:33:41
**	Retrieved	: 11/6/98 10:33:49
**
**  ident @(#)riocmd.c	1.2
**
** -----------------------------------------------------------------------------
*/
#ifdef SCCS_LABELS
static char *_riocmd_c_sccs_ = "@(#)riocmd.c	1.2";
#endif

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
#include <asm/semaphore.h>

#include <linux/termios.h>
#include <linux/serial.h>

#include <linux/generic_serial.h>

#include "linux_compat.h"
#include "rio_linux.h"
#include "typdef.h"
#include "pkt.h"
#include "daemon.h"
#include "rio.h"
#include "riospace.h"
#include "top.h"
#include "cmdpkt.h"
#include "map.h"
#include "riotypes.h"
#include "rup.h"
#include "port.h"
#include "riodrvr.h"
#include "rioinfo.h"
#include "func.h"
#include "errors.h"
#include "pci.h"

#include "parmmap.h"
#include "unixrup.h"
#include "board.h"
#include "host.h"
#include "error.h"
#include "phb.h"
#include "link.h"
#include "cmdblk.h"
#include "route.h"
#include "control.h"
#include "cirrus.h"


static struct IdentifyRta IdRta;
static struct KillNeighbour KillUnit;

int
RIOFoadRta(struct Host *HostP, struct Map *MapP)
{
	struct CmdBlk *CmdBlkP;

	rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA\n");

	CmdBlkP = RIOGetCmdBlk();

	if ( !CmdBlkP ) {
		rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n");
		return -ENXIO;
	}

	CmdBlkP->Packet.dest_unit = MapP->ID;
	CmdBlkP->Packet.dest_port = BOOT_RUP;
	CmdBlkP->Packet.src_unit  = 0;
	CmdBlkP->Packet.src_port  = BOOT_RUP;
	CmdBlkP->Packet.len	   = 0x84;
	CmdBlkP->Packet.data[0]   = IFOAD;
	CmdBlkP->Packet.data[1]   = 0;
	CmdBlkP->Packet.data[2]   = IFOAD_MAGIC & 0xFF;
	CmdBlkP->Packet.data[3]   = (IFOAD_MAGIC >> 8) & 0xFF;

	if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
		rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n");
		return -EIO;
	}
	return 0;
}

int
RIOZombieRta(struct Host *HostP, struct Map *MapP)
{
	struct CmdBlk *CmdBlkP;

	rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA\n");

	CmdBlkP = RIOGetCmdBlk();

	if ( !CmdBlkP ) {
		rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n");
		return -ENXIO;
	}

	CmdBlkP->Packet.dest_unit = MapP->ID;
	CmdBlkP->Packet.dest_port = BOOT_RUP;
	CmdBlkP->Packet.src_unit  = 0;
	CmdBlkP->Packet.src_port  = BOOT_RUP;
	CmdBlkP->Packet.len	   = 0x84;
	CmdBlkP->Packet.data[0]   = ZOMBIE;
	CmdBlkP->Packet.data[1]   = 0;
	CmdBlkP->Packet.data[2]   = ZOMBIE_MAGIC & 0xFF;
	CmdBlkP->Packet.data[3]   = (ZOMBIE_MAGIC >> 8) & 0xFF;

	if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
		rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n");
		return -EIO;
	}
	return 0;
}

int
RIOCommandRta(struct rio_info *p, uint RtaUnique,
	int (* func)(struct Host *HostP, struct Map *MapP))
{
	uint Host;

	rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func);

	if ( !RtaUnique )
		return(0);

	for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
		uint Rta;
		struct Host *HostP = &p->RIOHosts[Host];

		for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
			struct Map *MapP = &HostP->Mapping[Rta];

			if ( MapP->RtaUniqueNum == RtaUnique ) {
				uint Link;

				/*
				** now, lets just check we have a route to it...
				** IF the routing stuff is working, then one of the
				** topology entries for this unit will have a legit
				** route *somewhere*. We care not where - if its got
				** any connections, we can get to it.
				*/
				for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
					if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
						/*
						** Its worth trying the operation...
						*/
						return (*func)( HostP, MapP );
					}
				}
			}
		}
	}
	return -ENXIO;
}


int
RIOIdentifyRta(struct rio_info *p, caddr_t arg)
{
	uint Host;

	if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) {
		rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n");
		p->RIOError.Error = COPYIN_FAILED;
		return -EFAULT;
	}

	for ( Host = 0 ; Host < p->RIONumHosts; Host++ ) {
		uint Rta;
		struct Host *HostP = &p->RIOHosts[Host];

		for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
			struct Map *MapP = &HostP->Mapping[Rta];

			if ( MapP->RtaUniqueNum == IdRta.RtaUnique ) {
				uint Link;
				/*
				** now, lets just check we have a route to it...
				** IF the routing stuff is working, then one of the
				** topology entries for this unit will have a legit
				** route *somewhere*. We care not where - if its got
				** any connections, we can get to it.
				*/
				for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
					if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
						/*
						** Its worth trying the operation...
						*/
						struct CmdBlk *CmdBlkP;

						rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA\n");

						CmdBlkP = RIOGetCmdBlk();

						if ( !CmdBlkP ) {
							rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n");
							return -ENXIO;
						}
		
						CmdBlkP->Packet.dest_unit = MapP->ID;
						CmdBlkP->Packet.dest_port = BOOT_RUP;
						CmdBlkP->Packet.src_unit  = 0;
						CmdBlkP->Packet.src_port  = BOOT_RUP;
						CmdBlkP->Packet.len	   = 0x84;
						CmdBlkP->Packet.data[0]   = IDENTIFY;
						CmdBlkP->Packet.data[1]   = 0;
						CmdBlkP->Packet.data[2]   = IdRta.ID;
		
						if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
							rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n");
							return -EIO;
						}
						return 0;
					}
				}
			}
		}
	} 
	return -ENOENT;
}


int
RIOKillNeighbour(struct rio_info *p, caddr_t arg)
{
	uint Host;
	uint ID;
	struct Host *HostP;
	struct CmdBlk *CmdBlkP;

	rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n");

	if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) {
		rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n");
		p->RIOError.Error = COPYIN_FAILED;
		return -EFAULT;
	}

	if ( KillUnit.Link > 3 )
		return -ENXIO;
 
	CmdBlkP = RIOGetCmdBlk();

	if ( !CmdBlkP ) {
		rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n");
		return -ENXIO;
	}

	CmdBlkP->Packet.dest_unit = 0;
	CmdBlkP->Packet.src_unit  = 0;
	CmdBlkP->Packet.dest_port = BOOT_RUP;
	CmdBlkP->Packet.src_port  = BOOT_RUP;
	CmdBlkP->Packet.len	   = 0x84;
	CmdBlkP->Packet.data[0]   = UFOAD;
	CmdBlkP->Packet.data[1]   = KillUnit.Link;
	CmdBlkP->Packet.data[2]   = UFOAD_MAGIC & 0xFF;
	CmdBlkP->Packet.data[3]   = (UFOAD_MAGIC >> 8) & 0xFF;

	for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
		ID = 0;
		HostP = &p->RIOHosts[Host];

		if ( HostP->UniqueNum == KillUnit.UniqueNum ) {
			if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link,
							CmdBlkP) == RIO_FAIL ) {
				rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
				return -EIO;
			}
			return 0;
		}

		for ( ID=0; ID < RTAS_PER_HOST; ID++ ) {
			if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) {
				CmdBlkP->Packet.dest_unit = ID+1;
				if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) {
					rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
					return -EIO;
				}
				return 0;
			}
		}
	}
	RIOFreeCmdBlk( CmdBlkP );
	return -ENXIO;
}

int
RIOSuspendBootRta(struct Host *HostP, int ID, int Link)
{
	struct CmdBlk *CmdBlkP;

	rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link);

	CmdBlkP = RIOGetCmdBlk();

	if ( !CmdBlkP ) {
		rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n");
		return -ENXIO;
	}

	CmdBlkP->Packet.dest_unit = ID;
	CmdBlkP->Packet.dest_port = BOOT_RUP;
	CmdBlkP->Packet.src_unit  = 0;
	CmdBlkP->Packet.src_port  = BOOT_RUP;
	CmdBlkP->Packet.len	   = 0x84;
	CmdBlkP->Packet.data[0]   = IWAIT;
	CmdBlkP->Packet.data[1]   = Link;
	CmdBlkP->Packet.data[2]   = IWAIT_MAGIC & 0xFF;
	CmdBlkP->Packet.data[3]   = (IWAIT_MAGIC >> 8) & 0xFF;

	if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) {
		rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n");
		return -EIO;
	}
	return 0;
}

int
RIOFoadWakeup(struct rio_info *p)
{
	int port;
	register struct Port *PortP;
	unsigned long flags;

	for ( port=0; port<RIO_PORTS; port++) {
		PortP = p->RIOPortp[port];

		rio_spin_lock_irqsave(&PortP->portSem, flags);
		PortP->Config = 0;
		PortP->State = 0;
		PortP->InUse = NOT_INUSE;
		PortP->PortState = 0;
		PortP->FlushCmdBodge = 0;
		PortP->ModemLines = 0;
		PortP->ModemState = 0;
		PortP->CookMode = 0;
		PortP->ParamSem = 0;
		PortP->Mapped = 0;
		PortP->WflushFlag = 0;
		PortP->MagicFlags = 0;
		PortP->RxDataStart = 0;
		PortP->TxBufferIn = 0;
		PortP->TxBufferOut = 0;
		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
	}
	return(0);
}

/*
** Incoming command on the COMMAND_RUP to be processed.
*/
static int
RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP)
{
	struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;
	struct Port *PortP;
	struct UnixRup *UnixRupP;
	ushort SysPort;
	ushort ReportedModemStatus;
	ushort rup;
	ushort subCommand;
	unsigned long flags;

	func_enter ();

#ifdef CHECK
	CheckHost( Host );
	CheckHostP( HostP );
	CheckPacketP( PacketP );
#endif

	/*
	** 16 port RTA note:
	** Command rup packets coming from the RTA will have pkt->data[1] (which
	** translates to PktCmdP->PhbNum) set to the host port number for the
	** particular unit. To access the correct BaseSysPort for a 16 port RTA,
	** we can use PhbNum to get the rup number for the appropriate 8 port
	** block (for the first block, this should be equal to 'Rup').
	*/
	rup = RBYTE(PktCmdP->PhbNum) / (ushort)PORTS_PER_RTA;
	UnixRupP = &HostP->UnixRups[rup];
	SysPort = UnixRupP->BaseSysPort + 
			(RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);
	rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);

#ifdef CHECK
	CheckRup( rup );
	CheckUnixRupP( UnixRupP );
#endif
	if ( UnixRupP->BaseSysPort == NO_PORT ) {
		rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
		rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n", 
			     HostP-p->RIOHosts, HostP->Name );
		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number  0x%x\n", rup);

		if ( Rup >= (ushort)MAX_RUP ) {
			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n",
				     HostP->Mapping[Rup].Name);
		} else
			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", 
				     ('A' + Rup - MAX_RUP), HostP->Name);

		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n",
			     PacketP->dest_unit, PacketP->dest_port );
		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source	  0x%x:0x%x\n",
			     PacketP->src_unit, PacketP->src_port );
		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length	  0x%x (%d)\n", PacketP->len,PacketP->len );
		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control	 0x%x (%d)\n", PacketP->control, PacketP->control);
		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check	   0x%x (%d)\n", PacketP->csum, PacketP->csum );
		rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, "
					"Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command );
		return TRUE;
	}

#ifdef CHECK
	CheckSysPort( SysPort );
#endif
	PortP = p->RIOPortp[ SysPort ];
	rio_spin_lock_irqsave(&PortP->portSem, flags);
	switch( RBYTE(PktCmdP->Command) ) {
		case BREAK_RECEIVED:
			rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n");
			/* If the current line disc. is not multi-threading and
	   			the current processor is not the default, reset rup_intr
	   			and return FALSE to ensure that the command packet is
	   			not freed. */
			/* Call tmgr HANGUP HERE */
			/* Fix this later when every thing works !!!! RAMRAJ */
			gs_got_break (&PortP->gs);
			break;

		case COMPLETE:
			rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n",
			     RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);
			subCommand = 1;
			switch (RBYTE(PktCmdP->SubCommand)) {
				case MEMDUMP :
			rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n",
				     RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));
					break;
				case READ_REGISTER :
			rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr));
					p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);
					break;
				default :
					subCommand = 0;
				break;
			}
			if (subCommand)
				break;
			rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n",
				     RBYTE(PktCmdP->PortStatus),PortP->PortState);
			if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {
				rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n");
				PortP->PortState = RBYTE(PktCmdP->PortStatus);
				/* What should we do here ...
				wakeup( &PortP->PortState );
				*/
		} else 
			rio_dprintk (RIO_DEBUG_CMD, "No change\n");

			/* FALLTHROUGH */
		case MODEM_STATUS:
			/*
			** Knock out the tbusy and tstop bits, as these are not relevant
			** to the check for modem status change (they're just there because
			** it's a convenient place to put them!).
			*/
			ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);
			if ((PortP->ModemState & MSVR1_HOST) ==
					(ReportedModemStatus & MSVR1_HOST)) {
				rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
				/*
				** Update ModemState just in case tbusy or tstop states have
				** changed.
				*/
				PortP->ModemState = ReportedModemStatus;
			}
			else {
				rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n",
				     PortP->ModemState, ReportedModemStatus);
				PortP->ModemState = ReportedModemStatus;
#ifdef MODEM_SUPPORT
				if ( PortP->Mapped ) {
				/***********************************************************\
				*************************************************************
				***													   ***
				***		  M O D E M   S T A T E   C H A N G E		  ***
				***													   ***
				*************************************************************
				\***********************************************************/
				/*
				** If the device is a modem, then check the modem
				** carrier.
				*/
				if (PortP->gs.tty == NULL)
					break;
				if (PortP->gs.tty->termios == NULL)
					break;
			  
				if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
				((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {

					rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n");
			/*
			** Is there a carrier?
			*/
					if ( PortP->ModemState & MSVR1_CD ) {
			/*
			** Has carrier just appeared?
			*/
						if (!(PortP->State & RIO_CARR_ON)) {
							rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n");
							PortP->State |= RIO_CARR_ON;
				/*
				** wakeup anyone in WOPEN
				*/
							if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )
								wake_up_interruptible (&PortP->gs.open_wait);
#ifdef STATS
				PortP->Stat.ModemOnCnt++;
#endif
			}
					} else {
			/*
			** Has carrier just dropped?
			*/
						if (PortP->State & RIO_CARR_ON) {
							if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))
								tty_hangup (PortP->gs.tty);
							PortP->State &= ~RIO_CARR_ON;
							rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n");
#ifdef STATS
				PortP->Stat.ModemOffCnt++;
#endif
			}
			}
		}
		}
#endif
			}
			break;

		default:
			rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n",
			     RBYTE(PktCmdP->Command),HostP-p->RIOHosts);
			break;
	}
	rio_spin_unlock_irqrestore(&PortP->portSem, flags);

	func_exit ();

	return TRUE;
}
/*
** The command mechanism:
**	Each rup has a chain of commands associated with it.
**	This chain is maintained by routines in this file.
**	Periodically we are called and we run a quick check of all the
**	active chains to determine if there is a command to be executed,
**	and if the rup is ready to accept it.
**
*/

/*
** Allocate an empty command block.
*/
struct CmdBlk *
RIOGetCmdBlk(void)
{
	struct CmdBlk *CmdBlkP;

	CmdBlkP = (struct CmdBlk *)sysbrk(sizeof(struct CmdBlk));
	if (CmdBlkP)
		bzero(CmdBlkP, sizeof(struct CmdBlk));

	return CmdBlkP;
}

/*
** Return a block to the head of the free list.
*/
void
RIOFreeCmdBlk(struct CmdBlk *CmdBlkP)
{
	sysfree((void *)CmdBlkP, sizeof(struct CmdBlk));
}

/*
** attach a command block to the list of commands to be performed for
** a given rup.
*/
int
RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP)
{
	struct CmdBlk **Base;
	struct UnixRup *UnixRupP;
	unsigned long flags;

#ifdef CHECK
	CheckHostP( HostP );
	CheckRup( Rup );
	CheckCmdBlkP( CmdBlkP );
#endif
	if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {
		rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup);
		RIOFreeCmdBlk( CmdBlkP );
		return RIO_FAIL;
	}

	UnixRupP = &HostP->UnixRups[Rup];

	rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);

	/*
	** If the RUP is currently inactive, then put the request
	** straight on the RUP....
	*/
	if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && 
	     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&
		(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)
							:TRUE)) {
		rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
					     CmdBlkP->Packet.data[0]);

		/*
		** Whammy! blat that pack!
		*/
		HostP->Copy( (caddr_t)&CmdBlkP->Packet, 
			RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt ), sizeof(PKT) );

		/*
		** place command packet on the pending position.
		*/
		UnixRupP->CmdPendingP = CmdBlkP;

		/*
		** set the command register
		*/
		WWORD(UnixRupP->RupP->txcontrol , TX_PACKET_READY);

		rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);

		return RIO_SUCCESS;
	}
	rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n");

	if ( UnixRupP->CmdsWaitingP != NULL)
		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n");
	if ( UnixRupP->CmdPendingP != NULL )
		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n");
	if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )
		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n");

	Base = &UnixRupP->CmdsWaitingP;

	rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base);

	while ( *Base ) {
		rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base));
		Base = &((*Base)->NextP);
		rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%x\n",
					     (int)CmdBlkP,(int)Base);
	}

	rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base);

	*Base = CmdBlkP;

	CmdBlkP->NextP = NULL;

	rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);

	return RIO_SUCCESS;
}

/*
** Here we go - if there is an empty rup, fill it!
** must be called at splrio() or higher.
*/
void
RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
{
	register struct CmdBlk *CmdBlkP;
	register struct UnixRup *UnixRupP;
	struct PKT *PacketP;
	ushort Rup;
	unsigned long flags;


	Rup = MAX_RUP+LINKS_PER_UNIT;

	do {	/* do this loop for each RUP */
		/*
		** locate the rup we are processing & lock it
		*/
		UnixRupP = &HostP->UnixRups[--Rup];

		spin_lock_irqsave(&UnixRupP->RupLock, flags);

		/*
		** First check for incoming commands:
		*/
		if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) {
			int FreeMe;

			PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt));

			ShowPacket( DBG_CMD, PacketP );

			switch ( RBYTE(PacketP->dest_port) ) {
				case BOOT_RUP:
					rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", 
						RBYTE(PacketP->len) & 0x80 ? "Command":"Data", 
							     RBYTE(PacketP->data[0])); 
					rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
					FreeMe= RIOBootRup(p, Rup,HostP,PacketP);
					rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
					break;

				case COMMAND_RUP:
					/*
					** Free the RUP lock as loss of carrier causes a
					** ttyflush which will (eventually) call another
					** routine that uses the RUP lock.
					*/
					rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
					FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
					if (PacketP->data[5] == MEMDUMP) {
						rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n",
								     *(ushort *) &(PacketP->data[6]));
						HostP->Copy( (caddr_t)&(PacketP->data[8]), 
								(caddr_t)p->RIOMemDump, 32 );
					}
					rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
					break;

				case ROUTE_RUP:
					rio_spin_unlock_irqrestore( &UnixRupP->RupLock, flags);
					FreeMe = RIORouteRup(p, Rup, HostP, PacketP );
					rio_spin_lock_irqsave( &UnixRupP->RupLock, flags );
					break;

				default:
					rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %d\n", RBYTE(PacketP->dest_port));
					FreeMe = 1;
					break;
			}

			if ( FreeMe ) {
				rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packet\n");
				put_free_end(HostP,PacketP);

				WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE);

				if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) {
					rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %d\n",Rup);
					WWORD(UnixRupP->RupP->handshake,
						PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
				}
			}
		}

		/*
		** IF a command was running on the port, 
		** and it has completed, then tidy it up.
		*/
		if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
		     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
			/*
			** we are idle.
			** there is a command in pending.
			** Therefore, this command has finished.
			** So, wakeup whoever is waiting for it (and tell them
			** what happened).
			*/
			if ( CmdBlkP->Packet.dest_port == BOOT_RUP )
				rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", 
						CmdBlkP->Packet.len & 0x80 ? "Command":"Data", 
							     CmdBlkP->Packet.data[0]);

			rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completed\n",(int)CmdBlkP);

			/*
			** Clear the Rup lock to prevent mutual exclusion.
			*/
			if ( CmdBlkP->PostFuncP ) {
				rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
				(*CmdBlkP->PostFuncP) (CmdBlkP->PostArg,CmdBlkP);
				rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
			}

			/*
			** ....clear the pending flag....
			*/
			UnixRupP->CmdPendingP = NULL;

			/*
			** ....and return the command block to the freelist.
			*/
			RIOFreeCmdBlk( CmdBlkP );
		}

		/*
		** If there is a command for this rup, and the rup
		** is idle, then process the command
		*/
		if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
			(UnixRupP->CmdPendingP == NULL) &&
		     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
			/*
			** if the pre-function is non-zero, call it.
			** If it returns RIO_FAIL then don't
			** send this command yet!
			*/
#ifdef CHECK
			CheckCmdBlkP (CmdBlkP);
#endif
			if ( !(CmdBlkP->PreFuncP ?
				(*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) {
				rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%x\n",(int)CmdBlkP);
			}
			else {
				rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%x\n",
							     (int)CmdBlkP, CmdBlkP->Packet.data[0]);
				/*
				** Whammy! blat that pack!
				*/
#ifdef CHECK
				CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt));
#endif
				HostP->Copy( (caddr_t)&CmdBlkP->Packet, 
					RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT));

				/*
				** remove the command from the rup command queue...
				*/
				UnixRupP->CmdsWaitingP = CmdBlkP->NextP;

				/*
				** ...and place it on the pending position.
				*/
				UnixRupP->CmdPendingP = CmdBlkP;

				/*
				** set the command register
				*/
				WWORD(UnixRupP->RupP->txcontrol,TX_PACKET_READY);

				/*
				** the command block will be freed
				** when the command has been processed.
				*/
			}
		}
		spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
	} while ( Rup );
}

int
RIOWFlushMark(int iPortP, struct CmdBlk *CmdBlkP)
{
	struct Port *	PortP = (struct Port *)iPortP;
	unsigned long flags;

	rio_spin_lock_irqsave(&PortP->portSem, flags);
#ifdef CHECK
	CheckPortP( PortP );
#endif
	PortP->WflushFlag++;
	PortP->MagicFlags |= MAGIC_FLUSH;
	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
	return RIOUnUse( iPortP, CmdBlkP );
}

int
RIORFlushEnable(int iPortP, struct CmdBlk *CmdBlkP)
{
	struct Port *	PortP = (struct Port *)iPortP;
	PKT *PacketP;
	unsigned long flags;

	rio_spin_lock_irqsave(&PortP->portSem, flags);

	while ( can_remove_receive(&PacketP, PortP) ) {
		remove_receive(PortP);
		ShowPacket(DBG_PROC, PacketP );
		put_free_end( PortP->HostP, PacketP );
	}

	if ( RWORD(PortP->PhbP->handshake)==PHB_HANDSHAKE_SET ) {
		/*
		** MAGIC! (Basically, handshake the RX buffer, so that
		** the RTAs upstream can be re-enabled.)
		*/
		rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bit\n");
		WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
	}
	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
	return RIOUnUse( iPortP, CmdBlkP );
}

int
RIOUnUse(int iPortP, struct CmdBlk *CmdBlkP)
{
	struct Port *	PortP = (struct Port *)iPortP;
	unsigned long flags;

	rio_spin_lock_irqsave(&PortP->portSem, flags);

#ifdef CHECK
	CheckPortP( PortP );
#endif
	rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for port\n");

	if (PortP->InUse) {
		if ( --PortP->InUse != NOT_INUSE ) {
			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
			return 0;
		}
	}
	/*
	** While PortP->InUse is set (i.e. a preemptive command has been sent to
	** the RTA and is awaiting completion), any transmit data is prevented from
	** being transferred from the write queue into the transmit packets
	** (add_transmit) and no furthur transmit interrupt will be sent for that
	** data. The next interrupt will occur up to 500ms later (RIOIntr is called
	** twice a second as a saftey measure). This was the case when kermit was
	** used to send data into a RIO port. After each packet was sent, TCFLSH
	** was called to flush the read queue preemptively. PortP->InUse was
	** incremented, thereby blocking the 6 byte acknowledgement packet
	** transmitted back. This acknowledgment hung around for 500ms before
	** being sent, thus reducing input performance substantially!.
	** When PortP->InUse becomes NOT_INUSE, we must ensure that any data
	** hanging around in the transmit buffer is sent immediately.
	*/
	WWORD(PortP->HostP->ParmMapP->tx_intr, 1);
	/* What to do here ..
	wakeup( (caddr_t)&(PortP->InUse) );
	*/
	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
	return 0;
}

void
ShowPacket(uint Flags, struct PKT *PacketP)
{
}

/*
** 
** How to use this file:
** 
** To send a command down a rup, you need to allocate a command block, fill
** in the packet information, fill in the command number, fill in the pre-
** and post- functions and arguments, and then add the command block to the
** queue of command blocks for the port in question. When the port is idle,
** then the pre-function will be called. If this returns RIO_FAIL then the
** command will be re-queued and tried again at a later date (probably in one
** clock tick). If the pre-function returns NOT RIO_FAIL, then the command
** packet will be queued on the RUP, and the txcontrol field set to the
** command number. When the txcontrol field has changed from being the
** command number, then the post-function will be called, with the argument
** specified earlier, a pointer to the command block, and the value of
** txcontrol.
** 
** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer
** to the command block structure allocated, or NULL if there aren't any.
** The block will have been zeroed for you.
** 
** The structure has the following fields:
** 
** struct CmdBlk
** {
**	 struct CmdBlk *NextP;		  ** Pointer to next command block   **
**	 struct PKT	 Packet;		** A packet, to copy to the rup	**
**			int	 (*PreFuncP)();  ** The func to call to check if OK **
**			int	 PreArg;		** The arg for the func			**
**			int	 (*PostFuncP)(); ** The func to call when completed **
**			int	 PostArg;	   ** The arg for the func			**
** };
** 
** You need to fill in ALL fields EXCEPT NextP, which is used to link the
** blocks together either on the free list or on the Rup list.
** 
** Packet is an actual packet structure to be filled in with the packet
** information associated with the command. You need to fill in everything,
** as the command processore doesn't process the command packet in any way.
** 
** The PreFuncP is called before the packet is enqueued on the host rup.
** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must
** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL
** if the packet is NOT to be queued.
** 
** The PostFuncP is called when the command has completed. It is called
** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected
** to return a value. PostFuncP does NOT need to free the command block,
** as this happens automatically after PostFuncP returns.
** 
** Once the command block has been filled in, it is attached to the correct
** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is
** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer
** to it!), and CmdBlkP is the pointer to the command block allocated using
** RIOGetCmdBlk().
** 
*/
