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

📄 exfldio.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		status =		    acpi_ex_insert_into_field(obj_desc->bank_field.bank_obj,					      &obj_desc->bank_field.value,					      sizeof(obj_desc->bank_field.						     value));		if (ACPI_FAILURE(status)) {			return_ACPI_STATUS(status);		}		/*		 * Now that the Bank has been selected, fall through to the		 * region_field case and write the datum to the Operation Region		 */		/*lint -fallthrough */	case ACPI_TYPE_LOCAL_REGION_FIELD:		/*		 * For simple region_fields, we just directly access the owning		 * Operation Region.		 */		status =		    acpi_ex_access_region(obj_desc, field_datum_byte_offset,					  value, read_write);		break;	case ACPI_TYPE_LOCAL_INDEX_FIELD:		/*		 * Ensure that the index_value is not beyond the capacity of		 * the register		 */		if (acpi_ex_register_overflow(obj_desc->index_field.index_obj,					      (acpi_integer) obj_desc->					      index_field.value)) {			return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);		}		/* Write the index value to the index_register (itself a region_field) */		field_datum_byte_offset += obj_desc->index_field.value;		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,				  "Write to Index Register: Value %8.8X\n",				  field_datum_byte_offset));		status =		    acpi_ex_insert_into_field(obj_desc->index_field.index_obj,					      &field_datum_byte_offset,					      sizeof(field_datum_byte_offset));		if (ACPI_FAILURE(status)) {			return_ACPI_STATUS(status);		}		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,				  "I/O to Data Register: value_ptr %p\n",				  value));		if (read_write == ACPI_READ) {			/* Read the datum from the data_register */			status =			    acpi_ex_extract_from_field(obj_desc->index_field.						       data_obj, value,						       sizeof(acpi_integer));		} else {			/* Write the datum to the data_register */			status =			    acpi_ex_insert_into_field(obj_desc->index_field.						      data_obj, value,						      sizeof(acpi_integer));		}		break;	default:		ACPI_REPORT_ERROR(("Wrong object type in field I/O %X\n",				   ACPI_GET_OBJECT_TYPE(obj_desc)));		status = AE_AML_INTERNAL;		break;	}	if (ACPI_SUCCESS(status)) {		if (read_write == ACPI_READ) {			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,					  "Value Read %8.8X%8.8X, Width %d\n",					  ACPI_FORMAT_UINT64(*value),					  obj_desc->common_field.					  access_byte_width));		} else {			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,					  "Value Written %8.8X%8.8X, Width %d\n",					  ACPI_FORMAT_UINT64(*value),					  obj_desc->common_field.					  access_byte_width));		}	}	return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION:    acpi_ex_write_with_update_rule * * PARAMETERS:  obj_desc                - Field to be written *              Mask                    - bitmask within field datum *              field_value             - Value to write *              field_datum_byte_offset - Offset of datum within field * * RETURN:      Status * * DESCRIPTION: Apply the field update rule to a field write * ******************************************************************************/acpi_statusacpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,			       acpi_integer mask,			       acpi_integer field_value,			       u32 field_datum_byte_offset){	acpi_status status = AE_OK;	acpi_integer merged_value;	acpi_integer current_value;	ACPI_FUNCTION_TRACE_U32("ex_write_with_update_rule", mask);	/* Start with the new bits  */	merged_value = field_value;	/* If the mask is all ones, we don't need to worry about the update rule */	if (mask != ACPI_INTEGER_MAX) {		/* Decode the update rule */		switch (obj_desc->common_field.			field_flags & AML_FIELD_UPDATE_RULE_MASK) {		case AML_FIELD_UPDATE_PRESERVE:			/*			 * Check if update rule needs to be applied (not if mask is all			 * ones)  The left shift drops the bits we want to ignore.			 */			if ((~mask << (ACPI_MUL_8(sizeof(mask)) -				       ACPI_MUL_8(obj_desc->common_field.						  access_byte_width))) != 0) {				/*				 * Read the current contents of the byte/word/dword containing				 * the field, and merge with the new field value.				 */				status =				    acpi_ex_field_datum_io(obj_desc,							   field_datum_byte_offset,							   &current_value,							   ACPI_READ);				if (ACPI_FAILURE(status)) {					return_ACPI_STATUS(status);				}				merged_value |= (current_value & ~mask);			}			break;		case AML_FIELD_UPDATE_WRITE_AS_ONES:			/* Set positions outside the field to all ones */			merged_value |= ~mask;			break;		case AML_FIELD_UPDATE_WRITE_AS_ZEROS:			/* Set positions outside the field to all zeros */			merged_value &= mask;			break;		default:			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,					  "write_with_update_rule: Unknown update_rule setting: %X\n",					  (obj_desc->common_field.					   field_flags &					   AML_FIELD_UPDATE_RULE_MASK)));			return_ACPI_STATUS(AE_AML_OPERAND_VALUE);		}	}	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,			  "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",			  ACPI_FORMAT_UINT64(mask),			  field_datum_byte_offset,			  obj_desc->common_field.access_byte_width,			  ACPI_FORMAT_UINT64(field_value),			  ACPI_FORMAT_UINT64(merged_value)));	/* Write the merged value */	status = acpi_ex_field_datum_io(obj_desc, field_datum_byte_offset,					&merged_value, ACPI_WRITE);	return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION:    acpi_ex_extract_from_field * * PARAMETERS:  obj_desc            - Field to be read *              Buffer              - Where to store the field data *              buffer_length       - Length of Buffer * * RETURN:      Status * * DESCRIPTION: Retrieve the current value of the given field * ******************************************************************************/acpi_statusacpi_ex_extract_from_field(union acpi_operand_object *obj_desc,			   void *buffer, u32 buffer_length){	acpi_status status;	acpi_integer raw_datum;	acpi_integer merged_datum;	u32 field_offset = 0;	u32 buffer_offset = 0;	u32 buffer_tail_bits;	u32 datum_count;	u32 field_datum_count;	u32 i;	ACPI_FUNCTION_TRACE("ex_extract_from_field");	/* Validate target buffer and clear it */	if (buffer_length <	    ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,				  "Field size %X (bits) is too large for buffer (%X)\n",				  obj_desc->common_field.bit_length,				  buffer_length));		return_ACPI_STATUS(AE_BUFFER_OVERFLOW);	}	ACPI_MEMSET(buffer, 0, buffer_length);	/* Compute the number of datums (access width data items) */	datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,				       obj_desc->common_field.access_bit_width);	field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +					     obj_desc->common_field.					     start_field_bit_offset,					     obj_desc->common_field.					     access_bit_width);	/* Priming read from the field */	status =	    acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum,				   ACPI_READ);	if (ACPI_FAILURE(status)) {		return_ACPI_STATUS(status);	}	merged_datum =	    raw_datum >> obj_desc->common_field.start_field_bit_offset;	/* Read the rest of the field */	for (i = 1; i < field_datum_count; i++) {		/* Get next input datum from the field */		field_offset += obj_desc->common_field.access_byte_width;		status = acpi_ex_field_datum_io(obj_desc, field_offset,						&raw_datum, ACPI_READ);		if (ACPI_FAILURE(status)) {			return_ACPI_STATUS(status);		}		/* Merge with previous datum if necessary */		merged_datum |= raw_datum <<		    (obj_desc->common_field.access_bit_width -		     obj_desc->common_field.start_field_bit_offset);		if (i == datum_count) {			break;		}		/* Write merged datum to target buffer */		ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,			    ACPI_MIN(obj_desc->common_field.access_byte_width,				     buffer_length - buffer_offset));		buffer_offset += obj_desc->common_field.access_byte_width;		merged_datum =		    raw_datum >> obj_desc->common_field.start_field_bit_offset;	}	/* Mask off any extra bits in the last datum */	buffer_tail_bits = obj_desc->common_field.bit_length %	    obj_desc->common_field.access_bit_width;	if (buffer_tail_bits) {		merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);	}	/* Write the last datum to the buffer */	ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,		    ACPI_MIN(obj_desc->common_field.access_byte_width,			     buffer_length - buffer_offset));	return_ACPI_STATUS(AE_OK);}/******************************************************************************* * * FUNCTION:    acpi_ex_insert_into_field * * PARAMETERS:  obj_desc            - Field to be written *              Buffer              - Data to be written *              buffer_length       - Length of Buffer * * RETURN:      Status * * DESCRIPTION: Store the Buffer contents into the given field * ******************************************************************************/acpi_statusacpi_ex_insert_into_field(union acpi_operand_object *obj_desc,			  void *buffer, u32 buffer_length){	acpi_status status;	acpi_integer mask;	acpi_integer merged_datum;	acpi_integer raw_datum = 0;	u32 field_offset = 0;	u32 buffer_offset = 0;	u32 buffer_tail_bits;	u32 datum_count;	u32 field_datum_count;	u32 i;	ACPI_FUNCTION_TRACE("ex_insert_into_field");	/* Validate input buffer */	if (buffer_length <	    ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,				  "Field size %X (bits) is too large for buffer (%X)\n",				  obj_desc->common_field.bit_length,				  buffer_length));		return_ACPI_STATUS(AE_BUFFER_OVERFLOW);	}	/* Compute the number of datums (access width data items) */	mask =	    ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);	datum_count =	    ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,			     obj_desc->common_field.access_bit_width);	field_datum_count =	    ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +			     obj_desc->common_field.start_field_bit_offset,			     obj_desc->common_field.access_bit_width);	/* Get initial Datum from the input buffer */	ACPI_MEMCPY(&raw_datum, buffer,		    ACPI_MIN(obj_desc->common_field.access_byte_width,			     buffer_length - buffer_offset));	merged_datum =	    raw_datum << obj_desc->common_field.start_field_bit_offset;	/* Write the entire field */	for (i = 1; i < field_datum_count; i++) {		/* Write merged datum to the target field */		merged_datum &= mask;		status = acpi_ex_write_with_update_rule(obj_desc, mask,							merged_datum,							field_offset);		if (ACPI_FAILURE(status)) {			return_ACPI_STATUS(status);		}		/* Start new output datum by merging with previous input datum */		field_offset += obj_desc->common_field.access_byte_width;		merged_datum = raw_datum >>		    (obj_desc->common_field.access_bit_width -		     obj_desc->common_field.start_field_bit_offset);		mask = ACPI_INTEGER_MAX;		if (i == datum_count) {			break;		}		/* Get the next input datum from the buffer */		buffer_offset += obj_desc->common_field.access_byte_width;		ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,			    ACPI_MIN(obj_desc->common_field.access_byte_width,				     buffer_length - buffer_offset));		merged_datum |=		    raw_datum << obj_desc->common_field.start_field_bit_offset;	}	/* Mask off any extra bits in the last datum */	buffer_tail_bits = (obj_desc->common_field.bit_length +			    obj_desc->common_field.start_field_bit_offset) %	    obj_desc->common_field.access_bit_width;	if (buffer_tail_bits) {		mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);	}	/* Write the last datum to the field */	merged_datum &= mask;	status = acpi_ex_write_with_update_rule(obj_desc,						mask, merged_datum,						field_offset);	return_ACPI_STATUS(status);}

⌨️ 快捷键说明

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