/*
** -----------------------------------------------------------------------------
**
**  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
**
** -----------------------------------------------------------------------------
*/

#include <linux/module.h>
#include <linux/sched.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/uaccess.h>

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

#include <linux/generic_serial.h>

#include "linux_compat.h"
#include "rio_linux.h"
#include "pkt.h"
#include "daemon.h"
#include "rio.h"
#include "riospace.h"
#include "cmdpkt.h"
#include "map.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 "phb.h"
#include "link.h"
#include "cmdblk.h"
#include "route.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, unsigned long RtaUnique, int (*func) (struct Host * HostP, struct Map * MapP))
{
	unsigned int Host;

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

	if (!RtaUnique)
		return (0);

	for (Host = 0; Host < p->RIONumHosts; Host++) {
		unsigned int 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 <= (u8) MAX_RUP) {
						/*
						 ** Its worth trying the operation...
						 */
						return (*func) (HostP, MapP);
					}
				}
			}
		}
	}
	return -ENXIO;
}


int RIOIdentifyRta(struct rio_info *p, void __user * arg)
{
	unsigned int Host;

	if (copy_from_user(&IdRta, arg, sizeof(IdRta))) {
		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++) {
		unsigned int 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 <= (u8) 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, void __user * arg)
{
	uint Host;
	uint ID;
	struct Host *HostP;
	struct CmdBlk *CmdBlkP;

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

	if (copy_from_user(&KillUnit, arg, sizeof(KillUnit))) {
		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;
	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, struct PKT __iomem *PacketP)
{
	struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data;
	struct Port *PortP;
	struct UnixRup *UnixRupP;
	unsigned short SysPort;
	unsigned short ReportedModemStatus;
	unsigned short rup;
	unsigned short subCommand;
	unsigned long flags;

	func_enter();

	/*
	 ** 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 = readb(&PktCmdP->PhbNum) / (unsigned short) PORTS_PER_RTA;
	UnixRupP = &HostP->UnixRups[rup];
	SysPort = UnixRupP->BaseSysPort + (readb(&PktCmdP->PhbNum) % (unsigned short) PORTS_PER_RTA);
	rio_dprintk(RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);

	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 %Zd, name ``%s''\n", HostP - p->RIOHosts, HostP->Name);
		rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Rup number  0x%x\n", rup);

		if (Rup < (unsigned short) 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", readb(&PacketP->dest_unit), readb(&PacketP->dest_port));
		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source	  0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port));
		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length	  0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len));
		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control	 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control));
		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check	   0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum));
		rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command));
		return 1;
	}
	PortP = p->RIOPortp[SysPort];
	rio_spin_lock_irqsave(&PortP->portSem, flags);
	switch (readb(&PktCmdP->Command)) {
	case RIOC_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 0 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 RIOC_COMPLETE:
		rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts);
		subCommand = 1;
		switch (readb(&PktCmdP->SubCommand)) {
		case RIOC_MEMDUMP:
			rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr));
			break;
		case RIOC_READ_REGISTER:
			rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr));
			p->CdRegister = (readb(&PktCmdP->ModemStatus) & RIOC_MSVR1_HOST);
			break;
		default:
			subCommand = 0;
			break;
		}
		if (subCommand)
			break;
		rio_dprintk(RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n", readb(&PktCmdP->PortStatus), PortP->PortState);
		if (PortP->PortState != readb(&PktCmdP->PortStatus)) {
			rio_dprintk(RIO_DEBUG_CMD, "Mark status & wakeup\n");
			PortP->PortState = readb(&PktCmdP->PortStatus);
			/* What should we do here ...
			   wakeup( &PortP->PortState );
			 */
		} else
			rio_dprintk(RIO_DEBUG_CMD, "No change\n");

		/* FALLTHROUGH */
	case RIOC_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 = readb(&PktCmdP->ModemStatus);
		if ((PortP->ModemState & RIOC_MSVR1_HOST) ==
				(ReportedModemStatus & RIOC_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.port.tty == NULL)
					break;
				if (PortP->gs.port.tty->termios == NULL)
					break;

				if (!(PortP->gs.port.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 & RIOC_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.port.open_wait);
						}
					} else {
						/*
						 ** Has carrier just dropped?
						 */
						if (PortP->State & RIO_CARR_ON) {
							if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN))
								tty_hangup(PortP->gs.port.tty);
							PortP->State &= ~RIO_CARR_ON;
							rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n");
						}
					}
				}
			}
#endif
		}
		break;

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

	func_exit();

	return 1;
}

/*
** 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 = kzalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
	return CmdBlkP;
}

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

/*
** 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;

	if (Rup >= (unsigned short) (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) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) && (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP)
																	     : 1)) {
		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(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT));

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

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

		rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);

		return 0;
	}
	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 (readw(&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 %p at %p\n", CmdBlkP, Base);

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

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

	*Base = CmdBlkP;

	CmdBlkP->NextP = NULL;

	rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);

	return 0;
}

/*
** 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)
{
	struct CmdBlk *CmdBlkP;
	struct UnixRup *UnixRupP;
	struct PKT __iomem *PacketP;
	unsigned short 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 (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) {
			int FreeMe;

			PacketP = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt));

			switch (readb(&PacketP->dest_port)) {
			case BOOT_RUP:
				rio_dprintk(RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", readb(&PacketP->len) & 0x80 ? "Command" : "Data", readb(&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 (readb(&PacketP->data[5]) == RIOC_MEMDUMP) {
					rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6])));
					rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 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", readb(&PacketP->dest_port));
				FreeMe = 1;
				break;
			}

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

				writew(RX_RUP_INACTIVE, &UnixRupP->RupP->rxcontrol);

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

		/*
		 ** IF a command was running on the port,
		 ** and it has completed, then tidy it up.
		 */
		if ((CmdBlkP = UnixRupP->CmdPendingP) &&	/* ASSIGN! */
		    (readw(&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 %p completed\n", 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) && (readw(&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!
			 */
			if (!(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) : 1)) {
				rio_dprintk(RIO_DEBUG_CMD, "Not ready to start command %p\n", CmdBlkP);
			} else {
				rio_dprintk(RIO_DEBUG_CMD, "Start new command %p Cmd byte is 0x%x\n", CmdBlkP, CmdBlkP->Packet.data[0]);
				/*
				 ** Whammy! blat that pack!
				 */
				HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct 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
				 */
				writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol);

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

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

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

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

	rio_spin_lock_irqsave(&PortP->portSem, flags);

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

	if (readw(&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");
		writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
	}
	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
	return RIOUnUse(iPortP, CmdBlkP);
}

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

	rio_spin_lock_irqsave(&PortP->portSem, flags);

	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.
	 */
	writew(1, &PortP->HostP->ParmMapP->tx_intr);
	/* What to do here ..
	   wakeup( (caddr_t)&(PortP->InUse) );
	 */
	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
	return 0;
}

/*
** 
** 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 processor 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().
** 
*/
