📄 riotable.c
字号:
continue; } /* ** Its an RTA entry, so fill in the host mapping entries for it ** and the port mapping entries. Notice that entry zero is for ** ID one. */ HostMapP = &HostP->Mapping[MapP->ID-1]; if (MapP->Flags & SLOT_IN_USE) { rio_dprintk (RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name); /* ** structure assign, then sort out the bits we shouldn't have done */ *HostMapP = *MapP; HostMapP->Flags = SLOT_IN_USE; if (MapP->Flags & RTA16_SECOND_SLOT) HostMapP->Flags |= RTA16_SECOND_SLOT; RIOReMapPorts(p, HostP, HostMapP ); } else { rio_dprintk (RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name); } } for ( Entry=0; Entry< TOTAL_MAP_ENTRIES; Entry++ ) { p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry]; } for ( Host=0; Host<p->RIONumHosts; Host++ ) { for ( SubEnt=0; SubEnt<LINKS_PER_UNIT; SubEnt++ ) { p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT; p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK; } for ( Entry=0; Entry<MAX_RUP; Entry++ ) { for ( SubEnt=0; SubEnt<LINKS_PER_UNIT; SubEnt++ ) { p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit = ROUTE_DISCONNECT; p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link = NO_LINK; } } if ( !p->RIOHosts[Host].Name[0] ) { bcopy("HOST 1",p->RIOHosts[Host].Name,7); p->RIOHosts[Host].Name[5] += Host; } /* ** Check that default name assigned is unique. */ Host1 = Host; NameIsUnique = 0; while (!NameIsUnique) { NameIsUnique = 1; for ( Host2=0; Host2<p->RIONumHosts; Host2++ ) { if (Host2 == Host) continue; if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name) == 0) { NameIsUnique = 0; Host1++; if (Host1 >= p->RIONumHosts) Host1 = 0; p->RIOHosts[Host].Name[5] = '1' + Host1; } } } /* ** Rename host if name already used. */ if (Host1 != Host) { rio_dprintk (RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name); bcopy("HOST 1",p->RIOHosts[Host].Name,7); p->RIOHosts[Host].Name[5] += Host1; } rio_dprintk (RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name); } return 0;}/*** User process needs the config table - build it from first** principles.*/intRIOApel(p)struct rio_info * p;{ int Host; int link; int Rup; int Next = 0; struct Map *MapP; struct Host *HostP; long oldspl; disable(oldspl); /* strange but true! */ rio_dprintk (RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n"); bzero((caddr_t)&p->RIOConnectTable[0], sizeof(struct Map) * TOTAL_MAP_ENTRIES ); for ( Host=0; Host<RIO_HOSTS; Host++ ) { rio_dprintk (RIO_DEBUG_TABLE, "Processing host %d\n", Host); HostP = &p->RIOHosts[Host]; MapP = &p->RIOConnectTable[Next++]; MapP->HostUniqueNum = HostP->UniqueNum; if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) continue; MapP->RtaUniqueNum = 0; MapP->ID = 0; MapP->Flags = SLOT_IN_USE; MapP->SysPort = NO_PORT; for ( link=0; link<LINKS_PER_UNIT; link++ ) MapP->Topology[link] = HostP->Topology[link]; bcopy(HostP->Name,MapP->Name,MAX_NAME_LEN); for ( Rup=0; Rup<MAX_RUP; Rup++ ) { if ( HostP->Mapping[Rup].Flags & (SLOT_IN_USE|SLOT_TENTATIVE) ) { p->RIOConnectTable[Next] = HostP->Mapping[Rup]; if ( HostP->Mapping[Rup].Flags & SLOT_IN_USE) p->RIOConnectTable[Next].Flags |= SLOT_IN_USE; if ( HostP->Mapping[Rup].Flags & SLOT_TENTATIVE) p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE; if ( HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT ) p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT; Next++; } } } restore(oldspl); return 0;}/*** config.rio has taken a dislike to one of the gross maps entries.** if the entry is suitably inactive, then we can gob on it and remove** it from the table.*/intRIODeleteRta(p, MapP)struct rio_info *p;struct Map *MapP;{ int host, entry, port, link; int SysPort; struct Host *HostP; struct Map *HostMapP; struct Port *PortP; int work_done = 0; unsigned long lock_flags, sem_flags; rio_dprintk (RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n", MapP->HostUniqueNum, MapP->RtaUniqueNum); for ( host=0; host < p->RIONumHosts; host++ ) { HostP = &p->RIOHosts[host]; rio_spin_lock_irqsave( &HostP->HostLock, lock_flags ); if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) { rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); continue; } for ( entry=0; entry<MAX_RUP; entry++ ) { if ( MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum ) { HostMapP = &HostP->Mapping[entry]; rio_dprintk (RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", entry, HostP->Name); /* ** Check all four links of the unit are disconnected */ for ( link=0; link< LINKS_PER_UNIT; link++ ) { if ( HostMapP->Topology[link].Unit != ROUTE_DISCONNECT ) { rio_dprintk (RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n"); p->RIOError.Error = UNIT_IS_IN_USE; rio_spin_unlock_irqrestore( &HostP->HostLock, lock_flags); return -EBUSY; } } /* ** Slot has been allocated, BUT not booted/routed/ ** connected/selected or anything else-ed */ SysPort = HostMapP->SysPort; if ( SysPort != NO_PORT ) { for (port=SysPort; port < SysPort+PORTS_PER_RTA; port++) { PortP = p->RIOPortp[port]; rio_dprintk (RIO_DEBUG_TABLE, "Unmap port\n"); rio_spin_lock_irqsave( &PortP->portSem, sem_flags ); PortP->Mapped = 0; if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) { rio_dprintk (RIO_DEBUG_TABLE, "Gob on port\n"); PortP->TxBufferIn = PortP->TxBufferOut = 0; /* What should I do wakeup( &PortP->TxBufferIn ); wakeup( &PortP->TxBufferOut); */ PortP->InUse = NOT_INUSE; /* What should I do wakeup( &PortP->InUse ); signal(PortP->TtyP->t_pgrp,SIGKILL); ttyflush(PortP->TtyP,(FREAD|FWRITE)); */ PortP->State |= RIO_CLOSING | RIO_DELETED; } /* ** For the second slot of a 16 port RTA, the ** driver needs to reset the changes made to ** the phb to port mappings in RIORouteRup. */ if (PortP->SecondBlock) { ushort dest_unit = HostMapP->ID; ushort dest_port = port - SysPort; WORD *TxPktP; PKT *Pkt; 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, RWORD(*TxPktP)); rio_dprintk (RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", *TxPktP, Pkt->dest_unit, Pkt->dest_port, dest_unit, dest_port); WWORD(Pkt->dest_unit, dest_unit); WWORD(Pkt->dest_port, dest_port); } rio_dprintk (RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, PortP->PhbP->destination & 0xff, (PortP->PhbP->destination >> 8) & 0xff, dest_unit, dest_port); WWORD(PortP->PhbP->destination, dest_unit + (dest_port << 8)); } rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags); } } rio_dprintk (RIO_DEBUG_TABLE, "Entry nulled.\n"); bzero((char *)HostMapP,sizeof(struct Map)); work_done++; } } rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); } /* XXXXX lock me up */ for ( entry=0; entry< TOTAL_MAP_ENTRIES; entry++ ) { if ( p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum ) { bzero((char *)&p->RIOSavedTable[entry],sizeof(struct Map)); work_done++; } if ( p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum ) { bzero((char *)&p->RIOConnectTable[entry],sizeof(struct Map)); work_done++; } } if ( work_done ) return 0; rio_dprintk (RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n"); p->RIOError.Error = COULDNT_FIND_ENTRY; return -ENXIO;}int RIOAssignRta( struct rio_info *p, struct Map *MapP ){ int host; struct Map *HostMapP; char *sptr; int link; rio_dprintk (RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum,MapP->RtaUniqueNum, MapP->ID, (int)MapP->SysPort); if ((MapP->ID != (ushort)-1) && ((int)MapP->ID < (int)1 || (int)MapP->ID > MAX_RUP )) { rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; return -EINVAL; } if (MapP->RtaUniqueNum == 0) { rio_dprintk (RIO_DEBUG_TABLE, "Rta Unique number zero!\n"); p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO; return -EINVAL; } if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA) ) { rio_dprintk (RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA); p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; return -EINVAL; } if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS) ) { rio_dprintk (RIO_DEBUG_TABLE, "Port %d not valid!\n",(int)MapP->SysPort); p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; return -EINVAL; } /* ** Copy the name across to the map entry. */ MapP->Name[MAX_NAME_LEN-1] = '\0'; sptr = MapP->Name; while ( *sptr ) { if ( *sptr<' ' || *sptr>'~' ) { rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); p->RIOError.Error = BAD_CHARACTER_IN_NAME; return -EINVAL; } sptr++; } for ( host=0; host < p->RIONumHosts; host++ ) { if ( MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum ) { if ( (p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING ) { p->RIOError.Error = HOST_NOT_RUNNING; return -ENXIO; } /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -