diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-07-23 23:13:09 +0200 | 
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-07-23 23:13:09 +0200 | 
| commit | 9c14cc44575ab7faae6bcb5821e6cad5f0d8238d (patch) | |
| tree | 7480b5871c89b03b4fdd8c639241d664cbafab4a | |
| parent | 9a3c4145af32125c5ee39c0272662b47307a8323 (diff) | |
| parent | c12f07d17c12193256a99e20c9a0f130fb8f7be8 (diff) | |
Merge branch 'acpica' into acpi-gpe
38 files changed, 3340 insertions, 404 deletions
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index 185334114d71..340d09518f8e 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c @@ -69,11 +69,11 @@ static u32 l1_percpu_entry;  #define ELOG_ENTRY_ADDR(phyaddr) \  	(phyaddr - elog_base + (u8 *)elog_addr) -static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank) +static struct acpi_hest_generic_status *extlog_elog_entry_check(int cpu, int bank)  {  	int idx;  	u64 data; -	struct acpi_generic_status *estatus; +	struct acpi_hest_generic_status *estatus;  	WARN_ON(cpu < 0);  	idx = ELOG_IDX(cpu, bank); @@ -82,7 +82,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)  		return NULL;  	data &= EXT_ELOG_ENTRY_MASK; -	estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data); +	estatus = (struct acpi_hest_generic_status *)ELOG_ENTRY_ADDR(data);  	/* if no valid data in elog entry, just return */  	if (estatus->block_status == 0) @@ -92,7 +92,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)  }  static void __print_extlog_rcd(const char *pfx, -			       struct acpi_generic_status *estatus, int cpu) +			       struct acpi_hest_generic_status *estatus, int cpu)  {  	static atomic_t seqno;  	unsigned int curr_seqno; @@ -111,7 +111,7 @@ static void __print_extlog_rcd(const char *pfx,  }  static int print_extlog_rcd(const char *pfx, -			    struct acpi_generic_status *estatus, int cpu) +			    struct acpi_hest_generic_status *estatus, int cpu)  {  	/* Not more than 2 messages every 5 seconds */  	static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); @@ -137,7 +137,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,  	struct mce *mce = (struct mce *)data;  	int	bank = mce->bank;  	int	cpu = mce->extcpu; -	struct acpi_generic_status *estatus; +	struct acpi_hest_generic_status *estatus;  	int rc;  	estatus = extlog_elog_entry_check(cpu, bank); @@ -148,7 +148,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,  	/* clear record status to enable BIOS to update it again */  	estatus->block_status = 0; -	rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu); +	rc = print_extlog_rcd(NULL, (struct acpi_hest_generic_status *)elog_buf, cpu);  	return NOTIFY_STOP;  } diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 8bb43f06e11f..6b9ec239d578 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -175,5 +175,5 @@ acpi-y +=		\  	utxferror.o	\  	utxfmutex.o -acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o +acpi-$(ACPI_FUTURE_USAGE) += utfileio.o utprint.o uttrack.o utcache.o diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index 8698ffba6f39..3d2c88289da9 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h @@ -79,10 +79,13 @@  /* Macros for usage messages */  #define ACPI_USAGE_HEADER(usage) \ -	printf ("Usage: %s\nOptions:\n", usage); +	acpi_os_printf ("Usage: %s\nOptions:\n", usage); + +#define ACPI_USAGE_TEXT(description) \ +	acpi_os_printf (description);  #define ACPI_OPTION(name, description) \ -	printf ("  %-18s%s\n", name, description); +	acpi_os_printf (" %-18s%s\n", name, description);  #define FILE_SUFFIX_DISASSEMBLY     "dsl"  #define ACPI_TABLE_FILE_SUFFIX      ".dat" @@ -102,7 +105,7 @@ extern char *acpi_gbl_optarg;  /*   * cmfsize - Common get file size function   */ -u32 cm_get_file_size(FILE * file); +u32 cm_get_file_size(ACPI_FILE file);  #ifndef ACPI_DUMP_APP  /* diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 68a91eb0fa48..1d026ff1683f 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -233,9 +233,6 @@ acpi_status acpi_db_load_acpi_table(char *filename);  acpi_status  acpi_db_get_table_from_file(char *filename, struct acpi_table_header **table); -acpi_status -acpi_db_read_table_from_file(char *filename, struct acpi_table_header **table); -  /*   * dbhistry - debugger HISTORY command   */ diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 115eedcade1e..ebf02cc10a43 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -297,7 +297,7 @@ ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_layer);   *   ****************************************************************************/ -ACPI_GLOBAL(u8, acpi_gbl_db_output_flags); +ACPI_INIT_GLOBAL(u8, acpi_gbl_db_output_flags, ACPI_DB_CONSOLE_OUTPUT);  #ifdef ACPI_DISASSEMBLER @@ -362,6 +362,12 @@ ACPI_GLOBAL(u32, acpi_gbl_num_objects);  #ifdef ACPI_APPLICATION  ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); +ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL); + +/* Print buffer */ + +ACPI_GLOBAL(acpi_spinlock, acpi_gbl_print_lock);	/* For print buffer */ +ACPI_GLOBAL(char, acpi_gbl_print_buffer[1024]);  #endif				/* ACPI_APPLICATION */ diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 1e256c5bda20..ed614f4b2182 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -95,7 +95,6 @@ extern const char *acpi_gbl_pt_decode[];  #ifdef ACPI_ASL_COMPILER  #include <stdio.h> -extern FILE *acpi_gbl_output_file;  #define ACPI_MSG_REDIRECT_BEGIN \  	FILE                            *output_file = acpi_gbl_output_file; \ @@ -211,6 +210,8 @@ void acpi_ut_subsystem_shutdown(void);  acpi_size acpi_ut_strlen(const char *string); +char *acpi_ut_strchr(const char *string, int ch); +  char *acpi_ut_strcpy(char *dst_string, const char *src_string);  char *acpi_ut_strncpy(char *dst_string, @@ -257,7 +258,7 @@ extern const u8 _acpi_ctype[];  #define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD))  #define ACPI_IS_UPPER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP))  #define ACPI_IS_LOWER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) -#define ACPI_IS_PRINT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU)) +#define ACPI_IS_PRINT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU))  #define ACPI_IS_ALPHA(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))  #endif				/* !ACPI_USE_SYSTEM_CLIBRARY */ @@ -352,6 +353,13 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id);  void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset); +#ifdef ACPI_APPLICATION +void +acpi_ut_dump_buffer_to_file(ACPI_FILE file, +			    u8 *buffer, +			    u32 count, u32 display, u32 base_offset); +#endif +  void acpi_ut_report_error(char *module_name, u32 line_number);  void acpi_ut_report_info(char *module_name, u32 line_number); @@ -394,6 +402,14 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,  			      u8 method_count, u8 *out_values);  /* + * utfileio - file operations + */ +#ifdef ACPI_APPLICATION +acpi_status +acpi_ut_read_table_from_file(char *filename, struct acpi_table_header **table); +#endif + +/*   * utids - device ID support   */  acpi_status @@ -743,4 +759,23 @@ const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg);  const struct ah_device_id *acpi_ah_match_hardware_id(char *hid); +/* + * utprint - printf/vprintf output functions + */ +const char *acpi_ut_scan_number(const char *string, u64 *number_ptr); + +const char *acpi_ut_print_number(char *string, u64 number); + +int +acpi_ut_vsnprintf(char *string, +		  acpi_size size, const char *format, va_list args); + +int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...); + +#ifdef ACPI_APPLICATION +int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args); + +int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...); +#endif +  #endif				/* _ACUTILS_H */ diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 48f70013b488..e4ba4dec86af 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -698,21 +698,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,  	}  	/* -	 * If edge-triggered, clear the GPE status bit now. Note that -	 * level-triggered events are cleared after the GPE is serviced. -	 */ -	if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == -	    ACPI_GPE_EDGE_TRIGGERED) { -		status = acpi_hw_clear_gpe(gpe_event_info); -		if (ACPI_FAILURE(status)) { -			ACPI_EXCEPTION((AE_INFO, status, -					"Unable to clear GPE %02X", -					gpe_number)); -			return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); -		} -	} - -	/*  	 * Always disable the GPE so that it does not keep firing before  	 * any asynchronous activity completes (either from the execution  	 * of a GPE method or an asynchronous GPE handler.) @@ -729,6 +714,23 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,  	}  	/* +	 * If edge-triggered, clear the GPE status bit now. Note that +	 * level-triggered events are cleared after the GPE is serviced. +	 */ +	if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == +	    ACPI_GPE_EDGE_TRIGGERED) { +		status = acpi_hw_clear_gpe(gpe_event_info); +		if (ACPI_FAILURE(status)) { +			ACPI_EXCEPTION((AE_INFO, status, +					"Unable to clear GPE %02X", +					gpe_number)); +			(void)acpi_hw_low_set_gpe(gpe_event_info, +						  ACPI_GPE_CONDITIONAL_ENABLE); +			return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); +		} +	} + +	/*  	 * Dispatch the GPE to either an installed handler or the control  	 * method associated with this GPE (_Lxx or _Exx). If a handler  	 * exists, we invoke it and do not attempt to run the method. diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index cb534faf5369..0cf159cc6e6d 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -126,11 +126,19 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)  	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); -	/* Ensure that we have a valid GPE number */ - +	/* +	 * Ensure that we have a valid GPE number and that there is some way +	 * of handling the GPE (handler or a GPE method). In other words, we +	 * won't allow a valid GPE to be enabled if there is no way to handle it. +	 */  	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);  	if (gpe_event_info) { -		status = acpi_ev_add_gpe_reference(gpe_event_info); +		if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != +		    ACPI_GPE_DISPATCH_NONE) { +			status = acpi_ev_add_gpe_reference(gpe_event_info); +		} else { +			status = AE_NO_HANDLER; +		}  	}  	acpi_os_release_lock(acpi_gbl_gpe_lock, flags); @@ -179,6 +187,53 @@ ACPI_EXPORT_SYMBOL(acpi_disable_gpe)  /*******************************************************************************   * + * FUNCTION:    acpi_mark_gpe_for_wake + * + * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1 + *              gpe_number          - GPE level within the GPE block + * + * RETURN:      Status + * + * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply + *              sets the ACPI_GPE_CAN_WAKE flag. + * + * Some potential callers of acpi_setup_gpe_for_wake may know in advance that + * there won't be any notify handlers installed for device wake notifications + * from the given GPE (one example is a button GPE in Linux). For these cases, + * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake. + * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to + * setup implicit wake notification for it (since there's no handler method). + * + ******************************************************************************/ +acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number) +{ +	struct acpi_gpe_event_info *gpe_event_info; +	acpi_status status = AE_BAD_PARAMETER; +	acpi_cpu_flags flags; + +	ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake); + +	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + +	/* Ensure that we have a valid GPE number */ + +	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); +	if (gpe_event_info) { + +		/* Mark the GPE as a possible wake event */ + +		gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; +		status = AE_OK; +	} + +	acpi_os_release_lock(acpi_gbl_gpe_lock, flags); +	return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake) + +/******************************************************************************* + *   * FUNCTION:    acpi_setup_gpe_for_wake   *   * PARAMETERS:  wake_device         - Device associated with the GPE (via _PRW) diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 12878e1982f7..1ff42c07b42b 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -56,7 +56,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length);  /*******************************************************************************   * - * FUNCTION:    acpi_get_serial_access_bytes + * FUNCTION:    acpi_ex_get_serial_access_length   *   * PARAMETERS:  accessor_type   - The type of the protocol indicated by region   *                                field access attributes @@ -103,7 +103,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length)  	case AML_FIELD_ATTRIB_BLOCK_CALL:  	default: -		length = ACPI_GSBUS_BUFFER_SIZE; +		length = ACPI_GSBUS_BUFFER_SIZE - 2;  		break;  	} diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index e0fd9b4978cd..a4c34d2c556b 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -278,8 +278,9 @@ acpi_status acpi_hw_clear_acpi_status(void)  	acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); -	if (ACPI_FAILURE(status)) +	if (ACPI_FAILURE(status)) {  		goto exit; +	}  	/* Clear the GPE Bits in all GPE registers in all GPE blocks */ diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index fe54a8c73b8c..a42ee9d6970d 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -237,6 +237,16 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)  		    (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) {  			node->object = node->object->common.next_object;  		} + +		/* +		 * Detach the object from any data objects (which are still held by +		 * the namespace node) +		 */ +		if (obj_desc->common.next_object && +		    ((obj_desc->common.next_object)->common.type == +		     ACPI_TYPE_LOCAL_DATA)) { +			obj_desc->common.next_object = NULL; +		}  	}  	/* Reset the node type to untyped */ diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c index 3c1699740653..038ea887f562 100644 --- a/drivers/acpi/acpica/utbuffer.c +++ b/drivers/acpi/acpica/utbuffer.c @@ -199,3 +199,131 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)  	acpi_ut_dump_buffer(buffer, count, display, 0);  } + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION:    acpi_ut_dump_buffer_to_file + * + * PARAMETERS:  file                - File descriptor + *              buffer              - Buffer to dump + *              count               - Amount to dump, in bytes + *              display             - BYTE, WORD, DWORD, or QWORD display: + *                                      DB_BYTE_DISPLAY + *                                      DB_WORD_DISPLAY + *                                      DB_DWORD_DISPLAY + *                                      DB_QWORD_DISPLAY + *              base_offset         - Beginning buffer offset (display only) + * + * RETURN:      None + * + * DESCRIPTION: Generic dump buffer in both hex and ascii to a file. + * + ******************************************************************************/ + +void +acpi_ut_dump_buffer_to_file(ACPI_FILE file, +			    u8 *buffer, u32 count, u32 display, u32 base_offset) +{ +	u32 i = 0; +	u32 j; +	u32 temp32; +	u8 buf_char; + +	if (!buffer) { +		acpi_ut_file_printf(file, +				    "Null Buffer Pointer in DumpBuffer!\n"); +		return; +	} + +	if ((count < 4) || (count & 0x01)) { +		display = DB_BYTE_DISPLAY; +	} + +	/* Nasty little dump buffer routine! */ + +	while (i < count) { + +		/* Print current offset */ + +		acpi_ut_file_printf(file, "%6.4X: ", (base_offset + i)); + +		/* Print 16 hex chars */ + +		for (j = 0; j < 16;) { +			if (i + j >= count) { + +				/* Dump fill spaces */ + +				acpi_ut_file_printf(file, "%*s", +						    ((display * 2) + 1), " "); +				j += display; +				continue; +			} + +			switch (display) { +			case DB_BYTE_DISPLAY: +			default:	/* Default is BYTE display */ + +				acpi_ut_file_printf(file, "%02X ", +						    buffer[(acpi_size) i + j]); +				break; + +			case DB_WORD_DISPLAY: + +				ACPI_MOVE_16_TO_32(&temp32, +						   &buffer[(acpi_size) i + j]); +				acpi_ut_file_printf(file, "%04X ", temp32); +				break; + +			case DB_DWORD_DISPLAY: + +				ACPI_MOVE_32_TO_32(&temp32, +						   &buffer[(acpi_size) i + j]); +				acpi_ut_file_printf(file, "%08X ", temp32); +				break; + +			case DB_QWORD_DISPLAY: + +				ACPI_MOVE_32_TO_32(&temp32, +						   &buffer[(acpi_size) i + j]); +				acpi_ut_file_printf(file, "%08X", temp32); + +				ACPI_MOVE_32_TO_32(&temp32, +						   &buffer[(acpi_size) i + j + +							   4]); +				acpi_ut_file_printf(file, "%08X ", temp32); +				break; +			} + +			j += display; +		} + +		/* +		 * Print the ASCII equivalent characters but watch out for the bad +		 * unprintable ones (printable chars are 0x20 through 0x7E) +		 */ +		acpi_ut_file_printf(file, " "); +		for (j = 0; j < 16; j++) { +			if (i + j >= count) { +				acpi_ut_file_printf(file, "\n"); +				return; +			} + +			buf_char = buffer[(acpi_size) i + j]; +			if (ACPI_IS_PRINT(buf_char)) { +				acpi_ut_file_printf(file, "%c", buf_char); +			} else { +				acpi_ut_file_printf(file, "."); +			} +		} + +		/* Done with that line. */ + +		acpi_ut_file_printf(file, "\n"); +		i += 16; +	} + +	return; +} +#endif diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 270c16464dd9..ff601c0f7c7a 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -1001,5 +1001,11 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,  		status = acpi_ut_copy_simple_object(source_desc, *dest_desc);  	} +	/* Delete the allocated object if copy failed */ + +	if (ACPI_FAILURE(status)) { +		acpi_ut_remove_reference(*dest_desc); +	} +  	return_ACPI_STATUS(status);  } diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 21a20ac5b1e1..e516254c63b2 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -561,3 +561,29 @@ acpi_ut_ptr_exit(u32 line_number,  }  #endif + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION:    acpi_log_error + * + * PARAMETERS:  format              - Printf format field + *              ...                 - Optional printf arguments + * + * RETURN:      None + * + * DESCRIPTION: Print error message to the console, used by applications. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...) +{ +	va_list args; + +	va_start(args, format); +	(void)acpi_ut_file_vprintf(ACPI_FILE_ERR, format, args); +	va_end(args); +} + +ACPI_EXPORT_SYMBOL(acpi_log_error) +#endif diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c new file mode 100644 index 000000000000..bdf9914733cb --- /dev/null +++ b/drivers/acpi/acpica/utfileio.c @@ -0,0 +1,332 @@ +/******************************************************************************* + * + * Module Name: utfileio - simple file I/O routines + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions, and the following disclaimer, + *    without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + *    substantially similar to the "NO WARRANTY" disclaimer below + *    ("Disclaimer") and any redistribution must be conditioned upon + *    including a substantially similar Disclaimer requirement for further + *    binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + *    of any contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <acpi/acpi.h> +#include "accommon.h" +#include "actables.h" +#include "acapps.h" + +#ifdef ACPI_ASL_COMPILER +#include "aslcompiler.h" +#endif + +#define _COMPONENT          ACPI_CA_DEBUGGER +ACPI_MODULE_NAME("utfileio") + +#ifdef ACPI_APPLICATION +/* Local prototypes */ +static acpi_status +acpi_ut_check_text_mode_corruption(u8 *table, +				   u32 table_length, u32 file_length); + +static acpi_status +acpi_ut_read_table(FILE * fp, +		   struct acpi_table_header **table, u32 *table_length); + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_check_text_mode_corruption + * + * PARAMETERS:  table           - Table buffer + *              table_length    - Length of table from the table header + *              file_length     - Length of the file that contains the table + * + * RETURN:      Status + * + * DESCRIPTION: Check table for text mode file corruption where all linefeed + *              characters (LF) have been replaced by carriage return linefeed + *              pairs (CR/LF). + * + ******************************************************************************/ + +static acpi_status +acpi_ut_check_text_mode_corruption(u8 *table, u32 table_length, u32 file_length) +{ +	u32 i; +	u32 pairs = 0; + +	if (table_length != file_length) { +		ACPI_WARNING((AE_INFO, +			      "File length (0x%X) is not the same as the table length (0x%X)", +			      file_length, table_length)); +	} + +	/* Scan entire table to determine if each LF has been prefixed with a CR */ + +	for (i = 1; i < file_length; i++) { +		if (table[i] == 0x0A) { +			if (table[i - 1] != 0x0D) { + +				/* The LF does not have a preceding CR, table not corrupted */ + +				return (AE_OK); +			} else { +				/* Found a CR/LF pair */ + +				pairs++; +			} +			i++; +		} +	} + +	if (!pairs) { +		return (AE_OK); +	} + +	/* +	 * Entire table scanned, each CR is part of a CR/LF pair -- +	 * meaning that the table was treated as a text file somewhere. +	 * +	 * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the +	 * original table are left untouched by the text conversion process -- +	 * meaning that we cannot simply replace CR/LF pairs with LFs. +	 */ +	acpi_os_printf("Table has been corrupted by text mode conversion\n"); +	acpi_os_printf("All LFs (%u) were changed to CR/LF pairs\n", pairs); +	acpi_os_printf("Table cannot be repaired!\n"); +	return (AE_BAD_VALUE); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_read_table + * + * PARAMETERS:  fp              - File that contains table + *              table           - Return value, buffer with table + *              table_length    - Return value, length of table + * + * RETURN:      Status + * + * DESCRIPTION: Load the DSDT from the file pointer + * + ******************************************************************************/ + +static acpi_status +acpi_ut_read_table(FILE * fp, +		   struct acpi_table_header **table, u32 *table_length) +{ +	struct acpi_table_header table_header; +	u32 actual; +	acpi_status status; +	u32 file_size; +	u8 standard_header = TRUE; +	s32 count; + +	/* Get the file size */ + +	file_size = cm_get_file_size(fp); +	if (file_size == ACPI_UINT32_MAX) { +		return (AE_ERROR); +	} + +	if (file_size < 4) { +		return (AE_BAD_HEADER); +	} + +	/* Read the signature */ + +	fseek(fp, 0, SEEK_SET); + +	count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp); +	if (count != sizeof(struct acpi_table_header)) { +		acpi_os_printf("Could not read the table header\n"); +		return (AE_BAD_HEADER); +	} + +	/* The RSDP table does not have standard ACPI header */ + +	if (ACPI_VALIDATE_RSDP_SIG(table_header.signature)) { +		*table_length = file_size; +		standard_header = FALSE; +	} else { + +#if 0 +		/* Validate the table header/length */ + +		status = acpi_tb_validate_table_header(&table_header); +		if (ACPI_FAILURE(status)) { +			acpi_os_printf("Table header is invalid!\n"); +			return (status); +		} +#endif + +		/* File size must be at least as long as the Header-specified length */ + +		if (table_header.length > file_size) { +			acpi_os_printf +			    ("TableHeader length [0x%X] greater than the input file size [0x%X]\n", +			     table_header.length, file_size); + +#ifdef ACPI_ASL_COMPILER +			status = fl_check_for_ascii(fp, NULL, FALSE); +			if (ACPI_SUCCESS(status)) { +				acpi_os_printf +				    ("File appears to be ASCII only, must be binary\n", +				     table_header.length, file_size); +			} +#endif +			return (AE_BAD_HEADER); +		} +#ifdef ACPI_OBSOLETE_CODE +		/* We only support a limited number of table types */ + +		if (!ACPI_COMPARE_NAME +		    ((char *)table_header.signature, ACPI_SIG_DSDT) +		    && !ACPI_COMPARE_NAME((char *)table_header.signature, +					  ACPI_SIG_PSDT) +		    && !ACPI_COMPARE_NAME((char *)table_header.signature, +					  ACPI_SIG_SSDT)) { +			acpi_os_printf +			    ("Table signature [%4.4s] is invalid or not supported\n", +			     (char *)table_header.signature); +			ACPI_DUMP_BUFFER(&table_header, +					 sizeof(struct acpi_table_header)); +			return (AE_ERROR); +		} +#endif + +		*table_length = table_header.length; +	} + +	/* Allocate a buffer for the table */ + +	*table = acpi_os_allocate((size_t) file_size); +	if (!*table) { +		acpi_os_printf +		    ("Could not allocate memory for ACPI table %4.4s (size=0x%X)\n", +		     table_header.signature, *table_length); +		return (AE_NO_MEMORY); +	} + +	/* Get the rest of the table */ + +	fseek(fp, 0, SEEK_SET); +	actual = fread(*table, 1, (size_t) file_size, fp); +	if (actual == file_size) { +		if (standard_header) { + +			/* Now validate the checksum */ + +			status = acpi_tb_verify_checksum((void *)*table, +							 ACPI_CAST_PTR(struct +								       acpi_table_header, +								       *table)-> +							 length); + +			if (status == AE_BAD_CHECKSUM) { +				status = +				    acpi_ut_check_text_mode_corruption((u8 *) +								       *table, +								       file_size, +								       (*table)-> +								       length); +				return (status); +			} +		} +		return (AE_OK); +	} + +	if (actual > 0) { +		acpi_os_printf("Warning - reading table, asked for %X got %X\n", +			       file_size, actual); +		return (AE_OK); +	} + +	acpi_os_printf("Error - could not read the table file\n"); +	acpi_os_free(*table); +	*table = NULL; +	*table_length = 0; +	return (AE_ERROR); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_read_table_from_file + * + * PARAMETERS:  filename         - File where table is located + *              table            - Where a pointer to the table is returned + * + * RETURN:      Status + * + * DESCRIPTION: Get an ACPI table from a file + * + ******************************************************************************/ + +acpi_status +acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table) +{ +	FILE *file; +	u32 file_size; +	u32 table_length; +	acpi_status status = AE_ERROR; + +	/* Open the file, get current size */ + +	file = fopen(filename, "rb"); +	if (!file) { +		perror("Could not open input file"); +		return (status); +	} + +	file_size = cm_get_file_size(file); +	if (file_size == ACPI_UINT32_MAX) { +		goto exit; +	} + +	/* Get the entire file */ + +	fprintf(stderr, +		"Loading Acpi table from file %10s - Length %.8u (%06X)\n", +		filename, file_size, file_size); + +	status = acpi_ut_read_table(file, table, &table_length); +	if (ACPI_FAILURE(status)) { +		acpi_os_printf("Could not get table from the file\n"); +	} + +exit: +	fclose(file); +	return (status); +} + +#endif diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index d69be3cb3fae..77ceac715f28 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -214,152 +214,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =  };  #endif				/* !ACPI_REDUCED_HARDWARE */ -/******************************************************************************* - * - * FUNCTION:    acpi_ut_init_globals - * - * PARAMETERS:  None - * - * RETURN:      Status - * - * DESCRIPTION: Initialize ACPICA globals. All globals that require specific - *              initialization should be initialized here. This allows for - *              a warm restart. - * - ******************************************************************************/ - -acpi_status acpi_ut_init_globals(void) -{ -	acpi_status status; -	u32 i; - -	ACPI_FUNCTION_TRACE(ut_init_globals); - -	/* Create all memory caches */ - -	status = acpi_ut_create_caches(); -	if (ACPI_FAILURE(status)) { -		return_ACPI_STATUS(status); -	} - -	/* Address Range lists */ - -	for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) { -		acpi_gbl_address_range_list[i] = NULL; -	} - -	/* Mutex locked flags */ - -	for (i = 0; i < ACPI_NUM_MUTEX; i++) { -		acpi_gbl_mutex_info[i].mutex = NULL; -		acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED; -		acpi_gbl_mutex_info[i].use_count = 0; -	} - -	for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) { -		acpi_gbl_owner_id_mask[i] = 0; -	} - -	/* Last owner_ID is never valid */ - -	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; - -	/* Event counters */ - -	acpi_method_count = 0; -	acpi_sci_count = 0; -	acpi_gpe_count = 0; - -	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { -		acpi_fixed_event_count[i] = 0; -	} - -#if (!ACPI_REDUCED_HARDWARE) - -	/* GPE/SCI support */ - -	acpi_gbl_all_gpes_initialized = FALSE; -	acpi_gbl_gpe_xrupt_list_head = NULL; -	acpi_gbl_gpe_fadt_blocks[0] = NULL; -	acpi_gbl_gpe_fadt_blocks[1] = NULL; -	acpi_current_gpe_count = 0; - -	acpi_gbl_global_event_handler = NULL; -	acpi_gbl_sci_handler_list = NULL; - -#endif				/* !ACPI_REDUCED_HARDWARE */ - -	/* Global handlers */ - -	acpi_gbl_global_notify[0].handler = NULL; -	acpi_gbl_global_notify[1].handler = NULL; -	acpi_gbl_exception_handler = NULL; -	acpi_gbl_init_handler = NULL; -	acpi_gbl_table_handler = NULL; -	acpi_gbl_interface_handler = NULL; - -	/* Global Lock support */ - -	acpi_gbl_global_lock_semaphore = NULL; -	acpi_gbl_global_lock_mutex = NULL; -	acpi_gbl_global_lock_acquired = FALSE; -	acpi_gbl_global_lock_handle = 0; -	acpi_gbl_global_lock_present = FALSE; - -	/* Miscellaneous variables */ - -	acpi_gbl_DSDT = NULL; -	acpi_gbl_cm_single_step = FALSE; -	acpi_gbl_shutdown = FALSE; -	acpi_gbl_ns_lookup_count = 0; -	acpi_gbl_ps_find_count = 0; -	acpi_gbl_acpi_hardware_present = TRUE; -	acpi_gbl_last_owner_id_index = 0; -	acpi_gbl_next_owner_id_offset = 0; -	acpi_gbl_trace_dbg_level = 0; -	acpi_gbl_trace_dbg_layer = 0; -	acpi_gbl_debugger_configuration = DEBUGGER_THREADING; -	acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; -	acpi_gbl_osi_mutex = NULL; -	acpi_gbl_reg_methods_executed = FALSE; - -	/* Hardware oriented */ - -	acpi_gbl_events_initialized = FALSE; -	acpi_gbl_system_awake_and_running = TRUE; - -	/* Namespace */ - -	acpi_gbl_module_code_list = NULL; -	acpi_gbl_root_node = NULL; -	acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; -	acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; -	acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; -	acpi_gbl_root_node_struct.parent = NULL; -	acpi_gbl_root_node_struct.child = NULL; -	acpi_gbl_root_node_struct.peer = NULL; -	acpi_gbl_root_node_struct.object = NULL; - -#ifdef ACPI_DISASSEMBLER -	acpi_gbl_external_list = NULL; -	acpi_gbl_num_external_methods = 0; -	acpi_gbl_resolved_external_methods = 0; -#endif - -#ifdef ACPI_DEBUG_OUTPUT -	acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); -#endif - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS -	acpi_gbl_display_final_mem_stats = FALSE; -	acpi_gbl_disable_mem_tracking = FALSE; -#endif - -	ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE); - -	return_ACPI_STATUS(AE_OK); -} -  /* Public globals */  ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 5f56fc49021e..77120ec9ea86 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -102,6 +102,151 @@ static void acpi_ut_free_gpe_lists(void)  }  #endif				/* !ACPI_REDUCED_HARDWARE */ +/******************************************************************************* + * + * FUNCTION:    acpi_ut_init_globals + * + * PARAMETERS:  None + * + * RETURN:      Status + * + * DESCRIPTION: Initialize ACPICA globals. All globals that require specific + *              initialization should be initialized here. This allows for + *              a warm restart. + * + ******************************************************************************/ + +acpi_status acpi_ut_init_globals(void) +{ +	acpi_status status; +	u32 i; + +	ACPI_FUNCTION_TRACE(ut_init_globals); + +	/* Create all memory caches */ + +	status = acpi_ut_create_caches(); +	if (ACPI_FAILURE(status)) { +		return_ACPI_STATUS(status); +	} + +	/* Address Range lists */ + +	for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) { +		acpi_gbl_address_range_list[i] = NULL; +	} + +	/* Mutex locked flags */ + +	for (i = 0; i < ACPI_NUM_MUTEX; i++) { +		acpi_gbl_mutex_info[i].mutex = NULL; +		acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED; +		acpi_gbl_mutex_info[i].use_count = 0; +	} + +	for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) { +		acpi_gbl_owner_id_mask[i] = 0; +	} + +	/* Last owner_ID is never valid */ + +	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; + +	/* Event counters */ + +	acpi_method_count = 0; +	acpi_sci_count = 0; +	acpi_gpe_count = 0; + +	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { +		acpi_fixed_event_count[i] = 0; +	} + +#if (!ACPI_REDUCED_HARDWARE) + +	/* GPE/SCI support */ + +	acpi_gbl_all_gpes_initialized = FALSE; +	acpi_gbl_gpe_xrupt_list_head = NULL; +	acpi_gbl_gpe_fadt_blocks[0] = NULL; +	acpi_gbl_gpe_fadt_blocks[1] = NULL; +	acpi_current_gpe_count = 0; + +	acpi_gbl_global_event_handler = NULL; +	acpi_gbl_sci_handler_list = NULL; + +#endif				/* !ACPI_REDUCED_HARDWARE */ + +	/* Global handlers */ + +	acpi_gbl_global_notify[0].handler = NULL; +	acpi_gbl_global_notify[1].handler = NULL; +	acpi_gbl_exception_handler = NULL; +	acpi_gbl_init_handler = NULL; +	acpi_gbl_table_handler = NULL; +	acpi_gbl_interface_handler = NULL; + +	/* Global Lock support */ + +	acpi_gbl_global_lock_semaphore = NULL; +	acpi_gbl_global_lock_mutex = NULL; +	acpi_gbl_global_lock_acquired = FALSE; +	acpi_gbl_global_lock_handle = 0; +	acpi_gbl_global_lock_present = FALSE; + +	/* Miscellaneous variables */ + +	acpi_gbl_DSDT = NULL; +	acpi_gbl_cm_single_step = FALSE; +	acpi_gbl_shutdown = FALSE; +	acpi_gbl_ns_lookup_count = 0; +	acpi_gbl_ps_find_count = 0; +	acpi_gbl_acpi_hardware_present = TRUE; +	acpi_gbl_last_owner_id_index = 0; +	acpi_gbl_next_owner_id_offset = 0; +	acpi_gbl_trace_dbg_level = 0; +	acpi_gbl_trace_dbg_layer = 0; +	acpi_gbl_debugger_configuration = DEBUGGER_THREADING; +	acpi_gbl_osi_mutex = NULL; +	acpi_gbl_reg_methods_executed = FALSE; + +	/* Hardware oriented */ + +	acpi_gbl_events_initialized = FALSE; +	acpi_gbl_system_awake_and_running = TRUE; + +	/* Namespace */ + +	acpi_gbl_module_code_list = NULL; +	acpi_gbl_root_node = NULL; +	acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; +	acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; +	acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; +	acpi_gbl_root_node_struct.parent = NULL; +	acpi_gbl_root_node_struct.child = NULL; +	acpi_gbl_root_node_struct.peer = NULL; +	acpi_gbl_root_node_struct.object = NULL; + +#ifdef ACPI_DISASSEMBLER +	acpi_gbl_external_list = NULL; +	acpi_gbl_num_external_methods = 0; +	acpi_gbl_resolved_external_methods = 0; +#endif + +#ifdef ACPI_DEBUG_OUTPUT +	acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); +#endif + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS +	acpi_gbl_display_final_mem_stats = FALSE; +	acpi_gbl_disable_mem_tracking = FALSE; +#endif + +	ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE); + +	return_ACPI_STATUS(AE_OK); +} +  /******************************************************************************   *   * FUNCTION:    acpi_ut_terminate diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c new file mode 100644 index 000000000000..10311648f701 --- /dev/null +++ b/drivers/acpi/acpica/utprint.c @@ -0,0 +1,661 @@ +/****************************************************************************** + * + * Module Name: utprint - Formatted printing routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions, and the following disclaimer, + *    without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + *    substantially similar to the "NO WARRANTY" disclaimer below + *    ("Disclaimer") and any redistribution must be conditioned upon + *    including a substantially similar Disclaimer requirement for further + *    binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + *    of any contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <acpi/acpi.h> +#include "accommon.h" + +#define _COMPONENT          ACPI_UTILITIES +ACPI_MODULE_NAME("utprint") + +#define ACPI_FORMAT_SIGN            0x01 +#define ACPI_FORMAT_SIGN_PLUS       0x02 +#define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04 +#define ACPI_FORMAT_ZERO            0x08 +#define ACPI_FORMAT_LEFT            0x10 +#define ACPI_FORMAT_UPPER           0x20 +#define ACPI_FORMAT_PREFIX          0x40 +/* Local prototypes */ +static acpi_size +acpi_ut_bound_string_length(const char *string, acpi_size count); + +static char *acpi_ut_bound_string_output(char *string, const char *end, char c); + +static char *acpi_ut_format_number(char *string, +				   char *end, +				   u64 number, +				   u8 base, s32 width, s32 precision, u8 type); + +static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper); + +/* Module globals */ + +static const char acpi_gbl_lower_hex_digits[] = "0123456789abcdef"; +static const char acpi_gbl_upper_hex_digits[] = "0123456789ABCDEF"; + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_bound_string_length + * + * PARAMETERS:  string              - String with boundary + *              count               - Boundary of the string + * + * RETURN:      Length of the string. Less than or equal to Count. + * + * DESCRIPTION: Calculate the length of a string with boundary. + * + ******************************************************************************/ + +static acpi_size +acpi_ut_bound_string_length(const char *string, acpi_size count) +{ +	u32 length = 0; + +	while (*string && count) { +		length++; +		string++; +		count--; +	} + +	return (length); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_bound_string_output + * + * PARAMETERS:  string              - String with boundary + *              end                 - Boundary of the string + *              c                   - Character to be output to the string + * + * RETURN:      Updated position for next valid character + * + * DESCRIPTION: Output a character into a string with boundary check. + * + ******************************************************************************/ + +static char *acpi_ut_bound_string_output(char *string, const char *end, char c) +{ + +	if (string < end) { +		*string = c; +	} + +	++string; +	return (string); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_put_number + * + * PARAMETERS:  string              - Buffer to hold reverse-ordered string + *              number              - Integer to be converted + *              base                - Base of the integer + *              upper               - Whether or not using upper cased digits + * + * RETURN:      Updated position for next valid character + * + * DESCRIPTION: Convert an integer into a string, note that, the string holds a + *              reversed ordered number without the trailing zero. + * + ******************************************************************************/ + +static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper) +{ +	const char *digits; +	u64 digit_index; +	char *pos; + +	pos = string; +	digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits; + +	if (number == 0) { +		*(pos++) = '0'; +	} else { +		while (number) { +			(void)acpi_ut_divide(number, base, &number, +					     &digit_index); +			*(pos++) = digits[digit_index]; +		} +	} + +	/* *(Pos++) = '0'; */ +	return (pos); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_scan_number + * + * PARAMETERS:  string              - String buffer + *              number_ptr          - Where the number is returned + * + * RETURN:      Updated position for next valid character + * + * DESCRIPTION: Scan a string for a decimal integer. + * + ******************************************************************************/ + +const char *acpi_ut_scan_number(const char *string, u64 *number_ptr) +{ +	u64 number = 0; + +	while (ACPI_IS_DIGIT(*string)) { +		number *= 10; +		number += *(string++) - '0'; +	} + +	*number_ptr = number; +	return (string); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_print_number + * + * PARAMETERS:  string              - String buffer + *              number              - The number to be converted + * + * RETURN:      Updated position for next valid character + * + * DESCRIPTION: Print a decimal integer into a string. + * + ******************************************************************************/ + +const char *acpi_ut_print_number(char *string, u64 number) +{ +	char ascii_string[20]; +	const char *pos1; +	char *pos2; + +	pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE); +	pos2 = string; + +	while (pos1 != ascii_string) { +		*(pos2++) = *(--pos1); +	} + +	*pos2 = 0; +	return (string); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_format_number + * + * PARAMETERS:  string              - String buffer with boundary + *              end                 - Boundary of the string + *              number              - The number to be converted + *              base                - Base of the integer + *              width               - Field width + *              precision           - Precision of the integer + *              type                - Special printing flags + * + * RETURN:      Updated position for next valid character + * + * DESCRIPTION: Print an integer into a string with any base and any precision. + * + ******************************************************************************/ + +static char *acpi_ut_format_number(char *string, +				   char *end, +				   u64 number, +				   u8 base, s32 width, s32 precision, u8 type) +{ +	char sign; +	char zero; +	u8 need_prefix; +	u8 upper; +	s32 i; +	char reversed_string[66]; + +	/* Parameter validation */ + +	if (base < 2 || base > 16) { +		return (NULL); +	} + +	if (type & ACPI_FORMAT_LEFT) { +		type &= ~ACPI_FORMAT_ZERO; +	} + +	need_prefix = ((type & ACPI_FORMAT_PREFIX) +		       && base != 10) ? TRUE : FALSE; +	upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE; +	zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' '; + +	/* Calculate size according to sign and prefix */ + +	sign = '\0'; +	if (type & ACPI_FORMAT_SIGN) { +		if ((s64) number < 0) { +			sign = '-'; +			number = -(s64) number; +			width--; +		} else if (type & ACPI_FORMAT_SIGN_PLUS) { +			sign = '+'; +			width--; +		} else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) { +			sign = ' '; +			width--; +		} +	} +	if (need_prefix) { +		width--; +		if (base == 16) { +			width--; +		} +	} + +	/* Generate full string in reverse order */ + +	i = ACPI_PTR_DIFF(acpi_ut_put_number +			  (reversed_string, number, base, upper), +			  reversed_string); + +	/* Printing 100 using %2d gives "100", not "00" */ + +	if (i > precision) { +		precision = i; +	} + +	width -= precision; + +	/* Output the string */ + +	if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) { +		while (--width >= 0) { +			string = acpi_ut_bound_string_output(string, end, ' '); +		} +	} +	if (sign) { +		string = acpi_ut_bound_string_output(string, end, sign); +	} +	if (need_prefix) { +		string = acpi_ut_bound_string_output(string, end, '0'); +		if (base == 16) { +			string = acpi_ut_bound_string_output(string, end, +							     upper ? 'X' : 'x'); +		} +	} +	if (!(type & ACPI_FORMAT_LEFT)) { +		while (--width >= 0) { +			string = acpi_ut_bound_string_output(string, end, zero); +		} +	} + +	while (i <= --precision) { +		string = acpi_ut_bound_string_output(string, end, '0'); +	} +	while (--i >= 0) { +		string = acpi_ut_bound_string_output(string, end, +						     reversed_string[i]); +	} +	while (--width >= 0) { +		string = acpi_ut_bound_string_output(string, end, ' '); +	} + +	return (string); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_vsnprintf + * + * PARAMETERS:  string              - String with boundary + *              size                - Boundary of the string + *              format              - Standard printf format + *              args                - Argument list + * + * RETURN:      Number of bytes actually written. + * + * DESCRIPTION: Formatted output to a string using argument list pointer. + * + ******************************************************************************/ + +int +acpi_ut_vsnprintf(char *string, +		  acpi_size size, const char *format, va_list args) +{ +	u8 base = 10; +	u8 type = 0; +	s32 width = -1; +	s32 precision = -1; +	char qualifier = 0; +	u64 number; +	char *pos; +	char *end; +	char c; +	const char *s; +	const void *p; +	s32 length; +	int i; + +	pos = string; +	end = string + size; + +	for (; *format; ++format) { +		if (*format != '%') { +			pos = acpi_ut_bound_string_output(pos, end, *format); +			continue; +		} + +		/* Process sign */ + +		do { +			++format; +			if (*format == '#') { +				type |= ACPI_FORMAT_PREFIX; +			} else if (*format == '0') { +				type |= ACPI_FORMAT_ZERO; +			} else if (*format == '+') { +				type |= ACPI_FORMAT_SIGN_PLUS; +			} else if (*format == ' ') { +				type |= ACPI_FORMAT_SIGN_PLUS_SPACE; +			} else if (*format == '-') { +				type |= ACPI_FORMAT_LEFT; +			} else { +				break; +			} +		} while (1); + +		/* Process width */ + +		if (ACPI_IS_DIGIT(*format)) { +			format = acpi_ut_scan_number(format, &number); +			width = (s32) number; +		} else if (*format == '*') { +			++format; +			width = va_arg(args, int); +			if (width < 0) { +				width = -width; +				type |= ACPI_FORMAT_LEFT; +			} +		} + +		/* Process precision */ + +		if (*format == '.') { +			++format; +			if (ACPI_IS_DIGIT(*format)) { +				format = acpi_ut_scan_number(format, &number); +				precision = (s32) number; +			} else if (*format == '*') { +				++format; +				precision = va_arg(args, int); +			} +			if (precision < 0) { +				precision = 0; +			} +		} + +		/* Process qualifier */ + +		if (*format == 'h' || *format == 'l' || *format == 'L') { +			qualifier = *format; +			++format; + +			if (qualifier == 'l' && *format == 'l') { +				qualifier = 'L'; +				++format; +			} +		} + +		switch (*format) { +		case '%': + +			pos = acpi_ut_bound_string_output(pos, end, '%'); +			continue; + +		case 'c': + +			if (!(type & ACPI_FORMAT_LEFT)) { +				while (--width > 0) { +					pos = +					    acpi_ut_bound_string_output(pos, +									end, +									' '); +				} +			} + +			c = (char)va_arg(args, int); +			pos = acpi_ut_bound_string_output(pos, end, c); + +			while (--width > 0) { +				pos = +				    acpi_ut_bound_string_output(pos, end, ' '); +			} +			continue; + +		case 's': + +			s = va_arg(args, char *); +			if (!s) { +				s = "<NULL>"; +			} +			length = acpi_ut_bound_string_length(s, precision); +			if (!(type & ACPI_FORMAT_LEFT)) { +				while (length < width--) { +					pos = +					    acpi_ut_bound_string_output(pos, +									end, +									' '); +				} +			} +			for (i = 0; i < length; ++i) { +				pos = acpi_ut_bound_string_output(pos, end, *s); +				++s; +			} +			while (length < width--) { +				pos = +				    acpi_ut_bound_string_output(pos, end, ' '); +			} +			continue; + +		case 'o': + +			base = 8; +			break; + +		case 'X': + +			type |= ACPI_FORMAT_UPPER; + +		case 'x': + +			base = 16; +			break; + +		case 'd': +		case 'i': + +			type |= ACPI_FORMAT_SIGN; + +		case 'u': + +			break; + +		case 'p': + +			if (width == -1) { +				width = 2 * sizeof(void *); +				type |= ACPI_FORMAT_ZERO; +			} + +			p = va_arg(args, void *); +			pos = acpi_ut_format_number(pos, end, +						    ACPI_TO_INTEGER(p), 16, +						    width, precision, type); +			continue; + +		default: + +			pos = acpi_ut_bound_string_output(pos, end, '%'); +			if (*format) { +				pos = +				    acpi_ut_bound_string_output(pos, end, +								*format); +			} else { +				--format; +			} +			continue; +		} + +		if (qualifier == 'L') { +			number = va_arg(args, u64); +			if (type & ACPI_FORMAT_SIGN) { +				number = (s64) number; +			} +		} else if (qualifier == 'l') { +			number = va_arg(args, unsigned long); +			if (type & ACPI_FORMAT_SIGN) { +				number = (s32) number; +			} +		} else if (qualifier == 'h') { +			number = (u16)va_arg(args, int); +			if (type & ACPI_FORMAT_SIGN) { +				number = (s16) number; +			} +		} else { +			number = va_arg(args, unsigned int); +			if (type & ACPI_FORMAT_SIGN) { +				number = (signed int)number; +			} +		} + +		pos = acpi_ut_format_number(pos, end, number, base, +					    width, precision, type); +	} + +	if (size > 0) { +		if (pos < end) { +			*pos = '\0'; +		} else { +			end[-1] = '\0'; +		} +	} + +	return (ACPI_PTR_DIFF(pos, string)); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_snprintf + * + * PARAMETERS:  string              - String with boundary + *              size                - Boundary of the string + *              Format, ...         - Standard printf format + * + * RETURN:      Number of bytes actually written. + * + * DESCRIPTION: Formatted output to a string. + * + ******************************************************************************/ + +int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...) +{ +	va_list args; +	int length; + +	va_start(args, format); +	length = acpi_ut_vsnprintf(string, size, format, args); +	va_end(args); + +	return (length); +} + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION:    acpi_ut_file_vprintf + * + * PARAMETERS:  file                - File descriptor + *              format              - Standard printf format + *              args                - Argument list + * + * RETURN:      Number of bytes actually written. + * + * DESCRIPTION: Formatted output to a file using argument list pointer. + * + ******************************************************************************/ + +int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args) +{ +	acpi_cpu_flags flags; +	int length; + +	flags = acpi_os_acquire_lock(acpi_gbl_print_lock); +	length = acpi_ut_vsnprintf(acpi_gbl_print_buffer, +				   sizeof(acpi_gbl_print_buffer), format, args); + +	(void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1); +	acpi_os_release_lock(acpi_gbl_print_lock, flags); + +	return (length); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ut_file_printf + * + * PARAMETERS:  file                - File descriptor + *              Format, ...         - Standard printf format + * + * RETURN:      Number of bytes actually written. + * + * DESCRIPTION: Formatted output to a file. + * + ******************************************************************************/ + +int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...) +{ +	va_list args; +	int length; + +	va_start(args, format); +	length = acpi_ut_file_vprintf(file, format, args); +	va_end(args); + +	return (length); +} +#endif diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index e5bcd919d4e6..16129c78b489 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h @@ -121,11 +121,11 @@ struct dentry;  struct dentry *apei_get_debugfs_dir(void);  #define apei_estatus_for_each_section(estatus, section)			\ -	for (section = (struct acpi_generic_data *)(estatus + 1);	\ +	for (section = (struct acpi_hest_generic_data *)(estatus + 1);	\  	     (void *)section - (void *)estatus < estatus->data_length;	\  	     section = (void *)(section+1) + section->error_data_length) -static inline u32 cper_estatus_len(struct acpi_generic_status *estatus) +static inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus)  {  	if (estatus->raw_data_length)  		return estatus->raw_data_offset + \ @@ -135,9 +135,9 @@ static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)  }  void cper_estatus_print(const char *pfx, -			const struct acpi_generic_status *estatus); -int cper_estatus_check_header(const struct acpi_generic_status *estatus); -int cper_estatus_check(const struct acpi_generic_status *estatus); +			const struct acpi_hest_generic_status *estatus); +int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus); +int cper_estatus_check(const struct acpi_hest_generic_status *estatus);  int apei_osc_setup(void);  #endif diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index dab7cb7349df..7a38d1465b61 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -74,13 +74,13 @@  #define GHES_ESTATUS_CACHE_LEN(estatus_len)			\  	(sizeof(struct ghes_estatus_cache) + (estatus_len))  #define GHES_ESTATUS_FROM_CACHE(estatus_cache)			\ -	((struct acpi_generic_status *)				\ +	((struct acpi_hest_generic_status *)				\  	 ((struct ghes_estatus_cache *)(estatus_cache) + 1))  #define GHES_ESTATUS_NODE_LEN(estatus_len)			\  	(sizeof(struct ghes_estatus_node) + (estatus_len))  #define GHES_ESTATUS_FROM_NODE(estatus_node)			\ -	((struct acpi_generic_status *)				\ +	((struct acpi_hest_generic_status *)				\  	 ((struct ghes_estatus_node *)(estatus_node) + 1))  bool ghes_disable; @@ -408,7 +408,7 @@ static void ghes_clear_estatus(struct ghes *ghes)  	ghes->flags &= ~GHES_TO_CLEAR;  } -static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev) +static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev)  {  #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE  	unsigned long pfn; @@ -441,10 +441,10 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)  }  static void ghes_do_proc(struct ghes *ghes, -			 const struct acpi_generic_status *estatus) +			 const struct acpi_hest_generic_status *estatus)  {  	int sev, sec_sev; -	struct acpi_generic_data *gdata; +	struct acpi_hest_generic_data *gdata;  	sev = ghes_severity(estatus->error_severity);  	apei_estatus_for_each_section(estatus, gdata) { @@ -498,7 +498,7 @@ static void ghes_do_proc(struct ghes *ghes,  static void __ghes_print_estatus(const char *pfx,  				 const struct acpi_hest_generic *generic, -				 const struct acpi_generic_status *estatus) +				 const struct acpi_hest_generic_status *estatus)  {  	static atomic_t seqno;  	unsigned int curr_seqno; @@ -520,7 +520,7 @@ static void __ghes_print_estatus(const char *pfx,  static int ghes_print_estatus(const char *pfx,  			      const struct acpi_hest_generic *generic, -			      const struct acpi_generic_status *estatus) +			      const struct acpi_hest_generic_status *estatus)  {  	/* Not more than 2 messages every 5 seconds */  	static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); @@ -542,13 +542,13 @@ static int ghes_print_estatus(const char *pfx,   * GHES error status reporting throttle, to report more kinds of   * errors, instead of just most frequently occurred errors.   */ -static int ghes_estatus_cached(struct acpi_generic_status *estatus) +static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus)  {  	u32 len;  	int i, cached = 0;  	unsigned long long now;  	struct ghes_estatus_cache *cache; -	struct acpi_generic_status *cache_estatus; +	struct acpi_hest_generic_status *cache_estatus;  	len = cper_estatus_len(estatus);  	rcu_read_lock(); @@ -573,12 +573,12 @@ static int ghes_estatus_cached(struct acpi_generic_status *estatus)  static struct ghes_estatus_cache *ghes_estatus_cache_alloc(  	struct acpi_hest_generic *generic, -	struct acpi_generic_status *estatus) +	struct acpi_hest_generic_status *estatus)  {  	int alloced;  	u32 len, cache_len;  	struct ghes_estatus_cache *cache; -	struct acpi_generic_status *cache_estatus; +	struct acpi_hest_generic_status *cache_estatus;  	alloced = atomic_add_return(1, &ghes_estatus_cache_alloced);  	if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) { @@ -621,7 +621,7 @@ static void ghes_estatus_cache_rcu_free(struct rcu_head *head)  static void ghes_estatus_cache_add(  	struct acpi_hest_generic *generic, -	struct acpi_generic_status *estatus) +	struct acpi_hest_generic_status *estatus)  {  	int i, slot = -1, count;  	unsigned long long now, duration, period, max_period = 0; @@ -753,7 +753,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)  	struct llist_node *llnode, *next;  	struct ghes_estatus_node *estatus_node;  	struct acpi_hest_generic *generic; -	struct acpi_generic_status *estatus; +	struct acpi_hest_generic_status *estatus;  	u32 len, node_len;  	llnode = llist_del_all(&ghes_estatus_llist); @@ -786,7 +786,7 @@ static void ghes_print_queued_estatus(void)  	struct llist_node *llnode;  	struct ghes_estatus_node *estatus_node;  	struct acpi_hest_generic *generic; -	struct acpi_generic_status *estatus; +	struct acpi_hest_generic_status *estatus;  	u32 len, node_len;  	llnode = llist_del_all(&ghes_estatus_llist); @@ -845,7 +845,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)  #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG  		u32 len, node_len;  		struct ghes_estatus_node *estatus_node; -		struct acpi_generic_status *estatus; +		struct acpi_hest_generic_status *estatus;  #endif  		if (!(ghes->flags & GHES_TO_CLEAR))  			continue; @@ -925,7 +925,7 @@ static int ghes_probe(struct platform_device *ghes_dev)  	rc = -EIO;  	if (generic->error_block_length < -	    sizeof(struct acpi_generic_status)) { +	    sizeof(struct acpi_hest_generic_status)) {  		pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",  			   generic->error_block_length,  			   generic->header.source_id); diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 1491dd4f08f9..65f2f3fdde24 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -262,7 +262,7 @@ static const char *cper_pcie_port_type_strs[] = {  };  static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, -			    const struct acpi_generic_data *gdata) +			    const struct acpi_hest_generic_data *gdata)  {  	if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)  		printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, @@ -298,7 +298,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,  }  static void cper_estatus_print_section( -	const char *pfx, const struct acpi_generic_data *gdata, int sec_no) +	const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)  {  	uuid_le *sec_type = (uuid_le *)gdata->section_type;  	__u16 severity; @@ -344,9 +344,9 @@ err_section_too_small:  }  void cper_estatus_print(const char *pfx, -			const struct acpi_generic_status *estatus) +			const struct acpi_hest_generic_status *estatus)  { -	struct acpi_generic_data *gdata; +	struct acpi_hest_generic_data *gdata;  	unsigned int data_len, gedata_len;  	int sec_no = 0;  	char newpfx[64]; @@ -359,7 +359,7 @@ void cper_estatus_print(const char *pfx,  		       "and requires no further action");  	printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));  	data_len = estatus->data_length; -	gdata = (struct acpi_generic_data *)(estatus + 1); +	gdata = (struct acpi_hest_generic_data *)(estatus + 1);  	snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);  	while (data_len >= sizeof(*gdata)) {  		gedata_len = gdata->error_data_length; @@ -371,10 +371,10 @@ void cper_estatus_print(const char *pfx,  }  EXPORT_SYMBOL_GPL(cper_estatus_print); -int cper_estatus_check_header(const struct acpi_generic_status *estatus) +int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus)  {  	if (estatus->data_length && -	    estatus->data_length < sizeof(struct acpi_generic_data)) +	    estatus->data_length < sizeof(struct acpi_hest_generic_data))  		return -EINVAL;  	if (estatus->raw_data_length &&  	    estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length) @@ -384,9 +384,9 @@ int cper_estatus_check_header(const struct acpi_generic_status *estatus)  }  EXPORT_SYMBOL_GPL(cper_estatus_check_header); -int cper_estatus_check(const struct acpi_generic_status *estatus) +int cper_estatus_check(const struct acpi_hest_generic_status *estatus)  { -	struct acpi_generic_data *gdata; +	struct acpi_hest_generic_data *gdata;  	unsigned int data_len, gedata_len;  	int rc; @@ -394,7 +394,7 @@ int cper_estatus_check(const struct acpi_generic_status *estatus)  	if (rc)  		return rc;  	data_len = estatus->data_length; -	gdata = (struct acpi_generic_data *)(estatus + 1); +	gdata = (struct acpi_hest_generic_data *)(estatus + 1);  	while (data_len >= sizeof(*gdata)) {  		gedata_len = gdata->error_data_length;  		if (gedata_len > data_len - sizeof(*gdata)) diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index f6f5f8af2112..03b3e6d405ff 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -399,4 +399,35 @@ char *acpi_os_get_next_filename(void *dir_handle);  void acpi_os_close_directory(void *dir_handle);  #endif +/* + * File I/O and related support + */ +#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_open_file +ACPI_FILE acpi_os_open_file(const char *path, u8 modes); +#endif + +#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_close_file +void acpi_os_close_file(ACPI_FILE file); +#endif + +#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_read_file +int +acpi_os_read_file(ACPI_FILE file, +		  void *buffer, acpi_size size, acpi_size count); +#endif + +#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_write_file +int +acpi_os_write_file(ACPI_FILE file, +		   void *buffer, acpi_size size, acpi_size count); +#endif + +#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_file_offset +long acpi_os_get_file_offset(ACPI_FILE file); +#endif + +#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_set_file_offset +acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from); +#endif +  #endif				/* __ACPIOSXF_H__ */ diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 35b525c19711..508e5649dda9 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -46,7 +46,7 @@  /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION                 0x20140424 +#define ACPI_CA_VERSION                 0x20140627  #include <acpi/acconfig.h>  #include <acpi/actypes.h> @@ -335,6 +335,23 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);  #endif				/* ACPI_DEBUG_OUTPUT */ +/* + * Application prototypes + * + * All interfaces used by application will be configured + * out of the ACPICA build unless the ACPI_APPLICATION + * flag is defined. + */ +#ifdef ACPI_APPLICATION +#define ACPI_APP_DEPENDENT_RETURN_VOID(prototype) \ +	prototype; + +#else +#define ACPI_APP_DEPENDENT_RETURN_VOID(prototype) \ +	static ACPI_INLINE prototype {return;} + +#endif				/* ACPI_APPLICATION */ +  /*****************************************************************************   *   * ACPICA public interface prototypes @@ -658,6 +675,10 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status  						u32 gpe_number))  ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status +				acpi_mark_gpe_for_wake(acpi_handle gpe_device, +						       u32 gpe_number)) + +ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status  				acpi_setup_gpe_for_wake(acpi_handle  							parent_device,  							acpi_handle gpe_device, @@ -861,6 +882,9 @@ ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6)  						     const char *module_name,  						     u32 component_id,  						     const char *format, ...)) +ACPI_APP_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(1) +				void ACPI_INTERNAL_VAR_XFACE +				acpi_log_error(const char *format, ...))  /*   * Divergences diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 4ad7da805180..9613e8e97960 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -604,7 +604,7 @@ struct acpi_hest_generic {  /* Generic Error Status block */ -struct acpi_generic_status { +struct acpi_hest_generic_status {  	u32 block_status;  	u32 raw_data_offset;  	u32 raw_data_length; @@ -614,15 +614,15 @@ struct acpi_generic_status {  /* Values for block_status flags above */ -#define ACPI_GEN_ERR_UC			BIT(0) -#define ACPI_GEN_ERR_CE			BIT(1) -#define ACPI_GEN_ERR_MULTI_UC		BIT(2) -#define ACPI_GEN_ERR_MULTI_CE		BIT(3) -#define ACPI_GEN_ERR_COUNT_SHIFT	(0xFF<<4) /* 8 bits, error count */ +#define ACPI_HEST_UNCORRECTABLE             (1) +#define ACPI_HEST_CORRECTABLE               (1<<1) +#define ACPI_HEST_MULTIPLE_UNCORRECTABLE    (1<<2) +#define ACPI_HEST_MULTIPLE_CORRECTABLE      (1<<3) +#define ACPI_HEST_ERROR_ENTRY_COUNT         (0xFF<<4)	/* 8 bits, error count */  /* Generic Error Data entry */ -struct acpi_generic_data { +struct acpi_hest_generic_data {  	u8 section_type[16];  	u32 error_severity;  	u16 revision; diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index 860e5c883eb3..21314d37cb07 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -516,7 +516,7 @@ struct acpi_dmar_andd {  	struct acpi_dmar_header header;  	u8 reserved[3];  	u8 device_number; -	u8 object_name[]; +	char object_name[1];  };  /******************************************************************************* diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 19b26bb69a70..608a04019372 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -126,6 +126,7 @@  typedef unsigned char u8;  typedef unsigned char u8;  typedef unsigned short u16; +typedef short s16;  typedef COMPILER_DEPENDENT_UINT64 u64;  typedef COMPILER_DEPENDENT_INT64 s64; @@ -1244,4 +1245,17 @@ struct acpi_memory_list {  #define ACPI_OSI_WIN_7                  0x0B  #define ACPI_OSI_WIN_8                  0x0C +/* Definitions of file IO */ + +#define ACPI_FILE_READING               0x01 +#define ACPI_FILE_WRITING               0x02 +#define ACPI_FILE_BINARY                0x04 + +#define ACPI_FILE_BEGIN                 0x01 +#define ACPI_FILE_END                   0x02 + +/* Definitions of getopt */ + +#define ACPI_OPT_END                    -1 +  #endif				/* __ACTYPES_H__ */ diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h index dfd60d0bfd27..720446cb243e 100644 --- a/include/acpi/ghes.h +++ b/include/acpi/ghes.h @@ -14,7 +14,7 @@  struct ghes {  	struct acpi_hest_generic *generic; -	struct acpi_generic_status *estatus; +	struct acpi_hest_generic_status *estatus;  	u64 buffer_paddr;  	unsigned long flags;  	union { diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index e863dd5c4e04..5f8cc1fa3278 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -87,20 +87,14 @@  #define ACPI_DBG_TRACK_ALLOCATIONS  #endif -/* acpi_names configuration. Single threaded with debugger output enabled. */ - -#ifdef ACPI_NAMES_APP -#define ACPI_DEBUGGER -#define ACPI_APPLICATION -#define ACPI_SINGLE_THREADED -#endif -  /* - * acpi_bin/acpi_dump/acpi_src/acpi_xtract/Example configuration. All single - * threaded, with no debug output. + * acpi_bin/acpi_dump/acpi_help/acpi_names/acpi_src/acpi_xtract/Example configuration. + * All single threaded.   */  #if (defined ACPI_BIN_APP)      || \  	(defined ACPI_DUMP_APP)     || \ +	(defined ACPI_HELP_APP)     || \ +	(defined ACPI_NAMES_APP)    || \  	(defined ACPI_SRC_APP)      || \  	(defined ACPI_XTRACT_APP)   || \  	(defined ACPI_EXAMPLE_APP) @@ -108,12 +102,40 @@  #define ACPI_SINGLE_THREADED  #endif +/* acpi_help configuration. Error messages disabled. */ +  #ifdef ACPI_HELP_APP -#define ACPI_APPLICATION -#define ACPI_SINGLE_THREADED  #define ACPI_NO_ERROR_MESSAGES  #endif +/* acpi_names configuration. Debug output enabled. */ + +#ifdef ACPI_NAMES_APP +#define ACPI_DEBUG_OUTPUT +#endif + +/* acpi_exec/acpi_names/Example configuration. Native RSDP used. */ + +#if (defined ACPI_EXEC_APP)     || \ +	(defined ACPI_EXAMPLE_APP)  || \ +	(defined ACPI_NAMES_APP) +#define ACPI_USE_NATIVE_RSDP_POINTER +#endif + +/* acpi_dump configuration. Native mapping used if provied by OSPMs */ + +#ifdef ACPI_DUMP_APP +#define ACPI_USE_NATIVE_MEMORY_MAPPING +#define USE_NATIVE_ALLOCATE_ZEROED +#endif + +/* acpi_names/Example configuration. Hardware disabled */ + +#if (defined ACPI_EXAMPLE_APP)  || \ +	(defined ACPI_NAMES_APP) +#define ACPI_REDUCED_HARDWARE 1 +#endif +  /* Linkable ACPICA library */  #ifdef ACPI_LIBRARY @@ -185,6 +207,9 @@  #elif defined(_AED_EFI)  #include "acefi.h" +#elif defined(_GNU_EFI) +#include "acefi.h" +  #elif defined(__HAIKU__)  #include "achaiku.h" @@ -399,8 +424,12 @@ typedef char *va_list;  #ifdef ACPI_APPLICATION  #include <stdio.h>  #define ACPI_FILE              FILE * +#define ACPI_FILE_OUT          stdout +#define ACPI_FILE_ERR          stderr  #else  #define ACPI_FILE              void * +#define ACPI_FILE_OUT          NULL +#define ACPI_FILE_ERR          NULL  #endif				/* ACPI_APPLICATION */  #endif				/* ACPI_FILE */ diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index e5a3c4be2a10..3d1537b93c64 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile @@ -108,13 +108,18 @@ DUMP_OBJS = \  	apmain.o\  	osunixdir.o\  	osunixmap.o\ +	osunixxf.o\  	tbprint.o\  	tbxfroot.o\  	utbuffer.o\ +	utdebug.o\  	utexcep.o\ +	utglobal.o\  	utmath.o\ +	utprint.o\  	utstring.o\  	utxferror.o\ +	oslibcfs.o\  	oslinuxtbl.o\  	cmfsize.o\  	getopt.o diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c index 5140e5edae1f..f4b953354ff7 100644 --- a/tools/power/acpi/common/cmfsize.c +++ b/tools/power/acpi/common/cmfsize.c @@ -58,44 +58,46 @@ ACPI_MODULE_NAME("cmfsize")   * RETURN:      File Size. On error, -1 (ACPI_UINT32_MAX)   *   * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open. - *              Does not disturb the current file pointer. Uses perror for - *              error messages. + *              Does not disturb the current file pointer.   *   ******************************************************************************/ -u32 cm_get_file_size(FILE * file) +u32 cm_get_file_size(ACPI_FILE file)  {  	long file_size;  	long current_offset; +	acpi_status status;  	/* Save the current file pointer, seek to EOF to obtain file size */ -	current_offset = ftell(file); +	current_offset = acpi_os_get_file_offset(file);  	if (current_offset < 0) {  		goto offset_error;  	} -	if (fseek(file, 0, SEEK_END)) { +	status = acpi_os_set_file_offset(file, 0, ACPI_FILE_END); +	if (ACPI_FAILURE(status)) {  		goto seek_error;  	} -	file_size = ftell(file); +	file_size = acpi_os_get_file_offset(file);  	if (file_size < 0) {  		goto offset_error;  	}  	/* Restore original file pointer */ -	if (fseek(file, current_offset, SEEK_SET)) { +	status = acpi_os_set_file_offset(file, current_offset, ACPI_FILE_BEGIN); +	if (ACPI_FAILURE(status)) {  		goto seek_error;  	}  	return ((u32)file_size);  offset_error: -	perror("Could not get file offset"); +	acpi_log_error("Could not get file offset");  	return (ACPI_UINT32_MAX);  seek_error: -	perror("Could not seek file"); +	acpi_log_error("Could not set file offset");  	return (ACPI_UINT32_MAX);  } diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c index a302f52e4fd3..2f0f34a36db4 100644 --- a/tools/power/acpi/common/getopt.c +++ b/tools/power/acpi/common/getopt.c @@ -51,14 +51,12 @@   *    "f|"      - Option has required single-char sub-options   */ -#include <stdio.h> -#include <string.h>  #include <acpi/acpi.h>  #include "accommon.h"  #include "acapps.h"  #define ACPI_OPTION_ERROR(msg, badchar) \ -	if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);} +	if (acpi_gbl_opterr) {acpi_log_error ("%s%c\n", msg, badchar);}  int acpi_gbl_opterr = 1;  int acpi_gbl_optind = 1; @@ -113,7 +111,7 @@ int acpi_getopt_argument(int argc, char **argv)   * PARAMETERS:  argc, argv          - from main   *              opts                - options info list   * - * RETURN:      Option character or EOF + * RETURN:      Option character or ACPI_OPT_END   *   * DESCRIPTION: Get the next option   * @@ -128,10 +126,10 @@ int acpi_getopt(int argc, char **argv, char *opts)  		if (acpi_gbl_optind >= argc ||  		    argv[acpi_gbl_optind][0] != '-' ||  		    argv[acpi_gbl_optind][1] == '\0') { -			return (EOF); -		} else if (strcmp(argv[acpi_gbl_optind], "--") == 0) { +			return (ACPI_OPT_END); +		} else if (ACPI_STRCMP(argv[acpi_gbl_optind], "--") == 0) {  			acpi_gbl_optind++; -			return (EOF); +			return (ACPI_OPT_END);  		}  	} @@ -142,7 +140,7 @@ int acpi_getopt(int argc, char **argv, char *opts)  	/* Make sure that the option is legal */  	if (current_char == ':' || -	    (opts_ptr = strchr(opts, current_char)) == NULL) { +	    (opts_ptr = ACPI_STRCHR(opts, current_char)) == NULL) {  		ACPI_OPTION_ERROR("Illegal option: -", current_char);  		if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') { diff --git a/tools/power/acpi/os_specific/service_layers/oslibcfs.c b/tools/power/acpi/os_specific/service_layers/oslibcfs.c new file mode 100644 index 000000000000..c13ff9c51d74 --- /dev/null +++ b/tools/power/acpi/os_specific/service_layers/oslibcfs.c @@ -0,0 +1,214 @@ +/****************************************************************************** + * + * Module Name: oslibcfs - C library OSL for file I/O + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions, and the following disclaimer, + *    without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + *    substantially similar to the "NO WARRANTY" disclaimer below + *    ("Disclaimer") and any redistribution must be conditioned upon + *    including a substantially similar Disclaimer requirement for further + *    binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + *    of any contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <acpi/acpi.h> +#include <stdio.h> +#include <stdarg.h> + +#define _COMPONENT          ACPI_OS_SERVICES +ACPI_MODULE_NAME("oslibcfs") + +/******************************************************************************* + * + * FUNCTION:    acpi_os_open_file + * + * PARAMETERS:  path                - File path + *              modes               - File operation type + * + * RETURN:      File descriptor. + * + * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing + *              (ACPI_FILE_WRITING). + * + ******************************************************************************/ +ACPI_FILE acpi_os_open_file(const char *path, u8 modes) +{ +	ACPI_FILE file; +	u32 i = 0; +	char modes_str[4]; + +	if (modes & ACPI_FILE_READING) { +		modes_str[i++] = 'r'; +	} +	if (modes & ACPI_FILE_WRITING) { +		modes_str[i++] = 'w'; +	} +	if (modes & ACPI_FILE_BINARY) { +		modes_str[i++] = 'b'; +	} + +	modes_str[i++] = '\0'; + +	file = fopen(path, modes_str); +	if (!file) { +		perror("Could not open file"); +	} + +	return (file); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_os_close_file + * + * PARAMETERS:  file                - An open file descriptor + * + * RETURN:      None. + * + * DESCRIPTION: Close a file opened via acpi_os_open_file. + * + ******************************************************************************/ + +void acpi_os_close_file(ACPI_FILE file) +{ +	fclose(file); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_os_read_file + * + * PARAMETERS:  file                - An open file descriptor + *              buffer              - Data buffer + *              size                - Data block size + *              count               - Number of data blocks + * + * RETURN:      Number of bytes actually read. + * + * DESCRIPTION: Read from a file. + * + ******************************************************************************/ + +int +acpi_os_read_file(ACPI_FILE file, void *buffer, acpi_size size, acpi_size count) +{ +	int length; + +	length = fread(buffer, size, count, file); +	if (length < 0) { +		perror("Error reading file"); +	} + +	return (length); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_os_write_file + * + * PARAMETERS:  file                - An open file descriptor + *              buffer              - Data buffer + *              size                - Data block size + *              count               - Number of data blocks + * + * RETURN:      Number of bytes actually written. + * + * DESCRIPTION: Write to a file. + * + ******************************************************************************/ + +int +acpi_os_write_file(ACPI_FILE file, +		   void *buffer, acpi_size size, acpi_size count) +{ +	int length; + +	length = fwrite(buffer, size, count, file); +	if (length < 0) { +		perror("Error writing file"); +	} + +	return (length); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_os_get_file_offset + * + * PARAMETERS:  file                - An open file descriptor + * + * RETURN:      Current file pointer position. + * + * DESCRIPTION: Get current file offset. + * + ******************************************************************************/ + +long acpi_os_get_file_offset(ACPI_FILE file) +{ +	long offset; + +	offset = ftell(file); +	return (offset); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_os_set_file_offset + * + * PARAMETERS:  file                - An open file descriptor + *              offset              - New file offset + *              from                - From begin/end of file + * + * RETURN:      Status + * + * DESCRIPTION: Set current file offset. + * + ******************************************************************************/ + +acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from) +{ +	int ret = 0; + +	if (from == ACPI_FILE_BEGIN) { +		ret = fseek(file, offset, SEEK_SET); +	} +	if (from == ACPI_FILE_END) { +		ret = fseek(file, offset, SEEK_END); +	} + +	if (ret < 0) { +		return (AE_ERROR); +	} else { +		return (AE_OK); +	} +} diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c index 28c52008e854..0dc2485dedf5 100644 --- a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c +++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c @@ -77,6 +77,9 @@ osl_map_table(acpi_size address,  static void osl_unmap_table(struct acpi_table_header *table); +static acpi_physical_address +osl_find_rsdp_via_efi_by_keyword(FILE * file, const char *keyword); +  static acpi_physical_address osl_find_rsdp_via_efi(void);  static acpi_status osl_load_rsdp(void); @@ -417,6 +420,38 @@ acpi_os_get_table_by_index(u32 index,  /******************************************************************************   * + * FUNCTION:    osl_find_rsdp_via_efi_by_keyword + * + * PARAMETERS:  keyword         - Character string indicating ACPI GUID version + *                                in the EFI table + * + * RETURN:      RSDP address if found + * + * DESCRIPTION: Find RSDP address via EFI using keyword indicating the ACPI + *              GUID version. + * + *****************************************************************************/ + +static acpi_physical_address +osl_find_rsdp_via_efi_by_keyword(FILE * file, const char *keyword) +{ +	char buffer[80]; +	unsigned long long address = 0; +	char format[32]; + +	snprintf(format, 32, "%s=%s", keyword, "%llx"); +	fseek(file, 0, SEEK_SET); +	while (fgets(buffer, 80, file)) { +		if (sscanf(buffer, format, &address) == 1) { +			break; +		} +	} + +	return ((acpi_physical_address) (address)); +} + +/****************************************************************************** + *   * FUNCTION:    osl_find_rsdp_via_efi   *   * PARAMETERS:  None @@ -430,20 +465,19 @@ acpi_os_get_table_by_index(u32 index,  static acpi_physical_address osl_find_rsdp_via_efi(void)  {  	FILE *file; -	char buffer[80]; -	unsigned long address = 0; +	acpi_physical_address address = 0;  	file = fopen(EFI_SYSTAB, "r");  	if (file) { -		while (fgets(buffer, 80, file)) { -			if (sscanf(buffer, "ACPI20=0x%lx", &address) == 1) { -				break; -			} +		address = osl_find_rsdp_via_efi_by_keyword(file, "ACPI20"); +		if (!address) { +			address = +			    osl_find_rsdp_via_efi_by_keyword(file, "ACPI");  		}  		fclose(file);  	} -	return ((acpi_physical_address) (address)); +	return (address);  }  /****************************************************************************** diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c new file mode 100644 index 000000000000..60b58cd18410 --- /dev/null +++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c @@ -0,0 +1,1311 @@ +/****************************************************************************** + * + * Module Name: osunixxf - UNIX OSL interfaces + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions, and the following disclaimer, + *    without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + *    substantially similar to the "NO WARRANTY" disclaimer below + *    ("Disclaimer") and any redistribution must be conditioned upon + *    including a substantially similar Disclaimer requirement for further + *    binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + *    of any contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * These interfaces are required in order to compile the ASL compiler and the + * various ACPICA tools under Linux or other Unix-like system. + */ +#include <acpi/acpi.h> +#include "accommon.h" +#include "amlcode.h" +#include "acparser.h" +#include "acdebug.h" + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <unistd.h> +#include <sys/time.h> +#include <semaphore.h> +#include <pthread.h> +#include <errno.h> + +#define _COMPONENT          ACPI_OS_SERVICES +ACPI_MODULE_NAME("osunixxf") + +u8 acpi_gbl_debug_timeout = FALSE; + +/* Upcalls to acpi_exec */ + +void +ae_table_override(struct acpi_table_header *existing_table, +		  struct acpi_table_header **new_table); + +typedef void *(*PTHREAD_CALLBACK) (void *); + +/* Buffer used by acpi_os_vprintf */ + +#define ACPI_VPRINTF_BUFFER_SIZE    512 +#define _ASCII_NEWLINE              '\n' + +/* Terminal support for acpi_exec only */ + +#ifdef ACPI_EXEC_APP +#include <termios.h> + +struct termios original_term_attributes; +int term_attributes_were_set = 0; + +acpi_status acpi_ut_read_line(char *buffer, u32 buffer_length, u32 *bytes_read); + +static void os_enter_line_edit_mode(void); + +static void os_exit_line_edit_mode(void); + +/****************************************************************************** + * + * FUNCTION:    os_enter_line_edit_mode, os_exit_line_edit_mode + * + * PARAMETERS:  None + * + * RETURN:      None + * + * DESCRIPTION: Enter/Exit the raw character input mode for the terminal. + * + * Interactive line-editing support for the AML debugger. Used with the + * common/acgetline module. + * + * readline() is not used because of non-portability. It is not available + * on all systems, and if it is, often the package must be manually installed. + * + * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line + * editing that we need in acpi_os_get_line. + * + * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these + * calls will also work: + *     For os_enter_line_edit_mode: system ("stty cbreak -echo") + *     For os_exit_line_edit_mode: system ("stty cooked echo") + * + *****************************************************************************/ + +static void os_enter_line_edit_mode(void) +{ +	struct termios local_term_attributes; + +	/* Get and keep the original attributes */ + +	if (tcgetattr(STDIN_FILENO, &original_term_attributes)) { +		fprintf(stderr, "Could not get terminal attributes!\n"); +		return; +	} + +	/* Set the new attributes to enable raw character input */ + +	memcpy(&local_term_attributes, &original_term_attributes, +	       sizeof(struct termios)); + +	local_term_attributes.c_lflag &= ~(ICANON | ECHO); +	local_term_attributes.c_cc[VMIN] = 1; +	local_term_attributes.c_cc[VTIME] = 0; + +	if (tcsetattr(STDIN_FILENO, TCSANOW, &local_term_attributes)) { +		fprintf(stderr, "Could not set terminal attributes!\n"); +		return; +	} + +	term_attributes_were_set = 1; +} + +static void os_exit_line_edit_mode(void) +{ + +	if (!term_attributes_were_set) { +		return; +	} + +	/* Set terminal attributes back to the original values */ + +	if (tcsetattr(STDIN_FILENO, TCSANOW, &original_term_attributes)) { +		fprintf(stderr, "Could not restore terminal attributes!\n"); +	} +} + +#else + +/* These functions are not needed for other ACPICA utilities */ + +#define os_enter_line_edit_mode() +#define os_exit_line_edit_mode() +#endif + +/****************************************************************************** + * + * FUNCTION:    acpi_os_initialize, acpi_os_terminate + * + * PARAMETERS:  None + * + * RETURN:      Status + * + * DESCRIPTION: Initialize and terminate this module. + * + *****************************************************************************/ + +acpi_status acpi_os_initialize(void) +{ +	acpi_status status; + +	acpi_gbl_output_file = stdout; + +	os_enter_line_edit_mode(); + +	status = acpi_os_create_lock(&acpi_gbl_print_lock); +	if (ACPI_FAILURE(status)) { +		return (status); +	} + +	return (AE_OK); +} + +acpi_status acpi_os_terminate(void) +{ + +	os_exit_line_edit_mode(); +	return (AE_OK); +} + +#ifndef ACPI_USE_NATIVE_RSDP_POINTER +/****************************************************************************** + * + * FUNCTION:    acpi_os_get_root_pointer + * + * PARAMETERS:  None + * + * RETURN:      RSDP physical address + * + * DESCRIPTION: Gets the ACPI root pointer (RSDP) + * + *****************************************************************************/ + +acpi_physical_address acpi_os_get_root_pointer(void) +{ + +	return (0); +} +#endif + +/****************************************************************************** + * + * FUNCTION:    acpi_os_predefined_override + * + * PARAMETERS:  init_val            - Initial value of the predefined object + *              new_val             - The new value for the object + * + * RETURN:      Status, pointer to value. Null pointer returned if not + *              overriding. + * + * DESCRIPTION: Allow the OS to override predefined names + * + *****************************************************************************/ + +acpi_status +acpi_os_predefined_override(const struct acpi_predefined_names * init_val, +			    acpi_string * new_val) +{ + +	if (!init_val || !new_val) { +		return (AE_BAD_PARAMETER); +	} + +	*new_val = NULL; +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_table_override + * + * PARAMETERS:  existing_table      - Header of current table (probably + *                                    firmware) + *              new_table           - Where an entire new table is returned. + * + * RETURN:      Status, pointer to new table. Null pointer returned if no + *              table is available to override + * + * DESCRIPTION: Return a different version of a table if one is available + * + *****************************************************************************/ + +acpi_status +acpi_os_table_override(struct acpi_table_header * existing_table, +		       struct acpi_table_header ** new_table) +{ + +	if (!existing_table || !new_table) { +		return (AE_BAD_PARAMETER); +	} + +	*new_table = NULL; + +#ifdef ACPI_EXEC_APP + +	ae_table_override(existing_table, new_table); +	return (AE_OK); +#else + +	return (AE_NO_ACPI_TABLES); +#endif +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_physical_table_override + * + * PARAMETERS:  existing_table      - Header of current table (probably firmware) + *              new_address         - Where new table address is returned + *                                    (Physical address) + *              new_table_length    - Where new table length is returned + * + * RETURN:      Status, address/length of new table. Null pointer returned + *              if no table is available to override. + * + * DESCRIPTION: Returns AE_SUPPORT, function not used in user space. + * + *****************************************************************************/ + +acpi_status +acpi_os_physical_table_override(struct acpi_table_header * existing_table, +				acpi_physical_address * new_address, +				u32 *new_table_length) +{ + +	return (AE_SUPPORT); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_redirect_output + * + * PARAMETERS:  destination         - An open file handle/pointer + * + * RETURN:      None + * + * DESCRIPTION: Causes redirect of acpi_os_printf and acpi_os_vprintf + * + *****************************************************************************/ + +void acpi_os_redirect_output(void *destination) +{ + +	acpi_gbl_output_file = destination; +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_printf + * + * PARAMETERS:  fmt, ...            - Standard printf format + * + * RETURN:      None + * + * DESCRIPTION: Formatted output. Note: very similar to acpi_os_vprintf + *              (performance), changes should be tracked in both functions. + * + *****************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...) +{ +	va_list args; +	u8 flags; + +	flags = acpi_gbl_db_output_flags; +	if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) { + +		/* Output is directable to either a file (if open) or the console */ + +		if (acpi_gbl_debug_file) { + +			/* Output file is open, send the output there */ + +			va_start(args, fmt); +			vfprintf(acpi_gbl_debug_file, fmt, args); +			va_end(args); +		} else { +			/* No redirection, send output to console (once only!) */ + +			flags |= ACPI_DB_CONSOLE_OUTPUT; +		} +	} + +	if (flags & ACPI_DB_CONSOLE_OUTPUT) { +		va_start(args, fmt); +		vfprintf(acpi_gbl_output_file, fmt, args); +		va_end(args); +	} +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_vprintf + * + * PARAMETERS:  fmt                 - Standard printf format + *              args                - Argument list + * + * RETURN:      None + * + * DESCRIPTION: Formatted output with argument list pointer. Note: very + *              similar to acpi_os_printf, changes should be tracked in both + *              functions. + * + *****************************************************************************/ + +void acpi_os_vprintf(const char *fmt, va_list args) +{ +	u8 flags; +	char buffer[ACPI_VPRINTF_BUFFER_SIZE]; + +	/* +	 * We build the output string in a local buffer because we may be +	 * outputting the buffer twice. Using vfprintf is problematic because +	 * some implementations modify the args pointer/structure during +	 * execution. Thus, we use the local buffer for portability. +	 * +	 * Note: Since this module is intended for use by the various ACPICA +	 * utilities/applications, we can safely declare the buffer on the stack. +	 * Also, This function is used for relatively small error messages only. +	 */ +	vsnprintf(buffer, ACPI_VPRINTF_BUFFER_SIZE, fmt, args); + +	flags = acpi_gbl_db_output_flags; +	if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) { + +		/* Output is directable to either a file (if open) or the console */ + +		if (acpi_gbl_debug_file) { + +			/* Output file is open, send the output there */ + +			fputs(buffer, acpi_gbl_debug_file); +		} else { +			/* No redirection, send output to console (once only!) */ + +			flags |= ACPI_DB_CONSOLE_OUTPUT; +		} +	} + +	if (flags & ACPI_DB_CONSOLE_OUTPUT) { +		fputs(buffer, acpi_gbl_output_file); +	} +} + +#ifndef ACPI_EXEC_APP +/****************************************************************************** + * + * FUNCTION:    acpi_os_get_line + * + * PARAMETERS:  buffer              - Where to return the command line + *              buffer_length       - Maximum length of Buffer + *              bytes_read          - Where the actual byte count is returned + * + * RETURN:      Status and actual bytes read + * + * DESCRIPTION: Get the next input line from the terminal. NOTE: For the + *              acpi_exec utility, we use the acgetline module instead to + *              provide line-editing and history support. + * + *****************************************************************************/ + +acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read) +{ +	int input_char; +	u32 end_of_line; + +	/* Standard acpi_os_get_line for all utilities except acpi_exec */ + +	for (end_of_line = 0;; end_of_line++) { +		if (end_of_line >= buffer_length) { +			return (AE_BUFFER_OVERFLOW); +		} + +		if ((input_char = getchar()) == EOF) { +			return (AE_ERROR); +		} + +		if (!input_char || input_char == _ASCII_NEWLINE) { +			break; +		} + +		buffer[end_of_line] = (char)input_char; +	} + +	/* Null terminate the buffer */ + +	buffer[end_of_line] = 0; + +	/* Return the number of bytes in the string */ + +	if (bytes_read) { +		*bytes_read = end_of_line; +	} + +	return (AE_OK); +} +#endif + +#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING +/****************************************************************************** + * + * FUNCTION:    acpi_os_map_memory + * + * PARAMETERS:  where               - Physical address of memory to be mapped + *              length              - How much memory to map + * + * RETURN:      Pointer to mapped memory. Null on error. + * + * DESCRIPTION: Map physical memory into caller's address space + * + *****************************************************************************/ + +void *acpi_os_map_memory(acpi_physical_address where, acpi_size length) +{ + +	return (ACPI_TO_POINTER((acpi_size) where)); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_unmap_memory + * + * PARAMETERS:  where               - Logical address of memory to be unmapped + *              length              - How much memory to unmap + * + * RETURN:      None. + * + * DESCRIPTION: Delete a previously created mapping. Where and Length must + *              correspond to a previous mapping exactly. + * + *****************************************************************************/ + +void acpi_os_unmap_memory(void *where, acpi_size length) +{ + +	return; +} +#endif + +/****************************************************************************** + * + * FUNCTION:    acpi_os_allocate + * + * PARAMETERS:  size                - Amount to allocate, in bytes + * + * RETURN:      Pointer to the new allocation. Null on error. + * + * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS. + * + *****************************************************************************/ + +void *acpi_os_allocate(acpi_size size) +{ +	void *mem; + +	mem = (void *)malloc((size_t) size); +	return (mem); +} + +#ifdef USE_NATIVE_ALLOCATE_ZEROED +/****************************************************************************** + * + * FUNCTION:    acpi_os_allocate_zeroed + * + * PARAMETERS:  size                - Amount to allocate, in bytes + * + * RETURN:      Pointer to the new allocation. Null on error. + * + * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS. + * + *****************************************************************************/ + +void *acpi_os_allocate_zeroed(acpi_size size) +{ +	void *mem; + +	mem = (void *)calloc(1, (size_t) size); +	return (mem); +} +#endif + +/****************************************************************************** + * + * FUNCTION:    acpi_os_free + * + * PARAMETERS:  mem                 - Pointer to previously allocated memory + * + * RETURN:      None. + * + * DESCRIPTION: Free memory allocated via acpi_os_allocate + * + *****************************************************************************/ + +void acpi_os_free(void *mem) +{ + +	free(mem); +} + +#ifdef ACPI_SINGLE_THREADED +/****************************************************************************** + * + * FUNCTION:    Semaphore stub functions + * + * DESCRIPTION: Stub functions used for single-thread applications that do + *              not require semaphore synchronization. Full implementations + *              of these functions appear after the stubs. + * + *****************************************************************************/ + +acpi_status +acpi_os_create_semaphore(u32 max_units, +			 u32 initial_units, acpi_handle * out_handle) +{ +	*out_handle = (acpi_handle) 1; +	return (AE_OK); +} + +acpi_status acpi_os_delete_semaphore(acpi_handle handle) +{ +	return (AE_OK); +} + +acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) +{ +	return (AE_OK); +} + +acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) +{ +	return (AE_OK); +} + +#else +/****************************************************************************** + * + * FUNCTION:    acpi_os_create_semaphore + * + * PARAMETERS:  initial_units       - Units to be assigned to the new semaphore + *              out_handle          - Where a handle will be returned + * + * RETURN:      Status + * + * DESCRIPTION: Create an OS semaphore + * + *****************************************************************************/ + +acpi_status +acpi_os_create_semaphore(u32 max_units, +			 u32 initial_units, acpi_handle * out_handle) +{ +	sem_t *sem; + +	if (!out_handle) { +		return (AE_BAD_PARAMETER); +	} +#ifdef __APPLE__ +	{ +		char *semaphore_name = tmpnam(NULL); + +		sem = +		    sem_open(semaphore_name, O_EXCL | O_CREAT, 0755, +			     initial_units); +		if (!sem) { +			return (AE_NO_MEMORY); +		} +		sem_unlink(semaphore_name);	/* This just deletes the name */ +	} + +#else +	sem = acpi_os_allocate(sizeof(sem_t)); +	if (!sem) { +		return (AE_NO_MEMORY); +	} + +	if (sem_init(sem, 0, initial_units) == -1) { +		acpi_os_free(sem); +		return (AE_BAD_PARAMETER); +	} +#endif + +	*out_handle = (acpi_handle) sem; +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_delete_semaphore + * + * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore + * + * RETURN:      Status + * + * DESCRIPTION: Delete an OS semaphore + * + *****************************************************************************/ + +acpi_status acpi_os_delete_semaphore(acpi_handle handle) +{ +	sem_t *sem = (sem_t *) handle; + +	if (!sem) { +		return (AE_BAD_PARAMETER); +	} + +	if (sem_destroy(sem) == -1) { +		return (AE_BAD_PARAMETER); +	} + +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_wait_semaphore + * + * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore + *              units               - How many units to wait for + *              msec_timeout        - How long to wait (milliseconds) + * + * RETURN:      Status + * + * DESCRIPTION: Wait for units + * + *****************************************************************************/ + +acpi_status +acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 msec_timeout) +{ +	acpi_status status = AE_OK; +	sem_t *sem = (sem_t *) handle; +#ifndef ACPI_USE_ALTERNATE_TIMEOUT +	struct timespec time; +	int ret_val; +#endif + +	if (!sem) { +		return (AE_BAD_PARAMETER); +	} + +	switch (msec_timeout) { +		/* +		 * No Wait: +		 * -------- +		 * A zero timeout value indicates that we shouldn't wait - just +		 * acquire the semaphore if available otherwise return AE_TIME +		 * (a.k.a. 'would block'). +		 */ +	case 0: + +		if (sem_trywait(sem) == -1) { +			status = (AE_TIME); +		} +		break; + +		/* Wait Indefinitely */ + +	case ACPI_WAIT_FOREVER: + +		if (sem_wait(sem)) { +			status = (AE_TIME); +		} +		break; + +		/* Wait with msec_timeout */ + +	default: + +#ifdef ACPI_USE_ALTERNATE_TIMEOUT +		/* +		 * Alternate timeout mechanism for environments where +		 * sem_timedwait is not available or does not work properly. +		 */ +		while (msec_timeout) { +			if (sem_trywait(sem) == 0) { + +				/* Got the semaphore */ +				return (AE_OK); +			} + +			if (msec_timeout >= 10) { +				msec_timeout -= 10; +				usleep(10 * ACPI_USEC_PER_MSEC);	/* ten milliseconds */ +			} else { +				msec_timeout--; +				usleep(ACPI_USEC_PER_MSEC);	/* one millisecond */ +			} +		} +		status = (AE_TIME); +#else +		/* +		 * The interface to sem_timedwait is an absolute time, so we need to +		 * get the current time, then add in the millisecond Timeout value. +		 */ +		if (clock_gettime(CLOCK_REALTIME, &time) == -1) { +			perror("clock_gettime"); +			return (AE_TIME); +		} + +		time.tv_sec += (msec_timeout / ACPI_MSEC_PER_SEC); +		time.tv_nsec += +		    ((msec_timeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC); + +		/* Handle nanosecond overflow (field must be less than one second) */ + +		if (time.tv_nsec >= ACPI_NSEC_PER_SEC) { +			time.tv_sec += (time.tv_nsec / ACPI_NSEC_PER_SEC); +			time.tv_nsec = (time.tv_nsec % ACPI_NSEC_PER_SEC); +		} + +		while (((ret_val = sem_timedwait(sem, &time)) == -1) +		       && (errno == EINTR)) { +			continue; +		} + +		if (ret_val != 0) { +			if (errno != ETIMEDOUT) { +				perror("sem_timedwait"); +			} +			status = (AE_TIME); +		} +#endif +		break; +	} + +	return (status); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_signal_semaphore + * + * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore + *              units               - Number of units to send + * + * RETURN:      Status + * + * DESCRIPTION: Send units + * + *****************************************************************************/ + +acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) +{ +	sem_t *sem = (sem_t *) handle; + +	if (!sem) { +		return (AE_BAD_PARAMETER); +	} + +	if (sem_post(sem) == -1) { +		return (AE_LIMIT); +	} + +	return (AE_OK); +} + +#endif				/* ACPI_SINGLE_THREADED */ + +/****************************************************************************** + * + * FUNCTION:    Spinlock interfaces + * + * DESCRIPTION: Map these interfaces to semaphore interfaces + * + *****************************************************************************/ + +acpi_status acpi_os_create_lock(acpi_spinlock * out_handle) +{ + +	return (acpi_os_create_semaphore(1, 1, out_handle)); +} + +void acpi_os_delete_lock(acpi_spinlock handle) +{ +	acpi_os_delete_semaphore(handle); +} + +acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle) +{ +	acpi_os_wait_semaphore(handle, 1, 0xFFFF); +	return (0); +} + +void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags) +{ +	acpi_os_signal_semaphore(handle, 1); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_install_interrupt_handler + * + * PARAMETERS:  interrupt_number    - Level handler should respond to. + *              isr                 - Address of the ACPI interrupt handler + *              except_ptr          - Where status is returned + * + * RETURN:      Handle to the newly installed handler. + * + * DESCRIPTION: Install an interrupt handler. Used to install the ACPI + *              OS-independent handler. + * + *****************************************************************************/ + +u32 +acpi_os_install_interrupt_handler(u32 interrupt_number, +				  acpi_osd_handler service_routine, +				  void *context) +{ + +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_remove_interrupt_handler + * + * PARAMETERS:  handle              - Returned when handler was installed + * + * RETURN:      Status + * + * DESCRIPTION: Uninstalls an interrupt handler. + * + *****************************************************************************/ + +acpi_status +acpi_os_remove_interrupt_handler(u32 interrupt_number, +				 acpi_osd_handler service_routine) +{ + +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_stall + * + * PARAMETERS:  microseconds        - Time to sleep + * + * RETURN:      Blocks until sleep is completed. + * + * DESCRIPTION: Sleep at microsecond granularity + * + *****************************************************************************/ + +void acpi_os_stall(u32 microseconds) +{ + +	if (microseconds) { +		usleep(microseconds); +	} +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_sleep + * + * PARAMETERS:  milliseconds        - Time to sleep + * + * RETURN:      Blocks until sleep is completed. + * + * DESCRIPTION: Sleep at millisecond granularity + * + *****************************************************************************/ + +void acpi_os_sleep(u64 milliseconds) +{ + +	/* Sleep for whole seconds */ + +	sleep(milliseconds / ACPI_MSEC_PER_SEC); + +	/* +	 * Sleep for remaining microseconds. +	 * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second). +	 */ +	usleep((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_get_timer + * + * PARAMETERS:  None + * + * RETURN:      Current time in 100 nanosecond units + * + * DESCRIPTION: Get the current system time + * + *****************************************************************************/ + +u64 acpi_os_get_timer(void) +{ +	struct timeval time; + +	/* This timer has sufficient resolution for user-space application code */ + +	gettimeofday(&time, NULL); + +	/* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */ + +	return (((u64)time.tv_sec * ACPI_100NSEC_PER_SEC) + +		((u64)time.tv_usec * ACPI_100NSEC_PER_USEC)); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_read_pci_configuration + * + * PARAMETERS:  pci_id              - Seg/Bus/Dev + *              pci_register        - Device Register + *              value               - Buffer where value is placed + *              width               - Number of bits + * + * RETURN:      Status + * + * DESCRIPTION: Read data from PCI configuration space + * + *****************************************************************************/ + +acpi_status +acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, +			       u32 pci_register, u64 *value, u32 width) +{ + +	*value = 0; +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_write_pci_configuration + * + * PARAMETERS:  pci_id              - Seg/Bus/Dev + *              pci_register        - Device Register + *              value               - Value to be written + *              width               - Number of bits + * + * RETURN:      Status. + * + * DESCRIPTION: Write data to PCI configuration space + * + *****************************************************************************/ + +acpi_status +acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, +				u32 pci_register, u64 value, u32 width) +{ + +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_read_port + * + * PARAMETERS:  address             - Address of I/O port/register to read + *              value               - Where value is placed + *              width               - Number of bits + * + * RETURN:      Value read from port + * + * DESCRIPTION: Read data from an I/O port or register + * + *****************************************************************************/ + +acpi_status acpi_os_read_port(acpi_io_address address, u32 *value, u32 width) +{ + +	switch (width) { +	case 8: + +		*value = 0xFF; +		break; + +	case 16: + +		*value = 0xFFFF; +		break; + +	case 32: + +		*value = 0xFFFFFFFF; +		break; + +	default: + +		return (AE_BAD_PARAMETER); +	} + +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_write_port + * + * PARAMETERS:  address             - Address of I/O port/register to write + *              value               - Value to write + *              width               - Number of bits + * + * RETURN:      None + * + * DESCRIPTION: Write data to an I/O port or register + * + *****************************************************************************/ + +acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width) +{ + +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_read_memory + * + * PARAMETERS:  address             - Physical Memory Address to read + *              value               - Where value is placed + *              width               - Number of bits (8,16,32, or 64) + * + * RETURN:      Value read from physical memory address. Always returned + *              as a 64-bit integer, regardless of the read width. + * + * DESCRIPTION: Read data from a physical memory address + * + *****************************************************************************/ + +acpi_status +acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width) +{ + +	switch (width) { +	case 8: +	case 16: +	case 32: +	case 64: + +		*value = 0; +		break; + +	default: + +		return (AE_BAD_PARAMETER); +	} +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_write_memory + * + * PARAMETERS:  address             - Physical Memory Address to write + *              value               - Value to write + *              width               - Number of bits (8,16,32, or 64) + * + * RETURN:      None + * + * DESCRIPTION: Write data to a physical memory address + * + *****************************************************************************/ + +acpi_status +acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width) +{ + +	return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_readable + * + * PARAMETERS:  pointer             - Area to be verified + *              length              - Size of area + * + * RETURN:      TRUE if readable for entire length + * + * DESCRIPTION: Verify that a pointer is valid for reading + * + *****************************************************************************/ + +u8 acpi_os_readable(void *pointer, acpi_size length) +{ + +	return (TRUE); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_writable + * + * PARAMETERS:  pointer             - Area to be verified + *              length              - Size of area + * + * RETURN:      TRUE if writable for entire length + * + * DESCRIPTION: Verify that a pointer is valid for writing + * + *****************************************************************************/ + +u8 acpi_os_writable(void *pointer, acpi_size length) +{ + +	return (TRUE); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_signal + * + * PARAMETERS:  function            - ACPI A signal function code + *              info                - Pointer to function-dependent structure + * + * RETURN:      Status + * + * DESCRIPTION: Miscellaneous functions. Example implementation only. + * + *****************************************************************************/ + +acpi_status acpi_os_signal(u32 function, void *info) +{ + +	switch (function) { +	case ACPI_SIGNAL_FATAL: + +		break; + +	case ACPI_SIGNAL_BREAKPOINT: + +		break; + +	default: + +		break; +	} + +	return (AE_OK); +} + +/* Optional multi-thread support */ + +#ifndef ACPI_SINGLE_THREADED +/****************************************************************************** + * + * FUNCTION:    acpi_os_get_thread_id + * + * PARAMETERS:  None + * + * RETURN:      Id of the running thread + * + * DESCRIPTION: Get the ID of the current (running) thread + * + *****************************************************************************/ + +acpi_thread_id acpi_os_get_thread_id(void) +{ +	pthread_t thread; + +	thread = pthread_self(); +	return (ACPI_CAST_PTHREAD_T(thread)); +} + +/****************************************************************************** + * + * FUNCTION:    acpi_os_execute + * + * PARAMETERS:  type                - Type of execution + *              function            - Address of the function to execute + *              context             - Passed as a parameter to the function + * + * RETURN:      Status. + * + * DESCRIPTION: Execute a new thread + * + *****************************************************************************/ + +acpi_status +acpi_os_execute(acpi_execute_type type, +		acpi_osd_exec_callback function, void *context) +{ +	pthread_t thread; +	int ret; + +	ret = +	    pthread_create(&thread, NULL, (PTHREAD_CALLBACK) function, context); +	if (ret) { +		acpi_os_printf("Create thread failed"); +	} +	return (0); +} + +#else				/* ACPI_SINGLE_THREADED */ +acpi_thread_id acpi_os_get_thread_id(void) +{ +	return (1); +} + +acpi_status +acpi_os_execute(acpi_execute_type type, +		acpi_osd_exec_callback function, void *context) +{ + +	function(context); + +	return (AE_OK); +} + +#endif				/* ACPI_SINGLE_THREADED */ + +/****************************************************************************** + * + * FUNCTION:    acpi_os_wait_events_complete + * + * PARAMETERS:  None + * + * RETURN:      None + * + * DESCRIPTION: Wait for all asynchronous events to complete. This + *              implementation does nothing. + * + *****************************************************************************/ + +void acpi_os_wait_events_complete(void) +{ +	return; +} diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h index 46f519597fe5..a2d37d610639 100644 --- a/tools/power/acpi/tools/acpidump/acpidump.h +++ b/tools/power/acpi/tools/acpidump/acpidump.h @@ -47,7 +47,6 @@  #ifdef _DECLARE_GLOBALS  #define EXTERN  #define INIT_GLOBAL(a,b)        a=b -#define DEFINE_ACPI_GLOBALS     1  #else  #define EXTERN                  extern  #define INIT_GLOBAL(a,b)        a @@ -69,7 +68,7 @@ EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE);  EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE);  EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE);  EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE); -EXTERN FILE INIT_GLOBAL(*gbl_output_file, NULL); +EXTERN ACPI_FILE INIT_GLOBAL(gbl_output_file, NULL);  EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL);  EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0); diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c index 3cac12378366..53cee781e24e 100644 --- a/tools/power/acpi/tools/acpidump/apdump.c +++ b/tools/power/acpi/tools/acpidump/apdump.c @@ -69,17 +69,16 @@ u8 ap_is_valid_header(struct acpi_table_header *table)  		/* Make sure signature is all ASCII and a valid ACPI name */  		if (!acpi_ut_valid_acpi_name(table->signature)) { -			fprintf(stderr, -				"Table signature (0x%8.8X) is invalid\n", -				*(u32 *)table->signature); +			acpi_log_error("Table signature (0x%8.8X) is invalid\n", +				       *(u32 *)table->signature);  			return (FALSE);  		}  		/* Check for minimum table length */  		if (table->length < sizeof(struct acpi_table_header)) { -			fprintf(stderr, "Table length (0x%8.8X) is invalid\n", -				table->length); +			acpi_log_error("Table length (0x%8.8X) is invalid\n", +				       table->length);  			return (FALSE);  		}  	} @@ -116,8 +115,8 @@ u8 ap_is_valid_checksum(struct acpi_table_header *table)  	}  	if (ACPI_FAILURE(status)) { -		fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n", -			table->signature); +		acpi_log_error("%4.4s: Warning: wrong checksum in table\n", +			       table->signature);  	}  	return (AE_OK); @@ -196,12 +195,13 @@ ap_dump_table_buffer(struct acpi_table_header *table,  	 * Note: simplest to just always emit a 64-bit address. acpi_xtract  	 * utility can handle this.  	 */ -	printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature, -	       ACPI_FORMAT_UINT64(address)); +	acpi_ut_file_printf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n", +			    table->signature, ACPI_FORMAT_UINT64(address)); -	acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length, -			    DB_BYTE_DISPLAY, 0); -	printf("\n"); +	acpi_ut_dump_buffer_to_file(gbl_output_file, +				    ACPI_CAST_PTR(u8, table), table_length, +				    DB_BYTE_DISPLAY, 0); +	acpi_ut_file_printf(gbl_output_file, "\n");  	return (0);  } @@ -239,20 +239,20 @@ int ap_dump_all_tables(void)  			if (status == AE_LIMIT) {  				return (0);  			} else if (i == 0) { -				fprintf(stderr, -					"Could not get ACPI tables, %s\n", -					acpi_format_exception(status)); +				acpi_log_error +				    ("Could not get ACPI tables, %s\n", +				     acpi_format_exception(status));  				return (-1);  			} else { -				fprintf(stderr, -					"Could not get ACPI table at index %u, %s\n", -					i, acpi_format_exception(status)); +				acpi_log_error +				    ("Could not get ACPI table at index %u, %s\n", +				     i, acpi_format_exception(status));  				continue;  			}  		}  		table_status = ap_dump_table_buffer(table, instance, address); -		free(table); +		ACPI_FREE(table);  		if (table_status) {  			break; @@ -288,22 +288,22 @@ int ap_dump_table_by_address(char *ascii_address)  	status = acpi_ut_strtoul64(ascii_address, 0, &long_address);  	if (ACPI_FAILURE(status)) { -		fprintf(stderr, "%s: Could not convert to a physical address\n", -			ascii_address); +		acpi_log_error("%s: Could not convert to a physical address\n", +			       ascii_address);  		return (-1);  	}  	address = (acpi_physical_address) long_address;  	status = acpi_os_get_table_by_address(address, &table);  	if (ACPI_FAILURE(status)) { -		fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n", -			ACPI_FORMAT_UINT64(address), -			acpi_format_exception(status)); +		acpi_log_error("Could not get table at 0x%8.8X%8.8X, %s\n", +			       ACPI_FORMAT_UINT64(address), +			       acpi_format_exception(status));  		return (-1);  	}  	table_status = ap_dump_table_buffer(table, 0, address); -	free(table); +	ACPI_FREE(table);  	return (table_status);  } @@ -329,24 +329,24 @@ int ap_dump_table_by_name(char *signature)  	acpi_status status;  	int table_status; -	if (strlen(signature) != ACPI_NAME_SIZE) { -		fprintf(stderr, -			"Invalid table signature [%s]: must be exactly 4 characters\n", -			signature); +	if (ACPI_STRLEN(signature) != ACPI_NAME_SIZE) { +		acpi_log_error +		    ("Invalid table signature [%s]: must be exactly 4 characters\n", +		     signature);  		return (-1);  	}  	/* Table signatures are expected to be uppercase */ -	strcpy(local_signature, signature); +	ACPI_STRCPY(local_signature, signature);  	acpi_ut_strupr(local_signature);  	/* To be friendly, handle tables whose signatures do not match the name */  	if (ACPI_COMPARE_NAME(local_signature, "FADT")) { -		strcpy(local_signature, ACPI_SIG_FADT); +		ACPI_STRCPY(local_signature, ACPI_SIG_FADT);  	} else if (ACPI_COMPARE_NAME(local_signature, "MADT")) { -		strcpy(local_signature, ACPI_SIG_MADT); +		ACPI_STRCPY(local_signature, ACPI_SIG_MADT);  	}  	/* Dump all instances of this signature (to handle multiple SSDTs) */ @@ -362,14 +362,14 @@ int ap_dump_table_by_name(char *signature)  				return (0);  			} -			fprintf(stderr, -				"Could not get ACPI table with signature [%s], %s\n", -				local_signature, acpi_format_exception(status)); +			acpi_log_error +			    ("Could not get ACPI table with signature [%s], %s\n", +			     local_signature, acpi_format_exception(status));  			return (-1);  		}  		table_status = ap_dump_table_buffer(table, instance, address); -		free(table); +		ACPI_FREE(table);  		if (table_status) {  			break; @@ -409,43 +409,21 @@ int ap_dump_table_from_file(char *pathname)  	/* File must be at least as long as the table length */  	if (table->length > file_size) { -		fprintf(stderr, -			"Table length (0x%X) is too large for input file (0x%X) %s\n", -			table->length, file_size, pathname); +		acpi_log_error +		    ("Table length (0x%X) is too large for input file (0x%X) %s\n", +		     table->length, file_size, pathname);  		goto exit;  	}  	if (gbl_verbose_mode) { -		fprintf(stderr, -			"Input file:  %s contains table [%4.4s], 0x%X (%u) bytes\n", -			pathname, table->signature, file_size, file_size); +		acpi_log_error +		    ("Input file:  %s contains table [%4.4s], 0x%X (%u) bytes\n", +		     pathname, table->signature, file_size, file_size);  	}  	table_status = ap_dump_table_buffer(table, 0, 0);  exit: -	free(table); +	ACPI_FREE(table);  	return (table_status);  } - -/****************************************************************************** - * - * FUNCTION:    acpi_os* print functions - * - * DESCRIPTION: Used for linkage with ACPICA modules - * - ******************************************************************************/ - -void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...) -{ -	va_list args; - -	va_start(args, fmt); -	vfprintf(stdout, fmt, args); -	va_end(args); -} - -void acpi_os_vprintf(const char *fmt, va_list args) -{ -	vfprintf(stdout, fmt, args); -} diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index 4488accc010b..d470046a6d81 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c @@ -44,6 +44,27 @@  #include "acpidump.h"  #include "acapps.h" +/* Local prototypes */ + +static int ap_is_existing_file(char *pathname); + +static int ap_is_existing_file(char *pathname) +{ +#ifndef _GNU_EFI +	struct stat stat_info; + +	if (!stat(pathname, &stat_info)) { +		acpi_log_error("Target path already exists, overwrite? [y|n] "); + +		if (getchar() != 'y') { +			return (-1); +		} +	} +#endif + +	return 0; +} +  /******************************************************************************   *   * FUNCTION:    ap_open_output_file @@ -59,25 +80,19 @@  int ap_open_output_file(char *pathname)  { -	struct stat stat_info; -	FILE *file; +	ACPI_FILE file;  	/* If file exists, prompt for overwrite */ -	if (!stat(pathname, &stat_info)) { -		fprintf(stderr, -			"Target path already exists, overwrite? [y|n] "); - -		if (getchar() != 'y') { -			return (-1); -		} +	if (ap_is_existing_file(pathname) != 0) { +		return (-1);  	}  	/* Point stdout to the file */ -	file = freopen(pathname, "w", stdout); +	file = acpi_os_open_file(pathname, ACPI_FILE_WRITING);  	if (!file) { -		perror("Could not open output file"); +		acpi_log_error("Could not open output file: %s\n", pathname);  		return (-1);  	} @@ -106,7 +121,7 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)  {  	char filename[ACPI_NAME_SIZE + 16];  	char instance_str[16]; -	FILE *file; +	ACPI_FILE file;  	size_t actual;  	u32 table_length; @@ -130,35 +145,37 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)  	/* Handle multiple SSDts - create different filenames for each */  	if (instance > 0) { -		sprintf(instance_str, "%u", instance); -		strcat(filename, instance_str); +		acpi_ut_snprintf(instance_str, sizeof(instance_str), "%u", +				 instance); +		ACPI_STRCAT(filename, instance_str);  	} -	strcat(filename, ACPI_TABLE_FILE_SUFFIX); +	ACPI_STRCAT(filename, ACPI_TABLE_FILE_SUFFIX);  	if (gbl_verbose_mode) { -		fprintf(stderr, -			"Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", -			table->signature, filename, table->length, -			table->length); +		acpi_log_error +		    ("Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", +		     table->signature, filename, table->length, table->length);  	}  	/* Open the file and dump the entire table in binary mode */ -	file = fopen(filename, "wb"); +	file = acpi_os_open_file(filename, +				 ACPI_FILE_WRITING | ACPI_FILE_BINARY);  	if (!file) { -		perror("Could not open output file"); +		acpi_log_error("Could not open output file: %s\n", filename);  		return (-1);  	} -	actual = fwrite(table, 1, table_length, file); +	actual = acpi_os_write_file(file, table, 1, table_length);  	if (actual != table_length) { -		perror("Error writing binary output file"); -		fclose(file); +		acpi_log_error("Error writing binary output file: %s\n", +			       filename); +		acpi_os_close_file(file);  		return (-1);  	} -	fclose(file); +	acpi_os_close_file(file);  	return (0);  } @@ -179,15 +196,16 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,  						 u32 *out_file_size)  {  	struct acpi_table_header *buffer = NULL; -	FILE *file; +	ACPI_FILE file;  	u32 file_size;  	size_t actual;  	/* Must use binary mode */ -	file = fopen(pathname, "rb"); +	file = +	    acpi_os_open_file(pathname, ACPI_FILE_READING | ACPI_FILE_BINARY);  	if (!file) { -		perror("Could not open input file"); +		acpi_log_error("Could not open input file: %s\n", pathname);  		return (NULL);  	} @@ -195,27 +213,25 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,  	file_size = cm_get_file_size(file);  	if (file_size == ACPI_UINT32_MAX) { -		fprintf(stderr, -			"Could not get input file size: %s\n", pathname); +		acpi_log_error("Could not get input file size: %s\n", pathname);  		goto cleanup;  	}  	/* Allocate a buffer for the entire file */ -	buffer = calloc(1, file_size); +	buffer = ACPI_ALLOCATE_ZEROED(file_size);  	if (!buffer) { -		fprintf(stderr, -			"Could not allocate file buffer of size: %u\n", -			file_size); +		acpi_log_error("Could not allocate file buffer of size: %u\n", +			       file_size);  		goto cleanup;  	}  	/* Read the entire file */ -	actual = fread(buffer, 1, file_size, file); +	actual = acpi_os_read_file(file, buffer, 1, file_size);  	if (actual != file_size) { -		fprintf(stderr, "Could not read input file: %s\n", pathname); -		free(buffer); +		acpi_log_error("Could not read input file: %s\n", pathname); +		ACPI_FREE(buffer);  		buffer = NULL;  		goto cleanup;  	} @@ -223,6 +239,6 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,  	*out_file_size = file_size;  cleanup: -	fclose(file); +	acpi_os_close_file(file);  	return (buffer);  } diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index 51e8d638db18..853b4da22c3e 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c @@ -72,7 +72,7 @@ static void ap_display_usage(void);  static int ap_do_options(int argc, char **argv); -static void ap_insert_action(char *argument, u32 to_be_done); +static int ap_insert_action(char *argument, u32 to_be_done);  /* Table for deferred actions from command line options */ @@ -104,7 +104,7 @@ static void ap_display_usage(void)  	ACPI_OPTION("-v", "Display version information");  	ACPI_OPTION("-z", "Verbose mode"); -	printf("\nTable Options:\n"); +	ACPI_USAGE_TEXT("\nTable Options:\n");  	ACPI_OPTION("-a <Address>", "Get table via a physical address");  	ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file"); @@ -112,9 +112,9 @@ static void ap_display_usage(void)  	ACPI_OPTION("-x", "Do not use but dump XSDT");  	ACPI_OPTION("-x -x", "Do not use or dump XSDT"); -	printf("\n" -	       "Invocation without parameters dumps all available tables\n" -	       "Multiple mixed instances of -a, -f, and -n are supported\n\n"); +	ACPI_USAGE_TEXT("\n" +			"Invocation without parameters dumps all available tables\n" +			"Multiple mixed instances of -a, -f, and -n are supported\n\n");  }  /****************************************************************************** @@ -124,13 +124,13 @@ static void ap_display_usage(void)   * PARAMETERS:  argument            - Pointer to the argument for this action   *              to_be_done          - What to do to process this action   * - * RETURN:      None. Exits program if action table becomes full. + * RETURN:      Status   *   * DESCRIPTION: Add an action item to the action table   *   ******************************************************************************/ -static void ap_insert_action(char *argument, u32 to_be_done) +static int ap_insert_action(char *argument, u32 to_be_done)  {  	/* Insert action and check for table overflow */ @@ -140,10 +140,12 @@ static void ap_insert_action(char *argument, u32 to_be_done)  	current_action++;  	if (current_action > AP_MAX_ACTIONS) { -		fprintf(stderr, "Too many table options (max %u)\n", -			AP_MAX_ACTIONS); -		exit(-1); +		acpi_log_error("Too many table options (max %u)\n", +			       AP_MAX_ACTIONS); +		return (-1);  	} + +	return (0);  }  /****************************************************************************** @@ -166,7 +168,8 @@ static int ap_do_options(int argc, char **argv)  	/* Command line options */ -	while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF) +	while ((j = +		acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END)  		switch (j) {  			/*  			 * Global options @@ -185,12 +188,12 @@ static int ap_do_options(int argc, char **argv)  		case '?':  			ap_display_usage(); -			exit(0); +			return (1);  		case 'o':	/* Redirect output to a single file */  			if (ap_open_output_file(acpi_gbl_optarg)) { -				exit(-1); +				return (-1);  			}  			continue; @@ -200,10 +203,10 @@ static int ap_do_options(int argc, char **argv)  			    acpi_ut_strtoul64(acpi_gbl_optarg, 0,  					      &gbl_rsdp_base);  			if (ACPI_FAILURE(status)) { -				fprintf(stderr, -					"%s: Could not convert to a physical address\n", -					acpi_gbl_optarg); -				exit(-1); +				acpi_log_error +				    ("%s: Could not convert to a physical address\n", +				     acpi_gbl_optarg); +				return (-1);  			}  			continue; @@ -223,13 +226,13 @@ static int ap_do_options(int argc, char **argv)  		case 'v':	/* Revision/version */ -			printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); -			exit(0); +			acpi_os_printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); +			return (1);  		case 'z':	/* Verbose mode */  			gbl_verbose_mode = TRUE; -			fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); +			acpi_log_error(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));  			continue;  			/* @@ -237,32 +240,40 @@ static int ap_do_options(int argc, char **argv)  			 */  		case 'a':	/* Get table by physical address */ -			ap_insert_action(acpi_gbl_optarg, -					 AP_DUMP_TABLE_BY_ADDRESS); +			if (ap_insert_action +			    (acpi_gbl_optarg, AP_DUMP_TABLE_BY_ADDRESS)) { +				return (-1); +			}  			break;  		case 'f':	/* Get table from a file */ -			ap_insert_action(acpi_gbl_optarg, -					 AP_DUMP_TABLE_BY_FILE); +			if (ap_insert_action +			    (acpi_gbl_optarg, AP_DUMP_TABLE_BY_FILE)) { +				return (-1); +			}  			break;  		case 'n':	/* Get table by input name (signature) */ -			ap_insert_action(acpi_gbl_optarg, -					 AP_DUMP_TABLE_BY_NAME); +			if (ap_insert_action +			    (acpi_gbl_optarg, AP_DUMP_TABLE_BY_NAME)) { +				return (-1); +			}  			break;  		default:  			ap_display_usage(); -			exit(-1); +			return (-1);  		}  	/* If there are no actions, this means "get/dump all tables" */  	if (current_action == 0) { -		ap_insert_action(NULL, AP_DUMP_ALL_TABLES); +		if (ap_insert_action(NULL, AP_DUMP_ALL_TABLES)) { +			return (-1); +		}  	}  	return (0); @@ -280,7 +291,11 @@ static int ap_do_options(int argc, char **argv)   *   ******************************************************************************/ +#ifndef _GNU_EFI  int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) +#else +int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[]) +#endif  {  	int status = 0;  	struct ap_dump_action *action; @@ -288,11 +303,17 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])  	u32 i;  	ACPI_DEBUG_INITIALIZE();	/* For debug version only */ +	acpi_os_initialize(); +	gbl_output_file = ACPI_FILE_OUT;  	/* Process command line options */ -	if (ap_do_options(argc, argv)) { -		return (-1); +	status = ap_do_options(argc, argv); +	if (status > 0) { +		return (0); +	} +	if (status < 0) { +		return (status);  	}  	/* Get/dump ACPI table(s) as requested */ @@ -322,9 +343,8 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])  		default: -			fprintf(stderr, -				"Internal error, invalid action: 0x%X\n", -				action->to_be_done); +			acpi_log_error("Internal error, invalid action: 0x%X\n", +				       action->to_be_done);  			return (-1);  		} @@ -333,18 +353,18 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])  		}  	} -	if (gbl_output_file) { +	if (gbl_output_filename) {  		if (gbl_verbose_mode) {  			/* Summary for the output file */  			file_size = cm_get_file_size(gbl_output_file); -			fprintf(stderr, -				"Output file %s contains 0x%X (%u) bytes\n\n", -				gbl_output_filename, file_size, file_size); +			acpi_log_error +			    ("Output file %s contains 0x%X (%u) bytes\n\n", +			     gbl_output_filename, file_size, file_size);  		} -		fclose(gbl_output_file); +		acpi_os_close_file(gbl_output_file);  	}  	return (status);  | 
