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

📄 atapi.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (!KeyWord) {
        return 0;
    }

    //
    // Calculate the string length and lower case all characters.
    //

    cptr = String;
    while (*cptr) {
        if (*cptr >= 'A' && *cptr <= 'Z') {
            *cptr = *cptr + ('a' - 'A');
        }
        cptr++;
        stringLength++;
    }

    //
    // Calculate the keyword length and lower case all characters.
    //

    cptr = KeyWord;
    while (*cptr) {

        if (*cptr >= 'A' && *cptr <= 'Z') {
            *cptr = *cptr + ('a' - 'A');
        }
        cptr++;
        keyWordLength++;
    }

    if (keyWordLength > stringLength) {

        //
        // Can't possibly have a match.
        //

        return 0;
    }

    //
    // Now setup and start the compare.
    //

    cptr = String;

ContinueSearch:

    //
    // The input string may start with white space.  Skip it.
    //

    while (*cptr == ' ' || *cptr == '\t') {
        cptr++;
    }

    if (*cptr == '\0') {

        //
        // end of string.
        //

        return 0;
    }

    kptr = KeyWord;
    while (*cptr++ == *kptr++) {

        if (*(cptr - 1) == '\0') {

            //
            // end of string
            //

            return 0;
        }
    }

    if (*(kptr - 1) == '\0') {

        //
        // May have a match backup and check for blank or equals.
        //

        cptr--;
        while (*cptr == ' ' || *cptr == '\t') {
            cptr++;
        }

        //
        // Found a match.  Make sure there is an equals.
        //

        if (*cptr != '=') {

            //
            // Not a match so move to the next semicolon.
            //

            while (*cptr) {
                if (*cptr++ == ';') {
                    goto ContinueSearch;
                }
            }
            return 0;
        }

        //
        // Skip the equals sign.
        //

        cptr++;

        //
        // Skip white space.
        //

        while ((*cptr == ' ') || (*cptr == '\t')) {
            cptr++;
        }

        if (*cptr == '\0') {

            //
            // Early end of string, return not found
            //

            return 0;
        }

        if (*cptr == ';') {

            //
            // This isn't it either.
            //

            cptr++;
            goto ContinueSearch;
        }

        value = 0;
        if ((*cptr == '0') && (*(cptr + 1) == 'x')) {

            //
            // Value is in Hex.  Skip the "0x"
            //

            cptr += 2;
            for (index = 0; *(cptr + index); index++) {

                if (*(cptr + index) == ' ' ||
                    *(cptr + index) == '\t' ||
                    *(cptr + index) == ';') {
                     break;
                }

                if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
                    value = (16 * value) + (*(cptr + index) - '0');
                } else {
                    if ((*(cptr + index) >= 'a') && (*(cptr + index) <= 'f')) {
                        value = (16 * value) + (*(cptr + index) - 'a' + 10);
                    } else {

                        //
                        // Syntax error, return not found.
                        //
                        return 0;
                    }
                }
            }
        } else {

            //
            // Value is in Decimal.
            //

            for (index = 0; *(cptr + index); index++) {

                if (*(cptr + index) == ' ' ||
                    *(cptr + index) == '\t' ||
                    *(cptr + index) == ';') {
                     break;
                }

                if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
                    value = (10 * value) + (*(cptr + index) - '0');
                } else {

                    //
                    // Syntax error return not found.
                    //
                    return 0;
                }
            }
        }

        return value;
    } else {

        //
        // Not a match check for ';' to continue search.
        //

        while (*cptr) {
            if (*cptr++ == ';') {
                goto ContinueSearch;
            }
        }

        return 0;
    }
}





ULONG
STDCALL
AtapiFindController(
    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
    Context - Address of adapter count
    ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.
    ConfigInfo - Configuration information structure describing HBA
    Again - Indicates search for adapters to continue

Return Value:

    ULONG

--*/

{
    PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
    PULONG               adapterCount    = (PULONG)Context;
    PUCHAR               ioSpace;
    ULONG                i,j;
    ULONG                irq;
    ULONG                portBase;
    ULONG                retryCount;
    PCI_SLOT_NUMBER      slotData;
    PPCI_COMMON_CONFIG   pciData;
    ULONG                pciBuffer;
    BOOLEAN              atapiOnly;
    UCHAR                statusByte;
    BOOLEAN              preConfig = FALSE;
    //
    // The following table specifies the ports to be checked when searching for
    // an IDE controller.  A zero entry terminates the search.
    //

    CONST ULONG AdapterAddresses[5] = {0x1F0, 0x170, 0x1e8, 0x168, 0};

    //
    // The following table specifies interrupt levels corresponding to the
    // port addresses in the previous table.
    //

    CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0};

    if (!deviceExtension) {
        return SP_RETURN_ERROR;
    }

    //
    // Check to see if this is a special configuration environment.
    //

    portBase = irq = 0;
    if (ArgumentString) {

        irq = AtapiParseArgumentString(ArgumentString, "Interrupt");
        if (irq ) {

            //
            // Both parameters must be present to proceed
            //

            portBase = AtapiParseArgumentString(ArgumentString, "BaseAddress");
            if (!portBase) {

                //
                // Try a default search for the part.
                //

                irq = 0;
            }
        }
    }



    //
    // Scan though the adapter address looking for adapters.
    //
    if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart) != 0) {
        ioSpace =  ScsiPortGetDeviceBase(HwDeviceExtension,
                                         ConfigInfo->AdapterInterfaceType,
                                         ConfigInfo->SystemIoBusNumber,
                                         (*ConfigInfo->AccessRanges)[0].RangeStart,
                                         (*ConfigInfo->AccessRanges)[0].RangeLength,
                                         (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory));
        *Again = FALSE;
        //
        // Since we have pre-configured information we only need to go through this loop once
        //
        preConfig = TRUE;
        portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart);

    }



    while (AdapterAddresses[*adapterCount] != 0) {

        retryCount = 4;

        for (i = 0; i < 4; i++) {

            //
            // Zero device fields to ensure that if earlier devices were found,
            // but not claimed, the fields are cleared.
            //

            deviceExtension->DeviceFlags[i] &= ~(DFLAGS_ATAPI_DEVICE | DFLAGS_DEVICE_PRESENT | DFLAGS_TAPE_DEVICE);
        }

        //
        // Get the system physical address for this IO range.
        //


        //
        // Check if configInfo has the default information
        // if not, we go and find ourselves
        //

        if (preConfig == FALSE) {

            if (portBase) {
                ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
                                                ConfigInfo->AdapterInterfaceType,
                                                ConfigInfo->SystemIoBusNumber,
                                                ScsiPortConvertUlongToPhysicalAddress(portBase),
                                                8,
                                                TRUE);
            } else {
                ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
                                                ConfigInfo->AdapterInterfaceType,
                                                ConfigInfo->SystemIoBusNumber,
                                                ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount]),
                                                8,
                                                TRUE);
            }

        }// ConfigInfo check
        //
        // Update the adapter count.
        //

        (*adapterCount)++;

        //
        // Check if ioSpace accessible.
        //

        if (!ioSpace) {
            continue;
        }

retryIdentifier:

        //
        // Select master.
        //

        ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect, 0xA0);

        //
        // Check if card at this address.
        //

        ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow, 0xAA);

        //
        // Check if indentifier can be read back.
        //

        if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {

            DebugPrint((2,
                        "AtapiFindController: Identifier read back from Master (%x)\n",
                        statusByte));

            statusByte = ScsiPortReadPortUchar(&((PATAPI_REGISTERS_2)ioSpace)->AlternateStatus);

            if (statusByte & IDE_STATUS_BUSY) {

                i = 0;

                //
                // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
                // warm boots don't clear.
                //

                do {
                    ScsiPortStallExecution(1000);
                    statusByte = ScsiPortReadPortUchar(&((PATAPI_REGISTERS_1)ioSpace)->Command);
                    DebugPrint((3,
                                "AtapiFindController: First access to status %x\n",
                                statusByte));
                } while ((statusByte & IDE_STATUS_BUSY) && ++i < 10);

                if (retryCount-- && (!(statusByte & IDE_STATUS_BUSY))) {
                    goto retryIdentifier;
                }
            }

            //
            // Select slave.
            //

            ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect, 0xB0);

            //
            // See if slave is present.
            //

            ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow, 0xAA);

            if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {

                DebugPrint((2,
                            "AtapiFindController: Identifier read back from Slave (%x)\n",
                            statusByte));

                //
                //
                // No controller at this base address.
                //

                ScsiPortFreeDeviceBase(HwDeviceExtension,
                                       ioSpace);

                continue;
            }
        }

        //
        // Record base IO address.
        //

        d

⌨️ 快捷键说明

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