Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
ia64
kernel
acpi-ext.c
Go to the documentation of this file.
1
/*
2
* (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P.
3
* Alex Williamson <
[email protected]
>
4
* Bjorn Helgaas <
[email protected]
>
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
9
*/
10
11
#include <linux/module.h>
12
#include <linux/types.h>
13
#include <linux/slab.h>
14
#include <
linux/acpi.h
>
15
16
#include <
asm/acpi-ext.h
>
17
18
/*
19
* Device CSRs that do not appear in PCI config space should be described
20
* via ACPI. This would normally be done with Address Space Descriptors
21
* marked as "consumer-only," but old versions of Windows and Linux ignore
22
* the producer/consumer flag, so HP invented a vendor-defined resource to
23
* describe the location and size of CSR space.
24
*/
25
26
struct
acpi_vendor_uuid
hp_ccsr_uuid
= {
27
.subtype = 2,
28
.data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
29
0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
30
};
31
32
static
acpi_status
hp_ccsr_locate(
acpi_handle
obj,
u64
*base,
u64
*
length
)
33
{
34
acpi_status
status
;
35
struct
acpi_buffer
buffer
= {
ACPI_ALLOCATE_BUFFER
,
NULL
};
36
struct
acpi_resource
*
resource
;
37
struct
acpi_resource_vendor_typed
*
vendor
;
38
39
status =
acpi_get_vendor_resource
(obj,
METHOD_NAME__CRS
, &hp_ccsr_uuid,
40
&buffer);
41
42
resource = buffer.
pointer
;
43
vendor = &resource->
data
.
vendor_typed
;
44
45
if
(
ACPI_FAILURE
(status) || vendor->
byte_length
< 16) {
46
status =
AE_NOT_FOUND
;
47
goto
exit
;
48
}
49
50
memcpy
(base, vendor->
byte_data
,
sizeof
(*base));
51
memcpy
(length, vendor->
byte_data
+ 8,
sizeof
(*length));
52
53
exit
:
54
kfree
(buffer.
pointer
);
55
return
status
;
56
}
57
58
struct
csr_space
{
59
u64
base
;
60
u64
length
;
61
};
62
63
static
acpi_status
find_csr_space(
struct
acpi_resource
*resource,
void
*
data
)
64
{
65
struct
csr_space
*space =
data
;
66
struct
acpi_resource_address64
addr;
67
acpi_status
status
;
68
69
status =
acpi_resource_to_address64
(resource, &addr);
70
if
(
ACPI_SUCCESS
(status) &&
71
addr.resource_type ==
ACPI_MEMORY_RANGE
&&
72
addr.
address_length
&&
73
addr.producer_consumer ==
ACPI_CONSUMER
) {
74
space->
base
= addr.
minimum
;
75
space->
length
= addr.
address_length
;
76
return
AE_CTRL_TERMINATE
;
77
}
78
return
AE_OK
;
/* keep looking */
79
}
80
81
static
acpi_status
hp_crs_locate(
acpi_handle
obj,
u64
*base,
u64
*length)
82
{
83
struct
csr_space
space = { 0, 0 };
84
85
acpi_walk_resources
(obj,
METHOD_NAME__CRS
, find_csr_space, &space);
86
if
(!space.
length
)
87
return
AE_NOT_FOUND
;
88
89
*base = space.
base
;
90
*length = space.
length
;
91
return
AE_OK
;
92
}
93
94
acpi_status
hp_acpi_csr_space
(
acpi_handle
obj,
u64
*csr_base,
u64
*csr_length)
95
{
96
acpi_status
status
;
97
98
status = hp_ccsr_locate(obj, csr_base, csr_length);
99
if
(
ACPI_SUCCESS
(status))
100
return
status
;
101
102
return
hp_crs_locate(obj, csr_base, csr_length);
103
}
104
EXPORT_SYMBOL
(
hp_acpi_csr_space
);
Generated on Thu Jan 10 2013 13:06:26 for Linux Kernel by
1.8.2