!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/char/rio/   drwxr-xr-x
Free 318.35 GB of 458.09 GB (69.49%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     rioinit.c (42.38 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** -----------------------------------------------------------------------------
**
**  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_LABELS
static char *_rioinit_c_sccs_ = "@(#)rioinit.c    1.3";
#endif

#define __NO_VERSION__
#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.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/compatmac.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_pcicopy

int
RIOPCIinit(struct rio_info *p, int Mode);


#if 0
extern int    rio_intr();

/*
**    Init time code.
*/
void
rioinit( 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 
*/ 
void
RIOInitHosts(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 accomodate 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
*/
void
RIOISAinit(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.
*/
int
RIODoAT(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_t
RIOCheckForATCard(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.
*/
int
RIOAssignAT(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_RELEASE
int 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);
    }
    }
    /*
    ** Now we have checked all the slots, turn off the MCA slot selector
    */
    outb(McaSlotSelect,0);
    rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
    return ret;
}

int RIOEISAinit( int Mode )
{
    static int EISADone = 0;
    uint Paddr;
    int PollIntMixMsgDone = 0;
    caddr_t Caddr;
    ushort Ident;
    uchar EisaSlot;
    uchar Ivec;
    int ret = 0;

    /*
    ** The only valid mode information for EISA hosts is fast or slow
    ** links.
    */
    Mode = (Mode & FAST_LINKS) ? EISA_TP_FAST_LINKS : EISA_TP_SLOW_LINKS;

    if ( EISADone )
    {
        rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit() - already done, return.\n");
        return(0);
    }

    EISADone++;

    rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit()\n");


    /*
    ** First check all cards to see if ANY are set for polled mode operation.
    ** If so, set ALL to polled.
    */

    for ( EisaSlot=1; EisaSlot<=RIO_MAX_EISA_SLOTS; EisaSlot++ )
    {
    Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) |
         INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO);

    if ( Ident == RIO_EISA_IDENT )
    {
        rio_dprintk (RIO_DEBUG_INIT, "Found Specialix product\n");

        if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE )
        {
        rio_dprintk (RIO_DEBUG_INIT, "Not Specialix RIO - Product number %x\n",
                        INBZ(EisaSlot, EISA_PRODUCT_NUMBER));
        continue;  /* next slot */
        }
        /*
        ** Its a Specialix RIO!
        */
        rio_dprintk (RIO_DEBUG_INIT, "RIO Revision %d\n",
                    INBZ(EisaSlot, EISA_REVISION_NUMBER));
        
        RIOMachineType |= (1<<RIO_EISA);

        /*
        ** Just check we haven't found too many wonderful objects
        */
        if ( RIONumHosts >= RIO_HOSTS )
        {
        Rprintf(RIOMesgTooManyCards);
        return 0;
        }

        /*
        ** Ensure that the enable bit is set!
        */
        OUTBZ( EisaSlot, EISA_ENABLE, RIO_EISA_ENABLE_BIT );

        /*
        ** EISA_INTERRUPT_VEC contains the interrupt vector.
        */
        Ivec = INBZ(EisaSlot,EISA_INTERRUPT_VEC);

#ifdef RIODEBUG
        switch ( Ivec & EISA_INTERRUPT_MASK )
        {
        case EISA_IRQ_3:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 3\n");
        break;
        case EISA_IRQ_4:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 4\n");
        break;
        case EISA_IRQ_5:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 5\n");
        break;
        case EISA_IRQ_6:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 6\n");
        break;
        case EISA_IRQ_7:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 7\n");
        break;
        case EISA_IRQ_9:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 9\n");
        break;
        case EISA_IRQ_10:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 10\n");
        break;
        case EISA_IRQ_11:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 11\n");
        break;
        case EISA_IRQ_12:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 12\n");
        break;
        case EISA_IRQ_14:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 14\n");
        break;
        case EISA_IRQ_15:
            rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 15\n");
        break;
        case EISA_POLLED:
            rio_dprintk (RIO_DEBUG_INIT, "EISA POLLED\n");
        break;
        default:
            rio_dprintk (RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n");
        Ivec &= EISA_CONTROL_MASK;
        }
#endif

        if ( (Ivec & EISA_INTERRUPT_MASK) ==
         EISA_POLLED )
        {
        RIOWillPoll = 1;
        break;        /* From EisaSlot loop */
        }
    }
    }

    /*
    ** Do it all again now we know whether to change all cards to polled
    ** mode or not
    */

    for ( EisaSlot=1; EisaSlot<=RIO_MAX_EISA_SLOTS; EisaSlot++ )
    {
    Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) |
         INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO);

    if ( Ident == RIO_EISA_IDENT )
    {
        if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE )
        continue;  /* next slot */

        /*
        ** Its a Specialix RIO!
        */
        
        /*
        ** Ensure that the enable bit is set!
        */
        OUTBZ( EisaSlot, EISA_ENABLE, RIO_EISA_ENABLE_BIT );

        /*
        ** EISA_INTERRUPT_VEC contains the interrupt vector.
        */
        Ivec = INBZ(EisaSlot,EISA_INTERRUPT_VEC);

        if ( RIOWillPoll )
        {
            /*
            ** If we are going to operate in polled mode, but this
            ** board is configured to be interrupt driven, display
            ** the message explaining the situation to the punter,
            ** assuming we haven't already done so.
            */

            if ( !PollIntMixMsgDone &&
             (Ivec & EISA_INTERRUPT_MASK) != EISA_POLLED )
            {
            Rprintf(RIOMesgAllPolled);
            PollIntMixMsgDone = 1;
            }

            /*
            ** Ungraciously ignore whatever the board reports as its
            ** interrupt vector...
            */

            Ivec &= ~EISA_INTERRUPT_MASK;

            /*
            ** ...and force it to dance to the poll tune.
            */

            Ivec |= EISA_POLLED;
        }

        /*
        ** Convert the IRQ enable mask into something useful (0-15)
        */
        Ivec = RIOEisaToIvec(Ivec);

        rio_dprintk (RIO_DEBUG_INIT, "EISA host in slot %d has Ivec 0x%x\n",
         EisaSlot, Ivec);

        /*
        ** Find the physical address
        */
        Paddr = (INBZ(EisaSlot,EISA_MEMORY_BASE_HI)<<24) |
                (INBZ(EisaSlot,EISA_MEMORY_BASE_LO)<<16);

        rio_dprintk (RIO_DEBUG_INIT, "EISA card has Ivec %d Addr %x\n", Ivec, Paddr);

        if ( Paddr == 0 )
        {
        rio_dprintk (RIO_DEBUG_INIT,
         "Board in slot %d configured for address zero!\n", EisaSlot);
        continue;
        }

        /*
        ** Tell the memory mapper that we want to talk to it
        */
        rio_dprintk (RIO_DEBUG_INIT, "About to map EISA card \n");

        if (RIOMapin( Paddr, RIO_EISA_MEM_SIZE, &Caddr) == -1) {
        rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n",
                            RIO_EISA_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_EISA,EisaSlot) == RIO_SUCCESS )
            {
        rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
        rio_dprintk (RIO_DEBUG_INIT, 
        "Slot %d. Ivec %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
            EisaSlot,Ivec,RIO_EISA,Paddr,Caddr,Mode);

        /*
        ** Board has passed its scrub test. Fill in all the
        ** transient stuff.
        */
        p->RIOHosts[RIONumHosts].Slot     = EisaSlot;
        p->RIOHosts[RIONumHosts].Ivec     = Ivec;
        p->RIOHosts[RIONumHosts].Type     = RIO_EISA;
        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;
        /*
        ** because the EISA prom is mapped into IO space, we
        ** need to copy the unqiue number into the memory area
        ** that it would have occupied, so that the download
        ** code can determine its ID and card type.
        */
     WBYTE(p->RIOHosts[RIONumHosts].Unique[0],INBZ(EisaSlot,EISA_UNIQUE_NUM_0));
     WBYTE(p->RIOHosts[RIONumHosts].Unique[1],INBZ(EisaSlot,EISA_UNIQUE_NUM_1));
     WBYTE(p->RIOHosts[RIONumHosts].Unique[2],INBZ(EisaSlot,EISA_UNIQUE_NUM_2));
     WBYTE(p->RIOHosts[RIONumHosts].Unique[3],INBZ(EisaSlot,EISA_UNIQUE_NUM_3));
        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);
        INBZ(EisaSlot,EISA_INTERRUPT_RESET);
                RIONumHosts++;
        ret++;
            }
        else
        {
        /*
        ** It failed the test, so ignore it.
        */
        rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");

        RIOMapout(Paddr, RIO_EISA_MEM_SIZE, Caddr );
        }
    }
    }
    if (RIOMachineType & RIO_EISA)
    return ret+1;
    return ret;
}
#endif


#ifndef linux

#define CONFIG_ADDRESS    0xcf8
#define CONFIG_DATA        0xcfc
#define FORWARD_REG        0xcfa


static int
read_config(int bus_number, int device_num, int r_number) 
{
    unsigned int cav;
    unsigned int val;

/*
   Build config_address_value:

      31        24 23        16 15      11 10  8 7        0 
      ------------------------------------------------------
      |1| 0000000 | bus_number | device # | 000 | register |
      ------------------------------------------------------
*/

    cav = r_number & 0xff;
    cav |= ((device_num & 0x1f) << 11);
    cav |= ((bus_number & 0xff) << 16);
    cav |= 0x80000000; /* Enable bit */
    outpd(CONFIG_ADDRESS,cav);
    val = inpd(CONFIG_DATA);
    outpd(CONFIG_ADDRESS,0);
    return val;
}

static
write_config(bus_number,device_num,r_number,val) 
{
    unsigned int cav;

/*
   Build config_address_value:

      31        24 23        16 15      11 10  8 7        0 
      ------------------------------------------------------
      |1| 0000000 | bus_number | device # | 000 | register |
      ------------------------------------------------------
*/

    cav = r_number & 0xff;
    cav |= ((device_num & 0x1f) << 11);
    cav |= ((bus_number & 0xff) << 16);
    cav |= 0x80000000; /* Enable bit */
    outpd(CONFIG_ADDRESS, cav);
    outpd(CONFIG_DATA, val);
    outpd(CONFIG_ADDRESS, 0);
    return val;
}
#else
/* XXX Implement these... */
static int
read_config(int bus_number, int device_num, int r_number) 
{
  return 0;
}

static int
write_config(int bus_number, int device_num, int r_number) 
{
  return 0;
}

#endif

int
RIOPCIinit(p, Mode)
struct rio_info    *p;
int         Mode;
{
    #define MAX_PCI_SLOT        32
    #define RIO_PCI_JET_CARD    0x200011CB

    static int    slot;    /* count of machine's PCI slots searched so far */
    caddr_t        Caddr;    /* Virtual address of the current PCI host card. */
    unsigned char    Ivec;    /* interrupt vector for the current PCI host */
    unsigned long    Paddr;    /* Physical address for the current PCI host */
    int        Handle;    /* Handle to Virtual memory allocated for current PCI host */


    rio_dprintk (RIO_DEBUG_INIT,  "Search for a RIO PCI card - start at slot %d\n", slot);

    /*
    ** Initialise the search status
    */
    p->RIOLastPCISearch    = RIO_FAIL;

    while ( (slot < MAX_PCI_SLOT) & (p->RIOLastPCISearch != RIO_SUCCESS) )
    {
        rio_dprintk (RIO_DEBUG_INIT,  "Currently testing slot %d\n", slot);

        if (read_config(0,slot,0) == RIO_PCI_JET_CARD) {
            p->RIOHosts[p->RIONumHosts].Ivec = 0;
            Paddr = read_config(0,slot,0x18);
            Paddr = Paddr - (Paddr & 0x1); /* Mask off the io bit */

            if ( (Paddr == 0) || ((Paddr & 0xffff0000) == 0xffff0000) ) {
                rio_dprintk (RIO_DEBUG_INIT,  "Goofed up slot\n");    /* what! */
                slot++;
                continue;
            }

            p->RIOHosts[p->RIONumHosts].PaddrP = Paddr;
            Ivec = (read_config(0,slot,0x3c) & 0xff);

            rio_dprintk (RIO_DEBUG_INIT,  "PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec);

            Handle = RIOMapin( Paddr, RIO_PCI_MEM_SIZE, &Caddr );
            if (Handle == -1) {
                rio_dprintk (RIO_DEBUG_INIT,  "Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr);
                slot++;
                continue;
            }
            p->RIOHosts[p->RIONumHosts].Ivec = Ivec + 32;
            p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
                        (int (*)())rio_intr, (char *)p->RIONumHosts);
            if (RIOBoardTest( Paddr, Caddr, RIO_PCI, 0 ) == RIO_SUCCESS) {
                rio_dprintk (RIO_DEBUG_INIT, ("Board has passed test\n");
                rio_dprintk (RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr, Mode);

                /*
                ** Board has passed its scrub test. Fill in all the
                ** transient stuff.
                */
                p->RIOHosts[p->RIONumHosts].Slot       = 0;
                p->RIOHosts[p->RIONumHosts].Ivec       = Ivec + 32;
                p->RIOHosts[p->RIONumHosts].Type       = RIO_PCI;
                p->RIOHosts[p->RIONumHosts].Copy       = rio_pcicopy; 
                p->RIOHosts[p->RIONumHosts].PaddrP       = Paddr;
                p->RIOHosts[p->RIONumHosts].Caddr       = Caddr;
                p->RIOHosts[p->RIONumHosts].CardP       = (struct DpRam *)Caddr;
                p->RIOHosts[p->RIONumHosts].Mode       = Mode;

#if 0
                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);
#else
                WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
#endif
                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, "Unique no 0x%x.\n", 
                    p->RIOHosts[p->RIONumHosts].UniqueNum);

                p->RIOLastPCISearch = RIO_SUCCESS;
                p->RIONumHosts++;
            }
        }
        slot++;
    }

    if ( slot >= MAX_PCI_SLOT ) {
        rio_dprintk (RIO_DEBUG_INIT,  "All %d PCI slots have tested for RIO cards !!!\n",
                 MAX_PCI_SLOT);
    }


    /*
    ** I don't think we want to do this anymore
    **

    if (!p->RIOLastPCISearch == RIO_FAIL ) {
        p->RIOFailed++;
    }

    **
    */
}

#ifdef FUTURE_RELEASE
void riohalt( void )
{
    int host;
    for ( host=0; host<p->RIONumHosts; host++ )
    {
        rio_dprintk (RIO_DEBUG_INIT, "Stop host %d\n", host);
        (void)RIOBoardTest( p->RIOHosts[host].PaddrP, p->RIOHosts[host].Caddr, p->RIOHosts[host].Type,p->RIOHosts[host].Slot );
    }
}
#endif
#endif

static    uchar    val[] = {
#ifdef VERY_LONG_TEST
      0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
      0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36, 
#endif
      0xff, 0x00, 0x00 };

#define    TEST_END sizeof(val)

/*
** RAM test a board. 
** Nothing too complicated, just enough to check it out.
*/
int
RIOBoardTest(paddr, caddr, type, slot)
paddr_t    paddr;
caddr_t    caddr;
uchar    type;
int        slot;
{
    struct DpRam *DpRam = (struct DpRam *)caddr;
    char *ram[4];
    int  size[4];
    int  op, bank;
    int  nbanks;

    rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n",
            type,(int)DpRam, slot);

    RIOHostReset(type, DpRam, slot);

    /*
    ** Scrub the memory. This comes in several banks:
    ** DPsram1    - 7000h bytes
    ** DPsram2    - 200h  bytes
    ** DPsram3    - 7000h bytes
    ** scratch    - 1000h bytes
    */

    rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n");

    size[0] = DP_SRAM1_SIZE;
    size[1] = DP_SRAM2_SIZE;
    size[2] = DP_SRAM3_SIZE;
    size[3] = DP_SCRATCH_SIZE;

    ram[0] = (char *)&DpRam->DpSram1[0];
    ram[1] = (char *)&DpRam->DpSram2[0];
    ram[2] = (char *)&DpRam->DpSram3[0];
    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.
*/
int
RIOScrub(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.
*/
void
RIOAllocateInterrupts(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.
*/
void
RIOStopInterrupts(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
        }
    }
}

#if 0
/*
** This function is called at init time to setup the data structures.
*/
void
RIOAllocDataStructs(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?)
*/
void
RIOSetupDataStructs(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);
            }
            HostP->UnixRups[rup].RupLock = SPIN_LOCK_UNLOCKED;
        }
    }
}
#endif

int
RIODefaultName(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"

int
RIOReport(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;
}

/*
** This function returns release/version information as used by ioctl() calls
** It returns a MAX_VERSION_LEN byte string, null terminated.
*/
char *
OLD_RIOVersid( void )
{
    static char    Info[MAX_VERSION_LEN];
    char *    RIORelease = RIO_RELEASE;
    char *    cp;
    int        ct = 0;

    for ( ct=0; RIORelease[ct] && ct<MAX_VERSION_LEN; ct++ )
        Info[ct] = RIORelease[ct];
    if ( ct>=MAX_VERSION_LEN ) {
        Info[MAX_VERSION_LEN-1] = '\0';
        return Info;
    }
    Info[ct++]=' ';
    if ( ct>=MAX_VERSION_LEN ) {
        Info[MAX_VERSION_LEN-1] = '\0';
        return Info;
    }

    cp="";    /* Fill the RCS Id here */

    while ( *cp && ct<MAX_VERSION_LEN )
        Info[ct++] = *cp++;
    if ( ct<MAX_VERSION_LEN-1 )
        Info[ct] = '\0';
    Info[MAX_VERSION_LEN-1] = '\0';
    return Info;
}


static struct rioVersion    stVersion;

struct rioVersion *
RIOVersid(void)
{
    strncpy(stVersion.version, "RIO driver for linux V1.0", 255);
    strncpy(stVersion.buildDate, __DATE__, 255);

    return &stVersion;
}

#if 0
int
RIOMapin(paddr, size, vaddr)
paddr_t        paddr;
int            size;
caddr_t *    vaddr;
{
    *vaddr = (caddr_t)permap( (long)paddr, size);
    return ((int)*vaddr);
}

void
RIOMapout(paddr, size, vaddr)
paddr_t        paddr;
long        size;
caddr_t     vaddr;
{
}
#endif


void
RIOHostReset(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);
            rio_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);
            rio_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;
        rio_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;
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0167 ]--