rscalc.c

来自「linux 内核源代码」· C语言 代码 · 共 598 行 · 第 1/2 页

C
598
字号
		}		/* Update the total */		aml_size_needed += total_size;		/* Point to the next object */		resource =		    ACPI_ADD_PTR(struct acpi_resource, resource,				 resource->length);	}	/* Did not find an end_tag resource descriptor */	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);}/******************************************************************************* * * FUNCTION:    acpi_rs_get_list_length * * PARAMETERS:  aml_buffer          - Pointer to the resource byte stream *              aml_buffer_length   - Size of aml_buffer *              size_needed         - Where the size needed is returned * * RETURN:      Status * * DESCRIPTION: Takes an external resource byte stream and calculates the size *              buffer needed to hold the corresponding internal resource *              descriptor linked list. * ******************************************************************************/acpi_statusacpi_rs_get_list_length(u8 * aml_buffer,			u32 aml_buffer_length, acpi_size * size_needed){	acpi_status status;	u8 *end_aml;	u8 *buffer;	u32 buffer_size;	u16 temp16;	u16 resource_length;	u32 extra_struct_bytes;	u8 resource_index;	u8 minimum_aml_resource_length;	ACPI_FUNCTION_TRACE(rs_get_list_length);	*size_needed = 0;	end_aml = aml_buffer + aml_buffer_length;	/* Walk the list of AML resource descriptors */	while (aml_buffer < end_aml) {		/* Validate the Resource Type and Resource Length */		status = acpi_ut_validate_resource(aml_buffer, &resource_index);		if (ACPI_FAILURE(status)) {			return_ACPI_STATUS(status);		}		/* Get the resource length and base (minimum) AML size */		resource_length = acpi_ut_get_resource_length(aml_buffer);		minimum_aml_resource_length =		    acpi_gbl_resource_aml_sizes[resource_index];		/*		 * Augment the size for descriptors with optional		 * and/or variable length fields		 */		extra_struct_bytes = 0;		buffer =		    aml_buffer + acpi_ut_get_resource_header_length(aml_buffer);		switch (acpi_ut_get_resource_type(aml_buffer)) {		case ACPI_RESOURCE_NAME_IRQ:			/*			 * IRQ Resource:			 * Get the number of bits set in the 16-bit IRQ mask			 */			ACPI_MOVE_16_TO_16(&temp16, buffer);			extra_struct_bytes = acpi_rs_count_set_bits(temp16);			break;		case ACPI_RESOURCE_NAME_DMA:			/*			 * DMA Resource:			 * Get the number of bits set in the 8-bit DMA mask			 */			extra_struct_bytes = acpi_rs_count_set_bits(*buffer);			break;		case ACPI_RESOURCE_NAME_VENDOR_SMALL:		case ACPI_RESOURCE_NAME_VENDOR_LARGE:			/*			 * Vendor Resource:			 * Get the number of vendor data bytes			 */			extra_struct_bytes = resource_length;			break;		case ACPI_RESOURCE_NAME_END_TAG:			/*			 * End Tag:			 * This is the normal exit, add size of end_tag			 */			*size_needed += ACPI_RS_SIZE_MIN;			return_ACPI_STATUS(AE_OK);		case ACPI_RESOURCE_NAME_ADDRESS32:		case ACPI_RESOURCE_NAME_ADDRESS16:		case ACPI_RESOURCE_NAME_ADDRESS64:			/*			 * Address Resource:			 * Add the size of the optional resource_source			 */			extra_struct_bytes =			    acpi_rs_stream_option_length(resource_length,							 minimum_aml_resource_length);			break;		case ACPI_RESOURCE_NAME_EXTENDED_IRQ:			/*			 * Extended IRQ Resource:			 * Using the interrupt_table_length, add 4 bytes for each additional			 * interrupt. Note: at least one interrupt is required and is			 * included in the minimum descriptor size (reason for the -1)			 */			extra_struct_bytes = (buffer[1] - 1) * sizeof(u32);			/* Add the size of the optional resource_source */			extra_struct_bytes +=			    acpi_rs_stream_option_length(resource_length -							 extra_struct_bytes,							 minimum_aml_resource_length);			break;		default:			break;		}		/*		 * Update the required buffer size for the internal descriptor structs		 *		 * Important: Round the size up for the appropriate alignment. This		 * is a requirement on IA64.		 */		buffer_size = acpi_gbl_resource_struct_sizes[resource_index] +		    extra_struct_bytes;		buffer_size = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);		*size_needed += buffer_size;		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,				  "Type %.2X, AmlLength %.2X InternalLength %.2X\n",				  acpi_ut_get_resource_type(aml_buffer),				  acpi_ut_get_descriptor_length(aml_buffer),				  buffer_size));		/*		 * Point to the next resource within the AML stream using the length		 * contained in the resource descriptor header		 */		aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);	}	/* Did not find an end_tag resource descriptor */	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);}/******************************************************************************* * * FUNCTION:    acpi_rs_get_pci_routing_table_length * * PARAMETERS:  package_object          - Pointer to the package object *              buffer_size_needed      - u32 pointer of the size buffer *                                        needed to properly return the *                                        parsed data * * RETURN:      Status * * DESCRIPTION: Given a package representing a PCI routing table, this *              calculates the size of the corresponding linked list of *              descriptions. * ******************************************************************************/acpi_statusacpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,				     acpi_size * buffer_size_needed){	u32 number_of_elements;	acpi_size temp_size_needed = 0;	union acpi_operand_object **top_object_list;	u32 index;	union acpi_operand_object *package_element;	union acpi_operand_object **sub_object_list;	u8 name_found;	u32 table_index;	ACPI_FUNCTION_TRACE(rs_get_pci_routing_table_length);	number_of_elements = package_object->package.count;	/*	 * Calculate the size of the return buffer.	 * The base size is the number of elements * the sizes of the	 * structures.  Additional space for the strings is added below.	 * The minus one is to subtract the size of the u8 Source[1]	 * member because it is added below.	 *	 * But each PRT_ENTRY structure has a pointer to a string and	 * the size of that string must be found.	 */	top_object_list = package_object->package.elements;	for (index = 0; index < number_of_elements; index++) {		/* Dereference the sub-package */		package_element = *top_object_list;		/*		 * The sub_object_list will now point to an array of the		 * four IRQ elements: Address, Pin, Source and source_index		 */		sub_object_list = package_element->package.elements;		/* Scan the irq_table_elements for the Source Name String */		name_found = FALSE;		for (table_index = 0; table_index < 4 && !name_found;		     table_index++) {			if (*sub_object_list &&	/* Null object allowed */			    ((ACPI_TYPE_STRING ==			      ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||			     ((ACPI_TYPE_LOCAL_REFERENCE ==			       ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&			      ((*sub_object_list)->reference.opcode ==			       AML_INT_NAMEPATH_OP)))) {				name_found = TRUE;			} else {				/* Look at the next element */				sub_object_list++;			}		}		temp_size_needed += (sizeof(struct acpi_pci_routing_table) - 4);		/* Was a String type found? */		if (name_found) {			if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==			    ACPI_TYPE_STRING) {				/*				 * The length String.Length field does not include the				 * terminating NULL, add 1				 */				temp_size_needed += ((acpi_size)						     (*sub_object_list)->string.						     length + 1);			} else {				temp_size_needed +=				    acpi_ns_get_pathname_length((*sub_object_list)->reference.node);			}		} else {			/*			 * If no name was found, then this is a NULL, which is			 * translated as a u32 zero.			 */			temp_size_needed += sizeof(u32);		}		/* Round up the size since each element must be aligned */		temp_size_needed = ACPI_ROUND_UP_TO_64BIT(temp_size_needed);		/* Point to the next union acpi_operand_object */		top_object_list++;	}	/*	 * Add an extra element to the end of the list, essentially a	 * NULL terminator	 */	*buffer_size_needed =	    temp_size_needed + sizeof(struct acpi_pci_routing_table);	return_ACPI_STATUS(AE_OK);}

⌨️ 快捷键说明

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