⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 riocmd.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** -----------------------------------------------------------------------------****  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_LABELSstatic 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;intRIOFoadRta(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;}intRIOZombieRta(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;}intRIOCommandRta(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;}intRIOIdentifyRta(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;}intRIOKillNeighbour(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;}intRIOSuspendBootRta(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;}intRIOFoadWakeup(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 intRIOCommandRup(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 ) {				/***********************************************************\				*************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -