📄 rioinit.c
字号:
/*** -----------------------------------------------------------------------------**** Perle Specialix driver for Linux** Ported from existing RIO Driver for SCO sources. * * (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 : rioinit.c** SID : 1.3** Last Modified : 11/6/98 10:33:43** Retrieved : 11/6/98 10:33:49**** ident @(#)rioinit.c 1.3**** -----------------------------------------------------------------------------*/#ifdef SCCS_LABELSstatic char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";#endif#include <linux/config.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/errno.h>#include <linux/delay.h>#include <asm/io.h>#include <asm/system.h>#include <asm/string.h>#include <asm/semaphore.h>#include <asm/uaccess.h>#include <linux/termios.h>#include <linux/serial.h>#include <linux/generic_serial.h>#include "linux_compat.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"#include "rioioctl.h"#include "rio_linux.h"#undef bcopy#define bcopy rio_pcicopyint RIOPCIinit(struct rio_info *p, int Mode);#if 0static void RIOAllocateInterrupts(struct rio_info *);static int RIOReport(struct rio_info *);static void RIOStopInterrupts(struct rio_info *, int, int);#endifstatic int RIOScrub(int, BYTE *, int);#if 0extern int rio_intr();/*** Init time code.*/voidrioinit( p, info )struct rio_info * p;struct RioHostInfo * info;{ /* ** Multi-Host card support - taking the easy way out - sorry ! ** We allocate and set up the Host and Port structs when the ** driver is called to 'install' the first host. ** We check for this first 'call' by testing the RIOPortp pointer. */ if ( !p->RIOPortp ) { rio_dprintk (RIO_DEBUG_INIT, "Allocating and setting up driver data structures\n"); RIOAllocDataStructs(p); /* allocate host/port structs */ RIOSetupDataStructs(p); /* setup topology structs */ } RIOInitHosts( p, info ); /* hunt down the hardware */ RIOAllocateInterrupts(p); /* allocate interrupts */ RIOReport(p); /* show what we found */}/*** Initialise the Cards */ voidRIOInitHosts(p, info)struct rio_info * p;struct RioHostInfo * info;{/*** 15.10.1998 ARG - ESIL 0762 part fix** If there is no ISA card definition - we always look for PCI cards.** As we currently only support one host card this lets an ISA card** definition take precedence over PLUG and PLAY.** No ISA card - we are PLUG and PLAY with PCI.*/ /* ** Note - for PCI both these will be zero, that's okay because ** RIOPCIInit() fills them in if a card is found. */ p->RIOHosts[p->RIONumHosts].Ivec = info->vector; p->RIOHosts[p->RIONumHosts].PaddrP = info->location; /* ** Check that we are able to accommodate another host */ if ( p->RIONumHosts >= RIO_HOSTS ) { p->RIOFailed++; return; } if ( info->bus & ISA_BUS ) { rio_dprintk (RIO_DEBUG_INIT, "initialising card %d (ISA)\n", p->RIONumHosts); RIOISAinit(p, p->mode); } else { rio_dprintk (RIO_DEBUG_INIT, "initialising card %d (PCI)\n", p->RIONumHosts); RIOPCIinit(p, RIO_PCI_DEFAULT_MODE); } rio_dprintk (RIO_DEBUG_INIT, "Total hosts initialised so far : %d\n", p->RIONumHosts);#ifdef FUTURE_RELEASE if (p->bus & EISA_BUS) /* EISA card */ RIOEISAinit(p, RIO_EISA_DEFAULT_MODE); if (p->bus & MCA_BUS) /* MCA card */ RIOMCAinit(p, RIO_MCA_DEFAULT_MODE);#endif}/*** go through memory for an AT host that we pass in the device info** structure and initialise*/voidRIOISAinit(p, mode)struct rio_info * p;int mode;{ /* XXX Need to implement this. */#if 0 p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec, (int (*)())rio_intr, (char*)p->RIONumHosts); rio_dprintk (RIO_DEBUG_INIT, "Set interrupt handler, intr_tid = 0x%x\n", p->intr_tid ); if (RIODoAT(p, p->RIOHosts[p->RIONumHosts].PaddrP, mode)) { return; } else { rio_dprintk (RIO_DEBUG_INIT, "RIODoAT failed\n"); p->RIOFailed++; }#endif}/*** RIODoAT :**** Map in a boards physical address, check that the board is there,** test the board and if everything is okay assign the board an entry** in the Rio Hosts structure.*/intRIODoAT(p, Base, mode)struct rio_info * p;int Base;int mode;{#define FOUND 1#define NOT_FOUND 0 caddr_t cardAddr; /* ** Check to see if we actually have a board at this physical address. */ if ((cardAddr = RIOCheckForATCard(Base)) != 0) { /* ** Now test the board to see if it is working. */ if (RIOBoardTest(Base, cardAddr, RIO_AT, 0) == RIO_SUCCESS) { /* ** Fill out a slot in the Rio host structure. */ if (RIOAssignAT(p, Base, cardAddr, mode)) { return(FOUND); } } RIOMapout(Base, RIO_AT_MEM_SIZE, cardAddr); } return(NOT_FOUND);}caddr_tRIOCheckForATCard(Base)int Base;{ int off; struct DpRam *cardp; /* (Points at the host) */ caddr_t virtAddr; unsigned char RIOSigTab[24];/*** Table of values to search for as prom signature of a host card*/ strcpy(RIOSigTab, "JBJGPGGHINSMJPJR"); /* ** Hey! Yes, You reading this code! Yo, grab a load a this: ** ** IF the card is using WORD MODE rather than BYTE MODE ** then it will occupy 128K of PHYSICAL memory area. So, ** you might think that the following Mapin is wrong. Well, ** it isn't, because the SECOND 64K of occupied space is an ** EXACT COPY of the FIRST 64K. (good?), so, we need only ** map it in in one 64K block. */ if (RIOMapin(Base, RIO_AT_MEM_SIZE, &virtAddr) == -1) { rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't map the board in!\n"); return((caddr_t)0); } /* ** virtAddr points to the DP ram of the system. ** We now cast this to a pointer to a RIO Host, ** and have a rummage about in the PROM. */ cardp = (struct DpRam *)virtAddr; for (off=0; RIOSigTab[off]; off++) { if ((RBYTE(cardp->DpSignature[off]) & 0xFF) != RIOSigTab[off]) { /* ** Signature mismatch - card not at this address */ RIOMapout(Base, RIO_AT_MEM_SIZE, virtAddr); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't match the signature 0x%x 0x%x!\n", (int)cardp, off); return((caddr_t)0); } } /* ** If we get here then we must have found a valid board so return ** its virtual address. */ return(virtAddr);}#endif/**** RIOAssignAT :**** Fill out the fields in the p->RIOHosts structure now we know we know** we have a board present.**** bits < 0 indicates 8 bit operation requested,** bits > 0 indicates 16 bit operation.*/intRIOAssignAT(p, Base, virtAddr, mode)struct rio_info * p;int Base;caddr_t virtAddr;int mode;{ int bits; struct DpRam *cardp = (struct DpRam *)virtAddr; if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE)) bits = BYTE_OPERATION; else bits = WORD_OPERATION; /* ** Board has passed its scrub test. Fill in all the ** transient stuff. */ p->RIOHosts[p->RIONumHosts].Caddr = virtAddr; p->RIOHosts[p->RIONumHosts].CardP = (struct DpRam *)virtAddr; /* ** Revision 01 AT host cards don't support WORD operations, */ if ( RBYTE(cardp->DpRevision) == 01 ) bits = BYTE_OPERATION; p->RIOHosts[p->RIONumHosts].Type = RIO_AT; p->RIOHosts[p->RIONumHosts].Copy = bcopy; /* set this later */ p->RIOHosts[p->RIONumHosts].Slot = -1; p->RIOHosts[p->RIONumHosts].Mode = SLOW_LINKS | SLOW_AT_BUS | bits; WBYTE(p->RIOHosts[p->RIONumHosts].Control, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE ); WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt,0xff); WBYTE(p->RIOHosts[p->RIONumHosts].Control, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE ); WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt,0xff); p->RIOHosts[p->RIONumHosts].UniqueNum = ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)| ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)| ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)| ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24); rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum); p->RIONumHosts++; rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base); return(1);}#if 0#ifdef FUTURE_RELEASEint RIOMCAinit(int Mode){ uchar SlotNumber; caddr_t Caddr; uint Paddr; uint Ivec; int Handle; int ret = 0; /* ** Valid mode information for MCA cards ** is only FAST LINKS */ Mode = (Mode & FAST_LINKS) ? McaTpFastLinks : McaTpSlowLinks; rio_dprintk (RIO_DEBUG_INIT, "RIOMCAinit(%d)\n",Mode); /* ** Check out each of the slots */ for (SlotNumber = 0; SlotNumber < McaMaxSlots; SlotNumber++) { /* ** Enable the slot we want to talk to */ outb( McaSlotSelect, SlotNumber | McaSlotEnable ); /* ** Read the ID word from the slot */ if (((inb(McaIdHigh)<< 8)|inb(McaIdLow)) == McaRIOId) { rio_dprintk (RIO_DEBUG_INIT, "Potential MCA card in slot %d\n", SlotNumber); /* ** Card appears to be a RIO MCA card! */ RIOMachineType |= (1<<RIO_MCA); /* ** Just check we haven't found too many wonderful objects */ if ( RIONumHosts >= RIO_HOSTS ) { Rprintf(RIOMesgTooManyCards); return(ret); } /* ** McaIrqEnable contains the interrupt vector, and a card ** enable bit. */ Ivec = inb(McaIrqEnable); rio_dprintk (RIO_DEBUG_INIT, "Ivec is %x\n", Ivec); switch ( Ivec & McaIrqMask ) { case McaIrq9: rio_dprintk (RIO_DEBUG_INIT, "IRQ9\n"); break; case McaIrq3: rio_dprintk (RIO_DEBUG_INIT, "IRQ3\n"); break; case McaIrq4: rio_dprintk (RIO_DEBUG_INIT, "IRQ4\n"); break; case McaIrq7: rio_dprintk (RIO_DEBUG_INIT, "IRQ7\n"); break; case McaIrq10: rio_dprintk (RIO_DEBUG_INIT, "IRQ10\n"); break; case McaIrq11: rio_dprintk (RIO_DEBUG_INIT, "IRQ11\n"); break; case McaIrq12: rio_dprintk (RIO_DEBUG_INIT, "IRQ12\n"); break; case McaIrq15: rio_dprintk (RIO_DEBUG_INIT, "IRQ15\n"); break; } /* ** If the card enable bit isn't set, then set it! */ if ((Ivec & McaCardEnable) != McaCardEnable) { rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable not set - setting!\n"); outb(McaIrqEnable,Ivec|McaCardEnable); } else rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable already set\n"); /* ** Convert the IRQ enable mask into something useful */ Ivec = RIOMcaToIvec[Ivec & McaIrqMask]; /* ** Find the physical address */ rio_dprintk (RIO_DEBUG_INIT, "inb(McaMemory) is %x\n", inb(McaMemory)); Paddr = McaAddress(inb(McaMemory)); rio_dprintk (RIO_DEBUG_INIT, "MCA card has Ivec %d Addr %x\n", Ivec, Paddr); if ( Paddr != 0 ) { /* ** Tell the memory mapper that we want to talk to it */ Handle = RIOMapin( Paddr, RIO_MCA_MEM_SIZE, &Caddr ); if ( Handle == -1 ) { rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n", RIO_MCA_MEM_SIZE, Paddr; continue; } rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr); /* ** And check that it is actually there! */ if ( RIOBoardTest( Paddr,Caddr,RIO_MCA,SlotNumber ) == RIO_SUCCESS ) { rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n"); rio_dprintk (RIO_DEBUG_INIT, "Slot %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", SlotNumber, RIO_MCA, Paddr, Caddr, Mode); /* ** Board has passed its scrub test. Fill in all the ** transient stuff. */ p->RIOHosts[RIONumHosts].Slot = SlotNumber; p->RIOHosts[RIONumHosts].Ivec = Ivec; p->RIOHosts[RIONumHosts].Type = RIO_MCA; p->RIOHosts[RIONumHosts].Copy = bcopy; p->RIOHosts[RIONumHosts].PaddrP = Paddr; p->RIOHosts[RIONumHosts].Caddr = Caddr; p->RIOHosts[RIONumHosts].CardP = (struct DpRam *)Caddr; p->RIOHosts[RIONumHosts].Mode = Mode; WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt , 0xff); p->RIOHosts[RIONumHosts].UniqueNum = ((RBYTE(p->RIOHosts[RIONumHosts].Unique[0])&0xFF)<<0)| ((RBYTE(p->RIOHosts[RIONumHosts].Unique[1])&0xFF)<<8)| ((RBYTE(p->RIOHosts[RIONumHosts].Unique[2])&0xFF)<<16)| ((RBYTE(p->RIOHosts[RIONumHosts].Unique[3])&0xFF)<<24); RIONumHosts++; ret++; } else { /* ** It failed the test, so ignore it. */ rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n"); RIOMapout(Paddr, RIO_MCA_MEM_SIZE, Caddr ); } } else { rio_dprintk (RIO_DEBUG_INIT, "Slot %d - Paddr zero!\n", SlotNumber); } } else { rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -