Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
X
xcap-capability-linux
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
xcap
xcap-capability-linux
Commits
2900681b
Commit
2900681b
authored
15 years ago
by
Len Brown
Browse files
Options
Downloads
Plain Diff
Merge branch 'osc' into release
parents
243e1ef8
3563ff96
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
drivers/acpi/bus.c
+148
-0
148 additions, 0 deletions
drivers/acpi/bus.c
drivers/acpi/pci_root.c
+14
-62
14 additions, 62 deletions
drivers/acpi/pci_root.c
include/linux/acpi.h
+19
-2
19 additions, 2 deletions
include/linux/acpi.h
with
181 additions
and
64 deletions
drivers/acpi/bus.c
+
148
−
0
View file @
2900681b
...
...
@@ -344,6 +344,152 @@ bool acpi_bus_can_wakeup(acpi_handle handle)
EXPORT_SYMBOL
(
acpi_bus_can_wakeup
);
static
void
acpi_print_osc_error
(
acpi_handle
handle
,
struct
acpi_osc_context
*
context
,
char
*
error
)
{
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
};
int
i
;
if
(
ACPI_FAILURE
(
acpi_get_name
(
handle
,
ACPI_FULL_PATHNAME
,
&
buffer
)))
printk
(
KERN_DEBUG
"%s
\n
"
,
error
);
else
{
printk
(
KERN_DEBUG
"%s:%s
\n
"
,
(
char
*
)
buffer
.
pointer
,
error
);
kfree
(
buffer
.
pointer
);
}
printk
(
KERN_DEBUG
"_OSC request data:"
);
for
(
i
=
0
;
i
<
context
->
cap
.
length
;
i
+=
sizeof
(
u32
))
printk
(
"%x "
,
*
((
u32
*
)(
context
->
cap
.
pointer
+
i
)));
printk
(
"
\n
"
);
}
static
u8
hex_val
(
unsigned
char
c
)
{
return
isdigit
(
c
)
?
c
-
'0'
:
toupper
(
c
)
-
'A'
+
10
;
}
static
acpi_status
acpi_str_to_uuid
(
char
*
str
,
u8
*
uuid
)
{
int
i
;
static
int
opc_map_to_uuid
[
16
]
=
{
6
,
4
,
2
,
0
,
11
,
9
,
16
,
14
,
19
,
21
,
24
,
26
,
28
,
30
,
32
,
34
};
if
(
strlen
(
str
)
!=
36
)
return
AE_BAD_PARAMETER
;
for
(
i
=
0
;
i
<
36
;
i
++
)
{
if
(
i
==
8
||
i
==
13
||
i
==
18
||
i
==
23
)
{
if
(
str
[
i
]
!=
'-'
)
return
AE_BAD_PARAMETER
;
}
else
if
(
!
isxdigit
(
str
[
i
]))
return
AE_BAD_PARAMETER
;
}
for
(
i
=
0
;
i
<
16
;
i
++
)
{
uuid
[
i
]
=
hex_val
(
str
[
opc_map_to_uuid
[
i
]])
<<
4
;
uuid
[
i
]
|=
hex_val
(
str
[
opc_map_to_uuid
[
i
]
+
1
]);
}
return
AE_OK
;
}
acpi_status
acpi_run_osc
(
acpi_handle
handle
,
struct
acpi_osc_context
*
context
)
{
acpi_status
status
;
struct
acpi_object_list
input
;
union
acpi_object
in_params
[
4
];
union
acpi_object
*
out_obj
;
u8
uuid
[
16
];
u32
errors
;
if
(
!
context
)
return
AE_ERROR
;
if
(
ACPI_FAILURE
(
acpi_str_to_uuid
(
context
->
uuid_str
,
uuid
)))
return
AE_ERROR
;
context
->
ret
.
length
=
ACPI_ALLOCATE_BUFFER
;
context
->
ret
.
pointer
=
NULL
;
/* Setting up input parameters */
input
.
count
=
4
;
input
.
pointer
=
in_params
;
in_params
[
0
].
type
=
ACPI_TYPE_BUFFER
;
in_params
[
0
].
buffer
.
length
=
16
;
in_params
[
0
].
buffer
.
pointer
=
uuid
;
in_params
[
1
].
type
=
ACPI_TYPE_INTEGER
;
in_params
[
1
].
integer
.
value
=
context
->
rev
;
in_params
[
2
].
type
=
ACPI_TYPE_INTEGER
;
in_params
[
2
].
integer
.
value
=
context
->
cap
.
length
/
sizeof
(
u32
);
in_params
[
3
].
type
=
ACPI_TYPE_BUFFER
;
in_params
[
3
].
buffer
.
length
=
context
->
cap
.
length
;
in_params
[
3
].
buffer
.
pointer
=
context
->
cap
.
pointer
;
status
=
acpi_evaluate_object
(
handle
,
"_OSC"
,
&
input
,
&
context
->
ret
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
/* return buffer should have the same length as cap buffer */
if
(
context
->
ret
.
length
!=
context
->
cap
.
length
)
return
AE_NULL_OBJECT
;
out_obj
=
context
->
ret
.
pointer
;
if
(
out_obj
->
type
!=
ACPI_TYPE_BUFFER
)
{
acpi_print_osc_error
(
handle
,
context
,
"_OSC evaluation returned wrong type"
);
status
=
AE_TYPE
;
goto
out_kfree
;
}
/* Need to ignore the bit0 in result code */
errors
=
*
((
u32
*
)
out_obj
->
buffer
.
pointer
)
&
~
(
1
<<
0
);
if
(
errors
)
{
if
(
errors
&
OSC_REQUEST_ERROR
)
acpi_print_osc_error
(
handle
,
context
,
"_OSC request failed"
);
if
(
errors
&
OSC_INVALID_UUID_ERROR
)
acpi_print_osc_error
(
handle
,
context
,
"_OSC invalid UUID"
);
if
(
errors
&
OSC_INVALID_REVISION_ERROR
)
acpi_print_osc_error
(
handle
,
context
,
"_OSC invalid revision"
);
if
(
errors
&
OSC_CAPABILITIES_MASK_ERROR
)
{
if
(((
u32
*
)
context
->
cap
.
pointer
)[
OSC_QUERY_TYPE
]
&
OSC_QUERY_ENABLE
)
goto
out_success
;
status
=
AE_SUPPORT
;
goto
out_kfree
;
}
status
=
AE_ERROR
;
goto
out_kfree
;
}
out_success:
return
AE_OK
;
out_kfree:
kfree
(
context
->
ret
.
pointer
);
context
->
ret
.
pointer
=
NULL
;
return
status
;
}
EXPORT_SYMBOL
(
acpi_run_osc
);
static
u8
sb_uuid_str
[]
=
"0811B06E-4A27-44F9-8D60-3CBBC22E7B48"
;
static
void
acpi_bus_osc_support
(
void
)
{
u32
capbuf
[
2
];
struct
acpi_osc_context
context
=
{
.
uuid_str
=
sb_uuid_str
,
.
rev
=
1
,
.
cap
.
length
=
8
,
.
cap
.
pointer
=
capbuf
,
};
acpi_handle
handle
;
capbuf
[
OSC_QUERY_TYPE
]
=
OSC_QUERY_ENABLE
;
capbuf
[
OSC_SUPPORT_TYPE
]
=
OSC_SB_PR3_SUPPORT
;
/* _PR3 is in use */
#ifdef CONFIG_ACPI_PROCESSOR_AGGREGATOR
capbuf
[
OSC_SUPPORT_TYPE
]
|=
OSC_SB_PAD_SUPPORT
;
#endif
if
(
ACPI_FAILURE
(
acpi_get_handle
(
NULL
,
"
\\
_SB"
,
&
handle
)))
return
;
if
(
ACPI_SUCCESS
(
acpi_run_osc
(
handle
,
&
context
)))
kfree
(
context
.
ret
.
pointer
);
/* do we need to check the returned cap? Sounds no */
}
/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
...
...
@@ -734,6 +880,8 @@ static int __init acpi_bus_init(void)
status
=
acpi_ec_ecdt_probe
();
/* Ignore result. Not having an ECDT is not fatal. */
acpi_bus_osc_support
();
status
=
acpi_initialize_objects
(
ACPI_FULL_INITIALIZATION
);
if
(
ACPI_FAILURE
(
status
))
{
printk
(
KERN_ERR
PREFIX
"Unable to initialize ACPI objects
\n
"
);
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/pci_root.c
+
14
−
62
View file @
2900681b
...
...
@@ -202,72 +202,24 @@ static void acpi_pci_bridge_scan(struct acpi_device *device)
}
}
static
u8
OSC_UUID
[
16
]
=
{
0x5B
,
0x4D
,
0xDB
,
0x33
,
0xF7
,
0x1F
,
0x1C
,
0x40
,
0x96
,
0x57
,
0x74
,
0x41
,
0xC0
,
0x3D
,
0xD7
,
0x66
};
static
u8
pci_osc_uuid_str
[]
=
"33DB4D5B-1FF7-401C-9657-7441C03DD766"
;
static
acpi_status
acpi_pci_run_osc
(
acpi_handle
handle
,
const
u32
*
capbuf
,
u32
*
retval
)
{
struct
acpi_osc_context
context
=
{
.
uuid_str
=
pci_osc_uuid_str
,
.
rev
=
1
,
.
cap
.
length
=
12
,
.
cap
.
pointer
=
(
void
*
)
capbuf
,
};
acpi_status
status
;
struct
acpi_object_list
input
;
union
acpi_object
in_params
[
4
];
struct
acpi_buffer
output
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
union
acpi_object
*
out_obj
;
u32
errors
;
/* Setting up input parameters */
input
.
count
=
4
;
input
.
pointer
=
in_params
;
in_params
[
0
].
type
=
ACPI_TYPE_BUFFER
;
in_params
[
0
].
buffer
.
length
=
16
;
in_params
[
0
].
buffer
.
pointer
=
OSC_UUID
;
in_params
[
1
].
type
=
ACPI_TYPE_INTEGER
;
in_params
[
1
].
integer
.
value
=
1
;
in_params
[
2
].
type
=
ACPI_TYPE_INTEGER
;
in_params
[
2
].
integer
.
value
=
3
;
in_params
[
3
].
type
=
ACPI_TYPE_BUFFER
;
in_params
[
3
].
buffer
.
length
=
12
;
in_params
[
3
].
buffer
.
pointer
=
(
u8
*
)
capbuf
;
status
=
acpi_evaluate_object
(
handle
,
"_OSC"
,
&
input
,
&
output
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
if
(
!
output
.
length
)
return
AE_NULL_OBJECT
;
out_obj
=
output
.
pointer
;
if
(
out_obj
->
type
!=
ACPI_TYPE_BUFFER
)
{
printk
(
KERN_DEBUG
"_OSC evaluation returned wrong type
\n
"
);
status
=
AE_TYPE
;
goto
out_kfree
;
}
/* Need to ignore the bit0 in result code */
errors
=
*
((
u32
*
)
out_obj
->
buffer
.
pointer
)
&
~
(
1
<<
0
);
if
(
errors
)
{
if
(
errors
&
OSC_REQUEST_ERROR
)
printk
(
KERN_DEBUG
"_OSC request failed
\n
"
);
if
(
errors
&
OSC_INVALID_UUID_ERROR
)
printk
(
KERN_DEBUG
"_OSC invalid UUID
\n
"
);
if
(
errors
&
OSC_INVALID_REVISION_ERROR
)
printk
(
KERN_DEBUG
"_OSC invalid revision
\n
"
);
if
(
errors
&
OSC_CAPABILITIES_MASK_ERROR
)
{
if
(
capbuf
[
OSC_QUERY_TYPE
]
&
OSC_QUERY_ENABLE
)
goto
out_success
;
printk
(
KERN_DEBUG
"Firmware did not grant requested _OSC control
\n
"
);
status
=
AE_SUPPORT
;
goto
out_kfree
;
}
status
=
AE_ERROR
;
goto
out_kfree
;
status
=
acpi_run_osc
(
handle
,
&
context
);
if
(
ACPI_SUCCESS
(
status
))
{
*
retval
=
*
((
u32
*
)(
context
.
ret
.
pointer
+
8
));
kfree
(
context
.
ret
.
pointer
);
}
out_success:
*
retval
=
*
((
u32
*
)(
out_obj
->
buffer
.
pointer
+
8
));
status
=
AE_OK
;
out_kfree:
kfree
(
output
.
pointer
);
return
status
;
}
...
...
@@ -277,10 +229,10 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
u32
support_set
,
result
,
capbuf
[
3
];
/* do _OSC query for all possible controls */
support_set
=
root
->
osc_support_set
|
(
flags
&
OSC_SUPPORT_MASKS
);
support_set
=
root
->
osc_support_set
|
(
flags
&
OSC_
PCI_
SUPPORT_MASKS
);
capbuf
[
OSC_QUERY_TYPE
]
=
OSC_QUERY_ENABLE
;
capbuf
[
OSC_SUPPORT_TYPE
]
=
support_set
;
capbuf
[
OSC_CONTROL_TYPE
]
=
OSC_CONTROL_MASKS
;
capbuf
[
OSC_CONTROL_TYPE
]
=
OSC_
PCI_
CONTROL_MASKS
;
status
=
acpi_pci_run_osc
(
root
->
device
->
handle
,
capbuf
,
&
result
);
if
(
ACPI_SUCCESS
(
status
))
{
...
...
@@ -427,7 +379,7 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags)
if
(
ACPI_FAILURE
(
status
))
return
status
;
control_req
=
(
flags
&
OSC_CONTROL_MASKS
);
control_req
=
(
flags
&
OSC_
PCI_
CONTROL_MASKS
);
if
(
!
control_req
)
return
AE_TYPE
;
...
...
This diff is collapsed.
Click to expand it.
include/linux/acpi.h
+
19
−
2
View file @
2900681b
...
...
@@ -253,10 +253,16 @@ void __init acpi_old_suspend_ordering(void);
void
__init
acpi_s4_no_nvs
(
void
);
#endif
/* CONFIG_PM_SLEEP */
struct
acpi_osc_context
{
char
*
uuid_str
;
/* uuid string */
int
rev
;
struct
acpi_buffer
cap
;
/* arg2/arg3 */
struct
acpi_buffer
ret
;
/* free by caller if success */
};
#define OSC_QUERY_TYPE 0
#define OSC_SUPPORT_TYPE 1
#define OSC_CONTROL_TYPE 2
#define OSC_SUPPORT_MASKS 0x1f
/* _OSC DW0 Definition */
#define OSC_QUERY_ENABLE 1
...
...
@@ -265,12 +271,23 @@ void __init acpi_s4_no_nvs(void);
#define OSC_INVALID_REVISION_ERROR 8
#define OSC_CAPABILITIES_MASK_ERROR 16
acpi_status
acpi_run_osc
(
acpi_handle
handle
,
struct
acpi_osc_context
*
context
);
/* platform-wide _OSC bits */
#define OSC_SB_PAD_SUPPORT 1
#define OSC_SB_PPC_OST_SUPPORT 2
#define OSC_SB_PR3_SUPPORT 4
#define OSC_SB_CPUHP_OST_SUPPORT 8
#define OSC_SB_APEI_SUPPORT 16
/* PCI defined _OSC bits */
/* _OSC DW1 Definition (OS Support Fields) */
#define OSC_EXT_PCI_CONFIG_SUPPORT 1
#define OSC_ACTIVE_STATE_PWR_SUPPORT 2
#define OSC_CLOCK_PWR_CAPABILITY_SUPPORT 4
#define OSC_PCI_SEGMENT_GROUPS_SUPPORT 8
#define OSC_MSI_SUPPORT 16
#define OSC_PCI_SUPPORT_MASKS 0x1f
/* _OSC DW1 Definition (OS Control Fields) */
#define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL 1
...
...
@@ -279,7 +296,7 @@ void __init acpi_s4_no_nvs(void);
#define OSC_PCI_EXPRESS_AER_CONTROL 8
#define OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL 16
#define OSC_CONTROL_MASKS (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
#define OSC_
PCI_
CONTROL_MASKS (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
OSC_SHPC_NATIVE_HP_CONTROL | \
OSC_PCI_EXPRESS_PME_CONTROL | \
OSC_PCI_EXPRESS_AER_CONTROL | \
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment