📄 rioinit.c
字号:
nbanks = (type == RIO_PCI) ? 3 : 4; if (nbanks == 4) ram[3] = (char *)&DpRam->DpScratch[0]; if (nbanks == 3) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n", (int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2]); } else { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n", (int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2], (int)ram[3], size[3]); } /* ** This scrub operation will test for crosstalk between ** banks. TEST_END is a magic number, and relates to the offset ** within the 'val' array used by Scrub. */ for (op=0; op<TEST_END; op++) { for (bank=0; bank<nbanks; bank++) { if (RIOScrub(op, (BYTE *)ram[bank], size[bank]) == RIO_FAIL) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n", bank, op); return RIO_FAIL; } } } rio_dprintk (RIO_DEBUG_INIT, "Test completed\n"); return RIO_SUCCESS;}/*** Scrub an area of RAM.** Define PRETEST and POSTTEST for a more thorough checking of the** state of the memory.** Call with op set to an index into the above 'val' array to determine** which value will be written into memory.** Call with op set to zero means that the RAM will not be read and checked** before it is written.** Call with op not zero, and the RAM will be read and compated with val[op-1]** to check that the data from the previous phase was retained.*/static intRIOScrub(op, ram, size)int op;BYTE * ram;int size; { int off; unsigned char oldbyte; unsigned char newbyte; unsigned char invbyte; unsigned short oldword; unsigned short newword; unsigned short invword; unsigned short swapword; if (op) { oldbyte = val[op-1]; oldword = oldbyte | (oldbyte<<8); } else oldbyte = oldword = 0; /* Tell the compiler we've initilalized them. */ newbyte = val[op]; newword = newbyte | (newbyte<<8); invbyte = ~newbyte; invword = invbyte | (invbyte<<8); /* ** Check that the RAM contains the value that should have been left there ** by the previous test (not applicable for pass zero) */ if (op) { for (off=0; off<size; off++) { if (RBYTE(ram[off]) != oldbyte) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off])); return RIO_FAIL; } } for (off=0; off<size; off+=2) { if (*(ushort *)&ram[off] != oldword) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword,*(ushort *)&ram[off]); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1])); return RIO_FAIL; } } } /* ** Now write the INVERSE of the test data into every location, using ** BYTE write operations, first checking before each byte is written ** that the location contains the old value still, and checking after ** the write that the location contains the data specified - this is ** the BYTE read/write test. */ for (off=0; off<size; off++) { if (op && (RBYTE(ram[off]) != oldbyte)) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off])); return RIO_FAIL; } WBYTE(ram[off],invbyte); if (RBYTE(ram[off]) != invbyte) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, invbyte, RBYTE(ram[off])); return RIO_FAIL; } } /* ** now, use WORD operations to write the test value into every location, ** check as before that the location contains the previous test value ** before overwriting, and that it contains the data value written ** afterwards. ** This is the WORD operation test. */ for (off=0; off<size; off+=2) { if (*(ushort *)&ram[off] != invword) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n", off, invword, *(ushort *)&ram[off]); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1])); return RIO_FAIL; } *(ushort *)&ram[off] = newword; if ( *(ushort *)&ram[off] != newword ) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1])); return RIO_FAIL; } } /* ** now run through the block of memory again, first in byte mode ** then in word mode, and check that all the locations contain the ** required test data. */ for (off=0; off<size; off++) { if (RBYTE(ram[off]) != newbyte) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off])); return RIO_FAIL; } } for (off=0; off<size; off+=2) { if ( *(ushort *)&ram[off] != newword ) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1])); return RIO_FAIL; } } /* ** time to check out byte swapping errors */ swapword = invbyte | (newbyte << 8); for (off=0; off<size; off+=2) { WBYTE(ram[off],invbyte); WBYTE(ram[off+1],newbyte); } for ( off=0; off<size; off+=2 ) { if (*(ushort *)&ram[off] != swapword) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, swapword, *((ushort *)&ram[off])); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1])); return RIO_FAIL; } *((ushort *)&ram[off]) = ~swapword; } for (off=0; off<size; off+=2) { if (RBYTE(ram[off]) != newbyte) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off])); return RIO_FAIL; } if (RBYTE(ram[off+1]) != invbyte) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off+1, invbyte, RBYTE(ram[off+1])); return RIO_FAIL; } *((ushort *)&ram[off]) = newword; } return RIO_SUCCESS;}/*** try to ensure that every host is either in polled mode** or is in interrupt mode. Only allow interrupt mode if** all hosts can interrupt (why?)** and force into polled mode if told to. Patch up the** interrupt vector & salute The Queen when you've done.*/#if 0static voidRIOAllocateInterrupts(p)struct rio_info * p;{ int Host; /* ** Easy case - if we have been told to poll, then we poll. */ if (p->mode & POLLED_MODE) { RIOStopInterrupts(p, 0, 0); return; } /* ** check - if any host has been set to polled mode, then all must be. */ for (Host=0; Host<p->RIONumHosts; Host++) { if ( (p->RIOHosts[Host].Type != RIO_AT) && (p->RIOHosts[Host].Ivec == POLLED) ) { RIOStopInterrupts(p, 1, Host ); return; } } for (Host=0; Host<p->RIONumHosts; Host++) { if (p->RIOHosts[Host].Type == RIO_AT) { if ( (p->RIOHosts[Host].Ivec - 32) == 0) { RIOStopInterrupts(p, 2, Host ); return; } } }}/*** something has decided that we can't be doing with these** new-fangled interrupt thingies. Set everything up to just** poll.*/static voidRIOStopInterrupts(p, Reason, Host)struct rio_info * p;int Reason;int Host; {#ifdef FUTURE_RELEASE switch (Reason) { case 0: /* forced into polling by rio_polled */ break; case 1: /* SCU has set 'Host' into polled mode */ break; case 2: /* there aren't enough interrupt vectors for 'Host' */ break; }#endif for (Host=0; Host<p->RIONumHosts; Host++ ) { struct Host *HostP = &p->RIOHosts[Host]; switch (HostP->Type) { case RIO_AT: /* ** The AT host has it's interrupts disabled by clearing the ** int_enable bit. */ HostP->Mode &= ~INTERRUPT_ENABLE; HostP->Ivec = POLLED; break;#ifdef FUTURE_RELEASE case RIO_EISA: /* ** The EISA host has it's interrupts disabled by setting the ** Ivec to zero */ HostP->Ivec = POLLED; break;#endif case RIO_PCI: /* ** The PCI host has it's interrupts disabled by clearing the ** int_enable bit, like a regular host card. */ HostP->Mode &= ~RIO_PCI_INT_ENABLE; HostP->Ivec = POLLED; break;#ifdef FUTURE_RELEASE case RIO_MCA: /* ** There's always one, isn't there? ** The MCA host card cannot have it's interrupts disabled. */ RIOPatchVec(HostP); break;#endif } }}/*** This function is called at init time to setup the data structures.*/voidRIOAllocDataStructs(p)struct rio_info * p;{ int port, host, tm; p->RIOPortp = (struct Port *)sysbrk(RIO_PORTS * sizeof(struct Port)); if (!p->RIOPortp) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for port structures\n"); p->RIOFailed++; return; } bzero( p->RIOPortp, sizeof(struct Port) * RIO_PORTS ); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: allocated and cleared memory for port structs\n"); rio_dprintk (RIO_DEBUG_INIT, "First RIO port struct @0x%x, size=0x%x bytes\n", (int)p->RIOPortp, sizeof(struct Port)); for( port=0; port<RIO_PORTS; port++ ) { p->RIOPortp[port].PortNum = port; p->RIOPortp[port].TtyP = &p->channel[port]; sreset (p->RIOPortp[port].InUse); /* Let the first guy uses it */ p->RIOPortp[port].portSem = -1; /* Let the first guy takes it */ p->RIOPortp[port].ParamSem = -1; /* Let the first guy takes it */ p->RIOPortp[port].timeout_id = 0; /* Let the first guy takes it */ } p->RIOHosts = (struct Host *)sysbrk(RIO_HOSTS * sizeof(struct Host)); if (!p->RIOHosts) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for host structures\n"); p->RIOFailed++; return; } bzero(p->RIOHosts, sizeof(struct Host)*RIO_HOSTS); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: allocated and cleared memory for host structs\n"); rio_dprintk (RIO_DEBUG_INIT, "First RIO host struct @0x%x, size=0x%x bytes\n", (int)p->RIOHosts, sizeof(struct Host)); for( host=0; host<RIO_HOSTS; host++ ) { spin_lock_init (&p->RIOHosts[host].HostLock); p->RIOHosts[host].timeout_id = 0; /* Let the first guy takes it */ } /* ** check that the buffer size is valid, round down to the next power of ** two if necessary; if the result is zero, then, hey, no double buffers. */ for ( tm = 1; tm && tm <= p->RIOConf.BufferSize; tm <<= 1 ) ; tm >>= 1; p->RIOBufferSize = tm; p->RIOBufferMask = tm ? tm - 1 : 0;}/*** this function gets called whenever the data structures need to be** re-setup, for example, after a riohalt (why did I ever invent it?)*/voidRIOSetupDataStructs(p)struct rio_info * p;{ int host, entry, rup; for ( host=0; host<RIO_HOSTS; host++ ) { struct Host *HostP = &p->RIOHosts[host]; for ( entry=0; entry<LINKS_PER_UNIT; entry++ ) { HostP->Topology[entry].Unit = ROUTE_DISCONNECT; HostP->Topology[entry].Link = NO_LINK; } bcopy("HOST X", HostP->Name, 7); HostP->Name[5] = '1'+host; for (rup=0; rup<(MAX_RUP + LINKS_PER_UNIT); rup++) { if (rup < MAX_RUP) { for (entry=0; entry<LINKS_PER_UNIT; entry++ ) { HostP->Mapping[rup].Topology[entry].Unit = ROUTE_DISCONNECT; HostP->Mapping[rup].Topology[entry].Link = NO_LINK; } RIODefaultName(p, HostP, rup); } spin_lock_init(&HostP->UnixRups[rup].RupLock); } }}#endifintRIODefaultName(p, HostP, UnitId)struct rio_info * p;struct Host * HostP;uint UnitId;{#ifdef CHECK CheckHost( Host ); CheckUnitId( UnitId );#endif bcopy("UNKNOWN RTA X-XX",HostP->Mapping[UnitId].Name,17); HostP->Mapping[UnitId].Name[12]='1'+(HostP-p->RIOHosts); if ((UnitId+1) > 9) { HostP->Mapping[UnitId].Name[14]='0'+((UnitId+1)/10); HostP->Mapping[UnitId].Name[15]='0'+((UnitId+1)%10); } else { HostP->Mapping[UnitId].Name[14]='1'+UnitId; HostP->Mapping[UnitId].Name[15]=0; } return 0;}#define RIO_RELEASE "Linux"#define RELEASE_ID "1.0"#if 0static intRIOReport(p)struct rio_info * p;{ char * RIORelease = RIO_RELEASE; char * RIORelID = RELEASE_ID; int host; rio_dprintk (RIO_DEBUG_INIT, "RIO : Release: %s ID: %s\n", RIORelease, RIORelID); if ( p->RIONumHosts==0 ) { rio_dprintk (RIO_DEBUG_INIT, "\nNo Hosts configured\n"); return(0); } for ( host=0; host < p->RIONumHosts; host++ ) { struct Host *HostP = &p->RIOHosts[host]; switch ( HostP->Type ) { case RIO_AT: rio_dprintk (RIO_DEBUG_INIT, "AT BUS : found the card at 0x%x\n", HostP->PaddrP); } } return 0;}#endifstatic struct rioVersion stVersion;struct rioVersion *RIOVersid(void){ strlcpy(stVersion.version, "RIO driver for linux V1.0", sizeof(stVersion.version)); strlcpy(stVersion.buildDate, __DATE__, sizeof(stVersion.buildDate)); return &stVersion;}#if 0intRIOMapin(paddr, size, vaddr)paddr_t paddr;int size;caddr_t * vaddr;{ *vaddr = (caddr_t)permap( (long)paddr, size); return ((int)*vaddr);}voidRIOMapout(paddr, size, vaddr)paddr_t paddr;long size;caddr_t vaddr;{}#endifvoidRIOHostReset(Type, DpRamP, Slot)uint Type;volatile struct DpRam *DpRamP;uint Slot; { /* ** Reset the Tpu */ rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type); switch ( Type ) { case RIO_AT: rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n"); WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | BYTE_OPERATION | SLOW_LINKS | SLOW_AT_BUS); WBYTE(DpRamP->DpResetTpu, 0xFF); udelay(3); rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | BYTE_OPERATION | SLOW_LINKS | SLOW_AT_BUS); WBYTE(DpRamP->DpResetTpu, 0xFF); udelay(3); break;#ifdef FUTURE_RELEASE case RIO_EISA: /* ** Bet this doesn't work! */ OUTBZ( Slot, EISA_CONTROL_PORT, EISA_TP_RUN | EISA_TP_BUS_DISABLE | EISA_TP_SLOW_LINKS | EISA_TP_BOOT_FROM_RAM ); OUTBZ( Slot, EISA_CONTROL_PORT, EISA_TP_RESET | EISA_TP_BUS_DISABLE | EISA_TP_SLOW_LINKS | EISA_TP_BOOT_FROM_RAM ); suspend( 3 ); OUTBZ( Slot, EISA_CONTROL_PORT, EISA_TP_RUN | EISA_TP_BUS_DISABLE | EISA_TP_SLOW_LINKS | EISA_TP_BOOT_FROM_RAM ); break; case RIO_MCA: WBYTE(DpRamP->DpControl , McaTpBootFromRam | McaTpBusDisable ); WBYTE(DpRamP->DpResetTpu , 0xFF ); suspend( 3 ); WBYTE(DpRamP->DpControl , McaTpBootFromRam | McaTpBusDisable ); WBYTE(DpRamP->DpResetTpu , 0xFF ); suspend( 3 ); break;#endif case RIO_PCI: rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n"); DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM; DpRamP->DpResetInt = 0xFF; DpRamP->DpResetTpu = 0xFF; udelay(100); /* for (i=0; i<6000; i++); */ /* suspend( 3 ); */ break;#ifdef FUTURE_RELEASE default: Rprintf(RIOMesgNoSupport,Type,DpRamP,Slot); return;#endif default: rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n"); break; } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -