📄 riocmd.c
字号:
/*** -----------------------------------------------------------------------------**** 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(HostP, MapP)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(HostP, MapP)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(p, RtaUnique, func)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(p, arg)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(p, arg)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(HostP, ID, Link)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");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -