static u8 ReadVirtIODeviceByte(ULONG_PTR ulRegister)
{
    if (ulRegister & ~PORT_MASK) {
        return ScsiPortReadRegisterUchar((PUCHAR)(ulRegister));
    } else {
        return ScsiPortReadPortUchar((PUCHAR)(ulRegister));
    }
}
Esempio n. 2
0
BOOLEAN
Wd7000ExAdapterState(
    IN PVOID    DeviceExtension,
    IN PVOID    AdaptersFound,
    IN BOOLEAN  SaveState
    )

/*++

Routine Description:

    Saves/restores adapter's real-mode configuration state.

Arguments:

    DeviceExtension - Adapter object device extension.
    AdaptersFound   - Passed through from DriverEntry as additional
                      context for the call.
    SaveState       - TRUE = Save adapter state, FALSE = restore state.

Return Value:

    The spec did not intend for this routine to have a return value.
    Whoever did the header file just forgot to change the BOOLEAN to
    a VOID.  We will just return FALSE to shot the compiler up.

--*/

{
    PHW_DEVICE_EXTENSION  deviceExtension = DeviceExtension;

    if (SaveState) {

        //
        // Remember system interrupt state.
        //
        deviceExtension->InterruptState = ScsiPortReadPortUchar(
                    &deviceExtension->EisaController->SystemInterruptEnable);

    } else {

        //
        // Restore system interrupt state.
        //
        ScsiPortWritePortUchar(&deviceExtension->EisaController->SystemInterruptEnable,
            deviceExtension->InterruptState);

    }

    return FALSE;
}
Esempio n. 3
0
ULONG
Wd7000ExFindAdapter(
    IN PVOID HwDeviceExtension,
    IN PVOID 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
    ConfigInfo - Configuration information structure describing HBA

Return Value:

    TRUE if adapter present in system

--*/

{
    PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
    PEISA_CONTROLLER eisaController;
    PULONG adapterCount = Context;
    PNONCACHED_EXTENSION ncExtension;
    ULONG eisaSlotNumber;
    PICB icb;
    PADAPTER_INQUIRY adapterInquiry;
    ULONG physicalIcb;
    ULONG i;
    ULONG length;
    UCHAR status;

    //
    // Check to see if adapter present in system.
    //
    if (!AdapterPresent(deviceExtension, ConfigInfo, Context)) {
        DebugPrint((1,"Wd7000EX: SCSI adapter not present\n"));
        *Again = FALSE;
        return SP_RETURN_NOT_FOUND;
    }

    //
    // There is still more to look at.
    //

    *Again = FALSE;

    //
    // Fill in the access array information only if there are no
    // default parameters already there.
    //
    if (ScsiPortConvertPhysicalAddressToUlong(
            (*ConfigInfo->AccessRanges)[0].RangeStart) == 0) {

        *Again = TRUE;
        (*ConfigInfo->AccessRanges)[0].RangeStart =
            ScsiPortConvertUlongToPhysicalAddress(0x1000 * (*((PULONG) Context)) + EISA_ADDRESS_BASE);
        (*ConfigInfo->AccessRanges)[0].RangeLength = sizeof(EISA_CONTROLLER);
        (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;

        //
        // Indicate maximum transfer length in bytes.
        //
        ConfigInfo->MaximumTransferLength = MAXIMUM_TRANSFER_SIZE;

        //
        // Maximum number of physical segments is 32.
        //
        ConfigInfo->NumberOfPhysicalBreaks = MAXIMUM_SDL_SIZE;

        //
        // Set the configuration parameters for this card.
        //
    
        ConfigInfo->NumberOfBuses = 1;
        deviceExtension->NumberOfBuses = 1;
        ConfigInfo->ScatterGather = TRUE;
        ConfigInfo->Master = TRUE;
    
        //
        // Get a noncached extension for an adapter inquiry command.
        //
    
        ncExtension = ScsiPortGetUncachedExtension(
                                    deviceExtension,
                                    ConfigInfo,
                                    sizeof(NONCACHED_EXTENSION));
    
        if (ncExtension == NULL) {
    
            //
            // Log error.
            //
    
            ScsiPortLogError(
                deviceExtension,
                NULL,
                0,
                0,
                0,
                SP_INTERNAL_ADAPTER_ERROR,
                6 << 16
                );
    
            return SP_RETURN_ERROR;
        }
    
        length = sizeof(NONCACHED_EXTENSION);
    
        //
        // Convert virtual to physical address.
        //
    
        physicalIcb = ScsiPortConvertPhysicalAddressToUlong(
            ScsiPortGetPhysicalAddress(deviceExtension,
                                     NULL,
                                     ncExtension,
                                     &length));
    
        //
        // Initialize the pointers.
        //
    
        icb = &ncExtension->Icb;
        adapterInquiry = &ncExtension->AdapterInquiry;
    
        //
        // Create ICB for Adapter Inquiry Command.
        //
    
        icb->IcbFlags = 0;
        icb->CompletionStatus = 0;
        icb->Reserved = 0;
        icb->DataBufferAddress = ScsiPortConvertPhysicalAddressToUlong(
            ScsiPortGetPhysicalAddress(
                deviceExtension,
                NULL,
                adapterInquiry,
                &length));
    
        icb->TransferCount = sizeof(ADAPTER_INQUIRY);
    
        icb->OpCode = ADAPTER_INQUIRY_COMMAND;
    
        //
        // Get ICB physical address.
        //
    
        physicalIcb = ScsiPortConvertPhysicalAddressToUlong(
            ScsiPortGetPhysicalAddress(
                deviceExtension,
                NULL,
                icb,
                &length));
    
        //
        // Disable system interrupts.
        //
    
        ScsiPortWritePortUchar(&deviceExtension->EisaController->SystemInterruptEnable,
            SYSTEM_INTERRUPTS_DISABLE);
    
        //
        // Write ICB physical address and command to mailbox.
        //
    
        SendCommand(PROCESS_ICB,
                physicalIcb,
                deviceExtension);
    
        //
        // Poll for ICB completion.
        //
    
        i = 0;
        while ((status =
            ScsiPortReadPortUchar(
            &deviceExtension->EisaController->ResponseRegister)) == 0) {
    
            i++;
    
            if (i > 100000) {
    
                break;
            }
    
            ScsiPortStallExecution(10);
        }
    
        if (status == 0) {
    
            //
            // The request timed out. Log an error and return.
            //
    
            ScsiPortLogError(
                deviceExtension,
                NULL,
                0,
                0,
                0,
                SP_INTERNAL_ADAPTER_ERROR,
                7 << 16
                );
            return SP_RETURN_ERROR;
        }
    
        DebugPrint((1, "Wd7000ExFindAdapter: Get configuration request time = %d.\n", i * 10));
    
        //
        // Acknowledge interrupt.
        //
    
        ScsiPortWritePortUchar(&deviceExtension->EisaController->ResponseRegister, 0xFF);
    
        //
        // Enable system interrupts.
        //
    
        ScsiPortWritePortUchar(&deviceExtension->EisaController->SystemInterruptEnable,
            SYSTEM_INTERRUPTS_ENABLE);
    
        //
        // Check returned status for success.
        //
    
        if (status != COMPLETE_SUCCESS) {
    
            //
            // Give up.
            //
    
            DebugPrint((1,"Wd7000Ex: Response register %x\n", status));
            DebugPrint((1,"Wd7000Ex: Adapter inquiry failed\n"));
    
            //
            // Log error.
            //
    
            ScsiPortLogError(
                deviceExtension,
                NULL,
                0,
                0,
                0,
                SP_INTERNAL_ADAPTER_ERROR,
                8 << 16
                );
    
            return SP_RETURN_ERROR;
        }
    
        //
        // NOTE: Delay here. I don't understand this latency between
        //          when the device interrupts and the status of the ICB
        //          is success and when the data is actually available in
        //          the buffer.
        //
    
        ScsiPortStallExecution(300);
    
        if (adapterInquiry->AdapterInformation & DUAL_CHANNEL) {
    
            //
            // There are two buses on the adapter.
            //
    
            ConfigInfo->InitiatorBusId[1] =
                (adapterInquiry->ChannelInformation >> 4) & BUS_ID_MASK;
            ConfigInfo->NumberOfBuses = 2;
            deviceExtension->NumberOfBuses = 2;
        }
Esempio n. 4
0
BOOLEAN
AdapterPresent(
    IN PVOID HwDeviceExtension,
    IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
    IN OUT PULONG AdapterCount
    )

/*++

Routine Description:

    Determine if WD7000EX SCSI adapter is installed in system
    by reading the EISA board configuration registers for each
    EISA slot looking for the correct signature.

Arguments:

    HwDeviceExtension - HBA miniport driver's adapter data storage

    ConfigInfo - Supplies the configuration information stucture.  If an
        adapter is found the access range is update.

    AdapterCount - Supplies the count of slots which have already been checked.

Return Value:

    TRUE if adapter present.

--*/

{
    PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
    ULONG eisaSlotNumber;
    PEISA_CONTROLLER eisaController;

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


    for (eisaSlotNumber=*AdapterCount + 1; eisaSlotNumber<MAXIMUM_EISA_SLOTS; eisaSlotNumber++) {

        //
        // Update the adapter count.
        //

        (*AdapterCount)++;

        //
        // Get the system address for this card.  The card uses I/O space.
        // If ConfigInfo already has default information about this
        // controller, use it.  If not, then we derive our own.  This
        // is for Chicago compatibility.
        //
        if (ScsiPortConvertPhysicalAddressToUlong(
                (*ConfigInfo->AccessRanges)[0].RangeStart) != 0) {

            eisaController = ScsiPortGetDeviceBase(
                                deviceExtension,
                                ConfigInfo->AdapterInterfaceType,
                                ConfigInfo->SystemIoBusNumber,
                                (*ConfigInfo->AccessRanges)[0].RangeStart,
                                (*ConfigInfo->AccessRanges)[0].RangeLength,
                                (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory));
        } else {

            eisaController = ScsiPortGetDeviceBase(
                                deviceExtension,
                                ConfigInfo->AdapterInterfaceType,
                                ConfigInfo->SystemIoBusNumber,
                                ScsiPortConvertUlongToPhysicalAddress(0x1000 * eisaSlotNumber),
                                0x1000,
                                TRUE);
        }

        eisaController =
            (PEISA_CONTROLLER)((PUCHAR)eisaController + EISA_ADDRESS_BASE);

        if ((ScsiPortReadPortUchar(&eisaController->BoardId[0]) == 0x5C) &&
            (ScsiPortReadPortUchar(&eisaController->BoardId[1]) == 0x83) &&
            (ScsiPortReadPortUchar(&eisaController->BoardId[2]) == 0x20)) {

            deviceExtension->EisaController = eisaController;

            return TRUE;
        }

        //
        // The card is not here so clean up.
        //

        ScsiPortFreeDeviceBase(deviceExtension,
                               (PUCHAR)eisaController - EISA_ADDRESS_BASE);

    } // end for (eisaSlotNumber ...

    //
    // Clear the adapter count for the next bus.
    //

    *AdapterCount = 0;

    return FALSE;

} // end AdapterPresent()