ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ACPI_STATUS AcpiRsCreatePciRoutingTable ( ACPI_OPERAND_OBJECT PackageObject,
ACPI_BUFFER OutputBuffer 
)

Definition at line 229 of file rscreate.c.

Referenced by AcpiRsGetPrtMethodData().

{
    UINT8                   *Buffer;
    ACPI_OPERAND_OBJECT     **TopObjectList;
    ACPI_OPERAND_OBJECT     **SubObjectList;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_SIZE               BufferSizeNeeded = 0;
    UINT32                  NumberOfElements;
    UINT32                  Index;
    ACPI_PCI_ROUTING_TABLE  *UserPrt;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;
    ACPI_BUFFER             PathBuffer;


    ACPI_FUNCTION_TRACE (RsCreatePciRoutingTable);


    /* Params already validated, so we don't re-validate here */

    /* Get the required buffer length */

    Status = AcpiRsGetPciRoutingTableLength (PackageObject,
                &BufferSizeNeeded);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "BufferSizeNeeded = %X\n",
        (UINT32) BufferSizeNeeded));

    /* Validate/Allocate/Clear caller buffer */

    Status = AcpiUtInitializeBuffer (OutputBuffer, BufferSizeNeeded);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a
     * package that in turn contains an UINT64 Address, a UINT8 Pin,
     * a Name, and a UINT8 SourceIndex.
     */
    TopObjectList    = PackageObject->Package.Elements;
    NumberOfElements = PackageObject->Package.Count;
    Buffer           = OutputBuffer->Pointer;
    UserPrt          = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, Buffer);

    for (Index = 0; Index < NumberOfElements; Index++)
    {
        /*
         * Point UserPrt past this current structure
         *
         * NOTE: On the first iteration, UserPrt->Length will
         * be zero because we cleared the return buffer earlier
         */
        Buffer += UserPrt->Length;
        UserPrt = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, Buffer);

        /*
         * Fill in the Length field with the information we have at this point.
         * The minus four is to subtract the size of the UINT8 Source[4] member
         * because it is added below.
         */
        UserPrt->Length = (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);

        /* Each element of the top-level package must also be a package */

        if ((*TopObjectList)->Common.Type != ACPI_TYPE_PACKAGE)
        {
            ACPI_ERROR ((AE_INFO,
                "(PRT[%u]) Need sub-package, found %s",
                Index, AcpiUtGetObjectTypeName (*TopObjectList)));
            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
        }

        /* Each sub-package must be of length 4 */

        if ((*TopObjectList)->Package.Count != 4)
        {
            ACPI_ERROR ((AE_INFO,
                "(PRT[%u]) Need package of length 4, found length %u",
                Index, (*TopObjectList)->Package.Count));
            return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT);
        }

        /*
         * Dereference the sub-package.
         * The SubObjectList will now point to an array of the four IRQ
         * elements: [Address, Pin, Source, SourceIndex]
         */
        SubObjectList = (*TopObjectList)->Package.Elements;

        /* 1) First subobject: Dereference the PRT.Address */

        ObjDesc = SubObjectList[0];
        if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
        {
            ACPI_ERROR ((AE_INFO, "(PRT[%u].Address) Need Integer, found %s",
                Index, AcpiUtGetObjectTypeName (ObjDesc)));
            return_ACPI_STATUS (AE_BAD_DATA);
        }

        UserPrt->Address = ObjDesc->Integer.Value;

        /* 2) Second subobject: Dereference the PRT.Pin */

        ObjDesc = SubObjectList[1];
        if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
        {
            ACPI_ERROR ((AE_INFO, "(PRT[%u].Pin) Need Integer, found %s",
                Index, AcpiUtGetObjectTypeName (ObjDesc)));
            return_ACPI_STATUS (AE_BAD_DATA);
        }

        UserPrt->Pin = (UINT32) ObjDesc->Integer.Value;

        /*
         * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
         * and the SourceIndex (index 3), fix it. _PRT is important enough to
         * workaround this BIOS error. This also provides compatibility with
         * other ACPI implementations.
         */
        ObjDesc = SubObjectList[3];
        if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
        {
            SubObjectList[3] = SubObjectList[2];
            SubObjectList[2] = ObjDesc;

            ACPI_WARNING ((AE_INFO,
                "(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed",
                Index));
        }

        /*
         * 3) Third subobject: Dereference the PRT.SourceName
         * The name may be unresolved (slack mode), so allow a null object
         */
        ObjDesc = SubObjectList[2];
        if (ObjDesc)
        {
            switch (ObjDesc->Common.Type)
            {
            case ACPI_TYPE_LOCAL_REFERENCE:

                if (ObjDesc->Reference.Class != ACPI_REFCLASS_NAME)
                {
                    ACPI_ERROR ((AE_INFO,
                        "(PRT[%u].Source) Need name, found Reference Class 0x%X",
                        Index, ObjDesc->Reference.Class));
                    return_ACPI_STATUS (AE_BAD_DATA);
                }

                Node = ObjDesc->Reference.Node;

                /* Use *remaining* length of the buffer as max for pathname */

                PathBuffer.Length = OutputBuffer->Length -
                                    (UINT32) ((UINT8 *) UserPrt->Source -
                                    (UINT8 *) OutputBuffer->Pointer);
                PathBuffer.Pointer = UserPrt->Source;

                Status = AcpiNsHandleToPathname ((ACPI_HANDLE) Node, &PathBuffer);

                /* +1 to include null terminator */

                UserPrt->Length += (UINT32) ACPI_STRLEN (UserPrt->Source) + 1;
                break;


            case ACPI_TYPE_STRING:

                ACPI_STRCPY (UserPrt->Source, ObjDesc->String.Pointer);

                /*
                 * Add to the Length field the length of the string
                 * (add 1 for terminator)
                 */
                UserPrt->Length += ObjDesc->String.Length + 1;
                break;


            case ACPI_TYPE_INTEGER:
                /*
                 * If this is a number, then the Source Name is NULL, since the
                 * entire buffer was zeroed out, we can leave this alone.
                 *
                 * Add to the Length field the length of the UINT32 NULL
                 */
                UserPrt->Length += sizeof (UINT32);
                break;


            default:

               ACPI_ERROR ((AE_INFO,
                   "(PRT[%u].Source) Need Ref/String/Integer, found %s",
                   Index, AcpiUtGetObjectTypeName (ObjDesc)));
               return_ACPI_STATUS (AE_BAD_DATA);
            }
        }

        /* Now align the current length */

        UserPrt->Length = (UINT32) ACPI_ROUND_UP_TO_64BIT (UserPrt->Length);

        /* 4) Fourth subobject: Dereference the PRT.SourceIndex */

        ObjDesc = SubObjectList[3];
        if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
        {
            ACPI_ERROR ((AE_INFO,
                "(PRT[%u].SourceIndex) Need Integer, found %s",
                Index, AcpiUtGetObjectTypeName (ObjDesc)));
            return_ACPI_STATUS (AE_BAD_DATA);
        }

        UserPrt->SourceIndex = (UINT32) ObjDesc->Integer.Value;

        /* Point to the next ACPI_OPERAND_OBJECT in the top level package */

        TopObjectList++;
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
            OutputBuffer->Pointer, (UINT32) OutputBuffer->Length));
    return_ACPI_STATUS (AE_OK);
}

Generated on Sat May 26 2012 05:21:34 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.