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

📄 rioboot.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		HostP->Flags &= ~RUN_STATE;		HostP->Flags |= RC_STARTUP;		/*		** Grab a copy of the current ParmMap pointer, so we		** can tell when it has changed.		*/		OldParmMap = RWORD(HostP->__ParmMapR);		rio_dprintk (RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n",OldParmMap);		/*		** And start it running (I hope).		** As there is nothing dodgy or obscure about the		** above code, this is guaranteed to work every time.		*/		rio_dprintk (RIO_DEBUG_BOOT,  "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",		    HostP->Type, HostP->Mode, HostP->Ivec);		rio_start_card_running(HostP);		rio_dprintk (RIO_DEBUG_BOOT, "Set control port\n");		/*		** Now, wait for upto five seconds for the Tp to setup the parmmap		** pointer:		*/		for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&&			(RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {			rio_dprintk (RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR));			delay(HostP, HUNDRED_MS);		}		/*		** If the parmmap pointer is unchanged, then the host code		** has crashed & burned in a really spectacular way		*/		if ( RWORD(HostP->__ParmMapR) == OldParmMap ) {			rio_dprintk (RIO_DEBUG_BOOT, "parmmap 0x%x\n", RWORD(HostP->__ParmMapR));			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n");#define	HOST_DISABLE \		HostP->Flags &= ~RUN_STATE; \		HostP->Flags |= RC_STUFFED; \		RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot );\		continue			HOST_DISABLE;		}		rio_dprintk (RIO_DEBUG_BOOT, "Running 0x%x\n", RWORD(HostP->__ParmMapR));		/*		** Well, the board thought it was OK, and setup its parmmap		** pointer. For the time being, we will pretend that this		** board is running, and check out what the error flag says.		*/		/*		** Grab a 32 bit pointer to the parmmap structure		*/		ParmMapP = (PARM_MAP *)RIO_PTR(Cad,RWORD(HostP->__ParmMapR));		rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);		ParmMapP = (PARM_MAP *)((unsigned long)Cad + 						(unsigned long)((RWORD((HostP->__ParmMapR))) & 0xFFFF)); 		rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);		/*		** The links entry should be 0xFFFF; we set it up		** with a mask to say how many PHBs to use, and 		** which links to use.		*/		if ( (RWORD(ParmMapP->links) & 0xFFFF) != 0xFFFF ) {			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);			rio_dprintk (RIO_DEBUG_BOOT, "Links = 0x%x\n",RWORD(ParmMapP->links));			HOST_DISABLE;		}		WWORD(ParmMapP->links , RIO_LINK_ENABLE);		/*		** now wait for the card to set all the parmmap->XXX stuff		** this is a wait of upto two seconds....		*/		rio_dprintk (RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n",p->RIOConf.StartupTime);		HostP->timeout_id = 0;		for ( wait_count=0; (wait_count<p->RIOConf.StartupTime) && 						!RWORD(ParmMapP->init_done); wait_count++ ) {			rio_dprintk (RIO_DEBUG_BOOT, "Waiting for init_done\n");			delay(HostP, HUNDRED_MS);		}		rio_dprintk (RIO_DEBUG_BOOT, "OK! init_done!\n");		if (RWORD(ParmMapP->error) != E_NO_ERROR || 							!RWORD(ParmMapP->init_done) ) {			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);			rio_dprintk (RIO_DEBUG_BOOT, "Timedout waiting for init_done\n");			HOST_DISABLE;		}		rio_dprintk (RIO_DEBUG_BOOT, "Got init_done\n");		/*		** It runs! It runs!		*/		rio_dprintk (RIO_DEBUG_BOOT, "Host ID %x Running\n",HostP->UniqueNum);		/*		** set the time period between interrupts.		*/		WWORD(ParmMapP->timer, (short)p->RIOConf.Timer );		/*		** Translate all the 16 bit pointers in the __ParmMapR into		** 32 bit pointers for the driver.		*/		HostP->ParmMapP	 =	ParmMapP;		HostP->PhbP		 =	(PHB*)RIO_PTR(Cad,RWORD(ParmMapP->phb_ptr));		HostP->RupP		 =	(RUP*)RIO_PTR(Cad,RWORD(ParmMapP->rups));		HostP->PhbNumP	  = (ushort*)RIO_PTR(Cad,RWORD(ParmMapP->phb_num_ptr));		HostP->LinkStrP	 =	(LPB*)RIO_PTR(Cad,RWORD(ParmMapP->link_str_ptr));		/*		** point the UnixRups at the real Rups		*/		for ( RupN = 0; RupN<MAX_RUP; RupN++ ) {			HostP->UnixRups[RupN].RupP		= &HostP->RupP[RupN];			HostP->UnixRups[RupN].Id		  = RupN+1;			HostP->UnixRups[RupN].BaseSysPort = NO_PORT;			spin_lock_init(&HostP->UnixRups[RupN].RupLock);		}		for ( RupN = 0; RupN<LINKS_PER_UNIT; RupN++ ) {			HostP->UnixRups[RupN+MAX_RUP].RupP	= &HostP->LinkStrP[RupN].rup;			HostP->UnixRups[RupN+MAX_RUP].Id  = 0;			HostP->UnixRups[RupN+MAX_RUP].BaseSysPort = NO_PORT;			spin_lock_init(&HostP->UnixRups[RupN+MAX_RUP].RupLock);		}		/*		** point the PortP->Phbs at the real Phbs		*/		for ( PortN=p->RIOFirstPortsMapped; 				PortN<p->RIOLastPortsMapped+PORTS_PER_RTA; PortN++ ) {			if ( p->RIOPortp[PortN]->HostP == HostP ) {				struct Port *PortP = p->RIOPortp[PortN];				struct PHB *PhbP;				/* int oldspl; */				if ( !PortP->Mapped )					continue;				PhbP = &HostP->PhbP[PortP->HostPort];				rio_spin_lock_irqsave(&PortP->portSem, flags);				PortP->PhbP = PhbP;				PortP->TxAdd	= (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_add));				PortP->TxStart  = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_start));				PortP->TxEnd	= (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_end));				PortP->RxRemove = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_remove));				PortP->RxStart  = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_start));				PortP->RxEnd	= (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_end));				rio_spin_unlock_irqrestore(&PortP->portSem, flags);				/*				** point the UnixRup at the base SysPort				*/				if ( !(PortN % PORTS_PER_RTA) )					HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN;			}		}		rio_dprintk (RIO_DEBUG_BOOT, "Set the card running... \n");		/*		** last thing - show the world that everything is in place		*/		HostP->Flags &= ~RUN_STATE;		HostP->Flags |= RC_RUNNING;	}	/*	** MPX always uses a poller. This is actually patched into the system	** configuration and called directly from each clock tick.	**	*/	p->RIOPolling = 1;	p->RIOSystemUp++;		rio_dprintk (RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec);	func_exit ();	return 0;}/*** Boot an RTA. If we have successfully processed this boot, then** return 1. If we havent, then return 0.*/intRIOBootRup( p, Rup, HostP, PacketP)struct rio_info *	p;uint Rup;struct Host *HostP;struct PKT *PacketP; {	struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;	struct PktCmd_M *PktReplyP;	struct CmdBlk *CmdBlkP;	uint sequence;#ifdef CHECK	CheckHost(Host);	CheckRup(Rup);	CheckHostP(HostP);	CheckPacketP(PacketP);#endif	/*	** If we haven't been told what to boot, we can't boot it.	*/	if ( p->RIONumBootPkts == 0 ) {		rio_dprintk (RIO_DEBUG_BOOT, "No RTA code to download yet\n");		return 0;	}	/* rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_BOOT,"Incoming command packet\n"); */	/* ShowPacket( DBG_BOOT, PacketP ); */	/*	** Special case of boot completed - if we get one of these then we	** don't need a command block. For all other cases we do, so handle	** this first and then get a command block, then handle every other	** case, relinquishing the command block if disaster strikes!	*/	if ( (RBYTE(PacketP->len) & PKT_CMD_BIT) && 			(RBYTE(PktCmdP->Command)==BOOT_COMPLETED) )		return RIOBootComplete(p, HostP, Rup, PktCmdP );	/*	** try to unhook a command block from the command free list.	*/	if ( !(CmdBlkP = RIOGetCmdBlk()) ) {		rio_dprintk (RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n");		return 0;	}	/*	** Fill in the default info on the command block	*/	CmdBlkP->Packet.dest_unit = Rup < (ushort)MAX_RUP ? Rup : 0;	CmdBlkP->Packet.dest_port = BOOT_RUP;	CmdBlkP->Packet.src_unit  = 0;	CmdBlkP->Packet.src_port  = BOOT_RUP;	CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL;	PktReplyP = (struct PktCmd_M *)CmdBlkP->Packet.data;	/*	** process COMMANDS on the boot rup!	*/	if ( RBYTE(PacketP->len) & PKT_CMD_BIT ) {		/*		** We only expect one type of command - a BOOT_REQUEST!		*/		if ( RBYTE(PktCmdP->Command) != BOOT_REQUEST ) {			rio_dprintk (RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n", 						PktCmdP->Command,Rup,HostP-p->RIOHosts);			ShowPacket( DBG_BOOT, PacketP );			RIOFreeCmdBlk( CmdBlkP );			return 1;		}		/*		** Build a Boot Sequence command block		**		** 02.03.1999 ARG - ESIL 0820 fix		** We no longer need to use "Boot Mode", we'll always allow		** boot requests - the boot will not complete if the device		** appears in the bindings table.		** So, this conditional is not required ...		**		if (p->RIOBootMode == RC_BOOT_NONE)			**			** If the system is in slave mode, and a boot request is			** received, set command to BOOT_ABORT so that the boot			** will not complete.			**			PktReplyP->Command			 = BOOT_ABORT;		else		**		** We'll just (always) set the command field in packet reply		** to allow an attempted boot sequence :		*/		PktReplyP->Command = BOOT_SEQUENCE;		PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts;		PktReplyP->BootSequence.LoadBase   = p->RIOConf.RtaLoadBase;		PktReplyP->BootSequence.CodeSize   = p->RIOBootCount;		CmdBlkP->Packet.len				= BOOT_SEQUENCE_LEN | PKT_CMD_BIT;		bcopy("BOOT",(void *)&CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN],4);		rio_dprintk (RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",			HostP-p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, 								p->RIOConf.RtaLoadBase);		/*		** If this host is in slave mode, send the RTA an invalid boot		** sequence command block to force it to kill the boot. We wait		** for half a second before sending this packet to prevent the RTA		** attempting to boot too often. The master host should then grab		** the RTA and make it its own.		*/		p->RIOBooting++;		RIOQueueCmdBlk( HostP, Rup, CmdBlkP );		return 1;	}	/*	** It is a request for boot data.	*/	sequence = RWORD(PktCmdP->Sequence);	rio_dprintk (RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup);	if ( sequence >= p->RIONumBootPkts ) {		rio_dprintk (RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, 					p->RIONumBootPkts);		ShowPacket( DBG_BOOT, PacketP );	}	PktReplyP->Sequence = sequence;	bcopy( p->RIOBootPackets[ p->RIONumBootPkts - sequence - 1 ], 				PktReplyP->BootData, RTA_BOOT_DATA_SIZE );	CmdBlkP->Packet.len = PKT_MAX_DATA_LEN;	ShowPacket( DBG_BOOT, &CmdBlkP->Packet );	RIOQueueCmdBlk( HostP, Rup, CmdBlkP );	return 1;}/*** This function is called when an RTA been booted.** If booted by a host, HostP->HostUniqueNum is the booting host.** If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA.** RtaUniq is the booted RTA.*/static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP ){	struct Map	*MapP = NULL;	struct Map	*MapP2 = NULL;	int	Flag;	int	found;	int	host, rta;	int	EmptySlot = -1;	int	entry, entry2;	char	*MyType, *MyName;	uint	MyLink;	ushort	RtaType;	uint	RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) +			  (RBYTE(PktCmdP->UniqNum[1]) << 8) +			  (RBYTE(PktCmdP->UniqNum[2]) << 16) +			  (RBYTE(PktCmdP->UniqNum[3]) << 24);	/* Was RIOBooting-- . That's bad. If an RTA sends two of them, the	   driver will never think that the RTA has booted... -- REW */	p->RIOBooting = 0;	rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting);	/*	** Determine type of unit (16/8 port RTA).	*/	RtaType = GetUnitType(RtaUniq);        if ( Rup >= (ushort)MAX_RUP ) {	    rio_dprintk (RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n",	     HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A');	} else {	    rio_dprintk (RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n",	     HostP->Mapping[Rup].Name, 8 * RtaType,	     RBYTE(PktCmdP->LinkNum)+'A');	}	rio_dprintk (RIO_DEBUG_BOOT, "UniqNum is 0x%x\n",RtaUniq);        if ( ( RtaUniq == 0x00000000 ) || ( RtaUniq == 0xffffffff ) )	{	    rio_dprintk (RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n");	    return TRUE;	}	/*	** If this RTA has just booted an RTA which doesn't belong to this	** system, or the system is in slave mode, do not attempt to create	** a new table entry for it.	*/	if (!RIOBootOk(p, HostP, RtaUniq))	{	    MyLink = RBYTE(PktCmdP->LinkNum);	    if (Rup < (ushort) MAX_RUP)	    {		/*		** RtaUniq was clone booted (by this RTA). Instruct this RTA		** to hold off further attempts to boot on this link for 30		** seconds.		*/		if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink))		{		    rio_dprintk (RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n",		     'A' + MyLink);		}	    }	    else	    {		/*		** RtaUniq was booted by this host. Set the booting link		** to hold off for 30 seconds to give another unit a		** chance to boot it.		*/		WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30);	    }	    rio_dprintk (RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n",	      RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum);	    return TRUE;	}	/*	** Check for a SLOT_IN_USE entry for this RTA attached to the	** current host card in the driver table.	**	** If it exists, make a note that we have booted it. Other parts of	** the driver are interested in this information at a later date,	** in particular when the booting RTA asks for an ID for this unit,	** we must have set the BOOTED flag, and the NEWBOOT flag is used	** to force an open on any ports that where previously open on this	** unit.	*/        for ( entry=0; entry<MAX_RUP; entry++ )	{	    uint sysport;	    if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) && 	       (HostP->Mapping[entry].RtaUniqueNum==RtaUniq))	    {	        HostP->Mapping[entry].Flags |= RTA_BOOTED|RTA_NEWBOOT;#ifdef NEED_TO_FIX		RIO_SV_BROADCAST(HostP->svFlags[entry]);#endif		if ( (sysport=HostP->Mapping[entry].SysPort) != NO_PORT )

⌨️ 快捷键说明

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