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

📄 init.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 ************************************************************************
 *
 *	INIT.C
 *
 *
 * Portions Copyright (C) 1996-2001 National Semiconductor Corp.
 * All rights reserved.
 * Copyright (C) 1996-2001 Microsoft Corporation. All Rights Reserved.
 *
 *
 *
 *************************************************************************
 */


    #include "nsc.h"
    #include "newdong.h"
#include "init.tmh"


    #define  SIR      0
    #define  MIR      1
    #define  FIR      2




    #define NSC_DEMO_IRDA_SPEEDS ( NDIS_IRDA_SPEED_2400    |	   \
				   NDIS_IRDA_SPEED_2400    |	   \
				   NDIS_IRDA_SPEED_9600    |	   \
				   NDIS_IRDA_SPEED_19200   |	   \
				   NDIS_IRDA_SPEED_38400   |	   \
				   NDIS_IRDA_SPEED_57600   |	   \
				   NDIS_IRDA_SPEED_115200  |	   \
				   NDIS_IRDA_SPEED_1152K   |	   \
				   NDIS_IRDA_SPEED_4M )


    //	NSC PC87108 index registers.  See the spec for more info.
    //
    enum indexRegs {
	    BAIC_REG	    = 0,
	    CSRT_REG	    = 1,
	    MCTL_REG	    = 2,
	    GPDIR_REG	    = 3,
	    GPDAT_REG	    = 4
    };

#define CS_MODE_CONFIG_OFFSET 0x8

const UCHAR bankCode[] = { 0x03, 0x08, 0xE0, 0xE4, 0xE8, 0xEC, 0xF0, 0xF4 };

//////////////////////////////////////////////////////////////////////////
//									//
// Function :	   NSC_WriteBankReg					//
//									//
// Description: 							//
//  Write a value to the specified register of the specified register	//
//  bank.								//
//									//
//////////////////////////////////////////////////////////////////////////

void NSC_WriteBankReg(PUCHAR comBase, UINT bankNum, UINT regNum, UCHAR val)
{
    NdisRawWritePortUchar(comBase+3, bankCode[bankNum]);
    NdisRawWritePortUchar(comBase+regNum, val);

    // Always switch back to reg 0
    NdisRawWritePortUchar(comBase+3, bankCode[0]);
}

//////////////////////////////////////////////////////////////////////////
//									//
// Function :	   NSC_ReadBankReg					//
//									//
// Description: 							//
//  Write the value from the specified register of the specified	//
//  register bank.							//
//									//
//////////////////////////////////////////////////////////////////////////


UCHAR NSC_ReadBankReg(PUCHAR comBase, UINT bankNum, UINT regNum)
{
    UCHAR result;

    NdisRawWritePortUchar(comBase+3, bankCode[bankNum]);
    NdisRawReadPortUchar(comBase+regNum, &result);

    // Always switch back to reg 0
    NdisRawWritePortUchar(comBase+3, bankCode[0]);
		
    return result;
}

typedef struct _SYNC_PORT_ACCESS {

    PUCHAR    PortBase;
    UINT      BankNumber;
    UINT      RegisterIndex;
    UCHAR     Value;

} SYNC_PORT_ACCESS, *PSYNC_PORT_ACCESS;


VOID
ReadBankReg(
    PVOID     Context
    )

{
    PSYNC_PORT_ACCESS       PortAccess=(PSYNC_PORT_ACCESS)Context;

    NdisRawWritePortUchar(PortAccess->PortBase+3, bankCode[PortAccess->BankNumber]);
    NdisRawReadPortUchar(PortAccess->PortBase+PortAccess->RegisterIndex, &PortAccess->Value);

    // Always switch back to reg 0
    NdisRawWritePortUchar(PortAccess->PortBase+3, bankCode[0]);

    return;

}



VOID
WriteBankReg(
    PVOID     Context
    )

{
    PSYNC_PORT_ACCESS       PortAccess=(PSYNC_PORT_ACCESS)Context;

    NdisRawWritePortUchar(PortAccess->PortBase+3, bankCode[PortAccess->BankNumber]);
    NdisRawWritePortUchar(PortAccess->PortBase+PortAccess->RegisterIndex, PortAccess->Value);

    // Always switch back to reg 0
    NdisRawWritePortUchar(PortAccess->PortBase+3, bankCode[0]);

    return;

}


VOID
SyncWriteBankReg(
    PNDIS_MINIPORT_INTERRUPT InterruptObject,
    PUCHAR                   PortBase,
    UINT                     BankNumber,
    UINT                     RegisterIndex,
    UCHAR                    Value
    )

{
    SYNC_PORT_ACCESS        PortAccess;

    ASSERT(BankNumber <= 7);
    ASSERT(RegisterIndex <= 7);

    PortAccess.PortBase     = PortBase;
    PortAccess.BankNumber   = BankNumber;
    PortAccess.RegisterIndex= RegisterIndex;

    PortAccess.Value        = Value;

    NdisMSynchronizeWithInterrupt(
        InterruptObject,
        WriteBankReg,
        &PortAccess
        );

    return;
}

UCHAR
SyncReadBankReg(
    PNDIS_MINIPORT_INTERRUPT InterruptObject,
    PUCHAR                   PortBase,
    UINT                     BankNumber,
    UINT                     RegisterIndex
    )

{
    SYNC_PORT_ACCESS        PortAccess;

    ASSERT(BankNumber <= 7);
    ASSERT(RegisterIndex <= 7);


    PortAccess.PortBase     = PortBase;
    PortAccess.BankNumber   = BankNumber;
    PortAccess.RegisterIndex= RegisterIndex;

    NdisMSynchronizeWithInterrupt(
        InterruptObject,
        ReadBankReg,
        &PortAccess
        );

    return PortAccess.Value;
}



BOOLEAN
SyncGetDongleCapabilities(
    PNDIS_MINIPORT_INTERRUPT InterruptObject,
    UIR * Com,
    DongleParam *Dingle
    )

{
    SYNC_DONGLE    Dongle;

    Dongle.Com=Com;
    Dongle.Dingle=Dingle;

    NdisMSynchronizeWithInterrupt(
        InterruptObject,
        GetDongleCapabilities,
        &Dongle
        );

    return TRUE;

}


UINT
SyncSetDongleCapabilities(
    PNDIS_MINIPORT_INTERRUPT InterruptObject,
    UIR * Com,
    DongleParam *Dingle
    )

{
    SYNC_DONGLE    Dongle;

    Dongle.Com=Com;
    Dongle.Dingle=Dingle;


    NdisMSynchronizeWithInterrupt(
        InterruptObject,
        SetDongleCapabilities,
        &Dongle
        );

    return 0;

}


typedef struct _SYNC_FIFO_STATUS {

    PUCHAR     PortBase;
    PUCHAR     Status;
    PULONG     Length;

} SYNC_FIFO_STATUS, *PSYNC_FIFO_STATUS;

VOID
GetFifoStatus(
    PVOID     Context
    )

{
    PSYNC_FIFO_STATUS   FifoStatus=Context;

    NdisRawWritePortUchar(FifoStatus->PortBase+3, bankCode[5]);

    NdisRawReadPortUchar(FifoStatus->PortBase+FRM_ST, FifoStatus->Status);

    *FifoStatus->Length=0;

    if (*FifoStatus->Status & ST_FIFO_VALID) {

        UCHAR     High;
        UCHAR     Low;

        NdisRawReadPortUchar(FifoStatus->PortBase+RFRL_L, &Low);
        NdisRawReadPortUchar(FifoStatus->PortBase+RFRL_H, &High);

        *FifoStatus->Length =  Low;
        *FifoStatus->Length |= (ULONG)High << 8;
    }

    NdisRawWritePortUchar(FifoStatus->PortBase+3, bankCode[0]);

}

BOOLEAN
SyncGetFifoStatus(
    PNDIS_MINIPORT_INTERRUPT InterruptObject,
    PUCHAR                   PortBase,
    PUCHAR                   Status,
    PULONG                   Size
    )

{

    SYNC_FIFO_STATUS   FifoStatus;

    FifoStatus.PortBase=PortBase;
    FifoStatus.Status=Status;
    FifoStatus.Length=Size;

    NdisMSynchronizeWithInterrupt(
        InterruptObject,
        GetFifoStatus,
        &FifoStatus
        );

    return (*Status & ST_FIFO_VALID);

}


//////////////////////////////////////////////////////////////////////////
//									//
// Function :	   Ir108ConfigWrite					//
//									//
// Description: 							//
//  Write the data in the indexed register of the configuration I/O.	//
//									//
//////////////////////////////////////////////////////////////////////////

void Ir108ConfigWrite(PUCHAR configIOBase, UCHAR indexReg, UCHAR data, BOOLEAN CSMode)
{
    UCHAR IndexStore;

    if (CSMode)
    {
        NdisRawWritePortUchar(configIOBase+indexReg, data);
        NdisRawWritePortUchar(configIOBase+indexReg, data);
    }
    else
    {
        NdisRawReadPortUchar(configIOBase, &IndexStore);
        NdisRawWritePortUchar(configIOBase, indexReg);
        NdisRawWritePortUchar(configIOBase+1, data);
        NdisRawWritePortUchar(configIOBase+1, data);
        NdisRawWritePortUchar(configIOBase, IndexStore);
    }
}

//////////////////////////////////////////////////////////////////////////
//									//
// Function :	   Ir108ConfigRead					//
//									//
// Description: 							//
//  Read the data in the indexed register of the configuration I/O.	//
//									//
//////////////////////////////////////////////////////////////////////////

UCHAR Ir108ConfigRead(PUCHAR  configIOBase, UCHAR indexReg, BOOLEAN CSMode)
{
    UCHAR data,IndexStore;

    if (CSMode)
    {
        NdisRawReadPortUchar(configIOBase+indexReg, &data);
    }
    else
    {
        NdisRawReadPortUchar(configIOBase, &IndexStore);
        NdisRawWritePortUchar(configIOBase, indexReg);
        NdisRawReadPortUchar(configIOBase+1, &data);
        NdisRawWritePortUchar(configIOBase, IndexStore);
    }
    return (data);
}

//////////////////////////////////////////////////////////////////////////
//									//
// Function :	   NSC_DEMO_Init					//
//									//
// Description: 							//
//  Set up configuration registers for NSC evaluation board.		//
//									//
// NOTE:								//
//  Assumes configuration registers are at I/O addr 0x398.		//
//  This function configures the demo board to make the SIR UART appear //
//  at <comBase>.							//
//									//
//  Called By:								//
//  OpenCom								//
//////////////////////////////////////////////////////////////////////////

BOOLEAN NSC_DEMO_Init(IrDevice *thisDev)
{
    UCHAR val;
    UCHAR FifoClear;
    BOOLEAN CSMode = FALSE;
    switch(thisDev->CardType){
    case PUMA108:
        CSMode = TRUE;
        thisDev->portInfo.ConfigIoBaseAddr = thisDev->portInfo.ioBase + CS_MODE_CONFIG_OFFSET;

	case PC87108:
	    // Look for id at startup.
        if (!CSMode)
        {
            NdisRawReadPortUchar(thisDev->portInfo.ConfigIoBaseAddr, &val);
            if (val != 0x5A){
                if (val == (UCHAR)0xff){
                    DBGERR(("didn't see PC87108 id (0x5A); got ffh."));
                    return FALSE;
                }
                else {
                    //	ID only appears once, so in case we're resetting,
                    //	don't fail if we don't see it.
                    DBGOUT(("WARNING: didn't see PC87108 id (0x5A); got %xh.",
                         (UINT)val));
                }
            }
        }

        if (CSMode)
        {
            // base address ignored.
            val = 0;
        }
        else
        {
            // Select the base address for the UART
            switch ((DWORD_PTR)thisDev->portInfo.ioBase){
            case 0x3E8:	    val = 0;	    break;
            case 0x2E8:	    val = 1;	    break;
            case 0x3F8:	    val = 2;	    break;
            case 0x2F8:	    val = 3;	    break;
            default:	    return FALSE;
            }
        }
	    val |= 0x04;	// enable register banks
	    val |= 0x10;	// Set the interrupt line to Totempole output.
        Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, BAIC_REG, val, CSMode);

	    //	 Select interrupt level according to base address,
	    //	 following COM port mapping.
	    //	 Also select MIR/FIR DMA channels for rcv and xmit.
	    //
	    switch (thisDev->portInfo.irq){
		case 3:     val = 1;	    break;
		case 4:     val = 2;	    break;
		case 5:     val = 3;	    break;
		case 7:     val = 4;	    break;
		case 9:     val = 5;	    break;
		case 11:    val = 6;	    break;
		case 15:    val = 7;	    break;
		default:    return FALSE;
	    }

	    switch (thisDev->portInfo.DMAChannel){
		case 0: 		    val |= 0x08;    break;
		case 1: 		    val |= 0x10;    break;
		case 3: 		    val |= 0x18;    break;
		default:
		    DBGERR(("Bad rcv dma channel in NSC_DEMO_Init"));
		    return FALSE;
	    }

	    Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, CSRT_REG, val, CSMode);

	    // Select device-enable and normal-operating-mode.
	    Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, MCTL_REG, (UCHAR)3, CSMode);
	    break;

/*
	case PC87307:
	    //
	    //	Select Logical Device 5
	    //
	    Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x7, 0x5);

	    // Disable IO check
	    //
	    Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,0x31,0x0);

⌨️ 快捷键说明

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