acpi_package.c revision 148318
1122765Snjl/*- 2122765Snjl * Copyright (c) 2003 Nate Lawson 3122765Snjl * All rights reserved. 4122765Snjl * 5122765Snjl * Redistribution and use in source and binary forms, with or without 6122765Snjl * modification, are permitted provided that the following conditions 7122765Snjl * are met: 8122765Snjl * 1. Redistributions of source code must retain the above copyright 9122765Snjl * notice, this list of conditions and the following disclaimer. 10122765Snjl * 2. Redistributions in binary form must reproduce the above copyright 11122765Snjl * notice, this list of conditions and the following disclaimer in the 12122765Snjl * documentation and/or other materials provided with the distribution. 13122765Snjl * 14122765Snjl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15122765Snjl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16122765Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17122765Snjl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18122765Snjl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19122765Snjl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20122765Snjl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21122765Snjl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22122765Snjl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23122765Snjl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24122765Snjl * SUCH DAMAGE. 25122765Snjl */ 26122765Snjl 27148318Snjl#include <sys/cdefs.h> 28148318Snjl__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_package.c 148318 2005-07-22 23:10:02Z njl $"); 29148318Snjl 30122765Snjl#include <sys/param.h> 31122765Snjl#include <sys/kernel.h> 32122765Snjl#include <sys/bus.h> 33122765Snjl#include <sys/sbuf.h> 34122765Snjl 35122765Snjl#include <machine/bus.h> 36122765Snjl#include <machine/resource.h> 37122765Snjl#include <sys/rman.h> 38122765Snjl 39122765Snjl#include "acpi.h" 40122765Snjl#include <dev/acpica/acpivar.h> 41122765Snjl 42122765Snjl/* 43122765Snjl * Package manipulation convenience functions 44122765Snjl */ 45122765Snjl 46122765Snjlint 47123776Snjlacpi_PkgInt(ACPI_OBJECT *res, int idx, ACPI_INTEGER *dst) 48122765Snjl{ 49122765Snjl ACPI_OBJECT *obj; 50122765Snjl 51122765Snjl obj = &res->Package.Elements[idx]; 52123776Snjl if (obj == NULL || obj->Type != ACPI_TYPE_INTEGER) 53123776Snjl return (EINVAL); 54123776Snjl *dst = obj->Integer.Value; 55122765Snjl 56122765Snjl return (0); 57122765Snjl} 58122765Snjl 59122765Snjlint 60123776Snjlacpi_PkgInt32(ACPI_OBJECT *res, int idx, uint32_t *dst) 61122765Snjl{ 62123776Snjl ACPI_INTEGER tmp; 63123776Snjl int error; 64122765Snjl 65123776Snjl error = acpi_PkgInt(res, idx, &tmp); 66122765Snjl if (error == 0) 67122765Snjl *dst = (uint32_t)tmp; 68123776Snjl 69122765Snjl return (error); 70122765Snjl} 71122765Snjl 72122765Snjlint 73123776Snjlacpi_PkgStr(ACPI_OBJECT *res, int idx, void *dst, size_t size) 74122765Snjl{ 75122765Snjl ACPI_OBJECT *obj; 76122765Snjl void *ptr; 77122765Snjl size_t length; 78122765Snjl 79122765Snjl obj = &res->Package.Elements[idx]; 80123776Snjl if (obj == NULL) 81123776Snjl return (EINVAL); 82122765Snjl bzero(dst, sizeof(dst)); 83122765Snjl 84122765Snjl switch (obj->Type) { 85122765Snjl case ACPI_TYPE_STRING: 86122765Snjl ptr = obj->String.Pointer; 87122765Snjl length = obj->String.Length; 88122765Snjl break; 89122765Snjl case ACPI_TYPE_BUFFER: 90122765Snjl ptr = obj->Buffer.Pointer; 91122765Snjl length = obj->Buffer.Length; 92122765Snjl break; 93122765Snjl default: 94123776Snjl return (EINVAL); 95122765Snjl } 96122765Snjl 97122765Snjl /* Make sure string will fit, including terminating NUL */ 98123776Snjl if (++length > size) 99123776Snjl return (E2BIG); 100122765Snjl 101122765Snjl strlcpy(dst, ptr, length); 102122765Snjl return (0); 103122765Snjl} 104122765Snjl 105122765Snjlint 106141371Snjlacpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *type, int *rid, 107141371Snjl struct resource **dst) 108122765Snjl{ 109122765Snjl ACPI_GENERIC_ADDRESS gas; 110141371Snjl ACPI_OBJECT *obj; 111122765Snjl 112122765Snjl obj = &res->Package.Elements[idx]; 113122765Snjl if (obj == NULL || obj->Type != ACPI_TYPE_BUFFER || 114141294Snjl obj->Buffer.Length < sizeof(ACPI_GENERIC_ADDRESS) + 3) 115123776Snjl return (EINVAL); 116122765Snjl 117122765Snjl memcpy(&gas, obj->Buffer.Pointer + 3, sizeof(gas)); 118122765Snjl 119141371Snjl return (acpi_bus_alloc_gas(dev, type, rid, &gas, dst)); 120122765Snjl} 121128045Snjl 122128045SnjlACPI_HANDLE 123128045Snjlacpi_GetReference(ACPI_HANDLE scope, ACPI_OBJECT *obj) 124128045Snjl{ 125128045Snjl ACPI_HANDLE h; 126128045Snjl 127128045Snjl if (obj == NULL) 128128045Snjl return (NULL); 129128045Snjl 130128045Snjl switch (obj->Type) { 131128045Snjl case ACPI_TYPE_LOCAL_REFERENCE: 132128045Snjl case ACPI_TYPE_ANY: 133128045Snjl h = obj->Reference.Handle; 134128045Snjl break; 135128045Snjl case ACPI_TYPE_STRING: 136128045Snjl /* 137128045Snjl * The String object usually contains a fully-qualified path, so 138128045Snjl * scope can be NULL. 139128045Snjl * 140128045Snjl * XXX This may not always be the case. 141128045Snjl */ 142128045Snjl if (ACPI_FAILURE(AcpiGetHandle(scope, obj->String.Pointer, &h))) 143128045Snjl h = NULL; 144128045Snjl break; 145128045Snjl default: 146128045Snjl h = NULL; 147128045Snjl break; 148128045Snjl } 149128045Snjl 150128045Snjl return (h); 151128045Snjl} 152