/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright 2016, Joyent, Inc.
*/
/*
* Copyright (c) 2009-2010, Intel Corporation.
* All rights reserved.
*/
#include <sys/sysmacros.h>
#include <sys/acpidev_rsc.h>
#include <sys/acpidev_impl.h>
/* Data structure to hold parsed resources during walking. */
struct acpidev_resource_handle {
int acpidev_reg_count;
int acpidev_reg_max;
int acpidev_range_count;
int acpidev_range_max;
int acpidev_bus_count;
int acpidev_bus_max;
int acpidev_irq_count;
int acpidev_dma_count;
};
{
return (rhdl);
}
void
{
sz = sizeof (acpidev_phys_spec_t) *
}
sz = sizeof (acpidev_ranges_t) *
}
sz = sizeof (acpidev_bus_range_t) *
}
}
}
static void
{
/* Prefer linear incremental here. */
}
}
/* Prefer linear incremental here. */
}
}
/* Prefer linear incremental here. */
}
}
}
{
}
return (AE_OK);
}
{
uint_t i, j;
return (AE_BAD_PARAMETER);
}
for (i = 0, j = 0; i < rhdl->acpidev_reg_count; i++) {
if (j < *cntp) {
}
j++;
}
}
if (j >= *cntp) {
*cntp = j;
return (AE_LIMIT);
} else {
*cntp = j;
return (AE_OK);
}
}
{
uint_t i, j;
for (i = 0, j = 0; i < rhdl->acpidev_reg_count; i++) {
j++;
}
}
return (j);
}
{
}
return (AE_OK);
}
{
uint_t i, j;
return (AE_BAD_PARAMETER);
}
for (i = 0, j = 0; i < rhdl->acpidev_range_count; i++) {
if (j < *cntp) {
}
j++;
}
}
if (j >= *cntp) {
*cntp = j;
return (AE_LIMIT);
} else {
*cntp = j;
return (AE_OK);
}
}
{
uint_t i, j;
for (i = 0, j = 0; i < rhdl->acpidev_range_count; i++) {
j++;
}
}
return (j);
}
{
}
return (AE_OK);
}
{
uint_t i, j;
return (AE_BAD_PARAMETER);
}
for (i = 0, j = 0; i < rhdl->acpidev_bus_count; i++) {
if (j < *cntp) {
}
j++;
}
if (j >= *cntp) {
*cntp = j;
return (AE_LIMIT);
} else {
*cntp = j;
return (AE_OK);
}
}
{
return (rhdl->acpidev_bus_count);
}
{
"!acpidev: too many DMA resources, max %u.",
return (AE_LIMIT);
}
return (AE_OK);
}
{
uint_t i, j;
return (AE_BAD_PARAMETER);
}
for (i = 0, j = 0; i < rhdl->acpidev_dma_count; i++) {
if (j < *cntp) {
}
j++;
}
if (j >= *cntp) {
*cntp = j;
return (AE_LIMIT);
} else {
*cntp = j;
return (AE_OK);
}
}
{
return (rhdl->acpidev_dma_count);
}
{
"!acpidev: too many IRQ resources, max %u.",
return (AE_LIMIT);
}
return (AE_OK);
}
{
uint_t i, j;
return (AE_BAD_PARAMETER);
}
for (i = 0, j = 0; i < rhdl->acpidev_irq_count; i++) {
if (j < *cntp) {
}
j++;
}
if (j >= *cntp) {
*cntp = j;
return (AE_LIMIT);
} else {
*cntp = j;
return (AE_OK);
}
}
{
return (rhdl->acpidev_irq_count);
}
static ACPI_STATUS
{
return (AE_OK);
}
switch (addrp->ResourceType) {
case ACPI_MEMORY_RANGE:
}
}
} else {
"!acpidev: unknown memory caching type %u.",
break;
}
}
/* Generate 'reg' for producer. */
0xFFFFFFFF;
if (ACPI_FAILURE(rc)) {
"insert regspec into resource handle.");
}
/* Generate 'ranges' for producer. */
/* It's IO on parent side if Translation is true. */
} else {
}
0xFFFFFFFF;
if (ACPI_FAILURE(rc)) {
"insert range into resource handle.");
}
}
break;
case ACPI_IO_RANGE:
}
}
} else {
"!acpidev: unknown IO range type %u.",
break;
}
}
/* Generate 'reg' for producer. */
0xFFFFFFFF;
if (ACPI_FAILURE(rc)) {
"insert regspec into resource handle.");
}
/* Generate 'ranges' for producer. */
/* It's Memory on parent side if Translation is true. */
} else {
}
0xFFFFFFFF;
if (ACPI_FAILURE(rc)) {
"insert range into resource handle.");
}
}
break;
case ACPI_BUS_NUMBER_RANGE:
/* Only support producer of BUS. */
"in ADDRESS64 is invalid.");
break;
}
if (ACPI_FAILURE(rc)) {
"insert bus range into resource handle.");
}
}
break;
default:
"!acpidev: unknown resource type %u in ADDRESS64.",
}
return (rc);
}
static ACPI_STATUS
{
case ACPI_RESOURCE_TYPE_DMA:
case ACPI_RESOURCE_TYPE_IRQ:
"!acpidev: unsupported producer resource type %u, ignored.",
break;
case ACPI_RESOURCE_TYPE_IO:
{
}
"IO max is out of range.");
if (ACPI_FAILURE(rc)) {
"insert range into resource handle.");
}
}
break;
}
{
"a CONSUMER resource, ignored.");
&addr64))) {
"!acpidev: failed to convert resource to ADDR64.");
&addr64))) {
"!acpidev: failed to handle ADDRESS resource.");
}
break;
}
{
"a CONSUMER resource, ignored.");
break;
}
&addr64))) {
"!acpidev: failed to handle EXTADDRESS resource.");
}
break;
}
"START_DEPENDENT or END_DEPENDENT tag, ignored.");
break;
/* Finish walking when we encounter END_TAG. */
break;
default:
"!acpidev: unknown ACPI resource type %u, ignored.",
break;
}
return (rc);
}
static ACPI_STATUS
{
"!acpidev: unsupported consumer resource type %u, ignored.",
break;
{
int i;
"a PRODUCER resource, ignored.");
break;
}
continue;
}
"Extended IRQ into resource handle.");
break;
}
break;
}
case ACPI_RESOURCE_TYPE_IRQ:
{
int i;
continue;
}
"IRQ into resource handle.");
break;
}
break;
}
case ACPI_RESOURCE_TYPE_DMA:
{
int i;
continue;
}
"dma into resource handle.");
break;
}
break;
}
case ACPI_RESOURCE_TYPE_IO:
{
}
} else {
}
"record, IO max is out of range.");
if (ACPI_FAILURE(rc)) {
"insert reg into resource handle.");
}
}
break;
}
{
}
} else {
}
}
"!acpidev: invalid MEMORY32/FIXEDMEMORY32 record, "
"memory max is out of range.");
if (ACPI_FAILURE(rc)) {
"insert reg into resource handle.");
}
}
break;
}
{
"a PRODUCER resource, ignored.");
&addr64))) {
"!acpidev: failed to convert resource to ADDR64.");
&addr64))) {
"!acpidev: failed to handle ADDRESS resource.");
}
break;
}
{
"a PRODUCER resource, ignored.");
break;
}
&addr64))) {
"!acpidev: failed to handle EXTADDRESS resource.");
}
break;
}
"START_DEPENDENT or END_DEPENDENT tag, ignored.");
break;
/* Finish walking when we encounter END_TAG. */
break;
default:
"!acpidev: unknown ACPI resource type %u, ignored.",
break;
}
return (rc);
}
{
"!acpidev: hdl is NULL in acpidev_resource_walk().");
return (AE_BAD_PARAMETER);
"!acpidev: method is NULL in acpidev_resource_walk().");
return (AE_BAD_PARAMETER);
"in acpidev_resource_walk().");
return (AE_BAD_PARAMETER);
}
/* Check whether method exists under object. */
"!acpidev: method %s doesn't exist under %s",
return (AE_NOT_FOUND);
}
/* Walk all resources. */
if (consumer) {
} else {
}
if (ACPI_SUCCESS(rc)) {
} else {
}
if (ACPI_FAILURE(rc)) {
}
return (rc);
}
{
"in acpidev_resource_process().");
return (AE_BAD_PARAMETER);
}
/* Walk all resources. */
if (ACPI_FAILURE(rc)) {
"!acpidev: failed to walk ACPI resources of %s(%s).",
return (rc);
}
if (consumer) {
/* Create device properties for consumer. */
/* Create 'reg' and 'assigned-addresses' properties. */
if (rhdl->acpidev_reg_count > 0 &&
sizeof (int)) != NDI_SUCCESS) {
"'reg' property for %s.", path);
goto out;
}
if (rhdl->acpidev_reg_count > 0 &&
sizeof (int)) != NDI_SUCCESS) {
"'assigned-addresses' property for %s.", path);
goto out;
}
/* Create 'interrupts' property. */
if (rhdl->acpidev_irq_count > 0 &&
"'interrupts' property for %s.", path);
goto out;
}
/* Create 'dma-channels' property. */
if (rhdl->acpidev_dma_count > 0 &&
"'dma-channels' property for %s.", path);
goto out;
}
} else {
/* Create device properties for producer. */
/* Create 'ranges' property. */
if (rhdl->acpidev_range_count > 0 &&
sizeof (int)) != NDI_SUCCESS) {
"'ranges' property for %s.", path);
goto out;
}
/* Create 'bus-range' property. */
if (rhdl->acpidev_bus_count > 0 &&
sizeof (int)) != NDI_SUCCESS) {
"'bus-range' property for %s.", path);
goto out;
}
}
out:
/* Free resources allocated by acpidev_resource_walk. */
return (rc);
}