acpi_package.c revision 123776
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 * $FreeBSD: head/sys/dev/acpica/acpi_package.c 123776 2003-12-23 18:26:53Z njl $ 27122765Snjl */ 28122765Snjl 29122765Snjl#include <sys/param.h> 30122765Snjl#include <sys/kernel.h> 31122765Snjl#include <sys/bus.h> 32122765Snjl#include <sys/sbuf.h> 33122765Snjl 34122765Snjl#include <machine/bus_pio.h> 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 106122765Snjlacpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *rid, 107123776Snjl struct resource **dst) 108122765Snjl{ 109122765Snjl ACPI_GENERIC_ADDRESS gas; 110122765Snjl ACPI_OBJECT *obj; 111122765Snjl 112122765Snjl obj = &res->Package.Elements[idx]; 113122765Snjl if (obj == NULL || obj->Type != ACPI_TYPE_BUFFER || 114122765Snjl obj->Buffer.Length < sizeof(ACPI_GENERIC_ADDRESS) + 3) { 115122765Snjl 116123776Snjl return (EINVAL); 117122765Snjl } 118122765Snjl 119122765Snjl memcpy(&gas, obj->Buffer.Pointer + 3, sizeof(gas)); 120122765Snjl *dst = acpi_bus_alloc_gas(dev, rid, &gas); 121123776Snjl if (*dst == NULL) 122123776Snjl return (ENXIO); 123122765Snjl 124122765Snjl return (0); 125122765Snjl} 126