static ACPI_STATUS AcpiDbDeviceResources ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node; ACPI_NAMESPACE_NODE *PrtNode = NULL; ACPI_NAMESPACE_NODE *CrsNode = NULL; ACPI_NAMESPACE_NODE *PrsNode = NULL; ACPI_NAMESPACE_NODE *AeiNode = NULL; char *ParentPath; ACPI_BUFFER ReturnObj; ACPI_STATUS Status; Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); ParentPath = AcpiNsGetExternalPathname (Node); if (!ParentPath) { return (AE_NO_MEMORY); } /* Get handles to the resource methods for this device */ (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode)); (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode)); (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode)); (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode)); if (!PrtNode && !CrsNode && !PrsNode && !AeiNode) { goto Cleanup; /* Nothing to do */ } AcpiOsPrintf ("\nDevice: %s\n", ParentPath); /* Prepare for a return object of arbitrary size */ ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; /* _PRT */ if (PrtNode) { AcpiOsPrintf ("Evaluating _PRT\n"); Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not evaluate _PRT: %s\n", AcpiFormatException (Status)); goto GetCrs; } ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiGetIrqRoutingTable (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", AcpiFormatException (Status)); goto GetCrs; } AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer)); } /* _CRS */ GetCrs: if (CrsNode) { AcpiOsPrintf ("Evaluating _CRS\n"); ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not evaluate _CRS: %s\n", AcpiFormatException (Status)); goto GetPrs; } /* This code is here to exercise the AcpiWalkResources interface */ Status = AcpiWalkResources (Node, METHOD_NAME__CRS, AcpiDbResourceCallback, NULL); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiWalkResources failed: %s\n", AcpiFormatException (Status)); goto GetPrs; } /* Get the _CRS resource list */ ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiGetCurrentResources (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", AcpiFormatException (Status)); goto GetPrs; } /* Dump the _CRS resource list */ AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, ReturnObj.Pointer)); /* * Perform comparison of original AML to newly created AML. This tests both * the AML->Resource conversion and the Resource->Aml conversion. */ Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS); /* Execute _SRS with the resource list */ Status = AcpiSetCurrentResources (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", AcpiFormatException (Status)); goto GetPrs; } } /* _PRS */ GetPrs: if (PrsNode) { AcpiOsPrintf ("Evaluating _PRS\n"); ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not evaluate _PRS: %s\n", AcpiFormatException (Status)); goto GetAei; } ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiGetPossibleResources (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", AcpiFormatException (Status)); goto GetAei; } AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); } /* _AEI */ GetAei: if (AeiNode) { AcpiOsPrintf ("Evaluating _AEI\n"); ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not evaluate _AEI: %s\n", AcpiFormatException (Status)); goto Cleanup; } ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiGetEventResources (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiGetEventResources failed: %s\n", AcpiFormatException (Status)); goto Cleanup; } AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); } Cleanup: ACPI_FREE (ParentPath); return (AE_OK); }
/* * Retrieves a list of possible interrupt settings for the interrupt link * device. * * Stores polarity and sensitivity in the structure pointed to by intr_flagp. * Updates value pointed to by irqlistp with the address of a table it * allocates. where interrupt numbers are stored. Stores the number of entries * in this table in the value pointed to by num_entriesp; * * Each element in this table is of type int32_t. The table should be later * freed by caller via acpi_free_irq_list(). * * Returns ACPI_PSM_SUCCESS on success and ACPI_PSM_FAILURE upon failure */ int acpi_get_possible_irq_resources(acpi_psm_lnk_t *acpipsmlnkp, acpi_irqlist_t **irqlistp) { ACPI_HANDLE lnkobj; ACPI_BUFFER rsb; ACPI_RESOURCE *resp; int status; int i, el, po, irqlist_len; uint32_t *irqlist; void *tmplist; iflag_t intr_flags; ASSERT(acpipsmlnkp != NULL); lnkobj = acpipsmlnkp->lnkobj; rsb.Pointer = NULL; rsb.Length = ACPI_ALLOCATE_BUFFER; status = AcpiGetPossibleResources(lnkobj, &rsb); if (status != AE_OK) { cmn_err(CE_WARN, "!psm: get_irq: _PRS failed"); return (ACPI_PSM_FAILURE); } /* * Scan the resources looking for an interrupt resource */ *irqlistp = 0; for (resp = rsb.Pointer; resp->Type != ACPI_RESOURCE_TYPE_END_TAG; resp = ACPI_NEXT_RESOURCE(resp)) { switch (resp->Type) { case ACPI_RESOURCE_TYPE_IRQ: irqlist_len = resp->Data.Irq.InterruptCount; tmplist = resp->Data.Irq.Interrupts; el = resp->Data.Irq.Triggering; po = resp->Data.Irq.Polarity; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: irqlist_len = resp->Data.ExtendedIrq.InterruptCount; tmplist = resp->Data.ExtendedIrq.Interrupts; el = resp->Data.ExtendedIrq.Triggering; po = resp->Data.ExtendedIrq.Polarity; break; default: continue; } if (resp->Type != ACPI_RESOURCE_TYPE_IRQ && resp->Type != ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { cmn_err(CE_WARN, "!psm: get_irq: no IRQ resource"); return (ACPI_PSM_FAILURE); } /* NEEDSWORK: move this into add_irqlist_entry someday */ irqlist = kmem_zalloc(irqlist_len * sizeof (*irqlist), KM_SLEEP); for (i = 0; i < irqlist_len; i++) if (resp->Type == ACPI_RESOURCE_TYPE_IRQ) irqlist[i] = ((uint8_t *)tmplist)[i]; else irqlist[i] = ((uint32_t *)tmplist)[i]; intr_flags.intr_el = psm_acpi_edgelevel(el); intr_flags.intr_po = psm_acpi_po(po); acpi_add_irqlist_entry(irqlistp, irqlist, irqlist_len, &intr_flags); } AcpiOsFree(rsb.Pointer); return (irqlistp == NULL ? ACPI_PSM_FAILURE : ACPI_PSM_SUCCESS); }
status_t get_possible_resources(acpi_handle busDeviceHandle, acpi_data *retBuffer) { return AcpiGetPossibleResources(busDeviceHandle, (ACPI_BUFFER*)retBuffer) == AE_OK ? B_OK : B_ERROR; }
/* * Sets the irq resource of the lnk object to the requested irq value. * * Returns ACPI_PSM_SUCCESS on success, ACPI_PSM_FAILURE upon failure. */ int acpi_set_irq_resource(acpi_psm_lnk_t *acpipsmlnkp, int irq) { ACPI_BUFFER rsb; ACPI_RESOURCE *resp; ACPI_RESOURCE *srsp; ACPI_HANDLE lnkobj; int srs_len, status; ASSERT(acpipsmlnkp != NULL); lnkobj = acpipsmlnkp->lnkobj; /* * Fetch the possible resources for the link */ rsb.Pointer = NULL; rsb.Length = ACPI_ALLOCATE_BUFFER; status = AcpiGetPossibleResources(lnkobj, &rsb); if (status != AE_OK) { cmn_err(CE_WARN, "!psm: set_irq: _PRS failed"); return (ACPI_PSM_FAILURE); } /* * Find an IRQ resource descriptor to use as template */ srsp = NULL; for (resp = rsb.Pointer; resp->Type != ACPI_RESOURCE_TYPE_END_TAG; resp = ACPI_NEXT_RESOURCE(resp)) { if ((resp->Type == ACPI_RESOURCE_TYPE_IRQ) || (resp->Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ)) { ACPI_RESOURCE *endtag; /* * Allocate enough room for this resource entry * and one end tag following it */ srs_len = resp->Length + sizeof (*endtag); srsp = kmem_zalloc(srs_len, KM_SLEEP); bcopy(resp, srsp, resp->Length); endtag = ACPI_NEXT_RESOURCE(srsp); endtag->Type = ACPI_RESOURCE_TYPE_END_TAG; endtag->Length = 0; break; /* drop out of the loop */ } } /* * We're done with the PRS values, toss 'em lest we forget */ AcpiOsFree(rsb.Pointer); if (srsp == NULL) return (ACPI_PSM_FAILURE); /* * The Interrupts[] array is always at least one entry * long; see the definition of ACPI_RESOURCE. */ switch (srsp->Type) { case ACPI_RESOURCE_TYPE_IRQ: srsp->Data.Irq.InterruptCount = 1; srsp->Data.Irq.Interrupts[0] = irq; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: srsp->Data.ExtendedIrq.InterruptCount = 1; srsp->Data.ExtendedIrq.Interrupts[0] = irq; break; } rsb.Pointer = srsp; rsb.Length = srs_len; status = AcpiSetCurrentResources(lnkobj, &rsb); kmem_free(srsp, srs_len); if (status != AE_OK) { cmn_err(CE_WARN, "!psm: set_irq: _SRS failed"); return (ACPI_PSM_FAILURE); } if (acpica_eval_int(lnkobj, "_STA", &status) == AE_OK) { acpipsmlnkp->device_status = (uchar_t)status; return (ACPI_PSM_SUCCESS); } else return (ACPI_PSM_FAILURE); }