@@ -237,13 +237,60 @@ static int acpi_eval_osc(acpi_handle handle, guid_t *guid, int rev,
237237 return 0 ;
238238}
239239
240+ static bool acpi_osc_error_check (acpi_handle handle , guid_t * guid , int rev ,
241+ struct acpi_buffer * cap , u32 * retbuf )
242+ {
243+ /* Only take defined error bits into account. */
244+ u32 errors = retbuf [OSC_QUERY_DWORD ] & OSC_ERROR_MASK ;
245+ u32 * capbuf = cap -> pointer ;
246+ bool fail ;
247+
248+ /*
249+ * If OSC_QUERY_ENABLE is set, ignore the "capabilities masked"
250+ * bit because it merely means that some features have not been
251+ * acknowledged which is not unexpected.
252+ */
253+ if (capbuf [OSC_QUERY_DWORD ] & OSC_QUERY_ENABLE )
254+ errors &= ~OSC_CAPABILITIES_MASK_ERROR ;
255+
256+ if (!errors )
257+ return false;
258+
259+ acpi_dump_osc_data (handle , guid , rev , cap );
260+ /*
261+ * As a rule, fail only if OSC_QUERY_ENABLE is set because otherwise the
262+ * acknowledged features need to be controlled.
263+ */
264+ fail = !!(capbuf [OSC_QUERY_DWORD ] & OSC_QUERY_ENABLE );
265+
266+ if (errors & OSC_REQUEST_ERROR )
267+ acpi_handle_debug (handle , "_OSC: request failed\n" );
268+
269+ if (errors & OSC_INVALID_UUID_ERROR ) {
270+ acpi_handle_debug (handle , "_OSC: invalid UUID\n" );
271+ /*
272+ * Always fail if this bit is set because it means that the
273+ * request could not be processed.
274+ */
275+ fail = true;
276+ }
277+
278+ if (errors & OSC_INVALID_REVISION_ERROR )
279+ acpi_handle_debug (handle , "_OSC: invalid revision\n" );
280+
281+ if (errors & OSC_CAPABILITIES_MASK_ERROR )
282+ acpi_handle_debug (handle , "_OSC: capability bits masked\n" );
283+
284+ return fail ;
285+ }
286+
240287acpi_status acpi_run_osc (acpi_handle handle , struct acpi_osc_context * context )
241288{
242- u32 errors , * capbuf = context -> cap .pointer ;
243289 union acpi_object in_params [4 ], * out_obj ;
244290 struct acpi_buffer output ;
245291 acpi_status status = AE_OK ;
246292 guid_t guid ;
293+ u32 * retbuf ;
247294 int ret ;
248295
249296 if (!context || !context -> cap .pointer ||
@@ -257,51 +304,15 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
257304 return AE_ERROR ;
258305
259306 out_obj = output .pointer ;
260- /* Only take defined error bits into account. */
261- errors = * ((u32 * )out_obj -> buffer .pointer ) & OSC_ERROR_MASK ;
262- /*
263- * If OSC_QUERY_ENABLE is set, ignore the "capabilities masked"
264- * bit because it merely means that some features have not been
265- * acknowledged which is not unexpected.
266- */
267- if (capbuf [OSC_QUERY_DWORD ] & OSC_QUERY_ENABLE )
268- errors &= ~OSC_CAPABILITIES_MASK_ERROR ;
269-
270- if (errors ) {
271- /*
272- * As a rule, fail only if OSC_QUERY_ENABLE is set because
273- * otherwise the acknowledged features need to be controlled.
274- */
275- bool fail = !!(capbuf [OSC_QUERY_DWORD ] & OSC_QUERY_ENABLE );
276-
277- acpi_dump_osc_data (handle , & guid , context -> rev , & context -> cap );
278- if (errors & OSC_INVALID_UUID_ERROR ) {
279- acpi_handle_debug (handle , "_OSC: invalid UUID" );
280- /*
281- * Always fail if this bit is set because it means that
282- * the request could not be processed.
283- */
284- fail = true;
285- goto out_kfree ;
286- }
287- if (errors & OSC_REQUEST_ERROR )
288- acpi_handle_debug (handle , "_OSC: request failed" );
289-
290- if (errors & OSC_INVALID_REVISION_ERROR )
291- acpi_handle_debug (handle , "_OSC: invalid revision" );
292-
293- if (errors & OSC_CAPABILITIES_MASK_ERROR )
294- acpi_handle_debug (handle , "_OSC: capability bits masked" );
307+ retbuf = (u32 * )out_obj -> buffer .pointer ;
295308
296- if (fail ) {
297- status = AE_ERROR ;
298- goto out_kfree ;
299- }
309+ if (acpi_osc_error_check (handle , & guid , context -> rev , & context -> cap , retbuf )) {
310+ status = AE_ERROR ;
311+ goto out_kfree ;
300312 }
301313
302314 context -> ret .length = out_obj -> buffer .length ;
303- context -> ret .pointer = kmemdup (out_obj -> buffer .pointer ,
304- context -> ret .length , GFP_KERNEL );
315+ context -> ret .pointer = kmemdup (retbuf , context -> ret .length , GFP_KERNEL );
305316 if (!context -> ret .pointer ) {
306317 status = AE_NO_MEMORY ;
307318 goto out_kfree ;
0 commit comments