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

📄 aha154x.c

📁 This directory builds the miniport driver for Adaptec’s 1540 family of SCSI controllers. This driver
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c) 1990  Microsoft Corporation

Module Name:

    aha154x.c

Abstract:

    This is the port driver for the Adaptec 1540B SCSI Adapter.

Author:

    Mike Glass
    Tuong Hoang (Adaptec)
    Renato Maranon (Adaptec)
    Bill Williams (Adaptec)

Environment:

    kernel mode only

Notes:

Revision History:

--*/

#include "miniport.h"
#include "aha154x.h"           // includes scsi.h

VOID
ScsiPortZeroMemory(
    IN PVOID Destination,
    IN ULONG Length
    );

//
// This conditionally compiles in the code to force the DMA transfer speed
// to 5.0.
//

#define FORCE_DMA_SPEED 1

//
// Function declarations
//
// Functions that start with 'A154x' are entry points
// for the OS port driver.
//

ULONG
DriverEntry(
    IN PVOID DriverObject,
    IN PVOID Argument2
    );

ULONG
A154xDetermineInstalled(
    IN PHW_DEVICE_EXTENSION HwDeviceExtension,
    IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
    IN OUT PSCAN_CONTEXT Context,
    OUT PBOOLEAN Again
    );


VOID
A154xClaimBIOSSpace(
    IN PHW_DEVICE_EXTENSION HwDeviceExtension,
    IN PBASE_REGISTER baseIoAddress,
    IN PSCAN_CONTEXT Context,
    IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
    );

ULONG
A154xFindAdapter(
    IN PVOID HwDeviceExtension,
    IN PSCAN_CONTEXT Context,
    IN PVOID BusInformation,
    IN PCHAR ArgumentString,
    IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
    OUT PBOOLEAN Again
    );


BOOLEAN
A154xAdapterState(
    IN PVOID HwDeviceExtension,
    IN PVOID Context,
    IN BOOLEAN SaveState
    );


BOOLEAN
A154xHwInitialize(
    IN PVOID DeviceExtension
    );

#if defined(_SCAM_ENABLED)
//
// Issues SCAM command to HA
//
BOOLEAN
PerformScamProtocol(
    IN PHW_DEVICE_EXTENSION DeviceExtension
    );
#endif

BOOLEAN
A154xStartIo(
    IN PVOID DeviceExtension,
    IN PSCSI_REQUEST_BLOCK Srb
    );

BOOLEAN
A154xInterrupt(
    IN PVOID DeviceExtension
    );

BOOLEAN
A154xResetBus(
    IN PVOID HwDeviceExtension,
    IN ULONG PathId
    );

SCSI_ADAPTER_CONTROL_STATUS
A154xAdapterControl(
    IN PVOID HwDeviceExtension,
    IN SCSI_ADAPTER_CONTROL_TYPE ControlType,
    IN PVOID Parameters
    );

BOOLEAN
GetHostAdapterBoardId (
    IN PVOID HwDeviceExtension,
    OUT PUCHAR BoardId
    );

//
// This function is called from A154xStartIo.
//

VOID
BuildCcb(
    IN PHW_DEVICE_EXTENSION DeviceExtension,
    IN PSCSI_REQUEST_BLOCK Srb
    );

//
// This function is called from BuildCcb.
//

VOID
BuildSdl(
    IN PHW_DEVICE_EXTENSION DeviceExtension,
    IN PSCSI_REQUEST_BLOCK Srb
    );

//
// This function is called from A154xInitialize.
//

BOOLEAN
AdapterPresent(
    IN PVOID HwDeviceExtension
    );

//
// This function is called from A154xInterrupt.
//

UCHAR
MapError(
    IN PVOID HwDeviceExtension,
    IN PSCSI_REQUEST_BLOCK Srb,
    IN PCCB Ccb
    );

BOOLEAN
ScatterGatherSupported (
   IN PHW_DEVICE_EXTENSION HwDeviceExtension
   );

BOOLEAN SendUnlockCommand(
    IN PVOID HwDeviceExtension,
    IN UCHAR locktype
    );

BOOLEAN UnlockMailBoxes(
    IN PVOID HwDeviceExtension
    );

ULONG
AhaParseArgumentString(
    IN PCHAR String,
    IN PCHAR KeyWord
    );

//
// This function determines whether adapter is an AMI
//
BOOLEAN
A4448IsAmi(
    IN PHW_DEVICE_EXTENSION  HwDeviceExtension,
    IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
    ULONG portNumber
    );


ULONG
DriverEntry(
    IN PVOID DriverObject,
    IN PVOID Argument2
    )

/*++

Routine Description:

    Installable driver initialization entry point for system.

Arguments:

    Driver Object

Return Value:

    Status from ScsiPortInitialize()

--*/

{
    HW_INITIALIZATION_DATA hwInitializationData;
    SCAN_CONTEXT context;
    ULONG isaStatus;
    ULONG mcaStatus;
    ULONG i;

    DebugPrint((1,"\n\nSCSI Adaptec 154X MiniPort Driver\n"));

    //
    // Zero out structure.
    //

    for (i=0; i<sizeof(HW_INITIALIZATION_DATA); i++) {
    ((PUCHAR)&hwInitializationData)[i] = 0;
    }

    //
    // Set size of hwInitializationData.
    //

    hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);

    //
    // Set entry points.
    //

    hwInitializationData.HwInitialize = A154xHwInitialize;
    hwInitializationData.HwResetBus = A154xResetBus;
    hwInitializationData.HwStartIo = A154xStartIo;
    hwInitializationData.HwInterrupt = A154xInterrupt;
    hwInitializationData.HwFindAdapter = A154xFindAdapter;
    hwInitializationData.HwAdapterState = A154xAdapterState;
    hwInitializationData.HwAdapterControl = A154xAdapterControl;

    //
    // Indicate no buffer mapping but will need physical addresses.
    //

    hwInitializationData.NeedPhysicalAddresses = TRUE;

    //
    // Specify size of extensions.
    //

    hwInitializationData.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
    hwInitializationData.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);

    //
    // Specifiy the bus type.
    //

    hwInitializationData.AdapterInterfaceType = Isa;
    hwInitializationData.NumberOfAccessRanges = 2;

    //
    // Ask for SRB extensions for CCBs.
    //

    hwInitializationData.SrbExtensionSize = sizeof(CCB);

    //
    // The adapter count is used by the find adapter routine to track how
    // which adapter addresses have been tested.
    //

    context.adapterCount = 0;
    context.biosScanStart = 0;

    isaStatus = ScsiPortInitialize(DriverObject, Argument2, &hwInitializationData, &context);

    //
    // Now try to configure for the Mca bus.
    // Specifiy the bus type.
    //

    hwInitializationData.AdapterInterfaceType = MicroChannel;
    context.adapterCount = 0;
    context.biosScanStart = 0;
    mcaStatus = ScsiPortInitialize(DriverObject, Argument2, &hwInitializationData, &context);

    //
    // Return the smaller status.
    //

    return(mcaStatus < isaStatus ? mcaStatus : isaStatus);

} // end A154xEntry()


ULONG
A154xFindAdapter(
    IN PVOID HwDeviceExtension,
    IN PSCAN_CONTEXT Context,
    IN PVOID BusInformation,
    IN PCHAR ArgumentString,
    IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
    OUT PBOOLEAN Again
    )
/*++

Routine Description:

    This function is called by the OS-specific port driver after
    the necessary storage has been allocated, to gather information
    about the adapter's configuration.

Arguments:

    HwDeviceExtension - HBA miniport driver's adapter data storage
    Context - Register base address
    ConfigInfo - Configuration information structure describing HBA
    This structure is defined in PORT.H.

Return Value:

    ULONG

--*/

{
    PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
    ULONG length;
    ULONG status;
    UCHAR adapterTid;
    UCHAR dmaChannel;
    UCHAR irq;
    UCHAR bit;
    UCHAR hostAdapterId[4];

#if defined(_SCAM_ENABLED)
    UCHAR temp, i;
        UCHAR BoardID;
        UCHAR EepromData;
#endif

    //
    // Inform SCSIPORT that we are a WMI data provider and have we GUIDs
    // to register.
    //

    ConfigInfo->WmiDataProvider = TRUE;
    A154xWmiInitialize(deviceExtension);

    //
    // Determine if there are any adapters installed.  Determine installed
    // will initialize the BaseIoAddress if an adapter is found.
    //

    status = A154xDetermineInstalled(deviceExtension,
            ConfigInfo,
            Context,
            Again);

    //
    // If there are no adapters found then return.
    //

    if (status != SP_RETURN_FOUND) {
        return(status);
    }

    //
    // Issue adapter command to get IRQ, DMA channel, and adapter SCSI ID.
    // But first, check for PnP non-default values.  If any of these values
    // are default, then we do 'em all to save code space, since the same
    // command is used.
    //
    // Returns 3 data bytes:
    //
    // Byte 0   Dma Channel
    //
    // Byte 1   Interrupt Channel
    //
    // Byte 2   Adapter SCSI ID
    //

    if (((ConfigInfo->DmaChannel+1) == 0) ||            // default DMA channel ?
        (ConfigInfo->BusInterruptLevel == 0) ||         // default IRQ ?
        ((ConfigInfo->InitiatorBusId[0]+1) == 0)        // default adapter ID ?
        ) {



        if (!WriteCommandRegister(deviceExtension, AC_RET_CONFIGURATION_DATA, TRUE)) {
            DebugPrint((1,"A154xFindAdapter: Get configuration data command failed\n"));
            return SP_RETURN_ERROR;
        }

        //
        // Determine DMA channel.
        //

        if (!ReadCommandRegister(deviceExtension,&dmaChannel,TRUE)) {
            DebugPrint((1,"A154xFindAdapter: Can't read dma channel\n"));
            return SP_RETURN_ERROR;
        }

        if (ConfigInfo->AdapterInterfaceType != MicroChannel) {

            WHICH_BIT(dmaChannel,bit);

            ConfigInfo->DmaChannel = bit;

            DebugPrint((2,"A154xFindAdapter: DMA channel is %x\n",
            ConfigInfo->DmaChannel));

        } else {
            ConfigInfo->InterruptMode = LevelSensitive;
        }

        //
        // Determine hardware interrupt vector.
        //

        if (!ReadCommandRegister(deviceExtension,&irq,TRUE)) {
            DebugPrint((1,"A154xFindAdapter: Can't read adapter irq\n"));
            return SP_RETURN_ERROR;
        }

        WHICH_BIT(irq, bit);

        ConfigInfo->BusInterruptLevel = (UCHAR) 9 + bit;

        //
        // Determine what SCSI bus id the adapter is on.
        //

        if (!ReadCommandRegister(deviceExtension,&adapterTid,TRUE)) {
            DebugPrint((1,"A154xFindAdapter: Can't read adapter SCSI id\n"));
            return SP_RETURN_ERROR;
        }

        //
        // Wait for HACC interrupt.
        //

        SpinForInterrupt(deviceExtension,FALSE);  // eddy

        //
        // Use PnP fields
        //
    } else {
        adapterTid = ConfigInfo->InitiatorBusId[0];
    }

    //
    // Set number of buses.
    //

    ConfigInfo->NumberOfBuses = 1;
    ConfigInfo->InitiatorBusId[0] = adapterTid;
    deviceExtension->HostTargetId = adapterTid;

    //
    // Set default CCB command to scatter/gather with residual counts.
    // If the adapter rejects this command, then set the command
    // to scatter/gather without residual.
    //

    deviceExtension->CcbScatterGatherCommand = SCATTER_GATHER_COMMAND;

⌨️ 快捷键说明

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