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

📄 rioroute.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
    */    if ( (HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) &&         (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq) )    {      if (RtaType == TYPE_RTA16)      {	  ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1;          rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n",					    RtaUniq,ThisUnit,ThisUnit2);      }      else          rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n",					    RtaUniq,ThisUnit);      /*      ** If we have no knowledge of booting it, then the host has      ** been re-booted, and so we must kill the RTA, so that it      ** will be booted again (potentially with new bins)      ** and it will then re-ask for an ID, which we will service.      */      if ( (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) && 	  !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED) )      {	if ( !(HostP->Mapping[ThisUnit].Flags & MSG_DONE) )	{	    if ( !p->RIONoMessage )	        cprintf("RTA '%s' is being updated.\n",HostP->Mapping[ThisUnit].Name);	    HostP->Mapping[ThisUnit].Flags |= MSG_DONE;	}	PktReplyP->Command = ROUTE_FOAD;	HostP->Copy("RT_FOAD",PktReplyP->CommandText,7);	RIOQueueCmdBlk(HostP, Rup, CmdBlkP);	return TRUE;      }      /*      ** Send the ID (entry) to this RTA. The ID number is implicit as      ** the offset into the table. It is worth noting at this stage      ** that offset zero in the table contains the entries for the      ** RTA with ID 1!!!!      */      PktReplyP->Command = ROUTE_ALLOCATE;      PktReplyP->IDNum   = ThisUnit+1;      if (RtaType == TYPE_RTA16)      {        if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE)	    /*	    ** Adjust the phb and tx pkt dest_units for 2nd block of 8	    ** only if the RTA has ports associated (SLOT_IN_USE)	    */	    RIOFixPhbs(p, HostP, ThisUnit2);	    PktReplyP->IDNum2  = ThisUnit2+1;	    rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n",	          HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2);      }      else      {	    PktReplyP->IDNum2 = ROUTE_NO_ID;	    rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n",	          HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum);      }      HostP->Copy("RT_ALLOCAT",PktReplyP->CommandText,10);      RIOQueueCmdBlk( HostP, Rup, CmdBlkP);      /*      ** If this is a freshly booted RTA, then we need to re-open      ** the ports, if any where open, so that data may once more      ** flow around the system!      */      if ( (HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) &&	   (HostP->Mapping[ThisUnit].SysPort != NO_PORT) )      {	/*	** look at the ports associated with this beast and	** see if any where open. If they was, then re-open	** them, using the info from the tty flags.	*/	for ( port=0; port<PORTS_PER_RTA; port++ )	{	  PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort];	  if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )	  {	    rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");	    rio_spin_lock_irqsave(&PortP->portSem, flags);	    PortP->MagicFlags |= MAGIC_REBOOT;	    rio_spin_unlock_irqrestore(&PortP->portSem, flags);	  }	}	if (RtaType == TYPE_RTA16)	{	  for ( port=0; port<PORTS_PER_RTA; port++ )	  {	    PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort];	    if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )	    {	      rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");	      rio_spin_lock_irqsave(&PortP->portSem, flags);	      PortP->MagicFlags |= MAGIC_REBOOT;	      rio_spin_unlock_irqrestore(&PortP->portSem, flags);	    }	  }	}      }      /*      ** keep a copy of the module types!      */      HostP->UnixRups[ThisUnit].ModTypes = Mod;      if (RtaType == TYPE_RTA16)	      HostP->UnixRups[ThisUnit2].ModTypes = Mod;      /*      ** If either of the modules on this unit is read-only or write-only      ** or none-xprint, then we need to transfer that info over to the      ** relevant ports.      */      if ( HostP->Mapping[ThisUnit].SysPort != NO_PORT )      {        for ( port=0; port<PORTS_PER_MODULE; port++ )	{	  p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK;	  p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]->Config |=	   p->RIOModuleTypes[Mod1].Flags[port];	  p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK;	  p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port];	}	if (RtaType == TYPE_RTA16)	{          for ( port=0; port<PORTS_PER_MODULE; port++ )	  {	    p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK;	    p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port];	    p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK;	    p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port];          }	}      }      /*      ** Job done, get on with the interrupts!      */      return TRUE;    }  }  /*  ** There is no table entry for this RTA at all.  **  ** Lets check to see if we actually booted this unit - if not,  ** then we reset it and it will go round the loop of being booted  ** we can then worry about trying to fit it into the table.  */  for ( ThisUnit=0; ThisUnit<HostP->NumExtraBooted; ThisUnit++ )    if ( HostP->ExtraUnits[ThisUnit] == RtaUniq )      break;  if ( ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS )  {    /*    ** if the unit wasn't in the table, and the table wasn't full, then    ** we reset the unit, because we didn't boot it.    ** However, if the table is full, it could be that we did boot    ** this unit, and so we won't reboot it, because it isn't really    ** all that disasterous to keep the old bins in most cases. This    ** is a rather tacky feature, but we are on the edge of reallity    ** here, because the implication is that someone has connected    ** 16+MAX_EXTRA_UNITS onto one host.    */    static int UnknownMesgDone = 0;    if ( !UnknownMesgDone )    {	if (! p->RIONoMessage)	    cprintf("One or more unknown RTAs are being updated.\n");	UnknownMesgDone = 1;    }    PktReplyP->Command = ROUTE_FOAD;    HostP->Copy("RT_FOAD",PktReplyP->CommandText,7);  }  else  {    /*    ** we did boot it (as an extra), and there may now be a table    ** slot free (because of a delete), so we will try to make    ** a tentative entry for it, so that the configurator can see it    ** and fill in the details for us.    */    if (RtaType == TYPE_RTA16)    {	if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0)	{	    RIODefaultName(p, HostP, ThisUnit);	    FillSlot(ThisUnit, ThisUnit2, RtaUniq, HostP);	}    }    else    {	if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0)	{	    RIODefaultName(p, HostP, ThisUnit);	    FillSlot(ThisUnit, 0, RtaUniq, HostP);	}    }    PktReplyP->Command = ROUTE_USED;    HostP->Copy("RT_USED",PktReplyP->CommandText,7);  }  RIOQueueCmdBlk( HostP, Rup, CmdBlkP);  return TRUE;}voidRIOFixPhbs(p, HostP, unit)struct rio_info *p;struct Host *HostP;uint unit;{	ushort			link, port;	struct Port		*PortP;	unsigned long flags;	int PortN = HostP->Mapping[unit].SysPort;	rio_dprintk (RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN);	if (PortN != -1) {		ushort		dest_unit = HostP->Mapping[unit].ID2;		/*		** Get the link number used for the 1st 8 phbs on this unit.		*/		PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort];		link = RWORD(PortP->PhbP->link);		for (port = 0; port < PORTS_PER_RTA; port++, PortN++) {			ushort		dest_port = port + 8;#if 0			uint		PktInt;#endif			WORD		*TxPktP;			PKT		*Pkt;			PortP = p->RIOPortp[PortN];			rio_spin_lock_irqsave(&PortP->portSem, flags);			/*			** If RTA is not powered on, the tx packets will be			** unset, so go no further.			*/			if (PortP->TxStart == 0) {					rio_dprintk (RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n");					rio_spin_unlock_irqrestore(&PortP->portSem, flags);					break;			}			/*			** For the second slot of a 16 port RTA, the driver needs to			** sort out the phb to port mappings. The dest_unit for this			** group of 8 phbs is set to the dest_unit of the accompanying			** 8 port block. The dest_port of the second unit is set to			** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port			** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6			** (being the second map ID) will be sent to dest_unit 5, port			** 14. When this RTA is deleted, dest_unit for ID 6 will be			** restored, and the dest_port will be reduced by 8.			** Transmit packets also have a destination field which needs			** adjusting in the same manner.			** Note that the unit/port bytes in 'dest' are swapped.			** We also need to adjust the phb and rup link numbers for the			** second block of 8 ttys.			*/			for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) {				/*				** *TxPktP is the pointer to the transmit packet on the host				** card. This needs to be translated into a 32 bit pointer				** so it can be accessed from the driver.				*/				Pkt = (PKT *) RIO_PTR(HostP->Caddr,RINDW(TxPktP));				/*				** If the packet is used, reset it.				*/				Pkt = (PKT *)((uint)Pkt & ~PKT_IN_USE);				WBYTE(Pkt->dest_unit, dest_unit);				WBYTE(Pkt->dest_port, dest_port);			}			rio_dprintk (RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n",					RWORD(PortP->PhbP->destination) & 0xff,					(RWORD(PortP->PhbP->destination) >> 8) & 0xff,					dest_unit, dest_port);			WWORD(PortP->PhbP->destination, dest_unit + (dest_port << 8));			WWORD(PortP->PhbP->link, link);			rio_spin_unlock_irqrestore(&PortP->portSem, flags);		}		/*		** Now make sure the range of ports to be serviced includes		** the 2nd 8 on this 16 port RTA.		*/		if (link > 3) return;		if (((unit * 8) + 7) > RWORD(HostP->LinkStrP[link].last_port)) {			rio_dprintk (RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7);			WWORD(HostP->LinkStrP[link].last_port, (unit * 8) + 7);		}	}}/*** Check to see if the new disconnection has isolated this unit.** If it has, then invalidate all its link information, and tell** the world about it. This is done to ensure that the configurator** only gets up-to-date information about what is going on.*/static intRIOCheckIsolated(p, HostP, UnitId)struct rio_info *	p;struct Host *HostP;uint UnitId;{	unsigned long flags;	rio_spin_lock_irqsave(&HostP->HostLock, flags);#ifdef CHECK	CheckHostP( HostP );	CheckUnitId( UnitId );#endif	if ( RIOCheck( HostP, UnitId ) ) {		rio_dprintk (RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId);		rio_spin_unlock_irqrestore(&HostP->HostLock, flags);		return(0);	}	RIOIsolate(p, HostP, UnitId );	RIOSetChange(p);	rio_spin_unlock_irqrestore(&HostP->HostLock, flags);	return 1;}/*** Invalidate all the link interconnectivity of this unit, and of** all the units attached to it. This will mean that the entire** subnet will re-introduce itself.*/static intRIOIsolate(p, HostP, UnitId)struct rio_info *	p;struct Host *		HostP;uint UnitId; {	uint link, unit;#ifdef CHECK	CheckHostP( HostP );	CheckUnitId( UnitId );#endif	UnitId--;		/* this trick relies on the Unit Id being UNSIGNED! */	if ( UnitId >= MAX_RUP )	/* dontcha just lurv unsigned maths! */		return(0);	if ( HostP->Mapping[UnitId].Flags & BEEN_HERE )		return(0);	HostP->Mapping[UnitId].Flags |= BEEN_HERE;	if ( p->RIOPrintDisabled == DO_PRINT )		rio_dprintk (RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name);	for ( link=0; link<LINKS_PER_UNIT; link++) {		unit = HostP->Mapping[UnitId].Topology[link].Unit;		HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT;		HostP->Mapping[UnitId].Topology[link].Link = NO_LINK;		RIOIsolate(p, HostP, unit );	}	HostP->Mapping[UnitId].Flags &= ~BEEN_HERE;	return 1;}static intRIOCheck(HostP, UnitId)struct Host *HostP;uint UnitId;{  unsigned char link;#ifdef CHECK	CheckHostP( HostP );	CheckUnitId( UnitId );#endif/* 	rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */	rio_dprintk (RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId);	if ( UnitId == HOST_ID ) {		/* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */		return 1;	}	UnitId--;	if ( UnitId >= MAX_RUP ) {		/* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */		return 0;	}	for ( link=0; link<LINKS_PER_UNIT; link++ ) {		if ( HostP->Mapping[UnitId].Topology[link].Unit==HOST_ID ) {			/* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n", 						UnitId, 'A'+link)); */			return 1;		}	}	if ( HostP->Mapping[UnitId].Flags & BEEN_HERE ) {		/* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */

⌨️ 快捷键说明

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