aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interface/linux/linux_acpi.c99
1 files changed, 21 insertions, 78 deletions
diff --git a/src/interface/linux/linux_acpi.c b/src/interface/linux/linux_acpi.c
index 08833d6..851cc54 100644
--- a/src/interface/linux/linux_acpi.c
+++ b/src/interface/linux/linux_acpi.c
@@ -23,9 +23,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <stdio.h>
#include <errno.h>
#include <ipxe/linux_api.h>
+#include <ipxe/linux_sysfs.h>
#include <ipxe/linux.h>
#include <ipxe/list.h>
#include <ipxe/init.h>
+#include <ipxe/umalloc.h>
#include <ipxe/acpi.h>
/** ACPI sysfs directory */
@@ -40,7 +42,7 @@ struct linux_acpi_table {
/** Index */
unsigned int index;
/** Cached data */
- void *data;
+ userptr_t data;
};
/** List of cached ACPI tables */
@@ -55,7 +57,6 @@ static LIST_HEAD ( linux_acpi_tables );
*/
static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
struct linux_acpi_table *table;
- struct acpi_header header;
union {
uint32_t signature;
char filename[5];
@@ -63,16 +64,14 @@ static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
static const char prefix[] = ACPI_SYSFS_PREFIX;
char filename[ sizeof ( prefix ) - 1 /* NUL */ + 4 /* signature */
+ 3 /* "999" */ + 1 /* NUL */ ];
- ssize_t rlen;
- size_t len;
- void *data;
- int fd;
+ int len;
+ int rc;
/* Check for existing table */
list_for_each_entry ( table, &linux_acpi_tables, list ) {
if ( ( table->signature == signature ) &&
( table->index == index ) )
- return virt_to_user ( table->data );
+ return table->data;
}
/* Allocate a new table */
@@ -82,90 +81,34 @@ static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
table->signature = signature;
table->index = index;
- /* Construct filename */
+ /* Construct filename (including numeric suffix) */
memset ( &u, 0, sizeof ( u ) );
u.signature = le32_to_cpu ( signature );
snprintf ( filename, sizeof ( filename ), "%s%s%d", prefix,
u.filename, ( index + 1 ) );
- /* Open file */
- fd = linux_open ( filename, O_RDONLY );
- if ( ( fd < 0 ) && ( index == 0 ) ) {
+ /* Read file (with or without numeric suffix for index 0) */
+ len = linux_sysfs_read ( filename, &table->data );
+ if ( ( len < 0 ) && ( index == 0 ) ) {
filename[ sizeof ( prefix ) - 1 /* NUL */ +
4 /* signature */ ] = '\0';
- fd = linux_open ( filename, O_RDONLY );
+ len = linux_sysfs_read ( filename, &table->data );
}
- if ( fd < 0 ) {
- DBGC ( &linux_acpi_tables, "ACPI could not open %s: %s\n",
- filename, linux_strerror ( linux_errno ) );
- goto err_open;
+ if ( len < 0 ) {
+ rc = len;
+ DBGC ( &linux_acpi_tables, "ACPI could not read %s: %s\n",
+ filename, strerror ( rc ) );
+ goto err_read;
}
- /* Read header */
- rlen = linux_read ( fd, &header, sizeof ( header ) );
- if ( rlen < 0 ) {
- DBGC ( &linux_acpi_tables, "ACPI could not read %s header: "
- "%s\n", filename, linux_strerror ( linux_errno ) );
- goto err_header;
- }
- if ( ( ( size_t ) rlen ) != sizeof ( header ) ) {
- DBGC ( &linux_acpi_tables, "ACPI underlength %s header\n",
- filename );
- goto err_header_len;
- }
-
- /* Parse header */
- len = le32_to_cpu ( header.length );
- if ( len < sizeof ( header ) ) {
- DBGC ( &linux_acpi_tables, "ACPI malformed %s header\n",
- filename );
- goto err_malformed;
- }
-
- /* Allocate data */
- table->data = malloc ( len );
- if ( ! table->data )
- goto err_data;
-
- /* Read table */
- memcpy ( table->data, &header, sizeof ( header ) );
- data = ( table->data + sizeof ( header ) );
- len -= sizeof ( header );
- while ( len ) {
- rlen = linux_read ( fd, data, len );
- if ( rlen < 0 ) {
- DBGC ( &linux_acpi_tables, "ACPI could not read %s: "
- "%s\n", filename,
- linux_strerror ( linux_errno ) );
- goto err_body;
- }
- if ( rlen == 0 ) {
- DBGC ( &linux_acpi_tables, "ACPI underlength %s\n",
- filename );
- goto err_body_len;
- }
- data += rlen;
- len -= rlen;
- }
-
- /* Close file */
- linux_close ( fd );
-
/* Add to list of tables */
list_add ( &table->list, &linux_acpi_tables );
DBGC ( &linux_acpi_tables, "ACPI cached %s\n", filename );
- return virt_to_user ( table->data );
-
- err_body_len:
- err_body:
- free ( table->data );
- err_data:
- err_malformed:
- err_header_len:
- err_header:
- linux_close ( fd );
- err_open:
+ return table->data;
+
+ ufree ( table->data );
+ err_read:
free ( table );
err_alloc:
return UNULL;
@@ -181,7 +124,7 @@ static void linux_acpi_shutdown ( int booting __unused ) {
list_for_each_entry_safe ( table, tmp, &linux_acpi_tables, list ) {
list_del ( &table->list );
- free ( table->data );
+ ufree ( table->data );
free ( table );
}
}