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