⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amfldio.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Module Name: amfldio - Aml Field I/O *              $Revision: 32 $ * *****************************************************************************//* *  Copyright (C) 2000 R. Byron Moore * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "acpi.h"#include "acinterp.h"#include "amlcode.h"#include "acnamesp.h"#include "achware.h"#include "acevents.h"#define _COMPONENT          INTERPRETER	 MODULE_NAME         ("amfldio")/******************************************************************************* * * FUNCTION:    Acpi_aml_read_field_data * * PARAMETERS:  *Obj_desc           - Field to be read *              *Value              - Where to store value *              Field_bit_width     - Field Width in bits (8, 16, or 32) * * RETURN:      Status * * DESCRIPTION: Retrieve the value of the given field * ******************************************************************************/ACPI_STATUSacpi_aml_read_field_data (	ACPI_OPERAND_OBJECT     *obj_desc,	u32                     field_byte_offset,	u32                     field_bit_width,	u32                     *value){	ACPI_STATUS             status;	ACPI_OPERAND_OBJECT     *rgn_desc = NULL;	ACPI_PHYSICAL_ADDRESS   address;	u32                     local_value = 0;	u32                     field_byte_width;	/* Obj_desc is validated by callers */	if (obj_desc) {		rgn_desc = obj_desc->field.container;	}	field_byte_width = DIV_8 (field_bit_width);	status = acpi_aml_setup_field (obj_desc, rgn_desc, field_bit_width);	if (ACPI_FAILURE (status)) {		return (status);	}	/* Setup_field validated Rgn_desc and Field_bit_width */	if (!value) {		value = &local_value;   /*  support reads without saving value  */	}	/*	 * Set offset to next multiple of field width,	 *  add region base address and offset within the field	 */	address = rgn_desc->region.address +			  (obj_desc->field.offset * field_byte_width) +			  field_byte_offset;	/* Invoke the appropriate Address_space/Op_region handler */	status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ,			 address, field_bit_width, value);	return (status);}/******************************************************************************* * * FUNCTION:    Acpi_aml_read_field * * PARAMETERS:  *Obj_desc           - Field to be read *              *Value              - Where to store value *              Field_bit_width     - Field Width in bits (8, 16, or 32) * * RETURN:      Status * * DESCRIPTION: Retrieve the value of the given field * ******************************************************************************/ACPI_STATUSacpi_aml_read_field (	ACPI_OPERAND_OBJECT     *obj_desc,	void                    *buffer,	u32                     buffer_length,	u32                     byte_length,	u32                     datum_length,	u32                     bit_granularity,	u32                     byte_granularity){	ACPI_STATUS             status;	u32                     this_field_byte_offset;	u32                     this_field_datum_offset;	u32                     previous_raw_datum;	u32                     this_raw_datum;	u32                     valid_field_bits;	u32                     mask;	u32                     merged_datum = 0;	/*	 * Clear the caller's buffer (the whole buffer length as given)	 * This is very important, especially in the cases where a byte is read,	 * but the buffer is really a u32 (4 bytes).	 */	MEMSET (buffer, 0, buffer_length);	/* Read the first raw datum to prime the loop */	this_field_byte_offset = 0;	this_field_datum_offset= 0;	status = acpi_aml_read_field_data (obj_desc, this_field_byte_offset, bit_granularity,			   &previous_raw_datum);	if (ACPI_FAILURE (status)) {		goto cleanup;	}	/* We might actually be done if the request fits in one datum */	if ((datum_length == 1) &&		((obj_desc->field.bit_offset + obj_desc->field_unit.length) <=			(u16) bit_granularity))	{		merged_datum = previous_raw_datum;		merged_datum = (merged_datum >> obj_desc->field.bit_offset);		valid_field_bits = obj_desc->field_unit.length % bit_granularity;		if (valid_field_bits) {			mask = (((u32) 1 << valid_field_bits) - (u32) 1);			merged_datum &= mask;		}		/*		 * Place the Merged_datum into the proper format and return buffer		 * field		 */		switch (byte_granularity)		{		case 1:			((u8 *) buffer) [this_field_datum_offset] = (u8) merged_datum;			break;		case 2:			MOVE_UNALIGNED16_TO_16 (&(((u16 *) buffer)[this_field_datum_offset]), &merged_datum);			break;		case 4:			MOVE_UNALIGNED32_TO_32 (&(((u32 *) buffer)[this_field_datum_offset]), &merged_datum);			break;		}		this_field_byte_offset = 1;		this_field_datum_offset = 1;	}	else {		/* We need to get more raw data to complete one or more field data */		while (this_field_datum_offset < datum_length) {			/*			 * Get the next raw datum, it contains bits of the current			 * field datum			 */			status = acpi_aml_read_field_data (obj_desc,					  this_field_byte_offset + byte_granularity,					  bit_granularity, &this_raw_datum);			if (ACPI_FAILURE (status)) {				goto cleanup;			}			/* Before merging the data, make sure the unused bits are clear */			switch (byte_granularity)			{			case 1:				this_raw_datum &= 0x000000FF;				previous_raw_datum &= 0x000000FF;				break;			case 2:				this_raw_datum &= 0x0000FFFF;				previous_raw_datum &= 0x0000FFFF;				break;			}			/*			 * Put together bits of the two raw data to make a complete			 * field datum			 */			if (obj_desc->field.bit_offset != 0) {				merged_datum =					(previous_raw_datum >> obj_desc->field.bit_offset) |					(this_raw_datum << (bit_granularity - obj_desc->field.bit_offset));			}			else {				merged_datum = previous_raw_datum;			}			/*			 * Prepare the merged datum for storing into the caller's			 *  buffer.  It is possible to have a 32-bit buffer			 *  (Byte_granularity == 4), but a Obj_desc->Field.Length			 *  of 8 or 16, meaning that the upper bytes of merged data			 *  are undesired.  This section fixes that.			 */			switch (obj_desc->field.length)			{			case 8:				merged_datum &= 0x000000FF;				break;			case 16:				merged_datum &= 0x0000FFFF;				break;			}			/*			 * Now store the datum in the caller's buffer, according to			 * the data type			 */			switch (byte_granularity)			{			case 1:				((u8 *) buffer) [this_field_datum_offset] = (u8) merged_datum;				break;			case 2:				MOVE_UNALIGNED16_TO_16 (&(((u16 *) buffer) [this_field_datum_offset]), &merged_datum);				break;			case 4:				MOVE_UNALIGNED32_TO_32 (&(((u32 *) buffer) [this_field_datum_offset]), &merged_datum);				break;			}			/*			 * Save the most recent datum since it contains bits of			 * the *next* field datum			 */			previous_raw_datum = this_raw_datum;			this_field_byte_offset += byte_granularity;			this_field_datum_offset++;		}  /* while */	}cleanup:	return (status);}/******************************************************************************* * * FUNCTION:    Acpi_aml_write_field_data * * PARAMETERS:  *Obj_desc           - Field to be set *              Value               - Value to store *              Field_bit_width     - Field Width in bits (8, 16, or 32) * * RETURN:      Status * * DESCRIPTION: Store the value into the given field * ******************************************************************************/static ACPI_STATUSacpi_aml_write_field_data (	ACPI_OPERAND_OBJECT     *obj_desc,	u32                     field_byte_offset,	u32                     field_bit_width,	u32                     value){	ACPI_STATUS             status = AE_OK;	ACPI_OPERAND_OBJECT     *rgn_desc = NULL;	ACPI_PHYSICAL_ADDRESS   address;	u32                     field_byte_width;	/* Obj_desc is validated by callers */	if (obj_desc) {		rgn_desc = obj_desc->field.container;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -