Exemple #1
0
NTSTATUS
CmpSetupConfigurationTree(
     IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
     IN HANDLE ParentHandle,
     IN INTERFACE_TYPE InterfaceType,
     IN ULONG BusNumber
     )
/*++

Routine Description:

    This routine traverses loader configuration tree and register
    the hardware information to the registry data base.

    Note to reduce the stack usage on machines with large number of PCI buses,
    we do not recursively process the sibling nodes.  We only recursively
    process the child trees.

Arguments:

    CurrentEntry - Supplies a pointer to a loader configuration
        tree or subtree.

    ParentHandle - Supplies the parent handle of CurrentEntry node.

    InterfaceType - Specify the Interface type of the bus that the
        CurrentEntry component resides.

    BusNumber - Specify the Bus Number of the bus that the CurrentEntry
        component resides.  If Bus number is -1, it means InterfaceType
        and BusNumber are meaningless for this component.

Returns:

    None.

--*/
{
    NTSTATUS Status;
    HANDLE NewHandle;
    USHORT i;
    CONFIGURATION_COMPONENT *Component;
    INTERFACE_TYPE LocalInterfaceType = InterfaceType;
    ULONG LocalBusNumber = BusNumber;
    USHORT DeviceIndexTable[NUMBER_TYPES];

    for (i = 0; i < NUMBER_TYPES; i++) {
        DeviceIndexTable[i] = 0;
    }

    //
    // Process current entry and its siblings
    //

    while (CurrentEntry) {

        //
        // Register current entry first before going down to its children
        //

        Component = &CurrentEntry->ComponentEntry;

        //
        // If the current component is a bus component, we will set up
        // its bus number and Interface type and use them to initialize
        // its subtree.
        //

        if (Component->Class == AdapterClass &&
            CurrentEntry->Parent->ComponentEntry.Class == SystemClass) {

            switch (Component->Type) {

            case EisaAdapter:
                LocalInterfaceType = Eisa;
                LocalBusNumber = CmpTypeCount[EISA_ADAPTER_INDEX]++;
                break;
            case TcAdapter:
                LocalInterfaceType = TurboChannel;
                LocalBusNumber = CmpTypeCount[TURBOCHANNEL_ADAPTER_INDEX]++;
                break;
            case MultiFunctionAdapter:

                //
                // Here we try to distinguish if the Multifunction adapter is
                // Isa, Mca, Internal bus and assign BusNumber based on
                // its interface type (bus type.)
                //

                if (Component->Identifier) {
                    for (i=0; CmpMultifunctionTypes[i].AscString; i++) {
                        if (_stricmp((PCHAR)CmpMultifunctionTypes[i].AscString,
                                    Component->Identifier) == 0) {
                                        break;
                        }
                    }

                    LocalInterfaceType = CmpMultifunctionTypes[i].InterfaceType;
                    LocalBusNumber = CmpMultifunctionTypes[i].Count++;
                }
                break;

            case ScsiAdapter:

                //
                // Set the bus type to internal.
                //

                LocalInterfaceType = Internal;
                LocalBusNumber = CmpTypeCount[ScsiAdapter]++;
                break;

            default:
                LocalInterfaceType = -1;
                LocalBusNumber = CmpUnknownBusCount++;
                break;
            }
        }

        //
        // Initialize and copy current component to hardware registry
        //

        Status = CmpInitializeRegistryNode(
                     CurrentEntry,
                     ParentHandle,
                     &NewHandle,
                     LocalInterfaceType,
                     LocalBusNumber,
                     DeviceIndexTable
                     );

        if (!NT_SUCCESS(Status)) {
            return(Status);
        }

        //
        // Once we are going one level down, we need to clear the TypeCount
        // table for everything under the current component class ...
        //

        if (CurrentEntry->Child) {

            //
            // Process the child entry of current entry
            //

            Status = CmpSetupConfigurationTree(CurrentEntry->Child,
                                               NewHandle,
                                               LocalInterfaceType,
                                               LocalBusNumber
                                               );
            if (!NT_SUCCESS(Status)) {
                NtClose(NewHandle);
                return(Status);
            }
        }
        NtClose(NewHandle);
        CurrentEntry = CurrentEntry->Sibling;
    }
    return(STATUS_SUCCESS);
}
NTSTATUS
NTAPI
INIT_FUNCTION
CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
                          IN HANDLE ParentHandle,
                          IN INTERFACE_TYPE InterfaceType,
                          IN ULONG BusNumber)
{
    PCONFIGURATION_COMPONENT Component;
    USHORT DeviceIndexTable[MaximumType + 1] = {0};
    ULONG Interface = InterfaceType, Bus = BusNumber, i;
    NTSTATUS Status;
    HANDLE NewHandle;

    /* Loop each entry */
    while (CurrentEntry)
    {
        /* Check if this is an adapter */
        Component = &CurrentEntry->ComponentEntry;
        if ((Component->Class == AdapterClass) &&
            (CurrentEntry->Parent->ComponentEntry.Class == SystemClass))
        {
            /* Check what kind of adapter it is */
            switch (Component->Type)
            {
                /* EISA */
                case EisaAdapter:

                    /* Fixup information */
                    Interface = Eisa;
                    Bus = CmpTypeCount[EisaAdapter]++;
                    break;

                /* Turbo-channel */
                case TcAdapter:

                    /* Fixup information */
                    Interface = TurboChannel;
                    Bus = CmpTypeCount[TurboChannel]++;
                    break;

                /* ISA, PCI, etc busses */
                case MultiFunctionAdapter:

                    /* Check if we have an  identifier */
                    if (Component->Identifier)
                    {
                        /* Loop each multi-function adapter type */
                        for (i = 0; CmpMultifunctionTypes[i].Identifier; i++)
                        {
                            /* Check for a name match */
                            if (!_stricmp(CmpMultifunctionTypes[i].Identifier,
                                          Component->Identifier))
                            {
                                /* Match found */
                                break;
                            }
                        }

                        /* Fix up information */
                        Interface = CmpMultifunctionTypes[i].InterfaceType;
                        Bus = CmpMultifunctionTypes[i].Count++;
                    }
                    break;

                /* SCSI Bus */
                case ScsiAdapter:

                    /* Fix up */
                    Interface = Internal;
                    Bus = CmpTypeCount[ScsiAdapter]++;
                    break;

                /* Unknown */
                default:
                    Interface = -1;
                    Bus = CmpUnknownBusCount++;
                    break;
            }
        }

        /* Dump information on the component */

        /* Setup the hardware node */
        Status = CmpInitializeRegistryNode(CurrentEntry,
                                           ParentHandle,
                                           &NewHandle,
                                           Interface,
                                           Bus,
                                           DeviceIndexTable);
        if (!NT_SUCCESS(Status)) return Status;

        /* Check for children */
        if (CurrentEntry->Child)
        {
            /* Recurse child */
            Status = CmpSetupConfigurationTree(CurrentEntry->Child,
                                               NewHandle,
                                               Interface,
                                               Bus);
            if (!NT_SUCCESS(Status))
            {
                /* Fail */
                NtClose(NewHandle);
                return Status;
            }
        }

        /* Get to the next entry */
        NtClose(NewHandle);
        CurrentEntry = CurrentEntry->Sibling;
    }

    /* We're done */
    return STATUS_SUCCESS;
}