/* * proc handler for /proc/sys/kernel/unknown_nmi_panic */ int proc_unknown_nmi_panic(ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, loff_t *ppos) { int old_state; old_state = unknown_nmi_panic; proc_dointvec(table, write, file, buffer, length, ppos); if (!!old_state == !!unknown_nmi_panic) return 0; if (unknown_nmi_panic) { if (nmi_watchdog == NMI_LOCAL_APIC) disable_lapic_nmi_watchdog(); else if (nmi_watchdog == NMI_IO_APIC) acpi_nmi_disable(); } else { if (nmi_watchdog == NMI_LOCAL_APIC) enable_lapic_nmi_watchdog(); else if (nmi_watchdog == NMI_IO_APIC) acpi_nmi_enable(); } return 0; }
void restart_nmi(void) { ignore_nmis--; acpi_nmi_enable(); }
static acpi_status acpi_ns_init_one_device(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { struct acpi_device_walk_info *walk_info = ACPI_CAST_PTR(struct acpi_device_walk_info, context); struct acpi_evaluate_info *info = walk_info->evaluate_info; u32 flags; acpi_status status; struct acpi_namespace_node *device_node; ACPI_FUNCTION_TRACE(ns_init_one_device); /* We are interested in Devices, Processors and thermal_zones only */ device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); if ((device_node->type != ACPI_TYPE_DEVICE) && (device_node->type != ACPI_TYPE_PROCESSOR) && (device_node->type != ACPI_TYPE_THERMAL)) { return_ACPI_STATUS(AE_OK); } /* * Because of an earlier namespace analysis, all subtrees that contain an * _INI method are tagged. * * If this device subtree does not contain any _INI methods, we * can exit now and stop traversing this entire subtree. */ if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) { return_ACPI_STATUS(AE_CTRL_DEPTH); } /* * Run _STA to determine if this device is present and functioning. We * must know this information for two important reasons (from ACPI spec): * * 1) We can only run _INI if the device is present. * 2) We must abort the device tree walk on this subtree if the device is * not present and is not functional (we will not examine the children) * * The _STA method is not required to be present under the device, we * assume the device is present if _STA does not exist. */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA)); status = acpi_ut_execute_STA(device_node, &flags); if (ACPI_FAILURE(status)) { /* Ignore error and move on to next device */ return_ACPI_STATUS(AE_OK); } /* * Flags == -1 means that _STA was not found. In this case, we assume that * the device is both present and functional. * * From the ACPI spec, description of _STA: * * "If a device object (including the processor object) does not have an * _STA object, then OSPM assumes that all of the above bits are set (in * other words, the device is present, ..., and functioning)" */ if (flags != ACPI_UINT32_MAX) { walk_info->num_STA++; } /* * Examine the PRESENT and FUNCTIONING status bits * * Note: ACPI spec does not seem to specify behavior for the present but * not functioning case, so we assume functioning if present. */ if (!(flags & ACPI_STA_DEVICE_PRESENT)) { /* Device is not present, we must examine the Functioning bit */ if (flags & ACPI_STA_DEVICE_FUNCTIONING) { /* * Device is not present but is "functioning". In this case, * we will not run _INI, but we continue to examine the children * of this device. * * From the ACPI spec, description of _STA: (Note - no mention * of whether to run _INI or not on the device in question) * * "_STA may return bit 0 clear (not present) with bit 3 set * (device is functional). This case is used to indicate a valid * device for which no device driver should be loaded (for example, * a bridge device.) Children of this device may be present and * valid. OSPM should continue enumeration below a device whose * _STA returns this bit combination" */ return_ACPI_STATUS(AE_OK); } else { /* * Device is not present and is not functioning. We must abort the * walk of this subtree immediately -- don't look at the children * of such a device. * * From the ACPI spec, description of _INI: * * "If the _STA method indicates that the device is not present, * OSPM will not run the _INI and will not examine the children * of the device for _INI methods" */ return_ACPI_STATUS(AE_CTRL_DEPTH); } } /* * The device is present or is assumed present if no _STA exists. * Run the _INI if it exists (not required to exist) * * Note: We know there is an _INI within this subtree, but it may not be * under this particular device, it may be lower in the branch. */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); info->prefix_node = device_node; info->pathname = METHOD_NAME__INI; info->parameters = NULL; info->flags = ACPI_IGNORE_RETURN_VALUE; /* * Some hardware relies on this being executed as atomically * as possible (without an NMI being received in the middle of * this) - so disable NMIs and initialize the device: */ acpi_nmi_disable(); status = acpi_ns_evaluate(info); acpi_nmi_enable(); if (ACPI_SUCCESS(status)) { walk_info->num_INI++; if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); } } #ifdef ACPI_DEBUG_OUTPUT else if (status != AE_NOT_FOUND) { /* Ignore error and move on to next device */ char *scope_name = acpi_ns_get_external_pathname(info->resolved_node); ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", scope_name)); ACPI_FREE(scope_name); } #endif /* Ignore errors from above */ status = AE_OK; /* * The _INI method has been run if present; call the Global Initialization * Handler for this device. */ if (acpi_gbl_init_handler) { status = acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI); } return_ACPI_STATUS(status); }