acpi_status acpi_get_table_header ( acpi_table_type table_type, u32 instance, acpi_table_header *out_table_header) { acpi_table_header *tbl_ptr; acpi_status status; FUNCTION_TRACE ("Acpi_get_table_header"); if ((instance == 0) || (table_type == ACPI_TABLE_RSDP) || (!out_table_header)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Check the table type and instance */ if ((table_type > ACPI_TABLE_MAX) || (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get a pointer to the entire table */ status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* * The function will return a NULL pointer if the table is not loaded */ if (tbl_ptr == NULL) { return_ACPI_STATUS (AE_NOT_EXIST); } /* * Copy the header to the caller's buffer */ MEMCPY ((void *) out_table_header, (void *) tbl_ptr, sizeof (acpi_table_header)); return_ACPI_STATUS (status); }
acpi_status acpi_tb_init_table_descriptor ( acpi_table_type table_type, acpi_table_desc *table_info) { acpi_table_desc *list_head; acpi_table_desc *table_desc; FUNCTION_TRACE_U32 ("Tb_init_table_descriptor", table_type); /* * Install the table into the global data structure */ list_head = &acpi_gbl_acpi_tables[table_type]; table_desc = list_head; /* * Two major types of tables: 1) Only one instance is allowed. This * includes most ACPI tables such as the DSDT. 2) Multiple instances of * the table are allowed. This includes SSDT and PSDTs. */ if (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) { /* * Only one table allowed, and a table has alread been installed * at this location, so return an error. */ if (list_head->pointer) { return_ACPI_STATUS (AE_EXIST); } table_desc->count = 1; } else { /* * Multiple tables allowed for this table type, we must link * the new table in to the list of tables of this type. */ if (list_head->pointer) { table_desc = ACPI_MEM_CALLOCATE (sizeof (acpi_table_desc)); if (!table_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } list_head->count++; /* Update the original previous */ list_head->prev->next = table_desc; /* Update new entry */ table_desc->prev = list_head->prev; table_desc->next = list_head; /* Update list head */ list_head->prev = table_desc; } else { table_desc->count = 1; } } /* Common initialization of the table descriptor */ table_desc->pointer = table_info->pointer; table_desc->base_pointer = table_info->base_pointer; table_desc->length = table_info->length; table_desc->allocation = table_info->allocation; table_desc->aml_start = (u8 *) (table_desc->pointer + 1), table_desc->aml_length = (u32) (table_desc->length - (u32) sizeof (acpi_table_header)); table_desc->table_id = acpi_ut_allocate_owner_id (OWNER_TYPE_TABLE); table_desc->loaded_into_namespace = FALSE; /* * Set the appropriate global pointer (if there is one) to point to the * newly installed table */ if (acpi_gbl_acpi_table_data[table_type].global_ptr) { *(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer; } /* Return Data */ table_info->table_id = table_desc->table_id; table_info->installed_desc = table_desc; return_ACPI_STATUS (AE_OK); }
acpi_status acpi_get_table ( acpi_table_type table_type, u32 instance, acpi_buffer *ret_buffer) { acpi_table_header *tbl_ptr; acpi_status status; u32 ret_buf_len; FUNCTION_TRACE ("Acpi_get_table"); /* * If we have a buffer, we must have a length too */ if ((instance == 0) || (!ret_buffer) || ((!ret_buffer->pointer) && (ret_buffer->length))) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Check the table type and instance */ if ((table_type > ACPI_TABLE_MAX) || (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get a pointer to the entire table */ status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* * Acpi_tb_get_table_ptr will return a NULL pointer if the * table is not loaded. */ if (tbl_ptr == NULL) { return_ACPI_STATUS (AE_NOT_EXIST); } /* * Got a table ptr, assume it's ok and copy it to the user's buffer */ if (table_type == ACPI_TABLE_RSDP) { /* * RSD PTR is the only "table" without a header */ ret_buf_len = sizeof (RSDP_DESCRIPTOR); } else { ret_buf_len = tbl_ptr->length; } /* * Verify we have space in the caller's buffer for the table */ if (ret_buffer->length < ret_buf_len) { ret_buffer->length = ret_buf_len; return_ACPI_STATUS (AE_BUFFER_OVERFLOW); } ret_buffer->length = ret_buf_len; MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, ret_buf_len); return_ACPI_STATUS (AE_OK); }