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

📄 aha154x.c

📁 This directory builds the miniport driver for Adaptec’s 1540 family of SCSI controllers. This driver
💻 C
📖 第 1 页 / 共 5 页
字号:
                        ScsiPortWritePortUchar(&baseIoAddress->StatusRegister, IOP_INTERRUPT_RESET);

                        if (!(ScsiPortReadPortUchar(&baseIoAddress->InterruptRegister) & IOP_ANY_INTERRUPT)) {
                            //
                            // Sucess!
                            //
                            return Status;
                        }
                    }

                    //
                    // one ms delay
                    //
                    ScsiPortStallExecution(1);
                }
                //
                // Operation should be retried a few times in case it fails.
                //
            } while (Retries < 10);

            break;

            case ScsiRestartAdapter:
                //
                // This entry point is called by SCSIPort when it needs to re-enable
                // a previously stopped adapter. In the generic case, previously
                // suspended IO operations should be restarted and the adapter's
                // previous configuration should be reinstated. Our hardware device
                // extension and uncached extensions have been preserved so no
                // actual driver software reinitialization is necesarry.
                //

                //
                // The adapter's firmware configuration is returned via HwAdapterState.
                //
                if (A154xAdapterState(HwDeviceExtension, NULL, FALSE) == FALSE) {
                    //
                    // Adapter is unable to restore it's state information, we must fail this
                    // request since the process of restarting the adapter will not succeed.
                    //
                    Status = ScsiAdapterControlUnsuccessful;
                }

                A154xResetBus(deviceExtension, SP_UNTAGGED);
                break;

            case ScsiSetBootConfig:
                Status = ScsiAdapterControlUnsuccessful;
                break;

            case ScsiSetRunningConfig:
                Status = ScsiAdapterControlUnsuccessful;
                break;

            case ScsiAdapterControlMax:
                Status = ScsiAdapterControlUnsuccessful;
                break;

            default:
                Status = ScsiAdapterControlUnsuccessful;
                break;
    }

    return Status;
}


BOOLEAN
AdaptecAdapter(
    IN PHW_DEVICE_EXTENSION HwDeviceExtension,
    IN ULONG   IoPort,
    IN BOOLEAN Mca
    )

/*++

Routine Description:

    This routine checks the Special Options byte of the Adapter Inquiry
    command to see if it is one of the two values returned by Adaptec
    Adapters.  This avoids claiming adapters from BusLogic and DTC.

Arguments:

    HwDeviceExtension - miniport driver's adapter extension.

Return Values:

    TRUE if the adapter looks like an Adaptec.
    FALSE if not.

--*/

{
    UCHAR byte;
    UCHAR specialOptions;
    PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
    PBASE_REGISTER baseIoAddress = deviceExtension->BaseIoAddress;

    if (Mca == TRUE) {
        INIT_DATA initData;
        LONG slot;
        LONG i;

        for (slot = 0; slot < NUMBER_POS_SLOTS; slot++) {
            i = ScsiPortGetBusData(HwDeviceExtension,
                       Pos,
                       0,
                       slot,
                       &initData.PosData[slot],
                       sizeof(POS_DATA));
            if (i < (sizeof(POS_DATA))) {
                initData.PosData[slot].AdapterId = 0xffff;
            }
        }

        for (slot = 0; slot < NUMBER_POS_SLOTS; slot++) {
            if (initData.PosData[slot].AdapterId == POS_IDENTIFIER) {
                switch (initData.PosData[slot].IoPortInformation & POS_PORT_MASK) {
                    case POS_PORT_130:
                        if (IoPort == 0x0130) {
                            return TRUE;
                        }
                        break;
                    case POS_PORT_134:
                        if (IoPort == 0x0134) {
                            return TRUE;
                        }
                        break;
                    case POS_PORT_230:
                        if (IoPort == 0x0230) {
                            return TRUE;
                        }
                        break;
                    case POS_PORT_234:
                        if (IoPort == 0x234) {
                            return TRUE;
                        }
                        break;
                    case POS_PORT_330:
                        if (IoPort == 0x330) {
                            return TRUE;
                        }
                        break;
                    case POS_PORT_334:
                        if (IoPort == 0x334) {
                            return TRUE;
                        }
                        break;
                }
            }
        }
        return FALSE;
    }

    ScsiPortWritePortUchar(&baseIoAddress->StatusRegister,
        IOP_INTERRUPT_RESET);

    if (!WriteCommandRegister(HwDeviceExtension,AC_ADAPTER_INQUIRY,FALSE)) {
        return FALSE;
    }

    //
    // Byte 0.
    //

    if ((ReadCommandRegister(HwDeviceExtension,&byte,TRUE)) == FALSE) {
        return FALSE;
    }

    //
    // Get the special options byte.
    //

    if ((ReadCommandRegister(HwDeviceExtension,&specialOptions,TRUE)) == FALSE) {
        return FALSE;
    }

    //
    // Get the last two bytes and clear the interrupt.
    //

    if ((ReadCommandRegister(HwDeviceExtension,&byte,TRUE)) == FALSE) {
        return FALSE;
    }

    if ((ReadCommandRegister(HwDeviceExtension,&byte,TRUE)) == FALSE) {
        return FALSE;
    }

    //
    // Wait for HACC interrupt.
    //

    SpinForInterrupt(HwDeviceExtension,FALSE);   // eddy


    if ((specialOptions == 0x30) || (specialOptions == 0x42)) {
        return TRUE;
    }

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

/*++

Routine Description:

    Determine if Adaptec 154X SCSI adapter is installed in system
    by reading the status register as each base I/O address
    and looking for a pattern.  If an adapter is found, the BaseIoAddres is
    initialized.

Arguments:

    HwDeviceExtension - HBA miniport driver's adapter data storage

    ConfigInfo - Supplies the known configuraiton information.

    AdapterCount - Supplies the count of adapter slots which have been tested.

    Again - Returns whehter the  OS specific driver should call again.

Return Value:

    Returns a status indicating whether a driver is present or not.

--*/

{
    PBASE_REGISTER baseIoAddress;
    PUCHAR ioSpace;
    UCHAR  portValue;
    ULONG  ioPort;

    //
    // Check for configuration information passed in from system.
    //

    if ((*ConfigInfo->AccessRanges)[0].RangeLength != 0) {

        ULONG i;
        PACCESS_RANGE ioRange = NULL;

        for(i = 0; i < ConfigInfo->NumberOfAccessRanges; i++) {

            ioRange = &((*ConfigInfo->AccessRanges)[i]);

            //
            // Search for an io port range.
            //

            if(ioRange->RangeInMemory == FALSE) {
                break;
            }
        }

        if(ioRange->RangeInMemory) {

            //
            // No i/o range found for the card in the provided config.  Bail
            //

            *Again = TRUE;
            return SP_RETURN_BAD_CONFIG;
        }

        ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
                                        ConfigInfo->AdapterInterfaceType,
                                        ConfigInfo->SystemIoBusNumber,
                                        ioRange->RangeStart,
                                        ioRange->RangeLength,
                                        TRUE);

        if(ioSpace == NULL) {
            return SP_RETURN_ERROR;
        }

        baseIoAddress = (PBASE_REGISTER) ioSpace;

        HwDeviceExtension->BaseIoAddress = baseIoAddress;

        *Again = FALSE;

        return (ULONG)SP_RETURN_FOUND;

    } else {

        //
        // The following table specifies the ports to be checked when searching for
        // an adapter.  A zero entry terminates the search.
        //

        CONST ULONG AdapterAddresses[7] = {0X330, 0X334, 0X234, 0X134, 0X130, 0X230, 0};

        //
        // Scan possible base addresses looking for adapters.
        //

        while (AdapterAddresses[Context->adapterCount] != 0) {

            //
            // Get the system physical address for this card.  The card uses
            // I/O space.
            //

            ioPort = AdapterAddresses[Context->adapterCount];

            ioSpace =
                ScsiPortGetDeviceBase(HwDeviceExtension,
                                      ConfigInfo->AdapterInterfaceType,
                                      ConfigInfo->SystemIoBusNumber,
                                      ScsiPortConvertUlongToPhysicalAddress(ioPort),
                                      0x4,
                                      TRUE);

            //
            // Get next base address.
            //

            baseIoAddress = (PBASE_REGISTER) ioSpace;

            HwDeviceExtension->BaseIoAddress = baseIoAddress;

            //
            // Update the Adapter count
            //

            (Context->adapterCount)++;

            //
            // Check to see if adapter present in system.
            //

            portValue = ScsiPortReadPortUchar((PUCHAR)baseIoAddress);

            //
            // Check for Adaptec adapter.
            // The mask (0x29) are bits that may or may not be set.
            // The bit 0x10 (IOP_SCSI_HBA_IDLE) should be set.
            //

            if ((portValue & ~0x29) == IOP_SCSI_HBA_IDLE) {

                if (!AdaptecAdapter(
                        HwDeviceExtension,
                        ioPort,
                        (BOOLEAN)(ConfigInfo->AdapterInterfaceType == MicroChannel ? TRUE : FALSE))) {

                    DebugPrint((1,"A154xDetermineInstalled: Clone command completed successfully - \n not our board;"));

                    ScsiPortFreeDeviceBase(HwDeviceExtension, ioSpace);
                    continue;

                //
                // Run AMI4448 detection code.
                //

                } else if (A4448IsAmi(HwDeviceExtension,
                                      ConfigInfo,
                                      AdapterAddresses[(Context->adapterCount) - 1])) {

                    DebugPrint ((1,
                                 "A154xDetermineInstalled: Detected AMI4448\n"));
                    ScsiPortFreeDeviceBase(HwDeviceExtension, ioSpace);
                    continue;
                }

                //
                // An adapter has been found. Request another call.
                //

                *Again = TRUE;

                //
                // Fill in the access array information.
                //

                (*ConfigInfo->AccessRanges)[0].RangeStart =
                    ScsiPortConvertUlongToPhysicalAddress(
                        AdapterAddresses[Context->adapterCount - 1]);
                (*ConfigInfo->AccessRanges)[0].RangeLength = 4;
                (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;

                //
                // Check if BIOS is enabled and claim that memory range.
                //

                A154xClaimBIOSSpace(HwDeviceExtension,
                                    baseIoAddress,
                                    Context,
                                    ConfigInfo);

                return (ULONG)SP_RETURN_FOUND;

            } else {
                ScsiPortFreeDeviceBase(HwDeviceExtension, ioSpace);
            }
        }
    }

    //
    // The entire table has been searched and no adapters have been found.
    // There is no need to call again and the device base can now be freed.
    // Clear the adapter count for the next bus.
    //

    *Again = FALSE;
    Context->adapterCount = 0;
    Context->biosScanStart = 0;

     return SP_RETURN_NOT_FOUND;

} // end A154xDetermineInstalled()

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

/*++

Routine Description:

    This routine is called from A154xDetermineInstalled to find
    and claim BIOS space.

Arguments:

    HwDeviceExtension - HBA miniport driver's adapter data storage
    BaseIoAddress - IO address of adapter
    ConfigInfo - Miniport configuration information

Return Value:

    None.

--*/

{

    UCHAR  inboundData, byte;
    ULONG  baseBIOSAddress;
    ULONG  i, j;
    PUCHAR biosSpace, biosPtr;
    UCHAR  aha154xBSignature[16] =
           { 0x06, 0x73, 0x01, 0xC3, 0x8A, 0xE7, 0xC6, 0x06,
             0x42, 0x00, 0x00, 0xF9, 0xC3, 0x88, 0x26, 0x42 };

    //
    // Reset interrupt just in case.
    //

    ScsiPortWritePortUchar(&BaseIoAddress->StatusRegister,
                           IOP_INTERRUPT_RESET);

    //
    // The Adapter Inquiry command will return 4 bytes describing
    // the firmware revision level.
    //

    if (WriteCommandRegister(HwDeviceExtension,
                             AC_ADAPTER_INQUIRY,TRUE) == FALSE) {
        return;
    }

    if ((ReadCommandRegister(HwDeviceExtension,
                             &inboundData,TRUE)) == FALSE) {
        return;
    }

    if ((ReadCommandRegister(HwDeviceExtension,&byte,TRUE)) == FALSE) {
        return;
    }

    if ((ReadCommandRegister(HwDeviceExtension,&byte,TRUE)) == FALSE) {
        return;
    }

    if ((ReadCommandRegister(HwDeviceExtension,&byte,TRUE)) == FALSE) {
        return;
    }

⌨️ 快捷键说明

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