From bda663d36b94c723153246a4231bbc0f1cd1836e Mon Sep 17 00:00:00 2001 From: Robert Moore Date: Fri, 16 Sep 2005 16:51:15 -0400 Subject: [PATCH 001/695] [ACPI] ACPICA 20050916 Fixed a problem within the Resource Manager where support for the Generic Register descriptor was not fully implemented. This descriptor is now fully recognized, parsed, disassembled, and displayed. Restructured the Resource Manager code to utilize table-driven dispatch and lookup, eliminating many of the large switch() statements. This reduces overall subsystem code size and code complexity. Affects the resource parsing and construction, disassembly, and debug dump output. Cleaned up and restructured the debug dump output for all resource descriptors. Improved readability of the output and reduced code size. Fixed a problem where changes to internal data structures caused the optional ACPI_MUTEX_DEBUG code to fail compilation if specified. Signed-off-by: Robert Moore Signed-off-by: Len Brown --- drivers/acpi/resources/rsaddr.c | 99 +- drivers/acpi/resources/rscalc.c | 1037 ++++++++--------- drivers/acpi/resources/rsdump.c | 1782 ++++++++++++++--------------- drivers/acpi/resources/rsio.c | 56 +- drivers/acpi/resources/rsirq.c | 57 +- drivers/acpi/resources/rslist.c | 535 +++------ drivers/acpi/resources/rsmemory.c | 68 +- drivers/acpi/resources/rsmisc.c | 236 +++- drivers/acpi/resources/rsxface.c | 8 +- drivers/acpi/utilities/utmisc.c | 2 +- drivers/acpi/utilities/utmutex.c | 4 +- include/acpi/acconfig.h | 4 +- include/acpi/acdisasm.h | 36 +- include/acpi/aclocal.h | 23 +- include/acpi/acresrc.h | 46 +- include/acpi/actypes.h | 13 +- include/acpi/amlresrc.h | 56 +- include/acpi/platform/acenv.h | 1 + 18 files changed, 1978 insertions(+), 2085 deletions(-) diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 23b54baa0cb2..798778261fb9 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c @@ -270,7 +270,7 @@ acpi_rs_address16_resource(u8 * byte_stream_buffer, } *bytes_consumed = temp16 + 3; - output_struct->id = ACPI_RSTYPE_ADDRESS16; + output_struct->type = ACPI_RSTYPE_ADDRESS16; /* Get the Resource Type (Byte3) */ @@ -400,7 +400,7 @@ acpi_rs_address16_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_address16_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -413,7 +413,7 @@ acpi_rs_address16_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_address16_stream(struct acpi_resource *linked_list, +acpi_rs_address16_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -434,59 +434,56 @@ acpi_rs_address16_stream(struct acpi_resource *linked_list, /* Set the Resource Type (Memory, Io, bus_number) */ - *buffer = (u8) (linked_list->data.address16.resource_type & 0x03); + *buffer = (u8) (resource->data.address16.resource_type & 0x03); buffer += 1; /* Set the general flags */ - *buffer = acpi_rs_encode_general_flags(&linked_list->data); + *buffer = acpi_rs_encode_general_flags(&resource->data); buffer += 1; /* Set the type specific flags */ - *buffer = acpi_rs_encode_specific_flags(&linked_list->data); + *buffer = acpi_rs_encode_specific_flags(&resource->data); buffer += 1; /* Set the address space granularity */ - ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.granularity); + ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.granularity); buffer += 2; /* Set the address range minimum */ - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.address16.min_address_range); + ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.min_address_range); buffer += 2; /* Set the address range maximum */ - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.address16.max_address_range); + ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.max_address_range); buffer += 2; /* Set the address translation offset */ ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.address16. + &resource->data.address16. address_translation_offset); buffer += 2; /* Set the address length */ - ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.address_length); + ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.address_length); buffer += 2; /* Resource Source Index and Resource Source are optional */ - if (linked_list->data.address16.resource_source.string_length) { - *buffer = - (u8) linked_list->data.address16.resource_source.index; + if (resource->data.address16.resource_source.string_length) { + *buffer = (u8) resource->data.address16.resource_source.index; buffer += 1; /* Copy the resource_source string */ ACPI_STRCPY((char *)buffer, - linked_list->data.address16.resource_source. + resource->data.address16.resource_source. string_ptr); /* @@ -495,7 +492,7 @@ acpi_rs_address16_stream(struct acpi_resource *linked_list, */ buffer += (acpi_size) (ACPI_STRLEN - (linked_list->data.address16.resource_source. + (resource->data.address16.resource_source. string_ptr) + 1); } @@ -562,7 +559,7 @@ acpi_rs_address32_resource(u8 * byte_stream_buffer, } *bytes_consumed = temp16 + 3; - output_struct->id = ACPI_RSTYPE_ADDRESS32; + output_struct->type = ACPI_RSTYPE_ADDRESS32; /* Get the Resource Type (Byte3) */ @@ -690,7 +687,7 @@ acpi_rs_address32_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_address32_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -703,7 +700,7 @@ acpi_rs_address32_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_address32_stream(struct acpi_resource *linked_list, +acpi_rs_address32_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer; @@ -725,59 +722,56 @@ acpi_rs_address32_stream(struct acpi_resource *linked_list, /* Set the Resource Type (Memory, Io, bus_number) */ - *buffer = (u8) (linked_list->data.address32.resource_type & 0x03); + *buffer = (u8) (resource->data.address32.resource_type & 0x03); buffer += 1; /* Set the general flags */ - *buffer = acpi_rs_encode_general_flags(&linked_list->data); + *buffer = acpi_rs_encode_general_flags(&resource->data); buffer += 1; /* Set the type specific flags */ - *buffer = acpi_rs_encode_specific_flags(&linked_list->data); + *buffer = acpi_rs_encode_specific_flags(&resource->data); buffer += 1; /* Set the address space granularity */ - ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.granularity); + ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.granularity); buffer += 4; /* Set the address range minimum */ - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.address32.min_address_range); + ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.min_address_range); buffer += 4; /* Set the address range maximum */ - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.address32.max_address_range); + ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.max_address_range); buffer += 4; /* Set the address translation offset */ ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.address32. + &resource->data.address32. address_translation_offset); buffer += 4; /* Set the address length */ - ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.address_length); + ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.address_length); buffer += 4; /* Resource Source Index and Resource Source are optional */ - if (linked_list->data.address32.resource_source.string_length) { - *buffer = - (u8) linked_list->data.address32.resource_source.index; + if (resource->data.address32.resource_source.string_length) { + *buffer = (u8) resource->data.address32.resource_source.index; buffer += 1; /* Copy the resource_source string */ ACPI_STRCPY((char *)buffer, - linked_list->data.address32.resource_source. + resource->data.address32.resource_source. string_ptr); /* @@ -786,7 +780,7 @@ acpi_rs_address32_stream(struct acpi_resource *linked_list, */ buffer += (acpi_size) (ACPI_STRLEN - (linked_list->data.address32.resource_source. + (resource->data.address32.resource_source. string_ptr) + 1); } @@ -856,7 +850,7 @@ acpi_rs_address64_resource(u8 * byte_stream_buffer, } *bytes_consumed = temp16 + 3; - output_struct->id = ACPI_RSTYPE_ADDRESS64; + output_struct->type = ACPI_RSTYPE_ADDRESS64; /* Get the Resource Type (Byte3) */ @@ -1005,7 +999,7 @@ acpi_rs_address64_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_address64_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -1018,7 +1012,7 @@ acpi_rs_address64_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_address64_stream(struct acpi_resource *linked_list, +acpi_rs_address64_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer; @@ -1040,59 +1034,56 @@ acpi_rs_address64_stream(struct acpi_resource *linked_list, /* Set the Resource Type (Memory, Io, bus_number) */ - *buffer = (u8) (linked_list->data.address64.resource_type & 0x03); + *buffer = (u8) (resource->data.address64.resource_type & 0x03); buffer += 1; /* Set the general flags */ - *buffer = acpi_rs_encode_general_flags(&linked_list->data); + *buffer = acpi_rs_encode_general_flags(&resource->data); buffer += 1; /* Set the type specific flags */ - *buffer = acpi_rs_encode_specific_flags(&linked_list->data); + *buffer = acpi_rs_encode_specific_flags(&resource->data); buffer += 1; /* Set the address space granularity */ - ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.granularity); + ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.granularity); buffer += 8; /* Set the address range minimum */ - ACPI_MOVE_64_TO_64(buffer, - &linked_list->data.address64.min_address_range); + ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.min_address_range); buffer += 8; /* Set the address range maximum */ - ACPI_MOVE_64_TO_64(buffer, - &linked_list->data.address64.max_address_range); + ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.max_address_range); buffer += 8; /* Set the address translation offset */ ACPI_MOVE_64_TO_64(buffer, - &linked_list->data.address64. + &resource->data.address64. address_translation_offset); buffer += 8; /* Set the address length */ - ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.address_length); + ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.address_length); buffer += 8; /* Resource Source Index and Resource Source are optional */ - if (linked_list->data.address64.resource_source.string_length) { - *buffer = - (u8) linked_list->data.address64.resource_source.index; + if (resource->data.address64.resource_source.string_length) { + *buffer = (u8) resource->data.address64.resource_source.index; buffer += 1; /* Copy the resource_source string */ ACPI_STRCPY((char *)buffer, - linked_list->data.address64.resource_source. + resource->data.address64.resource_source. string_ptr); /* @@ -1101,7 +1092,7 @@ acpi_rs_address64_stream(struct acpi_resource *linked_list, */ buffer += (acpi_size) (ACPI_STRLEN - (linked_list->data.address64.resource_source. + (resource->data.address64.resource_source. string_ptr) + 1); } diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 378f58390fc1..cd051c97bf5b 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -44,225 +44,414 @@ #include #include #include +#include #include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rscalc") +/* + * Base sizes for external resource descriptors, indexed by internal type. + * Includes size of the descriptor header (1 byte for small descriptors, + * 3 bytes for large descriptors) + */ +static u8 acpi_gbl_stream_sizes[] = { + 4, /* ACPI_RSTYPE_IRQ (Byte 3 is optional, but always created) */ + 3, /* ACPI_RSTYPE_DMA */ + 2, /* ACPI_RSTYPE_START_DPF (Byte 1 is optional, but always created) */ + 1, /* ACPI_RSTYPE_END_DPF */ + 8, /* ACPI_RSTYPE_IO */ + 4, /* ACPI_RSTYPE_FIXED_IO */ + 1, /* ACPI_RSTYPE_VENDOR */ + 2, /* ACPI_RSTYPE_END_TAG */ + 12, /* ACPI_RSTYPE_MEM24 */ + 20, /* ACPI_RSTYPE_MEM32 */ + 12, /* ACPI_RSTYPE_FIXED_MEM32 */ + 16, /* ACPI_RSTYPE_ADDRESS16 */ + 26, /* ACPI_RSTYPE_ADDRESS32 */ + 46, /* ACPI_RSTYPE_ADDRESS64 */ + 9, /* ACPI_RSTYPE_EXT_IRQ */ + 15 /* ACPI_RSTYPE_GENERIC_REG */ +}; + +/* + * Base sizes of resource descriptors, both the actual AML stream length and + * size of the internal struct representation. + */ +typedef struct acpi_resource_sizes { + u8 minimum_stream_size; + u8 minimum_struct_size; + +} ACPI_RESOURCE_SIZES; + +static ACPI_RESOURCE_SIZES acpi_gbl_sm_resource_sizes[] = { + 0, 0, /* 0x00, Reserved */ + 0, 0, /* 0x01, Reserved */ + 0, 0, /* 0x02, Reserved */ + 0, 0, /* 0x03, Reserved */ + 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq), /* ACPI_RDESC_TYPE_IRQ_FORMAT */ + 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma), /* ACPI_RDESC_TYPE_DMA_FORMAT */ + 1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf), /* ACPI_RDESC_TYPE_START_DEPENDENT */ + 1, ACPI_RESOURCE_LENGTH, /* ACPI_RDESC_TYPE_END_DEPENDENT */ + 8, ACPI_SIZEOF_RESOURCE(struct acpi_resource_io), /* ACPI_RDESC_TYPE_IO_PORT */ + 4, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io), /* ACPI_RDESC_TYPE_FIXED_IO_PORT */ + 0, 0, /* 0x0A, Reserved */ + 0, 0, /* 0x0B, Reserved */ + 0, 0, /* 0x0C, Reserved */ + 0, 0, /* 0x0D, Reserved */ + 1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor), /* ACPI_RDESC_TYPE_SMALL_VENDOR */ + 2, ACPI_RESOURCE_LENGTH, /* ACPI_RDESC_TYPE_END_TAG */ +}; + +static ACPI_RESOURCE_SIZES acpi_gbl_lg_resource_sizes[] = { + 0, 0, /* 0x00, Reserved */ + 12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24), /* ACPI_RDESC_TYPE_MEMORY_24 */ + 15, ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg), /* ACPI_RDESC_TYPE_GENERIC_REGISTER */ + 0, 0, /* 0x03, Reserved */ + 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor), /* ACPI_RDESC_TYPE_LARGE_VENDOR */ + 20, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32), /* ACPI_RDESC_TYPE_MEMORY_32 */ + 12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32), /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */ + 26, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32), /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */ + 16, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16), /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */ + 9, ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq), /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */ + 46, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64), /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */ + 56, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64), /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */ +}; + +/* Local prototypes */ + +static u8 acpi_rs_count_set_bits(u16 bit_field); + +static ACPI_RESOURCE_SIZES *acpi_rs_get_resource_sizes(u8 resource_type); + +static u16 acpi_rs_get_resource_length(u8 * resource); + +static acpi_size +acpi_rs_struct_option_length(struct acpi_resource_source *resource_source); + +static u32 +acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length); + +/******************************************************************************* + * + * FUNCTION: acpi_rs_count_set_bits + * + * PARAMETERS: bit_field - Field in which to count bits + * + * RETURN: Number of bits set within the field + * + * DESCRIPTION: Count the number of bits set in a resource field. Used for + * (Short descriptor) interrupt and DMA lists. + * + ******************************************************************************/ + +static u8 acpi_rs_count_set_bits(u16 bit_field) +{ + u8 bits_set; + + ACPI_FUNCTION_ENTRY(); + + for (bits_set = 0; bit_field; bits_set++) { + /* Zero the least significant bit that is set */ + + bit_field &= (bit_field - 1); + } + + return (bits_set); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_sizes + * + * PARAMETERS: resource_type - Byte 0 of a resource descriptor + * + * RETURN: Pointer to the resource conversion handler + * + * DESCRIPTION: Extract the Resource Type/Name from the first byte of + * a resource descriptor. + * + ******************************************************************************/ + +static ACPI_RESOURCE_SIZES *acpi_rs_get_resource_sizes(u8 resource_type) +{ + ACPI_RESOURCE_SIZES *size_info; + + ACPI_FUNCTION_ENTRY(); + + /* Determine if this is a small or large resource */ + + if (resource_type & ACPI_RDESC_TYPE_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ + + if (resource_type > ACPI_RDESC_LARGE_MAX) { + return (NULL); + } + + size_info = &acpi_gbl_lg_resource_sizes[(resource_type & + ACPI_RDESC_LARGE_MASK)]; + } else { + /* Small Resource Type -- bits 6:3 contain the name */ + + size_info = &acpi_gbl_sm_resource_sizes[((resource_type & + ACPI_RDESC_SMALL_MASK) + >> 3)]; + } + + /* Zero entry indicates an invalid resource type */ + + if (!size_info->minimum_stream_size) { + return (NULL); + } + + return (size_info); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_length + * + * PARAMETERS: Resource - Pointer to the resource descriptor + * + * RETURN: Byte length of the (AML byte stream) descriptor. By definition, + * this does not include the size of the descriptor header and the + * length field itself. + * + * DESCRIPTION: Extract the length of a resource descriptor. + * + ******************************************************************************/ + +static u16 acpi_rs_get_resource_length(u8 * resource) +{ + u16 resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* Determine if this is a small or large resource */ + + if (*resource & ACPI_RDESC_TYPE_LARGE) { + /* Large Resource type -- length is in bytes 1-2 */ + + ACPI_MOVE_16_TO_16(&resource_length, (resource + 1)); + + } else { + /* Small Resource Type -- bits 2:0 of byte 0 contain the length */ + + resource_length = + (u16) (*resource & ACPI_RDESC_SMALL_LENGTH_MASK); + } + + return (resource_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_struct_option_length + * + * PARAMETERS: resource_source - Pointer to optional descriptor field + * + * RETURN: Status + * + * DESCRIPTION: Common code to handle optional resource_source_index and + * resource_source fields in some Large descriptors. Used during + * list-to-stream conversion + * + ******************************************************************************/ + +static acpi_size +acpi_rs_struct_option_length(struct acpi_resource_source *resource_source) +{ + ACPI_FUNCTION_ENTRY(); + + /* + * If the resource_source string is valid, return the size of the string + * (string_length includes the NULL terminator) plus the size of the + * resource_source_index (1). + */ + if (resource_source->string_ptr) { + return ((acpi_size) resource_source->string_length + 1); + } + + return (0); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_stream_option_length + * + * PARAMETERS: resource_length - Length from the resource header + * minimum_total_length - Minimum length of this resource, before + * any optional fields. Includes header size + * + * RETURN: Length of optional string (0 if no string present) + * + * DESCRIPTION: Common code to handle optional resource_source_index and + * resource_source fields in some Large descriptors. Used during + * stream-to-list conversion + * + ******************************************************************************/ + +static u32 +acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length) +{ + u32 string_length = 0; + u32 minimum_resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* + * The resource_source_index and resource_source are optional elements of some + * Large-type resource descriptors. + */ + + /* Compute minimum size of the data part of the resource descriptor */ + + minimum_resource_length = + minimum_total_length - sizeof(struct asl_large_header); + + /* + * If the length of the actual resource descriptor is greater than the ACPI + * spec-defined minimum length, it means that a resource_source_index exists + * and is followed by a (required) null terminated string. The string length + * (including the null terminator) is the resource length minus the minimum + * length, minus one byte for the resource_source_index itself. + */ + if (resource_length > minimum_resource_length) { + /* Compute the length of the optional string */ + + string_length = resource_length - minimum_resource_length - 1; + } + + /* Round up length to 32 bits for internal structure alignment */ + + return (ACPI_ROUND_UP_to_32_bITS(string_length)); +} + /******************************************************************************* * * FUNCTION: acpi_rs_get_byte_stream_length * - * PARAMETERS: linked_list - Pointer to the resource linked list - * size_needed - u32 pointer of the size buffer needed - * to properly return the parsed data + * PARAMETERS: Resource - Pointer to the resource linked list + * size_needed - Where the required size is returned * * RETURN: Status * - * DESCRIPTION: Takes the resource byte stream and parses it once, calculating - * the size buffer needed to hold the linked list that conveys - * the resource data. + * DESCRIPTION: Takes a linked list of internal resource descriptors and + * calculates the size buffer needed to hold the corresponding + * external resource byte stream. * ******************************************************************************/ + acpi_status -acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list, +acpi_rs_get_byte_stream_length(struct acpi_resource * resource, acpi_size * size_needed) { acpi_size byte_stream_size_needed = 0; acpi_size segment_size; - u8 done = FALSE; ACPI_FUNCTION_TRACE("rs_get_byte_stream_length"); - while (!done) { - /* Init the variable that will hold the size to add to the total. */ + /* Traverse entire list of internal resource descriptors */ - segment_size = 0; + while (resource) { + /* Validate the descriptor type */ - switch (linked_list->id) { - case ACPI_RSTYPE_IRQ: - /* - * IRQ Resource - * For an IRQ Resource, Byte 3, although optional, will always be - * created - it holds IRQ information. - */ - segment_size = 4; - break; + if (resource->type > ACPI_RSTYPE_MAX) { + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + } - case ACPI_RSTYPE_DMA: - /* - * DMA Resource - * For this resource the size is static - */ - segment_size = 3; - break; + /* Get the base size of the (external stream) resource descriptor */ - case ACPI_RSTYPE_START_DPF: - /* - * Start Dependent Functions Resource - * For a start_dependent_functions Resource, Byte 1, although - * optional, will always be created. - */ - segment_size = 2; - break; - - case ACPI_RSTYPE_END_DPF: - /* - * End Dependent Functions Resource - * For this resource the size is static - */ - segment_size = 1; - break; - - case ACPI_RSTYPE_IO: - /* - * IO Port Resource - * For this resource the size is static - */ - segment_size = 8; - break; - - case ACPI_RSTYPE_FIXED_IO: - /* - * Fixed IO Port Resource - * For this resource the size is static - */ - segment_size = 4; - break; + segment_size = acpi_gbl_stream_sizes[resource->type]; + /* + * Augment the base size for descriptors with optional and/or + * variable-length fields + */ + switch (resource->type) { case ACPI_RSTYPE_VENDOR: /* - * Vendor Defined Resource + * Vendor Defined Resource: * For a Vendor Specific resource, if the Length is between 1 and 7 * it will be created as a Small Resource data type, otherwise it * is a Large Resource data type. */ - if (linked_list->data.vendor_specific.length > 7) { + if (resource->data.vendor_specific.length > 7) { + /* Base size of a Large resource descriptor */ + segment_size = 3; - } else { - segment_size = 1; } - segment_size += - linked_list->data.vendor_specific.length; + + /* Add the size of the vendor-specific data */ + + segment_size += resource->data.vendor_specific.length; break; case ACPI_RSTYPE_END_TAG: /* - * End Tag - * For this resource the size is static + * End Tag: + * We are done -- return the accumulated total size. */ - segment_size = 2; - done = TRUE; - break; + *size_needed = byte_stream_size_needed + segment_size; - case ACPI_RSTYPE_MEM24: - /* - * 24-Bit Memory Resource - * For this resource the size is static - */ - segment_size = 12; - break; + /* Normal exit */ - case ACPI_RSTYPE_MEM32: - /* - * 32-Bit Memory Range Resource - * For this resource the size is static - */ - segment_size = 20; - break; - - case ACPI_RSTYPE_FIXED_MEM32: - /* - * 32-Bit Fixed Memory Resource - * For this resource the size is static - */ - segment_size = 12; - break; + return_ACPI_STATUS(AE_OK); case ACPI_RSTYPE_ADDRESS16: /* - * 16-Bit Address Resource - * The base size of this byte stream is 16. If a Resource Source - * string is not NULL, add 1 for the Index + the length of the null - * terminated string Resource Source + 1 for the null. + * 16-Bit Address Resource: + * Add the size of the optional resource_source info */ - segment_size = 16; - - if (linked_list->data.address16.resource_source. - string_ptr) { - segment_size += - linked_list->data.address16.resource_source. - string_length; - segment_size++; - } + segment_size += + acpi_rs_struct_option_length(&resource->data. + address16. + resource_source); break; case ACPI_RSTYPE_ADDRESS32: /* - * 32-Bit Address Resource - * The base size of this byte stream is 26. If a Resource - * Source string is not NULL, add 1 for the Index + the - * length of the null terminated string Resource Source + - * 1 for the null. + * 32-Bit Address Resource: + * Add the size of the optional resource_source info */ - segment_size = 26; - - if (linked_list->data.address32.resource_source. - string_ptr) { - segment_size += - linked_list->data.address32.resource_source. - string_length; - segment_size++; - } + segment_size += + acpi_rs_struct_option_length(&resource->data. + address32. + resource_source); break; case ACPI_RSTYPE_ADDRESS64: /* - * 64-Bit Address Resource - * The base size of this byte stream is 46. If a resource_source - * string is not NULL, add 1 for the Index + the length of the null - * terminated string Resource Source + 1 for the null. + * 64-Bit Address Resource: + * Add the size of the optional resource_source info */ - segment_size = 46; - - if (linked_list->data.address64.resource_source. - string_ptr) { - segment_size += - linked_list->data.address64.resource_source. - string_length; - segment_size++; - } + segment_size += + acpi_rs_struct_option_length(&resource->data. + address64. + resource_source); break; case ACPI_RSTYPE_EXT_IRQ: /* - * Extended IRQ Resource - * The base size of this byte stream is 9. This is for an Interrupt - * table length of 1. For each additional interrupt, add 4. - * If a Resource Source string is not NULL, add 1 for the - * Index + the length of the null terminated string - * Resource Source + 1 for the null. + * Extended IRQ Resource: + * Add the size of each additional optional interrupt beyond the + * required 1 (4 bytes for each u32 interrupt number) */ - segment_size = 9 + (((acpi_size) - linked_list->data.extended_irq. - number_of_interrupts - 1) * 4); + segment_size += (((acpi_size) + resource->data.extended_irq. + number_of_interrupts - 1) * 4); - if (linked_list->data.extended_irq.resource_source. - string_ptr) { - segment_size += - linked_list->data.extended_irq. - resource_source.string_length; - segment_size++; - } + /* Add the size of the optional resource_source info */ + + segment_size += + acpi_rs_struct_option_length(&resource->data. + extended_irq. + resource_source); break; default: - - /* If we get here, everything is out of sync, exit with error */ - - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - - } /* switch (linked_list->Id) */ + break; + } /* Update the total */ @@ -270,14 +459,13 @@ acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list, /* Point to the next object */ - linked_list = ACPI_PTR_ADD(struct acpi_resource, - linked_list, linked_list->length); + resource = ACPI_PTR_ADD(struct acpi_resource, + resource, resource->length); } - /* This is the data the caller needs */ + /* Did not find an END_TAG descriptor */ - *size_needed = byte_stream_size_needed; - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } /******************************************************************************* @@ -286,15 +474,13 @@ acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list, * * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream * byte_stream_buffer_length - Size of byte_stream_buffer - * size_needed - u32 pointer of the size buffer - * needed to properly return the - * parsed data + * size_needed - Where the size needed is returned * * RETURN: Status * - * DESCRIPTION: Takes the resource byte stream and parses it once, calculating - * the size buffer needed to hold the linked list that conveys - * the resource data. + * DESCRIPTION: Takes an external resource byte stream and calculates the size + * buffer needed to hold the corresponding internal resource + * descriptor linked list. * ******************************************************************************/ @@ -302,393 +488,176 @@ acpi_status acpi_rs_get_list_length(u8 * byte_stream_buffer, u32 byte_stream_buffer_length, acpi_size * size_needed) { + u8 *buffer; + ACPI_RESOURCE_SIZES *resource_info; u32 buffer_size = 0; u32 bytes_parsed = 0; - u8 number_of_interrupts = 0; - u8 number_of_channels = 0; u8 resource_type; - u32 structure_size; - u32 bytes_consumed; - u8 *buffer; - u8 temp8; u16 temp16; - u8 index; - u8 additional_bytes; + u16 resource_length; + u16 header_length; + u32 extra_struct_bytes; ACPI_FUNCTION_TRACE("rs_get_list_length"); while (bytes_parsed < byte_stream_buffer_length) { - /* The next byte in the stream is the resource type */ + /* The next byte in the stream is the resource descriptor type */ resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); - switch (resource_type) { - case ACPI_RDESC_TYPE_MEMORY_24: - /* - * 24-Bit Memory Resource - */ - bytes_consumed = 12; + /* Get the base stream size and structure sizes for the descriptor */ - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24); - break; - - case ACPI_RDESC_TYPE_LARGE_VENDOR: - /* - * Vendor Defined Resource - */ - buffer = byte_stream_buffer; - ++buffer; - - ACPI_MOVE_16_TO_16(&temp16, buffer); - bytes_consumed = temp16 + 3; - - /* Ensure a 32-bit boundary for the structure */ - - temp16 = (u16) ACPI_ROUND_UP_to_32_bITS(temp16); - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + - (temp16 * sizeof(u8)); - break; - - case ACPI_RDESC_TYPE_MEMORY_32: - /* - * 32-Bit Memory Range Resource - */ - bytes_consumed = 20; - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32); - break; - - case ACPI_RDESC_TYPE_FIXED_MEMORY_32: - /* - * 32-Bit Fixed Memory Resource - */ - bytes_consumed = 12; - - structure_size = - ACPI_SIZEOF_RESOURCE(struct - acpi_resource_fixed_mem32); - break; - - case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: - /* - * 64-Bit Address Resource - */ - buffer = byte_stream_buffer; - - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - bytes_consumed = temp16 + 3; - structure_size = - ACPI_SIZEOF_RESOURCE(struct - acpi_resource_address64); - break; - - case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: - /* - * 64-Bit Address Resource - */ - buffer = byte_stream_buffer; - - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - bytes_consumed = temp16 + 3; - - /* - * Resource Source Index and Resource Source are optional elements. - * Check the length of the Bytestream. If it is greater than 43, - * that means that an Index exists and is followed by a null - * terminated string. Therefore, set the temp variable to the - * length minus the minimum byte stream length plus the byte for - * the Index to determine the size of the NULL terminated string. - */ - if (43 < temp16) { - temp8 = (u8) (temp16 - 44); - } else { - temp8 = 0; - } - - /* Ensure a 64-bit boundary for the structure */ - - temp8 = (u8) ACPI_ROUND_UP_to_64_bITS(temp8); - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64) - + (temp8 * sizeof(u8)); - break; - - case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: - /* - * 32-Bit Address Resource - */ - buffer = byte_stream_buffer; - - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - bytes_consumed = temp16 + 3; - - /* - * Resource Source Index and Resource Source are optional elements. - * Check the length of the Bytestream. If it is greater than 23, - * that means that an Index exists and is followed by a null - * terminated string. Therefore, set the temp variable to the - * length minus the minimum byte stream length plus the byte for - * the Index to determine the size of the NULL terminated string. - */ - if (23 < temp16) { - temp8 = (u8) (temp16 - 24); - } else { - temp8 = 0; - } - - /* Ensure a 32-bit boundary for the structure */ - - temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32) - + (temp8 * sizeof(u8)); - break; - - case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: - /* - * 16-Bit Address Resource - */ - buffer = byte_stream_buffer; - - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - bytes_consumed = temp16 + 3; - - /* - * Resource Source Index and Resource Source are optional elements. - * Check the length of the Bytestream. If it is greater than 13, - * that means that an Index exists and is followed by a null - * terminated string. Therefore, set the temp variable to the - * length minus the minimum byte stream length plus the byte for - * the Index to determine the size of the NULL terminated string. - */ - if (13 < temp16) { - temp8 = (u8) (temp16 - 14); - } else { - temp8 = 0; - } - - /* Ensure a 32-bit boundary for the structure */ - - temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16) - + (temp8 * sizeof(u8)); - break; - - case ACPI_RDESC_TYPE_EXTENDED_XRUPT: - /* - * Extended IRQ - */ - buffer = byte_stream_buffer; - - ++buffer; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - bytes_consumed = temp16 + 3; - - /* - * Point past the length field and the Interrupt vector flags to - * save off the Interrupt table length to the Temp8 variable. - */ - buffer += 3; - temp8 = *buffer; - - /* - * To compensate for multiple interrupt numbers, add 4 bytes for - * each additional interrupts greater than 1 - */ - additional_bytes = (u8) ((temp8 - 1) * 4); - - /* - * Resource Source Index and Resource Source are optional elements. - * Check the length of the Bytestream. If it is greater than 9, - * that means that an Index exists and is followed by a null - * terminated string. Therefore, set the temp variable to the - * length minus the minimum byte stream length plus the byte for - * the Index to determine the size of the NULL terminated string. - */ - if (9 + additional_bytes < temp16) { - temp8 = (u8) (temp16 - (9 + additional_bytes)); - } else { - temp8 = 0; - } - - /* Ensure a 32-bit boundary for the structure */ - - temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq) + - (additional_bytes * sizeof(u8)) + - (temp8 * sizeof(u8)); - break; - - case ACPI_RDESC_TYPE_IRQ_FORMAT: - /* - * IRQ Resource. - * Determine if it there are two or three trailing bytes - */ - buffer = byte_stream_buffer; - temp8 = *buffer; - - if (temp8 & 0x01) { - bytes_consumed = 4; - } else { - bytes_consumed = 3; - } - - /* Point past the descriptor */ - - ++buffer; - - /* Look at the number of bits set */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - - for (index = 0; index < 16; index++) { - if (temp16 & 0x1) { - ++number_of_interrupts; - } - - temp16 >>= 1; - } - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_io) + - (number_of_interrupts * sizeof(u32)); - break; - - case ACPI_RDESC_TYPE_DMA_FORMAT: - /* - * DMA Resource - */ - buffer = byte_stream_buffer; - bytes_consumed = 3; - - /* Point past the descriptor */ - - ++buffer; - - /* Look at the number of bits set */ - - temp8 = *buffer; - - for (index = 0; index < 8; index++) { - if (temp8 & 0x1) { - ++number_of_channels; - } - - temp8 >>= 1; - } - - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma) + - (number_of_channels * sizeof(u32)); - break; - - case ACPI_RDESC_TYPE_START_DEPENDENT: - /* - * Start Dependent Functions Resource - * Determine if it there are two or three trailing bytes - */ - buffer = byte_stream_buffer; - temp8 = *buffer; - - if (temp8 & 0x01) { - bytes_consumed = 2; - } else { - bytes_consumed = 1; - } - - structure_size = - ACPI_SIZEOF_RESOURCE(struct - acpi_resource_start_dpf); - break; - - case ACPI_RDESC_TYPE_END_DEPENDENT: - /* - * End Dependent Functions Resource - */ - bytes_consumed = 1; - structure_size = ACPI_RESOURCE_LENGTH; - break; - - case ACPI_RDESC_TYPE_IO_PORT: - /* - * IO Port Resource - */ - bytes_consumed = 8; - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); - break; - - case ACPI_RDESC_TYPE_FIXED_IO_PORT: - /* - * Fixed IO Port Resource - */ - bytes_consumed = 4; - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); - break; - - case ACPI_RDESC_TYPE_SMALL_VENDOR: - /* - * Vendor Specific Resource - */ - buffer = byte_stream_buffer; - - temp8 = *buffer; - temp8 = (u8) (temp8 & 0x7); - bytes_consumed = temp8 + 1; - - /* Ensure a 32-bit boundary for the structure */ - - temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); - structure_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + - (temp8 * sizeof(u8)); - break; - - case ACPI_RDESC_TYPE_END_TAG: - /* - * End Tag - */ - bytes_consumed = 2; - structure_size = ACPI_RESOURCE_LENGTH; - byte_stream_buffer_length = bytes_parsed; - break; - - default: - /* - * If we get here, everything is out of sync, - * exit with an error - */ + resource_info = acpi_rs_get_resource_sizes(resource_type); + if (!resource_info) { return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } - /* Update the return value and counter */ + /* Get the Length field from the input resource descriptor */ - buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(structure_size); - bytes_parsed += bytes_consumed; + resource_length = + acpi_rs_get_resource_length(byte_stream_buffer); - /* Set the byte stream to point to the next resource */ + /* Augment the size for descriptors with optional fields */ - byte_stream_buffer += bytes_consumed; + extra_struct_bytes = 0; + + if (!(resource_type & ACPI_RDESC_TYPE_LARGE)) { + /* + * Small resource descriptors + */ + header_length = 1; + buffer = byte_stream_buffer + header_length; + + switch (resource_type) { + case ACPI_RDESC_TYPE_IRQ_FORMAT: + /* + * IRQ Resource: + * Get the number of bits set in the IRQ word + */ + ACPI_MOVE_16_TO_16(&temp16, buffer); + + extra_struct_bytes = + (acpi_rs_count_set_bits(temp16) * + sizeof(u32)); + break; + + case ACPI_RDESC_TYPE_DMA_FORMAT: + /* + * DMA Resource: + * Get the number of bits set in the DMA channels byte + */ + extra_struct_bytes = + (acpi_rs_count_set_bits((u16) * buffer) * + sizeof(u32)); + break; + + case ACPI_RDESC_TYPE_SMALL_VENDOR: + /* + * Vendor Specific Resource: + * Ensure a 32-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length); + break; + + case ACPI_RDESC_TYPE_END_TAG: + /* + * End Tag: + * Terminate the loop now + */ + byte_stream_buffer_length = bytes_parsed; + break; + + default: + break; + } + } else { + /* + * Large resource descriptors + */ + header_length = sizeof(struct asl_large_header); + buffer = byte_stream_buffer + header_length; + + switch (resource_type) { + case ACPI_RDESC_TYPE_LARGE_VENDOR: + /* + * Vendor Defined Resource: + * Add vendor data and ensure a 32-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length); + break; + + case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: + case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: + /* + * 32-Bit or 16-bit Address Resource: + * Add the size of any optional data (resource_source) + */ + extra_struct_bytes = + acpi_rs_stream_option_length + (resource_length, + resource_info->minimum_stream_size); + break; + + case ACPI_RDESC_TYPE_EXTENDED_XRUPT: + /* + * Extended IRQ: + * Point past the interrupt_vector_flags to get the + * interrupt_table_length. + */ + buffer++; + + /* + * Add 4 bytes for each additional interrupt. Note: at least one + * interrupt is required and is included in the minimum + * descriptor size + */ + extra_struct_bytes = + ((*buffer - 1) * sizeof(u32)); + + /* Add the size of any optional data (resource_source) */ + + extra_struct_bytes += + acpi_rs_stream_option_length(resource_length + - + extra_struct_bytes, + resource_info-> + minimum_stream_size); + break; + + case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: + /* + * 64-Bit Address Resource: + * Add the size of any optional data (resource_source) + * Ensure a 64-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_64_bITS + (acpi_rs_stream_option_length + (resource_length, + resource_info->minimum_stream_size)); + break; + + default: + break; + } + } + + /* Update the required buffer size for the internal descriptor structs */ + + temp16 = + (u16) (resource_info->minimum_struct_size + + extra_struct_bytes); + buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(temp16); + + /* + * Update byte count and point to the next resource within the stream + * using the size of the header plus the length contained in the header + */ + temp16 = (u16) (header_length + resource_length); + bytes_parsed += temp16; + byte_stream_buffer += temp16; } /* This is the data the caller needs */ diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 75bd34d1783f..9d93ee5f0060 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -49,914 +49,324 @@ ACPI_MODULE_NAME("rsdump") #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /* Local prototypes */ -static void acpi_rs_dump_irq(union acpi_resource_data *data); +static void acpi_rs_dump_irq(union acpi_resource_data *resource); -static void acpi_rs_dump_address16(union acpi_resource_data *data); +static void acpi_rs_dump_address16(union acpi_resource_data *resource); -static void acpi_rs_dump_address32(union acpi_resource_data *data); +static void acpi_rs_dump_address32(union acpi_resource_data *resource); -static void acpi_rs_dump_address64(union acpi_resource_data *data); +static void acpi_rs_dump_address64(union acpi_resource_data *resource); -static void acpi_rs_dump_dma(union acpi_resource_data *data); +static void acpi_rs_dump_dma(union acpi_resource_data *resource); -static void acpi_rs_dump_io(union acpi_resource_data *data); +static void acpi_rs_dump_io(union acpi_resource_data *resource); -static void acpi_rs_dump_extended_irq(union acpi_resource_data *data); +static void acpi_rs_dump_extended_irq(union acpi_resource_data *resource); -static void acpi_rs_dump_fixed_io(union acpi_resource_data *data); +static void acpi_rs_dump_fixed_io(union acpi_resource_data *resource); -static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data); +static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource); -static void acpi_rs_dump_memory24(union acpi_resource_data *data); +static void acpi_rs_dump_memory24(union acpi_resource_data *resource); -static void acpi_rs_dump_memory32(union acpi_resource_data *data); +static void acpi_rs_dump_memory32(union acpi_resource_data *resource); -static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data); +static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *resource); -static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data); +static void acpi_rs_dump_vendor_specific(union acpi_resource_data *resource); + +static void acpi_rs_dump_generic_reg(union acpi_resource_data *resource); + +static void acpi_rs_dump_end_depend_fns(union acpi_resource_data *resource); + +static void acpi_rs_dump_end_tag(union acpi_resource_data *resource); + +static void acpi_rs_out_string(char *title, char *value); + +static void acpi_rs_out_integer8(char *title, u8 value); + +static void acpi_rs_out_integer16(char *title, u16 value); + +static void acpi_rs_out_integer32(char *title, u32 value); + +static void acpi_rs_out_integer64(char *title, u64 value); + +static void acpi_rs_out_title(char *title); + +static void acpi_rs_dump_byte_list(u32 length, u8 * data); + +static void acpi_rs_dump_dword_list(u32 length, u32 * data); + +static void acpi_rs_dump_short_byte_list(u32 length, u32 * data); + +static void +acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source); + +static void acpi_rs_dump_address_common(union acpi_resource_data *resource); + +/* Dispatch table for resource dump functions */ + +typedef +void (*ACPI_DUMP_RESOURCE) (union acpi_resource_data * data); + +static ACPI_DUMP_RESOURCE acpi_gbl_dump_resource_dispatch[] = { + acpi_rs_dump_irq, /* ACPI_RSTYPE_IRQ */ + acpi_rs_dump_dma, /* ACPI_RSTYPE_DMA */ + acpi_rs_dump_start_depend_fns, /* ACPI_RSTYPE_START_DPF */ + acpi_rs_dump_end_depend_fns, /* ACPI_RSTYPE_END_DPF */ + acpi_rs_dump_io, /* ACPI_RSTYPE_IO */ + acpi_rs_dump_fixed_io, /* ACPI_RSTYPE_FIXED_IO */ + acpi_rs_dump_vendor_specific, /* ACPI_RSTYPE_VENDOR */ + acpi_rs_dump_end_tag, /* ACPI_RSTYPE_END_TAG */ + acpi_rs_dump_memory24, /* ACPI_RSTYPE_MEM24 */ + acpi_rs_dump_memory32, /* ACPI_RSTYPE_MEM32 */ + acpi_rs_dump_fixed_memory32, /* ACPI_RSTYPE_FIXED_MEM32 */ + acpi_rs_dump_address16, /* ACPI_RSTYPE_ADDRESS16 */ + acpi_rs_dump_address32, /* ACPI_RSTYPE_ADDRESS32 */ + acpi_rs_dump_address64, /* ACPI_RSTYPE_ADDRESS64 */ + acpi_rs_dump_extended_irq, /* ACPI_RSTYPE_EXT_IRQ */ + acpi_rs_dump_generic_reg /* ACPI_RSTYPE_GENERIC_REG */ +}; /******************************************************************************* * - * FUNCTION: acpi_rs_dump_irq + * FUNCTION: acpi_rs_out* * - * PARAMETERS: Data - pointer to the resource structure to dump. + * PARAMETERS: Title - Name of the resource field + * Value - Value of the resource field * * RETURN: None * - * DESCRIPTION: Prints out the various members of the Data structure type. + * DESCRIPTION: Miscellaneous helper functions to consistently format the + * output of the resource dump routines * ******************************************************************************/ -static void acpi_rs_dump_irq(union acpi_resource_data *data) +static void acpi_rs_out_string(char *title, char *value) { - struct acpi_resource_irq *irq_data = (struct acpi_resource_irq *)data; - u8 index = 0; + acpi_os_printf("%30s : %s\n", title, value); +} - ACPI_FUNCTION_ENTRY(); +static void acpi_rs_out_integer8(char *title, u8 value) +{ + acpi_os_printf("%30s : %2.2X\n", title, value); +} - acpi_os_printf("IRQ Resource\n"); +static void acpi_rs_out_integer16(char *title, u16 value) +{ + acpi_os_printf("%30s : %4.4X\n", title, value); +} - acpi_os_printf(" %s Triggered\n", - ACPI_LEVEL_SENSITIVE == - irq_data->edge_level ? "Level" : "Edge"); +static void acpi_rs_out_integer32(char *title, u32 value) +{ + acpi_os_printf("%30s : %8.8X\n", title, value); +} - acpi_os_printf(" Active %s\n", - ACPI_ACTIVE_LOW == - irq_data->active_high_low ? "Low" : "High"); +static void acpi_rs_out_integer64(char *title, u64 value) +{ + acpi_os_printf("%30s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value)); +} - acpi_os_printf(" %s\n", - ACPI_SHARED == - irq_data->shared_exclusive ? "Shared" : "Exclusive"); +static void acpi_rs_out_title(char *title) +{ + acpi_os_printf("%30s : ", title); +} - acpi_os_printf(" %X Interrupts ( ", irq_data->number_of_interrupts); +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump*List + * + * PARAMETERS: Length - Number of elements in the list + * Data - Start of the list + * + * RETURN: None + * + * DESCRIPTION: Miscellaneous functions to dump lists of raw data + * + ******************************************************************************/ - for (index = 0; index < irq_data->number_of_interrupts; index++) { - acpi_os_printf("%X ", irq_data->interrupts[index]); +static void acpi_rs_dump_byte_list(u32 length, u8 * data) +{ + u32 i; + + for (i = 0; i < length; i++) { + acpi_os_printf("%28s%2.2X : %2.2X\n", "Byte", i, data[i]); + } +} + +static void acpi_rs_dump_dword_list(u32 length, u32 * data) +{ + u32 i; + + for (i = 0; i < length; i++) { + acpi_os_printf("%28s%2.2X : %8.8X\n", "Dword", i, data[i]); + } +} + +static void acpi_rs_dump_short_byte_list(u32 length, u32 * data) +{ + u32 i; + + for (i = 0; i < length; i++) { + acpi_os_printf("%X ", data[i]); + } + acpi_os_printf("\n"); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_resource_source + * + * PARAMETERS: resource_source - Pointer to a Resource Source struct + * + * RETURN: None + * + * DESCRIPTION: Common routine for dumping the optional resource_source and the + * corresponding resource_source_index. + * + ******************************************************************************/ + +static void +acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source) +{ + + if (resource_source->index == 0xFF) { + return; } - acpi_os_printf(")\n"); - return; + acpi_rs_out_integer8("Resource Source Index", + (u8) resource_source->index); + + acpi_rs_out_string("Resource Source", + resource_source->string_ptr ? + resource_source->string_ptr : "[Not Specified]"); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_dma + * FUNCTION: acpi_rs_dump_address_common * - * PARAMETERS: Data - pointer to the resource structure to dump. + * PARAMETERS: Resource - Pointer to an internal resource descriptor * * RETURN: None * - * DESCRIPTION: Prints out the various members of the Data structure type. + * DESCRIPTION: Dump the fields that are common to all Address resource + * descriptors * ******************************************************************************/ -static void acpi_rs_dump_dma(union acpi_resource_data *data) +static void acpi_rs_dump_address_common(union acpi_resource_data *resource) { - struct acpi_resource_dma *dma_data = (struct acpi_resource_dma *)data; - u8 index = 0; - ACPI_FUNCTION_ENTRY(); - acpi_os_printf("DMA Resource\n"); + /* Decode the type-specific flags */ - switch (dma_data->type) { - case ACPI_COMPATIBILITY: - acpi_os_printf(" Compatibility mode\n"); - break; - - case ACPI_TYPE_A: - acpi_os_printf(" Type A\n"); - break; - - case ACPI_TYPE_B: - acpi_os_printf(" Type B\n"); - break; - - case ACPI_TYPE_F: - acpi_os_printf(" Type F\n"); - break; - - default: - acpi_os_printf(" Invalid DMA type\n"); - break; - } - - acpi_os_printf(" %sBus Master\n", - ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a "); - - switch (dma_data->transfer) { - case ACPI_TRANSFER_8: - acpi_os_printf(" 8-bit only transfer\n"); - break; - - case ACPI_TRANSFER_8_16: - acpi_os_printf(" 8 and 16-bit transfer\n"); - break; - - case ACPI_TRANSFER_16: - acpi_os_printf(" 16 bit only transfer\n"); - break; - - default: - acpi_os_printf(" Invalid transfer preference\n"); - break; - } - - acpi_os_printf(" Number of Channels: %X ( ", - dma_data->number_of_channels); - - for (index = 0; index < dma_data->number_of_channels; index++) { - acpi_os_printf("%X ", dma_data->channels[index]); - } - - acpi_os_printf(")\n"); - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_start_depend_fns - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data) -{ - struct acpi_resource_start_dpf *sdf_data = - (struct acpi_resource_start_dpf *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Start Dependent Functions Resource\n"); - - switch (sdf_data->compatibility_priority) { - case ACPI_GOOD_CONFIGURATION: - acpi_os_printf(" Good configuration\n"); - break; - - case ACPI_ACCEPTABLE_CONFIGURATION: - acpi_os_printf(" Acceptable configuration\n"); - break; - - case ACPI_SUB_OPTIMAL_CONFIGURATION: - acpi_os_printf(" Sub-optimal configuration\n"); - break; - - default: - acpi_os_printf(" Invalid compatibility priority\n"); - break; - } - - switch (sdf_data->performance_robustness) { - case ACPI_GOOD_CONFIGURATION: - acpi_os_printf(" Good configuration\n"); - break; - - case ACPI_ACCEPTABLE_CONFIGURATION: - acpi_os_printf(" Acceptable configuration\n"); - break; - - case ACPI_SUB_OPTIMAL_CONFIGURATION: - acpi_os_printf(" Sub-optimal configuration\n"); - break; - - default: - acpi_os_printf(" Invalid performance robustness preference\n"); - break; - } - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_io - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_io(union acpi_resource_data *data) -{ - struct acpi_resource_io *io_data = (struct acpi_resource_io *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Io Resource\n"); - - acpi_os_printf(" %d bit decode\n", - ACPI_DECODE_16 == io_data->io_decode ? 16 : 10); - - acpi_os_printf(" Range minimum base: %08X\n", - io_data->min_base_address); - - acpi_os_printf(" Range maximum base: %08X\n", - io_data->max_base_address); - - acpi_os_printf(" Alignment: %08X\n", io_data->alignment); - - acpi_os_printf(" Range Length: %08X\n", io_data->range_length); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_fixed_io - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_fixed_io(union acpi_resource_data *data) -{ - struct acpi_resource_fixed_io *fixed_io_data = - (struct acpi_resource_fixed_io *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Fixed Io Resource\n"); - acpi_os_printf(" Range base address: %08X", - fixed_io_data->base_address); - - acpi_os_printf(" Range length: %08X", fixed_io_data->range_length); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_vendor_specific - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data) -{ - struct acpi_resource_vendor *vendor_data = - (struct acpi_resource_vendor *)data; - u16 index = 0; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Vendor Specific Resource\n"); - - acpi_os_printf(" Length: %08X\n", vendor_data->length); - - for (index = 0; index < vendor_data->length; index++) { - acpi_os_printf(" Byte %X: %08X\n", - index, vendor_data->reserved[index]); - } - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_memory24 - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_memory24(union acpi_resource_data *data) -{ - struct acpi_resource_mem24 *memory24_data = - (struct acpi_resource_mem24 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("24-Bit Memory Range Resource\n"); - - acpi_os_printf(" Read%s\n", - ACPI_READ_WRITE_MEMORY == - memory24_data->read_write_attribute ? - "/Write" : " only"); - - acpi_os_printf(" Range minimum base: %08X\n", - memory24_data->min_base_address); - - acpi_os_printf(" Range maximum base: %08X\n", - memory24_data->max_base_address); - - acpi_os_printf(" Alignment: %08X\n", memory24_data->alignment); - - acpi_os_printf(" Range length: %08X\n", memory24_data->range_length); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_memory32 - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_memory32(union acpi_resource_data *data) -{ - struct acpi_resource_mem32 *memory32_data = - (struct acpi_resource_mem32 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("32-Bit Memory Range Resource\n"); - - acpi_os_printf(" Read%s\n", - ACPI_READ_WRITE_MEMORY == - memory32_data->read_write_attribute ? - "/Write" : " only"); - - acpi_os_printf(" Range minimum base: %08X\n", - memory32_data->min_base_address); - - acpi_os_printf(" Range maximum base: %08X\n", - memory32_data->max_base_address); - - acpi_os_printf(" Alignment: %08X\n", memory32_data->alignment); - - acpi_os_printf(" Range length: %08X\n", memory32_data->range_length); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_fixed_memory32 - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data) -{ - struct acpi_resource_fixed_mem32 *fixed_memory32_data = - (struct acpi_resource_fixed_mem32 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("32-Bit Fixed Location Memory Range Resource\n"); - - acpi_os_printf(" Read%s\n", - ACPI_READ_WRITE_MEMORY == - fixed_memory32_data-> - read_write_attribute ? "/Write" : " Only"); - - acpi_os_printf(" Range base address: %08X\n", - fixed_memory32_data->range_base_address); - - acpi_os_printf(" Range length: %08X\n", - fixed_memory32_data->range_length); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_address16 - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_address16(union acpi_resource_data *data) -{ - struct acpi_resource_address16 *address16_data = - (struct acpi_resource_address16 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("16-Bit Address Space Resource\n"); - acpi_os_printf(" Resource Type: "); - - switch (address16_data->resource_type) { + switch (resource->address.resource_type) { case ACPI_MEMORY_RANGE: - acpi_os_printf("Memory Range\n"); + acpi_rs_out_string("Resource Type", "Memory Range"); - switch (address16_data->attribute.memory.cache_attribute) { + acpi_rs_out_title("Type-Specific Flags"); + + switch (resource->address.attribute.memory.cache_attribute) { case ACPI_NON_CACHEABLE_MEMORY: - acpi_os_printf - (" Type Specific: Noncacheable memory\n"); + acpi_os_printf("Noncacheable memory\n"); break; case ACPI_CACHABLE_MEMORY: - acpi_os_printf(" Type Specific: Cacheable memory\n"); + acpi_os_printf("Cacheable memory\n"); break; case ACPI_WRITE_COMBINING_MEMORY: - acpi_os_printf - (" Type Specific: Write-combining memory\n"); + acpi_os_printf("Write-combining memory\n"); break; case ACPI_PREFETCHABLE_MEMORY: - acpi_os_printf - (" Type Specific: Prefetchable memory\n"); + acpi_os_printf("Prefetchable memory\n"); break; default: - acpi_os_printf - (" Type Specific: Invalid cache attribute\n"); + acpi_os_printf("Invalid cache attribute\n"); break; } - acpi_os_printf(" Type Specific: Read%s\n", - ACPI_READ_WRITE_MEMORY == - address16_data->attribute.memory. - read_write_attribute ? "/Write" : " Only"); + acpi_rs_out_string("Read/Write Attribute", + ACPI_READ_WRITE_MEMORY == + resource->address.attribute.memory. + read_write_attribute ? "Read/Write" : + "Read Only"); break; case ACPI_IO_RANGE: - acpi_os_printf("I/O Range\n"); + acpi_rs_out_string("Resource Type", "I/O Range"); - switch (address16_data->attribute.io.range_attribute) { + acpi_rs_out_title("Type-Specific Flags"); + + switch (resource->address.attribute.io.range_attribute) { case ACPI_NON_ISA_ONLY_RANGES: - acpi_os_printf - (" Type Specific: Non-ISA Io Addresses\n"); + acpi_os_printf("Non-ISA I/O Addresses\n"); break; case ACPI_ISA_ONLY_RANGES: - acpi_os_printf(" Type Specific: ISA Io Addresses\n"); + acpi_os_printf("ISA I/O Addresses\n"); break; case ACPI_ENTIRE_RANGE: - acpi_os_printf - (" Type Specific: ISA and non-ISA Io Addresses\n"); + acpi_os_printf("ISA and non-ISA I/O Addresses\n"); break; default: - acpi_os_printf - (" Type Specific: Invalid range attribute\n"); + acpi_os_printf("Invalid range attribute\n"); break; } - acpi_os_printf(" Type Specific: %s Translation\n", - ACPI_SPARSE_TRANSLATION == - address16_data->attribute.io. - translation_attribute ? "Sparse" : "Dense"); + acpi_rs_out_string("Translation Attribute", + ACPI_SPARSE_TRANSLATION == + resource->address.attribute.io. + translation_attribute ? "Sparse Translation" + : "Dense Translation"); break; case ACPI_BUS_NUMBER_RANGE: - acpi_os_printf("Bus Number Range\n"); + acpi_rs_out_string("Resource Type", "Bus Number Range"); break; default: - acpi_os_printf("0x%2.2X\n", address16_data->resource_type); + acpi_rs_out_integer8("Resource Type", + (u8) resource->address.resource_type); break; } - acpi_os_printf(" Resource %s\n", - ACPI_CONSUMER == address16_data->producer_consumer ? - "Consumer" : "Producer"); - - acpi_os_printf(" %s decode\n", - ACPI_SUB_DECODE == address16_data->decode ? - "Subtractive" : "Positive"); - - acpi_os_printf(" Min address is %s fixed\n", - ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ? - "" : "not"); - - acpi_os_printf(" Max address is %s fixed\n", - ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ? - "" : "not"); - - acpi_os_printf(" Granularity: %08X\n", address16_data->granularity); - - acpi_os_printf(" Address range min: %08X\n", - address16_data->min_address_range); - - acpi_os_printf(" Address range max: %08X\n", - address16_data->max_address_range); - - acpi_os_printf(" Address translation offset: %08X\n", - address16_data->address_translation_offset); - - acpi_os_printf(" Address Length: %08X\n", - address16_data->address_length); - - if (0xFF != address16_data->resource_source.index) { - acpi_os_printf(" Resource Source Index: %X\n", - address16_data->resource_source.index); - - acpi_os_printf(" Resource Source: %s\n", - address16_data->resource_source.string_ptr); - } - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_address32 - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_address32(union acpi_resource_data *data) -{ - struct acpi_resource_address32 *address32_data = - (struct acpi_resource_address32 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("32-Bit Address Space Resource\n"); - - switch (address32_data->resource_type) { - case ACPI_MEMORY_RANGE: - - acpi_os_printf(" Resource Type: Memory Range\n"); - - switch (address32_data->attribute.memory.cache_attribute) { - case ACPI_NON_CACHEABLE_MEMORY: - acpi_os_printf - (" Type Specific: Noncacheable memory\n"); - break; - - case ACPI_CACHABLE_MEMORY: - acpi_os_printf(" Type Specific: Cacheable memory\n"); - break; - - case ACPI_WRITE_COMBINING_MEMORY: - acpi_os_printf - (" Type Specific: Write-combining memory\n"); - break; - - case ACPI_PREFETCHABLE_MEMORY: - acpi_os_printf - (" Type Specific: Prefetchable memory\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid cache attribute\n"); - break; - } - - acpi_os_printf(" Type Specific: Read%s\n", - ACPI_READ_WRITE_MEMORY == - address32_data->attribute.memory. - read_write_attribute ? "/Write" : " Only"); - break; - - case ACPI_IO_RANGE: - - acpi_os_printf(" Resource Type: Io Range\n"); - - switch (address32_data->attribute.io.range_attribute) { - case ACPI_NON_ISA_ONLY_RANGES: - acpi_os_printf - (" Type Specific: Non-ISA Io Addresses\n"); - break; - - case ACPI_ISA_ONLY_RANGES: - acpi_os_printf(" Type Specific: ISA Io Addresses\n"); - break; - - case ACPI_ENTIRE_RANGE: - acpi_os_printf - (" Type Specific: ISA and non-ISA Io Addresses\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid Range attribute"); - break; - } - - acpi_os_printf(" Type Specific: %s Translation\n", - ACPI_SPARSE_TRANSLATION == - address32_data->attribute.io. - translation_attribute ? "Sparse" : "Dense"); - break; - - case ACPI_BUS_NUMBER_RANGE: - - acpi_os_printf(" Resource Type: Bus Number Range\n"); - break; - - default: - - acpi_os_printf(" Resource Type: 0x%2.2X\n", - address32_data->resource_type); - break; - } - - acpi_os_printf(" Resource %s\n", - ACPI_CONSUMER == address32_data->producer_consumer ? - "Consumer" : "Producer"); - - acpi_os_printf(" %s decode\n", - ACPI_SUB_DECODE == address32_data->decode ? - "Subtractive" : "Positive"); - - acpi_os_printf(" Min address is %s fixed\n", - ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ? - "" : "not "); - - acpi_os_printf(" Max address is %s fixed\n", - ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ? - "" : "not "); - - acpi_os_printf(" Granularity: %08X\n", address32_data->granularity); - - acpi_os_printf(" Address range min: %08X\n", - address32_data->min_address_range); - - acpi_os_printf(" Address range max: %08X\n", - address32_data->max_address_range); - - acpi_os_printf(" Address translation offset: %08X\n", - address32_data->address_translation_offset); - - acpi_os_printf(" Address Length: %08X\n", - address32_data->address_length); - - if (0xFF != address32_data->resource_source.index) { - acpi_os_printf(" Resource Source Index: %X\n", - address32_data->resource_source.index); - - acpi_os_printf(" Resource Source: %s\n", - address32_data->resource_source.string_ptr); - } - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_address64 - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_address64(union acpi_resource_data *data) -{ - struct acpi_resource_address64 *address64_data = - (struct acpi_resource_address64 *)data; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("64-Bit Address Space Resource\n"); - - switch (address64_data->resource_type) { - case ACPI_MEMORY_RANGE: - - acpi_os_printf(" Resource Type: Memory Range\n"); - - switch (address64_data->attribute.memory.cache_attribute) { - case ACPI_NON_CACHEABLE_MEMORY: - acpi_os_printf - (" Type Specific: Noncacheable memory\n"); - break; - - case ACPI_CACHABLE_MEMORY: - acpi_os_printf(" Type Specific: Cacheable memory\n"); - break; - - case ACPI_WRITE_COMBINING_MEMORY: - acpi_os_printf - (" Type Specific: Write-combining memory\n"); - break; - - case ACPI_PREFETCHABLE_MEMORY: - acpi_os_printf - (" Type Specific: Prefetchable memory\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid cache attribute\n"); - break; - } - - acpi_os_printf(" Type Specific: Read%s\n", - ACPI_READ_WRITE_MEMORY == - address64_data->attribute.memory. - read_write_attribute ? "/Write" : " Only"); - break; - - case ACPI_IO_RANGE: - - acpi_os_printf(" Resource Type: Io Range\n"); - - switch (address64_data->attribute.io.range_attribute) { - case ACPI_NON_ISA_ONLY_RANGES: - acpi_os_printf - (" Type Specific: Non-ISA Io Addresses\n"); - break; - - case ACPI_ISA_ONLY_RANGES: - acpi_os_printf(" Type Specific: ISA Io Addresses\n"); - break; - - case ACPI_ENTIRE_RANGE: - acpi_os_printf - (" Type Specific: ISA and non-ISA Io Addresses\n"); - break; - - default: - acpi_os_printf - (" Type Specific: Invalid Range attribute"); - break; - } - - acpi_os_printf(" Type Specific: %s Translation\n", - ACPI_SPARSE_TRANSLATION == - address64_data->attribute.io. - translation_attribute ? "Sparse" : "Dense"); - break; - - case ACPI_BUS_NUMBER_RANGE: - - acpi_os_printf(" Resource Type: Bus Number Range\n"); - break; - - default: - - acpi_os_printf(" Resource Type: 0x%2.2X\n", - address64_data->resource_type); - break; - } - - acpi_os_printf(" Resource %s\n", - ACPI_CONSUMER == address64_data->producer_consumer ? - "Consumer" : "Producer"); - - acpi_os_printf(" %s decode\n", - ACPI_SUB_DECODE == address64_data->decode ? - "Subtractive" : "Positive"); - - acpi_os_printf(" Min address is %s fixed\n", - ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ? - "" : "not "); - - acpi_os_printf(" Max address is %s fixed\n", - ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ? - "" : "not "); - - acpi_os_printf(" Granularity: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data->granularity)); - - acpi_os_printf(" Address range min: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data->min_address_range)); - - acpi_os_printf(" Address range max: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data->max_address_range)); - - acpi_os_printf(" Address translation offset: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data-> - address_translation_offset)); - - acpi_os_printf(" Address Length: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data->address_length)); - - acpi_os_printf(" Type Specific Attributes: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(address64_data-> - type_specific_attributes)); - - if (0xFF != address64_data->resource_source.index) { - acpi_os_printf(" Resource Source Index: %X\n", - address64_data->resource_source.index); - - acpi_os_printf(" Resource Source: %s\n", - address64_data->resource_source.string_ptr); - } - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_extended_irq - * - * PARAMETERS: Data - pointer to the resource structure to dump. - * - * RETURN: None - * - * DESCRIPTION: Prints out the various members of the Data structure type. - * - ******************************************************************************/ - -static void acpi_rs_dump_extended_irq(union acpi_resource_data *data) -{ - struct acpi_resource_ext_irq *ext_irq_data = - (struct acpi_resource_ext_irq *)data; - u8 index = 0; - - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Extended IRQ Resource\n"); - - acpi_os_printf(" Resource %s\n", - ACPI_CONSUMER == ext_irq_data->producer_consumer ? - "Consumer" : "Producer"); - - acpi_os_printf(" %s\n", - ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ? - "Level" : "Edge"); - - acpi_os_printf(" Active %s\n", - ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ? - "low" : "high"); - - acpi_os_printf(" %s\n", - ACPI_SHARED == ext_irq_data->shared_exclusive ? - "Shared" : "Exclusive"); - - acpi_os_printf(" Interrupts : %X ( ", - ext_irq_data->number_of_interrupts); - - for (index = 0; index < ext_irq_data->number_of_interrupts; index++) { - acpi_os_printf("%X ", ext_irq_data->interrupts[index]); - } - - acpi_os_printf(")\n"); - - if (0xFF != ext_irq_data->resource_source.index) { - acpi_os_printf(" Resource Source Index: %X", - ext_irq_data->resource_source.index); - - acpi_os_printf(" Resource Source: %s", - ext_irq_data->resource_source.string_ptr); - } - - return; + /* Decode the general flags */ + + acpi_rs_out_string("Resource", + ACPI_CONSUMER == + resource->address. + producer_consumer ? "Consumer" : "Producer"); + + acpi_rs_out_string("Decode", + ACPI_SUB_DECODE == resource->address.decode ? + "Subtractive" : "Positive"); + + acpi_rs_out_string("Min Address", + ACPI_ADDRESS_FIXED == + resource->address. + min_address_fixed ? "Fixed" : "Not Fixed"); + + acpi_rs_out_string("Max Address", + ACPI_ADDRESS_FIXED == + resource->address. + max_address_fixed ? "Fixed" : "Not Fixed"); } /******************************************************************************* * * FUNCTION: acpi_rs_dump_resource_list * - * PARAMETERS: Resource - pointer to the resource structure to dump. + * PARAMETERS: resource_list - Pointer to a resource descriptor list * * RETURN: None * @@ -964,106 +374,642 @@ static void acpi_rs_dump_extended_irq(union acpi_resource_data *data) * ******************************************************************************/ -void acpi_rs_dump_resource_list(struct acpi_resource *resource) +void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) { - u8 count = 0; - u8 done = FALSE; + u32 count = 0; ACPI_FUNCTION_ENTRY(); - if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { - while (!done) { - acpi_os_printf("Resource structure %X.\n", count++); - - switch (resource->id) { - case ACPI_RSTYPE_IRQ: - acpi_rs_dump_irq(&resource->data); - break; - - case ACPI_RSTYPE_DMA: - acpi_rs_dump_dma(&resource->data); - break; - - case ACPI_RSTYPE_START_DPF: - acpi_rs_dump_start_depend_fns(&resource->data); - break; - - case ACPI_RSTYPE_END_DPF: - acpi_os_printf - ("end_dependent_functions Resource\n"); - /* acpi_rs_dump_end_dependent_functions (Resource->Data); */ - break; - - case ACPI_RSTYPE_IO: - acpi_rs_dump_io(&resource->data); - break; - - case ACPI_RSTYPE_FIXED_IO: - acpi_rs_dump_fixed_io(&resource->data); - break; - - case ACPI_RSTYPE_VENDOR: - acpi_rs_dump_vendor_specific(&resource->data); - break; - - case ACPI_RSTYPE_END_TAG: - /*rs_dump_end_tag (Resource->Data); */ - acpi_os_printf("end_tag Resource\n"); - done = TRUE; - break; - - case ACPI_RSTYPE_MEM24: - acpi_rs_dump_memory24(&resource->data); - break; - - case ACPI_RSTYPE_MEM32: - acpi_rs_dump_memory32(&resource->data); - break; - - case ACPI_RSTYPE_FIXED_MEM32: - acpi_rs_dump_fixed_memory32(&resource->data); - break; - - case ACPI_RSTYPE_ADDRESS16: - acpi_rs_dump_address16(&resource->data); - break; - - case ACPI_RSTYPE_ADDRESS32: - acpi_rs_dump_address32(&resource->data); - break; - - case ACPI_RSTYPE_ADDRESS64: - acpi_rs_dump_address64(&resource->data); - break; - - case ACPI_RSTYPE_EXT_IRQ: - acpi_rs_dump_extended_irq(&resource->data); - break; - - default: - acpi_os_printf("Invalid resource type\n"); - break; - - } - - resource = - ACPI_PTR_ADD(struct acpi_resource, resource, - resource->length); - } + if (!(acpi_dbg_level & ACPI_LV_RESOURCES) + || !(_COMPONENT & acpi_dbg_layer)) { + return; } - return; + /* Dump all resource descriptors in the list */ + + while (resource_list) { + acpi_os_printf("\n[%02X] ", count); + + /* Validate Type before dispatch */ + + if (resource_list->type > ACPI_RSTYPE_MAX) { + acpi_os_printf + ("Invalid descriptor type (%X) in resource list\n", + resource_list->type); + return; + } + + /* Dump the resource descriptor */ + + acpi_gbl_dump_resource_dispatch[resource_list-> + type] (&resource_list->data); + + /* Exit on end tag */ + + if (resource_list->type == ACPI_RSTYPE_END_TAG) { + return; + } + + /* Get the next resource structure */ + + resource_list = + ACPI_PTR_ADD(struct acpi_resource, resource_list, + resource_list->length); + count++; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_irq + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_irq(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("IRQ Resource\n"); + + acpi_rs_out_string("Triggering", + ACPI_LEVEL_SENSITIVE == + resource->irq.edge_level ? "Level" : "Edge"); + + acpi_rs_out_string("Active", + ACPI_ACTIVE_LOW == + resource->irq.active_high_low ? "Low" : "High"); + + acpi_rs_out_string("Sharing", + ACPI_SHARED == + resource->irq. + shared_exclusive ? "Shared" : "Exclusive"); + + acpi_rs_out_integer8("Interrupt Count", + (u8) resource->irq.number_of_interrupts); + + acpi_rs_out_title("Interrupt List"); + acpi_rs_dump_short_byte_list(resource->irq.number_of_interrupts, + resource->irq.interrupts); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_dma + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_dma(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("DMA Resource\n"); + + acpi_rs_out_title("DMA Type"); + switch (resource->dma.type) { + case ACPI_COMPATIBILITY: + acpi_os_printf("Compatibility mode\n"); + break; + + case ACPI_TYPE_A: + acpi_os_printf("Type A\n"); + break; + + case ACPI_TYPE_B: + acpi_os_printf("Type B\n"); + break; + + case ACPI_TYPE_F: + acpi_os_printf("Type F\n"); + break; + + default: + acpi_os_printf("**** Invalid DMA type\n"); + break; + } + + acpi_rs_out_string("Bus Master", + ACPI_BUS_MASTER == + resource->dma.bus_master ? "Yes" : "No"); + + acpi_rs_out_title("Transfer Type"); + switch (resource->dma.transfer) { + case ACPI_TRANSFER_8: + acpi_os_printf("8-bit transfers only\n"); + break; + + case ACPI_TRANSFER_8_16: + acpi_os_printf("8-bit and 16-bit transfers\n"); + break; + + case ACPI_TRANSFER_16: + acpi_os_printf("16-bit transfers only\n"); + break; + + default: + acpi_os_printf("**** Invalid transfer preference\n"); + break; + } + + acpi_rs_out_integer8("DMA Channel Count", + (u8) resource->dma.number_of_channels); + + acpi_rs_out_title("Channel List"); + acpi_rs_dump_short_byte_list(resource->dma.number_of_channels, + resource->dma.channels); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_start_depend_fns + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("Start Dependent Functions Resource\n"); + + acpi_rs_out_title("Compatibility Priority"); + switch (resource->start_dpf.compatibility_priority) { + case ACPI_GOOD_CONFIGURATION: + acpi_os_printf("Good configuration\n"); + break; + + case ACPI_ACCEPTABLE_CONFIGURATION: + acpi_os_printf("Acceptable configuration\n"); + break; + + case ACPI_SUB_OPTIMAL_CONFIGURATION: + acpi_os_printf("Sub-optimal configuration\n"); + break; + + default: + acpi_os_printf("**** Invalid compatibility priority\n"); + break; + } + + acpi_rs_out_title("Performance/Robustness"); + switch (resource->start_dpf.performance_robustness) { + case ACPI_GOOD_CONFIGURATION: + acpi_os_printf("Good configuration\n"); + break; + + case ACPI_ACCEPTABLE_CONFIGURATION: + acpi_os_printf("Acceptable configuration\n"); + break; + + case ACPI_SUB_OPTIMAL_CONFIGURATION: + acpi_os_printf("Sub-optimal configuration\n"); + break; + + default: + acpi_os_printf + ("**** Invalid performance robustness preference\n"); + break; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_io + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_io(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("I/O Resource\n"); + + acpi_rs_out_string("Decode", + ACPI_DECODE_16 == + resource->io.io_decode ? "16-bit" : "10-bit"); + + acpi_rs_out_integer32("Range Minimum Base", + resource->io.min_base_address); + + acpi_rs_out_integer32("Range Maximum Base", + resource->io.max_base_address); + + acpi_rs_out_integer32("Alignment", resource->io.alignment); + + acpi_rs_out_integer32("Range Length", resource->io.range_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_fixed_io + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_fixed_io(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("Fixed I/O Resource\n"); + + acpi_rs_out_integer32("Range Base Address", + resource->fixed_io.base_address); + + acpi_rs_out_integer32("Range Length", resource->fixed_io.range_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_vendor_specific + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_vendor_specific(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("Vendor Specific Resource\n"); + + acpi_rs_out_integer16("Length", (u16) resource->vendor_specific.length); + + acpi_rs_dump_byte_list(resource->vendor_specific.length, + resource->vendor_specific.reserved); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_memory24 + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_memory24(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("24-Bit Memory Range Resource\n"); + + acpi_rs_out_string("Attribute", + ACPI_READ_WRITE_MEMORY == + resource->memory24.read_write_attribute ? + "Read/Write" : "Read Only"); + + acpi_rs_out_integer16("Range Minimum Base", + (u16) resource->memory24.min_base_address); + + acpi_rs_out_integer16("Range Maximum Base", + (u16) resource->memory24.max_base_address); + + acpi_rs_out_integer16("Alignment", (u16) resource->memory24.alignment); + + acpi_rs_out_integer16("Range Length", + (u16) resource->memory24.range_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_memory32 + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_memory32(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("32-Bit Memory Range Resource\n"); + + acpi_rs_out_string("Attribute", + ACPI_READ_WRITE_MEMORY == + resource->memory32.read_write_attribute ? + "Read/Write" : "Read Only"); + + acpi_rs_out_integer32("Range Minimum Base", + resource->memory32.min_base_address); + + acpi_rs_out_integer32("Range Maximum Base", + resource->memory32.max_base_address); + + acpi_rs_out_integer32("Alignment", resource->memory32.alignment); + + acpi_rs_out_integer32("Range Length", resource->memory32.range_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_fixed_memory32 + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("32-Bit Fixed Location Memory Range Resource\n"); + + acpi_rs_out_string("Attribute", + ACPI_READ_WRITE_MEMORY == + resource->fixed_memory32.read_write_attribute ? + "Read/Write" : "Read Only"); + + acpi_rs_out_integer32("Range Base Address", + resource->fixed_memory32.range_base_address); + + acpi_rs_out_integer32("Range Length", + resource->fixed_memory32.range_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_address16 + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_address16(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("16-Bit Address Space Resource\n"); + + acpi_rs_dump_address_common(resource); + + acpi_rs_out_integer16("Granularity", + (u16) resource->address16.granularity); + + acpi_rs_out_integer16("Address Range Min", + (u16) resource->address16.min_address_range); + + acpi_rs_out_integer16("Address Range Max", + (u16) resource->address16.max_address_range); + + acpi_rs_out_integer16("Address Translation Offset", + (u16) resource->address16. + address_translation_offset); + + acpi_rs_out_integer16("Address Length", + (u16) resource->address16.address_length); + + acpi_rs_dump_resource_source(&resource->address16.resource_source); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_address32 + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_address32(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("32-Bit Address Space Resource\n"); + + acpi_rs_dump_address_common(resource); + + acpi_rs_out_integer32("Granularity", resource->address32.granularity); + + acpi_rs_out_integer32("Address Range Min", + resource->address32.min_address_range); + + acpi_rs_out_integer32("Address Range Max", + resource->address32.max_address_range); + + acpi_rs_out_integer32("Address Translation Offset", + resource->address32.address_translation_offset); + + acpi_rs_out_integer32("Address Length", + resource->address32.address_length); + + acpi_rs_dump_resource_source(&resource->address32.resource_source); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_address64 + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_address64(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("64-Bit Address Space Resource\n"); + + acpi_rs_dump_address_common(resource); + + acpi_rs_out_integer64("Granularity", resource->address64.granularity); + + acpi_rs_out_integer64("Address Range Min", + resource->address64.min_address_range); + + acpi_rs_out_integer64("Address Range Max", + resource->address64.max_address_range); + + acpi_rs_out_integer64("Address Translation Offset", + resource->address64.address_translation_offset); + + acpi_rs_out_integer64("Address Length", + resource->address64.address_length); + + acpi_rs_out_integer64("Type Specific Attributes", + resource->address64.type_specific_attributes); + + acpi_rs_dump_resource_source(&resource->address64.resource_source); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_extended_irq + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_extended_irq(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("Extended IRQ Resource\n"); + + acpi_rs_out_string("Resource", + ACPI_CONSUMER == + resource->extended_irq. + producer_consumer ? "Consumer" : "Producer"); + + acpi_rs_out_string("Triggering", + ACPI_LEVEL_SENSITIVE == + resource->extended_irq. + edge_level ? "Level" : "Edge"); + + acpi_rs_out_string("Active", + ACPI_ACTIVE_LOW == + resource->extended_irq. + active_high_low ? "Low" : "High"); + + acpi_rs_out_string("Sharing", + ACPI_SHARED == + resource->extended_irq. + shared_exclusive ? "Shared" : "Exclusive"); + + acpi_rs_dump_resource_source(&resource->extended_irq.resource_source); + + acpi_rs_out_integer8("Interrupts", + (u8) resource->extended_irq.number_of_interrupts); + + acpi_rs_dump_dword_list(resource->extended_irq.number_of_interrupts, + resource->extended_irq.interrupts); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_generic_reg + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +static void acpi_rs_dump_generic_reg(union acpi_resource_data *resource) +{ + + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("Generic Register Resource\n"); + + acpi_rs_out_integer8("Space ID", (u8) resource->generic_reg.space_id); + + acpi_rs_out_integer8("Bit Width", (u8) resource->generic_reg.bit_width); + + acpi_rs_out_integer8("Bit Offset", + (u8) resource->generic_reg.bit_offset); + + acpi_rs_out_integer8("Address Size", + (u8) resource->generic_reg.address_size); + + acpi_rs_out_integer64("Address", resource->generic_reg.address); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_end_depend_fns + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Print type, no data. + * + ******************************************************************************/ + +static void acpi_rs_dump_end_depend_fns(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("end_dependent_functions Resource\n"); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_end_tag + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Print type, no data. + * + ******************************************************************************/ + +static void acpi_rs_dump_end_tag(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("end_tag Resource\n"); } /******************************************************************************* * * FUNCTION: acpi_rs_dump_irq_list * - * PARAMETERS: route_table - pointer to the routing table to dump. + * PARAMETERS: route_table - Pointer to the routing table to dump. * * RETURN: None * - * DESCRIPTION: Dispatches the structures to the correct dump routine. + * DESCRIPTION: Print IRQ routing table * ******************************************************************************/ @@ -1071,41 +1017,35 @@ void acpi_rs_dump_irq_list(u8 * route_table) { u8 *buffer = route_table; u8 count = 0; - u8 done = FALSE; struct acpi_pci_routing_table *prt_element; ACPI_FUNCTION_ENTRY(); - if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { - prt_element = - ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); - - while (!done) { - acpi_os_printf("PCI IRQ Routing Table structure %X.\n", - count++); - - acpi_os_printf(" Address: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(prt_element-> - address)); - - acpi_os_printf(" Pin: %X\n", prt_element->pin); - - acpi_os_printf(" Source: %s\n", prt_element->source); - - acpi_os_printf(" source_index: %X\n", - prt_element->source_index); - - buffer += prt_element->length; - prt_element = - ACPI_CAST_PTR(struct acpi_pci_routing_table, - buffer); - if (0 == prt_element->length) { - done = TRUE; - } - } + if (!(acpi_dbg_level & ACPI_LV_RESOURCES) + || !(_COMPONENT & acpi_dbg_layer)) { + return; } - return; + prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); + + /* Dump all table elements, Exit on null length element */ + + while (prt_element->length) { + acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n", + count); + + acpi_rs_out_integer64("Address", prt_element->address); + + acpi_rs_out_integer32("Pin", prt_element->pin); + acpi_rs_out_string("Source", prt_element->source); + acpi_rs_out_integer32("Source Index", + prt_element->source_index); + + buffer += prt_element->length; + prt_element = + ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); + count++; + } } #endif diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index d53bbe89e851..6574e2ae2e52 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -84,7 +84,7 @@ acpi_rs_io_resource(u8 * byte_stream_buffer, *bytes_consumed = 8; - output_struct->id = ACPI_RSTYPE_IO; + output_struct->type = ACPI_RSTYPE_IO; /* Check Decode */ @@ -170,7 +170,7 @@ acpi_rs_fixed_io_resource(u8 * byte_stream_buffer, *bytes_consumed = 4; - output_struct->id = ACPI_RSTYPE_FIXED_IO; + output_struct->type = ACPI_RSTYPE_FIXED_IO; /* Check Range Base Address */ @@ -200,7 +200,7 @@ acpi_rs_fixed_io_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_io_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -213,7 +213,7 @@ acpi_rs_fixed_io_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_io_stream(struct acpi_resource *linked_list, +acpi_rs_io_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -222,42 +222,42 @@ acpi_rs_io_stream(struct acpi_resource *linked_list, ACPI_FUNCTION_TRACE("rs_io_stream"); - /* The descriptor field is static */ + /* The Descriptor Type field is static */ - *buffer = 0x47; + *buffer = ACPI_RDESC_TYPE_IO_PORT | 0x07; buffer += 1; /* Io Information Byte */ - temp8 = (u8) (linked_list->data.io.io_decode & 0x01); + temp8 = (u8) (resource->data.io.io_decode & 0x01); *buffer = temp8; buffer += 1; /* Set the Range minimum base address */ - temp16 = (u16) linked_list->data.io.min_base_address; + temp16 = (u16) resource->data.io.min_base_address; ACPI_MOVE_16_TO_16(buffer, &temp16); buffer += 2; /* Set the Range maximum base address */ - temp16 = (u16) linked_list->data.io.max_base_address; + temp16 = (u16) resource->data.io.max_base_address; ACPI_MOVE_16_TO_16(buffer, &temp16); buffer += 2; /* Set the base alignment */ - temp8 = (u8) linked_list->data.io.alignment; + temp8 = (u8) resource->data.io.alignment; *buffer = temp8; buffer += 1; /* Set the range length */ - temp8 = (u8) linked_list->data.io.range_length; + temp8 = (u8) resource->data.io.range_length; *buffer = temp8; buffer += 1; @@ -272,7 +272,7 @@ acpi_rs_io_stream(struct acpi_resource *linked_list, * * FUNCTION: acpi_rs_fixed_io_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -285,7 +285,7 @@ acpi_rs_io_stream(struct acpi_resource *linked_list, ******************************************************************************/ acpi_status -acpi_rs_fixed_io_stream(struct acpi_resource *linked_list, +acpi_rs_fixed_io_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -294,22 +294,21 @@ acpi_rs_fixed_io_stream(struct acpi_resource *linked_list, ACPI_FUNCTION_TRACE("rs_fixed_io_stream"); - /* The descriptor field is static */ - - *buffer = 0x4B; + /* The Descriptor Type field is static */ + *buffer = ACPI_RDESC_TYPE_FIXED_IO_PORT | 0x03; buffer += 1; /* Set the Range base address */ - temp16 = (u16) linked_list->data.fixed_io.base_address; + temp16 = (u16) resource->data.fixed_io.base_address; ACPI_MOVE_16_TO_16(buffer, &temp16); buffer += 2; /* Set the range length */ - temp8 = (u8) linked_list->data.fixed_io.range_length; + temp8 = (u8) resource->data.fixed_io.range_length; *buffer = temp8; buffer += 1; @@ -358,7 +357,7 @@ acpi_rs_dma_resource(u8 * byte_stream_buffer, /* The number of bytes consumed are Constant */ *bytes_consumed = 3; - output_struct->id = ACPI_RSTYPE_DMA; + output_struct->type = ACPI_RSTYPE_DMA; /* Point to the 8-bits of Byte 1 */ @@ -420,7 +419,7 @@ acpi_rs_dma_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_dma_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -433,7 +432,7 @@ acpi_rs_dma_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_dma_stream(struct acpi_resource *linked_list, +acpi_rs_dma_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -443,17 +442,16 @@ acpi_rs_dma_stream(struct acpi_resource *linked_list, ACPI_FUNCTION_TRACE("rs_dma_stream"); - /* The descriptor field is static */ + /* The Descriptor Type field is static */ - *buffer = 0x2A; + *buffer = ACPI_RDESC_TYPE_DMA_FORMAT | 0x02; buffer += 1; temp8 = 0; /* Loop through all of the Channels and set the mask bits */ - for (index = 0; - index < linked_list->data.dma.number_of_channels; index++) { - temp16 = (u16) linked_list->data.dma.channels[index]; + for (index = 0; index < resource->data.dma.number_of_channels; index++) { + temp16 = (u16) resource->data.dma.channels[index]; temp8 |= 0x1 << temp16; } @@ -462,9 +460,9 @@ acpi_rs_dma_stream(struct acpi_resource *linked_list, /* Set the DMA Info */ - temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5); - temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2); - temp8 |= (linked_list->data.dma.transfer & 0x03); + temp8 = (u8) ((resource->data.dma.type & 0x03) << 5); + temp8 |= ((resource->data.dma.bus_master & 0x01) << 2); + temp8 |= (resource->data.dma.transfer & 0x03); *buffer = temp8; buffer += 1; diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 56043fee96cb..75df962115cc 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -88,7 +88,7 @@ acpi_rs_irq_resource(u8 * byte_stream_buffer, */ temp8 = *buffer; *bytes_consumed = (temp8 & 0x03) + 1; - output_struct->id = ACPI_RSTYPE_IRQ; + output_struct->type = ACPI_RSTYPE_IRQ; /* Point to the 16-bits of Bytes 1 and 2 */ @@ -177,7 +177,7 @@ acpi_rs_irq_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_irq_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -190,7 +190,7 @@ acpi_rs_irq_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_irq_stream(struct acpi_resource *linked_list, +acpi_rs_irq_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -205,13 +205,13 @@ acpi_rs_irq_stream(struct acpi_resource *linked_list, * The descriptor field is set based upon whether a third byte is * needed to contain the IRQ Information. */ - if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level && - ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low && - ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) { - *buffer = 0x22; + if (ACPI_EDGE_SENSITIVE == resource->data.irq.edge_level && + ACPI_ACTIVE_HIGH == resource->data.irq.active_high_low && + ACPI_EXCLUSIVE == resource->data.irq.shared_exclusive) { + *buffer = ACPI_RDESC_TYPE_IRQ_FORMAT | 0x02; IRqinfo_byte_needed = FALSE; } else { - *buffer = 0x23; + *buffer = ACPI_RDESC_TYPE_IRQ_FORMAT | 0x03; IRqinfo_byte_needed = TRUE; } @@ -221,8 +221,8 @@ acpi_rs_irq_stream(struct acpi_resource *linked_list, /* Loop through all of the interrupts and set the mask bits */ for (index = 0; - index < linked_list->data.irq.number_of_interrupts; index++) { - temp8 = (u8) linked_list->data.irq.interrupts[index]; + index < resource->data.irq.number_of_interrupts; index++) { + temp8 = (u8) resource->data.irq.interrupts[index]; temp16 |= 0x1 << temp8; } @@ -233,11 +233,11 @@ acpi_rs_irq_stream(struct acpi_resource *linked_list, if (IRqinfo_byte_needed) { temp8 = 0; - temp8 = (u8) ((linked_list->data.irq.shared_exclusive & + temp8 = (u8) ((resource->data.irq.shared_exclusive & 0x01) << 4); - if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level && - ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) { + if (ACPI_LEVEL_SENSITIVE == resource->data.irq.edge_level && + ACPI_ACTIVE_LOW == resource->data.irq.active_high_low) { temp8 |= 0x08; } else { temp8 |= 0x01; @@ -302,7 +302,7 @@ acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, } *bytes_consumed = temp16 + 3; - output_struct->id = ACPI_RSTYPE_EXT_IRQ; + output_struct->type = ACPI_RSTYPE_EXT_IRQ; /* Point to the Byte3 */ @@ -441,7 +441,7 @@ acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_extended_irq_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -454,7 +454,7 @@ acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, +acpi_rs_extended_irq_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -476,9 +476,8 @@ acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, /* Set the Interrupt vector flags */ - temp8 = (u8) (linked_list->data.extended_irq.producer_consumer & 0x01); - temp8 |= - ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3); + temp8 = (u8) (resource->data.extended_irq.producer_consumer & 0x01); + temp8 |= ((resource->data.extended_irq.shared_exclusive & 0x01) << 3); /* * Set the Interrupt Mode @@ -489,44 +488,44 @@ acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, * * - Edge/Level are defined opposite in the table vs the headers */ - if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) { + if (ACPI_EDGE_SENSITIVE == resource->data.extended_irq.edge_level) { temp8 |= 0x2; } /* Set the Interrupt Polarity */ - temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2); + temp8 |= ((resource->data.extended_irq.active_high_low & 0x1) << 2); *buffer = temp8; buffer += 1; /* Set the Interrupt table length */ - temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts; + temp8 = (u8) resource->data.extended_irq.number_of_interrupts; *buffer = temp8; buffer += 1; for (index = 0; - index < linked_list->data.extended_irq.number_of_interrupts; + index < resource->data.extended_irq.number_of_interrupts; index++) { ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.extended_irq. + &resource->data.extended_irq. interrupts[index]); buffer += 4; } /* Resource Source Index and Resource Source are optional */ - if (0 != linked_list->data.extended_irq.resource_source.string_length) { + if (0 != resource->data.extended_irq.resource_source.string_length) { *buffer = - (u8) linked_list->data.extended_irq.resource_source.index; + (u8) resource->data.extended_irq.resource_source.index; buffer += 1; /* Copy the string */ ACPI_STRCPY((char *)buffer, - linked_list->data.extended_irq.resource_source. + resource->data.extended_irq.resource_source. string_ptr); /* @@ -535,8 +534,8 @@ acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, */ buffer += (acpi_size) (ACPI_STRLEN - (linked_list->data.extended_irq. - resource_source.string_ptr) + 1); + (resource->data.extended_irq.resource_source. + string_ptr) + 1); } /* Return the number of bytes consumed in this operation */ diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 103eb31c284e..87e75349dd0a 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -47,44 +47,143 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rslist") +/* Dispatch table for convert-to-stream functions */ +typedef +acpi_status(*ACPI_STREAM_HANDLER) (struct acpi_resource * resource, + u8 ** output_buffer, + acpi_size * bytes_consumed); + +static ACPI_STREAM_HANDLER acpi_gbl_stream_dispatch[] = { + acpi_rs_irq_stream, /* ACPI_RSTYPE_IRQ */ + acpi_rs_dma_stream, /* ACPI_RSTYPE_DMA */ + acpi_rs_start_depend_fns_stream, /* ACPI_RSTYPE_START_DPF */ + acpi_rs_end_depend_fns_stream, /* ACPI_RSTYPE_END_DPF */ + acpi_rs_io_stream, /* ACPI_RSTYPE_IO */ + acpi_rs_fixed_io_stream, /* ACPI_RSTYPE_FIXED_IO */ + acpi_rs_vendor_stream, /* ACPI_RSTYPE_VENDOR */ + acpi_rs_end_tag_stream, /* ACPI_RSTYPE_END_TAG */ + acpi_rs_memory24_stream, /* ACPI_RSTYPE_MEM24 */ + acpi_rs_memory32_range_stream, /* ACPI_RSTYPE_MEM32 */ + acpi_rs_fixed_memory32_stream, /* ACPI_RSTYPE_FIXED_MEM32 */ + acpi_rs_address16_stream, /* ACPI_RSTYPE_ADDRESS16 */ + acpi_rs_address32_stream, /* ACPI_RSTYPE_ADDRESS32 */ + acpi_rs_address64_stream, /* ACPI_RSTYPE_ADDRESS64 */ + acpi_rs_extended_irq_stream, /* ACPI_RSTYPE_EXT_IRQ */ + acpi_rs_generic_register_stream /* ACPI_RSTYPE_GENERIC_REG */ +}; + +/* Dispatch tables for convert-to-resource functions */ + +typedef +acpi_status(*ACPI_RESOURCE_HANDLER) (u8 * byte_stream_buffer, + acpi_size * bytes_consumed, + u8 ** output_buffer, + acpi_size * structure_size); + +static ACPI_RESOURCE_HANDLER acpi_gbl_sm_resource_dispatch[] = { + NULL, /* 0x00, Reserved */ + NULL, /* 0x01, Reserved */ + NULL, /* 0x02, Reserved */ + NULL, /* 0x03, Reserved */ + acpi_rs_irq_resource, /* ACPI_RDESC_TYPE_IRQ_FORMAT */ + acpi_rs_dma_resource, /* ACPI_RDESC_TYPE_DMA_FORMAT */ + acpi_rs_start_depend_fns_resource, /* ACPI_RDESC_TYPE_START_DEPENDENT */ + acpi_rs_end_depend_fns_resource, /* ACPI_RDESC_TYPE_END_DEPENDENT */ + acpi_rs_io_resource, /* ACPI_RDESC_TYPE_IO_PORT */ + acpi_rs_fixed_io_resource, /* ACPI_RDESC_TYPE_FIXED_IO_PORT */ + NULL, /* 0x0A, Reserved */ + NULL, /* 0x0B, Reserved */ + NULL, /* 0x0C, Reserved */ + NULL, /* 0x0D, Reserved */ + acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_SMALL_VENDOR */ + acpi_rs_end_tag_resource /* ACPI_RDESC_TYPE_END_TAG */ +}; + +static ACPI_RESOURCE_HANDLER acpi_gbl_lg_resource_dispatch[] = { + NULL, /* 0x00, Reserved */ + acpi_rs_memory24_resource, /* ACPI_RDESC_TYPE_MEMORY_24 */ + acpi_rs_generic_register_resource, /* ACPI_RDESC_TYPE_GENERIC_REGISTER */ + NULL, /* 0x03, Reserved */ + acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_LARGE_VENDOR */ + acpi_rs_memory32_range_resource, /* ACPI_RDESC_TYPE_MEMORY_32 */ + acpi_rs_fixed_memory32_resource, /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */ + acpi_rs_address32_resource, /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */ + acpi_rs_address16_resource, /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */ + acpi_rs_extended_irq_resource, /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */ + acpi_rs_address64_resource, /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */ + acpi_rs_address64_resource /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */ +}; + +/* Local prototypes */ + +static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); + /******************************************************************************* * * FUNCTION: acpi_rs_get_resource_type * - * PARAMETERS: resource_start_byte - Byte 0 of a resource descriptor + * PARAMETERS: resource_type - Byte 0 of a resource descriptor * - * RETURN: The Resource Type with no extraneous bits + * RETURN: The Resource Type with no extraneous bits (except the large/ + * small bit -- left alone) * * DESCRIPTION: Extract the Resource Type/Name from the first byte of * a resource descriptor. * ******************************************************************************/ -u8 acpi_rs_get_resource_type(u8 resource_start_byte) -{ +u8 acpi_rs_get_resource_type(u8 resource_type) +{ ACPI_FUNCTION_ENTRY(); /* Determine if this is a small or large resource */ - switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) { - case ACPI_RDESC_TYPE_SMALL: + if (resource_type & ACPI_RDESC_TYPE_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ - /* Small Resource Type -- Only bits 6:3 are valid */ + return (resource_type); + } else { + /* Small Resource Type -- bits 6:3 contain the name */ - return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK)); - - case ACPI_RDESC_TYPE_LARGE: - - /* Large Resource Type -- All bits are valid */ - - return (resource_start_byte); - - default: - /* Invalid type */ - break; + return ((u8) (resource_type & ACPI_RDESC_SMALL_MASK)); } +} - return (0xFF); +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_handler + * + * PARAMETERS: resource_type - Byte 0 of a resource descriptor + * + * RETURN: Pointer to the resource conversion handler + * + * DESCRIPTION: Extract the Resource Type/Name from the first byte of + * a resource descriptor. + * + ******************************************************************************/ + +static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) +{ + ACPI_FUNCTION_ENTRY(); + + /* Determine if this is a small or large resource */ + + if (resource_type & ACPI_RDESC_TYPE_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ + + if (resource_type > ACPI_RDESC_LARGE_MAX) { + return (NULL); + } + + return (acpi_gbl_lg_resource_dispatch[(resource_type & + ACPI_RDESC_LARGE_MASK)]); + } else { + /* Small Resource Type -- bits 6:3 contain the name */ + + return (acpi_gbl_sm_resource_dispatch[((resource_type & + ACPI_RDESC_SMALL_MASK) + >> 3)]); + } } /******************************************************************************* @@ -107,228 +206,70 @@ acpi_status acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, u32 byte_stream_buffer_length, u8 * output_buffer) { + u8 *buffer = output_buffer; acpi_status status; acpi_size bytes_parsed = 0; - u8 resource_type = 0; acpi_size bytes_consumed = 0; - u8 *buffer = output_buffer; acpi_size structure_size = 0; - u8 end_tag_processed = FALSE; struct acpi_resource *resource; + ACPI_RESOURCE_HANDLER handler; ACPI_FUNCTION_TRACE("rs_byte_stream_to_list"); - while (bytes_parsed < byte_stream_buffer_length && !end_tag_processed) { - /* The next byte in the stream is the resource type */ + /* Loop until end-of-buffer or an end_tag is found */ - resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); + while (bytes_parsed < byte_stream_buffer_length) { + /* Get the handler associated with this Descriptor Type */ - switch (resource_type) { - case ACPI_RDESC_TYPE_MEMORY_24: - /* - * 24-Bit Memory Resource - */ - status = acpi_rs_memory24_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; + handler = acpi_rs_get_resource_handler(*byte_stream_buffer); + if (handler) { + /* Convert a byte stream resource to local resource struct */ - case ACPI_RDESC_TYPE_LARGE_VENDOR: - /* - * Vendor Defined Resource - */ - status = acpi_rs_vendor_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; + status = handler(byte_stream_buffer, &bytes_consumed, + &buffer, &structure_size); + } else { + /* Invalid resource type */ - case ACPI_RDESC_TYPE_MEMORY_32: - /* - * 32-Bit Memory Range Resource - */ - status = - acpi_rs_memory32_range_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_FIXED_MEMORY_32: - /* - * 32-Bit Fixed Memory Resource - */ - status = - acpi_rs_fixed_memory32_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: - case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: - /* - * 64-Bit Address Resource - */ - status = acpi_rs_address64_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: - /* - * 32-Bit Address Resource - */ - status = acpi_rs_address32_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: - /* - * 16-Bit Address Resource - */ - status = acpi_rs_address16_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_EXTENDED_XRUPT: - /* - * Extended IRQ - */ - status = - acpi_rs_extended_irq_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_IRQ_FORMAT: - /* - * IRQ Resource - */ - status = acpi_rs_irq_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_DMA_FORMAT: - /* - * DMA Resource - */ - status = acpi_rs_dma_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_START_DEPENDENT: - /* - * Start Dependent Functions Resource - */ - status = - acpi_rs_start_depend_fns_resource - (byte_stream_buffer, &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_END_DEPENDENT: - /* - * End Dependent Functions Resource - */ - status = - acpi_rs_end_depend_fns_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_IO_PORT: - /* - * IO Port Resource - */ - status = acpi_rs_io_resource(byte_stream_buffer, - &bytes_consumed, &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_FIXED_IO_PORT: - /* - * Fixed IO Port Resource - */ - status = acpi_rs_fixed_io_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_SMALL_VENDOR: - /* - * Vendor Specific Resource - */ - status = acpi_rs_vendor_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - case ACPI_RDESC_TYPE_END_TAG: - /* - * End Tag - */ - end_tag_processed = TRUE; - status = acpi_rs_end_tag_resource(byte_stream_buffer, - &bytes_consumed, - &buffer, - &structure_size); - break; - - default: - /* - * Invalid/Unknown resource type - */ status = AE_AML_INVALID_RESOURCE_TYPE; - break; } if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Update the return value and counter */ - - bytes_parsed += bytes_consumed; - - /* Set the byte stream to point to the next resource */ - - byte_stream_buffer += bytes_consumed; - - /* Set the Buffer to the next structure */ + /* Set the aligned length of the new resource descriptor */ resource = ACPI_CAST_PTR(struct acpi_resource, buffer); resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); + + /* Normal exit on completion of an end_tag resource descriptor */ + + if (acpi_rs_get_resource_type(*byte_stream_buffer) == + ACPI_RDESC_TYPE_END_TAG) { + return_ACPI_STATUS(AE_OK); + } + + /* Update counter and point to the next input resource */ + + bytes_parsed += bytes_consumed; + byte_stream_buffer += bytes_consumed; + + /* Point to the next structure in the output buffer */ + buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); } - /* Check the reason for exiting the while loop */ + /* Completed buffer, but did not find an end_tag resource descriptor */ - if (!end_tag_processed) { - return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); - } - - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* * * FUNCTION: acpi_rs_list_to_byte_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * byte_steam_size_needed - Calculated size of the byte stream * needed from calling * acpi_rs_get_byte_stream_length() @@ -346,180 +287,52 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list, +acpi_rs_list_to_byte_stream(struct acpi_resource *resource, acpi_size byte_stream_size_needed, u8 * output_buffer) { - acpi_status status; u8 *buffer = output_buffer; acpi_size bytes_consumed = 0; - u8 done = FALSE; + acpi_status status; ACPI_FUNCTION_TRACE("rs_list_to_byte_stream"); - while (!done) { - switch (linked_list->id) { - case ACPI_RSTYPE_IRQ: - /* - * IRQ Resource - */ - status = - acpi_rs_irq_stream(linked_list, &buffer, - &bytes_consumed); - break; + /* Convert each resource descriptor in the list */ - case ACPI_RSTYPE_DMA: - /* - * DMA Resource - */ - status = - acpi_rs_dma_stream(linked_list, &buffer, - &bytes_consumed); - break; + while (1) { + /* Validate Type before dispatch */ - case ACPI_RSTYPE_START_DPF: - /* - * Start Dependent Functions Resource - */ - status = acpi_rs_start_depend_fns_stream(linked_list, - &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_END_DPF: - /* - * End Dependent Functions Resource - */ - status = acpi_rs_end_depend_fns_stream(linked_list, - &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_IO: - /* - * IO Port Resource - */ - status = - acpi_rs_io_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_FIXED_IO: - /* - * Fixed IO Port Resource - */ - status = - acpi_rs_fixed_io_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_VENDOR: - /* - * Vendor Defined Resource - */ - status = - acpi_rs_vendor_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_END_TAG: - /* - * End Tag - */ - status = - acpi_rs_end_tag_stream(linked_list, &buffer, - &bytes_consumed); - - /* An End Tag indicates the end of the Resource Template */ - - done = TRUE; - break; - - case ACPI_RSTYPE_MEM24: - /* - * 24-Bit Memory Resource - */ - status = - acpi_rs_memory24_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_MEM32: - /* - * 32-Bit Memory Range Resource - */ - status = - acpi_rs_memory32_range_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_FIXED_MEM32: - /* - * 32-Bit Fixed Memory Resource - */ - status = - acpi_rs_fixed_memory32_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS16: - /* - * 16-Bit Address Descriptor Resource - */ - status = acpi_rs_address16_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS32: - /* - * 32-Bit Address Descriptor Resource - */ - status = acpi_rs_address32_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_ADDRESS64: - /* - * 64-Bit Address Descriptor Resource - */ - status = acpi_rs_address64_stream(linked_list, &buffer, - &bytes_consumed); - break; - - case ACPI_RSTYPE_EXT_IRQ: - /* - * Extended IRQ Resource - */ - status = - acpi_rs_extended_irq_stream(linked_list, &buffer, - &bytes_consumed); - break; - - default: - /* - * If we get here, everything is out of sync, - * so exit with an error - */ + if (resource->type > ACPI_RSTYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n", - linked_list->id)); - status = AE_BAD_DATA; - break; + resource->type)); + return_ACPI_STATUS(AE_BAD_DATA); } + /* Perform the conversion, per resource type */ + + status = acpi_gbl_stream_dispatch[resource->type] (resource, + &buffer, + &bytes_consumed); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Set the Buffer to point to the open byte */ + /* Check for end-of-list */ + + if (resource->type == ACPI_RSTYPE_END_TAG) { + /* An End Tag indicates the end of the Resource Template */ + + return_ACPI_STATUS(AE_OK); + } + + /* Set the Buffer to point to the next (output) resource descriptor */ buffer += bytes_consumed; - /* Point to the next object */ + /* Point to the next input resource object */ - linked_list = ACPI_PTR_ADD(struct acpi_resource, - linked_list, linked_list->length); + resource = ACPI_PTR_ADD(struct acpi_resource, + resource, resource->length); } - - return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index daba1a1ed46d..418f1afb10a3 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c @@ -84,11 +84,11 @@ acpi_rs_memory24_resource(u8 * byte_stream_buffer, /* Point past the Descriptor to get the number of bytes consumed */ buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); + buffer += 2; *bytes_consumed = (acpi_size) temp16 + 3; - output_struct->id = ACPI_RSTYPE_MEM24; + output_struct->type = ACPI_RSTYPE_MEM24; /* Check Byte 3 the Read/Write bit */ @@ -133,7 +133,7 @@ acpi_rs_memory24_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_memory24_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -146,7 +146,7 @@ acpi_rs_memory24_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_memory24_stream(struct acpi_resource *linked_list, +acpi_rs_memory24_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -155,9 +155,9 @@ acpi_rs_memory24_stream(struct acpi_resource *linked_list, ACPI_FUNCTION_TRACE("rs_memory24_stream"); - /* The descriptor field is static */ + /* The Descriptor Type field is static */ - *buffer = 0x81; + *buffer = ACPI_RDESC_TYPE_MEMORY_24; buffer += 1; /* The length field is static */ @@ -168,30 +168,28 @@ acpi_rs_memory24_stream(struct acpi_resource *linked_list, /* Set the Information Byte */ - temp8 = (u8) (linked_list->data.memory24.read_write_attribute & 0x01); + temp8 = (u8) (resource->data.memory24.read_write_attribute & 0x01); *buffer = temp8; buffer += 1; /* Set the Range minimum base address */ - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.memory24.min_base_address); + ACPI_MOVE_32_TO_16(buffer, &resource->data.memory24.min_base_address); buffer += 2; /* Set the Range maximum base address */ - ACPI_MOVE_32_TO_16(buffer, - &linked_list->data.memory24.max_base_address); + ACPI_MOVE_32_TO_16(buffer, &resource->data.memory24.max_base_address); buffer += 2; /* Set the base alignment */ - ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.alignment); + ACPI_MOVE_32_TO_16(buffer, &resource->data.memory24.alignment); buffer += 2; /* Set the range length */ - ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.range_length); + ACPI_MOVE_32_TO_16(buffer, &resource->data.memory24.range_length); buffer += 2; /* Return the number of bytes consumed in this operation */ @@ -238,12 +236,11 @@ acpi_rs_memory32_range_resource(u8 * byte_stream_buffer, /* Point past the Descriptor to get the number of bytes consumed */ buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); + buffer += 2; *bytes_consumed = (acpi_size) temp16 + 3; - - output_struct->id = ACPI_RSTYPE_MEM32; + output_struct->type = ACPI_RSTYPE_MEM32; /* * Point to the place in the output buffer where the data portion will @@ -335,8 +332,7 @@ acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer, buffer += 2; *bytes_consumed = (acpi_size) temp16 + 3; - - output_struct->id = ACPI_RSTYPE_FIXED_MEM32; + output_struct->type = ACPI_RSTYPE_FIXED_MEM32; /* Check Byte 3 the Read/Write bit */ @@ -369,7 +365,7 @@ acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_memory32_range_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -382,7 +378,7 @@ acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_memory32_range_stream(struct acpi_resource *linked_list, +acpi_rs_memory32_range_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -391,9 +387,9 @@ acpi_rs_memory32_range_stream(struct acpi_resource *linked_list, ACPI_FUNCTION_TRACE("rs_memory32_range_stream"); - /* The descriptor field is static */ + /* The Descriptor Type field is static */ - *buffer = 0x85; + *buffer = ACPI_RDESC_TYPE_MEMORY_32; buffer += 1; /* The length field is static */ @@ -405,30 +401,28 @@ acpi_rs_memory32_range_stream(struct acpi_resource *linked_list, /* Set the Information Byte */ - temp8 = (u8) (linked_list->data.memory32.read_write_attribute & 0x01); + temp8 = (u8) (resource->data.memory32.read_write_attribute & 0x01); *buffer = temp8; buffer += 1; /* Set the Range minimum base address */ - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.memory32.min_base_address); + ACPI_MOVE_32_TO_32(buffer, &resource->data.memory32.min_base_address); buffer += 4; /* Set the Range maximum base address */ - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.memory32.max_base_address); + ACPI_MOVE_32_TO_32(buffer, &resource->data.memory32.max_base_address); buffer += 4; /* Set the base alignment */ - ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.alignment); + ACPI_MOVE_32_TO_32(buffer, &resource->data.memory32.alignment); buffer += 4; /* Set the range length */ - ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.range_length); + ACPI_MOVE_32_TO_32(buffer, &resource->data.memory32.range_length); buffer += 4; /* Return the number of bytes consumed in this operation */ @@ -441,7 +435,7 @@ acpi_rs_memory32_range_stream(struct acpi_resource *linked_list, * * FUNCTION: acpi_rs_fixed_memory32_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -454,7 +448,7 @@ acpi_rs_memory32_range_stream(struct acpi_resource *linked_list, ******************************************************************************/ acpi_status -acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list, +acpi_rs_fixed_memory32_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -463,9 +457,9 @@ acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list, ACPI_FUNCTION_TRACE("rs_fixed_memory32_stream"); - /* The descriptor field is static */ + /* The Descriptor Type field is static */ - *buffer = 0x86; + *buffer = ACPI_RDESC_TYPE_FIXED_MEMORY_32; buffer += 1; /* The length field is static */ @@ -478,21 +472,19 @@ acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list, /* Set the Information Byte */ temp8 = - (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01); + (u8) (resource->data.fixed_memory32.read_write_attribute & 0x01); *buffer = temp8; buffer += 1; /* Set the Range base address */ ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.fixed_memory32. - range_base_address); + &resource->data.fixed_memory32.range_base_address); buffer += 4; /* Set the range length */ - ACPI_MOVE_32_TO_32(buffer, - &linked_list->data.fixed_memory32.range_length); + ACPI_MOVE_32_TO_32(buffer, &resource->data.fixed_memory32.range_length); buffer += 4; /* Return the number of bytes consumed in this operation */ diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 7a8a34e757f5..fa7f5a85b61d 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -49,7 +49,7 @@ ACPI_MODULE_NAME("rsmisc") /******************************************************************************* * - * FUNCTION: acpi_rs_end_tag_resource + * FUNCTION: acpi_rs_generic_register_resource * * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte * stream @@ -68,6 +68,170 @@ ACPI_MODULE_NAME("rsmisc") * ******************************************************************************/ acpi_status +acpi_rs_generic_register_resource(u8 * byte_stream_buffer, + acpi_size * bytes_consumed, + u8 ** output_buffer, + acpi_size * structure_size) +{ + u8 *buffer = byte_stream_buffer; + struct acpi_resource *output_struct = (void *)*output_buffer; + u16 temp16; + u8 temp8; + acpi_size struct_size = + ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg); + + ACPI_FUNCTION_TRACE("rs_generic_register_resource"); + + /* Byte 0 is the Descriptor Type */ + + buffer += 1; + + /* Get the Descriptor Length field (Bytes 1-2) */ + + ACPI_MOVE_16_TO_16(&temp16, buffer); + buffer += 2; + + /* Validate the descriptor length */ + + if (temp16 != 12) { + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); + } + + /* The number of bytes consumed is fixed (12 + 3) */ + + *bytes_consumed = 15; + + /* Fill out the structure */ + + output_struct->type = ACPI_RSTYPE_GENERIC_REG; + + /* Get space_id (Byte 3) */ + + temp8 = *buffer; + output_struct->data.generic_reg.space_id = temp8; + buffer += 1; + + /* Get register_bit_width (Byte 4) */ + + temp8 = *buffer; + output_struct->data.generic_reg.bit_width = temp8; + buffer += 1; + + /* Get register_bit_offset (Byte 5) */ + + temp8 = *buffer; + output_struct->data.generic_reg.bit_offset = temp8; + buffer += 1; + + /* Get address_size (Byte 6) */ + + temp8 = *buffer; + output_struct->data.generic_reg.address_size = temp8; + buffer += 1; + + /* Get register_address (Bytes 7-14) */ + + ACPI_MOVE_64_TO_64(&output_struct->data.generic_reg.address, buffer); + + /* Set the Length parameter */ + + output_struct->length = (u32) struct_size; + + /* Return the final size of the structure */ + + *structure_size = struct_size; + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_generic_register_stream + * + * PARAMETERS: Resource - Pointer to the resource linked list + * output_buffer - Pointer to the user's return buffer + * bytes_consumed - Pointer to where the number of bytes + * used in the output_buffer is returned + * + * RETURN: Status + * + * DESCRIPTION: Take the linked list resource structure and fills in the + * the appropriate bytes in a byte stream + * + ******************************************************************************/ + +acpi_status +acpi_rs_generic_register_stream(struct acpi_resource *resource, + u8 ** output_buffer, acpi_size * bytes_consumed) +{ + u8 *buffer = *output_buffer; + u16 temp16; + + ACPI_FUNCTION_TRACE("rs_generic_register_stream"); + + /* Set the Descriptor Type (Byte 0) */ + + *buffer = ACPI_RDESC_TYPE_GENERIC_REGISTER; + buffer += 1; + + /* Set the Descriptor Length (Bytes 1-2) */ + + temp16 = 12; + ACPI_MOVE_16_TO_16(buffer, &temp16); + buffer += 2; + + /* Set space_id (Byte 3) */ + + *buffer = (u8) resource->data.generic_reg.space_id; + buffer += 1; + + /* Set register_bit_width (Byte 4) */ + + *buffer = (u8) resource->data.generic_reg.bit_width; + buffer += 1; + + /* Set register_bit_offset (Byte 5) */ + + *buffer = (u8) resource->data.generic_reg.bit_offset; + buffer += 1; + + /* Set address_size (Byte 6) */ + + *buffer = (u8) resource->data.generic_reg.address_size; + buffer += 1; + + /* Set register_address (Bytes 7-14) */ + + ACPI_MOVE_64_TO_64(buffer, &resource->data.generic_reg.address); + buffer += 8; + + /* Return the number of bytes consumed in this operation */ + + *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_end_tag_resource + * + * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte + * stream + * bytes_consumed - Pointer to where the number of bytes + * consumed the byte_stream_buffer is + * returned + * output_buffer - Pointer to the return data buffer + * structure_size - Pointer to where the number of bytes + * in the return data struct is returned + * + * RETURN: Status + * + * DESCRIPTION: Take the resource byte stream and fill out the appropriate + * structure pointed to by the output_buffer. Return the + * number of bytes consumed from the byte stream. + * + ******************************************************************************/ + +acpi_status acpi_rs_end_tag_resource(u8 * byte_stream_buffer, acpi_size * bytes_consumed, u8 ** output_buffer, acpi_size * structure_size) @@ -81,9 +245,9 @@ acpi_rs_end_tag_resource(u8 * byte_stream_buffer, *bytes_consumed = 2; - /* Fill out the structure */ + /* Fill out the structure */ - output_struct->id = ACPI_RSTYPE_END_TAG; + output_struct->type = ACPI_RSTYPE_END_TAG; /* Set the Length parameter */ @@ -99,7 +263,7 @@ acpi_rs_end_tag_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_end_tag_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -112,7 +276,7 @@ acpi_rs_end_tag_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_end_tag_stream(struct acpi_resource *linked_list, +acpi_rs_end_tag_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -120,9 +284,9 @@ acpi_rs_end_tag_stream(struct acpi_resource *linked_list, ACPI_FUNCTION_TRACE("rs_end_tag_stream"); - /* The descriptor field is static */ + /* The Descriptor Type field is static */ - *buffer = 0x79; + *buffer = ACPI_RDESC_TYPE_END_TAG | 0x01; buffer += 1; /* @@ -180,7 +344,7 @@ acpi_rs_vendor_resource(u8 * byte_stream_buffer, temp8 = *buffer; - if (temp8 & 0x80) { + if (temp8 & ACPI_RDESC_TYPE_LARGE) { /* Large Item, point to the length field */ buffer += 1; @@ -210,7 +374,7 @@ acpi_rs_vendor_resource(u8 * byte_stream_buffer, buffer += 1; } - output_struct->id = ACPI_RSTYPE_VENDOR; + output_struct->type = ACPI_RSTYPE_VENDOR; output_struct->data.vendor_specific.length = temp16; for (index = 0; index < temp16; index++) { @@ -239,7 +403,7 @@ acpi_rs_vendor_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_vendor_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -252,7 +416,7 @@ acpi_rs_vendor_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_vendor_stream(struct acpi_resource *linked_list, +acpi_rs_vendor_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -264,21 +428,21 @@ acpi_rs_vendor_stream(struct acpi_resource *linked_list, /* Dereference the length to find if this is a large or small item. */ - if (linked_list->data.vendor_specific.length > 7) { + if (resource->data.vendor_specific.length > 7) { /* Large Item, Set the descriptor field and length bytes */ - *buffer = 0x84; + *buffer = ACPI_RDESC_TYPE_LARGE_VENDOR; buffer += 1; - temp16 = (u16) linked_list->data.vendor_specific.length; + temp16 = (u16) resource->data.vendor_specific.length; ACPI_MOVE_16_TO_16(buffer, &temp16); buffer += 2; } else { /* Small Item, Set the descriptor field */ - temp8 = 0x70; - temp8 |= (u8) linked_list->data.vendor_specific.length; + temp8 = ACPI_RDESC_TYPE_SMALL_VENDOR; + temp8 |= (u8) resource->data.vendor_specific.length; *buffer = temp8; buffer += 1; @@ -286,9 +450,8 @@ acpi_rs_vendor_stream(struct acpi_resource *linked_list, /* Loop through all of the Vendor Specific fields */ - for (index = 0; index < linked_list->data.vendor_specific.length; - index++) { - temp8 = linked_list->data.vendor_specific.reserved[index]; + for (index = 0; index < resource->data.vendor_specific.length; index++) { + temp8 = resource->data.vendor_specific.reserved[index]; *buffer = temp8; buffer += 1; @@ -341,7 +504,7 @@ acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer, *bytes_consumed = (temp8 & 0x01) + 1; - output_struct->id = ACPI_RSTYPE_START_DPF; + output_struct->type = ACPI_RSTYPE_START_DPF; /* Point to Byte 1 if it is used */ @@ -421,7 +584,7 @@ acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer, /* Fill out the structure */ - output_struct->id = ACPI_RSTYPE_END_DPF; + output_struct->type = ACPI_RSTYPE_END_DPF; /* Set the Length parameter */ @@ -437,7 +600,7 @@ acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer, * * FUNCTION: acpi_rs_start_depend_fns_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -451,7 +614,7 @@ acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list, +acpi_rs_start_depend_fns_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; @@ -460,26 +623,25 @@ acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list, ACPI_FUNCTION_TRACE("rs_start_depend_fns_stream"); /* - * The descriptor field is set based upon whether a byte is needed + * The descriptor type field is set based upon whether a byte is needed * to contain Priority data. */ if (ACPI_ACCEPTABLE_CONFIGURATION == - linked_list->data.start_dpf.compatibility_priority && + resource->data.start_dpf.compatibility_priority && ACPI_ACCEPTABLE_CONFIGURATION == - linked_list->data.start_dpf.performance_robustness) { - *buffer = 0x30; + resource->data.start_dpf.performance_robustness) { + *buffer = ACPI_RDESC_TYPE_START_DEPENDENT; } else { - *buffer = 0x31; + *buffer = ACPI_RDESC_TYPE_START_DEPENDENT | 0x01; buffer += 1; /* Set the Priority Byte Definition */ temp8 = 0; - temp8 = - (u8) ((linked_list->data.start_dpf. - performance_robustness & 0x03) << 2); - temp8 |= - (linked_list->data.start_dpf.compatibility_priority & 0x03); + temp8 = (u8) ((resource->data.start_dpf.performance_robustness & + 0x03) << 2); + temp8 |= (resource->data.start_dpf.compatibility_priority & + 0x03); *buffer = temp8; } @@ -495,7 +657,7 @@ acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list, * * FUNCTION: acpi_rs_end_depend_fns_stream * - * PARAMETERS: linked_list - Pointer to the resource linked list + * PARAMETERS: Resource - Pointer to the resource linked list * output_buffer - Pointer to the user's return buffer * bytes_consumed - Pointer to where the number of bytes * used in the output_buffer is returned @@ -508,16 +670,16 @@ acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list, ******************************************************************************/ acpi_status -acpi_rs_end_depend_fns_stream(struct acpi_resource *linked_list, +acpi_rs_end_depend_fns_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed) { u8 *buffer = *output_buffer; ACPI_FUNCTION_TRACE("rs_end_depend_fns_stream"); - /* The descriptor field is static */ + /* The Descriptor Type field is static */ - *buffer = 0x38; + *buffer = ACPI_RDESC_TYPE_END_DEPENDENT; buffer += 1; /* Return the number of bytes consumed in this operation */ diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index ee5a5c509199..1a87c4c7bd97 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -269,7 +269,7 @@ acpi_walk_resources(acpi_handle device_handle, /* Walk the resource list */ for (;;) { - if (!resource || resource->id == ACPI_RSTYPE_END_TAG) { + if (!resource || resource->type == ACPI_RSTYPE_END_TAG) { break; } @@ -360,8 +360,8 @@ EXPORT_SYMBOL(acpi_set_current_resources); * * FUNCTION: acpi_resource_to_address64 * - * PARAMETERS: resource - Pointer to a resource - * out - Pointer to the users's return + * PARAMETERS: Resource - Pointer to a resource + * Out - Pointer to the users's return * buffer (a struct * struct acpi_resource_address64) * @@ -381,7 +381,7 @@ acpi_resource_to_address64(struct acpi_resource *resource, struct acpi_resource_address16 *address16; struct acpi_resource_address32 *address32; - switch (resource->id) { + switch (resource->type) { case ACPI_RSTYPE_ADDRESS16: address16 = (struct acpi_resource_address16 *)&resource->data; diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 0c5abc536c7a..aa1dcd851f89 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -811,7 +811,7 @@ u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc) while (buffer < end_buffer) { buffer_byte = *buffer; - if (buffer_byte & ACPI_RDESC_TYPE_MASK) { + if (buffer_byte & ACPI_RDESC_TYPE_LARGE) { /* Large Descriptor - Length is next 2 bytes */ buffer += ((*(buffer + 1) | (*(buffer + 2) << 8)) + 3); diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c index 90134c56ece9..e158b1b6313b 100644 --- a/drivers/acpi/utilities/utmutex.c +++ b/drivers/acpi/utilities/utmutex.c @@ -214,7 +214,7 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) * the ACPI subsystem code. */ for (i = mutex_id; i < MAX_MUTEX; i++) { - if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { + if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Mutex [%s] already acquired by this thread [%X]\n", @@ -313,7 +313,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) * the ACPI subsystem code. */ for (i = mutex_id; i < MAX_MUTEX; i++) { - if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { + if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { continue; } diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 427cff1a3f83..1427c5cf4304 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -61,9 +61,9 @@ * */ -/* Version string */ +/* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20050902 +#define ACPI_CA_VERSION 0x20050916 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index 3d96dcb1bb4b..759b4cff4f88 100644 --- a/include/acpi/acdisasm.h +++ b/include/acpi/acdisasm.h @@ -187,73 +187,73 @@ void acpi_dm_decode_attribute(u8 attribute); * dmresrcl */ void -acpi_dm_word_descriptor(struct asl_word_address_desc *resource, +acpi_dm_word_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_dword_descriptor(struct asl_dword_address_desc *resource, +acpi_dm_dword_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_extended_descriptor(struct asl_extended_address_desc *resource, +acpi_dm_extended_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_qword_descriptor(struct asl_qword_address_desc *resource, +acpi_dm_qword_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_memory24_descriptor(struct asl_memory_24_desc *resource, +acpi_dm_memory24_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_memory32_descriptor(struct asl_memory_32_desc *resource, +acpi_dm_memory32_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_fixed_mem32_descriptor(struct asl_fixed_memory_32_desc *resource, - u32 length, u32 level); +acpi_dm_fixed_memory32_descriptor(union asl_resource_desc *resource, + u32 length, u32 level); void -acpi_dm_generic_register_descriptor(struct asl_general_register_desc *resource, +acpi_dm_generic_register_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_interrupt_descriptor(struct asl_extended_xrupt_desc *resource, +acpi_dm_interrupt_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_vendor_large_descriptor(struct asl_large_vendor_desc *resource, +acpi_dm_vendor_large_descriptor(union asl_resource_desc *resource, u32 length, u32 level); /* * dmresrcs */ void -acpi_dm_irq_descriptor(struct asl_irq_format_desc *resource, +acpi_dm_irq_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_dma_descriptor(struct asl_dma_format_desc *resource, +acpi_dm_dma_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_io_descriptor(struct asl_io_port_desc *resource, u32 length, u32 level); +acpi_dm_io_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_fixed_io_descriptor(struct asl_fixed_io_port_desc *resource, +acpi_dm_fixed_io_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_start_dependent_descriptor(struct asl_start_dependent_desc *resource, +acpi_dm_start_dependent_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_end_dependent_descriptor(struct asl_start_dependent_desc *resource, +acpi_dm_end_dependent_descriptor(union asl_resource_desc *resource, u32 length, u32 level); void -acpi_dm_vendor_small_descriptor(struct asl_small_vendor_desc *resource, +acpi_dm_vendor_small_descriptor(union asl_resource_desc *resource, u32 length, u32 level); /* diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index 9fba0fddda90..76ac1533c405 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -744,12 +744,13 @@ struct acpi_bit_register_info { #define ACPI_RDESC_TYPE_LARGE 0x80 #define ACPI_RDESC_TYPE_SMALL 0x00 -#define ACPI_RDESC_TYPE_MASK 0x80 -#define ACPI_RDESC_SMALL_MASK 0x78 /* Only bits 6:3 contain the type */ +#define ACPI_RDESC_SMALL_MASK 0x78 /* Bits 6:3 contain the type */ +#define ACPI_RDESC_SMALL_LENGTH_MASK 0x07 /* Bits 2:0 contain the length */ +#define ACPI_RDESC_LARGE_MASK 0x7F /* Bits 6:0 contain the type */ /* * Small resource descriptor types - * Note: The 3 length bits (2:0) must be zero + * Note: Bits 2:0 are used for the descriptor length */ #define ACPI_RDESC_TYPE_IRQ_FORMAT 0x20 #define ACPI_RDESC_TYPE_DMA_FORMAT 0x28 @@ -757,6 +758,10 @@ struct acpi_bit_register_info { #define ACPI_RDESC_TYPE_END_DEPENDENT 0x38 #define ACPI_RDESC_TYPE_IO_PORT 0x40 #define ACPI_RDESC_TYPE_FIXED_IO_PORT 0x48 +#define ACPI_RDESC_TYPE_RESERVED_S1 0x50 +#define ACPI_RDESC_TYPE_RESERVED_S2 0x58 +#define ACPI_RDESC_TYPE_RESERVED_S3 0x60 +#define ACPI_RDESC_TYPE_RESERVED_S4 0x68 #define ACPI_RDESC_TYPE_SMALL_VENDOR 0x70 #define ACPI_RDESC_TYPE_END_TAG 0x78 @@ -764,7 +769,8 @@ struct acpi_bit_register_info { * Large resource descriptor types */ #define ACPI_RDESC_TYPE_MEMORY_24 0x81 -#define ACPI_RDESC_TYPE_GENERAL_REGISTER 0x82 +#define ACPI_RDESC_TYPE_GENERIC_REGISTER 0x82 +#define ACPI_RDESC_TYPE_RESERVED_L1 0x83 #define ACPI_RDESC_TYPE_LARGE_VENDOR 0x84 #define ACPI_RDESC_TYPE_MEMORY_32 0x85 #define ACPI_RDESC_TYPE_FIXED_MEMORY_32 0x86 @@ -773,6 +779,15 @@ struct acpi_bit_register_info { #define ACPI_RDESC_TYPE_EXTENDED_XRUPT 0x89 #define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE 0x8A #define ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE 0x8B +#define ACPI_RDESC_LARGE_MAX 0x8B + +/* + * Minimum lengths for descriptors with optional fields + */ +#define ACPI_RDESC_QWORD_MIN 43 +#define ACPI_RDESC_DWORD_MIN 23 +#define ACPI_RDESC_WORD_MIN 13 +#define ACPI_RDESC_EXT_XRUPT_MIN 6 /***************************************************************************** * diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h index 38e798b05d08..ce2cf72fd4c8 100644 --- a/include/acpi/acresrc.h +++ b/include/acpi/acresrc.h @@ -110,7 +110,7 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, u32 byte_stream_buffer_length, u8 * output_buffer); acpi_status -acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list, +acpi_rs_list_to_byte_stream(struct acpi_resource *resource, acpi_size byte_stream_size_needed, u8 * output_buffer); @@ -125,11 +125,11 @@ acpi_rs_fixed_io_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_io_stream(struct acpi_resource *linked_list, +acpi_rs_io_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status -acpi_rs_fixed_io_stream(struct acpi_resource *linked_list, +acpi_rs_fixed_io_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -138,7 +138,7 @@ acpi_rs_irq_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_irq_stream(struct acpi_resource *linked_list, +acpi_rs_irq_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -147,7 +147,7 @@ acpi_rs_dma_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_dma_stream(struct acpi_resource *linked_list, +acpi_rs_dma_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -156,7 +156,7 @@ acpi_rs_address16_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_address16_stream(struct acpi_resource *linked_list, +acpi_rs_address16_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -165,7 +165,7 @@ acpi_rs_address32_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_address32_stream(struct acpi_resource *linked_list, +acpi_rs_address32_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -174,7 +174,7 @@ acpi_rs_address64_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_address64_stream(struct acpi_resource *linked_list, +acpi_rs_address64_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -190,12 +190,12 @@ acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer, acpi_size * structure_size); acpi_status -acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list, +acpi_rs_start_depend_fns_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status -acpi_rs_end_depend_fns_stream(struct acpi_resource *linked_list, +acpi_rs_end_depend_fns_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -204,7 +204,7 @@ acpi_rs_memory24_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_memory24_stream(struct acpi_resource *linked_list, +acpi_rs_memory24_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -220,11 +220,11 @@ acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer, acpi_size * structure_size); acpi_status -acpi_rs_memory32_range_stream(struct acpi_resource *linked_list, +acpi_rs_memory32_range_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status -acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list, +acpi_rs_fixed_memory32_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -233,7 +233,7 @@ acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, +acpi_rs_extended_irq_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -242,7 +242,7 @@ acpi_rs_end_tag_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_end_tag_stream(struct acpi_resource *linked_list, +acpi_rs_end_tag_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); acpi_status @@ -251,9 +251,23 @@ acpi_rs_vendor_resource(u8 * byte_stream_buffer, u8 ** output_buffer, acpi_size * structure_size); acpi_status -acpi_rs_vendor_stream(struct acpi_resource *linked_list, +acpi_rs_vendor_stream(struct acpi_resource *resource, u8 ** output_buffer, acpi_size * bytes_consumed); u8 acpi_rs_get_resource_type(u8 resource_start_byte); +/* + * rsmisc + */ +acpi_status +acpi_rs_generic_register_resource(u8 * byte_stream_buffer, + acpi_size * bytes_consumed, + u8 ** output_buffer, + acpi_size * structure_size); + +acpi_status +acpi_rs_generic_register_stream(struct acpi_resource *resource, + u8 ** output_buffer, + acpi_size * bytes_consumed); + #endif /* __ACRESRC_H__ */ diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 6213b27516e8..1dfa64fae4ec 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1125,6 +1125,14 @@ struct acpi_resource_ext_irq { u32 interrupts[1]; }; +struct acpi_resource_generic_reg { + u32 space_id; + u32 bit_width; + u32 bit_offset; + u32 address_size; + u64 address; +}; + /* ACPI_RESOURCE_TYPEs */ #define ACPI_RSTYPE_IRQ 0 @@ -1142,6 +1150,8 @@ struct acpi_resource_ext_irq { #define ACPI_RSTYPE_ADDRESS32 12 #define ACPI_RSTYPE_ADDRESS64 13 #define ACPI_RSTYPE_EXT_IRQ 14 +#define ACPI_RSTYPE_GENERIC_REG 15 +#define ACPI_RSTYPE_MAX 15 typedef u32 acpi_resource_type; @@ -1161,10 +1171,11 @@ union acpi_resource_data { struct acpi_resource_address32 address32; struct acpi_resource_address64 address64; struct acpi_resource_ext_irq extended_irq; + struct acpi_resource_generic_reg generic_reg; }; struct acpi_resource { - acpi_resource_type id; + acpi_resource_type type; u32 length; union acpi_resource_data data; }; diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h index 051786e4b210..a3c46ba6358d 100644 --- a/include/acpi/amlresrc.h +++ b/include/acpi/amlresrc.h @@ -157,10 +157,15 @@ struct asl_end_tag_desc { /* LARGE descriptors */ +#define ASL_LARGE_HEADER_COMMON \ + u8 descriptor_type;\ + u16 length; + +struct asl_large_header { +ASL_LARGE_HEADER_COMMON}; + struct asl_memory_24_desc { - u8 descriptor_type; - u16 length; - u8 information; + ASL_LARGE_HEADER_COMMON u8 information; u16 address_min; u16 address_max; u16 alignment; @@ -168,15 +173,11 @@ struct asl_memory_24_desc { }; struct asl_large_vendor_desc { - u8 descriptor_type; - u16 length; - u8 vendor_defined[1]; + ASL_LARGE_HEADER_COMMON u8 vendor_defined[1]; }; struct asl_memory_32_desc { - u8 descriptor_type; - u16 length; - u8 information; + ASL_LARGE_HEADER_COMMON u8 information; u32 address_min; u32 address_max; u32 alignment; @@ -184,17 +185,13 @@ struct asl_memory_32_desc { }; struct asl_fixed_memory_32_desc { - u8 descriptor_type; - u16 length; - u8 information; + ASL_LARGE_HEADER_COMMON u8 information; u32 base_address; u32 range_length; }; struct asl_extended_address_desc { - u8 descriptor_type; - u16 length; - u8 resource_type; + ASL_LARGE_HEADER_COMMON u8 resource_type; u8 flags; u8 specific_flags; u8 revision_iD; @@ -211,9 +208,7 @@ struct asl_extended_address_desc { #define ASL_EXTENDED_ADDRESS_DESC_REVISION 1 /* ACPI 3.0 */ struct asl_qword_address_desc { - u8 descriptor_type; - u16 length; - u8 resource_type; + ASL_LARGE_HEADER_COMMON u8 resource_type; u8 flags; u8 specific_flags; u64 granularity; @@ -225,9 +220,7 @@ struct asl_qword_address_desc { }; struct asl_dword_address_desc { - u8 descriptor_type; - u16 length; - u8 resource_type; + ASL_LARGE_HEADER_COMMON u8 resource_type; u8 flags; u8 specific_flags; u32 granularity; @@ -239,9 +232,7 @@ struct asl_dword_address_desc { }; struct asl_word_address_desc { - u8 descriptor_type; - u16 length; - u8 resource_type; + ASL_LARGE_HEADER_COMMON u8 resource_type; u8 flags; u8 specific_flags; u16 granularity; @@ -253,18 +244,14 @@ struct asl_word_address_desc { }; struct asl_extended_xrupt_desc { - u8 descriptor_type; - u16 length; - u8 flags; + ASL_LARGE_HEADER_COMMON u8 flags; u8 table_length; u32 interrupt_number[1]; /* res_source_index, res_source optional fields follow */ }; -struct asl_general_register_desc { - u8 descriptor_type; - u16 length; - u8 address_space_id; +struct asl_generic_register_desc { + ASL_LARGE_HEADER_COMMON u8 address_space_id; u8 bit_width; u8 bit_offset; u8 access_size; /* ACPI 3.0, was Reserved */ @@ -280,13 +267,14 @@ struct asl_general_register_desc { union asl_resource_desc { struct asl_irq_format_desc irq; struct asl_dma_format_desc dma; - struct asl_start_dependent_desc std; - struct asl_end_dependent_desc end; struct asl_io_port_desc iop; struct asl_fixed_io_port_desc fio; + struct asl_start_dependent_desc std; + struct asl_end_dependent_desc end; struct asl_small_vendor_desc smv; struct asl_end_tag_desc et; + struct asl_large_header lhd; struct asl_memory_24_desc M24; struct asl_large_vendor_desc lgv; struct asl_memory_32_desc M32; @@ -296,7 +284,7 @@ union asl_resource_desc { struct asl_word_address_desc was; struct asl_extended_address_desc eas; struct asl_extended_xrupt_desc exx; - struct asl_general_register_desc grg; + struct asl_generic_register_desc grg; u32 u32_item; u16 u16_item; u8 U8item; diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 16609c1ab2eb..08539125696a 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -68,6 +68,7 @@ #define ACPI_APPLICATION #define ACPI_DEBUGGER #define ACPI_DISASSEMBLER +#define ACPI_MUTEX_DEBUG #endif #ifdef ACPI_ASL_COMPILER From eca008c8134df15262a0362623edb59902628c95 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 22 Sep 2005 00:25:18 -0400 Subject: [PATCH 002/695] [ACPI] handle ACPICA 20050916's acpi_resource.type rename Signed-off-by: Len Brown --- drivers/acpi/ec.c | 2 +- drivers/acpi/glue.c | 6 +++--- drivers/acpi/motherboard.c | 4 ++-- drivers/acpi/pci_link.c | 10 +++++----- drivers/acpi/pci_root.c | 6 +++--- drivers/char/hpet.c | 2 +- drivers/pnp/pnpacpi/rsparser.c | 36 +++++++++++++++++----------------- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 7e1a445955bc..c33bfba5df8f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1151,7 +1151,7 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context) union acpi_ec *ec = (union acpi_ec *)context; struct acpi_generic_address *addr; - if (resource->id != ACPI_RSTYPE_IO) { + if (resource->type != ACPI_RSTYPE_IO) { return AE_OK; } diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index e36c5da2b31a..00aeb4801d7a 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -99,9 +99,9 @@ do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) int *busnr = (int *)data; struct acpi_resource_address64 address; - if (resource->id != ACPI_RSTYPE_ADDRESS16 && - resource->id != ACPI_RSTYPE_ADDRESS32 && - resource->id != ACPI_RSTYPE_ADDRESS64) + if (resource->type != ACPI_RSTYPE_ADDRESS16 && + resource->type != ACPI_RSTYPE_ADDRESS32 && + resource->type != ACPI_RSTYPE_ADDRESS64) return AE_OK; acpi_resource_to_address64(resource, &address); diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c index e928e8c2c6ec..85c1fb5c9a5a 100644 --- a/drivers/acpi/motherboard.c +++ b/drivers/acpi/motherboard.c @@ -54,7 +54,7 @@ static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) ACPI_FUNCTION_TRACE("acpi_reserve_io_ranges"); - if (res->id == ACPI_RSTYPE_IO) { + if (res->type == ACPI_RSTYPE_IO) { struct acpi_resource_io *io_res = &res->data.io; if (io_res->min_base_address != io_res->max_base_address) @@ -70,7 +70,7 @@ static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) request_region(io_res->min_base_address, io_res->range_length, "motherboard"); } - } else if (res->id == ACPI_RSTYPE_FIXED_IO) { + } else if (res->type == ACPI_RSTYPE_FIXED_IO) { struct acpi_resource_fixed_io *fixed_io_res = &res->data.fixed_io; diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 82292b77e5c6..d8956c0bf143 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -108,7 +108,7 @@ acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible"); - switch (resource->id) { + switch (resource->type) { case ACPI_RSTYPE_START_DPF: return_ACPI_STATUS(AE_OK); case ACPI_RSTYPE_IRQ: @@ -201,7 +201,7 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context) ACPI_FUNCTION_TRACE("acpi_pci_link_check_current"); - switch (resource->id) { + switch (resource->type) { case ACPI_RSTYPE_IRQ: { struct acpi_resource_irq *p = &resource->data.irq; @@ -326,7 +326,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) switch (link->irq.resource_type) { case ACPI_RSTYPE_IRQ: - resource->res.id = ACPI_RSTYPE_IRQ; + resource->res.type = ACPI_RSTYPE_IRQ; resource->res.length = sizeof(struct acpi_resource); resource->res.data.irq.edge_level = link->irq.edge_level; resource->res.data.irq.active_high_low = @@ -341,7 +341,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) break; case ACPI_RSTYPE_EXT_IRQ: - resource->res.id = ACPI_RSTYPE_EXT_IRQ; + resource->res.type = ACPI_RSTYPE_EXT_IRQ; resource->res.length = sizeof(struct acpi_resource); resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER; @@ -364,7 +364,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) goto end; } - resource->end.id = ACPI_RSTYPE_END_TAG; + resource->end.type = ACPI_RSTYPE_END_TAG; /* Attempt to set the resource */ status = acpi_set_current_resources(link->handle, &buffer); diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 0fd9988c283d..5d6bc815fe72 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -122,9 +122,9 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) int *busnr = (int *)data; struct acpi_resource_address64 address; - if (resource->id != ACPI_RSTYPE_ADDRESS16 && - resource->id != ACPI_RSTYPE_ADDRESS32 && - resource->id != ACPI_RSTYPE_ADDRESS64) + if (resource->type != ACPI_RSTYPE_ADDRESS16 && + resource->type != ACPI_RSTYPE_ADDRESS32 && + resource->type != ACPI_RSTYPE_ADDRESS64) return AE_OK; acpi_resource_to_address64(resource, &address); diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index de0379b6d502..a5c3f9c0c909 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -897,7 +897,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) if (hpetp->hp_hpet == hdp->hd_address) return -EBUSY; - } else if (res->id == ACPI_RSTYPE_EXT_IRQ) { + } else if (res->type == ACPI_RSTYPE_EXT_IRQ) { struct acpi_resource_ext_irq *irqp; int i; diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 416d30debe6c..15ec05f69ddd 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -163,7 +163,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, struct pnp_resource_table * res_table = (struct pnp_resource_table *)data; int i; - switch (res->id) { + switch (res->type) { case ACPI_RSTYPE_IRQ: /* * Per spec, only one interrupt per descriptor is allowed in @@ -233,7 +233,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, case ACPI_RSTYPE_VENDOR: break; default: - pnp_warn("PnPACPI: unknown resource type %d", res->id); + pnp_warn("PnPACPI: unknown resource type %d", res->type); return AE_ERROR; } @@ -467,7 +467,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, struct pnp_dev *dev = parse_data->dev; struct pnp_option *option = parse_data->option; - switch (res->id) { + switch (res->type) { case ACPI_RSTYPE_IRQ: pnpacpi_parse_irq_option(option, &res->data.irq); break; @@ -528,7 +528,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, parse_data->option_independent = NULL; break; default: - pnp_warn("PnPACPI: unknown resource type %d", res->id); + pnp_warn("PnPACPI: unknown resource type %d", res->type); return AE_ERROR; } @@ -559,7 +559,7 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, void *data) { int *res_cnt = (int *)data; - switch (res->id) { + switch (res->type) { case ACPI_RSTYPE_IRQ: case ACPI_RSTYPE_EXT_IRQ: case ACPI_RSTYPE_DMA: @@ -584,7 +584,7 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) { struct acpi_resource **resource = (struct acpi_resource **)data; - switch (res->id) { + switch (res->type) { case ACPI_RSTYPE_IRQ: case ACPI_RSTYPE_EXT_IRQ: case ACPI_RSTYPE_DMA: @@ -598,7 +598,7 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, case ACPI_RSTYPE_ADDRESS32: case ACPI_RSTYPE_ADDRESS64: #endif - (*resource)->id = res->id; + (*resource)->type = res->type; (*resource)++; default: return AE_OK; @@ -636,7 +636,7 @@ int pnpacpi_build_resource_template(acpi_handle handle, return -EINVAL; } /* resource will pointer the end resource now */ - resource->id = ACPI_RSTYPE_END_TAG; + resource->type = ACPI_RSTYPE_END_TAG; return 0; } @@ -648,7 +648,7 @@ static void pnpacpi_encode_irq(struct acpi_resource *resource, decode_irq_flags(p->flags & IORESOURCE_BITS, &edge_level, &active_high_low); - resource->id = ACPI_RSTYPE_IRQ; + resource->type = ACPI_RSTYPE_IRQ; resource->length = sizeof(struct acpi_resource); resource->data.irq.edge_level = edge_level; resource->data.irq.active_high_low = active_high_low; @@ -667,7 +667,7 @@ static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, decode_irq_flags(p->flags & IORESOURCE_BITS, &edge_level, &active_high_low); - resource->id = ACPI_RSTYPE_EXT_IRQ; + resource->type = ACPI_RSTYPE_EXT_IRQ; resource->length = sizeof(struct acpi_resource); resource->data.extended_irq.producer_consumer = ACPI_CONSUMER; resource->data.extended_irq.edge_level = edge_level; @@ -683,7 +683,7 @@ static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, static void pnpacpi_encode_dma(struct acpi_resource *resource, struct resource *p) { - resource->id = ACPI_RSTYPE_DMA; + resource->type = ACPI_RSTYPE_DMA; resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ if (p->flags & IORESOURCE_DMA_COMPATIBLE) @@ -708,7 +708,7 @@ static void pnpacpi_encode_dma(struct acpi_resource *resource, static void pnpacpi_encode_io(struct acpi_resource *resource, struct resource *p) { - resource->id = ACPI_RSTYPE_IO; + resource->type = ACPI_RSTYPE_IO; resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR)? @@ -722,7 +722,7 @@ static void pnpacpi_encode_io(struct acpi_resource *resource, static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, struct resource *p) { - resource->id = ACPI_RSTYPE_FIXED_IO; + resource->type = ACPI_RSTYPE_FIXED_IO; resource->length = sizeof(struct acpi_resource); resource->data.fixed_io.base_address = p->start; resource->data.fixed_io.range_length = p->end - p->start + 1; @@ -731,7 +731,7 @@ static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, static void pnpacpi_encode_mem24(struct acpi_resource *resource, struct resource *p) { - resource->id = ACPI_RSTYPE_MEM24; + resource->type = ACPI_RSTYPE_MEM24; resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ resource->data.memory24.read_write_attribute = @@ -746,7 +746,7 @@ static void pnpacpi_encode_mem24(struct acpi_resource *resource, static void pnpacpi_encode_mem32(struct acpi_resource *resource, struct resource *p) { - resource->id = ACPI_RSTYPE_MEM32; + resource->type = ACPI_RSTYPE_MEM32; resource->length = sizeof(struct acpi_resource); resource->data.memory32.read_write_attribute = (p->flags & IORESOURCE_MEM_WRITEABLE) ? @@ -760,7 +760,7 @@ static void pnpacpi_encode_mem32(struct acpi_resource *resource, static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource, struct resource *p) { - resource->id = ACPI_RSTYPE_FIXED_MEM32; + resource->type = ACPI_RSTYPE_FIXED_MEM32; resource->length = sizeof(struct acpi_resource); resource->data.fixed_memory32.read_write_attribute = (p->flags & IORESOURCE_MEM_WRITEABLE) ? @@ -780,7 +780,7 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, pnp_dbg("res cnt %d", res_cnt); while (i < res_cnt) { - switch(resource->id) { + switch(resource->type) { case ACPI_RSTYPE_IRQ: pnp_dbg("Encode irq"); pnpacpi_encode_irq(resource, @@ -831,7 +831,7 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, mem ++; break; default: /* other type */ - pnp_warn("unknown resource type %d", resource->id); + pnp_warn("unknown resource type %d", resource->type); return -EINVAL; } resource ++; From 486368bf33a2844319ad4865039543cd50ac90dd Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 22 Sep 2005 01:57:01 -0400 Subject: [PATCH 003/695] [ACPI] clean up ACPICA 20050916's rscalc typedef syntax Signed-off-by: Len Brown --- drivers/acpi/resources/rscalc.c | 78 ++++++++++++++++----------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index cd051c97bf5b..2da7c6a8182e 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -78,51 +78,50 @@ static u8 acpi_gbl_stream_sizes[] = { * Base sizes of resource descriptors, both the actual AML stream length and * size of the internal struct representation. */ -typedef struct acpi_resource_sizes { +struct acpi_resource_sizes { u8 minimum_stream_size; u8 minimum_struct_size; - -} ACPI_RESOURCE_SIZES; - -static ACPI_RESOURCE_SIZES acpi_gbl_sm_resource_sizes[] = { - 0, 0, /* 0x00, Reserved */ - 0, 0, /* 0x01, Reserved */ - 0, 0, /* 0x02, Reserved */ - 0, 0, /* 0x03, Reserved */ - 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq), /* ACPI_RDESC_TYPE_IRQ_FORMAT */ - 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma), /* ACPI_RDESC_TYPE_DMA_FORMAT */ - 1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf), /* ACPI_RDESC_TYPE_START_DEPENDENT */ - 1, ACPI_RESOURCE_LENGTH, /* ACPI_RDESC_TYPE_END_DEPENDENT */ - 8, ACPI_SIZEOF_RESOURCE(struct acpi_resource_io), /* ACPI_RDESC_TYPE_IO_PORT */ - 4, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io), /* ACPI_RDESC_TYPE_FIXED_IO_PORT */ - 0, 0, /* 0x0A, Reserved */ - 0, 0, /* 0x0B, Reserved */ - 0, 0, /* 0x0C, Reserved */ - 0, 0, /* 0x0D, Reserved */ - 1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor), /* ACPI_RDESC_TYPE_SMALL_VENDOR */ - 2, ACPI_RESOURCE_LENGTH, /* ACPI_RDESC_TYPE_END_TAG */ }; -static ACPI_RESOURCE_SIZES acpi_gbl_lg_resource_sizes[] = { - 0, 0, /* 0x00, Reserved */ - 12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24), /* ACPI_RDESC_TYPE_MEMORY_24 */ - 15, ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg), /* ACPI_RDESC_TYPE_GENERIC_REGISTER */ - 0, 0, /* 0x03, Reserved */ - 3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor), /* ACPI_RDESC_TYPE_LARGE_VENDOR */ - 20, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32), /* ACPI_RDESC_TYPE_MEMORY_32 */ - 12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32), /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */ - 26, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32), /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */ - 16, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16), /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */ - 9, ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq), /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */ - 46, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64), /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */ - 56, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64), /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */ +static struct acpi_resource_sizes acpi_gbl_sm_resource_sizes[] = { + {0, 0}, /* 0x00, Reserved */ + {0, 0}, /* 0x01, Reserved */ + {0, 0}, /* 0x02, Reserved */ + {0, 0}, /* 0x03, Reserved */ + {3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq)}, /* ACPI_RDESC_TYPE_IRQ_FORMAT */ + {3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma)}, /* ACPI_RDESC_TYPE_DMA_FORMAT */ + {1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf)}, /* ACPI_RDESC_TYPE_START_DEPENDENT */ + {1, ACPI_RESOURCE_LENGTH}, /* ACPI_RDESC_TYPE_END_DEPENDENT */ + {8, ACPI_SIZEOF_RESOURCE(struct acpi_resource_io)}, /* ACPI_RDESC_TYPE_IO_PORT */ + {4, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io)}, /* ACPI_RDESC_TYPE_FIXED_IO_PORT */ + {0, 0}, /* 0x0A, Reserved */ + {0, 0}, /* 0x0B, Reserved */ + {0, 0}, /* 0x0C, Reserved */ + {0, 0}, /* 0x0D, Reserved */ + {1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor)}, /* ACPI_RDESC_TYPE_SMALL_VENDOR */ + {2, ACPI_RESOURCE_LENGTH}, /* ACPI_RDESC_TYPE_END_TAG */ +}; + +static struct acpi_resource_sizes acpi_gbl_lg_resource_sizes[] = { + {0, 0}, /* 0x00, Reserved */ + {12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24)}, /* ACPI_RDESC_TYPE_MEMORY_24 */ + {15, ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg)}, /* ACPI_RDESC_TYPE_GENERIC_REGISTER */ + {0, 0}, /* 0x03, Reserved */ + {3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor)}, /* ACPI_RDESC_TYPE_LARGE_VENDOR */ + {20, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32)}, /* ACPI_RDESC_TYPE_MEMORY_32 */ + {12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32)}, /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */ + {26, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32)}, /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */ + {16, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16)}, /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */ + {9, ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq)}, /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */ + {46, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64)}, /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */ + {56, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64)}, /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */ }; /* Local prototypes */ static u8 acpi_rs_count_set_bits(u16 bit_field); -static ACPI_RESOURCE_SIZES *acpi_rs_get_resource_sizes(u8 resource_type); +static struct acpi_resource_sizes *acpi_rs_get_resource_sizes(u8 resource_type); static u16 acpi_rs_get_resource_length(u8 * resource); @@ -173,9 +172,9 @@ static u8 acpi_rs_count_set_bits(u16 bit_field) * ******************************************************************************/ -static ACPI_RESOURCE_SIZES *acpi_rs_get_resource_sizes(u8 resource_type) +static struct acpi_resource_sizes *acpi_rs_get_resource_sizes(u8 resource_type) { - ACPI_RESOURCE_SIZES *size_info; + struct acpi_resource_sizes *size_info; ACPI_FUNCTION_ENTRY(); @@ -489,7 +488,7 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, u32 byte_stream_buffer_length, acpi_size * size_needed) { u8 *buffer; - ACPI_RESOURCE_SIZES *resource_info; + struct acpi_resource_sizes *resource_info; u32 buffer_size = 0; u32 bytes_parsed = 0; u8 resource_type; @@ -759,7 +758,8 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, (*sub_object_list)->string. length + 1); } else { - temp_size_needed += acpi_ns_get_pathname_length((*sub_object_list)->reference.node); + temp_size_needed += + acpi_ns_get_pathname_length((*sub_object_list)->reference.node); } } else { /* From c780f964902a8c4e7f702ff3e0a2b754e82b3ca3 Mon Sep 17 00:00:00 2001 From: MAEDA Naoaki Date: Wed, 30 Nov 2005 18:00:24 -0500 Subject: [PATCH 004/695] [ACPI] ia64 build fix arch/ia64/kernel/acpi-ext.c: In function `acpi_vendor_resource_match': arch/ia64/kernel/acpi-ext.c:38: error: structure has no member named `id' Signed-off-by: MAEDA Naoaki Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- arch/ia64/kernel/acpi-ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index 13a5b3b49bf8..a146016d7ad7 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c @@ -35,7 +35,7 @@ acpi_vendor_resource_match(struct acpi_resource *resource, void *context) struct acpi_vendor_descriptor *descriptor; u32 length; - if (resource->id != ACPI_RSTYPE_VENDOR) + if (resource->type != ACPI_RSTYPE_VENDOR) return AE_OK; vendor = (struct acpi_resource_vendor *)&resource->data; From 378b2556f4e09fa6f87ff0cb5c4395ff28257d02 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 30 Nov 2005 21:03:21 -0500 Subject: [PATCH 005/695] [ACPI] 8250_acpi.c buildfix Signed-off-by: Len Brown --- drivers/serial/8250_acpi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/serial/8250_acpi.c b/drivers/serial/8250_acpi.c index a802bdce6e5d..36681ba7b033 100644 --- a/drivers/serial/8250_acpi.c +++ b/drivers/serial/8250_acpi.c @@ -83,11 +83,11 @@ static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data) status = acpi_resource_to_address64(res, &addr); if (ACPI_SUCCESS(status)) return acpi_serial_mmio(port, &addr); - else if (res->id == ACPI_RSTYPE_IO) + else if (res->type == ACPI_RSTYPE_IO) return acpi_serial_port(port, &res->data.io); - else if (res->id == ACPI_RSTYPE_EXT_IRQ) + else if (res->type == ACPI_RSTYPE_EXT_IRQ) return acpi_serial_ext_irq(port, &res->data.extended_irq); - else if (res->id == ACPI_RSTYPE_IRQ) + else if (res->type == ACPI_RSTYPE_IRQ) return acpi_serial_irq(port, &res->data.irq); return AE_OK; } From 1a38416cea8ac801ae8f261074721f35317613dc Mon Sep 17 00:00:00 2001 From: David Shaohua Li Date: Wed, 23 Nov 2005 12:36:00 -0500 Subject: [PATCH 006/695] [ACPI] SMP S3 resume: evaluate _WAK after INIT On SMP resume from S3, we reset (INIT) the non-boot processors to boot them cleanly. But the BIOS needs to execute _WAK after INIT in order to properly initialized these processors upon resume. http://bugzilla.kernel.org/show_bug.cgi?id=5651 Signed-off-by: David Shaohua Li Signed-off-by: Len Brown --- kernel/power/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/power/main.c b/kernel/power/main.c index d253f3ae2fa5..9cb235cba4a9 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -133,10 +133,10 @@ static int suspend_enter(suspend_state_t state) static void suspend_finish(suspend_state_t state) { device_resume(); - if (pm_ops && pm_ops->finish) - pm_ops->finish(state); thaw_processes(); enable_nonboot_cpus(); + if (pm_ops && pm_ops->finish) + pm_ops->finish(state); pm_restore_console(); } From 05131ecc99ea9da7f45ba3058fe8a2c1d0ceeab8 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Sun, 23 Oct 2005 16:31:00 -0400 Subject: [PATCH 007/695] [ACPI] Avoid BIOS inflicted crashes by evaluating _PDC only once Linux invokes the AML _PDC method (Processor Driver Capabilities) to tell the BIOS what features it can handle. While the ACPI spec says nothing about the OS invoking _PDC multiple times, doing so with changing bits seems to hopelessly confuse the BIOS on multiple platforms up to and including crashing the system. Factor out the _PDC invocation so Linux invokes it only once. http://bugzilla.kernel.org/show_bug.cgi?id=5483 Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- arch/i386/kernel/acpi/Makefile | 2 +- arch/i386/kernel/acpi/cstate.c | 58 -------------- arch/i386/kernel/acpi/processor.c | 75 +++++++++++++++++++ arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 67 ----------------- .../kernel/cpu/cpufreq/speedstep-centrino.c | 12 --- arch/ia64/kernel/cpufreq/Makefile | 5 ++ arch/ia64/kernel/cpufreq/acpi-cpufreq.c | 51 ------------- arch/ia64/kernel/cpufreq/acpi-processor.c | 67 +++++++++++++++++ arch/x86_64/kernel/acpi/Makefile | 5 ++ arch/x86_64/kernel/acpi/processor.c | 72 ++++++++++++++++++ drivers/acpi/processor_core.c | 28 +++---- drivers/acpi/processor_idle.c | 2 - drivers/acpi/processor_perflib.c | 2 - include/acpi/pdc_intel.h | 4 +- include/acpi/processor.h | 22 ++---- include/asm-i386/acpi.h | 2 +- 16 files changed, 243 insertions(+), 231 deletions(-) create mode 100644 arch/i386/kernel/acpi/processor.c create mode 100644 arch/ia64/kernel/cpufreq/acpi-processor.c create mode 100644 arch/x86_64/kernel/acpi/processor.c diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index 267ca48e1b6c..d51c7313cae8 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile @@ -3,6 +3,6 @@ obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o ifneq ($(CONFIG_ACPI_PROCESSOR),) -obj-y += cstate.o +obj-y += cstate.o processor.o endif diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c index 4c3036ba65df..25db49ef1770 100644 --- a/arch/i386/kernel/acpi/cstate.c +++ b/arch/i386/kernel/acpi/cstate.c @@ -14,64 +14,6 @@ #include #include -static void acpi_processor_power_init_intel_pdc(struct acpi_processor_power - *pow) -{ - struct acpi_object_list *obj_list; - union acpi_object *obj; - u32 *buf; - - /* allocate and initialize pdc. It will be used later. */ - obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); - if (!obj_list) { - printk(KERN_ERR "Memory allocation error\n"); - return; - } - - obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); - if (!obj) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj_list); - return; - } - - buf = kmalloc(12, GFP_KERNEL); - if (!buf) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj); - kfree(obj_list); - return; - } - - buf[0] = ACPI_PDC_REVISION_ID; - buf[1] = 1; - buf[2] = ACPI_PDC_C_CAPABILITY_SMP; - - obj->type = ACPI_TYPE_BUFFER; - obj->buffer.length = 12; - obj->buffer.pointer = (u8 *) buf; - obj_list->count = 1; - obj_list->pointer = obj; - pow->pdc = obj_list; - - return; -} - -/* Initialize _PDC data based on the CPU vendor */ -void acpi_processor_power_init_pdc(struct acpi_processor_power *pow, - unsigned int cpu) -{ - struct cpuinfo_x86 *c = cpu_data + cpu; - - pow->pdc = NULL; - if (c->x86_vendor == X86_VENDOR_INTEL) - acpi_processor_power_init_intel_pdc(pow); - - return; -} - -EXPORT_SYMBOL(acpi_processor_power_init_pdc); - /* * Initialize bm_flags based on the CPU cache properties * On SMP it depends on cache configuration diff --git a/arch/i386/kernel/acpi/processor.c b/arch/i386/kernel/acpi/processor.c new file mode 100644 index 000000000000..9f4cc02717ec --- /dev/null +++ b/arch/i386/kernel/acpi/processor.c @@ -0,0 +1,75 @@ +/* + * arch/i386/kernel/acpi/processor.c + * + * Copyright (C) 2005 Intel Corporation + * Venkatesh Pallipadi + * - Added _PDC for platforms with Intel CPUs + */ + +#include +#include +#include +#include + +#include +#include + +static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return; + } + + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + buf[2] = ACPI_PDC_C_CAPABILITY_SMP; + + if (cpu_has(c, X86_FEATURE_EST)) + buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + pr->pdc = obj_list; + + return; +} + +/* Initialize _PDC data based on the CPU vendor */ +void arch_acpi_processor_init_pdc(struct acpi_processor *pr) +{ + unsigned int cpu = pr->id; + struct cpuinfo_x86 *c = cpu_data + cpu; + + pr->pdc = NULL; + if (c->x86_vendor == X86_VENDOR_INTEL) + init_intel_pdc(pr, c); + + return; +} + +EXPORT_SYMBOL(arch_acpi_processor_init_pdc); diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 871366b83b3f..31ce890865d5 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -297,68 +297,6 @@ acpi_cpufreq_guess_freq ( } -/* - * acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities - * of this driver - * @perf: processor-specific acpi_io_data struct - * @cpu: CPU being initialized - * - * To avoid issues with legacy OSes, some BIOSes require to be informed of - * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC - * accordingly, for Enhanced Speedstep. Actual call to _PDC is done in - * driver/acpi/processor.c - */ -static void -acpi_processor_cpu_init_pdc_est( - struct acpi_processor_performance *perf, - unsigned int cpu, - struct acpi_object_list *obj_list - ) -{ - union acpi_object *obj; - u32 *buf; - struct cpuinfo_x86 *c = cpu_data + cpu; - dprintk("acpi_processor_cpu_init_pdc_est\n"); - - if (!cpu_has(c, X86_FEATURE_EST)) - return; - - /* Initialize pdc. It will be used later. */ - if (!obj_list) - return; - - if (!(obj_list->count && obj_list->pointer)) - return; - - obj = obj_list->pointer; - if ((obj->buffer.length == 12) && obj->buffer.pointer) { - buf = (u32 *)obj->buffer.pointer; - buf[0] = ACPI_PDC_REVISION_ID; - buf[1] = 1; - buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; - perf->pdc = obj_list; - } - return; -} - - -/* CPU specific PDC initialization */ -static void -acpi_processor_cpu_init_pdc( - struct acpi_processor_performance *perf, - unsigned int cpu, - struct acpi_object_list *obj_list - ) -{ - struct cpuinfo_x86 *c = cpu_data + cpu; - dprintk("acpi_processor_cpu_init_pdc\n"); - perf->pdc = NULL; - if (cpu_has(c, X86_FEATURE_EST)) - acpi_processor_cpu_init_pdc_est(perf, cpu, obj_list); - return; -} - - static int acpi_cpufreq_cpu_init ( struct cpufreq_policy *policy) @@ -373,9 +311,6 @@ acpi_cpufreq_cpu_init ( struct acpi_object_list arg_list = {1, &arg0}; dprintk("acpi_cpufreq_cpu_init\n"); - /* setup arg_list for _PDC settings */ - arg0.buffer.length = 12; - arg0.buffer.pointer = (u8 *) arg0_buf; data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) @@ -383,9 +318,7 @@ acpi_cpufreq_cpu_init ( acpi_io_data[cpu] = data; - acpi_processor_cpu_init_pdc(&data->acpi_data, cpu, &arg_list); result = acpi_processor_register_performance(&data->acpi_data, cpu); - data->acpi_data.pdc = NULL; if (result) goto err_free; diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index edb9873e27e3..d93023438c4f 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -364,22 +364,10 @@ static struct acpi_processor_performance p; */ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { - union acpi_object arg0 = {ACPI_TYPE_BUFFER}; - u32 arg0_buf[3]; - struct acpi_object_list arg_list = {1, &arg0}; unsigned long cur_freq; int result = 0, i; unsigned int cpu = policy->cpu; - /* _PDC settings */ - arg0.buffer.length = 12; - arg0.buffer.pointer = (u8 *) arg0_buf; - arg0_buf[0] = ACPI_PDC_REVISION_ID; - arg0_buf[1] = 1; - arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP_MSR; - - p.pdc = &arg_list; - /* register with ACPI core */ if (acpi_processor_register_performance(&p, cpu)) { dprintk(KERN_INFO PFX "obtaining ACPI data failed\n"); diff --git a/arch/ia64/kernel/cpufreq/Makefile b/arch/ia64/kernel/cpufreq/Makefile index f748d34c02f0..642648361ed3 100644 --- a/arch/ia64/kernel/cpufreq/Makefile +++ b/arch/ia64/kernel/cpufreq/Makefile @@ -1 +1,6 @@ obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o + +ifneq ($(CONFIG_ACPI_PROCESSOR),) +obj-y += acpi-processor.o +endif + diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index da4d5cf80a48..5a1bf815282d 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -269,48 +269,6 @@ acpi_cpufreq_verify ( } -/* - * processor_init_pdc - let BIOS know about the SMP capabilities - * of this driver - * @perf: processor-specific acpi_io_data struct - * @cpu: CPU being initialized - * - * To avoid issues with legacy OSes, some BIOSes require to be informed of - * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC - * accordingly. Actual call to _PDC is done in driver/acpi/processor.c - */ -static void -processor_init_pdc ( - struct acpi_processor_performance *perf, - unsigned int cpu, - struct acpi_object_list *obj_list - ) -{ - union acpi_object *obj; - u32 *buf; - - dprintk("processor_init_pdc\n"); - - perf->pdc = NULL; - /* Initialize pdc. It will be used later. */ - if (!obj_list) - return; - - if (!(obj_list->count && obj_list->pointer)) - return; - - obj = obj_list->pointer; - if ((obj->buffer.length == 12) && obj->buffer.pointer) { - buf = (u32 *)obj->buffer.pointer; - buf[0] = ACPI_PDC_REVISION_ID; - buf[1] = 1; - buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; - perf->pdc = obj_list; - } - return; -} - - static int acpi_cpufreq_cpu_init ( struct cpufreq_policy *policy) @@ -320,14 +278,7 @@ acpi_cpufreq_cpu_init ( struct cpufreq_acpi_io *data; unsigned int result = 0; - union acpi_object arg0 = {ACPI_TYPE_BUFFER}; - u32 arg0_buf[3]; - struct acpi_object_list arg_list = {1, &arg0}; - dprintk("acpi_cpufreq_cpu_init\n"); - /* setup arg_list for _PDC settings */ - arg0.buffer.length = 12; - arg0.buffer.pointer = (u8 *) arg0_buf; data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) @@ -337,9 +288,7 @@ acpi_cpufreq_cpu_init ( acpi_io_data[cpu] = data; - processor_init_pdc(&data->acpi_data, cpu, &arg_list); result = acpi_processor_register_performance(&data->acpi_data, cpu); - data->acpi_data.pdc = NULL; if (result) goto err_free; diff --git a/arch/ia64/kernel/cpufreq/acpi-processor.c b/arch/ia64/kernel/cpufreq/acpi-processor.c new file mode 100644 index 000000000000..e683630c8ce2 --- /dev/null +++ b/arch/ia64/kernel/cpufreq/acpi-processor.c @@ -0,0 +1,67 @@ +/* + * arch/ia64/kernel/cpufreq/processor.c + * + * Copyright (C) 2005 Intel Corporation + * Venkatesh Pallipadi + * - Added _PDC for platforms with Intel CPUs + */ + +#include +#include +#include +#include + +#include +#include + +static void init_intel_pdc(struct acpi_processor *pr) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return; + } + + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + pr->pdc = obj_list; + + return; +} + +/* Initialize _PDC data based on the CPU vendor */ +void arch_acpi_processor_init_pdc(struct acpi_processor *pr) +{ + pr->pdc = NULL; + init_intel_pdc(pr); + return; +} + +EXPORT_SYMBOL(arch_acpi_processor_init_pdc); diff --git a/arch/x86_64/kernel/acpi/Makefile b/arch/x86_64/kernel/acpi/Makefile index 7da9ace890bd..4fe97071f297 100644 --- a/arch/x86_64/kernel/acpi/Makefile +++ b/arch/x86_64/kernel/acpi/Makefile @@ -1,3 +1,8 @@ obj-y := boot.o boot-y := ../../../i386/kernel/acpi/boot.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o + +ifneq ($(CONFIG_ACPI_PROCESSOR),) +obj-y += processor.o +endif + diff --git a/arch/x86_64/kernel/acpi/processor.c b/arch/x86_64/kernel/acpi/processor.c new file mode 100644 index 000000000000..3bdc2baa5bb1 --- /dev/null +++ b/arch/x86_64/kernel/acpi/processor.c @@ -0,0 +1,72 @@ +/* + * arch/x86_64/kernel/acpi/processor.c + * + * Copyright (C) 2005 Intel Corporation + * Venkatesh Pallipadi + * - Added _PDC for platforms with Intel CPUs + */ + +#include +#include +#include +#include + +#include +#include + +static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return; + } + + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + pr->pdc = obj_list; + + return; +} + +/* Initialize _PDC data based on the CPU vendor */ +void arch_acpi_processor_init_pdc(struct acpi_processor *pr) +{ + unsigned int cpu = pr->id; + struct cpuinfo_x86 *c = cpu_data + cpu; + + pr->pdc = NULL; + if (c->x86_vendor == X86_VENDOR_INTEL && cpu_has(c, X86_FEATURE_EST)) + init_intel_pdc(pr, c); + + return; +} + +EXPORT_SYMBOL(arch_acpi_processor_init_pdc); diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 421792562642..66bbda78507a 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -253,31 +253,21 @@ static int acpi_processor_errata(struct acpi_processor *pr) * _PDC is required for a BIOS-OS handshake for most of the newer * ACPI processor features. */ - -int acpi_processor_set_pdc(struct acpi_processor *pr, - struct acpi_object_list *pdc_in) +static int acpi_processor_set_pdc(struct acpi_processor *pr) { + struct acpi_object_list *pdc_in = pr->pdc; acpi_status status = AE_OK; - u32 arg0_buf[3]; - union acpi_object arg0 = { ACPI_TYPE_BUFFER }; - struct acpi_object_list no_object = { 1, &arg0 }; - struct acpi_object_list *pdc; ACPI_FUNCTION_TRACE("acpi_processor_set_pdc"); - arg0.buffer.length = 12; - arg0.buffer.pointer = (u8 *) arg0_buf; - arg0_buf[0] = ACPI_PDC_REVISION_ID; - arg0_buf[1] = 0; - arg0_buf[2] = 0; + if (!pdc_in) + return_VALUE(status); - pdc = (pdc_in) ? pdc_in : &no_object; + status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); - status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL); - - if ((ACPI_FAILURE(status)) && (pdc_in)) + if (ACPI_FAILURE(status)) ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Error evaluating _PDC, using legacy perf. control...\n")); + "Could not evaluate _PDC, using legacy perf. control...\n")); return_VALUE(status); } @@ -574,6 +564,10 @@ static int acpi_processor_start(struct acpi_device *device) "Error installing device notify handler\n")); } + /* _PDC call should be done before doing anything else (if reqd.). */ + arch_acpi_processor_init_pdc(pr); + acpi_processor_set_pdc(pr); + acpi_processor_power_init(pr, device); if (pr->flags.throttling) { diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 70d8a6ec0920..1915c377bfc6 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -1014,8 +1014,6 @@ int acpi_processor_power_init(struct acpi_processor *pr, } } - acpi_processor_power_init_pdc(&(pr->power), pr->id); - acpi_processor_set_pdc(pr, pr->power.pdc); acpi_processor_get_power_info(pr); /* diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 22c7bb66c200..532370734c68 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -315,8 +315,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) if (!pr || !pr->performance || !pr->handle) return_VALUE(-EINVAL); - acpi_processor_set_pdc(pr, pr->performance->pdc); - status = acpi_get_handle(pr->handle, "_PCT", &handle); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h index 91f4a12a99a1..3fa81d55cd0c 100644 --- a/include/acpi/pdc_intel.h +++ b/include/acpi/pdc_intel.h @@ -15,9 +15,7 @@ #define ACPI_PDC_C_C1_FFH (0x0100) #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ - ACPI_PDC_C_C1_HALT) - -#define ACPI_PDC_EST_CAPABILITY_SMP_MSR (ACPI_PDC_EST_CAPABILITY_SMP | \ + ACPI_PDC_C_C1_HALT | \ ACPI_PDC_P_FFH) #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 7a00d5089de9..82a9b7d430ec 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -62,9 +62,6 @@ struct acpi_processor_power { u32 bm_activity; int count; struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER]; - - /* the _PDC objects passed by the driver, if any */ - struct acpi_object_list *pdc; }; /* Performance Management */ @@ -96,8 +93,6 @@ struct acpi_processor_performance { unsigned int state_count; struct acpi_processor_px *states; - /* the _PDC objects passed by the driver, if any */ - struct acpi_object_list *pdc; }; /* Throttling Control */ @@ -151,6 +146,9 @@ struct acpi_processor { struct acpi_processor_performance *performance; struct acpi_processor_throttling throttling; struct acpi_processor_limit limit; + + /* the _PDC objects for this processor, if any */ + struct acpi_object_list *pdc; }; struct acpi_processor_errata { @@ -178,22 +176,12 @@ int acpi_processor_notify_smm(struct module *calling_module); extern struct acpi_processor *processors[NR_CPUS]; extern struct acpi_processor_errata errata; -int acpi_processor_set_pdc(struct acpi_processor *pr, - struct acpi_object_list *pdc_in); +void arch_acpi_processor_init_pdc(struct acpi_processor *pr); -#ifdef ARCH_HAS_POWER_PDC_INIT -void acpi_processor_power_init_pdc(struct acpi_processor_power *pow, - unsigned int cpu); +#ifdef ARCH_HAS_POWER_INIT void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, unsigned int cpu); #else -static inline void acpi_processor_power_init_pdc(struct acpi_processor_power - *pow, unsigned int cpu) -{ - pow->pdc = NULL; - return; -} - static inline void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, unsigned int cpu) diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h index df4ed323aa4d..55059abf9c95 100644 --- a/include/asm-i386/acpi.h +++ b/include/asm-i386/acpi.h @@ -179,7 +179,7 @@ extern void acpi_reserve_bootmem(void); extern u8 x86_acpiid_to_apicid[]; -#define ARCH_HAS_POWER_PDC_INIT 1 +#define ARCH_HAS_POWER_INIT 1 #endif /*__KERNEL__*/ From cf82478840188f8c8494c1d7a668a8ae170d0e07 Mon Sep 17 00:00:00 2001 From: Janosch Machowinski Date: Sat, 20 Aug 2005 08:02:00 -0400 Subject: [PATCH 008/695] [ACPI] handle BIOS with implicit C1 in _CST The ASUS M6Ne specifies C2, implying C1 but not explicitly specifying it. http://bugzilla.kernel.org/show_bug.cgi?id=4485 Signed-off-by: Janosch Machowinski Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 64 +++++++++++++++++------------------ 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 83fd1b6c10c4..40c9f9ca5965 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -532,18 +532,10 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) if (!pr->pblk) return_VALUE(-ENODEV); - memset(pr->power.states, 0, sizeof(pr->power.states)); - /* if info is obtained from pblk/fadt, type equals state */ - pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; - /* the C0 state only exists as a filler in our array, - * and all processors need to support C1 */ - pr->power.states[ACPI_STATE_C0].valid = 1; - pr->power.states[ACPI_STATE_C1].valid = 1; - #ifndef CONFIG_HOTPLUG_CPU /* * Check for P_LVL2_UP flag before entering C2 and above on @@ -573,12 +565,11 @@ static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) { ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); + /* Zero initialize all the C-states info. */ memset(pr->power.states, 0, sizeof(pr->power.states)); - /* if info is obtained from pblk/fadt, type equals state */ + /* set the first C-State to C1 */ pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; - pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; - pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; /* the C0 state only exists as a filler in our array, * and all processors need to support C1 */ @@ -592,6 +583,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) { acpi_status status = 0; acpi_integer count; + int current_count; int i; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *cst; @@ -601,10 +593,12 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) if (nocst) return_VALUE(-ENODEV); - pr->power.count = 0; - for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) - memset(&(pr->power.states[i]), 0, - sizeof(struct acpi_processor_cx)); + current_count = 1; + + /* Zero initialize C2 onwards and prepare for fresh CST lookup */ + for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++) + memset(&(pr->power.states[i]), 0, + sizeof(struct acpi_processor_cx)); status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); if (ACPI_FAILURE(status)) { @@ -632,16 +626,6 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) goto end; } - /* We support up to ACPI_PROCESSOR_MAX_POWER. */ - if (count > ACPI_PROCESSOR_MAX_POWER) { - printk(KERN_WARNING - "Limiting number of power states to max (%d)\n", - ACPI_PROCESSOR_MAX_POWER); - printk(KERN_WARNING - "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n"); - count = ACPI_PROCESSOR_MAX_POWER; - } - /* Tell driver that at least _CST is supported. */ pr->flags.has_cst = 1; @@ -685,7 +669,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) continue; - if ((cx.type < ACPI_STATE_C1) || (cx.type > ACPI_STATE_C3)) + if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) continue; obj = (union acpi_object *)&(element->package.elements[2]); @@ -700,15 +684,28 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) cx.power = obj->integer.value; - (pr->power.count)++; - memcpy(&(pr->power.states[pr->power.count]), &cx, sizeof(cx)); + current_count++; + memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx)); + + /* + * We support total ACPI_PROCESSOR_MAX_POWER - 1 + * (From 1 through ACPI_PROCESSOR_MAX_POWER - 1) + */ + if (current_count >= (ACPI_PROCESSOR_MAX_POWER - 1)) { + printk(KERN_WARNING + "Limiting number of power states to max (%d)\n", + ACPI_PROCESSOR_MAX_POWER); + printk(KERN_WARNING + "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n"); + break; + } } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", - pr->power.count)); + current_count)); /* Validate number of power states discovered */ - if (pr->power.count < 2) + if (current_count < 2) status = -EFAULT; end: @@ -859,12 +856,13 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) /* NOTE: the idle thread may not be running while calling * this function */ + /* Adding C1 state */ + acpi_processor_get_power_info_default_c1(pr); result = acpi_processor_get_power_info_cst(pr); if (result == -ENODEV) - result = acpi_processor_get_power_info_fadt(pr); + acpi_processor_get_power_info_fadt(pr); - if ((result) || (acpi_processor_power_verify(pr) < 2)) - result = acpi_processor_get_power_info_default_c1(pr); + pr->power.count = acpi_processor_power_verify(pr); /* * Set Default Policy From 06a2a3855e20ed3df380d69b37130ba86bec8001 Mon Sep 17 00:00:00 2001 From: Luming Yu Date: Tue, 27 Sep 2005 00:43:00 -0400 Subject: [PATCH 009/695] [ACPI] Disable EC burst mode w/o disabling EC interrupts Need to de-couple the concept of polling/interrupts vs burst/non-burst. http://bugzilla.kernel.org/show_bug.cgi?id=4980 Signed-off-by: Luming Yu Signed-off-by: Len Brown --- drivers/acpi/ec.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 7e1a445955bc..6edfbe6f187c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -213,19 +213,14 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) smp_mb(); switch (event) { - case ACPI_EC_EVENT_OBF: - if (acpi_ec_read_status(ec) & event) { - ec->burst.expect_event = 0; - return_VALUE(0); - } - break; - case ACPI_EC_EVENT_IBE: if (~acpi_ec_read_status(ec) & event) { ec->burst.expect_event = 0; return_VALUE(0); } break; + default: + break; } result = wait_event_timeout(ec->burst.wait, @@ -255,7 +250,11 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) return_VALUE(-ETIME); } -static int acpi_ec_enter_burst_mode(union acpi_ec *ec) +/* + * Note: samsung nv5000 doesn't work with ec burst mode. + * http://bugzilla.kernel.org/show_bug.cgi?id=4980 + */ +int acpi_ec_enter_burst_mode(union acpi_ec *ec) { u32 tmp = 0; int status = 0; @@ -270,8 +269,6 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec) acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); - if (status) - return_VALUE(-EINVAL); acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); if (tmp != 0x90) { /* Burst ACK byte */ return_VALUE(-EINVAL); @@ -285,13 +282,25 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec) return_VALUE(-1); } -static int acpi_ec_leave_burst_mode(union acpi_ec *ec) +int acpi_ec_leave_burst_mode(union acpi_ec *ec) { + int status = 0; ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); + status = acpi_ec_read_status(ec); + if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ + status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); + if(status) + goto end; + acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); + acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); + } atomic_set(&ec->burst.leaving_burst, 1); return_VALUE(0); +end: + printk("leave burst_mode:error \n"); + return_VALUE(-1); } static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) @@ -424,7 +433,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) WARN_ON(in_interrupt()); down(&ec->burst.sem); - acpi_ec_enter_burst_mode(ec); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("read EC, IB not empty\n"); @@ -448,7 +456,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) *data, address)); end: - acpi_ec_leave_burst_mode(ec); up(&ec->burst.sem); if (ec->common.global_lock) @@ -476,8 +483,6 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) WARN_ON(in_interrupt()); down(&ec->burst.sem); - acpi_ec_enter_burst_mode(ec); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("write EC, IB not empty\n"); @@ -500,7 +505,6 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", data, address)); - acpi_ec_leave_burst_mode(ec); up(&ec->burst.sem); if (ec->common.global_lock) From 02b28a33aae93a3b53068e0858d62f8bcaef60a3 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 5 Dec 2005 16:33:04 -0500 Subject: [PATCH 010/695] [ACPI] Embedded Controller (EC) driver syntax update "intr" largely replaces "burst" for syntax to follow semantics "poll" largely replaces "polling" for economy of expression append "interrupt mode" or "polling mode" to dmesg line no functional changes Signed-off-by: Len Brown --- drivers/acpi/ec.c | 233 +++++++++++++++++++++++----------------------- 1 file changed, 117 insertions(+), 116 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 6edfbe6f187c..bb3963b49a98 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -60,20 +60,20 @@ ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_BURST_ENABLE 0x82 #define ACPI_EC_BURST_DISABLE 0x83 #define ACPI_EC_COMMAND_QUERY 0x84 -#define EC_POLLING 0xFF -#define EC_BURST 0x00 +#define EC_POLL 0xFF +#define EC_INTR 0x00 static int acpi_ec_remove(struct acpi_device *device, int type); static int acpi_ec_start(struct acpi_device *device); static int acpi_ec_stop(struct acpi_device *device, int type); -static int acpi_ec_burst_add(struct acpi_device *device); -static int acpi_ec_polling_add(struct acpi_device *device); +static int acpi_ec_intr_add(struct acpi_device *device); +static int acpi_ec_poll_add(struct acpi_device *device); static struct acpi_driver acpi_ec_driver = { .name = ACPI_EC_DRIVER_NAME, .class = ACPI_EC_CLASS, .ids = ACPI_EC_HID, .ops = { - .add = acpi_ec_polling_add, + .add = acpi_ec_poll_add, .remove = acpi_ec_remove, .start = acpi_ec_start, .stop = acpi_ec_stop, @@ -105,7 +105,7 @@ union acpi_ec { atomic_t pending_gpe; struct semaphore sem; wait_queue_head_t wait; - } burst; + } intr; struct { u32 mode; @@ -117,37 +117,37 @@ union acpi_ec { struct acpi_generic_address data_addr; unsigned long global_lock; spinlock_t lock; - } polling; + } poll; }; -static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event); -static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event); -static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data); -static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data); -static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data); -static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data); -static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data); -static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data); -static void acpi_ec_gpe_polling_query(void *ec_cxt); -static void acpi_ec_gpe_burst_query(void *ec_cxt); -static u32 acpi_ec_gpe_polling_handler(void *data); -static u32 acpi_ec_gpe_burst_handler(void *data); +static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event); +static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event); +static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data); +static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data); +static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data); +static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data); +static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data); +static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data); +static void acpi_ec_gpe_poll_query(void *ec_cxt); +static void acpi_ec_gpe_intr_query(void *ec_cxt); +static u32 acpi_ec_gpe_poll_handler(void *data); +static u32 acpi_ec_gpe_intr_handler(void *data); static acpi_status __init -acpi_fake_ecdt_polling_callback(acpi_handle handle, +acpi_fake_ecdt_poll_callback(acpi_handle handle, u32 Level, void *context, void **retval); static acpi_status __init -acpi_fake_ecdt_burst_callback(acpi_handle handle, +acpi_fake_ecdt_intr_callback(acpi_handle handle, u32 Level, void *context, void **retval); -static int __init acpi_ec_polling_get_real_ecdt(void); -static int __init acpi_ec_burst_get_real_ecdt(void); +static int __init acpi_ec_poll_get_real_ecdt(void); +static int __init acpi_ec_intr_get_real_ecdt(void); /* If we find an EC via the ECDT, we need to keep a ptr to its context */ static union acpi_ec *ec_ecdt; /* External interfaces use first EC only, so remember */ static struct acpi_device *first_ec; -static int acpi_ec_polling_mode = EC_POLLING; +static int acpi_ec_poll_mode = EC_POLL; /* -------------------------------------------------------------------------- Transaction Management @@ -163,13 +163,13 @@ static inline u32 acpi_ec_read_status(union acpi_ec *ec) static int acpi_ec_wait(union acpi_ec *ec, u8 event) { - if (acpi_ec_polling_mode) - return acpi_ec_polling_wait(ec, event); + if (acpi_ec_poll_mode) + return acpi_ec_poll_wait(ec, event); else - return acpi_ec_burst_wait(ec, event); + return acpi_ec_intr_wait(ec, event); } -static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event) +static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event) { u32 acpi_ec_status = 0; u32 i = ACPI_EC_UDELAY_COUNT; @@ -203,19 +203,19 @@ static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event) return -ETIME; } -static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) +static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event) { int result = 0; ACPI_FUNCTION_TRACE("acpi_ec_wait"); - ec->burst.expect_event = event; + ec->intr.expect_event = event; smp_mb(); switch (event) { case ACPI_EC_EVENT_IBE: if (~acpi_ec_read_status(ec) & event) { - ec->burst.expect_event = 0; + ec->intr.expect_event = 0; return_VALUE(0); } break; @@ -223,11 +223,11 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) break; } - result = wait_event_timeout(ec->burst.wait, - !ec->burst.expect_event, + result = wait_event_timeout(ec->intr.wait, + !ec->intr.expect_event, msecs_to_jiffies(ACPI_EC_DELAY)); - ec->burst.expect_event = 0; + ec->intr.expect_event = 0; smp_mb(); /* @@ -250,6 +250,7 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) return_VALUE(-ETIME); } +#ifdef ACPI_FUTURE_USAGE /* * Note: samsung nv5000 doesn't work with ec burst mode. * http://bugzilla.kernel.org/show_bug.cgi?id=4980 @@ -275,7 +276,7 @@ int acpi_ec_enter_burst_mode(union acpi_ec *ec) } } - atomic_set(&ec->burst.leaving_burst, 0); + atomic_set(&ec->intr.leaving_burst, 0); return_VALUE(0); end: printk("Error in acpi_ec_wait\n"); @@ -296,28 +297,29 @@ int acpi_ec_leave_burst_mode(union acpi_ec *ec) acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); } - atomic_set(&ec->burst.leaving_burst, 1); + atomic_set(&ec->intr.leaving_burst, 1); return_VALUE(0); end: printk("leave burst_mode:error \n"); return_VALUE(-1); } +#endif /* ACPI_FUTURE_USAGE */ static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) { - if (acpi_ec_polling_mode) - return acpi_ec_polling_read(ec, address, data); + if (acpi_ec_poll_mode) + return acpi_ec_poll_read(ec, address, data); else - return acpi_ec_burst_read(ec, address, data); + return acpi_ec_intr_read(ec, address, data); } static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data) { - if (acpi_ec_polling_mode) - return acpi_ec_polling_write(ec, address, data); + if (acpi_ec_poll_mode) + return acpi_ec_poll_write(ec, address, data); else - return acpi_ec_burst_write(ec, address, data); + return acpi_ec_intr_write(ec, address, data); } -static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data) +static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) { acpi_status status = AE_OK; int result = 0; @@ -337,7 +339,7 @@ static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data) return_VALUE(-ENODEV); } - spin_lock_irqsave(&ec->polling.lock, flags); + spin_lock_irqsave(&ec->poll.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); @@ -356,7 +358,7 @@ static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data) *data, address)); end: - spin_unlock_irqrestore(&ec->polling.lock, flags); + spin_unlock_irqrestore(&ec->poll.lock, flags); if (ec->common.global_lock) acpi_release_global_lock(glk); @@ -364,7 +366,7 @@ static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data) return_VALUE(result); } -static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data) +static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) { int result = 0; acpi_status status = AE_OK; @@ -382,7 +384,7 @@ static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data) return_VALUE(-ENODEV); } - spin_lock_irqsave(&ec->polling.lock, flags); + spin_lock_irqsave(&ec->poll.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); @@ -404,7 +406,7 @@ static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data) data, address)); end: - spin_unlock_irqrestore(&ec->polling.lock, flags); + spin_unlock_irqrestore(&ec->poll.lock, flags); if (ec->common.global_lock) acpi_release_global_lock(glk); @@ -412,7 +414,7 @@ static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data) return_VALUE(result); } -static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) +static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data) { int status = 0; u32 glk; @@ -431,7 +433,7 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) } WARN_ON(in_interrupt()); - down(&ec->burst.sem); + down(&ec->intr.sem); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { @@ -456,7 +458,7 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) *data, address)); end: - up(&ec->burst.sem); + up(&ec->intr.sem); if (ec->common.global_lock) acpi_release_global_lock(glk); @@ -464,7 +466,7 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) return_VALUE(status); } -static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) +static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data) { int status = 0; u32 glk; @@ -481,7 +483,7 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) } WARN_ON(in_interrupt()); - down(&ec->burst.sem); + down(&ec->intr.sem); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { @@ -505,7 +507,7 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", data, address)); - up(&ec->burst.sem); + up(&ec->intr.sem); if (ec->common.global_lock) acpi_release_global_lock(glk); @@ -557,12 +559,12 @@ EXPORT_SYMBOL(ec_write); static int acpi_ec_query(union acpi_ec *ec, u32 * data) { - if (acpi_ec_polling_mode) - return acpi_ec_polling_query(ec, data); + if (acpi_ec_poll_mode) + return acpi_ec_poll_query(ec, data); else - return acpi_ec_burst_query(ec, data); + return acpi_ec_intr_query(ec, data); } -static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data) +static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) { int result = 0; acpi_status status = AE_OK; @@ -587,7 +589,7 @@ static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data) * Note that successful completion of the query causes the ACPI_EC_SCI * bit to be cleared (and thus clearing the interrupt source). */ - spin_lock_irqsave(&ec->polling.lock, flags); + spin_lock_irqsave(&ec->poll.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); @@ -600,14 +602,14 @@ static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data) result = -ENODATA; end: - spin_unlock_irqrestore(&ec->polling.lock, flags); + spin_unlock_irqrestore(&ec->poll.lock, flags); if (ec->common.global_lock) acpi_release_global_lock(glk); return_VALUE(result); } -static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) +static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data) { int status = 0; u32 glk; @@ -624,7 +626,7 @@ static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) return_VALUE(-ENODEV); } - down(&ec->burst.sem); + down(&ec->intr.sem); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { @@ -649,7 +651,7 @@ static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) status = -ENODATA; end: - up(&ec->burst.sem); + up(&ec->intr.sem); if (ec->common.global_lock) acpi_release_global_lock(glk); @@ -668,13 +670,13 @@ union acpi_ec_query_data { static void acpi_ec_gpe_query(void *ec_cxt) { - if (acpi_ec_polling_mode) - acpi_ec_gpe_polling_query(ec_cxt); + if (acpi_ec_poll_mode) + acpi_ec_gpe_poll_query(ec_cxt); else - acpi_ec_gpe_burst_query(ec_cxt); + acpi_ec_gpe_intr_query(ec_cxt); } -static void acpi_ec_gpe_polling_query(void *ec_cxt) +static void acpi_ec_gpe_poll_query(void *ec_cxt) { union acpi_ec *ec = (union acpi_ec *)ec_cxt; u32 value = 0; @@ -689,9 +691,9 @@ static void acpi_ec_gpe_polling_query(void *ec_cxt) if (!ec_cxt) goto end; - spin_lock_irqsave(&ec->polling.lock, flags); + spin_lock_irqsave(&ec->poll.lock, flags); acpi_hw_low_level_read(8, &value, &ec->common.command_addr); - spin_unlock_irqrestore(&ec->polling.lock, flags); + spin_unlock_irqrestore(&ec->poll.lock, flags); /* TBD: Implement asynch events! * NOTE: All we care about are EC-SCI's. Other EC events are @@ -715,7 +717,7 @@ static void acpi_ec_gpe_polling_query(void *ec_cxt) end: acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); } -static void acpi_ec_gpe_burst_query(void *ec_cxt) +static void acpi_ec_gpe_intr_query(void *ec_cxt) { union acpi_ec *ec = (union acpi_ec *)ec_cxt; u32 value; @@ -740,18 +742,18 @@ static void acpi_ec_gpe_burst_query(void *ec_cxt) acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); end: - atomic_dec(&ec->burst.pending_gpe); + atomic_dec(&ec->intr.pending_gpe); return; } static u32 acpi_ec_gpe_handler(void *data) { - if (acpi_ec_polling_mode) - return acpi_ec_gpe_polling_handler(data); + if (acpi_ec_poll_mode) + return acpi_ec_gpe_poll_handler(data); else - return acpi_ec_gpe_burst_handler(data); + return acpi_ec_gpe_intr_handler(data); } -static u32 acpi_ec_gpe_polling_handler(void *data) +static u32 acpi_ec_gpe_poll_handler(void *data) { acpi_status status = AE_OK; union acpi_ec *ec = (union acpi_ec *)data; @@ -769,7 +771,7 @@ static u32 acpi_ec_gpe_polling_handler(void *data) else return ACPI_INTERRUPT_NOT_HANDLED; } -static u32 acpi_ec_gpe_burst_handler(void *data) +static u32 acpi_ec_gpe_intr_handler(void *data) { acpi_status status = AE_OK; u32 value; @@ -781,22 +783,22 @@ static u32 acpi_ec_gpe_burst_handler(void *data) acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); value = acpi_ec_read_status(ec); - switch (ec->burst.expect_event) { + switch (ec->intr.expect_event) { case ACPI_EC_EVENT_OBF: if (!(value & ACPI_EC_FLAG_OBF)) break; case ACPI_EC_EVENT_IBE: if ((value & ACPI_EC_FLAG_IBF)) break; - ec->burst.expect_event = 0; - wake_up(&ec->burst.wait); + ec->intr.expect_event = 0; + wake_up(&ec->intr.wait); return ACPI_INTERRUPT_HANDLED; default: break; } if (value & ACPI_EC_FLAG_SCI) { - atomic_add(1, &ec->burst.pending_gpe); + atomic_add(1, &ec->intr.pending_gpe); status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, acpi_ec_gpe_query, ec); return status == AE_OK ? @@ -984,7 +986,7 @@ static int acpi_ec_remove_fs(struct acpi_device *device) Driver Interface -------------------------------------------------------------------------- */ -static int acpi_ec_polling_add(struct acpi_device *device) +static int acpi_ec_poll_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; @@ -1003,7 +1005,7 @@ static int acpi_ec_polling_add(struct acpi_device *device) ec->common.handle = device->handle; ec->common.uid = -1; - spin_lock_init(&ec->polling.lock); + spin_lock_init(&ec->poll.lock); strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_EC_CLASS); acpi_driver_data(device) = ec; @@ -1042,7 +1044,7 @@ static int acpi_ec_polling_add(struct acpi_device *device) if (result) goto end; - printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", + printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n", acpi_device_name(device), acpi_device_bid(device), (u32) ec->common.gpe_bit); @@ -1055,7 +1057,7 @@ static int acpi_ec_polling_add(struct acpi_device *device) return_VALUE(result); } -static int acpi_ec_burst_add(struct acpi_device *device) +static int acpi_ec_intr_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; @@ -1074,10 +1076,10 @@ static int acpi_ec_burst_add(struct acpi_device *device) ec->common.handle = device->handle; ec->common.uid = -1; - atomic_set(&ec->burst.pending_gpe, 0); - atomic_set(&ec->burst.leaving_burst, 1); - init_MUTEX(&ec->burst.sem); - init_waitqueue_head(&ec->burst.wait); + atomic_set(&ec->intr.pending_gpe, 0); + atomic_set(&ec->intr.leaving_burst, 1); + init_MUTEX(&ec->intr.sem); + init_waitqueue_head(&ec->intr.wait); strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_EC_CLASS); acpi_driver_data(device) = ec; @@ -1116,8 +1118,7 @@ static int acpi_ec_burst_add(struct acpi_device *device) if (result) goto end; - printk("burst-mode-ec-10-Aug\n"); - printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", + printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n", acpi_device_name(device), acpi_device_bid(device), (u32) ec->common.gpe_bit); @@ -1271,16 +1272,16 @@ acpi_fake_ecdt_callback(acpi_handle handle, u32 Level, void *context, void **retval) { - if (acpi_ec_polling_mode) - return acpi_fake_ecdt_polling_callback(handle, + if (acpi_ec_poll_mode) + return acpi_fake_ecdt_poll_callback(handle, Level, context, retval); else - return acpi_fake_ecdt_burst_callback(handle, + return acpi_fake_ecdt_intr_callback(handle, Level, context, retval); } static acpi_status __init -acpi_fake_ecdt_polling_callback(acpi_handle handle, +acpi_fake_ecdt_poll_callback(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; @@ -1299,7 +1300,7 @@ acpi_fake_ecdt_polling_callback(acpi_handle handle, &ec_ecdt->common.gpe_bit); if (ACPI_FAILURE(status)) return status; - spin_lock_init(&ec_ecdt->polling.lock); + spin_lock_init(&ec_ecdt->poll.lock); ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.handle = handle; @@ -1312,13 +1313,13 @@ acpi_fake_ecdt_polling_callback(acpi_handle handle, } static acpi_status __init -acpi_fake_ecdt_burst_callback(acpi_handle handle, +acpi_fake_ecdt_intr_callback(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; - init_MUTEX(&ec_ecdt->burst.sem); - init_waitqueue_head(&ec_ecdt->burst.wait); + init_MUTEX(&ec_ecdt->intr.sem); + init_waitqueue_head(&ec_ecdt->intr.wait); status = acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_ec_io_ports, ec_ecdt); if (ACPI_FAILURE(status)) @@ -1384,13 +1385,13 @@ static int __init acpi_ec_fake_ecdt(void) static int __init acpi_ec_get_real_ecdt(void) { - if (acpi_ec_polling_mode) - return acpi_ec_polling_get_real_ecdt(); + if (acpi_ec_poll_mode) + return acpi_ec_poll_get_real_ecdt(); else - return acpi_ec_burst_get_real_ecdt(); + return acpi_ec_intr_get_real_ecdt(); } -static int __init acpi_ec_polling_get_real_ecdt(void) +static int __init acpi_ec_poll_get_real_ecdt(void) { acpi_status status; struct acpi_table_ecdt *ecdt_ptr; @@ -1415,7 +1416,7 @@ static int __init acpi_ec_polling_get_real_ecdt(void) ec_ecdt->common.status_addr = ecdt_ptr->ec_control; ec_ecdt->common.data_addr = ecdt_ptr->ec_data; ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; - spin_lock_init(&ec_ecdt->polling.lock); + spin_lock_init(&ec_ecdt->poll.lock); /* use the GL just to be safe */ ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.uid = ecdt_ptr->uid; @@ -1435,7 +1436,7 @@ static int __init acpi_ec_polling_get_real_ecdt(void) return -ENODEV; } -static int __init acpi_ec_burst_get_real_ecdt(void) +static int __init acpi_ec_intr_get_real_ecdt(void) { acpi_status status; struct acpi_table_ecdt *ecdt_ptr; @@ -1456,8 +1457,8 @@ static int __init acpi_ec_burst_get_real_ecdt(void) return -ENOMEM; memset(ec_ecdt, 0, sizeof(union acpi_ec)); - init_MUTEX(&ec_ecdt->burst.sem); - init_waitqueue_head(&ec_ecdt->burst.wait); + init_MUTEX(&ec_ecdt->intr.sem); + init_waitqueue_head(&ec_ecdt->intr.wait); ec_ecdt->common.command_addr = ecdt_ptr->ec_control; ec_ecdt->common.status_addr = ecdt_ptr->ec_control; ec_ecdt->common.data_addr = ecdt_ptr->ec_data; @@ -1575,22 +1576,22 @@ static int __init acpi_fake_ecdt_setup(char *str) } __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup); -static int __init acpi_ec_set_polling_mode(char *str) +static int __init acpi_ec_set_intr_mode(char *str) { - int burst; + int intr; - if (!get_option(&str, &burst)) + if (!get_option(&str, &intr)) return 0; - if (burst) { - acpi_ec_polling_mode = EC_BURST; - acpi_ec_driver.ops.add = acpi_ec_burst_add; + if (intr) { + acpi_ec_poll_mode = EC_INTR; + acpi_ec_driver.ops.add = acpi_ec_intr_add; } else { - acpi_ec_polling_mode = EC_POLLING; - acpi_ec_driver.ops.add = acpi_ec_polling_add; + acpi_ec_poll_mode = EC_POLL; + acpi_ec_driver.ops.add = acpi_ec_poll_add; } - printk(KERN_INFO PREFIX "EC %s mode.\n", burst ? "burst" : "polling"); + printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); return 0; } -__setup("ec_burst=", acpi_ec_set_polling_mode); +__setup("ec_burst=", acpi_ec_set_intr_mode); From 53f11d4ff8797bcceaf014e62bd39f16ce84baec Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 5 Dec 2005 16:46:36 -0500 Subject: [PATCH 011/695] [ACPI] Enable Embedded Controller (EC) interrupt mode by default "ec_intr=0" reverts to polling "ec_burst=" no longer exists. Signed-off-by: Len Brown Acked-by: Luming Yu --- Documentation/kernel-parameters.txt | 5 +++++ drivers/acpi/ec.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5dffcfefc3c7..2ad64efdf183 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -452,6 +452,11 @@ running once the system is up. eata= [HW,SCSI] + ec_intr= [HW,ACPI] ACPI Embedded Controller interrupt mode + Format: + 0: polling mode + non-0: interrupt mode (default) + eda= [HW,PS2] edb= [HW,PS2] diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index bb3963b49a98..d4366ad4edcd 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -73,7 +73,7 @@ static struct acpi_driver acpi_ec_driver = { .class = ACPI_EC_CLASS, .ids = ACPI_EC_HID, .ops = { - .add = acpi_ec_poll_add, + .add = acpi_ec_intr_add, .remove = acpi_ec_remove, .start = acpi_ec_start, .stop = acpi_ec_stop, @@ -147,7 +147,7 @@ static union acpi_ec *ec_ecdt; /* External interfaces use first EC only, so remember */ static struct acpi_device *first_ec; -static int acpi_ec_poll_mode = EC_POLL; +static int acpi_ec_poll_mode = EC_INTR; /* -------------------------------------------------------------------------- Transaction Management @@ -1594,4 +1594,4 @@ static int __init acpi_ec_set_intr_mode(char *str) return 0; } -__setup("ec_burst=", acpi_ec_set_intr_mode); +__setup("ec_intr=", acpi_ec_set_intr_mode); From 1e8df53c925024548cca4374f03bed1a7e2b0c45 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 5 Dec 2005 16:47:46 -0500 Subject: [PATCH 012/695] [ACPI] Embedded Controller (EC) driver printk syntax update no functional changes Signed-off-by: Len Brown --- drivers/acpi/ec.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d4366ad4edcd..93fcaec6d589 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -279,7 +279,7 @@ int acpi_ec_enter_burst_mode(union acpi_ec *ec) atomic_set(&ec->intr.leaving_burst, 0); return_VALUE(0); end: - printk("Error in acpi_ec_wait\n"); + printk(KERN_WARNING PREFIX "Error in acpi_ec_wait\n"); return_VALUE(-1); } @@ -300,7 +300,7 @@ int acpi_ec_leave_burst_mode(union acpi_ec *ec) atomic_set(&ec->intr.leaving_burst, 1); return_VALUE(0); end: - printk("leave burst_mode:error \n"); + printk(KERN_WARNING PREFIX "leave burst_mode:error\n"); return_VALUE(-1); } #endif /* ACPI_FUTURE_USAGE */ @@ -437,20 +437,20 @@ static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data) status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { - printk("read EC, IB not empty\n"); + printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); goto end; } acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { - printk("read EC, IB not empty\n"); + printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); } acpi_hw_low_level_write(8, address, &ec->common.data_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { - printk("read EC, OB not full\n"); + printk(KERN_DEBUG PREFIX "read EC, OB not full\n"); goto end; } acpi_hw_low_level_read(8, data, &ec->common.data_addr); @@ -487,19 +487,19 @@ static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data) status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { - printk("write EC, IB not empty\n"); + printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); } acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { - printk("write EC, IB not empty\n"); + printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); } acpi_hw_low_level_write(8, address, &ec->common.data_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { - printk("write EC, IB not empty\n"); + printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); } acpi_hw_low_level_write(8, data, &ec->common.data_addr); @@ -630,7 +630,7 @@ static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data) status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { - printk("query EC, IB not empty\n"); + printk(KERN_DEBUG PREFIX "query EC, IB not empty\n"); goto end; } /* @@ -642,7 +642,7 @@ static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data) &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { - printk("query EC, OB not full\n"); + printk(KERN_DEBUG PREFIX "query EC, OB not full\n"); goto end; } From c82e6abfb3182c84d0204b178363086b09881a4a Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Thu, 1 Dec 2005 18:16:00 -0500 Subject: [PATCH 013/695] [ACPI] IA64 ZX1 buildfix for _PDC patch http://bugzilla.kernel.org/show_bug.cgi?id=5483 ZX1 config doesn't include cpufreq, so move move acpi-processor.c up out of ia64/cpufreq directory. no functional changes Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- arch/ia64/kernel/Makefile | 5 +++++ arch/ia64/kernel/{cpufreq => }/acpi-processor.c | 0 arch/ia64/kernel/cpufreq/Makefile | 4 ---- 3 files changed, 5 insertions(+), 4 deletions(-) rename arch/ia64/kernel/{cpufreq => }/acpi-processor.c (100%) diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 307514f7a282..09a0dbc17fb6 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -13,6 +13,11 @@ obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o + +ifneq ($(CONFIG_ACPI_PROCESSOR),) +obj-y += acpi-processor.o +endif + obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_IOSAPIC) += iosapic.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/ia64/kernel/cpufreq/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c similarity index 100% rename from arch/ia64/kernel/cpufreq/acpi-processor.c rename to arch/ia64/kernel/acpi-processor.c diff --git a/arch/ia64/kernel/cpufreq/Makefile b/arch/ia64/kernel/cpufreq/Makefile index 642648361ed3..4838f2a57c7a 100644 --- a/arch/ia64/kernel/cpufreq/Makefile +++ b/arch/ia64/kernel/cpufreq/Makefile @@ -1,6 +1,2 @@ obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o -ifneq ($(CONFIG_ACPI_PROCESSOR),) -obj-y += acpi-processor.o -endif - From 50eca3eb89d73d9f0aa070b126c7ee6a616016ab Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 30 Sep 2005 19:03:00 -0400 Subject: [PATCH 014/695] [ACPI] ACPICA 20050930 Completed a major overhaul of the Resource Manager code - specifically, optimizations in the area of the AML/internal resource conversion code. The code has been optimized to simplify and eliminate duplicated code, CPU stack use has been decreased by optimizing function parameters and local variables, and naming conventions across the manager have been standardized for clarity and ease of maintenance (this includes function, parameter, variable, and struct/typedef names.) All Resource Manager dispatch and information tables have been moved to a single location for clarity and ease of maintenance. One new file was created, named "rsinfo.c". The ACPI return macros (return_ACPI_STATUS, etc.) have been modified to guarantee that the argument is not evaluated twice, making them less prone to macro side-effects. However, since there exists the possibility of additional stack use if a particular compiler cannot optimize them (such as in the debug generation case), the original macros are optionally available. Note that some invocations of the return_VALUE macro may now cause size mismatch warnings; the return_UINT8 and return_UINT32 macros are provided to eliminate these. (From Randy Dunlap) Implemented a new mechanism to enable debug tracing for individual control methods. A new external interface, acpi_debug_trace(), is provided to enable this mechanism. The intent is to allow the host OS to easily enable and disable tracing for problematic control methods. This interface can be easily exposed to a user or debugger interface if desired. See the file psxface.c for details. acpi_ut_callocate() will now return a valid pointer if a length of zero is specified - a length of one is used and a warning is issued. This matches the behavior of acpi_ut_allocate(). Signed-off-by: Bob Moore Signed-off-by: Len Brown --- arch/ia64/kernel/acpi-ext.c | 22 +- arch/ia64/pci/pci.c | 8 +- arch/x86_64/kernel/io_apic.c | 10 +- arch/x86_64/kernel/mpparse.c | 8 +- drivers/acpi/acpi_memhotplug.c | 4 +- drivers/acpi/dispatcher/dsutils.c | 12 +- drivers/acpi/ec.c | 4 +- drivers/acpi/events/evgpe.c | 10 +- drivers/acpi/events/evsci.c | 4 +- drivers/acpi/executer/exdump.c | 10 +- drivers/acpi/executer/exnames.c | 4 +- drivers/acpi/executer/exprep.c | 4 +- drivers/acpi/executer/exresop.c | 2 +- drivers/acpi/executer/exutils.c | 6 +- drivers/acpi/glue.c | 8 +- drivers/acpi/hardware/hwacpi.c | 8 +- drivers/acpi/motherboard.c | 30 +- drivers/acpi/namespace/nsaccess.c | 2 +- drivers/acpi/namespace/nsnames.c | 2 +- drivers/acpi/namespace/nsutils.c | 12 +- drivers/acpi/parser/psargs.c | 2 +- drivers/acpi/parser/psxface.c | 142 ++++ drivers/acpi/pci_irq.c | 48 +- drivers/acpi/pci_link.c | 92 +-- drivers/acpi/pci_root.c | 8 +- drivers/acpi/resources/Makefile | 2 +- drivers/acpi/resources/rsaddr.c | 1252 ++++++++++------------------- drivers/acpi/resources/rscalc.c | 282 ++----- drivers/acpi/resources/rscreate.c | 59 +- drivers/acpi/resources/rsdump.c | 313 ++++---- drivers/acpi/resources/rsinfo.c | 2 +- drivers/acpi/resources/rsio.c | 445 ++++------ drivers/acpi/resources/rsirq.c | 494 ++++-------- drivers/acpi/resources/rslist.c | 298 +++---- drivers/acpi/resources/rsmemory.c | 574 +++++-------- drivers/acpi/resources/rsmisc.c | 767 +++++++----------- drivers/acpi/resources/rsutils.c | 437 +++++++++- drivers/acpi/resources/rsxface.c | 14 +- drivers/acpi/tables/tbrsdt.c | 2 +- drivers/acpi/tables/tbxfroot.c | 2 +- drivers/acpi/utilities/utalloc.c | 6 +- drivers/acpi/utilities/utglobal.c | 3 + drivers/acpi/utilities/utmisc.c | 6 +- drivers/char/hpet.c | 26 +- drivers/pnp/pnpacpi/rsparser.c | 364 ++++----- drivers/serial/8250_acpi.c | 22 +- include/acpi/acconfig.h | 2 +- include/acpi/acdisasm.h | 42 +- include/acpi/acglobal.h | 9 + include/acpi/aclocal.h | 79 +- include/acpi/acmacros.h | 58 +- include/acpi/acpi_drivers.h | 4 +- include/acpi/acpixf.h | 3 + include/acpi/acresrc.h | 351 +++++--- include/acpi/actypes.h | 152 ++-- include/acpi/amlresrc.h | 242 +++--- include/asm-x86_64/mpspec.h | 2 +- include/linux/acpi.h | 2 +- 58 files changed, 3109 insertions(+), 3669 deletions(-) diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index a146016d7ad7..4a5574ff007b 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c @@ -33,33 +33,33 @@ acpi_vendor_resource_match(struct acpi_resource *resource, void *context) struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; struct acpi_resource_vendor *vendor; struct acpi_vendor_descriptor *descriptor; - u32 length; + u32 byte_length; - if (resource->type != ACPI_RSTYPE_VENDOR) + if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) return AE_OK; vendor = (struct acpi_resource_vendor *)&resource->data; - descriptor = (struct acpi_vendor_descriptor *)vendor->reserved; - if (vendor->length <= sizeof(*info->descriptor) || + descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data; + if (vendor->byte_length <= sizeof(*info->descriptor) || descriptor->guid_id != info->descriptor->guid_id || efi_guidcmp(descriptor->guid, info->descriptor->guid)) return AE_OK; - length = vendor->length - sizeof(struct acpi_vendor_descriptor); - info->data = acpi_os_allocate(length); + byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor); + info->data = acpi_os_allocate(byte_length); if (!info->data) return AE_NO_MEMORY; memcpy(info->data, - vendor->reserved + sizeof(struct acpi_vendor_descriptor), - length); - info->length = length; + vendor->byte_data + sizeof(struct acpi_vendor_descriptor), + byte_length); + info->length = byte_length; return AE_CTRL_TERMINATE; } acpi_status acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, - u8 ** data, u32 * length) + u8 ** data, u32 * byte_length) { struct acpi_vendor_info info; @@ -72,7 +72,7 @@ acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, return AE_NOT_FOUND; *data = info.data; - *length = info.length; + *byte_length = info.length; return AE_OK; } diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 20d76fae24e8..25f923d050e3 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -193,12 +193,12 @@ add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr) goto free_resource; } - min = addr->min_address_range; + min = addr->minimum; max = min + addr->address_length - 1; if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION) sparse = 1; - space_nr = new_space(addr->address_translation_offset, sparse); + space_nr = new_space(addr->translation_offset, sparse); if (space_nr == ~0) goto free_name; @@ -285,7 +285,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) if (addr.resource_type == ACPI_MEMORY_RANGE) { flags = IORESOURCE_MEM; root = &iomem_resource; - offset = addr.address_translation_offset; + offset = addr.translation_offset; } else if (addr.resource_type == ACPI_IO_RANGE) { flags = IORESOURCE_IO; root = &ioport_resource; @@ -298,7 +298,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) window = &info->controller->window[info->controller->windows++]; window->resource.name = info->name; window->resource.flags = flags; - window->resource.start = addr.min_address_range + offset; + window->resource.start = addr.minimum + offset; window->resource.end = window->resource.start + addr.address_length - 1; window->resource.child = NULL; window->offset = offset; diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 97154ab058b4..619767d3ea2b 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1956,7 +1956,7 @@ int __init io_apic_get_redir_entries (int ioapic) } -int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low) +int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity) { struct IO_APIC_route_entry entry; unsigned long flags; @@ -1978,8 +1978,8 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a entry.delivery_mode = INT_DELIVERY_MODE; entry.dest_mode = INT_DEST_MODE; entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); - entry.trigger = edge_level; - entry.polarity = active_high_low; + entry.trigger = triggering; + entry.polarity = polarity; entry.mask = 1; /* Disabled (masked) */ irq = gsi_irq_sharing(irq); @@ -1994,9 +1994,9 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> " "IRQ %d Mode:%i Active:%i)\n", ioapic, mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, - edge_level, active_high_low); + triggering, polarity); - ioapic_register_intr(irq, entry.vector, edge_level); + ioapic_register_intr(irq, entry.vector, triggering); if (!ioapic && (irq < 16)) disable_8259A_irq(irq); diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 1105250bf02c..ba817e7454b2 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c @@ -915,7 +915,7 @@ void __init mp_config_acpi_legacy_irqs (void) #define MAX_GSI_NUM 4096 -int mp_register_gsi(u32 gsi, int edge_level, int active_high_low) +int mp_register_gsi(u32 gsi, int triggering, int polarity) { int ioapic = -1; int ioapic_pin = 0; @@ -964,7 +964,7 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low) mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<read_write_attribute = address64.attribute.memory.read_write_attribute; - mem_device->start_addr = address64.min_address_range; - mem_device->end_addr = address64.max_address_range; + mem_device->start_addr = address64.minimum; + mem_device->end_addr = address64.maximum; } } diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 83ae1c1aa286..2cc53da5c0bd 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -177,7 +177,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, if (!op) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null Op\n")); - return_VALUE(TRUE); + return_UINT8(TRUE); } /* @@ -208,7 +208,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, "At Method level, result of [%s] not used\n", acpi_ps_get_opcode_name(op->common. aml_opcode))); - return_VALUE(FALSE); + return_UINT8(FALSE); } /* Get info on the parent. The root_op is AML_SCOPE */ @@ -218,7 +218,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, if (parent_info->class == AML_CLASS_UNKNOWN) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op)); - return_VALUE(FALSE); + return_UINT8(FALSE); } /* @@ -304,7 +304,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, acpi_ps_get_opcode_name(op->common.parent->common. aml_opcode), op)); - return_VALUE(TRUE); + return_UINT8(TRUE); result_not_used: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, @@ -313,7 +313,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, acpi_ps_get_opcode_name(op->common.parent->common. aml_opcode), op)); - return_VALUE(FALSE); + return_UINT8(FALSE); } /******************************************************************************* @@ -616,7 +616,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, if (op_info->flags & AML_HAS_RETVAL) { ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Argument previously created, already stacked \n")); + "Argument previously created, already stacked\n")); ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object (walk_state-> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index c33bfba5df8f..0ecbfa5db1ba 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1151,7 +1151,7 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context) union acpi_ec *ec = (union acpi_ec *)context; struct acpi_generic_address *addr; - if (resource->type != ACPI_RSTYPE_IO) { + if (resource->type != ACPI_RESOURCE_TYPE_IO) { return AE_OK; } @@ -1171,7 +1171,7 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context) addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; addr->register_bit_width = 8; addr->register_bit_offset = 0; - addr->address = resource->data.io.min_base_address; + addr->address = resource->data.io.minimum; return AE_OK; } diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index b2f232df13d8..f51c3b16c608 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -600,7 +600,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number)); - return_VALUE(ACPI_INTERRUPT_NOT_HANDLED); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } } @@ -638,7 +638,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number)); - return_VALUE(ACPI_INTERRUPT_NOT_HANDLED); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } } break; @@ -652,7 +652,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) status = acpi_ev_disable_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n", acpi_format_exception(status), gpe_number)); - return_VALUE(ACPI_INTERRUPT_NOT_HANDLED); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } /* @@ -680,12 +680,12 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) status = acpi_ev_disable_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n", acpi_format_exception(status), gpe_number)); - return_VALUE(ACPI_INTERRUPT_NOT_HANDLED); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } break; } - return_VALUE(ACPI_INTERRUPT_HANDLED); + return_UINT32(ACPI_INTERRUPT_HANDLED); } #ifdef ACPI_GPE_NOTIFY_CHECK diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c index 141835977002..e2c0b48a7e9f 100644 --- a/drivers/acpi/events/evsci.c +++ b/drivers/acpi/events/evsci.c @@ -88,7 +88,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) */ interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); - return_VALUE(interrupt_handled); + return_UINT32(interrupt_handled); } /******************************************************************************* @@ -121,7 +121,7 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context) */ interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); - return_VALUE(interrupt_handled); + return_UINT32(interrupt_handled); } /****************************************************************************** diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index bc2fa996047e..4477a62fed56 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -214,7 +214,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case ACPI_TYPE_BUFFER: - acpi_os_printf("Buffer len %X @ %p \n", + acpi_os_printf("Buffer len %X @ %p\n", obj_desc->buffer.length, obj_desc->buffer.pointer); @@ -320,17 +320,17 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case ACPI_TYPE_BUFFER_FIELD: - acpi_os_printf("buffer_field: %X bits at byte %X bit %X of \n", + acpi_os_printf("buffer_field: %X bits at byte %X bit %X of\n", obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset, obj_desc->buffer_field.start_field_bit_offset); if (!obj_desc->buffer_field.buffer_obj) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL* \n")); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n")); } else if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj) != ACPI_TYPE_BUFFER) { - acpi_os_printf("*not a Buffer* \n"); + acpi_os_printf("*not a Buffer*\n"); } else { acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj, depth + 1); @@ -618,7 +618,7 @@ acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index) case ACPI_TYPE_PACKAGE: - acpi_os_printf("[Package] Contains %d Elements: \n", + acpi_os_printf("[Package] Contains %d Elements:\n", obj_desc->package.count); for (i = 0; i < obj_desc->package.count; i++) { diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c index 239d8473e9a5..dff41121a304 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/executer/exnames.c @@ -191,10 +191,10 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) if (name_string) { ACPI_STRCAT(name_string, char_buf); ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "Appended to - %s \n", name_string)); + "Appended to - %s\n", name_string)); } else { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "No Name string - %s \n", char_buf)); + "No Name string - %s\n", char_buf)); } } else if (index == 0) { /* diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index 7476c363e407..88ccbf3b29d0 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c @@ -276,7 +276,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown field access type %X\n", access)); - return_VALUE(0); + return_UINT32(0); } if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) { @@ -289,7 +289,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, } *return_byte_alignment = byte_alignment; - return_VALUE(bit_length); + return_UINT32(bit_length); } /******************************************************************************* diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index ff064e79ab90..b04e4a3707a1 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c @@ -157,7 +157,7 @@ acpi_ex_resolve_operands(u16 opcode, } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Opcode %X [%s] required_operand_types=%8.8X \n", + "Opcode %X [%s] required_operand_types=%8.8X\n", opcode, op_info->name, arg_types)); /* diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index 1ee79d8c8f88..9f4e547d7734 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c @@ -206,7 +206,7 @@ u8 acpi_ex_acquire_global_lock(u32 field_flags) } } - return_VALUE(locked); + return_UINT8(locked); } /******************************************************************************* @@ -268,7 +268,7 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) /* acpi_integer is unsigned, so we don't worry about a '-' prefix */ if (value == 0) { - return_VALUE(1); + return_UINT32(1); } current_value = value; @@ -282,7 +282,7 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) num_digits++; } - return_VALUE(num_digits); + return_UINT32(num_digits); } /******************************************************************************* diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index fcb881db5b0b..8daef57b994c 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -99,15 +99,15 @@ do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) unsigned long *busnr = (unsigned long *)data; struct acpi_resource_address64 address; - if (resource->type != ACPI_RSTYPE_ADDRESS16 && - resource->type != ACPI_RSTYPE_ADDRESS32 && - resource->type != ACPI_RSTYPE_ADDRESS64) + if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && + resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && + resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) return AE_OK; acpi_resource_to_address64(resource, &address); if ((address.address_length > 0) && (address.resource_type == ACPI_BUS_NUMBER_RANGE)) - *busnr = address.min_address_range; + *busnr = address.minimum; return AE_OK; } diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c index 1bb3463d7040..20a335cc9bea 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/hardware/hwacpi.c @@ -204,18 +204,18 @@ u32 acpi_hw_get_mode(void) * system does not support mode transition. */ if (!acpi_gbl_FADT->smi_cmd) { - return_VALUE(ACPI_SYS_MODE_ACPI); + return_UINT32(ACPI_SYS_MODE_ACPI); } status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { - return_VALUE(ACPI_SYS_MODE_LEGACY); + return_UINT32(ACPI_SYS_MODE_LEGACY); } if (value) { - return_VALUE(ACPI_SYS_MODE_ACPI); + return_UINT32(ACPI_SYS_MODE_ACPI); } else { - return_VALUE(ACPI_SYS_MODE_LEGACY); + return_UINT32(ACPI_SYS_MODE_LEGACY); } } diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c index 85c1fb5c9a5a..468244147ec1 100644 --- a/drivers/acpi/motherboard.c +++ b/drivers/acpi/motherboard.c @@ -54,36 +54,36 @@ static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) ACPI_FUNCTION_TRACE("acpi_reserve_io_ranges"); - if (res->type == ACPI_RSTYPE_IO) { + if (res->type == ACPI_RESOURCE_TYPE_IO) { struct acpi_resource_io *io_res = &res->data.io; - if (io_res->min_base_address != io_res->max_base_address) + if (io_res->minimum != io_res->maximum) return_VALUE(AE_OK); if (IS_RESERVED_ADDR - (io_res->min_base_address, io_res->range_length)) { + (io_res->minimum, io_res->address_length)) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n", - io_res->min_base_address, - io_res->min_base_address + - io_res->range_length)); + io_res->minimum, + io_res->minimum + + io_res->address_length)); requested_res = - request_region(io_res->min_base_address, - io_res->range_length, "motherboard"); + request_region(io_res->minimum, + io_res->address_length, "motherboard"); } - } else if (res->type == ACPI_RSTYPE_FIXED_IO) { + } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_IO) { struct acpi_resource_fixed_io *fixed_io_res = &res->data.fixed_io; if (IS_RESERVED_ADDR - (fixed_io_res->base_address, fixed_io_res->range_length)) { + (fixed_io_res->address, fixed_io_res->address_length)) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n", - fixed_io_res->base_address, - fixed_io_res->base_address + - fixed_io_res->range_length)); + fixed_io_res->address, + fixed_io_res->address + + fixed_io_res->address_length)); requested_res = - request_region(fixed_io_res->base_address, - fixed_io_res->range_length, + request_region(fixed_io_res->address, + fixed_io_res->address_length, "motherboard"); } } else { diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index edfbe34600f5..6923059ba3c7 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c @@ -498,7 +498,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, path++; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "Multi Pathname (%d Segments, Flags=%X) \n", + "Multi Pathname (%d Segments, Flags=%X)\n", num_segments, flags)); break; diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index d5e8dea61c27..5400728eb791 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -241,7 +241,7 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle, acpi_ns_build_external_path(node, required_size, buffer->pointer); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X] \n", + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n", (char *)buffer->pointer, (u32) required_size)); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index ebec036423c9..549075fb9f88 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -249,10 +249,10 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) if (!node) { ACPI_REPORT_WARNING(("ns_get_type: Null Node input pointer\n")); - return_VALUE(ACPI_TYPE_ANY); + return_UINT32(ACPI_TYPE_ANY); } - return_VALUE((acpi_object_type) node->type); + return_UINT32((acpi_object_type) node->type); } /******************************************************************************* @@ -276,10 +276,10 @@ u32 acpi_ns_local(acpi_object_type type) /* Type code out of range */ ACPI_REPORT_WARNING(("ns_local: Invalid Object Type\n")); - return_VALUE(ACPI_NS_NORMAL); + return_UINT32(ACPI_NS_NORMAL); } - return_VALUE((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); + return_UINT32((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); } /******************************************************************************* @@ -805,10 +805,10 @@ u32 acpi_ns_opens_scope(acpi_object_type type) ACPI_REPORT_WARNING(("ns_opens_scope: Invalid Object Type %X\n", type)); - return_VALUE(ACPI_NS_NORMAL); + return_UINT32(ACPI_NS_NORMAL); } - return_VALUE(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE); + return_UINT32(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE); } /******************************************************************************* diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 5858188f94a6..562d0f822ab1 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -116,7 +116,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) break; } - return_VALUE(length); + return_UINT32(length); } /******************************************************************************* diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 4dcbd443160e..4c426f4c6af6 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -50,11 +50,145 @@ ACPI_MODULE_NAME("psxface") /* Local Prototypes */ +static void acpi_ps_start_trace(struct acpi_parameter_info *info); + +static void acpi_ps_stop_trace(struct acpi_parameter_info *info); + static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info); static void acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action); +/******************************************************************************* + * + * FUNCTION: acpi_debug_trace + * + * PARAMETERS: method_name - Valid ACPI name string + * debug_level - Optional level mask. 0 to use default + * debug_layer - Optional layer mask. 0 to use default + * Flags - bit 1: one shot(1) or persistent(0) + * + * RETURN: Status + * + * DESCRIPTION: External interface to enable debug tracing during control + * method execution + * + ******************************************************************************/ + +acpi_status +acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags) +{ + acpi_status status; + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* TBDs: Validate name, allow full path or just nameseg */ + + acpi_gbl_trace_method_name = *(u32 *) name; + acpi_gbl_trace_flags = flags; + + if (debug_level) { + acpi_gbl_trace_dbg_level = debug_level; + } + if (debug_layer) { + acpi_gbl_trace_dbg_layer = debug_layer; + } + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ps_start_trace + * + * PARAMETERS: Info - Method info struct + * + * RETURN: None + * + * DESCRIPTION: Start control method execution trace + * + ******************************************************************************/ + +static void acpi_ps_start_trace(struct acpi_parameter_info *info) +{ + acpi_status status; + + ACPI_FUNCTION_ENTRY(); + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return; + } + + if ((!acpi_gbl_trace_method_name) || + (acpi_gbl_trace_method_name != info->node->name.integer)) { + goto exit; + } + + acpi_gbl_original_dbg_level = acpi_dbg_level; + acpi_gbl_original_dbg_layer = acpi_dbg_layer; + + acpi_dbg_level = 0x00FFFFFF; + acpi_dbg_layer = ACPI_UINT32_MAX; + + if (acpi_gbl_trace_dbg_level) { + acpi_dbg_level = acpi_gbl_trace_dbg_level; + } + if (acpi_gbl_trace_dbg_layer) { + acpi_dbg_layer = acpi_gbl_trace_dbg_layer; + } + + exit: + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ps_stop_trace + * + * PARAMETERS: Info - Method info struct + * + * RETURN: None + * + * DESCRIPTION: Stop control method execution trace + * + ******************************************************************************/ + +static void acpi_ps_stop_trace(struct acpi_parameter_info *info) +{ + acpi_status status; + + ACPI_FUNCTION_ENTRY(); + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return; + } + + if ((!acpi_gbl_trace_method_name) || + (acpi_gbl_trace_method_name != info->node->name.integer)) { + goto exit; + } + + /* Disable further tracing if type is one-shot */ + + if (acpi_gbl_trace_flags & 1) { + acpi_gbl_trace_method_name = 0; + acpi_gbl_trace_dbg_level = 0; + acpi_gbl_trace_dbg_layer = 0; + } + + acpi_dbg_level = acpi_gbl_original_dbg_level; + acpi_dbg_layer = acpi_gbl_original_dbg_layer; + + exit: + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); +} + /******************************************************************************* * * FUNCTION: acpi_ps_execute_method @@ -104,6 +238,10 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) */ acpi_ps_update_parameter_list(info, REF_INCREMENT); + /* Begin tracing if requested */ + + acpi_ps_start_trace(info); + /* * 1) Perform the first pass parse of the method to enter any * named objects that it creates into the namespace @@ -129,6 +267,10 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) status = acpi_ps_execute_pass(info); cleanup: + /* End optional tracing */ + + acpi_ps_stop_trace(info); + /* Take away the extra reference that we gave the parameters above */ acpi_ps_update_parameter_list(info, REF_DECREMENT); diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 09567c2edcfb..726dda1fce1c 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -258,7 +258,7 @@ typedef int (*irq_lookup_func) (struct acpi_prt_entry *, int *, int *, char **); static int acpi_pci_allocate_irq(struct acpi_prt_entry *entry, - int *edge_level, int *active_high_low, char **link) + int *triggering, int *polarity, char **link) { int irq; @@ -266,8 +266,8 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry, if (entry->link.handle) { irq = acpi_pci_link_allocate_irq(entry->link.handle, - entry->link.index, edge_level, - active_high_low, link); + entry->link.index, triggering, + polarity, link); if (irq < 0) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n")); @@ -275,8 +275,8 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry, } } else { irq = entry->link.index; - *edge_level = ACPI_LEVEL_SENSITIVE; - *active_high_low = ACPI_ACTIVE_LOW; + *triggering = ACPI_LEVEL_SENSITIVE; + *polarity = ACPI_ACTIVE_LOW; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq)); @@ -285,7 +285,7 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry, static int acpi_pci_free_irq(struct acpi_prt_entry *entry, - int *edge_level, int *active_high_low, char **link) + int *triggering, int *polarity, char **link) { int irq; @@ -307,8 +307,8 @@ static int acpi_pci_irq_lookup(struct pci_bus *bus, int device, int pin, - int *edge_level, - int *active_high_low, char **link, irq_lookup_func func) + int *triggering, + int *polarity, char **link, irq_lookup_func func) { struct acpi_prt_entry *entry = NULL; int segment = pci_domain_nr(bus); @@ -327,7 +327,7 @@ acpi_pci_irq_lookup(struct pci_bus *bus, return_VALUE(-1); } - ret = func(entry, edge_level, active_high_low, link); + ret = func(entry, triggering, polarity, link); return_VALUE(ret); } @@ -339,8 +339,8 @@ acpi_pci_irq_lookup(struct pci_bus *bus, static int acpi_pci_irq_derive(struct pci_dev *dev, int pin, - int *edge_level, - int *active_high_low, char **link, irq_lookup_func func) + int *triggering, + int *polarity, char **link, irq_lookup_func func) { struct pci_dev *bridge = dev; int irq = -1; @@ -375,7 +375,7 @@ acpi_pci_irq_derive(struct pci_dev *dev, } irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), - pin, edge_level, active_high_low, + pin, triggering, polarity, link, func); } @@ -402,8 +402,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev) { int irq = 0; u8 pin = 0; - int edge_level = ACPI_LEVEL_SENSITIVE; - int active_high_low = ACPI_ACTIVE_LOW; + int triggering = ACPI_LEVEL_SENSITIVE; + int polarity = ACPI_ACTIVE_LOW; char *link = NULL; int rc; @@ -432,7 +432,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) * values override any BIOS-assigned IRQs set during boot. */ irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, - &edge_level, &active_high_low, &link, + &triggering, &polarity, &link, acpi_pci_allocate_irq); /* @@ -440,8 +440,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev) * device's parent bridge. */ if (irq < 0) - irq = acpi_pci_irq_derive(dev, pin, &edge_level, - &active_high_low, &link, + irq = acpi_pci_irq_derive(dev, pin, &triggering, + &polarity, &link, acpi_pci_allocate_irq); /* @@ -463,7 +463,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) } } - rc = acpi_register_gsi(irq, edge_level, active_high_low); + rc = acpi_register_gsi(irq, triggering, polarity); if (rc < 0) { printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: failed " "to register GSI\n", pci_name(dev), ('A' + pin)); @@ -478,8 +478,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev) printk("Link [%s] -> ", link); printk("GSI %u (%s, %s) -> IRQ %d\n", irq, - (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", - (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); + (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", + (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); return_VALUE(0); } @@ -495,8 +495,8 @@ void acpi_pci_irq_disable(struct pci_dev *dev) { int gsi = 0; u8 pin = 0; - int edge_level = ACPI_LEVEL_SENSITIVE; - int active_high_low = ACPI_ACTIVE_LOW; + int triggering = ACPI_LEVEL_SENSITIVE; + int polarity = ACPI_ACTIVE_LOW; ACPI_FUNCTION_TRACE("acpi_pci_irq_disable"); @@ -512,7 +512,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev) * First we check the PCI IRQ routing table (PRT) for an IRQ. */ gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, - &edge_level, &active_high_low, NULL, + &triggering, &polarity, NULL, acpi_pci_free_irq); /* * If no PRT entry was found, we'll try to derive an IRQ from the @@ -520,7 +520,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev) */ if (gsi < 0) gsi = acpi_pci_irq_derive(dev, pin, - &edge_level, &active_high_low, NULL, + &triggering, &polarity, NULL, acpi_pci_free_irq); if (gsi < 0) return_VOID; diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index d8956c0bf143..492170373494 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -70,8 +70,8 @@ static struct acpi_driver acpi_pci_link_driver = { */ struct acpi_pci_link_irq { u8 active; /* Current IRQ */ - u8 edge_level; /* All IRQs */ - u8 active_high_low; /* All IRQs */ + u8 triggering; /* All IRQs */ + u8 polarity; /* All IRQs */ u8 resource_type; u8 possible_count; u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; @@ -109,18 +109,18 @@ acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible"); switch (resource->type) { - case ACPI_RSTYPE_START_DPF: + case ACPI_RESOURCE_TYPE_START_DEPENDENT: return_ACPI_STATUS(AE_OK); - case ACPI_RSTYPE_IRQ: + case ACPI_RESOURCE_TYPE_IRQ: { struct acpi_resource_irq *p = &resource->data.irq; - if (!p || !p->number_of_interrupts) { + if (!p || !p->interrupt_count) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n")); return_ACPI_STATUS(AE_OK); } for (i = 0; - (i < p->number_of_interrupts + (i < p->interrupt_count && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) { if (!p->interrupts[i]) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, @@ -131,22 +131,22 @@ acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) link->irq.possible[i] = p->interrupts[i]; link->irq.possible_count++; } - link->irq.edge_level = p->edge_level; - link->irq.active_high_low = p->active_high_low; - link->irq.resource_type = ACPI_RSTYPE_IRQ; + link->irq.triggering = p->triggering; + link->irq.polarity = p->polarity; + link->irq.resource_type = ACPI_RESOURCE_TYPE_IRQ; break; } - case ACPI_RSTYPE_EXT_IRQ: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: { - struct acpi_resource_ext_irq *p = + struct acpi_resource_extended_irq *p = &resource->data.extended_irq; - if (!p || !p->number_of_interrupts) { + if (!p || !p->interrupt_count) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank EXT IRQ resource\n")); return_ACPI_STATUS(AE_OK); } for (i = 0; - (i < p->number_of_interrupts + (i < p->interrupt_count && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) { if (!p->interrupts[i]) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, @@ -157,9 +157,9 @@ acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) link->irq.possible[i] = p->interrupts[i]; link->irq.possible_count++; } - link->irq.edge_level = p->edge_level; - link->irq.active_high_low = p->active_high_low; - link->irq.resource_type = ACPI_RSTYPE_EXT_IRQ; + link->irq.triggering = p->triggering; + link->irq.polarity = p->polarity; + link->irq.resource_type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; break; } default: @@ -202,10 +202,10 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context) ACPI_FUNCTION_TRACE("acpi_pci_link_check_current"); switch (resource->type) { - case ACPI_RSTYPE_IRQ: + case ACPI_RESOURCE_TYPE_IRQ: { struct acpi_resource_irq *p = &resource->data.irq; - if (!p || !p->number_of_interrupts) { + if (!p || !p->interrupt_count) { /* * IRQ descriptors may have no IRQ# bits set, * particularly those those w/ _STA disabled @@ -217,11 +217,11 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context) *irq = p->interrupts[0]; break; } - case ACPI_RSTYPE_EXT_IRQ: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: { - struct acpi_resource_ext_irq *p = + struct acpi_resource_extended_irq *p = &resource->data.extended_irq; - if (!p || !p->number_of_interrupts) { + if (!p || !p->interrupt_count) { /* * extended IRQ descriptors must * return at least 1 IRQ @@ -325,36 +325,36 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) buffer.pointer = resource; switch (link->irq.resource_type) { - case ACPI_RSTYPE_IRQ: - resource->res.type = ACPI_RSTYPE_IRQ; + case ACPI_RESOURCE_TYPE_IRQ: + resource->res.type = ACPI_RESOURCE_TYPE_IRQ; resource->res.length = sizeof(struct acpi_resource); - resource->res.data.irq.edge_level = link->irq.edge_level; - resource->res.data.irq.active_high_low = - link->irq.active_high_low; - if (link->irq.edge_level == ACPI_EDGE_SENSITIVE) - resource->res.data.irq.shared_exclusive = + resource->res.data.irq.triggering = link->irq.triggering; + resource->res.data.irq.polarity = + link->irq.polarity; + if (link->irq.triggering == ACPI_EDGE_SENSITIVE) + resource->res.data.irq.sharable = ACPI_EXCLUSIVE; else - resource->res.data.irq.shared_exclusive = ACPI_SHARED; - resource->res.data.irq.number_of_interrupts = 1; + resource->res.data.irq.sharable = ACPI_SHARED; + resource->res.data.irq.interrupt_count = 1; resource->res.data.irq.interrupts[0] = irq; break; - case ACPI_RSTYPE_EXT_IRQ: - resource->res.type = ACPI_RSTYPE_EXT_IRQ; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + resource->res.type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; resource->res.length = sizeof(struct acpi_resource); resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER; - resource->res.data.extended_irq.edge_level = - link->irq.edge_level; - resource->res.data.extended_irq.active_high_low = - link->irq.active_high_low; - if (link->irq.edge_level == ACPI_EDGE_SENSITIVE) - resource->res.data.irq.shared_exclusive = + resource->res.data.extended_irq.triggering = + link->irq.triggering; + resource->res.data.extended_irq.polarity = + link->irq.polarity; + if (link->irq.triggering == ACPI_EDGE_SENSITIVE) + resource->res.data.irq.sharable = ACPI_EXCLUSIVE; else - resource->res.data.irq.shared_exclusive = ACPI_SHARED; - resource->res.data.extended_irq.number_of_interrupts = 1; + resource->res.data.irq.sharable = ACPI_SHARED; + resource->res.data.extended_irq.interrupt_count = 1; resource->res.data.extended_irq.interrupts[0] = irq; /* ignore resource_source, it's optional */ break; @@ -364,7 +364,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) goto end; } - resource->end.type = ACPI_RSTYPE_END_TAG; + resource->end.type = ACPI_RESOURCE_TYPE_END_TAG; /* Attempt to set the resource */ status = acpi_set_current_resources(link->handle, &buffer); @@ -613,7 +613,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) int acpi_pci_link_allocate_irq(acpi_handle handle, int index, - int *edge_level, int *active_high_low, char **name) + int *triggering, int *polarity, char **name) { int result = 0; struct acpi_device *device = NULL; @@ -653,10 +653,10 @@ acpi_pci_link_allocate_irq(acpi_handle handle, link->refcnt++; up(&acpi_link_lock); - if (edge_level) - *edge_level = link->irq.edge_level; - if (active_high_low) - *active_high_low = link->irq.active_high_low; + if (triggering) + *triggering = link->irq.triggering; + if (polarity) + *polarity = link->irq.polarity; if (name) *name = acpi_device_bid(link->device); ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 5d6bc815fe72..4c313eab6313 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -122,15 +122,15 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) int *busnr = (int *)data; struct acpi_resource_address64 address; - if (resource->type != ACPI_RSTYPE_ADDRESS16 && - resource->type != ACPI_RSTYPE_ADDRESS32 && - resource->type != ACPI_RSTYPE_ADDRESS64) + if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && + resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && + resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) return AE_OK; acpi_resource_to_address64(resource, &address); if ((address.address_length > 0) && (address.resource_type == ACPI_BUS_NUMBER_RANGE)) - *busnr = address.min_address_range; + *busnr = address.minimum; return AE_OK; } diff --git a/drivers/acpi/resources/Makefile b/drivers/acpi/resources/Makefile index 2130b74170c3..8de4f69dfa09 100644 --- a/drivers/acpi/resources/Makefile +++ b/drivers/acpi/resources/Makefile @@ -2,7 +2,7 @@ # Makefile for all Linux ACPI interpreter subdirectories # -obj-y := rsaddr.o rscreate.o rsio.o rslist.o rsmisc.o rsxface.o \ +obj-y := rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ rscalc.o rsirq.o rsmemory.o rsutils.o obj-$(ACPI_FUTURE_USAGE) += rsdump.o diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 798778261fb9..6f48ebf3304e 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c @@ -58,12 +58,20 @@ acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags); static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource); +static void +acpi_rs_set_address_common(union aml_resource *aml, + struct acpi_resource *resource); + +static u8 +acpi_rs_get_address_common(struct acpi_resource *resource, + union aml_resource *aml); + /******************************************************************************* * * FUNCTION: acpi_rs_decode_general_flags * * PARAMETERS: Resource - Address resource data struct - * Flags - Actual flag byte + * Flags - Raw AML flag byte * * RETURN: Decoded flag bits in resource struct * @@ -107,27 +115,19 @@ acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags) static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) { - u8 flags; - ACPI_FUNCTION_ENTRY(); - /* Producer / Consumer - flag bit[0] */ + return ((u8) - flags = (u8) (resource->address.producer_consumer & 0x01); - - /* Decode (_DEC) - flag bit[1] */ - - flags |= (u8) ((resource->address.decode & 0x01) << 1); - - /* Min Address Fixed (_MIF) - flag bit[2] */ - - flags |= (u8) ((resource->address.min_address_fixed & 0x01) << 2); - - /* Max Address Fixed (_MAF) - flag bit[3] */ - - flags |= (u8) ((resource->address.max_address_fixed & 0x01) << 3); - - return (flags); + /* Producer / Consumer - flag bit[0] */ + ((resource->address.producer_consumer & 0x01) | + /* Decode (_DEC) - flag bit[1] */ + ((resource->address.decode & 0x01) << 1) | + /* Min Address Fixed (_MIF) - flag bit[2] */ + ((resource->address.min_address_fixed & 0x01) << 2) | + /* Max Address Fixed (_MAF) - flag bit[3] */ + ((resource->address.max_address_fixed & 0x01) << 3)) + ); } /******************************************************************************* @@ -135,7 +135,7 @@ static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) * FUNCTION: acpi_rs_decode_specific_flags * * PARAMETERS: Resource - Address resource data struct - * Flags - Actual flag byte + * Flags - Raw AML flag byte * * RETURN: Decoded flag bits in attribute struct * @@ -189,921 +189,541 @@ acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags) static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) { - u8 flags = 0; - ACPI_FUNCTION_ENTRY(); if (resource->address.resource_type == ACPI_MEMORY_RANGE) { - /* Write Status (_RW) - flag bit[0] */ + return ((u8) - flags = (u8) - (resource->address.attribute.memory. - read_write_attribute & 0x01); - - /* Memory Attributes (_MEM) - flag bits[2:1] */ - - flags |= (u8) - ((resource->address.attribute.memory. - cache_attribute & 0x03) << 1); + /* Write Status (_RW) - flag bit[0] */ + ((resource->address.attribute.memory. + read_write_attribute & 0x01) | + /* Memory Attributes (_MEM) - flag bits[2:1] */ + ((resource->address.attribute.memory. + cache_attribute & 0x03) << 1))); } else if (resource->address.resource_type == ACPI_IO_RANGE) { - /* Ranges (_RNG) - flag bits[1:0] */ + return ((u8) - flags = (u8) - (resource->address.attribute.io.range_attribute & 0x03); - - /* Translations (_TTP and _TRS) - flag bits[5:4] */ - - flags |= (u8) - ((resource->address.attribute.io. - translation_attribute & 0x03) << 4); + /* Ranges (_RNG) - flag bits[1:0] */ + ((resource->address.attribute.io. + range_attribute & 0x03) | + /* Translations (_TTP and _TRS) - flag bits[5:4] */ + ((resource->address.attribute.io. + translation_attribute & 0x03) << 4))); } - return (flags); + return (0); } /******************************************************************************* * - * FUNCTION: acpi_rs_address16_resource + * FUNCTION: acpi_rs_set_address_common * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * Resource - Pointer to the internal resource struct * - * RETURN: Status + * RETURN: None * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert common flag fields from a resource descriptor to an + * AML descriptor * ******************************************************************************/ -acpi_status -acpi_rs_address16_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +static void +acpi_rs_set_address_common(union aml_resource *aml, + struct acpi_resource *resource) { - u32 index; - u16 temp16; - u8 temp8; - u8 *temp_ptr; - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16); + ACPI_FUNCTION_ENTRY(); - ACPI_FUNCTION_TRACE("rs_address16_resource"); + /* Set the Resource Type (Memory, Io, bus_number, etc.) */ - /* Get the Descriptor Length field */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - /* Validate minimum descriptor length */ - - if (temp16 < 13) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - *bytes_consumed = temp16 + 3; - output_struct->type = ACPI_RSTYPE_ADDRESS16; - - /* Get the Resource Type (Byte3) */ - - buffer += 2; - temp8 = *buffer; - - /* Values 0-2 and 0xC0-0xFF are valid */ - - if ((temp8 > 2) && (temp8 < 0xC0)) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - output_struct->data.address16.resource_type = temp8; - - /* Get the General Flags (Byte4) */ - - buffer += 1; - acpi_rs_decode_general_flags(&output_struct->data, *buffer); - - /* Get the Type Specific Flags (Byte5) */ - - buffer += 1; - acpi_rs_decode_specific_flags(&output_struct->data, *buffer); - - /* Get Granularity (Bytes 6-7) */ - - buffer += 1; - ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer); - - /* Get min_address_range (Bytes 8-9) */ - - buffer += 2; - ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range, - buffer); - - /* Get max_address_range (Bytes 10-11) */ - - buffer += 2; - ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range, - buffer); - - /* Get address_translation_offset (Bytes 12-13) */ - - buffer += 2; - ACPI_MOVE_16_TO_32(&output_struct->data.address16. - address_translation_offset, buffer); - - /* Get address_length (Bytes 14-15) */ - - buffer += 2; - ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length, - buffer); - - /* Resource Source Index (if present) */ - - buffer += 2; - - /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. - */ - if (*bytes_consumed > (16 + 1)) { - /* Dereference the Index */ - - output_struct->data.address16.resource_source.index = - (u32) * buffer; - - /* Point to the String */ - - buffer += 1; - - /* Point the String pointer to the end of this structure */ - - output_struct->data.address16.resource_source.string_ptr = - (char *)((u8 *) output_struct + struct_size); - - temp_ptr = (u8 *) - output_struct->data.address16.resource_source.string_ptr; - - /* Copy the resource_source string into the buffer */ - - index = 0; - while (*buffer) { - *temp_ptr = *buffer; - - temp_ptr++; - buffer++; - index++; - } - - /* Add the terminating null and set the string length */ - - *temp_ptr = 0; - output_struct->data.address16.resource_source.string_length = - index + 1; - - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); - } else { - output_struct->data.address16.resource_source.index = 0; - output_struct->data.address16.resource_source.string_length = 0; - output_struct->data.address16.resource_source.string_ptr = NULL; - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_address16_stream - * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_address16_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u8 *length_field; - acpi_size actual_bytes; - - ACPI_FUNCTION_TRACE("rs_address16_stream"); - - /* Set the Descriptor Type field */ - - *buffer = ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE; - buffer += 1; - - /* Save a pointer to the Length field - to be filled in later */ - - length_field = buffer; - buffer += 2; - - /* Set the Resource Type (Memory, Io, bus_number) */ - - *buffer = (u8) (resource->data.address16.resource_type & 0x03); - buffer += 1; + aml->address.resource_type = (u8) resource->data.address.resource_type; /* Set the general flags */ - *buffer = acpi_rs_encode_general_flags(&resource->data); - buffer += 1; + aml->address.flags = acpi_rs_encode_general_flags(&resource->data); - /* Set the type specific flags */ + /* Set the type-specific flags */ - *buffer = acpi_rs_encode_specific_flags(&resource->data); - buffer += 1; - - /* Set the address space granularity */ - - ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.granularity); - buffer += 2; - - /* Set the address range minimum */ - - ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.min_address_range); - buffer += 2; - - /* Set the address range maximum */ - - ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.max_address_range); - buffer += 2; - - /* Set the address translation offset */ - - ACPI_MOVE_32_TO_16(buffer, - &resource->data.address16. - address_translation_offset); - buffer += 2; - - /* Set the address length */ - - ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.address_length); - buffer += 2; - - /* Resource Source Index and Resource Source are optional */ - - if (resource->data.address16.resource_source.string_length) { - *buffer = (u8) resource->data.address16.resource_source.index; - buffer += 1; - - /* Copy the resource_source string */ - - ACPI_STRCPY((char *)buffer, - resource->data.address16.resource_source. - string_ptr); - - /* - * Buffer needs to be set to the length of the string + one for the - * terminating null - */ - buffer += - (acpi_size) (ACPI_STRLEN - (resource->data.address16.resource_source. - string_ptr) + 1); - } - - /* Return the number of bytes consumed in this operation */ - - actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer); - *bytes_consumed = actual_bytes; - - /* - * Set the length field to the number of bytes consumed - * minus the header size (3 bytes) - */ - actual_bytes -= 3; - ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes); - return_ACPI_STATUS(AE_OK); + aml->address.specific_flags = + acpi_rs_encode_specific_flags(&resource->data); } /******************************************************************************* * - * FUNCTION: acpi_rs_address32_resource + * FUNCTION: acpi_rs_get_address_common * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Resource - Pointer to the internal resource struct + * Aml - Pointer to the AML resource descriptor + * + * RETURN: TRUE if the resource_type field is OK, FALSE otherwise + * + * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor + * to an internal resource descriptor + * + ******************************************************************************/ + +static u8 +acpi_rs_get_address_common(struct acpi_resource *resource, + union aml_resource *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* Validate resource type */ + + if ((aml->address.resource_type > 2) + && (aml->address.resource_type < 0xC0)) { + return (FALSE); + } + + /* Get the Resource Type (Memory, Io, bus_number, etc.) */ + + resource->data.address.resource_type = aml->address.resource_type; + + /* Get the General Flags */ + + acpi_rs_decode_general_flags(&resource->data, aml->address.flags); + + /* Get the Type-Specific Flags */ + + acpi_rs_decode_specific_flags(&resource->data, + aml->address.specific_flags); + return (TRUE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_address16 + * + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_address32_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_get_address16(union aml_resource * aml, + u16 aml_resource_length, struct acpi_resource * resource) { - u16 temp16; - u8 temp8; - u8 *temp_ptr; - u32 index; - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32); + ACPI_FUNCTION_TRACE("rs_get_address16"); - ACPI_FUNCTION_TRACE("rs_address32_resource"); + /* Get the Resource Type, general flags, and type-specific flags */ - /* Get the Descriptor Length field */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - /* Validate minimum descriptor length */ - - if (temp16 < 23) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - *bytes_consumed = temp16 + 3; - output_struct->type = ACPI_RSTYPE_ADDRESS32; - - /* Get the Resource Type (Byte3) */ - - buffer += 2; - temp8 = *buffer; - - /* Values 0-2 and 0xC0-0xFF are valid */ - - if ((temp8 > 2) && (temp8 < 0xC0)) { + if (!acpi_rs_get_address_common(resource, aml)) { return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } - output_struct->data.address32.resource_type = temp8; - - /* Get the General Flags (Byte4) */ - - buffer += 1; - acpi_rs_decode_general_flags(&output_struct->data, *buffer); - - /* Get the Type Specific Flags (Byte5) */ - - buffer += 1; - acpi_rs_decode_specific_flags(&output_struct->data, *buffer); - - /* Get Granularity (Bytes 6-9) */ - - buffer += 1; - ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer); - - /* Get min_address_range (Bytes 10-13) */ - - buffer += 4; - ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range, - buffer); - - /* Get max_address_range (Bytes 14-17) */ - - buffer += 4; - ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range, - buffer); - - /* Get address_translation_offset (Bytes 18-21) */ - - buffer += 4; - ACPI_MOVE_32_TO_32(&output_struct->data.address32. - address_translation_offset, buffer); - - /* Get address_length (Bytes 22-25) */ - - buffer += 4; - ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length, - buffer); - - /* Resource Source Index (if present) */ - - buffer += 4; - /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. + * Get the following contiguous fields from the AML descriptor: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length */ - if (*bytes_consumed > (26 + 1)) { - /* Dereference the Index */ + acpi_rs_move_data(&resource->data.address16.granularity, + &aml->address16.granularity, 5, + ACPI_MOVE_TYPE_16_TO_32); - output_struct->data.address32.resource_source.index = - (u32) * buffer; + /* Get the optional resource_source (index and string) */ - /* Point to the String */ + resource->length = + ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16) + + acpi_rs_get_resource_source(aml_resource_length, + sizeof(struct aml_resource_address16), + &resource->data.address16. + resource_source, aml, NULL); - buffer += 1; + /* Complete the resource header */ - /* Point the String pointer to the end of this structure */ - - output_struct->data.address32.resource_source.string_ptr = - (char *)((u8 *) output_struct + struct_size); - - temp_ptr = (u8 *) - output_struct->data.address32.resource_source.string_ptr; - - /* Copy the resource_source string into the buffer */ - - index = 0; - while (*buffer) { - *temp_ptr = *buffer; - - temp_ptr++; - buffer++; - index++; - } - - /* Add the terminating null and set the string length */ - - *temp_ptr = 0; - output_struct->data.address32.resource_source.string_length = - index + 1; - - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); - } else { - output_struct->data.address32.resource_source.index = 0; - output_struct->data.address32.resource_source.string_length = 0; - output_struct->data.address32.resource_source.string_ptr = NULL; - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_ADDRESS16; return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_address32_stream + * FUNCTION: acpi_rs_set_address16 * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_address32_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_set_address16(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer; - u16 *length_field; + acpi_size descriptor_length; - ACPI_FUNCTION_TRACE("rs_address32_stream"); + ACPI_FUNCTION_TRACE("rs_set_address16"); - buffer = *output_buffer; + /* Set the Resource Type, General Flags, and Type-Specific Flags */ - /* Set the Descriptor Type field */ + acpi_rs_set_address_common(aml, resource); - *buffer = ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE; - buffer += 1; - - /* Save a pointer to the Length field - to be filled in later */ - - length_field = ACPI_CAST_PTR(u16, buffer); - buffer += 2; - - /* Set the Resource Type (Memory, Io, bus_number) */ - - *buffer = (u8) (resource->data.address32.resource_type & 0x03); - buffer += 1; - - /* Set the general flags */ - - *buffer = acpi_rs_encode_general_flags(&resource->data); - buffer += 1; - - /* Set the type specific flags */ - - *buffer = acpi_rs_encode_specific_flags(&resource->data); - buffer += 1; - - /* Set the address space granularity */ - - ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.granularity); - buffer += 4; - - /* Set the address range minimum */ - - ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.min_address_range); - buffer += 4; - - /* Set the address range maximum */ - - ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.max_address_range); - buffer += 4; - - /* Set the address translation offset */ - - ACPI_MOVE_32_TO_32(buffer, - &resource->data.address32. - address_translation_offset); - buffer += 4; - - /* Set the address length */ - - ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.address_length); - buffer += 4; + /* + * Set the following contiguous fields in the AML descriptor: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + acpi_rs_move_data(&aml->address16.granularity, + &resource->data.address16.granularity, 5, + ACPI_MOVE_TYPE_32_TO_16); /* Resource Source Index and Resource Source are optional */ - if (resource->data.address32.resource_source.string_length) { - *buffer = (u8) resource->data.address32.resource_source.index; - buffer += 1; + descriptor_length = acpi_rs_set_resource_source(aml, + sizeof(struct + aml_resource_address16), + &resource->data. + address16. + resource_source); - /* Copy the resource_source string */ + /* Complete the AML descriptor header */ - ACPI_STRCPY((char *)buffer, - resource->data.address32.resource_source. - string_ptr); - - /* - * Buffer needs to be set to the length of the string + one for the - * terminating null - */ - buffer += - (acpi_size) (ACPI_STRLEN - (resource->data.address32.resource_source. - string_ptr) + 1); - } - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - - /* - * Set the length field to the number of bytes consumed - * minus the header size (3 bytes) - */ - *length_field = (u16) (*bytes_consumed - 3); + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS16, + descriptor_length, aml); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_address64_resource + * FUNCTION: acpi_rs_get_address32 * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_address64_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_get_address32(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u16 temp16; - u8 temp8; - u8 resource_type; - u8 *temp_ptr; - u32 index; - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64); - ACPI_FUNCTION_TRACE("rs_address64_resource"); + ACPI_FUNCTION_TRACE("rs_get_address32"); - /* Get the Descriptor Type */ + /* Get the Resource Type, general flags, and type-specific flags */ - resource_type = *buffer; - - /* Get the Descriptor Length field */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - /* Validate minimum descriptor length */ - - if (temp16 < 43) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - *bytes_consumed = temp16 + 3; - output_struct->type = ACPI_RSTYPE_ADDRESS64; - - /* Get the Resource Type (Byte3) */ - - buffer += 2; - temp8 = *buffer; - - /* Values 0-2 and 0xC0-0xFF are valid */ - - if ((temp8 > 2) && (temp8 < 0xC0)) { + if (!acpi_rs_get_address_common(resource, (void *)aml)) { return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } - output_struct->data.address64.resource_type = temp8; + /* + * Get the following contiguous fields from the AML descriptor: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + acpi_rs_move_data(&resource->data.address32.granularity, + &aml->address32.granularity, 5, + ACPI_MOVE_TYPE_32_TO_32); - /* Get the General Flags (Byte4) */ + /* Get the optional resource_source (index and string) */ - buffer += 1; - acpi_rs_decode_general_flags(&output_struct->data, *buffer); + resource->length = + ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32) + + acpi_rs_get_resource_source(aml_resource_length, + sizeof(struct aml_resource_address32), + &resource->data.address32. + resource_source, aml, NULL); - /* Get the Type Specific Flags (Byte5) */ + /* Complete the resource header */ - buffer += 1; - acpi_rs_decode_specific_flags(&output_struct->data, *buffer); - - if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { - /* Move past revision_id and Reserved byte */ - - buffer += 2; - } - - /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */ - - buffer += 1; - ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer); - - /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range, - buffer); - - /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range, - buffer); - - /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64. - address_translation_offset, buffer); - - /* Get address_length (Bytes 38-45) or (Bytes 40-47) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length, - buffer); - - output_struct->data.address64.resource_source.index = 0; - output_struct->data.address64.resource_source.string_length = 0; - output_struct->data.address64.resource_source.string_ptr = NULL; - - if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { - /* Get type_specific_attribute (Bytes 48-55) */ - - buffer += 8; - ACPI_MOVE_64_TO_64(&output_struct->data.address64. - type_specific_attributes, buffer); - } else { - output_struct->data.address64.type_specific_attributes = 0; - - /* Resource Source Index (if present) */ - - buffer += 8; - - /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. - */ - if (*bytes_consumed > (46 + 1)) { - /* Dereference the Index */ - - output_struct->data.address64.resource_source.index = - (u32) * buffer; - - /* Point to the String */ - - buffer += 1; - - /* Point the String pointer to the end of this structure */ - - output_struct->data.address64.resource_source. - string_ptr = - (char *)((u8 *) output_struct + struct_size); - - temp_ptr = (u8 *) - output_struct->data.address64.resource_source. - string_ptr; - - /* Copy the resource_source string into the buffer */ - - index = 0; - while (*buffer) { - *temp_ptr = *buffer; - - temp_ptr++; - buffer++; - index++; - } - - /* - * Add the terminating null and set the string length - */ - *temp_ptr = 0; - output_struct->data.address64.resource_source. - string_length = index + 1; - - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); - } - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_ADDRESS32; return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_address64_stream + * FUNCTION: acpi_rs_set_address32 * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_address64_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_set_address32(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer; - u16 *length_field; + acpi_size descriptor_length; - ACPI_FUNCTION_TRACE("rs_address64_stream"); + ACPI_FUNCTION_TRACE("rs_set_address32"); - buffer = *output_buffer; + /* Set the Resource Type, General Flags, and Type-Specific Flags */ - /* Set the Descriptor Type field */ + acpi_rs_set_address_common(aml, resource); - *buffer = ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE; - buffer += 1; - - /* Save a pointer to the Length field - to be filled in later */ - - length_field = ACPI_CAST_PTR(u16, buffer); - buffer += 2; - - /* Set the Resource Type (Memory, Io, bus_number) */ - - *buffer = (u8) (resource->data.address64.resource_type & 0x03); - buffer += 1; - - /* Set the general flags */ - - *buffer = acpi_rs_encode_general_flags(&resource->data); - buffer += 1; - - /* Set the type specific flags */ - - *buffer = acpi_rs_encode_specific_flags(&resource->data); - buffer += 1; - - /* Set the address space granularity */ - - ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.granularity); - buffer += 8; - - /* Set the address range minimum */ - - ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.min_address_range); - buffer += 8; - - /* Set the address range maximum */ - - ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.max_address_range); - buffer += 8; - - /* Set the address translation offset */ - - ACPI_MOVE_64_TO_64(buffer, - &resource->data.address64. - address_translation_offset); - buffer += 8; - - /* Set the address length */ - - ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.address_length); - buffer += 8; + /* + * Set the following contiguous fields in the AML descriptor: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + acpi_rs_move_data(&aml->address32.granularity, + &resource->data.address32.granularity, 5, + ACPI_MOVE_TYPE_32_TO_32); /* Resource Source Index and Resource Source are optional */ - if (resource->data.address64.resource_source.string_length) { - *buffer = (u8) resource->data.address64.resource_source.index; - buffer += 1; + descriptor_length = acpi_rs_set_resource_source(aml, + sizeof(struct + aml_resource_address32), + &resource->data. + address32. + resource_source); - /* Copy the resource_source string */ + /* Complete the AML descriptor header */ - ACPI_STRCPY((char *)buffer, - resource->data.address64.resource_source. - string_ptr); - - /* - * Buffer needs to be set to the length of the string + one for the - * terminating null - */ - buffer += - (acpi_size) (ACPI_STRLEN - (resource->data.address64.resource_source. - string_ptr) + 1); - } - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - - /* - * Set the length field to the number of bytes consumed - * minus the header size (3 bytes) - */ - *length_field = (u16) (*bytes_consumed - 3); + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS32, + descriptor_length, aml); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_address64 + * + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. + * + ******************************************************************************/ + +acpi_status +acpi_rs_get_address64(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) +{ + ACPI_FUNCTION_TRACE("rs_get_address64"); + + /* Get the Resource Type, general Flags, and type-specific Flags */ + + if (!acpi_rs_get_address_common(resource, aml)) { + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + } + + /* + * Get the following contiguous fields from the AML descriptor: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + acpi_rs_move_data(&resource->data.address64.granularity, + &aml->address64.granularity, 5, + ACPI_MOVE_TYPE_64_TO_64); + + /* Get the optional resource_source (index and string) */ + + resource->length = + ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64) + + acpi_rs_get_resource_source(aml_resource_length, + sizeof(struct aml_resource_address64), + &resource->data.address64. + resource_source, aml, NULL); + + /* Complete the resource header */ + + resource->type = ACPI_RESOURCE_TYPE_ADDRESS64; + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_address64 + * + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. + * + ******************************************************************************/ + +acpi_status +acpi_rs_set_address64(struct acpi_resource *resource, union aml_resource *aml) +{ + acpi_size descriptor_length; + + ACPI_FUNCTION_TRACE("rs_set_address64"); + + /* Set the Resource Type, General Flags, and Type-Specific Flags */ + + acpi_rs_set_address_common(aml, resource); + + /* + * Set the following contiguous fields in the AML descriptor: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + acpi_rs_move_data(&aml->address64.granularity, + &resource->data.address64.granularity, 5, + ACPI_MOVE_TYPE_64_TO_64); + + /* Resource Source Index and Resource Source are optional */ + + descriptor_length = acpi_rs_set_resource_source(aml, + sizeof(struct + aml_resource_address64), + &resource->data. + address64. + resource_source); + + /* Complete the AML descriptor header */ + + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS64, + descriptor_length, aml); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_ext_address64 + * + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. + * + ******************************************************************************/ + +acpi_status +acpi_rs_get_ext_address64(union aml_resource *aml, + u16 aml_resource_length, + struct acpi_resource *resource) +{ + + ACPI_FUNCTION_TRACE("rs_get_ext_address64"); + + /* Get the Resource Type, general flags, and type-specific flags */ + + if (!acpi_rs_get_address_common(resource, aml)) { + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + } + + /* + * Get and validate the Revision ID + * Note: Only one revision ID is currently supported + */ + resource->data.ext_address64.revision_iD = + aml->ext_address64.revision_iD; + if (aml->ext_address64.revision_iD != + AML_RESOURCE_EXTENDED_ADDRESS_REVISION) { + return_ACPI_STATUS(AE_SUPPORT); + } + + /* + * Get the following contiguous fields from the AML descriptor: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + * Type-Specific Attribute + */ + acpi_rs_move_data(&resource->data.ext_address64.granularity, + &aml->ext_address64.granularity, 6, + ACPI_MOVE_TYPE_64_TO_64); + + /* Complete the resource header */ + + resource->type = ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64; + resource->length = + ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_address64); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_ext_address64 + * + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. + * + ******************************************************************************/ + +acpi_status +acpi_rs_set_ext_address64(struct acpi_resource *resource, + union aml_resource *aml) +{ + ACPI_FUNCTION_TRACE("rs_set_ext_address64"); + + /* Set the Resource Type, General Flags, and Type-Specific Flags */ + + acpi_rs_set_address_common(aml, resource); + + /* Only one Revision ID is currently supported */ + + aml->ext_address64.revision_iD = AML_RESOURCE_EXTENDED_ADDRESS_REVISION; + aml->ext_address64.reserved = 0; + + /* + * Set the following contiguous fields in the AML descriptor: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + * Type-Specific Attribute + */ + acpi_rs_move_data(&aml->ext_address64.granularity, + &resource->data.address64.granularity, 6, + ACPI_MOVE_TYPE_64_TO_64); + + /* Complete the AML descriptor header */ + + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, + sizeof(struct + aml_resource_extended_address64), + aml); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 2da7c6a8182e..d170dee07ce9 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -44,87 +44,14 @@ #include #include #include -#include #include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rscalc") -/* - * Base sizes for external resource descriptors, indexed by internal type. - * Includes size of the descriptor header (1 byte for small descriptors, - * 3 bytes for large descriptors) - */ -static u8 acpi_gbl_stream_sizes[] = { - 4, /* ACPI_RSTYPE_IRQ (Byte 3 is optional, but always created) */ - 3, /* ACPI_RSTYPE_DMA */ - 2, /* ACPI_RSTYPE_START_DPF (Byte 1 is optional, but always created) */ - 1, /* ACPI_RSTYPE_END_DPF */ - 8, /* ACPI_RSTYPE_IO */ - 4, /* ACPI_RSTYPE_FIXED_IO */ - 1, /* ACPI_RSTYPE_VENDOR */ - 2, /* ACPI_RSTYPE_END_TAG */ - 12, /* ACPI_RSTYPE_MEM24 */ - 20, /* ACPI_RSTYPE_MEM32 */ - 12, /* ACPI_RSTYPE_FIXED_MEM32 */ - 16, /* ACPI_RSTYPE_ADDRESS16 */ - 26, /* ACPI_RSTYPE_ADDRESS32 */ - 46, /* ACPI_RSTYPE_ADDRESS64 */ - 9, /* ACPI_RSTYPE_EXT_IRQ */ - 15 /* ACPI_RSTYPE_GENERIC_REG */ -}; - -/* - * Base sizes of resource descriptors, both the actual AML stream length and - * size of the internal struct representation. - */ -struct acpi_resource_sizes { - u8 minimum_stream_size; - u8 minimum_struct_size; -}; - -static struct acpi_resource_sizes acpi_gbl_sm_resource_sizes[] = { - {0, 0}, /* 0x00, Reserved */ - {0, 0}, /* 0x01, Reserved */ - {0, 0}, /* 0x02, Reserved */ - {0, 0}, /* 0x03, Reserved */ - {3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq)}, /* ACPI_RDESC_TYPE_IRQ_FORMAT */ - {3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma)}, /* ACPI_RDESC_TYPE_DMA_FORMAT */ - {1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf)}, /* ACPI_RDESC_TYPE_START_DEPENDENT */ - {1, ACPI_RESOURCE_LENGTH}, /* ACPI_RDESC_TYPE_END_DEPENDENT */ - {8, ACPI_SIZEOF_RESOURCE(struct acpi_resource_io)}, /* ACPI_RDESC_TYPE_IO_PORT */ - {4, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io)}, /* ACPI_RDESC_TYPE_FIXED_IO_PORT */ - {0, 0}, /* 0x0A, Reserved */ - {0, 0}, /* 0x0B, Reserved */ - {0, 0}, /* 0x0C, Reserved */ - {0, 0}, /* 0x0D, Reserved */ - {1, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor)}, /* ACPI_RDESC_TYPE_SMALL_VENDOR */ - {2, ACPI_RESOURCE_LENGTH}, /* ACPI_RDESC_TYPE_END_TAG */ -}; - -static struct acpi_resource_sizes acpi_gbl_lg_resource_sizes[] = { - {0, 0}, /* 0x00, Reserved */ - {12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24)}, /* ACPI_RDESC_TYPE_MEMORY_24 */ - {15, ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg)}, /* ACPI_RDESC_TYPE_GENERIC_REGISTER */ - {0, 0}, /* 0x03, Reserved */ - {3, ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor)}, /* ACPI_RDESC_TYPE_LARGE_VENDOR */ - {20, ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32)}, /* ACPI_RDESC_TYPE_MEMORY_32 */ - {12, ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32)}, /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */ - {26, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32)}, /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */ - {16, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16)}, /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */ - {9, ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq)}, /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */ - {46, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64)}, /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */ - {56, ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64)}, /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */ -}; - /* Local prototypes */ - static u8 acpi_rs_count_set_bits(u16 bit_field); -static struct acpi_resource_sizes *acpi_rs_get_resource_sizes(u8 resource_type); - -static u16 acpi_rs_get_resource_length(u8 * resource); - static acpi_size acpi_rs_struct_option_length(struct acpi_resource_source *resource_source); @@ -159,90 +86,6 @@ static u8 acpi_rs_count_set_bits(u16 bit_field) return (bits_set); } -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_resource_sizes - * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor - * - * RETURN: Pointer to the resource conversion handler - * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. - * - ******************************************************************************/ - -static struct acpi_resource_sizes *acpi_rs_get_resource_sizes(u8 resource_type) -{ - struct acpi_resource_sizes *size_info; - - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (resource_type & ACPI_RDESC_TYPE_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - if (resource_type > ACPI_RDESC_LARGE_MAX) { - return (NULL); - } - - size_info = &acpi_gbl_lg_resource_sizes[(resource_type & - ACPI_RDESC_LARGE_MASK)]; - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - size_info = &acpi_gbl_sm_resource_sizes[((resource_type & - ACPI_RDESC_SMALL_MASK) - >> 3)]; - } - - /* Zero entry indicates an invalid resource type */ - - if (!size_info->minimum_stream_size) { - return (NULL); - } - - return (size_info); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_resource_length - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * - * RETURN: Byte length of the (AML byte stream) descriptor. By definition, - * this does not include the size of the descriptor header and the - * length field itself. - * - * DESCRIPTION: Extract the length of a resource descriptor. - * - ******************************************************************************/ - -static u16 acpi_rs_get_resource_length(u8 * resource) -{ - u16 resource_length; - - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (*resource & ACPI_RDESC_TYPE_LARGE) { - /* Large Resource type -- length is in bytes 1-2 */ - - ACPI_MOVE_16_TO_16(&resource_length, (resource + 1)); - - } else { - /* Small Resource Type -- bits 2:0 of byte 0 contain the length */ - - resource_length = - (u16) (*resource & ACPI_RDESC_SMALL_LENGTH_MASK); - } - - return (resource_length); -} - /******************************************************************************* * * FUNCTION: acpi_rs_struct_option_length @@ -291,10 +134,10 @@ acpi_rs_struct_option_length(struct acpi_resource_source *resource_source) ******************************************************************************/ static u32 -acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length) +acpi_rs_stream_option_length(u32 resource_length, + u32 minimum_aml_resource_length) { u32 string_length = 0; - u32 minimum_resource_length; ACPI_FUNCTION_ENTRY(); @@ -303,11 +146,6 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length) * Large-type resource descriptors. */ - /* Compute minimum size of the data part of the resource descriptor */ - - minimum_resource_length = - minimum_total_length - sizeof(struct asl_large_header); - /* * If the length of the actual resource descriptor is greater than the ACPI * spec-defined minimum length, it means that a resource_source_index exists @@ -315,10 +153,11 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length) * (including the null terminator) is the resource length minus the minimum * length, minus one byte for the resource_source_index itself. */ - if (resource_length > minimum_resource_length) { + if (resource_length > minimum_aml_resource_length) { /* Compute the length of the optional string */ - string_length = resource_length - minimum_resource_length - 1; + string_length = + resource_length - minimum_aml_resource_length - 1; } /* Round up length to 32 bits for internal structure alignment */ @@ -328,7 +167,7 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length) /******************************************************************************* * - * FUNCTION: acpi_rs_get_byte_stream_length + * FUNCTION: acpi_rs_get_aml_length * * PARAMETERS: Resource - Pointer to the resource linked list * size_needed - Where the required size is returned @@ -342,62 +181,62 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length) ******************************************************************************/ acpi_status -acpi_rs_get_byte_stream_length(struct acpi_resource * resource, - acpi_size * size_needed) +acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) { - acpi_size byte_stream_size_needed = 0; + acpi_size aml_size_needed = 0; acpi_size segment_size; - ACPI_FUNCTION_TRACE("rs_get_byte_stream_length"); + ACPI_FUNCTION_TRACE("rs_get_aml_length"); /* Traverse entire list of internal resource descriptors */ while (resource) { /* Validate the descriptor type */ - if (resource->type > ACPI_RSTYPE_MAX) { + if (resource->type > ACPI_RESOURCE_TYPE_MAX) { return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } /* Get the base size of the (external stream) resource descriptor */ - segment_size = acpi_gbl_stream_sizes[resource->type]; + segment_size = acpi_gbl_aml_resource_sizes[resource->type]; /* * Augment the base size for descriptors with optional and/or * variable-length fields */ switch (resource->type) { - case ACPI_RSTYPE_VENDOR: + case ACPI_RESOURCE_TYPE_VENDOR: /* * Vendor Defined Resource: * For a Vendor Specific resource, if the Length is between 1 and 7 * it will be created as a Small Resource data type, otherwise it * is a Large Resource data type. */ - if (resource->data.vendor_specific.length > 7) { + if (resource->data.vendor.byte_length > 7) { /* Base size of a Large resource descriptor */ - segment_size = 3; + segment_size = + sizeof(struct aml_resource_large_header); } /* Add the size of the vendor-specific data */ - segment_size += resource->data.vendor_specific.length; + segment_size += resource->data.vendor.byte_length; break; - case ACPI_RSTYPE_END_TAG: + case ACPI_RESOURCE_TYPE_END_TAG: /* * End Tag: * We are done -- return the accumulated total size. */ - *size_needed = byte_stream_size_needed + segment_size; + *size_needed = aml_size_needed + segment_size; /* Normal exit */ return_ACPI_STATUS(AE_OK); - case ACPI_RSTYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS16: /* * 16-Bit Address Resource: * Add the size of the optional resource_source info @@ -408,7 +247,7 @@ acpi_rs_get_byte_stream_length(struct acpi_resource * resource, resource_source); break; - case ACPI_RSTYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS32: /* * 32-Bit Address Resource: * Add the size of the optional resource_source info @@ -419,7 +258,7 @@ acpi_rs_get_byte_stream_length(struct acpi_resource * resource, resource_source); break; - case ACPI_RSTYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_ADDRESS64: /* * 64-Bit Address Resource: * Add the size of the optional resource_source info @@ -430,7 +269,7 @@ acpi_rs_get_byte_stream_length(struct acpi_resource * resource, resource_source); break; - case ACPI_RSTYPE_EXT_IRQ: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: /* * Extended IRQ Resource: * Add the size of each additional optional interrupt beyond the @@ -438,7 +277,7 @@ acpi_rs_get_byte_stream_length(struct acpi_resource * resource, */ segment_size += (((acpi_size) resource->data.extended_irq. - number_of_interrupts - 1) * 4); + interrupt_count - 1) * 4); /* Add the size of the optional resource_source info */ @@ -454,7 +293,7 @@ acpi_rs_get_byte_stream_length(struct acpi_resource * resource, /* Update the total */ - byte_stream_size_needed += segment_size; + aml_size_needed += segment_size; /* Point to the next object */ @@ -471,9 +310,9 @@ acpi_rs_get_byte_stream_length(struct acpi_resource * resource, * * FUNCTION: acpi_rs_get_list_length * - * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream - * byte_stream_buffer_length - Size of byte_stream_buffer - * size_needed - Where the size needed is returned + * 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 * @@ -484,11 +323,11 @@ acpi_rs_get_byte_stream_length(struct acpi_resource * resource, ******************************************************************************/ acpi_status -acpi_rs_get_list_length(u8 * byte_stream_buffer, - u32 byte_stream_buffer_length, acpi_size * size_needed) +acpi_rs_get_list_length(u8 * aml_buffer, + u32 aml_buffer_length, acpi_size * size_needed) { u8 *buffer; - struct acpi_resource_sizes *resource_info; + struct acpi_resource_info *resource_info; u32 buffer_size = 0; u32 bytes_parsed = 0; u8 resource_type; @@ -499,14 +338,14 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, ACPI_FUNCTION_TRACE("rs_get_list_length"); - while (bytes_parsed < byte_stream_buffer_length) { + while (bytes_parsed < aml_buffer_length) { /* The next byte in the stream is the resource descriptor type */ - resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); + resource_type = acpi_rs_get_resource_type(*aml_buffer); /* Get the base stream size and structure sizes for the descriptor */ - resource_info = acpi_rs_get_resource_sizes(resource_type); + resource_info = acpi_rs_get_resource_info(resource_type); if (!resource_info) { return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } @@ -514,43 +353,46 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, /* Get the Length field from the input resource descriptor */ resource_length = - acpi_rs_get_resource_length(byte_stream_buffer); + acpi_rs_get_resource_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); /* Augment the size for descriptors with optional fields */ extra_struct_bytes = 0; - if (!(resource_type & ACPI_RDESC_TYPE_LARGE)) { + if (!(resource_type & ACPI_RESOURCE_NAME_LARGE)) { /* * Small resource descriptors */ - header_length = 1; - buffer = byte_stream_buffer + header_length; + header_length = + sizeof(struct aml_resource_small_header); + buffer = aml_buffer + header_length; switch (resource_type) { - case ACPI_RDESC_TYPE_IRQ_FORMAT: + case ACPI_RESOURCE_NAME_IRQ: /* * IRQ Resource: * Get the number of bits set in the IRQ word */ ACPI_MOVE_16_TO_16(&temp16, buffer); - extra_struct_bytes = (acpi_rs_count_set_bits(temp16) * sizeof(u32)); break; - case ACPI_RDESC_TYPE_DMA_FORMAT: + case ACPI_RESOURCE_NAME_DMA: /* * DMA Resource: * Get the number of bits set in the DMA channels byte */ + ACPI_MOVE_16_TO_16(&temp16, buffer); extra_struct_bytes = - (acpi_rs_count_set_bits((u16) * buffer) * + (acpi_rs_count_set_bits(temp16) * sizeof(u32)); break; - case ACPI_RDESC_TYPE_SMALL_VENDOR: + case ACPI_RESOURCE_NAME_VENDOR_SMALL: /* * Vendor Specific Resource: * Ensure a 32-bit boundary for the structure @@ -559,12 +401,12 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, ACPI_ROUND_UP_to_32_bITS(resource_length); break; - case ACPI_RDESC_TYPE_END_TAG: + case ACPI_RESOURCE_NAME_END_TAG: /* * End Tag: * Terminate the loop now */ - byte_stream_buffer_length = bytes_parsed; + aml_buffer_length = bytes_parsed; break; default: @@ -574,11 +416,12 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, /* * Large resource descriptors */ - header_length = sizeof(struct asl_large_header); - buffer = byte_stream_buffer + header_length; + header_length = + sizeof(struct aml_resource_large_header); + buffer = aml_buffer + header_length; switch (resource_type) { - case ACPI_RDESC_TYPE_LARGE_VENDOR: + case ACPI_RESOURCE_NAME_VENDOR_LARGE: /* * Vendor Defined Resource: * Add vendor data and ensure a 32-bit boundary for the structure @@ -587,8 +430,8 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, ACPI_ROUND_UP_to_32_bITS(resource_length); break; - case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: - case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: + case ACPI_RESOURCE_NAME_ADDRESS32: + case ACPI_RESOURCE_NAME_ADDRESS16: /* * 32-Bit or 16-bit Address Resource: * Add the size of any optional data (resource_source) @@ -596,10 +439,11 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, extra_struct_bytes = acpi_rs_stream_option_length (resource_length, - resource_info->minimum_stream_size); + resource_info-> + minimum_aml_resource_length); break; - case ACPI_RDESC_TYPE_EXTENDED_XRUPT: + case ACPI_RESOURCE_NAME_EXTENDED_IRQ: /* * Extended IRQ: * Point past the interrupt_vector_flags to get the @@ -622,10 +466,10 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, - extra_struct_bytes, resource_info-> - minimum_stream_size); + minimum_aml_resource_length); break; - case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: + case ACPI_RESOURCE_NAME_ADDRESS64: /* * 64-Bit Address Resource: * Add the size of any optional data (resource_source) @@ -635,7 +479,8 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, ACPI_ROUND_UP_to_64_bITS (acpi_rs_stream_option_length (resource_length, - resource_info->minimum_stream_size)); + resource_info-> + minimum_aml_resource_length)); break; default: @@ -646,7 +491,7 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, /* Update the required buffer size for the internal descriptor structs */ temp16 = - (u16) (resource_info->minimum_struct_size + + (u16) (resource_info->minimum_internal_struct_length + extra_struct_bytes); buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(temp16); @@ -656,7 +501,7 @@ acpi_rs_get_list_length(u8 * byte_stream_buffer, */ temp16 = (u16) (header_length + resource_length); bytes_parsed += temp16; - byte_stream_buffer += temp16; + aml_buffer += temp16; } /* This is the data the caller needs */ @@ -758,8 +603,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, (*sub_object_list)->string. length + 1); } else { - temp_size_needed += - acpi_ns_get_pathname_length((*sub_object_list)->reference.node); + temp_size_needed += acpi_ns_get_pathname_length((*sub_object_list)->reference.node); } } else { /* diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 0911526b7ad8..6c7c6c560635 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -53,10 +53,10 @@ ACPI_MODULE_NAME("rscreate") * * FUNCTION: acpi_rs_create_resource_list * - * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream - * output_buffer - Pointer to the user's buffer + * PARAMETERS: aml_buffer - Pointer to the resource byte stream + * output_buffer - Pointer to the user's buffer * - * RETURN: Status - AE_OK if okay, else a valid acpi_status code + * RETURN: Status: AE_OK if okay, else a valid acpi_status code * If output_buffer is not large enough, output_buffer_length * indicates how large output_buffer should be, else it * indicates how may u8 elements of output_buffer are valid. @@ -67,33 +67,30 @@ ACPI_MODULE_NAME("rscreate") * ******************************************************************************/ acpi_status -acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer, +acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, struct acpi_buffer *output_buffer) { acpi_status status; - u8 *byte_stream_start; + u8 *aml_start; acpi_size list_size_needed = 0; - u32 byte_stream_buffer_length; + u32 aml_buffer_length; ACPI_FUNCTION_TRACE("rs_create_resource_list"); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_buffer = %p\n", - byte_stream_buffer)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_buffer = %p\n", aml_buffer)); /* Params already validated, so we don't re-validate here */ - byte_stream_buffer_length = byte_stream_buffer->buffer.length; - byte_stream_start = byte_stream_buffer->buffer.pointer; + aml_buffer_length = aml_buffer->buffer.length; + aml_start = aml_buffer->buffer.pointer; /* - * Pass the byte_stream_buffer into a module that can calculate + * Pass the aml_buffer into a module that can calculate * the buffer size needed for the linked list */ - status = - acpi_rs_get_list_length(byte_stream_start, - byte_stream_buffer_length, - &list_size_needed); + status = acpi_rs_get_list_length(aml_start, aml_buffer_length, + &list_size_needed); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n", status, (u32) list_size_needed)); @@ -110,10 +107,8 @@ acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer, /* Do the conversion */ - status = - acpi_rs_byte_stream_to_list(byte_stream_start, - byte_stream_buffer_length, - output_buffer->pointer); + status = acpi_rs_convert_aml_to_resources(aml_start, aml_buffer_length, + output_buffer->pointer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -360,7 +355,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /******************************************************************************* * - * FUNCTION: acpi_rs_create_byte_stream + * FUNCTION: acpi_rs_create_aml_resources * * PARAMETERS: linked_list_buffer - Pointer to the resource linked list * output_buffer - Pointer to the user's buffer @@ -377,13 +372,13 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ******************************************************************************/ acpi_status -acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, - struct acpi_buffer *output_buffer) +acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, + struct acpi_buffer *output_buffer) { acpi_status status; - acpi_size byte_stream_size_needed = 0; + acpi_size aml_size_needed = 0; - ACPI_FUNCTION_TRACE("rs_create_byte_stream"); + ACPI_FUNCTION_TRACE("rs_create_aml_resources"); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "linked_list_buffer = %p\n", linked_list_buffer)); @@ -394,11 +389,10 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, * Pass the linked_list_buffer into a module that calculates * the buffer size needed for the byte stream. */ - status = acpi_rs_get_byte_stream_length(linked_list_buffer, - &byte_stream_size_needed); + status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n", - (u32) byte_stream_size_needed, + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_size_needed=%X, %s\n", + (u32) aml_size_needed, acpi_format_exception(status))); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -406,8 +400,7 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, /* Validate/Allocate/Clear caller buffer */ - status = - acpi_ut_initialize_buffer(output_buffer, byte_stream_size_needed); + status = acpi_ut_initialize_buffer(output_buffer, aml_size_needed); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -415,9 +408,9 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, /* Do the conversion */ status = - acpi_rs_list_to_byte_stream(linked_list_buffer, - byte_stream_size_needed, - output_buffer->pointer); + acpi_rs_convert_resources_to_aml(linked_list_buffer, + aml_size_needed, + output_buffer->pointer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 9d93ee5f0060..2f8990845b2d 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -49,38 +49,6 @@ ACPI_MODULE_NAME("rsdump") #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /* Local prototypes */ -static void acpi_rs_dump_irq(union acpi_resource_data *resource); - -static void acpi_rs_dump_address16(union acpi_resource_data *resource); - -static void acpi_rs_dump_address32(union acpi_resource_data *resource); - -static void acpi_rs_dump_address64(union acpi_resource_data *resource); - -static void acpi_rs_dump_dma(union acpi_resource_data *resource); - -static void acpi_rs_dump_io(union acpi_resource_data *resource); - -static void acpi_rs_dump_extended_irq(union acpi_resource_data *resource); - -static void acpi_rs_dump_fixed_io(union acpi_resource_data *resource); - -static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource); - -static void acpi_rs_dump_memory24(union acpi_resource_data *resource); - -static void acpi_rs_dump_memory32(union acpi_resource_data *resource); - -static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *resource); - -static void acpi_rs_dump_vendor_specific(union acpi_resource_data *resource); - -static void acpi_rs_dump_generic_reg(union acpi_resource_data *resource); - -static void acpi_rs_dump_end_depend_fns(union acpi_resource_data *resource); - -static void acpi_rs_dump_end_tag(union acpi_resource_data *resource); - static void acpi_rs_out_string(char *title, char *value); static void acpi_rs_out_integer8(char *title, u8 value); @@ -104,30 +72,6 @@ acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source); static void acpi_rs_dump_address_common(union acpi_resource_data *resource); -/* Dispatch table for resource dump functions */ - -typedef -void (*ACPI_DUMP_RESOURCE) (union acpi_resource_data * data); - -static ACPI_DUMP_RESOURCE acpi_gbl_dump_resource_dispatch[] = { - acpi_rs_dump_irq, /* ACPI_RSTYPE_IRQ */ - acpi_rs_dump_dma, /* ACPI_RSTYPE_DMA */ - acpi_rs_dump_start_depend_fns, /* ACPI_RSTYPE_START_DPF */ - acpi_rs_dump_end_depend_fns, /* ACPI_RSTYPE_END_DPF */ - acpi_rs_dump_io, /* ACPI_RSTYPE_IO */ - acpi_rs_dump_fixed_io, /* ACPI_RSTYPE_FIXED_IO */ - acpi_rs_dump_vendor_specific, /* ACPI_RSTYPE_VENDOR */ - acpi_rs_dump_end_tag, /* ACPI_RSTYPE_END_TAG */ - acpi_rs_dump_memory24, /* ACPI_RSTYPE_MEM24 */ - acpi_rs_dump_memory32, /* ACPI_RSTYPE_MEM32 */ - acpi_rs_dump_fixed_memory32, /* ACPI_RSTYPE_FIXED_MEM32 */ - acpi_rs_dump_address16, /* ACPI_RSTYPE_ADDRESS16 */ - acpi_rs_dump_address32, /* ACPI_RSTYPE_ADDRESS32 */ - acpi_rs_dump_address64, /* ACPI_RSTYPE_ADDRESS64 */ - acpi_rs_dump_extended_irq, /* ACPI_RSTYPE_EXT_IRQ */ - acpi_rs_dump_generic_reg /* ACPI_RSTYPE_GENERIC_REG */ -}; - /******************************************************************************* * * FUNCTION: acpi_rs_out* @@ -144,32 +88,32 @@ static ACPI_DUMP_RESOURCE acpi_gbl_dump_resource_dispatch[] = { static void acpi_rs_out_string(char *title, char *value) { - acpi_os_printf("%30s : %s\n", title, value); + acpi_os_printf("%27s : %s\n", title, value); } static void acpi_rs_out_integer8(char *title, u8 value) { - acpi_os_printf("%30s : %2.2X\n", title, value); + acpi_os_printf("%27s : %2.2X\n", title, value); } static void acpi_rs_out_integer16(char *title, u16 value) { - acpi_os_printf("%30s : %4.4X\n", title, value); + acpi_os_printf("%27s : %4.4X\n", title, value); } static void acpi_rs_out_integer32(char *title, u32 value) { - acpi_os_printf("%30s : %8.8X\n", title, value); + acpi_os_printf("%27s : %8.8X\n", title, value); } static void acpi_rs_out_integer64(char *title, u64 value) { - acpi_os_printf("%30s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value)); + acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value)); } static void acpi_rs_out_title(char *title) { - acpi_os_printf("%30s : ", title); + acpi_os_printf("%27s : ", title); } /******************************************************************************* @@ -190,7 +134,7 @@ static void acpi_rs_dump_byte_list(u32 length, u8 * data) u32 i; for (i = 0; i < length; i++) { - acpi_os_printf("%28s%2.2X : %2.2X\n", "Byte", i, data[i]); + acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]); } } @@ -199,7 +143,7 @@ static void acpi_rs_dump_dword_list(u32 length, u32 * data) u32 i; for (i = 0; i < length; i++) { - acpi_os_printf("%28s%2.2X : %8.8X\n", "Dword", i, data[i]); + acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]); } } @@ -213,6 +157,14 @@ static void acpi_rs_dump_short_byte_list(u32 length, u32 * data) acpi_os_printf("\n"); } +static void acpi_rs_dump_memory_attribute(u32 read_write_attribute) +{ + + acpi_rs_out_string("Read/Write Attribute", + ACPI_READ_WRITE_MEMORY == read_write_attribute ? + "Read/Write" : "Read-Only"); +} + /******************************************************************************* * * FUNCTION: acpi_rs_dump_resource_source @@ -229,6 +181,7 @@ static void acpi_rs_dump_short_byte_list(u32 length, u32 * data) static void acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source) { + ACPI_FUNCTION_ENTRY(); if (resource_source->index == 0xFF) { return; @@ -290,11 +243,8 @@ static void acpi_rs_dump_address_common(union acpi_resource_data *resource) break; } - acpi_rs_out_string("Read/Write Attribute", - ACPI_READ_WRITE_MEMORY == - resource->address.attribute.memory. - read_write_attribute ? "Read/Write" : - "Read Only"); + acpi_rs_dump_memory_attribute(resource->address.attribute. + memory.read_write_attribute); break; case ACPI_IO_RANGE: @@ -392,7 +342,7 @@ void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) /* Validate Type before dispatch */ - if (resource_list->type > ACPI_RSTYPE_MAX) { + if (resource_list->type > ACPI_RESOURCE_TYPE_MAX) { acpi_os_printf ("Invalid descriptor type (%X) in resource list\n", resource_list->type); @@ -406,7 +356,7 @@ void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) /* Exit on end tag */ - if (resource_list->type == ACPI_RSTYPE_END_TAG) { + if (resource_list->type == ACPI_RESOURCE_TYPE_END_TAG) { return; } @@ -431,7 +381,7 @@ void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) * ******************************************************************************/ -static void acpi_rs_dump_irq(union acpi_resource_data *resource) +void acpi_rs_dump_irq(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); @@ -439,22 +389,21 @@ static void acpi_rs_dump_irq(union acpi_resource_data *resource) acpi_rs_out_string("Triggering", ACPI_LEVEL_SENSITIVE == - resource->irq.edge_level ? "Level" : "Edge"); + resource->irq.triggering ? "Level" : "Edge"); acpi_rs_out_string("Active", ACPI_ACTIVE_LOW == - resource->irq.active_high_low ? "Low" : "High"); + resource->irq.polarity ? "Low" : "High"); acpi_rs_out_string("Sharing", ACPI_SHARED == - resource->irq. - shared_exclusive ? "Shared" : "Exclusive"); + resource->irq.sharable ? "Shared" : "Exclusive"); acpi_rs_out_integer8("Interrupt Count", - (u8) resource->irq.number_of_interrupts); + (u8) resource->irq.interrupt_count); acpi_rs_out_title("Interrupt List"); - acpi_rs_dump_short_byte_list(resource->irq.number_of_interrupts, + acpi_rs_dump_short_byte_list(resource->irq.interrupt_count, resource->irq.interrupts); } @@ -470,7 +419,7 @@ static void acpi_rs_dump_irq(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_dma(union acpi_resource_data *resource) +void acpi_rs_dump_dma(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); @@ -523,16 +472,16 @@ static void acpi_rs_dump_dma(union acpi_resource_data *resource) } acpi_rs_out_integer8("DMA Channel Count", - (u8) resource->dma.number_of_channels); + (u8) resource->dma.channel_count); acpi_rs_out_title("Channel List"); - acpi_rs_dump_short_byte_list(resource->dma.number_of_channels, + acpi_rs_dump_short_byte_list(resource->dma.channel_count, resource->dma.channels); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_start_depend_fns + * FUNCTION: acpi_rs_dump_start_dpf * * PARAMETERS: Resource - Pointer to an internal resource descriptor * @@ -542,7 +491,7 @@ static void acpi_rs_dump_dma(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *resource) +void acpi_rs_dump_start_dpf(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); @@ -600,7 +549,7 @@ static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_io(union acpi_resource_data *resource) +void acpi_rs_dump_io(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); @@ -610,15 +559,13 @@ static void acpi_rs_dump_io(union acpi_resource_data *resource) ACPI_DECODE_16 == resource->io.io_decode ? "16-bit" : "10-bit"); - acpi_rs_out_integer32("Range Minimum Base", - resource->io.min_base_address); + acpi_rs_out_integer32("Address Minimum", resource->io.minimum); - acpi_rs_out_integer32("Range Maximum Base", - resource->io.max_base_address); + acpi_rs_out_integer32("Address Maximum", resource->io.maximum); acpi_rs_out_integer32("Alignment", resource->io.alignment); - acpi_rs_out_integer32("Range Length", resource->io.range_length); + acpi_rs_out_integer32("Address Length", resource->io.address_length); } /******************************************************************************* @@ -633,21 +580,21 @@ static void acpi_rs_dump_io(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_fixed_io(union acpi_resource_data *resource) +void acpi_rs_dump_fixed_io(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); acpi_os_printf("Fixed I/O Resource\n"); - acpi_rs_out_integer32("Range Base Address", - resource->fixed_io.base_address); + acpi_rs_out_integer32("Address", resource->fixed_io.address); - acpi_rs_out_integer32("Range Length", resource->fixed_io.range_length); + acpi_rs_out_integer32("Address Length", + resource->fixed_io.address_length); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_vendor_specific + * FUNCTION: acpi_rs_dump_vendor * * PARAMETERS: Resource - Pointer to an internal resource descriptor * @@ -657,16 +604,16 @@ static void acpi_rs_dump_fixed_io(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_vendor_specific(union acpi_resource_data *resource) +void acpi_rs_dump_vendor(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); acpi_os_printf("Vendor Specific Resource\n"); - acpi_rs_out_integer16("Length", (u16) resource->vendor_specific.length); + acpi_rs_out_integer16("Length", (u16) resource->vendor.byte_length); - acpi_rs_dump_byte_list(resource->vendor_specific.length, - resource->vendor_specific.reserved); + acpi_rs_dump_byte_list(resource->vendor.byte_length, + resource->vendor.byte_data); } /******************************************************************************* @@ -681,27 +628,24 @@ static void acpi_rs_dump_vendor_specific(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_memory24(union acpi_resource_data *resource) +void acpi_rs_dump_memory24(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); acpi_os_printf("24-Bit Memory Range Resource\n"); - acpi_rs_out_string("Attribute", - ACPI_READ_WRITE_MEMORY == - resource->memory24.read_write_attribute ? - "Read/Write" : "Read Only"); + acpi_rs_dump_memory_attribute(resource->memory24.read_write_attribute); - acpi_rs_out_integer16("Range Minimum Base", - (u16) resource->memory24.min_base_address); + acpi_rs_out_integer16("Address Minimum", + (u16) resource->memory24.minimum); - acpi_rs_out_integer16("Range Maximum Base", - (u16) resource->memory24.max_base_address); + acpi_rs_out_integer16("Address Maximum", + (u16) resource->memory24.maximum); acpi_rs_out_integer16("Alignment", (u16) resource->memory24.alignment); - acpi_rs_out_integer16("Range Length", - (u16) resource->memory24.range_length); + acpi_rs_out_integer16("Address Length", + (u16) resource->memory24.address_length); } /******************************************************************************* @@ -716,26 +660,22 @@ static void acpi_rs_dump_memory24(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_memory32(union acpi_resource_data *resource) +void acpi_rs_dump_memory32(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); acpi_os_printf("32-Bit Memory Range Resource\n"); - acpi_rs_out_string("Attribute", - ACPI_READ_WRITE_MEMORY == - resource->memory32.read_write_attribute ? - "Read/Write" : "Read Only"); + acpi_rs_dump_memory_attribute(resource->memory32.read_write_attribute); - acpi_rs_out_integer32("Range Minimum Base", - resource->memory32.min_base_address); + acpi_rs_out_integer32("Address Minimum", resource->memory32.minimum); - acpi_rs_out_integer32("Range Maximum Base", - resource->memory32.max_base_address); + acpi_rs_out_integer32("Address Maximum", resource->memory32.maximum); acpi_rs_out_integer32("Alignment", resource->memory32.alignment); - acpi_rs_out_integer32("Range Length", resource->memory32.range_length); + acpi_rs_out_integer32("Address Length", + resource->memory32.address_length); } /******************************************************************************* @@ -750,22 +690,19 @@ static void acpi_rs_dump_memory32(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource) +void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); acpi_os_printf("32-Bit Fixed Location Memory Range Resource\n"); - acpi_rs_out_string("Attribute", - ACPI_READ_WRITE_MEMORY == - resource->fixed_memory32.read_write_attribute ? - "Read/Write" : "Read Only"); + acpi_rs_dump_memory_attribute(resource->fixed_memory32. + read_write_attribute); - acpi_rs_out_integer32("Range Base Address", - resource->fixed_memory32.range_base_address); + acpi_rs_out_integer32("Address", resource->fixed_memory32.address); - acpi_rs_out_integer32("Range Length", - resource->fixed_memory32.range_length); + acpi_rs_out_integer32("Address Length", + resource->fixed_memory32.address_length); } /******************************************************************************* @@ -780,26 +717,25 @@ static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_address16(union acpi_resource_data *resource) +void acpi_rs_dump_address16(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); - acpi_os_printf("16-Bit Address Space Resource\n"); + acpi_os_printf("16-Bit WORD Address Space Resource\n"); acpi_rs_dump_address_common(resource); acpi_rs_out_integer16("Granularity", (u16) resource->address16.granularity); - acpi_rs_out_integer16("Address Range Min", - (u16) resource->address16.min_address_range); + acpi_rs_out_integer16("Address Minimum", + (u16) resource->address16.minimum); - acpi_rs_out_integer16("Address Range Max", - (u16) resource->address16.max_address_range); + acpi_rs_out_integer16("Address Maximum", + (u16) resource->address16.maximum); - acpi_rs_out_integer16("Address Translation Offset", - (u16) resource->address16. - address_translation_offset); + acpi_rs_out_integer16("Translation Offset", + (u16) resource->address16.translation_offset); acpi_rs_out_integer16("Address Length", (u16) resource->address16.address_length); @@ -819,24 +755,22 @@ static void acpi_rs_dump_address16(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_address32(union acpi_resource_data *resource) +void acpi_rs_dump_address32(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); - acpi_os_printf("32-Bit Address Space Resource\n"); + acpi_os_printf("32-Bit DWORD Address Space Resource\n"); acpi_rs_dump_address_common(resource); acpi_rs_out_integer32("Granularity", resource->address32.granularity); - acpi_rs_out_integer32("Address Range Min", - resource->address32.min_address_range); + acpi_rs_out_integer32("Address Minimum", resource->address32.minimum); - acpi_rs_out_integer32("Address Range Max", - resource->address32.max_address_range); + acpi_rs_out_integer32("Address Maximum", resource->address32.maximum); - acpi_rs_out_integer32("Address Translation Offset", - resource->address32.address_translation_offset); + acpi_rs_out_integer32("Translation Offset", + resource->address32.translation_offset); acpi_rs_out_integer32("Address Length", resource->address32.address_length); @@ -856,37 +790,32 @@ static void acpi_rs_dump_address32(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_address64(union acpi_resource_data *resource) +void acpi_rs_dump_address64(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); - acpi_os_printf("64-Bit Address Space Resource\n"); + acpi_os_printf("64-Bit QWORD Address Space Resource\n"); acpi_rs_dump_address_common(resource); acpi_rs_out_integer64("Granularity", resource->address64.granularity); - acpi_rs_out_integer64("Address Range Min", - resource->address64.min_address_range); + acpi_rs_out_integer64("Address Minimum", resource->address64.minimum); - acpi_rs_out_integer64("Address Range Max", - resource->address64.max_address_range); + acpi_rs_out_integer64("Address Maximum", resource->address64.maximum); - acpi_rs_out_integer64("Address Translation Offset", - resource->address64.address_translation_offset); + acpi_rs_out_integer64("Translation Offset", + resource->address64.translation_offset); acpi_rs_out_integer64("Address Length", resource->address64.address_length); - acpi_rs_out_integer64("Type Specific Attributes", - resource->address64.type_specific_attributes); - acpi_rs_dump_resource_source(&resource->address64.resource_source); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_extended_irq + * FUNCTION: acpi_rs_dump_ext_address64 * * PARAMETERS: Resource - Pointer to an internal resource descriptor * @@ -896,7 +825,46 @@ static void acpi_rs_dump_address64(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_extended_irq(union acpi_resource_data *resource) +void acpi_rs_dump_ext_address64(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_os_printf("64-Bit Extended Address Space Resource\n"); + + acpi_rs_dump_address_common(resource); + + acpi_rs_out_integer64("Granularity", + resource->ext_address64.granularity); + + acpi_rs_out_integer64("Address Minimum", + resource->ext_address64.minimum); + + acpi_rs_out_integer64("Address Maximum", + resource->ext_address64.maximum); + + acpi_rs_out_integer64("Translation Offset", + resource->ext_address64.translation_offset); + + acpi_rs_out_integer64("Address Length", + resource->ext_address64.address_length); + + acpi_rs_out_integer64("Type-Specific Attribute", + resource->ext_address64.type_specific_attributes); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_ext_irq + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the field names and values of the resource descriptor + * + ******************************************************************************/ + +void acpi_rs_dump_ext_irq(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); @@ -910,24 +878,22 @@ static void acpi_rs_dump_extended_irq(union acpi_resource_data *resource) acpi_rs_out_string("Triggering", ACPI_LEVEL_SENSITIVE == resource->extended_irq. - edge_level ? "Level" : "Edge"); + triggering ? "Level" : "Edge"); acpi_rs_out_string("Active", - ACPI_ACTIVE_LOW == - resource->extended_irq. - active_high_low ? "Low" : "High"); + ACPI_ACTIVE_LOW == resource->extended_irq.polarity ? + "Low" : "High"); acpi_rs_out_string("Sharing", - ACPI_SHARED == - resource->extended_irq. - shared_exclusive ? "Shared" : "Exclusive"); + ACPI_SHARED == resource->extended_irq.sharable ? + "Shared" : "Exclusive"); acpi_rs_dump_resource_source(&resource->extended_irq.resource_source); acpi_rs_out_integer8("Interrupts", - (u8) resource->extended_irq.number_of_interrupts); + (u8) resource->extended_irq.interrupt_count); - acpi_rs_dump_dword_list(resource->extended_irq.number_of_interrupts, + acpi_rs_dump_dword_list(resource->extended_irq.interrupt_count, resource->extended_irq.interrupts); } @@ -943,9 +909,8 @@ static void acpi_rs_dump_extended_irq(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_generic_reg(union acpi_resource_data *resource) +void acpi_rs_dump_generic_reg(union acpi_resource_data *resource) { - ACPI_FUNCTION_ENTRY(); acpi_os_printf("Generic Register Resource\n"); @@ -957,15 +922,15 @@ static void acpi_rs_dump_generic_reg(union acpi_resource_data *resource) acpi_rs_out_integer8("Bit Offset", (u8) resource->generic_reg.bit_offset); - acpi_rs_out_integer8("Address Size", - (u8) resource->generic_reg.address_size); + acpi_rs_out_integer8("Access Size", + (u8) resource->generic_reg.access_size); acpi_rs_out_integer64("Address", resource->generic_reg.address); } /******************************************************************************* * - * FUNCTION: acpi_rs_dump_end_depend_fns + * FUNCTION: acpi_rs_dump_end_dpf * * PARAMETERS: Resource - Pointer to an internal resource descriptor * @@ -975,7 +940,7 @@ static void acpi_rs_dump_generic_reg(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_end_depend_fns(union acpi_resource_data *resource) +void acpi_rs_dump_end_dpf(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); @@ -994,7 +959,7 @@ static void acpi_rs_dump_end_depend_fns(union acpi_resource_data *resource) * ******************************************************************************/ -static void acpi_rs_dump_end_tag(union acpi_resource_data *resource) +void acpi_rs_dump_end_tag(union acpi_resource_data *resource) { ACPI_FUNCTION_ENTRY(); diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c index 49a5f81c727b..b31cb33ec565 100644 --- a/drivers/acpi/resources/rsinfo.c +++ b/drivers/acpi/resources/rsinfo.c @@ -207,7 +207,7 @@ struct acpi_resource_info acpi_gbl_lg_resource_info[] = { {0, ACPI_RLARGE(struct aml_resource_memory24), ACPI_SIZEOF_RESOURCE(struct acpi_resource_memory24)}, {0, ACPI_RLARGE(struct aml_resource_generic_register), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_registerister)}, + ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_register)}, {0, 0, 0}, {1, ACPI_RLARGE(struct aml_resource_vendor_large), ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor)}, diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index 6574e2ae2e52..0dab8cdfa800 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -49,426 +49,269 @@ ACPI_MODULE_NAME("rsio") /******************************************************************************* * - * FUNCTION: acpi_rs_io_resource + * FUNCTION: acpi_rs_get_io * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_io_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_get_io(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); + ACPI_FUNCTION_TRACE("rs_get_io"); - ACPI_FUNCTION_TRACE("rs_io_resource"); + /* Get the Decode flag */ - /* The number of bytes consumed are Constant */ + resource->data.io.io_decode = aml->io.information & 0x01; - *bytes_consumed = 8; + /* + * Get the following contiguous fields from the AML descriptor: + * Minimum Base Address + * Maximum Base Address + * Address Alignment + * Length + */ + ACPI_MOVE_16_TO_32(&resource->data.io.minimum, &aml->io.minimum); + ACPI_MOVE_16_TO_32(&resource->data.io.maximum, &aml->io.maximum); + resource->data.io.alignment = aml->io.alignment; + resource->data.io.address_length = aml->io.address_length; - output_struct->type = ACPI_RSTYPE_IO; + /* Complete the resource header */ - /* Check Decode */ - - buffer += 1; - temp8 = *buffer; - - output_struct->data.io.io_decode = temp8 & 0x01; - - /* Check min_base Address */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - output_struct->data.io.min_base_address = temp16; - - /* Check max_base Address */ - - buffer += 2; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - output_struct->data.io.max_base_address = temp16; - - /* Check Base alignment */ - - buffer += 2; - temp8 = *buffer; - - output_struct->data.io.alignment = temp8; - - /* Check range_length */ - - buffer += 1; - temp8 = *buffer; - - output_struct->data.io.range_length = temp8; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_IO; + resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_fixed_io_resource + * FUNCTION: acpi_rs_set_io * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_fixed_io_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_set_io(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); + ACPI_FUNCTION_TRACE("rs_set_io"); - ACPI_FUNCTION_TRACE("rs_fixed_io_resource"); + /* I/O Information Byte */ - /* The number of bytes consumed are Constant */ + aml->io.information = (u8) (resource->data.io.io_decode & 0x01); - *bytes_consumed = 4; + /* + * Set the following contiguous fields in the AML descriptor: + * Minimum Base Address + * Maximum Base Address + * Address Alignment + * Length + */ + ACPI_MOVE_32_TO_16(&aml->io.minimum, &resource->data.io.minimum); + ACPI_MOVE_32_TO_16(&aml->io.maximum, &resource->data.io.maximum); + aml->io.alignment = (u8) resource->data.io.alignment; + aml->io.address_length = (u8) resource->data.io.address_length; - output_struct->type = ACPI_RSTYPE_FIXED_IO; + /* Complete the AML descriptor header */ - /* Check Range Base Address */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - output_struct->data.fixed_io.base_address = temp16; - - /* Check range_length */ - - buffer += 2; - temp8 = *buffer; - - output_struct->data.fixed_io.range_length = temp8; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_IO, + sizeof(struct aml_resource_io), aml); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_io_stream + * FUNCTION: acpi_rs_get_fixed_io * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_io_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_get_fixed_io(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; + ACPI_FUNCTION_TRACE("rs_get_fixed_io"); - ACPI_FUNCTION_TRACE("rs_io_stream"); + /* + * Get the following contiguous fields from the AML descriptor: + * Base Address + * Length + */ + ACPI_MOVE_16_TO_32(&resource->data.fixed_io.address, + &aml->fixed_io.address); + resource->data.fixed_io.address_length = aml->fixed_io.address_length; - /* The Descriptor Type field is static */ + /* Complete the resource header */ - *buffer = ACPI_RDESC_TYPE_IO_PORT | 0x07; - buffer += 1; - - /* Io Information Byte */ - - temp8 = (u8) (resource->data.io.io_decode & 0x01); - - *buffer = temp8; - buffer += 1; - - /* Set the Range minimum base address */ - - temp16 = (u16) resource->data.io.min_base_address; - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the Range maximum base address */ - - temp16 = (u16) resource->data.io.max_base_address; - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the base alignment */ - - temp8 = (u8) resource->data.io.alignment; - - *buffer = temp8; - buffer += 1; - - /* Set the range length */ - - temp8 = (u8) resource->data.io.range_length; - - *buffer = temp8; - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + resource->type = ACPI_RESOURCE_TYPE_FIXED_IO; + resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_fixed_io_stream + * FUNCTION: acpi_rs_set_fixed_io * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_fixed_io_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_set_fixed_io(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; + ACPI_FUNCTION_TRACE("rs_set_fixed_io"); - ACPI_FUNCTION_TRACE("rs_fixed_io_stream"); + /* + * Set the following contiguous fields in the AML descriptor: + * Base Address + * Length + */ + ACPI_MOVE_32_TO_16(&aml->fixed_io.address, + &resource->data.fixed_io.address); + aml->fixed_io.address_length = + (u8) resource->data.fixed_io.address_length; - /* The Descriptor Type field is static */ + /* Complete the AML descriptor header */ - *buffer = ACPI_RDESC_TYPE_FIXED_IO_PORT | 0x03; - buffer += 1; - - /* Set the Range base address */ - - temp16 = (u16) resource->data.fixed_io.base_address; - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the range length */ - - temp8 = (u8) resource->data.fixed_io.range_length; - - *buffer = temp8; - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_FIXED_IO, + sizeof(struct aml_resource_fixed_io), aml); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_dma_resource + * FUNCTION: acpi_rs_get_dma * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_dma_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_get_dma(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u8 temp8 = 0; - u8 index; - u8 i; - acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma); + u32 channel_count = 0; + u32 i; + u8 temp8; - ACPI_FUNCTION_TRACE("rs_dma_resource"); - - /* The number of bytes consumed are Constant */ - - *bytes_consumed = 3; - output_struct->type = ACPI_RSTYPE_DMA; - - /* Point to the 8-bits of Byte 1 */ - - buffer += 1; - temp8 = *buffer; + ACPI_FUNCTION_TRACE("rs_get_dma"); /* Decode the DMA channel bits */ - for (i = 0, index = 0; index < 8; index++) { - if ((temp8 >> index) & 0x01) { - output_struct->data.dma.channels[i] = index; - i++; + for (i = 0; i < 8; i++) { + if ((aml->dma.dma_channel_mask >> i) & 0x01) { + resource->data.dma.channels[channel_count] = i; + channel_count++; } } - /* Zero DMA channels is valid */ + resource->length = 0; + resource->data.dma.channel_count = channel_count; - output_struct->data.dma.number_of_channels = i; - if (i > 0) { - /* Calculate the structure size based upon the number of interrupts */ - - struct_size += ((acpi_size) i - 1) * 4; + /* + * Calculate the structure size based upon the number of channels + * Note: Zero DMA channels is valid + */ + if (channel_count > 0) { + resource->length = (u32) (channel_count - 1) * 4; } - /* Point to Byte 2 */ + /* Get the flags: transfer preference, bus mastering, channel speed */ - buffer += 1; - temp8 = *buffer; + temp8 = aml->dma.flags; + resource->data.dma.transfer = temp8 & 0x03; + resource->data.dma.bus_master = (temp8 >> 2) & 0x01; + resource->data.dma.type = (temp8 >> 5) & 0x03; - /* Check for transfer preference (Bits[1:0]) */ - - output_struct->data.dma.transfer = temp8 & 0x03; - - if (0x03 == output_struct->data.dma.transfer) { + if (resource->data.dma.transfer == 0x03) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n")); return_ACPI_STATUS(AE_BAD_DATA); } - /* Get bus master preference (Bit[2]) */ + /* Complete the resource header */ - output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01; - - /* Get channel speed support (Bits[6:5]) */ - - output_struct->data.dma.type = (temp8 >> 5) & 0x03; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_DMA; + resource->length += ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_dma_stream + * FUNCTION: acpi_rs_set_dma * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_dma_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_set_dma(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; + u8 i; - ACPI_FUNCTION_TRACE("rs_dma_stream"); + ACPI_FUNCTION_TRACE("rs_set_dma"); - /* The Descriptor Type field is static */ + /* Convert channel list to 8-bit DMA channel bitmask */ - *buffer = ACPI_RDESC_TYPE_DMA_FORMAT | 0x02; - buffer += 1; - temp8 = 0; - - /* Loop through all of the Channels and set the mask bits */ - - for (index = 0; index < resource->data.dma.number_of_channels; index++) { - temp16 = (u16) resource->data.dma.channels[index]; - temp8 |= 0x1 << temp16; + aml->dma.dma_channel_mask = 0; + for (i = 0; i < resource->data.dma.channel_count; i++) { + aml->dma.dma_channel_mask |= + (1 << resource->data.dma.channels[i]); } - *buffer = temp8; - buffer += 1; + /* Set the DMA Flag bits */ - /* Set the DMA Info */ + aml->dma.flags = (u8) + (((resource->data.dma.type & 0x03) << 5) | + ((resource->data.dma.bus_master & 0x01) << 2) | + (resource->data.dma.transfer & 0x03)); - temp8 = (u8) ((resource->data.dma.type & 0x03) << 5); - temp8 |= ((resource->data.dma.bus_master & 0x01) << 2); - temp8 |= (resource->data.dma.transfer & 0x03); + /* Complete the AML descriptor header */ - *buffer = temp8; - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_DMA, + sizeof(struct aml_resource_dma), aml); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 75df962115cc..4e854ba70811 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -49,93 +49,67 @@ ACPI_MODULE_NAME("rsirq") /******************************************************************************* * - * FUNCTION: acpi_rs_irq_resource + * FUNCTION: acpi_rs_get_irq * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_irq_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_get_irq(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - u8 i; - acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq); + u32 interrupt_count = 0; + u32 i; + u32 resource_length; - ACPI_FUNCTION_TRACE("rs_irq_resource"); + ACPI_FUNCTION_TRACE("rs_get_irq"); - /* - * The number of bytes consumed are contained in the descriptor - * (Bits:0-1) - */ - temp8 = *buffer; - *bytes_consumed = (temp8 & 0x03) + 1; - output_struct->type = ACPI_RSTYPE_IRQ; + /* Get the IRQ mask (bytes 1:2) */ - /* Point to the 16-bits of Bytes 1 and 2 */ + ACPI_MOVE_16_TO_16(&temp16, &aml->irq.irq_mask); - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); + /* Decode the IRQ bits (up to 16 possible) */ - output_struct->data.irq.number_of_interrupts = 0; - - /* Decode the IRQ bits */ - - for (i = 0, index = 0; index < 16; index++) { - if ((temp16 >> index) & 0x01) { - output_struct->data.irq.interrupts[i] = index; - i++; + for (i = 0; i < 16; i++) { + if ((temp16 >> i) & 0x01) { + resource->data.irq.interrupts[interrupt_count] = i; + interrupt_count++; } } /* Zero interrupts is valid */ - output_struct->data.irq.number_of_interrupts = i; - if (i > 0) { + resource_length = 0; + resource->data.irq.interrupt_count = interrupt_count; + if (interrupt_count > 0) { /* Calculate the structure size based upon the number of interrupts */ - struct_size += ((acpi_size) i - 1) * 4; + resource_length = (u32) (interrupt_count - 1) * 4; } - /* Point to Byte 3 if it is used */ - - if (4 == *bytes_consumed) { - buffer += 2; - temp8 = *buffer; + /* Get Flags (Byte 3) if it is used */ + if (aml_resource_length == 3) { /* Check for HE, LL interrupts */ - switch (temp8 & 0x09) { + switch (aml->irq.flags & 0x09) { case 0x01: /* HE */ - output_struct->data.irq.edge_level = - ACPI_EDGE_SENSITIVE; - output_struct->data.irq.active_high_low = - ACPI_ACTIVE_HIGH; + resource->data.irq.triggering = ACPI_EDGE_SENSITIVE; + resource->data.irq.polarity = ACPI_ACTIVE_HIGH; break; case 0x08: /* LL */ - output_struct->data.irq.edge_level = - ACPI_LEVEL_SENSITIVE; - output_struct->data.irq.active_high_low = - ACPI_ACTIVE_LOW; + resource->data.irq.triggering = ACPI_LEVEL_SENSITIVE; + resource->data.irq.polarity = ACPI_ACTIVE_LOW; break; default: @@ -146,170 +120,131 @@ acpi_rs_irq_resource(u8 * byte_stream_buffer, */ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid interrupt polarity/trigger in resource list, %X\n", - temp8)); + aml->irq.flags)); return_ACPI_STATUS(AE_BAD_DATA); } - /* Check for sharable */ + /* Get Sharing flag */ - output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01; + resource->data.irq.sharable = (aml->irq.flags >> 3) & 0x01; } else { /* - * Assume Edge Sensitive, Active High, Non-Sharable - * per ACPI Specification + * Default configuration: assume Edge Sensitive, Active High, + * Non-Sharable as per the ACPI Specification */ - output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; - output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; - output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE; + resource->data.irq.triggering = ACPI_EDGE_SENSITIVE; + resource->data.irq.polarity = ACPI_ACTIVE_HIGH; + resource->data.irq.sharable = ACPI_EXCLUSIVE; } - /* Set the Length parameter */ + /* Complete the resource header */ - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_IRQ; + resource->length = + resource_length + ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_irq_stream + * FUNCTION: acpi_rs_set_irq * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_irq_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_set_irq(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - u8 IRqinfo_byte_needed; + acpi_size descriptor_length; + u16 irq_mask; + u8 i; - ACPI_FUNCTION_TRACE("rs_irq_stream"); + ACPI_FUNCTION_TRACE("rs_set_irq"); + + /* Convert interrupt list to 16-bit IRQ bitmask */ + + irq_mask = 0; + for (i = 0; i < resource->data.irq.interrupt_count; i++) { + irq_mask |= (1 << resource->data.irq.interrupts[i]); + } + + /* Set the interrupt mask */ + + ACPI_MOVE_16_TO_16(&aml->irq.irq_mask, &irq_mask); /* * The descriptor field is set based upon whether a third byte is * needed to contain the IRQ Information. */ - if (ACPI_EDGE_SENSITIVE == resource->data.irq.edge_level && - ACPI_ACTIVE_HIGH == resource->data.irq.active_high_low && - ACPI_EXCLUSIVE == resource->data.irq.shared_exclusive) { - *buffer = ACPI_RDESC_TYPE_IRQ_FORMAT | 0x02; - IRqinfo_byte_needed = FALSE; + if ((resource->data.irq.triggering == ACPI_EDGE_SENSITIVE) && + (resource->data.irq.polarity == ACPI_ACTIVE_HIGH) && + (resource->data.irq.sharable == ACPI_EXCLUSIVE)) { + /* irq_no_flags() descriptor can be used */ + + descriptor_length = sizeof(struct aml_resource_irq_noflags); } else { - *buffer = ACPI_RDESC_TYPE_IRQ_FORMAT | 0x03; - IRqinfo_byte_needed = TRUE; - } + /* Irq() descriptor must be used */ - buffer += 1; - temp16 = 0; + descriptor_length = sizeof(struct aml_resource_irq); - /* Loop through all of the interrupts and set the mask bits */ + /* Set the IRQ Info byte */ - for (index = 0; - index < resource->data.irq.number_of_interrupts; index++) { - temp8 = (u8) resource->data.irq.interrupts[index]; - temp16 |= 0x1 << temp8; - } + aml->irq.flags = (u8) + ((resource->data.irq.sharable & 0x01) << 4); - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the IRQ Info byte if needed. */ - - if (IRqinfo_byte_needed) { - temp8 = 0; - temp8 = (u8) ((resource->data.irq.shared_exclusive & - 0x01) << 4); - - if (ACPI_LEVEL_SENSITIVE == resource->data.irq.edge_level && - ACPI_ACTIVE_LOW == resource->data.irq.active_high_low) { - temp8 |= 0x08; + if (ACPI_LEVEL_SENSITIVE == resource->data.irq.triggering && + ACPI_ACTIVE_LOW == resource->data.irq.polarity) { + aml->irq.flags |= 0x08; } else { - temp8 |= 0x01; + aml->irq.flags |= 0x01; } - - *buffer = temp8; - buffer += 1; } - /* Return the number of bytes consumed in this operation */ + /* Complete the AML descriptor header */ - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_IRQ, descriptor_length, + aml); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_extended_irq_resource + * FUNCTION: acpi_rs_get_ext_irq * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_get_ext_irq(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 *temp_ptr; - u8 index; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq); + char *out_resource_string; + u8 temp8; - ACPI_FUNCTION_TRACE("rs_extended_irq_resource"); + ACPI_FUNCTION_TRACE("rs_get_ext_irq"); - /* Get the Descriptor Length field */ + /* Get the flag bits */ - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - /* Validate minimum descriptor length */ - - if (temp16 < 6) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - *bytes_consumed = temp16 + 3; - output_struct->type = ACPI_RSTYPE_EXT_IRQ; - - /* Point to the Byte3 */ - - buffer += 2; - temp8 = *buffer; - - output_struct->data.extended_irq.producer_consumer = temp8 & 0x01; + temp8 = aml->extended_irq.flags; + resource->data.extended_irq.producer_consumer = temp8 & 0x01; + resource->data.extended_irq.polarity = (temp8 >> 2) & 0x01; + resource->data.extended_irq.sharable = (temp8 >> 3) & 0x01; /* * Check for Interrupt Mode @@ -319,165 +254,80 @@ acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, * * - Edge/Level are defined opposite in the table vs the headers */ - output_struct->data.extended_irq.edge_level = + resource->data.extended_irq.triggering = (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; - /* Check Interrupt Polarity */ - - output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1; - - /* Check for sharable */ - - output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01; - - /* Point to Byte4 (IRQ Table length) */ - - buffer += 1; - temp8 = *buffer; - - /* Must have at least one IRQ */ + /* Get the IRQ Table length (Byte4) */ + temp8 = aml->extended_irq.table_length; + resource->data.extended_irq.interrupt_count = temp8; if (temp8 < 1) { + /* Must have at least one IRQ */ + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); } - output_struct->data.extended_irq.number_of_interrupts = temp8; - /* * Add any additional structure size to properly calculate * the next pointer at the end of this function */ - struct_size += (temp8 - 1) * 4; + resource->length = (temp8 - 1) * 4; + out_resource_string = ACPI_CAST_PTR(char, + (&resource->data.extended_irq. + interrupts[0] + temp8)); - /* Point to Byte5 (First IRQ Number) */ + /* Get every IRQ in the table, each is 32 bits */ - buffer += 1; + acpi_rs_move_data(resource->data.extended_irq.interrupts, + aml->extended_irq.interrupt_number, + (u16) temp8, ACPI_MOVE_TYPE_32_TO_32); - /* Cycle through every IRQ in the table */ + /* Get the optional resource_source (index and string) */ - for (index = 0; index < temp8; index++) { - ACPI_MOVE_32_TO_32(&output_struct->data.extended_irq. - interrupts[index], buffer); + resource->length += + acpi_rs_get_resource_source(aml_resource_length, + (acpi_size) resource->length + + sizeof(struct + aml_resource_extended_irq), + &resource->data.extended_irq. + resource_source, aml, + out_resource_string); - /* Point to the next IRQ */ + /* Complete the resource header */ - buffer += 4; - } - - /* - * This will leave us pointing to the Resource Source Index - * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. - * - * Note: Some resource descriptors will have an additional null, so - * we add 1 to the length. - */ - if (*bytes_consumed > - ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * - 4) + (5 + 1)) { - /* Dereference the Index */ - - temp8 = *buffer; - output_struct->data.extended_irq.resource_source.index = - (u32) temp8; - - /* Point to the String */ - - buffer += 1; - - /* Point the String pointer to the end of this structure. */ - - output_struct->data.extended_irq.resource_source.string_ptr = - (char *)((char *)output_struct + struct_size); - - temp_ptr = (u8 *) - output_struct->data.extended_irq.resource_source.string_ptr; - - /* Copy the string into the buffer */ - - index = 0; - while (*buffer) { - *temp_ptr = *buffer; - - temp_ptr += 1; - buffer += 1; - index += 1; - } - - /* Add the terminating null */ - - *temp_ptr = 0; - output_struct->data.extended_irq.resource_source.string_length = - index + 1; - - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - temp8 = (u8) (index + 1); - struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); - } else { - output_struct->data.extended_irq.resource_source.index = 0; - output_struct->data.extended_irq.resource_source.string_length = - 0; - output_struct->data.extended_irq.resource_source.string_ptr = - NULL; - } - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; + resource->length += + ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_irq); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_extended_irq_stream + * FUNCTION: acpi_rs_set_ext_irq * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_extended_irq_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_set_ext_irq(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer = *output_buffer; - u16 *length_field; - u8 temp8 = 0; - u8 index; + acpi_size descriptor_length; - ACPI_FUNCTION_TRACE("rs_extended_irq_stream"); - - /* Set the Descriptor Type field */ - - *buffer = ACPI_RDESC_TYPE_EXTENDED_XRUPT; - buffer += 1; - - /* Save a pointer to the Length field - to be filled in later */ - - length_field = ACPI_CAST_PTR(u16, buffer); - buffer += 2; + ACPI_FUNCTION_TRACE("rs_set_ext_irq"); /* Set the Interrupt vector flags */ - temp8 = (u8) (resource->data.extended_irq.producer_consumer & 0x01); - temp8 |= ((resource->data.extended_irq.shared_exclusive & 0x01) << 3); + aml->extended_irq.flags = (u8) + ((resource->data.extended_irq.producer_consumer & 0x01) | + ((resource->data.extended_irq.sharable & 0x01) << 3) | + ((resource->data.extended_irq.polarity & 0x1) << 2)); /* * Set the Interrupt Mode @@ -488,64 +338,36 @@ acpi_rs_extended_irq_stream(struct acpi_resource *resource, * * - Edge/Level are defined opposite in the table vs the headers */ - if (ACPI_EDGE_SENSITIVE == resource->data.extended_irq.edge_level) { - temp8 |= 0x2; + if (resource->data.extended_irq.triggering == ACPI_EDGE_SENSITIVE) { + aml->extended_irq.flags |= 0x02; } - /* Set the Interrupt Polarity */ - - temp8 |= ((resource->data.extended_irq.active_high_low & 0x1) << 2); - - *buffer = temp8; - buffer += 1; - /* Set the Interrupt table length */ - temp8 = (u8) resource->data.extended_irq.number_of_interrupts; + aml->extended_irq.table_length = (u8) + resource->data.extended_irq.interrupt_count; - *buffer = temp8; - buffer += 1; + descriptor_length = (sizeof(struct aml_resource_extended_irq) - 4) + + ((acpi_size) resource->data.extended_irq.interrupt_count * + sizeof(u32)); - for (index = 0; - index < resource->data.extended_irq.number_of_interrupts; - index++) { - ACPI_MOVE_32_TO_32(buffer, - &resource->data.extended_irq. - interrupts[index]); - buffer += 4; - } + /* Set each interrupt value */ + + acpi_rs_move_data(aml->extended_irq.interrupt_number, + resource->data.extended_irq.interrupts, + (u16) resource->data.extended_irq.interrupt_count, + ACPI_MOVE_TYPE_32_TO_32); /* Resource Source Index and Resource Source are optional */ - if (0 != resource->data.extended_irq.resource_source.string_length) { - *buffer = - (u8) resource->data.extended_irq.resource_source.index; - buffer += 1; + descriptor_length = acpi_rs_set_resource_source(aml, descriptor_length, + &resource->data. + extended_irq. + resource_source); - /* Copy the string */ + /* Complete the AML descriptor header */ - ACPI_STRCPY((char *)buffer, - resource->data.extended_irq.resource_source. - string_ptr); - - /* - * Buffer needs to be set to the length of the string + one for the - * terminating null - */ - buffer += - (acpi_size) (ACPI_STRLEN - (resource->data.extended_irq.resource_source. - string_ptr) + 1); - } - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - - /* - * Set the length field to the number of bytes consumed - * minus the header size (3 bytes) - */ - *length_field = (u16) (*bytes_consumed - 3); + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_EXTENDED_IRQ, + descriptor_length, aml); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 87e75349dd0a..f72d42e0927b 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -47,106 +47,70 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rslist") -/* Dispatch table for convert-to-stream functions */ -typedef -acpi_status(*ACPI_STREAM_HANDLER) (struct acpi_resource * resource, - u8 ** output_buffer, - acpi_size * bytes_consumed); - -static ACPI_STREAM_HANDLER acpi_gbl_stream_dispatch[] = { - acpi_rs_irq_stream, /* ACPI_RSTYPE_IRQ */ - acpi_rs_dma_stream, /* ACPI_RSTYPE_DMA */ - acpi_rs_start_depend_fns_stream, /* ACPI_RSTYPE_START_DPF */ - acpi_rs_end_depend_fns_stream, /* ACPI_RSTYPE_END_DPF */ - acpi_rs_io_stream, /* ACPI_RSTYPE_IO */ - acpi_rs_fixed_io_stream, /* ACPI_RSTYPE_FIXED_IO */ - acpi_rs_vendor_stream, /* ACPI_RSTYPE_VENDOR */ - acpi_rs_end_tag_stream, /* ACPI_RSTYPE_END_TAG */ - acpi_rs_memory24_stream, /* ACPI_RSTYPE_MEM24 */ - acpi_rs_memory32_range_stream, /* ACPI_RSTYPE_MEM32 */ - acpi_rs_fixed_memory32_stream, /* ACPI_RSTYPE_FIXED_MEM32 */ - acpi_rs_address16_stream, /* ACPI_RSTYPE_ADDRESS16 */ - acpi_rs_address32_stream, /* ACPI_RSTYPE_ADDRESS32 */ - acpi_rs_address64_stream, /* ACPI_RSTYPE_ADDRESS64 */ - acpi_rs_extended_irq_stream, /* ACPI_RSTYPE_EXT_IRQ */ - acpi_rs_generic_register_stream /* ACPI_RSTYPE_GENERIC_REG */ -}; - -/* Dispatch tables for convert-to-resource functions */ - -typedef -acpi_status(*ACPI_RESOURCE_HANDLER) (u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size); - -static ACPI_RESOURCE_HANDLER acpi_gbl_sm_resource_dispatch[] = { - NULL, /* 0x00, Reserved */ - NULL, /* 0x01, Reserved */ - NULL, /* 0x02, Reserved */ - NULL, /* 0x03, Reserved */ - acpi_rs_irq_resource, /* ACPI_RDESC_TYPE_IRQ_FORMAT */ - acpi_rs_dma_resource, /* ACPI_RDESC_TYPE_DMA_FORMAT */ - acpi_rs_start_depend_fns_resource, /* ACPI_RDESC_TYPE_START_DEPENDENT */ - acpi_rs_end_depend_fns_resource, /* ACPI_RDESC_TYPE_END_DEPENDENT */ - acpi_rs_io_resource, /* ACPI_RDESC_TYPE_IO_PORT */ - acpi_rs_fixed_io_resource, /* ACPI_RDESC_TYPE_FIXED_IO_PORT */ - NULL, /* 0x0A, Reserved */ - NULL, /* 0x0B, Reserved */ - NULL, /* 0x0C, Reserved */ - NULL, /* 0x0D, Reserved */ - acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_SMALL_VENDOR */ - acpi_rs_end_tag_resource /* ACPI_RDESC_TYPE_END_TAG */ -}; - -static ACPI_RESOURCE_HANDLER acpi_gbl_lg_resource_dispatch[] = { - NULL, /* 0x00, Reserved */ - acpi_rs_memory24_resource, /* ACPI_RDESC_TYPE_MEMORY_24 */ - acpi_rs_generic_register_resource, /* ACPI_RDESC_TYPE_GENERIC_REGISTER */ - NULL, /* 0x03, Reserved */ - acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_LARGE_VENDOR */ - acpi_rs_memory32_range_resource, /* ACPI_RDESC_TYPE_MEMORY_32 */ - acpi_rs_fixed_memory32_resource, /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */ - acpi_rs_address32_resource, /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */ - acpi_rs_address16_resource, /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */ - acpi_rs_extended_irq_resource, /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */ - acpi_rs_address64_resource, /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */ - acpi_rs_address64_resource /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */ -}; - /* Local prototypes */ +static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); -static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); +static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml); /******************************************************************************* * - * FUNCTION: acpi_rs_get_resource_type + * FUNCTION: acpi_rs_validate_resource_length * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor + * PARAMETERS: Aml - Pointer to the AML resource descriptor * - * RETURN: The Resource Type with no extraneous bits (except the large/ - * small bit -- left alone) + * RETURN: Status - AE_OK if the resource length appears valid * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. + * DESCRIPTION: Validate the resource_length. Fixed-length descriptors must + * have the exact length; variable-length descriptors must be + * at least as long as the minimum. Certain Small descriptors + * can vary in size by at most one byte. * ******************************************************************************/ -u8 acpi_rs_get_resource_type(u8 resource_type) +static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) { + struct acpi_resource_info *resource_info; + u16 minimum_aml_resource_length; + u16 resource_length; + ACPI_FUNCTION_ENTRY(); - /* Determine if this is a small or large resource */ + /* Get the size and type info about this resource descriptor */ - if (resource_type & ACPI_RDESC_TYPE_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - return (resource_type); - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - return ((u8) (resource_type & ACPI_RDESC_SMALL_MASK)); + resource_info = + acpi_rs_get_resource_info(aml->small_header.descriptor_type); + if (!resource_info) { + return (AE_AML_INVALID_RESOURCE_TYPE); } + + resource_length = acpi_rs_get_resource_length(aml); + minimum_aml_resource_length = + resource_info->minimum_aml_resource_length; + + /* Validate based upon the type of resource, fixed length or variable */ + + if (resource_info->length_type == ACPI_FIXED_LENGTH) { + /* Fixed length resource, length must match exactly */ + + if (resource_length != minimum_aml_resource_length) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + } else if (resource_info->length_type == ACPI_VARIABLE_LENGTH) { + /* Variable length resource, must be at least the minimum */ + + if (resource_length < minimum_aml_resource_length) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + } else { + /* Small variable length resource, allowed to be (Min) or (Min-1) */ + + if ((resource_length > minimum_aml_resource_length) || + (resource_length < (minimum_aml_resource_length - 1))) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + } + + return (AE_OK); } /******************************************************************************* @@ -162,38 +126,38 @@ u8 acpi_rs_get_resource_type(u8 resource_type) * ******************************************************************************/ -static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) +static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) { ACPI_FUNCTION_ENTRY(); /* Determine if this is a small or large resource */ - if (resource_type & ACPI_RDESC_TYPE_LARGE) { + if (resource_type & ACPI_RESOURCE_NAME_LARGE) { /* Large Resource Type -- bits 6:0 contain the name */ - if (resource_type > ACPI_RDESC_LARGE_MAX) { + if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { return (NULL); } - return (acpi_gbl_lg_resource_dispatch[(resource_type & - ACPI_RDESC_LARGE_MASK)]); + return (acpi_gbl_lg_get_resource_dispatch[(resource_type & + ACPI_RESOURCE_NAME_LARGE_MASK)]); } else { /* Small Resource Type -- bits 6:3 contain the name */ - return (acpi_gbl_sm_resource_dispatch[((resource_type & - ACPI_RDESC_SMALL_MASK) - >> 3)]); + return (acpi_gbl_sm_get_resource_dispatch[((resource_type & + ACPI_RESOURCE_NAME_SMALL_MASK) + >> 3)]); } } /******************************************************************************* * - * FUNCTION: acpi_rs_byte_stream_to_list + * FUNCTION: acpi_rs_convert_aml_to_resources * - * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream - * byte_stream_buffer_length - Length of byte_stream_buffer - * output_buffer - Pointer to the buffer that will - * contain the output structures + * PARAMETERS: aml_buffer - Pointer to the resource byte stream + * aml_buffer_length - Length of aml_buffer + * output_buffer - Pointer to the buffer that will + * contain the output structures * * RETURN: Status * @@ -203,40 +167,63 @@ static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) ******************************************************************************/ acpi_status -acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, - u32 byte_stream_buffer_length, u8 * output_buffer) +acpi_rs_convert_aml_to_resources(u8 * aml_buffer, + u32 aml_buffer_length, u8 * output_buffer) { u8 *buffer = output_buffer; acpi_status status; acpi_size bytes_parsed = 0; - acpi_size bytes_consumed = 0; - acpi_size structure_size = 0; struct acpi_resource *resource; - ACPI_RESOURCE_HANDLER handler; + u16 resource_length; + u32 descriptor_length; + ACPI_GET_RESOURCE_HANDLER handler; - ACPI_FUNCTION_TRACE("rs_byte_stream_to_list"); + ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); /* Loop until end-of-buffer or an end_tag is found */ - while (bytes_parsed < byte_stream_buffer_length) { + while (bytes_parsed < aml_buffer_length) { /* Get the handler associated with this Descriptor Type */ - handler = acpi_rs_get_resource_handler(*byte_stream_buffer); - if (handler) { - /* Convert a byte stream resource to local resource struct */ + handler = acpi_rs_get_resource_handler(*aml_buffer); + if (!handler) { + /* No handler indicates invalid resource type */ - status = handler(byte_stream_buffer, &bytes_consumed, - &buffer, &structure_size); - } else { - /* Invalid resource type */ - - status = AE_AML_INVALID_RESOURCE_TYPE; + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } + resource_length = + acpi_rs_get_resource_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); + + descriptor_length = + acpi_rs_get_descriptor_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); + + /* + * Perform limited validation of the resource length, based upon + * what we know about the resource type + */ + status = + acpi_rs_validate_resource_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } + /* Convert a byte stream resource to local resource struct */ + + status = handler(ACPI_CAST_PTR(union aml_resource, aml_buffer), + resource_length, + ACPI_CAST_PTR(struct acpi_resource, buffer)); + if (ACPI_FAILURE(status)) { + ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status))); + return_ACPI_STATUS(status); + } + /* Set the aligned length of the new resource descriptor */ resource = ACPI_CAST_PTR(struct acpi_resource, buffer); @@ -245,19 +232,19 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, /* Normal exit on completion of an end_tag resource descriptor */ - if (acpi_rs_get_resource_type(*byte_stream_buffer) == - ACPI_RDESC_TYPE_END_TAG) { + if (acpi_rs_get_resource_type(*aml_buffer) == + ACPI_RESOURCE_NAME_END_TAG) { return_ACPI_STATUS(AE_OK); } /* Update counter and point to the next input resource */ - bytes_parsed += bytes_consumed; - byte_stream_buffer += bytes_consumed; + bytes_parsed += descriptor_length; + aml_buffer += descriptor_length; /* Point to the next structure in the output buffer */ - buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); + buffer += resource->length; } /* Completed buffer, but did not find an end_tag resource descriptor */ @@ -267,17 +254,15 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, /******************************************************************************* * - * FUNCTION: acpi_rs_list_to_byte_stream + * FUNCTION: acpi_rs_convert_resources_to_aml * - * PARAMETERS: Resource - Pointer to the resource linked list - * byte_steam_size_needed - Calculated size of the byte stream - * needed from calling - * acpi_rs_get_byte_stream_length() - * The size of the output_buffer is - * guaranteed to be >= - * byte_stream_size_needed - * output_buffer - Pointer to the buffer that will - * contain the byte stream + * PARAMETERS: Resource - Pointer to the resource linked list + * aml_size_needed - Calculated size of the byte stream + * needed from calling acpi_rs_get_aml_length() + * The size of the output_buffer is + * guaranteed to be >= aml_size_needed + * output_buffer - Pointer to the buffer that will + * contain the byte stream * * RETURN: Status * @@ -287,52 +272,69 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, ******************************************************************************/ acpi_status -acpi_rs_list_to_byte_stream(struct acpi_resource *resource, - acpi_size byte_stream_size_needed, - u8 * output_buffer) +acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, + acpi_size aml_size_needed, u8 * output_buffer) { - u8 *buffer = output_buffer; - acpi_size bytes_consumed = 0; + u8 *aml_buffer = output_buffer; acpi_status status; - ACPI_FUNCTION_TRACE("rs_list_to_byte_stream"); + ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); /* Convert each resource descriptor in the list */ while (1) { - /* Validate Type before dispatch */ + /* Validate Resource Descriptor Type before dispatch */ - if (resource->type > ACPI_RSTYPE_MAX) { + if (resource->type > ACPI_RESOURCE_TYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n", resource->type)); return_ACPI_STATUS(AE_BAD_DATA); } - /* Perform the conversion, per resource type */ + /* Perform the conversion per resource type */ - status = acpi_gbl_stream_dispatch[resource->type] (resource, - &buffer, - &bytes_consumed); + status = + acpi_gbl_set_resource_dispatch[resource->type] (resource, + ACPI_CAST_PTR + (union + aml_resource, + aml_buffer)); + if (ACPI_FAILURE(status)) { + ACPI_REPORT_ERROR(("Could not convert resource (type %X) to AML, %s\n", resource->type, acpi_format_exception(status))); + return_ACPI_STATUS(status); + } + + /* Perform final sanity check on the new AML resource descriptor */ + + status = + acpi_rs_validate_resource_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Check for end-of-list */ + /* Check for end-of-list, normal exit */ - if (resource->type == ACPI_RSTYPE_END_TAG) { - /* An End Tag indicates the end of the Resource Template */ + if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + /* An End Tag indicates the end of the input Resource Template */ return_ACPI_STATUS(AE_OK); } - /* Set the Buffer to point to the next (output) resource descriptor */ + /* Extract the total length of the new descriptor */ + /* Set the aml_buffer to point to the next (output) resource descriptor */ - buffer += bytes_consumed; + aml_buffer += + acpi_rs_get_descriptor_length(ACPI_CAST_PTR + (union aml_resource, + aml_buffer)); - /* Point to the next input resource object */ + /* Point to the next input resource descriptor */ - resource = ACPI_PTR_ADD(struct acpi_resource, - resource, resource->length); + resource = + ACPI_PTR_ADD(struct acpi_resource, resource, + resource->length); } } diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index 418f1afb10a3..47e979e7ba35 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c @@ -49,446 +49,260 @@ ACPI_MODULE_NAME("rsmemory") /******************************************************************************* * - * FUNCTION: acpi_rs_memory24_resource + * FUNCTION: acpi_rs_get_memory24 * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_memory24_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_get_memory24(union aml_resource * aml, + u16 aml_resource_length, struct acpi_resource * resource) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24); + ACPI_FUNCTION_TRACE("rs_get_memory24"); - ACPI_FUNCTION_TRACE("rs_memory24_resource"); + /* Get the Read/Write bit */ - /* Point past the Descriptor to get the number of bytes consumed */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - buffer += 2; - *bytes_consumed = (acpi_size) temp16 + 3; - output_struct->type = ACPI_RSTYPE_MEM24; - - /* Check Byte 3 the Read/Write bit */ - - temp8 = *buffer; - buffer += 1; - output_struct->data.memory24.read_write_attribute = temp8 & 0x01; - - /* Get min_base_address (Bytes 4-5) */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - output_struct->data.memory24.min_base_address = temp16; - - /* Get max_base_address (Bytes 6-7) */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - output_struct->data.memory24.max_base_address = temp16; - - /* Get Alignment (Bytes 8-9) */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - output_struct->data.memory24.alignment = temp16; - - /* Get range_length (Bytes 10-11) */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - output_struct->data.memory24.range_length = temp16; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_memory24_stream - * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_memory24_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_memory24_stream"); - - /* The Descriptor Type field is static */ - - *buffer = ACPI_RDESC_TYPE_MEMORY_24; - buffer += 1; - - /* The length field is static */ - - temp16 = 0x09; - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set the Information Byte */ - - temp8 = (u8) (resource->data.memory24.read_write_attribute & 0x01); - *buffer = temp8; - buffer += 1; - - /* Set the Range minimum base address */ - - ACPI_MOVE_32_TO_16(buffer, &resource->data.memory24.min_base_address); - buffer += 2; - - /* Set the Range maximum base address */ - - ACPI_MOVE_32_TO_16(buffer, &resource->data.memory24.max_base_address); - buffer += 2; - - /* Set the base alignment */ - - ACPI_MOVE_32_TO_16(buffer, &resource->data.memory24.alignment); - buffer += 2; - - /* Set the range length */ - - ACPI_MOVE_32_TO_16(buffer, &resource->data.memory24.range_length); - buffer += 2; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_memory32_range_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. - * - ******************************************************************************/ - -acpi_status -acpi_rs_memory32_range_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32); - - ACPI_FUNCTION_TRACE("rs_memory32_range_resource"); - - /* Point past the Descriptor to get the number of bytes consumed */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - buffer += 2; - *bytes_consumed = (acpi_size) temp16 + 3; - output_struct->type = ACPI_RSTYPE_MEM32; + resource->data.memory24.read_write_attribute = + (aml->memory24.information & 0x01); /* - * Point to the place in the output buffer where the data portion will - * begin. - * 1. Set the RESOURCE_DATA * Data to point to its own address, then - * 2. Set the pointer to the next address. - * - * NOTE: output_struct->Data is cast to u8, otherwise, this addition adds - * 4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8) + * Get the following contiguous fields from the AML descriptor: + * Minimum Base Address + * Maximum Base Address + * Address Base Alignment + * Range Length */ + acpi_rs_move_data(&resource->data.memory24.minimum, + &aml->memory24.minimum, 4, ACPI_MOVE_TYPE_16_TO_32); - /* Check Byte 3 the Read/Write bit */ + /* Complete the resource header */ - temp8 = *buffer; - buffer += 1; - - output_struct->data.memory32.read_write_attribute = temp8 & 0x01; - - /* Get min_base_address (Bytes 4-7) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.memory32.min_base_address, - buffer); - buffer += 4; - - /* Get max_base_address (Bytes 8-11) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.memory32.max_base_address, - buffer); - buffer += 4; - - /* Get Alignment (Bytes 12-15) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.memory32.alignment, buffer); - buffer += 4; - - /* Get range_length (Bytes 16-19) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.memory32.range_length, buffer); - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_MEMORY24; + resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_memory24); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_fixed_memory32_resource + * FUNCTION: acpi_rs_set_memory24 * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_set_memory24(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32); - - ACPI_FUNCTION_TRACE("rs_fixed_memory32_resource"); - - /* Point past the Descriptor to get the number of bytes consumed */ - - buffer += 1; - ACPI_MOVE_16_TO_16(&temp16, buffer); - - buffer += 2; - *bytes_consumed = (acpi_size) temp16 + 3; - output_struct->type = ACPI_RSTYPE_FIXED_MEM32; - - /* Check Byte 3 the Read/Write bit */ - - temp8 = *buffer; - buffer += 1; - output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01; - - /* Get range_base_address (Bytes 4-7) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32. - range_base_address, buffer); - buffer += 4; - - /* Get range_length (Bytes 8-11) */ - - ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32.range_length, - buffer); - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_memory32_range_stream - * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_memory32_range_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_memory32_range_stream"); - - /* The Descriptor Type field is static */ - - *buffer = ACPI_RDESC_TYPE_MEMORY_32; - buffer += 1; - - /* The length field is static */ - - temp16 = 0x11; - - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; + ACPI_FUNCTION_TRACE("rs_set_memory24"); /* Set the Information Byte */ - temp8 = (u8) (resource->data.memory32.read_write_attribute & 0x01); - *buffer = temp8; - buffer += 1; + aml->memory24.information = (u8) + (resource->data.memory24.read_write_attribute & 0x01); - /* Set the Range minimum base address */ + /* + * Set the following contiguous fields in the AML descriptor: + * Minimum Base Address + * Maximum Base Address + * Address Base Alignment + * Range Length + */ + acpi_rs_move_data(&aml->memory24.minimum, + &resource->data.memory24.minimum, 4, + ACPI_MOVE_TYPE_32_TO_16); - ACPI_MOVE_32_TO_32(buffer, &resource->data.memory32.min_base_address); - buffer += 4; + /* Complete the AML descriptor header */ - /* Set the Range maximum base address */ - - ACPI_MOVE_32_TO_32(buffer, &resource->data.memory32.max_base_address); - buffer += 4; - - /* Set the base alignment */ - - ACPI_MOVE_32_TO_32(buffer, &resource->data.memory32.alignment); - buffer += 4; - - /* Set the range length */ - - ACPI_MOVE_32_TO_32(buffer, &resource->data.memory32.range_length); - buffer += 4; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_MEMORY24, + sizeof(struct aml_resource_memory24), aml); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_fixed_memory32_stream + * FUNCTION: acpi_rs_get_memory32 * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_fixed_memory32_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_get_memory32(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; + ACPI_FUNCTION_TRACE("rs_get_memory32"); - ACPI_FUNCTION_TRACE("rs_fixed_memory32_stream"); + /* Get the Read/Write bit */ - /* The Descriptor Type field is static */ + resource->data.memory32.read_write_attribute = + (aml->memory32.information & 0x01); - *buffer = ACPI_RDESC_TYPE_FIXED_MEMORY_32; - buffer += 1; + /* + * Get the following contiguous fields from the AML descriptor: + * Minimum Base Address + * Maximum Base Address + * Address Base Alignment + * Range Length + */ + acpi_rs_move_data(&resource->data.memory32.minimum, + &aml->memory32.minimum, 4, ACPI_MOVE_TYPE_32_TO_32); - /* The length field is static */ + /* Complete the resource header */ - temp16 = 0x09; + resource->type = ACPI_RESOURCE_TYPE_MEMORY32; + resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_memory32); + return_ACPI_STATUS(AE_OK); +} - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_memory32 + * + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. + * + ******************************************************************************/ + +acpi_status +acpi_rs_set_memory32(struct acpi_resource *resource, union aml_resource *aml) +{ + ACPI_FUNCTION_TRACE("rs_set_memory32"); /* Set the Information Byte */ - temp8 = - (u8) (resource->data.fixed_memory32.read_write_attribute & 0x01); - *buffer = temp8; - buffer += 1; + aml->memory32.information = (u8) + (resource->data.memory32.read_write_attribute & 0x01); - /* Set the Range base address */ + /* + * Set the following contiguous fields in the AML descriptor: + * Minimum Base Address + * Maximum Base Address + * Address Base Alignment + * Range Length + */ + acpi_rs_move_data(&aml->memory32.minimum, + &resource->data.memory32.minimum, 4, + ACPI_MOVE_TYPE_32_TO_32); - ACPI_MOVE_32_TO_32(buffer, - &resource->data.fixed_memory32.range_base_address); - buffer += 4; + /* Complete the AML descriptor header */ - /* Set the range length */ - - ACPI_MOVE_32_TO_32(buffer, &resource->data.fixed_memory32.range_length); - buffer += 4; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_MEMORY32, + sizeof(struct aml_resource_memory32), aml); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_fixed_memory32 + * + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. + * + ******************************************************************************/ + +acpi_status +acpi_rs_get_fixed_memory32(union aml_resource *aml, + u16 aml_resource_length, + struct acpi_resource *resource) +{ + ACPI_FUNCTION_TRACE("rs_get_fixed_memory32"); + + /* Get the Read/Write bit */ + + resource->data.fixed_memory32.read_write_attribute = + (aml->fixed_memory32.information & 0x01); + + /* + * Get the following contiguous fields from the AML descriptor: + * Base Address + * Range Length + */ + ACPI_MOVE_32_TO_32(&resource->data.fixed_memory32.address, + &aml->fixed_memory32.address); + ACPI_MOVE_32_TO_32(&resource->data.fixed_memory32.address_length, + &aml->fixed_memory32.address_length); + + /* Complete the resource header */ + + resource->type = ACPI_RESOURCE_TYPE_FIXED_MEMORY32; + resource->length = + ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_memory32); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_fixed_memory32 + * + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. + * + ******************************************************************************/ + +acpi_status +acpi_rs_set_fixed_memory32(struct acpi_resource *resource, + union aml_resource *aml) +{ + ACPI_FUNCTION_TRACE("rs_set_fixed_memory32"); + + /* Set the Information Byte */ + + aml->fixed_memory32.information = (u8) + (resource->data.fixed_memory32.read_write_attribute & 0x01); + + /* + * Set the following contiguous fields in the AML descriptor: + * Base Address + * Range Length + */ + ACPI_MOVE_32_TO_32(&aml->fixed_memory32.address, + &resource->data.fixed_memory32.address); + ACPI_MOVE_32_TO_32(&aml->fixed_memory32.address_length, + &resource->data.fixed_memory32.address_length); + + /* Complete the AML descriptor header */ + + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_FIXED_MEMORY32, + sizeof(struct aml_resource_fixed_memory32), + aml); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index fa7f5a85b61d..337a0f01cb23 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -49,578 +49,288 @@ ACPI_MODULE_NAME("rsmisc") /******************************************************************************* * - * FUNCTION: acpi_rs_generic_register_resource + * FUNCTION: acpi_rs_get_generic_reg * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_generic_register_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size) +acpi_rs_get_generic_reg(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16; - u8 temp8; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg); - - ACPI_FUNCTION_TRACE("rs_generic_register_resource"); - - /* Byte 0 is the Descriptor Type */ - - buffer += 1; - - /* Get the Descriptor Length field (Bytes 1-2) */ - - ACPI_MOVE_16_TO_16(&temp16, buffer); - buffer += 2; - - /* Validate the descriptor length */ - - if (temp16 != 12) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } - - /* The number of bytes consumed is fixed (12 + 3) */ - - *bytes_consumed = 15; - - /* Fill out the structure */ - - output_struct->type = ACPI_RSTYPE_GENERIC_REG; - - /* Get space_id (Byte 3) */ - - temp8 = *buffer; - output_struct->data.generic_reg.space_id = temp8; - buffer += 1; - - /* Get register_bit_width (Byte 4) */ - - temp8 = *buffer; - output_struct->data.generic_reg.bit_width = temp8; - buffer += 1; - - /* Get register_bit_offset (Byte 5) */ - - temp8 = *buffer; - output_struct->data.generic_reg.bit_offset = temp8; - buffer += 1; - - /* Get address_size (Byte 6) */ - - temp8 = *buffer; - output_struct->data.generic_reg.address_size = temp8; - buffer += 1; - - /* Get register_address (Bytes 7-14) */ - - ACPI_MOVE_64_TO_64(&output_struct->data.generic_reg.address, buffer); - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_generic_register_stream - * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_generic_register_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u16 temp16; - - ACPI_FUNCTION_TRACE("rs_generic_register_stream"); - - /* Set the Descriptor Type (Byte 0) */ - - *buffer = ACPI_RDESC_TYPE_GENERIC_REGISTER; - buffer += 1; - - /* Set the Descriptor Length (Bytes 1-2) */ - - temp16 = 12; - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; - - /* Set space_id (Byte 3) */ - - *buffer = (u8) resource->data.generic_reg.space_id; - buffer += 1; - - /* Set register_bit_width (Byte 4) */ - - *buffer = (u8) resource->data.generic_reg.bit_width; - buffer += 1; - - /* Set register_bit_offset (Byte 5) */ - - *buffer = (u8) resource->data.generic_reg.bit_offset; - buffer += 1; - - /* Set address_size (Byte 6) */ - - *buffer = (u8) resource->data.generic_reg.address_size; - buffer += 1; - - /* Set register_address (Bytes 7-14) */ - - ACPI_MOVE_64_TO_64(buffer, &resource->data.generic_reg.address); - buffer += 8; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_end_tag_resource - * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. - * - ******************************************************************************/ - -acpi_status -acpi_rs_end_tag_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) -{ - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = ACPI_RESOURCE_LENGTH; - - ACPI_FUNCTION_TRACE("rs_end_tag_resource"); - - /* The number of bytes consumed is static */ - - *bytes_consumed = 2; - - /* Fill out the structure */ - - output_struct->type = ACPI_RSTYPE_END_TAG; - - /* Set the Length parameter */ - - output_struct->length = 0; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_end_tag_stream - * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_end_tag_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_end_tag_stream"); - - /* The Descriptor Type field is static */ - - *buffer = ACPI_RDESC_TYPE_END_TAG | 0x01; - buffer += 1; + ACPI_FUNCTION_TRACE("rs_get_generic_reg"); /* - * Set the Checksum - zero means that the resource data is treated as if - * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8) + * Get the following fields from the AML descriptor: + * Address Space ID + * Register Bit Width + * Register Bit Offset + * Access Size + * Register Address */ - temp8 = 0; + resource->data.generic_reg.space_id = aml->generic_reg.address_space_id; + resource->data.generic_reg.bit_width = aml->generic_reg.bit_width; + resource->data.generic_reg.bit_offset = aml->generic_reg.bit_offset; + resource->data.generic_reg.access_size = aml->generic_reg.access_size; + ACPI_MOVE_64_TO_64(&resource->data.generic_reg.address, + &aml->generic_reg.address); - *buffer = temp8; - buffer += 1; + /* Complete the resource header */ - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + resource->type = ACPI_RESOURCE_TYPE_GENERIC_REGISTER; + resource->length = + ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_register); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_vendor_resource + * FUNCTION: acpi_rs_set_generic_reg * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_vendor_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_set_generic_reg(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor); + ACPI_FUNCTION_TRACE("rs_set_generic_reg"); - ACPI_FUNCTION_TRACE("rs_vendor_resource"); + /* + * Set the following fields in the AML descriptor: + * Address Space ID + * Register Bit Width + * Register Bit Offset + * Access Size + * Register Address + */ + aml->generic_reg.address_space_id = + (u8) resource->data.generic_reg.space_id; + aml->generic_reg.bit_width = (u8) resource->data.generic_reg.bit_width; + aml->generic_reg.bit_offset = + (u8) resource->data.generic_reg.bit_offset; + aml->generic_reg.access_size = + (u8) resource->data.generic_reg.access_size; + ACPI_MOVE_64_TO_64(&aml->generic_reg.address, + &resource->data.generic_reg.address); - /* Dereference the Descriptor to find if this is a large or small item. */ + /* Complete the AML descriptor header */ - temp8 = *buffer; + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_GENERIC_REGISTER, + sizeof(struct + aml_resource_generic_register), aml); + return_ACPI_STATUS(AE_OK); +} - if (temp8 & ACPI_RDESC_TYPE_LARGE) { - /* Large Item, point to the length field */ +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_vendor + * + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. + * + ******************************************************************************/ - buffer += 1; +acpi_status +acpi_rs_get_vendor(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) +{ + u8 *aml_byte_data; - /* Dereference */ + ACPI_FUNCTION_TRACE("rs_get_vendor"); - ACPI_MOVE_16_TO_16(&temp16, buffer); + /* Determine if this is a large or small vendor specific item */ - /* Calculate bytes consumed */ + if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large item, Point to the first vendor byte */ - *bytes_consumed = (acpi_size) temp16 + 3; - - /* Point to the first vendor byte */ - - buffer += 2; + aml_byte_data = + ((u8 *) aml) + sizeof(struct aml_resource_large_header); } else { - /* Small Item, dereference the size */ + /* Small item, Point to the first vendor byte */ - temp16 = (u8) (*buffer & 0x07); - - /* Calculate bytes consumed */ - - *bytes_consumed = (acpi_size) temp16 + 1; - - /* Point to the first vendor byte */ - - buffer += 1; + aml_byte_data = + ((u8 *) aml) + sizeof(struct aml_resource_small_header); } - output_struct->type = ACPI_RSTYPE_VENDOR; - output_struct->data.vendor_specific.length = temp16; + /* Copy the vendor-specific bytes */ - for (index = 0; index < temp16; index++) { - output_struct->data.vendor_specific.reserved[index] = *buffer; - buffer += 1; - } + ACPI_MEMCPY(resource->data.vendor.byte_data, + aml_byte_data, aml_resource_length); + resource->data.vendor.byte_length = aml_resource_length; /* * In order for the struct_size to fall on a 32-bit boundary, * calculate the length of the vendor string and expand the * struct_size to the next 32-bit boundary. */ - struct_size += ACPI_ROUND_UP_to_32_bITS(temp16); - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_VENDOR; + resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + + ACPI_ROUND_UP_to_32_bITS(aml_resource_length); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_vendor_stream + * FUNCTION: acpi_rs_set_vendor * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_vendor_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_set_vendor(struct acpi_resource *resource, union aml_resource *aml) { - u8 *buffer = *output_buffer; - u16 temp16 = 0; - u8 temp8 = 0; - u8 index; + u32 resource_length; + u8 *source; + u8 *destination; - ACPI_FUNCTION_TRACE("rs_vendor_stream"); + ACPI_FUNCTION_TRACE("rs_set_vendor"); - /* Dereference the length to find if this is a large or small item. */ + resource_length = resource->data.vendor.byte_length; + source = ACPI_CAST_PTR(u8, resource->data.vendor.byte_data); - if (resource->data.vendor_specific.length > 7) { - /* Large Item, Set the descriptor field and length bytes */ + /* Length determines if this is a large or small resource */ - *buffer = ACPI_RDESC_TYPE_LARGE_VENDOR; - buffer += 1; + if (resource_length > 7) { + /* Large item, get pointer to the data part of the descriptor */ - temp16 = (u16) resource->data.vendor_specific.length; + destination = + ((u8 *) aml) + sizeof(struct aml_resource_large_header); - ACPI_MOVE_16_TO_16(buffer, &temp16); - buffer += 2; + /* Complete the AML descriptor header */ + + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_VENDOR_LARGE, + (u32) (resource_length + + sizeof(struct + aml_resource_large_header)), + aml); } else { - /* Small Item, Set the descriptor field */ + /* Small item, get pointer to the data part of the descriptor */ - temp8 = ACPI_RDESC_TYPE_SMALL_VENDOR; - temp8 |= (u8) resource->data.vendor_specific.length; + destination = + ((u8 *) aml) + sizeof(struct aml_resource_small_header); - *buffer = temp8; - buffer += 1; + /* Complete the AML descriptor header */ + + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_VENDOR_SMALL, + (u32) (resource_length + + sizeof(struct + aml_resource_small_header)), + aml); } - /* Loop through all of the Vendor Specific fields */ + /* Copy the vendor-specific bytes */ - for (index = 0; index < resource->data.vendor_specific.length; index++) { - temp8 = resource->data.vendor_specific.reserved[index]; - - *buffer = temp8; - buffer += 1; - } - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + ACPI_MEMCPY(destination, source, resource_length); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_start_depend_fns_resource + * FUNCTION: acpi_rs_get_start_dpf * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size) +acpi_rs_get_start_dpf(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = byte_stream_buffer; - struct acpi_resource *output_struct = (void *)*output_buffer; - u8 temp8 = 0; - acpi_size struct_size = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf); + ACPI_FUNCTION_TRACE("rs_get_start_dpf"); - ACPI_FUNCTION_TRACE("rs_start_depend_fns_resource"); + /* Get the flags byte if present */ - /* The number of bytes consumed are found in the descriptor (Bits:0-1) */ + if (aml_resource_length == 1) { + /* Get the Compatibility priority */ - temp8 = *buffer; + resource->data.start_dpf.compatibility_priority = + (aml->start_dpf.flags & 0x03); - *bytes_consumed = (temp8 & 0x01) + 1; - - output_struct->type = ACPI_RSTYPE_START_DPF; - - /* Point to Byte 1 if it is used */ - - if (2 == *bytes_consumed) { - buffer += 1; - temp8 = *buffer; - - /* Check Compatibility priority */ - - output_struct->data.start_dpf.compatibility_priority = - temp8 & 0x03; - - if (3 == output_struct->data.start_dpf.compatibility_priority) { + if (resource->data.start_dpf.compatibility_priority >= 3) { return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); } - /* Check Performance/Robustness preference */ + /* Get the Performance/Robustness preference */ - output_struct->data.start_dpf.performance_robustness = - (temp8 >> 2) & 0x03; + resource->data.start_dpf.performance_robustness = + ((aml->start_dpf.flags >> 2) & 0x03); - if (3 == output_struct->data.start_dpf.performance_robustness) { + if (resource->data.start_dpf.performance_robustness >= 3) { return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); } } else { - output_struct->data.start_dpf.compatibility_priority = + /* start_dependent_no_pri(), no flags byte, set defaults */ + + resource->data.start_dpf.compatibility_priority = ACPI_ACCEPTABLE_CONFIGURATION; - output_struct->data.start_dpf.performance_robustness = + resource->data.start_dpf.performance_robustness = ACPI_ACCEPTABLE_CONFIGURATION; } - /* Set the Length parameter */ + /* Complete the resource header */ - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; + resource->type = ACPI_RESOURCE_TYPE_START_DEPENDENT; + resource->length = + ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dependent); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_end_depend_fns_resource + * FUNCTION: acpi_rs_set_start_dpf * - * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte - * stream - * bytes_consumed - Pointer to where the number of bytes - * consumed the byte_stream_buffer is - * returned - * output_buffer - Pointer to the return data buffer - * structure_size - Pointer to where the number of bytes - * in the return data struct is returned + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned * * RETURN: Status * - * DESCRIPTION: Take the resource byte stream and fill out the appropriate - * structure pointed to by the output_buffer. Return the - * number of bytes consumed from the byte stream. + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. * ******************************************************************************/ acpi_status -acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size) +acpi_rs_set_start_dpf(struct acpi_resource *resource, union aml_resource *aml) { - struct acpi_resource *output_struct = (void *)*output_buffer; - acpi_size struct_size = ACPI_RESOURCE_LENGTH; - - ACPI_FUNCTION_TRACE("rs_end_depend_fns_resource"); - - /* The number of bytes consumed is static */ - - *bytes_consumed = 1; - - /* Fill out the structure */ - - output_struct->type = ACPI_RSTYPE_END_DPF; - - /* Set the Length parameter */ - - output_struct->length = (u32) struct_size; - - /* Return the final size of the structure */ - - *structure_size = struct_size; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_start_depend_fns_stream - * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - u32 pointer that is filled with - * the number of bytes of the - * output_buffer used - * - * RETURN: Status - * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream - * - ******************************************************************************/ - -acpi_status -acpi_rs_start_depend_fns_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) -{ - u8 *buffer = *output_buffer; - u8 temp8 = 0; - - ACPI_FUNCTION_TRACE("rs_start_depend_fns_stream"); + ACPI_FUNCTION_TRACE("rs_set_start_dpf"); /* * The descriptor type field is set based upon whether a byte is needed @@ -630,60 +340,141 @@ acpi_rs_start_depend_fns_stream(struct acpi_resource *resource, resource->data.start_dpf.compatibility_priority && ACPI_ACCEPTABLE_CONFIGURATION == resource->data.start_dpf.performance_robustness) { - *buffer = ACPI_RDESC_TYPE_START_DEPENDENT; + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_START_DEPENDENT, + sizeof(struct + aml_resource_start_dependent_noprio), + aml); } else { - *buffer = ACPI_RDESC_TYPE_START_DEPENDENT | 0x01; - buffer += 1; + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_START_DEPENDENT, + sizeof(struct + aml_resource_start_dependent), + aml); - /* Set the Priority Byte Definition */ + /* Set the Flags byte */ - temp8 = 0; - temp8 = (u8) ((resource->data.start_dpf.performance_robustness & - 0x03) << 2); - temp8 |= (resource->data.start_dpf.compatibility_priority & - 0x03); - *buffer = temp8; + aml->start_dpf.flags = (u8) + (((resource->data.start_dpf. + performance_robustness & 0x03) << 2) | (resource->data. + start_dpf. + compatibility_priority + & 0x03)); } - - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_rs_end_depend_fns_stream + * FUNCTION: acpi_rs_get_end_dpf * - * PARAMETERS: Resource - Pointer to the resource linked list - * output_buffer - Pointer to the user's return buffer - * bytes_consumed - Pointer to where the number of bytes - * used in the output_buffer is returned + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned * * RETURN: Status * - * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. * ******************************************************************************/ acpi_status -acpi_rs_end_depend_fns_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed) +acpi_rs_get_end_dpf(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) { - u8 *buffer = *output_buffer; + ACPI_FUNCTION_TRACE("rs_get_end_dpf"); - ACPI_FUNCTION_TRACE("rs_end_depend_fns_stream"); + /* Complete the resource header */ - /* The Descriptor Type field is static */ - - *buffer = ACPI_RDESC_TYPE_END_DEPENDENT; - buffer += 1; - - /* Return the number of bytes consumed in this operation */ - - *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); + resource->type = ACPI_RESOURCE_TYPE_END_DEPENDENT; + resource->length = (u32) ACPI_RESOURCE_LENGTH; + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_end_dpf + * + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. + * + ******************************************************************************/ + +acpi_status +acpi_rs_set_end_dpf(struct acpi_resource *resource, union aml_resource *aml) +{ + ACPI_FUNCTION_TRACE("rs_set_end_dpf"); + + /* Complete the AML descriptor header */ + + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_END_DEPENDENT, + sizeof(struct aml_resource_end_dependent), + aml); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_end_tag + * + * PARAMETERS: Aml - Pointer to the AML resource descriptor + * aml_resource_length - Length of the resource from the AML header + * Resource - Where the internal resource is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding + * internal resource descriptor, simplifying bitflags and handling + * alignment and endian issues if necessary. + * + ******************************************************************************/ + +acpi_status +acpi_rs_get_end_tag(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource) +{ + ACPI_FUNCTION_TRACE("rs_get_end_tag"); + + /* Complete the resource header */ + + resource->type = ACPI_RESOURCE_TYPE_END_TAG; + resource->length = ACPI_RESOURCE_LENGTH; + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_end_tag + * + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. + * + ******************************************************************************/ + +acpi_status +acpi_rs_set_end_tag(struct acpi_resource *resource, union aml_resource *aml) +{ + ACPI_FUNCTION_TRACE("rs_set_end_tag"); + + /* + * Set the Checksum - zero means that the resource data is treated as if + * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8) + */ + aml->end_tag.checksum = 0; + + /* Complete the AML descriptor header */ + + acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_END_TAG, + sizeof(struct aml_resource_end_tag), aml); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 4446778eaf79..9d503de1a349 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -48,6 +48,438 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsutils") +/******************************************************************************* + * + * FUNCTION: acpi_rs_move_data + * + * PARAMETERS: Destination - Pointer to the destination descriptor + * Source - Pointer to the source descriptor + * item_count - How many items to move + * move_type - Byte width + * + * RETURN: None + * + * DESCRIPTION: Move multiple data items from one descriptor to another. Handles + * alignment issues and endian issues if necessary, as configured + * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) + * + ******************************************************************************/ +void +acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) +{ + acpi_native_uint i; + + /* One move per item */ + + for (i = 0; i < item_count; i++) { + switch (move_type) { + case ACPI_MOVE_TYPE_16_TO_32: + ACPI_MOVE_16_TO_32(&((u32 *) destination)[i], + &((u16 *) source)[i]); + break; + + case ACPI_MOVE_TYPE_32_TO_16: + ACPI_MOVE_32_TO_16(&((u16 *) destination)[i], + &((u32 *) source)[i]); + break; + + case ACPI_MOVE_TYPE_32_TO_32: + ACPI_MOVE_32_TO_32(&((u32 *) destination)[i], + &((u32 *) source)[i]); + break; + + case ACPI_MOVE_TYPE_64_TO_64: + ACPI_MOVE_64_TO_64(&((u64 *) destination)[i], + &((u64 *) source)[i]); + break; + + default: + return; + } + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_info + * + * PARAMETERS: resource_type - Byte 0 of a resource descriptor + * + * RETURN: Pointer to the resource conversion handler + * + * DESCRIPTION: Extract the Resource Type/Name from the first byte of + * a resource descriptor. + * + ******************************************************************************/ + +struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type) +{ + struct acpi_resource_info *size_info; + + ACPI_FUNCTION_ENTRY(); + + /* Determine if this is a small or large resource */ + + if (resource_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ + + if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { + return (NULL); + } + + size_info = &acpi_gbl_lg_resource_info[(resource_type & + ACPI_RESOURCE_NAME_LARGE_MASK)]; + } else { + /* Small Resource Type -- bits 6:3 contain the name */ + + size_info = &acpi_gbl_sm_resource_info[((resource_type & + ACPI_RESOURCE_NAME_SMALL_MASK) + >> 3)]; + } + + /* Zero entry indicates an invalid resource type */ + + if (!size_info->minimum_internal_struct_length) { + return (NULL); + } + + return (size_info); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Byte Length + * + * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By + * definition, this does not include the size of the descriptor + * header or the length field itself. + * + ******************************************************************************/ + +u16 acpi_rs_get_resource_length(union aml_resource * aml) +{ + u16 resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* Determine if this is a small or large resource */ + + if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource type -- bytes 1-2 contain the 16-bit length */ + + ACPI_MOVE_16_TO_16(&resource_length, + &aml->large_header.resource_length); + + } else { + /* Small Resource type -- bits 2:0 of byte 0 contain the length */ + + resource_length = (u16) (aml->small_header.descriptor_type & + ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); + } + + return (resource_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_descriptor_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Byte length + * + * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the + * length of the descriptor header and the length field itself. + * Used to walk descriptor lists. + * + ******************************************************************************/ + +u32 acpi_rs_get_descriptor_length(union aml_resource * aml) +{ + u32 descriptor_length; + + ACPI_FUNCTION_ENTRY(); + + /* Determine if this is a small or large resource */ + + if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource type -- bytes 1-2 contain the 16-bit length */ + + ACPI_MOVE_16_TO_32(&descriptor_length, + &aml->large_header.resource_length); + descriptor_length += sizeof(struct aml_resource_large_header); + + } else { + /* Small Resource type -- bits 2:0 of byte 0 contain the length */ + + descriptor_length = (u32) (aml->small_header.descriptor_type & + ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); + descriptor_length += sizeof(struct aml_resource_small_header); + } + + return (descriptor_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_resource_header + * + * PARAMETERS: descriptor_type - Byte to be inserted as the type + * total_length - Length of the AML descriptor, including + * the header and length fields. + * Aml - Pointer to the raw AML descriptor + * + * RETURN: None + * + * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML + * resource descriptor, both Large and Small descriptors are + * supported automatically + * + ******************************************************************************/ + +void +acpi_rs_set_resource_header(u8 descriptor_type, + acpi_size total_length, union aml_resource *aml) +{ + u16 resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* Set the descriptor type */ + + aml->small_header.descriptor_type = descriptor_type; + + /* Determine if this is a small or large resource */ + + if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource type -- bytes 1-2 contain the 16-bit length */ + + resource_length = + (u16) (total_length - + sizeof(struct aml_resource_large_header)); + + /* Insert length into the Large descriptor length field */ + + ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, + &resource_length); + } else { + /* Small Resource type -- bits 2:0 of byte 0 contain the length */ + + resource_length = + (u16) (total_length - + sizeof(struct aml_resource_small_header)); + + /* Insert length into the descriptor type byte */ + + aml->small_header.descriptor_type |= (u8) resource_length; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_type + * + * PARAMETERS: resource_type - Byte 0 of a resource descriptor + * + * RETURN: The Resource Type with no extraneous bits (except the + * Large/Small descriptor bit -- this is left alone) + * + * DESCRIPTION: Extract the Resource Type/Name from the first byte of + * a resource descriptor. + * + ******************************************************************************/ + +u8 acpi_rs_get_resource_type(u8 resource_type) +{ + ACPI_FUNCTION_ENTRY(); + + /* Determine if this is a small or large resource */ + + if (resource_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ + + return (resource_type); + } else { + /* Small Resource Type -- bits 6:3 contain the name */ + + return ((u8) (resource_type & ACPI_RESOURCE_NAME_SMALL_MASK)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_strcpy + * + * PARAMETERS: Destination - Pointer to the destination string + * Source - Pointer to the source string + * + * RETURN: String length, including NULL terminator + * + * DESCRIPTION: Local string copy that returns the string length, saving a + * strcpy followed by a strlen. + * + ******************************************************************************/ + +static u16 acpi_rs_strcpy(char *destination, char *source) +{ + u16 i; + + ACPI_FUNCTION_ENTRY(); + + for (i = 0; source[i]; i++) { + destination[i] = source[i]; + } + + destination[i] = 0; + + /* Return string length including the NULL terminator */ + + return ((u16) (i + 1)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_source + * + * PARAMETERS: resource_length - Length field of the descriptor + * minimum_length - Minimum length of the descriptor (minus + * any optional fields) + * resource_source - Where the resource_source is returned + * Aml - Pointer to the raw AML descriptor + * string_ptr - (optional) where to store the actual + * resource_source string + * + * RETURN: Length of the string plus NULL terminator, rounded up to 32 bit + * + * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor + * to an internal resource descriptor + * + ******************************************************************************/ + +u16 +acpi_rs_get_resource_source(u16 resource_length, + acpi_size minimum_length, + struct acpi_resource_source * resource_source, + union aml_resource * aml, char *string_ptr) +{ + acpi_size total_length; + u8 *aml_resource_source; + + ACPI_FUNCTION_ENTRY(); + + total_length = + resource_length + sizeof(struct aml_resource_large_header); + aml_resource_source = ((u8 *) aml) + minimum_length; + + /* + * resource_source is present if the length of the descriptor is longer than + * the minimum length. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the minimum length. + */ + if (total_length > (minimum_length + 1)) { + /* Get the resource_source_index */ + + resource_source->index = aml_resource_source[0]; + + resource_source->string_ptr = string_ptr; + if (!string_ptr) { + /* + * String destination pointer is not specified; Set the String + * pointer to the end of the current resource_source structure. + */ + resource_source->string_ptr = (char *) + ((u8 *) resource_source) + + sizeof(struct acpi_resource_source); + } + + /* Copy the resource_source string to the destination */ + + resource_source->string_length = + acpi_rs_strcpy(resource_source->string_ptr, + (char *)&aml_resource_source[1]); + + /* + * In order for the struct_size to fall on a 32-bit boundary, + * calculate the length of the string and expand the + * struct_size to the next 32-bit boundary. + */ + return ((u16) + ACPI_ROUND_UP_to_32_bITS(resource_source-> + string_length)); + } else { + /* resource_source is not present */ + + resource_source->index = 0; + resource_source->string_length = 0; + resource_source->string_ptr = NULL; + return (0); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_resource_source + * + * PARAMETERS: Aml - Pointer to the raw AML descriptor + * minimum_length - Minimum length of the descriptor (minus + * any optional fields) + * resource_source - Internal resource_source + + * + * RETURN: Total length of the AML descriptor + * + * DESCRIPTION: Convert an optoinal resource_source from internal format to a + * raw AML resource descriptor + * + ******************************************************************************/ + +acpi_size +acpi_rs_set_resource_source(union aml_resource * aml, + acpi_size minimum_length, + struct acpi_resource_source * resource_source) +{ + u8 *aml_resource_source; + acpi_size descriptor_length; + + ACPI_FUNCTION_ENTRY(); + + descriptor_length = minimum_length; + + /* Non-zero string length indicates presence of a resource_source */ + + if (resource_source->string_length) { + /* Point to the end of the AML descriptor */ + + aml_resource_source = ((u8 *) aml) + minimum_length; + + /* Copy the resource_source_index */ + + aml_resource_source[0] = (u8) resource_source->index; + + /* Copy the resource_source string */ + + ACPI_STRCPY((char *)&aml_resource_source[1], + resource_source->string_ptr); + + /* + * Add the length of the string (+ 1 for null terminator) to the + * final descriptor length + */ + descriptor_length += + ((acpi_size) resource_source->string_length + 1); + } + + /* Return the new total length of the AML descriptor */ + + return (descriptor_length); +} + /******************************************************************************* * * FUNCTION: acpi_rs_get_prt_method_data @@ -65,8 +497,9 @@ ACPI_MODULE_NAME("rsutils") * and the contents of the callers buffer is undefined. * ******************************************************************************/ + acpi_status -acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) +acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) { union acpi_operand_object *obj_desc; acpi_status status; @@ -284,7 +717,7 @@ acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer) * Convert the linked list into a byte stream */ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_rs_create_byte_stream(in_buffer->pointer, &buffer); + status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 1a87c4c7bd97..9d179beb17ae 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -59,9 +59,9 @@ ACPI_MODULE_NAME("rsxface") ACPI_COPY_FIELD(out, in, max_address_fixed); \ ACPI_COPY_FIELD(out, in, attribute); \ ACPI_COPY_FIELD(out, in, granularity); \ - ACPI_COPY_FIELD(out, in, min_address_range); \ - ACPI_COPY_FIELD(out, in, max_address_range); \ - ACPI_COPY_FIELD(out, in, address_translation_offset); \ + ACPI_COPY_FIELD(out, in, minimum); \ + ACPI_COPY_FIELD(out, in, maximum); \ + ACPI_COPY_FIELD(out, in, translation_offset); \ ACPI_COPY_FIELD(out, in, address_length); \ ACPI_COPY_FIELD(out, in, resource_source); /******************************************************************************* @@ -269,7 +269,7 @@ acpi_walk_resources(acpi_handle device_handle, /* Walk the resource list */ for (;;) { - if (!resource || resource->type == ACPI_RSTYPE_END_TAG) { + if (!resource || resource->type == ACPI_RESOURCE_TYPE_END_TAG) { break; } @@ -382,19 +382,19 @@ acpi_resource_to_address64(struct acpi_resource *resource, struct acpi_resource_address32 *address32; switch (resource->type) { - case ACPI_RSTYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS16: address16 = (struct acpi_resource_address16 *)&resource->data; ACPI_COPY_ADDRESS(out, address16); break; - case ACPI_RSTYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS32: address32 = (struct acpi_resource_address32 *)&resource->data; ACPI_COPY_ADDRESS(out, address32); break; - case ACPI_RSTYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_ADDRESS64: /* Simple copy for 64 bit source */ diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index ad0252c2f7db..3cee0cee4cc2 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c @@ -251,7 +251,7 @@ acpi_status acpi_tb_get_table_rsdt(void) } ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n", + "RSDP located at %p, points to RSDT physical=%8.8X%8.8X\n", acpi_gbl_RSDP, ACPI_FORMAT_UINT64(address.pointer.value))); diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index 3b8a7e063e8a..b01a4b2ae7da 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c @@ -251,7 +251,7 @@ acpi_get_firmware_table(acpi_string signature, acpi_tb_get_rsdt_address(&address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", + "RSDP located at %p, RSDT physical=%8.8X%8.8X\n", acpi_gbl_RSDP, ACPI_FORMAT_UINT64(address.pointer.value))); diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 068450b36475..dc7f24b3a1c0 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c @@ -304,7 +304,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) if (!size) { _ACPI_REPORT_ERROR(module, line, component, - ("ut_allocate: Attempt to allocate zero bytes\n")); + ("ut_allocate: Attempt to allocate zero bytes, allocating 1 byte\n")); size = 1; } @@ -347,8 +347,8 @@ void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line) if (!size) { _ACPI_REPORT_ERROR(module, line, component, - ("ut_callocate: Attempt to allocate zero bytes\n")); - return_PTR(NULL); + ("ut_callocate: Attempt to allocate zero bytes, allocating 1 byte\n")); + size = 1; } allocation = acpi_os_allocate(size); diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 399e64b51886..7f72839841ca 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -825,6 +825,9 @@ void acpi_ut_init_globals(void) acpi_gbl_ps_find_count = 0; acpi_gbl_acpi_hardware_present = TRUE; acpi_gbl_owner_id_mask = 0; + acpi_gbl_trace_method_name = 0; + acpi_gbl_trace_dbg_level = 0; + acpi_gbl_trace_dbg_layer = 0; acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index aa1dcd851f89..b57afa7421e8 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -811,15 +811,15 @@ u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc) while (buffer < end_buffer) { buffer_byte = *buffer; - if (buffer_byte & ACPI_RDESC_TYPE_LARGE) { + if (buffer_byte & ACPI_RESOURCE_NAME_LARGE) { /* Large Descriptor - Length is next 2 bytes */ buffer += ((*(buffer + 1) | (*(buffer + 2) << 8)) + 3); } else { /* Small Descriptor. End Tag will be found here */ - if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == - ACPI_RDESC_TYPE_END_TAG) { + if ((buffer_byte & ACPI_RESOURCE_NAME_SMALL_MASK) == + ACPI_RESOURCE_NAME_END_TAG) { /* Found the end tag descriptor, all done. */ return (buffer); diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 5172d4e1236c..66a2fee06eb9 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -927,9 +927,9 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) if (ACPI_SUCCESS(status)) { unsigned long size; - size = addr.max_address_range - addr.min_address_range + 1; - hdp->hd_phys_address = addr.min_address_range; - hdp->hd_address = ioremap(addr.min_address_range, size); + size = addr.maximum - addr.minimum + 1; + hdp->hd_phys_address = addr.minimum; + hdp->hd_address = ioremap(addr.minimum, size); if (hpet_is_known(hdp)) { printk(KERN_DEBUG "%s: 0x%lx is busy\n", @@ -937,15 +937,15 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) iounmap(hdp->hd_address); return -EBUSY; } - } else if (res->type == ACPI_RSTYPE_FIXED_MEM32) { - struct acpi_resource_fixed_mem32 *fixmem32; + } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) { + struct acpi_resource_fixed_memory32 *fixmem32; fixmem32 = &res->data.fixed_memory32; if (!fixmem32) return -EINVAL; - hdp->hd_phys_address = fixmem32->range_base_address; - hdp->hd_address = ioremap(fixmem32->range_base_address, + hdp->hd_phys_address = fixmem32->address; + hdp->hd_address = ioremap(fixmem32->address, HPET_RANGE_SIZE); if (hpet_is_known(hdp)) { @@ -954,20 +954,20 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) iounmap(hdp->hd_address); return -EBUSY; } - } else if (res->type == ACPI_RSTYPE_EXT_IRQ) { - struct acpi_resource_ext_irq *irqp; + } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { + struct acpi_resource_extended_irq *irqp; int i; irqp = &res->data.extended_irq; - if (irqp->number_of_interrupts > 0) { - hdp->hd_nirqs = irqp->number_of_interrupts; + if (irqp->interrupt_count > 0) { + hdp->hd_nirqs = irqp->interrupt_count; for (i = 0; i < hdp->hd_nirqs; i++) { int rc = acpi_register_gsi(irqp->interrupts[i], - irqp->edge_level, - irqp->active_high_low); + irqp->triggering, + irqp->polarity); if (rc < 0) return AE_ERROR; hdp->hd_irq[i] = rc; diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 15ec05f69ddd..f4adebde6155 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -3,7 +3,7 @@ * * Copyright (c) 2004 Matthieu Castet * Copyright (c) 2004 Li Shaohua - * + * * 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, or (at your option) any @@ -32,17 +32,17 @@ /* * Allocated Resources */ -static int irq_flags(int edge_level, int active_high_low) +static int irq_flags(int triggering, int polarity) { int flag; - if (edge_level == ACPI_LEVEL_SENSITIVE) { - if(active_high_low == ACPI_ACTIVE_LOW) + if (triggering == ACPI_LEVEL_SENSITIVE) { + if(polarity == ACPI_ACTIVE_LOW) flag = IORESOURCE_IRQ_LOWLEVEL; else flag = IORESOURCE_IRQ_HIGHLEVEL; } else { - if(active_high_low == ACPI_ACTIVE_LOW) + if(polarity == ACPI_ACTIVE_LOW) flag = IORESOURCE_IRQ_LOWEDGE; else flag = IORESOURCE_IRQ_HIGHEDGE; @@ -50,31 +50,31 @@ static int irq_flags(int edge_level, int active_high_low) return flag; } -static void decode_irq_flags(int flag, int *edge_level, int *active_high_low) +static void decode_irq_flags(int flag, int *triggering, int *polarity) { switch (flag) { case IORESOURCE_IRQ_LOWLEVEL: - *edge_level = ACPI_LEVEL_SENSITIVE; - *active_high_low = ACPI_ACTIVE_LOW; + *triggering = ACPI_LEVEL_SENSITIVE; + *polarity = ACPI_ACTIVE_LOW; break; case IORESOURCE_IRQ_HIGHLEVEL: - *edge_level = ACPI_LEVEL_SENSITIVE; - *active_high_low = ACPI_ACTIVE_HIGH; + *triggering = ACPI_LEVEL_SENSITIVE; + *polarity = ACPI_ACTIVE_HIGH; break; case IORESOURCE_IRQ_LOWEDGE: - *edge_level = ACPI_EDGE_SENSITIVE; - *active_high_low = ACPI_ACTIVE_LOW; + *triggering = ACPI_EDGE_SENSITIVE; + *polarity = ACPI_ACTIVE_LOW; break; case IORESOURCE_IRQ_HIGHEDGE: - *edge_level = ACPI_EDGE_SENSITIVE; - *active_high_low = ACPI_ACTIVE_HIGH; + *triggering = ACPI_EDGE_SENSITIVE; + *polarity = ACPI_ACTIVE_HIGH; break; } } static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, u32 gsi, - int edge_level, int active_high_low) + int triggering, int polarity) { int i = 0; int irq; @@ -89,7 +89,7 @@ pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, u32 gsi, return; res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag - irq = acpi_register_gsi(gsi, edge_level, active_high_low); + irq = acpi_register_gsi(gsi, triggering, polarity); if (irq < 0) { res->irq_resource[i].flags |= IORESOURCE_DISABLED; return; @@ -164,73 +164,73 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, int i; switch (res->type) { - case ACPI_RSTYPE_IRQ: + case ACPI_RESOURCE_TYPE_IRQ: /* * Per spec, only one interrupt per descriptor is allowed in * _CRS, but some firmware violates this, so parse them all. */ - for (i = 0; i < res->data.irq.number_of_interrupts; i++) { + for (i = 0; i < res->data.irq.interrupt_count; i++) { pnpacpi_parse_allocated_irqresource(res_table, res->data.irq.interrupts[i], - res->data.irq.edge_level, - res->data.irq.active_high_low); + res->data.irq.triggering, + res->data.irq.polarity); } break; - case ACPI_RSTYPE_EXT_IRQ: - for (i = 0; i < res->data.extended_irq.number_of_interrupts; i++) { + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { pnpacpi_parse_allocated_irqresource(res_table, res->data.extended_irq.interrupts[i], - res->data.extended_irq.edge_level, - res->data.extended_irq.active_high_low); + res->data.extended_irq.triggering, + res->data.extended_irq.polarity); } break; - case ACPI_RSTYPE_DMA: - if (res->data.dma.number_of_channels > 0) - pnpacpi_parse_allocated_dmaresource(res_table, + case ACPI_RESOURCE_TYPE_DMA: + if (res->data.dma.channel_count > 0) + pnpacpi_parse_allocated_dmaresource(res_table, res->data.dma.channels[0]); break; - case ACPI_RSTYPE_IO: - pnpacpi_parse_allocated_ioresource(res_table, - res->data.io.min_base_address, - res->data.io.range_length); + case ACPI_RESOURCE_TYPE_IO: + pnpacpi_parse_allocated_ioresource(res_table, + res->data.io.minimum, + res->data.io.address_length); break; - case ACPI_RSTYPE_FIXED_IO: - pnpacpi_parse_allocated_ioresource(res_table, - res->data.fixed_io.base_address, - res->data.fixed_io.range_length); + case ACPI_RESOURCE_TYPE_FIXED_IO: + pnpacpi_parse_allocated_ioresource(res_table, + res->data.fixed_io.address, + res->data.fixed_io.address_length); break; - case ACPI_RSTYPE_MEM24: - pnpacpi_parse_allocated_memresource(res_table, - res->data.memory24.min_base_address, - res->data.memory24.range_length); + case ACPI_RESOURCE_TYPE_MEMORY24: + pnpacpi_parse_allocated_memresource(res_table, + res->data.memory24.minimum, + res->data.memory24.address_length); break; - case ACPI_RSTYPE_MEM32: - pnpacpi_parse_allocated_memresource(res_table, - res->data.memory32.min_base_address, - res->data.memory32.range_length); + case ACPI_RESOURCE_TYPE_MEMORY32: + pnpacpi_parse_allocated_memresource(res_table, + res->data.memory32.minimum, + res->data.memory32.address_length); break; - case ACPI_RSTYPE_FIXED_MEM32: - pnpacpi_parse_allocated_memresource(res_table, - res->data.fixed_memory32.range_base_address, - res->data.fixed_memory32.range_length); + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + pnpacpi_parse_allocated_memresource(res_table, + res->data.fixed_memory32.address, + res->data.fixed_memory32.address_length); break; - case ACPI_RSTYPE_ADDRESS16: - pnpacpi_parse_allocated_memresource(res_table, - res->data.address16.min_address_range, + case ACPI_RESOURCE_TYPE_ADDRESS16: + pnpacpi_parse_allocated_memresource(res_table, + res->data.address16.minimum, res->data.address16.address_length); break; - case ACPI_RSTYPE_ADDRESS32: - pnpacpi_parse_allocated_memresource(res_table, - res->data.address32.min_address_range, + case ACPI_RESOURCE_TYPE_ADDRESS32: + pnpacpi_parse_allocated_memresource(res_table, + res->data.address32.minimum, res->data.address32.address_length); break; - case ACPI_RSTYPE_ADDRESS64: - pnpacpi_parse_allocated_memresource(res_table, - res->data.address64.min_address_range, + case ACPI_RESOURCE_TYPE_ADDRESS64: + pnpacpi_parse_allocated_memresource(res_table, + res->data.address64.minimum, res->data.address64.address_length); break; - case ACPI_RSTYPE_VENDOR: + case ACPI_RESOURCE_TYPE_VENDOR: break; default: pnp_warn("PnPACPI: unknown resource type %d", res->type); @@ -253,13 +253,13 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, struct acpi_reso int i; struct pnp_dma * dma; - if (p->number_of_channels == 0) + if (p->channel_count == 0) return; dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL); if (!dma) return; - for(i = 0; i < p->number_of_channels; i++) + for(i = 0; i < p->channel_count; i++) dma->map |= 1 << p->channels[i]; dma->flags = 0; if (p->bus_master) @@ -309,37 +309,37 @@ static void pnpacpi_parse_irq_option(struct pnp_option *option, int i; struct pnp_irq * irq; - if (p->number_of_interrupts == 0) + if (p->interrupt_count == 0) return; irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL); if (!irq) return; - for(i = 0; i < p->number_of_interrupts; i++) + for(i = 0; i < p->interrupt_count; i++) if (p->interrupts[i]) __set_bit(p->interrupts[i], irq->map); - irq->flags = irq_flags(p->edge_level, p->active_high_low); + irq->flags = irq_flags(p->triggering, p->polarity); pnp_register_irq_resource(option, irq); return; } static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, - struct acpi_resource_ext_irq *p) + struct acpi_resource_extended_irq *p) { int i; struct pnp_irq * irq; - if (p->number_of_interrupts == 0) + if (p->interrupt_count == 0) return; irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL); if (!irq) return; - for(i = 0; i < p->number_of_interrupts; i++) + for(i = 0; i < p->interrupt_count; i++) if (p->interrupts[i]) __set_bit(p->interrupts[i], irq->map); - irq->flags = irq_flags(p->edge_level, p->active_high_low); + irq->flags = irq_flags(p->triggering, p->polarity); pnp_register_irq_resource(option, irq); return; @@ -351,16 +351,16 @@ pnpacpi_parse_port_option(struct pnp_option *option, { struct pnp_port * port; - if (io->range_length == 0) + if (io->address_length == 0) return; port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL); if (!port) return; - port->min = io->min_base_address; - port->max = io->max_base_address; + port->min = io->minimum; + port->max = io->maximum; port->align = io->alignment; - port->size = io->range_length; - port->flags = ACPI_DECODE_16 == io->io_decode ? + port->size = io->address_length; + port->flags = ACPI_DECODE_16 == io->io_decode ? PNP_PORT_FLAG_16BITADDR : 0; pnp_register_port_resource(option,port); return; @@ -372,13 +372,13 @@ pnpacpi_parse_fixed_port_option(struct pnp_option *option, { struct pnp_port * port; - if (io->range_length == 0) + if (io->address_length == 0) return; port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL); if (!port) return; - port->min = port->max = io->base_address; - port->size = io->range_length; + port->min = port->max = io->address; + port->size = io->address_length; port->align = 0; port->flags = PNP_PORT_FLAG_FIXED; pnp_register_port_resource(option,port); @@ -387,19 +387,19 @@ pnpacpi_parse_fixed_port_option(struct pnp_option *option, static void pnpacpi_parse_mem24_option(struct pnp_option *option, - struct acpi_resource_mem24 *p) + struct acpi_resource_memory24 *p) { struct pnp_mem * mem; - if (p->range_length == 0) + if (p->address_length == 0) return; mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL); if (!mem) return; - mem->min = p->min_base_address; - mem->max = p->max_base_address; + mem->min = p->minimum; + mem->max = p->maximum; mem->align = p->alignment; - mem->size = p->range_length; + mem->size = p->address_length; mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ? IORESOURCE_MEM_WRITEABLE : 0; @@ -410,19 +410,19 @@ pnpacpi_parse_mem24_option(struct pnp_option *option, static void pnpacpi_parse_mem32_option(struct pnp_option *option, - struct acpi_resource_mem32 *p) + struct acpi_resource_memory32 *p) { struct pnp_mem * mem; - if (p->range_length == 0) + if (p->address_length == 0) return; mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL); if (!mem) return; - mem->min = p->min_base_address; - mem->max = p->max_base_address; + mem->min = p->minimum; + mem->max = p->maximum; mem->align = p->alignment; - mem->size = p->range_length; + mem->size = p->address_length; mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ? IORESOURCE_MEM_WRITEABLE : 0; @@ -433,17 +433,17 @@ pnpacpi_parse_mem32_option(struct pnp_option *option, static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, - struct acpi_resource_fixed_mem32 *p) + struct acpi_resource_fixed_memory32 *p) { struct pnp_mem * mem; - if (p->range_length == 0) + if (p->address_length == 0) return; mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL); if (!mem) return; - mem->min = mem->max = p->range_base_address; - mem->size = p->range_length; + mem->min = mem->max = p->address; + mem->size = p->address_length; mem->align = 0; mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ? @@ -459,7 +459,7 @@ struct acpipnp_parse_option_s { struct pnp_dev *dev; }; -static acpi_status pnpacpi_option_resource(struct acpi_resource *res, +static acpi_status pnpacpi_option_resource(struct acpi_resource *res, void *data) { int priority = 0; @@ -468,34 +468,34 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, struct pnp_option *option = parse_data->option; switch (res->type) { - case ACPI_RSTYPE_IRQ: + case ACPI_RESOURCE_TYPE_IRQ: pnpacpi_parse_irq_option(option, &res->data.irq); break; - case ACPI_RSTYPE_EXT_IRQ: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: pnpacpi_parse_ext_irq_option(option, &res->data.extended_irq); break; - case ACPI_RSTYPE_DMA: + case ACPI_RESOURCE_TYPE_DMA: pnpacpi_parse_dma_option(option, &res->data.dma); break; - case ACPI_RSTYPE_IO: + case ACPI_RESOURCE_TYPE_IO: pnpacpi_parse_port_option(option, &res->data.io); break; - case ACPI_RSTYPE_FIXED_IO: + case ACPI_RESOURCE_TYPE_FIXED_IO: pnpacpi_parse_fixed_port_option(option, &res->data.fixed_io); break; - case ACPI_RSTYPE_MEM24: + case ACPI_RESOURCE_TYPE_MEMORY24: pnpacpi_parse_mem24_option(option, &res->data.memory24); break; - case ACPI_RSTYPE_MEM32: + case ACPI_RESOURCE_TYPE_MEMORY32: pnpacpi_parse_mem32_option(option, &res->data.memory32); break; - case ACPI_RSTYPE_FIXED_MEM32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: pnpacpi_parse_fixed_mem32_option(option, &res->data.fixed_memory32); break; - case ACPI_RSTYPE_START_DPF: + case ACPI_RESOURCE_TYPE_START_DEPENDENT: switch (res->data.start_dpf.compatibility_priority) { case ACPI_GOOD_CONFIGURATION: priority = PNP_RES_PRIORITY_PREFERRED; @@ -518,7 +518,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, return AE_ERROR; parse_data->option = option; break; - case ACPI_RSTYPE_END_DPF: + case ACPI_RESOURCE_TYPE_END_DEPENDENT: /*only one EndDependentFn is allowed*/ if (!parse_data->option_independent) { pnp_warn("PnPACPI: more than one EndDependentFn"); @@ -535,7 +535,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, return AE_OK; } -acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, +acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, struct pnp_dev *dev) { acpi_status status; @@ -546,7 +546,7 @@ acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, return AE_ERROR; parse_data.option_independent = parse_data.option; parse_data.dev = dev; - status = acpi_walk_resources(handle, METHOD_NAME__PRS, + status = acpi_walk_resources(handle, METHOD_NAME__PRS, pnpacpi_option_resource, &parse_data); return status; @@ -560,18 +560,18 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, { int *res_cnt = (int *)data; switch (res->type) { - case ACPI_RSTYPE_IRQ: - case ACPI_RSTYPE_EXT_IRQ: - case ACPI_RSTYPE_DMA: - case ACPI_RSTYPE_IO: - case ACPI_RSTYPE_FIXED_IO: - case ACPI_RSTYPE_MEM24: - case ACPI_RSTYPE_MEM32: - case ACPI_RSTYPE_FIXED_MEM32: + case ACPI_RESOURCE_TYPE_IRQ: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + case ACPI_RESOURCE_TYPE_DMA: + case ACPI_RESOURCE_TYPE_IO: + case ACPI_RESOURCE_TYPE_FIXED_IO: + case ACPI_RESOURCE_TYPE_MEMORY24: + case ACPI_RESOURCE_TYPE_MEMORY32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: #if 0 - case ACPI_RSTYPE_ADDRESS16: - case ACPI_RSTYPE_ADDRESS32: - case ACPI_RSTYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS64: #endif (*res_cnt) ++; default: @@ -585,18 +585,18 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, { struct acpi_resource **resource = (struct acpi_resource **)data; switch (res->type) { - case ACPI_RSTYPE_IRQ: - case ACPI_RSTYPE_EXT_IRQ: - case ACPI_RSTYPE_DMA: - case ACPI_RSTYPE_IO: - case ACPI_RSTYPE_FIXED_IO: - case ACPI_RSTYPE_MEM24: - case ACPI_RSTYPE_MEM32: - case ACPI_RSTYPE_FIXED_MEM32: + case ACPI_RESOURCE_TYPE_IRQ: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + case ACPI_RESOURCE_TYPE_DMA: + case ACPI_RESOURCE_TYPE_IO: + case ACPI_RESOURCE_TYPE_FIXED_IO: + case ACPI_RESOURCE_TYPE_MEMORY24: + case ACPI_RESOURCE_TYPE_MEMORY32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: #if 0 - case ACPI_RSTYPE_ADDRESS16: - case ACPI_RSTYPE_ADDRESS32: - case ACPI_RSTYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS64: #endif (*resource)->type = res->type; (*resource)++; @@ -607,14 +607,14 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, return AE_OK; } -int pnpacpi_build_resource_template(acpi_handle handle, +int pnpacpi_build_resource_template(acpi_handle handle, struct acpi_buffer *buffer) { struct acpi_resource *resource; int res_cnt = 0; acpi_status status; - status = acpi_walk_resources(handle, METHOD_NAME__CRS, + status = acpi_walk_resources(handle, METHOD_NAME__CRS, pnpacpi_count_resources, &res_cnt); if (ACPI_FAILURE(status)) { pnp_err("Evaluate _CRS failed"); @@ -628,7 +628,7 @@ int pnpacpi_build_resource_template(acpi_handle handle, return -ENOMEM; pnp_dbg("Res cnt %d", res_cnt); resource = (struct acpi_resource *)buffer->pointer; - status = acpi_walk_resources(handle, METHOD_NAME__CRS, + status = acpi_walk_resources(handle, METHOD_NAME__CRS, pnpacpi_type_resources, &resource); if (ACPI_FAILURE(status)) { kfree(buffer->pointer); @@ -636,54 +636,54 @@ int pnpacpi_build_resource_template(acpi_handle handle, return -EINVAL; } /* resource will pointer the end resource now */ - resource->type = ACPI_RSTYPE_END_TAG; + resource->type = ACPI_RESOURCE_TYPE_END_TAG; return 0; } -static void pnpacpi_encode_irq(struct acpi_resource *resource, +static void pnpacpi_encode_irq(struct acpi_resource *resource, struct resource *p) { - int edge_level, active_high_low; + int triggering, polarity; - decode_irq_flags(p->flags & IORESOURCE_BITS, &edge_level, - &active_high_low); - resource->type = ACPI_RSTYPE_IRQ; + decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, + &polarity); + resource->type = ACPI_RESOURCE_TYPE_IRQ; resource->length = sizeof(struct acpi_resource); - resource->data.irq.edge_level = edge_level; - resource->data.irq.active_high_low = active_high_low; - if (edge_level == ACPI_EDGE_SENSITIVE) - resource->data.irq.shared_exclusive = ACPI_EXCLUSIVE; + resource->data.irq.triggering = triggering; + resource->data.irq.polarity = polarity; + if (triggering == ACPI_EDGE_SENSITIVE) + resource->data.irq.sharable = ACPI_EXCLUSIVE; else - resource->data.irq.shared_exclusive = ACPI_SHARED; - resource->data.irq.number_of_interrupts = 1; + resource->data.irq.sharable = ACPI_SHARED; + resource->data.irq.interrupt_count = 1; resource->data.irq.interrupts[0] = p->start; } static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, struct resource *p) { - int edge_level, active_high_low; + int triggering, polarity; - decode_irq_flags(p->flags & IORESOURCE_BITS, &edge_level, - &active_high_low); - resource->type = ACPI_RSTYPE_EXT_IRQ; + decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, + &polarity); + resource->type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; resource->length = sizeof(struct acpi_resource); resource->data.extended_irq.producer_consumer = ACPI_CONSUMER; - resource->data.extended_irq.edge_level = edge_level; - resource->data.extended_irq.active_high_low = active_high_low; - if (edge_level == ACPI_EDGE_SENSITIVE) - resource->data.irq.shared_exclusive = ACPI_EXCLUSIVE; + resource->data.extended_irq.triggering = triggering; + resource->data.extended_irq.polarity = polarity; + if (triggering == ACPI_EDGE_SENSITIVE) + resource->data.irq.sharable = ACPI_EXCLUSIVE; else - resource->data.irq.shared_exclusive = ACPI_SHARED; - resource->data.extended_irq.number_of_interrupts = 1; + resource->data.irq.sharable = ACPI_SHARED; + resource->data.extended_irq.interrupt_count = 1; resource->data.extended_irq.interrupts[0] = p->start; } static void pnpacpi_encode_dma(struct acpi_resource *resource, struct resource *p) { - resource->type = ACPI_RSTYPE_DMA; + resource->type = ACPI_RESOURCE_TYPE_DMA; resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ if (p->flags & IORESOURCE_DMA_COMPATIBLE) @@ -701,75 +701,75 @@ static void pnpacpi_encode_dma(struct acpi_resource *resource, else if (p->flags & IORESOURCE_DMA_16BIT) resource->data.dma.transfer = ACPI_TRANSFER_16; resource->data.dma.bus_master = p->flags & IORESOURCE_DMA_MASTER; - resource->data.dma.number_of_channels = 1; + resource->data.dma.channel_count = 1; resource->data.dma.channels[0] = p->start; } static void pnpacpi_encode_io(struct acpi_resource *resource, struct resource *p) { - resource->type = ACPI_RSTYPE_IO; + resource->type = ACPI_RESOURCE_TYPE_IO; resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR)? - ACPI_DECODE_16 : ACPI_DECODE_10; - resource->data.io.min_base_address = p->start; - resource->data.io.max_base_address = p->end; + ACPI_DECODE_16 : ACPI_DECODE_10; + resource->data.io.minimum = p->start; + resource->data.io.maximum = p->end; resource->data.io.alignment = 0; /* Correct? */ - resource->data.io.range_length = p->end - p->start + 1; + resource->data.io.address_length = p->end - p->start + 1; } static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, struct resource *p) { - resource->type = ACPI_RSTYPE_FIXED_IO; + resource->type = ACPI_RESOURCE_TYPE_FIXED_IO; resource->length = sizeof(struct acpi_resource); - resource->data.fixed_io.base_address = p->start; - resource->data.fixed_io.range_length = p->end - p->start + 1; + resource->data.fixed_io.address = p->start; + resource->data.fixed_io.address_length = p->end - p->start + 1; } static void pnpacpi_encode_mem24(struct acpi_resource *resource, struct resource *p) { - resource->type = ACPI_RSTYPE_MEM24; + resource->type = ACPI_RESOURCE_TYPE_MEMORY24; resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ resource->data.memory24.read_write_attribute = (p->flags & IORESOURCE_MEM_WRITEABLE) ? ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; - resource->data.memory24.min_base_address = p->start; - resource->data.memory24.max_base_address = p->end; + resource->data.memory24.minimum = p->start; + resource->data.memory24.maximum = p->end; resource->data.memory24.alignment = 0; - resource->data.memory24.range_length = p->end - p->start + 1; + resource->data.memory24.address_length = p->end - p->start + 1; } static void pnpacpi_encode_mem32(struct acpi_resource *resource, struct resource *p) { - resource->type = ACPI_RSTYPE_MEM32; + resource->type = ACPI_RESOURCE_TYPE_MEMORY32; resource->length = sizeof(struct acpi_resource); resource->data.memory32.read_write_attribute = (p->flags & IORESOURCE_MEM_WRITEABLE) ? ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; - resource->data.memory32.min_base_address = p->start; - resource->data.memory32.max_base_address = p->end; + resource->data.memory32.minimum = p->start; + resource->data.memory32.maximum = p->end; resource->data.memory32.alignment = 0; - resource->data.memory32.range_length = p->end - p->start + 1; + resource->data.memory32.address_length = p->end - p->start + 1; } static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource, struct resource *p) { - resource->type = ACPI_RSTYPE_FIXED_MEM32; + resource->type = ACPI_RESOURCE_TYPE_FIXED_MEMORY32; resource->length = sizeof(struct acpi_resource); resource->data.fixed_memory32.read_write_attribute = (p->flags & IORESOURCE_MEM_WRITEABLE) ? ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; - resource->data.fixed_memory32.range_base_address = p->start; - resource->data.fixed_memory32.range_length = p->end - p->start + 1; + resource->data.fixed_memory32.address = p->start; + resource->data.fixed_memory32.address_length = p->end - p->start + 1; } -int pnpacpi_encode_resources(struct pnp_resource_table *res_table, +int pnpacpi_encode_resources(struct pnp_resource_table *res_table, struct acpi_buffer *buffer) { int i = 0; @@ -781,50 +781,50 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, pnp_dbg("res cnt %d", res_cnt); while (i < res_cnt) { switch(resource->type) { - case ACPI_RSTYPE_IRQ: + case ACPI_RESOURCE_TYPE_IRQ: pnp_dbg("Encode irq"); - pnpacpi_encode_irq(resource, + pnpacpi_encode_irq(resource, &res_table->irq_resource[irq]); irq++; break; - case ACPI_RSTYPE_EXT_IRQ: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: pnp_dbg("Encode ext irq"); - pnpacpi_encode_ext_irq(resource, + pnpacpi_encode_ext_irq(resource, &res_table->irq_resource[irq]); irq++; break; - case ACPI_RSTYPE_DMA: + case ACPI_RESOURCE_TYPE_DMA: pnp_dbg("Encode dma"); - pnpacpi_encode_dma(resource, + pnpacpi_encode_dma(resource, &res_table->dma_resource[dma]); dma ++; break; - case ACPI_RSTYPE_IO: + case ACPI_RESOURCE_TYPE_IO: pnp_dbg("Encode io"); - pnpacpi_encode_io(resource, + pnpacpi_encode_io(resource, &res_table->port_resource[port]); port ++; break; - case ACPI_RSTYPE_FIXED_IO: + case ACPI_RESOURCE_TYPE_FIXED_IO: pnp_dbg("Encode fixed io"); pnpacpi_encode_fixed_io(resource, &res_table->port_resource[port]); port ++; break; - case ACPI_RSTYPE_MEM24: + case ACPI_RESOURCE_TYPE_MEMORY24: pnp_dbg("Encode mem24"); pnpacpi_encode_mem24(resource, &res_table->mem_resource[mem]); mem ++; break; - case ACPI_RSTYPE_MEM32: + case ACPI_RESOURCE_TYPE_MEMORY32: pnp_dbg("Encode mem32"); pnpacpi_encode_mem32(resource, &res_table->mem_resource[mem]); mem ++; break; - case ACPI_RSTYPE_FIXED_MEM32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: pnp_dbg("Encode fixed mem32"); pnpacpi_encode_fixed_mem32(resource, &res_table->mem_resource[mem]); diff --git a/drivers/serial/8250_acpi.c b/drivers/serial/8250_acpi.c index 36681ba7b033..809f89ab965c 100644 --- a/drivers/serial/8250_acpi.c +++ b/drivers/serial/8250_acpi.c @@ -27,7 +27,7 @@ struct serial_private { static acpi_status acpi_serial_mmio(struct uart_port *port, struct acpi_resource_address64 *addr) { - port->mapbase = addr->min_address_range; + port->mapbase = addr->minimum; port->iotype = UPIO_MEM; port->flags |= UPF_IOREMAP; return AE_OK; @@ -36,8 +36,8 @@ static acpi_status acpi_serial_mmio(struct uart_port *port, static acpi_status acpi_serial_port(struct uart_port *port, struct acpi_resource_io *io) { - if (io->range_length) { - port->iobase = io->min_base_address; + if (io->address_length) { + port->iobase = io->minimum; port->iotype = UPIO_PORT; } else printk(KERN_ERR "%s: zero-length IO port range?\n", __FUNCTION__); @@ -45,13 +45,13 @@ static acpi_status acpi_serial_port(struct uart_port *port, } static acpi_status acpi_serial_ext_irq(struct uart_port *port, - struct acpi_resource_ext_irq *ext_irq) + struct acpi_resource_extended_irq *ext_irq) { int rc; - if (ext_irq->number_of_interrupts > 0) { + if (ext_irq->interrupt_count > 0) { rc = acpi_register_gsi(ext_irq->interrupts[0], - ext_irq->edge_level, ext_irq->active_high_low); + ext_irq->triggering, ext_irq->polarity); if (rc < 0) return AE_ERROR; port->irq = rc; @@ -64,9 +64,9 @@ static acpi_status acpi_serial_irq(struct uart_port *port, { int rc; - if (irq->number_of_interrupts > 0) { + if (irq->interrupt_count > 0) { rc = acpi_register_gsi(irq->interrupts[0], - irq->edge_level, irq->active_high_low); + irq->triggering, irq->polarity); if (rc < 0) return AE_ERROR; port->irq = rc; @@ -83,11 +83,11 @@ static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data) status = acpi_resource_to_address64(res, &addr); if (ACPI_SUCCESS(status)) return acpi_serial_mmio(port, &addr); - else if (res->type == ACPI_RSTYPE_IO) + else if (res->type == ACPI_RESOURCE_TYPE_IO) return acpi_serial_port(port, &res->data.io); - else if (res->type == ACPI_RSTYPE_EXT_IRQ) + else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) return acpi_serial_ext_irq(port, &res->data.extended_irq); - else if (res->type == ACPI_RSTYPE_IRQ) + else if (res->type == ACPI_RESOURCE_TYPE_IRQ) return acpi_serial_irq(port, &res->data.irq); return AE_OK; } diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 1427c5cf4304..cb59b018c84c 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20050916 +#define ACPI_CA_VERSION 0x20050930 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index 759b4cff4f88..b2921b869bb4 100644 --- a/include/acpi/acdisasm.h +++ b/include/acpi/acdisasm.h @@ -187,73 +187,67 @@ void acpi_dm_decode_attribute(u8 attribute); * dmresrcl */ void -acpi_dm_word_descriptor(union asl_resource_desc *resource, - u32 length, u32 level); +acpi_dm_word_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_dword_descriptor(union asl_resource_desc *resource, - u32 length, u32 level); +acpi_dm_dword_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_extended_descriptor(union asl_resource_desc *resource, +acpi_dm_extended_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_qword_descriptor(union asl_resource_desc *resource, - u32 length, u32 level); +acpi_dm_qword_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_memory24_descriptor(union asl_resource_desc *resource, +acpi_dm_memory24_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_memory32_descriptor(union asl_resource_desc *resource, +acpi_dm_memory32_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_fixed_memory32_descriptor(union asl_resource_desc *resource, +acpi_dm_fixed_memory32_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_generic_register_descriptor(union asl_resource_desc *resource, +acpi_dm_generic_register_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_interrupt_descriptor(union asl_resource_desc *resource, +acpi_dm_interrupt_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_vendor_large_descriptor(union asl_resource_desc *resource, +acpi_dm_vendor_large_descriptor(union aml_resource *resource, u32 length, u32 level); /* * dmresrcs */ void -acpi_dm_irq_descriptor(union asl_resource_desc *resource, - u32 length, u32 level); +acpi_dm_irq_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_dma_descriptor(union asl_resource_desc *resource, - u32 length, u32 level); +acpi_dm_dma_descriptor(union aml_resource *resource, u32 length, u32 level); + +void acpi_dm_io_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_io_descriptor(union asl_resource_desc *resource, u32 length, u32 level); - -void -acpi_dm_fixed_io_descriptor(union asl_resource_desc *resource, +acpi_dm_fixed_io_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_start_dependent_descriptor(union asl_resource_desc *resource, +acpi_dm_start_dependent_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_end_dependent_descriptor(union asl_resource_desc *resource, +acpi_dm_end_dependent_descriptor(union aml_resource *resource, u32 length, u32 level); void -acpi_dm_vendor_small_descriptor(union asl_resource_desc *resource, +acpi_dm_vendor_small_descriptor(union aml_resource *resource, u32 length, u32 level); /* diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index e9c2790139ec..cef51b1ddf94 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h @@ -80,6 +80,15 @@ extern u32 acpi_dbg_layer; extern u32 acpi_gbl_nesting_level; +/* Support for dynamic control method tracing mechanism */ + +ACPI_EXTERN u32 acpi_gbl_original_dbg_level; +ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; +ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; +ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; +ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; +ACPI_EXTERN u32 acpi_gbl_trace_flags; + /***************************************************************************** * * Runtime configuration (static defaults that can be overriden at runtime) diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index 76ac1533c405..dca0d40ea395 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -735,59 +735,52 @@ struct acpi_bit_register_info { /* resource_type values */ -#define ACPI_RESOURCE_TYPE_MEMORY_RANGE 0 -#define ACPI_RESOURCE_TYPE_IO_RANGE 1 -#define ACPI_RESOURCE_TYPE_BUS_NUMBER_RANGE 2 +#define ACPI_ADDRESS_TYPE_MEMORY_RANGE 0 +#define ACPI_ADDRESS_TYPE_IO_RANGE 1 +#define ACPI_ADDRESS_TYPE_BUS_NUMBER_RANGE 2 /* Resource descriptor types and masks */ -#define ACPI_RDESC_TYPE_LARGE 0x80 -#define ACPI_RDESC_TYPE_SMALL 0x00 +#define ACPI_RESOURCE_NAME_LARGE 0x80 +#define ACPI_RESOURCE_NAME_SMALL 0x00 -#define ACPI_RDESC_SMALL_MASK 0x78 /* Bits 6:3 contain the type */ -#define ACPI_RDESC_SMALL_LENGTH_MASK 0x07 /* Bits 2:0 contain the length */ -#define ACPI_RDESC_LARGE_MASK 0x7F /* Bits 6:0 contain the type */ +#define ACPI_RESOURCE_NAME_SMALL_MASK 0x78 /* Bits 6:3 contain the type */ +#define ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK 0x07 /* Bits 2:0 contain the length */ +#define ACPI_RESOURCE_NAME_LARGE_MASK 0x7F /* Bits 6:0 contain the type */ /* - * Small resource descriptor types + * Small resource descriptor "names" as defined by the ACPI specification. * Note: Bits 2:0 are used for the descriptor length */ -#define ACPI_RDESC_TYPE_IRQ_FORMAT 0x20 -#define ACPI_RDESC_TYPE_DMA_FORMAT 0x28 -#define ACPI_RDESC_TYPE_START_DEPENDENT 0x30 -#define ACPI_RDESC_TYPE_END_DEPENDENT 0x38 -#define ACPI_RDESC_TYPE_IO_PORT 0x40 -#define ACPI_RDESC_TYPE_FIXED_IO_PORT 0x48 -#define ACPI_RDESC_TYPE_RESERVED_S1 0x50 -#define ACPI_RDESC_TYPE_RESERVED_S2 0x58 -#define ACPI_RDESC_TYPE_RESERVED_S3 0x60 -#define ACPI_RDESC_TYPE_RESERVED_S4 0x68 -#define ACPI_RDESC_TYPE_SMALL_VENDOR 0x70 -#define ACPI_RDESC_TYPE_END_TAG 0x78 +#define ACPI_RESOURCE_NAME_IRQ 0x20 +#define ACPI_RESOURCE_NAME_DMA 0x28 +#define ACPI_RESOURCE_NAME_START_DEPENDENT 0x30 +#define ACPI_RESOURCE_NAME_END_DEPENDENT 0x38 +#define ACPI_RESOURCE_NAME_IO 0x40 +#define ACPI_RESOURCE_NAME_FIXED_IO 0x48 +#define ACPI_RESOURCE_NAME_RESERVED_S1 0x50 +#define ACPI_RESOURCE_NAME_RESERVED_S2 0x58 +#define ACPI_RESOURCE_NAME_RESERVED_S3 0x60 +#define ACPI_RESOURCE_NAME_RESERVED_S4 0x68 +#define ACPI_RESOURCE_NAME_VENDOR_SMALL 0x70 +#define ACPI_RESOURCE_NAME_END_TAG 0x78 /* - * Large resource descriptor types + * Large resource descriptor "names" as defined by the ACPI specification. + * Note: includes the Large Descriptor bit in bit[7] */ -#define ACPI_RDESC_TYPE_MEMORY_24 0x81 -#define ACPI_RDESC_TYPE_GENERIC_REGISTER 0x82 -#define ACPI_RDESC_TYPE_RESERVED_L1 0x83 -#define ACPI_RDESC_TYPE_LARGE_VENDOR 0x84 -#define ACPI_RDESC_TYPE_MEMORY_32 0x85 -#define ACPI_RDESC_TYPE_FIXED_MEMORY_32 0x86 -#define ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE 0x87 -#define ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE 0x88 -#define ACPI_RDESC_TYPE_EXTENDED_XRUPT 0x89 -#define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE 0x8A -#define ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE 0x8B -#define ACPI_RDESC_LARGE_MAX 0x8B - -/* - * Minimum lengths for descriptors with optional fields - */ -#define ACPI_RDESC_QWORD_MIN 43 -#define ACPI_RDESC_DWORD_MIN 23 -#define ACPI_RDESC_WORD_MIN 13 -#define ACPI_RDESC_EXT_XRUPT_MIN 6 +#define ACPI_RESOURCE_NAME_MEMORY24 0x81 +#define ACPI_RESOURCE_NAME_GENERIC_REGISTER 0x82 +#define ACPI_RESOURCE_NAME_RESERVED_L1 0x83 +#define ACPI_RESOURCE_NAME_VENDOR_LARGE 0x84 +#define ACPI_RESOURCE_NAME_MEMORY32 0x85 +#define ACPI_RESOURCE_NAME_FIXED_MEMORY32 0x86 +#define ACPI_RESOURCE_NAME_ADDRESS32 0x87 +#define ACPI_RESOURCE_NAME_ADDRESS16 0x88 +#define ACPI_RESOURCE_NAME_EXTENDED_IRQ 0x89 +#define ACPI_RESOURCE_NAME_ADDRESS64 0x8A +#define ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 0x8B +#define ACPI_RESOURCE_NAME_LARGE_MAX 0x8B /***************************************************************************** * @@ -795,7 +788,7 @@ struct acpi_bit_register_info { * ****************************************************************************/ -#define ACPI_ASCII_ZERO 0x30 +#define ACPI_ASCII_ZERO 0x30 /***************************************************************************** * diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 702cc4e57f5f..258cfe5e2aac 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -525,6 +525,9 @@ * bad form, but having a separate exit macro is very ugly and difficult to maintain. * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros * so that "_acpi_function_name" is defined. + * + * Note: the DO_WHILE0 macro is used to prevent some compilers from complaining + * about these constructs. */ #ifdef ACPI_USE_DO_WHILE_0 #define ACPI_DO_WHILE0(a) do a while(0) @@ -532,10 +535,55 @@ #define ACPI_DO_WHILE0(a) a #endif -#define return_VOID ACPI_DO_WHILE0 ({acpi_ut_exit(ACPI_DEBUG_PARAMETERS);return;}) -#define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({acpi_ut_status_exit(ACPI_DEBUG_PARAMETERS,(s));return((s));}) -#define return_VALUE(s) ACPI_DO_WHILE0 ({acpi_ut_value_exit(ACPI_DEBUG_PARAMETERS,(acpi_integer)(s));return((s));}) -#define return_PTR(s) ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(ACPI_DEBUG_PARAMETERS,(u8 *)(s));return((s));}) +#define return_VOID ACPI_DO_WHILE0 ({ \ + acpi_ut_exit (ACPI_DEBUG_PARAMETERS); \ + return;}) +/* + * There are two versions of most of the return macros. The default version is + * safer, since it avoids side-effects by guaranteeing that the argument will + * not be evaluated twice. + * + * A less-safe version of the macros is provided for optional use if the + * compiler uses excessive CPU stack (for example, this may happen in the + * debug case if code optimzation is disabled.) + */ +#ifndef ACPI_SIMPLE_RETURN_MACROS + +#define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({ \ + register acpi_status _s = (s); \ + acpi_ut_status_exit (ACPI_DEBUG_PARAMETERS, _s); \ + return (_s); }) +#define return_PTR(s) ACPI_DO_WHILE0 ({ \ + register void *_s = (void *) (s); \ + acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) _s); \ + return (_s); }) +#define return_VALUE(s) ACPI_DO_WHILE0 ({ \ + register acpi_integer _s = (s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \ + return (_s); }) +#define return_UINT8(s) ACPI_DO_WHILE0 ({ \ + register u8 _s = (u8) (s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \ + return (_s); }) +#define return_UINT32(s) ACPI_DO_WHILE0 ({ \ + register u32 _s = (u32) (s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \ + return (_s); }) +#else /* Use original less-safe macros */ + +#define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({ \ + acpi_ut_status_exit (ACPI_DEBUG_PARAMETERS, (s)); \ + return((s)); }) +#define return_PTR(s) ACPI_DO_WHILE0 ({ \ + acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) (s)); \ + return((s)); }) +#define return_VALUE(s) ACPI_DO_WHILE0 ({ \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) (s)); \ + return((s)); }) +#define return_UINT8(s) return_VALUE(s) +#define return_UINT32(s) return_VALUE(s) + +#endif /* ACPI_SIMPLE_RETURN_MACROS */ /* Conditional execution */ @@ -612,6 +660,8 @@ #define return_VOID return #define return_ACPI_STATUS(s) return(s) #define return_VALUE(s) return(s) +#define return_UINT8(s) return(s) +#define return_UINT32(s) return(s) #define return_PTR(s) return(s) #endif diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index c1b4e1f882e4..b425f9bb6d43 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -52,8 +52,8 @@ /* ACPI PCI Interrupt Link (pci_link.c) */ int acpi_irq_penalty_init(void); -int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *edge_level, - int *active_high_low, char **name); +int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, + int *polarity, char **name); int acpi_pci_link_free_irq(acpi_handle handle); /* ACPI PCI Interrupt Routing (pci_irq.c) */ diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 2a9dbc13b0f2..02f00a8fee03 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -149,6 +149,9 @@ acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler); acpi_status acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data); +acpi_status +acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags); + /* * Object manipulation and enumeration */ diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h index ce2cf72fd4c8..b66994e9e4ee 100644 --- a/include/acpi/acresrc.h +++ b/include/acpi/acresrc.h @@ -44,6 +44,51 @@ #ifndef __ACRESRC_H__ #define __ACRESRC_H__ +/* Need the AML resource descriptor structs */ + +#include "amlresrc.h" + +/* + * Resource dispatch and info tables + */ +struct acpi_resource_info { + u8 length_type; + u8 minimum_aml_resource_length; + u8 minimum_internal_struct_length; +}; + +/* Types for length_type above */ + +#define ACPI_FIXED_LENGTH 0 +#define ACPI_VARIABLE_LENGTH 1 +#define ACPI_SMALL_VARIABLE_LENGTH 2 + +/* Handlers */ + +typedef acpi_status(*ACPI_SET_RESOURCE_HANDLER) (struct acpi_resource * + resource, + union aml_resource * aml); + +typedef acpi_status(*ACPI_GET_RESOURCE_HANDLER) (union aml_resource * aml, + u16 aml_resource_length, + struct acpi_resource * + resource); + +typedef void (*ACPI_DUMP_RESOURCE_HANDLER) (union acpi_resource_data * data); + +/* Tables indexed by internal resource type */ + +extern u8 acpi_gbl_aml_resource_sizes[]; +extern ACPI_SET_RESOURCE_HANDLER acpi_gbl_set_resource_dispatch[]; +extern ACPI_DUMP_RESOURCE_HANDLER acpi_gbl_dump_resource_dispatch[]; + +/* Tables indexed by raw AML resource descriptor type */ + +extern struct acpi_resource_info acpi_gbl_sm_resource_info[]; +extern struct acpi_resource_info acpi_gbl_lg_resource_info[]; +extern ACPI_GET_RESOURCE_HANDLER acpi_gbl_sm_get_resource_dispatch[]; +extern ACPI_GET_RESOURCE_HANDLER acpi_gbl_lg_get_resource_dispatch[]; + /* * Function prototypes called from Acpi* APIs */ @@ -66,12 +111,12 @@ acpi_status acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer); acpi_status -acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer, +acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, struct acpi_buffer *output_buffer); acpi_status -acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, - struct acpi_buffer *output_buffer); +acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, + struct acpi_buffer *output_buffer); acpi_status acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, @@ -90,184 +135,240 @@ void acpi_rs_dump_irq_list(u8 * route_table); * rscalc */ acpi_status -acpi_rs_get_byte_stream_start(u8 * byte_stream_buffer, - u8 ** byte_stream_start, u32 * size); +acpi_rs_get_list_length(u8 * aml_buffer, + u32 aml_buffer_length, acpi_size * size_needed); acpi_status -acpi_rs_get_list_length(u8 * byte_stream_buffer, - u32 byte_stream_buffer_length, acpi_size * size_needed); - -acpi_status -acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list_buffer, - acpi_size * size_needed); +acpi_rs_get_aml_length(struct acpi_resource *linked_list_buffer, + acpi_size * size_needed); acpi_status acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, acpi_size * buffer_size_needed); acpi_status -acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, - u32 byte_stream_buffer_length, u8 * output_buffer); +acpi_rs_convert_aml_to_resources(u8 * aml_buffer, + u32 aml_buffer_length, u8 * output_buffer); acpi_status -acpi_rs_list_to_byte_stream(struct acpi_resource *resource, - acpi_size byte_stream_size_needed, - u8 * output_buffer); +acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, + acpi_size aml_size_needed, u8 * output_buffer); + +/* + * rsio + */ +acpi_status +acpi_rs_get_io(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_io_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); +acpi_rs_set_io(struct acpi_resource *resource, union aml_resource *aml); acpi_status -acpi_rs_fixed_io_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); +acpi_rs_get_fixed_io(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_io_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); +acpi_rs_set_fixed_io(struct acpi_resource *resource, union aml_resource *aml); acpi_status -acpi_rs_fixed_io_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); +acpi_rs_get_dma(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_irq_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); +acpi_rs_set_dma(struct acpi_resource *resource, union aml_resource *aml); + +/* + * rsirq + */ +acpi_status +acpi_rs_get_irq(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_irq_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); +acpi_rs_set_irq(struct acpi_resource *resource, union aml_resource *aml); acpi_status -acpi_rs_dma_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); +acpi_rs_get_ext_irq(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_dma_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); +acpi_rs_set_ext_irq(struct acpi_resource *resource, union aml_resource *aml); + +/* + * rsaddr + */ +acpi_status +acpi_rs_get_address16(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_address16_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); +acpi_rs_set_address16(struct acpi_resource *resource, union aml_resource *aml); acpi_status -acpi_rs_address16_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); +acpi_rs_get_address32(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_address32_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); +acpi_rs_set_address32(struct acpi_resource *resource, union aml_resource *aml); acpi_status -acpi_rs_address32_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); +acpi_rs_get_address64(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_address64_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); +acpi_rs_set_address64(struct acpi_resource *resource, union aml_resource *aml); acpi_status -acpi_rs_address64_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); +acpi_rs_get_ext_address64(union aml_resource *aml, + u16 aml_resource_length, + struct acpi_resource *resource); acpi_status -acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size); +acpi_rs_set_ext_address64(struct acpi_resource *resource, + union aml_resource *aml); + +/* + * rsmemory + */ +acpi_status +acpi_rs_get_memory24(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size); +acpi_rs_set_memory24(struct acpi_resource *resource, union aml_resource *aml); acpi_status -acpi_rs_start_depend_fns_stream(struct acpi_resource *resource, - u8 ** output_buffer, - acpi_size * bytes_consumed); +acpi_rs_get_memory32(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); acpi_status -acpi_rs_end_depend_fns_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); +acpi_rs_set_memory32(struct acpi_resource *resource, union aml_resource *aml); acpi_status -acpi_rs_memory24_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); +acpi_rs_get_fixed_memory32(union aml_resource *aml, + u16 aml_resource_length, + struct acpi_resource *resource); acpi_status -acpi_rs_memory24_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); - -acpi_status -acpi_rs_memory32_range_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size); - -acpi_status -acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size); - -acpi_status -acpi_rs_memory32_range_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); - -acpi_status -acpi_rs_fixed_memory32_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); - -acpi_status -acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); - -acpi_status -acpi_rs_extended_irq_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); - -acpi_status -acpi_rs_end_tag_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); - -acpi_status -acpi_rs_end_tag_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); - -acpi_status -acpi_rs_vendor_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, acpi_size * structure_size); - -acpi_status -acpi_rs_vendor_stream(struct acpi_resource *resource, - u8 ** output_buffer, acpi_size * bytes_consumed); - -u8 acpi_rs_get_resource_type(u8 resource_start_byte); +acpi_rs_set_fixed_memory32(struct acpi_resource *resource, + union aml_resource *aml); /* * rsmisc */ acpi_status -acpi_rs_generic_register_resource(u8 * byte_stream_buffer, - acpi_size * bytes_consumed, - u8 ** output_buffer, - acpi_size * structure_size); +acpi_rs_get_generic_reg(union aml_resource *aml, + u16 aml_resource_length, + struct acpi_resource *resource); acpi_status -acpi_rs_generic_register_stream(struct acpi_resource *resource, - u8 ** output_buffer, - acpi_size * bytes_consumed); +acpi_rs_set_generic_reg(struct acpi_resource *resource, + union aml_resource *aml); + +acpi_status +acpi_rs_get_vendor(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); + +acpi_status +acpi_rs_set_vendor(struct acpi_resource *resource, union aml_resource *aml); + +acpi_status +acpi_rs_get_start_dpf(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); + +acpi_status +acpi_rs_set_start_dpf(struct acpi_resource *resource, union aml_resource *aml); + +acpi_status +acpi_rs_get_end_dpf(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); + +acpi_status +acpi_rs_set_end_dpf(struct acpi_resource *resource, union aml_resource *aml); + +acpi_status +acpi_rs_get_end_tag(union aml_resource *aml, + u16 aml_resource_length, struct acpi_resource *resource); + +acpi_status +acpi_rs_set_end_tag(struct acpi_resource *resource, union aml_resource *aml); + +/* + * rsutils + */ +void +acpi_rs_move_data(void *destination, + void *source, u16 item_count, u8 move_type); + +/* Types used in move_type above */ + +#define ACPI_MOVE_TYPE_16_TO_32 0 +#define ACPI_MOVE_TYPE_32_TO_16 1 +#define ACPI_MOVE_TYPE_32_TO_32 2 +#define ACPI_MOVE_TYPE_64_TO_64 3 + +u16 +acpi_rs_get_resource_source(u16 resource_length, + acpi_size minimum_length, + struct acpi_resource_source *resource_source, + union aml_resource *aml, char *string_ptr); + +acpi_size +acpi_rs_set_resource_source(union aml_resource *aml, + acpi_size minimum_length, + struct acpi_resource_source *resource_source); + +u8 acpi_rs_get_resource_type(u8 resource_start_byte); + +u32 acpi_rs_get_descriptor_length(union aml_resource *aml); + +u16 acpi_rs_get_resource_length(union aml_resource *aml); + +void +acpi_rs_set_resource_header(u8 descriptor_type, + acpi_size total_length, union aml_resource *aml); + +struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type); + +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +/* + * rsdump + */ +void acpi_rs_dump_irq(union acpi_resource_data *resource); + +void acpi_rs_dump_address16(union acpi_resource_data *resource); + +void acpi_rs_dump_address32(union acpi_resource_data *resource); + +void acpi_rs_dump_address64(union acpi_resource_data *resource); + +void acpi_rs_dump_ext_address64(union acpi_resource_data *resource); + +void acpi_rs_dump_dma(union acpi_resource_data *resource); + +void acpi_rs_dump_io(union acpi_resource_data *resource); + +void acpi_rs_dump_ext_irq(union acpi_resource_data *resource); + +void acpi_rs_dump_fixed_io(union acpi_resource_data *resource); + +void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource); + +void acpi_rs_dump_memory24(union acpi_resource_data *resource); + +void acpi_rs_dump_memory32(union acpi_resource_data *resource); + +void acpi_rs_dump_start_dpf(union acpi_resource_data *resource); + +void acpi_rs_dump_vendor(union acpi_resource_data *resource); + +void acpi_rs_dump_generic_reg(union acpi_resource_data *resource); + +void acpi_rs_dump_end_dpf(union acpi_resource_data *resource); + +void acpi_rs_dump_end_tag(union acpi_resource_data *resource); + +#endif #endif /* __ACRESRC_H__ */ diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 1dfa64fae4ec..43f7c509317a 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -978,10 +978,10 @@ struct acpi_mem_space_context { * Structures used to describe device resources */ struct acpi_resource_irq { - u32 edge_level; - u32 active_high_low; - u32 shared_exclusive; - u32 number_of_interrupts; + u32 triggering; + u32 polarity; + u32 sharable; + u32 interrupt_count; u32 interrupts[1]; }; @@ -989,11 +989,11 @@ struct acpi_resource_dma { u32 type; u32 bus_master; u32 transfer; - u32 number_of_channels; + u32 channel_count; u32 channels[1]; }; -struct acpi_resource_start_dpf { +struct acpi_resource_start_dependent { u32 compatibility_priority; u32 performance_robustness; }; @@ -1005,46 +1005,46 @@ struct acpi_resource_start_dpf { struct acpi_resource_io { u32 io_decode; - u32 min_base_address; - u32 max_base_address; + u32 minimum; + u32 maximum; u32 alignment; - u32 range_length; + u32 address_length; }; struct acpi_resource_fixed_io { - u32 base_address; - u32 range_length; + u32 address; + u32 address_length; }; struct acpi_resource_vendor { - u32 length; - u8 reserved[1]; + u32 byte_length; + u8 byte_data[1]; }; struct acpi_resource_end_tag { u8 checksum; }; -struct acpi_resource_mem24 { +struct acpi_resource_memory24 { u32 read_write_attribute; - u32 min_base_address; - u32 max_base_address; + u32 minimum; + u32 maximum; u32 alignment; - u32 range_length; + u32 address_length; }; -struct acpi_resource_mem32 { +struct acpi_resource_memory32 { u32 read_write_attribute; - u32 min_base_address; - u32 max_base_address; + u32 minimum; + u32 maximum; u32 alignment; - u32 range_length; + u32 address_length; }; -struct acpi_resource_fixed_mem32 { +struct acpi_resource_fixed_memory32 { u32 read_write_attribute; - u32 range_base_address; - u32 range_length; + u32 address; + u32 address_length; }; struct acpi_memory_attribute { @@ -1089,93 +1089,105 @@ ACPI_RESOURCE_ADDRESS_COMMON}; struct acpi_resource_address16 { ACPI_RESOURCE_ADDRESS_COMMON u32 granularity; - u32 min_address_range; - u32 max_address_range; - u32 address_translation_offset; + u32 minimum; + u32 maximum; + u32 translation_offset; u32 address_length; struct acpi_resource_source resource_source; }; struct acpi_resource_address32 { ACPI_RESOURCE_ADDRESS_COMMON u32 granularity; - u32 min_address_range; - u32 max_address_range; - u32 address_translation_offset; + u32 minimum; + u32 maximum; + u32 translation_offset; u32 address_length; struct acpi_resource_source resource_source; }; struct acpi_resource_address64 { ACPI_RESOURCE_ADDRESS_COMMON u64 granularity; - u64 min_address_range; - u64 max_address_range; - u64 address_translation_offset; + u64 minimum; + u64 maximum; + u64 translation_offset; u64 address_length; - u64 type_specific_attributes; struct acpi_resource_source resource_source; }; -struct acpi_resource_ext_irq { +struct acpi_resource_extended_address64 { + ACPI_RESOURCE_ADDRESS_COMMON u64 granularity; + u64 minimum; + u64 maximum; + u64 translation_offset; + u64 address_length; + u64 type_specific_attributes; + u8 revision_iD; +}; + +struct acpi_resource_extended_irq { u32 producer_consumer; - u32 edge_level; - u32 active_high_low; - u32 shared_exclusive; - u32 number_of_interrupts; + u32 triggering; + u32 polarity; + u32 sharable; + u32 interrupt_count; struct acpi_resource_source resource_source; u32 interrupts[1]; }; -struct acpi_resource_generic_reg { +struct acpi_resource_generic_register { u32 space_id; u32 bit_width; u32 bit_offset; - u32 address_size; + u32 access_size; u64 address; }; /* ACPI_RESOURCE_TYPEs */ -#define ACPI_RSTYPE_IRQ 0 -#define ACPI_RSTYPE_DMA 1 -#define ACPI_RSTYPE_START_DPF 2 -#define ACPI_RSTYPE_END_DPF 3 -#define ACPI_RSTYPE_IO 4 -#define ACPI_RSTYPE_FIXED_IO 5 -#define ACPI_RSTYPE_VENDOR 6 -#define ACPI_RSTYPE_END_TAG 7 -#define ACPI_RSTYPE_MEM24 8 -#define ACPI_RSTYPE_MEM32 9 -#define ACPI_RSTYPE_FIXED_MEM32 10 -#define ACPI_RSTYPE_ADDRESS16 11 -#define ACPI_RSTYPE_ADDRESS32 12 -#define ACPI_RSTYPE_ADDRESS64 13 -#define ACPI_RSTYPE_EXT_IRQ 14 -#define ACPI_RSTYPE_GENERIC_REG 15 -#define ACPI_RSTYPE_MAX 15 - -typedef u32 acpi_resource_type; +#define ACPI_RESOURCE_TYPE_IRQ 0 +#define ACPI_RESOURCE_TYPE_DMA 1 +#define ACPI_RESOURCE_TYPE_START_DEPENDENT 2 +#define ACPI_RESOURCE_TYPE_END_DEPENDENT 3 +#define ACPI_RESOURCE_TYPE_IO 4 +#define ACPI_RESOURCE_TYPE_FIXED_IO 5 +#define ACPI_RESOURCE_TYPE_VENDOR 6 +#define ACPI_RESOURCE_TYPE_END_TAG 7 +#define ACPI_RESOURCE_TYPE_MEMORY24 8 +#define ACPI_RESOURCE_TYPE_MEMORY32 9 +#define ACPI_RESOURCE_TYPE_FIXED_MEMORY32 10 +#define ACPI_RESOURCE_TYPE_ADDRESS16 11 +#define ACPI_RESOURCE_TYPE_ADDRESS32 12 +#define ACPI_RESOURCE_TYPE_ADDRESS64 13 +#define ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 14 /* ACPI 3.0 */ +#define ACPI_RESOURCE_TYPE_EXTENDED_IRQ 15 +#define ACPI_RESOURCE_TYPE_GENERIC_REGISTER 16 +#define ACPI_RESOURCE_TYPE_MAX 16 union acpi_resource_data { struct acpi_resource_irq irq; struct acpi_resource_dma dma; - struct acpi_resource_start_dpf start_dpf; + struct acpi_resource_start_dependent start_dpf; struct acpi_resource_io io; struct acpi_resource_fixed_io fixed_io; - struct acpi_resource_vendor vendor_specific; + struct acpi_resource_vendor vendor; struct acpi_resource_end_tag end_tag; - struct acpi_resource_mem24 memory24; - struct acpi_resource_mem32 memory32; - struct acpi_resource_fixed_mem32 fixed_memory32; - struct acpi_resource_address address; /* Common 16/32/64 address fields */ + struct acpi_resource_memory24 memory24; + struct acpi_resource_memory32 memory32; + struct acpi_resource_fixed_memory32 fixed_memory32; struct acpi_resource_address16 address16; struct acpi_resource_address32 address32; struct acpi_resource_address64 address64; - struct acpi_resource_ext_irq extended_irq; - struct acpi_resource_generic_reg generic_reg; + struct acpi_resource_extended_address64 ext_address64; + struct acpi_resource_extended_irq extended_irq; + struct acpi_resource_generic_register generic_reg; + + /* Common fields */ + + struct acpi_resource_address address; /* Common 16/32/64 address fields */ }; struct acpi_resource { - acpi_resource_type type; + u32 type; u32 length; union acpi_resource_data data; }; @@ -1183,7 +1195,7 @@ struct acpi_resource { #define ACPI_RESOURCE_LENGTH 12 #define ACPI_RESOURCE_LENGTH_NO_DATA 8 /* Id + Length fields */ -#define ACPI_SIZEOF_RESOURCE(type) (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type)) +#define ACPI_SIZEOF_RESOURCE(type) (u32) (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type)) #define ACPI_NEXT_RESOURCE(res) (struct acpi_resource *)((u8 *) res + res->length) diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h index a3c46ba6358d..103aff07db18 100644 --- a/include/acpi/amlresrc.h +++ b/include/acpi/amlresrc.h @@ -96,165 +96,159 @@ struct asl_resource_node { * Resource descriptors defined in the ACPI specification. * * Packing/alignment must be BYTE because these descriptors - * are used to overlay the AML byte stream. + * are used to overlay the raw AML byte stream. */ #pragma pack(1) -struct asl_irq_format_desc { - u8 descriptor_type; - u16 irq_mask; +/* + * SMALL descriptors + */ +#define AML_RESOURCE_SMALL_HEADER_COMMON \ + u8 descriptor_type; + +struct aml_resource_small_header { +AML_RESOURCE_SMALL_HEADER_COMMON}; + +struct aml_resource_irq { + AML_RESOURCE_SMALL_HEADER_COMMON u16 irq_mask; u8 flags; }; -struct asl_irq_noflags_desc { - u8 descriptor_type; - u16 irq_mask; +struct aml_resource_irq_noflags { + AML_RESOURCE_SMALL_HEADER_COMMON u16 irq_mask; }; -struct asl_dma_format_desc { - u8 descriptor_type; - u8 dma_channel_mask; +struct aml_resource_dma { + AML_RESOURCE_SMALL_HEADER_COMMON u8 dma_channel_mask; u8 flags; }; -struct asl_start_dependent_desc { - u8 descriptor_type; - u8 flags; +struct aml_resource_start_dependent { + AML_RESOURCE_SMALL_HEADER_COMMON u8 flags; }; -struct asl_start_dependent_noprio_desc { - u8 descriptor_type; -}; +struct aml_resource_start_dependent_noprio { +AML_RESOURCE_SMALL_HEADER_COMMON}; -struct asl_end_dependent_desc { - u8 descriptor_type; -}; +struct aml_resource_end_dependent { +AML_RESOURCE_SMALL_HEADER_COMMON}; -struct asl_io_port_desc { - u8 descriptor_type; - u8 information; - u16 address_min; - u16 address_max; +struct aml_resource_io { + AML_RESOURCE_SMALL_HEADER_COMMON u8 information; + u16 minimum; + u16 maximum; u8 alignment; - u8 length; + u8 address_length; }; -struct asl_fixed_io_port_desc { - u8 descriptor_type; - u16 base_address; - u8 length; +struct aml_resource_fixed_io { + AML_RESOURCE_SMALL_HEADER_COMMON u16 address; + u8 address_length; }; -struct asl_small_vendor_desc { - u8 descriptor_type; - u8 vendor_defined[7]; +struct aml_resource_vendor_small { +AML_RESOURCE_SMALL_HEADER_COMMON}; + +struct aml_resource_end_tag { + AML_RESOURCE_SMALL_HEADER_COMMON u8 checksum; }; -struct asl_end_tag_desc { - u8 descriptor_type; - u8 checksum; -}; - -/* LARGE descriptors */ - -#define ASL_LARGE_HEADER_COMMON \ +/* + * LARGE descriptors + */ +#define AML_RESOURCE_LARGE_HEADER_COMMON \ u8 descriptor_type;\ - u16 length; + u16 resource_length; -struct asl_large_header { -ASL_LARGE_HEADER_COMMON}; +struct aml_resource_large_header { +AML_RESOURCE_LARGE_HEADER_COMMON}; -struct asl_memory_24_desc { - ASL_LARGE_HEADER_COMMON u8 information; - u16 address_min; - u16 address_max; +struct aml_resource_memory24 { + AML_RESOURCE_LARGE_HEADER_COMMON u8 information; + u16 minimum; + u16 maximum; u16 alignment; - u16 range_length; + u16 address_length; }; -struct asl_large_vendor_desc { - ASL_LARGE_HEADER_COMMON u8 vendor_defined[1]; -}; +struct aml_resource_vendor_large { +AML_RESOURCE_LARGE_HEADER_COMMON}; -struct asl_memory_32_desc { - ASL_LARGE_HEADER_COMMON u8 information; - u32 address_min; - u32 address_max; +struct aml_resource_memory32 { + AML_RESOURCE_LARGE_HEADER_COMMON u8 information; + u32 minimum; + u32 maximum; u32 alignment; - u32 range_length; + u32 address_length; }; -struct asl_fixed_memory_32_desc { - ASL_LARGE_HEADER_COMMON u8 information; - u32 base_address; - u32 range_length; +struct aml_resource_fixed_memory32 { + AML_RESOURCE_LARGE_HEADER_COMMON u8 information; + u32 address; + u32 address_length; }; -struct asl_extended_address_desc { - ASL_LARGE_HEADER_COMMON u8 resource_type; - u8 flags; - u8 specific_flags; - u8 revision_iD; +#define AML_RESOURCE_ADDRESS_COMMON \ + u8 resource_type; \ + u8 flags; \ + u8 specific_flags; + +struct aml_resource_address { +AML_RESOURCE_LARGE_HEADER_COMMON AML_RESOURCE_ADDRESS_COMMON}; + +struct aml_resource_extended_address64 { + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON u8 revision_iD; u8 reserved; u64 granularity; - u64 address_min; - u64 address_max; + u64 minimum; + u64 maximum; u64 translation_offset; u64 address_length; u64 type_specific_attributes; - u8 optional_fields[2]; /* Used for length calculation only */ }; -#define ASL_EXTENDED_ADDRESS_DESC_REVISION 1 /* ACPI 3.0 */ +#define AML_RESOURCE_EXTENDED_ADDRESS_REVISION 1 /* ACPI 3.0 */ -struct asl_qword_address_desc { - ASL_LARGE_HEADER_COMMON u8 resource_type; - u8 flags; - u8 specific_flags; - u64 granularity; - u64 address_min; - u64 address_max; +struct aml_resource_address64 { + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON u64 granularity; + u64 minimum; + u64 maximum; u64 translation_offset; u64 address_length; - u8 optional_fields[2]; }; -struct asl_dword_address_desc { - ASL_LARGE_HEADER_COMMON u8 resource_type; - u8 flags; - u8 specific_flags; - u32 granularity; - u32 address_min; - u32 address_max; +struct aml_resource_address32 { + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON u32 granularity; + u32 minimum; + u32 maximum; u32 translation_offset; u32 address_length; - u8 optional_fields[2]; }; -struct asl_word_address_desc { - ASL_LARGE_HEADER_COMMON u8 resource_type; - u8 flags; - u8 specific_flags; - u16 granularity; - u16 address_min; - u16 address_max; +struct aml_resource_address16 { + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON u16 granularity; + u16 minimum; + u16 maximum; u16 translation_offset; u16 address_length; - u8 optional_fields[2]; }; -struct asl_extended_xrupt_desc { - ASL_LARGE_HEADER_COMMON u8 flags; +struct aml_resource_extended_irq { + AML_RESOURCE_LARGE_HEADER_COMMON u8 flags; u8 table_length; u32 interrupt_number[1]; /* res_source_index, res_source optional fields follow */ }; -struct asl_generic_register_desc { - ASL_LARGE_HEADER_COMMON u8 address_space_id; +struct aml_resource_generic_register { + AML_RESOURCE_LARGE_HEADER_COMMON u8 address_space_id; u8 bit_width; u8 bit_offset; - u8 access_size; /* ACPI 3.0, was Reserved */ + u8 access_size; /* ACPI 3.0, was previously Reserved */ u64 address; }; @@ -264,27 +258,39 @@ struct asl_generic_register_desc { /* Union of all resource descriptors, so we can allocate the worst case */ -union asl_resource_desc { - struct asl_irq_format_desc irq; - struct asl_dma_format_desc dma; - struct asl_io_port_desc iop; - struct asl_fixed_io_port_desc fio; - struct asl_start_dependent_desc std; - struct asl_end_dependent_desc end; - struct asl_small_vendor_desc smv; - struct asl_end_tag_desc et; +union aml_resource { + /* Descriptor headers */ - struct asl_large_header lhd; - struct asl_memory_24_desc M24; - struct asl_large_vendor_desc lgv; - struct asl_memory_32_desc M32; - struct asl_fixed_memory_32_desc F32; - struct asl_qword_address_desc qas; - struct asl_dword_address_desc das; - struct asl_word_address_desc was; - struct asl_extended_address_desc eas; - struct asl_extended_xrupt_desc exx; - struct asl_generic_register_desc grg; + struct aml_resource_small_header small_header; + struct aml_resource_large_header large_header; + + /* Small resource descriptors */ + + struct aml_resource_irq irq; + struct aml_resource_dma dma; + struct aml_resource_start_dependent start_dpf; + struct aml_resource_end_dependent end_dpf; + struct aml_resource_io io; + struct aml_resource_fixed_io fixed_io; + struct aml_resource_vendor_small vendor_small; + struct aml_resource_end_tag end_tag; + + /* Large resource descriptors */ + + struct aml_resource_memory24 memory24; + struct aml_resource_generic_register generic_reg; + struct aml_resource_vendor_large vendor_large; + struct aml_resource_memory32 memory32; + struct aml_resource_fixed_memory32 fixed_memory32; + struct aml_resource_address16 address16; + struct aml_resource_address32 address32; + struct aml_resource_address64 address64; + struct aml_resource_extended_address64 ext_address64; + struct aml_resource_extended_irq extended_irq; + + /* Utility overlays */ + + struct aml_resource_address address; u32 u32_item; u16 u16_item; u8 U8item; diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h index 6f8a17d105ab..ac59045e7bab 100644 --- a/include/asm-x86_64/mpspec.h +++ b/include/asm-x86_64/mpspec.h @@ -188,7 +188,7 @@ extern void mp_register_lapic_address (u64 address); extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi); extern void mp_config_acpi_legacy_irqs (void); -extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low); +extern int mp_register_gsi (u32 gsi, int triggering, int polarity); #endif /*CONFIG_X86_IO_APIC*/ #endif diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 026c3c011dc0..84d3d9f034ce 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -435,7 +435,7 @@ extern int sbf_port ; #endif /* !CONFIG_ACPI */ -int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low); +int acpi_register_gsi (u32 gsi, int triggering, int polarity); int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); /* From 0897831bb54eb36fd9e2a22da7f0f64be1b20d09 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 21 Oct 2005 00:00:00 -0400 Subject: [PATCH 015/695] [ACPI] ACPICA 20051021 Implemented support for the EM64T and other x86_64 processors. This essentially entails recognizing that these processors support non-aligned memory transfers. Previously, all 64-bit processors were assumed to lack hardware support for non-aligned transfers. Completed conversion of the Resource Manager to nearly full table-driven operation. Specifically, the resource conversion code (convert AML to internal format and the reverse) and the debug code to dump internal resource descriptors are fully table-driven, reducing code and data size and improving maintainability. The OSL interfaces for Acquire and Release Lock now use a 64-bit flag word on 64-bit processors instead of a fixed 32-bit word. (Alexey Starikovskiy) Implemented support within the resource conversion code for the Type-Specific byte within the various ACPI 3.0 *WordSpace macros. Fixed some issues within the resource conversion code for the type-specific flags for both Memory and I/O address resource descriptors. For Memory, implemented support for the MTP and TTP flags. For I/O, split the TRS and TTP flags into two separate fields. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- arch/ia64/pci/pci.c | 2 +- drivers/acpi/events/evgpe.c | 12 +- drivers/acpi/events/evgpeblk.c | 10 +- drivers/acpi/events/evxface.c | 4 +- drivers/acpi/executer/exmisc.c | 5 +- drivers/acpi/executer/exregion.c | 4 +- drivers/acpi/osl.c | 6 +- drivers/acpi/resources/rsaddr.c | 933 ++++++------------ drivers/acpi/resources/rscalc.c | 71 +- drivers/acpi/resources/rsdump.c | 1483 ++++++++++++----------------- drivers/acpi/resources/rsinfo.c | 115 ++- drivers/acpi/resources/rsio.c | 375 +++----- drivers/acpi/resources/rsirq.c | 377 +++----- drivers/acpi/resources/rslist.c | 92 +- drivers/acpi/resources/rsmemory.c | 337 +++---- drivers/acpi/resources/rsmisc.c | 812 +++++++++------- drivers/acpi/resources/rsutils.c | 277 +++--- drivers/acpi/resources/rsxface.c | 2 +- drivers/acpi/tables/tbutils.c | 5 +- drivers/acpi/utilities/utalloc.c | 2 +- drivers/acpi/utilities/utglobal.c | 64 +- drivers/acpi/utilities/utmisc.c | 148 ++- drivers/pnp/pnpacpi/rsparser.c | 12 +- include/acpi/acconfig.h | 2 +- include/acpi/acdisasm.h | 19 +- include/acpi/acmacros.h | 6 +- include/acpi/acpiosxf.h | 4 +- include/acpi/acresrc.h | 395 ++++---- include/acpi/actypes.h | 183 ++-- include/acpi/acutils.h | 7 +- include/acpi/amlresrc.h | 14 +- include/acpi/platform/acenv.h | 11 +- 32 files changed, 2541 insertions(+), 3248 deletions(-) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 25f923d050e3..5536027da9d8 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -195,7 +195,7 @@ add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr) min = addr->minimum; max = min + addr->address_length - 1; - if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION) + if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION) sparse = 1; space_nr = new_space(addr->translation_offset, sparse); diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index f51c3b16c608..bdd86537738e 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -372,14 +372,14 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) { - u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; - u8 enabled_status_byte; - struct acpi_gpe_register_info *gpe_register_info; - u32 status_reg; - u32 enable_reg; - u32 flags; acpi_status status; struct acpi_gpe_block_info *gpe_block; + struct acpi_gpe_register_info *gpe_register_info; + u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; + u8 enabled_status_byte; + u32 status_reg; + u32 enable_reg; + acpi_native_uint flags; acpi_native_uint i; acpi_native_uint j; diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index b312eb33c43e..7ca10c5f2914 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c @@ -136,7 +136,7 @@ acpi_status acpi_ev_walk_gpe_list(ACPI_GPE_CALLBACK gpe_walk_callback) struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_xrupt_info *gpe_xrupt_info; acpi_status status = AE_OK; - u32 flags; + acpi_native_uint flags; ACPI_FUNCTION_TRACE("ev_walk_gpe_list"); @@ -479,7 +479,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 struct acpi_gpe_xrupt_info *next_gpe_xrupt; struct acpi_gpe_xrupt_info *gpe_xrupt; acpi_status status; - u32 flags; + acpi_native_uint flags; ACPI_FUNCTION_TRACE("ev_get_gpe_xrupt_block"); @@ -553,7 +553,7 @@ static acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) { acpi_status status; - u32 flags; + acpi_native_uint flags; ACPI_FUNCTION_TRACE("ev_delete_gpe_xrupt"); @@ -610,7 +610,7 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, struct acpi_gpe_block_info *next_gpe_block; struct acpi_gpe_xrupt_info *gpe_xrupt_block; acpi_status status; - u32 flags; + acpi_native_uint flags; ACPI_FUNCTION_TRACE("ev_install_gpe_block"); @@ -663,7 +663,7 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) { acpi_status status; - u32 flags; + acpi_native_uint flags; ACPI_FUNCTION_TRACE("ev_install_gpe_block"); diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index 43b33d19cdf9..57d73299298e 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c @@ -562,7 +562,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, struct acpi_gpe_event_info *gpe_event_info; struct acpi_handler_info *handler; acpi_status status; - u32 flags; + acpi_native_uint flags; ACPI_FUNCTION_TRACE("acpi_install_gpe_handler"); @@ -653,7 +653,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, struct acpi_gpe_event_info *gpe_event_info; struct acpi_handler_info *handler; acpi_status status; - u32 flags; + acpi_native_uint flags; ACPI_FUNCTION_TRACE("acpi_remove_gpe_handler"); diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index a3f4d72bedc9..1899ab251393 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -625,9 +625,8 @@ acpi_ex_do_logical_op(u16 opcode, /* Lexicographic compare: compare the data bytes */ - compare = ACPI_MEMCMP((const char *)operand0->buffer.pointer, - (const char *)local_operand1->buffer. - pointer, + compare = ACPI_MEMCMP(operand0->buffer.pointer, + local_operand1->buffer.pointer, (length0 > length1) ? length1 : length0); switch (opcode) { diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 9a2f5bea3afe..1897379b5f90 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c @@ -77,7 +77,7 @@ acpi_ex_system_memory_space_handler(u32 function, struct acpi_mem_space_context *mem_info = region_context; u32 length; acpi_size window_size; -#ifndef ACPI_MISALIGNED_TRANSFERS +#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED u32 remainder; #endif @@ -109,7 +109,7 @@ acpi_ex_system_memory_space_handler(u32 function, return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } -#ifndef ACPI_MISALIGNED_TRANSFERS +#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e3cd0b16031a..4ece850b2af1 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1058,11 +1058,9 @@ EXPORT_SYMBOL(max_cstate); * Acquire a spinlock. * * handle is a pointer to the spinlock_t. - * flags is *not* the result of save_flags - it is an ACPI-specific flag variable - * that indicates whether we are at interrupt level. */ -unsigned long acpi_os_acquire_lock(acpi_handle handle) +acpi_native_uint acpi_os_acquire_lock(acpi_handle handle) { unsigned long flags; spin_lock_irqsave((spinlock_t *) handle, flags); @@ -1073,7 +1071,7 @@ unsigned long acpi_os_acquire_lock(acpi_handle handle) * Release a spinlock. See above. */ -void acpi_os_release_lock(acpi_handle handle, unsigned long flags) +void acpi_os_release_lock(acpi_handle handle, acpi_native_uint flags) { spin_unlock_irqrestore((spinlock_t *) handle, flags); } diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 6f48ebf3304e..4ac942badbc0 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c @@ -47,171 +47,295 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsaddr") -/* Local prototypes */ -static void -acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags); +/******************************************************************************* + * + * acpi_rs_convert_address16 - All WORD (16-bit) address resources + * + ******************************************************************************/ +struct acpi_rsconvert_info acpi_rs_convert_address16[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16, + ACPI_RS_SIZE(struct acpi_resource_address16), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)}, -static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource); + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16, + sizeof(struct aml_resource_address16), + 0}, -static void -acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags); + /* Resource Type, General Flags, and Type-Specific Flags */ -static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource); + {ACPI_RSC_ADDRESS, 0, 0, 0}, -static void -acpi_rs_set_address_common(union aml_resource *aml, - struct acpi_resource *resource); + /* + * These fields are contiguous in both the source and destination: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity), + AML_OFFSET(address16.granularity), + 5}, -static u8 + /* Optional resource_source (Index and String) */ + + {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source), + 0, + sizeof(struct aml_resource_address16)} +}; + +/******************************************************************************* + * + * acpi_rs_convert_address32 - All DWORD (32-bit) address resources + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_convert_address32[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32, + ACPI_RS_SIZE(struct acpi_resource_address32), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32, + sizeof(struct aml_resource_address32), + 0}, + + /* Resource Type, General Flags, and Type-Specific Flags */ + + {ACPI_RSC_ADDRESS, 0, 0, 0}, + + /* + * These fields are contiguous in both the source and destination: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity), + AML_OFFSET(address32.granularity), + 5}, + + /* Optional resource_source (Index and String) */ + + {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source), + 0, + sizeof(struct aml_resource_address32)} +}; + +/******************************************************************************* + * + * acpi_rs_convert_address64 - All QWORD (64-bit) address resources + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_convert_address64[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64, + ACPI_RS_SIZE(struct acpi_resource_address64), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64, + sizeof(struct aml_resource_address64), + 0}, + + /* Resource Type, General Flags, and Type-Specific Flags */ + + {ACPI_RSC_ADDRESS, 0, 0, 0}, + + /* + * These fields are contiguous in both the source and destination: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + */ + {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity), + AML_OFFSET(address64.granularity), + 5}, + + /* Optional resource_source (Index and String) */ + + {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source), + 0, + sizeof(struct aml_resource_address64)} +}; + +/******************************************************************************* + * + * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, + ACPI_RS_SIZE(struct acpi_resource_extended_address64), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, + sizeof(struct aml_resource_extended_address64), + 0}, + + /* Resource Type, General Flags, and Type-Specific Flags */ + + {ACPI_RSC_ADDRESS, 0, 0, 0}, + + /* Revision ID */ + + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_iD), + AML_OFFSET(ext_address64.revision_iD), + 1}, + /* + * These fields are contiguous in both the source and destination: + * Address Granularity + * Address Range Minimum + * Address Range Maximum + * Address Translation Offset + * Address Length + * Type-Specific Attribute + */ + {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity), + AML_OFFSET(ext_address64.granularity), + 6} +}; + +/******************************************************************************* + * + * acpi_rs_convert_general_flags - Flags common to all address descriptors + * + ******************************************************************************/ + +static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = { + {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)}, + + /* Resource Type (Memory, Io, bus_number, etc.) */ + + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type), + AML_OFFSET(address.resource_type), + 1}, + + /* General Flags - Consume, Decode, min_fixed, max_fixed */ + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer), + AML_OFFSET(address.flags), + 0}, + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode), + AML_OFFSET(address.flags), + 1}, + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed), + AML_OFFSET(address.flags), + 2}, + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed), + AML_OFFSET(address.flags), + 3} +}; + +/******************************************************************************* + * + * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors + * + ******************************************************************************/ + +static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = { + {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)}, + + /* Memory-specific flags */ + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect), + AML_OFFSET(address.specific_flags), + 0}, + + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching), + AML_OFFSET(address.specific_flags), + 1}, + + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type), + AML_OFFSET(address.specific_flags), + 3}, + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation), + AML_OFFSET(address.specific_flags), + 5} +}; + +/******************************************************************************* + * + * acpi_rs_convert_io_flags - Flags common to I/O address descriptors + * + ******************************************************************************/ + +static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = { + {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)}, + + /* I/O-specific flags */ + + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type), + AML_OFFSET(address.specific_flags), + 0}, + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation), + AML_OFFSET(address.specific_flags), + 4}, + + {ACPI_RSC_1BITFLAG, + ACPI_RS_OFFSET(data.address.info.io.translation_type), + AML_OFFSET(address.specific_flags), + 5} +}; + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_address_common + * + * PARAMETERS: Resource - Pointer to the internal resource struct + * Aml - Pointer to the AML resource descriptor + * + * RETURN: TRUE if the resource_type field is OK, FALSE otherwise + * + * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor + * to an internal resource descriptor + * + ******************************************************************************/ + +u8 acpi_rs_get_address_common(struct acpi_resource *resource, - union aml_resource *aml); - -/******************************************************************************* - * - * FUNCTION: acpi_rs_decode_general_flags - * - * PARAMETERS: Resource - Address resource data struct - * Flags - Raw AML flag byte - * - * RETURN: Decoded flag bits in resource struct - * - * DESCRIPTION: Decode a general flag byte to an address resource struct - * - ******************************************************************************/ - -static void -acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags) + union aml_resource *aml) { ACPI_FUNCTION_ENTRY(); - /* Producer / Consumer - flag bit[0] */ + /* Validate the Resource Type */ - resource->address.producer_consumer = (u32) (flags & 0x01); - - /* Decode (_DEC) - flag bit[1] */ - - resource->address.decode = (u32) ((flags >> 1) & 0x01); - - /* Min Address Fixed (_MIF) - flag bit[2] */ - - resource->address.min_address_fixed = (u32) ((flags >> 2) & 0x01); - - /* Max Address Fixed (_MAF) - flag bit[3] */ - - resource->address.max_address_fixed = (u32) ((flags >> 3) & 0x01); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_encode_general_flags - * - * PARAMETERS: Resource - Address resource data struct - * - * RETURN: Encoded general flag byte - * - * DESCRIPTION: Construct a general flag byte from an address resource struct - * - ******************************************************************************/ - -static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - return ((u8) - - /* Producer / Consumer - flag bit[0] */ - ((resource->address.producer_consumer & 0x01) | - /* Decode (_DEC) - flag bit[1] */ - ((resource->address.decode & 0x01) << 1) | - /* Min Address Fixed (_MIF) - flag bit[2] */ - ((resource->address.min_address_fixed & 0x01) << 2) | - /* Max Address Fixed (_MAF) - flag bit[3] */ - ((resource->address.max_address_fixed & 0x01) << 3)) - ); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_decode_specific_flags - * - * PARAMETERS: Resource - Address resource data struct - * Flags - Raw AML flag byte - * - * RETURN: Decoded flag bits in attribute struct - * - * DESCRIPTION: Decode a type-specific flag byte to an attribute struct. - * Type-specific flags are only defined for the Memory and IO - * resource types. - * - ******************************************************************************/ - -static void -acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags) -{ - ACPI_FUNCTION_ENTRY(); - - if (resource->address.resource_type == ACPI_MEMORY_RANGE) { - /* Write Status (_RW) - flag bit[0] */ - - resource->address.attribute.memory.read_write_attribute = - (u16) (flags & 0x01); - - /* Memory Attributes (_MEM) - flag bits[2:1] */ - - resource->address.attribute.memory.cache_attribute = - (u16) ((flags >> 1) & 0x03); - } else if (resource->address.resource_type == ACPI_IO_RANGE) { - /* Ranges (_RNG) - flag bits[1:0] */ - - resource->address.attribute.io.range_attribute = - (u16) (flags & 0x03); - - /* Translations (_TTP and _TRS) - flag bits[5:4] */ - - resource->address.attribute.io.translation_attribute = - (u16) ((flags >> 4) & 0x03); - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_encode_specific_flags - * - * PARAMETERS: Resource - Address resource data struct - * - * RETURN: Encoded type-specific flag byte - * - * DESCRIPTION: Construct a type-specific flag byte from an attribute struct. - * Type-specific flags are only defined for the Memory and IO - * resource types. - * - ******************************************************************************/ - -static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - if (resource->address.resource_type == ACPI_MEMORY_RANGE) { - return ((u8) - - /* Write Status (_RW) - flag bit[0] */ - ((resource->address.attribute.memory. - read_write_attribute & 0x01) | - /* Memory Attributes (_MEM) - flag bits[2:1] */ - ((resource->address.attribute.memory. - cache_attribute & 0x03) << 1))); - } else if (resource->address.resource_type == ACPI_IO_RANGE) { - return ((u8) - - /* Ranges (_RNG) - flag bits[1:0] */ - ((resource->address.attribute.io. - range_attribute & 0x03) | - /* Translations (_TTP and _TRS) - flag bits[5:4] */ - ((resource->address.attribute.io. - translation_attribute & 0x03) << 4))); + if ((aml->address.resource_type > 2) + && (aml->address.resource_type < 0xC0)) { + return (FALSE); } - return (0); + /* Get the Resource Type and General Flags */ + + (void)acpi_rs_convert_aml_to_resource(resource, aml, + acpi_rs_convert_general_flags); + + /* Get the Type-Specific Flags (Memory and I/O descriptors only) */ + + if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { + (void)acpi_rs_convert_aml_to_resource(resource, aml, + acpi_rs_convert_mem_flags); + } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { + (void)acpi_rs_convert_aml_to_resource(resource, aml, + acpi_rs_convert_io_flags); + } else { + /* Generic resource type, just grab the type_specific byte */ + + resource->data.address.info.type_specific = + aml->address.specific_flags; + } + + return (TRUE); } /******************************************************************************* @@ -228,502 +352,29 @@ static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) * ******************************************************************************/ -static void +void acpi_rs_set_address_common(union aml_resource *aml, struct acpi_resource *resource) { ACPI_FUNCTION_ENTRY(); - /* Set the Resource Type (Memory, Io, bus_number, etc.) */ + /* Set the Resource Type and General Flags */ - aml->address.resource_type = (u8) resource->data.address.resource_type; + (void)acpi_rs_convert_resource_to_aml(resource, aml, + acpi_rs_convert_general_flags); - /* Set the general flags */ + /* Set the Type-Specific Flags (Memory and I/O descriptors only) */ - aml->address.flags = acpi_rs_encode_general_flags(&resource->data); + if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { + (void)acpi_rs_convert_resource_to_aml(resource, aml, + acpi_rs_convert_mem_flags); + } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { + (void)acpi_rs_convert_resource_to_aml(resource, aml, + acpi_rs_convert_io_flags); + } else { + /* Generic resource type, just copy the type_specific byte */ - /* Set the type-specific flags */ - - aml->address.specific_flags = - acpi_rs_encode_specific_flags(&resource->data); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_address_common - * - * PARAMETERS: Resource - Pointer to the internal resource struct - * Aml - Pointer to the AML resource descriptor - * - * RETURN: TRUE if the resource_type field is OK, FALSE otherwise - * - * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor - * to an internal resource descriptor - * - ******************************************************************************/ - -static u8 -acpi_rs_get_address_common(struct acpi_resource *resource, - union aml_resource *aml) -{ - ACPI_FUNCTION_ENTRY(); - - /* Validate resource type */ - - if ((aml->address.resource_type > 2) - && (aml->address.resource_type < 0xC0)) { - return (FALSE); + aml->address.specific_flags = + resource->data.address.info.type_specific; } - - /* Get the Resource Type (Memory, Io, bus_number, etc.) */ - - resource->data.address.resource_type = aml->address.resource_type; - - /* Get the General Flags */ - - acpi_rs_decode_general_flags(&resource->data, aml->address.flags); - - /* Get the Type-Specific Flags */ - - acpi_rs_decode_specific_flags(&resource->data, - aml->address.specific_flags); - return (TRUE); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_address16 - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ - -acpi_status -acpi_rs_get_address16(union aml_resource * aml, - u16 aml_resource_length, struct acpi_resource * resource) -{ - ACPI_FUNCTION_TRACE("rs_get_address16"); - - /* Get the Resource Type, general flags, and type-specific flags */ - - if (!acpi_rs_get_address_common(resource, aml)) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - /* - * Get the following contiguous fields from the AML descriptor: - * Address Granularity - * Address Range Minimum - * Address Range Maximum - * Address Translation Offset - * Address Length - */ - acpi_rs_move_data(&resource->data.address16.granularity, - &aml->address16.granularity, 5, - ACPI_MOVE_TYPE_16_TO_32); - - /* Get the optional resource_source (index and string) */ - - resource->length = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16) + - acpi_rs_get_resource_source(aml_resource_length, - sizeof(struct aml_resource_address16), - &resource->data.address16. - resource_source, aml, NULL); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_ADDRESS16; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_address16 - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ - -acpi_status -acpi_rs_set_address16(struct acpi_resource *resource, union aml_resource *aml) -{ - acpi_size descriptor_length; - - ACPI_FUNCTION_TRACE("rs_set_address16"); - - /* Set the Resource Type, General Flags, and Type-Specific Flags */ - - acpi_rs_set_address_common(aml, resource); - - /* - * Set the following contiguous fields in the AML descriptor: - * Address Granularity - * Address Range Minimum - * Address Range Maximum - * Address Translation Offset - * Address Length - */ - acpi_rs_move_data(&aml->address16.granularity, - &resource->data.address16.granularity, 5, - ACPI_MOVE_TYPE_32_TO_16); - - /* Resource Source Index and Resource Source are optional */ - - descriptor_length = acpi_rs_set_resource_source(aml, - sizeof(struct - aml_resource_address16), - &resource->data. - address16. - resource_source); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS16, - descriptor_length, aml); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_address32 - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ - -acpi_status -acpi_rs_get_address32(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - - ACPI_FUNCTION_TRACE("rs_get_address32"); - - /* Get the Resource Type, general flags, and type-specific flags */ - - if (!acpi_rs_get_address_common(resource, (void *)aml)) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - /* - * Get the following contiguous fields from the AML descriptor: - * Address Granularity - * Address Range Minimum - * Address Range Maximum - * Address Translation Offset - * Address Length - */ - acpi_rs_move_data(&resource->data.address32.granularity, - &aml->address32.granularity, 5, - ACPI_MOVE_TYPE_32_TO_32); - - /* Get the optional resource_source (index and string) */ - - resource->length = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32) + - acpi_rs_get_resource_source(aml_resource_length, - sizeof(struct aml_resource_address32), - &resource->data.address32. - resource_source, aml, NULL); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_ADDRESS32; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_address32 - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ - -acpi_status -acpi_rs_set_address32(struct acpi_resource *resource, union aml_resource *aml) -{ - acpi_size descriptor_length; - - ACPI_FUNCTION_TRACE("rs_set_address32"); - - /* Set the Resource Type, General Flags, and Type-Specific Flags */ - - acpi_rs_set_address_common(aml, resource); - - /* - * Set the following contiguous fields in the AML descriptor: - * Address Granularity - * Address Range Minimum - * Address Range Maximum - * Address Translation Offset - * Address Length - */ - acpi_rs_move_data(&aml->address32.granularity, - &resource->data.address32.granularity, 5, - ACPI_MOVE_TYPE_32_TO_32); - - /* Resource Source Index and Resource Source are optional */ - - descriptor_length = acpi_rs_set_resource_source(aml, - sizeof(struct - aml_resource_address32), - &resource->data. - address32. - resource_source); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS32, - descriptor_length, aml); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_address64 - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ - -acpi_status -acpi_rs_get_address64(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_address64"); - - /* Get the Resource Type, general Flags, and type-specific Flags */ - - if (!acpi_rs_get_address_common(resource, aml)) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - /* - * Get the following contiguous fields from the AML descriptor: - * Address Granularity - * Address Range Minimum - * Address Range Maximum - * Address Translation Offset - * Address Length - */ - acpi_rs_move_data(&resource->data.address64.granularity, - &aml->address64.granularity, 5, - ACPI_MOVE_TYPE_64_TO_64); - - /* Get the optional resource_source (index and string) */ - - resource->length = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64) + - acpi_rs_get_resource_source(aml_resource_length, - sizeof(struct aml_resource_address64), - &resource->data.address64. - resource_source, aml, NULL); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_ADDRESS64; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_address64 - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ - -acpi_status -acpi_rs_set_address64(struct acpi_resource *resource, union aml_resource *aml) -{ - acpi_size descriptor_length; - - ACPI_FUNCTION_TRACE("rs_set_address64"); - - /* Set the Resource Type, General Flags, and Type-Specific Flags */ - - acpi_rs_set_address_common(aml, resource); - - /* - * Set the following contiguous fields in the AML descriptor: - * Address Granularity - * Address Range Minimum - * Address Range Maximum - * Address Translation Offset - * Address Length - */ - acpi_rs_move_data(&aml->address64.granularity, - &resource->data.address64.granularity, 5, - ACPI_MOVE_TYPE_64_TO_64); - - /* Resource Source Index and Resource Source are optional */ - - descriptor_length = acpi_rs_set_resource_source(aml, - sizeof(struct - aml_resource_address64), - &resource->data. - address64. - resource_source); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS64, - descriptor_length, aml); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_ext_address64 - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ - -acpi_status -acpi_rs_get_ext_address64(union aml_resource *aml, - u16 aml_resource_length, - struct acpi_resource *resource) -{ - - ACPI_FUNCTION_TRACE("rs_get_ext_address64"); - - /* Get the Resource Type, general flags, and type-specific flags */ - - if (!acpi_rs_get_address_common(resource, aml)) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - /* - * Get and validate the Revision ID - * Note: Only one revision ID is currently supported - */ - resource->data.ext_address64.revision_iD = - aml->ext_address64.revision_iD; - if (aml->ext_address64.revision_iD != - AML_RESOURCE_EXTENDED_ADDRESS_REVISION) { - return_ACPI_STATUS(AE_SUPPORT); - } - - /* - * Get the following contiguous fields from the AML descriptor: - * Address Granularity - * Address Range Minimum - * Address Range Maximum - * Address Translation Offset - * Address Length - * Type-Specific Attribute - */ - acpi_rs_move_data(&resource->data.ext_address64.granularity, - &aml->ext_address64.granularity, 6, - ACPI_MOVE_TYPE_64_TO_64); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64; - resource->length = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_address64); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_ext_address64 - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ - -acpi_status -acpi_rs_set_ext_address64(struct acpi_resource *resource, - union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_ext_address64"); - - /* Set the Resource Type, General Flags, and Type-Specific Flags */ - - acpi_rs_set_address_common(aml, resource); - - /* Only one Revision ID is currently supported */ - - aml->ext_address64.revision_iD = AML_RESOURCE_EXTENDED_ADDRESS_REVISION; - aml->ext_address64.reserved = 0; - - /* - * Set the following contiguous fields in the AML descriptor: - * Address Granularity - * Address Range Minimum - * Address Range Maximum - * Address Translation Offset - * Address Length - * Type-Specific Attribute - */ - acpi_rs_move_data(&aml->ext_address64.granularity, - &resource->data.address64.granularity, 6, - ACPI_MOVE_TYPE_64_TO_64); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, - sizeof(struct - aml_resource_extended_address64), - aml); - return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index d170dee07ce9..c29d3a447278 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -52,7 +52,7 @@ ACPI_MODULE_NAME("rscalc") /* Local prototypes */ static u8 acpi_rs_count_set_bits(u16 bit_field); -static acpi_size +static acpi_rs_length acpi_rs_struct_option_length(struct acpi_resource_source *resource_source); static u32 @@ -100,7 +100,7 @@ static u8 acpi_rs_count_set_bits(u16 bit_field) * ******************************************************************************/ -static acpi_size +static acpi_rs_length acpi_rs_struct_option_length(struct acpi_resource_source *resource_source) { ACPI_FUNCTION_ENTRY(); @@ -111,7 +111,7 @@ acpi_rs_struct_option_length(struct acpi_resource_source *resource_source) * resource_source_index (1). */ if (resource_source->string_ptr) { - return ((acpi_size) resource_source->string_length + 1); + return ((acpi_rs_length) (resource_source->string_length + 1)); } return (0); @@ -184,7 +184,7 @@ acpi_status acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) { acpi_size aml_size_needed = 0; - acpi_size segment_size; + acpi_rs_length total_size; ACPI_FUNCTION_TRACE("rs_get_aml_length"); @@ -199,7 +199,7 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) /* Get the base size of the (external stream) resource descriptor */ - segment_size = acpi_gbl_aml_resource_sizes[resource->type]; + total_size = acpi_gbl_aml_resource_sizes[resource->type]; /* * Augment the base size for descriptors with optional and/or @@ -216,13 +216,14 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) if (resource->data.vendor.byte_length > 7) { /* Base size of a Large resource descriptor */ - segment_size = + total_size = sizeof(struct aml_resource_large_header); } /* Add the size of the vendor-specific data */ - segment_size += resource->data.vendor.byte_length; + total_size = (acpi_rs_length) + (total_size + resource->data.vendor.byte_length); break; case ACPI_RESOURCE_TYPE_END_TAG: @@ -230,7 +231,7 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) * End Tag: * We are done -- return the accumulated total size. */ - *size_needed = aml_size_needed + segment_size; + *size_needed = aml_size_needed + total_size; /* Normal exit */ @@ -241,10 +242,11 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) * 16-Bit Address Resource: * Add the size of the optional resource_source info */ - segment_size += - acpi_rs_struct_option_length(&resource->data. - address16. - resource_source); + total_size = (acpi_rs_length) + (total_size + + acpi_rs_struct_option_length(&resource->data. + address16. + resource_source)); break; case ACPI_RESOURCE_TYPE_ADDRESS32: @@ -252,10 +254,11 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) * 32-Bit Address Resource: * Add the size of the optional resource_source info */ - segment_size += - acpi_rs_struct_option_length(&resource->data. - address32. - resource_source); + total_size = (acpi_rs_length) + (total_size + + acpi_rs_struct_option_length(&resource->data. + address32. + resource_source)); break; case ACPI_RESOURCE_TYPE_ADDRESS64: @@ -263,10 +266,11 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) * 64-Bit Address Resource: * Add the size of the optional resource_source info */ - segment_size += - acpi_rs_struct_option_length(&resource->data. - address64. - resource_source); + total_size = (acpi_rs_length) + (total_size + + acpi_rs_struct_option_length(&resource->data. + address64. + resource_source)); break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: @@ -275,16 +279,14 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) * Add the size of each additional optional interrupt beyond the * required 1 (4 bytes for each u32 interrupt number) */ - segment_size += (((acpi_size) - resource->data.extended_irq. - interrupt_count - 1) * 4); - - /* Add the size of the optional resource_source info */ - - segment_size += - acpi_rs_struct_option_length(&resource->data. - extended_irq. - resource_source); + total_size = (acpi_rs_length) + (total_size + + ((resource->data.extended_irq.interrupt_count - + 1) * 4) + + /* Add the size of the optional resource_source info */ + acpi_rs_struct_option_length(&resource->data. + extended_irq. + resource_source)); break; default: @@ -293,7 +295,7 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) /* Update the total */ - aml_size_needed += segment_size; + aml_size_needed += total_size; /* Point to the next object */ @@ -341,7 +343,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, while (bytes_parsed < aml_buffer_length) { /* The next byte in the stream is the resource descriptor type */ - resource_type = acpi_rs_get_resource_type(*aml_buffer); + resource_type = acpi_ut_get_resource_type(aml_buffer); /* Get the base stream size and structure sizes for the descriptor */ @@ -352,10 +354,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, /* Get the Length field from the input resource descriptor */ - resource_length = - acpi_rs_get_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + resource_length = acpi_ut_get_resource_length(aml_buffer); /* Augment the size for descriptors with optional fields */ diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 2f8990845b2d..27172a3d55d7 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -43,6 +43,7 @@ #include #include +#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsdump") @@ -61,17 +62,621 @@ static void acpi_rs_out_integer64(char *title, u64 value); static void acpi_rs_out_title(char *title); -static void acpi_rs_dump_byte_list(u32 length, u8 * data); +static void acpi_rs_dump_byte_list(u16 length, u8 * data); -static void acpi_rs_dump_dword_list(u32 length, u32 * data); +static void acpi_rs_dump_dword_list(u8 length, u32 * data); -static void acpi_rs_dump_short_byte_list(u32 length, u32 * data); +static void acpi_rs_dump_short_byte_list(u8 length, u8 * data); static void acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source); static void acpi_rs_dump_address_common(union acpi_resource_data *resource); +static void +acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table); + +#define ACPI_RSD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_resource_data,f) +#define ACPI_PRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f) +#define ACPI_RSD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_rsdump_info)) + +/******************************************************************************* + * + * Resource Descriptor info tables + * + * Note: The first table entry must be a Title or Literal and must contain + * the table length (number of table entries) + * + ******************************************************************************/ + +struct acpi_rsdump_info acpi_rs_dump_irq[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", + acpi_gbl_HEdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", + acpi_gbl_LLdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing", + acpi_gbl_SHRdecode}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count), + "Interrupt Count", NULL}, + {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]), + "Interrupt List", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_dma[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed", + acpi_gbl_TYPdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering", + acpi_gbl_BMdecode}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type", + acpi_gbl_SIZdecode}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count", + NULL}, + {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List", + NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), + "Start-Dependent-Functions", NULL}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), + "Compatibility Priority", acpi_gbl_config_decode}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), + "Performance/Robustness", acpi_gbl_config_decode} +}; + +struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf), + "End-Dependent-Functions", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_io[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding", + acpi_gbl_io_decode}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length", + NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io), + "Fixed I/O", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length), + "Address Length", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_vendor[3] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor), + "Vendor Specific", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL}, + {ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data", + NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "end_tag", + NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_memory24[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24), + "24-Bit Memory Range", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect), + "Write Protect", acpi_gbl_RWdecode}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length), + "Address Length", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_memory32[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32), + "32-Bit Memory Range", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect), + "Write Protect", acpi_gbl_RWdecode}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length), + "Address Length", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32), + "32-Bit Fixed Memory Range", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect), + "Write Protect", acpi_gbl_RWdecode}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length), + "Address Length", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_address16[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16), + "16-Bit WORD Address Space", NULL}, + {ACPI_RSD_ADDRESS, 0, NULL, NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset), + "Translation Offset", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length), + "Address Length", NULL}, + {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_address32[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32), + "32-Bit DWORD Address Space", NULL}, + {ACPI_RSD_ADDRESS, 0, NULL, NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset), + "Translation Offset", NULL}, + {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length), + "Address Length", NULL}, + {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_address64[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64), + "64-Bit QWORD Address Space", NULL}, + {ACPI_RSD_ADDRESS, 0, NULL, NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity", + NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum", + NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum", + NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset), + "Translation Offset", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length), + "Address Length", NULL}, + {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64), + "64-Bit Extended Address Space", NULL}, + {ACPI_RSD_ADDRESS, 0, NULL, NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity), + "Granularity", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum), + "Address Minimum", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum), + "Address Maximum", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset), + "Translation Offset", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length), + "Address Length", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific), + "Type-Specific Attribute", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq), + "Extended IRQ", NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer), + "Type", acpi_gbl_consume_decode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering), + "Triggering", acpi_gbl_HEdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity", + acpi_gbl_LLdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing", + acpi_gbl_SHRdecode}, + {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL, + NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count), + "Interrupt Count", NULL}, + {ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]), + "Interrupt List", NULL} +}; + +struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg), + "Generic Register", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID", + NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width", + NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset", + NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size), + "Access Size", NULL}, + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL} +}; + +/* + * Tables used for common address descriptor flag fields + */ +static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL, + NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer), + "Consumer/Producer", acpi_gbl_consume_decode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode", + acpi_gbl_DECdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed), + "Min Relocatability", acpi_gbl_min_decode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed), + "Max Relocatability", acpi_gbl_max_decode} +}; + +static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = { + {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags), + "Resource Type", "Memory Range"}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect), + "Write Protect", acpi_gbl_RWdecode}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching), + "Caching", acpi_gbl_MEMdecode}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type), + "Range Type", acpi_gbl_MTPdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation), + "Translation", acpi_gbl_TTPdecode} +}; + +static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = { + {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags), + "Resource Type", "I/O Range"}, + {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type), + "Range Type", acpi_gbl_RNGdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation), + "Translation", acpi_gbl_TTPdecode}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type), + "Translation Type", acpi_gbl_TRSdecode} +}; + +/* + * Table used to dump _PRT contents + */ +static struct acpi_rsdump_info acpi_rs_dump_prt[5] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL}, + {ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL}, + {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL}, + {ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL}, + {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL} +}; + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_descriptor + * + * PARAMETERS: Resource + * + * RETURN: None + * + * DESCRIPTION: + * + ******************************************************************************/ + +static void +acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) +{ + void *target = NULL; + void *previous_target; + char *name; + u8 count; + + /* First table entry must contain the table length (# of table entries) */ + + count = table->offset; + + while (count) { + previous_target = target; + target = ((u8 *) resource) + table->offset; + name = table->name; + + switch (table->opcode) { + case ACPI_RSD_TITLE: + /* + * Optional resource title + */ + if (table->name) { + acpi_os_printf("%s Resource\n", name); + } + break; + + /* Strings */ + + case ACPI_RSD_LITERAL: + acpi_rs_out_string(name, (char *)table->pointer); + break; + + case ACPI_RSD_STRING: + acpi_rs_out_string(name, (char *)target); + break; + + /* Data items, 8/16/32/64 bit */ + + case ACPI_RSD_UINT8: + acpi_rs_out_integer8(name, *(u8 *) target); + break; + + case ACPI_RSD_UINT16: + acpi_rs_out_integer16(name, *(u16 *) target); + break; + + case ACPI_RSD_UINT32: + acpi_rs_out_integer32(name, *(u32 *) target); + break; + + case ACPI_RSD_UINT64: + acpi_rs_out_integer64(name, *(u64 *) target); + break; + + /* Flags: 1-bit and 2-bit flags supported */ + + case ACPI_RSD_1BITFLAG: + acpi_rs_out_string(name, (char *) + ((const char **)table-> + pointer)[(*(u8 *) target) & 0x01]); + break; + + case ACPI_RSD_2BITFLAG: + acpi_rs_out_string(name, (char *) + ((const char **)table-> + pointer)[(*(u8 *) target) & 0x03]); + break; + + case ACPI_RSD_SHORTLIST: + /* + * Short byte list (single line output) for DMA and IRQ resources + * Note: The list length is obtained from the previous table entry + */ + if (previous_target) { + acpi_rs_out_title(name); + acpi_rs_dump_short_byte_list(* + ((u8 *) + previous_target), + (u8 *) target); + } + break; + + case ACPI_RSD_LONGLIST: + /* + * Long byte list for Vendor resource data + * Note: The list length is obtained from the previous table entry + */ + if (previous_target) { + acpi_rs_dump_byte_list(* + ((u16 *) + previous_target), + (u8 *) target); + } + break; + + case ACPI_RSD_DWORDLIST: + /* + * Dword list for Extended Interrupt resources + * Note: The list length is obtained from the previous table entry + */ + if (previous_target) { + acpi_rs_dump_dword_list(* + ((u8 *) + previous_target), + (u32 *) target); + } + break; + + case ACPI_RSD_ADDRESS: + /* + * Common flags for all Address resources + */ + acpi_rs_dump_address_common((union acpi_resource_data *) + target); + break; + + case ACPI_RSD_SOURCE: + /* + * Optional resource_source for Address resources + */ + acpi_rs_dump_resource_source((struct + acpi_resource_source *) + target); + break; + + default: + acpi_os_printf("**** Invalid table opcode [%X] ****\n", + table->opcode); + return; + } + + table++; + count--; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_resource_source + * + * PARAMETERS: resource_source - Pointer to a Resource Source struct + * + * RETURN: None + * + * DESCRIPTION: Common routine for dumping the optional resource_source and the + * corresponding resource_source_index. + * + ******************************************************************************/ + +static void +acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source) +{ + ACPI_FUNCTION_ENTRY(); + + if (resource_source->index == 0xFF) { + return; + } + + acpi_rs_out_integer8("Resource Source Index", resource_source->index); + + acpi_rs_out_string("Resource Source", + resource_source->string_ptr ? + resource_source->string_ptr : "[Not Specified]"); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_address_common + * + * PARAMETERS: Resource - Pointer to an internal resource descriptor + * + * RETURN: None + * + * DESCRIPTION: Dump the fields that are common to all Address resource + * descriptors + * + ******************************************************************************/ + +static void acpi_rs_dump_address_common(union acpi_resource_data *resource) +{ + ACPI_FUNCTION_ENTRY(); + + /* Decode the type-specific flags */ + + switch (resource->address.resource_type) { + case ACPI_MEMORY_RANGE: + + acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags); + break; + + case ACPI_IO_RANGE: + + acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags); + break; + + case ACPI_BUS_NUMBER_RANGE: + + acpi_rs_out_string("Resource Type", "Bus Number Range"); + break; + + default: + + acpi_rs_out_integer8("Resource Type", + (u8) resource->address.resource_type); + break; + } + + /* Decode the general flags */ + + acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_resource_list + * + * PARAMETERS: resource_list - Pointer to a resource descriptor list + * + * RETURN: None + * + * DESCRIPTION: Dispatches the structure to the correct dump routine. + * + ******************************************************************************/ + +void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) +{ + u32 count = 0; + u32 type; + + ACPI_FUNCTION_ENTRY(); + + if (!(acpi_dbg_level & ACPI_LV_RESOURCES) + || !(_COMPONENT & acpi_dbg_layer)) { + return; + } + + /* Walk list and dump all resource descriptors (END_TAG terminates) */ + + do { + acpi_os_printf("\n[%02X] ", count); + count++; + + /* Validate Type before dispatch */ + + type = resource_list->type; + if (type > ACPI_RESOURCE_TYPE_MAX) { + acpi_os_printf + ("Invalid descriptor type (%X) in resource list\n", + resource_list->type); + return; + } + + /* Dump the resource descriptor */ + + acpi_rs_dump_descriptor(&resource_list->data, + acpi_gbl_dump_resource_dispatch[type]); + + /* Point to the next resource structure */ + + resource_list = + ACPI_PTR_ADD(struct acpi_resource, resource_list, + resource_list->length); + + /* Exit when END_TAG descriptor is reached */ + + } while (type != ACPI_RESOURCE_TYPE_END_TAG); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_irq_list + * + * PARAMETERS: route_table - Pointer to the routing table to dump. + * + * RETURN: None + * + * DESCRIPTION: Print IRQ routing table + * + ******************************************************************************/ + +void acpi_rs_dump_irq_list(u8 * route_table) +{ + struct acpi_pci_routing_table *prt_element; + u8 count; + + ACPI_FUNCTION_ENTRY(); + + if (!(acpi_dbg_level & ACPI_LV_RESOURCES) + || !(_COMPONENT & acpi_dbg_layer)) { + return; + } + + prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table); + + /* Dump all table elements, Exit on zero length element */ + + for (count = 0; prt_element->length; count++) { + acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n", + count); + acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt); + + prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, + ((u8 *) prt_element) + + prt_element->length); + } +} + /******************************************************************************* * * FUNCTION: acpi_rs_out* @@ -129,27 +734,18 @@ static void acpi_rs_out_title(char *title) * ******************************************************************************/ -static void acpi_rs_dump_byte_list(u32 length, u8 * data) +static void acpi_rs_dump_byte_list(u16 length, u8 * data) { - u32 i; + u8 i; for (i = 0; i < length; i++) { acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]); } } -static void acpi_rs_dump_dword_list(u32 length, u32 * data) +static void acpi_rs_dump_short_byte_list(u8 length, u8 * data) { - u32 i; - - for (i = 0; i < length; i++) { - acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]); - } -} - -static void acpi_rs_dump_short_byte_list(u32 length, u32 * data) -{ - u32 i; + u8 i; for (i = 0; i < length; i++) { acpi_os_printf("%X ", data[i]); @@ -157,859 +753,12 @@ static void acpi_rs_dump_short_byte_list(u32 length, u32 * data) acpi_os_printf("\n"); } -static void acpi_rs_dump_memory_attribute(u32 read_write_attribute) +static void acpi_rs_dump_dword_list(u8 length, u32 * data) { + u8 i; - acpi_rs_out_string("Read/Write Attribute", - ACPI_READ_WRITE_MEMORY == read_write_attribute ? - "Read/Write" : "Read-Only"); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_resource_source - * - * PARAMETERS: resource_source - Pointer to a Resource Source struct - * - * RETURN: None - * - * DESCRIPTION: Common routine for dumping the optional resource_source and the - * corresponding resource_source_index. - * - ******************************************************************************/ - -static void -acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source) -{ - ACPI_FUNCTION_ENTRY(); - - if (resource_source->index == 0xFF) { - return; - } - - acpi_rs_out_integer8("Resource Source Index", - (u8) resource_source->index); - - acpi_rs_out_string("Resource Source", - resource_source->string_ptr ? - resource_source->string_ptr : "[Not Specified]"); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_address_common - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the fields that are common to all Address resource - * descriptors - * - ******************************************************************************/ - -static void acpi_rs_dump_address_common(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - /* Decode the type-specific flags */ - - switch (resource->address.resource_type) { - case ACPI_MEMORY_RANGE: - - acpi_rs_out_string("Resource Type", "Memory Range"); - - acpi_rs_out_title("Type-Specific Flags"); - - switch (resource->address.attribute.memory.cache_attribute) { - case ACPI_NON_CACHEABLE_MEMORY: - acpi_os_printf("Noncacheable memory\n"); - break; - - case ACPI_CACHABLE_MEMORY: - acpi_os_printf("Cacheable memory\n"); - break; - - case ACPI_WRITE_COMBINING_MEMORY: - acpi_os_printf("Write-combining memory\n"); - break; - - case ACPI_PREFETCHABLE_MEMORY: - acpi_os_printf("Prefetchable memory\n"); - break; - - default: - acpi_os_printf("Invalid cache attribute\n"); - break; - } - - acpi_rs_dump_memory_attribute(resource->address.attribute. - memory.read_write_attribute); - break; - - case ACPI_IO_RANGE: - - acpi_rs_out_string("Resource Type", "I/O Range"); - - acpi_rs_out_title("Type-Specific Flags"); - - switch (resource->address.attribute.io.range_attribute) { - case ACPI_NON_ISA_ONLY_RANGES: - acpi_os_printf("Non-ISA I/O Addresses\n"); - break; - - case ACPI_ISA_ONLY_RANGES: - acpi_os_printf("ISA I/O Addresses\n"); - break; - - case ACPI_ENTIRE_RANGE: - acpi_os_printf("ISA and non-ISA I/O Addresses\n"); - break; - - default: - acpi_os_printf("Invalid range attribute\n"); - break; - } - - acpi_rs_out_string("Translation Attribute", - ACPI_SPARSE_TRANSLATION == - resource->address.attribute.io. - translation_attribute ? "Sparse Translation" - : "Dense Translation"); - break; - - case ACPI_BUS_NUMBER_RANGE: - - acpi_rs_out_string("Resource Type", "Bus Number Range"); - break; - - default: - - acpi_rs_out_integer8("Resource Type", - (u8) resource->address.resource_type); - break; - } - - /* Decode the general flags */ - - acpi_rs_out_string("Resource", - ACPI_CONSUMER == - resource->address. - producer_consumer ? "Consumer" : "Producer"); - - acpi_rs_out_string("Decode", - ACPI_SUB_DECODE == resource->address.decode ? - "Subtractive" : "Positive"); - - acpi_rs_out_string("Min Address", - ACPI_ADDRESS_FIXED == - resource->address. - min_address_fixed ? "Fixed" : "Not Fixed"); - - acpi_rs_out_string("Max Address", - ACPI_ADDRESS_FIXED == - resource->address. - max_address_fixed ? "Fixed" : "Not Fixed"); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_resource_list - * - * PARAMETERS: resource_list - Pointer to a resource descriptor list - * - * RETURN: None - * - * DESCRIPTION: Dispatches the structure to the correct dump routine. - * - ******************************************************************************/ - -void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) -{ - u32 count = 0; - - ACPI_FUNCTION_ENTRY(); - - if (!(acpi_dbg_level & ACPI_LV_RESOURCES) - || !(_COMPONENT & acpi_dbg_layer)) { - return; - } - - /* Dump all resource descriptors in the list */ - - while (resource_list) { - acpi_os_printf("\n[%02X] ", count); - - /* Validate Type before dispatch */ - - if (resource_list->type > ACPI_RESOURCE_TYPE_MAX) { - acpi_os_printf - ("Invalid descriptor type (%X) in resource list\n", - resource_list->type); - return; - } - - /* Dump the resource descriptor */ - - acpi_gbl_dump_resource_dispatch[resource_list-> - type] (&resource_list->data); - - /* Exit on end tag */ - - if (resource_list->type == ACPI_RESOURCE_TYPE_END_TAG) { - return; - } - - /* Get the next resource structure */ - - resource_list = - ACPI_PTR_ADD(struct acpi_resource, resource_list, - resource_list->length); - count++; - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_irq - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_irq(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("IRQ Resource\n"); - - acpi_rs_out_string("Triggering", - ACPI_LEVEL_SENSITIVE == - resource->irq.triggering ? "Level" : "Edge"); - - acpi_rs_out_string("Active", - ACPI_ACTIVE_LOW == - resource->irq.polarity ? "Low" : "High"); - - acpi_rs_out_string("Sharing", - ACPI_SHARED == - resource->irq.sharable ? "Shared" : "Exclusive"); - - acpi_rs_out_integer8("Interrupt Count", - (u8) resource->irq.interrupt_count); - - acpi_rs_out_title("Interrupt List"); - acpi_rs_dump_short_byte_list(resource->irq.interrupt_count, - resource->irq.interrupts); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_dma - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_dma(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("DMA Resource\n"); - - acpi_rs_out_title("DMA Type"); - switch (resource->dma.type) { - case ACPI_COMPATIBILITY: - acpi_os_printf("Compatibility mode\n"); - break; - - case ACPI_TYPE_A: - acpi_os_printf("Type A\n"); - break; - - case ACPI_TYPE_B: - acpi_os_printf("Type B\n"); - break; - - case ACPI_TYPE_F: - acpi_os_printf("Type F\n"); - break; - - default: - acpi_os_printf("**** Invalid DMA type\n"); - break; - } - - acpi_rs_out_string("Bus Master", - ACPI_BUS_MASTER == - resource->dma.bus_master ? "Yes" : "No"); - - acpi_rs_out_title("Transfer Type"); - switch (resource->dma.transfer) { - case ACPI_TRANSFER_8: - acpi_os_printf("8-bit transfers only\n"); - break; - - case ACPI_TRANSFER_8_16: - acpi_os_printf("8-bit and 16-bit transfers\n"); - break; - - case ACPI_TRANSFER_16: - acpi_os_printf("16-bit transfers only\n"); - break; - - default: - acpi_os_printf("**** Invalid transfer preference\n"); - break; - } - - acpi_rs_out_integer8("DMA Channel Count", - (u8) resource->dma.channel_count); - - acpi_rs_out_title("Channel List"); - acpi_rs_dump_short_byte_list(resource->dma.channel_count, - resource->dma.channels); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_start_dpf - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_start_dpf(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Start Dependent Functions Resource\n"); - - acpi_rs_out_title("Compatibility Priority"); - switch (resource->start_dpf.compatibility_priority) { - case ACPI_GOOD_CONFIGURATION: - acpi_os_printf("Good configuration\n"); - break; - - case ACPI_ACCEPTABLE_CONFIGURATION: - acpi_os_printf("Acceptable configuration\n"); - break; - - case ACPI_SUB_OPTIMAL_CONFIGURATION: - acpi_os_printf("Sub-optimal configuration\n"); - break; - - default: - acpi_os_printf("**** Invalid compatibility priority\n"); - break; - } - - acpi_rs_out_title("Performance/Robustness"); - switch (resource->start_dpf.performance_robustness) { - case ACPI_GOOD_CONFIGURATION: - acpi_os_printf("Good configuration\n"); - break; - - case ACPI_ACCEPTABLE_CONFIGURATION: - acpi_os_printf("Acceptable configuration\n"); - break; - - case ACPI_SUB_OPTIMAL_CONFIGURATION: - acpi_os_printf("Sub-optimal configuration\n"); - break; - - default: - acpi_os_printf - ("**** Invalid performance robustness preference\n"); - break; - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_io - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_io(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("I/O Resource\n"); - - acpi_rs_out_string("Decode", - ACPI_DECODE_16 == - resource->io.io_decode ? "16-bit" : "10-bit"); - - acpi_rs_out_integer32("Address Minimum", resource->io.minimum); - - acpi_rs_out_integer32("Address Maximum", resource->io.maximum); - - acpi_rs_out_integer32("Alignment", resource->io.alignment); - - acpi_rs_out_integer32("Address Length", resource->io.address_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_fixed_io - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_fixed_io(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Fixed I/O Resource\n"); - - acpi_rs_out_integer32("Address", resource->fixed_io.address); - - acpi_rs_out_integer32("Address Length", - resource->fixed_io.address_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_vendor - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_vendor(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Vendor Specific Resource\n"); - - acpi_rs_out_integer16("Length", (u16) resource->vendor.byte_length); - - acpi_rs_dump_byte_list(resource->vendor.byte_length, - resource->vendor.byte_data); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_memory24 - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_memory24(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("24-Bit Memory Range Resource\n"); - - acpi_rs_dump_memory_attribute(resource->memory24.read_write_attribute); - - acpi_rs_out_integer16("Address Minimum", - (u16) resource->memory24.minimum); - - acpi_rs_out_integer16("Address Maximum", - (u16) resource->memory24.maximum); - - acpi_rs_out_integer16("Alignment", (u16) resource->memory24.alignment); - - acpi_rs_out_integer16("Address Length", - (u16) resource->memory24.address_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_memory32 - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_memory32(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("32-Bit Memory Range Resource\n"); - - acpi_rs_dump_memory_attribute(resource->memory32.read_write_attribute); - - acpi_rs_out_integer32("Address Minimum", resource->memory32.minimum); - - acpi_rs_out_integer32("Address Maximum", resource->memory32.maximum); - - acpi_rs_out_integer32("Alignment", resource->memory32.alignment); - - acpi_rs_out_integer32("Address Length", - resource->memory32.address_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_fixed_memory32 - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("32-Bit Fixed Location Memory Range Resource\n"); - - acpi_rs_dump_memory_attribute(resource->fixed_memory32. - read_write_attribute); - - acpi_rs_out_integer32("Address", resource->fixed_memory32.address); - - acpi_rs_out_integer32("Address Length", - resource->fixed_memory32.address_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_address16 - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_address16(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("16-Bit WORD Address Space Resource\n"); - - acpi_rs_dump_address_common(resource); - - acpi_rs_out_integer16("Granularity", - (u16) resource->address16.granularity); - - acpi_rs_out_integer16("Address Minimum", - (u16) resource->address16.minimum); - - acpi_rs_out_integer16("Address Maximum", - (u16) resource->address16.maximum); - - acpi_rs_out_integer16("Translation Offset", - (u16) resource->address16.translation_offset); - - acpi_rs_out_integer16("Address Length", - (u16) resource->address16.address_length); - - acpi_rs_dump_resource_source(&resource->address16.resource_source); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_address32 - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_address32(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("32-Bit DWORD Address Space Resource\n"); - - acpi_rs_dump_address_common(resource); - - acpi_rs_out_integer32("Granularity", resource->address32.granularity); - - acpi_rs_out_integer32("Address Minimum", resource->address32.minimum); - - acpi_rs_out_integer32("Address Maximum", resource->address32.maximum); - - acpi_rs_out_integer32("Translation Offset", - resource->address32.translation_offset); - - acpi_rs_out_integer32("Address Length", - resource->address32.address_length); - - acpi_rs_dump_resource_source(&resource->address32.resource_source); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_address64 - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_address64(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("64-Bit QWORD Address Space Resource\n"); - - acpi_rs_dump_address_common(resource); - - acpi_rs_out_integer64("Granularity", resource->address64.granularity); - - acpi_rs_out_integer64("Address Minimum", resource->address64.minimum); - - acpi_rs_out_integer64("Address Maximum", resource->address64.maximum); - - acpi_rs_out_integer64("Translation Offset", - resource->address64.translation_offset); - - acpi_rs_out_integer64("Address Length", - resource->address64.address_length); - - acpi_rs_dump_resource_source(&resource->address64.resource_source); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_ext_address64 - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_ext_address64(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("64-Bit Extended Address Space Resource\n"); - - acpi_rs_dump_address_common(resource); - - acpi_rs_out_integer64("Granularity", - resource->ext_address64.granularity); - - acpi_rs_out_integer64("Address Minimum", - resource->ext_address64.minimum); - - acpi_rs_out_integer64("Address Maximum", - resource->ext_address64.maximum); - - acpi_rs_out_integer64("Translation Offset", - resource->ext_address64.translation_offset); - - acpi_rs_out_integer64("Address Length", - resource->ext_address64.address_length); - - acpi_rs_out_integer64("Type-Specific Attribute", - resource->ext_address64.type_specific_attributes); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_ext_irq - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_ext_irq(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Extended IRQ Resource\n"); - - acpi_rs_out_string("Resource", - ACPI_CONSUMER == - resource->extended_irq. - producer_consumer ? "Consumer" : "Producer"); - - acpi_rs_out_string("Triggering", - ACPI_LEVEL_SENSITIVE == - resource->extended_irq. - triggering ? "Level" : "Edge"); - - acpi_rs_out_string("Active", - ACPI_ACTIVE_LOW == resource->extended_irq.polarity ? - "Low" : "High"); - - acpi_rs_out_string("Sharing", - ACPI_SHARED == resource->extended_irq.sharable ? - "Shared" : "Exclusive"); - - acpi_rs_dump_resource_source(&resource->extended_irq.resource_source); - - acpi_rs_out_integer8("Interrupts", - (u8) resource->extended_irq.interrupt_count); - - acpi_rs_dump_dword_list(resource->extended_irq.interrupt_count, - resource->extended_irq.interrupts); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_generic_reg - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Dump the field names and values of the resource descriptor - * - ******************************************************************************/ - -void acpi_rs_dump_generic_reg(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("Generic Register Resource\n"); - - acpi_rs_out_integer8("Space ID", (u8) resource->generic_reg.space_id); - - acpi_rs_out_integer8("Bit Width", (u8) resource->generic_reg.bit_width); - - acpi_rs_out_integer8("Bit Offset", - (u8) resource->generic_reg.bit_offset); - - acpi_rs_out_integer8("Access Size", - (u8) resource->generic_reg.access_size); - - acpi_rs_out_integer64("Address", resource->generic_reg.address); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_end_dpf - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Print type, no data. - * - ******************************************************************************/ - -void acpi_rs_dump_end_dpf(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("end_dependent_functions Resource\n"); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_end_tag - * - * PARAMETERS: Resource - Pointer to an internal resource descriptor - * - * RETURN: None - * - * DESCRIPTION: Print type, no data. - * - ******************************************************************************/ - -void acpi_rs_dump_end_tag(union acpi_resource_data *resource) -{ - ACPI_FUNCTION_ENTRY(); - - acpi_os_printf("end_tag Resource\n"); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_dump_irq_list - * - * PARAMETERS: route_table - Pointer to the routing table to dump. - * - * RETURN: None - * - * DESCRIPTION: Print IRQ routing table - * - ******************************************************************************/ - -void acpi_rs_dump_irq_list(u8 * route_table) -{ - u8 *buffer = route_table; - u8 count = 0; - struct acpi_pci_routing_table *prt_element; - - ACPI_FUNCTION_ENTRY(); - - if (!(acpi_dbg_level & ACPI_LV_RESOURCES) - || !(_COMPONENT & acpi_dbg_layer)) { - return; - } - - prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); - - /* Dump all table elements, Exit on null length element */ - - while (prt_element->length) { - acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n", - count); - - acpi_rs_out_integer64("Address", prt_element->address); - - acpi_rs_out_integer32("Pin", prt_element->pin); - acpi_rs_out_string("Source", prt_element->source); - acpi_rs_out_integer32("Source Index", - prt_element->source_index); - - buffer += prt_element->length; - prt_element = - ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); - count++; + for (i = 0; i < length; i++) { + acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]); } } diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c index b31cb33ec565..973fc2834cbb 100644 --- a/drivers/acpi/resources/rsinfo.c +++ b/drivers/acpi/resources/rsinfo.c @@ -58,60 +58,60 @@ ACPI_MODULE_NAME("rsinfo") * descriptors are indexed by the acpi_resource_type field. */ /* Dispatch table for resource-to-AML (Set Resource) conversion functions */ -ACPI_SET_RESOURCE_HANDLER acpi_gbl_set_resource_dispatch[] = { +struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[] = { acpi_rs_set_irq, /* 0x00, ACPI_RESOURCE_TYPE_IRQ */ - acpi_rs_set_dma, /* 0x01, ACPI_RESOURCE_TYPE_DMA */ + acpi_rs_convert_dma, /* 0x01, ACPI_RESOURCE_TYPE_DMA */ acpi_rs_set_start_dpf, /* 0x02, ACPI_RESOURCE_TYPE_START_DEPENDENT */ - acpi_rs_set_end_dpf, /* 0x03, ACPI_RESOURCE_TYPE_END_DEPENDENT */ - acpi_rs_set_io, /* 0x04, ACPI_RESOURCE_TYPE_IO */ - acpi_rs_set_fixed_io, /* 0x05, ACPI_RESOURCE_TYPE_FIXED_IO */ + acpi_rs_convert_end_dpf, /* 0x03, ACPI_RESOURCE_TYPE_END_DEPENDENT */ + acpi_rs_convert_io, /* 0x04, ACPI_RESOURCE_TYPE_IO */ + acpi_rs_convert_fixed_io, /* 0x05, ACPI_RESOURCE_TYPE_FIXED_IO */ acpi_rs_set_vendor, /* 0x06, ACPI_RESOURCE_TYPE_VENDOR */ - acpi_rs_set_end_tag, /* 0x07, ACPI_RESOURCE_TYPE_END_TAG */ - acpi_rs_set_memory24, /* 0x08, ACPI_RESOURCE_TYPE_MEMORY24 */ - acpi_rs_set_memory32, /* 0x09, ACPI_RESOURCE_TYPE_MEMORY32 */ - acpi_rs_set_fixed_memory32, /* 0x0A, ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */ - acpi_rs_set_address16, /* 0x0B, ACPI_RESOURCE_TYPE_ADDRESS16 */ - acpi_rs_set_address32, /* 0x0C, ACPI_RESOURCE_TYPE_ADDRESS32 */ - acpi_rs_set_address64, /* 0x0D, ACPI_RESOURCE_TYPE_ADDRESS64 */ - acpi_rs_set_ext_address64, /* 0x0E, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ - acpi_rs_set_ext_irq, /* 0x0F, ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ - acpi_rs_set_generic_reg /* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ + acpi_rs_convert_end_tag, /* 0x07, ACPI_RESOURCE_TYPE_END_TAG */ + acpi_rs_convert_memory24, /* 0x08, ACPI_RESOURCE_TYPE_MEMORY24 */ + acpi_rs_convert_memory32, /* 0x09, ACPI_RESOURCE_TYPE_MEMORY32 */ + acpi_rs_convert_fixed_memory32, /* 0x0A, ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */ + acpi_rs_convert_address16, /* 0x0B, ACPI_RESOURCE_TYPE_ADDRESS16 */ + acpi_rs_convert_address32, /* 0x0C, ACPI_RESOURCE_TYPE_ADDRESS32 */ + acpi_rs_convert_address64, /* 0x0D, ACPI_RESOURCE_TYPE_ADDRESS64 */ + acpi_rs_convert_ext_address64, /* 0x0E, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ + acpi_rs_convert_ext_irq, /* 0x0F, ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ + acpi_rs_convert_generic_reg /* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ }; /* Dispatch tables for AML-to-resource (Get Resource) conversion functions */ -ACPI_GET_RESOURCE_HANDLER acpi_gbl_sm_get_resource_dispatch[] = { +struct acpi_rsconvert_info *acpi_gbl_sm_get_resource_dispatch[] = { NULL, /* 0x00, Reserved */ NULL, /* 0x01, Reserved */ NULL, /* 0x02, Reserved */ NULL, /* 0x03, Reserved */ acpi_rs_get_irq, /* 0x04, ACPI_RESOURCE_NAME_IRQ */ - acpi_rs_get_dma, /* 0x05, ACPI_RESOURCE_NAME_DMA */ + acpi_rs_convert_dma, /* 0x05, ACPI_RESOURCE_NAME_DMA */ acpi_rs_get_start_dpf, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */ - acpi_rs_get_end_dpf, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */ - acpi_rs_get_io, /* 0x08, ACPI_RESOURCE_NAME_IO */ - acpi_rs_get_fixed_io, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO */ + acpi_rs_convert_end_dpf, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */ + acpi_rs_convert_io, /* 0x08, ACPI_RESOURCE_NAME_IO */ + acpi_rs_convert_fixed_io, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO */ NULL, /* 0x0A, Reserved */ NULL, /* 0x0B, Reserved */ NULL, /* 0x0C, Reserved */ NULL, /* 0x0D, Reserved */ - acpi_rs_get_vendor, /* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */ - acpi_rs_get_end_tag /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */ + acpi_rs_get_vendor_small, /* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */ + acpi_rs_convert_end_tag /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */ }; -ACPI_GET_RESOURCE_HANDLER acpi_gbl_lg_get_resource_dispatch[] = { +struct acpi_rsconvert_info *acpi_gbl_lg_get_resource_dispatch[] = { NULL, /* 0x00, Reserved */ - acpi_rs_get_memory24, /* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */ - acpi_rs_get_generic_reg, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */ + acpi_rs_convert_memory24, /* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */ + acpi_rs_convert_generic_reg, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */ NULL, /* 0x03, Reserved */ - acpi_rs_get_vendor, /* 0x04, ACPI_RESOURCE_NAME_VENDOR_LARGE */ - acpi_rs_get_memory32, /* 0x05, ACPI_RESOURCE_NAME_MEMORY32 */ - acpi_rs_get_fixed_memory32, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY32 */ - acpi_rs_get_address32, /* 0x07, ACPI_RESOURCE_NAME_ADDRESS32 */ - acpi_rs_get_address16, /* 0x08, ACPI_RESOURCE_NAME_ADDRESS16 */ - acpi_rs_get_ext_irq, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_IRQ */ - acpi_rs_get_address64, /* 0x0A, ACPI_RESOURCE_NAME_ADDRESS64 */ - acpi_rs_get_ext_address64 /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */ + acpi_rs_get_vendor_large, /* 0x04, ACPI_RESOURCE_NAME_VENDOR_LARGE */ + acpi_rs_convert_memory32, /* 0x05, ACPI_RESOURCE_NAME_MEMORY32 */ + acpi_rs_convert_fixed_memory32, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY32 */ + acpi_rs_convert_address32, /* 0x07, ACPI_RESOURCE_NAME_ADDRESS32 */ + acpi_rs_convert_address16, /* 0x08, ACPI_RESOURCE_NAME_ADDRESS16 */ + acpi_rs_convert_ext_irq, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_IRQ */ + acpi_rs_convert_address64, /* 0x0A, ACPI_RESOURCE_NAME_ADDRESS64 */ + acpi_rs_convert_ext_address64 /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */ }; #ifdef ACPI_FUTURE_USAGE @@ -119,7 +119,7 @@ ACPI_GET_RESOURCE_HANDLER acpi_gbl_lg_get_resource_dispatch[] = { /* Dispatch table for resource dump functions */ -ACPI_DUMP_RESOURCE_HANDLER acpi_gbl_dump_resource_dispatch[] = { +struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = { acpi_rs_dump_irq, /* ACPI_RESOURCE_TYPE_IRQ */ acpi_rs_dump_dma, /* ACPI_RESOURCE_TYPE_DMA */ acpi_rs_dump_start_dpf, /* ACPI_RESOURCE_TYPE_START_DEPENDENT */ @@ -136,17 +136,17 @@ ACPI_DUMP_RESOURCE_HANDLER acpi_gbl_dump_resource_dispatch[] = { acpi_rs_dump_address64, /* ACPI_RESOURCE_TYPE_ADDRESS64 */ acpi_rs_dump_ext_address64, /* ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ acpi_rs_dump_ext_irq, /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ - acpi_rs_dump_generic_reg /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ + acpi_rs_dump_generic_reg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ }; + #endif #endif /* ACPI_FUTURE_USAGE */ - /* * Base sizes for external AML resource descriptors, indexed by internal type. * Includes size of the descriptor header (1 byte for small descriptors, * 3 bytes for large descriptors) */ -u8 acpi_gbl_aml_resource_sizes[] = { +const u8 acpi_gbl_aml_resource_sizes[] = { sizeof(struct aml_resource_irq), /* ACPI_RESOURCE_TYPE_IRQ (optional Byte 3 always created) */ sizeof(struct aml_resource_dma), /* ACPI_RESOURCE_TYPE_DMA */ sizeof(struct aml_resource_start_dependent), /* ACPI_RESOURCE_TYPE_START_DEPENDENT (optional Byte 1 always created) */ @@ -168,8 +168,8 @@ u8 acpi_gbl_aml_resource_sizes[] = { /* Macros used in the tables below */ -#define ACPI_RLARGE(r) sizeof (r) - sizeof (struct aml_resource_large_header) -#define ACPI_RSMALL(r) sizeof (r) - sizeof (struct aml_resource_small_header) +#define ACPI_RLARGE(r) (sizeof (r) - sizeof (struct aml_resource_large_header)) +#define ACPI_RSMALL(r) (sizeof (r) - sizeof (struct aml_resource_small_header)) /* * Base sizes of resource descriptors, both the AML stream resource length @@ -182,47 +182,46 @@ struct acpi_resource_info acpi_gbl_sm_resource_info[] = { {0, 0, 0}, {0, 0, 0}, {2, ACPI_RSMALL(struct aml_resource_irq), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq)}, + ACPI_RS_SIZE(struct acpi_resource_irq)}, {0, ACPI_RSMALL(struct aml_resource_dma), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma)}, + ACPI_RS_SIZE(struct acpi_resource_dma)}, {2, ACPI_RSMALL(struct aml_resource_start_dependent), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dependent)}, - {0, ACPI_RSMALL(struct aml_resource_end_dependent), - ACPI_RESOURCE_LENGTH}, + ACPI_RS_SIZE(struct acpi_resource_start_dependent)}, + {0, ACPI_RSMALL(struct aml_resource_end_dependent), ACPI_RS_SIZE_MIN}, {0, ACPI_RSMALL(struct aml_resource_io), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_io)}, + ACPI_RS_SIZE(struct acpi_resource_io)}, {0, ACPI_RSMALL(struct aml_resource_fixed_io), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io)}, + ACPI_RS_SIZE(struct acpi_resource_fixed_io)}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, ACPI_RSMALL(struct aml_resource_vendor_small), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor)}, - {0, ACPI_RSMALL(struct aml_resource_end_tag), ACPI_RESOURCE_LENGTH} + ACPI_RS_SIZE(struct acpi_resource_vendor)}, + {0, ACPI_RSMALL(struct aml_resource_end_tag), ACPI_RS_SIZE_MIN} }; struct acpi_resource_info acpi_gbl_lg_resource_info[] = { {0, 0, 0}, {0, ACPI_RLARGE(struct aml_resource_memory24), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_memory24)}, + ACPI_RS_SIZE(struct acpi_resource_memory24)}, {0, ACPI_RLARGE(struct aml_resource_generic_register), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_register)}, + ACPI_RS_SIZE(struct acpi_resource_generic_register)}, {0, 0, 0}, {1, ACPI_RLARGE(struct aml_resource_vendor_large), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor)}, + ACPI_RS_SIZE(struct acpi_resource_vendor)}, {0, ACPI_RLARGE(struct aml_resource_memory32), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_memory32)}, + ACPI_RS_SIZE(struct acpi_resource_memory32)}, {0, ACPI_RLARGE(struct aml_resource_fixed_memory32), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_memory32)}, + ACPI_RS_SIZE(struct acpi_resource_fixed_memory32)}, {1, ACPI_RLARGE(struct aml_resource_address32), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32)}, + ACPI_RS_SIZE(struct acpi_resource_address32)}, {1, ACPI_RLARGE(struct aml_resource_address16), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16)}, + ACPI_RS_SIZE(struct acpi_resource_address16)}, {1, ACPI_RLARGE(struct aml_resource_extended_irq), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_irq)}, + ACPI_RS_SIZE(struct acpi_resource_extended_irq)}, {1, ACPI_RLARGE(struct aml_resource_address64), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64)}, + ACPI_RS_SIZE(struct acpi_resource_address64)}, {0, ACPI_RLARGE(struct aml_resource_extended_address64), - ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_address64)} + ACPI_RS_SIZE(struct acpi_resource_extended_address64)} }; diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index 0dab8cdfa800..ef24ba110c6e 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -49,269 +49,206 @@ ACPI_MODULE_NAME("rsio") /******************************************************************************* * - * FUNCTION: acpi_rs_get_io - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. + * acpi_rs_convert_io * ******************************************************************************/ -acpi_status -acpi_rs_get_io(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_io"); +struct acpi_rsconvert_info acpi_rs_convert_io[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IO, + ACPI_RS_SIZE(struct acpi_resource_io), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io)}, - /* Get the Decode flag */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IO, + sizeof(struct aml_resource_io), + 0}, - resource->data.io.io_decode = aml->io.information & 0x01; + /* Decode flag */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.io.io_decode), + AML_OFFSET(io.flags), + 0}, /* - * Get the following contiguous fields from the AML descriptor: - * Minimum Base Address - * Maximum Base Address + * These fields are contiguous in both the source and destination: * Address Alignment * Length + * Minimum Base Address + * Maximum Base Address */ - ACPI_MOVE_16_TO_32(&resource->data.io.minimum, &aml->io.minimum); - ACPI_MOVE_16_TO_32(&resource->data.io.maximum, &aml->io.maximum); - resource->data.io.alignment = aml->io.alignment; - resource->data.io.address_length = aml->io.address_length; + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.io.alignment), + AML_OFFSET(io.alignment), + 2}, - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_IO; - resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.io.minimum), + AML_OFFSET(io.minimum), + 2} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_set_io - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. + * acpi_rs_convert_fixed_io * ******************************************************************************/ -acpi_status -acpi_rs_set_io(struct acpi_resource *resource, union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_io"); - - /* I/O Information Byte */ - - aml->io.information = (u8) (resource->data.io.io_decode & 0x01); +struct acpi_rsconvert_info acpi_rs_convert_fixed_io[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_IO, + ACPI_RS_SIZE(struct acpi_resource_fixed_io), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_io)}, + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_IO, + sizeof(struct aml_resource_fixed_io), + 0}, /* - * Set the following contiguous fields in the AML descriptor: - * Minimum Base Address - * Maximum Base Address - * Address Alignment - * Length - */ - ACPI_MOVE_32_TO_16(&aml->io.minimum, &resource->data.io.minimum); - ACPI_MOVE_32_TO_16(&aml->io.maximum, &resource->data.io.maximum); - aml->io.alignment = (u8) resource->data.io.alignment; - aml->io.address_length = (u8) resource->data.io.address_length; - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_IO, - sizeof(struct aml_resource_io), aml); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_fixed_io - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ - -acpi_status -acpi_rs_get_fixed_io(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_fixed_io"); - - /* - * Get the following contiguous fields from the AML descriptor: + * These fields are contiguous in both the source and destination: * Base Address * Length */ - ACPI_MOVE_16_TO_32(&resource->data.fixed_io.address, - &aml->fixed_io.address); - resource->data.fixed_io.address_length = aml->fixed_io.address_length; + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_io.address_length), + AML_OFFSET(fixed_io.address_length), + 1}, - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_FIXED_IO; - resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_io.address), + AML_OFFSET(fixed_io.address), + 1} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_set_fixed_io - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. + * acpi_rs_convert_generic_reg * ******************************************************************************/ -acpi_status -acpi_rs_set_fixed_io(struct acpi_resource *resource, union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_fixed_io"); +struct acpi_rsconvert_info acpi_rs_convert_generic_reg[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GENERIC_REGISTER, + ACPI_RS_SIZE(struct acpi_resource_generic_register), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_generic_reg)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GENERIC_REGISTER, + sizeof(struct aml_resource_generic_register), + 0}, + /* + * These fields are contiguous in both the source and destination: + * Address Space ID + * Register Bit Width + * Register Bit Offset + * Access Size + */ + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.generic_reg.space_id), + AML_OFFSET(generic_reg.address_space_id), + 4}, + + /* Get the Register Address */ + + {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.generic_reg.address), + AML_OFFSET(generic_reg.address), + 1} +}; + +/******************************************************************************* + * + * acpi_rs_convert_end_dpf + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_convert_end_dpf[2] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_DEPENDENT, + ACPI_RS_SIZE_MIN, + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_dpf)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_DEPENDENT, + sizeof(struct aml_resource_end_dependent), + 0} +}; + +/******************************************************************************* + * + * acpi_rs_convert_end_tag + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_TAG, + ACPI_RS_SIZE_MIN, + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_tag)}, /* - * Set the following contiguous fields in the AML descriptor: - * Base Address - * Length + * Note: The checksum field is set to zero, meaning that the resource + * data is treated as if the checksum operation succeeded. + * (ACPI Spec 1.0b Section 6.4.2.8) */ - ACPI_MOVE_32_TO_16(&aml->fixed_io.address, - &resource->data.fixed_io.address); - aml->fixed_io.address_length = - (u8) resource->data.fixed_io.address_length; - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_FIXED_IO, - sizeof(struct aml_resource_fixed_io), aml); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_TAG, + sizeof(struct aml_resource_end_tag), + 0} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_get_dma - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. + * acpi_rs_get_start_dpf * ******************************************************************************/ -acpi_status -acpi_rs_get_dma(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - u32 channel_count = 0; - u32 i; - u8 temp8; +struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, + ACPI_RS_SIZE(struct acpi_resource_start_dependent), + ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, - ACPI_FUNCTION_TRACE("rs_get_dma"); + /* Defaults for Compatibility and Performance priorities */ - /* Decode the DMA channel bits */ + {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), + ACPI_ACCEPTABLE_CONFIGURATION, + 2}, - for (i = 0; i < 8; i++) { - if ((aml->dma.dma_channel_mask >> i) & 0x01) { - resource->data.dma.channels[channel_count] = i; - channel_count++; - } - } + /* All done if there is no flag byte present in the descriptor */ - resource->length = 0; - resource->data.dma.channel_count = channel_count; + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, + /* Flag byte is present, get the flags */ + + {ACPI_RSC_2BITFLAG, + ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), + AML_OFFSET(start_dpf.flags), + 0}, + + {ACPI_RSC_2BITFLAG, + ACPI_RS_OFFSET(data.start_dpf.performance_robustness), + AML_OFFSET(start_dpf.flags), + 2} +}; + +/******************************************************************************* + * + * acpi_rs_set_start_dpf + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, + sizeof(struct aml_resource_start_dependent), + ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, + + /* Set the default flag values */ + + {ACPI_RSC_2BITFLAG, + ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), + AML_OFFSET(start_dpf.flags), + 0}, + + {ACPI_RSC_2BITFLAG, + ACPI_RS_OFFSET(data.start_dpf.performance_robustness), + AML_OFFSET(start_dpf.flags), + 2}, /* - * Calculate the structure size based upon the number of channels - * Note: Zero DMA channels is valid + * All done if flags byte is necessary -- if either priority value + * is not ACPI_ACCEPTABLE_CONFIGURATION */ - if (channel_count > 0) { - resource->length = (u32) (channel_count - 1) * 4; - } + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), + ACPI_ACCEPTABLE_CONFIGURATION}, - /* Get the flags: transfer preference, bus mastering, channel speed */ + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.start_dpf.performance_robustness), + ACPI_ACCEPTABLE_CONFIGURATION}, - temp8 = aml->dma.flags; - resource->data.dma.transfer = temp8 & 0x03; - resource->data.dma.bus_master = (temp8 >> 2) & 0x01; - resource->data.dma.type = (temp8 >> 5) & 0x03; + /* Flag byte is not necessary */ - if (resource->data.dma.transfer == 0x03) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid DMA.Transfer preference (3)\n")); - return_ACPI_STATUS(AE_BAD_DATA); - } - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_DMA; - resource->length += ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_dma - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ - -acpi_status -acpi_rs_set_dma(struct acpi_resource *resource, union aml_resource *aml) -{ - u8 i; - - ACPI_FUNCTION_TRACE("rs_set_dma"); - - /* Convert channel list to 8-bit DMA channel bitmask */ - - aml->dma.dma_channel_mask = 0; - for (i = 0; i < resource->data.dma.channel_count; i++) { - aml->dma.dma_channel_mask |= - (1 << resource->data.dma.channels[i]); - } - - /* Set the DMA Flag bits */ - - aml->dma.flags = (u8) - (((resource->data.dma.type & 0x03) << 5) | - ((resource->data.dma.bus_master & 0x01) << 2) | - (resource->data.dma.transfer & 0x03)); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_DMA, - sizeof(struct aml_resource_dma), aml); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_LENGTH, 0, 0, + sizeof(struct aml_resource_start_dependent_noprio)} +}; diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 4e854ba70811..79e71257b69a 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -49,325 +49,182 @@ ACPI_MODULE_NAME("rsirq") /******************************************************************************* * - * FUNCTION: acpi_rs_get_irq - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. + * acpi_rs_get_irq * ******************************************************************************/ -acpi_status -acpi_rs_get_irq(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - u16 temp16 = 0; - u32 interrupt_count = 0; - u32 i; - u32 resource_length; - - ACPI_FUNCTION_TRACE("rs_get_irq"); +struct acpi_rsconvert_info acpi_rs_get_irq[7] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, + ACPI_RS_SIZE(struct acpi_resource_irq), + ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, /* Get the IRQ mask (bytes 1:2) */ - ACPI_MOVE_16_TO_16(&temp16, &aml->irq.irq_mask); + {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]), + AML_OFFSET(irq.irq_mask), + ACPI_RS_OFFSET(data.irq.interrupt_count)}, - /* Decode the IRQ bits (up to 16 possible) */ + /* Set default flags (others are zero) */ - for (i = 0; i < 16; i++) { - if ((temp16 >> i) & 0x01) { - resource->data.irq.interrupts[interrupt_count] = i; - interrupt_count++; - } - } + {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.irq.triggering), + ACPI_EDGE_SENSITIVE, + 1}, - /* Zero interrupts is valid */ + /* All done if no flag byte present in descriptor */ - resource_length = 0; - resource->data.irq.interrupt_count = interrupt_count; - if (interrupt_count > 0) { - /* Calculate the structure size based upon the number of interrupts */ + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, - resource_length = (u32) (interrupt_count - 1) * 4; - } + /* Get flags: Triggering[0], Polarity[3], Sharing[4] */ - /* Get Flags (Byte 3) if it is used */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), + AML_OFFSET(irq.flags), + 0}, - if (aml_resource_length == 3) { - /* Check for HE, LL interrupts */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity), + AML_OFFSET(irq.flags), + 3}, - switch (aml->irq.flags & 0x09) { - case 0x01: /* HE */ - resource->data.irq.triggering = ACPI_EDGE_SENSITIVE; - resource->data.irq.polarity = ACPI_ACTIVE_HIGH; - break; - - case 0x08: /* LL */ - resource->data.irq.triggering = ACPI_LEVEL_SENSITIVE; - resource->data.irq.polarity = ACPI_ACTIVE_LOW; - break; - - default: - /* - * Only _LL and _HE polarity/trigger interrupts - * are allowed (ACPI spec, section "IRQ Format") - * so 0x00 and 0x09 are illegal. - */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid interrupt polarity/trigger in resource list, %X\n", - aml->irq.flags)); - return_ACPI_STATUS(AE_BAD_DATA); - } - - /* Get Sharing flag */ - - resource->data.irq.sharable = (aml->irq.flags >> 3) & 0x01; - } else { - /* - * Default configuration: assume Edge Sensitive, Active High, - * Non-Sharable as per the ACPI Specification - */ - resource->data.irq.triggering = ACPI_EDGE_SENSITIVE; - resource->data.irq.polarity = ACPI_ACTIVE_HIGH; - resource->data.irq.sharable = ACPI_EXCLUSIVE; - } - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_IRQ; - resource->length = - resource_length + ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), + AML_OFFSET(irq.flags), + 4} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_set_irq - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. + * acpi_rs_set_irq * ******************************************************************************/ -acpi_status -acpi_rs_set_irq(struct acpi_resource *resource, union aml_resource *aml) -{ - acpi_size descriptor_length; - u16 irq_mask; - u8 i; - - ACPI_FUNCTION_TRACE("rs_set_irq"); +struct acpi_rsconvert_info acpi_rs_set_irq[9] = { + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, + sizeof(struct aml_resource_irq), + ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, /* Convert interrupt list to 16-bit IRQ bitmask */ - irq_mask = 0; - for (i = 0; i < resource->data.irq.interrupt_count; i++) { - irq_mask |= (1 << resource->data.irq.interrupts[i]); - } + {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]), + AML_OFFSET(irq.irq_mask), + ACPI_RS_OFFSET(data.irq.interrupt_count)}, - /* Set the interrupt mask */ + /* Set the flags byte by default */ - ACPI_MOVE_16_TO_16(&aml->irq.irq_mask, &irq_mask); + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), + AML_OFFSET(irq.flags), + 0}, + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity), + AML_OFFSET(irq.flags), + 3}, + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), + AML_OFFSET(irq.flags), + 4}, /* - * The descriptor field is set based upon whether a third byte is - * needed to contain the IRQ Information. + * Check if the flags byte is necessary. Not needed if the flags are: + * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE */ - if ((resource->data.irq.triggering == ACPI_EDGE_SENSITIVE) && - (resource->data.irq.polarity == ACPI_ACTIVE_HIGH) && - (resource->data.irq.sharable == ACPI_EXCLUSIVE)) { - /* irq_no_flags() descriptor can be used */ + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.irq.triggering), + ACPI_EDGE_SENSITIVE}, - descriptor_length = sizeof(struct aml_resource_irq_noflags); - } else { - /* Irq() descriptor must be used */ + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.irq.polarity), + ACPI_ACTIVE_HIGH}, - descriptor_length = sizeof(struct aml_resource_irq); + {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.irq.sharable), + ACPI_EXCLUSIVE}, - /* Set the IRQ Info byte */ + /* irq_no_flags() descriptor can be used */ - aml->irq.flags = (u8) - ((resource->data.irq.sharable & 0x01) << 4); - - if (ACPI_LEVEL_SENSITIVE == resource->data.irq.triggering && - ACPI_ACTIVE_LOW == resource->data.irq.polarity) { - aml->irq.flags |= 0x08; - } else { - aml->irq.flags |= 0x01; - } - } - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_IRQ, descriptor_length, - aml); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_get_ext_irq - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. + * acpi_rs_convert_ext_irq * ******************************************************************************/ -acpi_status -acpi_rs_get_ext_irq(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - char *out_resource_string; - u8 temp8; +struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ, + ACPI_RS_SIZE(struct acpi_resource_extended_irq), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)}, - ACPI_FUNCTION_TRACE("rs_get_ext_irq"); + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ, + sizeof(struct aml_resource_extended_irq), + 0}, - /* Get the flag bits */ + /* Flag bits */ - temp8 = aml->extended_irq.flags; - resource->data.extended_irq.producer_consumer = temp8 & 0x01; - resource->data.extended_irq.polarity = (temp8 >> 2) & 0x01; - resource->data.extended_irq.sharable = (temp8 >> 3) & 0x01; + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer), + AML_OFFSET(extended_irq.flags), + 0}, - /* - * Check for Interrupt Mode - * - * The definition of an Extended IRQ changed between ACPI spec v1.0b - * and ACPI spec 2.0 (section 6.4.3.6 in both). - * - * - Edge/Level are defined opposite in the table vs the headers - */ - resource->data.extended_irq.triggering = - (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.triggering), + AML_OFFSET(extended_irq.flags), + 1}, - /* Get the IRQ Table length (Byte4) */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.polarity), + AML_OFFSET(extended_irq.flags), + 2}, - temp8 = aml->extended_irq.table_length; - resource->data.extended_irq.interrupt_count = temp8; - if (temp8 < 1) { - /* Must have at least one IRQ */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.sharable), + AML_OFFSET(extended_irq.flags), + 3}, - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); - } + /* IRQ Table length (Byte4) */ - /* - * Add any additional structure size to properly calculate - * the next pointer at the end of this function - */ - resource->length = (temp8 - 1) * 4; - out_resource_string = ACPI_CAST_PTR(char, - (&resource->data.extended_irq. - interrupts[0] + temp8)); + {ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count), + AML_OFFSET(extended_irq.interrupt_count), + sizeof(u32)} + , - /* Get every IRQ in the table, each is 32 bits */ + /* Copy every IRQ in the table, each is 32 bits */ - acpi_rs_move_data(resource->data.extended_irq.interrupts, - aml->extended_irq.interrupt_number, - (u16) temp8, ACPI_MOVE_TYPE_32_TO_32); + {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]), + AML_OFFSET(extended_irq.interrupts[0]), + 0} + , - /* Get the optional resource_source (index and string) */ + /* Optional resource_source (Index and String) */ - resource->length += - acpi_rs_get_resource_source(aml_resource_length, - (acpi_size) resource->length + - sizeof(struct - aml_resource_extended_irq), - &resource->data.extended_irq. - resource_source, aml, - out_resource_string); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; - resource->length += - ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_irq); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_SOURCEX, ACPI_RS_OFFSET(data.extended_irq.resource_source), + ACPI_RS_OFFSET(data.extended_irq.interrupts[0]), + sizeof(struct aml_resource_extended_irq)} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_set_ext_irq - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. + * acpi_rs_convert_dma * ******************************************************************************/ -acpi_status -acpi_rs_set_ext_irq(struct acpi_resource *resource, union aml_resource *aml) -{ - acpi_size descriptor_length; +struct acpi_rsconvert_info acpi_rs_convert_dma[6] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA, + ACPI_RS_SIZE(struct acpi_resource_dma), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_dma)}, - ACPI_FUNCTION_TRACE("rs_set_ext_irq"); + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA, + sizeof(struct aml_resource_dma), + 0}, - /* Set the Interrupt vector flags */ + /* Flags: transfer preference, bus mastering, channel speed */ - aml->extended_irq.flags = (u8) - ((resource->data.extended_irq.producer_consumer & 0x01) | - ((resource->data.extended_irq.sharable & 0x01) << 3) | - ((resource->data.extended_irq.polarity & 0x1) << 2)); + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.transfer), + AML_OFFSET(dma.flags), + 0}, - /* - * Set the Interrupt Mode - * - * The definition of an Extended IRQ changed between ACPI spec v1.0b - * and ACPI spec 2.0 (section 6.4.3.6 in both). This code does not - * implement the more restrictive definition of 1.0b - * - * - Edge/Level are defined opposite in the table vs the headers - */ - if (resource->data.extended_irq.triggering == ACPI_EDGE_SENSITIVE) { - aml->extended_irq.flags |= 0x02; - } + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.dma.bus_master), + AML_OFFSET(dma.flags), + 2}, - /* Set the Interrupt table length */ + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.type), + AML_OFFSET(dma.flags), + 5}, - aml->extended_irq.table_length = (u8) - resource->data.extended_irq.interrupt_count; + /* DMA channel mask bits */ - descriptor_length = (sizeof(struct aml_resource_extended_irq) - 4) + - ((acpi_size) resource->data.extended_irq.interrupt_count * - sizeof(u32)); - - /* Set each interrupt value */ - - acpi_rs_move_data(aml->extended_irq.interrupt_number, - resource->data.extended_irq.interrupts, - (u16) resource->data.extended_irq.interrupt_count, - ACPI_MOVE_TYPE_32_TO_32); - - /* Resource Source Index and Resource Source are optional */ - - descriptor_length = acpi_rs_set_resource_source(aml, descriptor_length, - &resource->data. - extended_irq. - resource_source); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_EXTENDED_IRQ, - descriptor_length, aml); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_BITMASK, ACPI_RS_OFFSET(data.dma.channels[0]), + AML_OFFSET(dma.dma_channel_mask), + ACPI_RS_OFFSET(data.dma.channel_count)} +}; diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index f72d42e0927b..ee17ef3315f8 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -48,7 +48,8 @@ ACPI_MODULE_NAME("rslist") /* Local prototypes */ -static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); +static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 + resource_type); static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml); @@ -83,7 +84,7 @@ static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) return (AE_AML_INVALID_RESOURCE_TYPE); } - resource_length = acpi_rs_get_resource_length(aml); + resource_length = acpi_ut_get_resource_length(aml); minimum_aml_resource_length = resource_info->minimum_aml_resource_length; @@ -115,18 +116,17 @@ static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) /******************************************************************************* * - * FUNCTION: acpi_rs_get_resource_handler + * FUNCTION: acpi_rs_get_conversion_info * * PARAMETERS: resource_type - Byte 0 of a resource descriptor * - * RETURN: Pointer to the resource conversion handler + * RETURN: Pointer to the resource conversion info table * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. + * DESCRIPTION: Get the conversion table associated with this resource type * ******************************************************************************/ -static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) +static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) { ACPI_FUNCTION_ENTRY(); @@ -174,33 +174,24 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, acpi_status status; acpi_size bytes_parsed = 0; struct acpi_resource *resource; - u16 resource_length; - u32 descriptor_length; - ACPI_GET_RESOURCE_HANDLER handler; + acpi_rsdesc_size descriptor_length; + struct acpi_rsconvert_info *info; ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); /* Loop until end-of-buffer or an end_tag is found */ while (bytes_parsed < aml_buffer_length) { - /* Get the handler associated with this Descriptor Type */ + /* Get the conversion table associated with this Descriptor Type */ - handler = acpi_rs_get_resource_handler(*aml_buffer); - if (!handler) { - /* No handler indicates invalid resource type */ + info = acpi_rs_get_conversion_info(*aml_buffer); + if (!info) { + /* No table indicates an invalid resource type */ return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } - resource_length = - acpi_rs_get_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); - - descriptor_length = - acpi_rs_get_descriptor_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + descriptor_length = acpi_ut_get_descriptor_length(aml_buffer); /* * Perform limited validation of the resource length, based upon @@ -214,11 +205,16 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, return_ACPI_STATUS(status); } - /* Convert a byte stream resource to local resource struct */ + /* Convert the AML byte stream resource to a local resource struct */ - status = handler(ACPI_CAST_PTR(union aml_resource, aml_buffer), - resource_length, - ACPI_CAST_PTR(struct acpi_resource, buffer)); + status = + acpi_rs_convert_aml_to_resource(ACPI_CAST_PTR + (struct acpi_resource, + buffer), + ACPI_CAST_PTR(union + aml_resource, + aml_buffer), + info); if (ACPI_FAILURE(status)) { ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status))); return_ACPI_STATUS(status); @@ -232,7 +228,7 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, /* Normal exit on completion of an end_tag resource descriptor */ - if (acpi_rs_get_resource_type(*aml_buffer) == + if (acpi_ut_get_resource_type(aml_buffer) == ACPI_RESOURCE_NAME_END_TAG) { return_ACPI_STATUS(AE_OK); } @@ -276,14 +272,15 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, acpi_size aml_size_needed, u8 * output_buffer) { u8 *aml_buffer = output_buffer; + u8 *end_aml_buffer = output_buffer + aml_size_needed; acpi_status status; ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); - /* Convert each resource descriptor in the list */ + /* Walk the resource descriptor list, convert each descriptor */ - while (1) { - /* Validate Resource Descriptor Type before dispatch */ + while (aml_buffer < end_aml_buffer) { + /* Validate the Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, @@ -292,14 +289,14 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, return_ACPI_STATUS(AE_BAD_DATA); } - /* Perform the conversion per resource type */ + /* Perform the conversion */ - status = - acpi_gbl_set_resource_dispatch[resource->type] (resource, - ACPI_CAST_PTR - (union - aml_resource, - aml_buffer)); + status = acpi_rs_convert_resource_to_aml(resource, + ACPI_CAST_PTR(union + aml_resource, + aml_buffer), + acpi_gbl_set_resource_dispatch + [resource->type]); if (ACPI_FAILURE(status)) { ACPI_REPORT_ERROR(("Could not convert resource (type %X) to AML, %s\n", resource->type, acpi_format_exception(status))); return_ACPI_STATUS(status); @@ -323,18 +320,23 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, return_ACPI_STATUS(AE_OK); } - /* Extract the total length of the new descriptor */ - /* Set the aml_buffer to point to the next (output) resource descriptor */ - - aml_buffer += - acpi_rs_get_descriptor_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + /* + * Extract the total length of the new descriptor and set the + * aml_buffer to point to the next (output) resource descriptor + */ + aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); /* Point to the next input resource descriptor */ resource = ACPI_PTR_ADD(struct acpi_resource, resource, resource->length); + + /* Check for end-of-list, normal exit */ + } + + /* Completed buffer, but did not find an end_tag resource descriptor */ + + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index 47e979e7ba35..418a3fb64077 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c @@ -49,260 +49,187 @@ ACPI_MODULE_NAME("rsmemory") /******************************************************************************* * - * FUNCTION: acpi_rs_get_memory24 - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. + * acpi_rs_convert_memory24 * ******************************************************************************/ -acpi_status -acpi_rs_get_memory24(union aml_resource * aml, - u16 aml_resource_length, struct acpi_resource * resource) -{ - ACPI_FUNCTION_TRACE("rs_get_memory24"); +struct acpi_rsconvert_info acpi_rs_convert_memory24[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY24, + ACPI_RS_SIZE(struct acpi_resource_memory24), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory24)}, - /* Get the Read/Write bit */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY24, + sizeof(struct aml_resource_memory24), + 0}, - resource->data.memory24.read_write_attribute = - (aml->memory24.information & 0x01); + /* Read/Write bit */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory24.write_protect), + AML_OFFSET(memory24.flags), + 0}, /* - * Get the following contiguous fields from the AML descriptor: + * These fields are contiguous in both the source and destination: * Minimum Base Address * Maximum Base Address * Address Base Alignment * Range Length */ - acpi_rs_move_data(&resource->data.memory24.minimum, - &aml->memory24.minimum, 4, ACPI_MOVE_TYPE_16_TO_32); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_MEMORY24; - resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_memory24); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.memory24.minimum), + AML_OFFSET(memory24.minimum), + 4} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_set_memory24 - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. + * acpi_rs_convert_memory32 * ******************************************************************************/ -acpi_status -acpi_rs_set_memory24(struct acpi_resource *resource, union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_memory24"); +struct acpi_rsconvert_info acpi_rs_convert_memory32[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY32, + ACPI_RS_SIZE(struct acpi_resource_memory32), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory32)}, - /* Set the Information Byte */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY32, + sizeof(struct aml_resource_memory32), + 0}, - aml->memory24.information = (u8) - (resource->data.memory24.read_write_attribute & 0x01); + /* Read/Write bit */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory32.write_protect), + AML_OFFSET(memory32.flags), + 0}, /* - * Set the following contiguous fields in the AML descriptor: + * These fields are contiguous in both the source and destination: * Minimum Base Address * Maximum Base Address * Address Base Alignment * Range Length */ - acpi_rs_move_data(&aml->memory24.minimum, - &resource->data.memory24.minimum, 4, - ACPI_MOVE_TYPE_32_TO_16); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_MEMORY24, - sizeof(struct aml_resource_memory24), aml); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.memory32.minimum), + AML_OFFSET(memory32.minimum), + 4} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_get_memory32 - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. + * acpi_rs_convert_fixed_memory32 * ******************************************************************************/ -acpi_status -acpi_rs_get_memory32(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_memory32"); +struct acpi_rsconvert_info acpi_rs_convert_fixed_memory32[4] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_MEMORY32, + ACPI_RS_SIZE(struct acpi_resource_fixed_memory32), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_memory32)}, - /* Get the Read/Write bit */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_MEMORY32, + sizeof(struct aml_resource_fixed_memory32), + 0}, - resource->data.memory32.read_write_attribute = - (aml->memory32.information & 0x01); + /* Read/Write bit */ + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.fixed_memory32.write_protect), + AML_OFFSET(fixed_memory32.flags), + 0}, /* - * Get the following contiguous fields from the AML descriptor: - * Minimum Base Address - * Maximum Base Address - * Address Base Alignment - * Range Length - */ - acpi_rs_move_data(&resource->data.memory32.minimum, - &aml->memory32.minimum, 4, ACPI_MOVE_TYPE_32_TO_32); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_MEMORY32; - resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_memory32); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_memory32 - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ - -acpi_status -acpi_rs_set_memory32(struct acpi_resource *resource, union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_memory32"); - - /* Set the Information Byte */ - - aml->memory32.information = (u8) - (resource->data.memory32.read_write_attribute & 0x01); - - /* - * Set the following contiguous fields in the AML descriptor: - * Minimum Base Address - * Maximum Base Address - * Address Base Alignment - * Range Length - */ - acpi_rs_move_data(&aml->memory32.minimum, - &resource->data.memory32.minimum, 4, - ACPI_MOVE_TYPE_32_TO_32); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_MEMORY32, - sizeof(struct aml_resource_memory32), aml); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_fixed_memory32 - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ - -acpi_status -acpi_rs_get_fixed_memory32(union aml_resource *aml, - u16 aml_resource_length, - struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_fixed_memory32"); - - /* Get the Read/Write bit */ - - resource->data.fixed_memory32.read_write_attribute = - (aml->fixed_memory32.information & 0x01); - - /* - * Get the following contiguous fields from the AML descriptor: + * These fields are contiguous in both the source and destination: * Base Address * Range Length */ - ACPI_MOVE_32_TO_32(&resource->data.fixed_memory32.address, - &aml->fixed_memory32.address); - ACPI_MOVE_32_TO_32(&resource->data.fixed_memory32.address_length, - &aml->fixed_memory32.address_length); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_FIXED_MEMORY32; - resource->length = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_memory32); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.fixed_memory32.address), + AML_OFFSET(fixed_memory32.address), + 2} +}; /******************************************************************************* * - * FUNCTION: acpi_rs_set_fixed_memory32 - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. + * acpi_rs_get_vendor_small * ******************************************************************************/ -acpi_status -acpi_rs_set_fixed_memory32(struct acpi_resource *resource, - union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_fixed_memory32"); +struct acpi_rsconvert_info acpi_rs_get_vendor_small[3] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_small)}, - /* Set the Information Byte */ + /* Length of the vendor data (byte count) */ - aml->fixed_memory32.information = (u8) - (resource->data.fixed_memory32.read_write_attribute & 0x01); + {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), + 0, + sizeof(u8)} + , + + /* Vendor data */ + + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), + sizeof(struct aml_resource_small_header), + 0} +}; + +/******************************************************************************* + * + * acpi_rs_get_vendor_large + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_get_vendor_large[3] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_large)}, + + /* Length of the vendor data (byte count) */ + + {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), + 0, + sizeof(u8)} + , + + /* Vendor data */ + + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), + sizeof(struct aml_resource_large_header), + 0} +}; + +/******************************************************************************* + * + * acpi_rs_set_vendor + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_set_vendor[7] = { + /* Default is a small vendor descriptor */ + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_SMALL, + sizeof(struct aml_resource_small_header), + ACPI_RSC_TABLE_SIZE(acpi_rs_set_vendor)}, + + /* Get the length and copy the data */ + + {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), + 0, + 0}, + + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), + sizeof(struct aml_resource_small_header), + 0}, /* - * Set the following contiguous fields in the AML descriptor: - * Base Address - * Range Length + * All done if the Vendor byte length is 7 or less, meaning that it will + * fit within a small descriptor */ - ACPI_MOVE_32_TO_32(&aml->fixed_memory32.address, - &resource->data.fixed_memory32.address); - ACPI_MOVE_32_TO_32(&aml->fixed_memory32.address_length, - &resource->data.fixed_memory32.address_length); + {ACPI_RSC_EXIT_LE, 0, 0, 7}, - /* Complete the AML descriptor header */ + /* Must create a large vendor descriptor */ - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_FIXED_MEMORY32, - sizeof(struct aml_resource_fixed_memory32), - aml); - return_ACPI_STATUS(AE_OK); -} + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_LARGE, + sizeof(struct aml_resource_large_header), + 0}, + + {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), + 0, + 0}, + + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), + sizeof(struct aml_resource_large_header), + 0} +}; diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 337a0f01cb23..16ad3bfbee2a 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -47,434 +47,506 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsmisc") +#define INIT_RESOURCE_TYPE(i) i->resource_offset +#define INIT_RESOURCE_LENGTH(i) i->aml_offset +#define INIT_TABLE_LENGTH(i) i->value +#define COMPARE_OPCODE(i) i->resource_offset +#define COMPARE_TARGET(i) i->aml_offset +#define COMPARE_VALUE(i) i->value /******************************************************************************* * - * FUNCTION: acpi_rs_get_generic_reg - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ -acpi_status -acpi_rs_get_generic_reg(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_generic_reg"); - - /* - * Get the following fields from the AML descriptor: - * Address Space ID - * Register Bit Width - * Register Bit Offset - * Access Size - * Register Address - */ - resource->data.generic_reg.space_id = aml->generic_reg.address_space_id; - resource->data.generic_reg.bit_width = aml->generic_reg.bit_width; - resource->data.generic_reg.bit_offset = aml->generic_reg.bit_offset; - resource->data.generic_reg.access_size = aml->generic_reg.access_size; - ACPI_MOVE_64_TO_64(&resource->data.generic_reg.address, - &aml->generic_reg.address); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_GENERIC_REGISTER; - resource->length = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_register); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_generic_reg + * FUNCTION: acpi_rs_convert_aml_to_resource * * PARAMETERS: Resource - Pointer to the resource descriptor * Aml - Where the AML descriptor is returned + * Info - Pointer to appropriate conversion table * * RETURN: Status * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. + * DESCRIPTION: Convert an external AML resource descriptor to the corresponding + * internal resource descriptor * ******************************************************************************/ - acpi_status -acpi_rs_set_generic_reg(struct acpi_resource *resource, union aml_resource *aml) +acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, + union aml_resource *aml, + struct acpi_rsconvert_info *info) { - ACPI_FUNCTION_TRACE("rs_set_generic_reg"); + acpi_rs_length aml_resource_length; + void *source; + void *destination; + char *target; + u8 count; + u8 flags_mode = FALSE; + u16 item_count = 0; + u16 temp16 = 0; - /* - * Set the following fields in the AML descriptor: - * Address Space ID - * Register Bit Width - * Register Bit Offset - * Access Size - * Register Address - */ - aml->generic_reg.address_space_id = - (u8) resource->data.generic_reg.space_id; - aml->generic_reg.bit_width = (u8) resource->data.generic_reg.bit_width; - aml->generic_reg.bit_offset = - (u8) resource->data.generic_reg.bit_offset; - aml->generic_reg.access_size = - (u8) resource->data.generic_reg.access_size; - ACPI_MOVE_64_TO_64(&aml->generic_reg.address, - &resource->data.generic_reg.address); + ACPI_FUNCTION_TRACE("rs_get_resource"); - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_GENERIC_REGISTER, - sizeof(struct - aml_resource_generic_register), aml); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_vendor - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ - -acpi_status -acpi_rs_get_vendor(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - u8 *aml_byte_data; - - ACPI_FUNCTION_TRACE("rs_get_vendor"); - - /* Determine if this is a large or small vendor specific item */ - - if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large item, Point to the first vendor byte */ - - aml_byte_data = - ((u8 *) aml) + sizeof(struct aml_resource_large_header); - } else { - /* Small item, Point to the first vendor byte */ - - aml_byte_data = - ((u8 *) aml) + sizeof(struct aml_resource_small_header); + if (((acpi_native_uint) resource) & 0x3) { + acpi_os_printf + ("**** GET: Misaligned resource pointer: %p Type %2.2X Len %X\n", + resource, resource->type, resource->length); } - /* Copy the vendor-specific bytes */ + /* Extract the resource Length field (does not include header length) */ - ACPI_MEMCPY(resource->data.vendor.byte_data, - aml_byte_data, aml_resource_length); - resource->data.vendor.byte_length = aml_resource_length; + aml_resource_length = acpi_ut_get_resource_length(aml); /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the vendor string and expand the - * struct_size to the next 32-bit boundary. + * First table entry must be ACPI_RSC_INITxxx and must contain the + * table length (# of table entries) */ - resource->type = ACPI_RESOURCE_TYPE_VENDOR; - resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + - ACPI_ROUND_UP_to_32_bITS(aml_resource_length); - return_ACPI_STATUS(AE_OK); -} + count = INIT_TABLE_LENGTH(info); -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_vendor - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ + while (count) { + /* + * Source is the external AML byte stream buffer, + * destination is the internal resource descriptor + */ + source = ((u8 *) aml) + info->aml_offset; + destination = ((u8 *) resource) + info->resource_offset; -acpi_status -acpi_rs_set_vendor(struct acpi_resource *resource, union aml_resource *aml) -{ - u32 resource_length; - u8 *source; - u8 *destination; + switch (info->opcode) { + case ACPI_RSC_INITGET: + /* + * Get the resource type and the initial (minimum) length + */ + ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info)); + resource->type = INIT_RESOURCE_TYPE(info); + resource->length = INIT_RESOURCE_LENGTH(info); + break; - ACPI_FUNCTION_TRACE("rs_set_vendor"); + case ACPI_RSC_INITSET: + break; - resource_length = resource->data.vendor.byte_length; - source = ACPI_CAST_PTR(u8, resource->data.vendor.byte_data); + case ACPI_RSC_FLAGINIT: - /* Length determines if this is a large or small resource */ + flags_mode = TRUE; + break; - if (resource_length > 7) { - /* Large item, get pointer to the data part of the descriptor */ + case ACPI_RSC_1BITFLAG: + /* + * Mask and shift the flag bit + */ + *((u8 *) destination) = (u8) + ((*((u8 *) source) >> info->value) & 0x01); + break; - destination = - ((u8 *) aml) + sizeof(struct aml_resource_large_header); + case ACPI_RSC_2BITFLAG: + /* + * Mask and shift the flag bits + */ + *((u8 *) destination) = (u8) + ((*((u8 *) source) >> info->value) & 0x03); + break; - /* Complete the AML descriptor header */ + case ACPI_RSC_COUNT: - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_VENDOR_LARGE, - (u32) (resource_length + - sizeof(struct - aml_resource_large_header)), - aml); - } else { - /* Small item, get pointer to the data part of the descriptor */ + item_count = *((u8 *) source); + *((u8 *) destination) = (u8) item_count; - destination = - ((u8 *) aml) + sizeof(struct aml_resource_small_header); + resource->length = resource->length + + (info->value * (item_count - 1)); + break; - /* Complete the AML descriptor header */ + case ACPI_RSC_COUNT16: - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_VENDOR_SMALL, - (u32) (resource_length + - sizeof(struct - aml_resource_small_header)), - aml); - } + item_count = aml_resource_length; + *((u16 *) destination) = item_count; - /* Copy the vendor-specific bytes */ + resource->length = resource->length + + (info->value * (item_count - 1)); + break; - ACPI_MEMCPY(destination, source, resource_length); - return_ACPI_STATUS(AE_OK); -} + case ACPI_RSC_LENGTH: -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_start_dpf - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ + resource->length = resource->length + info->value; + break; -acpi_status -acpi_rs_get_start_dpf(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_start_dpf"); + case ACPI_RSC_MOVE8: + case ACPI_RSC_MOVE16: + case ACPI_RSC_MOVE32: + case ACPI_RSC_MOVE64: + /* + * Raw data move. Use the Info value field unless item_count has + * been previously initialized via a COUNT opcode + */ + if (info->value) { + item_count = info->value; + } + acpi_rs_move_data(destination, source, item_count, + info->opcode); + break; - /* Get the flags byte if present */ + case ACPI_RSC_SET8: - if (aml_resource_length == 1) { - /* Get the Compatibility priority */ + ACPI_MEMSET(destination, info->aml_offset, info->value); + break; - resource->data.start_dpf.compatibility_priority = - (aml->start_dpf.flags & 0x03); + case ACPI_RSC_DATA8: - if (resource->data.start_dpf.compatibility_priority >= 3) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); + target = ((char *)resource) + info->value; + ACPI_MEMCPY(destination, source, + *(ACPI_CAST_PTR(u16, target))); + break; + + case ACPI_RSC_ADDRESS: + /* + * Common handler for address descriptor flags + */ + if (!acpi_rs_get_address_common(resource, aml)) { + return_ACPI_STATUS + (AE_AML_INVALID_RESOURCE_TYPE); + } + break; + + case ACPI_RSC_SOURCE: + /* + * Optional resource_source (Index and String) + */ + resource->length += + acpi_rs_get_resource_source(aml_resource_length, + info->value, + destination, aml, NULL); + break; + + case ACPI_RSC_SOURCEX: + /* + * Optional resource_source (Index and String). This is the more + * complicated case used by the Interrupt() macro + */ + target = + ((char *)resource) + info->aml_offset + + (item_count * 4); + + resource->length += + acpi_rs_get_resource_source(aml_resource_length, + (acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target); + break; + + case ACPI_RSC_BITMASK: + /* + * 8-bit encoded bitmask (DMA macro) + */ + item_count = + acpi_rs_decode_bitmask(*((u8 *) source), + destination); + if (item_count) { + resource->length += + resource->length + (item_count - 1); + } + + target = ((char *)resource) + info->value; + *((u8 *) target) = (u8) item_count; + break; + + case ACPI_RSC_BITMASK16: + /* + * 16-bit encoded bitmask (IRQ macro) + */ + ACPI_MOVE_16_TO_16(&temp16, source); + + item_count = + acpi_rs_decode_bitmask(temp16, destination); + if (item_count) { + resource->length = + resource->length + (item_count - 1); + } + + target = ((char *)resource) + info->value; + *((u8 *) target) = (u8) item_count; + break; + + case ACPI_RSC_EXIT_NE: + /* + * Control - Exit conversion if not equal + */ + switch (info->resource_offset) { + case ACPI_RSC_COMPARE_AML_LENGTH: + if (aml_resource_length != info->value) { + goto exit; + } + break; + + case ACPI_RSC_COMPARE_VALUE: + if (*((u8 *) source) != info->value) { + goto exit; + } + break; + + default: + acpi_os_printf + ("*** Invalid conversion sub-opcode\n"); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + break; + + default: + + acpi_os_printf("*** Invalid conversion opcode\n"); + return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Get the Performance/Robustness preference */ + count--; + info++; + } - resource->data.start_dpf.performance_robustness = - ((aml->start_dpf.flags >> 2) & 0x03); + exit: + if (!flags_mode) { + /* Round the resource struct length up to the next 32-bit boundary */ - if (resource->data.start_dpf.performance_robustness >= 3) { - return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); + resource->length = ACPI_ROUND_UP_to_32_bITS(resource->length); + } + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_convert_resource_to_aml + * + * PARAMETERS: Resource - Pointer to the resource descriptor + * Aml - Where the AML descriptor is returned + * Info - Pointer to appropriate conversion table + * + * RETURN: Status + * + * DESCRIPTION: Convert an internal resource descriptor to the corresponding + * external AML resource descriptor. + * + ******************************************************************************/ + +acpi_status +acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, + union aml_resource *aml, + struct acpi_rsconvert_info *info) +{ + void *source = NULL; + void *destination; + acpi_rsdesc_size aml_length = 0; + u8 count; + u16 temp16 = 0; + u16 item_count = 0; + + ACPI_FUNCTION_TRACE("rs_convert_resource_to_aml"); + + /* Validate the Resource pointer, must be 32-bit aligned */ + + if (((acpi_native_uint) resource) & 0x3) { + acpi_os_printf + ("**** SET: Misaligned resource pointer: %p Type %2.2X Len %X\n", + resource, resource->type, resource->length); + } + + /* + * First table entry must be ACPI_RSC_INITxxx and must contain the + * table length (# of table entries) + */ + count = INIT_TABLE_LENGTH(info); + + while (count) { + /* + * Source is the internal resource descriptor, + * destination is the external AML byte stream buffer + */ + source = ((u8 *) resource) + info->resource_offset; + destination = ((u8 *) aml) + info->aml_offset; + + switch (info->opcode) { + case ACPI_RSC_INITSET: + + ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info)); + aml_length = INIT_RESOURCE_LENGTH(info); + acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info), + aml_length, aml); + break; + + case ACPI_RSC_INITGET: + break; + + case ACPI_RSC_FLAGINIT: + /* + * Clear the flag byte + */ + *((u8 *) destination) = 0; + break; + + case ACPI_RSC_1BITFLAG: + /* + * Mask and shift the flag bit + */ + *((u8 *) destination) |= (u8) + ((*((u8 *) source) & 0x01) << info->value); + break; + + case ACPI_RSC_2BITFLAG: + /* + * Mask and shift the flag bits + */ + *((u8 *) destination) |= (u8) + ((*((u8 *) source) & 0x03) << info->value); + break; + + case ACPI_RSC_COUNT: + + item_count = *((u8 *) source); + *((u8 *) destination) = (u8) item_count; + + aml_length = (u16) (aml_length + + (info->value * (item_count - 1))); + break; + + case ACPI_RSC_COUNT16: + + item_count = *((u16 *) source); + aml_length = (u16) (aml_length + item_count); + acpi_rs_set_resource_length(aml_length, aml); + break; + + case ACPI_RSC_LENGTH: + + acpi_rs_set_resource_length(info->value, aml); + break; + + case ACPI_RSC_MOVE8: + case ACPI_RSC_MOVE16: + case ACPI_RSC_MOVE32: + case ACPI_RSC_MOVE64: + + if (info->value) { + item_count = info->value; + } + acpi_rs_move_data(destination, source, item_count, + info->opcode); + break; + + case ACPI_RSC_ADDRESS: + + /* Set the Resource Type, General Flags, and Type-Specific Flags */ + + acpi_rs_set_address_common(aml, resource); + break; + + case ACPI_RSC_SOURCEX: + /* + * Optional resource_source (Index and String) + */ + aml_length = + acpi_rs_set_resource_source(aml, + (acpi_rs_length) + aml_length, source); + acpi_rs_set_resource_length(aml_length, aml); + break; + + case ACPI_RSC_SOURCE: + /* + * Optional resource_source (Index and String). This is the more + * complicated case used by the Interrupt() macro + */ + aml_length = + acpi_rs_set_resource_source(aml, info->value, + source); + acpi_rs_set_resource_length(aml_length, aml); + break; + + case ACPI_RSC_BITMASK: + /* + * 8-bit encoded bitmask (DMA macro) + */ + *((u8 *) destination) = (u8) + acpi_rs_encode_bitmask(source, + *(((u8 *) resource) + + info->value)); + break; + + case ACPI_RSC_BITMASK16: + /* + * 16-bit encoded bitmask (IRQ macro) + */ + temp16 = + acpi_rs_encode_bitmask(source, + *(((u8 *) resource) + + info->value)); + ACPI_MOVE_16_TO_16(destination, &temp16); + break; + + case ACPI_RSC_EXIT_LE: + /* + * Control - Exit conversion if less than or equal + */ + if (item_count <= info->value) { + goto exit; + } + break; + + case ACPI_RSC_EXIT_NE: + /* + * Control - Exit conversion if not equal + */ + switch (COMPARE_OPCODE(info)) { + case ACPI_RSC_COMPARE_VALUE: + if (* + ((u8 *) (((u8 *) resource) + + COMPARE_TARGET(info))) != + COMPARE_VALUE(info)) { + goto exit; + } + break; + + default: + acpi_os_printf + ("*** Invalid conversion sub-opcode\n"); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + break; + + default: + + acpi_os_printf("*** Invalid conversion opcode\n"); + return_ACPI_STATUS(AE_BAD_PARAMETER); } - } else { - /* start_dependent_no_pri(), no flags byte, set defaults */ - resource->data.start_dpf.compatibility_priority = - ACPI_ACCEPTABLE_CONFIGURATION; - - resource->data.start_dpf.performance_robustness = - ACPI_ACCEPTABLE_CONFIGURATION; + count--; + info++; } - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_START_DEPENDENT; - resource->length = - ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dependent); + exit: return_ACPI_STATUS(AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_start_dpf - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ +#if 0 +/* Previous resource validations */ -acpi_status -acpi_rs_set_start_dpf(struct acpi_resource *resource, union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_start_dpf"); +if (aml->ext_address64.revision_iD != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) { + return_ACPI_STATUS(AE_SUPPORT); +} +if (resource->data.start_dpf.performance_robustness >= 3) { + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); +} + +if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) { /* - * The descriptor type field is set based upon whether a byte is needed - * to contain Priority data. + * Only [active_high, edge_sensitive] or [active_low, level_sensitive] + * polarity/trigger interrupts are allowed (ACPI spec, section + * "IRQ Format"), so 0x00 and 0x09 are illegal. */ - if (ACPI_ACCEPTABLE_CONFIGURATION == - resource->data.start_dpf.compatibility_priority && - ACPI_ACCEPTABLE_CONFIGURATION == - resource->data.start_dpf.performance_robustness) { - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_START_DEPENDENT, - sizeof(struct - aml_resource_start_dependent_noprio), - aml); - } else { - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_START_DEPENDENT, - sizeof(struct - aml_resource_start_dependent), - aml); - - /* Set the Flags byte */ - - aml->start_dpf.flags = (u8) - (((resource->data.start_dpf. - performance_robustness & 0x03) << 2) | (resource->data. - start_dpf. - compatibility_priority - & 0x03)); - } - return_ACPI_STATUS(AE_OK); + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid interrupt polarity/trigger in resource list, %X\n", + aml->irq.flags)); + return_ACPI_STATUS(AE_BAD_DATA); } -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_end_dpf - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ +resource->data.extended_irq.interrupt_count = temp8; +if (temp8 < 1) { + /* Must have at least one IRQ */ -acpi_status -acpi_rs_get_end_dpf(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_end_dpf"); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_END_DEPENDENT; - resource->length = (u32) ACPI_RESOURCE_LENGTH; - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); } -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_end_dpf - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ - -acpi_status -acpi_rs_set_end_dpf(struct acpi_resource *resource, union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_end_dpf"); - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_END_DEPENDENT, - sizeof(struct aml_resource_end_dependent), - aml); - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_end_tag - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * aml_resource_length - Length of the resource from the AML header - * Resource - Where the internal resource is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding - * internal resource descriptor, simplifying bitflags and handling - * alignment and endian issues if necessary. - * - ******************************************************************************/ - -acpi_status -acpi_rs_get_end_tag(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource) -{ - ACPI_FUNCTION_TRACE("rs_get_end_tag"); - - /* Complete the resource header */ - - resource->type = ACPI_RESOURCE_TYPE_END_TAG; - resource->length = ACPI_RESOURCE_LENGTH; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_set_end_tag - * - * PARAMETERS: Resource - Pointer to the resource descriptor - * Aml - Where the AML descriptor is returned - * - * RETURN: Status - * - * DESCRIPTION: Convert an internal resource descriptor to the corresponding - * external AML resource descriptor. - * - ******************************************************************************/ - -acpi_status -acpi_rs_set_end_tag(struct acpi_resource *resource, union aml_resource *aml) -{ - ACPI_FUNCTION_TRACE("rs_set_end_tag"); - - /* - * Set the Checksum - zero means that the resource data is treated as if - * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8) - */ - aml->end_tag.checksum = 0; - - /* Complete the AML descriptor header */ - - acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_END_TAG, - sizeof(struct aml_resource_end_tag), aml); - return_ACPI_STATUS(AE_OK); +if (resource->data.dma.transfer == 0x03) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid DMA.Transfer preference (3)\n")); + return_ACPI_STATUS(AE_BAD_DATA); } +#endif diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 9d503de1a349..7613033f5dcf 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -48,6 +48,64 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsutils") +/******************************************************************************* + * + * FUNCTION: acpi_rs_decode_bitmask + * + * PARAMETERS: Mask - Bitmask to decode + * List - Where the converted list is returned + * + * RETURN: Count of bits set (length of list) + * + * DESCRIPTION: Convert a bit mask into a list of values + * + ******************************************************************************/ +u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) +{ + acpi_native_uint i; + u8 bit_count; + + /* Decode the mask bits */ + + for (i = 0, bit_count = 0; mask; i++) { + if (mask & 0x0001) { + list[bit_count] = (u8) i; + bit_count++; + } + + mask >>= 1; + } + + return (bit_count); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_encode_bitmask + * + * PARAMETERS: List - List of values to encode + * Count - Length of list + * + * RETURN: Encoded bitmask + * + * DESCRIPTION: Convert a list of values to an encoded bitmask + * + ******************************************************************************/ + +u16 acpi_rs_encode_bitmask(u8 * list, u8 count) +{ + acpi_native_uint i; + u16 mask; + + /* Encode the list into a single bitmask */ + + for (i = 0, mask = 0; i < count; i++) { + mask |= (0x0001 << list[i]); + } + + return (mask); +} + /******************************************************************************* * * FUNCTION: acpi_rs_move_data @@ -64,6 +122,7 @@ ACPI_MODULE_NAME("rsutils") * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) * ******************************************************************************/ + void acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) { @@ -73,22 +132,30 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) for (i = 0; i < item_count; i++) { switch (move_type) { - case ACPI_MOVE_TYPE_16_TO_32: - ACPI_MOVE_16_TO_32(&((u32 *) destination)[i], + /* + * For the 8-bit case, we can perform the move all at once + * since there are no alignment or endian issues + */ + case ACPI_RSC_MOVE8: + ACPI_MEMCPY(destination, source, item_count); + return; + + /* + * 16-, 32-, and 64-bit cases must use the move macros that perform + * endian conversion and/or accomodate hardware that cannot perform + * misaligned memory transfers + */ + case ACPI_RSC_MOVE16: + ACPI_MOVE_16_TO_16(&((u16 *) destination)[i], &((u16 *) source)[i]); break; - case ACPI_MOVE_TYPE_32_TO_16: - ACPI_MOVE_32_TO_16(&((u16 *) destination)[i], - &((u32 *) source)[i]); - break; - - case ACPI_MOVE_TYPE_32_TO_32: + case ACPI_RSC_MOVE32: ACPI_MOVE_32_TO_32(&((u32 *) destination)[i], &((u32 *) source)[i]); break; - case ACPI_MOVE_TYPE_64_TO_64: + case ACPI_RSC_MOVE64: ACPI_MOVE_64_TO_64(&((u64 *) destination)[i], &((u64 *) source)[i]); break; @@ -148,80 +215,57 @@ struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type) /******************************************************************************* * - * FUNCTION: acpi_rs_get_resource_length + * FUNCTION: acpi_rs_set_resource_length * - * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * PARAMETERS: total_length - Length of the AML descriptor, including + * the header and length fields. + * Aml - Pointer to the raw AML descriptor * - * RETURN: Byte Length + * RETURN: None * - * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By - * definition, this does not include the size of the descriptor - * header or the length field itself. + * DESCRIPTION: Set the resource_length field of an AML + * resource descriptor, both Large and Small descriptors are + * supported automatically. Note: Descriptor Type field must + * be valid. * ******************************************************************************/ -u16 acpi_rs_get_resource_length(union aml_resource * aml) +void +acpi_rs_set_resource_length(acpi_rsdesc_size total_length, + union aml_resource *aml) { - u16 resource_length; + acpi_rs_length resource_length; ACPI_FUNCTION_ENTRY(); /* Determine if this is a small or large resource */ - if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { + if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { /* Large Resource type -- bytes 1-2 contain the 16-bit length */ - ACPI_MOVE_16_TO_16(&resource_length, - &aml->large_header.resource_length); + resource_length = (acpi_rs_length) + (total_length - sizeof(struct aml_resource_large_header)); + /* Insert length into the Large descriptor length field */ + + ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, + &resource_length); } else { /* Small Resource type -- bits 2:0 of byte 0 contain the length */ - resource_length = (u16) (aml->small_header.descriptor_type & - ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); + resource_length = (acpi_rs_length) + (total_length - sizeof(struct aml_resource_small_header)); + + /* Insert length into the descriptor type byte */ + + aml->small_header.descriptor_type = (u8) + + /* Clear any existing length, preserving descriptor type bits */ + ((aml->small_header. + descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK) + + | resource_length); } - - return (resource_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_descriptor_length - * - * PARAMETERS: Aml - Pointer to the raw AML resource descriptor - * - * RETURN: Byte length - * - * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the - * length of the descriptor header and the length field itself. - * Used to walk descriptor lists. - * - ******************************************************************************/ - -u32 acpi_rs_get_descriptor_length(union aml_resource * aml) -{ - u32 descriptor_length; - - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource type -- bytes 1-2 contain the 16-bit length */ - - ACPI_MOVE_16_TO_32(&descriptor_length, - &aml->large_header.resource_length); - descriptor_length += sizeof(struct aml_resource_large_header); - - } else { - /* Small Resource type -- bits 2:0 of byte 0 contain the length */ - - descriptor_length = (u32) (aml->small_header.descriptor_type & - ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); - descriptor_length += sizeof(struct aml_resource_small_header); - } - - return (descriptor_length); } /******************************************************************************* @@ -243,71 +287,18 @@ u32 acpi_rs_get_descriptor_length(union aml_resource * aml) void acpi_rs_set_resource_header(u8 descriptor_type, - acpi_size total_length, union aml_resource *aml) + acpi_rsdesc_size total_length, + union aml_resource *aml) { - u16 resource_length; - ACPI_FUNCTION_ENTRY(); - /* Set the descriptor type */ + /* Set the Descriptor Type */ aml->small_header.descriptor_type = descriptor_type; - /* Determine if this is a small or large resource */ + /* Set the Resource Length */ - if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource type -- bytes 1-2 contain the 16-bit length */ - - resource_length = - (u16) (total_length - - sizeof(struct aml_resource_large_header)); - - /* Insert length into the Large descriptor length field */ - - ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, - &resource_length); - } else { - /* Small Resource type -- bits 2:0 of byte 0 contain the length */ - - resource_length = - (u16) (total_length - - sizeof(struct aml_resource_small_header)); - - /* Insert length into the descriptor type byte */ - - aml->small_header.descriptor_type |= (u8) resource_length; - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_resource_type - * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor - * - * RETURN: The Resource Type with no extraneous bits (except the - * Large/Small descriptor bit -- this is left alone) - * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. - * - ******************************************************************************/ - -u8 acpi_rs_get_resource_type(u8 resource_type) -{ - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (resource_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - return (resource_type); - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - return ((u8) (resource_type & ACPI_RESOURCE_NAME_SMALL_MASK)); - } + acpi_rs_set_resource_length(total_length, aml); } /******************************************************************************* @@ -360,13 +351,13 @@ static u16 acpi_rs_strcpy(char *destination, char *source) * ******************************************************************************/ -u16 -acpi_rs_get_resource_source(u16 resource_length, - acpi_size minimum_length, +acpi_rs_length +acpi_rs_get_resource_source(acpi_rs_length resource_length, + acpi_rs_length minimum_length, struct acpi_resource_source * resource_source, union aml_resource * aml, char *string_ptr) { - acpi_size total_length; + acpi_rsdesc_size total_length; u8 *aml_resource_source; ACPI_FUNCTION_ENTRY(); @@ -382,7 +373,7 @@ acpi_rs_get_resource_source(u16 resource_length, * Note: Some resource descriptors will have an additional null, so * we add 1 to the minimum length. */ - if (total_length > (minimum_length + 1)) { + if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) { /* Get the resource_source_index */ resource_source->index = aml_resource_source[0]; @@ -398,20 +389,26 @@ acpi_rs_get_resource_source(u16 resource_length, sizeof(struct acpi_resource_source); } + /* + * In order for the struct_size to fall on a 32-bit boundary, calculate + * the length of the string (+1 for the NULL terminator) and expand the + * struct_size to the next 32-bit boundary. + * + * Zero the entire area of the buffer. + */ + total_length = + ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN + ((char *)&aml_resource_source[1]) + + 1); + ACPI_MEMSET(resource_source->string_ptr, 0, total_length); + /* Copy the resource_source string to the destination */ resource_source->string_length = acpi_rs_strcpy(resource_source->string_ptr, (char *)&aml_resource_source[1]); - /* - * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. - */ - return ((u16) - ACPI_ROUND_UP_to_32_bITS(resource_source-> - string_length)); + return ((acpi_rs_length) total_length); } else { /* resource_source is not present */ @@ -434,18 +431,18 @@ acpi_rs_get_resource_source(u16 resource_length, * * RETURN: Total length of the AML descriptor * - * DESCRIPTION: Convert an optoinal resource_source from internal format to a + * DESCRIPTION: Convert an optional resource_source from internal format to a * raw AML resource descriptor * ******************************************************************************/ -acpi_size +acpi_rsdesc_size acpi_rs_set_resource_source(union aml_resource * aml, - acpi_size minimum_length, + acpi_rs_length minimum_length, struct acpi_resource_source * resource_source) { u8 *aml_resource_source; - acpi_size descriptor_length; + acpi_rsdesc_size descriptor_length; ACPI_FUNCTION_ENTRY(); @@ -472,7 +469,7 @@ acpi_rs_set_resource_source(union aml_resource * aml, * final descriptor length */ descriptor_length += - ((acpi_size) resource_source->string_length + 1); + ((acpi_rsdesc_size) resource_source->string_length + 1); } /* Return the new total length of the AML descriptor */ diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 9d179beb17ae..09d250ab9872 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -57,7 +57,7 @@ ACPI_MODULE_NAME("rsxface") ACPI_COPY_FIELD(out, in, decode); \ ACPI_COPY_FIELD(out, in, min_address_fixed); \ ACPI_COPY_FIELD(out, in, max_address_fixed); \ - ACPI_COPY_FIELD(out, in, attribute); \ + ACPI_COPY_FIELD(out, in, info); \ ACPI_COPY_FIELD(out, in, granularity); \ ACPI_COPY_FIELD(out, in, minimum); \ ACPI_COPY_FIELD(out, in, maximum); \ diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 4b2fbb592f49..e6dfe688b76b 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -94,9 +94,8 @@ acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) new_table_desc->pointer->length) && (!ACPI_MEMCMP - ((const char *)table_desc->pointer, - (const char *)new_table_desc->pointer, - (acpi_size) new_table_desc->pointer->length))) { + (table_desc->pointer, new_table_desc->pointer, + new_table_desc->pointer->length))) { /* Match: this table is already installed */ ACPI_DEBUG_PRINT((ACPI_DB_TABLES, diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index dc7f24b3a1c0..e04b6119a4d7 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c @@ -866,7 +866,7 @@ void acpi_ut_dump_allocations(u32 component, char *module) if (!num_outstanding) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No outstanding allocations.\n")); + "No outstanding allocations\n")); } else { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "%d(%X) Outstanding allocations\n", diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 7f72839841ca..413e1dd8ae36 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -217,23 +217,23 @@ const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = { * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to * perform a Notify() operation on it. */ -const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = - { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, -{"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, -{"_SB_", ACPI_TYPE_DEVICE, NULL}, -{"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, -{"_TZ_", ACPI_TYPE_THERMAL, NULL}, -{"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, -{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, -{"_GL_", ACPI_TYPE_MUTEX, (char *)1}, +const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { + {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_SB_", ACPI_TYPE_DEVICE, NULL}, + {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_TZ_", ACPI_TYPE_THERMAL, NULL}, + {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, + {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, + {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) -{"_OSI", ACPI_TYPE_METHOD, (char *)1}, + {"_OSI", ACPI_TYPE_METHOD, (char *)1}, #endif /* Table terminator */ -{NULL, ACPI_TYPE_ANY, NULL} + {NULL, ACPI_TYPE_ANY, NULL} }; /* @@ -503,11 +503,13 @@ char *acpi_ut_get_region_name(u8 space_id) /* Event type decoding */ static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = { +/*! [Begin] no source code translation (keep these strings as-is) */ "PM_Timer", - "global_lock", - "power_button", - "sleep_button", - "real_time_clock", + "GlobalLock", + "PowerButton", + "SleepButton", + "RealTimeClock", +/*! [End] no source code translation !*/ }; char *acpi_ut_get_event_name(u32 event_id) @@ -545,12 +547,13 @@ static const char acpi_gbl_bad_type[] = "UNDEFINED"; /* Printable names of the ACPI object types */ static const char *acpi_gbl_ns_type_names[] = { +/*! [Begin] no source code translation (keep these strings as-is) */ /* 00 */ "Untyped", /* 01 */ "Integer", /* 02 */ "String", /* 03 */ "Buffer", /* 04 */ "Package", - /* 05 */ "field_unit", + /* 05 */ "FieldUnit", /* 06 */ "Device", /* 07 */ "Event", /* 08 */ "Method", @@ -559,23 +562,24 @@ static const char *acpi_gbl_ns_type_names[] = { /* 11 */ "Power", /* 12 */ "Processor", /* 13 */ "Thermal", - /* 14 */ "buffer_field", - /* 15 */ "ddb_handle", - /* 16 */ "debug_object", - /* 17 */ "region_field", - /* 18 */ "bank_field", - /* 19 */ "index_field", + /* 14 */ "BufferField", + /* 15 */ "DdbHandle", + /* 16 */ "DebugObject", + /* 17 */ "RegionField", + /* 18 */ "BankField", + /* 19 */ "IndexField", /* 20 */ "Reference", /* 21 */ "Alias", - /* 22 */ "method_alias", + /* 22 */ "MethodAlias", /* 23 */ "Notify", - /* 24 */ "addr_handler", - /* 25 */ "resource_desc", - /* 26 */ "resource_fld", + /* 24 */ "AddrHandler", + /* 25 */ "ResourceDesc", + /* 26 */ "ResourceFld", /* 27 */ "Scope", /* 28 */ "Extra", /* 29 */ "Data", /* 30 */ "Invalid" +/*! [End] no source code translation !*/ }; char *acpi_ut_get_type_name(acpi_object_type type) @@ -658,15 +662,16 @@ char *acpi_ut_get_node_name(void *object) /* Printable names of object descriptor types */ static const char *acpi_gbl_desc_type_names[] = { +/*! [Begin] no source code translation (keep these ASL Keywords as-is) */ /* 00 */ "Invalid", /* 01 */ "Cached", /* 02 */ "State-Generic", /* 03 */ "State-Update", /* 04 */ "State-Package", /* 05 */ "State-Control", - /* 06 */ "State-root_parse_scope", - /* 07 */ "State-parse_scope", - /* 08 */ "State-walk_scope", + /* 06 */ "State-RootParseScope", + /* 07 */ "State-ParseScope", + /* 08 */ "State-WalkScope", /* 09 */ "State-Result", /* 10 */ "State-Notify", /* 11 */ "State-Thread", @@ -674,6 +679,7 @@ static const char *acpi_gbl_desc_type_names[] = { /* 13 */ "Parser", /* 14 */ "Operand", /* 15 */ "Node" +/*! [End] no source code translation !*/ }; char *acpi_ut_get_descriptor_name(void *object) diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index b57afa7421e8..e9058d4da122 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -43,6 +43,7 @@ #include #include +#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") @@ -788,6 +789,113 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) return ((u8) (0 - sum)); } +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_type + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: The Resource Type with no extraneous bits (except the + * Large/Small descriptor bit -- this is left alone) + * + * DESCRIPTION: Extract the Resource Type/Name from the first byte of + * a resource descriptor. + * + ******************************************************************************/ + +u8 acpi_ut_get_resource_type(void *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* + * Byte 0 contains the descriptor name (Resource Type) + * Determine if this is a small or large resource + */ + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ + + return (*((u8 *) aml)); + } else { + /* Small Resource Type -- bits 6:3 contain the name */ + + return ((u8) (*((u8 *) aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Byte Length + * + * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By + * definition, this does not include the size of the descriptor + * header or the length field itself. + * + ******************************************************************************/ + +u16 acpi_ut_get_resource_length(void *aml) +{ + u16 resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* + * Byte 0 contains the descriptor name (Resource Type) + * Determine if this is a small or large resource + */ + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource type -- bytes 1-2 contain the 16-bit length */ + + ACPI_MOVE_16_TO_16(&resource_length, &((u8 *) aml)[1]); + + } else { + /* Small Resource type -- bits 2:0 of byte 0 contain the length */ + + resource_length = (u16) (*((u8 *) aml) & + ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); + } + + return (resource_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_descriptor_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Byte length + * + * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the + * length of the descriptor header and the length field itself. + * Used to walk descriptor lists. + * + ******************************************************************************/ + +u32 acpi_ut_get_descriptor_length(void *aml) +{ + u32 descriptor_length; + + ACPI_FUNCTION_ENTRY(); + + /* First get the Resource Length (Does not include header length) */ + + descriptor_length = acpi_ut_get_resource_length(aml); + + /* Determine if this is a small or large resource */ + + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + descriptor_length += sizeof(struct aml_resource_large_header); + } else { + descriptor_length += sizeof(struct aml_resource_small_header); + } + + return (descriptor_length); +} + /******************************************************************************* * * FUNCTION: acpi_ut_get_resource_end_tag @@ -796,42 +904,34 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) * * RETURN: Pointer to the end tag * - * DESCRIPTION: Find the END_TAG resource descriptor in a resource template + * DESCRIPTION: Find the END_TAG resource descriptor in an AML resource template * ******************************************************************************/ u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc) { - u8 buffer_byte; - u8 *buffer; - u8 *end_buffer; + u8 *aml; + u8 *end_aml; - buffer = obj_desc->buffer.pointer; - end_buffer = buffer + obj_desc->buffer.length; + aml = obj_desc->buffer.pointer; + end_aml = aml + obj_desc->buffer.length; - while (buffer < end_buffer) { - buffer_byte = *buffer; - if (buffer_byte & ACPI_RESOURCE_NAME_LARGE) { - /* Large Descriptor - Length is next 2 bytes */ + /* Walk the resource template, one descriptor per loop */ - buffer += ((*(buffer + 1) | (*(buffer + 2) << 8)) + 3); - } else { - /* Small Descriptor. End Tag will be found here */ + while (aml < end_aml) { + if (acpi_ut_get_resource_type(aml) == + ACPI_RESOURCE_NAME_END_TAG) { + /* Found the end_tag descriptor, all done */ - if ((buffer_byte & ACPI_RESOURCE_NAME_SMALL_MASK) == - ACPI_RESOURCE_NAME_END_TAG) { - /* Found the end tag descriptor, all done. */ - - return (buffer); - } - - /* Length is in the header */ - - buffer += ((buffer_byte & 0x07) + 1); + return (aml); } + + /* Point to the next resource descriptor */ + + aml += acpi_ut_get_resource_length(aml); } - /* End tag not found */ + /* End tag was not found */ return (NULL); } diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index f4adebde6155..b8b46ab54f4e 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -401,7 +401,7 @@ pnpacpi_parse_mem24_option(struct pnp_option *option, mem->align = p->alignment; mem->size = p->address_length; - mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ? + mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? IORESOURCE_MEM_WRITEABLE : 0; pnp_register_mem_resource(option,mem); @@ -424,7 +424,7 @@ pnpacpi_parse_mem32_option(struct pnp_option *option, mem->align = p->alignment; mem->size = p->address_length; - mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ? + mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? IORESOURCE_MEM_WRITEABLE : 0; pnp_register_mem_resource(option,mem); @@ -446,7 +446,7 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, mem->size = p->address_length; mem->align = 0; - mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ? + mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? IORESOURCE_MEM_WRITEABLE : 0; pnp_register_mem_resource(option,mem); @@ -734,7 +734,7 @@ static void pnpacpi_encode_mem24(struct acpi_resource *resource, resource->type = ACPI_RESOURCE_TYPE_MEMORY24; resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ - resource->data.memory24.read_write_attribute = + resource->data.memory24.write_protect = (p->flags & IORESOURCE_MEM_WRITEABLE) ? ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; resource->data.memory24.minimum = p->start; @@ -748,7 +748,7 @@ static void pnpacpi_encode_mem32(struct acpi_resource *resource, { resource->type = ACPI_RESOURCE_TYPE_MEMORY32; resource->length = sizeof(struct acpi_resource); - resource->data.memory32.read_write_attribute = + resource->data.memory32.write_protect = (p->flags & IORESOURCE_MEM_WRITEABLE) ? ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; resource->data.memory32.minimum = p->start; @@ -762,7 +762,7 @@ static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource, { resource->type = ACPI_RESOURCE_TYPE_FIXED_MEMORY32; resource->length = sizeof(struct acpi_resource); - resource->data.fixed_memory32.read_write_attribute = + resource->data.fixed_memory32.write_protect = (p->flags & IORESOURCE_MEM_WRITEABLE) ? ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; resource->data.fixed_memory32.address = p->start; diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index cb59b018c84c..7676afec09a2 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20050930 +#define ACPI_CA_VERSION 0x20051021 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index b2921b869bb4..99250ee1b9d1 100644 --- a/include/acpi/acdisasm.h +++ b/include/acpi/acdisasm.h @@ -60,6 +60,7 @@ extern struct acpi_external_list *acpi_gbl_external_list; extern const char *acpi_gbl_io_decode[2]; extern const char *acpi_gbl_word_decode[4]; extern const char *acpi_gbl_consume_decode[2]; +extern const char *acpi_gbl_config_decode[4]; extern const char *acpi_gbl_min_decode[2]; extern const char *acpi_gbl_max_decode[2]; extern const char *acpi_gbl_DECdecode[2]; @@ -171,11 +172,19 @@ u8 acpi_dm_is_string_buffer(union acpi_parse_object *op); /* * dmresrc */ -void -acpi_dm_resource_descriptor(struct acpi_op_walk_info *info, - u8 * byte_data, u32 byte_count); +void acpi_dm_dump_integer8(u8 value, char *name); -u8 acpi_dm_is_resource_descriptor(union acpi_parse_object *op); +void acpi_dm_dump_integer16(u16 value, char *name); + +void acpi_dm_dump_integer32(u32 value, char *name); + +void acpi_dm_dump_integer64(u64 value, char *name); + +void +acpi_dm_resource_template(struct acpi_op_walk_info *info, + u8 * byte_data, u32 byte_count); + +u8 acpi_dm_is_resource_template(union acpi_parse_object *op); void acpi_dm_indent(u32 level); @@ -223,6 +232,8 @@ void acpi_dm_vendor_large_descriptor(union aml_resource *resource, u32 length, u32 level); +void acpi_dm_vendor_common(char *name, u8 * byte_data, u32 length, u32 level); + /* * dmresrcs */ diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 258cfe5e2aac..e42222c3d34c 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -202,7 +202,7 @@ #define ACPI_BUFFER_INDEX(buf_len,buf_offset,byte_gran) (buf_offset) -#ifdef ACPI_MISALIGNED_TRANSFERS +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED /* The hardware supports unaligned transfers, just do the little-endian move */ @@ -563,11 +563,11 @@ return (_s); }) #define return_UINT8(s) ACPI_DO_WHILE0 ({ \ register u8 _s = (u8) (s); \ - acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \ return (_s); }) #define return_UINT32(s) ACPI_DO_WHILE0 ({ \ register u32 _s = (u32) (s); \ - acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \ + acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \ return (_s); }) #else /* Use original less-safe macros */ diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 98e0b8cd14ed..58473f60755f 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -108,9 +108,9 @@ acpi_status acpi_os_create_lock(acpi_handle * out_handle); void acpi_os_delete_lock(acpi_handle handle); -unsigned long acpi_os_acquire_lock(acpi_handle handle); +acpi_native_uint acpi_os_acquire_lock(acpi_handle handle); -void acpi_os_release_lock(acpi_handle handle, unsigned long flags); +void acpi_os_release_lock(acpi_handle handle, acpi_native_uint flags); /* * Memory allocation and mapping diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h index b66994e9e4ee..25cff0d5ba58 100644 --- a/include/acpi/acresrc.h +++ b/include/acpi/acresrc.h @@ -48,49 +48,133 @@ #include "amlresrc.h" +/* + * If possible, pack the following structures to byte alignment, since we + * don't care about performance for debug output + */ +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED +#pragma pack(1) +#endif + +/* + * Individual entry for the resource conversion tables + */ +typedef const struct acpi_rsconvert_info { + u8 opcode; + u8 resource_offset; + u8 aml_offset; + u8 value; + +} acpi_rsconvert_info; + +/* Resource conversion opcodes */ + +#define ACPI_RSC_INITGET 0 +#define ACPI_RSC_INITSET 1 +#define ACPI_RSC_FLAGINIT 2 +#define ACPI_RSC_1BITFLAG 3 +#define ACPI_RSC_2BITFLAG 4 +#define ACPI_RSC_COUNT 5 +#define ACPI_RSC_COUNT16 6 +#define ACPI_RSC_LENGTH 7 +#define ACPI_RSC_MOVE8 8 +#define ACPI_RSC_MOVE16 9 +#define ACPI_RSC_MOVE32 10 +#define ACPI_RSC_MOVE64 11 +#define ACPI_RSC_SET8 12 +#define ACPI_RSC_DATA8 13 +#define ACPI_RSC_ADDRESS 14 +#define ACPI_RSC_SOURCE 15 +#define ACPI_RSC_SOURCEX 16 +#define ACPI_RSC_BITMASK 17 +#define ACPI_RSC_BITMASK16 18 +#define ACPI_RSC_EXIT_NE 19 +#define ACPI_RSC_EXIT_LE 20 + +/* Resource Conversion sub-opcodes */ + +#define ACPI_RSC_COMPARE_AML_LENGTH 0 +#define ACPI_RSC_COMPARE_VALUE 1 + +#define ACPI_RSC_TABLE_SIZE(d) (sizeof (d) / sizeof (struct acpi_rsconvert_info)) + +#define ACPI_RS_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_resource,f) +#define AML_OFFSET(f) (u8) ACPI_OFFSET (union aml_resource,f) + /* * Resource dispatch and info tables */ -struct acpi_resource_info { +typedef const struct acpi_resource_info { u8 length_type; u8 minimum_aml_resource_length; u8 minimum_internal_struct_length; -}; + +} acpi_resource_info; /* Types for length_type above */ -#define ACPI_FIXED_LENGTH 0 -#define ACPI_VARIABLE_LENGTH 1 -#define ACPI_SMALL_VARIABLE_LENGTH 2 +#define ACPI_FIXED_LENGTH 0 +#define ACPI_VARIABLE_LENGTH 1 +#define ACPI_SMALL_VARIABLE_LENGTH 2 -/* Handlers */ +typedef const struct acpi_rsdump_info { + u8 opcode; + u8 offset; + char *name; + const void *pointer; -typedef acpi_status(*ACPI_SET_RESOURCE_HANDLER) (struct acpi_resource * - resource, - union aml_resource * aml); +} acpi_rsdump_info; -typedef acpi_status(*ACPI_GET_RESOURCE_HANDLER) (union aml_resource * aml, - u16 aml_resource_length, - struct acpi_resource * - resource); +/* Values for the Opcode field above */ -typedef void (*ACPI_DUMP_RESOURCE_HANDLER) (union acpi_resource_data * data); +#define ACPI_RSD_TITLE 0 +#define ACPI_RSD_LITERAL 1 +#define ACPI_RSD_STRING 2 +#define ACPI_RSD_UINT8 3 +#define ACPI_RSD_UINT16 4 +#define ACPI_RSD_UINT32 5 +#define ACPI_RSD_UINT64 6 +#define ACPI_RSD_1BITFLAG 7 +#define ACPI_RSD_2BITFLAG 8 +#define ACPI_RSD_SHORTLIST 9 +#define ACPI_RSD_LONGLIST 10 +#define ACPI_RSD_DWORDLIST 11 +#define ACPI_RSD_ADDRESS 12 +#define ACPI_RSD_SOURCE 13 -/* Tables indexed by internal resource type */ +/* restore default alignment */ -extern u8 acpi_gbl_aml_resource_sizes[]; -extern ACPI_SET_RESOURCE_HANDLER acpi_gbl_set_resource_dispatch[]; -extern ACPI_DUMP_RESOURCE_HANDLER acpi_gbl_dump_resource_dispatch[]; +#pragma pack() -/* Tables indexed by raw AML resource descriptor type */ +/* Resource tables indexed by internal resource type */ + +extern const u8 acpi_gbl_aml_resource_sizes[]; +extern struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[]; + +/* Resource tables indexed by raw AML resource descriptor type */ extern struct acpi_resource_info acpi_gbl_sm_resource_info[]; extern struct acpi_resource_info acpi_gbl_lg_resource_info[]; -extern ACPI_GET_RESOURCE_HANDLER acpi_gbl_sm_get_resource_dispatch[]; -extern ACPI_GET_RESOURCE_HANDLER acpi_gbl_lg_get_resource_dispatch[]; +extern struct acpi_rsconvert_info *acpi_gbl_sm_get_resource_dispatch[]; +extern struct acpi_rsconvert_info *acpi_gbl_lg_get_resource_dispatch[]; /* - * Function prototypes called from Acpi* APIs + * rscreate + */ +acpi_status +acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, + struct acpi_buffer *output_buffer); + +acpi_status +acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, + struct acpi_buffer *output_buffer); + +acpi_status +acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, + struct acpi_buffer *output_buffer); + +/* + * rsutils */ acpi_status acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer); @@ -110,27 +194,6 @@ acpi_rs_get_method_data(acpi_handle handle, acpi_status acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer); -acpi_status -acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, - struct acpi_buffer *output_buffer); - -acpi_status -acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, - struct acpi_buffer *output_buffer); - -acpi_status -acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, - struct acpi_buffer *output_buffer); - -/* - * rsdump - */ -#ifdef ACPI_FUTURE_USAGE -void acpi_rs_dump_resource_list(struct acpi_resource *resource); - -void acpi_rs_dump_irq_list(u8 * route_table); -#endif /* ACPI_FUTURE_USAGE */ - /* * rscalc */ @@ -154,145 +217,29 @@ acpi_status acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, acpi_size aml_size_needed, u8 * output_buffer); -/* - * rsio - */ -acpi_status -acpi_rs_get_io(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_io(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_fixed_io(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_fixed_io(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_dma(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_dma(struct acpi_resource *resource, union aml_resource *aml); - -/* - * rsirq - */ -acpi_status -acpi_rs_get_irq(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_irq(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_ext_irq(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_ext_irq(struct acpi_resource *resource, union aml_resource *aml); - /* * rsaddr */ -acpi_status -acpi_rs_get_address16(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_address16(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_address32(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_address32(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_address64(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_address64(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_ext_address64(union aml_resource *aml, - u16 aml_resource_length, - struct acpi_resource *resource); - -acpi_status -acpi_rs_set_ext_address64(struct acpi_resource *resource, - union aml_resource *aml); - -/* - * rsmemory - */ -acpi_status -acpi_rs_get_memory24(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_memory24(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_memory32(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_memory32(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_fixed_memory32(union aml_resource *aml, - u16 aml_resource_length, +void +acpi_rs_set_address_common(union aml_resource *aml, struct acpi_resource *resource); -acpi_status -acpi_rs_set_fixed_memory32(struct acpi_resource *resource, +u8 +acpi_rs_get_address_common(struct acpi_resource *resource, union aml_resource *aml); /* * rsmisc */ acpi_status -acpi_rs_get_generic_reg(union aml_resource *aml, - u16 aml_resource_length, - struct acpi_resource *resource); +acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, + union aml_resource *aml, + struct acpi_rsconvert_info *info); acpi_status -acpi_rs_set_generic_reg(struct acpi_resource *resource, - union aml_resource *aml); - -acpi_status -acpi_rs_get_vendor(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_vendor(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_start_dpf(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_start_dpf(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_end_dpf(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_end_dpf(struct acpi_resource *resource, union aml_resource *aml); - -acpi_status -acpi_rs_get_end_tag(union aml_resource *aml, - u16 aml_resource_length, struct acpi_resource *resource); - -acpi_status -acpi_rs_set_end_tag(struct acpi_resource *resource, union aml_resource *aml); +acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, + union aml_resource *aml, + struct acpi_rsconvert_info *info); /* * rsutils @@ -301,74 +248,94 @@ void acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type); -/* Types used in move_type above */ +u8 acpi_rs_decode_bitmask(u16 mask, u8 * list); -#define ACPI_MOVE_TYPE_16_TO_32 0 -#define ACPI_MOVE_TYPE_32_TO_16 1 -#define ACPI_MOVE_TYPE_32_TO_32 2 -#define ACPI_MOVE_TYPE_64_TO_64 3 +u16 acpi_rs_encode_bitmask(u8 * list, u8 count); -u16 -acpi_rs_get_resource_source(u16 resource_length, - acpi_size minimum_length, +acpi_rs_length +acpi_rs_get_resource_source(acpi_rs_length resource_length, + acpi_rs_length minimum_length, struct acpi_resource_source *resource_source, union aml_resource *aml, char *string_ptr); -acpi_size +acpi_rsdesc_size acpi_rs_set_resource_source(union aml_resource *aml, - acpi_size minimum_length, + acpi_rs_length minimum_length, struct acpi_resource_source *resource_source); -u8 acpi_rs_get_resource_type(u8 resource_start_byte); - -u32 acpi_rs_get_descriptor_length(union aml_resource *aml); - -u16 acpi_rs_get_resource_length(union aml_resource *aml); - void acpi_rs_set_resource_header(u8 descriptor_type, - acpi_size total_length, union aml_resource *aml); + acpi_rsdesc_size total_length, + union aml_resource *aml); + +void +acpi_rs_set_resource_length(acpi_rsdesc_size total_length, + union aml_resource *aml); struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type); -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /* * rsdump */ -void acpi_rs_dump_irq(union acpi_resource_data *resource); +void acpi_rs_dump_resource_list(struct acpi_resource *resource); -void acpi_rs_dump_address16(union acpi_resource_data *resource); +void acpi_rs_dump_irq_list(u8 * route_table); -void acpi_rs_dump_address32(union acpi_resource_data *resource); +/* + * Resource conversion tables + */ +extern struct acpi_rsconvert_info acpi_rs_convert_dma[]; +extern struct acpi_rsconvert_info acpi_rs_convert_end_dpf[]; +extern struct acpi_rsconvert_info acpi_rs_convert_io[]; +extern struct acpi_rsconvert_info acpi_rs_convert_fixed_io[]; +extern struct acpi_rsconvert_info acpi_rs_convert_end_tag[]; +extern struct acpi_rsconvert_info acpi_rs_convert_memory24[]; +extern struct acpi_rsconvert_info acpi_rs_convert_generic_reg[]; +extern struct acpi_rsconvert_info acpi_rs_convert_memory32[]; +extern struct acpi_rsconvert_info acpi_rs_convert_fixed_memory32[]; +extern struct acpi_rsconvert_info acpi_rs_convert_address32[]; +extern struct acpi_rsconvert_info acpi_rs_convert_address16[]; +extern struct acpi_rsconvert_info acpi_rs_convert_ext_irq[]; +extern struct acpi_rsconvert_info acpi_rs_convert_address64[]; +extern struct acpi_rsconvert_info acpi_rs_convert_ext_address64[]; -void acpi_rs_dump_address64(union acpi_resource_data *resource); +/* These resources require separate get/set tables */ -void acpi_rs_dump_ext_address64(union acpi_resource_data *resource); +extern struct acpi_rsconvert_info acpi_rs_get_irq[]; +extern struct acpi_rsconvert_info acpi_rs_get_start_dpf[]; +extern struct acpi_rsconvert_info acpi_rs_get_vendor_small[]; +extern struct acpi_rsconvert_info acpi_rs_get_vendor_large[]; -void acpi_rs_dump_dma(union acpi_resource_data *resource); +extern struct acpi_rsconvert_info acpi_rs_set_irq[]; +extern struct acpi_rsconvert_info acpi_rs_set_start_dpf[]; +extern struct acpi_rsconvert_info acpi_rs_set_vendor[]; -void acpi_rs_dump_io(union acpi_resource_data *resource); - -void acpi_rs_dump_ext_irq(union acpi_resource_data *resource); - -void acpi_rs_dump_fixed_io(union acpi_resource_data *resource); - -void acpi_rs_dump_fixed_memory32(union acpi_resource_data *resource); - -void acpi_rs_dump_memory24(union acpi_resource_data *resource); - -void acpi_rs_dump_memory32(union acpi_resource_data *resource); - -void acpi_rs_dump_start_dpf(union acpi_resource_data *resource); - -void acpi_rs_dump_vendor(union acpi_resource_data *resource); - -void acpi_rs_dump_generic_reg(union acpi_resource_data *resource); - -void acpi_rs_dump_end_dpf(union acpi_resource_data *resource); - -void acpi_rs_dump_end_tag(union acpi_resource_data *resource); +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +/* + * rsinfo + */ +extern struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[]; +/* + * rsdump + */ +extern struct acpi_rsdump_info acpi_rs_dump_irq[]; +extern struct acpi_rsdump_info acpi_rs_dump_dma[]; +extern struct acpi_rsdump_info acpi_rs_dump_start_dpf[]; +extern struct acpi_rsdump_info acpi_rs_dump_end_dpf[]; +extern struct acpi_rsdump_info acpi_rs_dump_io[]; +extern struct acpi_rsdump_info acpi_rs_dump_fixed_io[]; +extern struct acpi_rsdump_info acpi_rs_dump_vendor[]; +extern struct acpi_rsdump_info acpi_rs_dump_end_tag[]; +extern struct acpi_rsdump_info acpi_rs_dump_memory24[]; +extern struct acpi_rsdump_info acpi_rs_dump_memory32[]; +extern struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[]; +extern struct acpi_rsdump_info acpi_rs_dump_address16[]; +extern struct acpi_rsdump_info acpi_rs_dump_address32[]; +extern struct acpi_rsdump_info acpi_rs_dump_address64[]; +extern struct acpi_rsdump_info acpi_rs_dump_ext_address64[]; +extern struct acpi_rsdump_info acpi_rs_dump_ext_irq[]; +extern struct acpi_rsdump_info acpi_rs_dump_generic_reg[]; #endif #endif /* __ACRESRC_H__ */ diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 43f7c509317a..29b887017b18 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -83,10 +83,11 @@ typedef COMPILER_DEPENDENT_UINT64 u64; * UINT32 32-bit (4 byte) unsigned value * INT64 64-bit (8 byte) signed value * UINT64 64-bit (8 byte) unsigned value - * ACPI_NATIVE_INT 32-bit on IA-32, 64-bit on IA-64 signed value - * ACPI_NATIVE_UINT 32-bit on IA-32, 64-bit on IA-64 unsigned value + * ACPI_NATIVE_UINT 32-bit on IA-32, 64-bit on x86_64/IA-64 unsigned value */ +typedef unsigned long acpi_native_uint; + #ifndef ACPI_MACHINE_WIDTH #error ACPI_MACHINE_WIDTH not defined #endif @@ -108,9 +109,6 @@ typedef COMPILER_DEPENDENT_UINT64 UINT64; /*! [End] no source code translation !*/ -typedef s64 acpi_native_int; -typedef u64 acpi_native_uint; - typedef u64 acpi_table_ptr; typedef u64 acpi_io_address; typedef u64 acpi_physical_address; @@ -121,9 +119,22 @@ typedef u64 acpi_size; #define ACPI_MAX_PTR ACPI_UINT64_MAX #define ACPI_SIZE_MAX ACPI_UINT64_MAX +/* + * In the case of the Itanium Processor Family (IPF), the hardware does not + * support misaligned memory transfers. Set the MISALIGNMENT_NOT_SUPPORTED flag + * to indicate that special precautions must be taken to avoid alignment faults. + * (IA64 or ia64 is currently used by existing compilers to indicate IPF.) + * + * Note: Em64_t and other X86-64 processors do support misaligned transfers, + * so there is no need to define this flag. + */ +#if defined (__IA64__) || defined (__ia64__) +#define ACPI_MISALIGNMENT_NOT_SUPPORTED +#endif + #elif ACPI_MACHINE_WIDTH == 16 -/*! [Begin] no source code translation (keep the typedefs) */ +/*! [Begin] no source code translation (keep the typedefs as-is) */ /* * 16-bit type definitions @@ -142,16 +153,12 @@ struct { /*! [End] no source code translation !*/ -typedef u16 acpi_native_uint; -typedef s16 acpi_native_int; - typedef u32 acpi_table_ptr; typedef u32 acpi_io_address; typedef char *acpi_physical_address; typedef u16 acpi_size; #define ALIGNED_ADDRESS_BOUNDARY 0x00000002 -#define ACPI_MISALIGNED_TRANSFERS #define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */ #define ACPI_MAX_PTR ACPI_UINT16_MAX #define ACPI_SIZE_MAX ACPI_UINT16_MAX @@ -179,16 +186,12 @@ typedef COMPILER_DEPENDENT_UINT64 UINT64; /*! [End] no source code translation !*/ -typedef s32 acpi_native_int; -typedef u32 acpi_native_uint; - typedef u64 acpi_table_ptr; typedef u32 acpi_io_address; typedef u64 acpi_physical_address; typedef u32 acpi_size; #define ALIGNED_ADDRESS_BOUNDARY 0x00000004 -#define ACPI_MISALIGNED_TRANSFERS #define ACPI_MAX_PTR ACPI_UINT32_MAX #define ACPI_SIZE_MAX ACPI_UINT32_MAX @@ -895,6 +898,8 @@ struct acpi_mem_space_context { /* * Definitions for Resource Attributes */ +typedef u16 acpi_rs_length; /* Resource Length field is fixed at 16 bits */ +typedef u32 acpi_rsdesc_size; /* Max Resource Descriptor size is (length+3) = (64_k-1)+3 */ /* * Memory Attributes @@ -927,8 +932,8 @@ struct acpi_mem_space_context { /* * IRQ Attributes */ -#define ACPI_EDGE_SENSITIVE (u8) 0x00 -#define ACPI_LEVEL_SENSITIVE (u8) 0x01 +#define ACPI_LEVEL_SENSITIVE (u8) 0x00 +#define ACPI_EDGE_SENSITIVE (u8) 0x01 #define ACPI_ACTIVE_HIGH (u8) 0x00 #define ACPI_ACTIVE_LOW (u8) 0x01 @@ -974,28 +979,35 @@ struct acpi_mem_space_context { #define ACPI_PRODUCER (u8) 0x00 #define ACPI_CONSUMER (u8) 0x01 +/* + * If possible, pack the following structures to byte alignment + */ +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED +#pragma pack(1) +#endif + /* * Structures used to describe device resources */ struct acpi_resource_irq { - u32 triggering; - u32 polarity; - u32 sharable; - u32 interrupt_count; - u32 interrupts[1]; + u8 triggering; + u8 polarity; + u8 sharable; + u8 interrupt_count; + u8 interrupts[1]; }; struct acpi_resource_dma { - u32 type; - u32 bus_master; - u32 transfer; - u32 channel_count; - u32 channels[1]; + u8 type; + u8 bus_master; + u8 transfer; + u8 channel_count; + u8 channels[1]; }; struct acpi_resource_start_dependent { - u32 compatibility_priority; - u32 performance_robustness; + u8 compatibility_priority; + u8 performance_robustness; }; /* @@ -1004,20 +1016,20 @@ struct acpi_resource_start_dependent { */ struct acpi_resource_io { - u32 io_decode; - u32 minimum; - u32 maximum; - u32 alignment; - u32 address_length; + u8 io_decode; + u8 alignment; + u8 address_length; + u16 minimum; + u16 maximum; }; struct acpi_resource_fixed_io { - u32 address; - u32 address_length; + u16 address; + u8 address_length; }; struct acpi_resource_vendor { - u32 byte_length; + u16 byte_length; u8 byte_data[1]; }; @@ -1026,15 +1038,15 @@ struct acpi_resource_end_tag { }; struct acpi_resource_memory24 { - u32 read_write_attribute; - u32 minimum; - u32 maximum; - u32 alignment; - u32 address_length; + u8 write_protect; + u16 minimum; + u16 maximum; + u16 alignment; + u16 address_length; }; struct acpi_resource_memory32 { - u32 read_write_attribute; + u8 write_protect; u32 minimum; u32 maximum; u32 alignment; @@ -1042,57 +1054,59 @@ struct acpi_resource_memory32 { }; struct acpi_resource_fixed_memory32 { - u32 read_write_attribute; + u8 write_protect; u32 address; u32 address_length; }; struct acpi_memory_attribute { - u16 cache_attribute; - u16 read_write_attribute; + u8 write_protect; + u8 caching; + u8 range_type; + u8 translation; }; struct acpi_io_attribute { - u16 range_attribute; - u16 translation_attribute; -}; - -struct acpi_bus_attribute { - u16 reserved1; - u16 reserved2; + u8 range_type; + u8 translation; + u8 translation_type; + u8 reserved1; }; union acpi_resource_attribute { - struct acpi_memory_attribute memory; + struct acpi_memory_attribute mem; struct acpi_io_attribute io; - struct acpi_bus_attribute bus; + + /* Used for the *word_space macros */ + + u8 type_specific; }; struct acpi_resource_source { - u32 index; - u32 string_length; + u8 index; + u16 string_length; char *string_ptr; }; /* Fields common to all address descriptors, 16/32/64 bit */ #define ACPI_RESOURCE_ADDRESS_COMMON \ - u32 resource_type; \ - u32 producer_consumer; \ - u32 decode; \ - u32 min_address_fixed; \ - u32 max_address_fixed; \ - union acpi_resource_attribute attribute; + u8 resource_type; \ + u8 producer_consumer; \ + u8 decode; \ + u8 min_address_fixed; \ + u8 max_address_fixed; \ + union acpi_resource_attribute info; struct acpi_resource_address { ACPI_RESOURCE_ADDRESS_COMMON}; struct acpi_resource_address16 { - ACPI_RESOURCE_ADDRESS_COMMON u32 granularity; - u32 minimum; - u32 maximum; - u32 translation_offset; - u32 address_length; + ACPI_RESOURCE_ADDRESS_COMMON u16 granularity; + u16 minimum; + u16 maximum; + u16 translation_offset; + u16 address_length; struct acpi_resource_source resource_source; }; @@ -1115,30 +1129,30 @@ struct acpi_resource_address64 { }; struct acpi_resource_extended_address64 { - ACPI_RESOURCE_ADDRESS_COMMON u64 granularity; + ACPI_RESOURCE_ADDRESS_COMMON u8 revision_iD; + u64 granularity; u64 minimum; u64 maximum; u64 translation_offset; u64 address_length; - u64 type_specific_attributes; - u8 revision_iD; + u64 type_specific; }; struct acpi_resource_extended_irq { - u32 producer_consumer; - u32 triggering; - u32 polarity; - u32 sharable; - u32 interrupt_count; + u8 producer_consumer; + u8 triggering; + u8 polarity; + u8 sharable; + u8 interrupt_count; struct acpi_resource_source resource_source; u32 interrupts[1]; }; struct acpi_resource_generic_register { - u32 space_id; - u32 bit_width; - u32 bit_offset; - u32 access_size; + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 access_size; u64 address; }; @@ -1192,14 +1206,17 @@ struct acpi_resource { union acpi_resource_data data; }; -#define ACPI_RESOURCE_LENGTH 12 -#define ACPI_RESOURCE_LENGTH_NO_DATA 8 /* Id + Length fields */ +/* restore default alignment */ -#define ACPI_SIZEOF_RESOURCE(type) (u32) (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type)) +#pragma pack() + +#define ACPI_RS_SIZE_MIN 12 +#define ACPI_RS_SIZE_NO_DATA 8 /* Id + Length fields */ +#define ACPI_RS_SIZE(type) (u32) (ACPI_RS_SIZE_NO_DATA + sizeof (type)) #define ACPI_NEXT_RESOURCE(res) (struct acpi_resource *)((u8 *) res + res->length) -#ifdef ACPI_MISALIGNED_TRANSFERS +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED #define ACPI_ALIGN_RESOURCE_SIZE(length) (length) #else #define ACPI_ALIGN_RESOURCE_SIZE(length) ACPI_ROUND_UP_TO_NATIVE_WORD(length) diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index c1086452696e..7386eb81bd2a 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -159,7 +159,6 @@ extern const u8 _acpi_ctype[]; #define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) #define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU)) #define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP)) -#define ACPI_IS_ASCII(c) ((c) < 0x80) #endif /* ACPI_USE_SYSTEM_CLIBRARY */ @@ -419,6 +418,12 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); #define ACPI_ANY_BASE 0 +u32 acpi_ut_get_descriptor_length(void *aml); + +u16 acpi_ut_get_resource_length(void *aml); + +u8 acpi_ut_get_resource_type(void *aml); + u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc); u8 acpi_ut_generate_checksum(u8 * buffer, u32 length); diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h index 103aff07db18..3112be527731 100644 --- a/include/acpi/amlresrc.h +++ b/include/acpi/amlresrc.h @@ -134,7 +134,7 @@ struct aml_resource_end_dependent { AML_RESOURCE_SMALL_HEADER_COMMON}; struct aml_resource_io { - AML_RESOURCE_SMALL_HEADER_COMMON u8 information; + AML_RESOURCE_SMALL_HEADER_COMMON u8 flags; u16 minimum; u16 maximum; u8 alignment; @@ -164,7 +164,7 @@ struct aml_resource_large_header { AML_RESOURCE_LARGE_HEADER_COMMON}; struct aml_resource_memory24 { - AML_RESOURCE_LARGE_HEADER_COMMON u8 information; + AML_RESOURCE_LARGE_HEADER_COMMON u8 flags; u16 minimum; u16 maximum; u16 alignment; @@ -175,7 +175,7 @@ struct aml_resource_vendor_large { AML_RESOURCE_LARGE_HEADER_COMMON}; struct aml_resource_memory32 { - AML_RESOURCE_LARGE_HEADER_COMMON u8 information; + AML_RESOURCE_LARGE_HEADER_COMMON u8 flags; u32 minimum; u32 maximum; u32 alignment; @@ -183,7 +183,7 @@ struct aml_resource_memory32 { }; struct aml_resource_fixed_memory32 { - AML_RESOURCE_LARGE_HEADER_COMMON u8 information; + AML_RESOURCE_LARGE_HEADER_COMMON u8 flags; u32 address; u32 address_length; }; @@ -205,7 +205,7 @@ struct aml_resource_extended_address64 { u64 maximum; u64 translation_offset; u64 address_length; - u64 type_specific_attributes; + u64 type_specific; }; #define AML_RESOURCE_EXTENDED_ADDRESS_REVISION 1 /* ACPI 3.0 */ @@ -239,8 +239,8 @@ struct aml_resource_address16 { struct aml_resource_extended_irq { AML_RESOURCE_LARGE_HEADER_COMMON u8 flags; - u8 table_length; - u32 interrupt_number[1]; + u8 interrupt_count; + u32 interrupts[1]; /* res_source_index, res_source optional fields follow */ }; diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 08539125696a..53aa997f05fc 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -206,6 +206,8 @@ * *****************************************************************************/ +#define ACPI_IS_ASCII(c) ((c) < 0x80) + #ifdef ACPI_USE_SYSTEM_CLIBRARY /* * Use the standard C library headers. @@ -235,7 +237,7 @@ #define ACPI_STRCAT(d,s) (void) strcat((d), (s)) #define ACPI_STRNCAT(d,s,n) strncat((d), (s), (acpi_size)(n)) #define ACPI_STRTOUL(d,s,n) strtoul((d), (s), (acpi_size)(n)) -#define ACPI_MEMCMP(s1,s2,n) memcmp((s1), (s2), (acpi_size)(n)) +#define ACPI_MEMCMP(s1,s2,n) memcmp((const char *)(s1), (const char *)(s2), (acpi_size)(n)) #define ACPI_MEMCPY(d,s,n) (void) memcpy((d), (s), (acpi_size)(n)) #define ACPI_MEMSET(d,s,n) (void) memset((d), (s), (acpi_size)(n)) @@ -247,7 +249,6 @@ #define ACPI_IS_UPPER(i) isupper((int) (i)) #define ACPI_IS_PRINT(i) isprint((int) (i)) #define ACPI_IS_ALPHA(i) isalpha((int) (i)) -#define ACPI_IS_ASCII(i) isascii((int) (i)) #else @@ -274,8 +275,8 @@ typedef char *va_list; /* * Storage alignment properties */ -#define _AUPBND (sizeof (acpi_native_int) - 1) -#define _ADNBND (sizeof (acpi_native_int) - 1) +#define _AUPBND (sizeof (acpi_native_uint) - 1) +#define _ADNBND (sizeof (acpi_native_uint) - 1) /* * Variable argument list macro definitions @@ -297,7 +298,7 @@ typedef char *va_list; #define ACPI_STRCAT(d,s) (void) acpi_ut_strcat ((d), (s)) #define ACPI_STRNCAT(d,s,n) acpi_ut_strncat ((d), (s), (acpi_size)(n)) #define ACPI_STRTOUL(d,s,n) acpi_ut_strtoul ((d), (s), (acpi_size)(n)) -#define ACPI_MEMCMP(s1,s2,n) acpi_ut_memcmp((s1), (s2), (acpi_size)(n)) +#define ACPI_MEMCMP(s1,s2,n) acpi_ut_memcmp((const char *)(s1), (const char *)(s2), (acpi_size)(n)) #define ACPI_MEMCPY(d,s,n) (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n)) #define ACPI_MEMSET(d,v,n) (void) acpi_ut_memset ((d), (v), (acpi_size)(n)) #define ACPI_TOUPPER acpi_ut_to_upper From 96db255c8f014ae3497507104e8df809785a619f Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 2 Nov 2005 00:00:00 -0500 Subject: [PATCH 016/695] [ACPI] ACPICA 20051102 Modified the subsystem initialization sequence to improve GPE support. The GPE initialization has been split into two parts in order to defer execution of the _PRW methods (Power Resources for Wake) until after the hardware is fully initialized and the SCI handler is installed. This allows the _PRW methods to access fields protected by the Global Lock. This will fix systems where a NO_GLOBAL_LOCK exception has been seen during initialization. Fixed a regression with the ConcatenateResTemplate() ASL operator introduced in the 20051021 release. Implemented support for "local" internal ACPI object types within the debugger "Object" command and the acpi_walk_namespace() external interfaces. These local types include RegionFields, BankFields, IndexFields, Alias, and reference objects. Moved common AML resource handling code into a new file, "utresrc.c". This code is shared by both the Resource Manager and the AML Debugger. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/events/evevent.c | 42 ++ drivers/acpi/events/evgpeblk.c | 159 ++++--- drivers/acpi/events/evxfevnt.c | 7 + drivers/acpi/executer/exdump.c | 660 ++++++++++++++++++------------ drivers/acpi/executer/exmisc.c | 49 ++- drivers/acpi/namespace/nsxfeval.c | 2 +- drivers/acpi/resources/rscalc.c | 251 +++++------- drivers/acpi/resources/rsdump.c | 70 ++-- drivers/acpi/resources/rsinfo.c | 99 ++--- drivers/acpi/resources/rslist.c | 195 ++------- drivers/acpi/resources/rsutils.c | 90 +--- drivers/acpi/utilities/Makefile | 5 +- drivers/acpi/utilities/utmisc.c | 148 ------- drivers/acpi/utilities/utresrc.c | 428 +++++++++++++++++++ drivers/acpi/utilities/utstate.c | 2 +- drivers/acpi/utilities/utxface.c | 52 ++- include/acpi/acconfig.h | 2 +- include/acpi/acevents.h | 6 + include/acpi/acinterp.h | 46 ++- include/acpi/acresrc.h | 27 +- include/acpi/acutils.h | 17 +- include/acpi/amlresrc.h | 5 + 22 files changed, 1372 insertions(+), 990 deletions(-) create mode 100644 drivers/acpi/utilities/utresrc.c diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index 842d1e3fb37b..9522c643b88b 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c @@ -98,6 +98,48 @@ acpi_status acpi_ev_initialize_events(void) return_ACPI_STATUS(status); } +/******************************************************************************* + * + * FUNCTION: acpi_ev_install_fadt_gpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks + * (0 and 1). This causes the _PRW methods to be run, so the HW + * must be fully initialized at this point, including global lock + * support. + * + ******************************************************************************/ + +acpi_status acpi_ev_install_fadt_gpes(void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE("ev_install_fadt_gpes"); + + /* Namespace must be locked */ + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* FADT GPE Block 0 */ + + (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, + acpi_gbl_gpe_fadt_blocks[0]); + + /* FADT GPE Block 1 */ + + (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, + acpi_gbl_gpe_fadt_blocks[1]); + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return_ACPI_STATUS(AE_OK); +} + /******************************************************************************* * * FUNCTION: acpi_ev_install_xrupt_handlers diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 7ca10c5f2914..8efca2eac27e 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c @@ -78,7 +78,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block); * * RETURN: TRUE if the gpe_event is valid * - * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. + * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. * Should be called only when the GPE lists are semaphore locked * and not subject to change. * @@ -264,7 +264,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle, * 2) Edge/Level determination is based on the 2nd character * of the method name * - * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE + * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE * if a _PRW object is found that points to this GPE. */ switch (name[1]) { @@ -313,14 +313,14 @@ acpi_ev_save_method_info(acpi_handle obj_handle, /* * Now we can add this information to the gpe_event_info block - * for use during dispatch of this GPE. Default type is RUNTIME, although + * for use during dispatch of this GPE. Default type is RUNTIME, although * this may change when the _PRW methods are executed later. */ gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; - gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD | - ACPI_GPE_TYPE_RUNTIME); + gpe_event_info->flags = (u8) + (type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME); gpe_event_info->dispatch.method_node = (struct acpi_namespace_node *)obj_handle; @@ -341,11 +341,11 @@ acpi_ev_save_method_info(acpi_handle obj_handle, * * PARAMETERS: Callback from walk_namespace * - * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is + * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is * not aborted on a single _PRW failure. * * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a - * Device. Run the _PRW method. If present, extract the GPE + * Device. Run the _PRW method. If present, extract the GPE * number and mark the GPE as a WAKE GPE. * ******************************************************************************/ @@ -443,6 +443,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, gpe_event_info->flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED); + status = acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE); if (ACPI_FAILURE(status)) { @@ -466,7 +467,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, * * RETURN: A GPE interrupt block * - * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt + * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt * block per unique interrupt level used for GPEs. * Should be called only when the GPE lists are semaphore locked * and not subject to change. @@ -566,8 +567,9 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) /* Disable this interrupt */ - status = acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number, - acpi_ev_gpe_xrupt_handler); + status = + acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number, + acpi_ev_gpe_xrupt_handler); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -750,7 +752,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) /* * Allocate the GPE event_info block. There are eight distinct GPEs - * per register. Initialization to zeros is sufficient. + * per register. Initialization to zeros is sufficient. */ gpe_event_info = ACPI_MEM_CALLOCATE(((acpi_size) gpe_block-> register_count * @@ -769,9 +771,9 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) gpe_block->event_info = gpe_event_info; /* - * Initialize the GPE Register and Event structures. A goal of these + * Initialize the GPE Register and Event structures. A goal of these * tables is to hide the fact that there are two separate GPE register sets - * in a given gpe hardware block, the status registers occupy the first half, + * in a given GPE hardware block, the status registers occupy the first half, * and the enable registers occupy the second half. */ this_register = gpe_register_info; @@ -812,11 +814,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) this_event++; } - /* - * Clear the status/enable registers. Note that status registers - * are cleared by writing a '1', while enable registers are cleared - * by writing a '0'. - */ + /* Disable all GPEs within this register */ + status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0x00, &this_register-> enable_address); @@ -824,6 +823,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) goto error_exit; } + /* Clear any pending GPE events within this register */ + status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0xFF, &this_register-> status_address); @@ -860,7 +861,9 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) * * RETURN: Status * - * DESCRIPTION: Create and Install a block of GPE registers + * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within + * the block are disabled at exit. + * Note: Assumes namespace is locked. * ******************************************************************************/ @@ -872,14 +875,8 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, u32 interrupt_number, struct acpi_gpe_block_info **return_gpe_block) { - struct acpi_gpe_block_info *gpe_block; - struct acpi_gpe_event_info *gpe_event_info; - acpi_native_uint i; - acpi_native_uint j; - u32 wake_gpe_count; - u32 gpe_enabled_count; acpi_status status; - struct acpi_gpe_walk_info gpe_info; + struct acpi_gpe_block_info *gpe_block; ACPI_FUNCTION_TRACE("ev_create_gpe_block"); @@ -896,22 +893,24 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, /* Initialize the new GPE block */ + gpe_block->node = gpe_device; gpe_block->register_count = register_count; gpe_block->block_base_number = gpe_block_base_number; - gpe_block->node = gpe_device; ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, sizeof(struct acpi_generic_address)); - /* Create the register_info and event_info sub-structures */ - + /* + * Create the register_info and event_info sub-structures + * Note: disables and clears all GPEs in the block + */ status = acpi_ev_create_gpe_info_blocks(gpe_block); if (ACPI_FAILURE(status)) { ACPI_MEM_FREE(gpe_block); return_ACPI_STATUS(status); } - /* Install the new block in the global list(s) */ + /* Install the new block in the global lists */ status = acpi_ev_install_gpe_block(gpe_block, interrupt_number); if (ACPI_FAILURE(status)) { @@ -926,16 +925,70 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, acpi_ev_save_method_info, gpe_block, NULL); + /* Return the new block */ + + if (return_gpe_block) { + (*return_gpe_block) = gpe_block; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INIT, + "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", + (u32) gpe_block->block_base_number, + (u32) (gpe_block->block_base_number + + ((gpe_block->register_count * + ACPI_GPE_REGISTER_WIDTH) - 1)), + gpe_device->name.ascii, gpe_block->register_count, + interrupt_number)); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ev_initialize_gpe_block + * + * PARAMETERS: gpe_device - Handle to the parent GPE block + * gpe_block - Gpe Block info + * + * RETURN: Status + * + * DESCRIPTION: Initialize and enable a GPE block. First find and run any + * _PRT methods associated with the block, then enable the + * appropriate GPEs. + * Note: Assumes namespace is locked. + * + ******************************************************************************/ + +acpi_status +acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, + struct acpi_gpe_block_info *gpe_block) +{ + acpi_status status; + struct acpi_gpe_event_info *gpe_event_info; + struct acpi_gpe_walk_info gpe_info; + u32 wake_gpe_count; + u32 gpe_enabled_count; + acpi_native_uint i; + acpi_native_uint j; + + ACPI_FUNCTION_TRACE("ev_initialize_gpe_block"); + + /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ + + if (!gpe_block) { + return_ACPI_STATUS(AE_OK); + } + /* - * Runtime option: Should Wake GPEs be enabled at runtime? The default - * is No, they should only be enabled just as the machine goes to sleep. + * Runtime option: Should wake GPEs be enabled at runtime? The default + * is no, they should only be enabled just as the machine goes to sleep. */ if (acpi_gbl_leave_wake_gpes_disabled) { /* - * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods. - * (Each GPE that has one or more _PRWs that reference it is by - * definition a WAKE GPE and will not be enabled while the machine - * is running.) + * Differentiate runtime vs wake GPEs, via the _PRW control methods. + * Each GPE that has one or more _PRWs that reference it is by + * definition a wake GPE and will not be enabled while the machine + * is running. */ gpe_info.gpe_block = gpe_block; gpe_info.gpe_device = gpe_device; @@ -948,9 +1001,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, } /* - * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs, - * and 2) have a corresponding _Lxx or _Exx method. All other GPEs must - * be enabled via the acpi_enable_gpe() external interface. + * Enable all GPEs in this block that have these attributes: + * 1) are "runtime" or "run/wake" GPEs, and + * 2) have a corresponding _Lxx or _Exx method + * + * Any other GPEs within this block must be enabled via the acpi_enable_gpe() + * external interface. */ wake_gpe_count = 0; gpe_enabled_count = 0; @@ -976,32 +1032,19 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, } } - /* Dump info about this GPE block */ - - ACPI_DEBUG_PRINT((ACPI_DB_INIT, - "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", - (u32) gpe_block->block_base_number, - (u32) (gpe_block->block_base_number + - ((gpe_block->register_count * - ACPI_GPE_REGISTER_WIDTH) - 1)), - gpe_device->name.ascii, gpe_block->register_count, - interrupt_number)); - - /* Enable all valid GPEs found above */ - - status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block); - ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Found %u Wake, Enabled %u Runtime GPEs in this block\n", wake_gpe_count, gpe_enabled_count)); - /* Return the new block */ + /* Enable all valid runtime GPEs found above */ - if (return_gpe_block) { - (*return_gpe_block) = gpe_block; + status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block); + if (ACPI_FAILURE(status)) { + ACPI_REPORT_ERROR(("Could not enable GPEs in gpe_block %p\n", + gpe_block)); } - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(status); } /******************************************************************************* diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 887ff9f28a0d..c1b898928256 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -626,6 +626,13 @@ acpi_install_gpe_block(acpi_handle gpe_device, goto unlock_and_exit; } + /* Run the _PRW methods and enable the GPEs */ + + status = acpi_ev_initialize_gpe_block(node, gpe_block); + if (ACPI_FAILURE(status)) { + goto unlock_and_exit; + } + /* Get the device_object attached to the node */ obj_desc = acpi_ns_get_attached_object(node); diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 4477a62fed56..5a4cca171af6 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -55,20 +55,386 @@ ACPI_MODULE_NAME("exdump") */ #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /* Local prototypes */ -#ifdef ACPI_FUTURE_USAGE static void acpi_ex_out_string(char *title, char *value); static void acpi_ex_out_pointer(char *title, void *value); -static void acpi_ex_out_integer(char *title, u32 value); - static void acpi_ex_out_address(char *title, acpi_physical_address value); -static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc); +static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc); static void -acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index); -#endif /* ACPI_FUTURE_USAGE */ +acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, + u32 level, u32 index); + +/******************************************************************************* + * + * Object Descriptor info tables + * + * Note: The first table entry must be an INIT opcode and must contain + * the table length (number of table entries) + * + ******************************************************************************/ + +static struct acpi_exdump_info acpi_ex_dump_integer[2] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_integer), NULL}, + {ACPI_EXD_UINT64, ACPI_EXD_OFFSET(integer.value), "Value"} +}; + +static struct acpi_exdump_info acpi_ex_dump_string[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_string), NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(string.length), "Length"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(string.pointer), "Pointer"}, + {ACPI_EXD_STRING, 0, NULL} +}; + +static struct acpi_exdump_info acpi_ex_dump_buffer[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"}, + {ACPI_EXD_BUFFER, 0, NULL} +}; + +static struct acpi_exdump_info acpi_ex_dump_package[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_package), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(package.flags), "Flags"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(package.count), "Elements"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(package.elements), "Element List"}, + {ACPI_EXD_PACKAGE, 0, NULL} +}; + +static struct acpi_exdump_info acpi_ex_dump_device[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_device), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.handler), "Handler"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.system_notify), + "System Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.device_notify), + "Device Notify"} +}; + +static struct acpi_exdump_info acpi_ex_dump_event[2] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_event), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.semaphore), "Semaphore"} +}; + +static struct acpi_exdump_info acpi_ex_dump_method[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "param_count"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.concurrency), "Concurrency"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.semaphore), "Semaphore"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(method.aml_length), "Aml Length"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} +}; + +static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, + {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), + "Acquire Depth"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.semaphore), "Semaphore"} +}; + +static struct acpi_exdump_info acpi_ex_dump_region[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.space_id), "Space Id"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.flags), "Flags"}, + {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(region.address), "Address"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(region.length), "Length"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.handler), "Handler"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.next), "Next"} +}; + +static struct acpi_exdump_info acpi_ex_dump_power[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_power), NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.system_level), + "System Level"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.resource_order), + "Resource Order"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.system_notify), + "System Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.device_notify), + "Device Notify"} +}; + +static struct acpi_exdump_info acpi_ex_dump_processor[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.length), "Length"}, + {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify), + "System Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.device_notify), + "Device Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.handler), "Handler"} +}; + +static struct acpi_exdump_info acpi_ex_dump_thermal[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_thermal), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.system_notify), + "System Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.device_notify), + "Device Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.handler), "Handler"} +}; + +static struct acpi_exdump_info acpi_ex_dump_buffer_field[3] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer_field.buffer_obj), + "Buffer Object"} +}; + +static struct acpi_exdump_info acpi_ex_dump_region_field[3] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"} +}; + +static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(bank_field.value), "Value"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.region_obj), + "Region Object"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.bank_obj), "Bank Object"} +}; + +static struct acpi_exdump_info acpi_ex_dump_index_field[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(index_field.value), "Value"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.index_obj), + "Index Object"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"} +}; + +static struct acpi_exdump_info acpi_ex_dump_reference[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.offset), "Offset"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"}, + {ACPI_EXD_REFERENCE, 0, NULL} +}; + +static struct acpi_exdump_info acpi_ex_dump_address_handler[6] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_address_handler), + NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(address_space.space_id), "Space Id"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.next), "Next"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.region_list), + "Region List"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.node), "Node"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.context), "Context"} +}; + +static struct acpi_exdump_info acpi_ex_dump_notify[3] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_notify), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.node), "Node"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.context), "Context"} +}; + +/* Miscellaneous tables */ + +static struct acpi_exdump_info acpi_ex_dump_common[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_common), NULL}, + {ACPI_EXD_TYPE, 0, NULL}, + {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(common.reference_count), + "Reference Count"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common.flags), "Flags"} +}; + +static struct acpi_exdump_info acpi_ex_dump_field_common[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_field_common), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.field_flags), + "Field Flags"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.access_byte_width), + "Access Byte Width"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.bit_length), + "Bit Length"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.start_field_bit_offset), + "Field Bit Offset"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.base_byte_offset), + "Base Byte Offset"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(common_field.node), "Parent Node"} +}; + +static struct acpi_exdump_info acpi_ex_dump_node[6] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_node), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(flags), "Flags"}, + {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(owner_id), "Owner Id"}, + {ACPI_EXD_UINT16, ACPI_EXD_NSOFFSET(reference_count), + "Reference Count"}, + {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(child), "Child List"}, + {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(peer), "Next Peer"} +}; + +/* Dispatch table, indexed by object type */ + +static struct acpi_exdump_info *acpi_ex_dump_info[] = { + NULL, + acpi_ex_dump_integer, + acpi_ex_dump_string, + acpi_ex_dump_buffer, + acpi_ex_dump_package, + NULL, + acpi_ex_dump_device, + acpi_ex_dump_event, + acpi_ex_dump_method, + acpi_ex_dump_mutex, + acpi_ex_dump_region, + acpi_ex_dump_power, + acpi_ex_dump_processor, + acpi_ex_dump_thermal, + acpi_ex_dump_buffer_field, + NULL, + NULL, + acpi_ex_dump_region_field, + acpi_ex_dump_bank_field, + acpi_ex_dump_index_field, + acpi_ex_dump_reference, + NULL, + NULL, + acpi_ex_dump_notify, + acpi_ex_dump_address_handler, + NULL, + NULL, + NULL +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ex_dump_object + * + * PARAMETERS: obj_desc - Descriptor to dump + * Info - Info table corresponding to this object + * type + * + * RETURN: None + * + * DESCRIPTION: Walk the info table for this object + * + ******************************************************************************/ + +static void +acpi_ex_dump_object(union acpi_operand_object *obj_desc, + struct acpi_exdump_info *info) +{ + u8 *target; + char *name; + u8 count; + + if (!info) { + acpi_os_printf + ("ex_dump_object: Display not implemented for object type %s\n", + acpi_ut_get_object_type_name(obj_desc)); + return; + } + + /* First table entry must contain the table length (# of table entries) */ + + count = info->offset; + + while (count) { + target = ((u8 *) obj_desc) + info->offset; + name = info->name; + + switch (info->opcode) { + case ACPI_EXD_INIT: + break; + + case ACPI_EXD_TYPE: + acpi_ex_out_string("Type", + acpi_ut_get_object_type_name + (obj_desc)); + break; + + case ACPI_EXD_UINT8: + + acpi_os_printf("%20s : %2.2X\n", name, *target); + break; + + case ACPI_EXD_UINT16: + + acpi_os_printf("%20s : %4.4X\n", name, + *ACPI_CAST_PTR(u16, target)); + break; + + case ACPI_EXD_UINT32: + + acpi_os_printf("%20s : %8.8X\n", name, + *ACPI_CAST_PTR(u32, target)); + break; + + case ACPI_EXD_UINT64: + + acpi_os_printf("%20s : %8.8X%8.8X\n", "Value", + ACPI_FORMAT_UINT64(*ACPI_CAST_PTR + (u64, target))); + break; + + case ACPI_EXD_POINTER: + + acpi_ex_out_pointer(name, + *ACPI_CAST_PTR(void *, target)); + break; + + case ACPI_EXD_ADDRESS: + + acpi_ex_out_address(name, + *ACPI_CAST_PTR + (acpi_physical_address, target)); + break; + + case ACPI_EXD_STRING: + + acpi_ut_print_string(obj_desc->string.pointer, + ACPI_UINT8_MAX); + acpi_os_printf("\n"); + break; + + case ACPI_EXD_BUFFER: + + ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, + obj_desc->buffer.length); + break; + + case ACPI_EXD_PACKAGE: + + /* Dump the package contents */ + + acpi_os_printf("\nPackage Contents:\n"); + acpi_ex_dump_package_obj(obj_desc, 0, 0); + break; + + case ACPI_EXD_FIELD: + + acpi_ex_dump_object(obj_desc, + acpi_ex_dump_field_common); + break; + + case ACPI_EXD_REFERENCE: + + acpi_ex_out_string("Opcode", + (acpi_ps_get_opcode_info + (obj_desc->reference.opcode))-> + name); + acpi_ex_dump_reference_obj(obj_desc); + break; + + default: + acpi_os_printf("**** Invalid table opcode [%X] ****\n", + info->opcode); + return; + } + + info++; + count--; + } +} /******************************************************************************* * @@ -441,7 +807,6 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, return; } -#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * * FUNCTION: acpi_ex_out* functions @@ -465,11 +830,6 @@ static void acpi_ex_out_pointer(char *title, void *value) acpi_os_printf("%20s : %p\n", title, value); } -static void acpi_ex_out_integer(char *title, u32 value) -{ - acpi_os_printf("%20s : %.2X\n", title, value); -} - static void acpi_ex_out_address(char *title, acpi_physical_address value) { @@ -482,16 +842,16 @@ static void acpi_ex_out_address(char *title, acpi_physical_address value) /******************************************************************************* * - * FUNCTION: acpi_ex_dump_node + * FUNCTION: acpi_ex_dump_namespace_node * - * PARAMETERS: *Node - Descriptor to dump + * PARAMETERS: Node - Descriptor to dump * Flags - Force display if TRUE * * DESCRIPTION: Dumps the members of the given.Node * ******************************************************************************/ -void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags) +void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags) { ACPI_FUNCTION_ENTRY(); @@ -506,19 +866,17 @@ void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags) acpi_os_printf("%20s : %4.4s\n", "Name", acpi_ut_get_node_name(node)); acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type)); - acpi_ex_out_integer("Flags", node->flags); - acpi_ex_out_integer("Owner Id", node->owner_id); - acpi_ex_out_integer("Reference Count", node->reference_count); acpi_ex_out_pointer("Attached Object", acpi_ns_get_attached_object(node)); - acpi_ex_out_pointer("child_list", node->child); - acpi_ex_out_pointer("next_peer", node->peer); acpi_ex_out_pointer("Parent", acpi_ns_get_parent_node(node)); + + acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node), + acpi_ex_dump_node); } /******************************************************************************* * - * FUNCTION: acpi_ex_dump_reference + * FUNCTION: acpi_ex_dump_reference_obj * * PARAMETERS: Object - Descriptor to dump * @@ -526,14 +884,16 @@ void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags) * ******************************************************************************/ -static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc) +static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) { struct acpi_buffer ret_buf; acpi_status status; + ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; + if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) { acpi_os_printf("Named Object %p ", obj_desc->reference.node); - ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_ns_handle_to_pathname(obj_desc->reference.node, &ret_buf); @@ -551,9 +911,9 @@ static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc) /******************************************************************************* * - * FUNCTION: acpi_ex_dump_package + * FUNCTION: acpi_ex_dump_package_obj * - * PARAMETERS: Object - Descriptor to dump + * PARAMETERS: obj_desc - Descriptor to dump * Level - Indentation Level * Index - Package index for this object * @@ -562,7 +922,8 @@ static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc) ******************************************************************************/ static void -acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index) +acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, + u32 level, u32 index) { u32 i; @@ -622,15 +983,15 @@ acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index) obj_desc->package.count); for (i = 0; i < obj_desc->package.count; i++) { - acpi_ex_dump_package(obj_desc->package.elements[i], - level + 1, i); + acpi_ex_dump_package_obj(obj_desc->package.elements[i], + level + 1, i); } break; case ACPI_TYPE_LOCAL_REFERENCE: acpi_os_printf("[Object Reference] "); - acpi_ex_dump_reference(obj_desc); + acpi_ex_dump_reference_obj(obj_desc); break; default: @@ -645,7 +1006,7 @@ acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index) * * FUNCTION: acpi_ex_dump_object_descriptor * - * PARAMETERS: Object - Descriptor to dump + * PARAMETERS: obj_desc - Descriptor to dump * Flags - Force display if TRUE * * DESCRIPTION: Dumps the members of the object descriptor given. @@ -670,11 +1031,13 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) { - acpi_ex_dump_node((struct acpi_namespace_node *)obj_desc, - flags); + acpi_ex_dump_namespace_node((struct acpi_namespace_node *) + obj_desc, flags); + acpi_os_printf("\nAttached Object (%p):\n", ((struct acpi_namespace_node *)obj_desc)-> object); + acpi_ex_dump_object_descriptor(((struct acpi_namespace_node *) obj_desc)->object, flags); return_VOID; @@ -687,233 +1050,18 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) return_VOID; } - /* Common Fields */ - - acpi_ex_out_string("Type", acpi_ut_get_object_type_name(obj_desc)); - acpi_ex_out_integer("Reference Count", - obj_desc->common.reference_count); - acpi_ex_out_integer("Flags", obj_desc->common.flags); - - /* Object-specific Fields */ - - switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { - case ACPI_TYPE_INTEGER: - - acpi_os_printf("%20s : %8.8X%8.8X\n", "Value", - ACPI_FORMAT_UINT64(obj_desc->integer.value)); - break; - - case ACPI_TYPE_STRING: - - acpi_ex_out_integer("Length", obj_desc->string.length); - - acpi_os_printf("%20s : %p ", "Pointer", - obj_desc->string.pointer); - acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX); - acpi_os_printf("\n"); - break; - - case ACPI_TYPE_BUFFER: - - acpi_ex_out_integer("Length", obj_desc->buffer.length); - acpi_ex_out_pointer("Pointer", obj_desc->buffer.pointer); - ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, - obj_desc->buffer.length); - break; - - case ACPI_TYPE_PACKAGE: - - acpi_ex_out_integer("Flags", obj_desc->package.flags); - acpi_ex_out_integer("Elements", obj_desc->package.count); - acpi_ex_out_pointer("Element List", obj_desc->package.elements); - - /* Dump the package contents */ - - acpi_os_printf("\nPackage Contents:\n"); - acpi_ex_dump_package(obj_desc, 0, 0); - break; - - case ACPI_TYPE_DEVICE: - - acpi_ex_out_pointer("Handler", obj_desc->device.handler); - acpi_ex_out_pointer("system_notify", - obj_desc->device.system_notify); - acpi_ex_out_pointer("device_notify", - obj_desc->device.device_notify); - break; - - case ACPI_TYPE_EVENT: - - acpi_ex_out_pointer("Semaphore", obj_desc->event.semaphore); - break; - - case ACPI_TYPE_METHOD: - - acpi_ex_out_integer("param_count", - obj_desc->method.param_count); - acpi_ex_out_integer("Concurrency", - obj_desc->method.concurrency); - acpi_ex_out_pointer("Semaphore", obj_desc->method.semaphore); - acpi_ex_out_integer("owner_id", obj_desc->method.owner_id); - acpi_ex_out_integer("aml_length", obj_desc->method.aml_length); - acpi_ex_out_pointer("aml_start", obj_desc->method.aml_start); - break; - - case ACPI_TYPE_MUTEX: - - acpi_ex_out_integer("sync_level", obj_desc->mutex.sync_level); - acpi_ex_out_pointer("owner_thread", - obj_desc->mutex.owner_thread); - acpi_ex_out_integer("acquire_depth", - obj_desc->mutex.acquisition_depth); - acpi_ex_out_pointer("Semaphore", obj_desc->mutex.semaphore); - break; - - case ACPI_TYPE_REGION: - - acpi_ex_out_integer("space_id", obj_desc->region.space_id); - acpi_ex_out_integer("Flags", obj_desc->region.flags); - acpi_ex_out_address("Address", obj_desc->region.address); - acpi_ex_out_integer("Length", obj_desc->region.length); - acpi_ex_out_pointer("Handler", obj_desc->region.handler); - acpi_ex_out_pointer("Next", obj_desc->region.next); - break; - - case ACPI_TYPE_POWER: - - acpi_ex_out_integer("system_level", - obj_desc->power_resource.system_level); - acpi_ex_out_integer("resource_order", - obj_desc->power_resource.resource_order); - acpi_ex_out_pointer("system_notify", - obj_desc->power_resource.system_notify); - acpi_ex_out_pointer("device_notify", - obj_desc->power_resource.device_notify); - break; - - case ACPI_TYPE_PROCESSOR: - - acpi_ex_out_integer("Processor ID", - obj_desc->processor.proc_id); - acpi_ex_out_integer("Length", obj_desc->processor.length); - acpi_ex_out_address("Address", - (acpi_physical_address) obj_desc->processor. - address); - acpi_ex_out_pointer("system_notify", - obj_desc->processor.system_notify); - acpi_ex_out_pointer("device_notify", - obj_desc->processor.device_notify); - acpi_ex_out_pointer("Handler", obj_desc->processor.handler); - break; - - case ACPI_TYPE_THERMAL: - - acpi_ex_out_pointer("system_notify", - obj_desc->thermal_zone.system_notify); - acpi_ex_out_pointer("device_notify", - obj_desc->thermal_zone.device_notify); - acpi_ex_out_pointer("Handler", obj_desc->thermal_zone.handler); - break; - - case ACPI_TYPE_BUFFER_FIELD: - case ACPI_TYPE_LOCAL_REGION_FIELD: - case ACPI_TYPE_LOCAL_BANK_FIELD: - case ACPI_TYPE_LOCAL_INDEX_FIELD: - - acpi_ex_out_integer("field_flags", - obj_desc->common_field.field_flags); - acpi_ex_out_integer("access_byte_width", - obj_desc->common_field.access_byte_width); - acpi_ex_out_integer("bit_length", - obj_desc->common_field.bit_length); - acpi_ex_out_integer("fld_bit_offset", - obj_desc->common_field. - start_field_bit_offset); - acpi_ex_out_integer("base_byte_offset", - obj_desc->common_field.base_byte_offset); - acpi_ex_out_pointer("parent_node", obj_desc->common_field.node); - - switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { - case ACPI_TYPE_BUFFER_FIELD: - acpi_ex_out_pointer("buffer_obj", - obj_desc->buffer_field.buffer_obj); - break; - - case ACPI_TYPE_LOCAL_REGION_FIELD: - acpi_ex_out_pointer("region_obj", - obj_desc->field.region_obj); - break; - - case ACPI_TYPE_LOCAL_BANK_FIELD: - acpi_ex_out_integer("Value", - obj_desc->bank_field.value); - acpi_ex_out_pointer("region_obj", - obj_desc->bank_field.region_obj); - acpi_ex_out_pointer("bank_obj", - obj_desc->bank_field.bank_obj); - break; - - case ACPI_TYPE_LOCAL_INDEX_FIELD: - acpi_ex_out_integer("Value", - obj_desc->index_field.value); - acpi_ex_out_pointer("Index", - obj_desc->index_field.index_obj); - acpi_ex_out_pointer("Data", - obj_desc->index_field.data_obj); - break; - - default: - /* All object types covered above */ - break; - } - break; - - case ACPI_TYPE_LOCAL_REFERENCE: - - acpi_ex_out_integer("target_type", - obj_desc->reference.target_type); - acpi_ex_out_string("Opcode", - (acpi_ps_get_opcode_info - (obj_desc->reference.opcode))->name); - acpi_ex_out_integer("Offset", obj_desc->reference.offset); - acpi_ex_out_pointer("obj_desc", obj_desc->reference.object); - acpi_ex_out_pointer("Node", obj_desc->reference.node); - acpi_ex_out_pointer("Where", obj_desc->reference.where); - - acpi_ex_dump_reference(obj_desc); - break; - - case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: - - acpi_ex_out_integer("space_id", - obj_desc->address_space.space_id); - acpi_ex_out_pointer("Next", obj_desc->address_space.next); - acpi_ex_out_pointer("region_list", - obj_desc->address_space.region_list); - acpi_ex_out_pointer("Node", obj_desc->address_space.node); - acpi_ex_out_pointer("Context", obj_desc->address_space.context); - break; - - case ACPI_TYPE_LOCAL_NOTIFY: - - acpi_ex_out_pointer("Node", obj_desc->notify.node); - acpi_ex_out_pointer("Context", obj_desc->notify.context); - break; - - case ACPI_TYPE_LOCAL_ALIAS: - case ACPI_TYPE_LOCAL_METHOD_ALIAS: - case ACPI_TYPE_LOCAL_EXTRA: - case ACPI_TYPE_LOCAL_DATA: - default: - - acpi_os_printf - ("ex_dump_object_descriptor: Display not implemented for object type %s\n", - acpi_ut_get_object_type_name(obj_desc)); - break; + if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) { + return_VOID; } + /* Common Fields */ + + acpi_ex_dump_object(obj_desc, acpi_ex_dump_common); + + /* Object-specific fields */ + + acpi_ex_dump_object(obj_desc, acpi_ex_dump_info[obj_desc->common.type]); return_VOID; } -#endif /* ACPI_FUTURE_USAGE */ #endif diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 1899ab251393..00a25f8188f4 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -45,6 +45,7 @@ #include #include #include +#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exmisc") @@ -157,40 +158,52 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, union acpi_operand_object **actual_return_desc, struct acpi_walk_state *walk_state) { + acpi_status status; union acpi_operand_object *return_desc; u8 *new_buf; - u8 *end_tag1; - u8 *end_tag2; + u8 *end_tag; + acpi_size length0; acpi_size length1; - acpi_size length2; ACPI_FUNCTION_TRACE("ex_concat_template"); - /* Find the end_tags in each resource template */ - - end_tag1 = acpi_ut_get_resource_end_tag(operand0); - end_tag2 = acpi_ut_get_resource_end_tag(operand1); - if (!end_tag1 || !end_tag2) { - return_ACPI_STATUS(AE_AML_OPERAND_TYPE); + /* + * Find the end_tag descriptor in each resource template. + * Note: returned pointers point TO the end_tag, not past it. + * + * Compute the length of each resource template + */ + status = acpi_ut_get_resource_end_tag(operand0, &end_tag); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - /* Compute the length of each part */ + length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer); - length1 = ACPI_PTR_DIFF(end_tag1, operand0->buffer.pointer); - length2 = ACPI_PTR_DIFF(end_tag2, operand1->buffer.pointer) + 2; /* Size of END_TAG */ + status = acpi_ut_get_resource_end_tag(operand1, &end_tag); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Include the end_tag in the second template length */ + + length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer) + + sizeof(struct aml_resource_end_tag); /* Create a new buffer object for the result */ - return_desc = acpi_ut_create_buffer_object(length1 + length2); + return_desc = acpi_ut_create_buffer_object(length0 + length1); if (!return_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } - /* Copy the templates to the new descriptor */ - + /* + * Copy the templates to the new buffer, 0 first, then 1 follows. One + * end_tag descriptor is copied from Operand1. + */ new_buf = return_desc->buffer.pointer; - ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length1); - ACPI_MEMCPY(new_buf + length1, operand1->buffer.pointer, length2); + ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0); + ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1); /* Compute the new checksum */ @@ -198,7 +211,7 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, acpi_ut_generate_checksum(return_desc->buffer.pointer, (return_desc->buffer.length - 1)); - /* Return the completed template descriptor */ + /* Return the completed resource template */ *actual_return_desc = return_desc; return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index c07b046659ff..8167af1fa57b 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -399,7 +399,7 @@ acpi_walk_namespace(acpi_object_type type, /* Parameter validation */ - if ((type > ACPI_TYPE_EXTERNAL_MAX) || (!max_depth) || (!user_function)) { + if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index c29d3a447278..eca7439ee9da 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -299,13 +299,14 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) /* Point to the next object */ - resource = ACPI_PTR_ADD(struct acpi_resource, - resource, resource->length); + resource = + ACPI_PTR_ADD(struct acpi_resource, resource, + resource->length); } - /* Did not find an END_TAG descriptor */ + /* Did not find an end_tag resource descriptor */ - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* @@ -328,185 +329,155 @@ acpi_status acpi_rs_get_list_length(u8 * aml_buffer, u32 aml_buffer_length, acpi_size * size_needed) { + acpi_status status; + u8 *end_aml; u8 *buffer; - struct acpi_resource_info *resource_info; u32 buffer_size = 0; - u32 bytes_parsed = 0; - u8 resource_type; u16 temp16; u16 resource_length; - u16 header_length; u32 extra_struct_bytes; + u8 resource_index; + u8 minimum_aml_resource_length; ACPI_FUNCTION_TRACE("rs_get_list_length"); - while (bytes_parsed < aml_buffer_length) { - /* The next byte in the stream is the resource descriptor type */ + end_aml = aml_buffer + aml_buffer_length; - resource_type = acpi_ut_get_resource_type(aml_buffer); + /* Walk the list of AML resource descriptors */ - /* Get the base stream size and structure sizes for the descriptor */ + while (aml_buffer < end_aml) { + /* Validate the Resource Type and Resource Length */ - resource_info = acpi_rs_get_resource_info(resource_type); - if (!resource_info) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + status = acpi_ut_validate_resource(aml_buffer, &resource_index); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - /* Get the Length field from the input resource descriptor */ + /* 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 fields */ - + /* + * 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); - if (!(resource_type & ACPI_RESOURCE_NAME_LARGE)) { + switch (acpi_ut_get_resource_type(aml_buffer)) { + case ACPI_RESOURCE_NAME_IRQ: /* - * Small resource descriptors + * IRQ Resource: + * Get the number of bits set in the 16-bit IRQ mask */ - header_length = - sizeof(struct aml_resource_small_header); - buffer = aml_buffer + header_length; + ACPI_MOVE_16_TO_16(&temp16, buffer); + extra_struct_bytes = + acpi_rs_count_set_bits(temp16) * sizeof(u32); + break; - switch (resource_type) { - case ACPI_RESOURCE_NAME_IRQ: - /* - * IRQ Resource: - * Get the number of bits set in the IRQ word - */ - ACPI_MOVE_16_TO_16(&temp16, buffer); - extra_struct_bytes = - (acpi_rs_count_set_bits(temp16) * - sizeof(u32)); - break; - - case ACPI_RESOURCE_NAME_DMA: - /* - * DMA Resource: - * Get the number of bits set in the DMA channels byte - */ - ACPI_MOVE_16_TO_16(&temp16, buffer); - extra_struct_bytes = - (acpi_rs_count_set_bits(temp16) * - sizeof(u32)); - break; - - case ACPI_RESOURCE_NAME_VENDOR_SMALL: - /* - * Vendor Specific Resource: - * Ensure a 32-bit boundary for the structure - */ - extra_struct_bytes = - ACPI_ROUND_UP_to_32_bITS(resource_length); - break; - - case ACPI_RESOURCE_NAME_END_TAG: - /* - * End Tag: - * Terminate the loop now - */ - aml_buffer_length = bytes_parsed; - break; - - default: - break; - } - } else { + case ACPI_RESOURCE_NAME_DMA: /* - * Large resource descriptors + * DMA Resource: + * Get the number of bits set in the 8-bit DMA mask */ - header_length = - sizeof(struct aml_resource_large_header); - buffer = aml_buffer + header_length; + extra_struct_bytes = + acpi_rs_count_set_bits(*buffer) * sizeof(u32); + break; - switch (resource_type) { - case ACPI_RESOURCE_NAME_VENDOR_LARGE: - /* - * Vendor Defined Resource: - * Add vendor data and ensure a 32-bit boundary for the structure - */ - extra_struct_bytes = - ACPI_ROUND_UP_to_32_bITS(resource_length); - break; + case ACPI_RESOURCE_NAME_VENDOR_SMALL: + /* + * Vendor Resource: + * Ensure a 32-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length) - + resource_length; + break; - case ACPI_RESOURCE_NAME_ADDRESS32: - case ACPI_RESOURCE_NAME_ADDRESS16: - /* - * 32-Bit or 16-bit Address Resource: - * Add the size of any optional data (resource_source) - */ - extra_struct_bytes = - acpi_rs_stream_option_length - (resource_length, - resource_info-> - minimum_aml_resource_length); - break; + case ACPI_RESOURCE_NAME_END_TAG: + /* + * End Tag: This is the normal exit + */ + *size_needed = buffer_size; + return_ACPI_STATUS(AE_OK); - case ACPI_RESOURCE_NAME_EXTENDED_IRQ: - /* - * Extended IRQ: - * Point past the interrupt_vector_flags to get the - * interrupt_table_length. - */ - buffer++; + case ACPI_RESOURCE_NAME_VENDOR_LARGE: + /* + * Vendor Resource: + * Add vendor data and ensure a 32-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length) - + resource_length; + break; - /* - * Add 4 bytes for each additional interrupt. Note: at least one - * interrupt is required and is included in the minimum - * descriptor size - */ - extra_struct_bytes = - ((*buffer - 1) * sizeof(u32)); + case ACPI_RESOURCE_NAME_ADDRESS32: + case ACPI_RESOURCE_NAME_ADDRESS16: + /* + * 32-Bit or 16-bit Address Resource: + * Add the size of any optional data (resource_source) + */ + extra_struct_bytes = + acpi_rs_stream_option_length(resource_length, + minimum_aml_resource_length); + break; - /* Add the size of any optional data (resource_source) */ + case ACPI_RESOURCE_NAME_EXTENDED_IRQ: + /* + * Extended IRQ: + * Point past the interrupt_vector_flags to get the + * interrupt_table_length. + */ + buffer++; - extra_struct_bytes += - acpi_rs_stream_option_length(resource_length - - - extra_struct_bytes, - resource_info-> - minimum_aml_resource_length); - break; + extra_struct_bytes = + /* + * Add 4 bytes for each additional interrupt. Note: at + * least one interrupt is required and is included in + * the minimum descriptor size + */ + ((*buffer - 1) * sizeof(u32)) + + /* Add the size of any optional data (resource_source) */ + acpi_rs_stream_option_length(resource_length - + extra_struct_bytes, + minimum_aml_resource_length); + break; - case ACPI_RESOURCE_NAME_ADDRESS64: - /* - * 64-Bit Address Resource: - * Add the size of any optional data (resource_source) - * Ensure a 64-bit boundary for the structure - */ - extra_struct_bytes = - ACPI_ROUND_UP_to_64_bITS - (acpi_rs_stream_option_length - (resource_length, - resource_info-> - minimum_aml_resource_length)); - break; + case ACPI_RESOURCE_NAME_ADDRESS64: + /* + * 64-Bit Address Resource: + * Add the size of any optional data (resource_source) + * Ensure a 64-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_64_bITS + (acpi_rs_stream_option_length + (resource_length, minimum_aml_resource_length)); + break; - default: - break; - } + default: + break; } /* Update the required buffer size for the internal descriptor structs */ - temp16 = - (u16) (resource_info->minimum_internal_struct_length + - extra_struct_bytes); + temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + + extra_struct_bytes); buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(temp16); /* - * Update byte count and point to the next resource within the stream + * Point to the next resource within the stream * using the size of the header plus the length contained in the header */ - temp16 = (u16) (header_length + resource_length); - bytes_parsed += temp16; - aml_buffer += temp16; + aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); } - /* This is the data the caller needs */ + /* Did not find an end_tag resource descriptor */ - *size_needed = buffer_size; - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 27172a3d55d7..f617ca80c5a6 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -324,7 +324,7 @@ static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = { static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = { {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags), - "Resource Type", "Memory Range"}, + "Resource Type", (void *)"Memory Range"}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect), "Write Protect", acpi_gbl_RWdecode}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching), @@ -337,7 +337,7 @@ static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = { static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = { {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags), - "Resource Type", "I/O Range"}, + "Resource Type", (void *)"I/O Range"}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type), "Range Type", acpi_gbl_RNGdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation), @@ -372,8 +372,8 @@ static struct acpi_rsdump_info acpi_rs_dump_prt[5] = { static void acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) { - void *target = NULL; - void *previous_target; + u8 *target = NULL; + u8 *previous_target; char *name; u8 count; @@ -399,43 +399,49 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) /* Strings */ case ACPI_RSD_LITERAL: - acpi_rs_out_string(name, (char *)table->pointer); + acpi_rs_out_string(name, + ACPI_CAST_PTR(char, table->pointer)); break; case ACPI_RSD_STRING: - acpi_rs_out_string(name, (char *)target); + acpi_rs_out_string(name, ACPI_CAST_PTR(char, target)); break; /* Data items, 8/16/32/64 bit */ case ACPI_RSD_UINT8: - acpi_rs_out_integer8(name, *(u8 *) target); + acpi_rs_out_integer8(name, *ACPI_CAST_PTR(u8, target)); break; case ACPI_RSD_UINT16: - acpi_rs_out_integer16(name, *(u16 *) target); + acpi_rs_out_integer16(name, + *ACPI_CAST_PTR(u16, target)); break; case ACPI_RSD_UINT32: - acpi_rs_out_integer32(name, *(u32 *) target); + acpi_rs_out_integer32(name, + *ACPI_CAST_PTR(u32, target)); break; case ACPI_RSD_UINT64: - acpi_rs_out_integer64(name, *(u64 *) target); + acpi_rs_out_integer64(name, + *ACPI_CAST_PTR(u64, target)); break; /* Flags: 1-bit and 2-bit flags supported */ case ACPI_RSD_1BITFLAG: - acpi_rs_out_string(name, (char *) - ((const char **)table-> - pointer)[(*(u8 *) target) & 0x01]); + acpi_rs_out_string(name, ACPI_CAST_PTR(char, + table-> + pointer[*target & + 0x01])); break; case ACPI_RSD_2BITFLAG: - acpi_rs_out_string(name, (char *) - ((const char **)table-> - pointer)[(*(u8 *) target) & 0x03]); + acpi_rs_out_string(name, ACPI_CAST_PTR(char, + table-> + pointer[*target & + 0x03])); break; case ACPI_RSD_SHORTLIST: @@ -445,10 +451,8 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) */ if (previous_target) { acpi_rs_out_title(name); - acpi_rs_dump_short_byte_list(* - ((u8 *) - previous_target), - (u8 *) target); + acpi_rs_dump_short_byte_list(*previous_target, + target); } break; @@ -458,10 +462,9 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) * Note: The list length is obtained from the previous table entry */ if (previous_target) { - acpi_rs_dump_byte_list(* - ((u16 *) - previous_target), - (u8 *) target); + acpi_rs_dump_byte_list(*ACPI_CAST_PTR + (u16, previous_target), + target); } break; @@ -471,10 +474,9 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) * Note: The list length is obtained from the previous table entry */ if (previous_target) { - acpi_rs_dump_dword_list(* - ((u8 *) - previous_target), - (u32 *) target); + acpi_rs_dump_dword_list(*previous_target, + ACPI_CAST_PTR(u32, + target)); } break; @@ -482,17 +484,19 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) /* * Common flags for all Address resources */ - acpi_rs_dump_address_common((union acpi_resource_data *) - target); + acpi_rs_dump_address_common(ACPI_CAST_PTR + (union acpi_resource_data, + target)); break; case ACPI_RSD_SOURCE: /* * Optional resource_source for Address resources */ - acpi_rs_dump_resource_source((struct - acpi_resource_source *) - target); + acpi_rs_dump_resource_source(ACPI_CAST_PTR + (struct + acpi_resource_source, + target)); break; default: diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c index 973fc2834cbb..623b06689336 100644 --- a/drivers/acpi/resources/rsinfo.c +++ b/drivers/acpi/resources/rsinfo.c @@ -80,7 +80,9 @@ struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[] = { /* Dispatch tables for AML-to-resource (Get Resource) conversion functions */ -struct acpi_rsconvert_info *acpi_gbl_sm_get_resource_dispatch[] = { +struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[] = { + /* Small descriptors */ + NULL, /* 0x00, Reserved */ NULL, /* 0x01, Reserved */ NULL, /* 0x02, Reserved */ @@ -96,10 +98,10 @@ struct acpi_rsconvert_info *acpi_gbl_sm_get_resource_dispatch[] = { NULL, /* 0x0C, Reserved */ NULL, /* 0x0D, Reserved */ acpi_rs_get_vendor_small, /* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */ - acpi_rs_convert_end_tag /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */ -}; + acpi_rs_convert_end_tag, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */ + + /* Large descriptors */ -struct acpi_rsconvert_info *acpi_gbl_lg_get_resource_dispatch[] = { NULL, /* 0x00, Reserved */ acpi_rs_convert_memory24, /* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */ acpi_rs_convert_generic_reg, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */ @@ -138,7 +140,6 @@ struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = { acpi_rs_dump_ext_irq, /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ acpi_rs_dump_generic_reg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ }; - #endif #endif /* ACPI_FUTURE_USAGE */ /* @@ -166,62 +167,38 @@ const u8 acpi_gbl_aml_resource_sizes[] = { sizeof(struct aml_resource_generic_register) /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ }; -/* Macros used in the tables below */ +const u8 acpi_gbl_resource_struct_sizes[] = { + /* Small descriptors */ -#define ACPI_RLARGE(r) (sizeof (r) - sizeof (struct aml_resource_large_header)) -#define ACPI_RSMALL(r) (sizeof (r) - sizeof (struct aml_resource_small_header)) + 0, + 0, + 0, + 0, + ACPI_RS_SIZE(struct acpi_resource_irq), + ACPI_RS_SIZE(struct acpi_resource_dma), + ACPI_RS_SIZE(struct acpi_resource_start_dependent), + ACPI_RS_SIZE_MIN, + ACPI_RS_SIZE(struct acpi_resource_io), + ACPI_RS_SIZE(struct acpi_resource_fixed_io), + 0, + 0, + 0, + 0, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RS_SIZE_MIN, -/* - * Base sizes of resource descriptors, both the AML stream resource length - * (minus size of header and length fields),and the size of the internal - * struct representation. - */ -struct acpi_resource_info acpi_gbl_sm_resource_info[] = { - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {2, ACPI_RSMALL(struct aml_resource_irq), - ACPI_RS_SIZE(struct acpi_resource_irq)}, - {0, ACPI_RSMALL(struct aml_resource_dma), - ACPI_RS_SIZE(struct acpi_resource_dma)}, - {2, ACPI_RSMALL(struct aml_resource_start_dependent), - ACPI_RS_SIZE(struct acpi_resource_start_dependent)}, - {0, ACPI_RSMALL(struct aml_resource_end_dependent), ACPI_RS_SIZE_MIN}, - {0, ACPI_RSMALL(struct aml_resource_io), - ACPI_RS_SIZE(struct acpi_resource_io)}, - {0, ACPI_RSMALL(struct aml_resource_fixed_io), - ACPI_RS_SIZE(struct acpi_resource_fixed_io)}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {1, ACPI_RSMALL(struct aml_resource_vendor_small), - ACPI_RS_SIZE(struct acpi_resource_vendor)}, - {0, ACPI_RSMALL(struct aml_resource_end_tag), ACPI_RS_SIZE_MIN} -}; - -struct acpi_resource_info acpi_gbl_lg_resource_info[] = { - {0, 0, 0}, - {0, ACPI_RLARGE(struct aml_resource_memory24), - ACPI_RS_SIZE(struct acpi_resource_memory24)}, - {0, ACPI_RLARGE(struct aml_resource_generic_register), - ACPI_RS_SIZE(struct acpi_resource_generic_register)}, - {0, 0, 0}, - {1, ACPI_RLARGE(struct aml_resource_vendor_large), - ACPI_RS_SIZE(struct acpi_resource_vendor)}, - {0, ACPI_RLARGE(struct aml_resource_memory32), - ACPI_RS_SIZE(struct acpi_resource_memory32)}, - {0, ACPI_RLARGE(struct aml_resource_fixed_memory32), - ACPI_RS_SIZE(struct acpi_resource_fixed_memory32)}, - {1, ACPI_RLARGE(struct aml_resource_address32), - ACPI_RS_SIZE(struct acpi_resource_address32)}, - {1, ACPI_RLARGE(struct aml_resource_address16), - ACPI_RS_SIZE(struct acpi_resource_address16)}, - {1, ACPI_RLARGE(struct aml_resource_extended_irq), - ACPI_RS_SIZE(struct acpi_resource_extended_irq)}, - {1, ACPI_RLARGE(struct aml_resource_address64), - ACPI_RS_SIZE(struct acpi_resource_address64)}, - {0, ACPI_RLARGE(struct aml_resource_extended_address64), - ACPI_RS_SIZE(struct acpi_resource_extended_address64)} + /* Large descriptors */ + + 0, + ACPI_RS_SIZE(struct acpi_resource_memory24), + ACPI_RS_SIZE(struct acpi_resource_generic_register), + 0, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RS_SIZE(struct acpi_resource_memory32), + ACPI_RS_SIZE(struct acpi_resource_fixed_memory32), + ACPI_RS_SIZE(struct acpi_resource_address32), + ACPI_RS_SIZE(struct acpi_resource_address16), + ACPI_RS_SIZE(struct acpi_resource_extended_irq), + ACPI_RS_SIZE(struct acpi_resource_address64), + ACPI_RS_SIZE(struct acpi_resource_extended_address64) }; diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index ee17ef3315f8..b83996233c1d 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -47,115 +47,12 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rslist") -/* Local prototypes */ -static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 - resource_type); - -static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml); - -/******************************************************************************* - * - * FUNCTION: acpi_rs_validate_resource_length - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * - * RETURN: Status - AE_OK if the resource length appears valid - * - * DESCRIPTION: Validate the resource_length. Fixed-length descriptors must - * have the exact length; variable-length descriptors must be - * at least as long as the minimum. Certain Small descriptors - * can vary in size by at most one byte. - * - ******************************************************************************/ - -static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) -{ - struct acpi_resource_info *resource_info; - u16 minimum_aml_resource_length; - u16 resource_length; - - ACPI_FUNCTION_ENTRY(); - - /* Get the size and type info about this resource descriptor */ - - resource_info = - acpi_rs_get_resource_info(aml->small_header.descriptor_type); - if (!resource_info) { - return (AE_AML_INVALID_RESOURCE_TYPE); - } - - resource_length = acpi_ut_get_resource_length(aml); - minimum_aml_resource_length = - resource_info->minimum_aml_resource_length; - - /* Validate based upon the type of resource, fixed length or variable */ - - if (resource_info->length_type == ACPI_FIXED_LENGTH) { - /* Fixed length resource, length must match exactly */ - - if (resource_length != minimum_aml_resource_length) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } else if (resource_info->length_type == ACPI_VARIABLE_LENGTH) { - /* Variable length resource, must be at least the minimum */ - - if (resource_length < minimum_aml_resource_length) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } else { - /* Small variable length resource, allowed to be (Min) or (Min-1) */ - - if ((resource_length > minimum_aml_resource_length) || - (resource_length < (minimum_aml_resource_length - 1))) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } - - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_conversion_info - * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor - * - * RETURN: Pointer to the resource conversion info table - * - * DESCRIPTION: Get the conversion table associated with this resource type - * - ******************************************************************************/ - -static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) -{ - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (resource_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { - return (NULL); - } - - return (acpi_gbl_lg_get_resource_dispatch[(resource_type & - ACPI_RESOURCE_NAME_LARGE_MASK)]); - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - return (acpi_gbl_sm_get_resource_dispatch[((resource_type & - ACPI_RESOURCE_NAME_SMALL_MASK) - >> 3)]); - } -} - /******************************************************************************* * * FUNCTION: acpi_rs_convert_aml_to_resources * - * PARAMETERS: aml_buffer - Pointer to the resource byte stream - * aml_buffer_length - Length of aml_buffer + * PARAMETERS: Aml - Pointer to the resource byte stream + * aml_length - Length of Aml * output_buffer - Pointer to the buffer that will * contain the output structures * @@ -165,42 +62,24 @@ static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) * linked list of resources in the caller's output buffer * ******************************************************************************/ - acpi_status -acpi_rs_convert_aml_to_resources(u8 * aml_buffer, - u32 aml_buffer_length, u8 * output_buffer) +acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) { - u8 *buffer = output_buffer; + struct acpi_resource *resource = (void *)output_buffer; acpi_status status; - acpi_size bytes_parsed = 0; - struct acpi_resource *resource; - acpi_rsdesc_size descriptor_length; - struct acpi_rsconvert_info *info; + u8 resource_index; + u8 *end_aml; ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); + end_aml = aml + aml_length; + /* Loop until end-of-buffer or an end_tag is found */ - while (bytes_parsed < aml_buffer_length) { - /* Get the conversion table associated with this Descriptor Type */ + while (aml < end_aml) { + /* Validate the Resource Type and Resource Length */ - info = acpi_rs_get_conversion_info(*aml_buffer); - if (!info) { - /* No table indicates an invalid resource type */ - - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } - - descriptor_length = acpi_ut_get_descriptor_length(aml_buffer); - - /* - * Perform limited validation of the resource length, based upon - * what we know about the resource type - */ - status = - acpi_rs_validate_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + status = acpi_ut_validate_resource(aml, &resource_index); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -208,42 +87,36 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, /* Convert the AML byte stream resource to a local resource struct */ status = - acpi_rs_convert_aml_to_resource(ACPI_CAST_PTR - (struct acpi_resource, - buffer), + acpi_rs_convert_aml_to_resource(resource, ACPI_CAST_PTR(union aml_resource, - aml_buffer), - info); + aml), + acpi_gbl_get_resource_dispatch + [resource_index]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not convert AML resource (Type %X) to resource, %s\n", *aml, acpi_format_exception(status))); return_ACPI_STATUS(status); } - /* Set the aligned length of the new resource descriptor */ - - resource = ACPI_CAST_PTR(struct acpi_resource, buffer); - resource->length = - (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); - /* Normal exit on completion of an end_tag resource descriptor */ - if (acpi_ut_get_resource_type(aml_buffer) == + if (acpi_ut_get_resource_type(aml) == ACPI_RESOURCE_NAME_END_TAG) { return_ACPI_STATUS(AE_OK); } - /* Update counter and point to the next input resource */ + /* Point to the next input AML resource */ - bytes_parsed += descriptor_length; - aml_buffer += descriptor_length; + aml += acpi_ut_get_descriptor_length(aml); /* Point to the next structure in the output buffer */ - buffer += resource->length; + resource = + ACPI_PTR_ADD(struct acpi_resource, resource, + resource->length); } - /* Completed buffer, but did not find an end_tag resource descriptor */ + /* Did not find an end_tag resource descriptor */ return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } @@ -271,16 +144,16 @@ acpi_status acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, acpi_size aml_size_needed, u8 * output_buffer) { - u8 *aml_buffer = output_buffer; - u8 *end_aml_buffer = output_buffer + aml_size_needed; + u8 *aml = output_buffer; + u8 *end_aml = output_buffer + aml_size_needed; acpi_status status; ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); /* Walk the resource descriptor list, convert each descriptor */ - while (aml_buffer < end_aml_buffer) { - /* Validate the Resource Type */ + while (aml < end_aml) { + /* Validate the (internal) Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, @@ -294,7 +167,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union aml_resource, - aml_buffer), + aml), acpi_gbl_set_resource_dispatch [resource->type]); if (ACPI_FAILURE(status)) { @@ -305,9 +178,8 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Perform final sanity check on the new AML resource descriptor */ status = - acpi_rs_validate_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + acpi_ut_validate_resource(ACPI_CAST_PTR + (union aml_resource, aml), NULL); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -322,18 +194,15 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* * Extract the total length of the new descriptor and set the - * aml_buffer to point to the next (output) resource descriptor + * Aml to point to the next (output) resource descriptor */ - aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); + aml += acpi_ut_get_descriptor_length(aml); /* Point to the next input resource descriptor */ resource = ACPI_PTR_ADD(struct acpi_resource, resource, resource->length); - - /* Check for end-of-list, normal exit */ - } /* Completed buffer, but did not find an end_tag resource descriptor */ diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 7613033f5dcf..a1eac0f1df54 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -65,6 +65,8 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) acpi_native_uint i; u8 bit_count; + ACPI_FUNCTION_ENTRY(); + /* Decode the mask bits */ for (i = 0, bit_count = 0; mask; i++) { @@ -97,6 +99,8 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count) acpi_native_uint i; u16 mask; + ACPI_FUNCTION_ENTRY(); + /* Encode the list into a single bitmask */ for (i = 0, mask = 0; i < count; i++) { @@ -128,6 +132,8 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) { acpi_native_uint i; + ACPI_FUNCTION_ENTRY(); + /* One move per item */ for (i = 0; i < item_count; i++) { @@ -166,53 +172,6 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) } } -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_resource_info - * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor - * - * RETURN: Pointer to the resource conversion handler - * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. - * - ******************************************************************************/ - -struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type) -{ - struct acpi_resource_info *size_info; - - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (resource_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { - return (NULL); - } - - size_info = &acpi_gbl_lg_resource_info[(resource_type & - ACPI_RESOURCE_NAME_LARGE_MASK)]; - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - size_info = &acpi_gbl_sm_resource_info[((resource_type & - ACPI_RESOURCE_NAME_SMALL_MASK) - >> 3)]; - } - - /* Zero entry indicates an invalid resource type */ - - if (!size_info->minimum_internal_struct_length) { - return (NULL); - } - - return (size_info); -} - /******************************************************************************* * * FUNCTION: acpi_rs_set_resource_length @@ -238,25 +197,20 @@ acpi_rs_set_resource_length(acpi_rsdesc_size total_length, ACPI_FUNCTION_ENTRY(); - /* Determine if this is a small or large resource */ + /* Length is the total descriptor length minus the header length */ + + resource_length = (acpi_rs_length) + (total_length - acpi_ut_get_resource_header_length(aml)); + + /* Length is stored differently for large and small descriptors */ if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource type -- bytes 1-2 contain the 16-bit length */ - - resource_length = (acpi_rs_length) - (total_length - sizeof(struct aml_resource_large_header)); - - /* Insert length into the Large descriptor length field */ + /* Large descriptor -- bytes 1-2 contain the 16-bit length */ ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, &resource_length); } else { - /* Small Resource type -- bits 2:0 of byte 0 contain the length */ - - resource_length = (acpi_rs_length) - (total_length - sizeof(struct aml_resource_small_header)); - - /* Insert length into the descriptor type byte */ + /* Small descriptor -- bits 2:0 of byte 0 contain the length */ aml->small_header.descriptor_type = (u8) @@ -292,7 +246,7 @@ acpi_rs_set_resource_header(u8 descriptor_type, { ACPI_FUNCTION_ENTRY(); - /* Set the Descriptor Type */ + /* Set the Resource Type */ aml->small_header.descriptor_type = descriptor_type; @@ -409,14 +363,14 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length, (char *)&aml_resource_source[1]); return ((acpi_rs_length) total_length); - } else { - /* resource_source is not present */ - - resource_source->index = 0; - resource_source->string_length = 0; - resource_source->string_ptr = NULL; - return (0); } + + /* resource_source is not present */ + + resource_source->index = 0; + resource_source->string_length = 0; + resource_source->string_ptr = NULL; + return (0); } /******************************************************************************* diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile index e87108b7338a..88eff14c4894 100644 --- a/drivers/acpi/utilities/Makefile +++ b/drivers/acpi/utilities/Makefile @@ -2,7 +2,8 @@ # Makefile for all Linux ACPI interpreter subdirectories # -obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ - utcopy.o utdelete.o utglobal.o utmath.o utobject.o utstate.o utmutex.o utobject.o utcache.o +obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ + utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ + utstate.o utmutex.o utobject.o utcache.o utresrc.o EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index e9058d4da122..2a9110c06391 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -43,7 +43,6 @@ #include #include -#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") @@ -789,153 +788,6 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) return ((u8) (0 - sum)); } -/******************************************************************************* - * - * FUNCTION: acpi_ut_get_resource_type - * - * PARAMETERS: Aml - Pointer to the raw AML resource descriptor - * - * RETURN: The Resource Type with no extraneous bits (except the - * Large/Small descriptor bit -- this is left alone) - * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. - * - ******************************************************************************/ - -u8 acpi_ut_get_resource_type(void *aml) -{ - ACPI_FUNCTION_ENTRY(); - - /* - * Byte 0 contains the descriptor name (Resource Type) - * Determine if this is a small or large resource - */ - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - return (*((u8 *) aml)); - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - return ((u8) (*((u8 *) aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_get_resource_length - * - * PARAMETERS: Aml - Pointer to the raw AML resource descriptor - * - * RETURN: Byte Length - * - * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By - * definition, this does not include the size of the descriptor - * header or the length field itself. - * - ******************************************************************************/ - -u16 acpi_ut_get_resource_length(void *aml) -{ - u16 resource_length; - - ACPI_FUNCTION_ENTRY(); - - /* - * Byte 0 contains the descriptor name (Resource Type) - * Determine if this is a small or large resource - */ - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource type -- bytes 1-2 contain the 16-bit length */ - - ACPI_MOVE_16_TO_16(&resource_length, &((u8 *) aml)[1]); - - } else { - /* Small Resource type -- bits 2:0 of byte 0 contain the length */ - - resource_length = (u16) (*((u8 *) aml) & - ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); - } - - return (resource_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_get_descriptor_length - * - * PARAMETERS: Aml - Pointer to the raw AML resource descriptor - * - * RETURN: Byte length - * - * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the - * length of the descriptor header and the length field itself. - * Used to walk descriptor lists. - * - ******************************************************************************/ - -u32 acpi_ut_get_descriptor_length(void *aml) -{ - u32 descriptor_length; - - ACPI_FUNCTION_ENTRY(); - - /* First get the Resource Length (Does not include header length) */ - - descriptor_length = acpi_ut_get_resource_length(aml); - - /* Determine if this is a small or large resource */ - - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { - descriptor_length += sizeof(struct aml_resource_large_header); - } else { - descriptor_length += sizeof(struct aml_resource_small_header); - } - - return (descriptor_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_get_resource_end_tag - * - * PARAMETERS: obj_desc - The resource template buffer object - * - * RETURN: Pointer to the end tag - * - * DESCRIPTION: Find the END_TAG resource descriptor in an AML resource template - * - ******************************************************************************/ - -u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc) -{ - u8 *aml; - u8 *end_aml; - - aml = obj_desc->buffer.pointer; - end_aml = aml + obj_desc->buffer.length; - - /* Walk the resource template, one descriptor per loop */ - - while (aml < end_aml) { - if (acpi_ut_get_resource_type(aml) == - ACPI_RESOURCE_NAME_END_TAG) { - /* Found the end_tag descriptor, all done */ - - return (aml); - } - - /* Point to the next resource descriptor */ - - aml += acpi_ut_get_resource_length(aml); - } - - /* End tag was not found */ - - return (NULL); -} - /******************************************************************************* * * FUNCTION: acpi_ut_report_error diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c new file mode 100644 index 000000000000..07a314c710d8 --- /dev/null +++ b/drivers/acpi/utilities/utresrc.c @@ -0,0 +1,428 @@ +/******************************************************************************* + * + * Module Name: utresrc - Resource managment utilities + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2005, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utmisc") + +/* + * Base sizes of the raw AML resource descriptors, indexed by resource type. + * Zero indicates a reserved (and therefore invalid) resource type. + */ +const u8 acpi_gbl_resource_aml_sizes[] = { + /* Small descriptors */ + + 0, + 0, + 0, + 0, + ACPI_AML_SIZE_SMALL(struct aml_resource_irq), + ACPI_AML_SIZE_SMALL(struct aml_resource_dma), + ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent), + ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent), + ACPI_AML_SIZE_SMALL(struct aml_resource_io), + ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io), + 0, + 0, + 0, + 0, + ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small), + ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag), + + /* Large descriptors */ + + 0, + ACPI_AML_SIZE_LARGE(struct aml_resource_memory24), + ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register), + 0, + ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large), + ACPI_AML_SIZE_LARGE(struct aml_resource_memory32), + ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32), + ACPI_AML_SIZE_LARGE(struct aml_resource_address32), + ACPI_AML_SIZE_LARGE(struct aml_resource_address16), + ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq), + ACPI_AML_SIZE_LARGE(struct aml_resource_address64), + ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64) +}; + +/* + * Resource types, used to validate the resource length field. + * The length of fixed-length types must match exactly, variable + * lengths must meet the minimum required length, etc. + * Zero indicates a reserved (and therefore invalid) resource type. + */ +static const u8 acpi_gbl_resource_types[] = { + /* Small descriptors */ + + 0, + 0, + 0, + 0, + ACPI_SMALL_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_SMALL_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_FIXED_LENGTH, + 0, + 0, + 0, + 0, + ACPI_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH, + + /* Large descriptors */ + + 0, + ACPI_FIXED_LENGTH, + ACPI_FIXED_LENGTH, + 0, + ACPI_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_VARIABLE_LENGTH, + ACPI_VARIABLE_LENGTH, + ACPI_VARIABLE_LENGTH, + ACPI_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ut_validate_resource + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * return_index - Where the resource index is returned. NULL + * if the index is not required. + * + * RETURN: Status, and optionally the Index into the global resource tables + * + * DESCRIPTION: Validate an AML resource descriptor by checking the Resource + * Type and Resource Length. Returns an index into the global + * resource information/dispatch tables for later use. + * + ******************************************************************************/ + +acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index) +{ + u8 resource_type; + u8 resource_index; + acpi_rs_length resource_length; + acpi_rs_length minimum_resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* + * 1) Validate the resource_type field (Byte 0) + */ + resource_type = *((u8 *) aml); + + /* + * Byte 0 contains the descriptor name (Resource Type) + * Examine the large/small bit in the resource header + */ + if (resource_type & ACPI_RESOURCE_NAME_LARGE) { + /* Verify the large resource type (name) against the max */ + + if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { + return (AE_AML_INVALID_RESOURCE_TYPE); + } + + /* + * Large Resource Type -- bits 6:0 contain the name + * Translate range 0x80-0x8B to index range 0x10-0x1B + */ + resource_index = (u8) (resource_type - 0x70); + } else { + /* + * Small Resource Type -- bits 6:3 contain the name + * Shift range to index range 0x00-0x0F + */ + resource_index = (u8) + ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); + } + + /* Check validity of the resource type, zero indicates name is invalid */ + + if (!acpi_gbl_resource_types[resource_index]) { + return (AE_AML_INVALID_RESOURCE_TYPE); + } + + /* + * 2) Validate the resource_length field. This ensures that the length + * is at least reasonable, and guarantees that it is non-zero. + */ + resource_length = acpi_ut_get_resource_length(aml); + minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index]; + + /* Validate based upon the type of resource - fixed length or variable */ + + switch (acpi_gbl_resource_types[resource_index]) { + case ACPI_FIXED_LENGTH: + + /* Fixed length resource, length must match exactly */ + + if (resource_length != minimum_resource_length) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + break; + + case ACPI_VARIABLE_LENGTH: + + /* Variable length resource, length must be at least the minimum */ + + if (resource_length < minimum_resource_length) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + break; + + case ACPI_SMALL_VARIABLE_LENGTH: + + /* Small variable length resource, length can be (Min) or (Min-1) */ + + if ((resource_length > minimum_resource_length) || + (resource_length < (minimum_resource_length - 1))) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + break; + + default: + + /* Shouldn't happen (because of validation earlier), but be sure */ + + return (AE_AML_INVALID_RESOURCE_TYPE); + } + + /* Optionally return the resource table index */ + + if (return_index) { + *return_index = resource_index; + } + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_type + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: The Resource Type with no extraneous bits (except the + * Large/Small descriptor bit -- this is left alone) + * + * DESCRIPTION: Extract the Resource Type/Name from the first byte of + * a resource descriptor. + * + ******************************************************************************/ + +u8 acpi_ut_get_resource_type(void *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* + * Byte 0 contains the descriptor name (Resource Type) + * Examine the large/small bit in the resource header + */ + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ + + return (*((u8 *) aml)); + } else { + /* Small Resource Type -- bits 6:3 contain the name */ + + return ((u8) (*((u8 *) aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Byte Length + * + * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By + * definition, this does not include the size of the descriptor + * header or the length field itself. + * + ******************************************************************************/ + +u16 acpi_ut_get_resource_length(void *aml) +{ + acpi_rs_length resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* + * Byte 0 contains the descriptor name (Resource Type) + * Examine the large/small bit in the resource header + */ + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource type -- bytes 1-2 contain the 16-bit length */ + + ACPI_MOVE_16_TO_16(&resource_length, &((u8 *) aml)[1]); + + } else { + /* Small Resource type -- bits 2:0 of byte 0 contain the length */ + + resource_length = (u16) (*((u8 *) aml) & + ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); + } + + return (resource_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_header_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Length of the AML header (depends on large/small descriptor) + * + * DESCRIPTION: Get the length of the header for this resource. + * + ******************************************************************************/ + +u8 acpi_ut_get_resource_header_length(void *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* Examine the large/small bit in the resource header */ + + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + return (sizeof(struct aml_resource_large_header)); + } else { + return (sizeof(struct aml_resource_small_header)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_descriptor_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Byte length + * + * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the + * length of the descriptor header and the length field itself. + * Used to walk descriptor lists. + * + ******************************************************************************/ + +u32 acpi_ut_get_descriptor_length(void *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* + * Get the Resource Length (does not include header length) and add + * the header length (depends on if this is a small or large resource) + */ + return (acpi_ut_get_resource_length(aml) + + acpi_ut_get_resource_header_length(aml)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_end_tag + * + * PARAMETERS: obj_desc - The resource template buffer object + * + * RETURN: Pointer to the end tag + * + * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template + * + ******************************************************************************/ + +acpi_status +acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc, + u8 ** end_tag) +{ + acpi_status status; + u8 *aml; + u8 *end_aml; + + ACPI_FUNCTION_TRACE("ut_get_resource_end_tag"); + + /* Get start and end pointers */ + + aml = obj_desc->buffer.pointer; + end_aml = aml + obj_desc->buffer.length; + + /* Walk the resource template, one descriptor per iteration */ + + while (aml < end_aml) { + /* Validate the Resource Type and Resource Length */ + + status = acpi_ut_validate_resource(aml, NULL); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* end_tag resource indicates the end of the resource template */ + + if (acpi_ut_get_resource_type(aml) == + ACPI_RESOURCE_NAME_END_TAG) { + /* Return the pointer to the end_tag */ + + *end_tag = aml; + return_ACPI_STATUS(AE_OK); + } + + /* + * Point to the next resource descriptor in the AML buffer. The + * descriptor length is guaranteed to be non-zero by resource + * validation above. + */ + aml += acpi_ut_get_descriptor_length(aml); + } + + /* Did not find an end_tag resource descriptor */ + + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); +} diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c index c1cb27583be8..6ff1d7073349 100644 --- a/drivers/acpi/utilities/utstate.c +++ b/drivers/acpi/utilities/utstate.c @@ -63,7 +63,7 @@ acpi_status acpi_ut_create_pkg_state_and_push(void *internal_object, void *external_object, u16 index, - union acpi_generic_state ** state_list) + union acpi_generic_state **state_list) { union acpi_generic_state *state; diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index f06bd5e5e9d1..57adc5bc02f3 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c @@ -178,10 +178,14 @@ acpi_status acpi_enable_subsystem(u32 flags) /* * Initialize ACPI Event handling (Fixed and General Purpose) * - * NOTE: We must have the hardware AND events initialized before we can - * execute ANY control methods SAFELY. Any control method can require - * ACPI hardware support, so the hardware MUST be initialized before - * execution! + * Note1: We must have the hardware and events initialized before we can + * execute any control methods safely. Any control method can require + * ACPI hardware support, so the hardware must be fully initialized before + * any method execution! + * + * Note2: Fixed events are initialized and enabled here. GPEs are + * initialized, but cannot be enabled until after the hardware is + * completely initialized (SCI and global_lock activated) */ if (!(flags & ACPI_NO_EVENT_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -193,8 +197,10 @@ acpi_status acpi_enable_subsystem(u32 flags) } } - /* Install the SCI handler and Global Lock handler */ - + /* + * Install the SCI handler and Global Lock handler. This completes the + * hardware initialization. + */ if (!(flags & ACPI_NO_HANDLER_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n")); @@ -205,6 +211,24 @@ acpi_status acpi_enable_subsystem(u32 flags) } } + /* + * Complete the GPE initialization for the GPE blocks defined in the FADT + * (GPE block 0 and 1). + * + * Note1: This is where the _PRW methods are executed for the GPEs. These + * methods can only be executed after the SCI and Global Lock handlers are + * installed and initialized. + * + * Note2: Currently, there seems to be no need to run the _REG methods + * before execution of the _PRW methods and enabling of the GPEs. + */ + if (!(flags & ACPI_NO_EVENT_INIT)) { + status = acpi_ev_install_fadt_gpes(); + if (ACPI_FAILURE(status)) { + return (status); + } + } + return_ACPI_STATUS(status); } @@ -230,9 +254,9 @@ acpi_status acpi_initialize_objects(u32 flags) /* * Run all _REG methods * - * NOTE: Any objects accessed - * by the _REG methods will be automatically initialized, even if they - * contain executable AML (see call to acpi_ns_initialize_objects below). + * Note: Any objects accessed by the _REG methods will be automatically + * initialized, even if they contain executable AML (see the call to + * acpi_ns_initialize_objects below). */ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -245,9 +269,9 @@ acpi_status acpi_initialize_objects(u32 flags) } /* - * Initialize the objects that remain uninitialized. This - * runs the executable AML that may be part of the declaration of these - * objects: operation_regions, buffer_fields, Buffers, and Packages. + * Initialize the objects that remain uninitialized. This runs the + * executable AML that may be part of the declaration of these objects: + * operation_regions, buffer_fields, Buffers, and Packages. */ if (!(flags & ACPI_NO_OBJECT_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -260,8 +284,8 @@ acpi_status acpi_initialize_objects(u32 flags) } /* - * Initialize all device objects in the namespace - * This runs the _STA and _INI methods. + * Initialize all device objects in the namespace. This runs the device + * _STA and _INI methods. */ if (!(flags & ACPI_NO_DEVICE_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 7676afec09a2..d371ec6b9812 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20051021 +#define ACPI_CA_VERSION 0x20051102 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h index bfa54600ecd9..b40062c3ba7a 100644 --- a/include/acpi/acevents.h +++ b/include/acpi/acevents.h @@ -51,6 +51,8 @@ acpi_status acpi_ev_initialize_events(void); acpi_status acpi_ev_install_xrupt_handlers(void); +acpi_status acpi_ev_install_fadt_gpes(void); + u32 acpi_ev_fixed_event_detect(void); /* @@ -105,6 +107,10 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, u32 interrupt_number, struct acpi_gpe_block_info **return_gpe_block); +acpi_status +acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, + struct acpi_gpe_block_info *gpe_block); + acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); u32 diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h index 2c9c1a1d1b7f..87e5e44572ca 100644 --- a/include/acpi/acinterp.h +++ b/include/acpi/acinterp.h @@ -44,7 +44,49 @@ #ifndef __ACINTERP_H__ #define __ACINTERP_H__ -#define ACPI_WALK_OPERANDS (&(walk_state->operands [walk_state->num_operands -1])) +#define ACPI_WALK_OPERANDS (&(walk_state->operands [walk_state->num_operands -1])) + +/* Macros for tables used for debug output */ + +#define ACPI_EXD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_operand_object,f) +#define ACPI_EXD_NSOFFSET(f) (u8) ACPI_OFFSET (struct acpi_namespace_node,f) +#define ACPI_EXD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_exdump_info)) + +/* + * If possible, pack the following structure to byte alignment, since we + * don't care about performance for debug output + */ +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED +#pragma pack(1) +#endif + +typedef const struct acpi_exdump_info { + u8 opcode; + u8 offset; + char *name; + +} acpi_exdump_info; + +/* Values for the Opcode field above */ + +#define ACPI_EXD_INIT 0 +#define ACPI_EXD_TYPE 1 +#define ACPI_EXD_UINT8 2 +#define ACPI_EXD_UINT16 3 +#define ACPI_EXD_UINT32 4 +#define ACPI_EXD_UINT64 5 +#define ACPI_EXD_LITERAL 6 +#define ACPI_EXD_POINTER 7 +#define ACPI_EXD_ADDRESS 8 +#define ACPI_EXD_STRING 9 +#define ACPI_EXD_BUFFER 10 +#define ACPI_EXD_PACKAGE 11 +#define ACPI_EXD_FIELD 12 +#define ACPI_EXD_REFERENCE 13 + +/* restore default alignment */ + +#pragma pack() /* * exconvrt - object conversion @@ -327,7 +369,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, void acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags); -void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags); +void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags); #endif /* ACPI_FUTURE_USAGE */ /* diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h index 25cff0d5ba58..2bf53940f259 100644 --- a/include/acpi/acresrc.h +++ b/include/acpi/acresrc.h @@ -101,27 +101,11 @@ typedef const struct acpi_rsconvert_info { #define ACPI_RS_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_resource,f) #define AML_OFFSET(f) (u8) ACPI_OFFSET (union aml_resource,f) -/* - * Resource dispatch and info tables - */ -typedef const struct acpi_resource_info { - u8 length_type; - u8 minimum_aml_resource_length; - u8 minimum_internal_struct_length; - -} acpi_resource_info; - -/* Types for length_type above */ - -#define ACPI_FIXED_LENGTH 0 -#define ACPI_VARIABLE_LENGTH 1 -#define ACPI_SMALL_VARIABLE_LENGTH 2 - typedef const struct acpi_rsdump_info { u8 opcode; u8 offset; char *name; - const void *pointer; + const char **pointer; } acpi_rsdump_info; @@ -153,10 +137,9 @@ extern struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[]; /* Resource tables indexed by raw AML resource descriptor type */ -extern struct acpi_resource_info acpi_gbl_sm_resource_info[]; -extern struct acpi_resource_info acpi_gbl_lg_resource_info[]; -extern struct acpi_rsconvert_info *acpi_gbl_sm_get_resource_dispatch[]; -extern struct acpi_rsconvert_info *acpi_gbl_lg_get_resource_dispatch[]; +extern struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[]; + +extern const u8 acpi_gbl_resource_struct_sizes[]; /* * rscreate @@ -272,8 +255,6 @@ void acpi_rs_set_resource_length(acpi_rsdesc_size total_length, union aml_resource *aml); -struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type); - /* * rsdump */ diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index 7386eb81bd2a..4ff963323de3 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -44,6 +44,15 @@ #ifndef _ACUTILS_H #define _ACUTILS_H +extern const u8 acpi_gbl_resource_aml_sizes[]; + +/* Types for Resource descriptor entries */ + +#define ACPI_INVALID_RESOURCE 0 +#define ACPI_FIXED_LENGTH 1 +#define ACPI_VARIABLE_LENGTH 2 +#define ACPI_SMALL_VARIABLE_LENGTH 3 + typedef acpi_status(*acpi_pkg_callback) (u8 object_type, union acpi_operand_object * source_object, @@ -418,13 +427,19 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); #define ACPI_ANY_BASE 0 +acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index); + u32 acpi_ut_get_descriptor_length(void *aml); u16 acpi_ut_get_resource_length(void *aml); +u8 acpi_ut_get_resource_header_length(void *aml); + u8 acpi_ut_get_resource_type(void *aml); -u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc); +acpi_status +acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, + u8 ** end_tag); u8 acpi_ut_generate_checksum(u8 * buffer, u32 length); diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h index 3112be527731..2e3382c1e5e3 100644 --- a/include/acpi/amlresrc.h +++ b/include/acpi/amlresrc.h @@ -92,6 +92,11 @@ struct asl_resource_node { struct asl_resource_node *next; }; +/* Macros used to generate AML resource length fields */ + +#define ACPI_AML_SIZE_LARGE(r) (sizeof (r) - sizeof (struct aml_resource_large_header)) +#define ACPI_AML_SIZE_SMALL(r) (sizeof (r) - sizeof (struct aml_resource_small_header)) + /* * Resource descriptors defined in the ACPI specification. * From c51a4de85de720670f2fbc592a6f8040af72ad87 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 17 Nov 2005 13:07:00 -0500 Subject: [PATCH 017/695] [ACPI] ACPICA 20051117 Fixed a problem in the AML parser where the method thread count could be decremented below zero if any errors occurred during the method parse phase. This should eliminate AE_AML_METHOD_LIMIT exceptions seen on some machines. This also fixed a related regression with the mechanism that detects and corrects methods that cannot properly handle reentrancy (related to the deployment of the new OwnerId mechanism.) Eliminated the pre-parsing of control methods (to detect errors) during table load. Related to the problem above, this was causing unwind issues if any errors occurred during the parse, and it seemed to be overkill. A table load should not be aborted if there are problems with any single control method, thus rendering this feature rather pointless. Fixed a problem with the new table-driven resource manager where an internal buffer overflow could occur for small resource templates. Implemented a new external interface, acpi_get_vendor_resource() This interface will find and return a vendor-defined resource descriptor within a _CRS or _PRS method via an ACPI 3.0 UUID match. (from Bjorn Helgaas) Removed the length limit (200) on string objects as per the upcoming ACPI 3.0A specification. This affects the following areas of the interpreter: 1) any implicit conversion of a Buffer to a String, 2) a String object result of the ASL Concatentate operator, 3) the String object result of the ASL ToString operator. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsinit.c | 25 ++-- drivers/acpi/dispatcher/dswload.c | 2 +- drivers/acpi/executer/exconvrt.c | 12 +- drivers/acpi/executer/exdump.c | 15 ++- drivers/acpi/executer/exmisc.c | 38 +++--- drivers/acpi/executer/exnames.c | 2 +- drivers/acpi/executer/exoparg2.c | 10 +- drivers/acpi/executer/exregion.c | 16 +-- drivers/acpi/executer/exstorob.c | 4 +- drivers/acpi/parser/psargs.c | 152 +++++++++++----------- drivers/acpi/parser/psparse.c | 35 +++-- drivers/acpi/parser/psxface.c | 2 +- drivers/acpi/resources/rscalc.c | 14 +- drivers/acpi/resources/rsdump.c | 24 ++-- drivers/acpi/resources/rslist.c | 4 +- drivers/acpi/resources/rsmisc.c | 92 ++++++------- drivers/acpi/resources/rsutils.c | 22 ++-- drivers/acpi/resources/rsxface.c | 208 +++++++++++++++++++++++------- drivers/acpi/scan.c | 2 +- drivers/acpi/tables/tbconvrt.c | 4 +- drivers/acpi/tables/tbgetall.c | 4 +- drivers/acpi/tables/tbutils.c | 8 +- drivers/acpi/utilities/utcopy.c | 19 +-- drivers/acpi/utilities/utglobal.c | 4 +- drivers/acpi/utilities/utmisc.c | 34 +++-- drivers/acpi/utilities/utresrc.c | 19 +-- include/acpi/acconfig.h | 14 +- include/acpi/acglobal.h | 1 + include/acpi/aclocal.h | 4 +- include/acpi/acmacros.h | 27 +++- include/acpi/acpixf.h | 8 +- include/acpi/acresrc.h | 7 +- include/acpi/actypes.h | 23 +++- include/acpi/platform/aclinux.h | 4 + 34 files changed, 515 insertions(+), 344 deletions(-) diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index 8693c704aea6..4fa80abfe6c0 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.c @@ -117,14 +117,6 @@ acpi_ds_init_one_object(acpi_handle obj_handle, case ACPI_TYPE_METHOD: - /* - * Print a dot for each method unless we are going to print - * the entire pathname - */ - if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { - ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); - } - /* * Set the execution data width (32 or 64) based upon the * revision number of the parent ACPI table. @@ -134,6 +126,21 @@ acpi_ds_init_one_object(acpi_handle obj_handle, if (info->table_desc->pointer->revision == 1) { node->flags |= ANOBJ_DATA_WIDTH_32; } +#ifdef ACPI_INIT_PARSE_METHODS + /* + * Note 11/2005: Removed this code to parse all methods during table + * load because it causes problems if there are any errors during the + * parse. Also, it seems like overkill and we probably don't want to + * abort a table load because of an issue with a single method. + */ + + /* + * Print a dot for each method unless we are going to print + * the entire pathname + */ + if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); + } /* * Always parse methods to detect errors, we will delete @@ -149,7 +156,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, /* This parse failed, but we will continue parsing more methods */ } - +#endif info->method_count++; break; diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 411731261c29..89d318cbc8a3 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -311,7 +311,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, op->named.name = node->name.integer; #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)) - op->named.path = (u8 *) path; + op->named.path = ACPI_CAST_PTR(u8, path); #endif /* diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index 04e5194989a6..fa9e75d4ec65 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c @@ -504,18 +504,12 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, } /* - * Perform the conversion. + * Create a new string object and string buffer * (-1 because of extra separator included in string_length from above) */ - string_length--; - if (string_length > ACPI_MAX_STRING_CONVERSION) { /* ACPI limit */ - return_ACPI_STATUS(AE_AML_STRING_LIMIT); - } - - /* Create a new string object and string buffer */ - return_desc = - acpi_ut_create_string_object((acpi_size) string_length); + acpi_ut_create_string_object((acpi_size) + (string_length - 1)); if (!return_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 5a4cca171af6..17c79cd91b31 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -117,12 +117,13 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = { {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.semaphore), "Semaphore"} }; -static struct acpi_exdump_info acpi_ex_dump_method[7] = { +static struct acpi_exdump_info acpi_ex_dump_method[8] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "param_count"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.concurrency), "Concurrency"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.semaphore), "Semaphore"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.thread_count), "Thread Count"}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(method.aml_length), "Aml Length"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} }; @@ -339,7 +340,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, count = info->offset; while (count) { - target = ((u8 *) obj_desc) + info->offset; + target = ACPI_ADD_PTR(u8, obj_desc, info->offset); name = info->name; switch (info->opcode) { @@ -360,20 +361,19 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, case ACPI_EXD_UINT16: acpi_os_printf("%20s : %4.4X\n", name, - *ACPI_CAST_PTR(u16, target)); + ACPI_GET16(target)); break; case ACPI_EXD_UINT32: acpi_os_printf("%20s : %8.8X\n", name, - *ACPI_CAST_PTR(u32, target)); + ACPI_GET32(target)); break; case ACPI_EXD_UINT64: acpi_os_printf("%20s : %8.8X%8.8X\n", "Value", - ACPI_FORMAT_UINT64(*ACPI_CAST_PTR - (u64, target))); + ACPI_FORMAT_UINT64(ACPI_GET64(target))); break; case ACPI_EXD_POINTER: @@ -969,7 +969,8 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, acpi_os_printf("[Buffer] Length %.2X = ", obj_desc->buffer.length); if (obj_desc->buffer.length) { - acpi_ut_dump_buffer((u8 *) obj_desc->buffer.pointer, + acpi_ut_dump_buffer(ACPI_CAST_PTR + (u8, obj_desc->buffer.pointer), obj_desc->buffer.length, DB_DWORD_DISPLAY, _COMPONENT); } else { diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 00a25f8188f4..0778bff632bf 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -205,11 +205,9 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0); ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1); - /* Compute the new checksum */ + /* Set the end_tag checksum to zero, means "ignore checksum" */ - new_buf[return_desc->buffer.length - 1] = - acpi_ut_generate_checksum(return_desc->buffer.pointer, - (return_desc->buffer.length - 1)); + new_buf[return_desc->buffer.length - 1] = 0; /* Return the completed resource template */ @@ -242,7 +240,6 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, union acpi_operand_object *return_desc; char *new_buf; acpi_status status; - acpi_size new_length; ACPI_FUNCTION_TRACE("ex_do_concatenate"); @@ -269,7 +266,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, break; default: - ACPI_REPORT_ERROR(("Concat - invalid obj type: %X\n", + ACPI_REPORT_ERROR(("Concatanate - invalid object type: %X\n", ACPI_GET_OBJECT_TYPE(operand0))); status = AE_AML_INTERNAL; } @@ -309,8 +306,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, /* Copy the first integer, LSB first */ - ACPI_MEMCPY(new_buf, - &operand0->integer.value, + ACPI_MEMCPY(new_buf, &operand0->integer.value, acpi_gbl_integer_byte_width); /* Copy the second integer (LSB first) after the first */ @@ -324,14 +320,11 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, /* Result of two Strings is a String */ - new_length = (acpi_size) operand0->string.length + - (acpi_size) local_operand1->string.length; - if (new_length > ACPI_MAX_STRING_CONVERSION) { - status = AE_AML_STRING_LIMIT; - goto cleanup; - } - - return_desc = acpi_ut_create_string_object(new_length); + return_desc = acpi_ut_create_string_object((acpi_size) + (operand0->string. + length + + local_operand1-> + string.length)); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -351,11 +344,10 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, /* Result of two Buffers is a Buffer */ return_desc = acpi_ut_create_buffer_object((acpi_size) - operand0->buffer. - length + - (acpi_size) - local_operand1-> - buffer.length); + (operand0->buffer. + length + + local_operand1-> + buffer.length)); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -365,8 +357,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, /* Concatenate the buffers */ - ACPI_MEMCPY(new_buf, - operand0->buffer.pointer, operand0->buffer.length); + ACPI_MEMCPY(new_buf, operand0->buffer.pointer, + operand0->buffer.length); ACPI_MEMCPY(new_buf + operand0->buffer.length, local_operand1->buffer.pointer, local_operand1->buffer.length); diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c index dff41121a304..7bb5e17b5680 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/executer/exnames.c @@ -216,7 +216,7 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) *aml_address, aml_address)); } - *in_aml_address = (u8 *) aml_address; + *in_aml_address = ACPI_CAST_PTR(u8, aml_address); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 8d70c6beef00..d8472842c1fd 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c @@ -344,10 +344,6 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) (length < operand[1]->integer.value) && (operand[0]->buffer.pointer[length])) { length++; - if (length > ACPI_MAX_STRING_CONVERSION) { - status = AE_AML_STRING_LIMIT; - goto cleanup; - } } /* Allocate a new string object */ @@ -358,8 +354,10 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) goto cleanup; } - /* Copy the raw buffer data with no transform. NULL terminated already */ - + /* + * Copy the raw buffer data with no transform. + * (NULL terminated already) + */ ACPI_MEMCPY(return_desc->string.pointer, operand[0]->buffer.pointer, length); break; diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 1897379b5f90..80118be3f544 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c @@ -199,20 +199,20 @@ acpi_ex_system_memory_space_handler(u32 function, *value = 0; switch (bit_width) { case 8: - *value = (acpi_integer) * ((u8 *) logical_addr_ptr); + *value = (acpi_integer) ACPI_GET8(logical_addr_ptr); break; case 16: - *value = (acpi_integer) * ((u16 *) logical_addr_ptr); + *value = (acpi_integer) ACPI_GET16(logical_addr_ptr); break; case 32: - *value = (acpi_integer) * ((u32 *) logical_addr_ptr); + *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); break; #if ACPI_MACHINE_WIDTH != 16 case 64: - *value = (acpi_integer) * ((u64 *) logical_addr_ptr); + *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); break; #endif default: @@ -225,20 +225,20 @@ acpi_ex_system_memory_space_handler(u32 function, switch (bit_width) { case 8: - *(u8 *) logical_addr_ptr = (u8) * value; + ACPI_SET8(logical_addr_ptr) = (u8) * value; break; case 16: - *(u16 *) logical_addr_ptr = (u16) * value; + ACPI_SET16(logical_addr_ptr) = (u16) * value; break; case 32: - *(u32 *) logical_addr_ptr = (u32) * value; + ACPI_SET32(logical_addr_ptr) = (u32) * value; break; #if ACPI_MACHINE_WIDTH != 16 case 64: - *(u64 *) logical_addr_ptr = (u64) * value; + ACPI_SET64(logical_addr_ptr) = (u64) * value; break; #endif diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c index c4ff654a6697..855db7130751 100644 --- a/drivers/acpi/executer/exstorob.c +++ b/drivers/acpi/executer/exstorob.c @@ -71,7 +71,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, /* We know that source_desc is a buffer by now */ - buffer = (u8 *) source_desc->buffer.pointer; + buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer); length = source_desc->buffer.length; /* @@ -160,7 +160,7 @@ acpi_ex_store_string_to_string(union acpi_operand_object *source_desc, /* We know that source_desc is a string by now */ - buffer = (u8 *) source_desc->string.pointer; + buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer); length = source_desc->string.length; /* diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 562d0f822ab1..6eae35febccd 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -62,61 +62,51 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state * * PARAMETERS: parser_state - Current parser state object * - * RETURN: Decoded package length. On completion, the AML pointer points + * RETURN: Decoded package length. On completion, the AML pointer points * past the length byte or bytes. * - * DESCRIPTION: Decode and return a package length field + * DESCRIPTION: Decode and return a package length field. + * Note: Largest package length is 28 bits, from ACPI specification * ******************************************************************************/ static u32 acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) { - u32 encoded_length; - u32 length = 0; + u8 *aml = parser_state->aml; + u32 package_length = 0; + acpi_native_uint byte_count; + u8 byte_zero_mask = 0x3F; /* Default [0:5] */ ACPI_FUNCTION_TRACE("ps_get_next_package_length"); - encoded_length = (u32) ACPI_GET8(parser_state->aml); - parser_state->aml++; + /* + * Byte 0 bits [6:7] contain the number of additional bytes + * used to encode the package length, either 0,1,2, or 3 + */ + byte_count = (aml[0] >> 6); + parser_state->aml += (byte_count + 1); - switch (encoded_length >> 6) { /* bits 6-7 contain encoding scheme */ - case 0: /* 1-byte encoding (bits 0-5) */ + /* Get bytes 3, 2, 1 as needed */ - length = (encoded_length & 0x3F); - break; + while (byte_count) { + /* + * Final bit positions for the package length bytes: + * Byte3->[20:27] + * Byte2->[12:19] + * Byte1->[04:11] + * Byte0->[00:03] + */ + package_length |= (aml[byte_count] << ((byte_count << 3) - 4)); - case 1: /* 2-byte encoding (next byte + bits 0-3) */ - - length = ((ACPI_GET8(parser_state->aml) << 04) | - (encoded_length & 0x0F)); - parser_state->aml++; - break; - - case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */ - - length = ((ACPI_GET8(parser_state->aml + 1) << 12) | - (ACPI_GET8(parser_state->aml) << 04) | - (encoded_length & 0x0F)); - parser_state->aml += 2; - break; - - case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */ - - length = ((ACPI_GET8(parser_state->aml + 2) << 20) | - (ACPI_GET8(parser_state->aml + 1) << 12) | - (ACPI_GET8(parser_state->aml) << 04) | - (encoded_length & 0x0F)); - parser_state->aml += 3; - break; - - default: - - /* Can't get here, only 2 bits / 4 cases */ - break; + byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */ + byte_count--; } - return_UINT32(length); + /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ + + package_length |= (aml[0] & byte_zero_mask); + return_UINT32(package_length); } /******************************************************************************* @@ -135,16 +125,15 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) { u8 *start = parser_state->aml; - acpi_native_uint length; + u32 package_length; ACPI_FUNCTION_TRACE("ps_get_next_package_end"); - /* Function below changes parser_state->Aml */ + /* Function below updates parser_state->Aml */ - length = - (acpi_native_uint) acpi_ps_get_next_package_length(parser_state); + package_length = acpi_ps_get_next_package_length(parser_state); - return_PTR(start + length); /* end of package */ + return_PTR(start + package_length); /* end of package */ } /******************************************************************************* @@ -169,17 +158,15 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) ACPI_FUNCTION_TRACE("ps_get_next_namestring"); - /* Handle multiple prefix characters */ - - while (acpi_ps_is_prefix_char(ACPI_GET8(end))) { - /* Include prefix '\\' or '^' */ + /* Point past any namestring prefix characters (backslash or carat) */ + while (acpi_ps_is_prefix_char(*end)) { end++; } - /* Decode the path */ + /* Decode the path prefix character */ - switch (ACPI_GET8(end)) { + switch (*end) { case 0: /* null_name */ @@ -199,9 +186,9 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) case AML_MULTI_NAME_PREFIX_OP: - /* Multiple name segments, 4 chars each */ + /* Multiple name segments, 4 chars each, count in next byte */ - end += 2 + ((acpi_size) ACPI_GET8(end + 1) * ACPI_NAME_SIZE); + end += 2 + (*(end + 1) * ACPI_NAME_SIZE); break; default: @@ -212,7 +199,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) break; } - parser_state->aml = (u8 *) end; + parser_state->aml = end; return_PTR((char *)start); } @@ -342,7 +329,6 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, ("search_node %p start_node %p return_node %p\n", scope_info.scope.node, parser_state->start_node, node); - } else { /* * We got a NOT_FOUND during table load or we encountered @@ -382,59 +368,63 @@ void acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, u32 arg_type, union acpi_parse_object *arg) { + u32 length; + u16 opcode; + u8 *aml = parser_state->aml; ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type); switch (arg_type) { case ARGP_BYTEDATA: - acpi_ps_init_op(arg, AML_BYTE_OP); - arg->common.value.integer = (u32) ACPI_GET8(parser_state->aml); - parser_state->aml++; + /* Get 1 byte from the AML stream */ + + opcode = AML_BYTE_OP; + arg->common.value.integer = (acpi_integer) * aml; + length = 1; break; case ARGP_WORDDATA: - acpi_ps_init_op(arg, AML_WORD_OP); - /* Get 2 bytes from the AML stream */ - ACPI_MOVE_16_TO_32(&arg->common.value.integer, - parser_state->aml); - parser_state->aml += 2; + opcode = AML_WORD_OP; + ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml); + length = 2; break; case ARGP_DWORDDATA: - acpi_ps_init_op(arg, AML_DWORD_OP); - /* Get 4 bytes from the AML stream */ - ACPI_MOVE_32_TO_32(&arg->common.value.integer, - parser_state->aml); - parser_state->aml += 4; + opcode = AML_DWORD_OP; + ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml); + length = 4; break; case ARGP_QWORDDATA: - acpi_ps_init_op(arg, AML_QWORD_OP); - /* Get 8 bytes from the AML stream */ - ACPI_MOVE_64_TO_64(&arg->common.value.integer, - parser_state->aml); - parser_state->aml += 8; + opcode = AML_QWORD_OP; + ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml); + length = 8; break; case ARGP_CHARLIST: - acpi_ps_init_op(arg, AML_STRING_OP); - arg->common.value.string = (char *)parser_state->aml; + /* Get a pointer to the string, point past the string */ - while (ACPI_GET8(parser_state->aml) != '\0') { - parser_state->aml++; + opcode = AML_STRING_OP; + arg->common.value.string = ACPI_CAST_PTR(char, aml); + + /* Find the null terminator */ + + length = 0; + while (aml[length]) { + length++; } - parser_state->aml++; + length++; break; case ARGP_NAME: @@ -443,14 +433,16 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); arg->common.value.name = acpi_ps_get_next_namestring(parser_state); - break; + return_VOID; default: ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type)); - break; + return_VOID; } + acpi_ps_init_op(arg, opcode); + parser_state->aml += length; return_VOID; } @@ -540,7 +532,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state * access_type is first operand, access_attribute is second */ field->common.value.integer = - (ACPI_GET8(parser_state->aml) << 8); + (((u32) ACPI_GET8(parser_state->aml) << 8)); parser_state->aml++; field->common.value.integer |= ACPI_GET8(parser_state->aml); parser_state->aml++; diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 76d4d640d83c..7cfa7eb0dfc7 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -503,22 +503,23 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) } else if (status == AE_CTRL_TERMINATE) { status = AE_OK; } else if ((status != AE_OK) && (walk_state->method_desc)) { - ACPI_REPORT_METHOD_ERROR("Method execution failed", - walk_state->method_node, NULL, - status); + /* Either the method parse or actual execution failed */ - /* Ensure proper cleanup */ - - walk_state->parse_flags |= ACPI_PARSE_EXECUTE; + ACPI_REPORT_METHOD_ERROR + ("Method parse/execution failed", + walk_state->method_node, NULL, status); /* Check for possible multi-thread reentrancy problem */ if ((status == AE_ALREADY_EXISTS) && (!walk_state->method_desc->method.semaphore)) { /* - * This method is marked not_serialized, but it tried to create + * Method tried to create an object twice. The probable cause is + * that the method cannot handle reentrancy. + * + * The method is marked not_serialized, but it tried to create * a named object, causing the second thread entrance to fail. - * We will workaround this by marking the method permanently + * Workaround this problem by marking the method permanently * as Serialized. */ walk_state->method_desc->method.method_flags |= @@ -536,15 +537,22 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) acpi_ds_scope_stack_clear(walk_state); /* - * If we just returned from the execution of a control method, - * there's lots of cleanup to do + * If we just returned from the execution of a control method or if we + * encountered an error during the method parse phase, there's lots of + * cleanup to do */ - if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == - ACPI_PARSE_EXECUTE) { + if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == + ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) { if (walk_state->method_desc) { /* Decrement the thread count on the method parse tree */ - walk_state->method_desc->method.thread_count--; + if (walk_state->method_desc->method. + thread_count) { + walk_state->method_desc->method. + thread_count--; + } else { + ACPI_REPORT_ERROR(("Invalid zero thread count in method\n")); + } } acpi_ds_terminate_control_method(walk_state); @@ -553,7 +561,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) /* Delete this walk state and all linked control states */ acpi_ps_cleanup_scope(&walk_state->parser_state); - previous_walk_state = walk_state; ACPI_DEBUG_PRINT((ACPI_DB_PARSE, diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 4c426f4c6af6..14d544d60867 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -87,7 +87,7 @@ acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags) /* TBDs: Validate name, allow full path or just nameseg */ - acpi_gbl_trace_method_name = *(u32 *) name; + acpi_gbl_trace_method_name = *ACPI_CAST_PTR(u32, name); acpi_gbl_trace_flags = flags; if (debug_level) { diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index eca7439ee9da..c2c4d9079c6c 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -300,7 +300,7 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) /* Point to the next object */ resource = - ACPI_PTR_ADD(struct acpi_resource, resource, + ACPI_ADD_PTR(struct acpi_resource, resource, resource->length); } @@ -374,8 +374,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, * 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) * sizeof(u32); + extra_struct_bytes = acpi_rs_count_set_bits(temp16); break; case ACPI_RESOURCE_NAME_DMA: @@ -383,8 +382,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, * DMA Resource: * Get the number of bits set in the 8-bit DMA mask */ - extra_struct_bytes = - acpi_rs_count_set_bits(*buffer) * sizeof(u32); + extra_struct_bytes = acpi_rs_count_set_bits(*buffer); break; case ACPI_RESOURCE_NAME_VENDOR_SMALL: @@ -399,9 +397,9 @@ acpi_rs_get_list_length(u8 * aml_buffer, case ACPI_RESOURCE_NAME_END_TAG: /* - * End Tag: This is the normal exit + * End Tag: This is the normal exit, add size of end_tag */ - *size_needed = buffer_size; + *size_needed = buffer_size + ACPI_RS_SIZE_MIN; return_ACPI_STATUS(AE_OK); case ACPI_RESOURCE_NAME_VENDOR_LARGE: @@ -466,7 +464,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + extra_struct_bytes); - buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(temp16); + buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16); /* * Point to the next resource within the stream diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index f617ca80c5a6..cebd890d3db5 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -383,7 +383,7 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) while (count) { previous_target = target; - target = ((u8 *) resource) + table->offset; + target = ACPI_ADD_PTR(u8, resource, table->offset); name = table->name; switch (table->opcode) { @@ -410,22 +410,19 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) /* Data items, 8/16/32/64 bit */ case ACPI_RSD_UINT8: - acpi_rs_out_integer8(name, *ACPI_CAST_PTR(u8, target)); + acpi_rs_out_integer8(name, ACPI_GET8(target)); break; case ACPI_RSD_UINT16: - acpi_rs_out_integer16(name, - *ACPI_CAST_PTR(u16, target)); + acpi_rs_out_integer16(name, ACPI_GET16(target)); break; case ACPI_RSD_UINT32: - acpi_rs_out_integer32(name, - *ACPI_CAST_PTR(u32, target)); + acpi_rs_out_integer32(name, ACPI_GET32(target)); break; case ACPI_RSD_UINT64: - acpi_rs_out_integer64(name, - *ACPI_CAST_PTR(u64, target)); + acpi_rs_out_integer64(name, ACPI_GET64(target)); break; /* Flags: 1-bit and 2-bit flags supported */ @@ -462,8 +459,8 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) * Note: The list length is obtained from the previous table entry */ if (previous_target) { - acpi_rs_dump_byte_list(*ACPI_CAST_PTR - (u16, previous_target), + acpi_rs_dump_byte_list(ACPI_GET16 + (previous_target), target); } break; @@ -634,7 +631,7 @@ void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) /* Point to the next resource structure */ resource_list = - ACPI_PTR_ADD(struct acpi_resource, resource_list, + ACPI_ADD_PTR(struct acpi_resource, resource_list, resource_list->length); /* Exit when END_TAG descriptor is reached */ @@ -675,9 +672,8 @@ void acpi_rs_dump_irq_list(u8 * route_table) count); acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt); - prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, - ((u8 *) prt_element) + - prt_element->length); + prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table, + prt_element, prt_element->length); } } diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index b83996233c1d..573c06705641 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -112,7 +112,7 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) /* Point to the next structure in the output buffer */ resource = - ACPI_PTR_ADD(struct acpi_resource, resource, + ACPI_ADD_PTR(struct acpi_resource, resource, resource->length); } @@ -201,7 +201,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Point to the next input resource descriptor */ resource = - ACPI_PTR_ADD(struct acpi_resource, resource, + ACPI_ADD_PTR(struct acpi_resource, resource, resource->length); } diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 16ad3bfbee2a..e1b5aa2af9a5 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -104,8 +104,9 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, * Source is the external AML byte stream buffer, * destination is the internal resource descriptor */ - source = ((u8 *) aml) + info->aml_offset; - destination = ((u8 *) resource) + info->resource_offset; + source = ACPI_ADD_PTR(void, aml, info->aml_offset); + destination = + ACPI_ADD_PTR(void, resource, info->resource_offset); switch (info->opcode) { case ACPI_RSC_INITGET: @@ -129,22 +130,22 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, /* * Mask and shift the flag bit */ - *((u8 *) destination) = (u8) - ((*((u8 *) source) >> info->value) & 0x01); + ACPI_SET8(destination) = (u8) + ((ACPI_GET8(source) >> info->value) & 0x01); break; case ACPI_RSC_2BITFLAG: /* * Mask and shift the flag bits */ - *((u8 *) destination) = (u8) - ((*((u8 *) source) >> info->value) & 0x03); + ACPI_SET8(destination) = (u8) + ((ACPI_GET8(source) >> info->value) & 0x03); break; case ACPI_RSC_COUNT: - item_count = *((u8 *) source); - *((u8 *) destination) = (u8) item_count; + item_count = ACPI_GET8(source); + ACPI_SET8(destination) = (u8) item_count; resource->length = resource->length + (info->value * (item_count - 1)); @@ -153,7 +154,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, case ACPI_RSC_COUNT16: item_count = aml_resource_length; - *((u16 *) destination) = item_count; + ACPI_SET16(destination) = item_count; resource->length = resource->length + (info->value * (item_count - 1)); @@ -186,9 +187,8 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, case ACPI_RSC_DATA8: - target = ((char *)resource) + info->value; - ACPI_MEMCPY(destination, source, - *(ACPI_CAST_PTR(u16, target))); + target = ACPI_ADD_PTR(char, resource, info->value); + ACPI_MEMCPY(destination, source, ACPI_GET16(target)); break; case ACPI_RSC_ADDRESS: @@ -217,8 +217,8 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, * complicated case used by the Interrupt() macro */ target = - ((char *)resource) + info->aml_offset + - (item_count * 4); + ACPI_ADD_PTR(char, resource, + info->aml_offset + (item_count * 4)); resource->length += acpi_rs_get_resource_source(aml_resource_length, @@ -230,15 +230,14 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, * 8-bit encoded bitmask (DMA macro) */ item_count = - acpi_rs_decode_bitmask(*((u8 *) source), + acpi_rs_decode_bitmask(ACPI_GET8(source), destination); if (item_count) { - resource->length += - resource->length + (item_count - 1); + resource->length += (item_count - 1); } - target = ((char *)resource) + info->value; - *((u8 *) target) = (u8) item_count; + target = ACPI_ADD_PTR(char, resource, info->value); + ACPI_SET8(target) = (u8) item_count; break; case ACPI_RSC_BITMASK16: @@ -250,12 +249,11 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, item_count = acpi_rs_decode_bitmask(temp16, destination); if (item_count) { - resource->length = - resource->length + (item_count - 1); + resource->length += (item_count - 1); } - target = ((char *)resource) + info->value; - *((u8 *) target) = (u8) item_count; + target = ACPI_ADD_PTR(char, resource, info->value); + ACPI_SET8(target) = (u8) item_count; break; case ACPI_RSC_EXIT_NE: @@ -270,7 +268,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, break; case ACPI_RSC_COMPARE_VALUE: - if (*((u8 *) source) != info->value) { + if (ACPI_GET8(source) != info->value) { goto exit; } break; @@ -349,8 +347,8 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, * Source is the internal resource descriptor, * destination is the external AML byte stream buffer */ - source = ((u8 *) resource) + info->resource_offset; - destination = ((u8 *) aml) + info->aml_offset; + source = ACPI_ADD_PTR(void, resource, info->resource_offset); + destination = ACPI_ADD_PTR(void, aml, info->aml_offset); switch (info->opcode) { case ACPI_RSC_INITSET: @@ -368,37 +366,38 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, /* * Clear the flag byte */ - *((u8 *) destination) = 0; + ACPI_SET8(destination) = 0; break; case ACPI_RSC_1BITFLAG: /* * Mask and shift the flag bit */ - *((u8 *) destination) |= (u8) - ((*((u8 *) source) & 0x01) << info->value); + ACPI_SET8(destination) |= (u8) + ((ACPI_GET8(source) & 0x01) << info->value); break; case ACPI_RSC_2BITFLAG: /* * Mask and shift the flag bits */ - *((u8 *) destination) |= (u8) - ((*((u8 *) source) & 0x03) << info->value); + ACPI_SET8(destination) |= (u8) + ((ACPI_GET8(source) & 0x03) << info->value); break; case ACPI_RSC_COUNT: - item_count = *((u8 *) source); - *((u8 *) destination) = (u8) item_count; + item_count = ACPI_GET8(source); + ACPI_SET8(destination) = (u8) item_count; - aml_length = (u16) (aml_length + - (info->value * (item_count - 1))); + aml_length = + (u16) (aml_length + + (info->value * (item_count - 1))); break; case ACPI_RSC_COUNT16: - item_count = *((u16 *) source); + item_count = ACPI_GET16(source); aml_length = (u16) (aml_length + item_count); acpi_rs_set_resource_length(aml_length, aml); break; @@ -453,20 +452,21 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, /* * 8-bit encoded bitmask (DMA macro) */ - *((u8 *) destination) = (u8) + ACPI_SET8(destination) = (u8) acpi_rs_encode_bitmask(source, - *(((u8 *) resource) + - info->value)); + *ACPI_ADD_PTR(u8, resource, + info->value)); break; case ACPI_RSC_BITMASK16: /* * 16-bit encoded bitmask (IRQ macro) */ - temp16 = - acpi_rs_encode_bitmask(source, - *(((u8 *) resource) + - info->value)); + temp16 = acpi_rs_encode_bitmask(source, + *ACPI_ADD_PTR(u8, + resource, + info-> + value)); ACPI_MOVE_16_TO_16(destination, &temp16); break; @@ -485,9 +485,9 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, */ switch (COMPARE_OPCODE(info)) { case ACPI_RSC_COMPARE_VALUE: - if (* - ((u8 *) (((u8 *) resource) + - COMPARE_TARGET(info))) != + + if (*ACPI_ADD_PTR(u8, resource, + COMPARE_TARGET(info)) != COMPARE_VALUE(info)) { goto exit; } diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index a1eac0f1df54..2236a0c90daa 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -152,18 +152,18 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) * misaligned memory transfers */ case ACPI_RSC_MOVE16: - ACPI_MOVE_16_TO_16(&((u16 *) destination)[i], - &((u16 *) source)[i]); + ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i], + &ACPI_CAST_PTR(u16, source)[i]); break; case ACPI_RSC_MOVE32: - ACPI_MOVE_32_TO_32(&((u32 *) destination)[i], - &((u32 *) source)[i]); + ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i], + &ACPI_CAST_PTR(u32, source)[i]); break; case ACPI_RSC_MOVE64: - ACPI_MOVE_64_TO_64(&((u64 *) destination)[i], - &((u64 *) source)[i]); + ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i], + &ACPI_CAST_PTR(u64, source)[i]); break; default: @@ -318,7 +318,7 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length, total_length = resource_length + sizeof(struct aml_resource_large_header); - aml_resource_source = ((u8 *) aml) + minimum_length; + aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); /* * resource_source is present if the length of the descriptor is longer than @@ -338,9 +338,9 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length, * String destination pointer is not specified; Set the String * pointer to the end of the current resource_source structure. */ - resource_source->string_ptr = (char *) - ((u8 *) resource_source) + - sizeof(struct acpi_resource_source); + resource_source->string_ptr = + ACPI_ADD_PTR(char, resource_source, + sizeof(struct acpi_resource_source)); } /* @@ -407,7 +407,7 @@ acpi_rs_set_resource_source(union aml_resource * aml, if (resource_source->string_length) { /* Point to the end of the AML descriptor */ - aml_resource_source = ((u8 *) aml) + minimum_length; + aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); /* Copy the resource_source_index */ diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 09d250ab9872..50a956b705b0 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -64,6 +64,10 @@ ACPI_MODULE_NAME("rsxface") ACPI_COPY_FIELD(out, in, translation_offset); \ ACPI_COPY_FIELD(out, in, address_length); \ ACPI_COPY_FIELD(out, in, resource_source); +/* Local prototypes */ +static acpi_status +acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context); + /******************************************************************************* * * FUNCTION: acpi_get_irq_routing_table @@ -86,6 +90,7 @@ ACPI_MODULE_NAME("rsxface") * the object indicated by the passed device_handle. * ******************************************************************************/ + acpi_status acpi_get_irq_routing_table(acpi_handle device_handle, struct acpi_buffer *ret_buffer) @@ -222,12 +227,12 @@ EXPORT_SYMBOL(acpi_get_possible_resources); * * FUNCTION: acpi_walk_resources * - * PARAMETERS: device_handle - a handle to the device object for the + * PARAMETERS: device_handle - Handle to the device object for the * device we are querying - * Path - method name of the resources we want + * Name - Method name of the resources we want * (METHOD_NAME__CRS or METHOD_NAME__PRS) - * user_function - called for each resource - * Context - passed to user_function + * user_function - Called for each resource + * Context - Passed to user_function * * RETURN: Status * @@ -239,79 +244,74 @@ EXPORT_SYMBOL(acpi_get_possible_resources); acpi_status acpi_walk_resources(acpi_handle device_handle, - char *path, + char *name, ACPI_WALK_RESOURCE_CALLBACK user_function, void *context) { acpi_status status; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer buffer; struct acpi_resource *resource; - struct acpi_resource *buffer_end; + struct acpi_resource *resource_end; ACPI_FUNCTION_TRACE("acpi_walk_resources"); - if (!device_handle || - (ACPI_STRNCMP(path, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) && - ACPI_STRNCMP(path, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) { + /* Parameter validation */ + + if (!device_handle || !user_function || !name || + (ACPI_STRNCMP(name, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) && + ACPI_STRNCMP(name, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - status = acpi_rs_get_method_data(device_handle, path, &buffer); + /* Get the _CRS or _PRS resource list */ + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_rs_get_method_data(device_handle, name, &buffer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Setup pointers */ + /* Buffer now contains the resource list */ - resource = (struct acpi_resource *)buffer.pointer; - buffer_end = ACPI_CAST_PTR(struct acpi_resource, - ((u8 *) buffer.pointer + buffer.length)); + resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); + resource_end = + ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); - /* Walk the resource list */ + /* Walk the resource list until the end_tag is found (or buffer end) */ - for (;;) { - if (!resource || resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + while (resource < resource_end) { + /* Sanity check the resource */ + + if (resource->type > ACPI_RESOURCE_TYPE_MAX) { + status = AE_AML_INVALID_RESOURCE_TYPE; break; } + /* Invoke the user function, abort on any error returned */ + status = user_function(resource, context); + if (ACPI_FAILURE(status)) { + if (status == AE_CTRL_TERMINATE) { + /* This is an OK termination by the user function */ - switch (status) { - case AE_OK: - case AE_CTRL_DEPTH: - - /* Just keep going */ - - status = AE_OK; + status = AE_OK; + } break; + } - case AE_CTRL_TERMINATE: + /* end_tag indicates end-of-list */ - /* Exit now, with OK stats */ - - status = AE_OK; - goto cleanup; - - default: - - /* All others are valid exceptions */ - - goto cleanup; + if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + break; } /* Get the next resource descriptor */ - resource = ACPI_NEXT_RESOURCE(resource); - - /* Check for end-of-buffer */ - - if (resource >= buffer_end) { - goto cleanup; - } + resource = + ACPI_ADD_PTR(struct acpi_resource, resource, + resource->length); } - cleanup: - - acpi_os_free(buffer.pointer); + ACPI_MEM_FREE(buffer.pointer); return_ACPI_STATUS(status); } @@ -381,6 +381,12 @@ acpi_resource_to_address64(struct acpi_resource *resource, struct acpi_resource_address16 *address16; struct acpi_resource_address32 *address32; + if (!resource || !out) { + return (AE_BAD_PARAMETER); + } + + /* Convert 16 or 32 address descriptor to 64 */ + switch (resource->type) { case ACPI_RESOURCE_TYPE_ADDRESS16: @@ -410,3 +416,113 @@ acpi_resource_to_address64(struct acpi_resource *resource, } EXPORT_SYMBOL(acpi_resource_to_address64); + +/******************************************************************************* + * + * FUNCTION: acpi_get_vendor_resource + * + * PARAMETERS: device_handle - Handle for the parent device object + * Name - Method name for the parent resource + * (METHOD_NAME__CRS or METHOD_NAME__PRS) + * Uuid - Pointer to the UUID to be matched. + * includes both subtype and 16-byte UUID + * ret_buffer - Where the vendor resource is returned + * + * RETURN: Status + * + * DESCRIPTION: Walk a resource template for the specified evice to find a + * vendor-defined resource that matches the supplied UUID and + * UUID subtype. Returns a struct acpi_resource of type Vendor. + * + ******************************************************************************/ + +acpi_status +acpi_get_vendor_resource(acpi_handle device_handle, + char *name, + struct acpi_vendor_uuid * uuid, + struct acpi_buffer * ret_buffer) +{ + struct acpi_vendor_walk_info info; + acpi_status status; + + /* Other parameters are validated by acpi_walk_resources */ + + if (!uuid || !ret_buffer) { + return (AE_BAD_PARAMETER); + } + + info.uuid = uuid; + info.buffer = ret_buffer; + info.status = AE_NOT_EXIST; + + /* Walk the _CRS or _PRS resource list for this device */ + + status = + acpi_walk_resources(device_handle, name, + acpi_rs_match_vendor_resource, &info); + if (ACPI_FAILURE(status)) { + return (status); + } + + return (info.status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_match_vendor_resource + * + * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID + * + ******************************************************************************/ + +static acpi_status +acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) +{ + struct acpi_vendor_walk_info *info = context; + struct acpi_resource_vendor_typed *vendor; + struct acpi_buffer *buffer; + acpi_status status; + + /* Ignore all descriptors except Vendor */ + + if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) { + return (AE_OK); + } + + vendor = &resource->data.vendor_typed; + + /* + * For a valid match, these conditions must hold: + * + * 1) Length of descriptor data must be at least as long as a UUID struct + * 2) The UUID subtypes must match + * 3) The UUID data must match + */ + if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) || + (vendor->uuid_subtype != info->uuid->subtype) || + (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) { + return (AE_OK); + } + + /* Validate/Allocate/Clear caller buffer */ + + buffer = info->buffer; + status = acpi_ut_initialize_buffer(buffer, resource->length); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Found the correct resource, copy and return it */ + + ACPI_MEMCPY(buffer->pointer, resource, resource->length); + buffer->length = resource->length; + + /* Found the desired descriptor, terminate resource walk */ + + info->status = AE_OK; + return (AE_CTRL_TERMINATE); +} diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 31218e1d2a18..e332306ae2b9 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -844,7 +844,7 @@ static void acpi_device_set_id(struct acpi_device *device, * ---- * Fix for the system root bus device -- the only root-level device. */ - if ((parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { + if (((acpi_handle)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { hid = ACPI_BUS_HID; strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); strcpy(device->pnp.device_class, ACPI_BUS_CLASS); diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index a03939399fa9..cd33397d9231 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c @@ -554,7 +554,9 @@ acpi_status acpi_tb_convert_table_fadt(void) ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Hex dump of common internal FADT, size %d (%X)\n", acpi_gbl_FADT->length, acpi_gbl_FADT->length)); - ACPI_DUMP_BUFFER((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length); + + ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_FADT), + acpi_gbl_FADT->length); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c index 8d72343537e7..33c9ed8a6f99 100644 --- a/drivers/acpi/tables/tbgetall.c +++ b/drivers/acpi/tables/tbgetall.c @@ -292,7 +292,9 @@ acpi_status acpi_tb_get_required_tables(void) "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n", acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width)); - ACPI_DUMP_BUFFER((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length); + + ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_DSDT), + acpi_gbl_DSDT->length); /* Always delete the RSDP mapping, we are done with it */ diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index e6dfe688b76b..9d0bf536d674 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -240,16 +240,16 @@ acpi_tb_verify_table_checksum(struct acpi_table_header * table_header) u8 acpi_tb_generate_checksum(void *buffer, u32 length) { - const u8 *limit; - const u8 *rover; + u8 *end_buffer; + u8 *rover; u8 sum = 0; if (buffer && length) { /* Buffer and Length are valid */ - limit = (u8 *) buffer + length; + end_buffer = ACPI_ADD_PTR(u8, buffer, length); - for (rover = buffer; rover < limit; rover++) { + for (rover = buffer; rover < end_buffer; rover++) { sum = (u8) (sum + *rover); } } diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 5442b32de611..568df9e42f89 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c @@ -398,14 +398,17 @@ acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object, * Build a simple object (no nested objects) */ status = acpi_ut_copy_isimple_to_esimple(internal_object, - (union acpi_object *) - ret_buffer->pointer, - ((u8 *) ret_buffer-> - pointer + - ACPI_ROUND_UP_TO_NATIVE_WORD - (sizeof - (union - acpi_object))), + ACPI_CAST_PTR(union + acpi_object, + ret_buffer-> + pointer), + ACPI_ADD_PTR(u8, + ret_buffer-> + pointer, + ACPI_ROUND_UP_TO_NATIVE_WORD + (sizeof + (union + acpi_object))), &ret_buffer->length); /* * build simple does not include the object size in the length diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 413e1dd8ae36..d6813d88a104 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -638,7 +638,7 @@ char *acpi_ut_get_node_name(void *object) /* Name must be a valid ACPI name */ - if (!acpi_ut_valid_acpi_name(*(u32 *) node->name.ascii)) { + if (!acpi_ut_valid_acpi_name(node->name.integer)) { return ("????"); } @@ -831,6 +831,7 @@ void acpi_ut_init_globals(void) acpi_gbl_ps_find_count = 0; acpi_gbl_acpi_hardware_present = TRUE; acpi_gbl_owner_id_mask = 0; + acpi_gbl_last_owner_id = 0; acpi_gbl_trace_method_name = 0; acpi_gbl_trace_dbg_level = 0; acpi_gbl_trace_dbg_layer = 0; @@ -845,7 +846,6 @@ void acpi_ut_init_globals(void) /* Namespace */ acpi_gbl_root_node = NULL; - acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; acpi_gbl_root_node_struct.descriptor = ACPI_DESC_TYPE_NAMED; acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 2a9110c06391..89efba7bf449 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -63,6 +63,7 @@ ACPI_MODULE_NAME("utmisc") acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) { acpi_native_uint i; + acpi_native_uint j; acpi_status status; ACPI_FUNCTION_TRACE("ut_allocate_owner_id"); @@ -82,29 +83,46 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) return_ACPI_STATUS(status); } - /* Find a free owner ID */ + /* + * Find a free owner ID, cycle through all possible IDs on repeated + * allocations. Note: Index for next possible ID is equal to the value + * of the last allocated ID. + */ + for (i = 0, j = acpi_gbl_last_owner_id; i < 32; i++, j++) { + if (j >= 32) { + j = 0; /* Wraparound to ID start */ + } + + if (!(acpi_gbl_owner_id_mask & (1 << j))) { + /* + * Found a free ID. The actual ID is the bit index plus one, + * making zero an invalid Owner ID. Save this as the last ID + * allocated and update the global ID mask. + */ + acpi_gbl_last_owner_id = (acpi_owner_id) (j + 1); + *owner_id = acpi_gbl_last_owner_id; - for (i = 0; i < 32; i++) { - if (!(acpi_gbl_owner_id_mask & (1 << i))) { ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "Current owner_id mask: %8.8X New ID: %2.2X\n", acpi_gbl_owner_id_mask, - (unsigned int)(i + 1))); + (unsigned int) + acpi_gbl_last_owner_id)); - acpi_gbl_owner_id_mask |= (1 << i); - *owner_id = (acpi_owner_id) (i + 1); + acpi_gbl_owner_id_mask |= (1 << j); goto exit; } } /* - * If we are here, all owner_ids have been allocated. This probably should + * All owner_ids have been allocated. This typically should * not happen since the IDs are reused after deallocation. The IDs are * allocated upon table load (one per table) and method execution, and * they are released when a table is unloaded or a method completes * execution. + * + * If this error happens, there may be very deep nesting of invoked control + * methods, or there may be a bug where the IDs are not released. */ - *owner_id = 0; status = AE_OWNER_ID_LIMIT; ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n")); diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index 07a314c710d8..6c0ce7b12194 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c @@ -157,7 +157,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index) /* * 1) Validate the resource_type field (Byte 0) */ - resource_type = *((u8 *) aml); + resource_type = ACPI_GET8(aml); /* * Byte 0 contains the descriptor name (Resource Type) @@ -266,14 +266,14 @@ u8 acpi_ut_get_resource_type(void *aml) * Byte 0 contains the descriptor name (Resource Type) * Examine the large/small bit in the resource header */ - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { /* Large Resource Type -- bits 6:0 contain the name */ - return (*((u8 *) aml)); + return (ACPI_GET8(aml)); } else { /* Small Resource Type -- bits 6:3 contain the name */ - return ((u8) (*((u8 *) aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); + return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); } } @@ -301,15 +301,15 @@ u16 acpi_ut_get_resource_length(void *aml) * Byte 0 contains the descriptor name (Resource Type) * Examine the large/small bit in the resource header */ - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { /* Large Resource type -- bytes 1-2 contain the 16-bit length */ - ACPI_MOVE_16_TO_16(&resource_length, &((u8 *) aml)[1]); + ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1)); } else { /* Small Resource type -- bits 2:0 of byte 0 contain the length */ - resource_length = (u16) (*((u8 *) aml) & + resource_length = (u16) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); } @@ -334,7 +334,7 @@ u8 acpi_ut_get_resource_header_length(void *aml) /* Examine the large/small bit in the resource header */ - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { return (sizeof(struct aml_resource_large_header)); } else { return (sizeof(struct aml_resource_small_header)); @@ -372,8 +372,9 @@ u32 acpi_ut_get_descriptor_length(void *aml) * FUNCTION: acpi_ut_get_resource_end_tag * * PARAMETERS: obj_desc - The resource template buffer object + * end_tag - Where the pointer to the end_tag is returned * - * RETURN: Pointer to the end tag + * RETURN: Status, pointer to the end tag * * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template * diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index d371ec6b9812..08eafece3eed 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20051102 +#define ACPI_CA_VERSION 0x20051117 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, @@ -98,11 +98,6 @@ #define ACPI_CA_SUPPORT_LEVEL 3 -/* String size constants */ - -#define ACPI_MAX_STRING_LENGTH 512 -#define ACPI_PATHNAME_MAX 256 /* A full namespace pathname */ - /* Maximum count for a semaphore object */ #define ACPI_MAX_SEMAPHORE_COUNT 256 @@ -134,14 +129,11 @@ #define ACPI_METHOD_NUM_ARGS 7 #define ACPI_METHOD_MAX_ARG 6 -/* Maximum length of resulting string when converting from a buffer */ - -#define ACPI_MAX_STRING_CONVERSION 200 - -/* Length of _HID, _UID, and _CID values */ +/* Length of _HID, _UID, _CID, and UUID values */ #define ACPI_DEVICE_ID_LENGTH 0x09 #define ACPI_MAX_CID_LENGTH 48 +#define ACPI_UUID_LENGTH 16 /* * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index cef51b1ddf94..bd344e51313b 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h @@ -223,6 +223,7 @@ ACPI_EXTERN u32 acpi_gbl_ps_find_count; ACPI_EXTERN u32 acpi_gbl_owner_id_mask; ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; ACPI_EXTERN u16 acpi_gbl_global_lock_handle; +ACPI_EXTERN u8 acpi_gbl_last_owner_id; ACPI_EXTERN u8 acpi_gbl_debugger_configuration; ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; ACPI_EXTERN u8 acpi_gbl_step_to_next_call; diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index dca0d40ea395..0cb61a72d971 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -573,6 +573,8 @@ struct acpi_parse_obj_named { /* The parse node is the fundamental element of the parse tree */ +#define ACPI_MAX_PARSEOP_NAME 20 + struct acpi_parse_obj_asl { ACPI_PARSE_COMMON union acpi_parse_object *child; union acpi_parse_object *parent_method; @@ -597,7 +599,7 @@ struct acpi_parse_obj_asl { u8 aml_opcode_length; u8 aml_pkg_len_bytes; u8 extra; - char parse_op_name[12]; + char parse_op_name[ACPI_MAX_PARSEOP_NAME]; }; union acpi_parse_object { diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index e42222c3d34c..5b78ff4091b9 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -107,23 +107,29 @@ * Extract a byte of data using a pointer. Any more than a byte and we * get into potential aligment issues -- see the STORE macros below */ -#define ACPI_GET8(addr) (*(u8*)(addr)) +#define ACPI_GET8(ptr) *ACPI_CAST_PTR (u8, ptr) +#define ACPI_GET16(ptr) *ACPI_CAST_PTR (u16, ptr) +#define ACPI_GET32(ptr) *ACPI_CAST_PTR (u32, ptr) +#define ACPI_GET64(ptr) *ACPI_CAST_PTR (u64, ptr) +#define ACPI_SET8(ptr) *ACPI_CAST_PTR (u8, ptr) +#define ACPI_SET16(ptr) *ACPI_CAST_PTR (u16, ptr) +#define ACPI_SET32(ptr) *ACPI_CAST_PTR (u32, ptr) +#define ACPI_SET64(ptr) *ACPI_CAST_PTR (u64, ptr) -/* Pointer arithmetic */ +/* Pointer manipulation */ -#define ACPI_PTR_ADD(t,a,b) (t *) (void *)((char *)(a) + (acpi_native_uint)(b)) +#define ACPI_CAST_PTR(t, p) ((t *)(void *)(p)) +#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **)(void *)(p)) +#define ACPI_ADD_PTR(t,a,b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8, (a)) + (acpi_native_uint)(b))) #define ACPI_PTR_DIFF(a,b) (acpi_native_uint) ((char *)(a) - (char *)(b)) /* Pointer/Integer type conversions */ -#define ACPI_TO_POINTER(i) ACPI_PTR_ADD (void, (void *) NULL,(acpi_native_uint)i) +#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL,(acpi_native_uint)i) #define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) #define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) #define ACPI_FADT_OFFSET(f) ACPI_OFFSET (FADT_DESCRIPTOR, f) -#define ACPI_CAST_PTR(t, p) ((t *)(void *)(p)) -#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **)(void *)(p)) - #if ACPI_MACHINE_WIDTH == 16 #define ACPI_STORE_POINTER(d,s) ACPI_MOVE_32_TO_32(d,s) #define ACPI_PHYSADDR_TO_PTR(i) (void *)(i) @@ -365,6 +371,13 @@ #define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) ((val << pos) & mask) #define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask) +/* Generate a UUID */ + +#define ACPI_INIT_UUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) (a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \ + (b) & 0xFF, ((b) >> 8) & 0xFF, \ + (c) & 0xFF, ((c) >> 8) & 0xFF, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) + /* * An struct acpi_namespace_node * can appear in some contexts, * where a pointer to an union acpi_operand_object can also diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 02f00a8fee03..2a88429bc4ec 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -271,6 +271,12 @@ typedef acpi_status(*ACPI_WALK_RESOURCE_CALLBACK) (struct acpi_resource * resource, void *context); +acpi_status +acpi_get_vendor_resource(acpi_handle device_handle, + char *name, + struct acpi_vendor_uuid *uuid, + struct acpi_buffer *ret_buffer); + acpi_status acpi_get_current_resources(acpi_handle device_handle, struct acpi_buffer *ret_buffer); @@ -283,7 +289,7 @@ acpi_get_possible_resources(acpi_handle device_handle, acpi_status acpi_walk_resources(acpi_handle device_handle, - char *path, + char *name, ACPI_WALK_RESOURCE_CALLBACK user_function, void *context); acpi_status diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h index 2bf53940f259..ba281f7740a0 100644 --- a/include/acpi/acresrc.h +++ b/include/acpi/acresrc.h @@ -137,9 +137,14 @@ extern struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[]; /* Resource tables indexed by raw AML resource descriptor type */ +extern const u8 acpi_gbl_resource_struct_sizes[]; extern struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[]; -extern const u8 acpi_gbl_resource_struct_sizes[]; +struct acpi_vendor_walk_info { + struct acpi_vendor_uuid *uuid; + struct acpi_buffer *buffer; + acpi_status status; +}; /* * rscreate diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 29b887017b18..11847592ed1b 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -326,7 +326,7 @@ typedef u64 acpi_integer; /* * Constants with special meanings */ -#define ACPI_ROOT_OBJECT (acpi_handle) ACPI_PTR_ADD (char, NULL, ACPI_MAX_PTR) +#define ACPI_ROOT_OBJECT ACPI_ADD_PTR (acpi_handle, NULL, ACPI_MAX_PTR) /* * Initialization sequence @@ -986,6 +986,17 @@ typedef u32 acpi_rsdesc_size; /* Max Resource Descriptor size is (length+3) = (6 #pragma pack(1) #endif +/* UUID data structures for use in vendor-defined resource descriptors */ + +struct acpi_uuid { + u8 data[ACPI_UUID_LENGTH]; +}; + +struct acpi_vendor_uuid { + u8 subtype; + u8 data[ACPI_UUID_LENGTH]; +}; + /* * Structures used to describe device resources */ @@ -1033,6 +1044,15 @@ struct acpi_resource_vendor { u8 byte_data[1]; }; +/* Vendor resource with UUID info (introduced in ACPI 3.0) */ + +struct acpi_resource_vendor_typed { + u16 byte_length; + u8 uuid_subtype; + u8 uuid[ACPI_UUID_LENGTH]; + u8 byte_data[1]; +}; + struct acpi_resource_end_tag { u8 checksum; }; @@ -1184,6 +1204,7 @@ union acpi_resource_data { struct acpi_resource_io io; struct acpi_resource_fixed_io fixed_io; struct acpi_resource_vendor vendor; + struct acpi_resource_vendor_typed vendor_typed; struct acpi_resource_end_tag end_tag; struct acpi_resource_memory24 memory24; struct acpi_resource_memory32 memory32; diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index c93e6562f0e1..1b9cbf05b79e 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -71,6 +71,10 @@ #define acpi_cache_t kmem_cache_t #endif +/* Full namespace pathname length limit - arbitrary */ + +#define ACPI_PATHNAME_MAX 256 + #else /* !__KERNEL__ */ #include From 28f55ebce5bd2fceec8adc7c8860953d3e4532a8 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 2 Dec 2005 18:27:00 -0500 Subject: [PATCH 018/695] [ACPI] ACPICA 20051202 Modified the parsing of control methods to no longer create namespace objects during the first pass of the parse. Objects are now created only during the execute phase, at the moment the namespace creation operator is encountered in the AML (Name, OperationRegion, CreateByteField, etc.) This should eliminate ALREADY_EXISTS exceptions seen on some machines where reentrant control methods are protected by an AML mutex. The mutex will now correctly block multiple threads from attempting to create the same object more than once. Increased the number of available Owner Ids for namespace object tracking from 32 to 255. This should eliminate the OWNER_ID_LIMIT exceptions seen on some machines with a large number of ACPI tables (either static or dynamic). Enhanced the namespace dump routine to output the owner ID for each namespace object. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsmethod.c | 337 +++++++++++++++-------------- drivers/acpi/dispatcher/dswload.c | 132 +++++++---- drivers/acpi/namespace/nsdump.c | 4 +- drivers/acpi/utilities/utglobal.c | 9 +- drivers/acpi/utilities/utmisc.c | 79 ++++--- include/acpi/acconfig.h | 6 +- include/acpi/acglobal.h | 5 +- include/acpi/acmacros.h | 4 + 8 files changed, 350 insertions(+), 226 deletions(-) diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 36c1ca0b9adb..58ad00b31ee9 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -51,133 +51,6 @@ #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsmethod") -/******************************************************************************* - * - * FUNCTION: acpi_ds_parse_method - * - * PARAMETERS: Node - Method node - * - * RETURN: Status - * - * DESCRIPTION: Parse the AML that is associated with the method. - * - * MUTEX: Assumes parser is locked - * - ******************************************************************************/ -acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node) -{ - acpi_status status; - union acpi_operand_object *obj_desc; - union acpi_parse_object *op; - struct acpi_walk_state *walk_state; - - ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node); - - /* Parameter Validation */ - - if (!node) { - return_ACPI_STATUS(AE_NULL_ENTRY); - } - - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "**** Parsing [%4.4s] **** named_obj=%p\n", - acpi_ut_get_node_name(node), node)); - - /* Extract the method object from the method Node */ - - obj_desc = acpi_ns_get_attached_object(node); - if (!obj_desc) { - return_ACPI_STATUS(AE_NULL_OBJECT); - } - - /* Create a mutex for the method if there is a concurrency limit */ - - if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) && - (!obj_desc->method.semaphore)) { - status = acpi_os_create_semaphore(obj_desc->method.concurrency, - obj_desc->method.concurrency, - &obj_desc->method.semaphore); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } - - /* - * Allocate a new parser op to be the root of the parsed - * method tree - */ - op = acpi_ps_alloc_op(AML_METHOD_OP); - if (!op) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* Init new op with the method name and pointer back to the Node */ - - acpi_ps_set_name(op, node->name.integer); - op->common.node = node; - - /* - * Get a new owner_id for objects created by this method. Namespace - * objects (such as Operation Regions) can be created during the - * first pass parse. - */ - status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id); - if (ACPI_FAILURE(status)) { - goto cleanup; - } - - /* Create and initialize a new walk state */ - - walk_state = - acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, NULL, - NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup2; - } - - status = acpi_ds_init_aml_walk(walk_state, op, node, - obj_desc->method.aml_start, - obj_desc->method.aml_length, NULL, 1); - if (ACPI_FAILURE(status)) { - acpi_ds_delete_walk_state(walk_state); - goto cleanup2; - } - - /* - * Parse the method, first pass - * - * The first pass load is where newly declared named objects are added into - * the namespace. Actual evaluation of the named objects (what would be - * called a "second pass") happens during the actual execution of the - * method so that operands to the named objects can take on dynamic - * run-time values. - */ - status = acpi_ps_parse_aml(walk_state); - if (ACPI_FAILURE(status)) { - goto cleanup2; - } - - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", - acpi_ut_get_node_name(node), node, op)); - - /* - * Delete the parse tree. We simply re-parse the method for every - * execution since there isn't much overhead (compared to keeping lots - * of parse trees around) - */ - acpi_ns_delete_namespace_subtree(node); - acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id); - - cleanup2: - acpi_ut_release_owner_id(&obj_desc->method.owner_id); - - cleanup: - acpi_ps_delete_parse_tree(op); - return_ACPI_STATUS(status); -} - /******************************************************************************* * * FUNCTION: acpi_ds_begin_method_execution @@ -193,7 +66,6 @@ acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node) * for clearance to execute. * ******************************************************************************/ - acpi_status acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, union acpi_operand_object *obj_desc, @@ -545,16 +417,54 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) } } + /* + * There are no more threads executing this method. Perform + * additional cleanup. + * + * The method Node is stored in the walk state + */ + method_node = walk_state->method_node; + + /* Lock namespace for possible update */ + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* + * Delete any namespace entries created immediately underneath + * the method + */ + if (method_node->child) { + acpi_ns_delete_namespace_subtree(method_node); + } + + /* + * Delete any namespace entries created anywhere else within + * the namespace by the execution of this method + */ + acpi_ns_delete_namespace_by_owner(walk_state->method_desc->method. + owner_id); + status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + + /* Are there any other threads currently executing this method? */ + if (walk_state->method_desc->method.thread_count) { + /* + * Additional threads. Do not release the owner_id in this case, + * we immediately reuse it for the next thread executing this method + */ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "*** Not deleting method namespace, there are still %d threads\n", + "*** Completed execution of one thread, %d threads remaining\n", walk_state->method_desc->method. thread_count)); - } else { /* This is the last executing thread */ + } else { + /* This is the only executing thread for this method */ /* * Support to dynamically change a method from not_serialized to - * Serialized if it appears that the method is written foolishly and + * Serialized if it appears that the method is incorrectly written and * does not support multiple thread execution. The best example of this * is if such a method creates namespace objects and blocks. A second * thread will fail with an AE_ALREADY_EXISTS exception @@ -570,34 +480,8 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) semaphore); } - /* - * There are no more threads executing this method. Perform - * additional cleanup. - * - * The method Node is stored in the walk state - */ - method_node = walk_state->method_node; + /* No more threads, we can free the owner_id */ - /* - * Delete any namespace entries created immediately underneath - * the method - */ - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - goto exit; - } - - if (method_node->child) { - acpi_ns_delete_namespace_subtree(method_node); - } - - /* - * Delete any namespace entries created anywhere else within - * the namespace - */ - acpi_ns_delete_namespace_by_owner(walk_state->method_desc-> - method.owner_id); - status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); acpi_ut_release_owner_id(&walk_state->method_desc->method. owner_id); } @@ -606,3 +490,140 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) (void)acpi_ut_release_mutex(ACPI_MTX_PARSER); return_VOID; } + +#ifdef ACPI_INIT_PARSE_METHODS + /* + * Note 11/2005: Removed this code to parse all methods during table + * load because it causes problems if there are any errors during the + * parse. Also, it seems like overkill and we probably don't want to + * abort a table load because of an issue with a single method. + */ + +/******************************************************************************* + * + * FUNCTION: acpi_ds_parse_method + * + * PARAMETERS: Node - Method node + * + * RETURN: Status + * + * DESCRIPTION: Parse the AML that is associated with the method. + * + * MUTEX: Assumes parser is locked + * + ******************************************************************************/ + +acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node) +{ + acpi_status status; + union acpi_operand_object *obj_desc; + union acpi_parse_object *op; + struct acpi_walk_state *walk_state; + + ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node); + + /* Parameter Validation */ + + if (!node) { + return_ACPI_STATUS(AE_NULL_ENTRY); + } + + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "**** Parsing [%4.4s] **** named_obj=%p\n", + acpi_ut_get_node_name(node), node)); + + /* Extract the method object from the method Node */ + + obj_desc = acpi_ns_get_attached_object(node); + if (!obj_desc) { + return_ACPI_STATUS(AE_NULL_OBJECT); + } + + /* Create a mutex for the method if there is a concurrency limit */ + + if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) && + (!obj_desc->method.semaphore)) { + status = acpi_os_create_semaphore(obj_desc->method.concurrency, + obj_desc->method.concurrency, + &obj_desc->method.semaphore); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + + /* + * Allocate a new parser op to be the root of the parsed + * method tree + */ + op = acpi_ps_alloc_op(AML_METHOD_OP); + if (!op) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Init new op with the method name and pointer back to the Node */ + + acpi_ps_set_name(op, node->name.integer); + op->common.node = node; + + /* + * Get a new owner_id for objects created by this method. Namespace + * objects (such as Operation Regions) can be created during the + * first pass parse. + */ + status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* Create and initialize a new walk state */ + + walk_state = + acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, NULL, + NULL); + if (!walk_state) { + status = AE_NO_MEMORY; + goto cleanup2; + } + + status = acpi_ds_init_aml_walk(walk_state, op, node, + obj_desc->method.aml_start, + obj_desc->method.aml_length, NULL, 1); + if (ACPI_FAILURE(status)) { + acpi_ds_delete_walk_state(walk_state); + goto cleanup2; + } + + /* + * Parse the method, first pass + * + * The first pass load is where newly declared named objects are added into + * the namespace. Actual evaluation of the named objects (what would be + * called a "second pass") happens during the actual execution of the + * method so that operands to the named objects can take on dynamic + * run-time values. + */ + status = acpi_ps_parse_aml(walk_state); + if (ACPI_FAILURE(status)) { + goto cleanup2; + } + + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", + acpi_ut_get_node_name(node), node, op)); + + /* + * Delete the parse tree. We simply re-parse the method for every + * execution since there isn't much overhead (compared to keeping lots + * of parse trees around) + */ + acpi_ns_delete_namespace_subtree(node); + acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id); + + cleanup2: + acpi_ut_release_owner_id(&obj_desc->method.owner_id); + + cleanup: + acpi_ps_delete_parse_tree(op); + return_ACPI_STATUS(status); +} +#endif diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 89d318cbc8a3..44d4f4bb2f92 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -127,7 +127,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, char *path; u32 flags; - ACPI_FUNCTION_NAME("ds_load1_begin_op"); + ACPI_FUNCTION_TRACE("ds_load1_begin_op"); op = walk_state->op; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, @@ -138,14 +138,14 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, if (op) { if (!(walk_state->op_info->flags & AML_NAMED)) { *out_op = op; - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* Check if this object has already been installed in the namespace */ if (op->common.node) { *out_op = op; - return (AE_OK); + return_ACPI_STATUS(AE_OK); } } @@ -188,7 +188,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, #endif if (ACPI_FAILURE(status)) { ACPI_REPORT_NSERROR(path, status); - return (status); + return_ACPI_STATUS(status); } /* @@ -235,7 +235,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n", acpi_ut_get_type_name(node->type), path)); - return (AE_AML_OPERAND_TYPE); + return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } break; @@ -257,6 +257,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, * buffer_field, or Package), the name of the object is already * in the namespace. */ + if (walk_state->deferred_node) { /* This name is already in the namespace, get the node */ @@ -265,6 +266,16 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, break; } + /* + * If we are executing a method, do not create any namespace objects + * during the load phase, only during execution. + */ + if (walk_state->method_node) { + node = NULL; + status = AE_OK; + break; + } + flags = ACPI_NS_NO_UPSEARCH; if ((walk_state->opcode != AML_SCOPE_OP) && (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) { @@ -290,7 +301,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, &(node)); if (ACPI_FAILURE(status)) { ACPI_REPORT_NSERROR(path, status); - return (status); + return_ACPI_STATUS(status); } break; } @@ -302,28 +313,29 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, op = acpi_ps_alloc_op(walk_state->opcode); if (!op) { - return (AE_NO_MEMORY); + return_ACPI_STATUS(AE_NO_MEMORY); } } - /* Initialize */ - - op->named.name = node->name.integer; + /* Initialize the op */ #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)) op->named.path = ACPI_CAST_PTR(u8, path); #endif - /* - * Put the Node in the "op" object that the parser uses, so we - * can get it again quickly when this scope is closed - */ - op->common.node = node; + if (node) { + /* + * Put the Node in the "op" object that the parser uses, so we + * can get it again quickly when this scope is closed + */ + op->common.node = node; + op->named.name = node->name.integer; + } + acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state), op); - *out_op = op; - return (status); + return_ACPI_STATUS(status); } /******************************************************************************* @@ -339,13 +351,13 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, * ******************************************************************************/ -acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) +acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) { union acpi_parse_object *op; acpi_object_type object_type; acpi_status status = AE_OK; - ACPI_FUNCTION_NAME("ds_load1_end_op"); + ACPI_FUNCTION_TRACE("ds_load1_end_op"); op = walk_state->op; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, @@ -354,7 +366,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) /* We are only interested in opcodes that have an associated name */ if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* Get the object type to determine if we should pop the scope */ @@ -363,21 +375,37 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) #ifndef ACPI_NO_METHOD_EXECUTION if (walk_state->op_info->flags & AML_FIELD) { - if (walk_state->opcode == AML_FIELD_OP || - walk_state->opcode == AML_BANK_FIELD_OP || - walk_state->opcode == AML_INDEX_FIELD_OP) { - status = acpi_ds_init_field_objects(op, walk_state); + /* + * If we are executing a method, do not create any namespace objects + * during the load phase, only during execution. + */ + if (!walk_state->method_node) { + if (walk_state->opcode == AML_FIELD_OP || + walk_state->opcode == AML_BANK_FIELD_OP || + walk_state->opcode == AML_INDEX_FIELD_OP) { + status = + acpi_ds_init_field_objects(op, walk_state); + } } - return (status); + return_ACPI_STATUS(status); } - if (op->common.aml_opcode == AML_REGION_OP) { - status = acpi_ex_create_region(op->named.data, op->named.length, - (acpi_adr_space_type) - ((op->common.value.arg)->common. - value.integer), walk_state); - if (ACPI_FAILURE(status)) { - return (status); + /* + * If we are executing a method, do not create any namespace objects + * during the load phase, only during execution. + */ + if (!walk_state->method_node) { + if (op->common.aml_opcode == AML_REGION_OP) { + status = + acpi_ex_create_region(op->named.data, + op->named.length, + (acpi_adr_space_type) + ((op->common.value.arg)-> + common.value.integer), + walk_state); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } } } #endif @@ -391,7 +419,12 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) common. aml_opcode))-> object_type; - op->common.node->type = (u8) object_type; + + /* Set node type if we have a namespace node */ + + if (op->common.node) { + op->common.node->type = (u8) object_type; + } } } @@ -424,7 +457,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) walk_state->num_operands = 0; if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } } } @@ -439,7 +472,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) status = acpi_ds_scope_stack_pop(walk_state); } - return (status); + return_ACPI_STATUS(status); } /******************************************************************************* @@ -456,8 +489,8 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) ******************************************************************************/ acpi_status -acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state, - union acpi_parse_object ** out_op) +acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op) { union acpi_parse_object *op; struct acpi_namespace_node *node; @@ -840,6 +873,13 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) case AML_TYPE_NAMED_FIELD: + /* + * If we are executing a method, initialize the field + */ + if (walk_state->method_node) { + status = acpi_ds_init_field_objects(op, walk_state); + } + switch (op->common.aml_opcode) { case AML_INDEX_FIELD_OP: @@ -929,6 +969,24 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) switch (op->common.aml_opcode) { #ifndef ACPI_NO_METHOD_EXECUTION case AML_REGION_OP: + + /* + * If we are executing a method, initialize the region + */ + if (walk_state->method_node) { + status = + acpi_ex_create_region(op->named.data, + op->named.length, + (acpi_adr_space_type) + ((op->common.value. + arg)->common.value. + integer), + walk_state); + if (ACPI_FAILURE(status)) { + return (status); + } + } + /* * The op_region is not fully parsed at this time. Only valid * argument is the space_id. (We must save the address of the diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index 9faf1d5c86ed..864c642759fa 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c @@ -212,7 +212,9 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, /* * Now we can print out the pertinent information */ - acpi_os_printf(" %-12s %p ", acpi_ut_get_type_name(type), this_node); + acpi_os_printf(" %-12s %p %2.2X ", + acpi_ut_get_type_name(type), this_node, + this_node->owner_id); dbg_level = acpi_dbg_level; acpi_dbg_level = 0; diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index d6813d88a104..6828c7aefa8a 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -793,6 +793,11 @@ void acpi_ut_init_globals(void) acpi_gbl_mutex_info[i].use_count = 0; } + for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) { + acpi_gbl_owner_id_mask[i] = 0; + } + acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; /* Last ID is never valid */ + /* GPE support */ acpi_gbl_gpe_xrupt_list_head = NULL; @@ -830,8 +835,8 @@ void acpi_ut_init_globals(void) acpi_gbl_ns_lookup_count = 0; acpi_gbl_ps_find_count = 0; acpi_gbl_acpi_hardware_present = TRUE; - acpi_gbl_owner_id_mask = 0; - acpi_gbl_last_owner_id = 0; + acpi_gbl_last_owner_id_index = 0; + acpi_gbl_next_owner_id_offset = 0; acpi_gbl_trace_method_name = 0; acpi_gbl_trace_dbg_level = 0; acpi_gbl_trace_dbg_layer = 0; diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 89efba7bf449..64dd64b1aa18 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -64,6 +64,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) { acpi_native_uint i; acpi_native_uint j; + acpi_native_uint k; acpi_status status; ACPI_FUNCTION_TRACE("ut_allocate_owner_id"); @@ -85,32 +86,50 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) /* * Find a free owner ID, cycle through all possible IDs on repeated - * allocations. Note: Index for next possible ID is equal to the value - * of the last allocated ID. + * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have + * to be scanned twice. */ - for (i = 0, j = acpi_gbl_last_owner_id; i < 32; i++, j++) { - if (j >= 32) { - j = 0; /* Wraparound to ID start */ + for (i = 0, j = acpi_gbl_last_owner_id_index; + i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) { + if (j >= ACPI_NUM_OWNERID_MASKS) { + j = 0; /* Wraparound to start of mask array */ } - if (!(acpi_gbl_owner_id_mask & (1 << j))) { - /* - * Found a free ID. The actual ID is the bit index plus one, - * making zero an invalid Owner ID. Save this as the last ID - * allocated and update the global ID mask. - */ - acpi_gbl_last_owner_id = (acpi_owner_id) (j + 1); - *owner_id = acpi_gbl_last_owner_id; + for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) { + if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) { + /* There are no free IDs in this mask */ - ACPI_DEBUG_PRINT((ACPI_DB_VALUES, - "Current owner_id mask: %8.8X New ID: %2.2X\n", - acpi_gbl_owner_id_mask, - (unsigned int) - acpi_gbl_last_owner_id)); + break; + } - acpi_gbl_owner_id_mask |= (1 << j); - goto exit; + if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) { + /* + * Found a free ID. The actual ID is the bit index plus one, + * making zero an invalid Owner ID. Save this as the last ID + * allocated and update the global ID mask. + */ + acpi_gbl_owner_id_mask[j] |= (1 << k); + + acpi_gbl_last_owner_id_index = (u8) j; + acpi_gbl_next_owner_id_offset = (u8) (k + 1); + + /* + * Construct encoded ID from the index and bit position + * + * Note: Last [j].k (bit 255) is never used and is marked + * permanently allocated (prevents +1 overflow) + */ + *owner_id = + (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j)); + + ACPI_DEBUG_PRINT((ACPI_DB_VALUES, + "Allocated owner_id: %2.2X\n", + (unsigned int)*owner_id)); + goto exit; + } } + + acpi_gbl_next_owner_id_offset = 0; } /* @@ -124,7 +143,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) * methods, or there may be a bug where the IDs are not released. */ status = AE_OWNER_ID_LIMIT; - ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n")); + ACPI_REPORT_ERROR(("Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT\n")); exit: (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); @@ -141,7 +160,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) * control method or unloading a table. Either way, we would * ignore any error anyway. * - * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 32 + * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255 * ******************************************************************************/ @@ -149,6 +168,8 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) { acpi_owner_id owner_id = *owner_id_ptr; acpi_status status; + acpi_native_uint index; + u32 bit; ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id); @@ -158,7 +179,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) /* Zero is not a valid owner_iD */ - if ((owner_id == 0) || (owner_id > 32)) { + if ((owner_id == 0) || (owner_id > 255)) { ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id)); return_VOID; } @@ -174,10 +195,18 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) owner_id--; + /* Decode ID to index/offset pair */ + + index = ACPI_DIV_32(owner_id); + bit = 1 << ACPI_MOD_32(owner_id); + /* Free the owner ID only if it is valid */ - if (acpi_gbl_owner_id_mask & (1 << owner_id)) { - acpi_gbl_owner_id_mask ^= (1 << owner_id); + if (acpi_gbl_owner_id_mask[index] & bit) { + acpi_gbl_owner_id_mask[index] ^= bit; + } else { + ACPI_REPORT_ERROR(("Release of non-allocated owner_id: %2.2X\n", + owner_id + 1)); } (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 08eafece3eed..f48b9ee9a876 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20051117 +#define ACPI_CA_VERSION 0x20051202 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, @@ -110,6 +110,10 @@ #define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096 +/* owner_id tracking. 8 entries allows for 255 owner_ids */ + +#define ACPI_NUM_OWNERID_MASKS 8 + /****************************************************************************** * * ACPI Specification constants (Do not change unless the specification changes) diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index bd344e51313b..3f37560c26ab 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h @@ -220,10 +220,11 @@ ACPI_EXTERN u32 acpi_gbl_original_mode; ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; ACPI_EXTERN u32 acpi_gbl_ps_find_count; -ACPI_EXTERN u32 acpi_gbl_owner_id_mask; +ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS]; ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; ACPI_EXTERN u16 acpi_gbl_global_lock_handle; -ACPI_EXTERN u8 acpi_gbl_last_owner_id; +ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; +ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; ACPI_EXTERN u8 acpi_gbl_debugger_configuration; ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; ACPI_EXTERN u8 acpi_gbl_step_to_next_call; diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 5b78ff4091b9..65a1a5c1a689 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -332,6 +332,10 @@ #define ACPI_MUL_16(a) _ACPI_MUL(a,4) #define ACPI_MOD_16(a) _ACPI_MOD(a,16) +#define ACPI_DIV_32(a) _ACPI_DIV(a,5) +#define ACPI_MUL_32(a) _ACPI_MUL(a,5) +#define ACPI_MOD_32(a) _ACPI_MOD(a,32) + /* * Rounding macros (Power of two boundaries only) */ From 729b4d4ce1982c52040bbf22d6711cdf8db07ad8 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 1 Dec 2005 04:29:00 -0500 Subject: [PATCH 019/695] [ACPI] fix reboot upon suspend-to-disk http://bugzilla.kernel.org/show_bug.cgi?id=4320 Signed-off-by: Alexey Starikovskiy Acked-by: Pavel Machek Signed-off-by: Len Brown --- drivers/acpi/sleep/poweroff.c | 15 +++++++++------ drivers/acpi/sleep/sleep.h | 2 +- drivers/acpi/sleep/wakeup.c | 6 +++--- include/linux/kernel.h | 1 + include/linux/reboot.h | 3 +-- kernel/power/disk.c | 9 +-------- kernel/sys.c | 25 ++++++++++--------------- 7 files changed, 26 insertions(+), 35 deletions(-) diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c index af7935a95bcc..47fb4b394eec 100644 --- a/drivers/acpi/sleep/poweroff.c +++ b/drivers/acpi/sleep/poweroff.c @@ -33,9 +33,7 @@ int acpi_sleep_prepare(u32 acpi_state) ACPI_FLUSH_CPU_CACHE(); acpi_enable_wakeup_device_prep(acpi_state); #endif - if (acpi_state == ACPI_STATE_S5) { - acpi_wakeup_gpe_poweroff_prepare(); - } + acpi_gpe_sleep_prepare(acpi_state); acpi_enter_sleep_state_prep(acpi_state); return 0; } @@ -53,11 +51,16 @@ void acpi_power_off(void) static int acpi_shutdown(struct sys_device *x) { - if (system_state == SYSTEM_POWER_OFF) { - /* Prepare if we are going to power off the system */ + switch (system_state) { + case SYSTEM_POWER_OFF: + /* Prepare to power off the system */ return acpi_sleep_prepare(ACPI_STATE_S5); + case SYSTEM_SUSPEND_DISK: + /* Prepare to suspend the system to disk */ + return acpi_sleep_prepare(ACPI_STATE_S4); + default: + return 0; } - return 0; } static struct sysdev_class acpi_sysclass = { diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h index efd0001c6f05..f3e70397a7d6 100644 --- a/drivers/acpi/sleep/sleep.h +++ b/drivers/acpi/sleep/sleep.h @@ -5,4 +5,4 @@ extern int acpi_suspend (u32 state); extern void acpi_enable_wakeup_device_prep(u8 sleep_state); extern void acpi_enable_wakeup_device(u8 sleep_state); extern void acpi_disable_wakeup_device(u8 sleep_state); -extern void acpi_wakeup_gpe_poweroff_prepare(void); +extern void acpi_gpe_sleep_prepare(u32 sleep_state); diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index 4134ed43d026..85df0ceda2a9 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c @@ -192,7 +192,7 @@ late_initcall(acpi_wakeup_device_init); * RUNTIME GPEs, we simply mark all GPES that * are not enabled for wakeup from S5 as RUNTIME. */ -void acpi_wakeup_gpe_poweroff_prepare(void) +void acpi_gpe_sleep_prepare(u32 sleep_state) { struct list_head *node, *next; @@ -201,8 +201,8 @@ void acpi_wakeup_gpe_poweroff_prepare(void) struct acpi_device, wakeup_list); - /* The GPE can wakeup system from S5, don't touch it */ - if ((u32) dev->wakeup.sleep_state == ACPI_STATE_S5) + /* The GPE can wakeup system from this state, don't touch it */ + if ((u32) dev->wakeup.sleep_state >= sleep_state) continue; /* acpi_set_gpe_type will automatically disable GPE */ acpi_set_gpe_type(dev->wakeup.gpe_device, diff --git a/include/linux/kernel.h b/include/linux/kernel.h index b1e407a4fbda..73aa55a73334 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -181,6 +181,7 @@ extern enum system_states { SYSTEM_HALT, SYSTEM_POWER_OFF, SYSTEM_RESTART, + SYSTEM_SUSPEND_DISK, } system_state; #define TAINT_PROPRIETARY_MODULE (1<<0) diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 7ab2cdb83ef0..015297ff73fa 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -60,8 +60,7 @@ extern void machine_crash_shutdown(struct pt_regs *); */ extern void kernel_restart_prepare(char *cmd); -extern void kernel_halt_prepare(void); -extern void kernel_power_off_prepare(void); +extern void kernel_shutdown_prepare(enum system_states state); extern void kernel_restart(char *cmd); extern void kernel_halt(void); diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 027322a564f4..f2cd279d07c7 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -52,7 +52,7 @@ static void power_down(suspend_disk_method_t mode) switch(mode) { case PM_DISK_PLATFORM: - kernel_power_off_prepare(); + kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); error = pm_ops->enter(PM_SUSPEND_DISK); break; case PM_DISK_SHUTDOWN: @@ -119,13 +119,6 @@ static int prepare_processes(void) goto thaw; } - if (pm_disk_mode == PM_DISK_PLATFORM) { - if (pm_ops && pm_ops->prepare) { - if ((error = pm_ops->prepare(PM_SUSPEND_DISK))) - goto thaw; - } - } - /* Free memory before shutting down devices. */ free_some_memory(); return 0; diff --git a/kernel/sys.c b/kernel/sys.c index eecf84526afe..c3b1874661fa 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -427,23 +427,25 @@ void kernel_kexec(void) } EXPORT_SYMBOL_GPL(kernel_kexec); +void kernel_shutdown_prepare(enum system_states state) +{ + notifier_call_chain(&reboot_notifier_list, + (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL); + system_state = state; + device_shutdown(); +} /** * kernel_halt - halt the system * * Shutdown everything and perform a clean system halt. */ -void kernel_halt_prepare(void) -{ - notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); - system_state = SYSTEM_HALT; - device_shutdown(); -} void kernel_halt(void) { - kernel_halt_prepare(); + kernel_shutdown_prepare(SYSTEM_HALT); printk(KERN_EMERG "System halted.\n"); machine_halt(); } + EXPORT_SYMBOL_GPL(kernel_halt); /** @@ -451,20 +453,13 @@ EXPORT_SYMBOL_GPL(kernel_halt); * * Shutdown everything and perform a clean system power_off. */ -void kernel_power_off_prepare(void) -{ - notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); - system_state = SYSTEM_POWER_OFF; - device_shutdown(); -} void kernel_power_off(void) { - kernel_power_off_prepare(); + kernel_shutdown_prepare(SYSTEM_POWER_OFF); printk(KERN_EMERG "Power down.\n"); machine_power_off(); } EXPORT_SYMBOL_GPL(kernel_power_off); - /* * Reboot system call: for obvious reasons only root may call it, * and even root needs to set up some magic numbers in the registers From f8a363b83f18356ebf0df0904fa4807ae48b21f2 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 20 Dec 2005 12:13:30 -0800 Subject: [PATCH 020/695] [X86] Remove Winchip 4 ID. This CPU never made it into production. It went on to become the basis for the VIA Samuel. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/centaur.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c index 394814e57672..0dd92a23d622 100644 --- a/arch/i386/kernel/cpu/centaur.c +++ b/arch/i386/kernel/cpu/centaur.c @@ -405,10 +405,6 @@ static void __init init_centaur(struct cpuinfo_x86 *c) winchip2_protect_mcr(); #endif break; - case 10: - name="4"; - /* no info on the WC4 yet */ - break; default: name="??"; } From c32017a43d552b78717160bf6aab2af8a7ff84c4 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 20 Dec 2005 14:46:07 -0800 Subject: [PATCH 021/695] [X86] Rename MTRR mutex to something more sensible. I spotted 'main_lock' whilst grovelling through a vmlinux with objdump. Even if it is static, it's a horrible name. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/mtrr/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 1e9db198c440..1a577768d4da 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -49,7 +49,7 @@ u32 num_var_ranges = 0; unsigned int *usage_table; -static DECLARE_MUTEX(main_lock); +static DECLARE_MUTEX(mtrr_sem); u32 size_or_mask, size_and_mask; @@ -335,7 +335,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, /* No CPU hotplug when we change MTRR entries */ lock_cpu_hotplug(); /* Search for existing MTRR */ - down(&main_lock); + down(&mtrr_sem); for (i = 0; i < num_var_ranges; ++i) { mtrr_if->get(i, &lbase, &lsize, <ype); if (base >= lbase + lsize) @@ -373,7 +373,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, printk(KERN_INFO "mtrr: no more MTRRs available\n"); error = i; out: - up(&main_lock); + up(&mtrr_sem); unlock_cpu_hotplug(); return error; } @@ -466,7 +466,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) max = num_var_ranges; /* No CPU hotplug when we change MTRR entries */ lock_cpu_hotplug(); - down(&main_lock); + down(&mtrr_sem); if (reg < 0) { /* Search for existing MTRR */ for (i = 0; i < max; ++i) { @@ -505,7 +505,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) set_mtrr(reg, 0, 0, 0); error = reg; out: - up(&main_lock); + up(&mtrr_sem); unlock_cpu_hotplug(); return error; } @@ -688,7 +688,7 @@ void mtrr_ap_init(void) if (!mtrr_if || !use_intel()) return; /* - * Ideally we should hold main_lock here to avoid mtrr entries changed, + * Ideally we should hold mtrr_sem here to avoid mtrr entries changed, * but this routine will be called in cpu boot time, holding the lock * breaks it. This routine is called in two cases: 1.very earily time * of software resume, when there absolutely isn't mtrr entry changes; From 63c94b68ec30847a6e2b36651703f41066f91480 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Mon, 5 Dec 2005 20:51:00 -0500 Subject: [PATCH 022/695] [ACPI] build EC driver on IA64 Signed-off-by: Kenji Kaneshige Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index fe1e8126fbae..0c6abf49528e 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -270,7 +270,6 @@ config ACPI_DEBUG config ACPI_EC bool - depends on X86 default y help This driver is required on some systems for the proper operation of From cb654695f6b912cef7cb3271665b6ee0d416124c Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 28 Dec 2005 02:43:51 -0500 Subject: [PATCH 023/695] [ACPI] acpi_register_gsi() fix needed for ACPICA 20051021 Use the #define for ACPI_LEVEL_SENSITIVE instead of assuming non-zero, because ACPICA 20051021 changes its value to zero. Also, use uniform variable names: edge_level -> triggering active_high_low -> polarity Signed-off-by: Len Brown --- arch/i386/kernel/acpi/boot.c | 6 +++--- arch/i386/kernel/mpparse.c | 8 ++++---- arch/ia64/kernel/acpi.c | 6 +++--- arch/x86_64/kernel/mpparse.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 447fa9e33ffb..1f378df14f34 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -464,7 +464,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) * success: return IRQ number (>=0) * failure: return < 0 */ -int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) +int acpi_register_gsi(u32 gsi, int triggering, int polarity) { unsigned int irq; unsigned int plat_gsi = gsi; @@ -476,14 +476,14 @@ int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { extern void eisa_set_level_irq(unsigned int irq); - if (edge_level == ACPI_LEVEL_SENSITIVE) + if (triggering == ACPI_LEVEL_SENSITIVE) eisa_set_level_irq(gsi); } #endif #ifdef CONFIG_X86_IO_APIC if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { - plat_gsi = mp_register_gsi(gsi, edge_level, active_high_low); + plat_gsi = mp_register_gsi(gsi, triggering, polarity); } #endif acpi_gsi_to_irq(plat_gsi, &irq); diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 1ca5269b1e86..d7cede83ba2e 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -1070,7 +1070,7 @@ void __init mp_config_acpi_legacy_irqs (void) #define MAX_GSI_NUM 4096 -int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) +int mp_register_gsi (u32 gsi, int triggering, int polarity) { int ioapic = -1; int ioapic_pin = 0; @@ -1119,7 +1119,7 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<=0) * failure: return < 0 */ -int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) +int acpi_register_gsi(u32 gsi, int triggering, int polarity) { if (has_8259 && gsi < 16) return isa_irq_to_vector(gsi); return iosapic_register_intr(gsi, - (active_high_low == + (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, - (edge_level == + (triggering == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); } diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index ba817e7454b2..dc49bfb6db0a 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c @@ -964,7 +964,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1< Date: Fri, 16 Dec 2005 17:05:00 -0500 Subject: [PATCH 024/695] [ACPI] ACPICA 20051216 Implemented optional support to allow unresolved names within ASL Package objects. A null object is inserted in the package when a named reference cannot be located in the current namespace. Enabled via the interpreter slack flag which Linux has enabled by default (acpi=strict to disable slack). This should eliminate AE_NOT_FOUND exceptions seen on machines that contain such code. Implemented an optimization to the initialization sequence that can improve boot time. During ACPI device initialization, the _STA method is now run if and only if the _INI method exists. The _STA method is used to determine if the device is present; An _INI can only be run if _STA returns present, but it is a waste of time to run the _STA method if the _INI does not exist. (Prototype and assistance from Dong Wei) Implemented use of the C99 uintptr_t for the pointer casting macros if it is available in the current compiler. Otherwise, the default (void *) cast is used as before. Fixed some possible memory leaks found within the execution path of the Break, Continue, If, and CreateField operators. (Valery Podrezov) Fixed a problem introduced in the 20051202 release where an exception is generated during method execution if a control method attempts to declare another method. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsmethod.c | 65 +++++- drivers/acpi/dispatcher/dsobject.c | 81 +++++--- drivers/acpi/dispatcher/dswexec.c | 35 +--- drivers/acpi/dispatcher/dswload.c | 110 +++++++--- drivers/acpi/executer/exoparg3.c | 4 +- drivers/acpi/hardware/hwregs.c | 3 +- drivers/acpi/namespace/nsinit.c | 99 +++++---- drivers/acpi/namespace/nssearch.c | 17 +- drivers/acpi/namespace/nsxfeval.c | 4 +- drivers/acpi/parser/psargs.c | 218 ++++++++++---------- drivers/acpi/parser/psloop.c | 9 + drivers/acpi/parser/psparse.c | 17 +- drivers/acpi/resources/rsdump.c | 1 - drivers/acpi/utilities/utalloc.c | 4 +- drivers/acpi/utilities/uteval.c | 20 +- drivers/acpi/utilities/utglobal.c | 9 +- drivers/acpi/utilities/utmisc.c | 2 +- drivers/acpi/utilities/utresrc.c | 109 ++++++++++ include/acpi/acconfig.h | 2 +- include/acpi/acdisasm.h | 24 +-- include/acpi/acdispat.h | 3 + include/acpi/acglobal.h | 8 +- include/acpi/aclocal.h | 31 +++ include/acpi/acmacros.h | 24 ++- include/acpi/actbl.h | 6 + include/acpi/actypes.h | 315 ++++++++++++++++------------- include/acpi/acutils.h | 24 +++ 27 files changed, 800 insertions(+), 444 deletions(-) diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 58ad00b31ee9..e7ce86b8d954 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -47,10 +47,68 @@ #include #include #include +#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsmethod") +/******************************************************************************* + * + * FUNCTION: acpi_ds_method_error + * + * PARAMETERS: Status - Execution status + * walk_state - Current state + * + * RETURN: Status + * + * DESCRIPTION: Called on method error. Invoke the global exception handler if + * present, dump the method data if the disassembler is configured + * + * Note: Allows the exception handler to change the status code + * + ******************************************************************************/ +acpi_status +acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) +{ + ACPI_FUNCTION_ENTRY(); + + /* Ignore AE_OK and control exception codes */ + + if (ACPI_SUCCESS(status) || (status & AE_CODE_CONTROL)) { + return (status); + } + + /* Invoke the global exception handler */ + + if (acpi_gbl_exception_handler) { + /* Exit the interpreter, allow handler to execute methods */ + + acpi_ex_exit_interpreter(); + + /* + * Handler can map the exception code to anything it wants, including + * AE_OK, in which case the executing method will not be aborted. + */ + status = acpi_gbl_exception_handler(status, + walk_state->method_node ? + walk_state->method_node-> + name.integer : 0, + walk_state->opcode, + walk_state->aml_offset, + NULL); + (void)acpi_ex_enter_interpreter(); + } +#ifdef ACPI_DISASSEMBLER + if (ACPI_FAILURE(status)) { + /* Display method locals/args if disassembler is present */ + + acpi_dm_dump_method_info(status, walk_state, walk_state->op); + } +#endif + + return (status); +} + /******************************************************************************* * * FUNCTION: acpi_ds_begin_method_execution @@ -66,10 +124,11 @@ ACPI_MODULE_NAME("dsmethod") * for clearance to execute. * ******************************************************************************/ + acpi_status -acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, - union acpi_operand_object *obj_desc, - struct acpi_namespace_node *calling_method_node) +acpi_ds_begin_method_execution(struct acpi_namespace_node * method_node, + union acpi_operand_object * obj_desc, + struct acpi_namespace_node * calling_method_node) { acpi_status status = AE_OK; diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 8ac0cd93adb5..905a84e4b145 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -51,6 +51,7 @@ #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsobject") +/* Local prototypes */ static acpi_status acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, union acpi_parse_object *op, @@ -85,7 +86,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, *obj_desc_ptr = NULL; if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { /* - * This is an named object reference. If this name was + * This is a named object reference. If this name was * previously looked up in the namespace, it was stored in this op. * Otherwise, go ahead and look it up now */ @@ -96,18 +97,48 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, - (struct acpi_namespace_node **) - &(op->common.node)); - + ACPI_CAST_INDIRECT_PTR(struct + acpi_namespace_node, + &(op-> + common. + node))); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(op->common.value.string, - status); + /* Check if we are resolving a named reference within a package */ + + if ((status == AE_NOT_FOUND) + && (acpi_gbl_enable_interpreter_slack) + && + ((op->common.parent->common.aml_opcode == + AML_PACKAGE_OP) + || (op->common.parent->common.aml_opcode == + AML_VAR_PACKAGE_OP))) { + /* + * We didn't find the target and we are populating elements + * of a package - ignore if slack enabled. Some ASL code + * contains dangling invalid references in packages and + * expects that no exception will be issued. Leave the + * element as a null element. It cannot be used, but it + * can be overwritten by subsequent ASL code - this is + * typically the case. + */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Ignoring unresolved reference in package [%4.4s]\n", + walk_state-> + scope_info->scope. + node->name.ascii)); + + return_ACPI_STATUS(AE_OK); + } else { + ACPI_REPORT_NSERROR(op->common.value. + string, status); + } + return_ACPI_STATUS(status); } } } - /* Create and init the internal ACPI object */ + /* Create and init a new internal ACPI object */ obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info (op->common.aml_opcode))-> @@ -157,13 +188,13 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, ACPI_FUNCTION_TRACE("ds_build_internal_buffer_obj"); + /* + * If we are evaluating a Named buffer object "Name (xxxx, Buffer)". + * The buffer object already exists (from the NS node), otherwise it must + * be created. + */ obj_desc = *obj_desc_ptr; - if (obj_desc) { - /* - * We are evaluating a Named buffer object "Name (xxxx, Buffer)". - * The buffer object already exists (from the NS node) - */ - } else { + if (!obj_desc) { /* Create a new buffer object */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); @@ -259,7 +290,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, union acpi_operand_object *obj_desc = NULL; u32 package_list_length; acpi_status status = AE_OK; - u32 i; + acpi_native_uint i; ACPI_FUNCTION_TRACE("ds_build_internal_package_obj"); @@ -271,13 +302,12 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, parent = parent->common.parent; } + /* + * If we are evaluating a Named package object "Name (xxxx, Package)", + * the package object already exists, otherwise it must be created. + */ obj_desc = *obj_desc_ptr; - if (obj_desc) { - /* - * We are evaluating a Named package object "Name (xxxx, Package)". - * Get the existing package object from the NS node - */ - } else { + if (!obj_desc) { obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE); *obj_desc_ptr = obj_desc; if (!obj_desc) { @@ -291,11 +321,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, /* Count the number of items in the package list */ - package_list_length = 0; arg = op->common.value.arg; arg = arg->common.next; - while (arg) { - package_list_length++; + for (package_list_length = 0; arg; package_list_length++) { arg = arg->common.next; } @@ -322,12 +350,11 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, } /* - * Now init the elements of the package + * Initialize all elements of the package */ - i = 0; arg = op->common.value.arg; arg = arg->common.next; - while (arg) { + for (i = 0; arg; i++) { if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { /* Object (package or buffer) is already built */ @@ -340,8 +367,6 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, package. elements[i]); } - - i++; arg = arg->common.next; } diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index e522763bb692..74f6996db2d7 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -314,12 +314,13 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, case AML_CLASS_EXECUTE: case AML_CLASS_CREATE: - /* * Most operators with arguments. * Start a new result/operand state */ - status = acpi_ds_result_stack_push(walk_state); + if (walk_state->opcode != AML_CREATE_FIELD_OP) { + status = acpi_ds_result_stack_push(walk_state); + } break; default: @@ -723,20 +724,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) cleanup: - /* Invoke exception handler on error */ - - if (ACPI_FAILURE(status) && - acpi_gbl_exception_handler && !(status & AE_CODE_CONTROL)) { - acpi_ex_exit_interpreter(); - status = acpi_gbl_exception_handler(status, - walk_state->method_node-> - name.integer, - walk_state->opcode, - walk_state->aml_offset, - NULL); - (void)acpi_ex_enter_interpreter(); - } - if (walk_state->result_obj) { /* Break to debugger to display result */ @@ -758,18 +745,14 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) } #endif + /* Invoke exception handler on error */ + + if (ACPI_FAILURE(status)) { + status = acpi_ds_method_error(status, walk_state); + } + /* Always clear the object stack */ walk_state->num_operands = 0; - -#ifdef ACPI_DISASSEMBLER - - /* On error, display method locals/args */ - - if (ACPI_FAILURE(status)) { - acpi_dm_dump_method_info(status, walk_state, op); - } -#endif - return_ACPI_STATUS(status); } diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 44d4f4bb2f92..441931cab08a 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -428,43 +428,54 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) } } - if (op->common.aml_opcode == AML_METHOD_OP) { - /* - * method_op pkg_length name_string method_flags term_list - * - * Note: We must create the method node/object pair as soon as we - * see the method declaration. This allows later pass1 parsing - * of invocations of the method (need to know the number of - * arguments.) - */ - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "LOADING-Method: State=%p Op=%p named_obj=%p\n", - walk_state, op, op->named.node)); + /* + * If we are executing a method, do not create any namespace objects + * during the load phase, only during execution. + */ + if (!walk_state->method_node) { + if (op->common.aml_opcode == AML_METHOD_OP) { + /* + * method_op pkg_length name_string method_flags term_list + * + * Note: We must create the method node/object pair as soon as we + * see the method declaration. This allows later pass1 parsing + * of invocations of the method (need to know the number of + * arguments.) + */ + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, + "LOADING-Method: State=%p Op=%p named_obj=%p\n", + walk_state, op, op->named.node)); - if (!acpi_ns_get_attached_object(op->named.node)) { - walk_state->operands[0] = (void *)op->named.node; - walk_state->num_operands = 1; + if (!acpi_ns_get_attached_object(op->named.node)) { + walk_state->operands[0] = + ACPI_CAST_PTR(void, op->named.node); + walk_state->num_operands = 1; - status = - acpi_ds_create_operands(walk_state, - op->common.value.arg); - if (ACPI_SUCCESS(status)) { - status = acpi_ex_create_method(op->named.data, - op->named.length, - walk_state); - } - walk_state->operands[0] = NULL; - walk_state->num_operands = 0; + status = + acpi_ds_create_operands(walk_state, + op->common.value. + arg); + if (ACPI_SUCCESS(status)) { + status = + acpi_ex_create_method(op->named. + data, + op->named. + length, + walk_state); + } + walk_state->operands[0] = NULL; + walk_state->num_operands = 0; - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } } } } - /* Pop the scope stack */ + /* Pop the scope stack (only if loading a table) */ - if (acpi_ns_opens_scope(object_type)) { + if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) { ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n", acpi_ut_get_type_name(object_type), op)); @@ -1015,11 +1026,50 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) status = acpi_ds_create_node(walk_state, node, op); break; + + case AML_METHOD_OP: + /* + * method_op pkg_length name_string method_flags term_list + * + * Note: We must create the method node/object pair as soon as we + * see the method declaration. This allows later pass1 parsing + * of invocations of the method (need to know the number of + * arguments.) + */ + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, + "LOADING-Method: State=%p Op=%p named_obj=%p\n", + walk_state, op, op->named.node)); + + if (!acpi_ns_get_attached_object(op->named.node)) { + walk_state->operands[0] = + ACPI_CAST_PTR(void, op->named.node); + walk_state->num_operands = 1; + + status = + acpi_ds_create_operands(walk_state, + op->common.value. + arg); + if (ACPI_SUCCESS(status)) { + status = + acpi_ex_create_method(op->named. + data, + op->named. + length, + walk_state); + } + walk_state->operands[0] = NULL; + walk_state->num_operands = 0; + + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + break; + #endif /* ACPI_NO_METHOD_EXECUTION */ default: /* All NAMED_COMPLEX opcodes must be handled above */ - /* Note: Method objects were already created in Pass 1 */ break; } break; diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c index 483365777670..2ea1c322970b 100644 --- a/drivers/acpi/executer/exoparg3.c +++ b/drivers/acpi/executer/exoparg3.c @@ -223,8 +223,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) goto cleanup; } - if (length > 0) { - /* Copy the portion requested */ + if (buffer) { + /* We have a buffer, copy the portion requested */ ACPI_MEMCPY(buffer, operand[0]->string.pointer + index, length); diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index 536a7aea80c9..b243f20708b7 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c @@ -144,7 +144,8 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) info.parameters = NULL; info.return_object = NULL; - sleep_state_name = (char *)acpi_gbl_sleep_state_names[sleep_state]; + sleep_state_name = + ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); status = acpi_ns_evaluate_by_name(sleep_state_name, &info); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index 0a08d2f04a06..efa3f4233736 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c @@ -336,23 +336,22 @@ acpi_ns_init_one_device(acpi_handle obj_handle, struct acpi_parameter_info pinfo; u32 flags; acpi_status status; + struct acpi_namespace_node *ini_node; + struct acpi_namespace_node *device_node; ACPI_FUNCTION_TRACE("ns_init_one_device"); - pinfo.parameters = NULL; - pinfo.parameter_type = ACPI_PARAM_ARGS; - - pinfo.node = acpi_ns_map_handle_to_node(obj_handle); - if (!pinfo.node) { + device_node = acpi_ns_map_handle_to_node(obj_handle); + if (!device_node) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* * We will run _STA/_INI on Devices, Processors and thermal_zones only */ - if ((pinfo.node->type != ACPI_TYPE_DEVICE) && - (pinfo.node->type != ACPI_TYPE_PROCESSOR) && - (pinfo.node->type != ACPI_TYPE_THERMAL)) { + if ((device_node->type != ACPI_TYPE_DEVICE) && + (device_node->type != ACPI_TYPE_PROCESSOR) && + (device_node->type != ACPI_TYPE_THERMAL)) { return_ACPI_STATUS(AE_OK); } @@ -364,57 +363,69 @@ acpi_ns_init_one_device(acpi_handle obj_handle, info->device_count++; /* - * Run _STA to determine if we can run _INI on the device. + * Check if the _INI method exists for this device - + * if _INI does not exist, there is no need to run _STA + * No _INI means device requires no initialization */ - ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, - pinfo.node, - METHOD_NAME__STA)); - status = acpi_ut_execute_STA(pinfo.node, &flags); - + status = acpi_ns_search_node(*ACPI_CAST_PTR(u32, METHOD_NAME__INI), + device_node, ACPI_TYPE_METHOD, &ini_node); if (ACPI_FAILURE(status)) { - if (pinfo.node->type == ACPI_TYPE_DEVICE) { - /* Ignore error and move on to next device */ + /* No _INI method found - move on to next device */ - return_ACPI_STATUS(AE_OK); - } - - /* _STA is not required for Processor or thermal_zone objects */ - } else { - info->num_STA++; - - if (!(flags & 0x01)) { - /* Don't look at children of a not present device */ - - return_ACPI_STATUS(AE_CTRL_DEPTH); - } + return_ACPI_STATUS(AE_OK); } /* - * The device is present. Run _INI. + * Run _STA to determine if we can run _INI on the device - + * the device must be present before _INI can be run. + * However, _STA is not required - assume device present if no _STA + */ + ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, + device_node, + METHOD_NAME__STA)); + + pinfo.node = device_node; + pinfo.parameters = NULL; + pinfo.parameter_type = ACPI_PARAM_ARGS; + + status = acpi_ut_execute_STA(pinfo.node, &flags); + if (ACPI_FAILURE(status)) { + /* Ignore error and move on to next device */ + + return_ACPI_STATUS(AE_OK); + } + + if (flags != ACPI_UINT32_MAX) { + info->num_STA++; + } + + if (!(flags & ACPI_STA_DEVICE_PRESENT)) { + /* Don't look at children of a not present device */ + + return_ACPI_STATUS(AE_CTRL_DEPTH); + } + + /* + * The device is present and _INI exists. Run the _INI method. + * (We already have the _INI node from above) */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, pinfo.node, METHOD_NAME__INI)); - status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo); - if (ACPI_FAILURE(status)) { - /* No _INI (AE_NOT_FOUND) means device requires no initialization */ - if (status != AE_NOT_FOUND) { - /* Ignore error and move on to next device */ + pinfo.node = ini_node; + status = acpi_ns_evaluate_by_handle(&pinfo); + if (ACPI_FAILURE(status)) { + /* Ignore error and move on to next device */ #ifdef ACPI_DEBUG_OUTPUT - char *scope_name = - acpi_ns_get_external_pathname(pinfo.node); + char *scope_name = acpi_ns_get_external_pathname(ini_node); - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "%s._INI failed: %s\n", - scope_name, - acpi_format_exception(status))); + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "%s._INI failed: %s\n", + scope_name, acpi_format_exception(status))); - ACPI_MEM_FREE(scope_name); + ACPI_MEM_FREE(scope_name); #endif - } - - status = AE_OK; } else { /* Delete any return object (especially if implicit_return is enabled) */ @@ -434,5 +445,5 @@ acpi_ns_init_one_device(acpi_handle obj_handle, acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI); } - return_ACPI_STATUS(status); + return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index 50a3ca5470ed..c1b1943d4670 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -99,8 +99,8 @@ acpi_ns_search_node(u32 target_name, if (scope_name) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Searching %s (%p) For [%4.4s] (%s)\n", - scope_name, node, - (char *)&target_name, + scope_name, node, ACPI_CAST_PTR(char, + &target_name), acpi_ut_get_type_name(type))); ACPI_MEM_FREE(scope_name); @@ -131,7 +131,7 @@ acpi_ns_search_node(u32 target_name, */ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", - (char *)&target_name, + ACPI_CAST_PTR(char, &target_name), acpi_ut_get_type_name(next_node-> type), next_node, @@ -160,7 +160,8 @@ acpi_ns_search_node(u32 target_name, ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", - (char *)&target_name, acpi_ut_get_type_name(type), + ACPI_CAST_PTR(char, &target_name), + acpi_ut_get_type_name(type), acpi_ut_get_node_name(node), node, node->child)); return_ACPI_STATUS(AE_NOT_FOUND); @@ -210,14 +211,14 @@ acpi_ns_search_parent_tree(u32 target_name, */ if (!parent_node) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] has no parent\n", - (char *)&target_name)); + ACPI_CAST_PTR(char, &target_name))); return_ACPI_STATUS(AE_NOT_FOUND); } if (acpi_ns_local(type)) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] type [%s] must be local to this scope (no parent search)\n", - (char *)&target_name, + ACPI_CAST_PTR(char, &target_name), acpi_ut_get_type_name(type))); return_ACPI_STATUS(AE_NOT_FOUND); } @@ -227,7 +228,7 @@ acpi_ns_search_parent_tree(u32 target_name, ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Searching parent [%4.4s] for [%4.4s]\n", acpi_ut_get_node_name(parent_node), - (char *)&target_name)); + ACPI_CAST_PTR(char, &target_name))); /* * Search parents until target is found or we have backed up to the root @@ -360,7 +361,7 @@ acpi_ns_search_and_enter(u32 target_name, if (interpreter_mode == ACPI_IMODE_EXECUTE) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%4.4s Not found in %p [Not adding]\n", - (char *)&target_name, node)); + ACPI_CAST_PTR(char, &target_name), node)); return_ACPI_STATUS(AE_NOT_FOUND); } diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index 8167af1fa57b..75b137a6a3c9 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -473,8 +473,8 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, return (AE_CTRL_DEPTH); } - if (!(flags & 0x01)) { - /* Don't return at the device or children of the device if not there */ + if (!(flags & ACPI_STA_DEVICE_PRESENT)) { + /* Don't examine children of the device if not present */ return (AE_CTRL_DEPTH); } diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 6eae35febccd..e6d4cb9fd303 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -45,6 +45,7 @@ #include #include #include +#include #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psargs") @@ -211,7 +212,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) * Arg - Where the namepath will be stored * arg_count - If the namepath points to a control method * the method's argument is returned here. - * method_call - Whether the namepath can possibly be the + * possible_method_call - Whether the namepath can possibly be the * start of a method call * * RETURN: Status @@ -227,11 +228,11 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) acpi_status acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, struct acpi_parse_state *parser_state, - union acpi_parse_object *arg, u8 method_call) + union acpi_parse_object *arg, u8 possible_method_call) { char *path; union acpi_parse_object *name_op; - acpi_status status = AE_OK; + acpi_status status; union acpi_operand_object *method_desc; struct acpi_namespace_node *node; union acpi_generic_state scope_info; @@ -239,114 +240,127 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, ACPI_FUNCTION_TRACE("ps_get_next_namepath"); path = acpi_ps_get_next_namestring(parser_state); + acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); - /* Null path case is allowed */ + /* Null path case is allowed, just exit */ - if (path) { - /* - * Lookup the name in the internal namespace - */ - scope_info.scope.node = NULL; - node = parser_state->start_node; - if (node) { - scope_info.scope.node = node; - } + if (!path) { + arg->common.value.name = path; + return_ACPI_STATUS(AE_OK); + } - /* - * Lookup object. We don't want to add anything new to the namespace - * here, however. So we use MODE_EXECUTE. Allow searching of the - * parent tree, but don't open a new scope -- we just want to lookup the - * object (MUST BE mode EXECUTE to perform upsearch) - */ - status = acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, - ACPI_IMODE_EXECUTE, - ACPI_NS_SEARCH_PARENT | - ACPI_NS_DONT_OPEN_SCOPE, NULL, &node); - if (ACPI_SUCCESS(status) && method_call) { - if (node->type == ACPI_TYPE_METHOD) { - /* This name is actually a control method invocation */ + /* Setup search scope info */ - method_desc = acpi_ns_get_attached_object(node); - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "Control Method - %p Desc %p Path=%p\n", - node, method_desc, path)); - - name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); - if (!name_op) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* Change arg into a METHOD CALL and attach name to it */ - - acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); - name_op->common.value.name = path; - - /* Point METHODCALL/NAME to the METHOD Node */ - - name_op->common.node = node; - acpi_ps_append_arg(arg, name_op); - - if (!method_desc) { - ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node)); - return_ACPI_STATUS(AE_AML_INTERNAL); - } - - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "Control Method - %p Args %X\n", - node, - method_desc->method. - param_count)); - - /* Get the number of arguments to expect */ - - walk_state->arg_count = - method_desc->method.param_count; - return_ACPI_STATUS(AE_OK); - } - - /* - * Else this is normal named object reference. - * Just init the NAMEPATH object with the pathname. - * (See code below) - */ - } - - if (ACPI_FAILURE(status)) { - /* - * 1) Any error other than NOT_FOUND is always severe - * 2) NOT_FOUND is only important if we are executing a method. - * 3) If executing a cond_ref_of opcode, NOT_FOUND is ok. - */ - if ((((walk_state-> - parse_flags & ACPI_PARSE_MODE_MASK) == - ACPI_PARSE_EXECUTE) && (status == AE_NOT_FOUND) - && (walk_state->op->common.aml_opcode != - AML_COND_REF_OF_OP)) - || (status != AE_NOT_FOUND)) { - ACPI_REPORT_NSERROR(path, status); - - acpi_os_printf - ("search_node %p start_node %p return_node %p\n", - scope_info.scope.node, - parser_state->start_node, node); - } else { - /* - * We got a NOT_FOUND during table load or we encountered - * a cond_ref_of(x) where the target does not exist. - * Either case is ok - */ - status = AE_OK; - } - } + scope_info.scope.node = NULL; + node = parser_state->start_node; + if (node) { + scope_info.scope.node = node; } /* - * Regardless of success/failure above, - * Just initialize the Op with the pathname. + * Lookup the name in the internal namespace. We don't want to add + * anything new to the namespace here, however, so we use MODE_EXECUTE. + * Allow searching of the parent tree, but don't open a new scope - + * we just want to lookup the object (must be mode EXECUTE to perform + * the upsearch) */ - acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); - arg->common.value.name = path; + status = + acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, + NULL, &node); + /* + * If this name is a control method invocation, we must + * setup the method call + */ + if (ACPI_SUCCESS(status) && + possible_method_call && (node->type == ACPI_TYPE_METHOD)) { + /* This name is actually a control method invocation */ + + method_desc = acpi_ns_get_attached_object(node); + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Control Method - %p Desc %p Path=%p\n", node, + method_desc, path)); + + name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); + if (!name_op) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Change Arg into a METHOD CALL and attach name to it */ + + acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); + name_op->common.value.name = path; + + /* Point METHODCALL/NAME to the METHOD Node */ + + name_op->common.node = node; + acpi_ps_append_arg(arg, name_op); + + if (!method_desc) { + ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node)); + return_ACPI_STATUS(AE_AML_INTERNAL); + } + + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Control Method - %p Args %X\n", + node, method_desc->method.param_count)); + + /* Get the number of arguments to expect */ + + walk_state->arg_count = method_desc->method.param_count; + return_ACPI_STATUS(AE_OK); + } + + /* + * Special handling if the name was not found during the lookup - + * some not_found cases are allowed + */ + if (status == AE_NOT_FOUND) { + /* 1) not_found is ok during load pass 1/2 (allow forward references) */ + + if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) != + ACPI_PARSE_EXECUTE) { + status = AE_OK; + } + + /* 2) not_found during a cond_ref_of(x) is ok by definition */ + + else if (walk_state->op->common.aml_opcode == + AML_COND_REF_OF_OP) { + status = AE_OK; + } + + /* + * 3) not_found while building a Package is ok at this point, we + * may flag as an error later if slack mode is not enabled. + * (Some ASL code depends on allowing this behavior) + */ + else if ((arg->common.parent) && + ((arg->common.parent->common.aml_opcode == + AML_PACKAGE_OP) + || (arg->common.parent->common.aml_opcode == + AML_VAR_PACKAGE_OP))) { + status = AE_OK; + } + } + + /* Final exception check (may have been changed from code above) */ + + if (ACPI_FAILURE(status)) { + ACPI_REPORT_NSERROR(path, status); + + if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == + ACPI_PARSE_EXECUTE) { + /* Report a control method execution error */ + + status = acpi_ds_method_error(status, walk_state); + } + } + + /* Save the namepath */ + + arg->common.value.name = path; return_ACPI_STATUS(status); } diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index 088d33999d90..e81e51b8b3ae 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c @@ -704,6 +704,15 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); + + if (op->common.aml_opcode != AML_WHILE_OP) { + status2 = + acpi_ds_result_stack_pop + (walk_state); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + } } /* Close this iteration of the While loop */ diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 7cfa7eb0dfc7..f0979b2956f2 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -333,7 +333,6 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, switch (callback_status) { case AE_CTRL_TERMINATE: - /* * A control method was terminated via a RETURN statement. * The walk of this method is complete. @@ -346,13 +345,19 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, parser_state->aml = walk_state->aml_last_while; walk_state->control_state->common.value = FALSE; - status = AE_CTRL_BREAK; + status = acpi_ds_result_stack_pop(walk_state); + if (ACPI_SUCCESS(status)) { + status = AE_CTRL_BREAK; + } break; case AE_CTRL_CONTINUE: parser_state->aml = walk_state->aml_last_while; - status = AE_CTRL_CONTINUE; + status = acpi_ds_result_stack_pop(walk_state); + if (ACPI_SUCCESS(status)) { + status = AE_CTRL_CONTINUE; + } break; case AE_CTRL_PENDING: @@ -369,16 +374,18 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, #endif case AE_CTRL_TRUE: - /* * Predicate of an IF was true, and we are at the matching ELSE. * Just close out this package */ parser_state->aml = acpi_ps_get_next_package_end(parser_state); + status = acpi_ds_result_stack_pop(walk_state); + if (ACPI_SUCCESS(status)) { + status = AE_CTRL_PENDING; + } break; case AE_CTRL_FALSE: - /* * Either an IF/WHILE Predicate was false or we encountered a BREAK * opcode. In both cases, we do not execute the rest of the diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index cebd890d3db5..c24e3eb658c3 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -43,7 +43,6 @@ #include #include -#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsdump") diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index e04b6119a4d7..b11b7ed788c6 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c @@ -47,7 +47,7 @@ ACPI_MODULE_NAME("utalloc") /* Local prototypes */ -#ifdef ACPI_DBG_TRACK_ALLOCATIONS +#ifdef ACPI_DBG_TRACK_ALLOCATIONS static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation); static acpi_status @@ -58,9 +58,7 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *address, static acpi_status acpi_ut_remove_allocation(struct acpi_debug_mem_block *address, u32 component, char *module, u32 line); -#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ -#ifdef ACPI_DBG_TRACK_ALLOCATIONS static acpi_status acpi_ut_create_list(char *list_name, u16 object_size, struct acpi_memory_list **return_cache); diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 7b81d5ef3c32..cd63a2d93fe3 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c @@ -95,7 +95,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) { if (!ACPI_STRCMP(string_desc->string.pointer, - (char *)acpi_gbl_valid_osi_strings[i])) { + ACPI_CAST_PTR(char, + acpi_gbl_valid_osi_strings[i]))) + { /* This string is supported */ return_desc->integer.value = 0xFFFFFFFF; @@ -592,7 +594,7 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) "_STA on %4.4s was not found, assuming device is present\n", acpi_ut_get_node_name(device_node))); - *flags = 0x0F; + *flags = ACPI_UINT32_MAX; status = AE_OK; } @@ -637,17 +639,17 @@ acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) for (i = 0; i < 4; i++) { highest[i] = 0xFF; status = acpi_ut_evaluate_object(device_node, - (char *) - acpi_gbl_highest_dstate_names - [i], ACPI_BTYPE_INTEGER, - &obj_desc); + ACPI_CAST_PTR(char, + acpi_gbl_highest_dstate_names + [i]), + ACPI_BTYPE_INTEGER, &obj_desc); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s on Device %4.4s, %s\n", - (char *) - acpi_gbl_highest_dstate_names - [i], + ACPI_CAST_PTR(char, + acpi_gbl_highest_dstate_names + [i]), acpi_ut_get_node_name (device_node), acpi_format_exception diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 6828c7aefa8a..7c59c2b0d953 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -485,7 +485,7 @@ char *acpi_ut_get_region_name(u8 space_id) return ("invalid_space_id"); } - return ((char *)acpi_gbl_region_types[space_id]); + return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id])); } /******************************************************************************* @@ -690,11 +690,12 @@ char *acpi_ut_get_descriptor_name(void *object) } if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) { - return ((char *)acpi_gbl_bad_type); + return (ACPI_CAST_PTR(char, acpi_gbl_bad_type)); } - return ((char *) - acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE(object)]); + return (ACPI_CAST_PTR(char, + acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE + (object)])); } diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 64dd64b1aa18..48d511d5c04b 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -179,7 +179,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) /* Zero is not a valid owner_iD */ - if ((owner_id == 0) || (owner_id > 255)) { + if (owner_id == 0) { ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id)); return_VOID; } diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index 6c0ce7b12194..eaf0edec6efe 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c @@ -47,6 +47,115 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") +#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) +/* + * Strings used to decode resource descriptors. + * Used by both the disasssembler and the debugger resource dump routines + */ +const char *acpi_gbl_BMdecode[2] = { + "not_bus_master", + "bus_master" +}; + +const char *acpi_gbl_config_decode[4] = { + "0 - Good Configuration", + "1 - Acceptable Configuration", + "2 - Suboptimal Configuration", + "3 - ***Invalid Configuration***", +}; + +const char *acpi_gbl_consume_decode[2] = { + "resource_producer", + "resource_consumer" +}; + +const char *acpi_gbl_DECdecode[2] = { + "pos_decode", + "sub_decode" +}; + +const char *acpi_gbl_HEdecode[2] = { + "Level", + "Edge" +}; + +const char *acpi_gbl_io_decode[2] = { + "Decode10", + "Decode16" +}; + +const char *acpi_gbl_LLdecode[2] = { + "active_high", + "active_low" +}; + +const char *acpi_gbl_max_decode[2] = { + "max_not_fixed", + "max_fixed" +}; + +const char *acpi_gbl_MEMdecode[4] = { + "non_cacheable", + "Cacheable", + "write_combining", + "Prefetchable" +}; + +const char *acpi_gbl_min_decode[2] = { + "min_not_fixed", + "min_fixed" +}; + +const char *acpi_gbl_MTPdecode[4] = { + "address_range_memory", + "address_range_reserved", + "address_range_aCPI", + "address_range_nVS" +}; + +const char *acpi_gbl_RNGdecode[4] = { + "invalid_ranges", + "non_iSAonly_ranges", + "ISAonly_ranges", + "entire_range" +}; + +const char *acpi_gbl_RWdecode[2] = { + "read_only", + "read_write" +}; + +const char *acpi_gbl_SHRdecode[2] = { + "Exclusive", + "Shared" +}; + +const char *acpi_gbl_SIZdecode[4] = { + "Transfer8", + "Transfer8_16", + "Transfer16", + "invalid_size" +}; + +const char *acpi_gbl_TRSdecode[2] = { + "dense_translation", + "sparse_translation" +}; + +const char *acpi_gbl_TTPdecode[2] = { + "type_static", + "type_translation" +}; + +const char *acpi_gbl_TYPdecode[4] = { + "Compatibility", + "type_a", + "type_b", + "type_f" +}; + +#endif + /* * Base sizes of the raw AML resource descriptors, indexed by resource type. * Zero indicates a reserved (and therefore invalid) resource type. diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index f48b9ee9a876..1f2477eb95fe 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20051202 +#define ACPI_CA_VERSION 0x20051216 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index 99250ee1b9d1..0a8f49f5d2f1 100644 --- a/include/acpi/acdisasm.h +++ b/include/acpi/acdisasm.h @@ -57,27 +57,11 @@ struct acpi_external_list { }; extern struct acpi_external_list *acpi_gbl_external_list; -extern const char *acpi_gbl_io_decode[2]; -extern const char *acpi_gbl_word_decode[4]; -extern const char *acpi_gbl_consume_decode[2]; -extern const char *acpi_gbl_config_decode[4]; -extern const char *acpi_gbl_min_decode[2]; -extern const char *acpi_gbl_max_decode[2]; -extern const char *acpi_gbl_DECdecode[2]; -extern const char *acpi_gbl_RNGdecode[4]; -extern const char *acpi_gbl_MEMdecode[4]; -extern const char *acpi_gbl_RWdecode[2]; -extern const char *acpi_gbl_irq_decode[2]; -extern const char *acpi_gbl_HEdecode[2]; -extern const char *acpi_gbl_LLdecode[2]; -extern const char *acpi_gbl_SHRdecode[2]; -extern const char *acpi_gbl_TYPdecode[4]; -extern const char *acpi_gbl_BMdecode[2]; -extern const char *acpi_gbl_SIZdecode[4]; -extern const char *acpi_gbl_TTPdecode[2]; -extern const char *acpi_gbl_MTPdecode[4]; -extern const char *acpi_gbl_TRSdecode[2]; +/* Strings used for decoding flags to ASL keywords */ + +extern const char *acpi_gbl_word_decode[4]; +extern const char *acpi_gbl_irq_decode[2]; extern const char *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES]; extern const char *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES]; extern const char *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES]; diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h index 065f24a77cfc..cc6407eef701 100644 --- a/include/acpi/acdispat.h +++ b/include/acpi/acdispat.h @@ -201,6 +201,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, union acpi_operand_object *obj_desc, struct acpi_namespace_node *calling_method_node); +acpi_status +acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state); + /* * dsinit */ diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index 3f37560c26ab..dfb3b2493ae5 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h @@ -98,11 +98,15 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; /* * Enable "slack" in the AML interpreter? Default is FALSE, and the * interpreter strictly follows the ACPI specification. Setting to TRUE - * allows the interpreter to forgive certain bad AML constructs. Currently: + * allows the interpreter to ignore certain errors and/or bad AML constructs. + * + * Currently, these features are enabled by this flag: + * * 1) Allow "implicit return" of last value in a control method - * 2) Allow access beyond end of operation region + * 2) Allow access beyond the end of an operation region * 3) Allow access to uninitialized locals/args (auto-init to integer 0) * 4) Allow ANY object type to be a source operand for the Store() operator + * 5) Allow unresolved references (invalid target name) in package objects */ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index 0cb61a72d971..da7f1cb96f5d 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -276,6 +276,37 @@ struct acpi_create_field_info { u8 field_type; }; +/* + * Bitmapped ACPI types. Used internally only + */ +#define ACPI_BTYPE_ANY 0x00000000 +#define ACPI_BTYPE_INTEGER 0x00000001 +#define ACPI_BTYPE_STRING 0x00000002 +#define ACPI_BTYPE_BUFFER 0x00000004 +#define ACPI_BTYPE_PACKAGE 0x00000008 +#define ACPI_BTYPE_FIELD_UNIT 0x00000010 +#define ACPI_BTYPE_DEVICE 0x00000020 +#define ACPI_BTYPE_EVENT 0x00000040 +#define ACPI_BTYPE_METHOD 0x00000080 +#define ACPI_BTYPE_MUTEX 0x00000100 +#define ACPI_BTYPE_REGION 0x00000200 +#define ACPI_BTYPE_POWER 0x00000400 +#define ACPI_BTYPE_PROCESSOR 0x00000800 +#define ACPI_BTYPE_THERMAL 0x00001000 +#define ACPI_BTYPE_BUFFER_FIELD 0x00002000 +#define ACPI_BTYPE_DDB_HANDLE 0x00004000 +#define ACPI_BTYPE_DEBUG_OBJECT 0x00008000 +#define ACPI_BTYPE_REFERENCE 0x00010000 +#define ACPI_BTYPE_RESOURCE 0x00020000 + +#define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER) + +#define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE) +#define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE) +#define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR) +#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */ +#define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF + /***************************************************************************** * * Event typedefs and structs diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 65a1a5c1a689..0fa8f72dbace 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -60,7 +60,7 @@ /* * For 16-bit addresses, we have to assume that the upper 32 bits - * are zero. + * (out of 64) are zero. */ #define ACPI_LODWORD(l) ((u32)(l)) #define ACPI_HIDWORD(l) ((u32)(0)) @@ -104,8 +104,9 @@ #define ACPI_FORMAT_UINT64(i) ACPI_HIDWORD(i),ACPI_LODWORD(i) /* - * Extract a byte of data using a pointer. Any more than a byte and we - * get into potential aligment issues -- see the STORE macros below + * Extract data using a pointer. Any more than a byte and we + * get into potential aligment issues -- see the STORE macros below. + * Use with care. */ #define ACPI_GET8(ptr) *ACPI_CAST_PTR (u8, ptr) #define ACPI_GET16(ptr) *ACPI_CAST_PTR (u16, ptr) @@ -116,16 +117,17 @@ #define ACPI_SET32(ptr) *ACPI_CAST_PTR (u32, ptr) #define ACPI_SET64(ptr) *ACPI_CAST_PTR (u64, ptr) -/* Pointer manipulation */ - -#define ACPI_CAST_PTR(t, p) ((t *)(void *)(p)) -#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **)(void *)(p)) -#define ACPI_ADD_PTR(t,a,b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8, (a)) + (acpi_native_uint)(b))) -#define ACPI_PTR_DIFF(a,b) (acpi_native_uint) ((char *)(a) - (char *)(b)) +/* + * Pointer manipulation + */ +#define ACPI_CAST_PTR(t, p) ((t *) (acpi_uintptr_t) (p)) +#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (acpi_uintptr_t) (p)) +#define ACPI_ADD_PTR(t,a,b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_native_uint)(b))) +#define ACPI_PTR_DIFF(a,b) (acpi_native_uint) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b))) /* Pointer/Integer type conversions */ -#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL,(acpi_native_uint)i) +#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void,(void *) NULL,(acpi_native_uint) i) #define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) #define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) #define ACPI_FADT_OFFSET(f) ACPI_OFFSET (FADT_DESCRIPTOR, f) @@ -133,7 +135,7 @@ #if ACPI_MACHINE_WIDTH == 16 #define ACPI_STORE_POINTER(d,s) ACPI_MOVE_32_TO_32(d,s) #define ACPI_PHYSADDR_TO_PTR(i) (void *)(i) -#define ACPI_PTR_TO_PHYSADDR(i) (u32) (char *)(i) +#define ACPI_PTR_TO_PHYSADDR(i) (u32) ACPI_CAST_PTR (u8,(i)) #else #define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) #define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index a46f406e1c94..ef2ddcadfe61 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -44,6 +44,12 @@ #ifndef __ACTBL_H__ #define __ACTBL_H__ +/* + * Note about bitfields: The u8 type is used for bitfields in ACPI tables. + * This is the only type that is even remotely portable. Anything else is not + * portable, so do not use any other bitfield types. + */ + /* * Values for description table header signatures */ diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 11847592ed1b..18e1338c5c7f 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -44,7 +44,15 @@ #ifndef __ACTYPES_H__ #define __ACTYPES_H__ -/*! [Begin] no source code translation (keep the typedefs) */ +/* + * ACPI_MACHINE_WIDTH must be specified in an OS- or compiler-dependent header + * and must be either 16, 32, or 64 + */ +#ifndef ACPI_MACHINE_WIDTH +#error ACPI_MACHINE_WIDTH not defined +#endif + +/*! [Begin] no source code translation */ /* * Data type ranges @@ -58,154 +66,210 @@ #define ACPI_UINT64_MAX (UINT64)(~((UINT64) 0)) /* 0xFFFFFFFFFFFFFFFF */ #define ACPI_ASCII_MAX 0x7F -#ifdef DEFINE_ALTERNATE_TYPES /* - * Types used only in translated source, defined here to enable - * cross-platform compilation only. - */ -typedef int s32; -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef COMPILER_DEPENDENT_UINT64 u64; - -#endif - -/* - * Data types - Fixed across all compilation models (16/32/64) + * Architecture-specific ACPICA Subsystem Data Types + * + * The goal of these types is to provide source code portability across + * 16-bit, 32-bit, and 64-bit targets. + * + * 1) The following types are of fixed size for all targets (16/32/64): + * + * BOOLEAN Logical boolean + * + * UINT8 8-bit (1 byte) unsigned value + * UINT16 16-bit (2 byte) unsigned value + * UINT32 32-bit (4 byte) unsigned value + * UINT64 64-bit (8 byte) unsigned value + * + * INT16 16-bit (2 byte) signed value + * INT32 32-bit (4 byte) signed value + * INT64 64-bit (8 byte) signed value + * + * COMPILER_DEPENDENT_UINT64/INT64 - These types are defined in the + * compiler-dependent header(s) and were introduced because there is no common + * 64-bit integer type across the various compilation models, as shown in + * the table below. + * + * Datatype LP64 ILP64 LLP64 ILP32 LP32 16bit + * char 8 8 8 8 8 8 + * short 16 16 16 16 16 16 + * _int32 32 + * int 32 64 32 32 16 16 + * long 64 64 32 32 32 32 + * long long 64 64 + * pointer 64 64 64 32 32 32 + * + * Note: ILP64 and LP32 are currently not supported. + * + * + * 2) These types represent the native word size of the target mode of the + * processor, and may be 16-bit, 32-bit, or 64-bit as required. They are + * usually used for memory allocation, efficient loop counters, and array + * indexes. The types are similar to the size_t type in the C library and are + * required because there is no C type that consistently represents the native + * data width. + * + * ACPI_SIZE 16/32/64-bit unsigned value + * ACPI_NATIVE_UINT 16/32/64-bit unsigned value + * ACPI_NATIVE_INT 16/32/64-bit signed value * - * BOOLEAN Logical Boolean. - * INT8 8-bit (1 byte) signed value - * UINT8 8-bit (1 byte) unsigned value - * INT16 16-bit (2 byte) signed value - * UINT16 16-bit (2 byte) unsigned value - * INT32 32-bit (4 byte) signed value - * UINT32 32-bit (4 byte) unsigned value - * INT64 64-bit (8 byte) signed value - * UINT64 64-bit (8 byte) unsigned value - * ACPI_NATIVE_UINT 32-bit on IA-32, 64-bit on x86_64/IA-64 unsigned value */ -typedef unsigned long acpi_native_uint; +/******************************************************************************* + * + * Common types for all compilers, all targets + * + ******************************************************************************/ -#ifndef ACPI_MACHINE_WIDTH -#error ACPI_MACHINE_WIDTH not defined -#endif +typedef unsigned char BOOLEAN; +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef COMPILER_DEPENDENT_UINT64 UINT64; +typedef COMPILER_DEPENDENT_INT64 INT64; + +/*! [End] no source code translation !*/ + +/******************************************************************************* + * + * Types specific to 64-bit targets + * + ******************************************************************************/ #if ACPI_MACHINE_WIDTH == 64 -/*! [Begin] no source code translation (keep the typedefs) */ +/*! [Begin] no source code translation (keep the typedefs as-is) */ -/* - * 64-bit type definitions - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned short UINT16; -typedef int INT32; typedef unsigned int UINT32; -typedef COMPILER_DEPENDENT_INT64 INT64; -typedef COMPILER_DEPENDENT_UINT64 UINT64; +typedef int INT32; /*! [End] no source code translation !*/ +typedef u64 acpi_native_uint; +typedef s64 acpi_native_int; + typedef u64 acpi_table_ptr; typedef u64 acpi_io_address; typedef u64 acpi_physical_address; -typedef u64 acpi_size; -#define ALIGNED_ADDRESS_BOUNDARY 0x00000008 /* No hardware alignment support in IA64 */ -#define ACPI_USE_NATIVE_DIVIDE /* Native 64-bit integer support */ #define ACPI_MAX_PTR ACPI_UINT64_MAX #define ACPI_SIZE_MAX ACPI_UINT64_MAX +#define ALIGNED_ADDRESS_BOUNDARY 0x00000008 +#define ACPI_USE_NATIVE_DIVIDE /* Has native 64-bit integer support */ + /* * In the case of the Itanium Processor Family (IPF), the hardware does not * support misaligned memory transfers. Set the MISALIGNMENT_NOT_SUPPORTED flag * to indicate that special precautions must be taken to avoid alignment faults. * (IA64 or ia64 is currently used by existing compilers to indicate IPF.) * - * Note: Em64_t and other X86-64 processors do support misaligned transfers, + * Note: Em64_t and other X86-64 processors support misaligned transfers, * so there is no need to define this flag. */ #if defined (__IA64__) || defined (__ia64__) #define ACPI_MISALIGNMENT_NOT_SUPPORTED #endif -#elif ACPI_MACHINE_WIDTH == 16 - -/*! [Begin] no source code translation (keep the typedefs as-is) */ - -/* - * 16-bit type definitions - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned int UINT16; -typedef long INT32; -typedef int INT16; -typedef unsigned long UINT32; - -struct { - UINT32 Lo; - UINT32 Hi; -}; - -/*! [End] no source code translation !*/ - -typedef u32 acpi_table_ptr; -typedef u32 acpi_io_address; -typedef char *acpi_physical_address; -typedef u16 acpi_size; - -#define ALIGNED_ADDRESS_BOUNDARY 0x00000002 -#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */ -#define ACPI_MAX_PTR ACPI_UINT16_MAX -#define ACPI_SIZE_MAX ACPI_UINT16_MAX - -/* - * (16-bit only) internal integers must be 32-bits, so - * 64-bit integers cannot be supported - */ -#define ACPI_NO_INTEGER64_SUPPORT +/******************************************************************************* + * + * Types specific to 32-bit targets + * + ******************************************************************************/ #elif ACPI_MACHINE_WIDTH == 32 -/*! [Begin] no source code translation (keep the typedefs) */ +/*! [Begin] no source code translation (keep the typedefs as-is) */ -/* - * 32-bit type definitions (default) - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned short UINT16; -typedef int INT32; typedef unsigned int UINT32; -typedef COMPILER_DEPENDENT_INT64 INT64; -typedef COMPILER_DEPENDENT_UINT64 UINT64; +typedef int INT32; /*! [End] no source code translation !*/ +typedef u32 acpi_native_uint; +typedef s32 acpi_native_int; + typedef u64 acpi_table_ptr; typedef u32 acpi_io_address; typedef u64 acpi_physical_address; -typedef u32 acpi_size; -#define ALIGNED_ADDRESS_BOUNDARY 0x00000004 #define ACPI_MAX_PTR ACPI_UINT32_MAX #define ACPI_SIZE_MAX ACPI_UINT32_MAX +#define ALIGNED_ADDRESS_BOUNDARY 0x00000004 + +/******************************************************************************* + * + * Types specific to 16-bit targets + * + ******************************************************************************/ + +#elif ACPI_MACHINE_WIDTH == 16 + +/*! [Begin] no source code translation (keep the typedefs as-is) */ + +typedef unsigned long UINT32; +typedef short INT16; +typedef long INT32; + +/*! [End] no source code translation !*/ + +typedef u16 acpi_native_uint; +typedef s16 acpi_native_int; + +typedef u32 acpi_table_ptr; +typedef u32 acpi_io_address; +typedef char *acpi_physical_address; + +#define ACPI_MAX_PTR ACPI_UINT16_MAX +#define ACPI_SIZE_MAX ACPI_UINT16_MAX + +#define ALIGNED_ADDRESS_BOUNDARY 0x00000002 +#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */ + +/* 64-bit integers cannot be supported */ + +#define ACPI_NO_INTEGER64_SUPPORT + #else + +/* ACPI_MACHINE_WIDTH must be either 64, 32, or 16 */ + #error unknown ACPI_MACHINE_WIDTH #endif +/******************************************************************************* + * + * OS- or compiler-dependent types + * + ******************************************************************************/ + /* - * This type is used for bitfields in ACPI tables. The only type that is - * even remotely portable is u8. Anything else is not portable, so - * do not add any more bitfield types. + * If acpi_uintptr_t was not defined in the OS- or compiler-dependent header, + * define it now (use C99 uintptr_t for pointer casting if available, + * "void *" otherwise) */ -typedef u8 UINT8_BIT; -typedef acpi_native_uint ACPI_PTRDIFF; +#ifndef acpi_uintptr_t +#define acpi_uintptr_t void * +#endif + +/* + * If acpi_cache_t was not defined in the OS-dependent header, + * define it now. This is typically the case where the local cache + * manager implementation is to be used (ACPI_USE_LOCAL_CACHE) + */ +#ifndef acpi_cache_t +#define acpi_cache_t struct acpi_memory_list +#endif + +/* Variable-width type, used instead of clib size_t */ + +typedef acpi_native_uint acpi_size; + +/******************************************************************************* + * + * Independent types + * + ******************************************************************************/ /* * Pointer overlays to avoid lots of typecasting for @@ -237,18 +301,8 @@ struct acpi_pointer { #define ACPI_LOGMODE_PHYSPTR ACPI_LOGICAL_ADDRESSING | ACPI_PHYSICAL_POINTER #define ACPI_LOGMODE_LOGPTR ACPI_LOGICAL_ADDRESSING | ACPI_LOGICAL_POINTER -/* - * If acpi_cache_t was not defined in the OS-dependent header, - * define it now. This is typically the case where the local cache - * manager implementation is to be used (ACPI_USE_LOCAL_CACHE) - */ -#ifndef acpi_cache_t -#define acpi_cache_t struct acpi_memory_list -#endif +/* Logical defines and NULL */ -/* - * Useful defines - */ #ifdef FALSE #undef FALSE #endif @@ -264,12 +318,12 @@ struct acpi_pointer { #endif /* - * Local datatypes + * Mescellaneous types */ typedef u32 acpi_status; /* All ACPI Exceptions */ typedef u32 acpi_name; /* 4-byte ACPI name */ typedef char *acpi_string; /* Null terminated ASCII string */ -typedef void *acpi_handle; /* Actually a ptr to an Node */ +typedef void *acpi_handle; /* Actually a ptr to a NS Node */ struct uint64_struct { u32 lo; @@ -472,37 +526,6 @@ typedef u32 acpi_object_type; #define ACPI_TYPE_INVALID 0x1E #define ACPI_TYPE_NOT_FOUND 0xFF -/* - * Bitmapped ACPI types. Used internally only - */ -#define ACPI_BTYPE_ANY 0x00000000 -#define ACPI_BTYPE_INTEGER 0x00000001 -#define ACPI_BTYPE_STRING 0x00000002 -#define ACPI_BTYPE_BUFFER 0x00000004 -#define ACPI_BTYPE_PACKAGE 0x00000008 -#define ACPI_BTYPE_FIELD_UNIT 0x00000010 -#define ACPI_BTYPE_DEVICE 0x00000020 -#define ACPI_BTYPE_EVENT 0x00000040 -#define ACPI_BTYPE_METHOD 0x00000080 -#define ACPI_BTYPE_MUTEX 0x00000100 -#define ACPI_BTYPE_REGION 0x00000200 -#define ACPI_BTYPE_POWER 0x00000400 -#define ACPI_BTYPE_PROCESSOR 0x00000800 -#define ACPI_BTYPE_THERMAL 0x00001000 -#define ACPI_BTYPE_BUFFER_FIELD 0x00002000 -#define ACPI_BTYPE_DDB_HANDLE 0x00004000 -#define ACPI_BTYPE_DEBUG_OBJECT 0x00008000 -#define ACPI_BTYPE_REFERENCE 0x00010000 -#define ACPI_BTYPE_RESOURCE 0x00020000 - -#define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER) - -#define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE) -#define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE) -#define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR) -#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */ -#define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF - /* * All I/O */ @@ -856,6 +879,14 @@ struct acpi_compatible_id_list { #define ACPI_VALID_CID 0x0010 #define ACPI_VALID_SXDS 0x0020 +/* Flags for _STA method */ + +#define ACPI_STA_DEVICE_PRESENT 0x01 +#define ACPI_STA_DEVICE_ENABLED 0x02 +#define ACPI_STA_DEVICE_UI 0x04 +#define ACPI_STA_DEVICE_OK 0x08 +#define ACPI_STA_BATTERY_PRESENT 0x10 + #define ACPI_COMMON_OBJ_INFO \ acpi_object_type type; /* ACPI object type */ \ acpi_name name /* ACPI object Name */ @@ -921,7 +952,9 @@ typedef u32 acpi_rsdesc_size; /* Max Resource Descriptor size is (length+3) = (6 #define ACPI_ISA_ONLY_RANGES (u8) 0x02 #define ACPI_ENTIRE_RANGE (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES) -#define ACPI_SPARSE_TRANSLATION (u8) 0x03 +/* Type of translation - 1=Sparse, 0=Dense */ + +#define ACPI_SPARSE_TRANSLATION (u8) 0x01 /* * IO Port Descriptor Decode diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index 4ff963323de3..5fa21e03a62f 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -46,6 +46,30 @@ extern const u8 acpi_gbl_resource_aml_sizes[]; +/* Strings used by the disassembler and debugger resource dump routines */ + +#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) + +extern const char *acpi_gbl_BMdecode[2]; +extern const char *acpi_gbl_config_decode[4]; +extern const char *acpi_gbl_consume_decode[2]; +extern const char *acpi_gbl_DECdecode[2]; +extern const char *acpi_gbl_HEdecode[2]; +extern const char *acpi_gbl_io_decode[2]; +extern const char *acpi_gbl_LLdecode[2]; +extern const char *acpi_gbl_max_decode[2]; +extern const char *acpi_gbl_MEMdecode[4]; +extern const char *acpi_gbl_min_decode[2]; +extern const char *acpi_gbl_MTPdecode[4]; +extern const char *acpi_gbl_RNGdecode[4]; +extern const char *acpi_gbl_RWdecode[2]; +extern const char *acpi_gbl_SHRdecode[2]; +extern const char *acpi_gbl_SIZdecode[4]; +extern const char *acpi_gbl_TRSdecode[2]; +extern const char *acpi_gbl_TTPdecode[2]; +extern const char *acpi_gbl_TYPdecode[4]; +#endif + /* Types for Resource descriptor entries */ #define ACPI_INVALID_RESOURCE 0 From 3173cdfe02995f6c6841a28b5148f94cefd8ab77 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 28 Dec 2005 03:20:03 -0500 Subject: [PATCH 025/695] [ACPI] fix osl.c build warning typecheck complains on i386 that u32 != unsigned long Signed-off-by: Len Brown --- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 4ece850b2af1..58e7c47354ee 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1073,7 +1073,7 @@ acpi_native_uint acpi_os_acquire_lock(acpi_handle handle) void acpi_os_release_lock(acpi_handle handle, acpi_native_uint flags) { - spin_unlock_irqrestore((spinlock_t *) handle, flags); + spin_unlock_irqrestore((spinlock_t *) handle, (unsigned long) flags); } #ifndef ACPI_USE_LOCAL_CACHE From b697b5372ecfe0c57ee26e0c3787fc2306109228 Mon Sep 17 00:00:00 2001 From: Karol Kozimor Date: Thu, 22 Dec 2005 12:42:00 -0500 Subject: [PATCH 026/695] [ASUS_ACPI] work around Samsung P30s oops The code used to rely on a certain method to return a NULL buffer, which is now hardly possible with the implicit return code on by default. This sort of fixes bugs #5067 and #5092 for now. Note: this patch makes the driver unusable on said machines (and on said machines only) iff acpi=strict is specified, but it seems noone really uses that. Signed-off-by: Karol Kozimor Signed-off-by: Len Brown --- drivers/acpi/asus_acpi.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index fec895af6ae6..582995ef9f34 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -987,9 +987,21 @@ static int __init asus_hotk_get_info(void) printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", bsts_result); - /* Samsung P30 has a device with a valid _HID whose INIT does not - * return anything. Catch this one and any similar here */ - if (buffer.pointer == NULL) { + /* This is unlikely with implicit return */ + if (buffer.pointer == NULL) + return -EINVAL; + + model = (union acpi_object *) buffer.pointer; + /* + * Samsung P30 has a device with a valid _HID whose INIT does not + * return anything. It used to be possible to catch this exception, + * but the implicit return code will now happily confuse the + * driver. We assume that every ACPI_TYPE_STRING is a valid model + * identifier but it's still possible to get completely bogus data. + */ + if (model->type == ACPI_TYPE_STRING) { + printk(KERN_NOTICE " %s model detected, ", model->string.pointer); + } else { if (asus_info && /* Samsung P30 */ strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) { hotk->model = P30; @@ -1002,13 +1014,10 @@ static int __init asus_hotk_get_info(void) "the developers with your DSDT\n"); } hotk->methods = &model_conf[hotk->model]; - return AE_OK; - } + + acpi_os_free(model); - model = (union acpi_object *)buffer.pointer; - if (model->type == ACPI_TYPE_STRING) { - printk(KERN_NOTICE " %s model detected, ", - model->string.pointer); + return AE_OK; } hotk->model = END_MODEL; From dacd9b80355525be0e3c519687868410e304ad1c Mon Sep 17 00:00:00 2001 From: Yu Luming Date: Sat, 31 Dec 2005 01:45:00 -0500 Subject: [PATCH 027/695] [ACPI] fix acpi_os_wait_sempahore() finite timeout case (AE_TIME warning) Before this fix, the finite timeout case behaved like the no-timeout (trylock) case. http://bugzilla.kernel.org/show_bug.cgi?id=4588 Signed-off-by: Luming Yu Signed-off-by: Len Brown --- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e3cd0b16031a..8653dac01a76 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -836,7 +836,7 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) static const int quantum_ms = 1000 / HZ; ret = down_trylock(sem); - for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) { + for (i = timeout; (i > 0 && ret != 0); i -= quantum_ms) { schedule_timeout_interruptible(1); ret = down_trylock(sem); } From bb84db937a875045de9e6d08d177ad3223ae0ae3 Mon Sep 17 00:00:00 2001 From: Karol Kozimor Date: Tue, 3 Jan 2006 23:03:00 -0500 Subject: [PATCH 028/695] [ACPI_ASUS] M6R display reading This patch corrects the node to read display settings on M6R laptops. Signed-off-by: Karol Kozimor Signed-off-by: Len Brown --- drivers/acpi/asus_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index 582995ef9f34..d4e1e95934fb 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -302,7 +302,7 @@ static struct model_data model_conf[END_MODEL] = { .brightness_set = "SPLV", .brightness_get = "GPLV", .display_set = "SDSP", - .display_get = "\\SSTE"}, + .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"}, { .name = "M6R", .mt_mled = "MLED", From aea19aa0780d4b006372fedab8434226e1cc7686 Mon Sep 17 00:00:00 2001 From: Karol Kozimor Date: Tue, 3 Jan 2006 23:05:00 -0500 Subject: [PATCH 029/695] [ACPI_ASUS] fix asus module param description Signed-off-by: Karol Kozimor Signed-off-by: Len Brown --- drivers/acpi/asus_acpi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index d4e1e95934fb..f4c87750dbf2 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -78,9 +78,9 @@ MODULE_LICENSE("GPL"); static uid_t asus_uid; static gid_t asus_gid; module_param(asus_uid, uint, 0); -MODULE_PARM_DESC(uid, "UID for entries in /proc/acpi/asus.\n"); +MODULE_PARM_DESC(asus_uid, "UID for entries in /proc/acpi/asus.\n"); module_param(asus_gid, uint, 0); -MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n"); +MODULE_PARM_DESC(asus_gid, "GID for entries in /proc/acpi/asus.\n"); /* For each model, all features implemented, * those marked with R are relative to HOTK, A for absolute */ @@ -851,6 +851,8 @@ static int __init asus_hotk_add_fs(struct acpi_device *device) mode = S_IFREG | S_IRUGO | S_IWUGO; } else { mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP; + printk(KERN_WARNING " asus_uid and asus_gid parameters are " + "deprecated, use chown and chmod instead!\n"); } acpi_device_dir(device) = asus_proc_dir; From ed349a8a0a780ed27e2a765f16cee54d9b63bfee Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 5 Jan 2006 02:40:11 -0500 Subject: [PATCH 030/695] [ACPI] fix pnpacpi regression resulting from ACPICA 20051117 In ACPICA 20051117, acpi_walk_resources() started sending ACPI_RESOURCE_TYPE_END_TAG to the callback routine which wasn't prepared for it, causing _CRS to fail and PnPACPI to not recognize any devices: pnp: ACPI device : hid PNP0C02 pnp: PnPACPI: unknown resource type 7 pnp: PnPACPI: METHOD_NAME__CRS failure for PNP0c02 Signed-off-by: Len Brown --- drivers/acpi/resources/rsxface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 50a956b705b0..5408e5d10cc3 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -286,6 +286,12 @@ acpi_walk_resources(acpi_handle device_handle, break; } + /* end_tag indicates end-of-list */ + + if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + break; + } + /* Invoke the user function, abort on any error returned */ status = user_function(resource, context); @@ -298,12 +304,6 @@ acpi_walk_resources(acpi_handle device_handle, break; } - /* end_tag indicates end-of-list */ - - if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { - break; - } - /* Get the next resource descriptor */ resource = From 2f27f8175831f9aad9f708da16814240327dba22 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 5 Jan 2006 19:31:51 -0800 Subject: [PATCH 031/695] [X86] Remove pointless versioning of mtrr driver. It's not like this has changed significantly, and probably never will. Reduce some bootup dmesg noise. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/mtrr/main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 1a577768d4da..3b4618bed70d 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -44,8 +44,6 @@ #include #include "mtrr.h" -#define MTRR_VERSION "2.0 (20020519)" - u32 num_var_ranges = 0; unsigned int *usage_table; @@ -671,7 +669,6 @@ void __init mtrr_bp_init(void) break; } } - printk(KERN_INFO "mtrr: v%s\n",MTRR_VERSION); if (mtrr_if) { set_num_var_ranges(); From 6f957eaf79356a32e838f5f262ee9a60544b1d5b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 20 Sep 2005 15:26:00 -0400 Subject: [PATCH 032/695] [ACPI] enable PNPACPI support for resource types used by HP serial ports PNPACPI complained about and ignored devices with ADDRESS16, ADDRESS32, or ADDRESS64 descriptors in _PRS. HP firmware uses them for built-in serial ports, so this patch adds support for parsing these descriptors from _PRS. Note that this does not add the corresponding support for encoding them in preparation for _SRS, because I don't have any machine that supports _SRS on these descriptors, so I couldn't test that support. Attempts to encode them will cause a warning and an -EINVAL return. http://sourceforge.net/mailarchive/forum.php?thread_id=8250154&forum_id=6102 Signed-off-by: Bjorn Helgaas Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/rsparser.c | 48 +++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 416d30debe6c..2424bd3620dc 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -453,6 +453,45 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, return; } +static void +pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r) +{ + struct acpi_resource_address64 addr, *p = &addr; + acpi_status status; + struct pnp_mem * mem; + struct pnp_port * port; + + status = acpi_resource_to_address64(r, p); + if (!ACPI_SUCCESS(status)) { + pnp_warn("PnPACPI: failed to convert resource type %d", r->id); + return; + } + + if (p->address_length == 0) + return; + + if (p->resource_type == ACPI_MEMORY_RANGE) { + mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL); + if (!mem) + return; + mem->min = mem->max = p->min_address_range; + mem->size = p->address_length; + mem->align = 0; + mem->flags = (p->attribute.memory.read_write_attribute == + ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0; + pnp_register_mem_resource(option,mem); + } else if (p->resource_type == ACPI_IO_RANGE) { + port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL); + if (!port) + return; + port->min = port->max = p->min_address_range; + port->size = p->address_length; + port->align = 0; + port->flags = PNP_PORT_FLAG_FIXED; + pnp_register_port_resource(option,port); + } +} + struct acpipnp_parse_option_s { struct pnp_option *option; struct pnp_option *option_independent; @@ -495,6 +534,11 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, pnpacpi_parse_fixed_mem32_option(option, &res->data.fixed_memory32); break; + case ACPI_RSTYPE_ADDRESS16: + case ACPI_RSTYPE_ADDRESS32: + case ACPI_RSTYPE_ADDRESS64: + pnpacpi_parse_address_option(option, res); + break; case ACPI_RSTYPE_START_DPF: switch (res->data.start_dpf.compatibility_priority) { case ACPI_GOOD_CONFIGURATION: @@ -568,11 +612,9 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, case ACPI_RSTYPE_MEM24: case ACPI_RSTYPE_MEM32: case ACPI_RSTYPE_FIXED_MEM32: -#if 0 case ACPI_RSTYPE_ADDRESS16: case ACPI_RSTYPE_ADDRESS32: case ACPI_RSTYPE_ADDRESS64: -#endif (*res_cnt) ++; default: return AE_OK; @@ -593,11 +635,9 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, case ACPI_RSTYPE_MEM24: case ACPI_RSTYPE_MEM32: case ACPI_RSTYPE_FIXED_MEM32: -#if 0 case ACPI_RSTYPE_ADDRESS16: case ACPI_RSTYPE_ADDRESS32: case ACPI_RSTYPE_ADDRESS64: -#endif (*resource)->id = res->id; (*resource)++; default: From d479e908457f4972205fcafa054f8030e91781ef Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 6 Jan 2006 16:47:00 -0500 Subject: [PATCH 033/695] [ACPI] move some run-time structure inits to compile time acpi_processor_limit_fops.write was written at run time, but can be initiailized at compile-time instead. Similar for acpi_video_bus_POST_fops.write and friends, but keep doing those at runtime to avoid prototype-hell. Signed-off-by: Arjan van de Ven Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 2 -- drivers/acpi/processor_perflib.c | 2 +- drivers/acpi/processor_thermal.c | 1 + drivers/acpi/processor_throttling.c | 1 + drivers/acpi/video.c | 8 ++++---- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 1278aca96fe3..60e550f1f955 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -357,7 +357,6 @@ static int acpi_processor_add_fs(struct acpi_device *device) ACPI_PROCESSOR_FILE_THROTTLING)); else { entry->proc_fops = &acpi_processor_throttling_fops; - entry->proc_fops->write = acpi_processor_write_throttling; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } @@ -372,7 +371,6 @@ static int acpi_processor_add_fs(struct acpi_device *device) ACPI_PROCESSOR_FILE_LIMIT)); else { entry->proc_fops = &acpi_processor_limit_fops; - entry->proc_fops->write = acpi_processor_write_limit; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 22c7bb66c200..0c0234e18261 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -520,8 +520,8 @@ static void acpi_cpufreq_add_file(struct acpi_processor *pr) "Unable to create '%s' fs entry\n", ACPI_PROCESSOR_FILE_PERFORMANCE)); else { + acpi_processor_perf_fops.write = acpi_processor_write_performance; entry->proc_fops = &acpi_processor_perf_fops; - entry->proc_fops->write = acpi_processor_write_performance; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index dc9817cfb882..22fc9e28a58d 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -394,6 +394,7 @@ ssize_t acpi_processor_write_limit(struct file * file, struct file_operations acpi_processor_limit_fops = { .open = acpi_processor_limit_open_fs, .read = seq_read, + .write = acpi_processor_write_limit, .llseek = seq_lseek, .release = single_release, }; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 74a52d4e79ae..5cd056abfcfb 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -337,6 +337,7 @@ ssize_t acpi_processor_write_throttling(struct file * file, struct file_operations acpi_processor_throttling_fops = { .open = acpi_processor_throttling_open_fs, .read = seq_read, + .write = acpi_processor_write_throttling, .llseek = seq_lseek, .release = single_release, }; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d10668f14699..bd4887518373 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -920,8 +920,8 @@ static int acpi_video_device_add_fs(struct acpi_device *device) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'state' fs entry\n")); else { + acpi_video_device_state_fops.write = acpi_video_device_write_state; entry->proc_fops = &acpi_video_device_state_fops; - entry->proc_fops->write = acpi_video_device_write_state; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } @@ -934,8 +934,8 @@ static int acpi_video_device_add_fs(struct acpi_device *device) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'brightness' fs entry\n")); else { + acpi_video_device_brightness_fops.write = acpi_video_device_write_brightness; entry->proc_fops = &acpi_video_device_brightness_fops; - entry->proc_fops->write = acpi_video_device_write_brightness; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } @@ -1239,8 +1239,8 @@ static int acpi_video_bus_add_fs(struct acpi_device *device) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'POST' fs entry\n")); else { + acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; entry->proc_fops = &acpi_video_bus_POST_fops; - entry->proc_fops->write = acpi_video_bus_write_POST; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } @@ -1253,8 +1253,8 @@ static int acpi_video_bus_add_fs(struct acpi_device *device) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'DOS' fs entry\n")); else { + acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; entry->proc_fops = &acpi_video_bus_DOS_fops; - entry->proc_fops->write = acpi_video_bus_write_DOS; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } From 3963f00831bc01f509c7dc38d050505fca64f67d Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Fri, 6 Jan 2006 01:31:00 -0500 Subject: [PATCH 034/695] [ACPI] acpi_memhotplug.c build fix drivers/acpi/acpi_memhotplug.c: In function `acpi_memory_get_device_resources': drivers/acpi/acpi_memhotplug.c:101: error: structure has no member named `attribute' drivers/acpi/acpi_memhotplug.c:103: error: structure has no member named `attribute' drivers/acpi/acpi_memhotplug.c: In function `acpi_memory_disable_device': drivers/acpi/acpi_memhotplug.c:253: warning: unused variable `attr' Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/acpi_memhotplug.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index b12946ccd135..d882bf87fa96 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -71,8 +71,8 @@ static struct acpi_driver acpi_memory_device_driver = { struct acpi_memory_device { acpi_handle handle; unsigned int state; /* State of the memory device */ - unsigned short cache_attribute; /* memory cache attribute */ - unsigned short read_write_attribute; /* memory read/write attribute */ + unsigned short caching; /* memory cache attribute */ + unsigned short write_protect; /* memory read/write attribute */ u64 start_addr; /* Memory Range start physical addr */ u64 end_addr; /* Memory Range end physical addr */ }; @@ -97,10 +97,10 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) if (ACPI_SUCCESS(status)) { if (address64.resource_type == ACPI_MEMORY_RANGE) { /* Populate the structure */ - mem_device->cache_attribute = - address64.attribute.memory.cache_attribute; - mem_device->read_write_attribute = - address64.attribute.memory.read_write_attribute; + mem_device->caching = + address64.info.mem.caching; + mem_device->write_protect = + address64.info.mem.write_protect; mem_device->start_addr = address64.minimum; mem_device->end_addr = address64.maximum; } @@ -250,7 +250,6 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) int result; u64 start = mem_device->start_addr; u64 len = mem_device->end_addr - start + 1; - unsigned long attr = mem_device->read_write_attribute; ACPI_FUNCTION_TRACE("acpi_memory_disable_device"); From 35f652b5ef4ef145ac5514f6302b3f4cebfbbad4 Mon Sep 17 00:00:00 2001 From: Benoit Boissinot Date: Fri, 6 Jan 2006 01:31:00 -0500 Subject: [PATCH 035/695] [ACPI] fix acpi_cpufreq.c build warrning Signed-off-by: Benoit Boissinot Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 31ce890865d5..8a5e159d8185 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -306,10 +306,6 @@ acpi_cpufreq_cpu_init ( struct cpufreq_acpi_io *data; unsigned int result = 0; - union acpi_object arg0 = {ACPI_TYPE_BUFFER}; - u32 arg0_buf[3]; - struct acpi_object_list arg_list = {1, &arg0}; - dprintk("acpi_cpufreq_cpu_init\n"); data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); From 876c184b31dc73cc3f38c5b86dee55d091a56769 Mon Sep 17 00:00:00 2001 From: Thomas Rosner Date: Fri, 6 Jan 2006 01:31:00 -0500 Subject: [PATCH 036/695] [ACPI] Disable C2/C3 for _all_ IBM R40e Laptops This adds all known BIOS versions of IBM R40e Laptops to the C2/C3 processor state blacklist and thus prevents them from crashing. workaround for http://bugzilla.kernel.org/show_bug.cgi?id=3549 Signed-off-by: Thomas Rosner Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 67 ++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 807b0df308f1..552420e1f890 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -95,22 +95,57 @@ static int set_max_cstate(struct dmi_system_id *id) } static struct dmi_system_id __initdata processor_power_dmi_table[] = { - {set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR, - "IBM"), - DMI_MATCH(DMI_BIOS_VERSION, - "1SET60WW")}, - (void *)1}, - {set_max_cstate, "Medion 41700", { - DMI_MATCH(DMI_BIOS_VENDOR, - "Phoenix Technologies LTD"), - DMI_MATCH(DMI_BIOS_VERSION, - "R01-A1J")}, (void *)1}, - {set_max_cstate, "Clevo 5600D", { - DMI_MATCH(DMI_BIOS_VENDOR, - "Phoenix Technologies LTD"), - DMI_MATCH(DMI_BIOS_VERSION, - "SHE845M0.86C.0013.D.0302131307")}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1}, + { set_max_cstate, "IBM ThinkPad R40e", { + DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), + DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1}, + { set_max_cstate, "Medion 41700", { + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), + DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1}, + { set_max_cstate, "Clevo 5600D", { + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, (void *)2}, {}, }; From 07b0120d53a3e7cbc88458a64a4d668fc416100f Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Fri, 6 Jan 2006 01:31:00 -0500 Subject: [PATCH 037/695] [PNPACPI] Ignore devices that have no resources Ignore devices that don't have a _CRS method. They are useless for the PNP layer as they don't provide any resources. Cc: Adam Belay Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 816479ad217b..e77d1feb759e 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -131,7 +131,8 @@ static int __init pnpacpi_add_device(struct acpi_device *device) struct pnp_id *dev_id; struct pnp_dev *dev; - if (!ispnpidacpi(acpi_device_hid(device)) || + status = acpi_get_handle(device->handle, "_CRS", &temp); + if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || is_exclusive_device(device)) return 0; From c4bb6f5ad968540d7f9619565bacd18d7419b85f Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Fri, 6 Jan 2006 01:31:00 -0500 Subject: [PATCH 038/695] [PNPACPI] clean excluded_id_list[] Clean the blacklist. Battery, Button, Fan have no _CRS and can be removed. PCI root is in pnpbios and is harmless. Cc: Adam Belay Cc: "Li, Shaohua" Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/core.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index e77d1feb759e..f104577f73e0 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -27,12 +27,15 @@ static int num = 0; +/* We need only to blacklist devices that have already an acpi driver that + * can't use pnp layer. We don't need to blacklist device that are directly + * used by the kernel (PCI root, ...), as it is harmless and there were + * already present in pnpbios. But there is an exception for devices that + * have irqs (PIC, Timer) because we call acpi_register_gsi. + * Finaly only devices that have a CRS method need to be in this list. + */ static char __initdata excluded_id_list[] = - "PNP0C0A," /* Battery */ - "PNP0C0C,PNP0C0E,PNP0C0D," /* Button */ "PNP0C09," /* EC */ - "PNP0C0B," /* Fan */ - "PNP0A03," /* PCI root */ "PNP0C0F," /* Link device */ "PNP0000," /* PIC */ "PNP0100," /* Timer */ From 757b18661ea0a0d890e8ce7b1a391e5b7d417d78 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 7 Jan 2006 13:19:00 -0500 Subject: [PATCH 039/695] [ACPI] make two processor functions static acpi_processor_write_throttling() acpi_processor_write_limit() Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/processor_thermal.c | 6 +++--- drivers/acpi/processor_throttling.c | 6 +++--- include/acpi/processor.h | 6 ------ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 22fc9e28a58d..f99ad05cd6a2 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -348,9 +348,9 @@ static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file) PDE(inode)->data); } -ssize_t acpi_processor_write_limit(struct file * file, - const char __user * buffer, - size_t count, loff_t * data) +static ssize_t acpi_processor_write_limit(struct file * file, + const char __user * buffer, + size_t count, loff_t * data) { int result = 0; struct seq_file *m = (struct seq_file *)file->private_data; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 5cd056abfcfb..b966549ec000 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -306,9 +306,9 @@ static int acpi_processor_throttling_open_fs(struct inode *inode, PDE(inode)->data); } -ssize_t acpi_processor_write_throttling(struct file * file, - const char __user * buffer, - size_t count, loff_t * data) +static ssize_t acpi_processor_write_throttling(struct file * file, + const char __user * buffer, + size_t count, loff_t * data) { int result = 0; struct seq_file *m = (struct seq_file *)file->private_data; diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 7a00d5089de9..edb5a8919cb6 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -235,9 +235,6 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) /* in processor_throttling.c */ int acpi_processor_get_throttling_info(struct acpi_processor *pr); int acpi_processor_set_throttling(struct acpi_processor *pr, int state); -ssize_t acpi_processor_write_throttling(struct file *file, - const char __user * buffer, - size_t count, loff_t * data); extern struct file_operations acpi_processor_throttling_fops; /* in processor_idle.c */ @@ -249,9 +246,6 @@ int acpi_processor_power_exit(struct acpi_processor *pr, /* in processor_thermal.c */ int acpi_processor_get_limit_info(struct acpi_processor *pr); -ssize_t acpi_processor_write_limit(struct file *file, - const char __user * buffer, - size_t count, loff_t * data); extern struct file_operations acpi_processor_limit_fops; #ifdef CONFIG_CPU_FREQ From 2ae4117435b30c7f9c12c89bcb323ce48b08c16a Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 16 Jan 2006 15:22:45 -0500 Subject: [PATCH 040/695] Revert "[ACPI] fix pnpacpi regression resulting from ACPICA 20051117" This reverts ed349a8a0a780ed27e2a765f16cee54d9b63bfee commit. --- drivers/acpi/resources/rsxface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 5408e5d10cc3..50a956b705b0 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -286,12 +286,6 @@ acpi_walk_resources(acpi_handle device_handle, break; } - /* end_tag indicates end-of-list */ - - if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { - break; - } - /* Invoke the user function, abort on any error returned */ status = user_function(resource, context); @@ -304,6 +298,12 @@ acpi_walk_resources(acpi_handle device_handle, break; } + /* end_tag indicates end-of-list */ + + if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + break; + } + /* Get the next resource descriptor */ resource = From 496ebd386439fee838df6b9c7d1306c36e7f6952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=3D=3FISO-8859-1=3FQ=3FMarjam=3DE4ki?= Date: Fri, 23 Dec 2005 16:18:54 +0000 Subject: [PATCH 041/695] [AGPGART] Loop cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The loop contains a command that is only used in the last iteration. I moved the command outside the loop. Compile-tested Signed-off-by: Daniel Marjamäki Signed-off-by: Dave Jones --- drivers/char/agp/isoch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c index 40083241804e..7c14a096b85e 100644 --- a/drivers/char/agp/isoch.c +++ b/drivers/char/agp/isoch.c @@ -218,10 +218,8 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, master[cdev].rq *= (1 << (master[cdev].y - 1)); tot_rq += master[cdev].rq; - - if (cdev == ndevs-1) - master[cdev].n += rem; } + master[ndevs-1].n += rem; /* Figure the number of isochronous and asynchronous RQ slots the * target is providing. */ From 90be4b49b8b54505772a6a766ac0891ec92b4c2d Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Tue, 3 Jan 2006 23:00:10 -0800 Subject: [PATCH 042/695] [AGPGART] Suspend/Resume support for AMD64 GART. This adds support for suspend/resume to the amd64-agp driver. Without it, X displays garbage after resume from swsusp. Signed-off-by: Michal Schmidt Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/char/agp/amd64-agp.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 810679dcbbb0..9964c508c111 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -600,6 +600,26 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) agp_put_bridge(bridge); } +#ifdef CONFIG_PM + +static int agp_amd64_suspend(struct pci_dev *pdev, pm_message_t state) +{ + pci_save_state(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +static int agp_amd64_resume(struct pci_dev *pdev) +{ + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + return amd_8151_configure(); +} + +#endif /* CONFIG_PM */ + static struct pci_device_id agp_amd64_pci_table[] = { { .class = (PCI_CLASS_BRIDGE_HOST << 8), @@ -718,6 +738,10 @@ static struct pci_driver agp_amd64_pci_driver = { .id_table = agp_amd64_pci_table, .probe = agp_amd64_probe, .remove = agp_amd64_remove, +#ifdef CONFIG_PM + .suspend = agp_amd64_suspend, + .resume = agp_amd64_resume, +#endif }; From 5dda4986752b531d89d49c218682e42c63ef1d61 Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Tue, 3 Jan 2006 23:00:59 -0800 Subject: [PATCH 043/695] [AGPGART] Suspend/Resume support for ATI GART Add suspend/resume support for the ati-agp module Signed-off-by: Jaco Kroon Acked-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/char/agp/ati-agp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 53372a83b675..5b74c36c116c 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -244,6 +244,22 @@ static int ati_configure(void) } +#ifdef CONFIG_PM +static int agp_ati_resume(struct pci_dev *dev) +{ + pci_restore_state(dev); + + return ati_configure(); +} + +static int agp_ati_suspend(struct pci_dev *dev, pm_message_t state) +{ + pci_save_state(dev); + + return 0; +} +#endif + /* *Since we don't need contigious memory we just try * to get the gatt table once @@ -525,6 +541,10 @@ static struct pci_driver agp_ati_pci_driver = { .id_table = agp_ati_pci_table, .probe = agp_ati_probe, .remove = agp_ati_remove, +#ifdef CONFIG_PM + .resume = agp_ati_resume, + .suspend = agp_ati_suspend, +#endif }; static int __init agp_ati_init(void) From 168678233ca45af3f74fef60c4265fa5dd217e29 Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Fri, 13 Jan 2006 15:51:02 -0800 Subject: [PATCH 044/695] [AGPGART] Semaphore to Mutex conversion. Semaphore to mutex conversion. The conversion was generated via scripts, and the result was validated automatically via a script as well. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/char/agp/frontend.c | 28 ++++++++++++++-------------- include/linux/agpgart.h | 3 ++- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 17f520c9d471..97eeb2345b18 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c @@ -592,7 +592,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) struct agp_file_private *priv = file->private_data; struct agp_kern_info kerninfo; - down(&(agp_fe.agp_mutex)); + mutex_lock(&(agp_fe.agp_mutex)); if (agp_fe.backend_acquired != TRUE) goto out_eperm; @@ -627,7 +627,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) size, vma->vm_page_prot)) { goto out_again; } - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return 0; } @@ -643,20 +643,20 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) size, vma->vm_page_prot)) { goto out_again; } - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return 0; } out_eperm: - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return -EPERM; out_inval: - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return -EINVAL; out_again: - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return -EAGAIN; } @@ -664,7 +664,7 @@ static int agp_release(struct inode *inode, struct file *file) { struct agp_file_private *priv = file->private_data; - down(&(agp_fe.agp_mutex)); + mutex_lock(&(agp_fe.agp_mutex)); DBG("priv=%p", priv); @@ -687,7 +687,7 @@ static int agp_release(struct inode *inode, struct file *file) agp_remove_file_private(priv); kfree(priv); file->private_data = NULL; - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return 0; } @@ -698,7 +698,7 @@ static int agp_open(struct inode *inode, struct file *file) struct agp_client *client; int rc = -ENXIO; - down(&(agp_fe.agp_mutex)); + mutex_lock(&(agp_fe.agp_mutex)); if (minor != AGPGART_MINOR) goto err_out; @@ -723,13 +723,13 @@ static int agp_open(struct inode *inode, struct file *file) file->private_data = (void *) priv; agp_insert_file_private(priv); DBG("private=%p, client=%p", priv, client); - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return 0; err_out_nomem: rc = -ENOMEM; err_out: - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return rc; } @@ -985,7 +985,7 @@ static int agp_ioctl(struct inode *inode, struct file *file, int ret_val = -ENOTTY; DBG("priv=%p, cmd=%x", curr_priv, cmd); - down(&(agp_fe.agp_mutex)); + mutex_lock(&(agp_fe.agp_mutex)); if ((agp_fe.current_controller == NULL) && (cmd != AGPIOC_ACQUIRE)) { @@ -1055,7 +1055,7 @@ static int agp_ioctl(struct inode *inode, struct file *file, ioctl_out: DBG("ioctl returns %d\n", ret_val); - up(&(agp_fe.agp_mutex)); + mutex_unlock(&(agp_fe.agp_mutex)); return ret_val; } @@ -1081,7 +1081,7 @@ static struct miscdevice agp_miscdev = int agp_frontend_initialize(void) { memset(&agp_fe, 0, sizeof(struct agp_front_data)); - sema_init(&(agp_fe.agp_mutex), 1); + mutex_init(&(agp_fe.agp_mutex)); if (misc_register(&agp_miscdev)) { printk(KERN_ERR PFX "unable to get minor: %d\n", AGPGART_MINOR); diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h index 17a17c55a17f..6d59c8efe3be 100644 --- a/include/linux/agpgart.h +++ b/include/linux/agpgart.h @@ -111,6 +111,7 @@ typedef struct _agp_unbind { } agp_unbind; #else /* __KERNEL__ */ +#include #define AGPGART_MINOR 175 @@ -201,7 +202,7 @@ struct agp_file_private { }; struct agp_front_data { - struct semaphore agp_mutex; + struct mutex agp_mutex; struct agp_controller *current_controller; struct agp_controller *controllers; struct agp_file_private *file_priv_list; From 47f7a0714b67b904a3a36e2f2d85904e8064219b Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 17 Jan 2006 09:22:05 -0800 Subject: [PATCH 045/695] IPoIB: Make sure path is fully initialized before using it The SA path record query completion can initialize path->pathrec.dlid before IPoIB's callback runs and initializes path->ah, so we must test ah rather than dlid. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index fd3f5c862a5d..c3b5f79d1168 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -505,7 +505,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) list_add_tail(&neigh->list, &path->neigh_list); - if (path->pathrec.dlid) { + if (path->ah) { kref_get(&path->ah->ref); neigh->ah = path->ah; @@ -591,7 +591,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, return; } - if (path->pathrec.dlid) { + if (path->ah) { ipoib_dbg(priv, "Send unicast ARP to %04x\n", be16_to_cpu(path->pathrec.dlid)); From cc76e33ec98ee2acab2d10828d31588d1b10f274 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 17 Jan 2006 09:41:47 -0800 Subject: [PATCH 046/695] IB/uverbs: Flush scheduled work before unloading module uverbs might schedule work to clean up when a file is closed. Make sure that this work runs before allowing module text to go away. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 96ea79b63df7..903f85a4bc0c 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -902,6 +902,7 @@ static void __exit ib_uverbs_cleanup(void) unregister_filesystem(&uverbs_event_fs); class_destroy(uverbs_class); unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); + flush_scheduled_work(); idr_destroy(&ib_uverbs_pd_idr); idr_destroy(&ib_uverbs_mr_idr); idr_destroy(&ib_uverbs_mw_idr); From 0f47ae0b3ec35dc5f4723f2e0ad0f6f3f55e9bcd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 17 Jan 2006 09:53:51 -0800 Subject: [PATCH 047/695] IB/sa_query: Flush scheduled work before unloading module sa_query schedules work on IB asynchronous events. After unregistering the async event handler, make sure that this work has completed before releasing the IB device (and possibly allowing the sa_query module text to go away). Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/core/sa_query.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index acda7d63d6fe..501cc054cb3b 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -956,6 +956,8 @@ static void ib_sa_remove_one(struct ib_device *device) ib_unregister_event_handler(&sa_dev->event_handler); + flush_scheduled_work(); + for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) { ib_unregister_mad_agent(sa_dev->port[i].agent); kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah); From b36f170b617a7cd147b694dabf504e856a50ee9d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 17 Jan 2006 12:19:40 -0800 Subject: [PATCH 048/695] IPoIB: Lock accesses to multicast packet queues Avoid corrupting mcast->pkt_queue by serializing access with priv->tx_lock. Also, update dropped packet statistics to count multicast packets removed from pkt_queue as dropped. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- .../infiniband/ulp/ipoib/ipoib_multicast.c | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 98039da0caf0..ccaa0c387076 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -97,6 +97,7 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_neigh *neigh, *tmp; unsigned long flags; + int tx_dropped = 0; ipoib_dbg_mcast(netdev_priv(dev), "deleting multicast group " IPOIB_GID_FMT "\n", @@ -123,8 +124,14 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) if (mcast->ah) ipoib_put_ah(mcast->ah); - while (!skb_queue_empty(&mcast->pkt_queue)) + while (!skb_queue_empty(&mcast->pkt_queue)) { + ++tx_dropped; dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); + } + + spin_lock_irqsave(&priv->tx_lock, flags); + priv->stats.tx_dropped += tx_dropped; + spin_unlock_irqrestore(&priv->tx_lock, flags); kfree(mcast); } @@ -276,8 +283,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, } /* actually send any queued packets */ + spin_lock_irq(&priv->tx_lock); while (!skb_queue_empty(&mcast->pkt_queue)) { struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); + spin_unlock_irq(&priv->tx_lock); skb->dev = dev; @@ -288,7 +297,9 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, if (dev_queue_xmit(skb)) ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n"); + spin_lock_irq(&priv->tx_lock); } + spin_unlock_irq(&priv->tx_lock); return 0; } @@ -300,6 +311,7 @@ ipoib_mcast_sendonly_join_complete(int status, { struct ipoib_mcast *mcast = mcast_ptr; struct net_device *dev = mcast->dev; + struct ipoib_dev_priv *priv = netdev_priv(dev); if (!status) ipoib_mcast_join_finish(mcast, mcmember); @@ -310,8 +322,12 @@ ipoib_mcast_sendonly_join_complete(int status, IPOIB_GID_ARG(mcast->mcmember.mgid), status); /* Flush out any queued packets */ - while (!skb_queue_empty(&mcast->pkt_queue)) + spin_lock_irq(&priv->tx_lock); + while (!skb_queue_empty(&mcast->pkt_queue)) { + ++priv->stats.tx_dropped; dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); + } + spin_unlock_irq(&priv->tx_lock); /* Clear the busy flag so we try again */ clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); @@ -687,6 +703,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, if (!mcast) { ipoib_warn(priv, "unable to allocate memory for " "multicast structure\n"); + ++priv->stats.tx_dropped; dev_kfree_skb_any(skb); goto out; } @@ -700,8 +717,10 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, if (!mcast->ah) { if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE) skb_queue_tail(&mcast->pkt_queue, skb); - else + else { + ++priv->stats.tx_dropped; dev_kfree_skb_any(skb); + } if (mcast->query) ipoib_dbg_mcast(priv, "no address vector, " From 3fc54d37ab64733448faf0185e19a80f070eb9e3 Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Fri, 13 Jan 2006 15:54:22 -0800 Subject: [PATCH 049/695] [CPUFREQ] Convert drivers/cpufreq semaphores to mutexes. Semaphore to mutex conversion. The conversion was generated via scripts, and the result was validated automatically via a script as well. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 19 +++++----- drivers/cpufreq/cpufreq_conservative.c | 52 +++++++++++++------------- drivers/cpufreq/cpufreq_ondemand.c | 41 ++++++++++---------- drivers/cpufreq/cpufreq_userspace.c | 25 +++++++------ 4 files changed, 70 insertions(+), 67 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 277a843a87a6..eb2f19d00e93 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -26,6 +26,7 @@ #include #include #include +#include #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "cpufreq-core", msg) @@ -55,7 +56,7 @@ static DECLARE_RWSEM (cpufreq_notifier_rwsem); static LIST_HEAD(cpufreq_governor_list); -static DECLARE_MUTEX (cpufreq_governor_sem); +static DEFINE_MUTEX (cpufreq_governor_mutex); struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu) { @@ -297,18 +298,18 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, return -EINVAL; } else { struct cpufreq_governor *t; - down(&cpufreq_governor_sem); + mutex_lock(&cpufreq_governor_mutex); if (!cpufreq_driver || !cpufreq_driver->target) goto out; list_for_each_entry(t, &cpufreq_governor_list, governor_list) { if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) { *governor = t; - up(&cpufreq_governor_sem); + mutex_unlock(&cpufreq_governor_mutex); return 0; } } out: - up(&cpufreq_governor_sem); + mutex_unlock(&cpufreq_governor_mutex); } return -EINVAL; } @@ -1217,17 +1218,17 @@ int cpufreq_register_governor(struct cpufreq_governor *governor) if (!governor) return -EINVAL; - down(&cpufreq_governor_sem); + mutex_lock(&cpufreq_governor_mutex); list_for_each_entry(t, &cpufreq_governor_list, governor_list) { if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) { - up(&cpufreq_governor_sem); + mutex_unlock(&cpufreq_governor_mutex); return -EBUSY; } } list_add(&governor->governor_list, &cpufreq_governor_list); - up(&cpufreq_governor_sem); + mutex_unlock(&cpufreq_governor_mutex); return 0; } @@ -1239,9 +1240,9 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor) if (!governor) return; - down(&cpufreq_governor_sem); + mutex_lock(&cpufreq_governor_mutex); list_del(&governor->governor_list); - up(&cpufreq_governor_sem); + mutex_unlock(&cpufreq_governor_mutex); return; } EXPORT_SYMBOL_GPL(cpufreq_unregister_governor); diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 39543a2bed0f..ac38766b2583 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -28,7 +28,7 @@ #include #include #include - +#include /* * dbs is used in this file as a shortform for demandbased switching * It helps to keep variable names smaller, simpler @@ -71,7 +71,7 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); static unsigned int dbs_enable; /* number of CPUs using this policy */ -static DECLARE_MUTEX (dbs_sem); +static DEFINE_MUTEX (dbs_mutex); static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); struct dbs_tuners { @@ -139,9 +139,9 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, if (ret != 1 ) return -EINVAL; - down(&dbs_sem); + mutex_lock(&dbs_mutex); dbs_tuners_ins.sampling_down_factor = input; - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -153,14 +153,14 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused, int ret; ret = sscanf (buf, "%u", &input); - down(&dbs_sem); + mutex_lock(&dbs_mutex); if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return -EINVAL; } dbs_tuners_ins.sampling_rate = input; - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -172,16 +172,16 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, int ret; ret = sscanf (buf, "%u", &input); - down(&dbs_sem); + mutex_lock(&dbs_mutex); if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || input < MIN_FREQUENCY_UP_THRESHOLD || input <= dbs_tuners_ins.down_threshold) { - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return -EINVAL; } dbs_tuners_ins.up_threshold = input; - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -193,16 +193,16 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused, int ret; ret = sscanf (buf, "%u", &input); - down(&dbs_sem); + mutex_lock(&dbs_mutex); if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || input < MIN_FREQUENCY_DOWN_THRESHOLD || input >= dbs_tuners_ins.up_threshold) { - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return -EINVAL; } dbs_tuners_ins.down_threshold = input; - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -222,9 +222,9 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, if ( input > 1 ) input = 1; - down(&dbs_sem); + mutex_lock(&dbs_mutex); if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } dbs_tuners_ins.ignore_nice = input; @@ -236,7 +236,7 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; } - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -257,9 +257,9 @@ static ssize_t store_freq_step(struct cpufreq_policy *policy, /* no need to test here if freq_step is zero as the user might actually * want this, they would be crazy though :) */ - down(&dbs_sem); + mutex_lock(&dbs_mutex); dbs_tuners_ins.freq_step = input; - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -444,12 +444,12 @@ static void dbs_check_cpu(int cpu) static void do_dbs_timer(void *data) { int i; - down(&dbs_sem); + mutex_lock(&dbs_mutex); for_each_online_cpu(i) dbs_check_cpu(i); schedule_delayed_work(&dbs_work, usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); - up(&dbs_sem); + mutex_unlock(&dbs_mutex); } static inline void dbs_timer_init(void) @@ -487,7 +487,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, if (this_dbs_info->enable) /* Already enabled */ break; - down(&dbs_sem); + mutex_lock(&dbs_mutex); for_each_cpu_mask(j, policy->cpus) { struct cpu_dbs_info_s *j_dbs_info; j_dbs_info = &per_cpu(cpu_dbs_info, j); @@ -521,11 +521,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, dbs_timer_init(); } - up(&dbs_sem); + mutex_unlock(&dbs_mutex); break; case CPUFREQ_GOV_STOP: - down(&dbs_sem); + mutex_lock(&dbs_mutex); this_dbs_info->enable = 0; sysfs_remove_group(&policy->kobj, &dbs_attr_group); dbs_enable--; @@ -536,12 +536,12 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, if (dbs_enable == 0) dbs_timer_exit(); - up(&dbs_sem); + mutex_unlock(&dbs_mutex); break; case CPUFREQ_GOV_LIMITS: - down(&dbs_sem); + mutex_lock(&dbs_mutex); if (policy->max < this_dbs_info->cur_policy->cur) __cpufreq_driver_target( this_dbs_info->cur_policy, @@ -550,7 +550,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, __cpufreq_driver_target( this_dbs_info->cur_policy, policy->min, CPUFREQ_RELATION_L); - up(&dbs_sem); + mutex_unlock(&dbs_mutex); break; } return 0; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index e69fd8dd1f1c..9ee9411f186f 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -27,6 +27,7 @@ #include #include #include +#include /* * dbs is used in this file as a shortform for demandbased switching @@ -70,7 +71,7 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); static unsigned int dbs_enable; /* number of CPUs using this policy */ -static DECLARE_MUTEX (dbs_sem); +static DEFINE_MUTEX (dbs_mutex); static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); struct dbs_tuners { @@ -136,9 +137,9 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1) return -EINVAL; - down(&dbs_sem); + mutex_lock(&dbs_mutex); dbs_tuners_ins.sampling_down_factor = input; - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -150,14 +151,14 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused, int ret; ret = sscanf (buf, "%u", &input); - down(&dbs_sem); + mutex_lock(&dbs_mutex); if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return -EINVAL; } dbs_tuners_ins.sampling_rate = input; - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -169,15 +170,15 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, int ret; ret = sscanf (buf, "%u", &input); - down(&dbs_sem); + mutex_lock(&dbs_mutex); if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || input < MIN_FREQUENCY_UP_THRESHOLD) { - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return -EINVAL; } dbs_tuners_ins.up_threshold = input; - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -197,9 +198,9 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, if ( input > 1 ) input = 1; - down(&dbs_sem); + mutex_lock(&dbs_mutex); if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } dbs_tuners_ins.ignore_nice = input; @@ -211,7 +212,7 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; } - up(&dbs_sem); + mutex_unlock(&dbs_mutex); return count; } @@ -356,12 +357,12 @@ static void dbs_check_cpu(int cpu) static void do_dbs_timer(void *data) { int i; - down(&dbs_sem); + mutex_lock(&dbs_mutex); for_each_online_cpu(i) dbs_check_cpu(i); schedule_delayed_work(&dbs_work, usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); - up(&dbs_sem); + mutex_unlock(&dbs_mutex); } static inline void dbs_timer_init(void) @@ -399,7 +400,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, if (this_dbs_info->enable) /* Already enabled */ break; - down(&dbs_sem); + mutex_lock(&dbs_mutex); for_each_cpu_mask(j, policy->cpus) { struct cpu_dbs_info_s *j_dbs_info; j_dbs_info = &per_cpu(cpu_dbs_info, j); @@ -435,11 +436,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, dbs_timer_init(); } - up(&dbs_sem); + mutex_unlock(&dbs_mutex); break; case CPUFREQ_GOV_STOP: - down(&dbs_sem); + mutex_lock(&dbs_mutex); this_dbs_info->enable = 0; sysfs_remove_group(&policy->kobj, &dbs_attr_group); dbs_enable--; @@ -450,12 +451,12 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, if (dbs_enable == 0) dbs_timer_exit(); - up(&dbs_sem); + mutex_unlock(&dbs_mutex); break; case CPUFREQ_GOV_LIMITS: - down(&dbs_sem); + mutex_lock(&dbs_mutex); if (policy->max < this_dbs_info->cur_policy->cur) __cpufreq_driver_target( this_dbs_info->cur_policy, @@ -464,7 +465,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, __cpufreq_driver_target( this_dbs_info->cur_policy, policy->min, CPUFREQ_RELATION_L); - up(&dbs_sem); + mutex_unlock(&dbs_mutex); break; } return 0; diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index d32bf3593cd3..4d6fa63da598 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -35,7 +36,7 @@ static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ static unsigned int cpu_is_managed[NR_CPUS]; static struct cpufreq_policy current_policy[NR_CPUS]; -static DECLARE_MUTEX (userspace_sem); +static DEFINE_MUTEX (userspace_mutex); #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg) @@ -70,7 +71,7 @@ static int cpufreq_set(unsigned int freq, unsigned int cpu) dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq); - down(&userspace_sem); + mutex_lock(&userspace_mutex); if (!cpu_is_managed[cpu]) goto err; @@ -83,16 +84,16 @@ static int cpufreq_set(unsigned int freq, unsigned int cpu) /* * We're safe from concurrent calls to ->target() here - * as we hold the userspace_sem lock. If we were calling + * as we hold the userspace_mutex lock. If we were calling * cpufreq_driver_target, a deadlock situation might occur: - * A: cpufreq_set (lock userspace_sem) -> cpufreq_driver_target(lock policy->lock) - * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_sem) + * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock) + * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex) */ ret = __cpufreq_driver_target(¤t_policy[cpu], freq, CPUFREQ_RELATION_L); err: - up(&userspace_sem); + mutex_unlock(&userspace_mutex); return ret; } @@ -134,7 +135,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, if (!cpu_online(cpu)) return -EINVAL; BUG_ON(!policy->cur); - down(&userspace_sem); + mutex_lock(&userspace_mutex); cpu_is_managed[cpu] = 1; cpu_min_freq[cpu] = policy->min; cpu_max_freq[cpu] = policy->max; @@ -143,20 +144,20 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); - up(&userspace_sem); + mutex_unlock(&userspace_mutex); break; case CPUFREQ_GOV_STOP: - down(&userspace_sem); + mutex_lock(&userspace_mutex); cpu_is_managed[cpu] = 0; cpu_min_freq[cpu] = 0; cpu_max_freq[cpu] = 0; cpu_set_freq[cpu] = 0; sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); dprintk("managing cpu %u stopped\n", cpu); - up(&userspace_sem); + mutex_unlock(&userspace_mutex); break; case CPUFREQ_GOV_LIMITS: - down(&userspace_sem); + mutex_lock(&userspace_mutex); cpu_min_freq[cpu] = policy->min; cpu_max_freq[cpu] = policy->max; dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]); @@ -171,7 +172,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, CPUFREQ_RELATION_L); } memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); - up(&userspace_sem); + mutex_unlock(&userspace_mutex); break; } return 0; From 83933af4720b282f6f6a0b6c05a2a47b4cf08819 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 14 Jan 2006 16:01:49 +0100 Subject: [PATCH 050/695] [CPUFREQ] convert remaining cpufreq semaphore to a mutex This one fell through the automation at first because it initializes the semaphore to locked, but that's easily remedied Signed-off-by: Arjan van de Ven Signed-off-by: Dave Jones drivers/cpufreq/cpufreq.c | 37 +++++++++++++++++++------------------ include/linux/cpufreq.h | 3 ++- 2 files changed, 21 insertions(+), 19 deletions(-) --- drivers/cpufreq/cpufreq.c | 37 +++++++++++++++++++------------------ include/linux/cpufreq.h | 3 ++- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index eb2f19d00e93..0675d9f02e34 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -601,7 +601,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) policy->cpu = cpu; policy->cpus = cpumask_of_cpu(cpu); - init_MUTEX_LOCKED(&policy->lock); + mutex_init(&policy->lock); + mutex_lock(&policy->lock); init_completion(&policy->kobj_unregister); INIT_WORK(&policy->update, handle_update, (void *)(long)cpu); @@ -642,7 +643,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) spin_unlock_irqrestore(&cpufreq_driver_lock, flags); policy->governor = NULL; /* to assure that the starting sequence is * run in cpufreq_set_policy */ - up(&policy->lock); + mutex_unlock(&policy->lock); /* set default policy */ @@ -763,10 +764,10 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev) spin_unlock_irqrestore(&cpufreq_driver_lock, flags); #endif - down(&data->lock); + mutex_lock(&data->lock); if (cpufreq_driver->target) __cpufreq_governor(data, CPUFREQ_GOV_STOP); - up(&data->lock); + mutex_unlock(&data->lock); kobject_unregister(&data->kobj); @@ -835,9 +836,9 @@ unsigned int cpufreq_quick_get(unsigned int cpu) unsigned int ret = 0; if (policy) { - down(&policy->lock); + mutex_lock(&policy->lock); ret = policy->cur; - up(&policy->lock); + mutex_unlock(&policy->lock); cpufreq_cpu_put(policy); } @@ -863,7 +864,7 @@ unsigned int cpufreq_get(unsigned int cpu) if (!cpufreq_driver->get) goto out; - down(&policy->lock); + mutex_lock(&policy->lock); ret = cpufreq_driver->get(cpu); @@ -876,7 +877,7 @@ unsigned int cpufreq_get(unsigned int cpu) } } - up(&policy->lock); + mutex_unlock(&policy->lock); out: cpufreq_cpu_put(policy); @@ -1159,11 +1160,11 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, if (!policy) return -EINVAL; - down(&policy->lock); + mutex_lock(&policy->lock); ret = __cpufreq_driver_target(policy, target_freq, relation); - up(&policy->lock); + mutex_unlock(&policy->lock); cpufreq_cpu_put(policy); @@ -1200,9 +1201,9 @@ int cpufreq_governor(unsigned int cpu, unsigned int event) if (!policy) return -EINVAL; - down(&policy->lock); + mutex_lock(&policy->lock); ret = __cpufreq_governor(policy, event); - up(&policy->lock); + mutex_unlock(&policy->lock); cpufreq_cpu_put(policy); @@ -1269,9 +1270,9 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) if (!cpu_policy) return -EINVAL; - down(&cpu_policy->lock); + mutex_lock(&cpu_policy->lock); memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy)); - up(&cpu_policy->lock); + mutex_unlock(&cpu_policy->lock); cpufreq_cpu_put(cpu_policy); @@ -1383,7 +1384,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) return -EINVAL; /* lock this CPU */ - down(&data->lock); + mutex_lock(&data->lock); ret = __cpufreq_set_policy(data, policy); data->user_policy.min = data->min; @@ -1391,7 +1392,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) data->user_policy.policy = data->policy; data->user_policy.governor = data->governor; - up(&data->lock); + mutex_unlock(&data->lock); cpufreq_cpu_put(data); return ret; @@ -1415,7 +1416,7 @@ int cpufreq_update_policy(unsigned int cpu) if (!data) return -ENODEV; - down(&data->lock); + mutex_lock(&data->lock); dprintk("updating policy for CPU %u\n", cpu); memcpy(&policy, @@ -1428,7 +1429,7 @@ int cpufreq_update_policy(unsigned int cpu) ret = __cpufreq_set_policy(data, &policy); - up(&data->lock); + mutex_unlock(&data->lock); cpufreq_cpu_put(data); return ret; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index c31650df9241..17866d7e2b71 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -14,6 +14,7 @@ #ifndef _LINUX_CPUFREQ_H #define _LINUX_CPUFREQ_H +#include #include #include #include @@ -82,7 +83,7 @@ struct cpufreq_policy { unsigned int policy; /* see above */ struct cpufreq_governor *governor; /* see below */ - struct semaphore lock; /* CPU ->setpolicy or ->target may + struct mutex lock; /* CPU ->setpolicy or ->target may only be called once a time */ struct work_struct update; /* if update_policy() needs to be From f3876c1bc7a23d4712c824f2ef5ec7d138259594 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 18 Jan 2006 13:40:54 -0800 Subject: [PATCH 051/695] [CPUFREQ] Don't free held mutex in cpufreq_add_dev() Make the cpufreq code play nicely with the mutex debugging code: don't free a held mutex. Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0675d9f02e34..0a6c4c8642e7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -612,6 +612,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) ret = cpufreq_driver->init(policy); if (ret) { dprintk("initialization failed\n"); + mutex_unlock(&policy->lock); goto err_out; } @@ -623,9 +624,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN); ret = kobject_register(&policy->kobj); - if (ret) + if (ret) { + mutex_unlock(&policy->lock); goto err_out_driver_exit; - + } /* set up files for this cpu device */ drv_attr = cpufreq_driver->attr; while ((drv_attr) && (*drv_attr)) { From 3b0e8eadc511eaceba6d6b8d0743359a34ee23c6 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 19 Jan 2006 14:08:40 +0000 Subject: [PATCH 052/695] [AGPGART] 945GM support for agpgart Here's a very small diff for 945GM support for agpgart. Patch against 2.6.15. From: Alan Hourihane Signed-off-by: Dave Jones --- drivers/char/agp/intel-agp.c | 15 +++++++++++++-- include/linux/pci_ids.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index e7bed5047dcc..631531fd97a5 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -422,7 +422,8 @@ static void intel_i830_init_gtt_entries(void) /* Check it's really I915G */ if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB) gtt_entries = MB(48) - KB(size); else gtt_entries = 0; @@ -431,7 +432,8 @@ static void intel_i830_init_gtt_entries(void) /* Check it's really I915G */ if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB) gtt_entries = MB(64) - KB(size); else gtt_entries = 0; @@ -1681,6 +1683,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } name = "945G"; break; + case PCI_DEVICE_ID_INTEL_82945GM_HB: + if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG)) { + bridge->driver = &intel_915_driver; + } else { + bridge->driver = &intel_845_driver; + } + name = "945GM"; + break; case PCI_DEVICE_ID_INTEL_7505_0: bridge->driver = &intel_7505_driver; name = "E7505"; @@ -1821,6 +1831,7 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_82915G_HB), ID(PCI_DEVICE_ID_INTEL_82915GM_HB), ID(PCI_DEVICE_ID_INTEL_82945G_HB), + ID(PCI_DEVICE_ID_INTEL_82945GM_HB), { } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5403257ae3e7..2726140a6732 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2084,6 +2084,8 @@ #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 #define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 #define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 +#define PCI_DEVICE_ID_INTEL_82945GM_HB 0x27A0 +#define PCI_DEVICE_ID_INTEL_82945GM_IG 0x27A2 #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 #define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 From cdc9cc1d740ffc3d8d8207fbf5df9bf05fcc9955 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 20 Jan 2006 01:25:37 +0100 Subject: [PATCH 053/695] [CPUFREQ] X86_GX_SUSPMOD must depend on PCI This patch fixes the following compile error: ... CC arch/i386/kernel/cpu/cpufreq/gx-suspmod.o arch/i386/kernel/cpu/cpufreq/gx-suspmod.c: In function 'gx_detect_chipset': arch/i386/kernel/cpu/cpufreq/gx-suspmod.c:193: error: implicit declaration of function 'pci_match_id' arch/i386/kernel/cpu/cpufreq/gx-suspmod.c:193: warning: comparison between pointer and integer make[3]: *** [arch/i386/kernel/cpu/cpufreq/gx-suspmod.o] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig index 0f1eb507233b..26892d2099b0 100644 --- a/arch/i386/kernel/cpu/cpufreq/Kconfig +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig @@ -96,6 +96,7 @@ config X86_POWERNOW_K8_ACPI config X86_GX_SUSPMOD tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" + depends on PCI help This add the CPUFreq driver for NatSemi Geode processors which support suspend modulation. From 0af5853bccd263161df80c259d61fc71211c5ac3 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 20 Jan 2006 01:11:37 -0500 Subject: [PATCH 054/695] [ACPI] better fix for pnpacpi regression resulting from ACPICA 20051117 Rather than tweaking acpi_walk_resource() again not return end tags, modify the pnpacpi code to ignore them. The pnpacpi resource type switch statements now include all known types in the order that they're defined -- so it is easy to see what is not implemented. The code will squawk only if it sees a truly undefined type. Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/rsparser.c | 145 +++++++++++++++++++++++---------- 1 file changed, 102 insertions(+), 43 deletions(-) diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index c6db14d30ed6..407b4eaddcbf 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -177,29 +177,34 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, } break; - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { - pnpacpi_parse_allocated_irqresource(res_table, - res->data.extended_irq.interrupts[i], - res->data.extended_irq.triggering, - res->data.extended_irq.polarity); - } - break; case ACPI_RESOURCE_TYPE_DMA: if (res->data.dma.channel_count > 0) pnpacpi_parse_allocated_dmaresource(res_table, res->data.dma.channels[0]); break; + case ACPI_RESOURCE_TYPE_IO: pnpacpi_parse_allocated_ioresource(res_table, res->data.io.minimum, res->data.io.address_length); break; + + case ACPI_RESOURCE_TYPE_START_DEPENDENT: + case ACPI_RESOURCE_TYPE_END_DEPENDENT: + break; + case ACPI_RESOURCE_TYPE_FIXED_IO: pnpacpi_parse_allocated_ioresource(res_table, res->data.fixed_io.address, res->data.fixed_io.address_length); break; + + case ACPI_RESOURCE_TYPE_VENDOR: + break; + + case ACPI_RESOURCE_TYPE_END_TAG: + break; + case ACPI_RESOURCE_TYPE_MEMORY24: pnpacpi_parse_allocated_memresource(res_table, res->data.memory24.minimum, @@ -230,8 +235,22 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, res->data.address64.minimum, res->data.address64.address_length); break; - case ACPI_RESOURCE_TYPE_VENDOR: + + case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: break; + + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { + pnpacpi_parse_allocated_irqresource(res_table, + res->data.extended_irq.interrupts[i], + res->data.extended_irq.triggering, + res->data.extended_irq.polarity); + } + break; + + case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: + break; + default: pnp_warn("PnPACPI: unknown resource type %d", res->type); return AE_ERROR; @@ -510,35 +529,11 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, case ACPI_RESOURCE_TYPE_IRQ: pnpacpi_parse_irq_option(option, &res->data.irq); break; - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - pnpacpi_parse_ext_irq_option(option, - &res->data.extended_irq); - break; + case ACPI_RESOURCE_TYPE_DMA: pnpacpi_parse_dma_option(option, &res->data.dma); break; - case ACPI_RESOURCE_TYPE_IO: - pnpacpi_parse_port_option(option, &res->data.io); - break; - case ACPI_RESOURCE_TYPE_FIXED_IO: - pnpacpi_parse_fixed_port_option(option, - &res->data.fixed_io); - break; - case ACPI_RESOURCE_TYPE_MEMORY24: - pnpacpi_parse_mem24_option(option, &res->data.memory24); - break; - case ACPI_RESOURCE_TYPE_MEMORY32: - pnpacpi_parse_mem32_option(option, &res->data.memory32); - break; - case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: - pnpacpi_parse_fixed_mem32_option(option, - &res->data.fixed_memory32); - break; - case ACPI_RESOURCE_TYPE_ADDRESS16: - case ACPI_RESOURCE_TYPE_ADDRESS32: - case ACPI_RESOURCE_TYPE_ADDRESS64: - pnpacpi_parse_address_option(option, res); - break; + case ACPI_RESOURCE_TYPE_START_DEPENDENT: switch (res->data.start_dpf.compatibility_priority) { case ACPI_GOOD_CONFIGURATION: @@ -562,6 +557,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, return AE_ERROR; parse_data->option = option; break; + case ACPI_RESOURCE_TYPE_END_DEPENDENT: /*only one EndDependentFn is allowed*/ if (!parse_data->option_independent) { @@ -571,6 +567,50 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, parse_data->option = parse_data->option_independent; parse_data->option_independent = NULL; break; + + case ACPI_RESOURCE_TYPE_IO: + pnpacpi_parse_port_option(option, &res->data.io); + break; + + case ACPI_RESOURCE_TYPE_FIXED_IO: + pnpacpi_parse_fixed_port_option(option, + &res->data.fixed_io); + break; + + case ACPI_RESOURCE_TYPE_VENDOR: + case ACPI_RESOURCE_TYPE_END_TAG: + break; + + case ACPI_RESOURCE_TYPE_MEMORY24: + pnpacpi_parse_mem24_option(option, &res->data.memory24); + break; + + case ACPI_RESOURCE_TYPE_MEMORY32: + pnpacpi_parse_mem32_option(option, &res->data.memory32); + break; + + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + pnpacpi_parse_fixed_mem32_option(option, + &res->data.fixed_memory32); + break; + + case ACPI_RESOURCE_TYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS64: + pnpacpi_parse_address_option(option, res); + break; + + case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: + break; + + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + pnpacpi_parse_ext_irq_option(option, + &res->data.extended_irq); + break; + + case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: + break; + default: pnp_warn("PnPACPI: unknown resource type %d", res->type); return AE_ERROR; @@ -605,7 +645,6 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, int *res_cnt = (int *)data; switch (res->type) { case ACPI_RESOURCE_TYPE_IRQ: - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: case ACPI_RESOURCE_TYPE_DMA: case ACPI_RESOURCE_TYPE_IO: case ACPI_RESOURCE_TYPE_FIXED_IO: @@ -615,7 +654,13 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, case ACPI_RESOURCE_TYPE_ADDRESS16: case ACPI_RESOURCE_TYPE_ADDRESS32: case ACPI_RESOURCE_TYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: (*res_cnt) ++; + case ACPI_RESOURCE_TYPE_START_DEPENDENT: + case ACPI_RESOURCE_TYPE_END_DEPENDENT: + case ACPI_RESOURCE_TYPE_VENDOR: + case ACPI_RESOURCE_TYPE_END_TAG: + case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: default: return AE_OK; } @@ -628,7 +673,6 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, struct acpi_resource **resource = (struct acpi_resource **)data; switch (res->type) { case ACPI_RESOURCE_TYPE_IRQ: - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: case ACPI_RESOURCE_TYPE_DMA: case ACPI_RESOURCE_TYPE_IO: case ACPI_RESOURCE_TYPE_FIXED_IO: @@ -638,8 +682,14 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, case ACPI_RESOURCE_TYPE_ADDRESS16: case ACPI_RESOURCE_TYPE_ADDRESS32: case ACPI_RESOURCE_TYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: (*resource)->type = res->type; (*resource)++; + case ACPI_RESOURCE_TYPE_START_DEPENDENT: + case ACPI_RESOURCE_TYPE_END_DEPENDENT: + case ACPI_RESOURCE_TYPE_VENDOR: + case ACPI_RESOURCE_TYPE_END_TAG: + case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: default: return AE_OK; } @@ -828,12 +878,6 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, irq++; break; - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - pnp_dbg("Encode ext irq"); - pnpacpi_encode_ext_irq(resource, - &res_table->irq_resource[irq]); - irq++; - break; case ACPI_RESOURCE_TYPE_DMA: pnp_dbg("Encode dma"); pnpacpi_encode_dma(resource, @@ -870,6 +914,21 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, &res_table->mem_resource[mem]); mem ++; break; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + pnp_dbg("Encode ext irq"); + pnpacpi_encode_ext_irq(resource, + &res_table->irq_resource[irq]); + irq++; + break; + case ACPI_RESOURCE_TYPE_START_DEPENDENT: + case ACPI_RESOURCE_TYPE_END_DEPENDENT: + case ACPI_RESOURCE_TYPE_VENDOR: + case ACPI_RESOURCE_TYPE_END_TAG: + case ACPI_RESOURCE_TYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: + case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: default: /* other type */ pnp_warn("unknown resource type %d", resource->type); return -EINVAL; From 3c5c363826e435cf4d54d917202567e5b57cae5f Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 20 Jan 2006 01:17:42 -0500 Subject: [PATCH 055/695] [ACPI] delete message "**** SET: Misaligned resource pointer:" This check, added in ACPICA 20051021, was overly paranoid. Signed-off-by: Len Brown --- drivers/acpi/resources/rsmisc.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index e1b5aa2af9a5..4a758bd4a5c8 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -328,14 +328,6 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, ACPI_FUNCTION_TRACE("rs_convert_resource_to_aml"); - /* Validate the Resource pointer, must be 32-bit aligned */ - - if (((acpi_native_uint) resource) & 0x3) { - acpi_os_printf - ("**** SET: Misaligned resource pointer: %p Type %2.2X Len %X\n", - resource, resource->type, resource->length); - } - /* * First table entry must be ACPI_RSC_INITxxx and must contain the * table length (# of table entries) From 4a90c7e86202f46fa9af011bdbcdf36e355d1721 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 13 Jan 2006 16:22:00 -0500 Subject: [PATCH 056/695] [ACPI] ACPICA 20060113 Added 2006 copyright. At SuSE's suggestion, enabled all error messages without enabling function tracing, ie with CONFIG_ACPI_DEBUG=n Replaced all instances of the ACPI_DEBUG_PRINT macro invoked at the ACPI_DB_ERROR and ACPI_DB_WARN debug levels with the ACPI_REPORT_ERROR and ACPI_REPORT_WARNING macros, respectively. This preserves all error and warning messages in the non-debug version of the ACPICA code (this has been referred to as the "debug lite" option.) Over 200 cases were converted to create a total of over 380 error/warning messages across the ACPICA code. This increases the code and data size of the default non-debug version by about 13K. Added ACPI_NO_ERROR_MESSAGES flag to enable deleting all messages. The size of the debug version remains about the same. Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsfield.c | 9 ++- drivers/acpi/dispatcher/dsinit.c | 20 ++---- drivers/acpi/dispatcher/dsmethod.c | 2 +- drivers/acpi/dispatcher/dsmthdat.c | 28 +++----- drivers/acpi/dispatcher/dsobject.c | 21 ++---- drivers/acpi/dispatcher/dsopcode.c | 41 ++++------- drivers/acpi/dispatcher/dsutils.c | 18 ++--- drivers/acpi/dispatcher/dswexec.c | 36 +++------- drivers/acpi/dispatcher/dswload.c | 2 +- drivers/acpi/dispatcher/dswscope.c | 6 +- drivers/acpi/dispatcher/dswstate.c | 106 ++++++++++------------------- drivers/acpi/events/evevent.c | 4 +- drivers/acpi/events/evgpe.c | 20 ++++-- drivers/acpi/events/evgpeblk.c | 20 ++---- drivers/acpi/events/evmisc.c | 12 ++-- drivers/acpi/events/evregion.c | 45 ++++-------- drivers/acpi/events/evrgnini.c | 2 +- drivers/acpi/events/evsci.c | 2 +- drivers/acpi/events/evxface.c | 13 ++-- drivers/acpi/events/evxfevnt.c | 23 +++---- drivers/acpi/events/evxfregn.c | 2 +- drivers/acpi/executer/exconfig.c | 6 +- drivers/acpi/executer/exconvrt.c | 15 +--- drivers/acpi/executer/excreate.c | 2 +- drivers/acpi/executer/exdump.c | 2 +- drivers/acpi/executer/exfield.c | 2 +- drivers/acpi/executer/exfldio.c | 60 +++++----------- drivers/acpi/executer/exmisc.c | 12 ++-- drivers/acpi/executer/exmutex.c | 2 +- drivers/acpi/executer/exnames.c | 16 ++--- drivers/acpi/executer/exoparg1.c | 59 +++++++--------- drivers/acpi/executer/exoparg2.c | 28 ++++---- drivers/acpi/executer/exoparg3.c | 8 ++- drivers/acpi/executer/exoparg6.c | 13 ++-- drivers/acpi/executer/exprep.c | 11 ++- drivers/acpi/executer/exregion.c | 12 ++-- drivers/acpi/executer/exresnte.c | 50 ++++++-------- drivers/acpi/executer/exresolv.c | 28 ++++---- drivers/acpi/executer/exresop.c | 89 +++++++----------------- drivers/acpi/executer/exstore.c | 19 ++---- drivers/acpi/executer/exstoren.c | 13 ++-- drivers/acpi/executer/exstorob.c | 2 +- drivers/acpi/executer/exsystem.c | 4 +- drivers/acpi/executer/exutils.c | 6 +- drivers/acpi/hardware/hwacpi.c | 7 +- drivers/acpi/hardware/hwgpe.c | 2 +- drivers/acpi/hardware/hwregs.c | 29 +++----- drivers/acpi/hardware/hwsleep.c | 2 +- drivers/acpi/hardware/hwtimer.c | 2 +- drivers/acpi/namespace/nsaccess.c | 18 +++-- drivers/acpi/namespace/nsalloc.c | 7 +- drivers/acpi/namespace/nsdump.c | 5 +- drivers/acpi/namespace/nsdumpdv.c | 2 +- drivers/acpi/namespace/nseval.c | 5 +- drivers/acpi/namespace/nsinit.c | 22 +++--- drivers/acpi/namespace/nsload.c | 6 +- drivers/acpi/namespace/nsnames.c | 10 ++- drivers/acpi/namespace/nsobject.c | 10 +-- drivers/acpi/namespace/nsparse.c | 2 +- drivers/acpi/namespace/nssearch.c | 11 ++- drivers/acpi/namespace/nsutils.c | 29 +++----- drivers/acpi/namespace/nswalk.c | 2 +- drivers/acpi/namespace/nsxfeval.c | 21 +++--- drivers/acpi/namespace/nsxfname.c | 2 +- drivers/acpi/namespace/nsxfobj.c | 2 +- drivers/acpi/parser/psargs.c | 4 +- drivers/acpi/parser/psloop.c | 23 ++----- drivers/acpi/parser/psopcode.c | 4 +- drivers/acpi/parser/psparse.c | 8 +-- drivers/acpi/parser/psscope.c | 2 +- drivers/acpi/parser/pstree.c | 5 +- drivers/acpi/parser/psutils.c | 2 +- drivers/acpi/parser/pswalk.c | 2 +- drivers/acpi/parser/psxface.c | 2 +- drivers/acpi/resources/rsaddr.c | 2 +- drivers/acpi/resources/rscalc.c | 2 +- drivers/acpi/resources/rscreate.c | 42 +++--------- drivers/acpi/resources/rsdump.c | 2 +- drivers/acpi/resources/rsinfo.c | 2 +- drivers/acpi/resources/rsio.c | 2 +- drivers/acpi/resources/rsirq.c | 2 +- drivers/acpi/resources/rslist.c | 6 +- drivers/acpi/resources/rsmemory.c | 2 +- drivers/acpi/resources/rsmisc.c | 9 +-- drivers/acpi/resources/rsutils.c | 2 +- drivers/acpi/resources/rsxface.c | 2 +- drivers/acpi/tables/tbconvrt.c | 2 +- drivers/acpi/tables/tbget.c | 6 +- drivers/acpi/tables/tbgetall.c | 2 +- drivers/acpi/tables/tbinstal.c | 2 +- drivers/acpi/tables/tbrsdt.c | 18 ++--- drivers/acpi/tables/tbutils.c | 22 +++--- drivers/acpi/tables/tbxface.c | 17 +++-- drivers/acpi/tables/tbxfroot.c | 22 ++---- drivers/acpi/utilities/utalloc.c | 32 ++++----- drivers/acpi/utilities/utcache.c | 2 +- drivers/acpi/utilities/utcopy.c | 7 +- drivers/acpi/utilities/utdebug.c | 2 +- drivers/acpi/utilities/utdelete.c | 9 +-- drivers/acpi/utilities/uteval.c | 22 +++--- drivers/acpi/utilities/utglobal.c | 21 +++--- drivers/acpi/utilities/utinit.c | 7 +- drivers/acpi/utilities/utmath.c | 10 +-- drivers/acpi/utilities/utmisc.c | 18 ++--- drivers/acpi/utilities/utmutex.c | 37 ++-------- drivers/acpi/utilities/utobject.c | 28 ++++---- drivers/acpi/utilities/utresrc.c | 2 +- drivers/acpi/utilities/utstate.c | 2 +- drivers/acpi/utilities/utxface.c | 7 +- include/acpi/acconfig.h | 4 +- include/acpi/acdebug.h | 2 +- include/acpi/acdisasm.h | 2 +- include/acpi/acdispat.h | 2 +- include/acpi/acevents.h | 2 +- include/acpi/acexcep.h | 2 +- include/acpi/acglobal.h | 2 +- include/acpi/achware.h | 2 +- include/acpi/acinterp.h | 2 +- include/acpi/aclocal.h | 2 +- include/acpi/acmacros.h | 93 +++++++++++++------------ include/acpi/acnames.h | 2 +- include/acpi/acnamesp.h | 4 +- include/acpi/acobject.h | 2 +- include/acpi/acopcode.h | 2 +- include/acpi/acoutput.h | 12 +++- include/acpi/acparser.h | 2 +- include/acpi/acpi.h | 2 +- include/acpi/acpiosxf.h | 2 +- include/acpi/acpixf.h | 2 +- include/acpi/acresrc.h | 2 +- include/acpi/acstruct.h | 2 +- include/acpi/actables.h | 2 +- include/acpi/actbl.h | 2 +- include/acpi/actbl1.h | 2 +- include/acpi/actbl2.h | 2 +- include/acpi/actypes.h | 2 +- include/acpi/acutils.h | 9 ++- include/acpi/amlcode.h | 2 +- include/acpi/amlresrc.h | 2 +- include/acpi/platform/acenv.h | 2 +- include/acpi/platform/acgcc.h | 2 +- include/acpi/platform/aclinux.h | 2 +- 142 files changed, 662 insertions(+), 1027 deletions(-) diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index 2022aeaecfbb..f3a008ff1eae 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -293,7 +293,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, + (acpi_integer) arg->common.value.size; if (position > ACPI_UINT32_MAX) { - ACPI_REPORT_ERROR(("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n", (char *)&info->field_node->name)); + ACPI_REPORT_ERROR(("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n", ACPI_CAST_PTR(char, &info->field_node->name))); return_ACPI_STATUS(AE_SUPPORT); } @@ -302,9 +302,8 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid opcode in field list: %X\n", - arg->common.aml_opcode)); + ACPI_REPORT_ERROR(("Invalid opcode in field list: %X\n", + arg->common.aml_opcode)); return_ACPI_STATUS(AE_AML_BAD_OPCODE); } diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index 4fa80abfe6c0..258fbdfaa69c 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -84,7 +84,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, acpi_object_type type; acpi_status status; - ACPI_FUNCTION_NAME("ds_init_one_object"); + ACPI_FUNCTION_ENTRY(); /* * We are only interested in NS nodes owned by the table that @@ -105,11 +105,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, status = acpi_ds_initialize_region(obj_handle); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Region %p [%4.4s] - Init failure, %s\n", - obj_handle, - acpi_ut_get_node_name(obj_handle), - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Region %p [%4.4s] - Init failure, %s\n", obj_handle, acpi_ut_get_node_name(obj_handle), acpi_format_exception(status))); } info->op_region_count++; @@ -148,11 +144,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, */ status = acpi_ds_parse_method(obj_handle); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "\n+Method %p [%4.4s] - parse failure, %s\n", - obj_handle, - acpi_ut_get_node_name(obj_handle), - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("\n+Method %p [%4.4s] - parse failure, %s\n", obj_handle, acpi_ut_get_node_name(obj_handle), acpi_format_exception(status))); /* This parse failed, but we will continue parsing more methods */ } @@ -214,8 +206,8 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, acpi_ds_init_one_object, &info, NULL); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed, %s\n", - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("walk_namespace failed, %s\n", + acpi_format_exception(status))); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index e7ce86b8d954..d861add3fc1f 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index 4095ce70982b..ce33c34f87c6 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -260,9 +260,7 @@ acpi_ds_method_data_get_node(u16 opcode, case AML_LOCAL_OP: if (index > ACPI_METHOD_MAX_LOCAL) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Local index %d is invalid (max %d)\n", - index, ACPI_METHOD_MAX_LOCAL)); + ACPI_REPORT_ERROR(("Local index %d is invalid (max %d)\n", index, ACPI_METHOD_MAX_LOCAL)); return_ACPI_STATUS(AE_AML_INVALID_INDEX); } @@ -274,9 +272,8 @@ acpi_ds_method_data_get_node(u16 opcode, case AML_ARG_OP: if (index > ACPI_METHOD_MAX_ARG) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Arg index %d is invalid (max %d)\n", - index, ACPI_METHOD_MAX_ARG)); + ACPI_REPORT_ERROR(("Arg index %d is invalid (max %d)\n", + index, ACPI_METHOD_MAX_ARG)); return_ACPI_STATUS(AE_AML_INVALID_INDEX); } @@ -286,8 +283,7 @@ acpi_ds_method_data_get_node(u16 opcode, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Opcode %d is invalid\n", - opcode)); + ACPI_REPORT_ERROR(("Opcode %d is invalid\n", opcode)); return_ACPI_STATUS(AE_AML_BAD_OPCODE); } @@ -378,8 +374,7 @@ acpi_ds_method_data_get_value(u16 opcode, /* Validate the object descriptor */ if (!dest_desc) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Null object descriptor pointer\n")); + ACPI_REPORT_ERROR(("Null object descriptor pointer\n")); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -424,23 +419,18 @@ acpi_ds_method_data_get_value(u16 opcode, switch (opcode) { case AML_ARG_OP: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Uninitialized Arg[%d] at node %p\n", - index, node)); + ACPI_REPORT_ERROR(("Uninitialized Arg[%d] at node %p\n", index, node)); return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG); case AML_LOCAL_OP: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Uninitialized Local[%d] at node %p\n", - index, node)); + ACPI_REPORT_ERROR(("Uninitialized Local[%d] at node %p\n", index, node)); return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); default: - ACPI_REPORT_ERROR(("Not Arg/Local opcode: %X\n", - opcode)); + ACPI_REPORT_ERROR(("Not a Arg/Local opcode: %X\n", opcode)); return_ACPI_STATUS(AE_AML_INTERNAL); } } diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 905a84e4b145..dc116d679a58 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -214,10 +214,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, byte_list = arg->named.next; if (byte_list) { if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Expecting bytelist, got AML opcode %X in op %p\n", - byte_list->common.aml_opcode, - byte_list)); + ACPI_REPORT_ERROR(("Expecting bytelist, got AML opcode %X in op %p\n", byte_list->common.aml_opcode, byte_list)); acpi_ut_remove_reference(obj_desc); return (AE_TYPE); @@ -543,9 +540,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown constant opcode %X\n", - opcode)); + ACPI_REPORT_ERROR(("Unknown constant opcode %X\n", opcode)); status = AE_AML_OPERAND_TYPE; break; } @@ -560,9 +555,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown Integer type %X\n", - op_info->type)); + ACPI_REPORT_ERROR(("Unknown Integer type %X\n", + op_info->type)); status = AE_AML_OPERAND_TYPE; break; } @@ -640,9 +634,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unimplemented data type: %X\n", - ACPI_GET_OBJECT_TYPE(obj_desc))); + ACPI_REPORT_ERROR(("Unimplemented data type: %X\n", + ACPI_GET_OBJECT_TYPE(obj_desc))); status = AE_AML_OPERAND_TYPE; break; diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index 939d167bf87b..60414ee84b0a 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -413,9 +413,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode, /* Host object must be a Buffer */ if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Target of Create Field is not a Buffer object - %s\n", - acpi_ut_get_object_type_name(buffer_desc))); + ACPI_REPORT_ERROR(("Target of Create Field is not a Buffer object - %s\n", acpi_ut_get_object_type_name(buffer_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -427,10 +425,9 @@ acpi_ds_init_buffer_field(u16 aml_opcode, * after resolution in acpi_ex_resolve_operands(). */ if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(%s) destination not a NS Node [%s]\n", - acpi_ps_get_opcode_name(aml_opcode), - acpi_ut_get_descriptor_name(result_desc))); + ACPI_REPORT_ERROR(("(%s) destination not a NS Node [%s]\n", + acpi_ps_get_opcode_name(aml_opcode), + acpi_ut_get_descriptor_name(result_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -453,8 +450,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode, /* Must have a valid (>0) bit count */ if (bit_count == 0) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Attempt to create_field of length 0\n")); + ACPI_REPORT_ERROR(("Attempt to create_field of length 0\n")); status = AE_AML_OPERAND_VALUE; goto cleanup; } @@ -507,9 +503,8 @@ acpi_ds_init_buffer_field(u16 aml_opcode, default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown field creation opcode %02x\n", - aml_opcode)); + ACPI_REPORT_ERROR(("Unknown field creation opcode %02x\n", + aml_opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -517,13 +512,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode, /* Entire field must fit within the current length of the buffer */ if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n", - acpi_ut_get_node_name(result_desc), - bit_offset + bit_count, - acpi_ut_get_node_name(buffer_desc->buffer. - node), - 8 * (u32) buffer_desc->buffer.length)); + ACPI_REPORT_ERROR(("Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n", acpi_ut_get_node_name(result_desc), bit_offset + bit_count, acpi_ut_get_node_name(buffer_desc->buffer.node), 8 * (u32) buffer_desc->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; } @@ -629,9 +618,10 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, "after acpi_ex_resolve_operands"); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n", - acpi_ps_get_opcode_name(op->common. - aml_opcode), status)); + ACPI_REPORT_ERROR(("(%s) bad operand(s) (%X)\n", + acpi_ps_get_opcode_name(op->common. + aml_opcode), + status)); return_ACPI_STATUS(status); } @@ -1155,9 +1145,8 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown control opcode=%X Op=%p\n", - op->common.aml_opcode, op)); + ACPI_REPORT_ERROR(("Unknown control opcode=%X Op=%p\n", + op->common.aml_opcode, op)); status = AE_AML_BAD_OPCODE; break; diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 2cc53da5c0bd..cd9aa7faa57b 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -176,7 +176,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, /* Must have both an Op and a Result Object */ if (!op) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null Op\n")); + ACPI_REPORT_ERROR(("Null Op\n")); return_UINT8(TRUE); } @@ -216,8 +216,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, parent_info = acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode); if (parent_info->class == AML_CLASS_UNKNOWN) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown parent opcode. Op=%p\n", op)); + ACPI_REPORT_ERROR(("Unknown parent opcode Op=%p\n", op)); return_UINT8(FALSE); } @@ -344,7 +343,7 @@ acpi_ds_delete_result_if_not_used(union acpi_parse_object *op, ACPI_FUNCTION_TRACE_PTR("ds_delete_result_if_not_used", result_obj); if (!op) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null Op\n")); + ACPI_REPORT_ERROR(("Null Op\n")); return_VOID; } @@ -635,10 +634,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, * Only error is underflow, and this indicates * a missing or null operand! */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Missing or null operand, %s\n", - acpi_format_exception - (status))); + ACPI_REPORT_ERROR(("Missing or null operand, %s\n", acpi_format_exception(status))); return_ACPI_STATUS(status); } } else { @@ -730,7 +726,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, */ (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "While creating Arg %d - %s\n", - (arg_count + 1), acpi_format_exception(status))); + ACPI_REPORT_ERROR(("While creating Arg %d - %s\n", + (arg_count + 1), acpi_format_exception(status))); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 74f6996db2d7..5a9b91fe93d2 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -100,9 +100,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, if (result_obj) { status = acpi_ds_result_pop(&obj_desc, walk_state); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not get result from predicate evaluation, %s\n", - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not get result from predicate evaluation, %s\n", acpi_format_exception(status))); return_ACPI_STATUS(status); } @@ -123,9 +121,8 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, } if (!obj_desc) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No predicate obj_desc=%p State=%p\n", - obj_desc, walk_state)); + ACPI_REPORT_ERROR(("No predicate obj_desc=%p State=%p\n", + obj_desc, walk_state)); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -140,10 +137,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, } if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n", - obj_desc, walk_state, - ACPI_GET_OBJECT_TYPE(obj_desc))); + ACPI_REPORT_ERROR(("Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n", obj_desc, walk_state, ACPI_GET_OBJECT_TYPE(obj_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -362,8 +356,8 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) op_class = walk_state->op_info->class; if (op_class == AML_CLASS_UNKNOWN) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown opcode %X\n", - op->common.aml_opcode)); + ACPI_REPORT_ERROR(("Unknown opcode %X\n", + op->common.aml_opcode)); return_ACPI_STATUS(AE_NOT_IMPLEMENTED); } @@ -453,12 +447,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) walk_state->operands[1]->reference.offset)) { status = AE_OK; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "[%s]: Could not resolve operands, %s\n", - acpi_ps_get_opcode_name - (walk_state->opcode), - acpi_format_exception - (status))); + ACPI_REPORT_ERROR(("[%s]: Could not resolve operands, %s\n", acpi_ps_get_opcode_name(walk_state->opcode), acpi_format_exception(status))); } } @@ -677,8 +666,8 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) case AML_TYPE_UNDEFINED: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Undefined opcode type Op=%p\n", op)); + ACPI_REPORT_ERROR(("Undefined opcode type Op=%p\n", + op)); return_ACPI_STATUS(AE_NOT_IMPLEMENTED); case AML_TYPE_BOGUS: @@ -690,10 +679,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n", - op_class, op_type, - op->common.aml_opcode, op)); + ACPI_REPORT_ERROR(("Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n", op_class, op_type, op->common.aml_opcode, op)); status = AE_NOT_IMPLEMENTED; break; diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 441931cab08a..4cad6afa82f7 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c index defe956ef751..e7fc88ca47ba 100644 --- a/drivers/acpi/dispatcher/dswscope.c +++ b/drivers/acpi/dispatcher/dswscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -107,14 +107,14 @@ acpi_ds_scope_stack_push(struct acpi_namespace_node *node, if (!node) { /* Invalid scope */ - ACPI_REPORT_ERROR(("ds_scope_stack_push: null scope passed\n")); + ACPI_REPORT_ERROR(("Null scope parameter\n")); return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Make sure object type is valid */ if (!acpi_ut_valid_object_type(type)) { - ACPI_REPORT_WARNING(("ds_scope_stack_push: Invalid object type: 0x%X\n", type)); + ACPI_REPORT_WARNING(("Invalid object type: 0x%X\n", type)); } /* Allocate a new scope object */ diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 7d68a5aaf3c4..61aae2dcc5e2 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -92,26 +92,23 @@ acpi_ds_result_remove(union acpi_operand_object **object, state = walk_state->results; if (!state) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No result object pushed! State=%p\n", - walk_state)); + ACPI_REPORT_ERROR(("No result object pushed! State=%p\n", + walk_state)); return (AE_NOT_EXIST); } if (index >= ACPI_OBJ_MAX_OPERAND) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Index out of range: %X State=%p Num=%X\n", - index, walk_state, - state->results.num_results)); + ACPI_REPORT_ERROR(("Index out of range: %X State=%p Num=%X\n", + index, walk_state, + state->results.num_results)); } /* Check for a valid result object */ if (!state->results.obj_desc[index]) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Null operand! State=%p #Ops=%X, Index=%X\n", - walk_state, state->results.num_results, - index)); + ACPI_REPORT_ERROR(("Null operand! State=%p #Ops=%X, Index=%X\n", + walk_state, state->results.num_results, + index)); return (AE_AML_NO_RETURN_VALUE); } @@ -163,9 +160,8 @@ acpi_ds_result_pop(union acpi_operand_object ** object, } if (!state->results.num_results) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Result stack is empty! State=%p\n", - walk_state)); + ACPI_REPORT_ERROR(("Result stack is empty! State=%p\n", + walk_state)); return (AE_AML_NO_RETURN_VALUE); } @@ -192,8 +188,7 @@ acpi_ds_result_pop(union acpi_operand_object ** object, } } - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No result objects! State=%p\n", walk_state)); + ACPI_REPORT_ERROR(("No result objects! State=%p\n", walk_state)); return (AE_AML_NO_RETURN_VALUE); } @@ -222,15 +217,14 @@ acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object, state = walk_state->results; if (!state) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Warning: No result object pushed! State=%p\n", - walk_state)); + ACPI_REPORT_ERROR(("No result object pushed! State=%p\n", + walk_state)); return (AE_NOT_EXIST); } if (!state->results.num_results) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No result objects! State=%p\n", walk_state)); + ACPI_REPORT_ERROR(("No result objects! State=%p\n", + walk_state)); return (AE_AML_NO_RETURN_VALUE); } @@ -250,10 +244,9 @@ acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object, /* Check for a valid result object */ if (!*object) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Null operand! State=%p #Ops=%X Index=%X\n", - walk_state, state->results.num_results, - (u32) index)); + ACPI_REPORT_ERROR(("Null operand! State=%p #Ops=%X Index=%X\n", + walk_state, state->results.num_results, + (u32) index)); return (AE_AML_NO_RETURN_VALUE); } @@ -293,18 +286,14 @@ acpi_ds_result_push(union acpi_operand_object * object, } if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Result stack overflow: Obj=%p State=%p Num=%X\n", - object, walk_state, - state->results.num_results)); + ACPI_REPORT_ERROR(("Result stack overflow: Obj=%p State=%p Num=%X\n", object, walk_state, state->results.num_results)); return (AE_STACK_OVERFLOW); } if (!object) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Null Object! Obj=%p State=%p Num=%X\n", - object, walk_state, - state->results.num_results)); + ACPI_REPORT_ERROR(("Null Object! Obj=%p State=%p Num=%X\n", + object, walk_state, + state->results.num_results)); return (AE_BAD_PARAMETER); } @@ -413,10 +402,7 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state) /* Check for stack overflow */ if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "overflow! Obj=%p State=%p #Ops=%X\n", - object, walk_state, - walk_state->num_operands)); + ACPI_REPORT_ERROR(("Object stack overflow! Obj=%p State=%p #Ops=%X\n", object, walk_state, walk_state->num_operands)); return (AE_STACK_OVERFLOW); } @@ -460,10 +446,7 @@ acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state) /* Check for stack underflow */ if (walk_state->num_operands == 0) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Underflow! Count=%X State=%p #Ops=%X\n", - pop_count, walk_state, - walk_state->num_operands)); + ACPI_REPORT_ERROR(("Object stack underflow! Count=%X State=%p #Ops=%X\n", pop_count, walk_state, walk_state->num_operands)); return (AE_STACK_UNDERFLOW); } @@ -506,10 +489,7 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count, /* Check for stack underflow */ if (walk_state->num_operands == 0) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Underflow! Count=%X State=%p #Ops=%X\n", - pop_count, walk_state, - walk_state->num_operands)); + ACPI_REPORT_ERROR(("Object stack underflow! Count=%X State=%p #Ops=%X\n", pop_count, walk_state, walk_state->num_operands)); return (AE_STACK_UNDERFLOW); } @@ -826,16 +806,14 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) } if (walk_state->data_type != ACPI_DESC_TYPE_WALK) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%p is not a valid walk state\n", - walk_state)); + ACPI_REPORT_ERROR(("%p is not a valid walk state\n", + walk_state)); return; } if (walk_state->parser_state.scope) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%p walk still has a scope list\n", - walk_state)); + ACPI_REPORT_ERROR(("%p walk still has a scope list\n", + walk_state)); } /* Always must free any linked control states */ @@ -894,25 +872,18 @@ acpi_ds_result_insert(void *object, state = walk_state->results; if (!state) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No result object pushed! State=%p\n", - walk_state)); + ACPI_REPORT_ERROR(("No result object pushed! State=%p\n", + walk_state)); return (AE_NOT_EXIST); } if (index >= ACPI_OBJ_NUM_OPERANDS) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Index out of range: %X Obj=%p State=%p Num=%X\n", - index, object, walk_state, - state->results.num_results)); + ACPI_REPORT_ERROR(("Index out of range: %X Obj=%p State=%p Num=%X\n", index, object, walk_state, state->results.num_results)); return (AE_BAD_PARAMETER); } if (!object) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Null Object! Index=%X Obj=%p State=%p Num=%X\n", - index, object, walk_state, - state->results.num_results)); + ACPI_REPORT_ERROR(("Null Object! Index=%X Obj=%p State=%p Num=%X\n", index, object, walk_state, state->results.num_results)); return (AE_BAD_PARAMETER); } @@ -986,9 +957,7 @@ acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, /* Check for stack underflow */ if (walk_state->num_operands == 0) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Missing operand/stack empty! State=%p #Ops=%X\n", - walk_state, walk_state->num_operands)); + ACPI_REPORT_ERROR(("Missing operand/stack empty! State=%p #Ops=%X\n", walk_state, walk_state->num_operands)); *object = NULL; return (AE_AML_NO_OPERAND); } @@ -1000,9 +969,8 @@ acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, /* Check for a valid operand */ if (!walk_state->operands[walk_state->num_operands]) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Null operand! State=%p #Ops=%X\n", - walk_state, walk_state->num_operands)); + ACPI_REPORT_ERROR(("Null operand! State=%p #Ops=%X\n", + walk_state, walk_state->num_operands)); *object = NULL; return (AE_AML_NO_OPERAND); } diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index 9522c643b88b..b380ae1044b7 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -73,7 +73,7 @@ acpi_status acpi_ev_initialize_events(void) /* Make sure we have ACPI tables */ if (!acpi_gbl_DSDT) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "No ACPI tables present!\n")); + ACPI_REPORT_WARNING(("No ACPI tables present!\n")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index bdd86537738e..353b907edbfa 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -599,7 +599,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) ACPI_GPE_EDGE_TRIGGERED) { status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number)); + ACPI_REPORT_ERROR(("%s, Unable to clear GPE[%2X]\n", + acpi_format_exception(status), + gpe_number)); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } } @@ -637,7 +639,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) ACPI_GPE_LEVEL_TRIGGERED) { status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number)); + ACPI_REPORT_ERROR(("%s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number)); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } } @@ -651,7 +653,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) */ status = acpi_ev_disable_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n", acpi_format_exception(status), gpe_number)); + ACPI_REPORT_ERROR(("%s, Unable to disable GPE[%2X]\n", + acpi_format_exception(status), + gpe_number)); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } @@ -663,7 +667,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) acpi_ev_asynch_execute_gpe_method, gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to queue handler for GPE[%2X] - event disabled\n", acpi_format_exception(status), gpe_number)); + ACPI_REPORT_ERROR(("%s, Unable to queue handler for GPE[%2X] - event disabled\n", acpi_format_exception(status), gpe_number)); } break; @@ -671,7 +675,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) /* No handler or method to run! */ - ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: No handler or method for GPE[%2X], disabling event\n", gpe_number)); + ACPI_REPORT_ERROR(("No handler or method for GPE[%2X], disabling event\n", gpe_number)); /* * Disable the GPE. The GPE will remain disabled until the ACPI @@ -679,7 +683,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) */ status = acpi_ev_disable_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n", acpi_format_exception(status), gpe_number)); + ACPI_REPORT_ERROR(("%s, Unable to disable GPE[%2X]\n", + acpi_format_exception(status), + gpe_number)); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } break; diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 8efca2eac27e..3b9bbdda551d 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -279,9 +279,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle, default: /* Unknown method type, just ignore it! */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown GPE method type: %s (name not of form _Lxx or _Exx)\n", - name)); + ACPI_REPORT_ERROR(("Unknown GPE method type: %s (name not of form _Lxx or _Exx)\n", name)); return_ACPI_STATUS(AE_OK); } @@ -291,9 +289,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle, if (gpe_number == ACPI_UINT32_MAX) { /* Conversion failed; invalid method, just ignore it */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)\n", - name)); + ACPI_REPORT_ERROR(("Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)\n", name)); return_ACPI_STATUS(AE_OK); } @@ -527,9 +523,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 acpi_ev_gpe_xrupt_handler, gpe_xrupt); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not install GPE interrupt handler at level 0x%X\n", - interrupt_number)); + ACPI_REPORT_ERROR(("Could not install GPE interrupt handler at level 0x%X\n", interrupt_number)); return_PTR(NULL); } } @@ -745,8 +739,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) sizeof(struct acpi_gpe_register_info)); if (!gpe_register_info) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not allocate the gpe_register_info table\n")); + ACPI_REPORT_ERROR(("Could not allocate the gpe_register_info table\n")); return_ACPI_STATUS(AE_NO_MEMORY); } @@ -759,8 +752,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) ACPI_GPE_REGISTER_WIDTH) * sizeof(struct acpi_gpe_event_info)); if (!gpe_event_info) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not allocate the gpe_event_info table\n")); + ACPI_REPORT_ERROR(("Could not allocate the gpe_event_info table\n")); status = AE_NO_MEMORY; goto error_exit; } diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 7e57b8470f55..78883239784a 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -542,9 +542,7 @@ void acpi_ev_terminate(void) for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { status = acpi_disable_event((u32) i, 0); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not disable fixed event %d\n", - (u32) i)); + ACPI_REPORT_ERROR(("Could not disable fixed event %d\n", (u32) i)); } } @@ -556,8 +554,7 @@ void acpi_ev_terminate(void) status = acpi_ev_remove_sci_handler(); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not remove SCI handler\n")); + ACPI_REPORT_ERROR(("Could not remove SCI handler\n")); } } @@ -570,8 +567,7 @@ void acpi_ev_terminate(void) if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) { status = acpi_disable(); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "acpi_disable failed\n")); + ACPI_REPORT_WARNING(("acpi_disable failed\n")); } } return_VOID; diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index 84fad082d80d..900e5b32e595 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -295,12 +295,11 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, handler_desc = region_obj->region.handler; if (!handler_desc) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No handler for Region [%4.4s] (%p) [%s]\n", - acpi_ut_get_node_name(region_obj->region. - node), region_obj, - acpi_ut_get_region_name(region_obj->region. - space_id))); + ACPI_REPORT_ERROR(("No handler for Region [%4.4s] (%p) [%s]\n", + acpi_ut_get_node_name(region_obj->region. + node), region_obj, + acpi_ut_get_region_name(region_obj->region. + space_id))); return_ACPI_STATUS(AE_NOT_EXIST); } @@ -317,12 +316,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, if (!region_setup) { /* No initialization routine, exit with error */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No init routine for region(%p) [%s]\n", - region_obj, - acpi_ut_get_region_name(region_obj-> - region. - space_id))); + ACPI_REPORT_ERROR(("No init routine for region(%p) [%s]\n", region_obj, acpi_ut_get_region_name(region_obj->region.space_id))); return_ACPI_STATUS(AE_NOT_EXIST); } @@ -347,12 +341,11 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, /* Check for failure of the Region Setup */ if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Region Init: %s [%s]\n", - acpi_format_exception(status), - acpi_ut_get_region_name(region_obj-> - region. - space_id))); + ACPI_REPORT_ERROR(("Region Initialization: %s [%s]\n", + acpi_format_exception(status), + acpi_ut_get_region_name(region_obj-> + region. + space_id))); return_ACPI_STATUS(status); } @@ -501,12 +494,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, status = acpi_ev_execute_reg_method(region_obj, 0); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%s from region _REG, [%s]\n", - acpi_format_exception(status), - acpi_ut_get_region_name - (region_obj->region. - space_id))); + ACPI_REPORT_ERROR(("%s from region _REG, [%s]\n", acpi_format_exception(status), acpi_ut_get_region_name(region_obj->region.space_id))); } if (acpi_ns_is_locked) { @@ -528,12 +516,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, /* Init routine may fail, Just ignore errors */ if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%s from region init, [%s]\n", - acpi_format_exception(status), - acpi_ut_get_region_name - (region_obj->region. - space_id))); + ACPI_REPORT_ERROR(("%s from region init, [%s]\n", acpi_format_exception(status), acpi_ut_get_region_name(region_obj->region.space_id))); } region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE); diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index a1bd2da27c45..de1a38e9ce22 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c index e2c0b48a7e9f..9a622169008a 100644 --- a/drivers/acpi/events/evsci.c +++ b/drivers/acpi/events/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index 57d73299298e..b2f69b1ac4b5 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -143,8 +143,8 @@ acpi_install_fixed_event_handler(u32 event, if (ACPI_SUCCESS(status)) status = acpi_enable_event(event, 0); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Could not enable fixed event.\n")); + ACPI_REPORT_WARNING(("Could not enable fixed event %X\n", + event)); /* Remove the handler */ @@ -204,10 +204,9 @@ acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) acpi_gbl_fixed_event_handlers[event].context = NULL; if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Could not write to fixed event enable register.\n")); + ACPI_REPORT_WARNING(("Could not write to fixed event enable register %X\n", event)); } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X.\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n", event)); } @@ -434,7 +433,7 @@ acpi_remove_notify_handler(acpi_handle device, if (device == ACPI_ROOT_OBJECT) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Removing notify handler for ROOT object.\n")); + "Removing notify handler for namespace root object\n")); if (((handler_type & ACPI_SYSTEM_NOTIFY) && !acpi_gbl_system_notify.handler) || diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index c1b898928256..90eb7939e986 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,8 +70,7 @@ acpi_status acpi_enable(void) /* Make sure we have the FADT */ if (!acpi_gbl_FADT) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "No FADT information present!\n")); + ACPI_REPORT_WARNING(("No FADT information present!\n")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -83,7 +82,7 @@ acpi_status acpi_enable(void) status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not transition to ACPI mode.\n")); + ACPI_REPORT_ERROR(("Could not transition to ACPI mode\n")); return_ACPI_STATUS(status); } @@ -113,8 +112,7 @@ acpi_status acpi_disable(void) ACPI_FUNCTION_TRACE("acpi_disable"); if (!acpi_gbl_FADT) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "No FADT information present!\n")); + ACPI_REPORT_WARNING(("No FADT information present!\n")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -127,8 +125,7 @@ acpi_status acpi_disable(void) status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not exit ACPI mode to legacy mode")); + ACPI_REPORT_ERROR(("Could not exit ACPI mode to legacy mode")); return_ACPI_STATUS(status); } @@ -185,9 +182,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags) } if (value != 1) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not enable %s event\n", - acpi_ut_get_event_name(event))); + ACPI_REPORT_ERROR(("Could not enable %s event\n", + acpi_ut_get_event_name(event))); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } @@ -384,9 +380,8 @@ acpi_status acpi_disable_event(u32 event, u32 flags) } if (value != 0) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not disable %s events\n", - acpi_ut_get_event_name(event))); + ACPI_REPORT_ERROR(("Could not disable %s events\n", + acpi_ut_get_event_name(event))); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c index 6f28ea2db5ba..abf5caca9ae5 100644 --- a/drivers/acpi/events/evxfregn.c +++ b/drivers/acpi/events/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 1ce365d651d8..109d0255a5bb 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -413,9 +413,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, (!ACPI_STRNCMP(table_ptr->signature, acpi_gbl_table_data[ACPI_TABLE_SSDT].signature, acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Table has invalid signature [%4.4s], must be SSDT or PSDT\n", - table_ptr->signature)); + ACPI_REPORT_ERROR(("Table has invalid signature [%4.4s], must be SSDT or PSDT\n", table_ptr->signature)); status = AE_BAD_SIGNATURE; goto cleanup; } diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index fa9e75d4ec65..e6f55cf8ad31 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -654,17 +654,8 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown Target type ID 0x%X Op %s dest_type %s\n", - GET_CURRENT_ARG_TYPE(walk_state->op_info-> - runtime_args), - walk_state->op_info->name, - acpi_ut_get_type_name(destination_type))); - - ACPI_REPORT_ERROR(("Bad Target Type (ARGI): %X\n", - GET_CURRENT_ARG_TYPE(walk_state->op_info-> - runtime_args))) - status = AE_AML_INTERNAL; + ACPI_REPORT_ERROR(("Unknown Target type ID 0x%X aml_opcode %X dest_type %s\n", GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args), walk_state->opcode, acpi_ut_get_type_name(destination_type))); + status = AE_AML_INTERNAL; } /* diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 91c49188fb07..da313dad576a 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 17c79cd91b31..a7cca8d4f855 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c index ab1ba399aa28..78a76f91a1c9 100644 --- a/drivers/acpi/executer/exfield.c +++ b/drivers/acpi/executer/exfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index ba6e08843c29..9fe27fd04a2f 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -94,10 +94,9 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, /* We must have a valid region */ if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed Region, found type %X (%s)\n", - ACPI_GET_OBJECT_TYPE(rgn_desc), - acpi_ut_get_object_type_name(rgn_desc))); + ACPI_REPORT_ERROR(("Needed Region, found type %X (%s)\n", + ACPI_GET_OBJECT_TYPE(rgn_desc), + acpi_ut_get_object_type_name(rgn_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -162,31 +161,14 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, * than the region itself. For example, a region of length one * byte, and a field with Dword access specified. */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n", - acpi_ut_get_node_name(obj_desc-> - common_field. - node), - obj_desc->common_field. - access_byte_width, - acpi_ut_get_node_name(rgn_desc-> - region.node), - rgn_desc->region.length)); + ACPI_REPORT_ERROR(("Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n", acpi_ut_get_node_name(obj_desc->common_field.node), obj_desc->common_field.access_byte_width, acpi_ut_get_node_name(rgn_desc->region.node), rgn_desc->region.length)); } /* * Offset rounded up to next multiple of field width * exceeds region length, indicate an error */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n", - acpi_ut_get_node_name(obj_desc->common_field. - node), - obj_desc->common_field.base_byte_offset, - field_datum_byte_offset, - obj_desc->common_field.access_byte_width, - acpi_ut_get_node_name(rgn_desc->region.node), - rgn_desc->region.length)); + ACPI_REPORT_ERROR(("Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n", acpi_ut_get_node_name(obj_desc->common_field.node), obj_desc->common_field.base_byte_offset, field_datum_byte_offset, obj_desc->common_field.access_byte_width, acpi_ut_get_node_name(rgn_desc->region.node), rgn_desc->region.length)); return_ACPI_STATUS(AE_AML_REGION_LIMIT); } @@ -270,12 +252,11 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, if (ACPI_FAILURE(status)) { if (status == AE_NOT_IMPLEMENTED) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Region %s(%X) not implemented\n", - acpi_ut_get_region_name(rgn_desc-> - region. - space_id), - rgn_desc->region.space_id)); + ACPI_REPORT_ERROR(("Region %s(%X) not implemented\n", + acpi_ut_get_region_name(rgn_desc-> + region. + space_id), + rgn_desc->region.space_id)); } else if (status == AE_NOT_EXIST) { ACPI_REPORT_ERROR(("Region %s(%X) has no handler\n", acpi_ut_get_region_name(rgn_desc-> @@ -618,11 +599,10 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, 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))); + ACPI_REPORT_ERROR(("Unknown update_rule value: %X\n", + (obj_desc->common_field. + field_flags & + AML_FIELD_UPDATE_RULE_MASK))); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } } @@ -677,10 +657,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, 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)); + ACPI_REPORT_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); } @@ -792,10 +769,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, 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)); + ACPI_REPORT_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); } diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 0778bff632bf..5ad34566738c 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -98,7 +98,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, default: - ACPI_REPORT_ERROR(("Unknown Reference opcode in get_reference %X\n", obj_desc->reference.opcode)); + ACPI_REPORT_ERROR(("Unknown Reference opcode %X\n", + obj_desc->reference.opcode)); return_ACPI_STATUS(AE_AML_INTERNAL); } break; @@ -113,7 +114,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, default: - ACPI_REPORT_ERROR(("Invalid descriptor type in get_reference: %X\n", ACPI_GET_DESCRIPTOR_TYPE(obj_desc))); + ACPI_REPORT_ERROR(("Invalid descriptor type %X\n", + ACPI_GET_DESCRIPTOR_TYPE(obj_desc))); return_ACPI_STATUS(AE_TYPE); } @@ -266,7 +268,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, break; default: - ACPI_REPORT_ERROR(("Concatanate - invalid object type: %X\n", + ACPI_REPORT_ERROR(("Invalid object type: %X\n", ACPI_GET_OBJECT_TYPE(operand0))); status = AE_AML_INTERNAL; } @@ -368,7 +370,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, /* Invalid object type, should not happen here */ - ACPI_REPORT_ERROR(("Concatenate - Invalid object type: %X\n", + ACPI_REPORT_ERROR(("Invalid object type: %X\n", ACPI_GET_OBJECT_TYPE(operand0))); status = AE_AML_INTERNAL; goto cleanup; diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c index ab47f6d8b5c0..89b8ab79410b 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/executer/exmutex.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c index 7bb5e17b5680..de3216b6a4fc 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/executer/exnames.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -99,7 +99,8 @@ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs) */ name_string = ACPI_MEM_ALLOCATE(size_needed); if (!name_string) { - ACPI_REPORT_ERROR(("ex_allocate_name_string: Could not allocate size %d\n", size_needed)); + ACPI_REPORT_ERROR(("Could not allocate size %d\n", + size_needed)); return_PTR(NULL); } @@ -167,8 +168,7 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) char_buf[0] = *aml_address; if ('0' <= char_buf[0] && char_buf[0] <= '9') { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "leading digit: %c\n", - char_buf[0])); + ACPI_REPORT_ERROR(("Invalid leading digit: %c\n", char_buf[0])); return_ACPI_STATUS(AE_CTRL_PENDING); } @@ -211,9 +211,8 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) * the required 4 */ status = AE_AML_BAD_NAME; - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Bad character %02x in name, at %p\n", - *aml_address, aml_address)); + ACPI_REPORT_ERROR(("Bad character %02x in name, at %p\n", + *aml_address, aml_address)); } *in_aml_address = ACPI_CAST_PTR(u8, aml_address); @@ -412,8 +411,7 @@ acpi_ex_get_name_string(acpi_object_type data_type, if (AE_CTRL_PENDING == status && has_prefix) { /* Ran out of segments after processing a prefix */ - ACPI_REPORT_ERROR(("ex_do_name: Malformed Name at %p\n", - name_string)); + ACPI_REPORT_ERROR(("Malformed Name at %p\n", name_string)); status = AE_AML_BAD_NAME; } diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 97e34542f5e4..bc8837ecb716 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -111,7 +111,8 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) default: /* Unknown opcode */ - ACPI_REPORT_ERROR(("acpi_ex_opcode_0A_0T_1R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; break; } @@ -188,7 +189,8 @@ acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state) default: /* Unknown opcode */ - ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; break; } @@ -227,7 +229,8 @@ acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state) default: /* Unknown opcode */ - ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -346,9 +349,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* Check the range of the digit */ if (temp32 > 9) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "BCD digit too large (not decimal): 0x%X\n", - temp32)); + ACPI_REPORT_ERROR(("BCD digit too large (not decimal): 0x%X\n", temp32)); status = AE_AML_NUMERIC_OVERFLOW; goto cleanup; @@ -393,12 +394,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* Overflow if there is any data left in Digit */ if (digit > 0) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Integer too large to convert to BCD: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(operand - [0]-> - integer. - value))); + ACPI_REPORT_ERROR(("Integer too large to convert to BCD: %8.8X%8.8X\n", ACPI_FORMAT_UINT64(operand[0]->integer.value))); status = AE_AML_NUMERIC_OVERFLOW; goto cleanup; } @@ -525,15 +521,16 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* These are two obsolete opcodes */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%s is obsolete and not implemented\n", - acpi_ps_get_opcode_name(walk_state->opcode))); + ACPI_REPORT_ERROR(("%s is obsolete and not implemented\n", + acpi_ps_get_opcode_name(walk_state-> + opcode))); status = AE_SUPPORT; goto cleanup; default: /* Unknown opcode */ - ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -639,11 +636,10 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) acpi_ex_resolve_operands(AML_LNOT_OP, &temp_desc, walk_state); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%s: bad operand(s) %s\n", - acpi_ps_get_opcode_name(walk_state-> - opcode), - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("%s: bad operand(s) %s\n", + acpi_ps_get_opcode_name(walk_state-> + opcode), + acpi_format_exception(status))); goto cleanup; } @@ -742,9 +738,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "size_of - Operand is not Buf/Int/Str/Pkg - found type %s\n", - acpi_ut_get_type_name(type))); + ACPI_REPORT_ERROR(("Operand is not Buf/Int/Str/Pkg - found type %s\n", acpi_ut_get_type_name(type))); status = AE_AML_OPERAND_TYPE; goto cleanup; } @@ -941,11 +935,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown Index target_type %X in obj %p\n", - operand[0]->reference. - target_type, - operand[0])); + ACPI_REPORT_ERROR(("Unknown Index target_type %X in obj %p\n", operand[0]->reference.target_type, operand[0])); status = AE_AML_OPERAND_TYPE; goto cleanup; } @@ -971,11 +961,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown opcode in ref(%p) - %X\n", - operand[0], - operand[0]->reference. - opcode)); + ACPI_REPORT_ERROR(("Unknown opcode in ref(%p) - %X\n", operand[0], operand[0]->reference.opcode)); status = AE_TYPE; goto cleanup; @@ -985,7 +971,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index d8472842c1fd..7c59dda40946 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -111,9 +111,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) /* Are notifies allowed on this object? */ if (!acpi_ev_is_notify_object(node)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unexpected notify object type [%s]\n", - acpi_ut_get_type_name(node->type))); + ACPI_REPORT_ERROR(("Unexpected notify object type [%s]\n", acpi_ut_get_type_name(node->type))); status = AE_AML_OPERAND_TYPE; break; @@ -157,7 +155,8 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; } @@ -221,7 +220,8 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -389,10 +389,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) /* Object to be indexed is a Package */ if (index >= operand[0]->package.count) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Index value (%X%8.8X) beyond package end (%X)\n", - ACPI_FORMAT_UINT64(index), - operand[0]->package.count)); + ACPI_REPORT_ERROR(("Index value (%X%8.8X) beyond package end (%X)\n", ACPI_FORMAT_UINT64(index), operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; goto cleanup; } @@ -405,10 +402,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) /* Object to be indexed is a Buffer/String */ if (index >= operand[0]->buffer.length) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Index value (%X%8.8X) beyond end of buffer (%X)\n", - ACPI_FORMAT_UINT64(index), - operand[0]->buffer.length)); + ACPI_REPORT_ERROR(("Index value (%X%8.8X) beyond end of buffer (%X)\n", ACPI_FORMAT_UINT64(index), operand[0]->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; } @@ -440,7 +434,8 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; break; } @@ -544,7 +539,8 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c index 2ea1c322970b..a979b338a491 100644 --- a/drivers/acpi/executer/exoparg3.c +++ b/drivers/acpi/executer/exoparg3.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -119,7 +119,8 @@ acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -242,7 +243,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c index 5dee77139576..05e7f9b67f29 100644 --- a/drivers/acpi/executer/exoparg6.c +++ b/drivers/acpi/executer/exoparg6.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -234,8 +234,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) || (operand[3]->integer.value > MAX_MATCH_OPERATOR)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Match operator out of range\n")); + ACPI_REPORT_ERROR(("Match operator out of range\n")); status = AE_AML_OPERAND_VALUE; goto cleanup; } @@ -244,10 +243,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) index = operand[5]->integer.value; if (index >= operand[0]->package.count) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Index (%X%8.8X) beyond package end (%X)\n", - ACPI_FORMAT_UINT64(index), - operand[0]->package.count)); + ACPI_REPORT_ERROR(("Index (%X%8.8X) beyond package end (%X)\n", ACPI_FORMAT_UINT64(index), operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; goto cleanup; } @@ -316,7 +312,8 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) default: - ACPI_REPORT_ERROR(("acpi_ex_opcode_6A_0T_1R: Unknown opcode %X\n", walk_state->opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index 88ccbf3b29d0..3bde780c94cf 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -274,8 +274,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, default: /* Invalid field access type */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown field access type %X\n", access)); + ACPI_REPORT_ERROR(("Unknown field access type %X\n", access)); return_UINT32(0); } @@ -422,15 +421,13 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) { if (!info->region_node) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null region_node\n")); + ACPI_REPORT_ERROR(("Null region_node\n")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } type = acpi_ns_get_type(info->region_node); if (type != ACPI_TYPE_REGION) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed Region, found type %X (%s)\n", - type, acpi_ut_get_type_name(type))); + ACPI_REPORT_ERROR(("Needed Region, found type %X (%s)\n", type, acpi_ut_get_type_name(type))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 80118be3f544..82983575cca6 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -103,9 +103,8 @@ acpi_ex_system_memory_space_handler(u32 function, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid system_memory width %d\n", - bit_width)); + ACPI_REPORT_ERROR(("Invalid system_memory width %d\n", + bit_width)); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } @@ -159,10 +158,7 @@ acpi_ex_system_memory_space_handler(u32 function, (void **)&mem_info-> mapped_logical_address); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not map memory at %8.8X%8.8X, size %X\n", - ACPI_FORMAT_UINT64(address), - (u32) window_size)); + ACPI_REPORT_ERROR(("Could not map memory at %8.8X%8.8X, size %X\n", ACPI_FORMAT_UINT64(address), (u32) window_size)); mem_info->mapped_length = 0; return_ACPI_STATUS(status); } diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c index ff5d8f97e8eb..a5cca7eda210 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/executer/exresnte.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -122,8 +122,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, } if (!source_desc) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No object attached to node %p\n", node)); + ACPI_REPORT_ERROR(("No object attached to node %p\n", node)); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -135,10 +134,9 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_PACKAGE: if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Object not a Package, type %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_REPORT_ERROR(("Object not a Package, type %s\n", + acpi_ut_get_object_type_name + (source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -154,10 +152,9 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_BUFFER: if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Object not a Buffer, type %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_REPORT_ERROR(("Object not a Buffer, type %s\n", + acpi_ut_get_object_type_name + (source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -173,10 +170,9 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_STRING: if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Object not a String, type %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_REPORT_ERROR(("Object not a String, type %s\n", + acpi_ut_get_object_type_name + (source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -189,10 +185,9 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_INTEGER: if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Object not a Integer, type %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_REPORT_ERROR(("Object not a Integer, type %s\n", + acpi_ut_get_object_type_name + (source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -236,9 +231,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_ANY: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Untyped entry %p, no attached object!\n", - node)); + ACPI_REPORT_ERROR(("Untyped entry %p, no attached object!\n", + node)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */ @@ -257,12 +251,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, default: /* No named references are allowed here */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported Reference opcode %X (%s)\n", - source_desc->reference.opcode, - acpi_ps_get_opcode_name(source_desc-> - reference. - opcode))); + ACPI_REPORT_ERROR(("Unsupported Reference opcode %X (%s)\n", source_desc->reference.opcode, acpi_ps_get_opcode_name(source_desc->reference.opcode))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -272,9 +261,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, /* Default case is for unknown types */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Node %p - Unknown object type %X\n", - node, entry_type)); + ACPI_REPORT_ERROR(("Node %p - Unknown object type %X\n", + node, entry_type)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index 97eecbd3242d..ae2d2da00844 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -81,7 +81,7 @@ acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr, ACPI_FUNCTION_TRACE_PTR("ex_resolve_to_value", stack_ptr); if (!stack_ptr || !*stack_ptr) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Internal - null pointer\n")); + ACPI_REPORT_ERROR(("Internal - null pointer\n")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -97,8 +97,7 @@ acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr, } if (!*stack_ptr) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Internal - null pointer\n")); + ACPI_REPORT_ERROR(("Internal - null pointer\n")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } } @@ -228,9 +227,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, * A NULL object descriptor means an unitialized element of * the package, can't dereference it */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Attempt to deref an Index to NULL pkg element Idx=%p\n", - stack_desc)); + ACPI_REPORT_ERROR(("Attempt to deref an Index to NULL pkg element Idx=%p\n", stack_desc)); status = AE_AML_UNINITIALIZED_ELEMENT; } break; @@ -239,7 +236,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, /* Invalid reference object */ - ACPI_REPORT_ERROR(("During resolve, Unknown target_type %X in Index/Reference obj %p\n", stack_desc->reference.target_type, stack_desc)); + ACPI_REPORT_ERROR(("Unknown target_type %X in Index/Reference obj %p\n", stack_desc->reference.target_type, stack_desc)); status = AE_AML_INTERNAL; break; } @@ -264,7 +261,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, default: - ACPI_REPORT_ERROR(("During resolve, Unknown Reference opcode %X (%s) in %p\n", opcode, acpi_ps_get_opcode_name(opcode), stack_desc)); + ACPI_REPORT_ERROR(("Unknown Reference opcode %X (%s) in %p\n", opcode, acpi_ps_get_opcode_name(opcode), stack_desc)); status = AE_AML_INTERNAL; break; } @@ -386,7 +383,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { - ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", node, acpi_ut_get_descriptor_name(node))); + ACPI_REPORT_ERROR(("Not a NS node %p [%s]\n", + node, + acpi_ut_get_descriptor_name + (node))); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -442,7 +442,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { - ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", node, acpi_ut_get_descriptor_name(node))); + ACPI_REPORT_ERROR(("Not a NS node %p [%s]\n", + node, + acpi_ut_get_descriptor_name + (node))); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -511,7 +514,8 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, default: - ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n", obj_desc->reference.opcode)); + ACPI_REPORT_ERROR(("Unknown Reference subtype %X\n", + obj_desc->reference.opcode)); return_ACPI_STATUS(AE_AML_INTERNAL); } } diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index b04e4a3707a1..804faebf825c 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -73,7 +73,7 @@ static acpi_status acpi_ex_check_object_type(acpi_object_type type_needed, acpi_object_type this_type, void *object) { - ACPI_FUNCTION_NAME("ex_check_object_type"); + ACPI_FUNCTION_ENTRY(); if (type_needed == ACPI_TYPE_ANY) { /* All types OK, so we don't perform any typechecks */ @@ -95,10 +95,9 @@ acpi_ex_check_object_type(acpi_object_type type_needed, } if (type_needed != this_type) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [%s], found [%s] %p\n", - acpi_ut_get_type_name(type_needed), - acpi_ut_get_type_name(this_type), object)); + ACPI_REPORT_ERROR(("Needed type [%s], found [%s] %p\n", + acpi_ut_get_type_name(type_needed), + acpi_ut_get_type_name(this_type), object)); return (AE_AML_OPERAND_TYPE); } @@ -151,7 +150,7 @@ acpi_ex_resolve_operands(u16 opcode, arg_types = op_info->runtime_args; if (arg_types == ARGI_INVALID_OPCODE) { - ACPI_REPORT_ERROR(("resolve_operands: %X is not a valid AML opcode\n", opcode)); + ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", opcode)); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -169,7 +168,8 @@ acpi_ex_resolve_operands(u16 opcode, */ while (GET_CURRENT_ARG_TYPE(arg_types)) { if (!stack_ptr || !*stack_ptr) { - ACPI_REPORT_ERROR(("resolve_operands: Null stack entry at %p\n", stack_ptr)); + ACPI_REPORT_ERROR(("Null stack entry at %p\n", + stack_ptr)); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -198,9 +198,7 @@ acpi_ex_resolve_operands(u16 opcode, /* Check for bad acpi_object_type */ if (!acpi_ut_valid_object_type(object_type)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Bad operand object type [%X]\n", - object_type)); + ACPI_REPORT_ERROR(("Bad operand object type [%X]\n", object_type)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -238,13 +236,7 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Operand is a Reference, Unknown Reference Opcode %X [%s]\n", - obj_desc->reference. - opcode, - (acpi_ps_get_opcode_info - (obj_desc->reference. - opcode))->name)); + ACPI_REPORT_ERROR(("Operand is a Reference, Unknown Reference Opcode: %X\n", obj_desc->reference.opcode)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -255,11 +247,10 @@ acpi_ex_resolve_operands(u16 opcode, /* Invalid descriptor */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid descriptor %p [%s]\n", - obj_desc, - acpi_ut_get_descriptor_name - (obj_desc))); + ACPI_REPORT_ERROR(("Invalid descriptor %p [%s]\n", + obj_desc, + acpi_ut_get_descriptor_name + (obj_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -417,11 +408,7 @@ acpi_ex_resolve_operands(u16 opcode, acpi_ex_convert_to_integer(obj_desc, stack_ptr, 16); if (ACPI_FAILURE(status)) { if (status == AE_TYPE) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), - obj_desc)); + ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -444,11 +431,7 @@ acpi_ex_resolve_operands(u16 opcode, status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr); if (ACPI_FAILURE(status)) { if (status == AE_TYPE) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), - obj_desc)); + ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -472,11 +455,7 @@ acpi_ex_resolve_operands(u16 opcode, ACPI_IMPLICIT_CONVERT_HEX); if (ACPI_FAILURE(status)) { if (status == AE_TYPE) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), - obj_desc)); + ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -502,10 +481,7 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), obj_desc)); + ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -539,10 +515,7 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [Integer/String/Buffer], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), obj_desc)); + ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -566,10 +539,7 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [Buffer/String/Package/Reference], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), obj_desc)); + ACPI_REPORT_ERROR(("Needed [Buffer/String/Package/Reference], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -588,10 +558,7 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [Buffer/String/Package], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), obj_desc)); + ACPI_REPORT_ERROR(("Needed [Buffer/String/Package], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -611,10 +578,7 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed [Region/region_field], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), obj_desc)); + ACPI_REPORT_ERROR(("Needed [Region/region_field], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -656,10 +620,7 @@ acpi_ex_resolve_operands(u16 opcode, break; } - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n", - acpi_ut_get_object_type_name - (obj_desc), obj_desc)); + ACPI_REPORT_ERROR(("Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -669,9 +630,7 @@ acpi_ex_resolve_operands(u16 opcode, /* Unknown type */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Internal - Unknown ARGI (required operand) type %X\n", - this_arg_type)); + ACPI_REPORT_ERROR(("Internal - Unknown ARGI (required operand) type %X\n", this_arg_type)); return_ACPI_STATUS(AE_BAD_PARAMETER); } diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index a7d8eea305c2..202ebe1eb957 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -250,7 +250,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, /* Validate parameters */ if (!source_desc || !dest_desc) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null parameter\n")); + ACPI_REPORT_ERROR(("Null parameter\n")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -290,10 +290,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, /* Destination is not a Reference object */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Target is not a Reference or Constant object - %s [%p]\n", - acpi_ut_get_object_type_name(dest_desc), - dest_desc)); + ACPI_REPORT_ERROR(("Target is not a Reference or Constant object - %s [%p]\n", acpi_ut_get_object_type_name(dest_desc), dest_desc)); ACPI_DUMP_STACK_ENTRY(source_desc); ACPI_DUMP_STACK_ENTRY(dest_desc); @@ -360,7 +357,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, default: - ACPI_REPORT_ERROR(("ex_store: Unknown Reference opcode %X\n", + ACPI_REPORT_ERROR(("Unknown Reference opcode %X\n", ref_desc->reference.opcode)); ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR); @@ -490,10 +487,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, /* All other types are invalid */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Source must be Integer/Buffer/String type, not %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_REPORT_ERROR(("Source must be Integer/Buffer/String type, not %s\n", acpi_ut_get_object_type_name(source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -503,8 +497,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Target is not a Package or buffer_field\n")); + ACPI_REPORT_ERROR(("Target is not a Package or buffer_field\n")); status = AE_AML_OPERAND_TYPE; break; } diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c index 382f63c14ea1..25bbc1d78547 100644 --- a/drivers/acpi/executer/exstoren.c +++ b/drivers/acpi/executer/exstoren.c @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -123,11 +123,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, && (source_desc->reference.opcode == AML_LOAD_OP))) { /* Conversion successful but still not a valid type */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Cannot assign type %s to %s (must be type Int/Str/Buf)\n", - acpi_ut_get_object_type_name - (source_desc), - acpi_ut_get_type_name(target_type))); + ACPI_REPORT_ERROR(("Cannot assign type %s to %s (must be type Int/Str/Buf)\n", acpi_ut_get_object_type_name(source_desc), acpi_ut_get_type_name(target_type))); status = AE_AML_OPERAND_TYPE; } break; @@ -280,9 +276,8 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc, /* * All other types come here. */ - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Store into type %s not implemented\n", - acpi_ut_get_object_type_name(dest_desc))); + ACPI_REPORT_WARNING(("Store into type %s not implemented\n", + acpi_ut_get_object_type_name(dest_desc))); status = AE_NOT_IMPLEMENTED; break; diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c index 855db7130751..6ab707087750 100644 --- a/drivers/acpi/executer/exstorob.c +++ b/drivers/acpi/executer/exstorob.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c index 8a88b841237d..9a3684d3cf87 100644 --- a/drivers/acpi/executer/exsystem.c +++ b/drivers/acpi/executer/exsystem.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -129,7 +129,7 @@ acpi_status acpi_ex_system_do_stall(u32 how_long) * (ACPI specifies 100 usec as max, but this gives some slack in * order to support existing BIOSs) */ - ACPI_REPORT_ERROR(("Stall: Time parameter is too large (%d)\n", + ACPI_REPORT_ERROR(("Time parameter is too large (%d)\n", how_long)); status = AE_AML_OPERAND_VALUE; } else { diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index 9f4e547d7734..990c40e0c041 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -200,9 +200,7 @@ u8 acpi_ex_acquire_global_lock(u32 field_flags) if (ACPI_SUCCESS(status)) { locked = TRUE; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not acquire Global Lock, %s\n", - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not acquire Global Lock, %s\n", acpi_format_exception(status))); } } diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c index 20a335cc9bea..5c068cc4f674 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/hardware/hwacpi.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -68,8 +68,7 @@ acpi_status acpi_hw_initialize(void) /* We must have the ACPI tables by the time we get here */ if (!acpi_gbl_FADT) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No FADT is present\n")); - + ACPI_REPORT_ERROR(("No FADT is present\n")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -108,7 +107,7 @@ acpi_status acpi_hw_set_mode(u32 mode) * system does not support mode transition. */ if (!acpi_gbl_FADT->smi_cmd) { - ACPI_REPORT_ERROR(("No SMI_CMD in FADT, mode transition failed.\n")); + ACPI_REPORT_ERROR(("No SMI_CMD in FADT, mode transition failed\n")); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c index 5c8e5dfd024e..d84942d22dd5 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index b243f20708b7..b4b50a3d1705 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c @@ -7,7 +7,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -202,12 +202,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) } if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n", - acpi_format_exception(status), - sleep_state_name, info.return_object, - acpi_ut_get_object_type_name(info. - return_object))); + ACPI_REPORT_ERROR(("%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n", acpi_format_exception(status), sleep_state_name, info.return_object, acpi_ut_get_object_type_name(info.return_object))); } acpi_ut_remove_reference(info.return_object); @@ -230,12 +225,11 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data); struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) { - ACPI_FUNCTION_NAME("hw_get_bit_register_info"); + ACPI_FUNCTION_ENTRY(); if (register_id > ACPI_BITREG_MAX) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid bit_register ID: %X\n", - register_id)); + ACPI_REPORT_ERROR(("Invalid bit_register ID: %X\n", + register_id)); return (NULL); } @@ -570,8 +564,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown Register ID: %X\n", - register_id)); + ACPI_REPORT_ERROR(("Unknown Register ID: %X\n", register_id)); status = AE_BAD_PARAMETER; break; } @@ -766,9 +759,8 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported address space: %X\n", - reg->address_space_id)); + ACPI_REPORT_ERROR(("Unsupported address space: %X\n", + reg->address_space_id)); return (AE_BAD_PARAMETER); } @@ -837,9 +829,8 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported address space: %X\n", - reg->address_space_id)); + ACPI_REPORT_ERROR(("Unsupported address space: %X\n", + reg->address_space_id)); return (AE_BAD_PARAMETER); } diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 34519069050c..992128d71117 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c index aff6dc141784..fc10b7cb456f 100644 --- a/drivers/acpi/hardware/hwtimer.c +++ b/drivers/acpi/hardware/hwtimer.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index 6923059ba3c7..c2db93e25b78 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -110,10 +110,7 @@ acpi_status acpi_ns_root_initialize(void) ACPI_NS_NO_UPSEARCH, NULL, &new_node); if (ACPI_FAILURE(status) || (!new_node)) { /* Must be on same line for code converter */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not create predefined name %s, %s\n", - init_val->name, - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not create predefined name %s, %s\n", init_val->name, acpi_format_exception(status))); } /* @@ -124,9 +121,7 @@ acpi_status acpi_ns_root_initialize(void) if (init_val->val) { status = acpi_os_predefined_override(init_val, &val); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not override predefined %s\n", - init_val->name)); + ACPI_REPORT_ERROR(("Could not override predefined %s\n", init_val->name)); } if (!val) { @@ -339,7 +334,10 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, prefix_node = scope_info->scope.node; if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) != ACPI_DESC_TYPE_NAMED) { - ACPI_REPORT_ERROR(("ns_lookup: %p is not a namespace node [%s]\n", prefix_node, acpi_ut_get_descriptor_name(prefix_node))); + ACPI_REPORT_ERROR(("%p is not a namespace node [%s]\n", + prefix_node, + acpi_ut_get_descriptor_name + (prefix_node))); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -600,7 +598,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, (this_node->type != type_to_check_for)) { /* Complain about a type mismatch */ - ACPI_REPORT_WARNING(("ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)\n", (char *)&simple_name, acpi_ut_get_type_name(this_node->type), acpi_ut_get_type_name(type_to_check_for))); + ACPI_REPORT_WARNING(("ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)\n", ACPI_CAST_PTR(char, &simple_name), acpi_ut_get_type_name(this_node->type), acpi_ut_get_type_name(type_to_check_for))); } /* diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index cc7a85f8cfe6..3db950f5d5a0 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -272,9 +272,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) /* Grandchildren should have all been deleted already */ if (child_node->child) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Found a grandchild! P=%p C=%p\n", - parent_node, child_node)); + ACPI_REPORT_ERROR(("Found a grandchild! P=%p C=%p\n", + parent_node, child_node)); } /* Now we can free this child object */ diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index 864c642759fa..2f0b70e3e881 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -198,7 +198,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, /* Check the node type and name */ if (type > ACPI_TYPE_LOCAL_MAX) { - ACPI_REPORT_WARNING(("Invalid ACPI Type %08X\n", type)); + ACPI_REPORT_WARNING(("Invalid ACPI Object Type %08X\n", + type)); } if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c index 55de883943d6..aff899a935e3 100644 --- a/drivers/acpi/namespace/nsdumpdv.c +++ b/drivers/acpi/namespace/nsdumpdv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 0191c7d92824..e3c667072e2f 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -373,8 +373,7 @@ acpi_ns_execute_control_method(struct acpi_parameter_info *info) info->obj_desc = acpi_ns_get_attached_object(info->node); if (!info->obj_desc) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No attached method object\n")); + ACPI_REPORT_ERROR(("No attached method object\n")); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return_ACPI_STATUS(AE_NULL_OBJECT); diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index efa3f4233736..6c117893f301 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -93,8 +93,8 @@ acpi_status acpi_ns_initialize_objects(void) ACPI_UINT32_MAX, acpi_ns_init_one_object, &info, NULL); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed! %s\n", - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("walk_namespace failed! %s\n", + acpi_format_exception(status))); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, @@ -159,8 +159,8 @@ acpi_status acpi_ns_initialize_devices(void) (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed! %s\n", - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("walk_namespace failed! %s\n", + acpi_format_exception(status))); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, @@ -289,12 +289,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle, } if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT_RAW((ACPI_DB_ERROR, "\n")); - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not execute arguments for [%4.4s] (%s), %s\n", - acpi_ut_get_node_name(node), - acpi_ut_get_type_name(type), - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("\nCould not execute arguments for [%4.4s] (%s), %s\n", acpi_ut_get_node_name(node), acpi_ut_get_type_name(type), acpi_format_exception(status))); } /* @@ -421,8 +416,9 @@ acpi_ns_init_one_device(acpi_handle obj_handle, #ifdef ACPI_DEBUG_OUTPUT char *scope_name = acpi_ns_get_external_pathname(ini_node); - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "%s._INI failed: %s\n", - scope_name, acpi_format_exception(status))); + ACPI_REPORT_WARNING(("%s._INI failed: %s\n", + scope_name, + acpi_format_exception(status))); ACPI_MEM_FREE(scope_name); #endif diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index c28849de465a..0b4a866ef5aa 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -92,7 +92,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, /* Check validity of the AML start and length */ if (!table_desc->aml_start) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null AML pointer\n")); + ACPI_REPORT_ERROR(("Null AML pointer\n")); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -263,7 +263,7 @@ acpi_status acpi_ns_load_namespace(void) /* There must be at least a DSDT installed */ if (acpi_gbl_DSDT == NULL) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "DSDT is not in memory\n")); + ACPI_REPORT_ERROR(("DSDT is not in memory\n")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index 5400728eb791..411e1f8b11d0 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,7 +75,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, acpi_size index; struct acpi_namespace_node *parent_node; - ACPI_FUNCTION_NAME("ns_build_external_path"); + ACPI_FUNCTION_ENTRY(); /* Special case for root */ @@ -110,9 +110,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, name_buffer[index] = AML_ROOT_PREFIX; if (index != 0) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not construct pathname; index=%X, size=%X, Path=%s\n", - (u32) index, (u32) size, &name_buffer[size])); + ACPI_REPORT_ERROR(("Could not construct pathname; index=%X, size=%X, Path=%s\n", (u32) index, (u32) size, &name_buffer[size])); } return; @@ -148,7 +146,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) name_buffer = ACPI_MEM_CALLOCATE(size); if (!name_buffer) { - ACPI_REPORT_ERROR(("ns_get_table_pathname: allocation failure\n")); + ACPI_REPORT_ERROR(("Allocation failure\n")); return_PTR(NULL); } diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c index fc9be946ebed..86113093f7b7 100644 --- a/drivers/acpi/namespace/nsobject.c +++ b/drivers/acpi/namespace/nsobject.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -84,21 +84,21 @@ acpi_ns_attach_object(struct acpi_namespace_node *node, if (!node) { /* Invalid handle */ - ACPI_REPORT_ERROR(("ns_attach_object: Null named_obj handle\n")); + ACPI_REPORT_ERROR(("Null named_obj handle\n")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { /* Null object */ - ACPI_REPORT_ERROR(("ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n")); + ACPI_REPORT_ERROR(("Null object, but type not ACPI_TYPE_ANY\n")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { /* Not a name handle */ - ACPI_REPORT_ERROR(("ns_attach_object: Invalid handle %p [%s]\n", + ACPI_REPORT_ERROR(("Invalid handle %p [%s]\n", node, acpi_ut_get_descriptor_name(node))); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -254,7 +254,7 @@ union acpi_operand_object *acpi_ns_get_attached_object(struct ACPI_FUNCTION_TRACE_PTR("ns_get_attached_object", node); if (!node) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Null Node ptr\n")); + ACPI_REPORT_WARNING(("Null Node ptr\n")); return_PTR(NULL); } diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index 433442a9ec74..232be4303653 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index c1b1943d4670..f094a2eb8512 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -298,18 +298,15 @@ acpi_ns_search_and_enter(u32 target_name, /* Parameter validation */ if (!node || !target_name || !return_node) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Null param: Node %p Name %X return_node %p\n", - node, target_name, return_node)); - - ACPI_REPORT_ERROR(("ns_search_and_enter: Null parameter\n")); + ACPI_REPORT_ERROR(("Null param: Node %p Name %X return_node %p\n", node, target_name, return_node)); return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Name must consist of printable characters */ if (!acpi_ut_valid_acpi_name(target_name)) { - ACPI_REPORT_ERROR(("ns_search_and_enter: Bad character in ACPI Name: %X\n", target_name)); + ACPI_REPORT_ERROR(("Bad character in ACPI Name: %X\n", + target_name)); return_ACPI_STATUS(AE_BAD_CHARACTER); } diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index 549075fb9f88..bc779fdd3caf 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,7 +63,6 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); * * PARAMETERS: module_name - Caller's module name (for error output) * line_number - Caller's line number (for error output) - * component_id - Caller's component ID (for error output) * internal_name - Name or path of the namespace node * lookup_status - Exception code from NS lookup * @@ -76,14 +75,12 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); void acpi_ns_report_error(char *module_name, u32 line_number, - u32 component_id, char *internal_name, acpi_status lookup_status) { acpi_status status; char *name = NULL; - acpi_os_printf("%8s-%04d: *** Error: Looking up ", - module_name, line_number); + acpi_ut_report_error(module_name, line_number); if (lookup_status == AE_BAD_CHARACTER) { /* There is a non-ascii character in the name */ @@ -109,7 +106,7 @@ acpi_ns_report_error(char *module_name, } } - acpi_os_printf(" in namespace, %s\n", + acpi_os_printf("Namespace lookup failure, %s\n", acpi_format_exception(lookup_status)); } @@ -119,10 +116,9 @@ acpi_ns_report_error(char *module_name, * * PARAMETERS: module_name - Caller's module name (for error output) * line_number - Caller's line number (for error output) - * component_id - Caller's component ID (for error output) * Message - Error message to use on failure * prefix_node - Prefix relative to the path - * Path - Path to the node + * Path - Path to the node (optional) * method_status - Execution status * * RETURN: None @@ -134,7 +130,6 @@ acpi_ns_report_error(char *module_name, void acpi_ns_report_method_error(char *module_name, u32 line_number, - u32 component_id, char *message, struct acpi_namespace_node *prefix_node, char *path, acpi_status method_status) @@ -142,17 +137,16 @@ acpi_ns_report_method_error(char *module_name, acpi_status status; struct acpi_namespace_node *node = prefix_node; + acpi_ut_report_error(module_name, line_number); + if (path) { status = acpi_ns_get_node_by_path(path, prefix_node, ACPI_NS_NO_UPSEARCH, &node); if (ACPI_FAILURE(status)) { - acpi_os_printf - ("report_method_error: Could not get node\n"); - return; + acpi_os_printf("[Could not get node by pathname]"); } } - acpi_os_printf("%8s-%04d: *** Error: ", module_name, line_number); acpi_ns_print_node_pathname(node, message); acpi_os_printf(", %s\n", acpi_format_exception(method_status)); } @@ -248,7 +242,7 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) ACPI_FUNCTION_TRACE("ns_get_type"); if (!node) { - ACPI_REPORT_WARNING(("ns_get_type: Null Node input pointer\n")); + ACPI_REPORT_WARNING(("Null Node parameter\n")); return_UINT32(ACPI_TYPE_ANY); } @@ -275,7 +269,7 @@ u32 acpi_ns_local(acpi_object_type type) if (!acpi_ut_valid_object_type(type)) { /* Type code out of range */ - ACPI_REPORT_WARNING(("ns_local: Invalid Object Type\n")); + ACPI_REPORT_WARNING(("Invalid Object Type %X\n", type)); return_UINT32(ACPI_NS_NORMAL); } @@ -627,7 +621,7 @@ acpi_ns_externalize_name(u32 internal_name_length, * with internal_name (invalid format). */ if (required_length > internal_name_length) { - ACPI_REPORT_ERROR(("ns_externalize_name: Invalid internal name\n")); + ACPI_REPORT_ERROR(("Invalid internal name\n")); return_ACPI_STATUS(AE_BAD_PATHNAME); } @@ -803,8 +797,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type) if (!acpi_ut_valid_object_type(type)) { /* type code out of range */ - ACPI_REPORT_WARNING(("ns_opens_scope: Invalid Object Type %X\n", - type)); + ACPI_REPORT_WARNING(("Invalid Object Type %X\n", type)); return_UINT32(ACPI_NS_NORMAL); } diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c index 5f164c0df33b..fcab1e784b81 100644 --- a/drivers/acpi/namespace/nswalk.c +++ b/drivers/acpi/namespace/nswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index 75b137a6a3c9..de13add43efc 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -112,8 +112,7 @@ acpi_evaluate_object_typed(acpi_handle handle, if (return_buffer->length == 0) { /* Error because caller specifically asked for a return value */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No return value\n")); - + ACPI_REPORT_ERROR(("No return value\n")); return_ACPI_STATUS(AE_NULL_OBJECT); } @@ -125,11 +124,11 @@ acpi_evaluate_object_typed(acpi_handle handle, /* Return object type does not match requested type */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Incorrect return type [%s] requested [%s]\n", - acpi_ut_get_type_name(((union acpi_object *) - return_buffer->pointer)->type), - acpi_ut_get_type_name(return_type))); + ACPI_REPORT_ERROR(("Incorrect return type [%s] requested [%s]\n", + acpi_ut_get_type_name(((union acpi_object *) + return_buffer->pointer)-> + type), + acpi_ut_get_type_name(return_type))); if (must_free) { /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ @@ -236,11 +235,9 @@ acpi_evaluate_object(acpi_handle handle, * qualified names above, this is an error */ if (!pathname) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Both Handle and Pathname are NULL\n")); + ACPI_REPORT_ERROR(("Both Handle and Pathname are NULL\n")); } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Handle is NULL and Pathname is relative\n")); + ACPI_REPORT_ERROR(("Handle is NULL and Pathname is relative\n")); } status = AE_BAD_PARAMETER; diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index 6b5f8d4481d1..853e6d170c96 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index 0856d42e6909..a0332595677a 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index e6d4cb9fd303..3c37cd0ecd80 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -298,7 +298,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, acpi_ps_append_arg(arg, name_op); if (!method_desc) { - ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node)); + ACPI_REPORT_ERROR(("Control Method %p has no attached object\n", node)); return_ACPI_STATUS(AE_AML_INTERNAL); } diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index e81e51b8b3ae..c66029b890b1 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -123,16 +123,10 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) && ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) { if (status == AE_AML_NO_RETURN_VALUE) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invoked method did not return a value, %s\n", - acpi_format_exception - (status))); + ACPI_REPORT_ERROR(("Invoked method did not return a value, %s\n", acpi_format_exception(status))); } - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "get_predicate Failed, %s\n", - acpi_format_exception - (status))); + ACPI_REPORT_ERROR(("get_predicate Failed, %s\n", acpi_format_exception(status))); return_ACPI_STATUS(status); } @@ -190,11 +184,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) /* The opcode is unrecognized. Just skip unknown opcodes */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Found unknown opcode %X at AML address %p offset %X, ignoring\n", - walk_state->opcode, - parser_state->aml, - walk_state->aml_offset)); + ACPI_REPORT_ERROR(("Found unknown opcode %X at AML address %p offset %X, ignoring\n", walk_state->opcode, parser_state->aml, walk_state->aml_offset)); ACPI_DUMP_BUFFER(parser_state->aml, 128); @@ -281,10 +271,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) walk_state->descending_callback(walk_state, &op); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "During name lookup/catalog, %s\n", - acpi_format_exception - (status))); + ACPI_REPORT_ERROR(("During name lookup/catalog, %s\n", acpi_format_exception(status))); goto close_this_op; } diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index 229ae86afe8b..11d6351ab8b2 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -747,7 +747,7 @@ const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode) /* Unknown AML opcode */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Unknown AML opcode [%4.4X]\n", opcode)); return (&acpi_gbl_aml_op_info[_UNK]); diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index f0979b2956f2..3b540fe17a0c 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -512,9 +512,9 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) } else if ((status != AE_OK) && (walk_state->method_desc)) { /* Either the method parse or actual execution failed */ - ACPI_REPORT_METHOD_ERROR - ("Method parse/execution failed", - walk_state->method_node, NULL, status); + ACPI_REPORT_MTERROR("Method parse/execution failed", + walk_state->method_node, NULL, + status); /* Check for possible multi-thread reentrancy problem */ diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c index 1c953b6f1af1..bc6047caccd9 100644 --- a/drivers/acpi/parser/psscope.c +++ b/drivers/acpi/parser/psscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c index f0e755884eea..d387e2b01dbb 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/parser/pstree.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -132,7 +132,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) if (op_info->class == AML_CLASS_UNKNOWN) { /* Invalid opcode */ - ACPI_REPORT_ERROR(("ps_append_arg: Invalid AML Opcode: 0x%2.2X\n", op->common.aml_opcode)); + ACPI_REPORT_ERROR(("Invalid AML Opcode: 0x%2.2X\n", + op->common.aml_opcode)); return; } diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index 2075efbb4324..3e07cb9cb748 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c index 08f2321b6ded..06f05bfd7612 100644 --- a/drivers/acpi/parser/pswalk.c +++ b/drivers/acpi/parser/pswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 14d544d60867..2dd48cbb7c02 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 4ac942badbc0..8fa3213ce000 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index c2c4d9079c6c..1dfa6906d455 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 6c7c6c560635..7f46ca0bf33a 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -207,21 +207,14 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* Each element of the top-level package must also be a package */ if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X]) Need sub-package, found %s\n", - index, - acpi_ut_get_object_type_name - (*top_object_list))); + ACPI_REPORT_ERROR(("(PRT[%X]) Need sub-package, found %s\n", index, acpi_ut_get_object_type_name(*top_object_list))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } /* Each sub-package must be of length 4 */ if ((*top_object_list)->package.count != 4) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X]) Need package of length 4, found length %d\n", - index, - (*top_object_list)->package.count)); + ACPI_REPORT_ERROR(("(PRT[%X]) Need package of length 4, found length %d\n", index, (*top_object_list)->package.count)); return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT); } @@ -238,11 +231,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->address = obj_desc->integer.value; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].Address) Need Integer, found %s\n", - index, - acpi_ut_get_object_type_name - (obj_desc))); + ACPI_REPORT_ERROR(("(PRT[%X].Address) Need Integer, found %s\n", index, acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } @@ -252,11 +241,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->pin = (u32) obj_desc->integer.value; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].Pin) Need Integer, found %s\n", - index, - acpi_ut_get_object_type_name - (obj_desc))); + ACPI_REPORT_ERROR(("(PRT[%X].Pin) Need Integer, found %s\n", index, acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } @@ -267,10 +252,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, case ACPI_TYPE_LOCAL_REFERENCE: if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].Source) Need name, found reference op %X\n", - index, - obj_desc->reference.opcode)); + ACPI_REPORT_ERROR(("(PRT[%X].Source) Need name, found reference op %X\n", index, obj_desc->reference.opcode)); return_ACPI_STATUS(AE_BAD_DATA); } @@ -316,11 +298,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].Source) Need Ref/String/Integer, found %s\n", - index, - acpi_ut_get_object_type_name - (obj_desc))); + ACPI_REPORT_ERROR(("(PRT[%X].Source) Need Ref/String/Integer, found %s\n", index, acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } @@ -335,11 +313,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->source_index = (u32) obj_desc->integer.value; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "(PRT[%X].source_index) Need Integer, found %s\n", - index, - acpi_ut_get_object_type_name - (obj_desc))); + ACPI_REPORT_ERROR(("(PRT[%X].source_index) Need Integer, found %s\n", index, acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index c24e3eb658c3..98356e2482c5 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c index 623b06689336..d9ae64b77bd9 100644 --- a/drivers/acpi/resources/rsinfo.c +++ b/drivers/acpi/resources/rsinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index ef24ba110c6e..ea567167c4f2 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 79e71257b69a..1fa63bc2e36f 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 573c06705641..e4778a51c17e 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -156,9 +156,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Validate the (internal) Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid descriptor type (%X) in resource list\n", - resource->type)); + ACPI_REPORT_ERROR(("Invalid descriptor type (%X) in resource list\n", resource->type)); return_ACPI_STATUS(AE_BAD_DATA); } diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index 418a3fb64077..a5131936d690 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 4a758bd4a5c8..83bfe0dd3eba 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -523,9 +523,7 @@ if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) { * polarity/trigger interrupts are allowed (ACPI spec, section * "IRQ Format"), so 0x00 and 0x09 are illegal. */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid interrupt polarity/trigger in resource list, %X\n", - aml->irq.flags)); + ACPI_REPORT_ERROR(("Invalid interrupt polarity/trigger in resource list, %X\n", aml->irq.flags)); return_ACPI_STATUS(AE_BAD_DATA); } @@ -537,8 +535,7 @@ if (temp8 < 1) { } if (resource->data.dma.transfer == 0x03) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid DMA.Transfer preference (3)\n")); + ACPI_REPORT_ERROR(("Invalid DMA.Transfer preference (3)\n")); return_ACPI_STATUS(AE_BAD_DATA); } #endif diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 2236a0c90daa..25b5aedd6612 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 50a956b705b0..88b67077aeeb 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index cd33397d9231..48290b7e6ba5 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 6acd5aeb093e..0fedf4b27ea5 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -362,8 +362,8 @@ acpi_tb_get_this_table(struct acpi_pointer *address, default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid address flags %X\n", - address->pointer_type)); + ACPI_REPORT_ERROR(("Invalid address flags %X\n", + address->pointer_type)); return_ACPI_STATUS(AE_BAD_PARAMETER); } diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c index 33c9ed8a6f99..496f336b3e3a 100644 --- a/drivers/acpi/tables/tbgetall.c +++ b/drivers/acpi/tables/tbgetall.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 10db8484e462..e1c9faa3982e 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index 3cee0cee4cc2..178309026850 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -176,7 +176,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) { int no_match; - ACPI_FUNCTION_NAME("tb_validate_rsdt"); + ACPI_FUNCTION_ENTRY(); /* * Search for appropriate signature, RSDT or XSDT @@ -192,15 +192,11 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) if (no_match) { /* Invalid RSDT or XSDT signature */ - ACPI_REPORT_ERROR(("Invalid signature where RSDP indicates RSDT/XSDT should be located\n")); + ACPI_REPORT_ERROR(("Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:\n")); ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20); - ACPI_DEBUG_PRINT_RAW((ACPI_DB_ERROR, - "RSDT/XSDT signature at %X (%p) is invalid\n", - acpi_gbl_RSDP->rsdt_physical_address, - (void *)(acpi_native_uint) acpi_gbl_RSDP-> - rsdt_physical_address)); + ACPI_REPORT_ERROR(("RSDT/XSDT signature at %X (%p) is invalid\n", acpi_gbl_RSDP->rsdt_physical_address, (void *)(acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address)); if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { ACPI_REPORT_ERROR(("Looking for RSDT\n")) @@ -209,7 +205,6 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) } ACPI_DUMP_BUFFER((char *)table_ptr, 48); - return (AE_BAD_SIGNATURE); } @@ -243,9 +238,8 @@ acpi_status acpi_tb_get_table_rsdt(void) table_info.type = ACPI_TABLE_XSDT; status = acpi_tb_get_table(&address, &table_info); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not get the RSDT/XSDT, %s\n", - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not get the RSDT/XSDT, %s\n", + acpi_format_exception(status))); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 9d0bf536d674..38c6749e43d5 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -144,14 +144,13 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) { acpi_name signature; - ACPI_FUNCTION_NAME("tb_validate_table_header"); + ACPI_FUNCTION_ENTRY(); /* Verify that this is a valid address */ if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Cannot read table header at %p\n", - table_header)); + ACPI_REPORT_ERROR(("Cannot read table header at %p\n", + table_header)); return (AE_BAD_ADDRESS); } @@ -160,12 +159,10 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) ACPI_MOVE_32_TO_32(&signature, table_header->signature); if (!acpi_ut_valid_acpi_name(signature)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Table signature at %p [%p] has invalid characters\n", - table_header, &signature)); + ACPI_REPORT_ERROR(("Table signature at %p [%p] has invalid characters\n", table_header, &signature)); ACPI_REPORT_WARNING(("Invalid table signature found: [%4.4s]\n", - (char *)&signature)); + ACPI_CAST_PTR(char, &signature))); ACPI_DUMP_BUFFER(table_header, sizeof(struct acpi_table_header)); @@ -175,9 +172,7 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) /* Validate the table length */ if (table_header->length < sizeof(struct acpi_table_header)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid length in table header %p name %4.4s\n", - table_header, (char *)&signature)); + ACPI_REPORT_ERROR(("Invalid length in table header %p name %4.4s\n", table_header, (char *)&signature)); ACPI_REPORT_WARNING(("Invalid table header length (0x%X) found\n", (u32) table_header->length)); @@ -291,8 +286,7 @@ acpi_tb_handle_to_object(u16 table_id, } } - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "table_id=%X does not exist\n", - table_id)); + ACPI_REPORT_ERROR(("table_id=%X does not exist\n", table_id)); return (AE_BAD_PARAMETER); } #endif diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 3f96a4909aad..83a9ca8cb98c 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,7 +75,7 @@ acpi_status acpi_load_tables(void) status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, &rsdp_address); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_load_tables: Could not get RSDP, %s\n", + ACPI_REPORT_ERROR(("Could not get RSDP, %s\n", acpi_format_exception(status))); goto error_exit; } @@ -86,7 +86,8 @@ acpi_status acpi_load_tables(void) status = acpi_tb_verify_rsdp(&rsdp_address); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_load_tables: RSDP Failed validation: %s\n", acpi_format_exception(status))); + ACPI_REPORT_ERROR(("RSDP Failed validation: %s\n", + acpi_format_exception(status))); goto error_exit; } @@ -94,7 +95,8 @@ acpi_status acpi_load_tables(void) status = acpi_tb_get_table_rsdt(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_load_tables: Could not load RSDT: %s\n", acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not load RSDT: %s\n", + acpi_format_exception(status))); goto error_exit; } @@ -102,7 +104,7 @@ acpi_status acpi_load_tables(void) status = acpi_tb_get_required_tables(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n", acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not get all required tables (DSDT/FADT/FACS): %s\n", acpi_format_exception(status))); goto error_exit; } @@ -112,14 +114,15 @@ acpi_status acpi_load_tables(void) status = acpi_ns_load_namespace(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("acpi_load_tables: Could not load namespace: %s\n", acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not load namespace: %s\n", + acpi_format_exception(status))); goto error_exit; } return_ACPI_STATUS(AE_OK); error_exit: - ACPI_REPORT_ERROR(("acpi_load_tables: Could not load tables: %s\n", + ACPI_REPORT_ERROR(("Could not load tables: %s\n", acpi_format_exception(status))); return_ACPI_STATUS(status); diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index b01a4b2ae7da..6538ed818f5b 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -396,9 +396,8 @@ acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) status = acpi_tb_find_rsdp(&table_info, flags); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "RSDP structure not found, %s Flags=%X\n", - acpi_format_exception(status), flags)); + ACPI_REPORT_ERROR(("RSDP structure not found, %s Flags=%X\n", + acpi_format_exception(status), flags)); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -503,10 +502,7 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) ACPI_EBDA_PTR_LENGTH, (void *)&table_ptr); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not map memory at %8.8X for length %X\n", - ACPI_EBDA_PTR_LOCATION, - ACPI_EBDA_PTR_LENGTH)); + ACPI_REPORT_ERROR(("Could not map memory at %8.8X for length %X\n", ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); return_ACPI_STATUS(status); } @@ -530,10 +526,7 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) ACPI_EBDA_WINDOW_SIZE, (void *)&table_ptr); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not map memory at %8.8X for length %X\n", - physical_address, - ACPI_EBDA_WINDOW_SIZE)); + ACPI_REPORT_ERROR(("Could not map memory at %8.8X for length %X\n", physical_address, ACPI_EBDA_WINDOW_SIZE)); return_ACPI_STATUS(status); } @@ -563,10 +556,7 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) (void *)&table_ptr); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Could not map memory at %8.8X for length %X\n", - ACPI_HI_RSDP_WINDOW_BASE, - ACPI_HI_RSDP_WINDOW_SIZE)); + ACPI_REPORT_ERROR(("Could not map memory at %8.8X for length %X\n", ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index b11b7ed788c6..0efcbdf7e620 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -301,7 +301,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) /* Check for an inadvertent size of zero bytes */ if (!size) { - _ACPI_REPORT_ERROR(module, line, component, + _ACPI_REPORT_ERROR(module, line, ("ut_allocate: Attempt to allocate zero bytes, allocating 1 byte\n")); size = 1; } @@ -310,7 +310,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) if (!allocation) { /* Report allocation error */ - _ACPI_REPORT_ERROR(module, line, component, + _ACPI_REPORT_ERROR(module, line, ("ut_allocate: Could not allocate size %X\n", (u32) size)); @@ -344,7 +344,7 @@ void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line) /* Check for an inadvertent size of zero bytes */ if (!size) { - _ACPI_REPORT_ERROR(module, line, component, + _ACPI_REPORT_ERROR(module, line, ("ut_callocate: Attempt to allocate zero bytes, allocating 1 byte\n")); size = 1; } @@ -353,7 +353,7 @@ void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line) if (!allocation) { /* Report allocation error */ - _ACPI_REPORT_ERROR(module, line, component, + _ACPI_REPORT_ERROR(module, line, ("ut_callocate: Could not allocate size %X\n", (u32) size)); return_PTR(NULL); @@ -480,7 +480,7 @@ void *acpi_ut_callocate_and_track(acpi_size size, if (!allocation) { /* Report allocation error */ - _ACPI_REPORT_ERROR(module, line, component, + _ACPI_REPORT_ERROR(module, line, ("ut_callocate: Could not allocate size %X\n", (u32) size)); return (NULL); @@ -524,7 +524,7 @@ acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line) ACPI_FUNCTION_TRACE_PTR("ut_free", allocation); if (NULL == allocation) { - _ACPI_REPORT_ERROR(module, line, component, + _ACPI_REPORT_ERROR(module, line, ("acpi_ut_free: Attempt to delete a NULL address\n")); return_VOID; @@ -540,8 +540,8 @@ acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line) status = acpi_ut_remove_allocation(debug_block, component, module, line); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Could not free memory, %s\n", - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not free memory, %s\n", + acpi_format_exception(status))); } acpi_os_free(debug_block); @@ -626,8 +626,8 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, if (element) { ACPI_REPORT_ERROR(("ut_track_allocation: Allocation already present in list! (%p)\n", allocation)); - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Element %p Address %p\n", - element, allocation)); + ACPI_REPORT_ERROR(("Element %p Address %p\n", + element, allocation)); goto unlock_and_exit; } @@ -687,7 +687,7 @@ acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation, if (NULL == mem_list->list_head) { /* No allocations! */ - _ACPI_REPORT_ERROR(module, line, component, + _ACPI_REPORT_ERROR(module, line, ("ut_remove_allocation: Empty allocation list, nothing to free!\n")); return_ACPI_STATUS(AE_OK); @@ -863,12 +863,10 @@ void acpi_ut_dump_allocations(u32 component, char *module) /* Print summary */ if (!num_outstanding) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "No outstanding allocations\n")); + ACPI_REPORT_INFO(("No outstanding allocations\n")); } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%d(%X) Outstanding allocations\n", - num_outstanding, num_outstanding)); + ACPI_REPORT_ERROR(("%d(%X) Outstanding allocations\n", + num_outstanding, num_outstanding)); } return_VOID; diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c index 93d48681d276..2177cb1ef2c4 100644 --- a/drivers/acpi/utilities/utcache.c +++ b/drivers/acpi/utilities/utcache.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 568df9e42f89..1a4da006822a 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -606,8 +606,7 @@ acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object, /* * Packages as external input to control methods are not supported, */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Packages as parameters not implemented!\n")); + ACPI_REPORT_ERROR(("Packages as parameters not implemented!\n")); return_ACPI_STATUS(AE_NOT_IMPLEMENTED); } @@ -870,7 +869,7 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, count + 1) * sizeof(void *)); if (!dest_obj->package.elements) { - ACPI_REPORT_ERROR(("aml_build_copy_internal_package_object: Package allocation failure\n")); + ACPI_REPORT_ERROR(("Package allocation failure\n")); return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index d80e92639932..35f3d581e034 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 2bc878f7a127..1079a1a1f195 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -363,8 +363,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown action (%X)\n", - action)); + ACPI_REPORT_ERROR(("Unknown action (%X)\n", action)); break; } @@ -374,9 +373,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) */ if (count > ACPI_MAX_REFERENCE_COUNT) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "**** Warning **** Large Reference Count (%X) in object %p\n\n", - count, object)); + ACPI_REPORT_WARNING(("Large Reference Count (%X) in object %p\n\n", count, object)); } return; diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index cd63a2d93fe3..f4dc374a0eec 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -154,8 +154,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_ut_get_node_name(prefix_node), path)); } else { - ACPI_REPORT_METHOD_ERROR("Method execution failed", - prefix_node, path, status); + ACPI_REPORT_MTERROR("Method execution failed", + prefix_node, path, status); } return_ACPI_STATUS(status); @@ -165,9 +165,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, if (!info.return_object) { if (expected_return_btypes) { - ACPI_REPORT_METHOD_ERROR("No object was returned from", - prefix_node, path, - AE_NOT_EXIST); + ACPI_REPORT_MTERROR("No object was returned from", + prefix_node, path, AE_NOT_EXIST); return_ACPI_STATUS(AE_NOT_EXIST); } @@ -212,15 +211,10 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, /* Is the return object one of the expected types? */ if (!(expected_return_btypes & return_btype)) { - ACPI_REPORT_METHOD_ERROR("Return object type is incorrect", - prefix_node, path, AE_TYPE); + ACPI_REPORT_MTERROR("Return object type is incorrect", + prefix_node, path, AE_TYPE); - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Type returned from %s was incorrect: %s, expected Btypes: %X\n", - path, - acpi_ut_get_object_type_name(info. - return_object), - expected_return_btypes)); + ACPI_REPORT_ERROR(("Type returned from %s was incorrect: %s, expected Btypes: %X\n", path, acpi_ut_get_object_type_name(info.return_object), expected_return_btypes)); /* On error exit, we must delete the return object */ diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 7c59c2b0d953..87ca9a0a8b76 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,8 +67,11 @@ const char *acpi_format_exception(acpi_status status) acpi_status sub_status; const char *exception = NULL; - ACPI_FUNCTION_NAME("format_exception"); + ACPI_FUNCTION_ENTRY(); + /* + * Status is composed of two parts, a "type" and an actual code + */ sub_status = (status & ~AE_CODE_MASK); switch (status & AE_CODE_MASK) { @@ -118,13 +121,13 @@ const char *acpi_format_exception(acpi_status status) if (!exception) { /* Exception code was not recognized */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unknown exception code: 0x%8.8X\n", status)); + ACPI_REPORT_ERROR(("Unknown exception code: 0x%8.8X\n", + status)); - return ((const char *)"UNKNOWN_STATUS_CODE"); + exception = "UNKNOWN_STATUS_CODE"; } - return ((const char *)exception); + return (ACPI_CAST_PTR(const char, exception)); } /******************************************************************************* @@ -519,7 +522,7 @@ char *acpi_ut_get_event_name(u32 event_id) return ("invalid_event_iD"); } - return ((char *)acpi_gbl_event_types[event_id]); + return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id])); } /******************************************************************************* @@ -586,10 +589,10 @@ char *acpi_ut_get_type_name(acpi_object_type type) { if (type > ACPI_TYPE_INVALID) { - return ((char *)acpi_gbl_bad_type); + return (ACPI_CAST_PTR(char, acpi_gbl_bad_type)); } - return ((char *)acpi_gbl_ns_type_names[type]); + return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type])); } char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c index 9dde82b0beaf..7565ba6f90d5 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/utilities/utinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -221,15 +221,14 @@ void acpi_ut_subsystem_shutdown(void) /* Just exit if subsystem is already shutdown */ if (acpi_gbl_shutdown) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "ACPI Subsystem is already terminated\n")); + ACPI_REPORT_ERROR(("ACPI Subsystem is already terminated\n")); return_VOID; } /* Subsystem appears active, go ahead and shut it down */ acpi_gbl_shutdown = TRUE; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n")); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); /* Close the acpi_event Handling */ diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c index 68a0a6f94129..06214201329d 100644 --- a/drivers/acpi/utilities/utmath.c +++ b/drivers/acpi/utilities/utmath.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -82,7 +82,7 @@ acpi_ut_short_divide(acpi_integer dividend, /* Always check for a zero divisor */ if (divisor == 0) { - ACPI_REPORT_ERROR(("acpi_ut_short_divide: Divide by zero\n")); + ACPI_REPORT_ERROR(("Divide by zero\n")); return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO); } @@ -144,7 +144,7 @@ acpi_ut_divide(acpi_integer in_dividend, /* Always check for a zero divisor */ if (in_divisor == 0) { - ACPI_REPORT_ERROR(("acpi_ut_divide: Divide by zero\n")); + ACPI_REPORT_ERROR(("Divide by zero\n")); return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO); } @@ -266,7 +266,7 @@ acpi_ut_short_divide(acpi_integer in_dividend, /* Always check for a zero divisor */ if (divisor == 0) { - ACPI_REPORT_ERROR(("acpi_ut_short_divide: Divide by zero\n")); + ACPI_REPORT_ERROR(("Divide by zero\n")); return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO); } @@ -292,7 +292,7 @@ acpi_ut_divide(acpi_integer in_dividend, /* Always check for a zero divisor */ if (in_divisor == 0) { - ACPI_REPORT_ERROR(("acpi_ut_divide: Divide by zero\n")); + ACPI_REPORT_ERROR(("Divide by zero\n")); return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO); } diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 48d511d5c04b..a77ffcd5570f 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -841,7 +841,6 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) * * PARAMETERS: module_name - Caller's module name (for error output) * line_number - Caller's line number (for error output) - * component_id - Caller's component ID (for error output) * * RETURN: None * @@ -849,10 +848,10 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) * ******************************************************************************/ -void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id) +void acpi_ut_report_error(char *module_name, u32 line_number) { - acpi_os_printf("%8s-%04d: *** Error: ", module_name, line_number); + acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); } /******************************************************************************* @@ -861,7 +860,6 @@ void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id) * * PARAMETERS: module_name - Caller's module name (for error output) * line_number - Caller's line number (for error output) - * component_id - Caller's component ID (for error output) * * RETURN: None * @@ -869,11 +867,10 @@ void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id) * ******************************************************************************/ -void -acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id) +void acpi_ut_report_warning(char *module_name, u32 line_number) { - acpi_os_printf("%8s-%04d: *** Warning: ", module_name, line_number); + acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); } /******************************************************************************* @@ -882,7 +879,6 @@ acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id) * * PARAMETERS: module_name - Caller's module name (for error output) * line_number - Caller's line number (for error output) - * component_id - Caller's component ID (for error output) * * RETURN: None * @@ -890,8 +886,8 @@ acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id) * ******************************************************************************/ -void acpi_ut_report_info(char *module_name, u32 line_number, u32 component_id) +void acpi_ut_report_info(char *module_name, u32 line_number) { - acpi_os_printf("%8s-%04d: *** Info: ", module_name, line_number); + acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); } diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c index e158b1b6313b..ffaff55270b1 100644 --- a/drivers/acpi/utilities/utmutex.c +++ b/drivers/acpi/utilities/utmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -216,21 +216,12 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) for (i = mutex_id; i < MAX_MUTEX; i++) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Mutex [%s] already acquired by this thread [%X]\n", - acpi_ut_get_mutex_name - (mutex_id), - this_thread_id)); + ACPI_REPORT_ERROR(("Mutex [%s] already acquired by this thread [%X]\n", acpi_ut_get_mutex_name(mutex_id), this_thread_id)); return (AE_ALREADY_ACQUIRED); } - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid acquire order: Thread %X owns [%s], wants [%s]\n", - this_thread_id, - acpi_ut_get_mutex_name(i), - acpi_ut_get_mutex_name - (mutex_id))); + ACPI_REPORT_ERROR(("Invalid acquire order: Thread %X owns [%s], wants [%s]\n", this_thread_id, acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(mutex_id))); return (AE_ACQUIRE_DEADLOCK); } @@ -253,11 +244,7 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) acpi_gbl_mutex_info[mutex_id].use_count++; acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Thread %X could not acquire Mutex [%s] %s\n", - this_thread_id, - acpi_ut_get_mutex_name(mutex_id), - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Thread %X could not acquire Mutex [%X] %s\n", this_thread_id, mutex_id, acpi_format_exception(status))); } return (status); @@ -295,9 +282,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) * Mutex must be acquired in order to release it! */ if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Mutex [%s] is not acquired, cannot release\n", - acpi_ut_get_mutex_name(mutex_id))); + ACPI_REPORT_ERROR(("Mutex [%X] is not acquired, cannot release\n", mutex_id)); return (AE_NOT_ACQUIRED); } @@ -318,11 +303,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) continue; } - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid release order: owns [%s], releasing [%s]\n", - acpi_ut_get_mutex_name(i), - acpi_ut_get_mutex_name - (mutex_id))); + ACPI_REPORT_ERROR(("Invalid release order: owns [%s], releasing [%s]\n", acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(mutex_id))); return (AE_RELEASE_DEADLOCK); } @@ -338,11 +319,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) acpi_os_signal_semaphore(acpi_gbl_mutex_info[mutex_id].mutex, 1); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Thread %X could not release Mutex [%s] %s\n", - this_thread_id, - acpi_ut_get_mutex_name(mutex_id), - acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Thread %X could not release Mutex [%X] %s\n", this_thread_id, mutex_id, acpi_format_exception(status))); } else { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index 3015e1540053..1b6b21577805 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -177,7 +177,8 @@ union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size) buffer = ACPI_MEM_CALLOCATE(buffer_size); if (!buffer) { - ACPI_REPORT_ERROR(("create_buffer: could not allocate size %X\n", (u32) buffer_size)); + ACPI_REPORT_ERROR(("Could not allocate size %X\n", + (u32) buffer_size)); acpi_ut_remove_reference(buffer_desc); return_PTR(NULL); } @@ -228,7 +229,8 @@ union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size) */ string = ACPI_MEM_CALLOCATE(string_size + 1); if (!string) { - ACPI_REPORT_ERROR(("create_string: could not allocate size %X\n", (u32) string_size)); + ACPI_REPORT_ERROR(("Could not allocate size %X\n", + (u32) string_size)); acpi_ut_remove_reference(string_desc); return_PTR(NULL); } @@ -310,7 +312,7 @@ void *acpi_ut_allocate_object_desc_dbg(char *module_name, object = acpi_os_acquire_object(acpi_gbl_operand_cache); if (!object) { - _ACPI_REPORT_ERROR(module_name, line_number, component_id, + _ACPI_REPORT_ERROR(module_name, line_number, ("Could not allocate an object descriptor\n")); return_PTR(NULL); @@ -345,9 +347,9 @@ void acpi_ut_delete_object_desc(union acpi_operand_object *object) /* Object must be an union acpi_operand_object */ if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "%p is not an ACPI Operand object [%s]\n", - object, acpi_ut_get_descriptor_name(object))); + ACPI_REPORT_ERROR(("%p is not an ACPI Operand object [%s]\n", + object, + acpi_ut_get_descriptor_name(object))); return_VOID; } @@ -449,10 +451,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, * Notably, Locals and Args are not supported, but this may be * required eventually. */ - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported Reference opcode=%X in object %p\n", - internal_object->reference.opcode, - internal_object)); + ACPI_REPORT_ERROR(("Unsupported Reference opcode=%X in object %p\n", internal_object->reference.opcode, internal_object)); status = AE_TYPE; break; } @@ -460,10 +459,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported type=%X in object %p\n", - ACPI_GET_OBJECT_TYPE(internal_object), - internal_object)); + ACPI_REPORT_ERROR(("Unsupported type=%X in object %p\n", + ACPI_GET_OBJECT_TYPE(internal_object), + internal_object)); status = AE_TYPE; break; } diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index eaf0edec6efe..36bf9e4bf529 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c index 6ff1d7073349..4b134a722907 100644 --- a/drivers/acpi/utilities/utstate.c +++ b/drivers/acpi/utilities/utstate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index 57adc5bc02f3..b4bc94883200 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,7 +75,7 @@ acpi_status acpi_initialize_subsystem(void) status = acpi_os_initialize(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("OSD failed to initialize, %s\n", + ACPI_REPORT_ERROR(("OSL failed to initialize, %s\n", acpi_format_exception(status))); return_ACPI_STATUS(status); } @@ -154,8 +154,7 @@ acpi_status acpi_enable_subsystem(u32 flags) status = acpi_enable(); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "acpi_enable failed.\n")); + ACPI_REPORT_WARNING(("acpi_enable failed\n")); return_ACPI_STATUS(status); } } diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 1f2477eb95fe..675a32f78329 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20051216 +#define ACPI_CA_VERSION 0x20060113 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff --git a/include/acpi/acdebug.h b/include/acpi/acdebug.h index 70ce3b4d006e..d8167095caf3 100644 --- a/include/acpi/acdebug.h +++ b/include/acpi/acdebug.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index 0a8f49f5d2f1..11a8fe39cb04 100644 --- a/include/acpi/acdisasm.h +++ b/include/acpi/acdisasm.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h index cc6407eef701..c41a926ff317 100644 --- a/include/acpi/acdispat.h +++ b/include/acpi/acdispat.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h index b40062c3ba7a..f2717be4fe0d 100644 --- a/include/acpi/acevents.h +++ b/include/acpi/acevents.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 4f005eb65928..dc768aa580e4 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index dfb3b2493ae5..734cc77bf2c7 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/achware.h b/include/acpi/achware.h index 3644d7248e7e..29b60a8c0593 100644 --- a/include/acpi/achware.h +++ b/include/acpi/achware.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h index 87e5e44572ca..9f22cfcb624b 100644 --- a/include/acpi/acinterp.h +++ b/include/acpi/acinterp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index da7f1cb96f5d..97f8e4185e4f 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 0fa8f72dbace..49ba151766de 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -443,56 +443,66 @@ #define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) /* - * Reporting macros that are never compiled out + * Module name is include in both debug and non-debug versions primarily for + * error messages. The __FILE__ macro is not very useful for this, because it + * often includes the entire pathname to the module */ -#define ACPI_PARAM_LIST(pl) pl - -/* - * Error reporting. These versions add callers module and line#. - * - * Since _acpi_module_name gets compiled out when ACPI_DEBUG_OUTPUT - * isn't defined, only use it in debug mode. - */ -#ifdef ACPI_DEBUG_OUTPUT - -#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info(_acpi_module_name,__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error(_acpi_module_name,__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning(_acpi_module_name,__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error(_acpi_module_name,__LINE__,_COMPONENT, s, e); - -#define ACPI_REPORT_METHOD_ERROR(s,n,p,e) acpi_ns_report_method_error(_acpi_module_name,__LINE__,_COMPONENT, s, n, p, e); +#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES) +#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_acpi_module_name = name; #else - -#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error("ACPI",__LINE__,_COMPONENT, s, e); - -#define ACPI_REPORT_METHOD_ERROR(s,n,p,e) acpi_ns_report_method_error("ACPI",__LINE__,_COMPONENT, s, n, p, e); - +#define ACPI_MODULE_NAME(name) #endif -/* Error reporting. These versions pass thru the module and line# */ +/* + * Ascii error messages can be configured out + */ +#ifndef ACPI_NO_ERROR_MESSAGES -#define _ACPI_REPORT_INFO(a,b,c,fp) {acpi_ut_report_info(a,b,c); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define _ACPI_REPORT_ERROR(a,b,c,fp) {acpi_ut_report_error(a,b,c); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define _ACPI_REPORT_WARNING(a,b,c,fp) {acpi_ut_report_warning(a,b,c); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} +#define ACPI_PARAM_LIST(pl) pl +#define ACPI_LOCATION_INFO _acpi_module_name, __LINE__ + +/* + * Error reporting. Callers module and line number are inserted automatically + * These macros are used for both the debug and non-debug versions of the code + */ +#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info (ACPI_LOCATION_INFO); \ + acpi_os_printf ACPI_PARAM_LIST (fp);} +#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error (ACPI_LOCATION_INFO); \ + acpi_os_printf ACPI_PARAM_LIST (fp);} +#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning (ACPI_LOCATION_INFO); \ + acpi_os_printf ACPI_PARAM_LIST (fp);} +#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error (ACPI_LOCATION_INFO, \ + s, e); +#define ACPI_REPORT_MTERROR(s,n,p,e) acpi_ns_report_method_error (ACPI_LOCATION_INFO, \ + s, n, p, e); + +/* Error reporting. These versions pass thru the module and lineno */ + +#define _ACPI_REPORT_INFO(a,b,fp) {acpi_ut_report_info (a,b); \ + acpi_os_printf ACPI_PARAM_LIST (fp);} +#define _ACPI_REPORT_ERROR(a,b,fp) {acpi_ut_report_error (a,b); \ + acpi_os_printf ACPI_PARAM_LIST (fp);} +#define _ACPI_REPORT_WARNING(a,b,fp) {acpi_ut_report_warning (a,b); \ + acpi_os_printf ACPI_PARAM_LIST (fp);} +#else + +/* No error messages */ + +#define ACPI_REPORT_INFO(fp) +#define ACPI_REPORT_ERROR(fp) +#define ACPI_REPORT_WARNING(fp) +#define ACPI_REPORT_NSERROR(s,e) +#define ACPI_REPORT_MTERROR(s,n,p,e) +#define _ACPI_REPORT_INFO(a,b,c,fp) +#define _ACPI_REPORT_ERROR(a,b,c,fp) +#define _ACPI_REPORT_WARNING(a,b,c,fp) +#endif /* * Debug macros that are conditionally compiled */ #ifdef ACPI_DEBUG_OUTPUT -#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_acpi_module_name = name; /* * Common parameters used for debug output functions: @@ -649,9 +659,6 @@ * This is the non-debug case -- make everything go away, * leaving no executable debug code! */ -#define ACPI_MODULE_NAME(name) -#define _acpi_module_name "" - #define ACPI_DEBUG_EXEC(a) #define ACPI_NORMAL_EXEC(a) a; diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 4f9063f3e951..b67da3636899 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h index dd3501f7e5d6..b667a804fc8a 100644 --- a/include/acpi/acnamesp.h +++ b/include/acpi/acnamesp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -263,13 +263,11 @@ u32 acpi_ns_local(acpi_object_type type); void acpi_ns_report_error(char *module_name, u32 line_number, - u32 component_id, char *internal_name, acpi_status lookup_status); void acpi_ns_report_method_error(char *module_name, u32 line_number, - u32 component_id, char *message, struct acpi_namespace_node *node, char *path, acpi_status lookup_status); diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h index 4a326ba6d482..1bd411962c77 100644 --- a/include/acpi/acobject.h +++ b/include/acpi/acobject.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acopcode.h b/include/acpi/acopcode.h index 64da42992199..e6d78bd9e90a 100644 --- a/include/acpi/acopcode.h +++ b/include/acpi/acopcode.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index 68d7edf0f697..7785d481dc3e 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -137,13 +137,19 @@ /* Exception level -- used in the global "debug_level" */ -#define ACPI_DB_ERROR ACPI_DEBUG_LEVEL (ACPI_LV_ERROR) -#define ACPI_DB_WARN ACPI_DEBUG_LEVEL (ACPI_LV_WARN) #define ACPI_DB_INIT ACPI_DEBUG_LEVEL (ACPI_LV_INIT) #define ACPI_DB_DEBUG_OBJECT ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT) #define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO) #define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS) +/* + * These two levels are essentially obsolete, all instances in the + * ACPICA core code have been replaced by REPORT_ERROR and REPORT_WARNING + * (Kept here because some drivers may still use them) + */ +#define ACPI_DB_ERROR ACPI_DEBUG_LEVEL (ACPI_LV_ERROR) +#define ACPI_DB_WARN ACPI_DEBUG_LEVEL (ACPI_LV_WARN) + /* Trace level -- also used in the global "debug_level" */ #define ACPI_DB_INIT_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES) diff --git a/include/acpi/acparser.h b/include/acpi/acparser.h index d352d40de1f3..5a1ff484af33 100644 --- a/include/acpi/acparser.h +++ b/include/acpi/acparser.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h index ccf34f9dac64..b9a39d1009bd 100644 --- a/include/acpi/acpi.h +++ b/include/acpi/acpi.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 58473f60755f..768f63f391cd 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -8,7 +8,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 2a88429bc4ec..66cf2ecef57a 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h index ba281f7740a0..fa02e8083381 100644 --- a/include/acpi/acresrc.h +++ b/include/acpi/acresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h index 99d235339801..d8c1c2cdac0c 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/actables.h b/include/acpi/actables.h index f92c1858b808..30a47542e1c8 100644 --- a/include/acpi/actables.h +++ b/include/acpi/actables.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index ef2ddcadfe61..ed53f842dad4 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 67312c3a915a..cd428d57add0 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index 50305ce2681a..dfc7ac1094bb 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 18e1338c5c7f..74819e9b4699 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index 5fa21e03a62f..10f6625f6390 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -275,12 +275,11 @@ acpi_ut_ptr_exit(u32 line_number, const char *function_name, char *module_name, u32 component_id, u8 * ptr); -void acpi_ut_report_info(char *module_name, u32 line_number, u32 component_id); +void acpi_ut_report_error(char *module_name, u32 line_number); -void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id); +void acpi_ut_report_info(char *module_name, u32 line_number); -void -acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id); +void acpi_ut_report_warning(char *module_name, u32 line_number); void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id); diff --git a/include/acpi/amlcode.h b/include/acpi/amlcode.h index 7fdf5299f501..37964a59aef8 100644 --- a/include/acpi/amlcode.h +++ b/include/acpi/amlcode.h @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h index 2e3382c1e5e3..fb4735315ad3 100644 --- a/include/acpi/amlresrc.h +++ b/include/acpi/amlresrc.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 53aa997f05fc..31b0f18342f6 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 4c0e0ba09ba0..ea2a6322f64d 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 1b9cbf05b79e..c21c27fe7e1e 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without From f9e61929e5e1dacc2afefbde6abc3e6571ca2887 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sat, 21 Jan 2006 14:02:59 -0800 Subject: [PATCH 057/695] IB/mthca: Use correct GID in MADs sent on port 2 mthca_create_ah() includes the port number in the GID index. The reverse needs to be done in mthca_read_ah(). Noted by Hal Rosenstock. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_av.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c index a14eed08a0fc..a19e0ed03d7c 100644 --- a/drivers/infiniband/hw/mthca/mthca_av.c +++ b/drivers/infiniband/hw/mthca/mthca_av.c @@ -184,7 +184,7 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff); ib_get_cached_gid(&dev->ib_dev, be32_to_cpu(ah->av->port_pd) >> 24, - ah->av->gid_index, + ah->av->gid_index % dev->limits.gid_table_len, &header->grh.source_gid); memcpy(header->grh.destination_gid.raw, ah->av->dgid, 16); From ce33941f027bc1853ceb43d04d6204f45181703d Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 10 Jan 2006 20:47:49 -0500 Subject: [PATCH 058/695] [PARISC] Make flush_tlb_all_local take a void * Make flush_tlb_all_local take a void * so it doesn't have to be cast when using on_each_cpu(). This becomes a problem when on_each_cpu is a macro. Also remove the prototype of flush_tlb_all_local from .c files. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/mm/init.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 720287d46e55..e54268004f53 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -792,8 +792,6 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm) EXPORT_SYMBOL(map_hpux_gateway_page); #endif -extern void flush_tlb_all_local(void); - void __init paging_init(void) { int i; @@ -802,7 +800,7 @@ void __init paging_init(void) pagetable_init(); gateway_init(); flush_cache_all_local(); /* start with known state */ - flush_tlb_all_local(); + flush_tlb_all_local(NULL); for (i = 0; i < npmem_ranges; i++) { unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 }; @@ -993,7 +991,7 @@ void flush_tlb_all(void) do_recycle++; } spin_unlock(&sid_lock); - on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1); + on_each_cpu(flush_tlb_all_local, NULL, 1, 1); if (do_recycle) { spin_lock(&sid_lock); recycle_sids(recycle_ndirty,recycle_dirty_array); From 6c1080c1ea0ecdd541dac25e6550449390935db6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 4 Jan 2006 12:15:07 +0100 Subject: [PATCH 059/695] [ALSA] via82xx - Add dxs_support for ASUS mobo Modules: VIA82xx driver Add a dxs_support entry for ASUS mobo. Signed-off-by: Takashi Iwai --- sound/pci/via82xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index ed26a155c344..9188a9f2315d 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -2340,6 +2340,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ { .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */ { .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */ + { .subvendor = 0x1043, .subdevice = 0x8174, .action = VIA_DXS_SRC }, /* ASUS */ { .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */ { .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */ { .subvendor = 0x10cf, .subdevice = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */ From d82ed2ffc2839413c20b41a271a4d8db12b0683c Mon Sep 17 00:00:00 2001 From: Ulrich Mueller Date: Wed, 4 Jan 2006 12:21:11 +0100 Subject: [PATCH 060/695] [ALSA] intel8x0 - Fix duplicate ac97_quirks entry Modules: Intel8x0 driver in recent -mm kernels additional quirks for ac97 hardware in HP laptops have been added. However, now the list in intel8x0.c contains a duplicate, since the HP nx6110 and nc6120 have identical subdevice ids. This was introduced in -mm1 by the following patch: add-new-quirk-for-devices-with-mute-leds-and-separate-headphone-volume.patch Since the HP nx6110 and nc6120 are almost identical, both entries should really be combined, as in the following patch. I have checked that AC97_TUNE_HP_MUTE_LED is the right thing to do. Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/pci/intel8x0.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 5466b1fa0cd5..2fe2a8ae82ce 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1845,12 +1845,6 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .name = "HP nx8220", .type = AC97_TUNE_MUTE_LED }, - { - .subvendor = 0x103c, - .subdevice = 0x099c, - .name = "HP nx6110", /* AD1981B */ - .type = AC97_TUNE_HP_ONLY - }, { .subvendor = 0x103c, .subdevice = 0x129d, @@ -1866,7 +1860,7 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { { .subvendor = 0x103c, .subdevice = 0x099c, - .name = "HP nc6120", + .name = "HP nx6110/nc6120", .type = AC97_TUNE_HP_MUTE_LED }, { From 59b1b34f47e6c8ac8f00660db2cd34216819b400 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 4 Jan 2006 15:06:44 +0100 Subject: [PATCH 061/695] [ALSA] Fix compilation without CONFIG_PNP Fix compilation of some ISA drivers without CONFIG_PNP. Signed-off-by: Takashi Iwai --- sound/isa/cmi8330.c | 6 ++++++ sound/isa/cs423x/cs4236.c | 7 +++++++ sound/isa/es18xx.c | 6 +++++- sound/isa/opl3sa2.c | 6 ++++++ sound/isa/sscape.c | 6 +++++- sound/isa/wavefront/wavefront.c | 7 +++++-- 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index bd8e23818460..fd9bb2575de8 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -109,7 +109,9 @@ module_param_array(wssdma, int, NULL, 0444); MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); static struct platform_device *platform_devices[SNDRV_CARDS]; +#ifdef CONFIG_PNP static int pnp_registered; +#endif #define CMI8330_RMUX3D 16 #define CMI8330_MUTEMUX 17 @@ -672,8 +674,10 @@ static void __init_or_module snd_cmi8330_unregister_all(void) { int i; +#ifdef CONFIG_PNP if (pnp_registered) pnp_unregister_card_driver(&cmi8330_pnpc_driver); +#endif for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) platform_device_unregister(platform_devices[i]); platform_driver_unregister(&snd_cmi8330_driver); @@ -700,11 +704,13 @@ static int __init alsa_card_cmi8330_init(void) cards++; } +#ifdef CONFIG_PNP err = pnp_register_card_driver(&cmi8330_pnpc_driver); if (err >= 0) { pnp_registered = 1; cards += err; } +#endif if (!cards) { #ifdef MODULE diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index e1683337e6cd..2bfa68b01fe4 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -125,10 +125,12 @@ module_param_array(dma2, int, NULL, 0444); MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); static struct platform_device *platform_devices[SNDRV_CARDS]; +#ifdef CONFIG_PNP static int pnpc_registered; #ifdef CS4232 static int pnp_registered; #endif +#endif /* CONFIG_PNP */ struct snd_card_cs4236 { struct snd_cs4231 *chip; @@ -747,12 +749,14 @@ static void __init_or_module snd_cs423x_unregister_all(void) { int i; +#ifdef CONFIG_PNP if (pnpc_registered) pnp_unregister_card_driver(&cs423x_pnpc_driver); #ifdef CS4232 if (pnp_registered) pnp_unregister_driver(&cs4232_pnp_driver); #endif +#endif /* CONFIG_PNP */ for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) platform_device_unregister(platform_devices[i]); platform_driver_unregister(&cs423x_nonpnp_driver); @@ -778,6 +782,7 @@ static int __init alsa_card_cs423x_init(void) platform_devices[i] = device; cards++; } +#ifdef CONFIG_PNP #ifdef CS4232 i = pnp_register_driver(&cs4232_pnp_driver); if (i >= 0) { @@ -790,6 +795,8 @@ static int __init alsa_card_cs423x_init(void) pnpc_registered = 1; cards += i; } +#endif /* CONFIG_PNP */ + if (!cards) { #ifdef MODULE printk(KERN_ERR IDENT " soundcard not found or device busy\n"); diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index bf5de0782eb0..08f032b51107 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -1878,9 +1878,9 @@ module_param_array(dma2, int, NULL, 0444); MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver."); static struct platform_device *platform_devices[SNDRV_CARDS]; -static int pnp_registered; #ifdef CONFIG_PNP +static int pnp_registered; static struct pnp_card_device_id snd_audiodrive_pnpids[] = { /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */ @@ -2209,8 +2209,10 @@ static void __init_or_module snd_es18xx_unregister_all(void) { int i; +#ifdef CONFIG_PNP if (pnp_registered) pnp_unregister_card_driver(&es18xx_pnpc_driver); +#endif for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) platform_device_unregister(platform_devices[i]); platform_driver_unregister(&snd_es18xx_nonpnp_driver); @@ -2237,11 +2239,13 @@ static int __init alsa_card_es18xx_init(void) cards++; } +#ifdef CONFIG_PNP i = pnp_register_card_driver(&es18xx_pnpc_driver); if (i >= 0) { pnp_registered = 1; cards += i; } +#endif if(!cards) { #ifdef MODULE diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index ca359e0c674b..84ffa8f0f26d 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -91,8 +91,10 @@ module_param_array(opl3sa3_ymode, int, NULL, 0444); MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi."); static struct platform_device *platform_devices[SNDRV_CARDS]; +#ifdef CONFIG_PNP static int pnp_registered; static int pnpc_registered; +#endif /* control ports */ #define OPL3SA2_PM_CTRL 0x01 @@ -929,10 +931,12 @@ static void __init_or_module snd_opl3sa2_unregister_all(void) { int i; +#ifdef CONFIG_PNP if (pnpc_registered) pnp_unregister_card_driver(&opl3sa2_pnpc_driver); if (pnp_registered) pnp_unregister_driver(&opl3sa2_pnp_driver); +#endif for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) platform_device_unregister(platform_devices[i]); platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); @@ -961,6 +965,7 @@ static int __init alsa_card_opl3sa2_init(void) cards++; } +#ifdef CONFIG_PNP err = pnp_register_driver(&opl3sa2_pnp_driver); if (err >= 0) { pnp_registered = 1; @@ -971,6 +976,7 @@ static int __init alsa_card_opl3sa2_init(void) pnpc_registered = 1; cards += err; } +#endif if (!cards) { #ifdef MODULE diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 5fb981c0a281..29bba8cc3ef3 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -69,9 +69,9 @@ module_param_array(dma, int, NULL, 0444); MODULE_PARM_DESC(dma, "DMA # for SoundScape driver."); static struct platform_device *platform_devices[SNDRV_CARDS]; -static int pnp_registered; #ifdef CONFIG_PNP +static int pnp_registered; static struct pnp_card_device_id sscape_pnpids[] = { { .id = "ENS3081", .devs = { { "ENS0000" } } }, { .id = "" } /* end */ @@ -1391,8 +1391,10 @@ static void __init_or_module sscape_unregister_all(void) { int i; +#ifdef CONFIG_PNP if (pnp_registered) pnp_unregister_card_driver(&sscape_pnpc_driver); +#endif for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) platform_device_unregister(platform_devices[i]); platform_driver_unregister(&snd_sscape_driver); @@ -1466,8 +1468,10 @@ static int __init sscape_init(void) ret = sscape_manual_probe(); if (ret < 0) return ret; +#ifdef CONFIG_PNP if (pnp_register_card_driver(&sscape_pnpc_driver) >= 0) pnp_registered = 1; +#endif return 0; } diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index a6dcb2f970ca..fa3ab960de17 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -84,10 +84,9 @@ module_param_array(use_cs4232_midi, bool, NULL, 0444); MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)"); static struct platform_device *platform_devices[SNDRV_CARDS]; -static int pnp_registered; - #ifdef CONFIG_PNP +static int pnp_registered; static struct pnp_card_device_id snd_wavefront_pnpids[] = { /* Tropez */ @@ -695,8 +694,10 @@ static void __init_or_module snd_wavefront_unregister_all(void) { int i; +#ifdef CONFIG_PNP if (pnp_registered) pnp_unregister_card_driver(&wavefront_pnpc_driver); +#endif for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) platform_device_unregister(platform_devices[i]); platform_driver_unregister(&snd_wavefront_driver); @@ -725,11 +726,13 @@ static int __init alsa_card_wavefront_init(void) cards++; } +#ifdef CONFIG_PNP i = pnp_register_card_driver(&wavefront_pnpc_driver); if (i >= 0) { pnp_registered = 1; cards += i; } +#endif if (!cards) { #ifdef MODULE From 4d7d7596287588a953f450a3f18c5d4587f763d0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 4 Jan 2006 16:00:48 +0100 Subject: [PATCH 062/695] [ALSA] emu10k1 - Fix silence problems after suspend Modules: EMU10K1/EMU10K2 driver Fix silence problems on some boards after suspend/resume (bug#1674). Signed-off-by: Takashi Iwai --- sound/pci/emu10k1/emumixer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 2e86a901a0a4..8c912b1bee39 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -829,9 +829,9 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, } if (emu->audigy) { /* set master volume to 0 dB */ - snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000); + snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000); /* set capture source to mic */ - snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000); + snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000); c = audigy_remove_ctls; } else { /* @@ -844,8 +844,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); } /* remove unused AC97 controls */ - snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202); - snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202); + snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); + snd_ac97_write_cache(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202); c = emu10k1_remove_ctls; } for (; *c; c++) From 6421776a6f8b8503a88e07b205162842d3f7d702 Mon Sep 17 00:00:00 2001 From: Martin Drab Date: Thu, 5 Jan 2006 18:33:56 +0100 Subject: [PATCH 063/695] [ALSA] bt87x - Fix the unability of snd-bt87x to recognize AVerMedia Studio Modules: BT87x driver The patch siply adds the PCI IDs of AVerMedia Studio No. 103, 203, and possibly even other versions with the same PCI IDs to the snd-bt87x driver and sets its default sampling rate to 48 kHz. Signed-off-by: Martin Drab Signed-off-by: Takashi Iwai --- sound/pci/bt87x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index dc9cd3079b14..aaaa2e0d45c2 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = { BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), /* Viewcast Osprey 200 */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), + /* AVerMedia Studio No. 103, 203, ...? */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000), { } }; MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); From 7eae36fbd5ea9db3d3fe0d671199121be782a5b3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 5 Jan 2006 18:40:56 +0100 Subject: [PATCH 064/695] [ALSA] emu10k1 - Fix the confliction of 'Front' control Modules: EMU10K1/EMU10K2 driver Fix the confliction of 'Front' controls on models with STAC9758 codec. Signed-off-by: Takashi Iwai --- sound/pci/emu10k1/emumixer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 8c912b1bee39..2a9d12d10680 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -759,6 +759,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, "Master Mono Playback Volume", "PCM Out Path & Mute", "Mono Output Select", + "Front Playback Switch", + "Front Playback Volume", "Surround Playback Switch", "Surround Playback Volume", "Center Playback Switch", From d0bd41e289768ff851066f1e952ae4c802c4dca7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 9 Jan 2006 12:36:53 +0100 Subject: [PATCH 065/695] [ALSA] via82xx - Add dxs_support entry Modules: VIA82xx driver Added a dxs_support entry for Jetway K8M8MS. Signed-off-by: Takashi Iwai --- sound/pci/via82xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 9188a9f2315d..8664bc478b1e 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -2372,6 +2372,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */ { .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */ { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ + { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */ { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ { .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ From d99e98891ccde745c6c25b7a11a139123e74db4c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jan 2006 16:44:46 +0100 Subject: [PATCH 066/695] [ALSA] Remove BKL from sound/core/info.c Modules: ALSA Core Remove BKL from sound/core/info.c Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/core/info.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/sound/core/info.c b/sound/core/info.c index ae8853921464..af123e3bdb24 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -444,8 +444,8 @@ static unsigned int snd_info_entry_poll(struct file *file, poll_table * wait) return mask; } -static inline int _snd_info_entry_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long snd_info_entry_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { struct snd_info_private_data *data; struct snd_info_entry *entry; @@ -465,17 +465,6 @@ static inline int _snd_info_entry_ioctl(struct inode *inode, struct file *file, return -ENOTTY; } -/* FIXME: need to unlock BKL to allow preemption */ -static int snd_info_entry_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int err; - unlock_kernel(); - err = _snd_info_entry_ioctl(inode, file, cmd, arg); - lock_kernel(); - return err; -} - static int snd_info_entry_mmap(struct file *file, struct vm_area_struct *vma) { struct inode *inode = file->f_dentry->d_inode; @@ -499,15 +488,15 @@ static int snd_info_entry_mmap(struct file *file, struct vm_area_struct *vma) static struct file_operations snd_info_entry_operations = { - .owner = THIS_MODULE, - .llseek = snd_info_entry_llseek, - .read = snd_info_entry_read, - .write = snd_info_entry_write, - .poll = snd_info_entry_poll, - .ioctl = snd_info_entry_ioctl, - .mmap = snd_info_entry_mmap, - .open = snd_info_entry_open, - .release = snd_info_entry_release, + .owner = THIS_MODULE, + .llseek = snd_info_entry_llseek, + .read = snd_info_entry_read, + .write = snd_info_entry_write, + .poll = snd_info_entry_poll, + .unlocked_ioctl = snd_info_entry_ioctl, + .mmap = snd_info_entry_mmap, + .open = snd_info_entry_open, + .release = snd_info_entry_release, }; /** From be3cd57aa65c366e479d6a21a5d49a08117b5d77 Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Mon, 9 Jan 2006 21:20:56 +0100 Subject: [PATCH 067/695] [ALSA] snd-ca0106: Fixed ALSA bug#1600 Modules: CA0106 driver Description: Shuttle XPC SD11G5 which has an onboard Creative Labs Sound Blaster Live! 24-bit EAX high-definition 7.1 audio processor'. Fixes ALSA bug#1600 Signed-off-by: James Courtier-Dutton --- sound/pci/ca0106/ca0106_main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 6ed7c0bfa091..9477838a9c88 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -199,7 +199,8 @@ static struct snd_ca0106_details ca0106_chip_details[] = { .name = "MSI K8N Diamond MB [SB0438]", .gpio_type = 1, .i2c_adc = 1 } , - /* Shuttle XPC SD31P which has an onboard Creative Labs Sound Blaster Live! 24-bit EAX + /* Shuttle XPC SD31P which has an onboard Creative Labs + * Sound Blaster Live! 24-bit EAX * high-definition 7.1 audio processor". * Added using info from andrewvegan in alsa bug #1298 */ @@ -207,6 +208,15 @@ static struct snd_ca0106_details ca0106_chip_details[] = { .name = "Shuttle XPC SD31P [SD31P]", .gpio_type = 1, .i2c_adc = 1 } , + /* Shuttle XPC SD11G5 which has an onboard Creative Labs + * Sound Blaster Live! 24-bit EAX + * high-definition 7.1 audio processor". + * Fixes ALSA bug#1600 + */ + { .serial = 0x30411297, + .name = "Shuttle XPC SD11G5 [SD11G5]", + .gpio_type = 1, + .i2c_adc = 1 } , { .serial = 0, .name = "AudigyLS [Unknown]" } }; From d2981393615f9a7adb8223a2ab1e0d7423d5c9dd Mon Sep 17 00:00:00 2001 From: Jason Gaston Date: Tue, 10 Jan 2006 11:07:37 +0100 Subject: [PATCH 068/695] [ALSA] hda-intel - patch for Intel ICH8 Modules: HDA Intel driver This patch adds the Intel ICH8 HD Audio DID to the hda_intel.c audio driver. Signed-off-by: Jason Gaston Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a983deba4025..fd12b6991fe4 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -75,6 +75,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{Intel, ICH6M}," "{Intel, ICH7}," "{Intel, ESB2}," + "{Intel, ICH8}," "{ATI, SB450}," "{VIA, VT8251}," "{VIA, VT8237A}," @@ -1586,6 +1587,7 @@ static struct pci_device_id azx_ids[] = { { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH6 */ { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH7 */ { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */ + { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */ { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ From 8937fd88558d5a741d6ed29d5f8c327646a4f1db Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Jan 2006 11:14:49 +0100 Subject: [PATCH 069/695] [ALSA] pcxhr - Fix the sample rate changes Modules: Digigram PCXHR driver Fix the hardware set up when the sample rate is changed multiple times. Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index b8c0853a8278..57fe9538f5a4 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -744,13 +744,14 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs) /* only the first stream can choose the sample rate */ /* the further opened streams will be limited to its frequency (see open) */ /* set the clock only once (first stream) */ - if (mgr->sample_rate == 0) { + if (mgr->sample_rate != subs->runtime->rate) { err = pcxhr_set_clock(mgr, subs->runtime->rate); if (err) break; + if (mgr->sample_rate == 0) + /* start the DSP-timer */ + err = pcxhr_hardware_timer(mgr, 1); mgr->sample_rate = subs->runtime->rate; - - err = pcxhr_hardware_timer(mgr, 1); /* start the DSP-timer */ } } while(0); /* do only once (so we can use break instead of goto) */ From b14e77e613a104c78ab455c0109b566dab430de6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Jan 2006 18:10:50 +0100 Subject: [PATCH 070/695] [ALSA] hda-codec - Add model entry for Sony VAIO Modules: HDA Codec driver Added an ALC260 model entry (basic) for Sony VAIO. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ad9e501a9818..543980d89b83 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2945,6 +2945,8 @@ static int alc260_auto_init(struct hda_codec *codec) */ static struct hda_board_config alc260_cfg_tbl[] = { { .modelname = "basic", .config = ALC260_BASIC }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, + .config = ALC260_BASIC }, /* Sony VAIO */ { .modelname = "hp", .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, From 128a46a55da81e563116e99e08e295fda41a145b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Jan 2006 18:15:43 +0100 Subject: [PATCH 071/695] [ALSA] ac97 - Suppress jack sense controls for Thinkpads Modules: AC97 Codec Added a blacklist to suppress to create jack sense controls. These controls must be always off on some devices (e.g. Thinkpad). Signed-off-by: Takashi Iwai --- sound/pci/ac97/ac97_patch.c | 49 ++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 4aa5fdc5688e..bccce44421ec 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1621,8 +1621,27 @@ static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense[] = { AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0), }; +/* black list to avoid HP/Line jack-sense controls + * (SS vendor << 16 | device) + */ +static unsigned int ad1981_jacks_blacklist[] = { + 0x10140554, /* Thinkpad T42p/R50p */ + 0 /* end */ +}; + +static int check_list(struct snd_ac97 *ac97, const unsigned int *list) +{ + u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; + for (; *list; list++) + if (*list == subid) + return 1; + return 0; +} + static int patch_ad1981a_specific(struct snd_ac97 * ac97) { + if (check_list(ac97, ad1981_jacks_blacklist)) + return 0; return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense, ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); } @@ -1635,22 +1654,26 @@ static struct snd_ac97_build_ops patch_ad1981a_build_ops = { #endif }; +/* white list to enable HP jack-sense bits + * (SS vendor << 16 | device) + */ +static unsigned int ad1981_jacks_whitelist[] = { + 0x0e11005a, /* HP nc4000/4010 */ + 0x103c0890, /* HP nc6000 */ + 0x103c0938, /* HP nc4220 */ + 0x103c099c, /* HP nx6110 */ + 0x103c0944, /* HP nc6220 */ + 0x103c0934, /* HP nc8220 */ + 0x103c006d, /* HP nx9105 */ + 0x17340088, /* FSC Scenic-W */ + 0 /* end */ +}; + static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97) { - u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; - switch (subid) { - case 0x0e11005a: /* HP nc4000/4010 */ - case 0x103c0890: /* HP nc6000 */ - case 0x103c0938: /* HP nc4220 */ - case 0x103c099c: /* HP nx6110 */ - case 0x103c0944: /* HP nc6220 */ - case 0x103c0934: /* HP nc8220 */ - case 0x103c006d: /* HP nx9105 */ - case 0x17340088: /* FSC Scenic-W */ + if (check_list(ac97, ad1981_jacks_whitelist)) /* enable headphone jack sense */ snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); - break; - } } int patch_ad1981a(struct snd_ac97 *ac97) @@ -1672,6 +1695,8 @@ static int patch_ad1981b_specific(struct snd_ac97 *ac97) if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0) return err; + if (check_list(ac97, ad1981_jacks_blacklist)) + return 0; return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense, ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); } From 54c63cfc153c6909a5d5dbe6072e8704b091f30e Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 12 Jan 2006 07:56:40 +0100 Subject: [PATCH 072/695] [ALSA] bt87x - fix detection of unknown card Modules: BT87x driver Signed-off-by: Jaroslav Kysela --- sound/pci/bt87x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index aaaa2e0d45c2..c840a4c08e98 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -810,7 +810,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) const struct pci_device_id *supported; supported = pci_match_device(&driver, pci); - if (supported) + if (supported && supported->driver_data > 0) return supported->driver_data; for (i = 0; i < ARRAY_SIZE(blacklist); ++i) From 4b2849283461a64c6d8cc6c7e72c62d7b4d91b43 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 12 Jan 2006 08:17:49 +0100 Subject: [PATCH 073/695] [ALSA] usb-audio: don't use empty packets at start of playback Modules: USB generic driver Some widespread USB interface chips with adaptive iso endpoints hang after receiving a series of empty packets when they expect data (ALSA bug#1585). To avoid this, we have to send packets containing silence (zero samples) instead. Signed-off-by: Clemens Ladisch --- sound/usb/usbaudio.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index a1bd8040dea4..95729730bcdc 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -478,22 +478,38 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, /* * Prepare urb for streaming before playback starts. * - * We don't care about (or have) any data, so we just send a transfer delimiter. + * We don't yet have data, so we send a frame of silence. */ static int prepare_startup_playback_urb(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *urb) { - unsigned int i; + unsigned int i, offs, counts; struct snd_urb_ctx *ctx = urb->context; + int stride = runtime->frame_bits >> 3; + offs = 0; urb->dev = ctx->subs->dev; urb->number_of_packets = subs->packs_per_ms; for (i = 0; i < subs->packs_per_ms; ++i) { - urb->iso_frame_desc[i].offset = 0; - urb->iso_frame_desc[i].length = 0; + /* calculate the size of a packet */ + if (subs->fill_max) + counts = subs->maxframesize; /* fixed */ + else { + subs->phase = (subs->phase & 0xffff) + + (subs->freqm << subs->datainterval); + counts = subs->phase >> 16; + if (counts > subs->maxframesize) + counts = subs->maxframesize; + } + urb->iso_frame_desc[i].offset = offs * stride; + urb->iso_frame_desc[i].length = counts * stride; + offs += counts; } - urb->transfer_buffer_length = 0; + urb->transfer_buffer_length = offs * stride; + memset(urb->transfer_buffer, + subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0, + offs * stride); return 0; } From 363fa1d615d93fe047659c16ff3277d78302b2eb Mon Sep 17 00:00:00 2001 From: Rene Rebe Date: Thu, 12 Jan 2006 11:42:47 +0100 Subject: [PATCH 074/695] [ALSA] AMD cs5536 ID for cs5535audio Modules: CS5535 driver Added AMD CS5536 to the cs5535audio driver. Signed-off-by: Rene Rebe Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/pci/cs5535audio/cs5535audio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index f36ede827479..02e3721030b7 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c @@ -46,8 +46,10 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static struct pci_device_id snd_cs5535audio_ids[] = { - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO, PCI_ANY_ID, - PCI_ANY_ID, 0, 0, 0, }, + { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, {} }; From da79e44df4fff22c7f815687ea210b2324b3507c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Jan 2006 11:45:51 +0100 Subject: [PATCH 075/695] [ALSA] ac97 - Fix CLFE channel setting of ALC850 Modules: AC97 Codec Fix CLFE channel setting of ALC850 (ALSA bug#1731). Signed-off-by: Takashi Iwai --- sound/pci/ac97/ac97_patch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index bccce44421ec..a444a78c7c94 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -2235,9 +2235,9 @@ static void alc850_update_jacks(struct snd_ac97 *ac97) /* Vref disable (bit12), 1kOhm (bit13) */ snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13), shared ? (1<<12) : (1<<13)); - /* MIC-IN = 1, CENTER-LFE = 2 */ + /* MIC-IN = 1, CENTER-LFE = 5 */ snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4, - shared ? (2<<4) : (1<<4)); + shared ? (5<<4) : (1<<4)); } static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = { From fc80a2027afc31e8447a0691ea1279166ce5d69f Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 13 Jan 2006 07:41:45 +0100 Subject: [PATCH 076/695] [ALSA] ymfpci: fix SPDIF sample rate information Modules: YMFPCI driver Set the (read only) sample rate field in the IEC958 mixer controls to 48 kHz (instead of 44.1 kHz) because that is the rate actually supported by the hardware. Signed-off-by: Clemens Ladisch --- sound/pci/ymfpci/ymfpci_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 1dfc7233c6a8..a1aa74b79b3d 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -1229,6 +1229,7 @@ static int snd_ymfpci_spdif_default_get(struct snd_kcontrol *kcontrol, spin_lock_irq(&chip->reg_lock); ucontrol->value.iec958.status[0] = (chip->spdif_bits >> 0) & 0xff; ucontrol->value.iec958.status[1] = (chip->spdif_bits >> 8) & 0xff; + ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; spin_unlock_irq(&chip->reg_lock); return 0; } @@ -1303,6 +1304,7 @@ static int snd_ymfpci_spdif_stream_get(struct snd_kcontrol *kcontrol, spin_lock_irq(&chip->reg_lock); ucontrol->value.iec958.status[0] = (chip->spdif_pcm_bits >> 0) & 0xff; ucontrol->value.iec958.status[1] = (chip->spdif_pcm_bits >> 8) & 0xff; + ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; spin_unlock_irq(&chip->reg_lock); return 0; } From 33159378254b67d0080a8d63197e95654b672cf7 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 13 Jan 2006 08:11:22 +0100 Subject: [PATCH 077/695] [ALSA] usb-audio: fix non-48k sample rates with SB Audigy 2 ZS Modules: USB generic driver On the Audigy 2 ZS, disable all sample rate that are not a multiple of 48 kHz because the others work only with the digital output which is not yet supported. Signed-off-by: Clemens Ladisch --- sound/usb/usbaudio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 95729730bcdc..d5013383fad7 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -2493,12 +2493,13 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp if (err < 0) return err; #if 1 - /* FIXME: temporary hack for extigy/audigy 2 nx */ + /* FIXME: temporary hack for extigy/audigy 2 nx/zs */ /* extigy apparently supports sample rates other than 48k * but not in ordinary way. so we enable only 48k atm. */ if (chip->usb_id == USB_ID(0x041e, 0x3000) || - chip->usb_id == USB_ID(0x041e, 0x3020)) { + chip->usb_id == USB_ID(0x041e, 0x3020) || + chip->usb_id == USB_ID(0x041e, 0x3061)) { if (fmt[3] == USB_FORMAT_TYPE_I && fp->rates != SNDRV_PCM_RATE_48000 && fp->rates != SNDRV_PCM_RATE_96000) From e3183ec9cd98db7800d078768b1c9edc2fd0425f Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 13 Jan 2006 13:14:53 +0100 Subject: [PATCH 078/695] [ALSA] Prevent ALSA trident driver from grabbing pcnet32 hardware Modules: Trident driver Some pcnet32 hardware erroneously has the Vendor ID for Trident. The pcnet32 driver looks for the PCI ethernet class before grabbing the hardware, but the current trident driver does not check against the PCI audio class. This allows the trident driver to claim the pcnet32 hardware. This patch prevents that. Per Jiri Slaby's request, I changed the trident driver to use PCI_DEVICE macro and PCI ID #defines. This patch is untested on Trident 4DWAVE_DX hardware, but has been tested on pcnet32 hardware. Signed-off-by: Jon Mason Signed-off-by: Takashi Iwai --- sound/pci/trident/trident.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index 2b21df16ad6a..b4538045049f 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -64,9 +64,11 @@ module_param_array(wavetable_size, int, NULL, 0444); MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth."); static struct pci_device_id snd_trident_ids[] = { - { 0x1023, 0x2000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Trident 4DWave DX PCI Audio */ - { 0x1023, 0x2001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Trident 4DWave NX PCI Audio */ - { 0x1039, 0x7018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* SiS SI7018 PCI Audio */ + {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX), + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, + {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX), + 0, 0, 0}, + {PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018), 0, 0, 0}, { 0, } }; From ec6c8c3b2588261669c1b101338ab4fe43b1b9c0 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 13 Jan 2006 13:17:43 +0100 Subject: [PATCH 079/695] [ALSA] ali5451: Add PCI_DEVICE and #defines in snd_ali_ids Modules: ALI5451 driver This patch uses #defines for the Vendor ID and Device ID and uses the new PCI_DEVICE macro. Signed-off-by: Jon Mason Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/pci/ali5451/ali5451.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index bc4d1ef08efa..e264136e8fb4 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -279,7 +279,7 @@ struct snd_ali { }; static struct pci_device_id snd_ali_ids[] = { - {0x10b9, 0x5451, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, + {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0}, {0, } }; MODULE_DEVICE_TABLE(pci, snd_ali_ids); From c9fe51c492fbb0de789a16828749595dc1985610 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Fri, 13 Jan 2006 13:26:42 +0100 Subject: [PATCH 080/695] [ALSA] intel8x0: Add quirk for Optiplex GX270 Modules: Intel8x0 driver This patch adds a quirk entry for the Dell Optiplex GX270, on which the volume is set by the headphone control, not the master control. Signed-off-by: Chris Ball Signed-off-by: Takashi Iwai --- sound/pci/intel8x0.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 2fe2a8ae82ce..b345894659bb 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1803,6 +1803,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .name = "Dell", /* which model? AD1981B*/ .type = AC97_TUNE_HP_ONLY }, + { + .subvendor = 0x1028, + .subdevice = 0x0151, + .name = "Dell Optiplex GX270", /* AD1981B */ + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x1028, .subdevice = 0x0163, From 0fd1708a199bf55ebf21d611225866955babc1ba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 13 Jan 2006 18:46:21 +0100 Subject: [PATCH 081/695] [ALSA] hda-codec - Fix capture on Sigmatel STAC92xx codecs Modules: HDA Codec driver Added the missing 'Capture Switch' control for Sigmatel STAC92xx codecs. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 61903848cd43..4f78b58416a4 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -183,6 +183,7 @@ static struct snd_kcontrol_new stac922x_mixer[] = { .put = stac92xx_mux_enum_put, }, HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT), { } /* end */ }; From cacd3347ce5b5ee4fce90c2627d80bf0ac15dec0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Jan 2006 13:00:50 +0100 Subject: [PATCH 082/695] [ALSA] via82xx - Add dxs_support entry for EpoX 9HEAI Modules: VIA82xx driver Added the dxs_support entry for EpoX 9HEAI. Signed-off-by: Takashi Iwai --- sound/pci/via82xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 8664bc478b1e..d59fe3e83f17 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -2372,6 +2372,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */ { .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */ { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ + { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */ { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */ { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ { .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ From 7113d680d4824dfd4db43bc9880cdc98bcc309b9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Jan 2006 13:55:48 +0100 Subject: [PATCH 083/695] [ALSA] au88x0 - Fix a compile warning Modules: au88x0 driver Fixed an uninitialized variable. Signed-off-by: Takashi Iwai --- sound/pci/au88x0/au88x0_eq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c index 13bc8ed301c5..c8280f82eb5a 100644 --- a/sound/pci/au88x0/au88x0_eq.c +++ b/sound/pci/au88x0/au88x0_eq.c @@ -849,7 +849,7 @@ static int snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { vortex_t *vortex = snd_kcontrol_chip(kcontrol); - int i, count; + int i, count = 0; u16 peaks[20]; vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count); From 2f25b7feab257bae406f1edb44438a347a1cc727 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 17 Jan 2006 18:31:42 +0100 Subject: [PATCH 084/695] [ALSA] Fix a typo in snd_assert() Modules: CS46xx driver Reported by in http://bugzilla.kernel.org/show_bug.cgi?id=5903 Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/pci/cs46xx/dsp_spos_scb_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index 509aa2b63331..d4e0fb39bd06 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -675,7 +675,7 @@ cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name, if (pass_through) { /* wont work with any other rate than the native DSP rate */ - snd_assert (rate = 48000); + snd_assert (rate == 48000); scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb, dest,"DMAREADER",parent_scb, From 62af9905a1f809094f5209ae15d2ce69599a8123 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 20 Jan 2006 14:03:06 +0100 Subject: [PATCH 085/695] [ALSA] opl3sa2 - Fix conflict of driver name on sysfs Modules: OPL3SA2 driver Fix the conflict of driver name 'opl3sa2' on sysfs with OSS driver. Signed-off-by: Takashi Iwai --- sound/isa/opl3sa2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 84ffa8f0f26d..9dc6b20e9a5c 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -781,7 +781,7 @@ static int snd_opl3sa2_pnp_resume(struct pnp_dev *pdev) #endif static struct pnp_driver opl3sa2_pnp_driver = { - .name = "opl3sa2-pnpbios", + .name = "snd-opl3sa2-pnpbios", .id_table = snd_opl3sa2_pnpbiosids, .probe = snd_opl3sa2_pnp_detect, .remove = __devexit_p(snd_opl3sa2_pnp_remove), @@ -848,7 +848,7 @@ static int snd_opl3sa2_pnp_cresume(struct pnp_card_link *pcard) static struct pnp_card_driver opl3sa2_pnpc_driver = { .flags = PNP_DRIVER_RES_DISABLE, - .name = "opl3sa2", + .name = "snd-opl3sa2-cpnp", .id_table = snd_opl3sa2_pnpids, .probe = snd_opl3sa2_pnp_cdetect, .remove = __devexit_p(snd_opl3sa2_pnp_cremove), From 80faf041cd731bde220523166f016377e1765acd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 20 Jan 2006 14:03:39 +0100 Subject: [PATCH 086/695] [ALSA] sb16 - Fix duplicated PnP entry Modules: SB16/AWE driver Fix the duplicated PnP entry between sb16 and sbawe drivers. Signed-off-by: Takashi Iwai --- sound/isa/sb/sb16.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index c0be7a5a3425..0667bd14ad60 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -179,6 +179,8 @@ static struct pnp_card_device_id snd_sb16_pnpids[] = { { .id = "CTL0086", .devs = { { "CTL0041" } } }, /* Sound Blaster Vibra16X */ { .id = "CTL00f0", .devs = { { "CTL0043" } } }, + /* Sound Blaster 16 (Virtual PC 2004) */ + { .id = "tBA03b0", .devs = { {.id="PNPb003" } } }, #else /* SNDRV_SBAWE defined */ /* Sound Blaster AWE 32 PnP */ { .id = "CTL0035", .devs = { { "CTL0031" }, { "CTL0021" } } }, @@ -235,8 +237,6 @@ static struct pnp_card_device_id snd_sb16_pnpids[] = { { .id = "CTLXXXX" , .devs = { { "CTL0044" }, { "CTL0023" } } }, { .id = "CTLXXXX" , .devs = { { "CTL0045" }, { "CTL0022" } } }, #endif /* SNDRV_SBAWE */ - /* Sound Blaster 16 PnP (Virtual PC 2004)*/ - { .id = "tBA03b0", .devs = { { "PNPb003" } } }, { .id = "", } }; From e2eba3e7d911b26525c17f0b7e2bc45aad8e2629 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 20 Jan 2006 14:07:13 +0100 Subject: [PATCH 087/695] [ALSA] hdsp - Fix printk warnings Modules: RME9652 driver sound/pci/rme9652/hdspm.c: In function 'snd_hdspm_preallocate_memory': sound/pci/rme9652/hdspm.c:3327: warning: int format, different type arg (arg 4) sound/pci/rme9652/hdspm.c:3331: warning: int format, different type arg (arg 4) sound/pci/rme9652/hdspm.c: In function 'snd_hdspm_create': sound/pci/rme9652/hdspm.c:3513: warning: int format, different type arg (arg 4) Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 3dec616bad6b..103b4d715ff4 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -3324,11 +3324,11 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) snd_dma_pci_data(hdspm->pci), wanted, wanted)) < 0) { - snd_printdd("Could not preallocate %d Bytes\n", wanted); + snd_printdd("Could not preallocate %zd Bytes\n", wanted); return err; } else - snd_printdd(" Preallocated %d Bytes\n", wanted); + snd_printdd(" Preallocated %zd Bytes\n", wanted); return 0; } @@ -3510,7 +3510,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp hdspm->monitor_outs = enable_monitor; - snd_printdd("kmalloc Mixer memory of %d Bytes\n", + snd_printdd("kmalloc Mixer memory of %zd Bytes\n", sizeof(struct hdspm_mixer)); if ((hdspm->mixer = kmalloc(sizeof(struct hdspm_mixer), GFP_KERNEL)) == NULL) { From 20cd22620ad3a8a57a942fa1f301d47a1e15d67e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 20 Jan 2006 14:07:47 +0100 Subject: [PATCH 088/695] [ALSA] pcxhr - Fix printk warning Modules: Digigram PCXHR driver sound/pci/pcxhr/pcxhr.c: In function 'pcxhr_update_r_buffer': sound/pci/pcxhr/pcxhr.c:460: warning: unsigned int format, different type arg (arg 7) Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 57fe9538f5a4..b2cba75b6b16 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -454,7 +454,7 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream) is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE); stream_num = is_capture ? 0 : subs->number; - snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%x) subs(%d)\n", + snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n", is_capture ? 'c' : 'p', chip->chip_idx, (void*)subs->runtime->dma_addr, subs->runtime->dma_bytes, subs->number); From 168a95f170070ddda1ba7505c2ce9ae8b50f21f6 Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Fri, 20 Jan 2006 14:44:41 +0100 Subject: [PATCH 089/695] [ALSA] sound/ppc/pmac.c typo Modules: PPC PMAC driver In 2.6.16-rc1 there is a small typo introduced by the 'Remove device_node addrs/n_addr' changes which prevents my Powerbook G4 sound from working: Advanced Linux Sound Architecture Driver Version 1.0.11rc2 (Wed Jan 04 08:57:20 2006 UTC). snd: can't request rsrc 0 (Sound Control: 0x80000000:80004fff) ALSA device list: No soundcards found. The patch below fixes it. Of course, the patch fixing the i2c issues ('i2c_smbus_write_i2c_block_data' patch) needs to be applied to in order for the sound to completly work. Signed-off-by: Stelian Pop Signed-off-by: Takashi Iwai --- sound/ppc/pmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index a642e4cfcf45..4988f873a7ba 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -1216,7 +1216,7 @@ int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) goto __error; } for (i = 0; i < 3; i ++) { - if (of_address_to_resource(np->parent, i, + if (of_address_to_resource(np, i, &chip->rsrc[i])) { printk(KERN_ERR "snd: can't translate rsrc " " %d (%s)\n", i, rnames[i]); From ec80859ed292a55334df68fc2492f1303cf3a0ac Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 22 Jan 2006 09:28:15 +0100 Subject: [PATCH 090/695] [ALSA] cs4232/cs4236 - moved CS423X_DRIVER define outside CONFIG_PNP Modules: CS4236+ driver Signed-off-by: Jaroslav Kysela --- sound/isa/cs423x/cs4236.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 2bfa68b01fe4..edf9279bf9d9 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -75,8 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235}," #ifdef CS4232 #define IDENT "CS4232" +#define CS423X_DRIVER "snd_cs4232" #else #define IDENT "CS4236+" +#define CS423X_DRIVER "snd_cs4236" #endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ @@ -160,7 +162,6 @@ MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpbiosids); #endif /* CS4232 */ #ifdef CS4232 -#define CS423X_DRIVER "snd_cs4232" #define CS423X_ISAPNP_DRIVER "cs4232_isapnp" static struct pnp_card_device_id snd_cs423x_pnpids[] = { /* Philips PCA70PS */ @@ -181,7 +182,6 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = { { .id = "" } /* end */ }; #else /* CS4236 */ -#define CS423X_DRIVER "snd_cs4236" #define CS423X_ISAPNP_DRIVER "cs4236_isapnp" static struct pnp_card_device_id snd_cs423x_pnpids[] = { /* Intel Marlin Spike Motherboard - CS4235 */ From d1d051b28e9d3c3bed0bd15a2b49df3d04f7768f Mon Sep 17 00:00:00 2001 From: Adam Belay Date: Fri, 20 Jan 2006 09:29:27 +0100 Subject: [PATCH 091/695] [ALSA] check return code in pnp_register_card_driver() Signed-off-by: Adam Belay Signed-off-by: Takashi Iwai --- drivers/pnp/card.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index 0ecbe4edbec1..aaa568a3806e 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -363,7 +363,7 @@ static int card_resume(struct pnp_dev *dev) int pnp_register_card_driver(struct pnp_card_driver * drv) { - int count = 0; + int count; struct list_head *pos, *temp; drv->link.name = drv->name; @@ -374,10 +374,15 @@ int pnp_register_card_driver(struct pnp_card_driver * drv) drv->link.suspend = drv->suspend ? card_suspend : NULL; drv->link.resume = drv->resume ? card_resume : NULL; + count = pnp_register_driver(&drv->link); + if (count < 0) + return count; + spin_lock(&pnp_lock); list_add_tail(&drv->global_list, &pnp_card_drivers); spin_unlock(&pnp_lock); - pnp_register_driver(&drv->link); + + count = 0; list_for_each_safe(pos,temp,&pnp_cards){ struct pnp_card *card = list_entry(pos, struct pnp_card, global_list); From a1c744439591b1d4350f0926615d501e7cfbb708 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 17 Jan 2006 11:05:35 -0700 Subject: [PATCH 092/695] [PARISC] Update b180_defconfig Update b180_defconfig to be more usable on other similar machines. Enabling Lasi 82596, Harmony, Mux console, CCIO, HPPB, etc., means this config is suitable for not only BXXX machines, but also CXXX and JXXX class machines. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/configs/b180_defconfig | 182 +++++++++++++++++++++++------ 1 file changed, 146 insertions(+), 36 deletions(-) diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig index 8819e7e6ae3f..37e98241ce4b 100644 --- a/arch/parisc/configs/b180_defconfig +++ b/arch/parisc/configs/b180_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.14-rc5-pa1 -# Fri Oct 21 23:06:10 2005 +# Linux kernel version: 2.6.16-rc1-pa0 +# Tue Jan 17 08:21:01 2006 # CONFIG_PARISC=y CONFIG_MMU=y @@ -29,8 +29,6 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" @@ -38,8 +36,10 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y +CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -48,8 +48,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -57,9 +59,27 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_KMOD is not set +# +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + # # Processor type and features # @@ -77,6 +97,7 @@ CONFIG_HZ=250 CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 # CONFIG_PREEMPT is not set # CONFIG_HPUX is not set @@ -84,8 +105,8 @@ CONFIG_FLAT_NODE_MEM_MAP=y # Bus options (PCI, PCMCIA, EISA, GSC, ISA) # CONFIG_GSC=y -# CONFIG_HPPB is not set -# CONFIG_IOMMU_CCIO is not set +CONFIG_HPPB=y +CONFIG_IOMMU_CCIO=y CONFIG_GSC_LASI=y CONFIG_GSC_WAX=y CONFIG_EISA=y @@ -165,8 +186,11 @@ CONFIG_IPV6=y # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -205,6 +229,7 @@ CONFIG_STANDALONE=y CONFIG_PARPORT=y CONFIG_PARPORT_PC=y # CONFIG_PARPORT_SERIAL is not set +CONFIG_PARPORT_NOT_PC=y CONFIG_PARPORT_GSC=y # CONFIG_PARPORT_1284 is not set @@ -230,14 +255,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_CDROM_PKTCDVD=m CONFIG_CDROM_PKTCDVD_BUFFERS=8 # CONFIG_CDROM_PKTCDVD_WCACHE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y CONFIG_ATA_OVER_ETH=y # @@ -281,6 +298,7 @@ CONFIG_SCSI_SPI_ATTRS=y # # SCSI low-level drivers # +# CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set @@ -313,21 +331,19 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +CONFIG_SCSI_SYM53C8XX_MMIO=y # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_ZALON is not set +CONFIG_SCSI_ZALON=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=40 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set @@ -397,7 +413,7 @@ CONFIG_NETDEVICES=y # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set -# CONFIG_LASI_82596 is not set +CONFIG_LASI_82596=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set @@ -464,6 +480,7 @@ CONFIG_NET_RADIO=y # Wireless 802.11b ISA/PCI cards support # # CONFIG_HERMES is not set +# CONFIG_ATMEL is not set # # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support @@ -527,7 +544,7 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_HIL_OLD is not set -# CONFIG_KEYBOARD_HIL is not set +CONFIG_KEYBOARD_HIL=y CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set @@ -535,7 +552,7 @@ CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_LOGIBM is not set # CONFIG_MOUSE_PC110PAD is not set # CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_MOUSE_HIL is not set +CONFIG_MOUSE_HIL=y # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y @@ -549,7 +566,8 @@ CONFIG_SERIO=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_PARKBD is not set CONFIG_SERIO_GSCPS2=y -# CONFIG_HP_SDC is not set +CONFIG_HP_SDC=y +CONFIG_HIL_MLC=y # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set @@ -569,6 +587,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=13 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y @@ -582,11 +601,10 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # # Non-8250 serial port support # -# CONFIG_SERIAL_MUX is not set -# CONFIG_PDC_CONSOLE is not set +CONFIG_SERIAL_MUX=y +CONFIG_SERIAL_MUX_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -625,6 +643,12 @@ CONFIG_GEN_RTC=y # # CONFIG_I2C is not set +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + # # Dallas's 1-wire bus # @@ -661,7 +685,6 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set @@ -671,6 +694,7 @@ CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_STI=y +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -683,9 +707,7 @@ CONFIG_FB_STI=y # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_CYBLA is not set # CONFIG_FB_TRIDENT is not set -# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -695,6 +717,7 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 CONFIG_DUMMY_CONSOLE_ROWS=64 CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_STI_CONSOLE=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y @@ -713,7 +736,85 @@ CONFIG_LOGO_PARISC_CLUT224=y # # Sound # -# CONFIG_SOUND is not set +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# GSC devices +# +CONFIG_SND_HARMONY=y + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set # # USB support @@ -722,6 +823,10 @@ CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_USB is not set +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + # # USB Gadget Support # @@ -877,18 +982,23 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_IOREMAP is not set # CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_DEBUG_RODATA is not set # # Security options From cb6fc18e9ca615f03d18e60c49855b434ca2e51e Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 17 Jan 2006 12:40:40 -0700 Subject: [PATCH 093/695] [PARISC] Use kzalloc and other janitor-style cleanups Helge, o Convert a bunch of kmalloc/memset uses to kzalloc. o pci.c: Add some __read_mostly annotations. o pci.c: Move constant pci_post_reset_delay to asm/pci.h o grfioctl.h: Add A4450A to comment of CRT_ID_VISUALIZE_EG. o Add some consts to perf.c/perf_images.h Matthew, o sticore.c: Add some consts to suppress compile warnings. Signed-off-by: Helge Deller Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/kernel/drivers.c | 3 +-- arch/parisc/kernel/pci.c | 11 ++++---- arch/parisc/kernel/perf.c | 35 +++++++++++++------------ arch/parisc/kernel/perf_images.h | 4 +-- arch/parisc/kernel/traps.c | 3 +-- drivers/parisc/ccio-dma.c | 7 +++-- drivers/parisc/dino.c | 4 +-- drivers/parisc/hppb.c | 3 +-- drivers/parisc/iosapic.c | 8 ++---- drivers/parisc/lasi.c | 2 +- drivers/parisc/lba_pci.c | 6 ++--- drivers/parisc/sba_iommu.c | 3 +-- drivers/parisc/wax.c | 2 +- drivers/parport/parport_gsc.c | 2 +- drivers/video/console/sticore.c | 45 ++++++++++++++------------------ include/asm-parisc/grfioctl.h | 2 +- include/asm-parisc/pci.h | 15 +++++++++-- 17 files changed, 73 insertions(+), 82 deletions(-) diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 2d804e2d16d1..3d569a485a1a 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -408,11 +408,10 @@ static void setup_bus_id(struct parisc_device *padev) struct parisc_device * create_tree_node(char id, struct device *parent) { - struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL); + struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; - memset(dev, 0, sizeof(*dev)); dev->hw_path = id; dev->id.hw_type = HPHW_FAULTY; diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 88cba49c5301..3a7dda860336 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -47,18 +47,17 @@ * this makes the boot time much longer than necessary. * 20ms seems to work for all the HP PCI implementations to date. * - * XXX: turn into a #defined constant in ? + * #define pci_post_reset_delay 50 */ -int pci_post_reset_delay = 50; -struct pci_port_ops *pci_port; -struct pci_bios_ops *pci_bios; +struct pci_port_ops *pci_port __read_mostly; +struct pci_bios_ops *pci_bios __read_mostly; -int pci_hba_count = 0; +static int pci_hba_count __read_mostly; /* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data. */ #define PCI_HBA_MAX 32 -struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX]; +struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX] __read_mostly; /******************************************************************** diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index 11d406cd0b3e..11178ccbb89a 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -68,20 +68,20 @@ struct rdr_tbl_ent { }; static int perf_processor_interface __read_mostly = UNKNOWN_INTF; -static int perf_enabled __read_mostly = 0; +static int perf_enabled __read_mostly; static spinlock_t perf_lock; -struct parisc_device *cpu_device __read_mostly = NULL; +struct parisc_device *cpu_device __read_mostly; /* RDRs to write for PCX-W */ -static int perf_rdrs_W[] = +static const int perf_rdrs_W[] = { 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 }; /* RDRs to write for PCX-U */ -static int perf_rdrs_U[] = +static const int perf_rdrs_U[] = { 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 }; /* RDR register descriptions for PCX-W */ -static struct rdr_tbl_ent perf_rdr_tbl_W[] = { +static const struct rdr_tbl_ent perf_rdr_tbl_W[] = { { 19, 1, 8 }, /* RDR 0 */ { 16, 1, 16 }, /* RDR 1 */ { 72, 2, 0 }, /* RDR 2 */ @@ -117,7 +117,7 @@ static struct rdr_tbl_ent perf_rdr_tbl_W[] = { }; /* RDR register descriptions for PCX-U */ -static struct rdr_tbl_ent perf_rdr_tbl_U[] = { +static const struct rdr_tbl_ent perf_rdr_tbl_U[] = { { 19, 1, 8 }, /* RDR 0 */ { 32, 1, 16 }, /* RDR 1 */ { 20, 1, 0 }, /* RDR 2 */ @@ -156,7 +156,7 @@ static struct rdr_tbl_ent perf_rdr_tbl_U[] = { * A non-zero write_control in the above tables is a byte offset into * this array. */ -static uint64_t perf_bitmasks[] = { +static const uint64_t perf_bitmasks[] = { 0x0000000000000000ul, /* first dbl word must be zero */ 0xfdffe00000000000ul, /* RDR0 bitmask */ 0x003f000000000000ul, /* RDR1 bitmask */ @@ -173,7 +173,7 @@ static uint64_t perf_bitmasks[] = { * Write control bitmasks for Pa-8700 processor given * somethings have changed slightly. */ -static uint64_t perf_bitmasks_piranha[] = { +static const uint64_t perf_bitmasks_piranha[] = { 0x0000000000000000ul, /* first dbl word must be zero */ 0xfdffe00000000000ul, /* RDR0 bitmask */ 0x003f000000000000ul, /* RDR1 bitmask */ @@ -186,7 +186,7 @@ static uint64_t perf_bitmasks_piranha[] = { 0xfffc000000000000ul }; -static uint64_t *bitmask_array; /* array of bitmasks to use */ +static const uint64_t *bitmask_array; /* array of bitmasks to use */ /****************************************************************************** * Function Prototypes @@ -200,7 +200,7 @@ static ssize_t perf_write(struct file *file, const char __user *buf, size_t coun static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static void perf_start_counters(void); static int perf_stop_counters(uint32_t *raddr); -static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num); +static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num); static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer); static int perf_rdr_clear(uint32_t rdr_num); static int perf_write_image(uint64_t *memaddr); @@ -655,7 +655,7 @@ static int perf_stop_counters(uint32_t *raddr) * Retrieve a pointer to the description of what this * RDR contains. */ -static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num) +static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num) { if (perf_processor_interface == ONYX_INTF) { return &perf_rdr_tbl_U[rdr_num]; @@ -673,7 +673,7 @@ static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer) { uint64_t data, data_mask = 0; uint32_t width, xbits, i; - struct rdr_tbl_ent *tentry; + const struct rdr_tbl_ent *tentry; tentry = perf_rdr_get_entry(rdr_num); if ((width = tentry->width) == 0) @@ -721,7 +721,7 @@ static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer) */ static int perf_rdr_clear(uint32_t rdr_num) { - struct rdr_tbl_ent *tentry; + const struct rdr_tbl_ent *tentry; int32_t i; tentry = perf_rdr_get_entry(rdr_num); @@ -753,10 +753,11 @@ static int perf_write_image(uint64_t *memaddr) uint64_t buffer[MAX_RDR_WORDS]; uint64_t *bptr; uint32_t dwords; - uint32_t *intrigue_rdr; - uint64_t *intrigue_bitmask, tmp64; + const uint32_t *intrigue_rdr; + const uint64_t *intrigue_bitmask; + uint64_t tmp64; void __iomem *runway; - struct rdr_tbl_ent *tentry; + const struct rdr_tbl_ent *tentry; int i; /* Clear out counters */ @@ -830,7 +831,7 @@ static int perf_write_image(uint64_t *memaddr) */ static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer) { - struct rdr_tbl_ent *tentry; + const struct rdr_tbl_ent *tentry; int32_t i; printk("perf_rdr_write\n"); diff --git a/arch/parisc/kernel/perf_images.h b/arch/parisc/kernel/perf_images.h index d9562fe3f75c..7fef9644df47 100644 --- a/arch/parisc/kernel/perf_images.h +++ b/arch/parisc/kernel/perf_images.h @@ -25,7 +25,7 @@ #define PCXU_IMAGE_SIZE 584 -static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = { +static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = { /* * CPI: * @@ -2093,7 +2093,7 @@ static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = { }; #define PCXW_IMAGE_SIZE 576 -static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] = { +static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = { /* * CPI: FROM CPI.IDF (Image 0) * diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 15914f0235a0..ff200608c851 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -193,10 +193,9 @@ void show_stack(struct task_struct *task, unsigned long *s) HERE: asm volatile ("copy %%r30, %0" : "=r"(sp)); - r = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL); + r = kzalloc(sizeof(struct pt_regs), GFP_KERNEL); if (!r) return; - memset(r, 0, sizeof(struct pt_regs)); r->iaoq[0] = (unsigned long)&&HERE; r->gr[2] = (unsigned long)__builtin_return_address(0); r->gr[30] = sp; diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 9e0229f7e25f..f46e8438e0d2 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -1423,7 +1423,7 @@ static void __init ccio_init_resources(struct ioc *ioc) struct resource *res = ioc->mmio_region; char *name = kmalloc(14, GFP_KERNEL); - sprintf(name, "GSC Bus [%d/]", ioc->hw_path); + snprintf(name, 14, "GSC Bus [%d/]", ioc->hw_path); ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); @@ -1557,12 +1557,11 @@ static int ccio_probe(struct parisc_device *dev) int i; struct ioc *ioc, **ioc_p = &ioc_list; - ioc = kmalloc(sizeof(struct ioc), GFP_KERNEL); + ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL); if (ioc == NULL) { printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); return 1; } - memset(ioc, 0, sizeof(struct ioc)); ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; @@ -1578,7 +1577,7 @@ static int ccio_probe(struct parisc_device *dev) ccio_ioc_init(ioc); ccio_init_resources(ioc); hppa_dma_ops = &ccio_ops; - dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL); + dev->dev.platform_data = kzalloc(sizeof(struct pci_hba_data), GFP_KERNEL); /* if this fails, no I/O cards will work, so may as well bug */ BUG_ON(dev->dev.platform_data == NULL); diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 216d1d859326..3d1a7f98c676 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -989,14 +989,12 @@ static int __init dino_probe(struct parisc_device *dev) */ } - dino_dev = kmalloc(sizeof(struct dino_device), GFP_KERNEL); + dino_dev = kzalloc(sizeof(struct dino_device), GFP_KERNEL); if (!dino_dev) { printk("dino_init_chip - couldn't alloc dino_device\n"); return 1; } - memset(dino_dev, 0, sizeof(struct dino_device)); - dino_dev->hba.dev = dev; dino_dev->hba.base_addr = ioremap(hpa, 4096); dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 5edf93f80757..07dc2b6d4e93 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c @@ -60,12 +60,11 @@ static int hppb_probe(struct parisc_device *dev) } if(card->hpa) { - card->next = kmalloc(sizeof(struct hppb_card), GFP_KERNEL); + card->next = kzalloc(sizeof(struct hppb_card), GFP_KERNEL); if(!card->next) { printk(KERN_ERR "HP-PB: Unable to allocate memory.\n"); return 1; } - memset(card->next, '\0', sizeof(struct hppb_card)); card = card->next; } printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 19657efa8dc3..8d7a36392eb8 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -873,28 +873,24 @@ void *iosapic_register(unsigned long hpa) return NULL; } - isi = (struct iosapic_info *)kmalloc(sizeof(struct iosapic_info), GFP_KERNEL); + isi = (struct iosapic_info *)kzalloc(sizeof(struct iosapic_info), GFP_KERNEL); if (!isi) { BUG(); return NULL; } - memset(isi, 0, sizeof(struct iosapic_info)); - isi->addr = ioremap(hpa, 4096); isi->isi_hpa = hpa; isi->isi_version = iosapic_rd_version(isi); isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; vip = isi->isi_vector = (struct vector_info *) - kmalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); + kzalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); if (vip == NULL) { kfree(isi); return NULL; } - memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors); - for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) { vip->irqline = (unsigned char) cnt; vip->iosapic = isi; diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index 2b3ba1dcf332..d043a8a33511 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c @@ -170,7 +170,7 @@ lasi_init_chip(struct parisc_device *dev) struct gsc_irq gsc_irq; int ret; - lasi = kmalloc(sizeof(*lasi), GFP_KERNEL); + lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); if (!lasi) return -ENOMEM; diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index cbae8c8963fa..e8a2a4a852f5 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1565,7 +1565,7 @@ lba_driver_probe(struct parisc_device *dev) } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { func_class &= 0xff; version = kmalloc(6, GFP_KERNEL); - sprintf(version,"TR%d.%d",(func_class >> 4),(func_class & 0xf)); + snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf)); /* We could use one printk for both Elroy and Mercury, * but for the mask for func_class. */ @@ -1586,14 +1586,12 @@ lba_driver_probe(struct parisc_device *dev) ** have an IRT entry will get NULL back from iosapic code. */ - lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL); + lba_dev = kzalloc(sizeof(struct lba_device), GFP_KERNEL); if (!lba_dev) { printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n"); return(1); } - memset(lba_dev, 0, sizeof(struct lba_device)); - /* ---------- First : initialize data we already have --------- */ diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index c85653f315aa..52f265e97729 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -2064,14 +2064,13 @@ sba_driver_callback(struct parisc_device *dev) printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME, version, dev->hpa.start); - sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL); + sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL); if (!sba_dev) { printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); return -ENOMEM; } parisc_set_drvdata(dev, sba_dev); - memset(sba_dev, 0, sizeof(struct sba_device)); for(i=0; iioc[i].res_lock)); diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c index 17dce2adf7fe..813c2c24ab1e 100644 --- a/drivers/parisc/wax.c +++ b/drivers/parisc/wax.c @@ -76,7 +76,7 @@ wax_init_chip(struct parisc_device *dev) struct gsc_irq gsc_irq; int ret; - wax = kmalloc(sizeof(*wax), GFP_KERNEL); + wax = kzalloc(sizeof(*wax), GFP_KERNEL); if (!wax) return -ENOMEM; diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index fde29a75f888..1de52d9febf9 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c @@ -249,7 +249,7 @@ struct parport *__devinit parport_gsc_probe_port (unsigned long base, struct parport tmp; struct parport *p = &tmp; - priv = kmalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); + priv = kzalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); if (!priv) { printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); return NULL; diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index a7bcd17112c0..0339f5640a78 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -30,10 +30,11 @@ #define STI_DRIVERVERSION "Version 0.9a" -struct sti_struct *default_sti; +struct sti_struct *default_sti __read_mostly; -static int num_sti_roms; /* # of STI ROMS found */ -static struct sti_struct *sti_roms[MAX_STI_ROMS]; /* ptr to each sti_struct */ +/* number of STI ROMS found and their ptrs to each struct */ +static int num_sti_roms __read_mostly; +static struct sti_struct *sti_roms[MAX_STI_ROMS] __read_mostly; /* The colour indices used by STI are @@ -266,7 +267,7 @@ sti_rom_copy(unsigned long base, unsigned long count, void *dest) -static char default_sti_path[21]; +static char default_sti_path[21] __read_mostly; #ifndef MODULE static int __init sti_setup(char *str) @@ -414,10 +415,10 @@ sti_init_glob_cfg(struct sti_struct *sti, if (!sti->sti_mem_request) sti->sti_mem_request = 256; /* STI default */ - glob_cfg = kmalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); - glob_cfg_ext = kmalloc(sizeof(*glob_cfg_ext), GFP_KERNEL); - save_addr = kmalloc(save_addr_size, GFP_KERNEL); - sti_mem_addr = kmalloc(sti->sti_mem_request, GFP_KERNEL); + glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); + glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL); + save_addr = kzalloc(save_addr_size, GFP_KERNEL); + sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL); if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { kfree(glob_cfg); @@ -427,11 +428,6 @@ sti_init_glob_cfg(struct sti_struct *sti, return -ENOMEM; } - memset(glob_cfg, 0, sizeof(*glob_cfg)); - memset(glob_cfg_ext, 0, sizeof(*glob_cfg_ext)); - memset(save_addr, 0, save_addr_size); - memset(sti_mem_addr, 0, sti->sti_mem_request); - glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext); glob_cfg->save_addr = STI_PTR(save_addr); for (i=0; i<8; i++) { @@ -502,9 +498,9 @@ sti_init_glob_cfg(struct sti_struct *sti, #ifdef CONFIG_FB struct sti_cooked_font * __init -sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) +sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) { - struct font_desc *fbfont; + const struct font_desc *fbfont; unsigned int size, bpc; void *dest; struct sti_rom_font *nf; @@ -525,10 +521,9 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) size = bpc * 256; size += sizeof(struct sti_rom_font); - nf = kmalloc(size, GFP_KERNEL); + nf = kzalloc(size, GFP_KERNEL); if (!nf) return NULL; - memset(nf, 0, size); nf->first_char = 0; nf->last_char = 255; @@ -544,7 +539,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) dest += sizeof(struct sti_rom_font); memcpy(dest, fbfont->data, bpc*256); - cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); + cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); if (!cooked_font) { kfree(nf); return NULL; @@ -559,7 +554,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) } #else struct sti_cooked_font * __init -sti_select_fbfont(struct sti_cooked_rom *cooked_rom, char *fbfont_name) +sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) { return NULL; } @@ -617,7 +612,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom, struct sti_rom_font *raw_font, *font_start; struct sti_cooked_font *cooked_font; - cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); + cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); if (!cooked_font) return 0; @@ -631,7 +626,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom, while (raw_font->next_font) { raw_font = ((void *)font_start) + (raw_font->next_font); - cooked_font->next_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); + cooked_font->next_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); if (!cooked_font->next_font) return 1; @@ -668,10 +663,9 @@ sti_bmode_font_raw(struct sti_cooked_font *f) unsigned char *n, *p, *q; int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); - n = kmalloc (4*size, GFP_KERNEL); + n = kzalloc (4*size, GFP_KERNEL); if (!n) return NULL; - memset (n, 0, 4*size); p = n + 3; q = (unsigned char *)f->raw; while (size--) { @@ -816,13 +810,12 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd return NULL; } - sti = kmalloc(sizeof(*sti), GFP_KERNEL); + sti = kzalloc(sizeof(*sti), GFP_KERNEL); if (!sti) { printk(KERN_ERR "Not enough memory !\n"); return NULL; } - memset(sti, 0, sizeof(*sti)); spin_lock_init(&sti->lock); test_rom: @@ -1035,7 +1028,7 @@ static struct parisc_driver pa_sti_driver = { * sti_init_roms() - detects all STI ROMs and stores them in sti_roms[] */ -static int sticore_initialized; +static int sticore_initialized __read_mostly; static void __init sti_init_roms(void) { diff --git a/include/asm-parisc/grfioctl.h b/include/asm-parisc/grfioctl.h index 6a910311b56b..671e06042b40 100644 --- a/include/asm-parisc/grfioctl.h +++ b/include/asm-parisc/grfioctl.h @@ -58,7 +58,7 @@ #define CRT_ID_ELK_1024DB 0x27849CA5 /* Elk 1024x768 double buffer */ #define CRT_ID_ELK_GS S9000_ID_A1924A /* Elk 1280x1024 GreyScale */ #define CRT_ID_CRX24 S9000_ID_A1439A /* Piranha */ -#define CRT_ID_VISUALIZE_EG 0x2D08C0A7 /* Graffiti (built-in B132+/B160L) */ +#define CRT_ID_VISUALIZE_EG 0x2D08C0A7 /* Graffiti, A4450A (built-in B132+/B160L) */ #define CRT_ID_THUNDER 0x2F23E5FC /* Thunder 1 VISUALIZE 48*/ #define CRT_ID_THUNDER2 0x2F8D570E /* Thunder 2 VISUALIZE 48 XP*/ #define CRT_ID_HCRX S9000_ID_HCRX /* Hyperdrive HCRX */ diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index f277254159b7..4c5e15ea3a02 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -18,6 +18,18 @@ */ #define PCI_MAX_BUSSES 256 + +/* To be used as: mdelay(pci_post_reset_delay); + * + * post_reset is the time the kernel should stall to prevent anyone from + * accessing the PCI bus once #RESET is de-asserted. + * PCI spec somewhere says 1 second but with multi-PCI bus systems, + * this makes the boot time much longer than necessary. + * 20ms seems to work for all the HP PCI implementations to date. + */ +#define pci_post_reset_delay 50 + + /* ** pci_hba_data (aka H2P_OBJECT in HP/UX) ** @@ -83,7 +95,7 @@ static __inline__ int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a) /* ** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses. -** See pcibios.c for more conversions used by Generic PCI code. +** See pci.c for more conversions used by Generic PCI code. ** ** Platform characteristics/firmware guarantee that ** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO @@ -191,7 +203,6 @@ struct pci_bios_ops { */ extern struct pci_port_ops *pci_port; extern struct pci_bios_ops *pci_bios; -extern int pci_post_reset_delay; /* delay after de-asserting #RESET */ extern int pci_hba_count; extern struct pci_hba_data *parisc_pci_hba[]; From 2c9aadabf454fb07b8f7533096e22bf005dd08df Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Thu, 19 Jan 2006 23:38:03 -0700 Subject: [PATCH 094/695] [PARISC] Remove unnecessary extern declarations from asm/pci.h Remove two unnecessary extern declarations from asm/pci.h. They collide with what gcc4.0 assumed was static (and should be static). Found by Joel Soete. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pci.c | 2 +- include/asm-parisc/pci.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 3a7dda860336..d66d7cb1c0d9 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -57,7 +57,7 @@ static int pci_hba_count __read_mostly; /* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data. */ #define PCI_HBA_MAX 32 -struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX] __read_mostly; +static struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX] __read_mostly; /******************************************************************** diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index 4c5e15ea3a02..fe7f6a2f5aa7 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -203,8 +203,6 @@ struct pci_bios_ops { */ extern struct pci_port_ops *pci_port; extern struct pci_bios_ops *pci_bios; -extern int pci_hba_count; -extern struct pci_hba_data *parisc_pci_hba[]; #ifdef CONFIG_PCI extern void pcibios_register_hba(struct pci_hba_data *); From c742842223269eb8eb4b86ac05ad07e6e156526b Mon Sep 17 00:00:00 2001 From: Thibaut VARENE Date: Wed, 11 Jan 2006 13:59:53 -0700 Subject: [PATCH 095/695] [PARISC] pdc_stable version 0.22 pdc_stable v0.22, changes since v0.10: o renamed root subsystem from 'pdc' to 'stable' o split 'info' into several files, one per PDC field o implemented 'autoboot' and 'autosearch' write calls to toggle these flags o grant read permission to all users on "safe" files o more code cleanup (removed duplicate code) o avoid bad stable storage clobbering by write locking critical sections o print consistent data as well o SMP cleanups Signed-off-by: Thibaut VARENE Signed-off-by: Kyle McMartin --- drivers/parisc/pdc_stable.c | 356 ++++++++++++++++++++++++++---------- 1 file changed, 262 insertions(+), 94 deletions(-) diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 42a3c54e8e6c..a28e17898fbd 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -1,7 +1,7 @@ /* * Interfaces to retrieve and set PDC Stable options (firmware) * - * Copyright (C) 2005 Thibaut VARENE + * Copyright (C) 2005-2006 Thibaut VARENE * * 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 @@ -26,11 +26,19 @@ * * Since locations between 96 and 192 are the various paths, most (if not * all) PA-RISC machines should have them. Anyway, for safety reasons, the - * following code can deal with only 96 bytes of Stable Storage, and all + * following code can deal with just 96 bytes of Stable Storage, and all * sizes between 96 and 192 bytes (provided they are multiple of struct * device_path size, eg: 128, 160 and 192) to provide full information. * The code makes no use of data above 192 bytes. One last word: there's one * path we can always count on: the primary path. + * + * The current policy wrt file permissions is: + * - write: root only + * - read: (reading triggers PDC calls) ? root only : everyone + * The rationale is that PDC calls could hog (DoS) the machine. + * + * TODO: + * - timer/fastsize write calls */ #undef PDCS_DEBUG @@ -50,13 +58,15 @@ #include #include #include +#include #include #include #include #include -#define PDCS_VERSION "0.10" +#define PDCS_VERSION "0.22" +#define PDCS_PREFIX "PDC Stable Storage" #define PDCS_ADDR_PPRI 0x00 #define PDCS_ADDR_OSID 0x40 @@ -70,10 +80,12 @@ MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); MODULE_LICENSE("GPL"); MODULE_VERSION(PDCS_VERSION); +/* holds Stable Storage size. Initialized once and for all, no lock needed */ static unsigned long pdcs_size __read_mostly; /* This struct defines what we need to deal with a parisc pdc path entry */ struct pdcspath_entry { + rwlock_t rw_lock; /* to protect path entry access */ short ready; /* entry record is valid if != 0 */ unsigned long addr; /* entry address in stable storage */ char *name; /* entry name */ @@ -121,6 +133,8 @@ struct pdcspath_attribute paths_attr_##_name = { \ * content of the stable storage WRT various paths in these structs. We read * these structs when reading the files, and we will write to these structs when * writing to the files, and only then write them back to the Stable Storage. + * + * This function expects to be called with @entry->rw_lock write-hold. */ static int pdcspath_fetch(struct pdcspath_entry *entry) @@ -160,14 +174,15 @@ pdcspath_fetch(struct pdcspath_entry *entry) * pointer, from which it'll find out the corresponding hardware path. * For now we do not handle the case where there's an error in writing to the * Stable Storage area, so you'd better not mess up the data :P + * + * This function expects to be called with @entry->rw_lock write-hold. */ -static int +static void pdcspath_store(struct pdcspath_entry *entry) { struct device_path *devpath; - if (!entry) - return -EINVAL; + BUG_ON(!entry); devpath = &entry->devpath; @@ -176,10 +191,8 @@ pdcspath_store(struct pdcspath_entry *entry) First case, we don't have a preset hwpath... */ if (!entry->ready) { /* ...but we have a device, map it */ - if (entry->dev) - device_to_hwpath(entry->dev, (struct hardware_path *)devpath); - else - return -EINVAL; + BUG_ON(!entry->dev); + device_to_hwpath(entry->dev, (struct hardware_path *)devpath); } /* else, we expect the provided hwpath to be valid. */ @@ -191,15 +204,13 @@ pdcspath_store(struct pdcspath_entry *entry) printk(KERN_ERR "%s: an error occured when writing to PDC.\n" "It is likely that the Stable Storage data has been corrupted.\n" "Please check it carefully upon next reboot.\n", __func__); - return -EIO; + WARN_ON(1); } /* kobject is already registered */ entry->ready = 2; DPRINTK("%s: device: 0x%p\n", __func__, entry->dev); - - return 0; } /** @@ -214,14 +225,17 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf) { char *out = buf; struct device_path *devpath; - unsigned short i; + short i; if (!entry || !buf) return -EINVAL; + read_lock(&entry->rw_lock); devpath = &entry->devpath; + i = entry->ready; + read_unlock(&entry->rw_lock); - if (!entry->ready) + if (!i) /* entry is not ready */ return -ENODATA; for (i = 0; i < 6; i++) { @@ -242,7 +256,7 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf) * * We will call this function to change the current hardware path. * Hardware paths are to be given '/'-delimited, without brackets. - * We take care to make sure that the provided path actually maps to an existing + * We make sure that the provided path actually maps to an existing * device, BUT nothing would prevent some foolish user to set the path to some * PCI bridge or even a CPU... * A better work around would be to make sure we are at the end of a device tree @@ -298,17 +312,19 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun } /* So far so good, let's get in deep */ + write_lock(&entry->rw_lock); entry->ready = 0; entry->dev = dev; /* Now, dive in. Write back to the hardware */ - WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */ + pdcspath_store(entry); /* Update the symlink to the real device */ sysfs_remove_link(&entry->kobj, "device"); sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); + write_unlock(&entry->rw_lock); - printk(KERN_INFO "PDC Stable Storage: changed \"%s\" path to \"%s\"\n", + printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n", entry->name, buf); return count; @@ -326,14 +342,17 @@ pdcspath_layer_read(struct pdcspath_entry *entry, char *buf) { char *out = buf; struct device_path *devpath; - unsigned short i; + short i; if (!entry || !buf) return -EINVAL; + read_lock(&entry->rw_lock); devpath = &entry->devpath; + i = entry->ready; + read_unlock(&entry->rw_lock); - if (!entry->ready) + if (!i) /* entry is not ready */ return -ENODATA; for (i = 0; devpath->layers[i] && (likely(i < 6)); i++) @@ -388,15 +407,17 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count } /* So far so good, let's get in deep */ + write_lock(&entry->rw_lock); /* First, overwrite the current layers with the new ones, not touching the hardware path. */ memcpy(&entry->devpath.layers, &layers, sizeof(layers)); /* Now, dive in. Write back to the hardware */ - WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */ + pdcspath_store(entry); + write_unlock(&entry->rw_lock); - printk(KERN_INFO "PDC Stable Storage: changed \"%s\" layers to \"%s\"\n", + printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" layers to \"%s\"\n", entry->name, buf); return count; @@ -415,9 +436,6 @@ pdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr); ssize_t ret = 0; - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (pdcs_attr->show) ret = pdcs_attr->show(entry, buf); @@ -454,8 +472,8 @@ static struct sysfs_ops pdcspath_attr_ops = { }; /* These are the two attributes of any PDC path. */ -static PATHS_ATTR(hwpath, 0600, pdcspath_hwpath_read, pdcspath_hwpath_write); -static PATHS_ATTR(layer, 0600, pdcspath_layer_read, pdcspath_layer_write); +static PATHS_ATTR(hwpath, 0644, pdcspath_hwpath_read, pdcspath_hwpath_write); +static PATHS_ATTR(layer, 0644, pdcspath_layer_read, pdcspath_layer_write); static struct attribute *paths_subsys_attrs[] = { &paths_attr_hwpath.attr, @@ -484,36 +502,119 @@ static struct pdcspath_entry *pdcspath_entries[] = { NULL, }; + +/* For more insight of what's going on here, refer to PDC Procedures doc, + * Section PDC_STABLE */ + /** - * pdcs_info_read - Pretty printing of the remaining useful data. + * pdcs_size_read - Stable Storage size output. * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. - * - * We will call this function to format the output of the 'info' attribute file. - * Please refer to PDC Procedures documentation, section PDC_STABLE to get a - * better insight of what we're doing here. */ static ssize_t -pdcs_info_read(struct subsystem *entry, char *buf) +pdcs_size_read(struct subsystem *entry, char *buf) { char *out = buf; - __u32 result; - struct device_path devpath; - char *tmpstr = NULL; if (!entry || !buf) return -EINVAL; /* show the size of the stable storage */ - out += sprintf(out, "Stable Storage size: %ld bytes\n", pdcs_size); + out += sprintf(out, "%ld\n", pdcs_size); - /* deal with flags */ - if (pdc_stable_read(PDCS_ADDR_PPRI, &devpath, sizeof(devpath)) != PDC_OK) - return -EIO; + return out - buf; +} + +/** + * pdcs_auto_read - Stable Storage autoboot/search flag output. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag + */ +static ssize_t +pdcs_auto_read(struct subsystem *entry, char *buf, int knob) +{ + char *out = buf; + struct pdcspath_entry *pathentry; - out += sprintf(out, "Autoboot: %s\n", (devpath.flags & PF_AUTOBOOT) ? "On" : "Off"); - out += sprintf(out, "Autosearch: %s\n", (devpath.flags & PF_AUTOSEARCH) ? "On" : "Off"); - out += sprintf(out, "Timer: %u s\n", (devpath.flags & PF_TIMER) ? (1 << (devpath.flags & PF_TIMER)) : 0); + if (!entry || !buf) + return -EINVAL; + + /* Current flags are stored in primary boot path entry */ + pathentry = &pdcspath_entry_primary; + + read_lock(&pathentry->rw_lock); + out += sprintf(out, "%s\n", (pathentry->devpath.flags & knob) ? + "On" : "Off"); + read_unlock(&pathentry->rw_lock); + + return out - buf; +} + +/** + * pdcs_autoboot_read - Stable Storage autoboot flag output. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + */ +static inline ssize_t +pdcs_autoboot_read(struct subsystem *entry, char *buf) +{ + return pdcs_auto_read(entry, buf, PF_AUTOBOOT); +} + +/** + * pdcs_autosearch_read - Stable Storage autoboot flag output. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + */ +static inline ssize_t +pdcs_autosearch_read(struct subsystem *entry, char *buf) +{ + return pdcs_auto_read(entry, buf, PF_AUTOSEARCH); +} + +/** + * pdcs_timer_read - Stable Storage timer count output (in seconds). + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + * + * The value of the timer field correponds to a number of seconds in powers of 2. + */ +static ssize_t +pdcs_timer_read(struct subsystem *entry, char *buf) +{ + char *out = buf; + struct pdcspath_entry *pathentry; + + if (!entry || !buf) + return -EINVAL; + + /* Current flags are stored in primary boot path entry */ + pathentry = &pdcspath_entry_primary; + + /* print the timer value in seconds */ + read_lock(&pathentry->rw_lock); + out += sprintf(out, "%u\n", (pathentry->devpath.flags & PF_TIMER) ? + (1 << (pathentry->devpath.flags & PF_TIMER)) : 0); + read_unlock(&pathentry->rw_lock); + + return out - buf; +} + +/** + * pdcs_osid_read - Stable Storage OS ID register output. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + */ +static ssize_t +pdcs_osid_read(struct subsystem *entry, char *buf) +{ + char *out = buf; + __u32 result; + char *tmpstr = NULL; + + if (!entry || !buf) + return -EINVAL; /* get OSID */ if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) @@ -529,13 +630,31 @@ pdcs_info_read(struct subsystem *entry, char *buf) case 0x0005: tmpstr = "Novell Netware dependent data"; break; default: tmpstr = "Unknown"; break; } - out += sprintf(out, "OS ID: %s (0x%.4x)\n", tmpstr, (result >> 16)); + out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16)); + + return out - buf; +} + +/** + * pdcs_fastsize_read - Stable Storage FastSize register output. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + * + * This register holds the amount of system RAM to be tested during boot sequence. + */ +static ssize_t +pdcs_fastsize_read(struct subsystem *entry, char *buf) +{ + char *out = buf; + __u32 result; + + if (!entry || !buf) + return -EINVAL; /* get fast-size */ if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK) return -EIO; - out += sprintf(out, "Memory tested: "); if ((result & 0x0F) < 0x0E) out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256); else @@ -546,22 +665,18 @@ pdcs_info_read(struct subsystem *entry, char *buf) } /** - * pdcs_info_write - This function handles boot flag modifying. + * pdcs_auto_write - This function handles autoboot/search flag modifying. * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The input buffer to read from. * @count: The number of bytes to be read. + * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag * - * We will call this function to change the current boot flags. + * We will call this function to change the current autoboot flag. * We expect a precise syntax: - * \"n n\" (n == 0 or 1) to toggle respectively AutoBoot and AutoSearch - * - * As of now there is no incentive on my side to provide more "knobs" to that - * interface, since modifying the rest of the data is pretty meaningless when - * the machine is running and for the expected use of that facility, such as - * PALO setting up the boot disk when installing a Linux distribution... + * \"n\" (n == 0 or 1) to toggle AutoBoot Off or On */ static ssize_t -pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) +pdcs_auto_write(struct subsystem *entry, const char *buf, size_t count, int knob) { struct pdcspath_entry *pathentry; unsigned char flags; @@ -582,7 +697,9 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) pathentry = &pdcspath_entry_primary; /* Be nice to the existing flag record */ + read_lock(&pathentry->rw_lock); flags = pathentry->devpath.flags; + read_unlock(&pathentry->rw_lock); DPRINTK("%s: flags before: 0x%X\n", __func__, flags); @@ -595,50 +712,85 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) if ((c != 0) && (c != 1)) goto parse_error; if (c == 0) - flags &= ~PF_AUTOBOOT; + flags &= ~knob; else - flags |= PF_AUTOBOOT; - - if (*temp++ != ' ') - goto parse_error; - - c = *temp++ - '0'; - if ((c != 0) && (c != 1)) - goto parse_error; - if (c == 0) - flags &= ~PF_AUTOSEARCH; - else - flags |= PF_AUTOSEARCH; + flags |= knob; DPRINTK("%s: flags after: 0x%X\n", __func__, flags); /* So far so good, let's get in deep */ + write_lock(&pathentry->rw_lock); /* Change the path entry flags first */ pathentry->devpath.flags = flags; /* Now, dive in. Write back to the hardware */ - WARN_ON(pdcspath_store(pathentry)); /* this warn should *NEVER* happen */ + pdcspath_store(pathentry); + write_unlock(&pathentry->rw_lock); - printk(KERN_INFO "PDC Stable Storage: changed flags to \"%s\"\n", buf); + printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" to \"%s\"\n", + (knob & PF_AUTOBOOT) ? "autoboot" : "autosearch", + (flags & knob) ? "On" : "Off"); return count; parse_error: - printk(KERN_WARNING "%s: Parse error: expect \"n n\" (n == 0 or 1) for AB and AS\n", __func__); + printk(KERN_WARNING "%s: Parse error: expect \"n\" (n == 0 or 1)\n", __func__); return -EINVAL; } -/* The last attribute (the 'root' one actually) with all remaining data. */ -static PDCS_ATTR(info, 0600, pdcs_info_read, pdcs_info_write); +/** + * pdcs_autoboot_write - This function handles autoboot flag modifying. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The input buffer to read from. + * @count: The number of bytes to be read. + * + * We will call this function to change the current boot flags. + * We expect a precise syntax: + * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On + */ +static inline ssize_t +pdcs_autoboot_write(struct subsystem *entry, const char *buf, size_t count) +{ + return pdcs_auto_write(entry, buf, count, PF_AUTOBOOT); +} + +/** + * pdcs_autosearch_write - This function handles autosearch flag modifying. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The input buffer to read from. + * @count: The number of bytes to be read. + * + * We will call this function to change the current boot flags. + * We expect a precise syntax: + * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On + */ +static inline ssize_t +pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count) +{ + return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); +} + +/* The remaining attributes. */ +static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); +static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); +static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); +static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); +static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL); +static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); static struct subsys_attribute *pdcs_subsys_attrs[] = { - &pdcs_attr_info, - NULL, /* maybe more in the future? */ + &pdcs_attr_size, + &pdcs_attr_autoboot, + &pdcs_attr_autosearch, + &pdcs_attr_timer, + &pdcs_attr_osid, + &pdcs_attr_fastsize, + NULL, }; static decl_subsys(paths, &ktype_pdcspath, NULL); -static decl_subsys(pdc, NULL, NULL); +static decl_subsys(stable, NULL, NULL); /** * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. @@ -656,8 +808,16 @@ pdcs_register_pathentries(void) struct pdcspath_entry *entry; int err; + /* Initialize the entries rw_lock before anything else */ + for (i = 0; (entry = pdcspath_entries[i]); i++) + rwlock_init(&entry->rw_lock); + for (i = 0; (entry = pdcspath_entries[i]); i++) { - if (pdcspath_fetch(entry) < 0) + write_lock(&entry->rw_lock); + err = pdcspath_fetch(entry); + write_unlock(&entry->rw_lock); + + if (err < 0) continue; if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) @@ -667,13 +827,14 @@ pdcs_register_pathentries(void) return err; /* kobject is now registered */ + write_lock(&entry->rw_lock); entry->ready = 2; - if (!entry->dev) - continue; - /* Add a nice symlink to the real device */ - sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); + if (entry->dev) + sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); + + write_unlock(&entry->rw_lock); } return 0; @@ -688,14 +849,17 @@ pdcs_unregister_pathentries(void) unsigned short i; struct pdcspath_entry *entry; - for (i = 0; (entry = pdcspath_entries[i]); i++) + for (i = 0; (entry = pdcspath_entries[i]); i++) { + read_lock(&entry->rw_lock); if (entry->ready >= 2) - kobject_unregister(&entry->kobj); + kobject_unregister(&entry->kobj); + read_unlock(&entry->rw_lock); + } } /* - * For now we register the pdc subsystem with the firmware subsystem - * and the paths subsystem with the pdc subsystem + * For now we register the stable subsystem with the firmware subsystem + * and the paths subsystem with the stable subsystem */ static int __init pdc_stable_init(void) @@ -707,19 +871,23 @@ pdc_stable_init(void) if (pdc_stable_get_size(&pdcs_size) != PDC_OK) return -ENODEV; - printk(KERN_INFO "PDC Stable Storage facility v%s\n", PDCS_VERSION); + /* make sure we have enough data */ + if (pdcs_size < 96) + return -ENODATA; - /* For now we'll register the pdc subsys within this driver */ - if ((rc = firmware_register(&pdc_subsys))) + printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); + + /* For now we'll register the stable subsys within this driver */ + if ((rc = firmware_register(&stable_subsys))) goto fail_firmreg; - /* Don't forget the info entry */ + /* Don't forget the root entries */ for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) if (attr->show) - error = subsys_create_file(&pdc_subsys, attr); + error = subsys_create_file(&stable_subsys, attr); - /* register the paths subsys as a subsystem of pdc subsys */ - kset_set_kset_s(&paths_subsys, pdc_subsys); + /* register the paths subsys as a subsystem of stable subsys */ + kset_set_kset_s(&paths_subsys, stable_subsys); if ((rc= subsystem_register(&paths_subsys))) goto fail_subsysreg; @@ -734,10 +902,10 @@ fail_pdcsreg: subsystem_unregister(&paths_subsys); fail_subsysreg: - firmware_unregister(&pdc_subsys); + firmware_unregister(&stable_subsys); fail_firmreg: - printk(KERN_INFO "PDC Stable Storage bailing out\n"); + printk(KERN_INFO PDCS_PREFIX " bailing out\n"); return rc; } @@ -747,7 +915,7 @@ pdc_stable_exit(void) pdcs_unregister_pathentries(); subsystem_unregister(&paths_subsys); - firmware_unregister(&pdc_subsys); + firmware_unregister(&stable_subsys); } From c475eea2929a7f0dac21d20e10562a491fcf7c45 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 15 Jan 2006 12:11:50 -0700 Subject: [PATCH 096/695] [PARISC] Drop unused do_check_pgt_cache() Drop the unused do_check_pgt_cache routine from mm/init.c and its prototype in asm/pgalloc.h Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin --- arch/parisc/mm/init.c | 5 ----- include/asm-parisc/pgalloc.h | 1 - 2 files changed, 6 deletions(-) diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index e54268004f53..9999eb045238 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -477,11 +477,6 @@ void __init mem_init(void) } -int do_check_pgt_cache(int low, int high) -{ - return 0; -} - unsigned long *empty_zero_page __read_mostly; void show_mem(void) diff --git a/include/asm-parisc/pgalloc.h b/include/asm-parisc/pgalloc.h index 6291d6692e5d..3122fad38a1b 100644 --- a/include/asm-parisc/pgalloc.h +++ b/include/asm-parisc/pgalloc.h @@ -137,7 +137,6 @@ static inline void pte_free_kernel(pte_t *pte) #define pte_free(page) pte_free_kernel(page_address(page)) -extern int do_check_pgt_cache(int, int); #define check_pgt_cache() do { } while (0) #endif From 370361f884c032216ece841ac5328393b136f0bb Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 11 Jan 2006 15:11:30 -0700 Subject: [PATCH 097/695] [PARISC] Fix floating point invalid exception trap handler Fix our trap handler to issue the correct floating point exception for both types of invalid trap. Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin --- arch/parisc/math-emu/decode_exc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/parisc/math-emu/decode_exc.c b/arch/parisc/math-emu/decode_exc.c index f84f2586672b..66c8a9f6a27e 100644 --- a/arch/parisc/math-emu/decode_exc.c +++ b/arch/parisc/math-emu/decode_exc.c @@ -337,6 +337,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[]) } break; case INVALIDEXCEPTION: + case OPC_2E_INVALIDEXCEPTION: update_trap_counts(Fpu_register, aflags, bflags, trap_counts); return SIGNALCODE(SIGFPE, FPE_FLTINV); case DIVISIONBYZEROEXCEPTION: From 10992092a8a6e445199f30e56789322851479019 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 13 Jan 2006 22:05:21 -0700 Subject: [PATCH 098/695] [PARISC] Use F_EXTEND() for COMMAND_GLOBAL Instead of wrapping the define of COMMAND_GLOBAL in #ifdef __LP64__ use the F_EXTEND() macro defined in asm/io.h, which is the preferred way of extending mmio space addresses for either 32 or 64 bit machines. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/process.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 5da41677e70b..f46259e2fab5 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -102,12 +102,7 @@ void cpu_idle(void) } -#ifdef __LP64__ -#define COMMAND_GLOBAL 0xfffffffffffe0030UL -#else -#define COMMAND_GLOBAL 0xfffe0030 -#endif - +#define COMMAND_GLOBAL F_EXTEND(0xfffe0030) #define CMD_RESET 5 /* reset any module */ /* From 96629c0b111dbb31d14338a55b7f650e9c490284 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 15 Jan 2006 11:52:22 -0700 Subject: [PATCH 099/695] [PARISC] Clean up compiler warning in pci.c Avoid compiler warning for unused variables on 32bit kernels by conditionalizing the local variables on CONFIG_64BIT. PCI_HOST_ADDR() only uses the hba argument on 64bit compiles. Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index d66d7cb1c0d9..79c7db2705fd 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -258,8 +258,10 @@ void __devinit pcibios_resource_to_bus(struct pci_dev *dev, void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region) { +#ifdef CONFIG_64BIT struct pci_bus *bus = dev->bus; struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data); +#endif if (res->flags & IORESOURCE_MEM) { res->start = PCI_HOST_ADDR(hba, region->start); From 2e13b31e5b0ff0b1f1e3359ebf8ca46c356e9391 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 17 Jan 2006 08:33:01 -0700 Subject: [PATCH 100/695] [PARISC] atomic64 support Implement atomic64_t so atomic_long_t works on parisc. Also clean up some of the coding style in atomic.h, and make sure ATOMIC_INIT is cast properly. Signed-off-by: Kyle McMartin --- include/asm-parisc/atomic.h | 84 ++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h index 2ca56d34aaad..4dc7253ff5d0 100644 --- a/include/asm-parisc/atomic.h +++ b/include/asm-parisc/atomic.h @@ -1,9 +1,13 @@ +/* Copyright (C) 2000 Philipp Rumpf + * Copyright (C) 2006 Kyle McMartin + */ + #ifndef _ASM_PARISC_ATOMIC_H_ #define _ASM_PARISC_ATOMIC_H_ #include +#include #include -/* Copyright (C) 2000 Philipp Rumpf . */ /* * Atomic operations that C can't guarantee us. Useful for @@ -46,15 +50,6 @@ extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; # define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0) #endif -/* Note that we need not lock read accesses - aligned word writes/reads - * are atomic, so a reader never sees unconsistent values. - * - * Cache-line alignment would conflict with, for example, linux/module.h - */ - -typedef struct { volatile int counter; } atomic_t; - - /* This should get optimized out since it's never called. ** Or get a link error if xchg is used "wrong". */ @@ -69,10 +64,9 @@ extern unsigned long __xchg64(unsigned long, unsigned long *); #endif /* optimizer better get rid of switch since size is a constant */ -static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr, - int size) +static __inline__ unsigned long +__xchg(unsigned long x, __volatile__ void * ptr, int size) { - switch(size) { #ifdef __LP64__ case 8: return __xchg64(x,(unsigned long *) ptr); @@ -129,7 +123,13 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) (unsigned long)_n_, sizeof(*(ptr))); \ }) +/* Note that we need not lock read accesses - aligned word writes/reads + * are atomic, so a reader never sees unconsistent values. + * + * Cache-line alignment would conflict with, for example, linux/module.h + */ +typedef struct { volatile int counter; } atomic_t; /* It's possible to reduce all atomic operations to either * __atomic_add_return, atomic_set and atomic_read (the latter @@ -210,12 +210,66 @@ static __inline__ int atomic_read(const atomic_t *v) #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) -#define ATOMIC_INIT(i) { (i) } +#define ATOMIC_INIT(i) ((atomic_t) { (i) }) #define smp_mb__before_atomic_dec() smp_mb() #define smp_mb__after_atomic_dec() smp_mb() #define smp_mb__before_atomic_inc() smp_mb() #define smp_mb__after_atomic_inc() smp_mb() +#ifdef __LP64__ + +typedef struct { volatile s64 counter; } atomic64_t; + +#define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) + +static __inline__ int +__atomic64_add_return(s64 i, atomic64_t *v) +{ + int ret; + unsigned long flags; + _atomic_spin_lock_irqsave(v, flags); + + ret = (v->counter += i); + + _atomic_spin_unlock_irqrestore(v, flags); + return ret; +} + +static __inline__ void +atomic64_set(atomic64_t *v, s64 i) +{ + unsigned long flags; + _atomic_spin_lock_irqsave(v, flags); + + v->counter = i; + + _atomic_spin_unlock_irqrestore(v, flags); +} + +static __inline__ s64 +atomic64_read(const atomic64_t *v) +{ + return v->counter; +} + +#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)i),(v)))) +#define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)i),(v)))) +#define atomic64_inc(v) ((void)(__atomic64_add_return( 1,(v)))) +#define atomic64_dec(v) ((void)(__atomic64_add_return( -1,(v)))) + +#define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)i),(v))) +#define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)i),(v))) +#define atomic64_inc_return(v) (__atomic64_add_return( 1,(v))) +#define atomic64_dec_return(v) (__atomic64_add_return( -1,(v))) + +#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) + +#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) +#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0) + +#endif /* __LP64__ */ + #include -#endif + +#endif /* _ASM_PARISC_ATOMIC_H_ */ From 9073315bbc3e2149d8ffcc4b86932ca6497c94ce Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 13 Jan 2006 22:05:21 -0700 Subject: [PATCH 101/695] [PARISC] Move pm_power_off export to process.c Move the EXPORT_SYMBOL() of pm_power_off from parisc_ksyms.c to the location of its definition in process.c Signed-off-by: Kyle McMartin --- arch/parisc/kernel/parisc_ksyms.c | 3 --- arch/parisc/kernel/process.c | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index f40a777dd388..1d00c365f2b1 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -48,9 +48,6 @@ EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strpbrk); -#include -EXPORT_SYMBOL(pm_power_off); - #include EXPORT_SYMBOL(__xchg8); EXPORT_SYMBOL(__xchg32); diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index f46259e2fab5..997ab542da8d 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -60,6 +60,7 @@ static int hlt_counter __read_mostly; * Power off function, if any */ void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); void disable_hlt(void) { From 526110f8c8d2326413e2de5496d196ee9d4856ad Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 13 Jan 2006 22:05:21 -0700 Subject: [PATCH 102/695] [PARISC] Remove obsolete _hlt cruft Remove a bunch of obsolete code from process.c, these routines were likely imported from the i386 version of process.c when the port started. The routines are only used in floppy.c, which I seriously doubt will ever work on parisc, due to architectural assumptions. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/process.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 997ab542da8d..998700ce4556 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -54,28 +54,12 @@ #include #include -static int hlt_counter __read_mostly; - /* * Power off function, if any */ void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); -void disable_hlt(void) -{ - hlt_counter++; -} - -EXPORT_SYMBOL(disable_hlt); - -void enable_hlt(void) -{ - hlt_counter--; -} - -EXPORT_SYMBOL(enable_hlt); - void default_idle(void) { barrier(); From 85509c00073d4bdd1f4b7796180a15198f2e62da Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 17 Jan 2006 22:33:32 -0700 Subject: [PATCH 103/695] [PARISC] Add chassis_power_off routine Define a chassis_power_off routine that machines which have a way to turn off the power supply can hook into. Formerly they were using pm_power_off, which is now being used by generic code. Make lasi.c use chassis_power_off instead of pm_power_off. Note, all machines need to call machine_power_off so that the switch can power off the machine, though halt -p may not necessarily be able to work properly on the machine. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/process.c | 13 +++++-------- drivers/parisc/lasi.c | 3 ++- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 998700ce4556..e8dea4177113 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -54,12 +54,6 @@ #include #include -/* - * Power off function, if any - */ -void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); - void default_idle(void) { barrier(); @@ -142,6 +136,7 @@ void machine_halt(void) */ } +void (*chassis_power_off)(void); /* * This routine is called from sys_reboot to actually turn off the @@ -150,8 +145,8 @@ void machine_halt(void) void machine_power_off(void) { /* If there is a registered power off handler, call it. */ - if(pm_power_off) - pm_power_off(); + if (chassis_power_off) + chassis_power_off(); /* Put the soft power button back under hardware control. * If the user had already pressed the power button, the @@ -167,6 +162,8 @@ void machine_power_off(void) KERN_EMERG "Please power this system off now."); } +void (*pm_power_off)(void) = machine_power_off; +EXPORT_SYMBOL(pm_power_off); /* * Create a kernel thread diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index d043a8a33511..cb3d28176129 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c @@ -166,6 +166,7 @@ static void lasi_power_off(void) int __init lasi_init_chip(struct parisc_device *dev) { + extern void (*chassis_power_off)(void); struct gsc_asic *lasi; struct gsc_irq gsc_irq; int ret; @@ -222,7 +223,7 @@ lasi_init_chip(struct parisc_device *dev) * ensure that only the first LASI (the one controlling the power off) * should set the HPA here */ lasi_power_off_hpa = lasi->hpa; - pm_power_off = lasi_power_off; + chassis_power_off = lasi_power_off; return ret; } From a2bb214dcd1db862fdb6421e21f1cff0c3535162 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 17 Jan 2006 11:43:48 -0700 Subject: [PATCH 104/695] [PARISC] Remove {,un}lock_kernel from perf ioctl Remove the lock_kernel/unlock_kernel pair in the ioctl method. It plainly wasn't protecting anything. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/kernel/perf.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index 11178ccbb89a..53f861c82f93 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -444,7 +444,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) uint32_t raddr[4]; int error = 0; - lock_kernel(); switch (cmd) { case PA_PERF_ON: @@ -477,8 +476,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) error = -ENOTTY; } - unlock_kernel(); - return error; } From 1bcdd8548286743e1d6b3d53c96a90c6da975620 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 13 Jan 2006 13:21:06 -0700 Subject: [PATCH 105/695] [PARISC] Add CONFIG_DEBUG_RODATA to protect read-only data Add the parisc version of the "mark rodata section read only" patches. Based on code from and Signed-off-by Arjan van de Ven , Ingo Molnar , Andi Kleen , Andrew Morton , Linus Torvalds . Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin --- arch/parisc/Kconfig.debug | 10 ++++++++++ arch/parisc/hpux/entry_hpux.S | 3 +-- arch/parisc/kernel/syscall.S | 2 ++ arch/parisc/mm/init.c | 15 ++++++++++++++- include/asm-parisc/cacheflush.h | 6 ++++++ include/asm-parisc/pgtable.h | 2 +- 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug index 8caaed187a1f..9166bd117267 100644 --- a/arch/parisc/Kconfig.debug +++ b/arch/parisc/Kconfig.debug @@ -11,4 +11,14 @@ config DEBUG_RWLOCK too many attempts. If you suspect a rwlock problem or a kernel hacker asks for this option then say Y. Otherwise say N. +config DEBUG_RODATA + bool "Write protect kernel read-only data structures" + depends on DEBUG_KERNEL + help + Mark the kernel read-only data as write-protected in the pagetables, + in order to catch accidental (and incorrect) writes to such const + data. This option may have a slight performance impact because a + portion of the kernel code won't be covered by a TLB anymore. + If in doubt, say "N". + endmenu diff --git a/arch/parisc/hpux/entry_hpux.S b/arch/parisc/hpux/entry_hpux.S index fa9bf38787e7..31c8cccfba31 100644 --- a/arch/parisc/hpux/entry_hpux.S +++ b/arch/parisc/hpux/entry_hpux.S @@ -22,10 +22,9 @@ #include #include - .text - #define ENTRY_NAME(_name_) .word _name_ + .section .rodata,"a" .align 4 .export hpux_call_table .import hpux_unimplemented_wrapper diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index d66163492890..af88afef41bd 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -650,6 +650,8 @@ end_linux_gateway_page: #define LWS_ENTRY(_name_) .word (lws_##_name_ - linux_gateway_page) #endif + .section .rodata,"a" + .align 4096 /* Light-weight-syscall table */ /* Start of lws table. */ diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 9999eb045238..6f36d0b17d9e 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -417,6 +417,19 @@ void free_initmem(void) #endif } + +#ifdef CONFIG_DEBUG_RODATA +void mark_rodata_ro(void) +{ + extern char __start_rodata, __end_rodata; + /* rodata memory was already mapped with KERNEL_RO access rights by + pagetable_init() and map_pages(). No need to do additional stuff here */ + printk (KERN_INFO "Write protecting the kernel read-only data: %luk\n", + (unsigned long)(&__end_rodata - &__start_rodata) >> 10); +} +#endif + + /* * Just an arbitrary offset to serve as a "hole" between mapping areas * (between top of physical memory and a potential pcxl dma mapping @@ -685,7 +698,7 @@ static void __init pagetable_init(void) #ifdef CONFIG_BLK_DEV_INITRD if (initrd_end && initrd_end > mem_limit) { - printk("initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end); + printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end); map_pages(initrd_start, __pa(initrd_start), initrd_end - initrd_start, PAGE_KERNEL); } diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h index 1bc3c83ee74b..c53af9ff41b5 100644 --- a/include/asm-parisc/cacheflush.h +++ b/include/asm-parisc/cacheflush.h @@ -183,4 +183,10 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long __flush_cache_page(vma, vmaddr); } + +#ifdef CONFIG_DEBUG_RODATA +void mark_rodata_ro(void); #endif + +#endif /* _PARISC_CACHEFLUSH_H */ + diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index b4554711c3e7..4e34c6b44059 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -213,7 +213,7 @@ extern void *vmalloc_start; #define PAGE_COPY PAGE_EXECREAD #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) -#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED) +#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) #define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ) #define PAGE_FLUSH __pgprot(_PAGE_FLUSH) From 81a3de3efd61c2483a303cf0b6227525d2f28df7 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 15 Jan 2006 12:11:50 -0700 Subject: [PATCH 106/695] [PARISC] Use DEBUG_KERNEL to catch used-after-free __init data Use CONFIG_DEBUG_KERNEL to catch kernel code which tries to access __init data after it is freed. When CONFIG_DEBUG_KERNEL is not set this also cleans up a WARN_ON at boot time. Also remove some dead code from mm/init.c Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin --- arch/parisc/mm/init.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 6f36d0b17d9e..7847ca13d6c2 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -371,17 +371,11 @@ static void __init setup_bootmem(void) void free_initmem(void) { - /* FIXME: */ -#if 0 - printk(KERN_INFO "NOT FREEING INITMEM (%dk)\n", - (&__init_end - &__init_begin) >> 10); - return; -#else unsigned long addr; printk(KERN_INFO "Freeing unused kernel memory: "); -#if 1 +#ifdef CONFIG_DEBUG_KERNEL /* Attempt to catch anyone trying to execute code here * by filling the page with BRK insns. * @@ -414,7 +408,6 @@ void free_initmem(void) pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10); -#endif } From 16541c8745e28f62b3dcb6cb354b73c9c01ea178 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sat, 21 Jan 2006 21:55:06 -0700 Subject: [PATCH 107/695] [PARISC] Clean up printk in superio.c Clean up some of the messages printed by the superio driver by defining a prefix instead of duplicating it in every message. Also some small coding style cleanups. Signed-off-by: Kyle McMartin --- drivers/parisc/superio.c | 41 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index d14888e149bb..ba971fecd0d8 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -89,6 +89,9 @@ static struct superio_device sio_dev; #define DBG_INIT(x...) #endif +#define SUPERIO "SuperIO" +#define PFX SUPERIO ": " + static irqreturn_t superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) { @@ -117,7 +120,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) local_irq = results & 0x0f; if (local_irq == 2 || local_irq > 7) { - printk(KERN_ERR "SuperIO: slave interrupted!\n"); + printk(KERN_ERR PFX "slave interrupted!\n"); return IRQ_HANDLED; } @@ -128,7 +131,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) outb(OCW3_ISR,IC_PIC1+0); results = inb(IC_PIC1+0); if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ - printk(KERN_WARNING "SuperIO: spurious interrupt!\n"); + printk(KERN_WARNING PFX "spurious interrupt!\n"); return IRQ_HANDLED; } } @@ -163,27 +166,27 @@ superio_init(struct pci_dev *pcidev) /* ...then properly fixup the USB to point at suckyio PIC */ sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); - printk(KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n", + printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", pci_name(pdev), pdev->irq); pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); sio->sp1_base &= ~1; - printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base); + printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base); pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); sio->sp2_base &= ~1; - printk (KERN_INFO "SuperIO: Serial port 2 at 0x%x\n", sio->sp2_base); + printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base); pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); sio->pp_base &= ~1; - printk (KERN_INFO "SuperIO: Parallel port at 0x%x\n", sio->pp_base); + printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base); pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); sio->fdc_base &= ~1; - printk (KERN_INFO "SuperIO: Floppy controller at 0x%x\n", sio->fdc_base); + printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base); pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); sio->acpi_base &= ~1; - printk (KERN_INFO "SuperIO: ACPI at 0x%x\n", sio->acpi_base); + printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base); request_region (IC_PIC1, 0x1f, "pic1"); request_region (IC_PIC2, 0x1f, "pic2"); @@ -263,14 +266,14 @@ superio_init(struct pci_dev *pcidev) /* Setup USB power regulation */ outb(1, sio->acpi_base + USB_REG_CR); if (inb(sio->acpi_base + USB_REG_CR) & 1) - printk(KERN_INFO "SuperIO: USB regulator enabled\n"); + printk(KERN_INFO PFX "USB regulator enabled\n"); else - printk(KERN_ERR "USB regulator not initialized!\n"); + printk(KERN_ERR PFX "USB regulator not initialized!\n"); if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT, - "SuperIO", (void *)sio)) { + SUPERIO, (void *)sio)) { - printk(KERN_ERR "SuperIO: could not get irq\n"); + printk(KERN_ERR PFX "could not get irq\n"); BUG(); return; } @@ -284,7 +287,7 @@ static void superio_disable_irq(unsigned int irq) u8 r8; if ((irq < 1) || (irq == 2) || (irq > 7)) { - printk(KERN_ERR "SuperIO: Illegal irq number.\n"); + printk(KERN_ERR PFX "Illegal irq number.\n"); BUG(); return; } @@ -301,7 +304,7 @@ static void superio_enable_irq(unsigned int irq) u8 r8; if ((irq < 1) || (irq == 2) || (irq > 7)) { - printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", irq); + printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq); BUG(); return; } @@ -319,7 +322,7 @@ static unsigned int superio_startup_irq(unsigned int irq) } static struct hw_interrupt_type superio_interrupt_type = { - .typename = "SuperIO", + .typename = SUPERIO, .startup = superio_startup_irq, .shutdown = superio_disable_irq, .enable = superio_enable_irq, @@ -413,7 +416,7 @@ static void __devinit superio_serial_init(void) retval = early_serial_setup(&serial[0]); if (retval < 0) { - printk(KERN_WARNING "SuperIO: Register Serial #0 failed.\n"); + printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); return; } @@ -423,7 +426,7 @@ static void __devinit superio_serial_init(void) retval = early_serial_setup(&serial[1]); if (retval < 0) - printk(KERN_WARNING "SuperIO: Register Serial #1 failed.\n"); + printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); #endif /* CONFIG_SERIAL_8250 */ } @@ -437,7 +440,7 @@ static void __devinit superio_parport_init(void) PARPORT_DMA_NONE /* dma */, NULL /*struct pci_dev* */) ) - printk(KERN_WARNING "SuperIO: Probing parallel port failed.\n"); + printk(KERN_WARNING PFX "Probing parallel port failed.\n"); #endif /* CONFIG_PARPORT_PC */ } @@ -499,7 +502,7 @@ static struct pci_device_id superio_tbl[] = { }; static struct pci_driver superio_driver = { - .name = "SuperIO", + .name = SUPERIO, .id_table = superio_tbl, .probe = superio_probe, }; From f671c45df23005692daa200aba768c642fb14ef2 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sun, 15 Jan 2006 14:10:29 -0500 Subject: [PATCH 108/695] [PARISC] Arch-specific compat signals Add enough arch-specific compat signals code to enable parisc64 to compile and boot out of the mainline tree. There are likely still many dragons here, but this is a start to squashing the last big difference between the mainline tree and the parisc-linux tree. The remaining bugs can be squashed as they come up. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/ptrace.c | 8 +- arch/parisc/kernel/signal.c | 2 +- arch/parisc/kernel/signal32.c | 102 ++++++++++++++++++++- arch/parisc/kernel/signal32.h | 127 ++++++++++++++++++++++++++- include/asm-parisc/compat_ucontext.h | 3 +- include/asm-parisc/rt_sigframe.h | 4 - 6 files changed, 232 insertions(+), 14 deletions(-) diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 27160e8bf15b..413292f1a4a3 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) int copied; #ifdef __LP64__ - if (is_compat_task(child)) { + if (personality(child->personality) == PER_LINUX32) { unsigned int tmp; addr &= 0xffffffffL; @@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_POKEDATA: ret = 0; #ifdef __LP64__ - if (is_compat_task(child)) { + if (personality(child->personality) == PER_LINUX32) { unsigned int tmp = (unsigned int)data; DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", request == PTRACE_POKETEXT ? "TEXT" : "DATA", @@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_PEEKUSR: { ret = -EIO; #ifdef __LP64__ - if (is_compat_task(child)) { + if (personality(child->personality) == PER_LINUX32) { unsigned int tmp; if (addr & (sizeof(int)-1)) @@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) goto out_tsk; } #ifdef __LP64__ - if (is_compat_task(child)) { + if (personality(child->personality) == PER_LINUX32) { if (addr & (sizeof(int)-1)) goto out_tsk; if ((addr = translate_usr_offset(addr)) < 0) diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 3a25a7bd673e..05767e83cf2d 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -317,7 +317,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, if(personality(current->personality) == PER_LINUX32) { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); - err |= compat_copy_siginfo_to_user(&compat_frame->info, info); + err |= copy_siginfo_to_user32(&compat_frame->info, info); DBG(1,"SETUP_RT_FRAME: 1\n"); compat_val = (compat_int_t)current->sas_ss_sp; err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp); diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 0792e20efef3..a6b4231cafa1 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -31,7 +31,6 @@ #include #include -#include #include #include "signal32.h" @@ -398,3 +397,104 @@ setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __ return err; } + +int +copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from) +{ + unsigned long tmp; + int err; + + if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t))) + return -EFAULT; + + err = __get_user(to->si_signo, &from->si_signo); + err |= __get_user(to->si_errno, &from->si_errno); + err |= __get_user(to->si_code, &from->si_code); + + if (to->si_code < 0) + err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); + else { + switch (to->si_code >> 16) { + case __SI_CHLD >> 16: + err |= __get_user(to->si_utime, &from->si_utime); + err |= __get_user(to->si_stime, &from->si_stime); + err |= __get_user(to->si_status, &from->si_status); + default: + err |= __get_user(to->si_pid, &from->si_pid); + err |= __get_user(to->si_uid, &from->si_uid); + break; + case __SI_FAULT >> 16: + err |= __get_user(tmp, &from->si_addr); + to->si_addr = (void __user *) tmp; + break; + case __SI_POLL >> 16: + err |= __get_user(to->si_band, &from->si_band); + err |= __get_user(to->si_fd, &from->si_fd); + break; + case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: + err |= __get_user(to->si_pid, &from->si_pid); + err |= __get_user(to->si_uid, &from->si_uid); + err |= __get_user(to->si_int, &from->si_int); + break; + } + } + return err; +} + +int +copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from) +{ + unsigned int addr; + int err; + + if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) + return -EFAULT; + + /* If you change siginfo_t structure, please be sure + this code is fixed accordingly. + It should never copy any pad contained in the structure + to avoid security leaks, but must copy the generic + 3 ints plus the relevant union member. + This routine must convert siginfo from 64bit to 32bit as well + at the same time. */ + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user((short)from->si_code, &to->si_code); + if (from->si_code < 0) + err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); + else { + switch (from->si_code >> 16) { + case __SI_CHLD >> 16: + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + err |= __put_user(from->si_status, &to->si_status); + default: + err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + break; + case __SI_FAULT >> 16: + /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */ + err |= __put_user(from->_sifields._pad[0], &to->si_addr); + break; + case __SI_POLL >> 16: + err |= __put_user(from->si_band, &to->si_band); + err |= __put_user(from->si_fd, &to->si_fd); + break; + case __SI_TIMER >> 16: + err |= __put_user(from->si_tid, &to->si_tid); + err |= __put_user(from->si_overrun, &to->si_overrun); + addr = (unsigned long) from->si_ptr; + err |= __put_user(addr, &to->si_ptr); + break; + case __SI_RT >> 16: /* Not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: + err |= __put_user(from->si_uid, &to->si_uid); + err |= __put_user(from->si_pid, &to->si_pid); + addr = (unsigned long) from->si_ptr; + err |= __put_user(addr, &to->si_ptr); + break; + } + } + return err; +} diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index 4d1569e717cc..e39b38a67a87 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h @@ -20,8 +20,34 @@ #define _PARISC64_KERNEL_SIGNAL32_H #include -#include -#include + +typedef compat_uptr_t compat_sighandler_t; + +typedef struct compat_sigaltstack { + compat_uptr_t ss_sp; + compat_int_t ss_flags; + compat_size_t ss_size; +} compat_stack_t; + +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +struct compat_sigaction { + compat_sighandler_t sa_handler; + compat_uint_t sa_flags; + compat_sigset_t sa_mask; /* mask last for extensibility */ +}; + +/* 32-bit ucontext as seen from an 64-bit kernel */ +struct compat_ucontext { + compat_uint_t uc_flags; + compat_uptr_t uc_link; + compat_stack_t uc_stack; /* struct compat_sigaltstack (12 bytes)*/ + /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */ + compat_uint_t pad[1]; + struct compat_sigcontext uc_mcontext; + compat_sigset_t uc_sigmask; /* mask last for extensibility */ +}; /* ELF32 signal handling */ @@ -29,6 +55,103 @@ struct k_sigaction32 { struct compat_sigaction sa; }; +typedef struct compat_siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[((128/sizeof(int)) - 3)]; + + /* kill() */ + struct { + unsigned int _pid; /* sender's pid */ + unsigned int _uid; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + compat_timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof(unsigned int) - sizeof(int)]; + compat_sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; + + /* POSIX.1b signals */ + struct { + unsigned int _pid; /* sender's pid */ + unsigned int _uid; /* sender's uid */ + compat_sigval_t _sigval; + } _rt; + + /* SIGCHLD */ + struct { + unsigned int _pid; /* which child */ + unsigned int _uid; /* sender's uid */ + int _status; /* exit code */ + compat_clock_t _utime; + compat_clock_t _stime; + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + unsigned int _addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} compat_siginfo_t; + +int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); +int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); + +/* In a deft move of uber-hackery, we decide to carry the top half of all + * 64-bit registers in a non-portable, non-ABI, hidden structure. + * Userspace can read the hidden structure if it *wants* but is never + * guaranteed to be in the same place. Infact the uc_sigmask from the + * ucontext_t structure may push the hidden register file downards + */ +struct compat_regfile { + /* Upper half of all the 64-bit registers that were truncated + on a copy to a 32-bit userspace */ + compat_int_t rf_gr[32]; + compat_int_t rf_iasq[2]; + compat_int_t rf_iaoq[2]; + compat_int_t rf_sar; +}; + +#define COMPAT_SIGRETURN_TRAMP 4 +#define COMPAT_SIGRESTARTBLOCK_TRAMP 5 +#define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \ + COMPAT_SIGRESTARTBLOCK_TRAMP) + +struct compat_rt_sigframe { + /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c + Secondary to that it must protect the ERESTART_RESTARTBLOCK + trampoline we left on the stack (we were bad and didn't + change sp so we could run really fast.) */ + compat_uint_t tramp[COMPAT_TRAMP_SIZE]; + compat_siginfo_t info; + struct compat_ucontext uc; + /* Hidden location of truncated registers, *must* be last. */ + struct compat_regfile regs; +}; + +/* + * The 32-bit ABI wants at least 48 bytes for a function call frame: + * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of + * which Linux/parisc uses is sp-20 for the saved return pointer...) + * Then, the stack pointer must be rounded to a cache line (64 bytes). + */ +#define SIGFRAME32 64 +#define FUNCTIONCALLFRAME32 48 +#define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32) + void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); int do_sigaltstack32 (const compat_stack_t __user *uss32, diff --git a/include/asm-parisc/compat_ucontext.h b/include/asm-parisc/compat_ucontext.h index a1228a3d2071..2f7292afde3c 100644 --- a/include/asm-parisc/compat_ucontext.h +++ b/include/asm-parisc/compat_ucontext.h @@ -1,8 +1,7 @@ #ifndef _ASM_PARISC_COMPAT_UCONTEXT_H #define _ASM_PARISC_COMPAT_UCONTEXT_H -#include -#include +#include /* 32-bit ucontext as seen from an 64-bit kernel */ struct compat_ucontext { diff --git a/include/asm-parisc/rt_sigframe.h b/include/asm-parisc/rt_sigframe.h index 5623c032b64c..f0dd3b30f6c4 100644 --- a/include/asm-parisc/rt_sigframe.h +++ b/include/asm-parisc/rt_sigframe.h @@ -1,10 +1,6 @@ #ifndef _ASM_PARISC_RT_SIGFRAME_H #define _ASM_PARISC_RT_SIGFRAME_H -#ifdef CONFIG_COMPAT -#include -#endif - #define SIGRETURN_TRAMP 4 #define SIGRESTARTBLOCK_TRAMP 5 #define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP) From 0820e15a35b3cf37caadf550ddb7c75a7a77afd0 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 23 Jan 2006 12:50:04 -0800 Subject: [PATCH 109/695] [CIFS] Do not zero non-existent iovec in SendReceive response processing. Could cause memory leak in some readpaths depending on what junk followed it in the stack. Signed-off-by: Steve French --- fs/cifs/transport.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 7b98792150ea..b12cb8a7da7c 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -498,7 +498,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, else *pRespBufType = CIFS_SMALL_BUFFER; iov[0].iov_len = receive_len + 4; - iov[1].iov_len = 0; dump_smb(midQ->resp_buf, 80); /* convert the length into a more usable form */ From e29054f92d7d575631691865c1b95bee5bc974cc Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:06:06 -0800 Subject: [PATCH 110/695] [BNX2]: Fix VLAN on ASF Always set up the device to strip incoming VLAN tags when ASF is enabled. ASF firmware will not parse packets correctly if VLAN tags are not stripped. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 10 +++++++--- drivers/net/bnx2.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 49fa1e4413fa..790dc926acae 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1916,11 +1916,11 @@ bnx2_set_rx_mode(struct net_device *dev) BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; #ifdef BCM_VLAN - if (!bp->vlgrp) { + if (!bp->vlgrp && !(bp->flags & ASF_ENABLE_FLAG)) rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; - } #else - rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; + if (!(bp->flags & ASF_ENABLE_FLAG)) + rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; #endif if (dev->flags & IFF_PROMISC) { /* Promiscuous mode. */ @@ -3218,6 +3218,10 @@ bnx2_init_chip(struct bnx2 *bp) REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE); + if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) & + BNX2_PORT_FEATURE_ASF_ENABLED) + bp->flags |= ASF_ENABLE_FLAG; + /* Initialize the receive filter. */ bnx2_set_rx_mode(bp->dev); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 76bb5f1a250b..8a70311d781f 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -3956,6 +3956,7 @@ struct bnx2 { #define NO_WOL_FLAG 8 #define USING_DAC_FLAG 0x10 #define USING_MSI_FLAG 0x20 +#define ASF_ENABLE_FLAG 0x40 u32 phy_flags; #define PHY_SERDES_FLAG 1 From b090ae2b59f3db57732340c6af3beceec8d6c148 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:07:10 -0800 Subject: [PATCH 111/695] [BNX2]: Improve handshake with firmware Improve handshake with bootcode with the following changes: 1. Increase timeout to 100msec and use msleep instead of udelay. 2. Add more error checking for timeouts and errors. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 44 +++++++++++++++++++++++--------------------- drivers/net/bnx2.h | 4 ++-- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 790dc926acae..3486324b6919 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1327,43 +1327,45 @@ bnx2_set_mac_loopback(struct bnx2 *bp) } static int -bnx2_fw_sync(struct bnx2 *bp, u32 msg_data) +bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent) { int i; u32 val; - if (bp->fw_timed_out) - return -EBUSY; - bp->fw_wr_seq++; msg_data |= bp->fw_wr_seq; REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); /* wait for an acknowledgement. */ - for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) { - udelay(5); + for (i = 0; i < (FW_ACK_TIME_OUT_MS / 10); i++) { + msleep(10); val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB); if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) break; } + if ((msg_data & BNX2_DRV_MSG_DATA) == BNX2_DRV_MSG_DATA_WAIT0) + return 0; /* If we timed out, inform the firmware that this is the case. */ - if (((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) && - ((msg_data & BNX2_DRV_MSG_DATA) != BNX2_DRV_MSG_DATA_WAIT0)) { + if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) { + if (!silent) + printk(KERN_ERR PFX "fw sync timeout, reset code = " + "%x\n", msg_data); msg_data &= ~BNX2_DRV_MSG_CODE; msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); - bp->fw_timed_out = 1; - return -EBUSY; } + if ((val & BNX2_FW_MSG_STATUS_MASK) != BNX2_FW_MSG_STATUS_OK) + return -EIO; + return 0; } @@ -2374,7 +2376,7 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; } - bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg); + bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 0); pmcsr &= ~PCI_PM_CTRL_STATE_MASK; if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || @@ -3014,16 +3016,14 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); udelay(5); + /* Wait for the firmware to tell us it is ok to issue a reset. */ + bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1); + /* Deposit a driver reset signature so the firmware knows that * this is a soft reset. */ REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE, BNX2_DRV_RESET_SIGNATURE_MAGIC); - bp->fw_timed_out = 0; - - /* Wait for the firmware to tell us it is ok to issue a reset. */ - bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code); - /* Do a dummy read to force the chip to complete all current transaction * before we issue a reset. */ val = REG_RD(bp, BNX2_MISC_ID); @@ -3062,10 +3062,10 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) return -ENODEV; } - bp->fw_timed_out = 0; - /* Wait for the firmware to finish its initialization. */ - bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code); + rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 0); + if (rc) + return rc; if (CHIP_ID(bp) == CHIP_ID_5706_A0) { /* Adjust the voltage regular to two steps lower. The default @@ -3083,6 +3083,7 @@ static int bnx2_init_chip(struct bnx2 *bp) { u32 val; + int rc; /* Make sure the interrupt is not active. */ REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT); @@ -3225,14 +3226,15 @@ bnx2_init_chip(struct bnx2 *bp) /* Initialize the receive filter. */ bnx2_set_rx_mode(bp->dev); - bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET); + rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET, + 0); REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff); REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS); udelay(20); - return 0; + return rc; } diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 8a70311d781f..a99b04143f69 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -3999,7 +3999,7 @@ struct bnx2 { u16 bus_speed_mhz; u8 wol; - u8 fw_timed_out; + u8 pad; u16 fw_wr_seq; u16 fw_drv_pulse_wr_seq; @@ -4173,7 +4173,7 @@ struct fw_info { * the firmware has timed out, the driver will assume there is no firmware * running and there won't be any firmware-driver synchronization during a * driver reset. */ -#define FW_ACK_TIME_OUT_MS 50 +#define FW_ACK_TIME_OUT_MS 100 #define BNX2_DRV_RESET_SIGNATURE 0x00000000 From dda1e390bf9e2889a3abc48590a015b307637753 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:08:14 -0800 Subject: [PATCH 112/695] [BNX2]: Misc. fixes Some misc. fixes for WoL, 5708 B1, and a typo '=' instead of '=='. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 20 ++++++++++++++------ drivers/net/bnx2.h | 1 + 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 3486324b6919..60ff9b6c929d 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1171,7 +1171,8 @@ bnx2_init_5708s_phy(struct bnx2 *bp) } if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || - (CHIP_ID(bp) == CHIP_ID_5708_B0)) { + (CHIP_ID(bp) == CHIP_ID_5708_B0) || + (CHIP_ID(bp) == CHIP_ID_5708_B1)) { /* increase tx signal amplitude */ bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_TX_MISC); @@ -2340,7 +2341,6 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) val |= BNX2_EMAC_MODE_PORT_MII | BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD | - BNX2_EMAC_MODE_FORCE_LINK | BNX2_EMAC_MODE_MPKT; REG_WR(bp, BNX2_EMAC_MODE, val); @@ -2376,7 +2376,8 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; } - bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 0); + if (!(bp->flags & NO_WOL_FLAG)) + bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 0); pmcsr &= ~PCI_PM_CTRL_STATE_MASK; if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || @@ -3099,7 +3100,7 @@ bnx2_init_chip(struct bnx2 *bp) val |= (0x2 << 20) | (1 << 11); - if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz = 133)) + if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz == 133)) val |= (1 << 23); if ((CHIP_NUM(bp) == CHIP_NUM_5706) && @@ -4473,7 +4474,9 @@ bnx2_close(struct net_device *dev) bnx2_netif_stop(bp); del_timer_sync(&bp->timer); - if (bp->wol) + if (bp->flags & NO_WOL_FLAG) + reset_code = BNX2_DRV_MSG_CODE_UNLOAD; + else if (bp->wol) reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL; else reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; @@ -5635,6 +5638,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) } } + if (CHIP_NUM(bp) == CHIP_NUM_5708) + bp->flags |= NO_WOL_FLAG; + if (CHIP_ID(bp) == CHIP_ID_5706_A0) { bp->tx_quick_cons_trip_int = bp->tx_quick_cons_trip; @@ -5818,7 +5824,9 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) bnx2_netif_stop(bp); netif_device_detach(dev); del_timer_sync(&bp->timer); - if (bp->wol) + if (bp->flags & NO_WOL_FLAG) + reset_code = BNX2_DRV_MSG_CODE_UNLOAD; + else if (bp->wol) reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL; else reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index a99b04143f69..95d7f3b2ee77 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -3987,6 +3987,7 @@ struct bnx2 { #define CHIP_ID_5706_A2 0x57060020 #define CHIP_ID_5708_A0 0x57080000 #define CHIP_ID_5708_B0 0x57081000 +#define CHIP_ID_5708_B1 0x57081010 #define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf) From ade2bfe7d1f0ea804d2e63209cc6318ad8bf17ae Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:09:51 -0800 Subject: [PATCH 113/695] [BNX2]: Fix UDP checksum verification Fix TCP/UDP checksum verification. Use status bits in the buffer descriptor instead of the checksum value to verify rx checksum. Using the checksum value will be incorrect if the UDP packet has zero in the UDP checksum field. Firmware update required for this fix. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 12 +- drivers/net/bnx2.h | 22 +- drivers/net/bnx2_fw.h | 833 ++++++++++++++++++++++-------------------- 3 files changed, 444 insertions(+), 423 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 60ff9b6c929d..ec08f833c32d 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1660,7 +1660,7 @@ bnx2_rx_int(struct bnx2 *bp, int budget) rmb(); while (sw_cons != hw_cons) { unsigned int len; - u16 status; + u32 status; struct sw_bd *rx_buf; struct sk_buff *skb; @@ -1676,7 +1676,7 @@ bnx2_rx_int(struct bnx2 *bp, int budget) rx_hdr = (struct l2_fhdr *) skb->data; len = rx_hdr->l2_fhdr_pkt_len - 4; - if (rx_hdr->l2_fhdr_errors & + if ((status = rx_hdr->l2_fhdr_status) & (L2_FHDR_ERRORS_BAD_CRC | L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT | @@ -1735,15 +1735,13 @@ reuse_rx: } - status = rx_hdr->l2_fhdr_status; skb->ip_summed = CHECKSUM_NONE; if (bp->rx_csum && (status & (L2_FHDR_STATUS_TCP_SEGMENT | L2_FHDR_STATUS_UDP_DATAGRAM))) { - u16 cksum = rx_hdr->l2_fhdr_tcp_udp_xsum; - - if (cksum == 0xffff) + if (likely((status & (L2_FHDR_ERRORS_TCP_XSUM | + L2_FHDR_ERRORS_UDP_XSUM)) == 0)) skb->ip_summed = CHECKSUM_UNNECESSARY; } @@ -3978,7 +3976,7 @@ bnx2_test_loopback(struct bnx2 *bp) pci_unmap_addr(rx_buf, mapping), bp->rx_buf_size, PCI_DMA_FROMDEVICE); - if (rx_hdr->l2_fhdr_errors & + if (rx_hdr->l2_fhdr_status & (L2_FHDR_ERRORS_BAD_CRC | L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT | diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 95d7f3b2ee77..ea70bbcd2542 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -277,19 +277,7 @@ struct statistics_block { * l2_fhdr definition */ struct l2_fhdr { -#if defined(__BIG_ENDIAN) - u16 l2_fhdr_errors; - u16 l2_fhdr_status; -#elif defined(__LITTLE_ENDIAN) - u16 l2_fhdr_status; - u16 l2_fhdr_errors; -#endif - #define L2_FHDR_ERRORS_BAD_CRC (1<<1) - #define L2_FHDR_ERRORS_PHY_DECODE (1<<2) - #define L2_FHDR_ERRORS_ALIGNMENT (1<<3) - #define L2_FHDR_ERRORS_TOO_SHORT (1<<4) - #define L2_FHDR_ERRORS_GIANT_FRAME (1<<5) - + u32 l2_fhdr_status; #define L2_FHDR_STATUS_RULE_CLASS (0x7<<0) #define L2_FHDR_STATUS_RULE_P2 (1<<3) #define L2_FHDR_STATUS_RULE_P3 (1<<4) @@ -301,6 +289,14 @@ struct l2_fhdr { #define L2_FHDR_STATUS_TCP_SEGMENT (1<<14) #define L2_FHDR_STATUS_UDP_DATAGRAM (1<<15) + #define L2_FHDR_ERRORS_BAD_CRC (1<<17) + #define L2_FHDR_ERRORS_PHY_DECODE (1<<18) + #define L2_FHDR_ERRORS_ALIGNMENT (1<<19) + #define L2_FHDR_ERRORS_TOO_SHORT (1<<20) + #define L2_FHDR_ERRORS_GIANT_FRAME (1<<21) + #define L2_FHDR_ERRORS_TCP_XSUM (1<<28) + #define L2_FHDR_ERRORS_UDP_XSUM (1<<31) + u32 l2_fhdr_hash; #if defined(__BIG_ENDIAN) u16 l2_fhdr_pkt_len; diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h index ab07a4900e9a..f6982c38019c 100644 --- a/drivers/net/bnx2_fw.h +++ b/drivers/net/bnx2_fw.h @@ -978,20 +978,20 @@ static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x0 }; static int bnx2_RXP_b06FwReleaseMajor = 0x1; static int bnx2_RXP_b06FwReleaseMinor = 0x0; static int bnx2_RXP_b06FwReleaseFix = 0x0; -static u32 bnx2_RXP_b06FwStartAddr = 0x08003104; +static u32 bnx2_RXP_b06FwStartAddr = 0x08003184; static u32 bnx2_RXP_b06FwTextAddr = 0x08000000; -static int bnx2_RXP_b06FwTextLen = 0x562c; -static u32 bnx2_RXP_b06FwDataAddr = 0x08005660; +static int bnx2_RXP_b06FwTextLen = 0x588c; +static u32 bnx2_RXP_b06FwDataAddr = 0x080058e0; static int bnx2_RXP_b06FwDataLen = 0x0; -static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000; -static int bnx2_RXP_b06FwRodataLen = 0x0; -static u32 bnx2_RXP_b06FwBssAddr = 0x08005680; -static int bnx2_RXP_b06FwBssLen = 0x1394; -static u32 bnx2_RXP_b06FwSbssAddr = 0x08005660; -static int bnx2_RXP_b06FwSbssLen = 0x18; -static u32 bnx2_RXP_b06FwText[(0x562c/4) + 1] = { - 0x0a000c41, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x322e352e, - 0x38000000, 0x02050803, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, +static u32 bnx2_RXP_b06FwRodataAddr = 0x08005890; +static int bnx2_RXP_b06FwRodataLen = 0x28; +static u32 bnx2_RXP_b06FwBssAddr = 0x08005900; +static int bnx2_RXP_b06FwBssLen = 0x13a4; +static u32 bnx2_RXP_b06FwSbssAddr = 0x080058e0; +static int bnx2_RXP_b06FwSbssLen = 0x1c; +static u32 bnx2_RXP_b06FwText[(0x588c/4) + 1] = { + 0x0a000c61, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x322e362e, + 0x31000000, 0x02060103, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -1513,408 +1513,435 @@ static u32 bnx2_RXP_b06FwText[(0x562c/4) + 1] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425660, - 0x3c030800, 0x24636a14, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004, - 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x26103104, 0x3c1c0800, - 0x279c5660, 0x0e001035, 0x00000000, 0x0000000d, 0x3c080800, 0x8d023100, - 0x2c420080, 0x50400001, 0xad003100, 0x8d073100, 0x3c040800, 0x24840100, - 0x8f460100, 0x00071840, 0x00671821, 0x00031940, 0x00641021, 0xac460000, - 0x8f450104, 0x00831021, 0xac450004, 0x8f460108, 0xac460008, 0x8f45010c, - 0xac45000c, 0x8f460114, 0xac460010, 0x8f450118, 0xac450014, 0x8f460124, - 0xac460018, 0x8f450128, 0xac45001c, 0x8f464010, 0xac460020, 0x8f454014, - 0xac450024, 0x8f464018, 0xac460028, 0x8f45401c, 0xac45002c, 0x8f464020, - 0xac460030, 0x8f454024, 0xac450034, 0x8f464028, 0xac460038, 0x8f45402c, - 0xac45003c, 0x8f464030, 0xac460040, 0x8f454034, 0xac450044, 0x8f464038, - 0xac460048, 0x8f45403c, 0xac45004c, 0x8f464040, 0xac460050, 0x8f454044, - 0xac450054, 0x8f464048, 0xac460058, 0x8f45404c, 0x24e70001, 0x00402021, - 0xad073100, 0x03e00008, 0xac85005c, 0x8f820004, 0x9743010c, 0x00804821, - 0x00403021, 0x30421000, 0x10400010, 0x306affff, 0x30c20020, 0x1440000e, - 0x24070005, 0x3c021000, 0x00c21024, 0x10400009, 0x3c030dff, 0x3463ffff, - 0x3c020e00, 0x00c21024, 0x0062182b, 0x50600004, 0x24070001, 0x0a000cb1, - 0x3c020800, 0x24070001, 0x3c020800, 0x8c430034, 0x1460001d, 0x00405821, - 0x8f820010, 0x30424000, 0x1440001a, 0x3c020001, 0x3c021f01, 0x00c24024, - 0x3c031000, 0x15030015, 0x3c020001, 0x31420200, 0x54400012, 0x3c020001, - 0x9744010e, 0x24020003, 0xa342018b, 0x97850012, 0x24020002, 0x34e30002, - 0xaf400180, 0xa742018c, 0xa7430188, 0x24840004, 0x30a5bfff, 0xa744018e, - 0xa74501a6, 0xaf4801b8, 0x03e00008, 0x00001021, 0x3c020001, 0x00c21024, - 0x10400039, 0x00000000, 0x9742010e, 0x3c038000, 0x3046ffff, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c, - 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005, - 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000cec, 0x00021400, 0x9743011e, - 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x24020003, - 0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc, 0x005a1021, - 0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000, 0x3c02ffff, - 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, - 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, - 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f820010, 0x30434000, - 0x10600016, 0x00404021, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000, - 0x93420116, 0x34424000, 0x03421821, 0x94650002, 0x2ca21389, 0x1040000b, - 0x3c020800, 0x24425680, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f, - 0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01244825, 0x11200039, - 0x3c021000, 0x9742010e, 0x34e70002, 0x3c038000, 0x24420004, 0x3046ffff, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, - 0x8f85000c, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, - 0x10a00005, 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000d41, 0x00021400, - 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, - 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, - 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, - 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, - 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, - 0xaf4201b8, 0x03e00008, 0x00001021, 0x00c21024, 0x104000e3, 0x3c020800, - 0x8c430030, 0x10600040, 0x31024000, 0x1040003e, 0x3c030f00, 0x00c31824, - 0x3c020100, 0x0043102b, 0x1440003a, 0x3c030800, 0x9742010e, 0x34e70002, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, + 0x3c020800, 0x244258e0, 0x3c030800, 0x24636ca4, 0xac400000, 0x0043202b, + 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, + 0x26103184, 0x3c1c0800, 0x279c58e0, 0x0e00104a, 0x00000000, 0x0000000d, + 0x27bdffe8, 0xafb00010, 0xafbf0014, 0x0e000f1d, 0x00808021, 0x1440000d, + 0x00000000, 0x8f820010, 0x10400005, 0x00000000, 0x9743011c, 0x9742011e, + 0x0a000c89, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, + 0xaf830004, 0x8f840008, 0x3c020020, 0x34424000, 0x00821824, 0x54620004, + 0x3c020020, 0x8f820014, 0x0a000c9a, 0x34421000, 0x34428000, 0x00821824, + 0x14620004, 0x00000000, 0x8f820014, 0x34428000, 0xaf820014, 0x8f820008, + 0x9743010c, 0x00403021, 0x30421000, 0x10400010, 0x3069ffff, 0x30c20020, + 0x1440000e, 0x24070005, 0x3c021000, 0x00c21024, 0x10400009, 0x3c030dff, + 0x3463ffff, 0x3c020e00, 0x00c21024, 0x0062182b, 0x50600004, 0x24070001, + 0x0a000cb2, 0x3c020800, 0x24070001, 0x3c020800, 0x8c430034, 0x1460001d, + 0x00405821, 0x8f820014, 0x30424000, 0x1440001a, 0x3c020001, 0x3c021f01, + 0x00c24024, 0x3c031000, 0x15030015, 0x3c020001, 0x31220200, 0x14400012, + 0x3c020001, 0x9744010e, 0x24020003, 0xa342018b, 0x97850016, 0x24020002, + 0x34e30002, 0xaf400180, 0xa742018c, 0xa7430188, 0x24840004, 0x30a5bfff, + 0xa744018e, 0xa74501a6, 0xaf4801b8, 0x0a000f19, 0x00001021, 0x3c020001, + 0x00c21024, 0x1040002f, 0x00000000, 0x9742010e, 0x3c038000, 0x3046ffff, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9784000a, + 0x8f850004, 0x8f870014, 0x24020080, 0x24030002, 0xaf420180, 0x24020003, + 0xa743018c, 0xa746018e, 0xa7420188, 0x30e28000, 0xa7440190, 0x1040000c, + 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, + 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00e21024, 0xaf820014, + 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, + 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, + 0x00001021, 0x8f820014, 0x30434000, 0x10600016, 0x00404021, 0x3c020f00, + 0x00c21024, 0x14400012, 0x00000000, 0x93420116, 0x34424000, 0x03421821, + 0x94650002, 0x2ca21389, 0x1040000b, 0x3c020800, 0x24425900, 0x00051942, + 0x00031880, 0x00621821, 0x30a5001f, 0x8c640000, 0x24020001, 0x00a21004, + 0x00822024, 0x02048025, 0x12000030, 0x3c021000, 0x9742010e, 0x34e80002, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c, 0x24020080, 0x24030002, - 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005, 0xa7440190, 0x9743011c, - 0x9742011e, 0x0a000d86, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, - 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, - 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, - 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, - 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, - 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, - 0x3c030800, 0x8c620024, 0x30420008, 0x1040003e, 0x34e80002, 0x3c020f00, - 0x00c21024, 0x1440003b, 0x8d620034, 0x31420200, 0x10400038, 0x8d620034, - 0x9742010e, 0x30e7fffb, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c, - 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005, - 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000dca, 0x00021400, 0x9743011e, - 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, - 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, - 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, - 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, - 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, - 0x8d620034, 0x8f860004, 0x1040001a, 0x30c20100, 0x10400018, 0x3c020f00, - 0x00c21024, 0x3c030200, 0x10430014, 0x00000000, 0x8f82000c, 0x10400004, - 0x00000000, 0x9742011c, 0x0a000df8, 0x3044ffff, 0x9742011e, 0x3044ffff, - 0x3c030800, 0x8c620038, 0x3c030800, 0x2463003c, 0x2442ffff, 0x00822024, - 0x00831821, 0x90620000, 0x24420004, 0x0a000e0d, 0x000229c0, 0x00000000, - 0x00061602, 0x3042000f, 0x000229c0, 0x3c04fc00, 0x00441021, 0x3c030300, - 0x0062182b, 0x50600001, 0x24050800, 0x9742010e, 0x3107ffff, 0x3c038000, + 0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020180, + 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000, + 0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, + 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, + 0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, + 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, + 0xaf4201b8, 0x0a000f19, 0x00001021, 0x00c21024, 0x104000c0, 0x3c020800, + 0x8c430030, 0x10600037, 0x31024000, 0x10400035, 0x3c030f00, 0x00c31824, + 0x3c020100, 0x0043102b, 0x14400031, 0x3c030800, 0x9742010e, 0x34e80002, + 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020080, + 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000, + 0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, + 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, + 0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, + 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, + 0xaf4201b8, 0x0a000f19, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008, + 0x10400035, 0x34ea0002, 0x3c020f00, 0x00c21024, 0x14400032, 0x8d620034, + 0x31220200, 0x1040002f, 0x8d620034, 0x9742010e, 0x30e8fffb, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, - 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf450180, 0xa742018c, - 0xa746018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a000e26, - 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, - 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, - 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, - 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, - 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, - 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100, - 0x104000f9, 0x3c020800, 0x8c440024, 0x24030001, 0x14830038, 0x00404821, - 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97830006, 0x8f84000c, - 0x24020002, 0xaf400180, 0xa742018c, 0xa745018e, 0x10800005, 0xa7430190, - 0x9743011c, 0x9742011e, 0x0a000e65, 0x00021400, 0x9743011e, 0x9742011c, - 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, - 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, - 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, - 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, - 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, - 0x00001021, 0x30820001, 0x10400037, 0x30ea0004, 0x9742010e, 0x30e8fffb, - 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x24020003, 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf400180, - 0xa742018c, 0xa745018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, - 0x0a000e9f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, - 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, - 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, - 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, - 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, - 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x3107ffff, 0x8d220024, 0x30420004, - 0x10400039, 0x8d220024, 0x9742010e, 0x30e8fffb, 0x3c038000, 0x24420004, - 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, - 0x97840006, 0x8f85000c, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c, - 0xa746018e, 0x10a00005, 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000eda, - 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, - 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, - 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, - 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, - 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, - 0x3c021000, 0xaf4201b8, 0x3107ffff, 0x8d220024, 0x30420008, 0x10400036, - 0x00000000, 0x9742010e, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c, - 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005, - 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000f14, 0x00021400, 0x9743011e, - 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, - 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, - 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, - 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, + 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020180, 0x24030002, + 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000, 0xa7440190, + 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, + 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00e21024, + 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, - 0x1540004a, 0x00001021, 0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024, - 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b, 0xa4800010, - 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800, 0x8c620024, - 0x30420001, 0x10400037, 0x00001021, 0x9742010e, 0x34e60002, 0x3c038000, - 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, - 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf400180, 0xa742018c, - 0xa745018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a000f5e, - 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, - 0x8f840010, 0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, + 0x8d620034, 0x8f860008, 0x10400012, 0x30c20100, 0x10400010, 0x3c020f00, + 0x00c21024, 0x3c030200, 0x1043000c, 0x3c020800, 0x8c430038, 0x8f840004, + 0x3c020800, 0x2442003c, 0x2463ffff, 0x00832024, 0x00822021, 0x90830000, + 0x24630004, 0x0a000de1, 0x000329c0, 0x00000000, 0x00061602, 0x3042000f, + 0x000229c0, 0x3c04fc00, 0x00441021, 0x3c030300, 0x0062182b, 0x50600001, + 0x24050800, 0x9742010e, 0x3148ffff, 0x3c038000, 0x24420004, 0x3046ffff, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a, + 0x8f840004, 0x8f870014, 0x24020002, 0xaf450180, 0xa742018c, 0xa746018e, + 0xa7480188, 0x30e28000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116, + 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, + 0x3c02ffff, 0x34427fff, 0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, + 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, + 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x8f424000, + 0x30420100, 0x104000d5, 0x3c020800, 0x8c440024, 0x24030001, 0x1483002f, + 0x00405021, 0x9742010e, 0x34e70002, 0x3c038000, 0x24420004, 0x3045ffff, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a, + 0x8f840004, 0x8f860014, 0x24020002, 0xaf400180, 0xa742018c, 0xa745018e, + 0xa7470188, 0x30c28000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116, + 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, + 0x3c02ffff, 0x34427fff, 0x00c21024, 0xaf820014, 0x97820016, 0x9743010c, + 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, + 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x30820001, + 0x1040002e, 0x30eb0004, 0x9742010e, 0x30e9fffb, 0x3c038000, 0x24420004, + 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, + 0x9783000a, 0x8f840004, 0x8f860014, 0x24020002, 0xaf400180, 0xa742018c, + 0xa745018e, 0xa7470188, 0x30c28000, 0xa7430190, 0x1040000c, 0xaf4401a8, + 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, + 0x14600004, 0x3c02ffff, 0x34427fff, 0x00c21024, 0xaf820014, 0x97820016, + 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, + 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x3127ffff, 0x8d420024, + 0x30420004, 0x10400030, 0x8d420024, 0x9742010e, 0x30e9fffb, 0x3c038000, + 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, + 0xa342018b, 0x9784000a, 0x8f850004, 0x8f880014, 0x24020100, 0x24030002, + 0xaf420180, 0xa743018c, 0xa746018e, 0xa7470188, 0x31028000, 0xa7440190, + 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, + 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x01021024, + 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, + 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, + 0x3127ffff, 0x8d420024, 0x30420008, 0x1040002d, 0x00000000, 0x9742010e, + 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f880014, 0x24020180, + 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7470188, 0x31028000, + 0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, + 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, + 0x01021024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, + 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, + 0xaf4201b8, 0x15600041, 0x00001021, 0x27440180, 0x3c038000, 0x8f4201b8, + 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b, + 0xa4800010, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x3c030800, + 0x8c620024, 0x30420001, 0x1040002e, 0x00001021, 0x9742010e, 0x34e70002, + 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x24020003, 0xa342018b, 0x9783000a, 0x8f840004, 0x8f860014, 0x24020002, + 0xaf400180, 0xa742018c, 0xa745018e, 0xa7470188, 0x30c28000, 0xa7430190, + 0x1040000c, 0xaf4401a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, + 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00c21024, + 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, + 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, + 0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x8f4b0070, + 0x93420112, 0x8f840008, 0x00022882, 0x30820100, 0x14400003, 0x24a30003, + 0x03e00008, 0x00001021, 0x30824000, 0x10400010, 0x27424000, 0x00031880, + 0x00431021, 0x8c470000, 0x24a30004, 0x00031880, 0x27424000, 0x00431021, + 0x8c490000, 0x93430116, 0x27424000, 0x306300fc, 0x00431021, 0x8c4a0000, + 0x0a000f45, 0x3c030800, 0x30822000, 0x1040ffea, 0x00031880, 0x27424000, + 0x00431021, 0x8c470000, 0x24a30004, 0x00031880, 0x27424000, 0x00431021, + 0x8c490000, 0x00005021, 0x3c030800, 0x24680100, 0x00071602, 0x00021080, + 0x00481021, 0x8c460000, 0x00071b82, 0x306303fc, 0x01031821, 0x8c640400, + 0x00071182, 0x304203fc, 0x01021021, 0x8c450800, 0x30e300ff, 0x00031880, + 0x01031821, 0x00091602, 0x00021080, 0x01021021, 0x00c43026, 0x8c640c00, + 0x8c431000, 0x00c53026, 0x00091382, 0x304203fc, 0x01021021, 0x8c451400, + 0x312200ff, 0x00021080, 0x01021021, 0x00c43026, 0x00c33026, 0x00091982, + 0x306303fc, 0x01031821, 0x8c641800, 0x8c431c00, 0x00c53026, 0x00c43026, + 0x11400015, 0x00c33026, 0x000a1602, 0x00021080, 0x01021021, 0x8c432000, + 0x000a1382, 0x304203fc, 0x01021021, 0x8c452400, 0x314200ff, 0x00021080, + 0x01021021, 0x00c33026, 0x000a1982, 0x306303fc, 0x01031821, 0x8c642800, + 0x8c432c00, 0x00c53026, 0x00c43026, 0x00c33026, 0x8f430070, 0x3c050800, + 0x8ca43100, 0x2c820020, 0x10400008, 0x006b5823, 0x3c020800, 0x24423104, + 0x00041880, 0x00621821, 0x24820001, 0xac6b0000, 0xaca23100, 0xaf860004, + 0x03e00008, 0x24020001, 0x27bdffe8, 0xafbf0010, 0x8f460128, 0x8f840010, + 0xaf460020, 0x8f450104, 0x8f420100, 0x24030800, 0xaf850008, 0xaf820014, + 0xaf4301b8, 0x1080000a, 0x3c020800, 0x8c430034, 0x10600007, 0x30a22000, + 0x10400005, 0x34a30100, 0x8f82000c, 0xaf830008, 0x24420001, 0xaf82000c, + 0x3c020800, 0x8c4300c0, 0x10600006, 0x3c030800, 0x8c6200c4, 0x24040001, + 0x24420001, 0x0a000fd5, 0xac6200c4, 0x8f820008, 0x3c030010, 0x00431024, + 0x14400009, 0x3c02001f, 0x3c030800, 0x8c620020, 0x00002021, 0x24420001, + 0x0e000c78, 0xac620020, 0x0a000fd5, 0x00402021, 0x3442ff00, 0x14c20009, + 0x2403bfff, 0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e000c78, + 0xac620020, 0x0a000fd5, 0x00402021, 0x8f820014, 0x00431024, 0x14400006, + 0x00000000, 0xaf400048, 0x0e0011a9, 0xaf400040, 0x0a000fd5, 0x00402021, + 0x0e001563, 0x00000000, 0x00402021, 0x10800005, 0x3c024000, 0x8f430124, + 0x3c026020, 0xac430014, 0x3c024000, 0xaf420138, 0x00000000, 0x8fbf0010, + 0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0xafb00010, + 0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000, 0x00621824, 0x3c023000, + 0x10620021, 0x0043102b, 0x14400006, 0x3c024000, 0x3c022000, 0x10620009, + 0x3c024000, 0x0a001040, 0x00000000, 0x10620045, 0x3c025000, 0x10620047, + 0x3c024000, 0x0a001040, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8, + 0x00431024, 0x1440fffd, 0x00000000, 0x8f420148, 0x24030002, 0xa083000b, + 0x00021402, 0xa4820008, 0x8f430148, 0xa4830010, 0x8f420144, 0x3c031000, + 0xac820024, 0xaf4301b8, 0x0a001040, 0x3c024000, 0x8f420148, 0x24030002, + 0x3044ffff, 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, + 0x10400005, 0x24020003, 0x0600001d, 0x36053000, 0x0a001027, 0x3c038000, + 0x12020007, 0x00000000, 0x0a001034, 0x00000000, 0x0e00112c, 0x00000000, + 0x0a001025, 0x00402021, 0x0e00113e, 0x00000000, 0x00402021, 0x36053000, + 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, + 0xa222000b, 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, + 0x0a001040, 0x3c024000, 0x0000000d, 0x00000000, 0x240002bf, 0x0a001040, + 0x3c024000, 0x0e001441, 0x00000000, 0x0a001040, 0x3c024000, 0x0e0015ea, + 0x00000000, 0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014, + 0x8fb00010, 0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8, + 0x27bdffe8, 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, + 0x2403ff7f, 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, + 0x3c020008, 0xaf430008, 0x8e040808, 0x0342d825, 0x8e020808, 0x3c030800, + 0xac600020, 0x3084fff0, 0x2c840001, 0x3042fff0, 0x38420010, 0x2c420001, + 0xaf840010, 0xaf820000, 0x0e00160c, 0x00000000, 0x0e001561, 0x00000000, + 0x3c020400, 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, + 0x8e021980, 0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd, + 0x32020001, 0x10400004, 0x32020002, 0x0e000f92, 0x00000000, 0x32020002, + 0x1040fff6, 0x00000000, 0x0e000fe0, 0x00000000, 0x0a001071, 0x00000000, + 0x27bdffe8, 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, + 0x2403ff7f, 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, + 0x3c020008, 0xaf430008, 0x8e040808, 0x0342d825, 0x8e020808, 0x3c030800, + 0xac600020, 0x3084fff0, 0x2c840001, 0x3042fff0, 0x38420010, 0x2c420001, + 0xaf840010, 0xaf820000, 0x0e00160c, 0x00000000, 0x0e001561, 0x00000000, + 0x3c020400, 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, + 0x8e021980, 0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008, + 0x27bd0018, 0x00804821, 0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a, + 0x8f840004, 0x8f880014, 0xaf490180, 0xa745018c, 0xa746018e, 0xa7470188, + 0x31028000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, - 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, + 0x34427fff, 0x01021024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, - 0x3c021000, 0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe8, - 0xafbf0010, 0x8f460128, 0x8f84000c, 0xaf460020, 0x8f450104, 0x8f420100, - 0x24030800, 0xaf850004, 0xaf820010, 0xaf4301b8, 0x1080000a, 0x3c020800, - 0x8c430034, 0x10600007, 0x30a22000, 0x10400005, 0x34a30100, 0x8f820008, - 0xaf830004, 0x24420001, 0xaf820008, 0x3c020800, 0x8c4300c0, 0x10600006, - 0x3c030800, 0x8c6200c4, 0x24040001, 0x24420001, 0x0a000fc0, 0xac6200c4, - 0x8f820004, 0x3c030010, 0x00431024, 0x14400009, 0x3c02001f, 0x3c030800, - 0x8c620020, 0x00002021, 0x24420001, 0x0e000c99, 0xac620020, 0x0a000fc0, - 0x00402021, 0x3442ff00, 0x14c20009, 0x2403bfff, 0x3c030800, 0x8c620020, - 0x24040001, 0x24420001, 0x0e000c99, 0xac620020, 0x0a000fc0, 0x00402021, - 0x8f820010, 0x00431024, 0x14400006, 0x00000000, 0xaf400048, 0x0e001144, - 0xaf400040, 0x0a000fc0, 0x00402021, 0x0e0014c9, 0x00000000, 0x00402021, - 0x10800005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000, - 0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0, - 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148, - 0x3c027000, 0x00621824, 0x3c023000, 0x10620021, 0x0043102b, 0x14400006, - 0x3c024000, 0x3c022000, 0x10620009, 0x3c024000, 0x0a00102b, 0x00000000, - 0x10620045, 0x3c025000, 0x10620047, 0x3c024000, 0x0a00102b, 0x00000000, + 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, + 0xa083000b, 0xa4800010, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420148, 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148, - 0xa4830010, 0x8f420144, 0x3c031000, 0xac820024, 0xaf4301b8, 0x0a00102b, - 0x3c024000, 0x8f420148, 0x24030002, 0x3044ffff, 0x00021402, 0x305000ff, - 0x1203000c, 0x27510180, 0x2a020003, 0x10400005, 0x24020003, 0x0600001d, - 0x36053000, 0x0a001012, 0x3c038000, 0x12020007, 0x00000000, 0x0a00101f, - 0x00000000, 0x0e00111f, 0x00000000, 0x0a001010, 0x00402021, 0x0e001131, - 0x00000000, 0x00402021, 0x36053000, 0x3c038000, 0x8f4201b8, 0x00431024, - 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, 0xa6240010, 0x8f420144, - 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00102b, 0x3c024000, 0x0000000d, - 0x00000000, 0x24000295, 0x0a00102b, 0x3c024000, 0x0e0013a7, 0x00000000, - 0x0a00102b, 0x3c024000, 0x0e001552, 0x00000000, 0x3c024000, 0xaf420178, - 0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, - 0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8, 0x3c04600c, 0xafbf0014, - 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x3c106000, 0x00431024, - 0x3442380c, 0x24030003, 0xac825000, 0x3c020008, 0xaf430008, 0x8e040808, - 0x0342d825, 0x8e020808, 0x3c030800, 0xac600020, 0x3084fff0, 0x2c840001, - 0x3042fff0, 0x38420010, 0x2c420001, 0xaf84000c, 0xaf820000, 0x0e001574, - 0x00000000, 0x0e0014c7, 0x00000000, 0x3c020400, 0x3442000c, 0x3c03ffff, - 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 0x34420200, 0xae021980, - 0x8f500000, 0x32020003, 0x1040fffd, 0x32020001, 0x10400004, 0x32020002, - 0x0e000f7d, 0x00000000, 0x32020002, 0x1040fff6, 0x00000000, 0x0e000fcb, - 0x00000000, 0x0a00105c, 0x00000000, 0x27bdffe8, 0x3c04600c, 0xafbf0014, - 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x3c106000, 0x00431024, - 0x3442380c, 0x24030003, 0xac825000, 0x3c020008, 0xaf430008, 0x8e040808, - 0x0342d825, 0x8e020808, 0x3c030800, 0xac600020, 0x3084fff0, 0x2c840001, - 0x3042fff0, 0x38420010, 0x2c420001, 0xaf84000c, 0xaf820000, 0x0e001574, - 0x00000000, 0x0e0014c7, 0x00000000, 0x3c020400, 0x3442000c, 0x3c03ffff, - 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 0x8fbf0014, 0x34420200, - 0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x30a5ffff, 0x30c6ffff, - 0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, - 0xa342018b, 0x97830006, 0x8f82000c, 0xaf440180, 0xa745018c, 0xa746018e, - 0x10400005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a0010ad, 0x00021400, - 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, - 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, - 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, - 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, - 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, - 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b, - 0xa4800010, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, - 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420148, - 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148, 0xa4830010, - 0x8f420144, 0x3c031000, 0xac820024, 0x03e00008, 0xaf4301b8, 0x27bdffe0, - 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, 0x3044ffff, - 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, 0x10400005, - 0x24020003, 0x0600001d, 0x36053000, 0x0a00110a, 0x3c038000, 0x12020007, - 0x00000000, 0x0a001117, 0x00000000, 0x0e00111f, 0x00000000, 0x0a001108, - 0x00402021, 0x0e001131, 0x00000000, 0x00402021, 0x36053000, 0x3c038000, - 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, - 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00111b, - 0x8fbf0018, 0x0000000d, 0x00000000, 0x24000295, 0x8fbf0018, 0x8fb10014, - 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, 0x1040000d, - 0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821, - 0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, 0x03e00008, - 0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, 0x1040000e, - 0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821, - 0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, 0x00832024, - 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0xafbf0048, - 0x93620023, 0x30420010, 0x1440025b, 0x24020001, 0x93420116, 0x93630005, - 0x34424000, 0x30630001, 0x14600005, 0x03425821, 0x0e001548, 0x00000000, - 0x0a0013a5, 0x8fbf0048, 0x93420112, 0x8f430104, 0x3c040020, 0x34424000, - 0x00641824, 0x10600012, 0x03422821, 0x27450180, 0x3c038000, 0x8f4201b8, + 0xa4830010, 0x8f420144, 0x3c031000, 0xac820024, 0x03e00008, 0xaf4301b8, + 0x27bdffe0, 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, + 0x3044ffff, 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, + 0x10400005, 0x24020003, 0x0600001d, 0x36053000, 0x0a001117, 0x3c038000, + 0x12020007, 0x00000000, 0x0a001124, 0x00000000, 0x0e00112c, 0x00000000, + 0x0a001115, 0x00402021, 0x0e00113e, 0x00000000, 0x00402021, 0x36053000, + 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, + 0xa222000b, 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, + 0x0a001128, 0x8fbf0018, 0x0000000d, 0x00000000, 0x240002bf, 0x8fbf0018, + 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, + 0x1040000d, 0x00001021, 0x3c030800, 0x24635900, 0x00042942, 0x00052880, + 0x00a32821, 0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, + 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, + 0x1040000e, 0x00001021, 0x3c030800, 0x24635900, 0x00042942, 0x00052880, + 0x00a32821, 0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, + 0x00832024, 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x9482000c, + 0x24870014, 0x00021302, 0x00021080, 0x00824021, 0x00e8182b, 0x1060004f, + 0x00000000, 0x90e30000, 0x2c620009, 0x10400047, 0x3c020800, 0x24425890, + 0x00031880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000, 0x0a0011a4, + 0x24e70001, 0x90e30001, 0x2402000a, 0x54620024, 0x01003821, 0x01071023, + 0x2c42000a, 0x54400020, 0x01003821, 0x3c050800, 0x8ca26c98, 0x24e70002, + 0x34420100, 0xaca26c98, 0x90e30000, 0x90e20001, 0x90e40002, 0x90e60003, + 0x24e70004, 0x24a56c98, 0x00031e00, 0x00021400, 0x00621825, 0x00042200, + 0x00641825, 0x00661825, 0xaca30004, 0x90e20000, 0x90e30001, 0x90e40002, + 0x90e60003, 0x24e70004, 0x00021600, 0x00031c00, 0x00431025, 0x00042200, + 0x00441025, 0x00461025, 0x0a0011a4, 0xaca20008, 0x90e30001, 0x24020004, + 0x1062000e, 0x00601021, 0x0a00119e, 0x01001021, 0x90e30001, 0x24020003, + 0x10620008, 0x00601021, 0x0a00119e, 0x01001021, 0x90e30001, 0x24020002, + 0x14620003, 0x01001021, 0x00601021, 0x00e21021, 0x0a0011a4, 0x00403821, + 0x90e20001, 0x0a0011a4, 0x00e23821, 0x01003821, 0x00e8102b, 0x5440ffb4, + 0x90e30000, 0x03e00008, 0x24020001, 0x27bdff90, 0x3c030800, 0xafbf006c, + 0xafbe0068, 0xafb70064, 0xafb60060, 0xafb5005c, 0xafb40058, 0xafb30054, + 0xafb20050, 0xafb1004c, 0xafb00048, 0xac606c98, 0x93620023, 0x30420010, + 0x1440027c, 0x24020001, 0x93420116, 0x93630005, 0x34424000, 0x30630001, + 0x14600005, 0x0342b021, 0x0e0015e0, 0x00000000, 0x0a001436, 0x8fbf006c, + 0x93420112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x10600012, + 0x03422821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x00000000, 0x8f420128, 0xaca20000, 0x8f640040, 0x24030008, 0x240240c1, + 0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000, 0x0a0011f1, 0xa0a3000a, + 0x8f420104, 0x3c030040, 0x00431024, 0x1040001d, 0x3c038000, 0x27450180, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, + 0x8f640040, 0x24030010, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a3000a, + 0x24030008, 0xa0a2000b, 0x3c021000, 0xa4a30010, 0xa0a00012, 0xa0a00013, + 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, 0xaca40018, 0x0e0015e0, + 0xaf4201b8, 0x0a001436, 0x8fbf006c, 0x8f820000, 0x10400016, 0x00000000, + 0x8f420104, 0x3c030001, 0x00431024, 0x10400011, 0x00000000, 0x8ca3000c, + 0x8f620030, 0x1462022d, 0x24020001, 0x8ca30010, 0x8f62002c, 0x14620229, + 0x24020001, 0x9763003a, 0x96c20000, 0x14430225, 0x24020001, 0x97630038, + 0x96c20002, 0x14430221, 0x24020001, 0xaf400048, 0xaf400054, 0xaf400040, + 0x8f740040, 0x8f650048, 0x00b43023, 0x04c10004, 0x00000000, 0x0000000d, + 0x00000000, 0x240001af, 0x9742011a, 0x3052ffff, 0x12400004, 0x8ed30004, + 0x02721021, 0x0a001228, 0x2451ffff, 0x02608821, 0x92d7000d, 0xa7a00020, + 0xa3a0001a, 0xafa00028, 0x9362003f, 0x32e30004, 0x1060003a, 0x305000ff, + 0x24040012, 0x16040006, 0x24020001, 0x3c040800, 0x8c830028, 0x24630001, + 0x0a001328, 0xac830028, 0x8f620044, 0x16620010, 0x27a60010, 0x27450180, + 0x3c038000, 0x2402001a, 0xa7a20020, 0x24020020, 0xafb40028, 0xa3b00022, + 0xa3a40023, 0xa3a2001a, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, + 0x0a00130d, 0x00000000, 0x8f620044, 0x02621023, 0x0440001a, 0x02651023, + 0x044100d9, 0x24020001, 0x3c020800, 0x8c4300d8, 0x10600004, 0x24020001, + 0xa7a20020, 0x0a00125e, 0xafb40028, 0x2402001a, 0xa7a20020, 0x24020020, + 0xafb40028, 0xa3b00022, 0xa3a40023, 0xa3a2001a, 0x27a60010, 0x27450180, + 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, + 0x00000000, 0x0a001328, 0x24020001, 0x0293f023, 0x1bc00016, 0x025e102a, + 0x54400007, 0x32f700fe, 0x57d2000f, 0x027e9821, 0x32e20001, 0x5440000c, + 0x027e9821, 0x32f700fe, 0x0240f021, 0x3c040800, 0x8c8300c8, 0x00009021, + 0x24020001, 0xa7a20020, 0xafb40028, 0x24630001, 0x0a001282, 0xac8300c8, + 0x025e1023, 0x0a001282, 0x3052ffff, 0x0000f021, 0x24a2ffff, 0x02221823, + 0x1860001f, 0x0072102a, 0x54400019, 0x00a08821, 0x97a20020, 0x3c040800, + 0x8c8300cc, 0xafb40028, 0x34420001, 0x24630001, 0xa7a20020, 0x02741026, + 0x2c420001, 0xac8300cc, 0x2cc30001, 0x00431024, 0x1440000a, 0x02401821, + 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x00000000, 0x0a00130d, 0x00000000, 0x00a08821, 0x02431023, 0x3052ffff, + 0x0a0012ae, 0x32f700f6, 0x02741023, 0x18400008, 0x97a20020, 0x3c040800, + 0x8c8300d4, 0xafb30028, 0x34420400, 0x24630001, 0xa7a20020, 0xac8300d4, + 0x32e20002, 0x1040001c, 0x32e20010, 0x8f620044, 0x1662000d, 0x27a60010, + 0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, 0xa7a20020, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, 0x00000000, + 0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, 0xa7a20020, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, 0x00000000, + 0x54400003, 0x8ed50008, 0x0a001328, 0x24020001, 0x8f630054, 0x26a2ffff, + 0x00431023, 0x18400011, 0x27a60010, 0x97a20020, 0x3c040800, 0x8c8300d0, + 0x27450180, 0x3c078000, 0xafb40028, 0x34420001, 0x24630001, 0xa7a20020, + 0xac8300d0, 0x8f4201b8, 0x00471024, 0x1440fffd, 0x00000000, 0x0a00130d, + 0x00000000, 0x32e20020, 0x10400011, 0x00000000, 0x96c20012, 0x0052102b, + 0x10400008, 0x97a20020, 0x96d20012, 0x12400003, 0x02721021, 0x0a0012f2, + 0x2451ffff, 0x02608821, 0x97a20020, 0x93a3001a, 0x34420008, 0x34630004, + 0xa7a20020, 0xa3a3001a, 0x8f420104, 0x3c030080, 0x00431024, 0x10400037, + 0x3a03000a, 0x0e001151, 0x02c02021, 0x24030002, 0x1443002b, 0x3c030800, + 0x27a60010, 0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, + 0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, + 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, 0x90c4000a, + 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, 0x90c30012, + 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, 0x8cc20024, + 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, 0x3c031000, + 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a001436, 0x8fbf006c, + 0x8c626c98, 0x30420100, 0x10400003, 0x24636c98, 0x8c620004, 0xaf62017c, + 0x3a03000a, 0x2c630001, 0x3a02000c, 0x2c420001, 0x00621825, 0x14600003, + 0x2402000e, 0x56020030, 0x00009021, 0x52400008, 0x96c4000e, 0x12400004, + 0xa7b20040, 0x02721021, 0x0a001343, 0x2451ffff, 0x02608821, 0x96c4000e, + 0x93630035, 0x8f62004c, 0x00642004, 0x00952021, 0x00821023, 0x18400015, + 0x00000000, 0x8f620018, 0x02621023, 0x1c400015, 0x97a20020, 0x8f620018, + 0x1662001c, 0x00000000, 0x8f62001c, 0x02a21023, 0x1c40000e, 0x97a20020, + 0x8f62001c, 0x16a20015, 0x00000000, 0x8f620058, 0x00821023, 0x18400011, + 0x97a20020, 0x0a001364, 0xafb10028, 0x8f620058, 0x00821023, 0x0441000b, + 0x97a20020, 0xafb10028, 0xafb30034, 0xafb50038, 0xafa4003c, 0x34420020, + 0x0a00136d, 0xa7a20020, 0x02809821, 0x02608821, 0x8f640058, 0x8f62004c, + 0x02a21023, 0x18400009, 0x00000000, 0x8f620054, 0x02a21023, 0x1c400005, + 0x97a20020, 0xafb10028, 0xafb50024, 0x0a001385, 0x34420040, 0x9742011a, + 0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c, + 0x8f620054, 0x10620004, 0x97a20020, 0xafb10028, 0x34420080, 0xa7a20020, + 0x24020014, 0x1202000a, 0x2a020015, 0x10400005, 0x2402000c, 0x12020006, + 0x32e20001, 0x0a0013c6, 0x00000000, 0x24020016, 0x16020035, 0x32e20001, + 0x8f620084, 0x24420001, 0x16a20031, 0x32e20001, 0x24020014, 0x12020021, + 0x2a020015, 0x10400005, 0x2402000c, 0x12020008, 0x32e20001, 0x0a0013c6, + 0x00000000, 0x24020016, 0x1202000c, 0x32e20001, 0x0a0013c6, 0x00000000, + 0x97a30020, 0x2402000e, 0xafb10028, 0xa3b00022, 0xa3a20023, 0xafb50024, + 0x34630054, 0x0a0013c5, 0xa7a30020, 0x97a20020, 0x93a4001a, 0x24030010, + 0xafb10028, 0xa3b00022, 0xa3a30023, 0xafb50024, 0x3442005d, 0x34840002, + 0xa7a20020, 0x0a0013c5, 0xa3a4001a, 0x97a20020, 0x24030012, 0xa3a30023, + 0x93a3001a, 0xafb10028, 0xa3b00022, 0xafb50024, 0x3042fffe, 0x3442005c, + 0x34630002, 0xa7a20020, 0xa3a3001a, 0x32e20001, 0x10400030, 0x2402000c, + 0x12020013, 0x2a02000d, 0x10400005, 0x2402000a, 0x12020008, 0x97a20020, + 0x0a0013f8, 0x32e20009, 0x2402000e, 0x1202001b, 0x32e20009, 0x0a0013f9, + 0x0002102b, 0x93a4001a, 0x24030008, 0xafb10028, 0xa3b00022, 0xa3a30023, + 0x0a0013f4, 0x34420013, 0x97a30020, 0x30620004, 0x14400005, 0x93a2001a, + 0x3463001b, 0xa7a30020, 0x0a0013e7, 0x24030016, 0x3463001b, 0xa7a30020, + 0x24030010, 0xafb10028, 0xa3b00022, 0xa3a30023, 0x34420002, 0x0a0013f7, + 0xa3a2001a, 0x97a20020, 0x93a4001a, 0x24030010, 0xafb10028, 0xa3b00022, + 0xa3a30023, 0x3442001b, 0x34840002, 0xa7a20020, 0xa3a4001a, 0x32e20009, + 0x0002102b, 0x00021023, 0x30420007, 0x12400015, 0x34450003, 0x8f820018, + 0x24030800, 0x27440180, 0x24420001, 0xaf820018, 0x24020004, 0xaf4301b8, + 0xa4850008, 0xa082000b, 0x93430120, 0x00003021, 0x3c021000, 0xa492000e, + 0xac950024, 0xac930028, 0x007e1821, 0xa483000c, 0xaf4201b8, 0x0a001413, + 0x97a20020, 0x24060001, 0x97a20020, 0x10400020, 0x27450180, 0x3c038000, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, + 0x8fa30028, 0x240240c1, 0xa4a20008, 0xaca30018, 0x93a4001a, 0x24020002, + 0xa0a2000b, 0xa0a4000a, 0x97a20020, 0xa4a20010, 0x93a30022, 0xa0a30012, + 0x93a20023, 0xa0a20013, 0x8fa30024, 0xaca30014, 0x8fa20034, 0xaca20024, + 0x8fa30038, 0xaca30028, 0x8fa2003c, 0x3c031000, 0xaca2002c, 0xaf4301b8, + 0x00c01021, 0x8fbf006c, 0x8fbe0068, 0x8fb70064, 0x8fb60060, 0x8fb5005c, + 0x8fb40058, 0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048, 0x03e00008, + 0x27bd0070, 0x8f470140, 0x8f460148, 0x3c028000, 0x00c24024, 0x00062c02, + 0x30a300ff, 0x24020019, 0x106200e7, 0x27440180, 0x2862001a, 0x1040001f, + 0x24020008, 0x106200be, 0x28620009, 0x1040000d, 0x24020001, 0x10620046, + 0x28620002, 0x50400005, 0x24020006, 0x1060002e, 0x00a01821, 0x0a00155e, + 0x00000000, 0x1062005b, 0x00a01821, 0x0a00155e, 0x00000000, 0x2402000b, + 0x10620084, 0x2862000c, 0x10400005, 0x24020009, 0x106200bc, 0x00061c02, + 0x0a00155e, 0x00000000, 0x2402000e, 0x106200b7, 0x00061c02, 0x0a00155e, + 0x00000000, 0x28620021, 0x10400009, 0x2862001f, 0x104000c1, 0x2402001b, + 0x106200bf, 0x2402001c, 0x1062009a, 0x00061c02, 0x0a00155e, 0x00000000, + 0x240200c2, 0x106200ca, 0x286200c3, 0x10400005, 0x24020080, 0x1062005a, + 0x00a01821, 0x0a00155e, 0x00000000, 0x240200c9, 0x106200cd, 0x30c5ffff, + 0x0a00155e, 0x00000000, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, + 0x24020001, 0xa4830008, 0x24030002, 0xac870000, 0xac800004, 0xa082000a, + 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, 0xac830024, + 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808, 0x11000009, 0x00a01821, + 0x3c020800, 0x24030002, 0xa0436c88, 0x24426c88, 0xac470008, 0x8f430144, + 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, + 0x24020002, 0xac800000, 0xac870004, 0xa4830008, 0xa082000a, 0xa082000b, + 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, 0xac820028, 0x3c026000, + 0xaf4301b8, 0x03e00008, 0xac400808, 0x3c080800, 0x3c058000, 0x8f4201b8, + 0x00451024, 0x1440fffd, 0x00000000, 0xac870000, 0x91026c88, 0x00002821, + 0x10400002, 0x25076c88, 0x8ce50008, 0xac850004, 0xa4830008, 0x91036c88, + 0x24020002, 0xa082000b, 0xa4860010, 0x34630001, 0xa083000a, 0x8f420144, + 0xac820024, 0x91036c88, 0x10600002, 0x00001021, 0x8ce20004, 0xac820028, + 0x3c021000, 0xaf4201b8, 0x3c026000, 0xa1006c88, 0x03e00008, 0xac400808, + 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xa082000b, + 0xa4830008, 0xa4860010, 0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008, + 0xaf4301b8, 0x30c2ffff, 0x14400028, 0x00061c02, 0x93620005, 0x30420004, + 0x14400020, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020, 0x3c038000, + 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, + 0x34630001, 0x00e31825, 0x34420004, 0xa3620005, 0xaf430020, 0x93620005, + 0x30420004, 0x14400003, 0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8, + 0x00431024, 0x1440fffd, 0x24020005, 0x3c031000, 0xac870000, 0xa082000b, + 0xaf4301b8, 0x0a00150d, 0x00061c02, 0x0000000d, 0x03e00008, 0x00000000, + 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, + 0xa4830008, 0x24030002, 0xac870000, 0xac800004, 0xa082000a, 0xa083000b, + 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, 0xac830024, 0x03e00008, + 0xaf4201b8, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, + 0xac800000, 0xac870004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4860010, + 0xac800024, 0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8, + 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, + 0xa4830008, 0x24030002, 0xa082000a, 0x3c021000, 0xac870000, 0xac800004, + 0xa083000b, 0xa4860010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8, + 0x00a01821, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, + 0xac870000, 0xac800004, 0xa4830008, 0xa080000a, 0x0a001518, 0xa082000b, + 0x8f440144, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, + 0x240340c9, 0xaf470180, 0xa342018b, 0x3c021000, 0xa7430188, 0xaf4401a4, + 0xaf4501a8, 0xaf4001ac, 0x03e00008, 0xaf4201b8, 0x0000000d, 0x03e00008, + 0x00000000, 0x03e00008, 0x00000000, 0x8f420100, 0x3042003e, 0x14400011, + 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, 0x10400005, 0x00000000, + 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, 0xaf400054, 0xaf400040, + 0x8f420100, 0x30423800, 0x54400001, 0xaf400044, 0x24020001, 0x03e00008, + 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, + 0x240340c9, 0xaf440180, 0xa342018b, 0x3c021000, 0xa7430188, 0xaf4501a4, + 0xaf4601a8, 0xaf4701ac, 0x03e00008, 0xaf4201b8, 0x3c029000, 0x34420001, + 0x00822025, 0xaf440020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, + 0x00000000, 0x03e00008, 0x00000000, 0x3c028000, 0x34420001, 0x00822025, + 0x03e00008, 0xaf440020, 0x308600ff, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8f640040, 0x24030008, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000, - 0x0a001181, 0xa0a3000a, 0x8f420104, 0x3c030040, 0x00431024, 0x1040001d, - 0x3c038000, 0x27450180, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, - 0x8f420128, 0xaca20000, 0x8f640040, 0x24030010, 0x240240c1, 0xa4a20008, - 0x24020002, 0xa0a3000a, 0x24030008, 0xa0a2000b, 0x3c021000, 0xa4a30010, - 0xa0a00012, 0xa0a00013, 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, - 0xaca40018, 0x0e001548, 0xaf4201b8, 0x0a0013a5, 0x8fbf0048, 0x8f820000, - 0x10400016, 0x00000000, 0x8f420104, 0x3c030001, 0x00431024, 0x10400011, - 0x00000000, 0x8ca3000c, 0x8f620030, 0x1462020c, 0x24020001, 0x8ca30010, - 0x8f62002c, 0x14620208, 0x24020001, 0x9763003a, 0x95620000, 0x14430204, - 0x24020001, 0x97630038, 0x95620002, 0x14430200, 0x24020001, 0xaf400048, - 0xaf400054, 0xaf400040, 0x8f690040, 0x8f6a0048, 0x01497023, 0x05c10004, - 0x00000000, 0x0000000d, 0x00000000, 0x24000169, 0x9742011a, 0x3046ffff, - 0x10c00004, 0x8d680004, 0x01061021, 0x0a0011b8, 0x2445ffff, 0x01002821, - 0x916c000d, 0xa7a00020, 0xa3a0001a, 0xafa00028, 0x9362003f, 0x31830004, - 0x1060003a, 0x304700ff, 0x24040012, 0x14e40006, 0x24020001, 0x3c040800, - 0x8c830028, 0x24630001, 0x0a00128d, 0xac830028, 0x8f620044, 0x15020010, - 0x27a60010, 0x27450180, 0x3c038000, 0x2402001a, 0xa7a20020, 0x24020020, - 0xafa90028, 0xa3a70022, 0xa3a40023, 0xa3a2001a, 0x8f4201b8, 0x00431024, - 0x1440fffd, 0x00000000, 0x0a001272, 0x00000000, 0x8f620044, 0x01021023, - 0x0440001a, 0x010a1023, 0x044100ae, 0x24020001, 0x3c020800, 0x8c4300d8, - 0x10600004, 0x24020001, 0xa7a20020, 0x0a0011ee, 0xafa90028, 0x2402001a, - 0xa7a20020, 0x24020020, 0xafa90028, 0xa3a70022, 0xa3a40023, 0xa3a2001a, - 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x00000000, 0x0a001272, 0x00000000, 0x0a00128d, 0x24020001, 0x01286823, - 0x19a00016, 0x00cd102a, 0x54400007, 0x318c00fe, 0x55a6000f, 0x010d4021, - 0x31820001, 0x5440000c, 0x010d4021, 0x318c00fe, 0x00c06821, 0x3c040800, - 0x8c8300c8, 0x00003021, 0x24020001, 0xa7a20020, 0xafa90028, 0x24630001, - 0x0a001212, 0xac8300c8, 0x00cd1023, 0x0a001212, 0x3046ffff, 0x00006821, - 0x2542ffff, 0x00a21823, 0x1860001e, 0x0066102a, 0x14400018, 0x01402821, - 0x97a20020, 0x3c040800, 0x8c8300cc, 0xafa90028, 0x34420001, 0x24630001, - 0xa7a20020, 0x01091026, 0x2c420001, 0xac8300cc, 0x2dc30001, 0x00431024, - 0x1440000a, 0x00c01821, 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272, 0x00000000, 0x00c31023, - 0x3046ffff, 0x0a00123d, 0x318c00f6, 0x01091023, 0x18400008, 0x97a20020, - 0x3c040800, 0x8c8300d4, 0xafa80028, 0x34420400, 0x24630001, 0xa7a20020, - 0xac8300d4, 0x31820002, 0x1040001c, 0x31820010, 0x8f620044, 0x1502000d, - 0x27a60010, 0x97a20020, 0x27450180, 0x3c038000, 0xafa90028, 0x34420001, - 0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272, - 0x00000000, 0x97a20020, 0x27450180, 0x3c038000, 0xafa90028, 0x34420001, - 0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272, - 0x00000000, 0x54400003, 0x8d6a0008, 0x0a00128d, 0x24020001, 0x8f630054, - 0x2542ffff, 0x00431023, 0x1840002e, 0x97a20020, 0x27a60010, 0x3c040800, - 0x8c8300d0, 0x27450180, 0x3c078000, 0xafa90028, 0x34420001, 0x24630001, - 0xa7a20020, 0xac8300d0, 0x8f4201b8, 0x00471024, 0x1440fffd, 0x00000000, - 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, - 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, - 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, - 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, - 0x3c031000, 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a0013a5, - 0x8fbf0048, 0x31820020, 0x10400011, 0x00000000, 0x95620012, 0x0046102b, - 0x10400008, 0x97a20020, 0x95660012, 0x10c00003, 0x01061021, 0x0a00129e, - 0x2445ffff, 0x01002821, 0x97a20020, 0x93a3001a, 0x34420008, 0x34630004, - 0xa7a20020, 0xa3a3001a, 0x8f420104, 0x38e3000a, 0x2c630001, 0x38e2000c, - 0x2c420001, 0x00621825, 0x14600003, 0x2402000e, 0x54e2002a, 0x00003021, - 0x50c00008, 0x9564000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a0012b6, - 0x2445ffff, 0x01002821, 0x9564000e, 0x93630035, 0x8f62004c, 0x00642004, - 0x008a2021, 0x00821023, 0x1840001d, 0x00000000, 0x8f620018, 0x01021023, - 0x1c40000f, 0x97a20020, 0x8f620018, 0x15020016, 0x00000000, 0x8f62001c, - 0x01421023, 0x1c400008, 0x97a20020, 0x8f62001c, 0x1542000f, 0x00000000, - 0x8f620058, 0x00821023, 0x1840000b, 0x97a20020, 0xafa50028, 0xafa80034, - 0xafaa0038, 0xafa4003c, 0x34420020, 0x0a0012da, 0xa7a20020, 0x01204021, - 0x01002821, 0x8f640058, 0x8f62004c, 0x01421023, 0x18400009, 0x00000000, - 0x8f620054, 0x01421023, 0x1c400005, 0x97a20020, 0xafa50028, 0xafaa0024, - 0x0a0012f2, 0x34420040, 0x9742011a, 0x1440000c, 0x24020014, 0x8f620058, - 0x14820009, 0x24020014, 0x8f63004c, 0x8f620054, 0x10620004, 0x97a20020, - 0xafa50028, 0x34420080, 0xa7a20020, 0x24020014, 0x10e2000a, 0x28e20015, - 0x10400005, 0x2402000c, 0x10e20006, 0x31820001, 0x0a001333, 0x00000000, - 0x24020016, 0x14e20035, 0x31820001, 0x8f620084, 0x24420001, 0x15420031, - 0x31820001, 0x24020014, 0x10e20021, 0x28e20015, 0x10400005, 0x2402000c, - 0x10e20008, 0x31820001, 0x0a001333, 0x00000000, 0x24020016, 0x10e2000c, - 0x31820001, 0x0a001333, 0x00000000, 0x97a30020, 0x2402000e, 0xafa50028, - 0xa3a70022, 0xa3a20023, 0xafaa0024, 0x34630054, 0x0a001332, 0xa7a30020, - 0x97a20020, 0x93a4001a, 0x24030010, 0xafa50028, 0xa3a70022, 0xa3a30023, - 0xafaa0024, 0x3442005d, 0x34840002, 0xa7a20020, 0x0a001332, 0xa3a4001a, - 0x97a20020, 0x24030012, 0xa3a30023, 0x93a3001a, 0xafa50028, 0xa3a70022, - 0xafaa0024, 0x3042fffe, 0x3442005c, 0x34630002, 0xa7a20020, 0xa3a3001a, - 0x31820001, 0x10400030, 0x2402000c, 0x10e20013, 0x28e2000d, 0x10400005, - 0x2402000a, 0x10e20008, 0x97a20020, 0x0a001365, 0x31820009, 0x2402000e, - 0x10e2001b, 0x31820009, 0x0a001366, 0x0002102b, 0x93a4001a, 0x24030008, - 0xafa50028, 0xa3a70022, 0xa3a30023, 0x0a001361, 0x34420013, 0x97a30020, - 0x30620004, 0x14400005, 0x93a2001a, 0x3463001b, 0xa7a30020, 0x0a001354, - 0x24030016, 0x3463001b, 0xa7a30020, 0x24030010, 0xafa50028, 0xa3a70022, - 0xa3a30023, 0x34420002, 0x0a001364, 0xa3a2001a, 0x97a20020, 0x93a4001a, - 0x24030010, 0xafa50028, 0xa3a70022, 0xa3a30023, 0x3442001b, 0x34840002, - 0xa7a20020, 0xa3a4001a, 0x31820009, 0x0002102b, 0x00021023, 0x30420007, - 0x10c00017, 0x34440003, 0x8f820014, 0x24030800, 0x27450180, 0x24420001, - 0xaf820014, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b, 0x93440120, - 0x3c031000, 0xa4a6000e, 0xacaa0024, 0xaca80028, 0x008d2021, 0xa4a4000c, - 0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a001381, 0xa7a20020, - 0x24060001, 0x97a20020, 0x10400020, 0x27450180, 0x3c038000, 0x8f4201b8, - 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8fa30028, - 0x240240c1, 0xa4a20008, 0xaca30018, 0x93a4001a, 0x24020002, 0xa0a2000b, - 0xa0a4000a, 0x97a20020, 0xa4a20010, 0x93a30022, 0xa0a30012, 0x93a20023, - 0xa0a20013, 0x8fa30024, 0xaca30014, 0x8fa20034, 0xaca20024, 0x8fa30038, - 0xaca30028, 0x8fa2003c, 0x3c031000, 0xaca2002c, 0xaf4301b8, 0x00c01021, - 0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f470140, 0x8f460148, 0x3c028000, - 0x00c24024, 0x00062c02, 0x30a300ff, 0x24020019, 0x106200e7, 0x27440180, - 0x2862001a, 0x1040001f, 0x24020008, 0x106200be, 0x28620009, 0x1040000d, - 0x24020001, 0x10620046, 0x28620002, 0x50400005, 0x24020006, 0x1060002e, - 0x00a01821, 0x0a0014c4, 0x00000000, 0x1062005b, 0x00a01821, 0x0a0014c4, - 0x00000000, 0x2402000b, 0x10620084, 0x2862000c, 0x10400005, 0x24020009, - 0x106200bc, 0x00061c02, 0x0a0014c4, 0x00000000, 0x2402000e, 0x106200b7, - 0x00061c02, 0x0a0014c4, 0x00000000, 0x28620021, 0x10400009, 0x2862001f, - 0x104000c1, 0x2402001b, 0x106200bf, 0x2402001c, 0x1062009a, 0x00061c02, - 0x0a0014c4, 0x00000000, 0x240200c2, 0x106200ca, 0x286200c3, 0x10400005, - 0x24020080, 0x1062005a, 0x00a01821, 0x0a0014c4, 0x00000000, 0x240200c9, - 0x106200cd, 0x30c5ffff, 0x0a0014c4, 0x00000000, 0x3c058000, 0x8f4201b8, - 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac870000, - 0xac800004, 0xa082000a, 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, - 0xac800028, 0xac830024, 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808, - 0x11000009, 0x00a01821, 0x3c020800, 0x24030002, 0xa0436a08, 0x24426a08, - 0xac470008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8, - 0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac870004, 0xa4830008, - 0xa082000a, 0xa082000b, 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, - 0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x3c080800, - 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000, 0xac870000, - 0x91026a08, 0x00002821, 0x10400002, 0x25076a08, 0x8ce50008, 0xac850004, - 0xa4830008, 0x91036a08, 0x24020002, 0xa082000b, 0xa4860010, 0x34630001, - 0xa083000a, 0x8f420144, 0xac820024, 0x91036a08, 0x10600002, 0x00001021, - 0x8ce20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000, 0xa1006a08, - 0x03e00008, 0xac400808, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, - 0x24020002, 0xa082000b, 0xa4830008, 0xa4860010, 0x8f420144, 0x3c031000, - 0xa4820012, 0x03e00008, 0xaf4301b8, 0x30c2ffff, 0x14400028, 0x00061c02, - 0x93620005, 0x30420004, 0x14400020, 0x3c029000, 0x34420001, 0x00e21025, - 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, - 0x93620005, 0x3c038000, 0x34630001, 0x00e31825, 0x34420004, 0xa3620005, - 0xaf430020, 0x93620005, 0x30420004, 0x14400003, 0x3c038000, 0x0000000d, - 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020005, 0x3c031000, - 0xac870000, 0xa082000b, 0xaf4301b8, 0x0a001473, 0x00061c02, 0x0000000d, - 0x03e00008, 0x00000000, 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, - 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac870000, 0xac800004, - 0xa082000a, 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, - 0xac830024, 0x03e00008, 0xaf4201b8, 0x3c058000, 0x8f4201b8, 0x00451024, - 0x1440fffd, 0x24020002, 0xac800000, 0xac870004, 0xa4830008, 0xa082000a, - 0xa082000b, 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, 0xac820028, - 0x03e00008, 0xaf4301b8, 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, - 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xa082000a, 0x3c021000, - 0xac870000, 0xac800004, 0xa083000b, 0xa4860010, 0xac800024, 0xac800028, - 0x03e00008, 0xaf4201b8, 0x00a01821, 0x3c058000, 0x8f4201b8, 0x00451024, - 0x1440fffd, 0x24020002, 0xac870000, 0xac800004, 0xa4830008, 0xa080000a, - 0x0a00147e, 0xa082000b, 0x8f440144, 0x3c038000, 0x8f4201b8, 0x00431024, - 0x1440fffd, 0x24020002, 0x240340c9, 0xaf470180, 0xa342018b, 0x3c021000, - 0xa7430188, 0xaf4401a4, 0xaf4501a8, 0xaf4001ac, 0x03e00008, 0xaf4201b8, - 0x0000000d, 0x03e00008, 0x00000000, 0x03e00008, 0x00000000, 0x8f420100, - 0x3042003e, 0x14400011, 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, - 0x10400005, 0x00000000, 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, - 0xaf400054, 0xaf400040, 0x8f420100, 0x30423800, 0x54400001, 0xaf400044, - 0x24020001, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024, - 0x1440fffd, 0x24020002, 0x240340c9, 0xaf440180, 0xa342018b, 0x3c021000, - 0xa7430188, 0xaf4501a4, 0xaf4601a8, 0xaf4701ac, 0x03e00008, 0xaf4201b8, - 0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000, 0x8f420020, - 0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000, 0x3c028000, - 0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x308600ff, 0x27450180, - 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, - 0xaca20000, 0x8f640040, 0x24030008, 0x240240c1, 0xa4a20008, 0x24020002, - 0xa0a2000b, 0x3c021000, 0xa0a6000a, 0xa4a30010, 0xa0a00012, 0xa0a00013, - 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, 0xaca40018, 0x03e00008, - 0xaf4201b8, 0x24020001, 0xacc40000, 0x03e00008, 0xa4e50000, 0x03e00008, - 0x24020001, 0x24020001, 0xaf400044, 0x03e00008, 0xaf400050, 0x00803021, - 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, - 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, - 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, - 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, - 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc2002c, 0x3c031000, - 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, 0x03e00008, 0xaf400050, - 0x27bdffe8, 0xafbf0010, 0x0e001032, 0x00000000, 0x00002021, 0x0e000c99, - 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f460148, 0x27450180, - 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, 0x00431024, 0x1440fffd, - 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, 0x00061c02, 0xaca20004, - 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, 0xaca30024, 0x10e0000a, - 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, 0x24020005, 0x54e20005, - 0xa0a0000a, 0x24020001, 0x0a001571, 0xa0a2000a, 0xa0a0000a, 0x3c021000, - 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007, 0x00000000, - 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004, - 0x03e00008, 0x00000000, 0x0a001587, 0x00a01021, 0xac860000, 0x00000000, - 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008, - 0x00000000, 0x00000000 }; + 0xa0a6000a, 0xa4a30010, 0xa0a00012, 0xa0a00013, 0xaca00014, 0xaca00024, + 0xaca00028, 0xaca0002c, 0xaca40018, 0x03e00008, 0xaf4201b8, 0x24020001, + 0xacc40000, 0x03e00008, 0xa4e50000, 0x24020001, 0xaf400044, 0x03e00008, + 0xaf400050, 0x00803021, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, + 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, + 0xa4a20008, 0xaca30018, 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, + 0x94c20010, 0xa4a20010, 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, + 0x8cc30014, 0xaca30014, 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, + 0x8cc2002c, 0x3c031000, 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, + 0x03e00008, 0xaf400050, 0x27bdffe8, 0xafbf0010, 0x0e001047, 0x00000000, + 0x00002021, 0x0e000c78, 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, + 0x8f460148, 0x27450180, 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, + 0x00431024, 0x1440fffd, 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, + 0x00061c02, 0xaca20004, 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, + 0xaca30024, 0x10e0000a, 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, + 0x24020005, 0x54e20005, 0xa0a0000a, 0x24020001, 0x0a001609, 0xa0a2000a, + 0xa0a0000a, 0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, + 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, + 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00161f, 0x00a01021, + 0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, + 0x24a5ffff, 0x03e00008, 0x00000000, 0x00000000 }; static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 }; -static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x0 }; -static u32 bnx2_RXP_b06FwBss[(0x1394/4) + 1] = { 0x0 }; -static u32 bnx2_RXP_b06FwSbss[(0x18/4) + 1] = { 0x0 }; +static u32 bnx2_RXP_b06FwRodata[(0x28/4) + 1] = { + 0x0800468c, 0x0800458c, 0x08004630, 0x08004648, 0x08004660, 0x08004680, + 0x0800468c, 0x0800468c, 0x08004594, 0x00000000, 0x00000000 }; +static u32 bnx2_RXP_b06FwBss[(0x13a4/4) + 1] = { 0x0 }; +static u32 bnx2_RXP_b06FwSbss[(0x1c/4) + 1] = { 0x0 }; static u32 bnx2_rv2p_proc1[] = { 0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004, From 1269a8a64a37c8a06af672f4cff4fed16a478734 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:11:03 -0800 Subject: [PATCH 114/695] [BNX2]: Workaround hw interrupt bug Add workaround for a hardware interrupt issue. When using INTA, unmasking of the interrupt and the tag update should be done separately to avoid some spurious interrupts, Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ec08f833c32d..7b99cf26a129 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -315,6 +315,10 @@ bnx2_enable_int(struct bnx2 *bp) { u32 val; + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx); + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx); @@ -1892,9 +1896,20 @@ bnx2_poll(struct net_device *dev, int *budget) if (!bnx2_has_work(bp)) { netif_rx_complete(dev); + if (likely(bp->flags & USING_MSI_FLAG)) { + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + bp->last_status_idx); + return 0; + } REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, - BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | - bp->last_status_idx); + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + BNX2_PCICFG_INT_ACK_CMD_MASK_INT | + bp->last_status_idx); + + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + bp->last_status_idx); return 0; } From 1122db717ab5443ca9043fc0d23c1e862cfb3a61 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:11:42 -0800 Subject: [PATCH 115/695] [BNX2]: Fix nvram sizing Add code to correctly determine nvram size. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 13 ++++++++++--- drivers/net/bnx2.h | 4 ++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7b99cf26a129..4f613b0be140 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -2724,9 +2724,16 @@ bnx2_init_nvram(struct bnx2 *bp) if (j == entry_count) { bp->flash_info = NULL; printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n"); - rc = -ENODEV; + return -ENODEV; } + val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2); + val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK; + if (val) + bp->flash_size = val; + else + bp->flash_size = bp->flash_info->total_size; + return rc; } @@ -4809,10 +4816,10 @@ bnx2_get_eeprom_len(struct net_device *dev) { struct bnx2 *bp = dev->priv; - if (bp->flash_info == 0) + if (bp->flash_info == NULL) return 0; - return (int) bp->flash_info->total_size; + return (int) bp->flash_size; } static int diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index ea70bbcd2542..ae17b63b98b4 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -4072,6 +4072,7 @@ struct bnx2 { struct net_device_stats net_stats; struct flash_spec *flash_info; + u32 flash_size; }; static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset); @@ -4273,6 +4274,9 @@ struct fw_info { #define BNX2_SHARED_HW_CFG_LED_MODE_GPHY1 0x100 #define BNX2_SHARED_HW_CFG_LED_MODE_GPHY2 0x200 +#define BNX2_SHARED_HW_CFG_CONFIG2 0x00000040 +#define BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK 0x00fff000 + #define BNX2_DEV_INFO_BC_REV 0x0000004c #define BNX2_PORT_HW_CFG_MAC_UPPER 0x00000050 From 972ec0d4ba67bf0ec7f00cd93fbac47452f80d25 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:12:43 -0800 Subject: [PATCH 116/695] [BNX2]: Use netdev_priv() Replace dev->priv with netdev_priv(dev) Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 80 +++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4f613b0be140..7be011f37d13 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1799,7 +1799,7 @@ static irqreturn_t bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); prefetch(bp->status_blk); REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, @@ -1819,7 +1819,7 @@ static irqreturn_t bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); /* When using INTx, it is possible for the interrupt to arrive * at the CPU before the status block posted prior to the @@ -1864,7 +1864,7 @@ bnx2_has_work(struct bnx2 *bp) static int bnx2_poll(struct net_device *dev, int *budget) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); if ((bp->status_blk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != @@ -1922,7 +1922,7 @@ bnx2_poll(struct net_device *dev, int *budget) static void bnx2_set_rx_mode(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); u32 rx_mode, sort_mode; int i; @@ -4194,7 +4194,7 @@ bnx2_restart_timer: static int bnx2_open(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); int rc; bnx2_set_power_state(bp, PCI_D0); @@ -4307,7 +4307,7 @@ bnx2_reset_task(void *data) static void bnx2_tx_timeout(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); /* This allows the netif to be shutdown gracefully before resetting */ schedule_work(&bp->reset_task); @@ -4318,7 +4318,7 @@ bnx2_tx_timeout(struct net_device *dev) static void bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); bnx2_netif_stop(bp); @@ -4332,7 +4332,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp) static void bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); bnx2_netif_stop(bp); @@ -4353,7 +4353,7 @@ bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) static int bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); dma_addr_t mapping; struct tx_bd *txbd; struct sw_bd *tx_buf; @@ -4482,7 +4482,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) static int bnx2_close(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); u32 reset_code; /* Calling flush_scheduled_work() may deadlock because @@ -4530,7 +4530,7 @@ bnx2_close(struct net_device *dev) static struct net_device_stats * bnx2_get_stats(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); struct statistics_block *stats_blk = bp->stats_blk; struct net_device_stats *net_stats = &bp->net_stats; @@ -4604,7 +4604,7 @@ bnx2_get_stats(struct net_device *dev) static int bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); cmd->supported = SUPPORTED_Autoneg; if (bp->phy_flags & PHY_SERDES_FLAG) { @@ -4651,7 +4651,7 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); u8 autoneg = bp->autoneg; u8 req_duplex = bp->req_duplex; u16 req_line_speed = bp->req_line_speed; @@ -4723,7 +4723,7 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) static void bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); strcpy(info->driver, DRV_MODULE_NAME); strcpy(info->version, DRV_MODULE_VERSION); @@ -4739,7 +4739,7 @@ bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) static void bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); if (bp->flags & NO_WOL_FLAG) { wol->supported = 0; @@ -4758,7 +4758,7 @@ bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) static int bnx2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; @@ -4778,7 +4778,7 @@ bnx2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) static int bnx2_nway_reset(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); u32 bmcr; if (!(bp->autoneg & AUTONEG_SPEED)) { @@ -4814,7 +4814,7 @@ bnx2_nway_reset(struct net_device *dev) static int bnx2_get_eeprom_len(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); if (bp->flash_info == NULL) return 0; @@ -4826,7 +4826,7 @@ static int bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *eebuf) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); int rc; /* parameters already validated in ethtool_get_eeprom */ @@ -4840,7 +4840,7 @@ static int bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *eebuf) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); int rc; /* parameters already validated in ethtool_set_eeprom */ @@ -4853,7 +4853,7 @@ bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, static int bnx2_get_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); memset(coal, 0, sizeof(struct ethtool_coalesce)); @@ -4875,7 +4875,7 @@ bnx2_get_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) static int bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); bp->rx_ticks = (u16) coal->rx_coalesce_usecs; if (bp->rx_ticks > 0x3ff) bp->rx_ticks = 0x3ff; @@ -4919,7 +4919,7 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) static void bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); ering->rx_max_pending = MAX_RX_DESC_CNT; ering->rx_mini_max_pending = 0; @@ -4936,7 +4936,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) static int bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); if ((ering->rx_pending > MAX_RX_DESC_CNT) || (ering->tx_pending > MAX_TX_DESC_CNT) || @@ -4959,7 +4959,7 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) static void bnx2_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); epause->autoneg = ((bp->autoneg & AUTONEG_FLOW_CTRL) != 0); epause->rx_pause = ((bp->flow_ctrl & FLOW_CTRL_RX) != 0); @@ -4969,7 +4969,7 @@ bnx2_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) static int bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); bp->req_flow_ctrl = 0; if (epause->rx_pause) @@ -4996,7 +4996,7 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) static u32 bnx2_get_rx_csum(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); return bp->rx_csum; } @@ -5004,7 +5004,7 @@ bnx2_get_rx_csum(struct net_device *dev) static int bnx2_set_rx_csum(struct net_device *dev, u32 data) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); bp->rx_csum = data; return 0; @@ -5153,7 +5153,7 @@ bnx2_self_test_count(struct net_device *dev) static void bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS); if (etest->flags & ETH_TEST_FL_OFFLINE) { @@ -5229,7 +5229,7 @@ static void bnx2_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *buf) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); int i; u32 *hw_stats = (u32 *) bp->stats_blk; u8 *stats_len_arr = NULL; @@ -5269,7 +5269,7 @@ bnx2_get_ethtool_stats(struct net_device *dev, static int bnx2_phys_id(struct net_device *dev, u32 data) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); int i; u32 save; @@ -5341,7 +5341,7 @@ static int bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = if_mii(ifr); - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); int err; switch(cmd) { @@ -5383,7 +5383,7 @@ static int bnx2_change_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; @@ -5399,7 +5399,7 @@ bnx2_change_mac_addr(struct net_device *dev, void *p) static int bnx2_change_mtu(struct net_device *dev, int new_mtu) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); if (((new_mtu + ETH_HLEN) > MAX_ETHERNET_JUMBO_PACKET_SIZE) || ((new_mtu + ETH_HLEN) < MIN_ETHERNET_PACKET_SIZE)) @@ -5420,7 +5420,7 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu) static void poll_bnx2(struct net_device *dev) { - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); disable_irq(bp->pdev->irq); bnx2_interrupt(bp->pdev->irq, dev, NULL); @@ -5438,7 +5438,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - bp = dev->priv; + bp = netdev_priv(dev); bp->flags = 0; bp->phy_flags = 0; @@ -5757,7 +5757,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->ethtool_ops = &bnx2_ethtool_ops; dev->weight = 64; - bp = dev->priv; + bp = netdev_priv(dev); #if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER) dev->poll_controller = poll_bnx2; @@ -5816,7 +5816,7 @@ static void __devexit bnx2_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); flush_scheduled_work(); @@ -5835,7 +5835,7 @@ static int bnx2_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); u32 reset_code; if (!netif_running(dev)) @@ -5860,7 +5860,7 @@ static int bnx2_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2 *bp = dev->priv; + struct bnx2 *bp = netdev_priv(dev); if (!netif_running(dev)) return 0; From bc5a0690e917206b423c7b565c997b06675fb572 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:13:22 -0800 Subject: [PATCH 117/695] [BNX2]: Add PHY loopback test Enhance the ethtool loopback test with PHY loopback test. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 101 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 22 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7be011f37d13..9f71cca81e91 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1331,6 +1331,38 @@ bnx2_set_mac_loopback(struct bnx2 *bp) return 0; } +static int bnx2_test_link(struct bnx2 *); + +static int +bnx2_set_phy_loopback(struct bnx2 *bp) +{ + u32 mac_mode; + int rc, i; + + spin_lock_bh(&bp->phy_lock); + rc = bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | + BMCR_SPEED1000); + spin_unlock_bh(&bp->phy_lock); + if (rc) + return rc; + + for (i = 0; i < 10; i++) { + if (bnx2_test_link(bp) == 0) + break; + udelay(10); + } + + mac_mode = REG_RD(bp, BNX2_EMAC_MODE); + mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | + BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | + BNX2_EMAC_MODE_25G); + + mac_mode |= BNX2_EMAC_MODE_PORT_GMII; + REG_WR(bp, BNX2_EMAC_MODE, mac_mode); + bp->link_up = 1; + return 0; +} + static int bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent) { @@ -3907,26 +3939,33 @@ bnx2_test_memory(struct bnx2 *bp) return ret; } +#define BNX2_MAC_LOOPBACK 0 +#define BNX2_PHY_LOOPBACK 1 + static int -bnx2_test_loopback(struct bnx2 *bp) +bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) { unsigned int pkt_size, num_pkts, i; struct sk_buff *skb, *rx_skb; unsigned char *packet; - u16 rx_start_idx, rx_idx, send_idx; - u32 send_bseq, val; + u16 rx_start_idx, rx_idx; + u32 val; dma_addr_t map; struct tx_bd *txbd; struct sw_bd *rx_buf; struct l2_fhdr *rx_hdr; int ret = -ENODEV; - if (!netif_running(bp->dev)) - return -ENODEV; - - bp->loopback = MAC_LOOPBACK; - bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_DIAG); - bnx2_set_mac_loopback(bp); + if (loopback_mode == BNX2_MAC_LOOPBACK) { + bp->loopback = MAC_LOOPBACK; + bnx2_set_mac_loopback(bp); + } + else if (loopback_mode == BNX2_PHY_LOOPBACK) { + bp->loopback = 0; + bnx2_set_phy_loopback(bp); + } + else + return -EINVAL; pkt_size = 1514; skb = dev_alloc_skb(pkt_size); @@ -3948,11 +3987,9 @@ bnx2_test_loopback(struct bnx2 *bp) udelay(5); rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0; - send_idx = 0; - send_bseq = 0; num_pkts = 0; - txbd = &bp->tx_desc_ring[send_idx]; + txbd = &bp->tx_desc_ring[TX_RING_IDX(bp->tx_prod)]; txbd->tx_bd_haddr_hi = (u64) map >> 32; txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff; @@ -3960,13 +3997,11 @@ bnx2_test_loopback(struct bnx2 *bp) txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END; num_pkts++; - send_idx = NEXT_TX_BD(send_idx); - - send_bseq += pkt_size; - - REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, send_idx); - REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, send_bseq); + bp->tx_prod = NEXT_TX_BD(bp->tx_prod); + bp->tx_prod_bseq += pkt_size; + REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, bp->tx_prod); + REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); udelay(100); @@ -3979,7 +4014,7 @@ bnx2_test_loopback(struct bnx2 *bp) pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); dev_kfree_skb_irq(skb); - if (bp->status_blk->status_tx_quick_consumer_index0 != send_idx) { + if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) { goto loopback_test_done; } @@ -4025,6 +4060,30 @@ loopback_test_done: return ret; } +#define BNX2_MAC_LOOPBACK_FAILED 1 +#define BNX2_PHY_LOOPBACK_FAILED 2 +#define BNX2_LOOPBACK_FAILED (BNX2_MAC_LOOPBACK_FAILED | \ + BNX2_PHY_LOOPBACK_FAILED) + +static int +bnx2_test_loopback(struct bnx2 *bp) +{ + int rc = 0; + + if (!netif_running(bp->dev)) + return BNX2_LOOPBACK_FAILED; + + bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET); + spin_lock_bh(&bp->phy_lock); + bnx2_init_phy(bp); + spin_unlock_bh(&bp->phy_lock); + if (bnx2_run_loopback(bp, BNX2_MAC_LOOPBACK)) + rc |= BNX2_MAC_LOOPBACK_FAILED; + if (bnx2_run_loopback(bp, BNX2_PHY_LOOPBACK)) + rc |= BNX2_PHY_LOOPBACK_FAILED; + return rc; +} + #define NVRAM_SIZE 0x200 #define CRC32_RESIDUAL 0xdebb20e3 @@ -5169,10 +5228,8 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) buf[1] = 1; etest->flags |= ETH_TEST_FL_FAILED; } - if (bnx2_test_loopback(bp) != 0) { - buf[2] = 1; + if ((buf[2] = bnx2_test_loopback(bp)) != 0) etest->flags |= ETH_TEST_FL_FAILED; - } if (!netif_running(bp->dev)) { bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); From 206cc83ccdc29e4a73786e9093f9eeec25868441 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 23 Jan 2006 16:14:05 -0800 Subject: [PATCH 118/695] [BNX2]: Update version and copyright year Update version to 1.4.31 and add 2006 copyright. Skip the last digit when reporting the firmware version. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 11 +++++------ drivers/net/bnx2.h | 2 +- drivers/net/bnx2_fw.h | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 9f71cca81e91..a24200d0a616 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1,6 +1,6 @@ /* bnx2.c: Broadcom NX2 network driver. * - * Copyright (c) 2004, 2005 Broadcom Corporation + * Copyright (c) 2004, 2005, 2006 Broadcom Corporation * * 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 @@ -14,8 +14,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.4.30" -#define DRV_MODULE_RELDATE "October 11, 2005" +#define DRV_MODULE_VERSION "1.4.31" +#define DRV_MODULE_RELDATE "January 19, 2006" #define RUN_AT(x) (jiffies + (x)) @@ -4790,9 +4790,8 @@ bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) info->fw_version[0] = ((bp->fw_ver & 0xff000000) >> 24) + '0'; info->fw_version[2] = ((bp->fw_ver & 0xff0000) >> 16) + '0'; info->fw_version[4] = ((bp->fw_ver & 0xff00) >> 8) + '0'; - info->fw_version[6] = (bp->fw_ver & 0xff) + '0'; - info->fw_version[1] = info->fw_version[3] = info->fw_version[5] = '.'; - info->fw_version[7] = 0; + info->fw_version[1] = info->fw_version[3] = '.'; + info->fw_version[5] = 0; } static void diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index ae17b63b98b4..9f691cbd666b 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -1,6 +1,6 @@ /* bnx2.h: Broadcom NX2 network driver. * - * Copyright (c) 2004, 2005 Broadcom Corporation + * Copyright (c) 2004, 2005, 2006 Broadcom Corporation * * 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 diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h index f6982c38019c..0c21bd849814 100644 --- a/drivers/net/bnx2_fw.h +++ b/drivers/net/bnx2_fw.h @@ -1,6 +1,6 @@ /* bnx2_fw.h: Broadcom NX2 network driver. * - * Copyright (c) 2004, 2005 Broadcom Corporation + * Copyright (c) 2004, 2005, 2006 Broadcom Corporation * * 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 From 2a792058c3aaf5fb806e09a456e25b9f4f748dd1 Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Tue, 24 Jan 2006 12:31:26 +1100 Subject: [PATCH 119/695] [IA64] Set the correct default OS status in the MCA handler sos->os_status is set to a default value of IA64_MCA_COLD_BOOT for an MCA, but then is incorrectly overwritten with IA64_MCA_SAME_CONTEXT (0). This makes SAL think that all MCAs have been recovered. Signed-off-by: Keith Owens Signed-off-by: Tony Luck --- arch/ia64/kernel/mca_asm.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 403a80a58c13..60a464bfd9e2 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S @@ -512,7 +512,7 @@ ia64_state_save: st8 [temp1]=r12 // os_status, default is cold boot mov r6=IA64_MCA_SAME_CONTEXT ;; - st8 [temp1]=r6 // context, default is same context + st8 [temp2]=r6 // context, default is same context // Save the pt_regs data that is not in minstate. The previous code // left regs at sos. From dc64161343015162a3fabfcd20b9b84409af67d5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Jan 2006 14:30:56 -0800 Subject: [PATCH 120/695] [IA64-SGI] sn_dma_alloc_coherent should use gfp flags Takashi helped us track down a bad page state bug we thought was coming from alsa. It turns out we weren't paying attention to the gfp flags that were passed in to sn_dma_alloc_coherent(). From: Takashi Iwai Signed-off-by: Greg Edwards Signed-off-by: Mark Maule Signed-off-by: Jes Sorensen --- arch/ia64/sn/pci/pci_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 9bf9f23b9a1f..5a36292388eb 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -90,14 +90,14 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, */ node = pcibus_to_node(pdev->bus); if (likely(node >=0)) { - struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size)); + struct page *p = alloc_pages_node(node, flags, get_order(size)); if (likely(p)) cpuaddr = page_address(p); else return NULL; } else - cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)); + cpuaddr = (void *)__get_free_pages(flags, get_order(size)); if (unlikely(!cpuaddr)) return NULL; From 79c83bd15af3b06079a9205db9c64c92ca1bd868 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 24 Jan 2006 16:32:11 -0600 Subject: [PATCH 121/695] [IA64] Scaling fix for simultaneous unaligned accesses Eliminate a hot shared cacheline that occurs if multiple cpus are taking unaligned exceptions. Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/kernel/unaligned.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index 43b45b65ee5a..f9e0ae936d1a 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c @@ -1283,8 +1283,9 @@ within_logging_rate_limit (void) if (jiffies - last_time > 5*HZ) count = 0; - if (++count < 5) { + if (count < 5) { last_time = jiffies; + count++; return 1; } return 0; From fd8b206d1621ad526e7b00dc26322f546b2a57fb Mon Sep 17 00:00:00 2001 From: Dean Roe Date: Tue, 24 Jan 2006 14:49:43 -0800 Subject: [PATCH 122/695] [IA64-SGI] add sn_feature_sets bit SGI's prom has added a new feature which avoids an Altix-specific MCA that can occur with excessive use of ia64_pal_cache_flush. This patch adds the #define to the sn_feature_sets.h to reflect that bit is taken. Signed-off-by: Dean Roe Signed-off-by: Tony Luck --- include/asm-ia64/sn/sn_feature_sets.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/include/asm-ia64/sn/sn_feature_sets.h b/include/asm-ia64/sn/sn_feature_sets.h index e68a80853d5d..f63f144e8170 100644 --- a/include/asm-ia64/sn/sn_feature_sets.h +++ b/include/asm-ia64/sn/sn_feature_sets.h @@ -8,7 +8,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2005 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2005-2006 Silicon Graphics, Inc. All rights reserved. */ @@ -27,14 +27,11 @@ extern int sn_prom_feature_available(int id); * "false" for new features. * * Use: - * if (sn_prom_feature_available(PRF_FEATURE_XXX)) + * if (sn_prom_feature_available(PRF_XXX)) * ... */ -/* - * Example: feature XXX - */ -#define PRF_FEATURE_XXX 0 +#define PRF_PAL_CACHE_FLUSH_SAFE 0 From e5ee7dda96476e09ee63af464ea17ddad1dc489d Mon Sep 17 00:00:00 2001 From: Greg Edwards Date: Wed, 18 Jan 2006 10:21:59 -0600 Subject: [PATCH 123/695] [IA64] sn2 maintainer update (Jes Sorensen) We lured Jes to the dark side, and he's going to take over as the sn2 maintainer. His experience and thoroughness will serve him well here. Signed-off-by: Greg Edwards Signed-off-by: Tony Luck --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3f8a90ac47d7..a37a2b38a557 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1176,8 +1176,8 @@ T: git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git S: Maintained SN-IA64 (Itanium) SUB-PLATFORM -P: Greg Edwards -M: edwardsg@sgi.com +P: Jes Sorensen +M: jes@sgi.com L: linux-altix@sgi.com L: linux-ia64@vger.kernel.org W: http://www.sgi.com/altix From 139366a093d1ce2749b1b4247947ceb9b78caa2a Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Tue, 24 Jan 2006 04:23:16 -0500 Subject: [PATCH 124/695] [IA64-SGI] XPC remove unnecessary GFP_DMA flag Remove the GFP_DMA flag from XPC kmalloc() calls. Signed-off-by: Jes Sorensen Acked-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/xpc_channel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 8d950c778bb6..36e5437a0fb6 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c @@ -447,7 +447,7 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch) nbytes = nentries * ch->msg_size; ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, - (GFP_KERNEL | GFP_DMA), + GFP_KERNEL, &ch->local_msgqueue_base); if (ch->local_msgqueue == NULL) { continue; @@ -455,7 +455,7 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch) memset(ch->local_msgqueue, 0, nbytes); nbytes = nentries * sizeof(struct xpc_notify); - ch->notify_queue = kmalloc(nbytes, (GFP_KERNEL | GFP_DMA)); + ch->notify_queue = kmalloc(nbytes, GFP_KERNEL); if (ch->notify_queue == NULL) { kfree(ch->local_msgqueue_base); ch->local_msgqueue = NULL; @@ -502,7 +502,7 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch) nbytes = nentries * ch->msg_size; ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, - (GFP_KERNEL | GFP_DMA), + GFP_KERNEL, &ch->remote_msgqueue_base); if (ch->remote_msgqueue == NULL) { continue; From d59cc22f7ce48bf5454f12eec8603bff81c34cdb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Jan 2006 14:31:45 +1100 Subject: [PATCH 125/695] drm: Fix sparce warning in radeon driver From: Luiz Fernando Capitulino drivers/char/drm/radeon_cp.c:1643:31: warning: Using plain integer as NULL pointer Signed-off-by: Luiz Capitulino Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- drivers/char/drm/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 915665c7fe7c..9bb8ae0c1c27 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c @@ -1640,7 +1640,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = 0; + dev_priv->gart_info.addr = NULL; } } /* only clear to the start of flags */ From 5457f38e01ae2d296ff49db42254679018f13fa9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Jan 2006 14:34:33 +1100 Subject: [PATCH 126/695] drm: add i945GM PCI ID From: Charles F. Johnson Signed-off-by: Dave Airlie --- drivers/char/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 5b1d3a04458d..27de81dad41e 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -242,5 +242,6 @@ {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} From 2fed3bd7436e8988980989493c16b4983be1a800 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Jan 2006 14:52:43 +1100 Subject: [PATCH 127/695] drm: add X600 PCI IDs From: Brice Goglin Now that Xorg 6.9/7.0 has been released, DRI is supported on more Radeon cards without ATI proprietary drivers. I got my X300 to work without problem. But, another Radeon X600 required to add its PCI ids to the Radeon driver. Patch is attached. I can't be sure about the "CHIP_RV350", I copied it from the X300 entry (from http://dri.freedesktop.org/wiki/ATIRadeon, X600 is a rv380 chip while X300 is a rv370). But, at least it works now. Signed-off-by: Brice Goglin Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- drivers/char/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 27de81dad41e..8fd6357a48da 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -3,6 +3,7 @@ Please contact dri-devel@lists.sf.net to add new cards to this list */ #define radeon_PCI_IDS \ + {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350},\ {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ From f1e5c03d34c39394781ae13543cd3355976e4812 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Jan 2006 14:54:15 +1100 Subject: [PATCH 128/695] drm: use NULL instead of 0 From: Randy Dunlap Use NULL instead of 0 (sparse warnings): drivers/char/drm/ati_pcigart.c:64:10: warning: Using plain integer as NULL pointer drivers/char/drm/ati_pcigart.c:130:21: warning: Using plain integer as NULL pointer drivers/char/drm/ati_pcigart.c:171:14: warning: Using plain integer as NULL pointer Signed-off-by: Randy Dunlap Signed-off-by: Dave Airlie --- drivers/char/drm/ati_pcigart.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index 5485382cadec..7d2a885b5db0 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c @@ -61,7 +61,7 @@ static void *drm_ati_alloc_pcigart_table(void) address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER); if (address == 0UL) { - return 0; + return NULL; } page = virt_to_page(address); @@ -127,7 +127,7 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) if (gart_info->gart_table_location == DRM_ATI_GART_MAIN && gart_info->addr) { drm_ati_free_pcigart_table(gart_info->addr); - gart_info->addr = 0; + gart_info->addr = NULL; } return 1; @@ -168,7 +168,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) if (bus_address == 0) { DRM_ERROR("unable to map PCIGART pages!\n"); drm_ati_free_pcigart_table(address); - address = 0; + address = NULL; goto done; } } else { From 507d256bae9eef7acd5049af6e3f67c24904a1e4 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Jan 2006 14:58:58 +1100 Subject: [PATCH 129/695] drm: ati_pcigart: simplify page_count manipulations From: Nick Piggin Allocate a compound page for the user mapping instead of tweaking the page refcounts. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- drivers/char/drm/ati_pcigart.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index 7d2a885b5db0..bd7be09ea53d 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c @@ -59,17 +59,16 @@ static void *drm_ati_alloc_pcigart_table(void) int i; DRM_DEBUG("%s\n", __FUNCTION__); - address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER); + address = __get_free_pages(GFP_KERNEL | __GFP_COMP, + ATI_PCIGART_TABLE_ORDER); if (address == 0UL) { return NULL; } page = virt_to_page(address); - for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { - get_page(page); + for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) SetPageReserved(page); - } DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); return (void *)address; @@ -83,10 +82,8 @@ static void drm_ati_free_pcigart_table(void *address) page = virt_to_page((unsigned long)address); - for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { - __put_page(page); + for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) ClearPageReserved(page); - } free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER); } From 17cbbafe8e82bde4258e407ce043b61f4f9a350f Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 24 Jan 2006 20:26:48 -0800 Subject: [PATCH 130/695] [CIFS] Make cifs default wsize match what we actually want to send (52K typically - header + 13 pages). Forgetting to set wsize on the mount command costs more than 10% on large write (can be much more) so this makes a saner default. We still shrink this default smaller if server can not support it. Signed-off-by: Steve French --- fs/cifs/connect.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 88f60aa52058..eae306fa24b2 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1785,7 +1785,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, } else if(volume_info.wsize) cifs_sb->wsize = volume_info.wsize; else - cifs_sb->wsize = CIFSMaxBufSize; /* default */ + cifs_sb->wsize = + min(PAGEVEC_SIZE * PAGE_CACHE_SIZE, 127*1024); + /* old default of CIFSMaxBufSize was too small now + that SMB Write2 can send multiple pages in kvec. + RFC1001 does not describe what happens when frame + bigger than 128K is sent so use that as max in + conjunction with 52K kvec constraint on arch with 4K + page size */ + if(cifs_sb->rsize < PAGE_CACHE_SIZE) { cifs_sb->rsize = PAGE_CACHE_SIZE; /* Windows ME does this */ From de227f5f32775d86e5c780a7cffdd2e08574f7fb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Jan 2006 15:31:43 +1100 Subject: [PATCH 131/695] drm: i915 patches from Tungsten Graphics Fix CMDBUFFER path, add heap destroy and flesh out sarea for rotation (Tungsten Graphics) From: Alan Hourihane Signed-off-by: Dave Airlie --- drivers/char/drm/i915_dma.c | 42 ++++++++++++++++++++++++++----------- drivers/char/drm/i915_drm.h | 33 +++++++++++++++++++++++++++++ drivers/char/drm/i915_drv.h | 6 ++++-- drivers/char/drm/i915_mem.c | 31 +++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 14 deletions(-) diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 9140703da1ba..1ff4c7ca0bff 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c @@ -344,18 +344,20 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) int i; RING_LOCALS; + if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) + return DRM_ERR(EINVAL); + + BEGIN_LP_RING(((dwords+1)&~1)); + for (i = 0; i < dwords;) { int cmd, sz; if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) return DRM_ERR(EINVAL); -/* printk("%d/%d ", i, dwords); */ - if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) return DRM_ERR(EINVAL); - BEGIN_LP_RING(sz); OUT_RING(cmd); while (++i, --sz) { @@ -365,9 +367,13 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) } OUT_RING(cmd); } - ADVANCE_LP_RING(); } + if (dwords & 1) + OUT_RING(0); + + ADVANCE_LP_RING(); + return 0; } @@ -401,6 +407,21 @@ static int i915_emit_box(drm_device_t * dev, return 0; } +static void i915_emit_breadcrumb(drm_device_t *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; + + BEGIN_LP_RING(4); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(20); + OUT_RING(dev_priv->counter); + OUT_RING(0); + ADVANCE_LP_RING(); +} + static int i915_dispatch_cmdbuffer(drm_device_t * dev, drm_i915_cmdbuffer_t * cmd) { @@ -429,6 +450,7 @@ static int i915_dispatch_cmdbuffer(drm_device_t * dev, return ret; } + i915_emit_breadcrumb(dev); return 0; } @@ -475,12 +497,7 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; - BEGIN_LP_RING(4); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(0); - ADVANCE_LP_RING(); + i915_emit_breadcrumb(dev); return 0; } @@ -657,7 +674,7 @@ static int i915_getparam(DRM_IOCTL_ARGS) value = READ_BREADCRUMB(dev_priv); break; default: - DRM_ERROR("Unkown parameter %d\n", param.param); + DRM_ERROR("Unknown parameter %d\n", param.param); return DRM_ERR(EINVAL); } @@ -742,7 +759,8 @@ drm_ioctl_desc_t i915_ioctls[] = { [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH} + [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY } }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h index 77412ddac007..4cb3da578330 100644 --- a/drivers/char/drm/i915_drm.h +++ b/drivers/char/drm/i915_drm.h @@ -74,6 +74,30 @@ typedef struct _drm_i915_sarea { int pf_active; int pf_current_page; /* which buffer is being displayed? */ int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; } drm_i915_sarea_t; /* Flags for perf_boxes @@ -99,6 +123,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_FREE 0x09 #define DRM_I915_INIT_HEAP 0x0a #define DRM_I915_CMDBUFFER 0x0b +#define DRM_I915_DESTROY_HEAP 0x0c #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -112,6 +137,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) #define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) +#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -191,4 +217,11 @@ typedef struct drm_i915_mem_init_heap { int start; } drm_i915_mem_init_heap_t; +/* Allow memory manager to be torn down and re-initialized (eg on + * rotate): + */ +typedef struct drm_i915_mem_destroy_heap { + int region; +} drm_i915_mem_destroy_heap_t; + #endif /* _I915_DRM_H_ */ diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index c6c71b45f101..7a65666899e4 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -37,16 +37,17 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20051209" +#define DRIVER_DATE "20060119" /* Interface history: * * 1.1: Original. * 1.2: Add Power Management * 1.3: Add vblank support + * 1.4: Fix cmdbuffer path, add heap destroy */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 +#define DRIVER_MINOR 4 #define DRIVER_PATCHLEVEL 0 typedef struct _drm_i915_ring_buffer { @@ -123,6 +124,7 @@ extern void i915_driver_irq_uninstall(drm_device_t * dev); extern int i915_mem_alloc(DRM_IOCTL_ARGS); extern int i915_mem_free(DRM_IOCTL_ARGS); extern int i915_mem_init_heap(DRM_IOCTL_ARGS); +extern int i915_mem_destroy_heap(DRM_IOCTL_ARGS); extern void i915_mem_takedown(struct mem_block **heap); extern void i915_mem_release(drm_device_t * dev, DRMFILE filp, struct mem_block *heap); diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c index ba87ff17ff64..52c67324df58 100644 --- a/drivers/char/drm/i915_mem.c +++ b/drivers/char/drm/i915_mem.c @@ -365,3 +365,34 @@ int i915_mem_init_heap(DRM_IOCTL_ARGS) return init_heap(heap, initheap.start, initheap.size); } + +int i915_mem_destroy_heap( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_mem_destroy_heap_t destroyheap; + struct mem_block **heap; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( destroyheap, (drm_i915_mem_destroy_heap_t *)data, + sizeof(destroyheap) ); + + heap = get_heap( dev_priv, destroyheap.region ); + if (!heap) { + DRM_ERROR("get_heap failed"); + return DRM_ERR(EFAULT); + } + + if (!*heap) { + DRM_ERROR("heap not initialized?"); + return DRM_ERR(EFAULT); + } + + i915_mem_takedown( heap ); + return 0; +} + From 339363c4c6fe01043c51e7d6e9fbeb8feee00841 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 26 Jan 2006 08:32:14 +1100 Subject: [PATCH 132/695] drm: Fixes sparse warnings in via_dmablit.c Fixes the following sparse warnings: drivers/char/drm/via_dmablit.c:111:35: warning: Using plain integer as NULL pointer drivers/char/drm/via_dmablit.c:584:23: warning: Using plain integer as NULL pointer Signed-off-by: Luiz Capitulino Signed-off-by: Dave Airlie --- drivers/char/drm/via_dmablit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 9d5e027dae0e..a28eece6281e 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c @@ -108,7 +108,7 @@ via_map_blit_for_device(struct pci_dev *pdev, int num_desc = 0; int cur_line; dma_addr_t next = 0 | VIA_DMA_DPR_EC; - drm_via_descriptor_t *desc_ptr = 0; + drm_via_descriptor_t *desc_ptr = NULL; if (mode == 1) desc_ptr = vsg->desc_pages[cur_descriptor_page]; @@ -581,7 +581,7 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t * int ret = 0; vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; - vsg->bounce_buffer = 0; + vsg->bounce_buffer = NULL; vsg->state = dr_via_sg_init; From 2dbb04c65561122cc53b22dbea9aa59f9609215b Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 16 Jan 2006 11:49:29 -0500 Subject: [PATCH 133/695] [SCSI] qla1280: remove < 2.6.0 support Remove support for kernels older than 2.6.0. Signed-off-by: Jes Sorensen Signed-off-by: James Bottomley --- drivers/scsi/qla1280.c | 311 +++-------------------------------------- 1 file changed, 23 insertions(+), 288 deletions(-) diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 0878f95b5449..e0230249fa0f 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -17,9 +17,11 @@ * General Public License for more details. * ******************************************************************************/ -#define QLA1280_VERSION "3.25" +#define QLA1280_VERSION "3.26" /***************************************************************************** Revision History: + Rev 3.26, January 16, 2006 Jes Sorensen + - Ditch all < 2.6 support Rev 3.25.1, February 10, 2005 Christoph Hellwig - use pci_map_single to map non-S/G requests - remove qla1280_proc_info @@ -356,25 +358,18 @@ #include #include -#if LINUX_VERSION_CODE >= 0x020545 #include #include #include #include #include -#else -#include -#include "scsi.h" -#include -#include "sd.h" -#endif #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) #include #endif -#if LINUX_VERSION_CODE < 0x020407 -#error "Kernels older than 2.4.7 are no longer supported" +#if LINUX_VERSION_CODE < 0x020600 +#error "Kernels older than 2.6.0 are no longer supported" #endif @@ -441,52 +436,6 @@ #define NVRAM_DELAY() udelay(500) /* 2 microseconds */ -#if LINUX_VERSION_CODE < 0x020500 -#define HOST_LOCK &io_request_lock -#define irqreturn_t void -#define IRQ_RETVAL(foo) -#define MSG_ORDERED_TAG 1 - -#define DMA_BIDIRECTIONAL SCSI_DATA_UNKNOWN -#define DMA_TO_DEVICE SCSI_DATA_WRITE -#define DMA_FROM_DEVICE SCSI_DATA_READ -#define DMA_NONE SCSI_DATA_NONE - -#ifndef HAVE_SECTOR_T -typedef unsigned int sector_t; -#endif - -static inline void -scsi_adjust_queue_depth(struct scsi_device *device, int tag, int depth) -{ - if (tag) { - device->tagged_queue = tag; - device->current_tag = 0; - } - device->queue_depth = depth; -} -static inline struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *t, size_t s) -{ - return scsi_register(t, s); -} -static inline void scsi_host_put(struct Scsi_Host *h) -{ - scsi_unregister(h); -} -#else -#define HOST_LOCK ha->host->host_lock -#endif -#if LINUX_VERSION_CODE < 0x020600 -#define DEV_SIMPLE_TAGS(device) device->tagged_queue -/* - * Hack around that qla1280_remove_one is called from - * qla1280_release in 2.4 - */ -#undef __devexit -#define __devexit -#else -#define DEV_SIMPLE_TAGS(device) device->simple_tags -#endif #if defined(__ia64__) && !defined(ia64_platform_is) #define ia64_platform_is(foo) (!strcmp(x, platform_name)) #endif @@ -506,9 +455,6 @@ static void qla1280_remove_one(struct pci_dev *); * QLogic Driver Support Function Prototypes. */ static void qla1280_done(struct scsi_qla_host *); -#if LINUX_VERSION_CODE < 0x020545 -static void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *); -#endif static int qla1280_get_token(char *); static int qla1280_setup(char *s) __init; @@ -610,11 +556,7 @@ __setup("qla1280=", qla1280_setup); #define CMD_SNSLEN(Cmnd) sizeof(Cmnd->sense_buffer) #define CMD_RESULT(Cmnd) Cmnd->result #define CMD_HANDLE(Cmnd) Cmnd->host_scribble -#if LINUX_VERSION_CODE < 0x020545 -#define CMD_REQUEST(Cmnd) Cmnd->request.cmd -#else #define CMD_REQUEST(Cmnd) Cmnd->request->cmd -#endif #define CMD_HOST(Cmnd) Cmnd->device->host #define SCSI_BUS_32(Cmnd) Cmnd->device->channel @@ -1064,10 +1006,10 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) add_timer(&timer); /* wait for the action to complete (or the timer to expire) */ - spin_unlock_irq(HOST_LOCK); + spin_unlock_irq(ha->host->host_lock); wait_for_completion(&wait); del_timer_sync(&timer); - spin_lock_irq(HOST_LOCK); + spin_lock_irq(ha->host->host_lock); sp->wait = NULL; /* the only action we might get a fail for is abort */ @@ -1173,96 +1115,6 @@ qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev, return 0; } -#if LINUX_VERSION_CODE < 0x020600 -static int -qla1280_detect(struct scsi_host_template *template) -{ - struct pci_device_id *id = &qla1280_pci_tbl[0]; - struct pci_dev *pdev = NULL; - int num_hosts = 0; - - if (sizeof(struct srb) > sizeof(Scsi_Pointer)) { - printk(KERN_WARNING - "qla1280: struct srb too big, aborting\n"); - return 0; - } - - if ((DMA_BIDIRECTIONAL != PCI_DMA_BIDIRECTIONAL) || - (DMA_TO_DEVICE != PCI_DMA_TODEVICE) || - (DMA_FROM_DEVICE != PCI_DMA_FROMDEVICE) || - (DMA_NONE != PCI_DMA_NONE)) { - printk(KERN_WARNING - "qla1280: dma direction bits don't match\n"); - return 0; - } - -#ifdef MODULE - /* - * If we are called as a module, the qla1280 pointer may not be null - * and it would point to our bootup string, just like on the lilo - * command line. IF not NULL, then process this config string with - * qla1280_setup - * - * Boot time Options - * To add options at boot time add a line to your lilo.conf file like: - * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}" - * which will result in the first four devices on the first two - * controllers being set to a tagged queue depth of 32. - */ - if (qla1280) - qla1280_setup(qla1280); -#endif - - /* First Initialize QLA12160 on PCI Bus 1 Dev 2 */ - while ((pdev = pci_find_device(id->vendor, id->device, pdev))) { - if (pdev->bus->number == 1 && PCI_SLOT(pdev->devfn) == 2) { - if (!qla1280_probe_one(pdev, id)) - num_hosts++; - } - } - - pdev = NULL; - /* Try and find each different type of adapter we support */ - for (id = &qla1280_pci_tbl[0]; id->device; id++) { - while ((pdev = pci_find_device(id->vendor, id->device, pdev))) { - /* - * skip QLA12160 already initialized on - * PCI Bus 1 Dev 2 since we already initialized - * and presented it - */ - if (id->device == PCI_DEVICE_ID_QLOGIC_ISP12160 && - pdev->bus->number == 1 && - PCI_SLOT(pdev->devfn) == 2) - continue; - - if (!qla1280_probe_one(pdev, id)) - num_hosts++; - } - } - - return num_hosts; -} - -/* - * This looks a bit ugly as we could just pass down host to - * qla1280_remove_one, but I want to keep qla1280_release purely a wrapper - * around pci_driver::remove as used from 2.6 onwards. - */ -static int -qla1280_release(struct Scsi_Host *host) -{ - struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; - - qla1280_remove_one(ha->pdev); - return 0; -} - -static int -qla1280_biosparam_old(Disk * disk, kdev_t dev, int geom[]) -{ - return qla1280_biosparam(disk->device, NULL, disk->capacity, geom); -} -#endif /* disable risc and host interrupts */ static inline void @@ -1295,7 +1147,7 @@ qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) ENTER_INTR ("qla1280_intr_handler"); ha = (struct scsi_qla_host *)dev_id; - spin_lock(HOST_LOCK); + spin_lock(ha->host->host_lock); ha->isr_count++; reg = ha->iobase; @@ -1311,7 +1163,7 @@ qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) if (!list_empty(&ha->done_q)) qla1280_done(ha); - spin_unlock(HOST_LOCK); + spin_unlock(ha->host->host_lock); qla1280_enable_intrs(ha); @@ -1411,11 +1263,9 @@ qla1280_slave_configure(struct scsi_device *device) scsi_adjust_queue_depth(device, 0, default_depth); } -#if LINUX_VERSION_CODE > 0x020500 nv->bus[bus].target[target].parameter.enable_sync = device->sdtr; nv->bus[bus].target[target].parameter.enable_wide = device->wdtr; nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = device->ppr; -#endif if (driver_setup.no_sync || (driver_setup.sync_mask && @@ -1432,38 +1282,14 @@ qla1280_slave_configure(struct scsi_device *device) nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0; } - spin_lock_irqsave(HOST_LOCK, flags); + spin_lock_irqsave(ha->host->host_lock, flags); if (nv->bus[bus].target[target].parameter.enable_sync) status = qla1280_set_target_parameters(ha, bus, target); qla1280_get_target_parameters(ha, device); - spin_unlock_irqrestore(HOST_LOCK, flags); + spin_unlock_irqrestore(ha->host->host_lock, flags); return status; } -#if LINUX_VERSION_CODE < 0x020545 -/************************************************************************** - * qla1280_select_queue_depth - * - * Sets the queue depth for each SCSI device hanging off the input - * host adapter. We use a queue depth of 2 for devices that do not - * support tagged queueing. - **************************************************************************/ -static void -qla1280_select_queue_depth(struct Scsi_Host *host, struct scsi_device *sdev_q) -{ - struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; - struct scsi_device *sdev; - - ENTER("qla1280_select_queue_depth"); - for (sdev = sdev_q; sdev; sdev = sdev->next) - if (sdev->host == host) - qla1280_slave_configure(sdev); - - if (sdev_q) - qla1280_check_for_dead_scsi_bus(ha, sdev_q->channel); - LEAVE("qla1280_select_queue_depth"); -} -#endif /* * qla1280_done @@ -1523,10 +1349,6 @@ qla1280_done(struct scsi_qla_host *ha) CMD_HANDLE(sp->cmd) = (unsigned char *)INVALID_HANDLE; ha->actthreads--; -#if LINUX_VERSION_CODE < 0x020500 - if (cmd->cmnd[0] == INQUIRY) - qla1280_get_target_options(cmd, ha); -#endif (*(cmd)->scsi_done)(cmd); if(sp->wait != NULL) @@ -1655,9 +1477,7 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha) struct device_reg __iomem *reg; int status; int bus; -#if LINUX_VERSION_CODE > 0x020500 unsigned long flags; -#endif ENTER("qla1280_initialize_adapter"); @@ -1695,15 +1515,12 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha) "NVRAM\n"); } -#if LINUX_VERSION_CODE >= 0x020500 /* * It's necessary to grab the spin here as qla1280_mailbox_command * needs to be able to drop the lock unconditionally to wait * for completion. - * In 2.4 ->detect is called with the io_request_lock held. */ - spin_lock_irqsave(HOST_LOCK, flags); -#endif + spin_lock_irqsave(ha->host->host_lock, flags); status = qla1280_load_firmware(ha); if (status) { @@ -1735,9 +1552,8 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha) ha->flags.online = 1; out: -#if LINUX_VERSION_CODE >= 0x020500 - spin_unlock_irqrestore(HOST_LOCK, flags); -#endif + spin_unlock_irqrestore(ha->host->host_lock, flags); + if (status) dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n"); @@ -2650,14 +2466,14 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb) timer.function = qla1280_mailbox_timeout; add_timer(&timer); - spin_unlock_irq(HOST_LOCK); + spin_unlock_irq(ha->host->host_lock); WRT_REG_WORD(®->host_cmd, HC_SET_HOST_INT); data = qla1280_debounce_register(®->istatus); wait_for_completion(&wait); del_timer_sync(&timer); - spin_lock_irq(HOST_LOCK); + spin_lock_irq(ha->host->host_lock); ha->mailbox_wait = NULL; @@ -2770,9 +2586,9 @@ qla1280_bus_reset(struct scsi_qla_host *ha, int bus) ha->bus_settings[bus].scsi_bus_dead = 1; ha->bus_settings[bus].failed_reset_count++; } else { - spin_unlock_irq(HOST_LOCK); + spin_unlock_irq(ha->host->host_lock); ssleep(reset_delay); - spin_lock_irq(HOST_LOCK); + spin_lock_irq(ha->host->host_lock); ha->bus_settings[bus].scsi_bus_dead = 0; ha->bus_settings[bus].failed_reset_count = 0; @@ -3078,7 +2894,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); /* Enable simple tag queuing if device supports it. */ - if (DEV_SIMPLE_TAGS(cmd->device)) + if (cmd->device->simple_tags) pkt->control_flags |= cpu_to_le16(BIT_3); /* Load SCSI command packet. */ @@ -3377,7 +3193,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); /* Enable simple tag queuing if device supports it. */ - if (DEV_SIMPLE_TAGS(cmd->device)) + if (cmd->device->simple_tags) pkt->control_flags |= cpu_to_le16(BIT_3); /* Load SCSI command packet. */ @@ -3889,50 +3705,6 @@ qla1280_rst_aen(struct scsi_qla_host *ha) } -#if LINUX_VERSION_CODE < 0x020500 -/* - * - */ -static void -qla1280_get_target_options(struct scsi_cmnd *cmd, struct scsi_qla_host *ha) -{ - unsigned char *result; - struct nvram *n; - int bus, target, lun; - - bus = SCSI_BUS_32(cmd); - target = SCSI_TCN_32(cmd); - lun = SCSI_LUN_32(cmd); - - /* - * Make sure to not touch anything if someone is using the - * sg interface. - */ - if (cmd->use_sg || (CMD_RESULT(cmd) >> 16) != DID_OK || lun) - return; - - result = cmd->request_buffer; - n = &ha->nvram; - - n->bus[bus].target[target].parameter.enable_wide = 0; - n->bus[bus].target[target].parameter.enable_sync = 0; - n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0; - - if (result[7] & 0x60) - n->bus[bus].target[target].parameter.enable_wide = 1; - if (result[7] & 0x10) - n->bus[bus].target[target].parameter.enable_sync = 1; - if ((result[2] >= 3) && (result[4] + 5 > 56) && - (result[56] & 0x4)) - n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1; - - dprintk(2, "get_target_options(): wide %i, sync %i, ppr %i\n", - n->bus[bus].target[target].parameter.enable_wide, - n->bus[bus].target[target].parameter.enable_sync, - n->bus[bus].target[target].ppr_1x160.flags.enable_ppr); -} -#endif - /* * qla1280_status_entry * Processes received ISP status entry. @@ -4271,7 +4043,7 @@ qla1280_get_target_parameters(struct scsi_qla_host *ha, } else printk(" Async"); - if (DEV_SIMPLE_TAGS(device)) + if (device->simple_tags) printk(", Tagged queuing: depth %d", device->queue_depth); printk("\n"); } @@ -4485,7 +4257,7 @@ qla1280_get_token(char *str) return ret; } -#if LINUX_VERSION_CODE >= 0x020600 + static struct scsi_host_template qla1280_driver_template = { .module = THIS_MODULE, .proc_name = "qla1280", @@ -4504,27 +4276,7 @@ static struct scsi_host_template qla1280_driver_template = { .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, }; -#else -static struct scsi_host_template qla1280_driver_template = { - .proc_name = "qla1280", - .name = "Qlogic ISP 1280/12160", - .detect = qla1280_detect, - .release = qla1280_release, - .info = qla1280_info, - .queuecommand = qla1280_queuecommand, - .eh_abort_handler = qla1280_eh_abort, - .eh_device_reset_handler= qla1280_eh_device_reset, - .eh_bus_reset_handler = qla1280_eh_bus_reset, - .eh_host_reset_handler = qla1280_eh_adapter_reset, - .bios_param = qla1280_biosparam_old, - .can_queue = 0xfffff, - .this_id = -1, - .sg_tablesize = SG_ALL, - .cmd_per_lun = 1, - .use_clustering = ENABLE_CLUSTERING, - .use_new_eh_code = 1, -}; -#endif + static int __devinit qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) @@ -4615,10 +4367,6 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->max_sectors = 1024; host->unique_id = host->host_no; -#if LINUX_VERSION_CODE < 0x020545 - host->select_queue_depths = qla1280_select_queue_depth; -#endif - error = -ENODEV; #if MEMORY_MAPPED_IO @@ -4666,21 +4414,15 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_set_drvdata(pdev, host); -#if LINUX_VERSION_CODE >= 0x020600 error = scsi_add_host(host, &pdev->dev); if (error) goto error_disable_adapter; scsi_scan_host(host); -#else - scsi_set_pci_device(host, pdev); -#endif return 0; -#if LINUX_VERSION_CODE >= 0x020600 error_disable_adapter: qla1280_disable_intrs(ha); -#endif error_free_irq: free_irq(pdev->irq, ha); error_release_region: @@ -4712,9 +4454,7 @@ qla1280_remove_one(struct pci_dev *pdev) struct Scsi_Host *host = pci_get_drvdata(pdev); struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; -#if LINUX_VERSION_CODE >= 0x020600 scsi_remove_host(host); -#endif qla1280_disable_intrs(ha); @@ -4738,7 +4478,6 @@ qla1280_remove_one(struct pci_dev *pdev) scsi_host_put(host); } -#if LINUX_VERSION_CODE >= 0x020600 static struct pci_driver qla1280_pci_driver = { .name = "qla1280", .id_table = qla1280_pci_tbl, @@ -4784,10 +4523,6 @@ qla1280_exit(void) module_init(qla1280_init); module_exit(qla1280_exit); -#else -# define driver_template qla1280_driver_template -# include "scsi_module.c" -#endif MODULE_AUTHOR("Qlogic & Jes Sorensen"); MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver"); From 2b541f8f77fd339e4c5c5cbe8549b52445012704 Mon Sep 17 00:00:00 2001 From: Dave C Boutcher Date: Thu, 19 Jan 2006 13:34:44 -0600 Subject: [PATCH 134/695] [SCSI] ibmvscsi: handle re-enable firmware message New versions of the Power5 firmware can send a "re-enable" message to the virtual scsi adapter. This fix makes us handle the message correctly. Without it, the driver goes catatonic and the system crashes unpleasantly. Signed-off-by: Dave Boutcher Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvscsi.c | 67 ++++++++++++++------------- drivers/scsi/ibmvscsi/ibmvscsi.h | 3 ++ drivers/scsi/ibmvscsi/iseries_vscsi.c | 13 ++++++ drivers/scsi/ibmvscsi/rpa_vscsi.c | 22 +++++++++ 4 files changed, 74 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 822b9fa706f3..eaefeddb2b4a 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -87,7 +87,7 @@ static int max_channel = 3; static int init_timeout = 5; static int max_requests = 50; -#define IBMVSCSI_VERSION "1.5.7" +#define IBMVSCSI_VERSION "1.5.8" MODULE_DESCRIPTION("IBM Virtual SCSI"); MODULE_AUTHOR("Dave Boutcher"); @@ -534,7 +534,6 @@ static int map_data_for_srp_cmd(struct scsi_cmnd *cmd, static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, struct ibmvscsi_host_data *hostdata) { - struct scsi_cmnd *cmnd; u64 *crq_as_u64 = (u64 *) &evt_struct->crq; int rc; @@ -544,19 +543,8 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, * can handle more requests (can_queue) when we actually can't */ if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) && - (atomic_dec_if_positive(&hostdata->request_limit) < 0)) { - /* See if the adapter is disabled */ - if (atomic_read(&hostdata->request_limit) < 0) - goto send_error; - - printk(KERN_WARNING - "ibmvscsi: Warning, request_limit exceeded\n"); - unmap_cmd_data(&evt_struct->iu.srp.cmd, - evt_struct, - hostdata->dev); - free_event_struct(&hostdata->pool, evt_struct); - return SCSI_MLQUEUE_HOST_BUSY; - } + (atomic_dec_if_positive(&hostdata->request_limit) < 0)) + goto send_error; /* Copy the IU into the transfer area */ *evt_struct->xfer_iu = evt_struct->iu; @@ -572,7 +560,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { list_del(&evt_struct->list); - printk(KERN_ERR "ibmvscsi: failed to send event struct rc %d\n", + printk(KERN_ERR "ibmvscsi: send error %d\n", rc); goto send_error; } @@ -582,14 +570,8 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, send_error: unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); - if ((cmnd = evt_struct->cmnd) != NULL) { - cmnd->result = DID_ERROR << 16; - evt_struct->cmnd_done(cmnd); - } else if (evt_struct->done) - evt_struct->done(evt_struct); - free_event_struct(&hostdata->pool, evt_struct); - return 0; + return SCSI_MLQUEUE_HOST_BUSY; } /** @@ -802,7 +784,8 @@ static void login_rsp(struct srp_event_struct *evt_struct) case SRP_LOGIN_RSP_TYPE: /* it worked! */ break; case SRP_LOGIN_REJ_TYPE: /* refused! */ - printk(KERN_INFO "ibmvscsi: SRP_LOGIN_REQ rejected\n"); + printk(KERN_INFO "ibmvscsi: SRP_LOGIN_REJ reason %u\n", + evt_struct->xfer_iu->srp.login_rej.reason); /* Login failed. */ atomic_set(&hostdata->request_limit, -1); return; @@ -834,6 +817,9 @@ static void login_rsp(struct srp_event_struct *evt_struct) return; } + /* If we had any pending I/Os, kick them */ + scsi_unblock_requests(hostdata->host); + send_mad_adapter_info(hostdata); return; } @@ -862,6 +848,7 @@ static int send_srp_login(struct ibmvscsi_host_data *hostdata) init_timeout * HZ); login = &evt_struct->iu.srp.login_req; + memset(login, 0x00, sizeof(struct srp_login_req)); login->type = SRP_LOGIN_REQ_TYPE; login->max_requested_initiator_to_target_iulen = sizeof(union srp_iu); login->required_buffer_formats = 0x0006; @@ -1122,7 +1109,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) * purge_requests: Our virtual adapter just shut down. purge any sent requests * @hostdata: the adapter */ -static void purge_requests(struct ibmvscsi_host_data *hostdata) +static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code) { struct srp_event_struct *tmp_evt, *pos; unsigned long flags; @@ -1131,7 +1118,7 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata) list_for_each_entry_safe(tmp_evt, pos, &hostdata->sent, list) { list_del(&tmp_evt->list); if (tmp_evt->cmnd) { - tmp_evt->cmnd->result = (DID_ERROR << 16); + tmp_evt->cmnd->result = (error_code << 16); unmap_cmd_data(&tmp_evt->iu.srp.cmd, tmp_evt, tmp_evt->hostdata->dev); @@ -1186,12 +1173,30 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, printk(KERN_ERR "ibmvscsi: unknown crq message type\n"); } return; - case 0xFF: /* Hypervisor telling us the connection is closed */ - printk(KERN_INFO "ibmvscsi: Virtual adapter failed!\n"); + case 0xFF: /* Hypervisor telling us the connection is closed */ + scsi_block_requests(hostdata->host); + if (crq->format == 0x06) { + /* We need to re-setup the interpartition connection */ + printk(KERN_INFO + "ibmvscsi: Re-enabling adapter!\n"); + purge_requests(hostdata, DID_REQUEUE); + if (ibmvscsi_reenable_crq_queue(&hostdata->queue, + hostdata) == 0) + if (ibmvscsi_send_crq(hostdata, + 0xC001000000000000LL, 0)) + printk(KERN_ERR + "ibmvscsi: transmit error after" + " enable\n"); + } else { + printk(KERN_INFO + "ibmvscsi: Virtual adapter failed rc %d!\n", + crq->format); - atomic_set(&hostdata->request_limit, -1); - purge_requests(hostdata); - ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); + atomic_set(&hostdata->request_limit, -1); + purge_requests(hostdata, DID_ERROR); + ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); + } + scsi_unblock_requests(hostdata->host); return; case 0x80: /* real payload */ break; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 5b0edd1f1921..4550d71e4744 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -103,6 +103,9 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata); +int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata); + void ibmvscsi_handle_crq(struct viosrp_crq *crq, struct ibmvscsi_host_data *hostdata); int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index ce15d9e39621..7eed0b098171 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -123,6 +123,19 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, return 0; } +/** + * reenable_crq_queue: - reenables a crq after a failure + * @queue: crq_queue to initialize and register + * @hostdata: ibmvscsi_host_data of host + * + * no-op for iSeries + */ +int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) +{ + return 0; +} + /** * ibmvscsi_send_crq: - Send a CRQ * @hostdata: the adapter diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 75db2f5c545e..f47dd87c05e7 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -280,6 +280,28 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, return -1; } +/** + * reenable_crq_queue: - reenables a crq after + * @queue: crq_queue to initialize and register + * @hostdata: ibmvscsi_host_data of host + * + */ +int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) +{ + int rc; + struct vio_dev *vdev = to_vio_dev(hostdata->dev); + + /* Re-enable the CRQ */ + do { + rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address); + } while ((rc == H_InProgress) || (rc == H_Busy) || (H_isLongBusy(rc))); + + if (rc) + printk(KERN_ERR "ibmvscsi: Error %d enabling adapter\n", rc); + return rc; +} + /** * reset_crq_queue: - resets a crq after a failure * @queue: crq_queue to initialize and register From 1d12d98d284665c37b75b9538916b5fbb8fcde37 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 20 Jan 2006 01:05:00 +0100 Subject: [PATCH 135/695] [SCSI] dc395x: "fix" virt_addr calculation on AUTO_REQSENSE The patch below "fixes" calculation of the virt_addr for the AUTO_REQSENSE case. I put "fixes" in quotes because the real fix would be to completely remove it, but that's beyond the scope of this patch. Signed-off-by: Guennadi Liakhovetski Signed-off-by: James Bottomley --- drivers/scsi/dc395x.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index c8a32cf47d73..cbf825263f3b 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -246,6 +246,7 @@ struct ScsiReqBlk { * total_xfer_length in xferred. These values are restored in * pci_unmap_srb_sense. This is the only place xferred is used. */ + unsigned char *virt_addr_req; /* Saved virtual address of the request buffer */ u32 xferred; /* Saved copy of total_xfer_length */ u16 state; @@ -2017,7 +2018,7 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left) sg_verify_length(srb); /* we need the corresponding virtual address */ - if (!segment) { + if (!segment || (srb->flag & AUTO_REQSENSE)) { srb->virt_addr += xferred; return; } @@ -3318,6 +3319,7 @@ static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb, srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].address; srb->segment_x[0].length = srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].length; + srb->virt_addr = srb->virt_addr_req; } @@ -3711,6 +3713,8 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, srb->xferred = srb->total_xfer_length; /* srb->segment_x : a one entry of S/G list table */ srb->total_xfer_length = sizeof(cmd->sense_buffer); + srb->virt_addr_req = srb->virt_addr; + srb->virt_addr = cmd->sense_buffer; srb->segment_x[0].length = sizeof(cmd->sense_buffer); /* Map sense buffer */ srb->segment_x[0].address = From d97994dc1fddcbb8212b745d9c9c9ce96262155c Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Fri, 20 Jan 2006 14:53:13 -0800 Subject: [PATCH 136/695] [SCSI] qla2xxx: Correct synchronization issues during rport addition/deletion. The driver can typically detect port-loss during an interrupt context (i.e. via interrogation of a status IOCB's completion status [CS_PORT_LOGGED_OUT]. Due to the calling requirements of the fc_rport APIs, the driver would defer removal of the device to the default workqueue. If the work-item was preceded by an event which caused the port to obtain visibility (relogin successful, target re-logged into the topology), deferred removal could inadvertently drop the rport. The code also no longer defers removal via the default workqueue, instead opting for use of the driver's own DPC thread. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 4 ++- drivers/scsi/qla2xxx/qla_gbl.h | 5 +-- drivers/scsi/qla2xxx/qla_init.c | 54 +++++++++++++++++++++++---------- drivers/scsi/qla2xxx/qla_isr.c | 16 +++++----- drivers/scsi/qla2xxx/qla_os.c | 46 +++++++++++++++++++++++----- 5 files changed, 91 insertions(+), 34 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 79d8a914f9d0..bad066e5772a 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1680,7 +1680,8 @@ typedef struct fc_port { uint8_t mp_byte; /* multi-path byte (not used) */ uint8_t cur_path; /* current path id */ - struct fc_rport *rport; + spinlock_t rport_lock; + struct fc_rport *rport, *drport; u32 supported_classes; struct work_struct rport_add_work; struct work_struct rport_del_work; @@ -2270,6 +2271,7 @@ typedef struct scsi_qla_host { #define LOOP_RESET_NEEDED 24 #define BEACON_BLINK_NEEDED 25 #define REGISTER_FDMI_NEEDED 26 +#define FCPORT_UPDATE_NEEDED 27 uint32_t device_flags; #define DFLG_LOCAL_DEVICES BIT_0 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 32be4c14cccb..0c1ec14f3072 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -47,6 +47,7 @@ extern int qla2x00_local_device_login(scsi_qla_host_t *, uint16_t); extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t); extern void qla2x00_rescan_fcports(scsi_qla_host_t *); +extern void qla2x00_update_fcports(scsi_qla_host_t *); extern int qla2x00_abort_isp(scsi_qla_host_t *); @@ -70,8 +71,8 @@ extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); extern void qla2x00_cmd_timeout(srb_t *); -extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); -extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *); +extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); +extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); extern void qla2x00_blink_led(scsi_qla_host_t *); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a91fea69ad63..4c7caece4ca7 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1688,10 +1688,16 @@ static void qla2x00_rport_del(void *data) { fc_port_t *fcport = data; + struct fc_rport *rport; + unsigned long flags; + + spin_lock_irqsave(&fcport->rport_lock, flags); + rport = fcport->drport; + fcport->drport = NULL; + spin_unlock_irqrestore(&fcport->rport_lock, flags); + if (rport) + fc_remote_port_delete(rport); - if (fcport->rport) - fc_remote_port_delete(fcport->rport); - fcport->rport = NULL; } /** @@ -1719,6 +1725,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) atomic_set(&fcport->state, FCS_UNCONFIGURED); fcport->flags = FCF_RLC_SUPPORT; fcport->supported_classes = FC_COS_UNSPECIFIED; + spin_lock_init(&fcport->rport_lock); INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); @@ -2008,7 +2015,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) { fc_port_t *fcport; - qla2x00_mark_all_devices_lost(ha); + qla2x00_mark_all_devices_lost(ha, 0); list_for_each_entry(fcport, &ha->fcports, list) { if (fcport->port_type != FCT_TARGET) continue; @@ -2084,24 +2091,29 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) { struct fc_rport_identifiers rport_ids; struct fc_rport *rport; + unsigned long flags; - if (fcport->rport) { - fc_remote_port_delete(fcport->rport); - fcport->rport = NULL; - } + if (fcport->drport) + qla2x00_rport_del(fcport); + if (fcport->rport) + return; rport_ids.node_name = wwn_to_u64(fcport->node_name); rport_ids.port_name = wwn_to_u64(fcport->port_name); rport_ids.port_id = fcport->d_id.b.domain << 16 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; - fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); + rport = fc_remote_port_add(ha->host, 0, &rport_ids); if (!rport) { qla_printk(KERN_WARNING, ha, "Unable to allocate fc remote port!\n"); return; } + spin_lock_irqsave(&fcport->rport_lock, flags); + fcport->rport = rport; *((fc_port_t **)rport->dd_data) = fcport; + spin_unlock_irqrestore(&fcport->rport_lock, flags); + rport->supported_classes = fcport->supported_classes; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; @@ -2217,12 +2229,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { qla2x00_mark_device_lost(ha, fcport, - ql2xplogiabsentdevice); + ql2xplogiabsentdevice, 0); if (fcport->loop_id != FC_NO_LOOP_ID && (fcport->flags & FCF_TAPE_PRESENT) == 0 && fcport->port_type != FCT_INITIATOR && fcport->port_type != FCT_BROADCAST) { - ha->isp_ops.fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, @@ -2694,7 +2705,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha) if (atomic_read(&fcport->state) == FCS_ONLINE) { if (format != 3 || fcport->port_type != FCT_INITIATOR) { - qla2x00_mark_device_lost(ha, fcport, 0); + qla2x00_mark_device_lost(ha, fcport, + 0, 0); } } fcport->flags &= ~FCF_FARP_DONE; @@ -2741,8 +2753,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport, ha->isp_ops.fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - qla2x00_mark_device_lost(ha, fcport, 1); - + qla2x00_mark_device_lost(ha, fcport, 1, 0); } else { qla2x00_update_fcport(ha, fcport); } @@ -2855,7 +2866,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, ha->isp_ops.fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - qla2x00_mark_device_lost(ha, fcport, 1); + qla2x00_mark_device_lost(ha, fcport, 1, 0); rval = 1; break; @@ -2990,6 +3001,17 @@ qla2x00_rescan_fcports(scsi_qla_host_t *ha) qla2x00_probe_for_all_luns(ha); } +void +qla2x00_update_fcports(scsi_qla_host_t *ha) +{ + fc_port_t *fcport; + + /* Go with deferred removal of rport references. */ + list_for_each_entry(fcport, &ha->fcports, list) + if (fcport->drport) + qla2x00_rport_del(fcport); +} + /* * qla2x00_abort_isp * Resets ISP and aborts all outstanding commands. @@ -3019,7 +3041,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); if (atomic_read(&ha->loop_state) != LOOP_DOWN) { atomic_set(&ha->loop_state, LOOP_DOWN); - qla2x00_mark_all_devices_lost(ha); + qla2x00_mark_all_devices_lost(ha, 0); } else { if (!atomic_read(&ha->loop_down_timer)) atomic_set(&ha->loop_down_timer, diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f63af081d4ff..71a46fcee8cc 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -389,7 +389,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) if (atomic_read(&ha->loop_state) != LOOP_DOWN) { atomic_set(&ha->loop_state, LOOP_DOWN); atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(ha); + qla2x00_mark_all_devices_lost(ha, 1); } set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); @@ -432,7 +432,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) atomic_set(&ha->loop_state, LOOP_DOWN); atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); ha->device_flags |= DFLG_NO_CABLE; - qla2x00_mark_all_devices_lost(ha); + qla2x00_mark_all_devices_lost(ha, 1); } ha->flags.management_server_logged_in = 0; @@ -453,7 +453,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) if (atomic_read(&ha->loop_state) != LOOP_DOWN) { atomic_set(&ha->loop_state, LOOP_DOWN); atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(ha); + qla2x00_mark_all_devices_lost(ha, 1); } set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); @@ -482,7 +482,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) if (!atomic_read(&ha->loop_down_timer)) atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(ha); + qla2x00_mark_all_devices_lost(ha, 1); } if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) { @@ -506,7 +506,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) if (!atomic_read(&ha->loop_down_timer)) atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(ha); + qla2x00_mark_all_devices_lost(ha, 1); } set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); @@ -580,7 +580,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) */ atomic_set(&ha->loop_state, LOOP_UP); - qla2x00_mark_all_devices_lost(ha); + qla2x00_mark_all_devices_lost(ha, 1); ha->flags.rscn_queue_overflow = 1; @@ -1091,7 +1091,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) cp->result = DID_BUS_BUSY << 16; if (atomic_read(&fcport->state) == FCS_ONLINE) { - qla2x00_mark_device_lost(ha, fcport, 1); + qla2x00_mark_device_lost(ha, fcport, 1, 1); } break; @@ -1135,7 +1135,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) /* Check to see if logout occurred. */ if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT)) - qla2x00_mark_device_lost(ha, fcport, 1); + qla2x00_mark_device_lost(ha, fcport, 1, 1); break; case CS_QUEUE_FULL: diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 4916847d84ec..089e0f500363 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -756,7 +756,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) if (ret == SUCCESS) { if (fcport->flags & FC_FABRIC_DEVICE) { ha->isp_ops.fabric_logout(ha, fcport->loop_id); - qla2x00_mark_device_lost(ha, fcport); + qla2x00_mark_device_lost(ha, fcport, 0, 0); } } #endif @@ -1642,6 +1642,31 @@ qla2x00_free_device(scsi_qla_host_t *ha) pci_disable_device(ha->pdev); } +static inline void +qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, + int defer) +{ + unsigned long flags; + struct fc_rport *rport; + + if (!fcport->rport) + return; + + rport = fcport->rport; + if (defer) { + spin_lock_irqsave(&fcport->rport_lock, flags); + fcport->drport = rport; + fcport->rport = NULL; + spin_unlock_irqrestore(&fcport->rport_lock, flags); + set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); + } else { + spin_lock_irqsave(&fcport->rport_lock, flags); + fcport->rport = NULL; + spin_unlock_irqrestore(&fcport->rport_lock, flags); + fc_remote_port_delete(rport); + } +} + /* * qla2x00_mark_device_lost Updates fcport state when device goes offline. * @@ -1652,10 +1677,10 @@ qla2x00_free_device(scsi_qla_host_t *ha) * Context: */ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, - int do_login) + int do_login, int defer) { - if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) - schedule_work(&fcport->rport_del_work); + if (atomic_read(&fcport->state) == FCS_ONLINE) + qla2x00_schedule_rport_del(ha, fcport, defer); /* * We may need to retry the login, so don't change the state of the @@ -1702,7 +1727,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, * Context: */ void -qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) +qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) { fc_port_t *fcport; @@ -1716,10 +1741,13 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) */ if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) continue; - if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) - schedule_work(&fcport->rport_del_work); + if (atomic_read(&fcport->state) == FCS_ONLINE) + qla2x00_schedule_rport_del(ha, fcport, defer); atomic_set(&fcport->state, FCS_DEVICE_LOST); } + + if (defer && ha->dpc_wait && !ha->dpc_active) + up(ha->dpc_wait); } /* @@ -2161,6 +2189,9 @@ qla2x00_do_dpc(void *data) ha->host_no)); } + if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) + qla2x00_update_fcports(ha); + if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) { DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n", ha->host_no)); @@ -2469,6 +2500,7 @@ qla2x00_timer(scsi_qla_host_t *ha) if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || + test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || start_dpc || test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || From 052c40c83b4ca37be226112049b60097cb9961e1 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Fri, 20 Jan 2006 14:53:19 -0800 Subject: [PATCH 137/695] [SCSI] qla2xxx: Correct issue where the rport's upcall was not being made after relogin. A target can LOGO an initiator at any time (i.e. during I/O, due to a controller hicup, or as a simple authentication mechanism after an initial CDB command), when this occurs, the driver attempts to relogin (PLOGI) to the device via the DPC thread. Add code to make the appropriate upcall to the FC transport layer (fc_remote_port_add()) upon successful completion of the PLOGI. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_gbl.h | 1 + drivers/scsi/qla2xxx/qla_init.c | 3 +-- drivers/scsi/qla2xxx/qla_os.c | 9 ++------- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 0c1ec14f3072..35266bd5d538 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -51,6 +51,7 @@ extern void qla2x00_update_fcports(scsi_qla_host_t *); extern int qla2x00_abort_isp(scsi_qla_host_t *); +extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); /* diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 4c7caece4ca7..16c889261d94 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -32,7 +32,6 @@ static int qla2x00_fw_ready(scsi_qla_host_t *); static int qla2x00_configure_hba(scsi_qla_host_t *); static int qla2x00_configure_loop(scsi_qla_host_t *); static int qla2x00_configure_local_loop(scsi_qla_host_t *); -static void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); static int qla2x00_configure_fabric(scsi_qla_host_t *); static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *); static int qla2x00_device_resync(scsi_qla_host_t *); @@ -2039,7 +2038,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) * Context: * Kernel context. */ -static void +void qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) { uint16_t index; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 089e0f500363..5866a7c706a8 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2250,13 +2250,8 @@ qla2x00_do_dpc(void *data) DEBUG(printk("scsi(%ld): port login OK: logged in ID 0x%x\n", ha->host_no, fcport->loop_id)); - fcport->port_login_retry_count = - ha->port_down_retry_count * PORT_RETRY_TIME; - atomic_set(&fcport->state, FCS_ONLINE); - atomic_set(&fcport->port_down_timer, - ha->port_down_retry_count * PORT_RETRY_TIME); - - fcport->login_retry = 0; + qla2x00_update_fcport(ha, + fcport); } else if (status == 1) { set_bit(RELOGIN_NEEDED, &ha->dpc_flags); /* retry the login again */ From 77427f514f88143bfef41ba8c1e624bc45f42297 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Fri, 20 Jan 2006 14:53:25 -0800 Subject: [PATCH 138/695] [SCSI] qla2xxx: Drop legacy 'bypass lun scan for tape device' code. Internal lun discovery has been removed since fc_transport integration. Short-circuiting for tape-devices in qla2x00_update_fcport() could inadvertently result in a blocked rport timing-out and its targets being reaped. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 16c889261d94..e67bb0997818 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2041,10 +2041,6 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) void qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) { - uint16_t index; - unsigned long flags; - srb_t *sp; - fcport->ha = ha; fcport->login_retry = 0; fcport->port_login_retry_count = ha->port_down_retry_count * @@ -2053,28 +2049,6 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) PORT_RETRY_TIME); fcport->flags &= ~FCF_LOGIN_NEEDED; - /* - * Check for outstanding cmd on tape Bypass LUN discovery if active - * command on tape. - */ - if (fcport->flags & FCF_TAPE_PRESENT) { - spin_lock_irqsave(&ha->hardware_lock, flags); - for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) { - fc_port_t *sfcp; - - if ((sp = ha->outstanding_cmds[index]) != 0) { - sfcp = sp->fcport; - if (sfcp == fcport) { - atomic_set(&fcport->state, FCS_ONLINE); - spin_unlock_irqrestore( - &ha->hardware_lock, flags); - return; - } - } - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - } - if (fcport->port_type == FCT_INITIATOR || fcport->port_type == FCT_BROADCAST) fcport->device_type = TYPE_PROCESSOR; From 15084a4a63bc300c18b28a8a9afac870c552abce Mon Sep 17 00:00:00 2001 From: Jack Hammer Date: Tue, 24 Jan 2006 14:43:41 -0500 Subject: [PATCH 139/695] [SCSI] ips soft lockup during reset/initialization Resetting the adapter causes the ServeRAID driver to exceed the max time allowed by the softlock watchdog. Resetting the hardware can easily require 30 or more seconds. To avoid the "BUG: soft lockup detected on CPU#0!" result, this patch replaces the mdelay() calls in the initialization/reset routines with msleep(). Signed-off-by: Jack Hammer Signed-off-by: James Bottomley --- drivers/scsi/ips.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index e5e1ca44e1ee..32d592befca6 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -5012,7 +5012,7 @@ ips_init_copperhead(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (j >= 45) @@ -5038,7 +5038,7 @@ ips_init_copperhead(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (j >= 240) @@ -5056,7 +5056,7 @@ ips_init_copperhead(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 240) @@ -5106,7 +5106,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (j >= 45) @@ -5132,7 +5132,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (j >= 240) @@ -5150,7 +5150,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 240) @@ -5202,7 +5202,7 @@ ips_init_morpheus(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 45) { @@ -5228,7 +5228,7 @@ ips_init_morpheus(ips_ha_t * ha) if (Post != 0x4F00) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 120) { @@ -5258,7 +5258,7 @@ ips_init_morpheus(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 240) { @@ -5318,12 +5318,12 @@ ips_reset_copperhead(ips_ha_t * ha) outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); outb(0, ha->io_addr + IPS_REG_SCPR); /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); if ((*ha->func.init) (ha)) break; @@ -5363,12 +5363,12 @@ ips_reset_copperhead_memio(ips_ha_t * ha) writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); writeb(0, ha->mem_ptr + IPS_REG_SCPR); /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); if ((*ha->func.init) (ha)) break; @@ -5409,7 +5409,7 @@ ips_reset_morpheus(ips_ha_t * ha) writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); /* Delay for 5 Seconds */ - MDELAY(5 * IPS_ONE_SEC); + msleep(5 * IPS_ONE_SEC); /* Do a PCI config read to wait for adapter */ pci_read_config_byte(ha->pcidev, 4, &junk); From c70ca00f77eb1bb69c5a2d029b3a911bc88eac1b Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Wed, 18 Jan 2006 23:45:39 -0800 Subject: [PATCH 140/695] [CPUFREQ] p4-clockmod: Workaround for CPU's with N60 errata Ignore clock frequencies below 2Ghz for CPU's detected with N60 errata bug. Signed-off-by: Ben Collins Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index 270f2188d68b..cc73a7ae34bc 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -52,6 +52,7 @@ enum { static int has_N44_O17_errata[NR_CPUS]; +static int has_N60_errata[NR_CPUS]; static unsigned int stock_freq; static struct cpufreq_driver p4clockmod_driver; static unsigned int cpufreq_p4_get(unsigned int cpu); @@ -226,6 +227,12 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) case 0x0f12: has_N44_O17_errata[policy->cpu] = 1; dprintk("has errata -- disabling low frequencies\n"); + break; + + case 0x0f29: + has_N60_errata[policy->cpu] = 1; + dprintk("has errata -- disabling frequencies lower than 2ghz\n"); + break; } /* get max frequency */ @@ -237,6 +244,8 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { if ((i<2) && (has_N44_O17_errata[policy->cpu])) p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; + else if (has_N60_errata[policy->cpu] && p4clockmod_table[i].frequency < 2000000) + p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; else p4clockmod_table[i].frequency = (stock_freq * i)/8; } From 0961dd0d217d072df736d964f47c2b6600931e19 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 26 Jan 2006 18:46:33 +0100 Subject: [PATCH 141/695] [CPUFREQ] _PPC frequency change issues BIOS might change frequency behind our back when BIOS changes allowed frequencies via _PPC. In this case cpufreq core got out of sync. Ask driver for current freq and notify governors about a change Signed-off-by: Thomas Renninger Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0a6c4c8642e7..7a511479ae29 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1429,6 +1429,14 @@ int cpufreq_update_policy(unsigned int cpu) policy.policy = data->user_policy.policy; policy.governor = data->user_policy.governor; + /* BIOS might change freq behind our back + -> ask driver for current freq and notify governors about a change */ + if (cpufreq_driver->get) { + policy.cur = cpufreq_driver->get(cpu); + if (data->cur != policy.cur) + cpufreq_out_of_sync(cpu, data->cur, policy.cur); + } + ret = __cpufreq_set_policy(data, &policy); mutex_unlock(&data->lock); From bb1d1073a10fdc8547e3eb821ee2488260094b39 Mon Sep 17 00:00:00 2001 From: "brking@us.ibm.com" Date: Mon, 23 Jan 2006 15:03:22 -0600 Subject: [PATCH 142/695] [SCSI] Prevent scsi_execute_async from guessing cdb length When the scsi_execute_async interface was added it ended up reducing the flexibility of userspace to send arbitrary scsi commands through sg using SG_IO. The SG_IO interface allows userspace to specify the CDB length. This is now ignored in scsi_execute_async and it is guessed using the COMMAND_SIZE macro, which is not always correct, particularly for vendor specific commands. This patch adds a cmd_len parameter to the scsi_execute_async interface to allow the caller to specify the length of the CDB. Signed-off-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 2 +- drivers/scsi/scsi_lib.c | 5 +++-- drivers/scsi/sg.c | 2 +- drivers/scsi/st.c | 2 +- include/scsi/scsi_device.h | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index a2333d2c7af0..5cc97b721661 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1350,7 +1350,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev) cmnd[4] = SCSI_REMOVAL_PREVENT; cmnd[5] = 0; - scsi_execute_async(sdev, cmnd, DMA_NONE, NULL, 0, 0, 10 * HZ, + scsi_execute_async(sdev, cmnd, 6, DMA_NONE, NULL, 0, 0, 10 * HZ, 5, NULL, NULL, GFP_KERNEL); } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3574ba935af8..4a602853a98e 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -436,6 +436,7 @@ free_bios: * scsi_execute_async - insert request * @sdev: scsi device * @cmd: scsi command + * @cmd_len: length of scsi cdb * @data_direction: data direction * @buffer: data buffer (this can be a kernel buffer or scatterlist) * @bufflen: len of buffer @@ -445,7 +446,7 @@ free_bios: * @flags: or into request flags **/ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, - int data_direction, void *buffer, unsigned bufflen, + int cmd_len, int data_direction, void *buffer, unsigned bufflen, int use_sg, int timeout, int retries, void *privdata, void (*done)(void *, char *, int, int), gfp_t gfp) { @@ -472,7 +473,7 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, if (err) goto free_req; - req->cmd_len = COMMAND_SIZE(cmd[0]); + req->cmd_len = cmd_len; memcpy(req->cmd, cmd, req->cmd_len); req->sense = sioc->sense; req->sense_len = 0; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 78aad9582bcf..7d0700091f3d 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -741,7 +741,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, hp->duration = jiffies_to_msecs(jiffies); /* Now send everything of to mid-level. The next time we hear about this packet is when sg_cmd_done() is called (i.e. a callback). */ - if (scsi_execute_async(sdp->device, cmnd, data_dir, srp->data.buffer, + if (scsi_execute_async(sdp->device, cmnd, hp->cmd_len, data_dir, srp->data.buffer, hp->dxfer_len, srp->data.k_use_sg, timeout, SG_DEFAULT_RETRIES, srp, sg_cmd_done, GFP_ATOMIC)) { diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 13b1d3aac265..7f96f33c1bb1 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -508,7 +508,7 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd STp->buffer->cmdstat.have_sense = 0; STp->buffer->syscall_result = 0; - if (scsi_execute_async(STp->device, cmd, direction, + if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs, timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) { /* could not allocate the buffer or request was too large */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index e94ca4d36035..290e3b4d2aec 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -275,7 +275,7 @@ extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, struct scsi_sense_hdr *, int timeout, int retries); extern int scsi_execute_async(struct scsi_device *sdev, - const unsigned char *cmd, int data_direction, + const unsigned char *cmd, int cmd_len, int data_direction, void *buffer, unsigned bufflen, int use_sg, int timeout, int retries, void *privdata, void (*done)(void *, char *, int, int), From 61d67f2e07d96d20d86135792ca591c491939c27 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Wed, 25 Jan 2006 18:51:14 -0500 Subject: [PATCH 143/695] [IA64-SGI] Add PROM feature set for device flush list Introduce PRF_DEVICE_FLUSH_LIST flag for older PROMs. Signed-off-by: Prarit Bhargava Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/io_init.c | 36 +++++++++++++-------------- include/asm-ia64/sn/sn_feature_sets.h | 7 +++--- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 00700f7e6837..a4c78152b336 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -173,8 +174,8 @@ sn_pcidev_info_get(struct pci_dev *dev) */ static u8 war_implemented = 0; -static void sn_device_fixup_war(u64 nasid, u64 widget, int device, - struct sn_flush_device_common *common) +static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, + struct sn_flush_device_common *common) { struct sn_flush_device_war *war_list; struct sn_flush_device_war *dev_entry; @@ -198,8 +199,9 @@ static void sn_device_fixup_war(u64 nasid, u64 widget, int device, dev_entry = war_list + device; memcpy(common,dev_entry, sizeof(*common)); - kfree(war_list); + + return isrv.status; } /* @@ -279,23 +281,21 @@ static void sn_fixup_ionodes(void) memset(dev_entry->common, 0x0, sizeof(struct sn_flush_device_common)); - status = sal_get_device_dmaflush_list(nasid, - widget, - device, + if (sn_prom_feature_available( + PRF_DEVICE_FLUSH_LIST)) + status = sal_get_device_dmaflush_list( + nasid, + widget, + device, (u64)(dev_entry->common)); - if (status) { - if (sn_sal_rev() < 0x0450) { - /* shortlived WAR for older - * PROM images - */ - sn_device_fixup_war(nasid, - widget, - device, + else + status = sn_device_fixup_war(nasid, + widget, + device, dev_entry->common); - } - else - BUG(); - } + if (status != SALRET_OK) + panic("SAL call failed: %s\n", + ia64_sal_strerror(status)); spin_lock_init(&dev_entry->sfdl_flush_lock); } diff --git a/include/asm-ia64/sn/sn_feature_sets.h b/include/asm-ia64/sn/sn_feature_sets.h index f63f144e8170..9ca642cad338 100644 --- a/include/asm-ia64/sn/sn_feature_sets.h +++ b/include/asm-ia64/sn/sn_feature_sets.h @@ -31,7 +31,8 @@ extern int sn_prom_feature_available(int id); * ... */ -#define PRF_PAL_CACHE_FLUSH_SAFE 0 +#define PRF_PAL_CACHE_FLUSH_SAFE 0 +#define PRF_DEVICE_FLUSH_LIST 1 @@ -48,7 +49,7 @@ extern int sn_prom_feature_available(int id); * * By default, features are disabled unless explicitly enabled. */ -#define OSF_MCA_SLV_TO_OS_INIT_SLV 0 -#define OSF_FEAT_LOG_SBES 1 +#define OSF_MCA_SLV_TO_OS_INIT_SLV 0 +#define OSF_FEAT_LOG_SBES 1 #endif /* _ASM_IA64_SN_FEATURE_SETS_H */ From d4ec6c7cc9a15a7a529719bc3b84f46812f9842e Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 26 Jan 2006 17:23:38 -0500 Subject: [PATCH 144/695] [ACPI] remove "Resource isn't an IRQ" warning In the case where a (broken) BIOS gives us a blank _CRS for a PCI Interrupt Link Device, the acpi_walk_resources() will not terminate, but will then give the callback the resource end tag. Ignore the end tag. Signed-off-by: Len Brown --- drivers/acpi/pci_link.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 1ffc77115367..07bc6dfe662b 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -233,8 +233,10 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context) *irq = p->interrupts[0]; break; } + break; default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Resource isn't an IRQ\n")); + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Resource %d isn't an IRQ\n", resource->type)); + case ACPI_RESOURCE_TYPE_END_TAG: return_ACPI_STATUS(AE_OK); } return_ACPI_STATUS(AE_CTRL_TERMINATE); From 6fe8f479d02e47c80f816b2b9f5d3996ebfe6af6 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 26 Jan 2006 22:40:40 -0800 Subject: [PATCH 145/695] [X86] Add new Intel cache descriptors. From http://www.intel.com/design/xeon/applnots/24161830.pdf 16MB of 16-way assoc 64 byte per cacheline L3 cache anyone? Yum. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/intel_cacheinfo.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index fbfd374aa336..af591c73345f 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -43,13 +43,23 @@ static struct _cache_table cache_table[] __cpuinitdata = { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */ { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */ { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */ { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */ { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */ + { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */ { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */ { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */ { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */ { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */ + { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */ + { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */ + { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ + { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */ + { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ + { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */ + { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */ { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */ { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */ { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */ @@ -57,6 +67,7 @@ static struct _cache_table cache_table[] __cpuinitdata = { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */ { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */ { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */ + { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */ { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */ { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */ { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */ From c0672860199ac009af7cf198a134ee7a4c3a9bb3 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 27 Jan 2006 16:15:26 +0100 Subject: [PATCH 146/695] [CPUFREQ] Get rid of userspace policy struct, make userspace gov _PPC safe. Userspace governor need not to hold it's own cpufreq_policy, better make use of the global core policy. Also fixes a bug in case of frequency changes via _PPC. Old min/max values have wrongly been passed to __cpufreq_driver_target() (kind of buffered) and when max freq was available again, only the old max(normally lowest freq) was still active. Signed-off-by: Thomas Renninger Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones cpufreq_userspace.c | 53 +++++++++++++++++++++++++++------------------------- 1 files changed, 28 insertions(+), 25 deletions(-) --- drivers/cpufreq/cpufreq_userspace.c | 53 +++++++++++++++-------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 4d6fa63da598..92a0be22a2a9 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -1,3 +1,4 @@ + /* * linux/drivers/cpufreq/cpufreq_userspace.c * @@ -34,7 +35,6 @@ static unsigned int cpu_min_freq[NR_CPUS]; static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ static unsigned int cpu_is_managed[NR_CPUS]; -static struct cpufreq_policy current_policy[NR_CPUS]; static DEFINE_MUTEX (userspace_mutex); @@ -65,22 +65,22 @@ static struct notifier_block userspace_cpufreq_notifier_block = { * * Sets the CPU frequency to freq. */ -static int cpufreq_set(unsigned int freq, unsigned int cpu) +static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) { int ret = -EINVAL; - dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq); + dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); mutex_lock(&userspace_mutex); - if (!cpu_is_managed[cpu]) + if (!cpu_is_managed[policy->cpu]) goto err; - cpu_set_freq[cpu] = freq; + cpu_set_freq[policy->cpu] = freq; - if (freq < cpu_min_freq[cpu]) - freq = cpu_min_freq[cpu]; - if (freq > cpu_max_freq[cpu]) - freq = cpu_max_freq[cpu]; + if (freq < cpu_min_freq[policy->cpu]) + freq = cpu_min_freq[policy->cpu]; + if (freq > cpu_max_freq[policy->cpu]) + freq = cpu_max_freq[policy->cpu]; /* * We're safe from concurrent calls to ->target() here @@ -89,8 +89,7 @@ static int cpufreq_set(unsigned int freq, unsigned int cpu) * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock) * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex) */ - ret = __cpufreq_driver_target(¤t_policy[cpu], freq, - CPUFREQ_RELATION_L); + ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); err: mutex_unlock(&userspace_mutex); @@ -114,7 +113,7 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count) if (ret != 1) return -EINVAL; - cpufreq_set(freq, policy->cpu); + cpufreq_set(freq, policy); return count; } @@ -142,7 +141,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, cpu_cur_freq[cpu] = policy->cur; cpu_set_freq[cpu] = policy->cur; sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); - memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); mutex_unlock(&userspace_mutex); break; @@ -158,20 +156,25 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, break; case CPUFREQ_GOV_LIMITS: mutex_lock(&userspace_mutex); + dprintk("limit event for cpu %u: %u - %u kHz," + "currently %u kHz, last set to %u kHz\n", + cpu, policy->min, policy->max, + cpu_cur_freq[cpu], cpu_set_freq[cpu]); + if (policy->max < cpu_set_freq[cpu]) { + __cpufreq_driver_target(policy, policy->max, + CPUFREQ_RELATION_H); + } + else if (policy->min > cpu_set_freq[cpu]) { + __cpufreq_driver_target(policy, policy->min, + CPUFREQ_RELATION_L); + } + else { + __cpufreq_driver_target(policy, cpu_set_freq[cpu], + CPUFREQ_RELATION_L); + } cpu_min_freq[cpu] = policy->min; cpu_max_freq[cpu] = policy->max; - dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]); - if (policy->max < cpu_set_freq[cpu]) { - __cpufreq_driver_target(¤t_policy[cpu], policy->max, - CPUFREQ_RELATION_H); - } else if (policy->min > cpu_set_freq[cpu]) { - __cpufreq_driver_target(¤t_policy[cpu], policy->min, - CPUFREQ_RELATION_L); - } else { - __cpufreq_driver_target(¤t_policy[cpu], cpu_set_freq[cpu], - CPUFREQ_RELATION_L); - } - memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); + cpu_cur_freq[cpu] = policy->cur; mutex_unlock(&userspace_mutex); break; } From eb9bdaa3f3b9d30d09bcad47037216aa39639b8e Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 27 Jan 2006 15:11:47 -0800 Subject: [PATCH 147/695] Signed-off-by: Steve French --- fs/cifs/file.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 77c990f0cb98..d17c97d07c80 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1190,7 +1190,6 @@ retry: /* BB what if continued retry is requested via mount flags? */ set_bit(AS_EIO, &mapping->flags); - SetPageError(page); } else { cifs_stats_bytes_written(cifs_sb->tcon, bytes_written); @@ -1198,6 +1197,13 @@ retry: } for (i = 0; i < n_iov; i++) { page = pvec.pages[first + i]; + /* Should we also set page error on + success rc but too little data written? */ + /* BB investigate retry logic on temporary + server crash cases and how recovery works + when page marked as error */ + if(rc) + SetPageError(page); kunmap(page); unlock_page(page); page_cache_release(page); From 1877c9ea66a29563987f22d0a86c66f438a87ce2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 27 Jan 2006 18:36:11 -0800 Subject: [PATCH 148/695] [CIFS] Remove compiler warning Signed-off-by: Steve French --- fs/cifs/connect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index eae306fa24b2..e488603fb1e7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1786,7 +1786,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->wsize = volume_info.wsize; else cifs_sb->wsize = - min(PAGEVEC_SIZE * PAGE_CACHE_SIZE, 127*1024); + min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE, + 127*1024); /* old default of CIFSMaxBufSize was too small now that SMB Write2 can send multiple pages in kvec. RFC1001 does not describe what happens when frame From bd12097c7415c13aff53aed473eec92acd15712a Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 29 Jan 2006 02:47:03 -0500 Subject: [PATCH 149/695] [libata ahci] Isolate Intel-ism, add JMicron JMB360 support Isolate some PCI config register bitbanging to Intel hardware, as it should have been all along. Add support for JMicron JMB360. --- drivers/scsi/ahci.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 19bd346951dd..2fffc7bf5d96 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -286,6 +286,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { board_ahci }, /* ICH8M */ { PCI_VENDOR_ID_INTEL, 0x282a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* ICH8M */ + { 0x197b, 0x2360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* JMicron JMB360 */ { } /* terminate list */ }; @@ -802,7 +804,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) struct pci_dev *pdev = to_pci_dev(probe_ent->dev); void __iomem *mmio = probe_ent->mmio_base; u32 tmp, cap_save; - u16 tmp16; unsigned int i, j, using_dac; int rc; void __iomem *port_mmio; @@ -836,9 +837,13 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) writel(0xf, mmio + HOST_PORTS_IMPL); (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ - pci_read_config_word(pdev, 0x92, &tmp16); - tmp16 |= 0xf; - pci_write_config_word(pdev, 0x92, tmp16); + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { + u16 tmp16; + + pci_read_config_word(pdev, 0x92, &tmp16); + tmp16 |= 0xf; + pci_write_config_word(pdev, 0x92, tmp16); + } hpriv->cap = readl(mmio + HOST_CAP); hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); @@ -1082,6 +1087,10 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (have_msi) hpriv->flags |= AHCI_FLAG_MSI; + /* JMicron-specific fixup: make sure we're in AHCI mode */ + if (pdev->vendor == 0x197b) + pci_write_config_byte(pdev, 0x41, 0xa1); + /* initialize adapter */ rc = ahci_host_init(probe_ent); if (rc) From cb59aa6a7ca1ae40fd436c45dff568a83f3fab2f Mon Sep 17 00:00:00 2001 From: Sumant Patro Date: Wed, 25 Jan 2006 11:53:25 -0800 Subject: [PATCH 150/695] [SCSI] megaraid_sas: cleanup queue command path This patch (originally submitted by Christoph Hellwig) removes code duplication in megasas_build_cmd. It also defines MEGASAS_IOC_FIRMWARE32 to allow 64 bit compiled applications to work. Signed-off-by: Sumant Patro Rejections fixed and Signed-off-by: James Bottomley --- Documentation/scsi/ChangeLog.megaraid_sas | 15 ++ drivers/scsi/megaraid/megaraid_sas.c | 160 +++++++--------------- drivers/scsi/megaraid/megaraid_sas.h | 12 +- 3 files changed, 68 insertions(+), 119 deletions(-) create mode 100644 Documentation/scsi/ChangeLog.megaraid_sas diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas new file mode 100644 index 000000000000..e2319aeffbcc --- /dev/null +++ b/Documentation/scsi/ChangeLog.megaraid_sas @@ -0,0 +1,15 @@ +1 Release Date : Mon Dec 19 14:36:26 PST 2005 - Sumant Patro +2 Current Version : 00.00.02.00-rc4 +3 Older Version : 00.00.02.01 + +i. Code reorganized to remove code duplication in megasas_build_cmd. + + "There's a lot of duplicate code megasas_build_cmd. Move that out of the different codepathes and merge the reminder of megasas_build_cmd into megasas_queue_command" + + - Christoph Hellwig + +ii. Defined MEGASAS_IOC_FIRMWARE32 for code paths that handles 32 bit applications in 64 bit systems. + + "MEGASAS_IOC_FIRMWARE can't be redefined if CONFIG_COMPAT is set, we need to define a MEGASAS_IOC_FIRMWARE32 define so native binaries continue to work" + + - Christoph Hellwig diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 511ed52a5807..2fb53af8de2a 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.02.00-rc4 + * Version : v00.00.02.01 * * Authors: * Sreenivas Bagalkote @@ -558,112 +558,29 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, } /** - * megasas_build_cmd - Prepares a command packet - * @instance: Adapter soft state - * @scp: SCSI command - * @frame_count: [OUT] Number of frames used to prepare this command + * megasas_is_ldio - Checks if the cmd is for logical drive + * @scmd: SCSI command + * + * Called by megasas_queue_command to find out if the command to be queued + * is a logical drive command */ -static struct megasas_cmd *megasas_build_cmd(struct megasas_instance - *instance, - struct scsi_cmnd *scp, - int *frame_count) +static inline int megasas_is_ldio(struct scsi_cmnd *cmd) { - u32 logical_cmd; - struct megasas_cmd *cmd; - - /* - * Find out if this is logical or physical drive command. - */ - logical_cmd = MEGASAS_IS_LOGICAL(scp); - - /* - * Logical drive command - */ - if (logical_cmd) { - - if (scp->device->id >= MEGASAS_MAX_LD) { - scp->result = DID_BAD_TARGET << 16; - return NULL; - } - - switch (scp->cmnd[0]) { - - case READ_10: - case WRITE_10: - case READ_12: - case WRITE_12: - case READ_6: - case WRITE_6: - case READ_16: - case WRITE_16: - /* - * Fail for LUN > 0 - */ - if (scp->device->lun) { - scp->result = DID_BAD_TARGET << 16; - return NULL; - } - - cmd = megasas_get_cmd(instance); - - if (!cmd) { - scp->result = DID_IMM_RETRY << 16; - return NULL; - } - - *frame_count = megasas_build_ldio(instance, scp, cmd); - - if (!(*frame_count)) { - megasas_return_cmd(instance, cmd); - return NULL; - } - - return cmd; - - default: - /* - * Fail for LUN > 0 - */ - if (scp->device->lun) { - scp->result = DID_BAD_TARGET << 16; - return NULL; - } - - cmd = megasas_get_cmd(instance); - - if (!cmd) { - scp->result = DID_IMM_RETRY << 16; - return NULL; - } - - *frame_count = megasas_build_dcdb(instance, scp, cmd); - - if (!(*frame_count)) { - megasas_return_cmd(instance, cmd); - return NULL; - } - - return cmd; - } - } else { - cmd = megasas_get_cmd(instance); - - if (!cmd) { - scp->result = DID_IMM_RETRY << 16; - return NULL; - } - - *frame_count = megasas_build_dcdb(instance, scp, cmd); - - if (!(*frame_count)) { - megasas_return_cmd(instance, cmd); - return NULL; - } - - return cmd; + if (!MEGASAS_IS_LOGICAL(cmd)) + return 0; + switch (cmd->cmnd[0]) { + case READ_10: + case WRITE_10: + case READ_12: + case WRITE_12: + case READ_6: + case WRITE_6: + case READ_16: + case WRITE_16: + return 1; + default: + return 0; } - - return NULL; } /** @@ -684,13 +601,27 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) scmd->scsi_done = done; scmd->result = 0; - cmd = megasas_build_cmd(instance, scmd, &frame_count); - - if (!cmd) { - done(scmd); - return 0; + if (MEGASAS_IS_LOGICAL(scmd) && + (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) { + scmd->result = DID_BAD_TARGET << 16; + goto out_done; } + cmd = megasas_get_cmd(instance); + if (!cmd) + return SCSI_MLQUEUE_HOST_BUSY; + + /* + * Logical drive command + */ + if (megasas_is_ldio(scmd)) + frame_count = megasas_build_ldio(instance, scmd, cmd); + else + frame_count = megasas_build_dcdb(instance, scmd, cmd); + + if (!frame_count) + goto out_return_cmd; + cmd->scmd = scmd; scmd->SCp.ptr = (char *)cmd; scmd->SCp.sent_command = jiffies; @@ -706,6 +637,12 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) &instance->reg_set->inbound_queue_port); return 0; + + out_return_cmd: + megasas_return_cmd(instance, cmd); + out_done: + done(scmd); + return 0; } /** @@ -2681,9 +2618,8 @@ megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { - case MEGASAS_IOC_FIRMWARE:{ - return megasas_mgmt_compat_ioctl_fw(file, arg); - } + case MEGASAS_IOC_FIRMWARE32: + return megasas_mgmt_compat_ioctl_fw(file, arg); case MEGASAS_IOC_GET_AEN: return megasas_mgmt_ioctl_aen(file, arg); } diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index eaec9d531424..67e07d30258f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -18,10 +18,9 @@ /** * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.02.00-rc4" -#define MEGASAS_RELDATE "Sep 16, 2005" -#define MEGASAS_EXT_VERSION "Fri Sep 16 12:37:08 EDT 2005" - +#define MEGASAS_VERSION "00.00.02.01" +#define MEGASAS_RELDATE "Dec 19, 2005" +#define MEGASAS_EXT_VERSION "Mon Dec 19 14:36:26 PST 2005" /* * ===================================== * MegaRAID SAS MFI firmware definitions @@ -1125,11 +1124,10 @@ struct compat_megasas_iocpacket { struct compat_iovec sgl[MAX_IOCTL_SGE]; } __attribute__ ((packed)); -#define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct compat_megasas_iocpacket) -#else -#define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) #endif +#define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) +#define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket) #define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen) struct megasas_mgmt_info { From 1341c939222f4d1cc8d9eb2b794f26f089fe0a61 Mon Sep 17 00:00:00 2001 From: Sumant Patro Date: Wed, 25 Jan 2006 12:02:40 -0800 Subject: [PATCH 151/695] [SCSI] megaraid_sas: new template defined to represent each type of controllers This patch defines a new template to represent each type of controllers (identified by the processor used). The template has members that is set with appropriate values during driver initialisation. This change is done to support new controllers with minimal change to existing code. In future, for a new controller support, a template will be declared and its members initialised appropriately. Signed-off-by: Sumant Patro Rejections fixed and Signed-off-by: James Bottomley --- Documentation/scsi/ChangeLog.megaraid_sas | 9 ++ drivers/scsi/megaraid/megaraid_sas.c | 133 +++++++++++++++------- drivers/scsi/megaraid/megaraid_sas.h | 18 ++- 3 files changed, 118 insertions(+), 42 deletions(-) diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas index e2319aeffbcc..f8c16cbf56ba 100644 --- a/Documentation/scsi/ChangeLog.megaraid_sas +++ b/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,3 +1,12 @@ +1 Release Date : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro +2 Current Version : 00.00.02.02 +3 Older Version : 00.00.02.01 + +i. New template defined to represent each family of controllers (identified by processor used). + The template will have defintions that will be initialised to appropritae values for a specific family of controllers. The template definition has four function pointers. During driver initialisation the function pointers will be set based on the controller family type. This change is done to support new controllers that has different processors and thus different register set. + + -Sumant Patro + 1 Release Date : Mon Dec 19 14:36:26 PST 2005 - Sumant Patro 2 Current Version : 00.00.02.00-rc4 3 Older Version : 00.00.02.01 diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 2fb53af8de2a..a487f414960e 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.02.01 + * Version : v00.00.02.02 * * Authors: * Sreenivas Bagalkote @@ -55,13 +55,13 @@ static struct pci_device_id megasas_pci_table[] = { { PCI_VENDOR_ID_LSI_LOGIC, - PCI_DEVICE_ID_LSI_SAS1064R, + PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_DELL, - PCI_DEVICE_ID_DELL_PERC5, + PCI_DEVICE_ID_DELL_PERC5, // xscale IOP PCI_ANY_ID, PCI_ANY_ID, }, @@ -119,12 +119,18 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); } + /** - * megasas_enable_intr - Enables interrupts +* The following functions are defined for xscale +* (deviceid : 1064R, PERC5) controllers +*/ + +/** + * megasas_enable_intr_xscale - Enables interrupts * @regs: MFI register set */ static inline void -megasas_enable_intr(struct megasas_register_set __iomem * regs) +megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs) { writel(1, &(regs)->outbound_intr_mask); @@ -132,6 +138,66 @@ megasas_enable_intr(struct megasas_register_set __iomem * regs) readl(®s->outbound_intr_mask); } +/** + * megasas_read_fw_status_reg_xscale - returns the current FW status value + * @regs: MFI register set + */ +static u32 +megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs) +{ + return readl(&(regs)->outbound_msg_0); +} +/** + * megasas_clear_interrupt_xscale - Check & clear interrupt + * @regs: MFI register set + */ +static int +megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs) +{ + u32 status; + /* + * Check if it is our interrupt + */ + status = readl(®s->outbound_intr_status); + + if (!(status & MFI_OB_INTR_STATUS_MASK)) { + return 1; + } + + /* + * Clear the interrupt by writing back the same value + */ + writel(status, ®s->outbound_intr_status); + + return 0; +} + +/** + * megasas_fire_cmd_xscale - Sends command to the FW + * @frame_phys_addr : Physical address of cmd + * @frame_count : Number of frames for the command + * @regs : MFI register set + */ +static inline void +megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs) +{ + writel((frame_phys_addr >> 3)|(frame_count), + &(regs)->inbound_queue_port); +} + +static struct megasas_instance_template megasas_instance_template_xscale = { + + .fire_cmd = megasas_fire_cmd_xscale, + .enable_intr = megasas_enable_intr_xscale, + .clear_intr = megasas_clear_intr_xscale, + .read_fw_status_reg = megasas_read_fw_status_reg_xscale, +}; + +/** +* This is the end of set of functions & definitions specific +* to xscale (deviceid : 1064R, PERC5) controllers +*/ + /** * megasas_disable_intr - Disables interrupts * @regs: MFI register set @@ -139,7 +205,7 @@ megasas_enable_intr(struct megasas_register_set __iomem * regs) static inline void megasas_disable_intr(struct megasas_register_set __iomem * regs) { - u32 mask = readl(®s->outbound_intr_mask) & (~0x00000001); + u32 mask = 0x1f; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ @@ -167,8 +233,7 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd) /* * Issue the frame using inbound queue port */ - writel(cmd->frame_phys_addr >> 3, - &instance->reg_set->inbound_queue_port); + instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); /* * Wait for cmd_status to change @@ -198,8 +263,7 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance, { cmd->cmd_status = ENODATA; - writel(cmd->frame_phys_addr >> 3, - &instance->reg_set->inbound_queue_port); + instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA)); @@ -242,8 +306,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, cmd->sync_cmd = 1; cmd->cmd_status = 0xFF; - writel(cmd->frame_phys_addr >> 3, - &instance->reg_set->inbound_queue_port); + instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); /* * Wait for this cmd to complete @@ -633,8 +696,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) instance->fw_outstanding++; spin_unlock_irqrestore(&instance->instance_lock, flags); - writel(((cmd->frame_phys_addr >> 3) | (cmd->frame_count - 1)), - &instance->reg_set->inbound_queue_port); + instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set); return 0; @@ -1045,7 +1107,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, static int megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) { - u32 status; u32 producer; u32 consumer; u32 context; @@ -1053,17 +1114,10 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) /* * Check if it is our interrupt + * Clear the interrupt */ - status = readl(&instance->reg_set->outbound_intr_status); - - if (!(status & MFI_OB_INTR_STATUS_MASK)) { + if(instance->instancet->clear_intr(instance->reg_set)) return IRQ_NONE; - } - - /* - * Clear the interrupt by writing back the same value - */ - writel(status, &instance->reg_set->outbound_intr_status); producer = *instance->producer; consumer = *instance->consumer; @@ -1097,7 +1151,7 @@ static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs) /** * megasas_transition_to_ready - Move the FW to READY state - * @reg_set: MFI register set + * @instance: Adapter soft state * * During the initialization, FW passes can potentially be in any one of * several possible states. If the FW in operational, waiting-for-handshake @@ -1105,14 +1159,14 @@ static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs) * has to wait for the ready state. */ static int -megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set) +megasas_transition_to_ready(struct megasas_instance* instance) { int i; u8 max_wait; u32 fw_state; u32 cur_state; - fw_state = readl(®_set->outbound_msg_0) & MFI_STATE_MASK; + fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; while (fw_state != MFI_STATE_READY) { @@ -1130,7 +1184,7 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set) * Set the CLR bit in inbound doorbell */ writel(MFI_INIT_CLEAR_HANDSHAKE, - ®_set->inbound_doorbell); + &instance->reg_set->inbound_doorbell); max_wait = 2; cur_state = MFI_STATE_WAIT_HANDSHAKE; @@ -1140,8 +1194,8 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set) /* * Bring it to READY state; assuming max wait 2 secs */ - megasas_disable_intr(reg_set); - writel(MFI_INIT_READY, ®_set->inbound_doorbell); + megasas_disable_intr(instance->reg_set); + writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); max_wait = 10; cur_state = MFI_STATE_OPERATIONAL; @@ -1190,8 +1244,8 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set) * The cur_state should not last for more than max_wait secs */ for (i = 0; i < (max_wait * 1000); i++) { - fw_state = MFI_STATE_MASK & - readl(®_set->outbound_msg_0); + fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & + MFI_STATE_MASK ; if (fw_state == cur_state) { msleep(1); @@ -1553,18 +1607,20 @@ static int megasas_init_mfi(struct megasas_instance *instance) reg_set = instance->reg_set; + instance->instancet = &megasas_instance_template_xscale; + /* * We expect the FW state to be READY */ - if (megasas_transition_to_ready(instance->reg_set)) + if (megasas_transition_to_ready(instance)) goto fail_ready_state; /* * Get various operational parameters from status register */ - instance->max_fw_cmds = readl(®_set->outbound_msg_0) & 0x00FFFF; - instance->max_num_sge = (readl(®_set->outbound_msg_0) & 0xFF0000) >> - 0x10; + instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; + instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> + 0x10; /* * Create a pool of commands */ @@ -1873,8 +1929,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num, /* * Issue the aen registration frame */ - writel(cmd->frame_phys_addr >> 3, - &instance->reg_set->inbound_queue_port); + instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); return 0; } @@ -2063,7 +2118,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) goto fail_irq; } - megasas_enable_intr(instance->reg_set); + instance->instancet->enable_intr(instance->reg_set); /* * Store instance in PCI softstate diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 67e07d30258f..d6d166c0663f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -18,9 +18,9 @@ /** * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.02.01" -#define MEGASAS_RELDATE "Dec 19, 2005" -#define MEGASAS_EXT_VERSION "Mon Dec 19 14:36:26 PST 2005" +#define MEGASAS_VERSION "00.00.02.02" +#define MEGASAS_RELDATE "Jan 23, 2006" +#define MEGASAS_EXT_VERSION "Mon Jan 23 14:09:01 PST 2006" /* * ===================================== * MegaRAID SAS MFI firmware definitions @@ -1012,6 +1012,16 @@ struct megasas_evt_detail { } __attribute__ ((packed)); + struct megasas_instance_template { + void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *); + + void (*enable_intr)(struct megasas_register_set __iomem *) ; + + int (*clear_intr)(struct megasas_register_set __iomem *); + + u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *); + }; + struct megasas_instance { u32 *producer; @@ -1055,6 +1065,8 @@ struct megasas_instance { u32 fw_outstanding; u32 hw_crit_error; spinlock_t instance_lock; + + struct megasas_instance_template *instancet; }; #define MEGASAS_IS_LOGICAL(scp) \ From 9220a2d0daa1e6782f02d47303340d7b5ca62ac0 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 29 Jan 2006 12:40:57 -0500 Subject: [PATCH 152/695] [libata ahci] add another JMicron pci id --- drivers/scsi/ahci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 2fffc7bf5d96..a800fb51168b 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -288,6 +288,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { board_ahci }, /* ICH8M */ { 0x197b, 0x2360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* JMicron JMB360 */ + { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* JMicron JMB363 */ { } /* terminate list */ }; From a2ba82cd7de281721a875a73a5a5894882760fab Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 27 Jan 2006 23:59:36 -0700 Subject: [PATCH 153/695] [PARISC] Simplify DISCONTIGMEM in Kconfig parisc was previously displaying both the mm/Kconfig memory model menu, and its own prompt. Remove prompt and have CONFIG_64BIT toggle between DISCONTIGMEM and FLATMEM. Also remove the EXPERIMENTAL from discontigmem support... It's been running fine for months (years?) now. Signed-off-by: Kyle McMartin --- arch/parisc/Kconfig | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index e77a06e9621e..7c914a4c67c3 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -149,14 +149,20 @@ config HOTPLUG_CPU default y if SMP select HOTPLUG +config ARCH_SELECT_MEMORY_MODEL + def_bool y + depends on 64BIT + config ARCH_DISCONTIGMEM_ENABLE - bool "Discontiguous memory support (EXPERIMENTAL)" - depends on 64BIT && EXPERIMENTAL - help - Say Y to support efficient handling of discontiguous physical memory, - for architectures which are either NUMA (Non-Uniform Memory Access) - or have huge holes in the physical address space for other reasons. - See for more. + def_bool y + depends on 64BIT + +config ARCH_FLATMEM_ENABLE + def_bool y + +config ARCH_DISCONTIGMEM_DEFAULT + def_bool y + depends on ARCH_DISCONTIGMEM_ENABLE source "kernel/Kconfig.hz" source "mm/Kconfig" From 01387959022def72f95f4bc1341aa69e32a06b30 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Sun, 29 Jan 2006 21:50:40 -0500 Subject: [PATCH 154/695] Input: add ixp4xx beeper driver This is a driver for beeper found in LinkSys NSLU2 boxes. It should work on any ixp4xx based platform. Signed-off-by: Alessandro Zummo Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 12 ++ drivers/input/misc/Makefile | 1 + drivers/input/misc/ixp4xx-beeper.c | 183 +++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 drivers/input/misc/ixp4xx-beeper.c diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index e08dbe08f46d..4bad588d0e5d 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -50,6 +50,18 @@ config INPUT_WISTRON_BTNS To compile this driver as a module, choose M here: the module will be called wistron_btns. +config INPUT_IXP4XX_BEEPER + tristate "IXP4XX Beeper support" + depends on ARCH_IXP4XX + help + If you say yes here, you can connect a beeper to the + ixp4xx gpio pins. This is used by the LinkSys NSLU2. + + If unsure, say Y. + + To compile this driver as a module, choose M here: the + module will be called ixp4xx-beeper. + config INPUT_UINPUT tristate "User level driver support" help diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index ce44cce01285..184c4129470d 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o +obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c new file mode 100644 index 000000000000..d448bb5e4869 --- /dev/null +++ b/drivers/input/misc/ixp4xx-beeper.c @@ -0,0 +1,183 @@ +/* + * Generic IXP4xx beeper driver + * + * Copyright (C) 2005 Tower Technologies + * + * based on nslu2-io.c + * Copyright (C) 2004 Karen Spearel + * + * Author: Alessandro Zummo + * Maintainers: http://www.nslu2-linux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Alessandro Zummo "); +MODULE_DESCRIPTION("ixp4xx beeper driver"); +MODULE_LICENSE("GPL"); + +static DEFINE_SPINLOCK(beep_lock); + +static void ixp4xx_spkr_control(unsigned int pin, unsigned int count) +{ + unsigned long flags; + + spin_lock_irqsave(&beep_lock, flags); + + if (count) { + gpio_line_config(pin, IXP4XX_GPIO_OUT); + gpio_line_set(pin, IXP4XX_GPIO_LOW); + + *IXP4XX_OSRT2 = (count & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; + } else { + gpio_line_config(pin, IXP4XX_GPIO_IN); + gpio_line_set(pin, IXP4XX_GPIO_HIGH); + + *IXP4XX_OSRT2 = 0; + } + + spin_unlock_irqrestore(&beep_lock, flags); +} + +static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) +{ + unsigned int pin = (unsigned int) dev->private; + unsigned int count = 0; + + if (type != EV_SND) + return -1; + + switch (code) { + case SND_BELL: + if (value) + value = 1000; + case SND_TONE: + break; + default: + return -1; + } + + if (value > 20 && value < 32767) +#ifndef FREQ + count = (ixp4xx_get_board_tick_rate() / (value * 4)) - 1; +#else + count = (FREQ / (value * 4)) - 1; +#endif + + ixp4xx_spkr_control(pin, count); + + return 0; +} + +static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + /* clear interrupt */ + *IXP4XX_OSST = IXP4XX_OSST_TIMER_2_PEND; + + /* flip the beeper output */ + *IXP4XX_GPIO_GPOUTR ^= (1 << (unsigned int) dev_id); + + return IRQ_HANDLED; +} + +static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) +{ + struct input_dev *input_dev; + int err; + + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + input_dev->private = (void *) dev->id; + input_dev->name = "ixp4xx beeper", + input_dev->phys = "ixp4xx/gpio"; + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x001f; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &dev->dev; + + input_dev->evbit[0] = BIT(EV_SND); + input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + input_dev->event = ixp4xx_spkr_event; + + err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt, + SA_INTERRUPT | SA_TIMER, "ixp4xx-beeper", (void *) dev->id); + if (err) + goto err_free_device; + + err = input_register_device(input_dev); + if (err) + goto err_free_irq; + + platform_set_drvdata(dev, input_dev); + + return 0; + + err_free_irq: + free_irq(IRQ_IXP4XX_TIMER2, dev); + err_free_device: + input_free_device(input_dev); + + return err; +} + +static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) +{ + struct input_dev *input_dev = platform_get_drvdata(dev); + unsigned int pin = (unsigned int) input_dev->private; + + input_unregister_device(input_dev); + platform_set_drvdata(dev, NULL); + + /* turn the speaker off */ + disable_irq(IRQ_IXP4XX_TIMER2); + ixp4xx_spkr_control(pin, 0); + + free_irq(IRQ_IXP4XX_TIMER2, dev); + + return 0; +} + +static void ixp4xx_spkr_shutdown(struct platform_device *dev) +{ + struct input_dev *input_dev = platform_get_drvdata(dev); + unsigned int pin = (unsigned int) input_dev->private; + + /* turn off the speaker */ + disable_irq(IRQ_IXP4XX_TIMER2); + ixp4xx_spkr_control(pin, 0); +} + +static struct platform_driver ixp4xx_spkr_platform_driver = { + .driver = { + .name = "ixp4xx-beeper", + .owner = THIS_MODULE, + }, + .probe = ixp4xx_spkr_probe, + .remove = __devexit_p(ixp4xx_spkr_remove), + .shutdown = ixp4xx_spkr_shutdown, +}; + +static int __init ixp4xx_spkr_init(void) +{ + return platform_driver_register(&ixp4xx_spkr_platform_driver); +} + +static void __exit ixp4xx_spkr_exit(void) +{ + platform_driver_unregister(&ixp4xx_spkr_platform_driver); +} + +module_init(ixp4xx_spkr_init); +module_exit(ixp4xx_spkr_exit); From a3f3f3176686ada02d9eb5e4a6d7dff1ee13396c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:50:46 -0500 Subject: [PATCH 155/695] Input: psmouse - set name for Genius mice Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 7665fd9ce559..19b1b0121726 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -403,6 +403,7 @@ static int genius_detect(struct psmouse *psmouse, int set_properties) set_bit(REL_WHEEL, psmouse->dev->relbit); psmouse->vendor = "Genius"; + psmouse->name = "Mouse"; psmouse->pktsize = 4; } From 5ae08f80ec5b2b08dd2f76a166140dd156fb31a1 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 29 Jan 2006 21:50:52 -0500 Subject: [PATCH 156/695] Input: iforce - do not return ENOMEM upon successful allocation Signed-off-by: Alexey Dobriyan Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/iforce/iforce-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 64b9c31c47fc..b6bc04998047 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -345,7 +345,7 @@ int iforce_init_device(struct iforce *iforce) int i; input_dev = input_allocate_device(); - if (input_dev) + if (!input_dev) return -ENOMEM; init_waitqueue_head(&iforce->wait); From 74570d413cbb5cede06a0183a91d3006f134bf6b Mon Sep 17 00:00:00 2001 From: Kimball Murray Date: Sun, 29 Jan 2006 21:50:59 -0500 Subject: [PATCH 157/695] Input: mousedev - fix memory leak Apparently, "while true; do cat /dev/input/mice; done" causes an OOM in a short amount of time. Funny that nobody noticed, it actually is very easy to trigger just by switching between VT1 and VT7... Signed-off-by: Pete Zaitcev Signed-off-by: Dmitry Torokhov --- drivers/input/mousedev.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 81fd7a97a93d..9abed18d2ecf 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -356,7 +356,7 @@ static void mousedev_free(struct mousedev *mousedev) kfree(mousedev); } -static int mixdev_release(void) +static void mixdev_release(void) { struct input_handle *handle; @@ -370,8 +370,6 @@ static int mixdev_release(void) mousedev_free(mousedev); } } - - return 0; } static int mousedev_release(struct inode * inode, struct file * file) @@ -384,9 +382,8 @@ static int mousedev_release(struct inode * inode, struct file * file) if (!--list->mousedev->open) { if (list->mousedev->minor == MOUSEDEV_MIX) - return mixdev_release(); - - if (!mousedev_mix.open) { + mixdev_release(); + else if (!mousedev_mix.open) { if (list->mousedev->exist) input_close_device(&list->mousedev->handle); else From ffc6b529e8c46c73827008c7406f43482d71beed Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 29 Jan 2006 21:51:07 -0500 Subject: [PATCH 158/695] Input: make needlessly global code static Signed-off-by: Adrian Bunk Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/twidjoy.c | 4 ++-- drivers/input/touchscreen/mk712.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index cd3a1e742a30..7f8b0093c5bc 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -265,13 +265,13 @@ static struct serio_driver twidjoy_drv = { * The functions for inserting/removing us as a module. */ -int __init twidjoy_init(void) +static int __init twidjoy_init(void) { serio_register_driver(&twidjoy_drv); return 0; } -void __exit twidjoy_exit(void) +static void __exit twidjoy_exit(void) { serio_unregister_driver(&twidjoy_drv); } diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index 4844d250a5eb..3226830eea08 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c @@ -154,7 +154,7 @@ static void mk712_close(struct input_dev *dev) spin_unlock_irqrestore(&mk712_lock, flags); } -int __init mk712_init(void) +static int __init mk712_init(void) { int err; From 3575c3410071dc778d2d9c6002493a5dce73ec0b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:51:16 -0500 Subject: [PATCH 159/695] Input: grip - fix crash when accessing device Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/grip.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index a936e7aedb10..330c6717c149 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -192,6 +192,9 @@ static void grip_poll(struct gameport *gameport) for (i = 0; i < 2; i++) { dev = grip->dev[i]; + if (!dev) + continue; + grip->reads++; switch (grip->mode[i]) { From 0399addd71565b27eae27821fa04dad44f8644fe Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:51:21 -0500 Subject: [PATCH 160/695] Input: grip - handle errors from input_register_device() Also set .owner in driver structure so we'll have a link between module and driver in sysfs. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/grip.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index 330c6717c149..20cb98ac2d79 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -384,12 +384,15 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) if (t > 0) set_bit(t, input_dev->keybit); - input_register_device(grip->dev[i]); + err = input_register_device(grip->dev[i]); + if (err) + goto fail4; } return 0; - fail3: for (i = 0; i < 2; i++) + fail4: input_free_device(grip->dev[i]); + fail3: while (--i >= 0) if (grip->dev[i]) input_unregister_device(grip->dev[i]); fail2: gameport_close(gameport); @@ -414,6 +417,7 @@ static void grip_disconnect(struct gameport *gameport) static struct gameport_driver grip_drv = { .driver = { .name = "grip", + .owner = THIS_MODULE, }, .description = DRIVER_DESC, .connect = grip_connect, From 84c61896bd756a440c54be07b6e97ad230f31a16 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:51:31 -0500 Subject: [PATCH 161/695] Input: db9 - fix possible crash with Saturn gamepads Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/db9.c | 70 ++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 499344c72756..98479b82842d 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -275,68 +275,70 @@ static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char /* * db9_saturn_report() analyzes packet and reports. */ -static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *dev, int n, int max_pads) +static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *devs[], int n, int max_pads) { + struct input_dev *dev; int tmp, i, j; tmp = (id == 0x41) ? 60 : 10; - for (j = 0; (j < tmp) && (n < max_pads); j += 10, n++) { + for (j = 0; j < tmp && n < max_pads; j += 10, n++) { + dev = devs[n]; switch (data[j]) { case 0x16: /* multi controller (analog 4 axis) */ - input_report_abs(dev + n, db9_abs[5], data[j + 6]); + input_report_abs(dev, db9_abs[5], data[j + 6]); case 0x15: /* mission stick (analog 3 axis) */ - input_report_abs(dev + n, db9_abs[3], data[j + 4]); - input_report_abs(dev + n, db9_abs[4], data[j + 5]); + input_report_abs(dev, db9_abs[3], data[j + 4]); + input_report_abs(dev, db9_abs[4], data[j + 5]); case 0x13: /* racing controller (analog 1 axis) */ - input_report_abs(dev + n, db9_abs[2], data[j + 3]); + input_report_abs(dev, db9_abs[2], data[j + 3]); case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */ case 0x02: /* digital pad (digital 2 axis + buttons) */ - input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); - input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16)); + input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); + input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16)); for (i = 0; i < 9; i++) - input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]); + input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]); break; case 0x19: /* mission stick x2 (analog 6 axis + buttons) */ - input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); - input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16)); + input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); + input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16)); for (i = 0; i < 9; i++) - input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]); - input_report_abs(dev + n, db9_abs[2], data[j + 3]); - input_report_abs(dev + n, db9_abs[3], data[j + 4]); - input_report_abs(dev + n, db9_abs[4], data[j + 5]); + input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]); + input_report_abs(dev, db9_abs[2], data[j + 3]); + input_report_abs(dev, db9_abs[3], data[j + 4]); + input_report_abs(dev, db9_abs[4], data[j + 5]); /* - input_report_abs(dev + n, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1)); - input_report_abs(dev + n, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1)); + input_report_abs(dev, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1)); + input_report_abs(dev, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1)); */ - input_report_abs(dev + n, db9_abs[6], data[j + 7]); - input_report_abs(dev + n, db9_abs[7], data[j + 8]); - input_report_abs(dev + n, db9_abs[5], data[j + 9]); + input_report_abs(dev, db9_abs[6], data[j + 7]); + input_report_abs(dev, db9_abs[7], data[j + 8]); + input_report_abs(dev, db9_abs[5], data[j + 9]); break; case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */ - input_report_key(dev + n, BTN_A, data[j + 3] & 0x80); - input_report_abs(dev + n, db9_abs[2], data[j + 3] & 0x7f); + input_report_key(dev, BTN_A, data[j + 3] & 0x80); + input_report_abs(dev, db9_abs[2], data[j + 3] & 0x7f); break; case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */ - input_report_key(dev + n, BTN_START, data[j + 1] & 0x08); - input_report_key(dev + n, BTN_A, data[j + 1] & 0x04); - input_report_key(dev + n, BTN_C, data[j + 1] & 0x02); - input_report_key(dev + n, BTN_B, data[j + 1] & 0x01); - input_report_abs(dev + n, db9_abs[2], data[j + 2] ^ 0x80); - input_report_abs(dev + n, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */ + input_report_key(dev, BTN_START, data[j + 1] & 0x08); + input_report_key(dev, BTN_A, data[j + 1] & 0x04); + input_report_key(dev, BTN_C, data[j + 1] & 0x02); + input_report_key(dev, BTN_B, data[j + 1] & 0x01); + input_report_abs(dev, db9_abs[2], data[j + 2] ^ 0x80); + input_report_abs(dev, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */ break; case 0xff: default: /* no pad */ - input_report_abs(dev + n, db9_abs[0], 0); - input_report_abs(dev + n, db9_abs[1], 0); + input_report_abs(dev, db9_abs[0], 0); + input_report_abs(dev, db9_abs[1], 0); for (i = 0; i < 9; i++) - input_report_key(dev + n, db9_cd32_btn[i], 0); + input_report_key(dev, db9_cd32_btn[i], 0); break; } } return n; } -static int db9_saturn(int mode, struct parport *port, struct input_dev *dev) +static int db9_saturn(int mode, struct parport *port, struct input_dev *devs[]) { unsigned char id, data[60]; int type, n, max_pads; @@ -361,7 +363,7 @@ static int db9_saturn(int mode, struct parport *port, struct input_dev *dev) max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES); for (tmp = 0, i = 0; i < n; i++) { id = db9_saturn_read_packet(port, data, type + i, 1); - tmp = db9_saturn_report(id, data, dev, tmp, max_pads); + tmp = db9_saturn_report(id, data, devs, tmp, max_pads); } return 0; } @@ -489,7 +491,7 @@ static void db9_timer(unsigned long private) case DB9_SATURN_DPP: case DB9_SATURN_DPP_2: - db9_saturn(db9->mode, port, dev); + db9_saturn(db9->mode, port, db9->dev); break; case DB9_CD32_PAD: From 2e9d675ed24bcefd0d99b531a9d7faf794b762c8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:51:36 -0500 Subject: [PATCH 162/695] Input: db9 - handle errors from input_register_device() Also db9_remove shouldn't be marked __exit as it is also called from __init code. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/db9.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 98479b82842d..dcffc34f30c3 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -616,7 +616,7 @@ static struct db9 __init *db9_probe(int parport, int mode) if (!input_dev) { printk(KERN_ERR "db9.c: Not enough memory for input device\n"); err = -ENOMEM; - goto err_free_devs; + goto err_unreg_devs; } sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i); @@ -642,13 +642,17 @@ static struct db9 __init *db9_probe(int parport, int mode) input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0); } - input_register_device(input_dev); + err = input_register_device(input_dev); + if (err) + goto err_free_dev; } parport_put_port(pp); return db9; - err_free_devs: + err_free_dev: + input_free_device(db9->dev[i]); + err_unreg_devs: while (--i >= 0) input_unregister_device(db9->dev[i]); kfree(db9); @@ -660,7 +664,7 @@ static struct db9 __init *db9_probe(int parport, int mode) return ERR_PTR(err); } -static void __exit db9_remove(struct db9 *db9) +static void db9_remove(struct db9 *db9) { int i; @@ -698,7 +702,8 @@ static int __init db9_init(void) if (err) { while (--i >= 0) - db9_remove(db9_base[i]); + if (db9_base[i]) + db9_remove(db9_base[i]); return err; } From 847fd5fbf70e82baf042556968f885066489b164 Mon Sep 17 00:00:00 2001 From: Zinx Verituse Date: Sun, 29 Jan 2006 21:51:51 -0500 Subject: [PATCH 163/695] Input: sidewinder - fix an oops Dynalloc conversion strikes again... Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/sidewinder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 78dd163cd702..03f9e7ed0304 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -736,7 +736,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]); sprintf(sw->phys[i], "%s/input%d", gameport->phys, i); - input_dev = input_allocate_device(); + sw->dev[i] = input_dev = input_allocate_device(); if (!input_dev) { err = -ENOMEM; goto fail3; From 07cf779c0098fd0007d2348e1cf948cc07bfe096 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:51:56 -0500 Subject: [PATCH 164/695] Input: sidewinder - handle errors from input_register_device() Also set .owner in driver structure so we'll have a link between module and driver in sysfs. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/sidewinder.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 03f9e7ed0304..2b2ec1057dee 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -771,12 +771,15 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k); - input_register_device(sw->dev[i]); + err = input_register_device(sw->dev[i]); + if (err) + goto fail4; } return 0; - fail3: while (--i >= 0) + fail4: input_free_device(sw->dev[i]); + fail3: while (--i >= 0) input_unregister_device(sw->dev[i]); fail2: gameport_close(gameport); fail1: gameport_set_drvdata(gameport, NULL); @@ -801,6 +804,7 @@ static void sw_disconnect(struct gameport *gameport) static struct gameport_driver sw_drv = { .driver = { .name = "sidewinder", + .owner = THIS_MODULE, }, .description = DRIVER_DESC, .connect = sw_connect, From c7fd018d75cae2b0c1cf03003b38f4c76e3df826 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:52:04 -0500 Subject: [PATCH 165/695] Input: gamecon - fix crash when accessing device Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/gamecon.c | 363 +++++++++++++++++-------------- 1 file changed, 204 insertions(+), 159 deletions(-) diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 7df2d82f2c83..d9757452c93a 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -159,6 +159,48 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) } +static void gc_n64_process_packet(struct gc *gc) +{ + unsigned char data[GC_N64_LENGTH]; + signed char axes[2]; + struct input_dev *dev; + int i, j, s; + + gc_n64_read_packet(gc, data); + + for (i = 0; i < GC_MAX_DEVICES; i++) { + + dev = gc->dev[i]; + if (!dev) + continue; + + s = gc_status_bit[i]; + + if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { + + axes[0] = axes[1] = 0; + + for (j = 0; j < 8; j++) { + if (data[23 - j] & s) + axes[0] |= 1 << j; + if (data[31 - j] & s) + axes[1] |= 1 << j; + } + + input_report_abs(dev, ABS_X, axes[0]); + input_report_abs(dev, ABS_Y, -axes[1]); + + input_report_abs(dev, ABS_HAT0X, !(s & data[6]) - !(s & data[7])); + input_report_abs(dev, ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); + + for (j = 0; j < 10; j++) + input_report_key(dev, gc_n64_btn[j], s & data[gc_n64_bytes[j]]); + + input_sync(dev); + } + } +} + /* * NES/SNES support. */ @@ -198,6 +240,39 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data) } } +static void gc_nes_process_packet(struct gc *gc) +{ + unsigned char data[GC_SNES_LENGTH]; + struct input_dev *dev; + int i, j, s; + + gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data); + + for (i = 0; i < GC_MAX_DEVICES; i++) { + + dev = gc->dev[i]; + if (!dev) + continue; + + s = gc_status_bit[i]; + + if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { + input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); + input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); + } + + if (s & gc->pads[GC_NES]) + for (j = 0; j < 4; j++) + input_report_key(dev, gc_snes_btn[j], s & data[gc_nes_bytes[j]]); + + if (s & gc->pads[GC_SNES]) + for (j = 0; j < 8; j++) + input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); + + input_sync(dev); + } +} + /* * Multisystem joystick support */ @@ -219,6 +294,35 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data) } } +static void gc_multi_process_packet(struct gc *gc) +{ + unsigned char data[GC_MULTI2_LENGTH]; + struct input_dev *dev; + int i, s; + + gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data); + + for (i = 0; i < GC_MAX_DEVICES; i++) { + + dev = gc->dev[i]; + if (!dev) + continue; + + s = gc_status_bit[i]; + + if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { + input_report_abs(dev, ABS_X, !(s & data[2]) - !(s & data[3])); + input_report_abs(dev, ABS_Y, !(s & data[0]) - !(s & data[1])); + input_report_key(dev, BTN_TRIGGER, s & data[4]); + } + + if (s & gc->pads[GC_MULTI2]) + input_report_key(dev, BTN_THUMB, s & data[5]); + + input_sync(dev); + } +} + /* * PSX support * @@ -263,10 +367,11 @@ static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; * the psx pad. */ -static void gc_psx_command(struct gc *gc, int b, unsigned char data[5]) +static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVICES]) { int i, j, cmd, read; - for (i = 0; i < 5; i++) + + for (i = 0; i < GC_MAX_DEVICES; i++) data[i] = 0; for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) { @@ -274,7 +379,7 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[5]) parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); udelay(gc_psx_delay); read = parport_read_status(gc->pd->port) ^ 0x80; - for (j = 0; j < 5; j++) + for (j = 0; j < GC_MAX_DEVICES; j++) data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0; parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); udelay(gc_psx_delay); @@ -286,11 +391,12 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[5]) * device identifier code. */ -static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES], unsigned char id[5]) +static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES], + unsigned char id[GC_MAX_DEVICES]) { int i, j, max_len = 0; unsigned long flags; - unsigned char data2[5]; + unsigned char data2[GC_MAX_DEVICES]; parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ udelay(gc_psx_delay); @@ -303,7 +409,7 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES gc_psx_command(gc, 0x42, id); /* Get device ids */ gc_psx_command(gc, 0, data2); /* Dump status */ - for (i =0; i < 5; i++) /* Find the longest pad */ + for (i =0; i < GC_MAX_DEVICES; i++) /* Find the longest pad */ if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) && (GC_PSX_LEN(id[i]) > max_len) && (GC_PSX_LEN(id[i]) <= GC_PSX_BYTES)) @@ -311,7 +417,7 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES for (i = 0; i < max_len; i++) { /* Read in all the data */ gc_psx_command(gc, 0, data2); - for (j = 0; j < 5; j++) + for (j = 0; j < GC_MAX_DEVICES; j++) data[j][i] = data2[j]; } @@ -319,185 +425,124 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); - for(i = 0; i < 5; i++) /* Set id's to the real value */ + for(i = 0; i < GC_MAX_DEVICES; i++) /* Set id's to the real value */ id[i] = GC_PSX_ID(id[i]); } -/* - * gc_timer() reads and analyzes console pads data. - */ +static void gc_psx_process_packet(struct gc *gc) +{ + unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; + unsigned char id[GC_MAX_DEVICES]; + struct input_dev *dev; + int i, j; -#define GC_MAX_LENGTH GC_N64_LENGTH + gc_psx_read_packet(gc, data, id); + + for (i = 0; i < GC_MAX_DEVICES; i++) { + + dev = gc->dev[i]; + if (!dev) + continue; + + switch (id[i]) { + + case GC_PSX_RUMBLE: + + input_report_key(dev, BTN_THUMBL, ~data[i][0] & 0x04); + input_report_key(dev, BTN_THUMBR, ~data[i][0] & 0x02); + + case GC_PSX_NEGCON: + case GC_PSX_ANALOG: + + if (gc->pads[GC_DDR] & gc_status_bit[i]) { + for(j = 0; j < 4; j++) + input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); + } else { + for (j = 0; j < 4; j++) + input_report_abs(dev, gc_psx_abs[j + 2], data[i][j + 2]); + + input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); + input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); + } + + for (j = 0; j < 8; j++) + input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); + + input_report_key(dev, BTN_START, ~data[i][0] & 0x08); + input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); + + input_sync(dev); + + break; + + case GC_PSX_NORMAL: + if (gc->pads[GC_DDR] & gc_status_bit[i]) { + for(j = 0; j < 4; j++) + input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); + } else { + input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); + input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); + + /* for some reason if the extra axes are left unset they drift */ + /* for (j = 0; j < 4; j++) + input_report_abs(dev, gc_psx_abs[j + 2], 128); + * This needs to be debugged properly, + * maybe fuzz processing needs to be done in input_sync() + * --vojtech + */ + } + + for (j = 0; j < 8; j++) + input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); + + input_report_key(dev, BTN_START, ~data[i][0] & 0x08); + input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); + + input_sync(dev); + + break; + + case 0: /* not a pad, ignore */ + break; + } + } +} + +/* + * gc_timer() initiates reads of console pads data. + */ static void gc_timer(unsigned long private) { struct gc *gc = (void *) private; - unsigned char data[GC_MAX_LENGTH]; - unsigned char data_psx[5][GC_PSX_BYTES]; - int i, j, s; /* * N64 pads - must be read first, any read confuses them for 200 us */ - if (gc->pads[GC_N64]) { - - gc_n64_read_packet(gc, data); - - for (i = 0; i < 5; i++) { - - s = gc_status_bit[i]; - - if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { - - signed char axes[2]; - axes[0] = axes[1] = 0; - - for (j = 0; j < 8; j++) { - if (data[23 - j] & s) axes[0] |= 1 << j; - if (data[31 - j] & s) axes[1] |= 1 << j; - } - - input_report_abs(gc->dev[i], ABS_X, axes[0]); - input_report_abs(gc->dev[i], ABS_Y, -axes[1]); - - input_report_abs(gc->dev[i], ABS_HAT0X, !(s & data[6]) - !(s & data[7])); - input_report_abs(gc->dev[i], ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); - - for (j = 0; j < 10; j++) - input_report_key(gc->dev[i], gc_n64_btn[j], s & data[gc_n64_bytes[j]]); - - input_sync(gc->dev[i]); - } - } - } + if (gc->pads[GC_N64]) + gc_n64_process_packet(gc); /* * NES and SNES pads */ - if (gc->pads[GC_NES] || gc->pads[GC_SNES]) { - - gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data); - - for (i = 0; i < 5; i++) { - - s = gc_status_bit[i]; - - if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { - input_report_abs(gc->dev[i], ABS_X, !(s & data[6]) - !(s & data[7])); - input_report_abs(gc->dev[i], ABS_Y, !(s & data[4]) - !(s & data[5])); - } - - if (s & gc->pads[GC_NES]) - for (j = 0; j < 4; j++) - input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_nes_bytes[j]]); - - if (s & gc->pads[GC_SNES]) - for (j = 0; j < 8; j++) - input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_snes_bytes[j]]); - - input_sync(gc->dev[i]); - } - } + if (gc->pads[GC_NES] || gc->pads[GC_SNES]) + gc_nes_process_packet(gc); /* * Multi and Multi2 joysticks */ - if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) { - - gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data); - - for (i = 0; i < 5; i++) { - - s = gc_status_bit[i]; - - if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { - input_report_abs(gc->dev[i], ABS_X, !(s & data[2]) - !(s & data[3])); - input_report_abs(gc->dev[i], ABS_Y, !(s & data[0]) - !(s & data[1])); - input_report_key(gc->dev[i], BTN_TRIGGER, s & data[4]); - } - - if (s & gc->pads[GC_MULTI2]) - input_report_key(gc->dev[i], BTN_THUMB, s & data[5]); - - input_sync(gc->dev[i]); - } - } + if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) + gc_multi_process_packet(gc); /* * PSX controllers */ - if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) { - - gc_psx_read_packet(gc, data_psx, data); - - for (i = 0; i < 5; i++) { - switch (data[i]) { - - case GC_PSX_RUMBLE: - - input_report_key(gc->dev[i], BTN_THUMBL, ~data_psx[i][0] & 0x04); - input_report_key(gc->dev[i], BTN_THUMBR, ~data_psx[i][0] & 0x02); - - case GC_PSX_NEGCON: - case GC_PSX_ANALOG: - - if (gc->pads[GC_DDR] & gc_status_bit[i]) { - for(j = 0; j < 4; j++) - input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); - } else { - for (j = 0; j < 4; j++) - input_report_abs(gc->dev[i], gc_psx_abs[j+2], data_psx[i][j + 2]); - - input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); - input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); - } - - for (j = 0; j < 8; j++) - input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); - - input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08); - input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01); - - input_sync(gc->dev[i]); - - break; - - case GC_PSX_NORMAL: - if (gc->pads[GC_DDR] & gc_status_bit[i]) { - for(j = 0; j < 4; j++) - input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); - } else { - input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); - input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); - - /* for some reason if the extra axes are left unset they drift */ - /* for (j = 0; j < 4; j++) - input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128); - * This needs to be debugged properly, - * maybe fuzz processing needs to be done in input_sync() - * --vojtech - */ - } - - for (j = 0; j < 8; j++) - input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); - - input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08); - input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01); - - input_sync(gc->dev[i]); - - break; - - case 0: /* not a pad, ignore */ - break; - } - } - } + if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) + gc_psx_process_packet(gc); mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); } @@ -654,7 +699,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) gc->timer.data = (long) gc; gc->timer.function = gc_timer; - for (i = 0; i < n_pads; i++) { + for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) { if (!pads[i]) continue; From 77fc46ca5b331df3fc0ffef24012ba0d51d601b3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:52:11 -0500 Subject: [PATCH 166/695] Input: gamecon - handle errors from input_register_device() Also gc_remove shouldn't be marked __exit as it is also called from __init code. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/gamecon.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index d9757452c93a..900587acdb47 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -706,9 +706,11 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i); err = gc_setup_pad(gc, i, pads[i]); if (err) - goto err_free_devs; + goto err_unreg_devs; - input_register_device(gc->dev[i]); + err = input_register_device(gc->dev[i]); + if (err) + goto err_free_dev; } if (!gc->pads[0]) { @@ -720,9 +722,12 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) parport_put_port(pp); return gc; - err_free_devs: + err_free_dev: + input_free_device(gc->dev[i]); + err_unreg_devs: while (--i >= 0) - input_unregister_device(gc->dev[i]); + if (gc->dev[i]) + input_unregister_device(gc->dev[i]); err_free_gc: kfree(gc); err_unreg_pardev: @@ -733,7 +738,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) return ERR_PTR(err); } -static void __exit gc_remove(struct gc *gc) +static void gc_remove(struct gc *gc) { int i; @@ -771,7 +776,8 @@ static int __init gc_init(void) if (err) { while (--i >= 0) - gc_remove(gc_base[i]); + if (gc_base[i]) + gc_remove(gc_base[i]); return err; } From ab52cd66ae4c3e097811b6c370de7fc057959419 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:52:18 -0500 Subject: [PATCH 167/695] Input: turbografx - handle errors from input_register_device() Also tgfx_remove shouldn't be marked __exit as it is also called from __init code. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/turbografx.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index 7e9764937d06..b154938e88a4 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -204,14 +204,14 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) if (n_buttons[i] > 6) { printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]); err = -EINVAL; - goto err_free_devs; + goto err_unreg_devs; } tgfx->dev[i] = input_dev = input_allocate_device(); if (!input_dev) { printk(KERN_ERR "turbografx.c: Not enough memory for input device\n"); err = -ENOMEM; - goto err_free_devs; + goto err_unreg_devs; } tgfx->sticks |= (1 << i); @@ -238,7 +238,9 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) for (j = 0; j < n_buttons[i]; j++) set_bit(tgfx_buttons[j], input_dev->keybit); - input_register_device(tgfx->dev[i]); + err = input_register_device(tgfx->dev[i]); + if (err) + goto err_free_dev; } if (!tgfx->sticks) { @@ -249,9 +251,12 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) return tgfx; - err_free_devs: + err_free_dev: + input_free_device(tgfx->dev[i]); + err_unreg_devs: while (--i >= 0) - input_unregister_device(tgfx->dev[i]); + if (tgfx->dev[i]) + input_unregister_device(tgfx->dev[i]); err_free_tgfx: kfree(tgfx); err_unreg_pardev: @@ -262,7 +267,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) return ERR_PTR(err); } -static void __exit tgfx_remove(struct tgfx *tgfx) +static void tgfx_remove(struct tgfx *tgfx) { int i; @@ -300,7 +305,8 @@ static int __init tgfx_init(void) if (err) { while (--i >= 0) - tgfx_remove(tgfx_base[i]); + if (tgfx_base[i]) + tgfx_remove(tgfx_base[i]); return err; } From 4d462b9e2372f9f5a885f8b7e1597fe7412347fd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:52:26 -0500 Subject: [PATCH 168/695] Input: tmdc - handle errors from input_register_device() Also set .owner in driver structure so we'll have a link between module and driver in sysfs. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/tmdc.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index 60e2aac7d06e..bb23ed2a04a6 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -284,13 +284,13 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) struct tmdc_port *port; struct input_dev *input_dev; int i, j, b = 0; + int err; tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL); input_dev = input_allocate_device(); if (!port || !input_dev) { - kfree(port); - input_free_device(input_dev); - return -ENOMEM; + err = -ENOMEM; + goto fail; } port->mode = data[TMDC_BYTE_ID]; @@ -347,9 +347,15 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) b += port->btnc[i]; } - input_register_device(port->dev); + err = input_register_device(port->dev); + if (err) + goto fail; return 0; + + fail: input_free_device(input_dev); + kfree(port); + return err; } /* @@ -424,6 +430,7 @@ static void tmdc_disconnect(struct gameport *gameport) static struct gameport_driver tmdc_drv = { .driver = { .name = "tmdc", + .owner = THIS_MODULE, }, .description = DRIVER_DESC, .connect = tmdc_connect, From 275c6ce25d679a4c0981a9a259e60e732a123cc6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Jan 2006 21:52:39 -0500 Subject: [PATCH 169/695] Input: a3d - convert to dynamic input_dev allocation Also set .owner in driver structure so we'll have a link between module and driver in sysfs. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/a3d.c | 88 +++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 4571ea3a4b92..4612d13ea756 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -57,7 +57,7 @@ static char *a3d_names[] = { NULL, "FP-Gaming Assassin 3D", "MadCatz Panther", " struct a3d { struct gameport *gameport; struct gameport *adc; - struct input_dev dev; + struct input_dev *dev; int axes[4]; int buttons; int mode; @@ -115,7 +115,7 @@ static int a3d_csum(char *data, int count) static void a3d_read(struct a3d *a3d, unsigned char *data) { - struct input_dev *dev = &a3d->dev; + struct input_dev *dev = a3d->dev; switch (a3d->mode) { @@ -265,14 +265,20 @@ static void a3d_close(struct input_dev *dev) static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) { struct a3d *a3d; + struct input_dev *input_dev; struct gameport *adc; unsigned char data[A3D_MAX_LENGTH]; int i; int err; - if (!(a3d = kzalloc(sizeof(struct a3d), GFP_KERNEL))) - return -ENOMEM; + a3d = kzalloc(sizeof(struct a3d), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!a3d || !input_dev) { + err = -ENOMEM; + goto fail1; + } + a3d->dev = input_dev; a3d->gameport = gameport; gameport_set_drvdata(gameport, a3d); @@ -302,42 +308,48 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) sprintf(a3d->phys, "%s/input0", gameport->phys); + input_dev->name = a3d_names[a3d->mode]; + input_dev->phys = a3d->phys; + input_dev->id.bustype = BUS_GAMEPORT; + input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ; + input_dev->id.product = a3d->mode; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &gameport->dev; + input_dev->private = a3d; + input_dev->open = a3d_open; + input_dev->close = a3d_close; + if (a3d->mode == A3D_MODE_PXL) { int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER }; a3d->length = 33; - init_input_dev(&a3d->dev); - - a3d->dev.evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); - a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y); - a3d->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER) - | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y); - - a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE) - | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - - a3d->dev.keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_PINKIE); + input_dev->evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); + input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y); + input_dev->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER) + | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y); + input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE) + | BIT(BTN_SIDE) | BIT(BTN_EXTRA); + input_dev->keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) + | BIT(BTN_PINKIE); a3d_read(a3d, data); for (i = 0; i < 4; i++) { if (i < 2) - input_set_abs_params(&a3d->dev, axes[i], 48, a3d->dev.abs[axes[i]] * 2 - 48, 0, 8); + input_set_abs_params(input_dev, axes[i], 48, input_dev->abs[axes[i]] * 2 - 48, 0, 8); else - input_set_abs_params(&a3d->dev, axes[i], 2, 253, 0, 0); - input_set_abs_params(&a3d->dev, ABS_HAT0X + i, -1, 1, 0, 0); + input_set_abs_params(input_dev, axes[i], 2, 253, 0, 0); + input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); } } else { a3d->length = 29; - init_input_dev(&a3d->dev); - - a3d->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_REL); - a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y); - a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE); + input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_REL); + input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y); + input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE); a3d_read(a3d, data); @@ -358,24 +370,17 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) } } - a3d->dev.private = a3d; - a3d->dev.open = a3d_open; - a3d->dev.close = a3d_close; - - a3d->dev.name = a3d_names[a3d->mode]; - a3d->dev.phys = a3d->phys; - a3d->dev.id.bustype = BUS_GAMEPORT; - a3d->dev.id.vendor = GAMEPORT_ID_VENDOR_MADCATZ; - a3d->dev.id.product = a3d->mode; - a3d->dev.id.version = 0x0100; - - input_register_device(&a3d->dev); - printk(KERN_INFO "input: %s on %s\n", a3d_names[a3d->mode], a3d->phys); + err = input_register_device(a3d->dev); + if (err) + goto fail3; return 0; -fail2: gameport_close(gameport); -fail1: gameport_set_drvdata(gameport, NULL); + fail3: if (a3d->adc) + gameport_unregister_port(a3d->adc); + fail2: gameport_close(gameport); + fail1: gameport_set_drvdata(gameport, NULL); + input_free_device(input_dev); kfree(a3d); return err; } @@ -384,11 +389,9 @@ static void a3d_disconnect(struct gameport *gameport) { struct a3d *a3d = gameport_get_drvdata(gameport); - input_unregister_device(&a3d->dev); - if (a3d->adc) { + input_unregister_device(a3d->dev); + if (a3d->adc) gameport_unregister_port(a3d->adc); - a3d->adc = NULL; - } gameport_close(gameport); gameport_set_drvdata(gameport, NULL); kfree(a3d); @@ -397,6 +400,7 @@ static void a3d_disconnect(struct gameport *gameport) static struct gameport_driver a3d_drv = { .driver = { .name = "adc", + .owner = THIS_MODULE, }, .description = DRIVER_DESC, .connect = a3d_connect, From 68ee3eb8295c9c164071fcbd367c419121bd55f8 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sun, 29 Jan 2006 20:25:49 -0700 Subject: [PATCH 170/695] [PARISC] New syscalls (inotify, *at, pselect6/ppoll, migrate_pages) Wire up some new syscalls that have been merged upstream, o inotify o openat et al o pselect6/ppoll o migrate_pages Signed-off-by: Kyle McMartin --- arch/parisc/kernel/syscall_table.S | 19 +++++++++++++++++++ include/asm-parisc/unistd.h | 21 ++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 32cbc0489324..51d2480627d1 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -374,5 +374,24 @@ ENTRY_SAME(keyctl) ENTRY_SAME(ioprio_set) ENTRY_SAME(ioprio_get) + ENTRY_SAME(inotify_init) + ENTRY_SAME(inotify_add_watch) /* 270 */ + ENTRY_SAME(inotify_rm_watch) + ENTRY_COMP(pselect6) + ENTRY_COMP(ppoll) + ENTRY_SAME(migrate_pages) + ENTRY_COMP(openat) /* 275 */ + ENTRY_SAME(mkdirat) + ENTRY_SAME(mknodat) + ENTRY_SAME(fchownat) + ENTRY_COMP(futimesat) + ENTRY_COMP(newfstatat) /* 280 */ + ENTRY_SAME(unlinkat) + ENTRY_SAME(renameat) + ENTRY_SAME(linkat) + ENTRY_SAME(symlinkat) + ENTRY_SAME(readlinkat) /* 285 */ + ENTRY_SAME(fchmodat) + ENTRY_SAME(faccessat) /* Nothing yet */ diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 80b7b98c70a1..c56fccbf34ad 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -761,8 +761,27 @@ #define __NR_keyctl (__NR_Linux + 266) #define __NR_ioprio_set (__NR_Linux + 267) #define __NR_ioprio_get (__NR_Linux + 268) +#define __NR_inotify_init (__NR_Linux + 269) +#define __NR_inotify_add_watch (__NR_Linux + 270) +#define __NR_inotify_rm_watch (__NR_Linux + 271) +#define __NR_migrate_pages (__NR_Linux + 272) +#define __NR_pselect6 (__NR_Linux + 273) +#define __NR_ppoll (__NR_Linux + 274) +#define __NR_openat (__NR_Linux + 275) +#define __NR_mkdirat (__NR_Linux + 276) +#define __NR_mknodat (__NR_Linux + 277) +#define __NR_fchownat (__NR_Linux + 278) +#define __NR_futimesat (__NR_Linux + 279) +#define __NR_newfstatat (__NR_Linux + 280) +#define __NR_unlinkat (__NR_Linux + 281) +#define __NR_renameat (__NR_Linux + 282) +#define __NR_linkat (__NR_Linux + 283) +#define __NR_symlinkat (__NR_Linux + 284) +#define __NR_readlinkat (__NR_Linux + 285) +#define __NR_fchmodat (__NR_Linux + 286) +#define __NR_faccessat (__NR_Linux + 287) -#define __NR_Linux_syscalls 269 +#define __NR_Linux_syscalls 288 #define HPUX_GATEWAY_ADDR 0xC0000004 #define LINUX_GATEWAY_ADDR 0x100 From cbd2981a97cb628431a987a8abd1731c74bcc32e Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 30 Jan 2006 15:20:35 -0800 Subject: [PATCH 171/695] IB/mthca: Relax UAR size check There are some cards around that have UAR (user access region) size different from 8 MB. Relax our sanity check to make sure that the PCI BAR is big enough to access the UAR size reported by the device firmware instead. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 8b00d9a0f6f4..9c849d27b06e 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -155,6 +155,13 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim return -ENODEV; } + if (dev_lim->uar_size > pci_resource_len(mdev->pdev, 2)) { + mthca_err(mdev, "HCA reported UAR size of 0x%x bigger than " + "PCI resource 2 size of 0x%lx, aborting.\n", + dev_lim->uar_size, pci_resource_len(mdev->pdev, 2)); + return -ENODEV; + } + mdev->limits.num_ports = dev_lim->num_ports; mdev->limits.vl_cap = dev_lim->max_vl; mdev->limits.mtu_cap = dev_lim->max_mtu; @@ -976,8 +983,7 @@ static int __devinit mthca_init_one(struct pci_dev *pdev, err = -ENODEV; goto err_disable_pdev; } - if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM) || - pci_resource_len(pdev, 2) != 1 << 23) { + if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) { dev_err(&pdev->dev, "Missing UAR, aborting.\n"); err = -ENODEV; goto err_disable_pdev; From 8e9e5f4f5eb1d44ddabfd1ddea4ca4e4244a9ffb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 30 Jan 2006 15:21:21 -0800 Subject: [PATCH 172/695] IB/srp: Semaphore to mutex conversion Convert srp_host->target_mutex from a semaphore to a mutex. Signed-off-by: Ingo Molnar Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/srp/ib_srp.c | 14 +++++++------- drivers/infiniband/ulp/srp/ib_srp.h | 5 ++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 31207e664148..2d2d4ac3525a 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -357,9 +357,9 @@ static void srp_remove_work(void *target_ptr) target->state = SRP_TARGET_REMOVED; spin_unlock_irq(target->scsi_host->host_lock); - down(&target->srp_host->target_mutex); + mutex_lock(&target->srp_host->target_mutex); list_del(&target->list); - up(&target->srp_host->target_mutex); + mutex_unlock(&target->srp_host->target_mutex); scsi_remove_host(target->scsi_host); ib_destroy_cm_id(target->cm_id); @@ -1254,9 +1254,9 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target) if (scsi_add_host(target->scsi_host, host->dev->dma_device)) return -ENODEV; - down(&host->target_mutex); + mutex_lock(&host->target_mutex); list_add_tail(&target->list, &host->target_list); - up(&host->target_mutex); + mutex_unlock(&host->target_mutex); target->state = SRP_TARGET_LIVE; @@ -1525,7 +1525,7 @@ static struct srp_host *srp_add_port(struct ib_device *device, u8 port) return NULL; INIT_LIST_HEAD(&host->target_list); - init_MUTEX(&host->target_mutex); + mutex_init(&host->target_mutex); init_completion(&host->released); host->dev = device; host->port = port; @@ -1626,7 +1626,7 @@ static void srp_remove_one(struct ib_device *device) * Mark all target ports as removed, so we stop queueing * commands and don't try to reconnect. */ - down(&host->target_mutex); + mutex_lock(&host->target_mutex); list_for_each_entry_safe(target, tmp_target, &host->target_list, list) { spin_lock_irqsave(target->scsi_host->host_lock, flags); @@ -1634,7 +1634,7 @@ static void srp_remove_one(struct ib_device *device) target->state = SRP_TARGET_REMOVED; spin_unlock_irqrestore(target->scsi_host->host_lock, flags); } - up(&host->target_mutex); + mutex_unlock(&host->target_mutex); /* * Wait for any reconnection tasks that may have diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index b564f18caf78..4e7727df32f1 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -37,8 +37,7 @@ #include #include - -#include +#include #include #include @@ -85,7 +84,7 @@ struct srp_host { struct ib_mr *mr; struct class_device class_dev; struct list_head target_list; - struct semaphore target_mutex; + struct mutex target_mutex; struct completion released; struct list_head list; }; From e3aa31c517cb6fd0a3d8b23e6a7e71a6aafc2393 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 30 Jan 2006 16:22:29 -0800 Subject: [PATCH 173/695] IB/mthca: Don't cancel commands on a signal We have run into the following problem: if a task receives a signal while in the process of e.g. destroying a resource (which could be because the relevant file was closed) mthca could bail out from trying to take a command interface semaphore without performing the appropriate command to tell hardware that the resource is being destroyed. As a result we see messages like ib_mthca 0000:04:00.0: HW2SW_CQ failed (-4) In this case, hardware could access the resource after the memory has been freed, possibly causing memory corruption. A simple solution is to replace down_interruptible() by down() in command interface activation. Signed-off-by: Michael S. Tsirkin [ It's also not safe to bail out on multicast table operations, since they may be invoked on the cleanup path too. So use down() for mcg_table.sem too. ] Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_cmd.c | 9 +++------ drivers/infiniband/hw/mthca/mthca_mcg.c | 14 ++++---------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index be1791be627b..69128fe60c53 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -199,8 +199,7 @@ static int mthca_cmd_post(struct mthca_dev *dev, { int err = 0; - if (down_interruptible(&dev->cmd.hcr_sem)) - return -EINTR; + down(&dev->cmd.hcr_sem); if (event) { unsigned long end = jiffies + GO_BIT_TIMEOUT; @@ -255,8 +254,7 @@ static int mthca_cmd_poll(struct mthca_dev *dev, int err = 0; unsigned long end; - if (down_interruptible(&dev->cmd.poll_sem)) - return -EINTR; + down(&dev->cmd.poll_sem); err = mthca_cmd_post(dev, in_param, out_param ? *out_param : 0, @@ -333,8 +331,7 @@ static int mthca_cmd_wait(struct mthca_dev *dev, int err = 0; struct mthca_cmd_context *context; - if (down_interruptible(&dev->cmd.event_sem)) - return -EINTR; + down(&dev->cmd.event_sem); spin_lock(&dev->cmd.context_lock); BUG_ON(dev->cmd.free_head < 0); diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index 77bc6c746f43..55ff5e5bcfef 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -154,10 +154,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return PTR_ERR(mailbox); mgm = mailbox->buf; - if (down_interruptible(&dev->mcg_table.sem)) { - err = -EINTR; - goto err_sem; - } + down(&dev->mcg_table.sem); err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); if (err) @@ -242,7 +239,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) mthca_free(&dev->mcg_table.alloc, index); } up(&dev->mcg_table.sem); - err_sem: + mthca_free_mailbox(dev, mailbox); return err; } @@ -263,10 +260,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return PTR_ERR(mailbox); mgm = mailbox->buf; - if (down_interruptible(&dev->mcg_table.sem)) { - err = -EINTR; - goto err_sem; - } + down(&dev->mcg_table.sem); err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); if (err) @@ -372,7 +366,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) out: up(&dev->mcg_table.sem); - err_sem: + mthca_free_mailbox(dev, mailbox); return err; } From fd9cfdd11be3b37b5c919b64b43990f14a1587bd Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 30 Jan 2006 16:45:11 -0800 Subject: [PATCH 174/695] IB/mthca: Semaphore to mutex conversions Convert semaphores to mutexes in mthca. Leave firmware command interface poll_sem and event_sem as semaphores. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_cmd.c | 6 ++-- drivers/infiniband/hw/mthca/mthca_dev.h | 8 +++-- drivers/infiniband/hw/mthca/mthca_mcg.c | 10 +++--- drivers/infiniband/hw/mthca/mthca_memfree.c | 36 ++++++++++---------- drivers/infiniband/hw/mthca/mthca_memfree.h | 7 ++-- drivers/infiniband/hw/mthca/mthca_provider.c | 6 ++-- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 69128fe60c53..f9b9b93dc501 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -199,7 +199,7 @@ static int mthca_cmd_post(struct mthca_dev *dev, { int err = 0; - down(&dev->cmd.hcr_sem); + mutex_lock(&dev->cmd.hcr_mutex); if (event) { unsigned long end = jiffies + GO_BIT_TIMEOUT; @@ -237,7 +237,7 @@ static int mthca_cmd_post(struct mthca_dev *dev, op), dev->hcr + 6 * 4); out: - up(&dev->cmd.hcr_sem); + mutex_unlock(&dev->cmd.hcr_mutex); return err; } @@ -435,7 +435,7 @@ static int mthca_cmd_imm(struct mthca_dev *dev, int mthca_cmd_init(struct mthca_dev *dev) { - sema_init(&dev->cmd.hcr_sem, 1); + mutex_init(&dev->cmd.hcr_mutex); sema_init(&dev->cmd.poll_sem, 1); dev->cmd.use_events = 0; diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index a104ab041ea3..2a165fd06e57 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -44,6 +44,8 @@ #include #include #include +#include + #include #include "mthca_provider.h" @@ -111,7 +113,7 @@ enum { struct mthca_cmd { struct pci_pool *pool; int use_events; - struct semaphore hcr_sem; + struct mutex hcr_mutex; struct semaphore poll_sem; struct semaphore event_sem; int max_cmds; @@ -256,7 +258,7 @@ struct mthca_av_table { }; struct mthca_mcg_table { - struct semaphore sem; + struct mutex mutex; struct mthca_alloc alloc; struct mthca_icm_table *table; }; @@ -301,7 +303,7 @@ struct mthca_dev { u64 ddr_end; MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock) - struct semaphore cap_mask_mutex; + struct mutex cap_mask_mutex; void __iomem *hcr; void __iomem *kar; diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index 55ff5e5bcfef..321f11e707f2 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -154,7 +154,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return PTR_ERR(mailbox); mgm = mailbox->buf; - down(&dev->mcg_table.sem); + mutex_lock(&dev->mcg_table.mutex); err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); if (err) @@ -238,7 +238,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) BUG_ON(index < dev->limits.num_mgms); mthca_free(&dev->mcg_table.alloc, index); } - up(&dev->mcg_table.sem); + mutex_unlock(&dev->mcg_table.mutex); mthca_free_mailbox(dev, mailbox); return err; @@ -260,7 +260,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return PTR_ERR(mailbox); mgm = mailbox->buf; - down(&dev->mcg_table.sem); + mutex_lock(&dev->mcg_table.mutex); err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); if (err) @@ -365,7 +365,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) } out: - up(&dev->mcg_table.sem); + mutex_unlock(&dev->mcg_table.mutex); mthca_free_mailbox(dev, mailbox); return err; @@ -383,7 +383,7 @@ int __devinit mthca_init_mcg_table(struct mthca_dev *dev) if (err) return err; - init_MUTEX(&dev->mcg_table.sem); + mutex_init(&dev->mcg_table.mutex); return 0; } diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 9fb985a016e9..d709cb162a72 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -50,7 +50,7 @@ enum { }; struct mthca_user_db_table { - struct semaphore mutex; + struct mutex mutex; struct { u64 uvirt; struct scatterlist mem; @@ -158,7 +158,7 @@ int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int ob int ret = 0; u8 status; - down(&table->mutex); + mutex_lock(&table->mutex); if (table->icm[i]) { ++table->icm[i]->refcount; @@ -184,7 +184,7 @@ int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int ob ++table->icm[i]->refcount; out: - up(&table->mutex); + mutex_unlock(&table->mutex); return ret; } @@ -198,7 +198,7 @@ void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int o i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE; - down(&table->mutex); + mutex_lock(&table->mutex); if (--table->icm[i]->refcount == 0) { mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE, @@ -207,7 +207,7 @@ void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int o table->icm[i] = NULL; } - up(&table->mutex); + mutex_unlock(&table->mutex); } void *mthca_table_find(struct mthca_icm_table *table, int obj) @@ -220,7 +220,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj) if (!table->lowmem) return NULL; - down(&table->mutex); + mutex_lock(&table->mutex); idx = (obj & (table->num_obj - 1)) * table->obj_size; icm = table->icm[idx / MTHCA_TABLE_CHUNK_SIZE]; @@ -240,7 +240,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj) } out: - up(&table->mutex); + mutex_unlock(&table->mutex); return page ? lowmem_page_address(page) + offset : NULL; } @@ -301,7 +301,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev, table->num_obj = nobj; table->obj_size = obj_size; table->lowmem = use_lowmem; - init_MUTEX(&table->mutex); + mutex_init(&table->mutex); for (i = 0; i < num_icm; ++i) table->icm[i] = NULL; @@ -380,7 +380,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, if (index < 0 || index > dev->uar_table.uarc_size / 8) return -EINVAL; - down(&db_tab->mutex); + mutex_lock(&db_tab->mutex); i = index / MTHCA_DB_REC_PER_PAGE; @@ -424,7 +424,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, db_tab->page[i].refcount = 1; out: - up(&db_tab->mutex); + mutex_unlock(&db_tab->mutex); return ret; } @@ -439,11 +439,11 @@ void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar, * pages until we clean up the whole db table. */ - down(&db_tab->mutex); + mutex_lock(&db_tab->mutex); --db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount; - up(&db_tab->mutex); + mutex_unlock(&db_tab->mutex); } struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) @@ -460,7 +460,7 @@ struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) if (!db_tab) return ERR_PTR(-ENOMEM); - init_MUTEX(&db_tab->mutex); + mutex_init(&db_tab->mutex); for (i = 0; i < npages; ++i) { db_tab->page[i].refcount = 0; db_tab->page[i].uvirt = 0; @@ -499,7 +499,7 @@ int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type, int ret = 0; u8 status; - down(&dev->db_tab->mutex); + mutex_lock(&dev->db_tab->mutex); switch (type) { case MTHCA_DB_TYPE_CQ_ARM: @@ -585,7 +585,7 @@ found: *db = (__be32 *) &page->db_rec[j]; out: - up(&dev->db_tab->mutex); + mutex_unlock(&dev->db_tab->mutex); return ret; } @@ -601,7 +601,7 @@ void mthca_free_db(struct mthca_dev *dev, int type, int db_index) page = dev->db_tab->page + i; - down(&dev->db_tab->mutex); + mutex_lock(&dev->db_tab->mutex); page->db_rec[j] = 0; if (i >= dev->db_tab->min_group2) @@ -624,7 +624,7 @@ void mthca_free_db(struct mthca_dev *dev, int type, int db_index) ++dev->db_tab->min_group2; } - up(&dev->db_tab->mutex); + mutex_unlock(&dev->db_tab->mutex); } int mthca_init_db_tab(struct mthca_dev *dev) @@ -638,7 +638,7 @@ int mthca_init_db_tab(struct mthca_dev *dev) if (!dev->db_tab) return -ENOMEM; - init_MUTEX(&dev->db_tab->mutex); + mutex_init(&dev->db_tab->mutex); dev->db_tab->npages = dev->uar_table.uarc_size / 4096; dev->db_tab->max_group1 = 0; diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h index 4fdca26eea85..36f1141a08aa 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.h +++ b/drivers/infiniband/hw/mthca/mthca_memfree.h @@ -39,8 +39,7 @@ #include #include - -#include +#include #define MTHCA_ICM_CHUNK_LEN \ ((256 - sizeof (struct list_head) - 2 * sizeof (int)) / \ @@ -64,7 +63,7 @@ struct mthca_icm_table { int num_obj; int obj_size; int lowmem; - struct semaphore mutex; + struct mutex mutex; struct mthca_icm *icm[0]; }; @@ -147,7 +146,7 @@ struct mthca_db_table { int max_group1; int min_group2; struct mthca_db_page *page; - struct semaphore mutex; + struct mutex mutex; }; enum mthca_db_type { diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 484a7e6b7f8c..e88e39aef85a 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -185,7 +185,7 @@ static int mthca_modify_port(struct ib_device *ibdev, int err; u8 status; - if (down_interruptible(&to_mdev(ibdev)->cap_mask_mutex)) + if (mutex_lock_interruptible(&to_mdev(ibdev)->cap_mask_mutex)) return -ERESTARTSYS; err = mthca_query_port(ibdev, port, &attr); @@ -207,7 +207,7 @@ static int mthca_modify_port(struct ib_device *ibdev, } out: - up(&to_mdev(ibdev)->cap_mask_mutex); + mutex_unlock(&to_mdev(ibdev)->cap_mask_mutex); return err; } @@ -1185,7 +1185,7 @@ int mthca_register_device(struct mthca_dev *dev) dev->ib_dev.post_recv = mthca_tavor_post_receive; } - init_MUTEX(&dev->cap_mask_mutex); + mutex_init(&dev->cap_mask_mutex); ret = ib_register_device(&dev->ib_dev); if (ret) From 97d4ebfe7946bc9b89791c932a15c990a24aa94d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 31 Jan 2006 01:31:07 -0500 Subject: [PATCH 175/695] Input: iforce - fix detection of USB devices Recent conversion to wait_event_interruptible_timeout() caused USB detection routine erroneously report timeouts for perfectly working devices. Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/iforce/iforce-packets.c | 4 ++-- drivers/input/joystick/iforce/iforce-usb.c | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 4a2629243e19..76cb1f88f4e8 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -167,9 +167,9 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, iforce->expect_packet = 0; iforce->ecmd = cmd; memcpy(iforce->edata, data, IFORCE_MAX_LENGTH); - wake_up(&iforce->wait); } #endif + wake_up(&iforce->wait); if (!iforce->type) { being_used--; @@ -264,7 +264,7 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) wait_event_interruptible_timeout(iforce->wait, iforce->ctrl->status != -EINPROGRESS, HZ); - if (iforce->ctrl->status != -EINPROGRESS) { + if (iforce->ctrl->status) { usb_unlink_urb(iforce->ctrl); return -1; } diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index bc2fce60f9f8..fe79d158456d 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -95,7 +95,6 @@ static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs) goto exit; } - wake_up(&iforce->wait); iforce_process_packet(iforce, (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs); From 6dea93477c3377cf4199fd37cc3fb11071987ae4 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Tue, 31 Jan 2006 01:31:13 -0500 Subject: [PATCH 176/695] Input: hiddev - fix off-by-one for num_values in uref_multi requests Found this when working with a HAPP UGCI device. It has a usage with 7 indexes. I could read them all one at a time, but using a multiref it would only allow me to read the first 6. The patch below fixed it. Signed-off-by: Ben Collins Signed-off-by: Dmitry Torokhov --- drivers/usb/input/hiddev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 4dff8473553d..3f7274906c13 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -632,7 +632,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) && (uref_multi->num_values > HID_MAX_MULTI_USAGES || - uref->usage_index + uref_multi->num_values >= field->report_count)) + uref->usage_index + uref_multi->num_values > field->report_count)) goto inval; } From b8e4d89357fc434618a59c1047cac72641191805 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 27 Jan 2006 16:43:00 -0500 Subject: [PATCH 177/695] [ACPI] ACPICA 20060127 Implemented support in the Resource Manager to allow unresolved namestring references within resource package objects for the _PRT method. This support is in addition to the previously implemented unresolved reference support within the AML parser. If the interpreter slack mode is enabled (true on Linux unless acpi=strict), these unresolved references will be passed through to the caller as a NULL package entry. http://bugzilla.kernel.org/show_bug.cgi?id=5741 Implemented and deployed new macros and functions for error and warning messages across the subsystem. These macros are simpler and generate less code than their predecessors. The new macros ACPI_ERROR, ACPI_EXCEPTION, ACPI_WARNING, and ACPI_INFO replace the ACPI_REPORT_* macros. Implemented the acpi_cpu_flags type to simplify host OS integration of the Acquire/Release Lock OSL interfaces. Suggested by Steven Rostedt and Andrew Morton. Fixed a problem where Alias ASL operators are sometimes not correctly resolved. causing AE_AML_INTERNAL http://bugzilla.kernel.org/show_bug.cgi?id=5189 http://bugzilla.kernel.org/show_bug.cgi?id=5674 Fixed several problems with the implementation of the ConcatenateResTemplate ASL operator. As per the ACPI specification, zero length buffers are now treated as a single EndTag. One-length buffers always cause a fatal exception. Non-zero length buffers that do not end with a full 2-byte EndTag cause a fatal exception. Fixed a possible structure overwrite in the AcpiGetObjectInfo external interface. (With assistance from Thomas Renninger) Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsfield.c | 34 ++++--- drivers/acpi/dispatcher/dsinit.c | 14 ++- drivers/acpi/dispatcher/dsmethod.c | 6 +- drivers/acpi/dispatcher/dsmthdat.c | 25 +++-- drivers/acpi/dispatcher/dsobject.c | 20 ++-- drivers/acpi/dispatcher/dsopcode.c | 45 +++++---- drivers/acpi/dispatcher/dsutils.c | 15 +-- drivers/acpi/dispatcher/dswexec.c | 31 +++++-- drivers/acpi/dispatcher/dswload.c | 26 ++++-- drivers/acpi/dispatcher/dswscope.c | 4 +- drivers/acpi/dispatcher/dswstate.c | 94 +++++++++++-------- drivers/acpi/events/evevent.c | 19 ++-- drivers/acpi/events/evgpe.c | 42 ++++++--- drivers/acpi/events/evgpeblk.c | 50 ++++++---- drivers/acpi/events/evmisc.c | 20 ++-- drivers/acpi/events/evregion.c | 44 +++++---- drivers/acpi/events/evrgnini.c | 6 +- drivers/acpi/events/evxface.c | 12 ++- drivers/acpi/events/evxfevnt.c | 20 ++-- drivers/acpi/executer/exconfig.c | 4 +- drivers/acpi/executer/exconvrt.c | 11 ++- drivers/acpi/executer/excreate.c | 4 +- drivers/acpi/executer/exfield.c | 9 +- drivers/acpi/executer/exfldio.c | 65 ++++++++----- drivers/acpi/executer/exmisc.c | 43 +++++---- drivers/acpi/executer/exmutex.c | 26 ++++-- drivers/acpi/executer/exnames.c | 13 +-- drivers/acpi/executer/exoparg1.c | 57 +++++++----- drivers/acpi/executer/exoparg2.c | 30 +++--- drivers/acpi/executer/exoparg3.c | 8 +- drivers/acpi/executer/exoparg6.c | 11 ++- drivers/acpi/executer/exprep.c | 25 +++-- drivers/acpi/executer/exregion.c | 9 +- drivers/acpi/executer/exresnte.c | 37 ++++---- drivers/acpi/executer/exresolv.c | 37 +++++--- drivers/acpi/executer/exresop.c | 96 ++++++++++++++----- drivers/acpi/executer/exstore.c | 18 ++-- drivers/acpi/executer/exstoren.c | 17 ++-- drivers/acpi/executer/exsystem.c | 4 +- drivers/acpi/executer/exutils.c | 10 +- drivers/acpi/hardware/hwacpi.c | 14 +-- drivers/acpi/hardware/hwregs.c | 43 ++++++--- drivers/acpi/hardware/hwsleep.c | 21 ++--- drivers/acpi/namespace/nsaccess.c | 29 ++++-- drivers/acpi/namespace/nsalloc.c | 8 +- drivers/acpi/namespace/nsdump.c | 8 +- drivers/acpi/namespace/nseval.c | 2 +- drivers/acpi/namespace/nsinit.c | 18 ++-- drivers/acpi/namespace/nsload.c | 8 +- drivers/acpi/namespace/nsnames.c | 6 +- drivers/acpi/namespace/nsobject.c | 11 ++- drivers/acpi/namespace/nssearch.c | 8 +- drivers/acpi/namespace/nsutils.c | 12 +-- drivers/acpi/namespace/nsxfeval.c | 18 ++-- drivers/acpi/namespace/nsxfname.c | 3 +- drivers/acpi/osl.c | 8 +- drivers/acpi/parser/psargs.c | 10 +- drivers/acpi/parser/psloop.c | 15 ++- drivers/acpi/parser/psparse.c | 9 +- drivers/acpi/parser/pstree.c | 4 +- drivers/acpi/resources/rscalc.c | 14 +-- drivers/acpi/resources/rscreate.c | 142 +++++++++++++++++------------ drivers/acpi/resources/rsdump.c | 6 +- drivers/acpi/resources/rslist.c | 12 ++- drivers/acpi/resources/rsmisc.c | 28 +++--- drivers/acpi/tables/tbconvrt.c | 17 ++-- drivers/acpi/tables/tbget.c | 37 ++++---- drivers/acpi/tables/tbgetall.c | 21 +++-- drivers/acpi/tables/tbinstal.c | 10 +- drivers/acpi/tables/tbrsdt.c | 18 ++-- drivers/acpi/tables/tbutils.c | 27 ++++-- drivers/acpi/tables/tbxface.c | 19 ++-- drivers/acpi/tables/tbxfroot.c | 21 +++-- drivers/acpi/utilities/utalloc.c | 51 +++++------ drivers/acpi/utilities/utcopy.c | 5 +- drivers/acpi/utilities/utdelete.c | 10 +- drivers/acpi/utilities/uteval.c | 18 ++-- drivers/acpi/utilities/utglobal.c | 4 +- drivers/acpi/utilities/utinit.c | 8 +- drivers/acpi/utilities/utmath.c | 8 +- drivers/acpi/utilities/utmisc.c | 108 +++++++++++++++------- drivers/acpi/utilities/utmutex.c | 29 ++++-- drivers/acpi/utilities/utobject.c | 29 +++--- drivers/acpi/utilities/utresrc.c | 16 ++++ drivers/acpi/utilities/utxface.c | 14 ++- include/acpi/acconfig.h | 4 +- include/acpi/aclocal.h | 9 +- include/acpi/acmacros.h | 87 +++++++----------- include/acpi/acobject.h | 2 +- include/acpi/acpiosxf.h | 4 +- include/acpi/actypes.h | 41 +++++++-- include/acpi/acutils.h | 25 ++++- include/acpi/platform/acenv.h | 10 +- include/acpi/platform/acgcc.h | 8 +- include/acpi/platform/aclinux.h | 2 + 95 files changed, 1352 insertions(+), 828 deletions(-) diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index f3a008ff1eae..76bc0463f6de 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c @@ -128,7 +128,7 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, ACPI_IMODE_LOAD_PASS1, flags, walk_state, &(node)); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(arg->common.value.string, status); return_ACPI_STATUS(status); } } @@ -232,7 +232,8 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, + (acpi_integer) arg->common.value.size; if (position > ACPI_UINT32_MAX) { - ACPI_REPORT_ERROR(("Bit offset within field too large (> 0xFFFFFFFF)\n")); + ACPI_ERROR((AE_INFO, + "Bit offset within field too large (> 0xFFFFFFFF)")); return_ACPI_STATUS(AE_SUPPORT); } @@ -268,8 +269,8 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, ACPI_NS_DONT_OPEN_SCOPE, walk_state, &info->field_node); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR((char *)&arg->named.name, - status); + ACPI_ERROR_NAMESPACE((char *)&arg->named.name, + status); if (status != AE_ALREADY_EXISTS) { return_ACPI_STATUS(status); } @@ -293,7 +294,11 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, + (acpi_integer) arg->common.value.size; if (position > ACPI_UINT32_MAX) { - ACPI_REPORT_ERROR(("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n", ACPI_CAST_PTR(char, &info->field_node->name))); + ACPI_ERROR((AE_INFO, + "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", + ACPI_CAST_PTR(char, + &info->field_node-> + name))); return_ACPI_STATUS(AE_SUPPORT); } @@ -302,8 +307,9 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, default: - ACPI_REPORT_ERROR(("Invalid opcode in field list: %X\n", - arg->common.aml_opcode)); + ACPI_ERROR((AE_INFO, + "Invalid opcode in field list: %X", + arg->common.aml_opcode)); return_ACPI_STATUS(AE_AML_BAD_OPCODE); } @@ -348,7 +354,7 @@ acpi_ds_create_field(union acpi_parse_object *op, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, ®ion_node); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(arg->common.value.name, status); + ACPI_ERROR_NAMESPACE(arg->common.value.name, status); return_ACPI_STATUS(status); } } @@ -430,8 +436,8 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, ACPI_NS_ERROR_IF_FOUND, walk_state, &node); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR((char *)&arg->named.name, - status); + ACPI_ERROR_NAMESPACE((char *)&arg->named.name, + status); if (status != AE_ALREADY_EXISTS) { return_ACPI_STATUS(status); } @@ -487,7 +493,7 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, ®ion_node); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(arg->common.value.name, status); + ACPI_ERROR_NAMESPACE(arg->common.value.name, status); return_ACPI_STATUS(status); } } @@ -501,7 +507,7 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(arg->common.value.string, status); return_ACPI_STATUS(status); } @@ -559,7 +565,7 @@ acpi_ds_create_index_field(union acpi_parse_object *op, ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(arg->common.value.string, status); return_ACPI_STATUS(status); } @@ -572,7 +578,7 @@ acpi_ds_create_index_field(union acpi_parse_object *op, ACPI_NS_SEARCH_PARENT, walk_state, &info.data_register_node); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(arg->common.value.string, status); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index 258fbdfaa69c..e65a07ad2422 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.c @@ -105,7 +105,10 @@ acpi_ds_init_one_object(acpi_handle obj_handle, status = acpi_ds_initialize_region(obj_handle); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Region %p [%4.4s] - Init failure, %s\n", obj_handle, acpi_ut_get_node_name(obj_handle), acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "During Region initialization %p [%4.4s]", + obj_handle, + acpi_ut_get_node_name(obj_handle))); } info->op_region_count++; @@ -144,7 +147,11 @@ acpi_ds_init_one_object(acpi_handle obj_handle, */ status = acpi_ds_parse_method(obj_handle); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("\n+Method %p [%4.4s] - parse failure, %s\n", obj_handle, acpi_ut_get_node_name(obj_handle), acpi_format_exception(status))); + ACPI_ERROR((AE_INFO, + "Method %p [%4.4s] - parse failure, %s", + obj_handle, + acpi_ut_get_node_name(obj_handle), + acpi_format_exception(status))); /* This parse failed, but we will continue parsing more methods */ } @@ -206,8 +213,7 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, acpi_ds_init_one_object, &info, NULL); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("walk_namespace failed, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace")); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index d861add3fc1f..c475546535b6 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -141,7 +141,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node * method_node, /* Prevent wraparound of thread count */ if (obj_desc->method.thread_count == ACPI_UINT8_MAX) { - ACPI_REPORT_ERROR(("Method reached maximum reentrancy limit (255)\n")); + ACPI_ERROR((AE_INFO, + "Method reached maximum reentrancy limit (255)")); return_ACPI_STATUS(AE_AML_METHOD_LIMIT); } @@ -470,7 +471,8 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) acpi_os_signal_semaphore(walk_state->method_desc->method. semaphore, 1); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not signal method semaphore\n")); + ACPI_ERROR((AE_INFO, + "Could not signal method semaphore")); /* Ignore error and continue cleanup */ } diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index ce33c34f87c6..c025674f938b 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.c @@ -260,7 +260,9 @@ acpi_ds_method_data_get_node(u16 opcode, case AML_LOCAL_OP: if (index > ACPI_METHOD_MAX_LOCAL) { - ACPI_REPORT_ERROR(("Local index %d is invalid (max %d)\n", index, ACPI_METHOD_MAX_LOCAL)); + ACPI_ERROR((AE_INFO, + "Local index %d is invalid (max %d)", + index, ACPI_METHOD_MAX_LOCAL)); return_ACPI_STATUS(AE_AML_INVALID_INDEX); } @@ -272,8 +274,9 @@ acpi_ds_method_data_get_node(u16 opcode, case AML_ARG_OP: if (index > ACPI_METHOD_MAX_ARG) { - ACPI_REPORT_ERROR(("Arg index %d is invalid (max %d)\n", - index, ACPI_METHOD_MAX_ARG)); + ACPI_ERROR((AE_INFO, + "Arg index %d is invalid (max %d)", + index, ACPI_METHOD_MAX_ARG)); return_ACPI_STATUS(AE_AML_INVALID_INDEX); } @@ -283,7 +286,7 @@ acpi_ds_method_data_get_node(u16 opcode, break; default: - ACPI_REPORT_ERROR(("Opcode %d is invalid\n", opcode)); + ACPI_ERROR((AE_INFO, "Opcode %d is invalid", opcode)); return_ACPI_STATUS(AE_AML_BAD_OPCODE); } @@ -374,7 +377,7 @@ acpi_ds_method_data_get_value(u16 opcode, /* Validate the object descriptor */ if (!dest_desc) { - ACPI_REPORT_ERROR(("Null object descriptor pointer\n")); + ACPI_ERROR((AE_INFO, "Null object descriptor pointer")); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -419,18 +422,24 @@ acpi_ds_method_data_get_value(u16 opcode, switch (opcode) { case AML_ARG_OP: - ACPI_REPORT_ERROR(("Uninitialized Arg[%d] at node %p\n", index, node)); + ACPI_ERROR((AE_INFO, + "Uninitialized Arg[%d] at node %p", + index, node)); return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG); case AML_LOCAL_OP: - ACPI_REPORT_ERROR(("Uninitialized Local[%d] at node %p\n", index, node)); + ACPI_ERROR((AE_INFO, + "Uninitialized Local[%d] at node %p", + index, node)); return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); default: - ACPI_REPORT_ERROR(("Not a Arg/Local opcode: %X\n", opcode)); + ACPI_ERROR((AE_INFO, + "Not a Arg/Local opcode: %X", + opcode)); return_ACPI_STATUS(AE_AML_INTERNAL); } } diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index dc116d679a58..8b21f0f9e517 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -129,8 +129,8 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, return_ACPI_STATUS(AE_OK); } else { - ACPI_REPORT_NSERROR(op->common.value. - string, status); + ACPI_ERROR_NAMESPACE(op->common.value. + string, status); } return_ACPI_STATUS(status); @@ -214,7 +214,9 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, byte_list = arg->named.next; if (byte_list) { if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) { - ACPI_REPORT_ERROR(("Expecting bytelist, got AML opcode %X in op %p\n", byte_list->common.aml_opcode, byte_list)); + ACPI_ERROR((AE_INFO, + "Expecting bytelist, got AML opcode %X in op %p", + byte_list->common.aml_opcode, byte_list)); acpi_ut_remove_reference(obj_desc); return (AE_TYPE); @@ -540,7 +542,9 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, default: - ACPI_REPORT_ERROR(("Unknown constant opcode %X\n", opcode)); + ACPI_ERROR((AE_INFO, + "Unknown constant opcode %X", + opcode)); status = AE_AML_OPERAND_TYPE; break; } @@ -555,8 +559,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, break; default: - ACPI_REPORT_ERROR(("Unknown Integer type %X\n", - op_info->type)); + ACPI_ERROR((AE_INFO, "Unknown Integer type %X", + op_info->type)); status = AE_AML_OPERAND_TYPE; break; } @@ -634,8 +638,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, default: - ACPI_REPORT_ERROR(("Unimplemented data type: %X\n", - ACPI_GET_OBJECT_TYPE(obj_desc))); + ACPI_ERROR((AE_INFO, "Unimplemented data type: %X", + ACPI_GET_OBJECT_TYPE(obj_desc))); status = AE_AML_OPERAND_TYPE; break; diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index 60414ee84b0a..6229c10674e1 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -245,7 +245,9 @@ acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc) node = obj_desc->buffer.node; if (!node) { - ACPI_REPORT_ERROR(("No pointer back to NS node in buffer obj %p\n", obj_desc)); + ACPI_ERROR((AE_INFO, + "No pointer back to NS node in buffer obj %p", + obj_desc)); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -287,8 +289,9 @@ acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc) node = obj_desc->package.node; if (!node) { - ACPI_REPORT_ERROR(("No pointer back to NS node in package %p\n", - obj_desc)); + ACPI_ERROR((AE_INFO, + "No pointer back to NS node in package %p", + obj_desc)); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -413,7 +416,9 @@ acpi_ds_init_buffer_field(u16 aml_opcode, /* Host object must be a Buffer */ if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) { - ACPI_REPORT_ERROR(("Target of Create Field is not a Buffer object - %s\n", acpi_ut_get_object_type_name(buffer_desc))); + ACPI_ERROR((AE_INFO, + "Target of Create Field is not a Buffer object - %s", + acpi_ut_get_object_type_name(buffer_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -425,9 +430,10 @@ acpi_ds_init_buffer_field(u16 aml_opcode, * after resolution in acpi_ex_resolve_operands(). */ if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) { - ACPI_REPORT_ERROR(("(%s) destination not a NS Node [%s]\n", - acpi_ps_get_opcode_name(aml_opcode), - acpi_ut_get_descriptor_name(result_desc))); + ACPI_ERROR((AE_INFO, + "(%s) destination not a NS Node [%s]", + acpi_ps_get_opcode_name(aml_opcode), + acpi_ut_get_descriptor_name(result_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -450,7 +456,8 @@ acpi_ds_init_buffer_field(u16 aml_opcode, /* Must have a valid (>0) bit count */ if (bit_count == 0) { - ACPI_REPORT_ERROR(("Attempt to create_field of length 0\n")); + ACPI_ERROR((AE_INFO, + "Attempt to create_field of length zero")); status = AE_AML_OPERAND_VALUE; goto cleanup; } @@ -503,8 +510,8 @@ acpi_ds_init_buffer_field(u16 aml_opcode, default: - ACPI_REPORT_ERROR(("Unknown field creation opcode %02x\n", - aml_opcode)); + ACPI_ERROR((AE_INFO, + "Unknown field creation opcode %02x", aml_opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -512,7 +519,12 @@ acpi_ds_init_buffer_field(u16 aml_opcode, /* Entire field must fit within the current length of the buffer */ if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) { - ACPI_REPORT_ERROR(("Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n", acpi_ut_get_node_name(result_desc), bit_offset + bit_count, acpi_ut_get_node_name(buffer_desc->buffer.node), 8 * (u32) buffer_desc->buffer.length)); + ACPI_ERROR((AE_INFO, + "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)", + acpi_ut_get_node_name(result_desc), + bit_offset + bit_count, + acpi_ut_get_node_name(buffer_desc->buffer.node), + 8 * (u32) buffer_desc->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; } @@ -618,10 +630,9 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, "after acpi_ex_resolve_operands"); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("(%s) bad operand(s) (%X)\n", - acpi_ps_get_opcode_name(op->common. - aml_opcode), - status)); + ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)", + acpi_ps_get_opcode_name(op->common.aml_opcode), + status)); return_ACPI_STATUS(status); } @@ -1145,8 +1156,8 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, default: - ACPI_REPORT_ERROR(("Unknown control opcode=%X Op=%p\n", - op->common.aml_opcode, op)); + ACPI_ERROR((AE_INFO, "Unknown control opcode=%X Op=%p", + op->common.aml_opcode, op)); status = AE_AML_BAD_OPCODE; break; diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index cd9aa7faa57b..53356a591ac1 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -176,7 +176,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, /* Must have both an Op and a Result Object */ if (!op) { - ACPI_REPORT_ERROR(("Null Op\n")); + ACPI_ERROR((AE_INFO, "Null Op")); return_UINT8(TRUE); } @@ -216,7 +216,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, parent_info = acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode); if (parent_info->class == AML_CLASS_UNKNOWN) { - ACPI_REPORT_ERROR(("Unknown parent opcode Op=%p\n", op)); + ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op)); return_UINT8(FALSE); } @@ -343,7 +343,7 @@ acpi_ds_delete_result_if_not_used(union acpi_parse_object *op, ACPI_FUNCTION_TRACE_PTR("ds_delete_result_if_not_used", result_obj); if (!op) { - ACPI_REPORT_ERROR(("Null Op\n")); + ACPI_ERROR((AE_INFO, "Null Op")); return_VOID; } @@ -566,7 +566,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, } if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(name_string, status); + ACPI_ERROR_NAMESPACE(name_string, status); } } @@ -634,7 +634,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, * Only error is underflow, and this indicates * a missing or null operand! */ - ACPI_REPORT_ERROR(("Missing or null operand, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Missing or null operand")); return_ACPI_STATUS(status); } } else { @@ -726,7 +727,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, */ (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); - ACPI_REPORT_ERROR(("While creating Arg %d - %s\n", - (arg_count + 1), acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", + (arg_count + 1))); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 5a9b91fe93d2..f1af655ff113 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -100,7 +100,8 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, if (result_obj) { status = acpi_ds_result_pop(&obj_desc, walk_state); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not get result from predicate evaluation, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not get result from predicate evaluation")); return_ACPI_STATUS(status); } @@ -121,8 +122,9 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, } if (!obj_desc) { - ACPI_REPORT_ERROR(("No predicate obj_desc=%p State=%p\n", - obj_desc, walk_state)); + ACPI_ERROR((AE_INFO, + "No predicate obj_desc=%p State=%p", + obj_desc, walk_state)); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -137,7 +139,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, } if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) { - ACPI_REPORT_ERROR(("Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n", obj_desc, walk_state, ACPI_GET_OBJECT_TYPE(obj_desc))); + ACPI_ERROR((AE_INFO, + "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X", + obj_desc, walk_state, + ACPI_GET_OBJECT_TYPE(obj_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -356,8 +361,8 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) op_class = walk_state->op_info->class; if (op_class == AML_CLASS_UNKNOWN) { - ACPI_REPORT_ERROR(("Unknown opcode %X\n", - op->common.aml_opcode)); + ACPI_ERROR((AE_INFO, "Unknown opcode %X", + op->common.aml_opcode)); return_ACPI_STATUS(AE_NOT_IMPLEMENTED); } @@ -447,7 +452,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) walk_state->operands[1]->reference.offset)) { status = AE_OK; } else { - ACPI_REPORT_ERROR(("[%s]: Could not resolve operands, %s\n", acpi_ps_get_opcode_name(walk_state->opcode), acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "While resolving operands for [%s]", + acpi_ps_get_opcode_name + (walk_state->opcode))); } } @@ -666,8 +674,8 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) case AML_TYPE_UNDEFINED: - ACPI_REPORT_ERROR(("Undefined opcode type Op=%p\n", - op)); + ACPI_ERROR((AE_INFO, + "Undefined opcode type Op=%p", op)); return_ACPI_STATUS(AE_NOT_IMPLEMENTED); case AML_TYPE_BOGUS: @@ -679,7 +687,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n", op_class, op_type, op->common.aml_opcode, op)); + ACPI_ERROR((AE_INFO, + "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p", + op_class, op_type, op->common.aml_opcode, + op)); status = AE_NOT_IMPLEMENTED; break; diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 4cad6afa82f7..d3d24da31c81 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -187,7 +187,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, } #endif if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(path, status); + ACPI_ERROR_NAMESPACE(path, status); return_ACPI_STATUS(status); } @@ -233,7 +233,9 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, /* All other types are an error */ - ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n", acpi_ut_get_type_name(node->type), path)); + ACPI_ERROR((AE_INFO, + "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)", + acpi_ut_get_type_name(node->type), path)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -300,7 +302,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, ACPI_IMODE_LOAD_PASS1, flags, walk_state, &(node)); if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(path, status); + ACPI_ERROR_NAMESPACE(path, status); return_ACPI_STATUS(status); } break; @@ -618,10 +620,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, if (status == AE_NOT_FOUND) { status = AE_OK; } else { - ACPI_REPORT_NSERROR(buffer_ptr, status); + ACPI_ERROR_NAMESPACE(buffer_ptr, status); } #else - ACPI_REPORT_NSERROR(buffer_ptr, status); + ACPI_ERROR_NAMESPACE(buffer_ptr, status); #endif return_ACPI_STATUS(status); } @@ -651,7 +653,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, * Scope (DEB) { ... } */ - ACPI_REPORT_WARNING(("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n", buffer_ptr, acpi_ut_get_type_name(node->type))); + ACPI_WARNING((AE_INFO, + "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)", + buffer_ptr, + acpi_ut_get_type_name(node->type))); node->type = ACPI_TYPE_ANY; walk_state->scope_info->common.value = ACPI_TYPE_ANY; @@ -661,7 +666,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, /* All other types are an error */ - ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s]\n", acpi_ut_get_type_name(node->type), buffer_ptr)); + ACPI_ERROR((AE_INFO, + "Invalid type (%s) for target of Scope operator [%4.4s]", + acpi_ut_get_type_name(node->type), + buffer_ptr)); return (AE_AML_OPERAND_TYPE); } @@ -714,7 +722,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, } if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(buffer_ptr, status); + ACPI_ERROR_NAMESPACE(buffer_ptr, status); return_ACPI_STATUS(status); } @@ -1112,7 +1120,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) */ op->common.node = new_node; } else { - ACPI_REPORT_NSERROR(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(arg->common.value.string, status); } break; diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c index e7fc88ca47ba..ada21ef4a174 100644 --- a/drivers/acpi/dispatcher/dswscope.c +++ b/drivers/acpi/dispatcher/dswscope.c @@ -107,14 +107,14 @@ acpi_ds_scope_stack_push(struct acpi_namespace_node *node, if (!node) { /* Invalid scope */ - ACPI_REPORT_ERROR(("Null scope parameter\n")); + ACPI_ERROR((AE_INFO, "Null scope parameter")); return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Make sure object type is valid */ if (!acpi_ut_valid_object_type(type)) { - ACPI_REPORT_WARNING(("Invalid object type: 0x%X\n", type)); + ACPI_WARNING((AE_INFO, "Invalid object type: 0x%X", type)); } /* Allocate a new scope object */ diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 61aae2dcc5e2..fa78cb74ee36 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c @@ -92,23 +92,23 @@ acpi_ds_result_remove(union acpi_operand_object **object, state = walk_state->results; if (!state) { - ACPI_REPORT_ERROR(("No result object pushed! State=%p\n", - walk_state)); + ACPI_ERROR((AE_INFO, "No result object pushed! State=%p", + walk_state)); return (AE_NOT_EXIST); } if (index >= ACPI_OBJ_MAX_OPERAND) { - ACPI_REPORT_ERROR(("Index out of range: %X State=%p Num=%X\n", - index, walk_state, - state->results.num_results)); + ACPI_ERROR((AE_INFO, + "Index out of range: %X State=%p Num=%X", + index, walk_state, state->results.num_results)); } /* Check for a valid result object */ if (!state->results.obj_desc[index]) { - ACPI_REPORT_ERROR(("Null operand! State=%p #Ops=%X, Index=%X\n", - walk_state, state->results.num_results, - index)); + ACPI_ERROR((AE_INFO, + "Null operand! State=%p #Ops=%X, Index=%X", + walk_state, state->results.num_results, index)); return (AE_AML_NO_RETURN_VALUE); } @@ -160,8 +160,8 @@ acpi_ds_result_pop(union acpi_operand_object ** object, } if (!state->results.num_results) { - ACPI_REPORT_ERROR(("Result stack is empty! State=%p\n", - walk_state)); + ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p", + walk_state)); return (AE_AML_NO_RETURN_VALUE); } @@ -188,7 +188,7 @@ acpi_ds_result_pop(union acpi_operand_object ** object, } } - ACPI_REPORT_ERROR(("No result objects! State=%p\n", walk_state)); + ACPI_ERROR((AE_INFO, "No result objects! State=%p", walk_state)); return (AE_AML_NO_RETURN_VALUE); } @@ -217,14 +217,14 @@ acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object, state = walk_state->results; if (!state) { - ACPI_REPORT_ERROR(("No result object pushed! State=%p\n", - walk_state)); + ACPI_ERROR((AE_INFO, + "No result object pushed! State=%p", walk_state)); return (AE_NOT_EXIST); } if (!state->results.num_results) { - ACPI_REPORT_ERROR(("No result objects! State=%p\n", - walk_state)); + ACPI_ERROR((AE_INFO, "No result objects! State=%p", + walk_state)); return (AE_AML_NO_RETURN_VALUE); } @@ -244,9 +244,10 @@ acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object, /* Check for a valid result object */ if (!*object) { - ACPI_REPORT_ERROR(("Null operand! State=%p #Ops=%X Index=%X\n", - walk_state, state->results.num_results, - (u32) index)); + ACPI_ERROR((AE_INFO, + "Null operand! State=%p #Ops=%X Index=%X", + walk_state, state->results.num_results, + (u32) index)); return (AE_AML_NO_RETURN_VALUE); } @@ -281,19 +282,21 @@ acpi_ds_result_push(union acpi_operand_object * object, state = walk_state->results; if (!state) { - ACPI_REPORT_ERROR(("No result stack frame during push\n")); + ACPI_ERROR((AE_INFO, "No result stack frame during push")); return (AE_AML_INTERNAL); } if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) { - ACPI_REPORT_ERROR(("Result stack overflow: Obj=%p State=%p Num=%X\n", object, walk_state, state->results.num_results)); + ACPI_ERROR((AE_INFO, + "Result stack overflow: Obj=%p State=%p Num=%X", + object, walk_state, state->results.num_results)); return (AE_STACK_OVERFLOW); } if (!object) { - ACPI_REPORT_ERROR(("Null Object! Obj=%p State=%p Num=%X\n", - object, walk_state, - state->results.num_results)); + ACPI_ERROR((AE_INFO, + "Null Object! Obj=%p State=%p Num=%X", + object, walk_state, state->results.num_results)); return (AE_BAD_PARAMETER); } @@ -402,7 +405,9 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state) /* Check for stack overflow */ if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) { - ACPI_REPORT_ERROR(("Object stack overflow! Obj=%p State=%p #Ops=%X\n", object, walk_state, walk_state->num_operands)); + ACPI_ERROR((AE_INFO, + "Object stack overflow! Obj=%p State=%p #Ops=%X", + object, walk_state, walk_state->num_operands)); return (AE_STACK_OVERFLOW); } @@ -446,7 +451,10 @@ acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state) /* Check for stack underflow */ if (walk_state->num_operands == 0) { - ACPI_REPORT_ERROR(("Object stack underflow! Count=%X State=%p #Ops=%X\n", pop_count, walk_state, walk_state->num_operands)); + ACPI_ERROR((AE_INFO, + "Object stack underflow! Count=%X State=%p #Ops=%X", + pop_count, walk_state, + walk_state->num_operands)); return (AE_STACK_UNDERFLOW); } @@ -489,7 +497,10 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count, /* Check for stack underflow */ if (walk_state->num_operands == 0) { - ACPI_REPORT_ERROR(("Object stack underflow! Count=%X State=%p #Ops=%X\n", pop_count, walk_state, walk_state->num_operands)); + ACPI_ERROR((AE_INFO, + "Object stack underflow! Count=%X State=%p #Ops=%X", + pop_count, walk_state, + walk_state->num_operands)); return (AE_STACK_UNDERFLOW); } @@ -806,14 +817,14 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) } if (walk_state->data_type != ACPI_DESC_TYPE_WALK) { - ACPI_REPORT_ERROR(("%p is not a valid walk state\n", - walk_state)); + ACPI_ERROR((AE_INFO, "%p is not a valid walk state", + walk_state)); return; } if (walk_state->parser_state.scope) { - ACPI_REPORT_ERROR(("%p walk still has a scope list\n", - walk_state)); + ACPI_ERROR((AE_INFO, "%p walk still has a scope list", + walk_state)); } /* Always must free any linked control states */ @@ -872,18 +883,24 @@ acpi_ds_result_insert(void *object, state = walk_state->results; if (!state) { - ACPI_REPORT_ERROR(("No result object pushed! State=%p\n", - walk_state)); + ACPI_ERROR((AE_INFO, "No result object pushed! State=%p", + walk_state)); return (AE_NOT_EXIST); } if (index >= ACPI_OBJ_NUM_OPERANDS) { - ACPI_REPORT_ERROR(("Index out of range: %X Obj=%p State=%p Num=%X\n", index, object, walk_state, state->results.num_results)); + ACPI_ERROR((AE_INFO, + "Index out of range: %X Obj=%p State=%p Num=%X", + index, object, walk_state, + state->results.num_results)); return (AE_BAD_PARAMETER); } if (!object) { - ACPI_REPORT_ERROR(("Null Object! Index=%X Obj=%p State=%p Num=%X\n", index, object, walk_state, state->results.num_results)); + ACPI_ERROR((AE_INFO, + "Null Object! Index=%X Obj=%p State=%p Num=%X", + index, object, walk_state, + state->results.num_results)); return (AE_BAD_PARAMETER); } @@ -957,7 +974,9 @@ acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, /* Check for stack underflow */ if (walk_state->num_operands == 0) { - ACPI_REPORT_ERROR(("Missing operand/stack empty! State=%p #Ops=%X\n", walk_state, walk_state->num_operands)); + ACPI_ERROR((AE_INFO, + "Missing operand/stack empty! State=%p #Ops=%X", + walk_state, walk_state->num_operands)); *object = NULL; return (AE_AML_NO_OPERAND); } @@ -969,8 +988,9 @@ acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, /* Check for a valid operand */ if (!walk_state->operands[walk_state->num_operands]) { - ACPI_REPORT_ERROR(("Null operand! State=%p #Ops=%X\n", - walk_state, walk_state->num_operands)); + ACPI_ERROR((AE_INFO, + "Null operand! State=%p #Ops=%X", + walk_state, walk_state->num_operands)); *object = NULL; return (AE_AML_NO_OPERAND); } diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index b380ae1044b7..c9ac05c4685f 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c @@ -73,7 +73,7 @@ acpi_status acpi_ev_initialize_events(void) /* Make sure we have ACPI tables */ if (!acpi_gbl_DSDT) { - ACPI_REPORT_WARNING(("No ACPI tables present!\n")); + ACPI_WARNING((AE_INFO, "No ACPI tables present!")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -84,14 +84,15 @@ acpi_status acpi_ev_initialize_events(void) */ status = acpi_ev_fixed_event_initialize(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Unable to initialize fixed events, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to initialize fixed events")); return_ACPI_STATUS(status); } status = acpi_ev_gpe_initialize(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Unable to initialize general purpose events, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to initialize general purpose events")); return_ACPI_STATUS(status); } @@ -162,7 +163,8 @@ acpi_status acpi_ev_install_xrupt_handlers(void) status = acpi_ev_install_sci_handler(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Unable to install System Control Interrupt Handler, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to install System Control Interrupt handler")); return_ACPI_STATUS(status); } @@ -170,7 +172,8 @@ acpi_status acpi_ev_install_xrupt_handlers(void) status = acpi_ev_init_global_lock_handler(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Unable to initialize Global Lock handler, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to initialize Global Lock handler")); return_ACPI_STATUS(status); } @@ -304,7 +307,9 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) enable_register_id, 0, ACPI_MTX_DO_NOT_LOCK); - ACPI_REPORT_ERROR(("No installed handler for fixed event [%08X]\n", event)); + ACPI_ERROR((AE_INFO, + "No installed handler for fixed event [%08X]", + event)); return (ACPI_INTERRUPT_NOT_HANDLED); } diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index 353b907edbfa..f64f977dd3d5 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -379,7 +379,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) u8 enabled_status_byte; u32 status_reg; u32 enable_reg; - acpi_native_uint flags; + acpi_cpu_flags flags; acpi_native_uint i; acpi_native_uint j; @@ -546,7 +546,11 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) status = acpi_ns_evaluate_by_handle(&info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s while evaluating method [%4.4s] for GPE[%2X]\n", acpi_format_exception(status), acpi_ut_get_node_name(local_gpe_event_info.dispatch.method_node), gpe_number)); + ACPI_EXCEPTION((AE_INFO, status, + "While evaluating method [%4.4s] for GPE[%2X]", + acpi_ut_get_node_name + (local_gpe_event_info.dispatch. + method_node), gpe_number)); } } @@ -599,9 +603,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) ACPI_GPE_EDGE_TRIGGERED) { status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s, Unable to clear GPE[%2X]\n", - acpi_format_exception(status), - gpe_number)); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to clear GPE[%2X]", + gpe_number)); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } } @@ -639,7 +643,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) ACPI_GPE_LEVEL_TRIGGERED) { status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number)); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to clear GPE[%2X]", + gpe_number)); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } } @@ -653,9 +659,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) */ status = acpi_ev_disable_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s, Unable to disable GPE[%2X]\n", - acpi_format_exception(status), - gpe_number)); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to disable GPE[%2X]", + gpe_number)); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } @@ -667,7 +673,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) acpi_ev_asynch_execute_gpe_method, gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s, Unable to queue handler for GPE[%2X] - event disabled\n", acpi_format_exception(status), gpe_number)); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to queue handler for GPE[%2X] - event disabled", + gpe_number)); } break; @@ -675,7 +683,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) /* No handler or method to run! */ - ACPI_REPORT_ERROR(("No handler or method for GPE[%2X], disabling event\n", gpe_number)); + ACPI_ERROR((AE_INFO, + "No handler or method for GPE[%2X], disabling event", + gpe_number)); /* * Disable the GPE. The GPE will remain disabled until the ACPI @@ -683,9 +693,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) */ status = acpi_ev_disable_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s, Unable to disable GPE[%2X]\n", - acpi_format_exception(status), - gpe_number)); + ACPI_EXCEPTION((AE_INFO, status, + "Unable to disable GPE[%2X]", + gpe_number)); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } break; @@ -728,7 +738,9 @@ acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info) acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE); - ACPI_REPORT_INFO(("GPE %p was updated from wake/run to wake-only\n", gpe_event_info)); + ACPI_INFO((AE_INFO, + "GPE %p was updated from wake/run to wake-only", + gpe_event_info)); /* This was a wake-only GPE */ diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 3b9bbdda551d..0fd00b5ad650 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c @@ -136,7 +136,7 @@ acpi_status acpi_ev_walk_gpe_list(ACPI_GPE_CALLBACK gpe_walk_callback) struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_xrupt_info *gpe_xrupt_info; acpi_status status = AE_OK; - acpi_native_uint flags; + acpi_cpu_flags flags; ACPI_FUNCTION_TRACE("ev_walk_gpe_list"); @@ -279,7 +279,9 @@ acpi_ev_save_method_info(acpi_handle obj_handle, default: /* Unknown method type, just ignore it! */ - ACPI_REPORT_ERROR(("Unknown GPE method type: %s (name not of form _Lxx or _Exx)\n", name)); + ACPI_ERROR((AE_INFO, + "Unknown GPE method type: %s (name not of form _Lxx or _Exx)", + name)); return_ACPI_STATUS(AE_OK); } @@ -289,7 +291,9 @@ acpi_ev_save_method_info(acpi_handle obj_handle, if (gpe_number == ACPI_UINT32_MAX) { /* Conversion failed; invalid method, just ignore it */ - ACPI_REPORT_ERROR(("Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)\n", name)); + ACPI_ERROR((AE_INFO, + "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)", + name)); return_ACPI_STATUS(AE_OK); } @@ -476,7 +480,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 struct acpi_gpe_xrupt_info *next_gpe_xrupt; struct acpi_gpe_xrupt_info *gpe_xrupt; acpi_status status; - acpi_native_uint flags; + acpi_cpu_flags flags; ACPI_FUNCTION_TRACE("ev_get_gpe_xrupt_block"); @@ -523,7 +527,9 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 acpi_ev_gpe_xrupt_handler, gpe_xrupt); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not install GPE interrupt handler at level 0x%X\n", interrupt_number)); + ACPI_ERROR((AE_INFO, + "Could not install GPE interrupt handler at level 0x%X", + interrupt_number)); return_PTR(NULL); } } @@ -548,7 +554,7 @@ static acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) { acpi_status status; - acpi_native_uint flags; + acpi_cpu_flags flags; ACPI_FUNCTION_TRACE("ev_delete_gpe_xrupt"); @@ -606,7 +612,7 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, struct acpi_gpe_block_info *next_gpe_block; struct acpi_gpe_xrupt_info *gpe_xrupt_block; acpi_status status; - acpi_native_uint flags; + acpi_cpu_flags flags; ACPI_FUNCTION_TRACE("ev_install_gpe_block"); @@ -659,7 +665,7 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) { acpi_status status; - acpi_native_uint flags; + acpi_cpu_flags flags; ACPI_FUNCTION_TRACE("ev_install_gpe_block"); @@ -739,7 +745,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) sizeof(struct acpi_gpe_register_info)); if (!gpe_register_info) { - ACPI_REPORT_ERROR(("Could not allocate the gpe_register_info table\n")); + ACPI_ERROR((AE_INFO, + "Could not allocate the gpe_register_info table")); return_ACPI_STATUS(AE_NO_MEMORY); } @@ -752,7 +759,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) ACPI_GPE_REGISTER_WIDTH) * sizeof(struct acpi_gpe_event_info)); if (!gpe_event_info) { - ACPI_REPORT_ERROR(("Could not allocate the gpe_event_info table\n")); + ACPI_ERROR((AE_INFO, + "Could not allocate the gpe_event_info table")); status = AE_NO_MEMORY; goto error_exit; } @@ -1032,8 +1040,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not enable GPEs in gpe_block %p\n", - gpe_block)); + ACPI_ERROR((AE_INFO, "Could not enable GPEs in gpe_block %p", + gpe_block)); } return_ACPI_STATUS(status); @@ -1107,8 +1115,8 @@ acpi_status acpi_ev_gpe_initialize(void) &acpi_gbl_gpe_fadt_blocks[0]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not create GPE Block 0, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not create GPE Block 0")); } } @@ -1121,7 +1129,12 @@ acpi_status acpi_ev_gpe_initialize(void) if ((register_count0) && (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) { - ACPI_REPORT_ERROR(("GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n", gpe_number_max, acpi_gbl_FADT->gpe1_base, acpi_gbl_FADT->gpe1_base + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1))); + ACPI_ERROR((AE_INFO, + "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", + gpe_number_max, acpi_gbl_FADT->gpe1_base, + acpi_gbl_FADT->gpe1_base + + ((register_count1 * + ACPI_GPE_REGISTER_WIDTH) - 1))); /* Ignore GPE1 block by setting the register count to zero */ @@ -1139,7 +1152,8 @@ acpi_status acpi_ev_gpe_initialize(void) [1]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not create GPE Block 1, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not create GPE Block 1")); } /* @@ -1165,7 +1179,9 @@ acpi_status acpi_ev_gpe_initialize(void) /* Check for Max GPE number out-of-range */ if (gpe_number_max > ACPI_GPE_MAX) { - ACPI_REPORT_ERROR(("Maximum GPE number from FADT is too large: 0x%X\n", gpe_number_max)); + ACPI_ERROR((AE_INFO, + "Maximum GPE number from FADT is too large: 0x%X", + gpe_number_max)); status = AE_BAD_VALUE; goto cleanup; } diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 78883239784a..0909ba69577e 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -303,7 +303,8 @@ static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context) acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, acpi_gbl_global_lock_thread_count); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not signal Global Lock semaphore\n")); + ACPI_ERROR((AE_INFO, + "Could not signal Global Lock semaphore")); } } } @@ -344,7 +345,8 @@ static u32 acpi_ev_global_lock_handler(void *context) acpi_ev_global_lock_thread, context); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not queue Global Lock thread, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not queue Global Lock thread")); return (ACPI_INTERRUPT_NOT_HANDLED); } @@ -384,7 +386,8 @@ acpi_status acpi_ev_init_global_lock_handler(void) * with an error. */ if (status == AE_NO_HARDWARE_RESPONSE) { - ACPI_REPORT_ERROR(("No response from Global Lock hardware, disabling lock\n")); + ACPI_ERROR((AE_INFO, + "No response from Global Lock hardware, disabling lock")); acpi_gbl_global_lock_present = FALSE; status = AE_OK; @@ -480,7 +483,8 @@ acpi_status acpi_ev_release_global_lock(void) ACPI_FUNCTION_TRACE("ev_release_global_lock"); if (!acpi_gbl_global_lock_thread_count) { - ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n")); + ACPI_WARNING((AE_INFO, + "Cannot release HW Global Lock, it has not been acquired")); return_ACPI_STATUS(AE_NOT_ACQUIRED); } @@ -542,7 +546,9 @@ void acpi_ev_terminate(void) for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { status = acpi_disable_event((u32) i, 0); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not disable fixed event %d\n", (u32) i)); + ACPI_ERROR((AE_INFO, + "Could not disable fixed event %d", + (u32) i)); } } @@ -554,7 +560,7 @@ void acpi_ev_terminate(void) status = acpi_ev_remove_sci_handler(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not remove SCI handler\n")); + ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); } } @@ -567,7 +573,7 @@ void acpi_ev_terminate(void) if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) { status = acpi_disable(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_WARNING(("acpi_disable failed\n")); + ACPI_WARNING((AE_INFO, "acpi_disable failed")); } } return_VOID; diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index 900e5b32e595..6da58e776413 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -295,11 +295,12 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, handler_desc = region_obj->region.handler; if (!handler_desc) { - ACPI_REPORT_ERROR(("No handler for Region [%4.4s] (%p) [%s]\n", - acpi_ut_get_node_name(region_obj->region. - node), region_obj, - acpi_ut_get_region_name(region_obj->region. - space_id))); + ACPI_ERROR((AE_INFO, + "No handler for Region [%4.4s] (%p) [%s]", + acpi_ut_get_node_name(region_obj->region.node), + region_obj, + acpi_ut_get_region_name(region_obj->region. + space_id))); return_ACPI_STATUS(AE_NOT_EXIST); } @@ -316,7 +317,11 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, if (!region_setup) { /* No initialization routine, exit with error */ - ACPI_REPORT_ERROR(("No init routine for region(%p) [%s]\n", region_obj, acpi_ut_get_region_name(region_obj->region.space_id))); + ACPI_ERROR((AE_INFO, + "No init routine for region(%p) [%s]", + region_obj, + acpi_ut_get_region_name(region_obj->region. + space_id))); return_ACPI_STATUS(AE_NOT_EXIST); } @@ -341,11 +346,11 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, /* Check for failure of the Region Setup */ if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Region Initialization: %s [%s]\n", - acpi_format_exception(status), - acpi_ut_get_region_name(region_obj-> - region. - space_id))); + ACPI_EXCEPTION((AE_INFO, status, + "During region initialization: [%s]", + acpi_ut_get_region_name(region_obj-> + region. + space_id))); return_ACPI_STATUS(status); } @@ -399,10 +404,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, region_obj2->extra.region_context); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Handler for [%s] returned %s\n", - acpi_ut_get_region_name(region_obj->region. - space_id), - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", + acpi_ut_get_region_name(region_obj->region. + space_id))); } if (! @@ -494,7 +498,10 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, status = acpi_ev_execute_reg_method(region_obj, 0); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s from region _REG, [%s]\n", acpi_format_exception(status), acpi_ut_get_region_name(region_obj->region.space_id))); + ACPI_EXCEPTION((AE_INFO, status, + "from region _REG, [%s]", + acpi_ut_get_region_name + (region_obj->region.space_id))); } if (acpi_ns_is_locked) { @@ -516,7 +523,10 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, /* Init routine may fail, Just ignore errors */ if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s from region init, [%s]\n", acpi_format_exception(status), acpi_ut_get_region_name(region_obj->region.space_id))); + ACPI_EXCEPTION((AE_INFO, status, + "from region init, [%s]", + acpi_ut_get_region_name + (region_obj->region.space_id))); } region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE); diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index de1a38e9ce22..baed8c1a1b9f 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c @@ -233,7 +233,11 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, */ status = AE_OK; } else { - ACPI_REPORT_ERROR(("Could not install pci_config handler for Root Bridge %4.4s, %s\n", acpi_ut_get_node_name(pci_root_node), acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, + status, + "Could not install pci_config handler for Root Bridge %4.4s", + acpi_ut_get_node_name + (pci_root_node))); } } break; diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index b2f69b1ac4b5..b38b39dde543 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c @@ -143,8 +143,8 @@ acpi_install_fixed_event_handler(u32 event, if (ACPI_SUCCESS(status)) status = acpi_enable_event(event, 0); if (ACPI_FAILURE(status)) { - ACPI_REPORT_WARNING(("Could not enable fixed event %X\n", - event)); + ACPI_WARNING((AE_INFO, "Could not enable fixed event %X", + event)); /* Remove the handler */ @@ -204,7 +204,9 @@ acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) acpi_gbl_fixed_event_handlers[event].context = NULL; if (ACPI_FAILURE(status)) { - ACPI_REPORT_WARNING(("Could not write to fixed event enable register %X\n", event)); + ACPI_WARNING((AE_INFO, + "Could not write to fixed event enable register %X", + event)); } else { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n", event)); @@ -561,7 +563,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, struct acpi_gpe_event_info *gpe_event_info; struct acpi_handler_info *handler; acpi_status status; - acpi_native_uint flags; + acpi_cpu_flags flags; ACPI_FUNCTION_TRACE("acpi_install_gpe_handler"); @@ -652,7 +654,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, struct acpi_gpe_event_info *gpe_event_info; struct acpi_handler_info *handler; acpi_status status; - acpi_native_uint flags; + acpi_cpu_flags flags; ACPI_FUNCTION_TRACE("acpi_remove_gpe_handler"); diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 90eb7939e986..ec9ce8429f15 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -70,7 +70,7 @@ acpi_status acpi_enable(void) /* Make sure we have the FADT */ if (!acpi_gbl_FADT) { - ACPI_REPORT_WARNING(("No FADT information present!\n")); + ACPI_WARNING((AE_INFO, "No FADT information present!")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -82,7 +82,8 @@ acpi_status acpi_enable(void) status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not transition to ACPI mode\n")); + ACPI_ERROR((AE_INFO, + "Could not transition to ACPI mode")); return_ACPI_STATUS(status); } @@ -112,7 +113,7 @@ acpi_status acpi_disable(void) ACPI_FUNCTION_TRACE("acpi_disable"); if (!acpi_gbl_FADT) { - ACPI_REPORT_WARNING(("No FADT information present!\n")); + ACPI_WARNING((AE_INFO, "No FADT information present!")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -125,7 +126,8 @@ acpi_status acpi_disable(void) status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not exit ACPI mode to legacy mode")); + ACPI_ERROR((AE_INFO, + "Could not exit ACPI mode to legacy mode")); return_ACPI_STATUS(status); } @@ -182,8 +184,9 @@ acpi_status acpi_enable_event(u32 event, u32 flags) } if (value != 1) { - ACPI_REPORT_ERROR(("Could not enable %s event\n", - acpi_ut_get_event_name(event))); + ACPI_ERROR((AE_INFO, + "Could not enable %s event", + acpi_ut_get_event_name(event))); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } @@ -380,8 +383,9 @@ acpi_status acpi_disable_event(u32 event, u32 flags) } if (value != 0) { - ACPI_REPORT_ERROR(("Could not disable %s events\n", - acpi_ut_get_event_name(event))); + ACPI_ERROR((AE_INFO, + "Could not disable %s events", + acpi_ut_get_event_name(event))); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 109d0255a5bb..a29782fe3ecf 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -413,7 +413,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, (!ACPI_STRNCMP(table_ptr->signature, acpi_gbl_table_data[ACPI_TABLE_SSDT].signature, acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) { - ACPI_REPORT_ERROR(("Table has invalid signature [%4.4s], must be SSDT or PSDT\n", table_ptr->signature)); + ACPI_ERROR((AE_INFO, + "Table has invalid signature [%4.4s], must be SSDT or PSDT", + table_ptr->signature)); status = AE_BAD_SIGNATURE; goto cleanup; } diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index e6f55cf8ad31..e6d52e12d77a 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c @@ -641,7 +641,9 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, break; default: - ACPI_REPORT_ERROR(("Bad destination type during conversion: %X\n", destination_type)); + ACPI_ERROR((AE_INFO, + "Bad destination type during conversion: %X", + destination_type)); status = AE_AML_INTERNAL; break; } @@ -654,7 +656,12 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, break; default: - ACPI_REPORT_ERROR(("Unknown Target type ID 0x%X aml_opcode %X dest_type %s\n", GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args), walk_state->opcode, acpi_ut_get_type_name(destination_type))); + ACPI_ERROR((AE_INFO, + "Unknown Target type ID 0x%X aml_opcode %X dest_type %s", + GET_CURRENT_ARG_TYPE(walk_state->op_info-> + runtime_args), + walk_state->opcode, + acpi_ut_get_type_name(destination_type))); status = AE_AML_INTERNAL; } diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index da313dad576a..680575402835 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c @@ -300,8 +300,8 @@ acpi_ex_create_region(u8 * aml_start, */ if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && (region_space < ACPI_USER_REGION_BEGIN)) { - ACPI_REPORT_ERROR(("Invalid address_space type %X\n", - region_space)); + ACPI_ERROR((AE_INFO, "Invalid address_space type %X", + region_space)); return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); } diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c index 78a76f91a1c9..e259201ce9a0 100644 --- a/drivers/acpi/executer/exfield.c +++ b/drivers/acpi/executer/exfield.c @@ -249,13 +249,18 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE). */ if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) { - ACPI_REPORT_ERROR(("SMBus write requires Buffer, found type %s\n", acpi_ut_get_object_type_name(source_desc))); + ACPI_ERROR((AE_INFO, + "SMBus write requires Buffer, found type %s", + acpi_ut_get_object_type_name(source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) { - ACPI_REPORT_ERROR(("SMBus write requires Buffer of length %X, found length %X\n", ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length)); + ACPI_ERROR((AE_INFO, + "SMBus write requires Buffer of length %X, found length %X", + ACPI_SMBUS_BUFFER_SIZE, + source_desc->buffer.length)); return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); } diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 9fe27fd04a2f..bd1af35f7fcf 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c @@ -94,9 +94,9 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, /* We must have a valid region */ if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) { - ACPI_REPORT_ERROR(("Needed Region, found type %X (%s)\n", - ACPI_GET_OBJECT_TYPE(rgn_desc), - acpi_ut_get_object_type_name(rgn_desc))); + ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)", + ACPI_GET_OBJECT_TYPE(rgn_desc), + acpi_ut_get_object_type_name(rgn_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -161,14 +161,28 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, * than the region itself. For example, a region of length one * byte, and a field with Dword access specified. */ - ACPI_REPORT_ERROR(("Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n", acpi_ut_get_node_name(obj_desc->common_field.node), obj_desc->common_field.access_byte_width, acpi_ut_get_node_name(rgn_desc->region.node), rgn_desc->region.length)); + ACPI_ERROR((AE_INFO, + "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)", + acpi_ut_get_node_name(obj_desc-> + common_field.node), + obj_desc->common_field.access_byte_width, + acpi_ut_get_node_name(rgn_desc->region. + node), + rgn_desc->region.length)); } /* * Offset rounded up to next multiple of field width * exceeds region length, indicate an error */ - ACPI_REPORT_ERROR(("Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n", acpi_ut_get_node_name(obj_desc->common_field.node), obj_desc->common_field.base_byte_offset, field_datum_byte_offset, obj_desc->common_field.access_byte_width, acpi_ut_get_node_name(rgn_desc->region.node), rgn_desc->region.length)); + ACPI_ERROR((AE_INFO, + "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)", + acpi_ut_get_node_name(obj_desc->common_field.node), + obj_desc->common_field.base_byte_offset, + field_datum_byte_offset, + obj_desc->common_field.access_byte_width, + acpi_ut_get_node_name(rgn_desc->region.node), + rgn_desc->region.length)); return_ACPI_STATUS(AE_AML_REGION_LIMIT); } @@ -252,17 +266,17 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, if (ACPI_FAILURE(status)) { if (status == AE_NOT_IMPLEMENTED) { - ACPI_REPORT_ERROR(("Region %s(%X) not implemented\n", - acpi_ut_get_region_name(rgn_desc-> - region. - space_id), - rgn_desc->region.space_id)); + ACPI_ERROR((AE_INFO, + "Region %s(%X) not implemented", + acpi_ut_get_region_name(rgn_desc->region. + space_id), + rgn_desc->region.space_id)); } else if (status == AE_NOT_EXIST) { - ACPI_REPORT_ERROR(("Region %s(%X) has no handler\n", - acpi_ut_get_region_name(rgn_desc-> - region. - space_id), - rgn_desc->region.space_id)); + ACPI_ERROR((AE_INFO, + "Region %s(%X) has no handler", + acpi_ut_get_region_name(rgn_desc->region. + space_id), + rgn_desc->region.space_id)); } } @@ -495,8 +509,8 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, default: - ACPI_REPORT_ERROR(("Wrong object type in field I/O %X\n", - ACPI_GET_OBJECT_TYPE(obj_desc))); + ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X", + ACPI_GET_OBJECT_TYPE(obj_desc))); status = AE_AML_INTERNAL; break; } @@ -599,10 +613,11 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, default: - ACPI_REPORT_ERROR(("Unknown update_rule value: %X\n", - (obj_desc->common_field. - field_flags & - AML_FIELD_UPDATE_RULE_MASK))); + ACPI_ERROR((AE_INFO, + "Unknown update_rule value: %X", + (obj_desc->common_field. + field_flags & + AML_FIELD_UPDATE_RULE_MASK))); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } } @@ -657,7 +672,9 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { - ACPI_REPORT_ERROR(("Field size %X (bits) is too large for buffer (%X)\n", obj_desc->common_field.bit_length, buffer_length)); + ACPI_ERROR((AE_INFO, + "Field size %X (bits) is too large for buffer (%X)", + obj_desc->common_field.bit_length, buffer_length)); return_ACPI_STATUS(AE_BUFFER_OVERFLOW); } @@ -769,7 +786,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { - ACPI_REPORT_ERROR(("Field size %X (bits) is too large for buffer (%X)\n", obj_desc->common_field.bit_length, buffer_length)); + ACPI_ERROR((AE_INFO, + "Field size %X (bits) is too large for buffer (%X)", + obj_desc->common_field.bit_length, buffer_length)); return_ACPI_STATUS(AE_BUFFER_OVERFLOW); } diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 5ad34566738c..48c18d29222a 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -98,8 +98,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, default: - ACPI_REPORT_ERROR(("Unknown Reference opcode %X\n", - obj_desc->reference.opcode)); + ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", + obj_desc->reference.opcode)); return_ACPI_STATUS(AE_AML_INTERNAL); } break; @@ -114,8 +114,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, default: - ACPI_REPORT_ERROR(("Invalid descriptor type %X\n", - ACPI_GET_DESCRIPTOR_TYPE(obj_desc))); + ACPI_ERROR((AE_INFO, "Invalid descriptor type %X", + ACPI_GET_DESCRIPTOR_TYPE(obj_desc))); return_ACPI_STATUS(AE_TYPE); } @@ -166,15 +166,18 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, u8 *end_tag; acpi_size length0; acpi_size length1; + acpi_size new_length; ACPI_FUNCTION_TRACE("ex_concat_template"); /* * Find the end_tag descriptor in each resource template. - * Note: returned pointers point TO the end_tag, not past it. - * - * Compute the length of each resource template + * Note1: returned pointers point TO the end_tag, not past it. + * Note2: zero-length buffers are allowed; treated like one end_tag */ + + /* Get the length of the first resource template */ + status = acpi_ut_get_resource_end_tag(operand0, &end_tag); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -182,19 +185,22 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer); + /* Get the length of the second resource template */ + status = acpi_ut_get_resource_end_tag(operand1, &end_tag); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* Include the end_tag in the second template length */ + length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer); - length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer) + - sizeof(struct aml_resource_end_tag); + /* Combine both lengths, minimum size will be 2 for end_tag */ - /* Create a new buffer object for the result */ + new_length = length0 + length1 + sizeof(struct aml_resource_end_tag); - return_desc = acpi_ut_create_buffer_object(length0 + length1); + /* Create a new buffer object for the result (with one end_tag) */ + + return_desc = acpi_ut_create_buffer_object(new_length); if (!return_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -207,9 +213,10 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0); ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1); - /* Set the end_tag checksum to zero, means "ignore checksum" */ + /* Insert end_tag and set the checksum to zero, means "ignore checksum" */ - new_buf[return_desc->buffer.length - 1] = 0; + new_buf[new_length - 1] = 0; + new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1; /* Return the completed resource template */ @@ -268,8 +275,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, break; default: - ACPI_REPORT_ERROR(("Invalid object type: %X\n", - ACPI_GET_OBJECT_TYPE(operand0))); + ACPI_ERROR((AE_INFO, "Invalid object type: %X", + ACPI_GET_OBJECT_TYPE(operand0))); status = AE_AML_INTERNAL; } @@ -370,8 +377,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, /* Invalid object type, should not happen here */ - ACPI_REPORT_ERROR(("Invalid object type: %X\n", - ACPI_GET_OBJECT_TYPE(operand0))); + ACPI_ERROR((AE_INFO, "Invalid object type: %X", + ACPI_GET_OBJECT_TYPE(operand0))); status = AE_AML_INTERNAL; goto cleanup; } diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c index 89b8ab79410b..f843b22e20b9 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/executer/exmutex.c @@ -153,7 +153,9 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Sanity check -- we must have a valid thread ID */ if (!walk_state->thread) { - ACPI_REPORT_ERROR(("Cannot acquire Mutex [%4.4s], null thread info\n", acpi_ut_get_node_name(obj_desc->mutex.node))); + ACPI_ERROR((AE_INFO, + "Cannot acquire Mutex [%4.4s], null thread info", + acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -162,7 +164,9 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, * mutex. This mechanism provides some deadlock prevention */ if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { - ACPI_REPORT_ERROR(("Cannot acquire Mutex [%4.4s], incorrect sync_level\n", acpi_ut_get_node_name(obj_desc->mutex.node))); + ACPI_ERROR((AE_INFO, + "Cannot acquire Mutex [%4.4s], incorrect sync_level", + acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_MUTEX_ORDER); } @@ -237,14 +241,18 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, /* The mutex must have been previously acquired in order to release it */ if (!obj_desc->mutex.owner_thread) { - ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], not acquired\n", acpi_ut_get_node_name(obj_desc->mutex.node))); + ACPI_ERROR((AE_INFO, + "Cannot release Mutex [%4.4s], not acquired", + acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); } /* Sanity check -- we must have a valid thread ID */ if (!walk_state->thread) { - ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], null thread info\n", acpi_ut_get_node_name(obj_desc->mutex.node))); + ACPI_ERROR((AE_INFO, + "Cannot release Mutex [%4.4s], null thread info", + acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -255,7 +263,11 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) && (obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) { - ACPI_REPORT_ERROR(("Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", walk_state->thread->thread_id, acpi_ut_get_node_name(obj_desc->mutex.node), obj_desc->mutex.owner_thread->thread_id)); + ACPI_ERROR((AE_INFO, + "Thread %X cannot release Mutex [%4.4s] acquired by thread %X", + walk_state->thread->thread_id, + acpi_ut_get_node_name(obj_desc->mutex.node), + obj_desc->mutex.owner_thread->thread_id)); return_ACPI_STATUS(AE_AML_NOT_OWNER); } @@ -264,7 +276,9 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, * equal to the current sync level */ if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { - ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], incorrect sync_level\n", acpi_ut_get_node_name(obj_desc->mutex.node))); + ACPI_ERROR((AE_INFO, + "Cannot release Mutex [%4.4s], incorrect sync_level", + acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_MUTEX_ORDER); } diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c index de3216b6a4fc..054fe5e1a314 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/executer/exnames.c @@ -99,8 +99,8 @@ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs) */ name_string = ACPI_MEM_ALLOCATE(size_needed); if (!name_string) { - ACPI_REPORT_ERROR(("Could not allocate size %d\n", - size_needed)); + ACPI_ERROR((AE_INFO, + "Could not allocate size %d", size_needed)); return_PTR(NULL); } @@ -168,7 +168,7 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) char_buf[0] = *aml_address; if ('0' <= char_buf[0] && char_buf[0] <= '9') { - ACPI_REPORT_ERROR(("Invalid leading digit: %c\n", char_buf[0])); + ACPI_ERROR((AE_INFO, "Invalid leading digit: %c", char_buf[0])); return_ACPI_STATUS(AE_CTRL_PENDING); } @@ -211,8 +211,9 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) * the required 4 */ status = AE_AML_BAD_NAME; - ACPI_REPORT_ERROR(("Bad character %02x in name, at %p\n", - *aml_address, aml_address)); + ACPI_ERROR((AE_INFO, + "Bad character %02x in name, at %p", + *aml_address, aml_address)); } *in_aml_address = ACPI_CAST_PTR(u8, aml_address); @@ -411,7 +412,7 @@ acpi_ex_get_name_string(acpi_object_type data_type, if (AE_CTRL_PENDING == status && has_prefix) { /* Ran out of segments after processing a prefix */ - ACPI_REPORT_ERROR(("Malformed Name at %p\n", name_string)); + ACPI_ERROR((AE_INFO, "Malformed Name at %p", name_string)); status = AE_AML_BAD_NAME; } diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index bc8837ecb716..23d0823bcd5e 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c @@ -111,8 +111,8 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) default: /* Unknown opcode */ - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; break; } @@ -189,8 +189,8 @@ acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state) default: /* Unknown opcode */ - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; break; } @@ -229,8 +229,8 @@ acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state) default: /* Unknown opcode */ - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -349,7 +349,9 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* Check the range of the digit */ if (temp32 > 9) { - ACPI_REPORT_ERROR(("BCD digit too large (not decimal): 0x%X\n", temp32)); + ACPI_ERROR((AE_INFO, + "BCD digit too large (not decimal): 0x%X", + temp32)); status = AE_AML_NUMERIC_OVERFLOW; goto cleanup; @@ -394,7 +396,10 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* Overflow if there is any data left in Digit */ if (digit > 0) { - ACPI_REPORT_ERROR(("Integer too large to convert to BCD: %8.8X%8.8X\n", ACPI_FORMAT_UINT64(operand[0]->integer.value))); + ACPI_ERROR((AE_INFO, + "Integer too large to convert to BCD: %8.8X%8.8X", + ACPI_FORMAT_UINT64(operand[0]-> + integer.value))); status = AE_AML_NUMERIC_OVERFLOW; goto cleanup; } @@ -521,16 +526,16 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* These are two obsolete opcodes */ - ACPI_REPORT_ERROR(("%s is obsolete and not implemented\n", - acpi_ps_get_opcode_name(walk_state-> - opcode))); + ACPI_ERROR((AE_INFO, + "%s is obsolete and not implemented", + acpi_ps_get_opcode_name(walk_state->opcode))); status = AE_SUPPORT; goto cleanup; default: /* Unknown opcode */ - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -636,10 +641,10 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) acpi_ex_resolve_operands(AML_LNOT_OP, &temp_desc, walk_state); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s: bad operand(s) %s\n", - acpi_ps_get_opcode_name(walk_state-> - opcode), - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "While resolving operands for [%s]", + acpi_ps_get_opcode_name(walk_state-> + opcode))); goto cleanup; } @@ -738,7 +743,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) break; default: - ACPI_REPORT_ERROR(("Operand is not Buf/Int/Str/Pkg - found type %s\n", acpi_ut_get_type_name(type))); + ACPI_ERROR((AE_INFO, + "Operand is not Buf/Int/Str/Pkg - found type %s", + acpi_ut_get_type_name(type))); status = AE_AML_OPERAND_TYPE; goto cleanup; } @@ -935,7 +942,10 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unknown Index target_type %X in obj %p\n", operand[0]->reference.target_type, operand[0])); + ACPI_ERROR((AE_INFO, + "Unknown Index target_type %X in obj %p", + operand[0]->reference. + target_type, operand[0])); status = AE_AML_OPERAND_TYPE; goto cleanup; } @@ -961,7 +971,10 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) break; default: - ACPI_REPORT_ERROR(("Unknown opcode in ref(%p) - %X\n", operand[0], operand[0]->reference.opcode)); + ACPI_ERROR((AE_INFO, + "Unknown opcode in ref(%p) - %X", + operand[0], + operand[0]->reference.opcode)); status = AE_TYPE; goto cleanup; @@ -971,8 +984,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 7c59dda40946..e263a5ddd405 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c @@ -111,7 +111,9 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) /* Are notifies allowed on this object? */ if (!acpi_ev_is_notify_object(node)) { - ACPI_REPORT_ERROR(("Unexpected notify object type [%s]\n", acpi_ut_get_type_name(node->type))); + ACPI_ERROR((AE_INFO, + "Unexpected notify object type [%s]", + acpi_ut_get_type_name(node->type))); status = AE_AML_OPERAND_TYPE; break; @@ -155,8 +157,8 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; } @@ -220,8 +222,8 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -389,7 +391,10 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) /* Object to be indexed is a Package */ if (index >= operand[0]->package.count) { - ACPI_REPORT_ERROR(("Index value (%X%8.8X) beyond package end (%X)\n", ACPI_FORMAT_UINT64(index), operand[0]->package.count)); + ACPI_ERROR((AE_INFO, + "Index value (%X%8.8X) beyond package end (%X)", + ACPI_FORMAT_UINT64(index), + operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; goto cleanup; } @@ -402,7 +407,10 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) /* Object to be indexed is a Buffer/String */ if (index >= operand[0]->buffer.length) { - ACPI_REPORT_ERROR(("Index value (%X%8.8X) beyond end of buffer (%X)\n", ACPI_FORMAT_UINT64(index), operand[0]->buffer.length)); + ACPI_ERROR((AE_INFO, + "Index value (%X%8.8X) beyond end of buffer (%X)", + ACPI_FORMAT_UINT64(index), + operand[0]->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; } @@ -434,8 +442,8 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; break; } @@ -539,8 +547,8 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c index a979b338a491..6a3a883cb8a3 100644 --- a/drivers/acpi/executer/exoparg3.c +++ b/drivers/acpi/executer/exoparg3.c @@ -119,8 +119,8 @@ acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -243,8 +243,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) default: - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c index 05e7f9b67f29..e043d924444f 100644 --- a/drivers/acpi/executer/exoparg6.c +++ b/drivers/acpi/executer/exoparg6.c @@ -234,7 +234,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) || (operand[3]->integer.value > MAX_MATCH_OPERATOR)) { - ACPI_REPORT_ERROR(("Match operator out of range\n")); + ACPI_ERROR((AE_INFO, "Match operator out of range")); status = AE_AML_OPERAND_VALUE; goto cleanup; } @@ -243,7 +243,10 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) index = operand[5]->integer.value; if (index >= operand[0]->package.count) { - ACPI_REPORT_ERROR(("Index (%X%8.8X) beyond package end (%X)\n", ACPI_FORMAT_UINT64(index), operand[0]->package.count)); + ACPI_ERROR((AE_INFO, + "Index (%X%8.8X) beyond package end (%X)", + ACPI_FORMAT_UINT64(index), + operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; goto cleanup; } @@ -312,8 +315,8 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) default: - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", - walk_state->opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", + walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index 3bde780c94cf..7719ae5d4f16 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c @@ -274,7 +274,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, default: /* Invalid field access type */ - ACPI_REPORT_ERROR(("Unknown field access type %X\n", access)); + ACPI_ERROR((AE_INFO, "Unknown field access type %X", access)); return_UINT32(0); } @@ -421,13 +421,15 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) { if (!info->region_node) { - ACPI_REPORT_ERROR(("Null region_node\n")); + ACPI_ERROR((AE_INFO, "Null region_node")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } type = acpi_ns_get_type(info->region_node); if (type != ACPI_TYPE_REGION) { - ACPI_REPORT_ERROR(("Needed Region, found type %X (%s)\n", type, acpi_ut_get_type_name(type))); + ACPI_ERROR((AE_INFO, + "Needed Region, found type %X (%s)", + type, acpi_ut_get_type_name(type))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -496,17 +498,17 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) case ACPI_TYPE_LOCAL_INDEX_FIELD: + /* Get the Index and Data registers */ + obj_desc->index_field.index_obj = acpi_ns_get_attached_object(info->register_node); obj_desc->index_field.data_obj = acpi_ns_get_attached_object(info->data_register_node); - obj_desc->index_field.value = (u32) - (info->field_bit_position / - ACPI_MUL_8(obj_desc->field.access_byte_width)); if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) { - ACPI_REPORT_ERROR(("Null Index Object during field prep\n")); + ACPI_ERROR((AE_INFO, + "Null Index Object during field prep")); acpi_ut_delete_object_desc(obj_desc); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -516,6 +518,15 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) acpi_ut_add_reference(obj_desc->index_field.data_obj); acpi_ut_add_reference(obj_desc->index_field.index_obj); + /* + * The value written to the Index register is the byte offset of the + * target field + * Note: may change code to: ACPI_DIV_8 (Info->field_bit_position) + */ + obj_desc->index_field.value = (u32) + (info->field_bit_position / + ACPI_MUL_8(obj_desc->field.access_byte_width)); + ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n", obj_desc->index_field.start_field_bit_offset, diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 82983575cca6..6a4cfdff606d 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c @@ -103,8 +103,8 @@ acpi_ex_system_memory_space_handler(u32 function, break; default: - ACPI_REPORT_ERROR(("Invalid system_memory width %d\n", - bit_width)); + ACPI_ERROR((AE_INFO, "Invalid system_memory width %d", + bit_width)); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } @@ -158,7 +158,10 @@ acpi_ex_system_memory_space_handler(u32 function, (void **)&mem_info-> mapped_logical_address); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not map memory at %8.8X%8.8X, size %X\n", ACPI_FORMAT_UINT64(address), (u32) window_size)); + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X%8.8X, size %X", + ACPI_FORMAT_UINT64(address), + (u32) window_size)); mem_info->mapped_length = 0; return_ACPI_STATUS(status); } diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c index a5cca7eda210..01b26c80d22b 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/executer/exresnte.c @@ -122,7 +122,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, } if (!source_desc) { - ACPI_REPORT_ERROR(("No object attached to node %p\n", node)); + ACPI_ERROR((AE_INFO, "No object attached to node %p", node)); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -134,9 +134,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_PACKAGE: if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) { - ACPI_REPORT_ERROR(("Object not a Package, type %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_ERROR((AE_INFO, "Object not a Package, type %s", + acpi_ut_get_object_type_name(source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -152,9 +151,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_BUFFER: if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) { - ACPI_REPORT_ERROR(("Object not a Buffer, type %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s", + acpi_ut_get_object_type_name(source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -170,9 +168,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_STRING: if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) { - ACPI_REPORT_ERROR(("Object not a String, type %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_ERROR((AE_INFO, "Object not a String, type %s", + acpi_ut_get_object_type_name(source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -185,9 +182,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_INTEGER: if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) { - ACPI_REPORT_ERROR(("Object not a Integer, type %s\n", - acpi_ut_get_object_type_name - (source_desc))); + ACPI_ERROR((AE_INFO, "Object not a Integer, type %s", + acpi_ut_get_object_type_name(source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -231,8 +227,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_ANY: - ACPI_REPORT_ERROR(("Untyped entry %p, no attached object!\n", - node)); + ACPI_ERROR((AE_INFO, + "Untyped entry %p, no attached object!", node)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */ @@ -251,7 +247,11 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, default: /* No named references are allowed here */ - ACPI_REPORT_ERROR(("Unsupported Reference opcode %X (%s)\n", source_desc->reference.opcode, acpi_ps_get_opcode_name(source_desc->reference.opcode))); + ACPI_ERROR((AE_INFO, + "Unsupported Reference opcode %X (%s)", + source_desc->reference.opcode, + acpi_ps_get_opcode_name(source_desc-> + reference.opcode))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -261,8 +261,9 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, /* Default case is for unknown types */ - ACPI_REPORT_ERROR(("Node %p - Unknown object type %X\n", - node, entry_type)); + ACPI_ERROR((AE_INFO, + "Node %p - Unknown object type %X", + node, entry_type)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index ae2d2da00844..1deed492fe88 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c @@ -81,7 +81,7 @@ acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr, ACPI_FUNCTION_TRACE_PTR("ex_resolve_to_value", stack_ptr); if (!stack_ptr || !*stack_ptr) { - ACPI_REPORT_ERROR(("Internal - null pointer\n")); + ACPI_ERROR((AE_INFO, "Internal - null pointer")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -97,7 +97,7 @@ acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr, } if (!*stack_ptr) { - ACPI_REPORT_ERROR(("Internal - null pointer\n")); + ACPI_ERROR((AE_INFO, "Internal - null pointer")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } } @@ -227,7 +227,9 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, * A NULL object descriptor means an unitialized element of * the package, can't dereference it */ - ACPI_REPORT_ERROR(("Attempt to deref an Index to NULL pkg element Idx=%p\n", stack_desc)); + ACPI_ERROR((AE_INFO, + "Attempt to deref an Index to NULL pkg element Idx=%p", + stack_desc)); status = AE_AML_UNINITIALIZED_ELEMENT; } break; @@ -236,7 +238,10 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, /* Invalid reference object */ - ACPI_REPORT_ERROR(("Unknown target_type %X in Index/Reference obj %p\n", stack_desc->reference.target_type, stack_desc)); + ACPI_ERROR((AE_INFO, + "Unknown target_type %X in Index/Reference obj %p", + stack_desc->reference.target_type, + stack_desc)); status = AE_AML_INTERNAL; break; } @@ -261,7 +266,10 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, default: - ACPI_REPORT_ERROR(("Unknown Reference opcode %X (%s) in %p\n", opcode, acpi_ps_get_opcode_name(opcode), stack_desc)); + ACPI_ERROR((AE_INFO, + "Unknown Reference opcode %X (%s) in %p", + opcode, acpi_ps_get_opcode_name(opcode), + stack_desc)); status = AE_AML_INTERNAL; break; } @@ -383,10 +391,9 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { - ACPI_REPORT_ERROR(("Not a NS node %p [%s]\n", - node, - acpi_ut_get_descriptor_name - (node))); + ACPI_ERROR((AE_INFO, "Not a NS node %p [%s]", + node, + acpi_ut_get_descriptor_name(node))); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -442,10 +449,9 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { - ACPI_REPORT_ERROR(("Not a NS node %p [%s]\n", - node, - acpi_ut_get_descriptor_name - (node))); + ACPI_ERROR((AE_INFO, "Not a NS node %p [%s]", + node, + acpi_ut_get_descriptor_name(node))); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -514,8 +520,9 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, default: - ACPI_REPORT_ERROR(("Unknown Reference subtype %X\n", - obj_desc->reference.opcode)); + ACPI_ERROR((AE_INFO, + "Unknown Reference subtype %X", + obj_desc->reference.opcode)); return_ACPI_STATUS(AE_AML_INTERNAL); } } diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index 804faebf825c..a1c000f5a415 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c @@ -46,6 +46,7 @@ #include #include #include +#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exresop") @@ -95,9 +96,10 @@ acpi_ex_check_object_type(acpi_object_type type_needed, } if (type_needed != this_type) { - ACPI_REPORT_ERROR(("Needed type [%s], found [%s] %p\n", - acpi_ut_get_type_name(type_needed), - acpi_ut_get_type_name(this_type), object)); + ACPI_ERROR((AE_INFO, + "Needed type [%s], found [%s] %p", + acpi_ut_get_type_name(type_needed), + acpi_ut_get_type_name(this_type), object)); return (AE_AML_OPERAND_TYPE); } @@ -150,7 +152,7 @@ acpi_ex_resolve_operands(u16 opcode, arg_types = op_info->runtime_args; if (arg_types == ARGI_INVALID_OPCODE) { - ACPI_REPORT_ERROR(("Unknown AML opcode %X\n", opcode)); + ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", opcode)); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -168,8 +170,8 @@ acpi_ex_resolve_operands(u16 opcode, */ while (GET_CURRENT_ARG_TYPE(arg_types)) { if (!stack_ptr || !*stack_ptr) { - ACPI_REPORT_ERROR(("Null stack entry at %p\n", - stack_ptr)); + ACPI_ERROR((AE_INFO, "Null stack entry at %p", + stack_ptr)); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -187,6 +189,22 @@ acpi_ex_resolve_operands(u16 opcode, object_type = ((struct acpi_namespace_node *)obj_desc)->type; + + /* + * Resolve an alias object. The construction of these objects + * guarantees that there is only one level of alias indirection; + * thus, the attached object is always the aliased namespace node + */ + if (object_type == ACPI_TYPE_LOCAL_ALIAS) { + obj_desc = + acpi_ns_get_attached_object((struct + acpi_namespace_node + *)obj_desc); + *stack_ptr = obj_desc; + object_type = + ((struct acpi_namespace_node *)obj_desc)-> + type; + } break; case ACPI_DESC_TYPE_OPERAND: @@ -198,7 +216,9 @@ acpi_ex_resolve_operands(u16 opcode, /* Check for bad acpi_object_type */ if (!acpi_ut_valid_object_type(object_type)) { - ACPI_REPORT_ERROR(("Bad operand object type [%X]\n", object_type)); + ACPI_ERROR((AE_INFO, + "Bad operand object type [%X]", + object_type)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -236,7 +256,10 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_REPORT_ERROR(("Operand is a Reference, Unknown Reference Opcode: %X\n", obj_desc->reference.opcode)); + ACPI_ERROR((AE_INFO, + "Operand is a Reference, Unknown Reference Opcode: %X", + obj_desc->reference. + opcode)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -247,10 +270,10 @@ acpi_ex_resolve_operands(u16 opcode, /* Invalid descriptor */ - ACPI_REPORT_ERROR(("Invalid descriptor %p [%s]\n", - obj_desc, - acpi_ut_get_descriptor_name - (obj_desc))); + ACPI_ERROR((AE_INFO, + "Invalid descriptor %p [%s]", + obj_desc, + acpi_ut_get_descriptor_name(obj_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -408,7 +431,10 @@ acpi_ex_resolve_operands(u16 opcode, acpi_ex_convert_to_integer(obj_desc, stack_ptr, 16); if (ACPI_FAILURE(status)) { if (status == AE_TYPE) { - ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed [Integer/String/Buffer], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -431,7 +457,10 @@ acpi_ex_resolve_operands(u16 opcode, status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr); if (ACPI_FAILURE(status)) { if (status == AE_TYPE) { - ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed [Integer/String/Buffer], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -455,7 +484,10 @@ acpi_ex_resolve_operands(u16 opcode, ACPI_IMPLICIT_CONVERT_HEX); if (ACPI_FAILURE(status)) { if (status == AE_TYPE) { - ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed [Integer/String/Buffer], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -481,7 +513,10 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed [Integer/String/Buffer], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -515,7 +550,10 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_REPORT_ERROR(("Needed [Integer/String/Buffer], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed [Integer/String/Buffer], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -539,7 +577,10 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_REPORT_ERROR(("Needed [Buffer/String/Package/Reference], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed [Buffer/String/Package/Reference], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -558,7 +599,10 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_REPORT_ERROR(("Needed [Buffer/String/Package], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed [Buffer/String/Package], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -578,7 +622,10 @@ acpi_ex_resolve_operands(u16 opcode, break; default: - ACPI_REPORT_ERROR(("Needed [Region/region_field], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed [Region/region_field], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -620,7 +667,10 @@ acpi_ex_resolve_operands(u16 opcode, break; } - ACPI_REPORT_ERROR(("Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n", acpi_ut_get_object_type_name(obj_desc), obj_desc)); + ACPI_ERROR((AE_INFO, + "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p", + acpi_ut_get_object_type_name + (obj_desc), obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -630,7 +680,9 @@ acpi_ex_resolve_operands(u16 opcode, /* Unknown type */ - ACPI_REPORT_ERROR(("Internal - Unknown ARGI (required operand) type %X\n", this_arg_type)); + ACPI_ERROR((AE_INFO, + "Internal - Unknown ARGI (required operand) type %X", + this_arg_type)); return_ACPI_STATUS(AE_BAD_PARAMETER); } diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 202ebe1eb957..3f020c0e2b95 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -250,7 +250,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, /* Validate parameters */ if (!source_desc || !dest_desc) { - ACPI_REPORT_ERROR(("Null parameter\n")); + ACPI_ERROR((AE_INFO, "Null parameter")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -290,7 +290,10 @@ acpi_ex_store(union acpi_operand_object *source_desc, /* Destination is not a Reference object */ - ACPI_REPORT_ERROR(("Target is not a Reference or Constant object - %s [%p]\n", acpi_ut_get_object_type_name(dest_desc), dest_desc)); + ACPI_ERROR((AE_INFO, + "Target is not a Reference or Constant object - %s [%p]", + acpi_ut_get_object_type_name(dest_desc), + dest_desc)); ACPI_DUMP_STACK_ENTRY(source_desc); ACPI_DUMP_STACK_ENTRY(dest_desc); @@ -357,8 +360,8 @@ acpi_ex_store(union acpi_operand_object *source_desc, default: - ACPI_REPORT_ERROR(("Unknown Reference opcode %X\n", - ref_desc->reference.opcode)); + ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", + ref_desc->reference.opcode)); ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR); status = AE_AML_INTERNAL; @@ -487,7 +490,9 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, /* All other types are invalid */ - ACPI_REPORT_ERROR(("Source must be Integer/Buffer/String type, not %s\n", acpi_ut_get_object_type_name(source_desc))); + ACPI_ERROR((AE_INFO, + "Source must be Integer/Buffer/String type, not %s", + acpi_ut_get_object_type_name(source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -497,7 +502,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, break; default: - ACPI_REPORT_ERROR(("Target is not a Package or buffer_field\n")); + ACPI_ERROR((AE_INFO, + "Target is not a Package or buffer_field")); status = AE_AML_OPERAND_TYPE; break; } diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c index 25bbc1d78547..42967baf760d 100644 --- a/drivers/acpi/executer/exstoren.c +++ b/drivers/acpi/executer/exstoren.c @@ -123,7 +123,10 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, && (source_desc->reference.opcode == AML_LOAD_OP))) { /* Conversion successful but still not a valid type */ - ACPI_REPORT_ERROR(("Cannot assign type %s to %s (must be type Int/Str/Buf)\n", acpi_ut_get_object_type_name(source_desc), acpi_ut_get_type_name(target_type))); + ACPI_ERROR((AE_INFO, + "Cannot assign type %s to %s (must be type Int/Str/Buf)", + acpi_ut_get_object_type_name(source_desc), + acpi_ut_get_type_name(target_type))); status = AE_AML_OPERAND_TYPE; } break; @@ -131,9 +134,11 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, case ACPI_TYPE_LOCAL_ALIAS: case ACPI_TYPE_LOCAL_METHOD_ALIAS: - /* Aliases are resolved by acpi_ex_prep_operands */ - - ACPI_REPORT_ERROR(("Store into Alias - should never happen\n")); + /* + * All aliases should have been resolved earlier, during the + * operand resolution phase. + */ + ACPI_ERROR((AE_INFO, "Store into an unresolved Alias object")); status = AE_AML_INTERNAL; break; @@ -276,8 +281,8 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc, /* * All other types come here. */ - ACPI_REPORT_WARNING(("Store into type %s not implemented\n", - acpi_ut_get_object_type_name(dest_desc))); + ACPI_WARNING((AE_INFO, "Store into type %s not implemented", + acpi_ut_get_object_type_name(dest_desc))); status = AE_NOT_IMPLEMENTED; break; diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c index 9a3684d3cf87..ea9144f42e1f 100644 --- a/drivers/acpi/executer/exsystem.c +++ b/drivers/acpi/executer/exsystem.c @@ -129,8 +129,8 @@ acpi_status acpi_ex_system_do_stall(u32 how_long) * (ACPI specifies 100 usec as max, but this gives some slack in * order to support existing BIOSs) */ - ACPI_REPORT_ERROR(("Time parameter is too large (%d)\n", - how_long)); + ACPI_ERROR((AE_INFO, "Time parameter is too large (%d)", + how_long)); status = AE_AML_OPERAND_VALUE; } else { acpi_os_stall(how_long); diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index 990c40e0c041..f73a61aeb7ec 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c @@ -91,7 +91,7 @@ acpi_status acpi_ex_enter_interpreter(void) status = acpi_ut_acquire_mutex(ACPI_MTX_EXECUTE); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not acquire interpreter mutex\n")); + ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex")); } return_ACPI_STATUS(status); @@ -127,7 +127,7 @@ void acpi_ex_exit_interpreter(void) status = acpi_ut_release_mutex(ACPI_MTX_EXECUTE); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not release interpreter mutex\n")); + ACPI_ERROR((AE_INFO, "Could not release interpreter mutex")); } return_VOID; @@ -200,7 +200,8 @@ u8 acpi_ex_acquire_global_lock(u32 field_flags) if (ACPI_SUCCESS(status)) { locked = TRUE; } else { - ACPI_REPORT_ERROR(("Could not acquire Global Lock, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not acquire Global Lock")); } } @@ -235,7 +236,8 @@ void acpi_ex_release_global_lock(u8 locked_by_me) if (ACPI_FAILURE(status)) { /* Report the error, but there isn't much else we can do */ - ACPI_REPORT_ERROR(("Could not release ACPI Global Lock, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not release ACPI Global Lock")); } } diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c index 5c068cc4f674..ea2f13271ff1 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/hardware/hwacpi.c @@ -68,7 +68,7 @@ acpi_status acpi_hw_initialize(void) /* We must have the ACPI tables by the time we get here */ if (!acpi_gbl_FADT) { - ACPI_REPORT_ERROR(("No FADT is present\n")); + ACPI_ERROR((AE_INFO, "No FADT is present")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -107,7 +107,8 @@ acpi_status acpi_hw_set_mode(u32 mode) * system does not support mode transition. */ if (!acpi_gbl_FADT->smi_cmd) { - ACPI_REPORT_ERROR(("No SMI_CMD in FADT, mode transition failed\n")); + ACPI_ERROR((AE_INFO, + "No SMI_CMD in FADT, mode transition failed")); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } @@ -119,7 +120,8 @@ acpi_status acpi_hw_set_mode(u32 mode) * transitions are not supported. */ if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { - ACPI_REPORT_ERROR(("No ACPI mode transition supported in this system (enable/disable both zero)\n")); + ACPI_ERROR((AE_INFO, + "No ACPI mode transition supported in this system (enable/disable both zero)")); return_ACPI_STATUS(AE_OK); } @@ -153,8 +155,8 @@ acpi_status acpi_hw_set_mode(u32 mode) } if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not write mode change, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not write ACPI mode change")); return_ACPI_STATUS(status); } @@ -174,7 +176,7 @@ acpi_status acpi_hw_set_mode(u32 mode) retry--; } - ACPI_REPORT_ERROR(("Hardware never changed modes\n")); + ACPI_ERROR((AE_INFO, "Hardware did not change modes")); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index b4b50a3d1705..e1fe75498415 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c @@ -160,15 +160,16 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) /* Must have a return object */ if (!info.return_object) { - ACPI_REPORT_ERROR(("No Sleep State object returned from [%s]\n", - sleep_state_name)); + ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", + sleep_state_name)); status = AE_NOT_EXIST; } /* It must be of type Package */ else if (ACPI_GET_OBJECT_TYPE(info.return_object) != ACPI_TYPE_PACKAGE) { - ACPI_REPORT_ERROR(("Sleep State return object is not a Package\n")); + ACPI_ERROR((AE_INFO, + "Sleep State return object is not a Package")); status = AE_AML_OPERAND_TYPE; } @@ -180,7 +181,8 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) * one per sleep type (A/B). */ else if (info.return_object->package.count < 2) { - ACPI_REPORT_ERROR(("Sleep State return package does not have at least two elements\n")); + ACPI_ERROR((AE_INFO, + "Sleep State return package does not have at least two elements")); status = AE_AML_NO_OPERAND; } @@ -190,7 +192,12 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) != ACPI_TYPE_INTEGER) || (ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) { - ACPI_REPORT_ERROR(("Sleep State return package elements are not both Integers (%s, %s)\n", acpi_ut_get_object_type_name(info.return_object->package.elements[0]), acpi_ut_get_object_type_name(info.return_object->package.elements[1]))); + ACPI_ERROR((AE_INFO, + "Sleep State return package elements are not both Integers (%s, %s)", + acpi_ut_get_object_type_name(info.return_object-> + package.elements[0]), + acpi_ut_get_object_type_name(info.return_object-> + package.elements[1]))); status = AE_AML_OPERAND_TYPE; } else { /* Valid _Sx_ package size, type, and value */ @@ -202,7 +209,11 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) } if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n", acpi_format_exception(status), sleep_state_name, info.return_object, acpi_ut_get_object_type_name(info.return_object))); + ACPI_EXCEPTION((AE_INFO, status, + "While evaluating sleep_state [%s], bad Sleep object %p type %s", + sleep_state_name, info.return_object, + acpi_ut_get_object_type_name(info. + return_object))); } acpi_ut_remove_reference(info.return_object); @@ -228,8 +239,8 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) ACPI_FUNCTION_ENTRY(); if (register_id > ACPI_BITREG_MAX) { - ACPI_REPORT_ERROR(("Invalid bit_register ID: %X\n", - register_id)); + ACPI_ERROR((AE_INFO, "Invalid bit_register ID: %X", + register_id)); return (NULL); } @@ -329,8 +340,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) bit_reg_info = acpi_hw_get_bit_register_info(register_id); if (!bit_reg_info) { - ACPI_REPORT_ERROR(("Bad ACPI HW register_id: %X\n", - register_id)); + ACPI_ERROR((AE_INFO, "Bad ACPI HW register_id: %X", + register_id)); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -564,7 +575,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) break; default: - ACPI_REPORT_ERROR(("Unknown Register ID: %X\n", register_id)); + ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); status = AE_BAD_PARAMETER; break; } @@ -759,8 +770,9 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) break; default: - ACPI_REPORT_ERROR(("Unsupported address space: %X\n", - reg->address_space_id)); + ACPI_ERROR((AE_INFO, + "Unsupported address space: %X", + reg->address_space_id)); return (AE_BAD_PARAMETER); } @@ -829,8 +841,9 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) break; default: - ACPI_REPORT_ERROR(("Unsupported address space: %X\n", - reg->address_space_id)); + ACPI_ERROR((AE_INFO, + "Unsupported address space: %X", + reg->address_space_id)); return (AE_BAD_PARAMETER); } diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 992128d71117..89269272fd62 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c @@ -199,8 +199,8 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_REPORT_ERROR(("Method _SST failed, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "While executing method _SST")); } return_ACPI_STATUS(AE_OK); @@ -232,9 +232,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { - ACPI_REPORT_ERROR(("Sleep values out of range: A=%X B=%X\n", - acpi_gbl_sleep_type_a, - acpi_gbl_sleep_type_b)); + ACPI_ERROR((AE_INFO, "Sleep values out of range: A=%X B=%X", + acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b)); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } @@ -533,21 +532,18 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) arg.integer.value = ACPI_SST_WAKING; status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_REPORT_ERROR(("Method _SST failed, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); } arg.integer.value = sleep_state; status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_REPORT_ERROR(("Method _BFS failed, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); } status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_REPORT_ERROR(("Method _WAK failed, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); } /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ @@ -582,8 +578,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) arg.integer.value = ACPI_SST_WORKING; status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_REPORT_ERROR(("Method _SST failed, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); } return_ACPI_STATUS(status); diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index c2db93e25b78..1149bc18fb35 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c @@ -110,7 +110,9 @@ acpi_status acpi_ns_root_initialize(void) ACPI_NS_NO_UPSEARCH, NULL, &new_node); if (ACPI_FAILURE(status) || (!new_node)) { /* Must be on same line for code converter */ - ACPI_REPORT_ERROR(("Could not create predefined name %s, %s\n", init_val->name, acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not create predefined name %s", + init_val->name)); } /* @@ -121,7 +123,9 @@ acpi_status acpi_ns_root_initialize(void) if (init_val->val) { status = acpi_os_predefined_override(init_val, &val); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not override predefined %s\n", init_val->name)); + ACPI_ERROR((AE_INFO, + "Could not override predefined %s", + init_val->name)); } if (!val) { @@ -228,7 +232,9 @@ acpi_status acpi_ns_root_initialize(void) default: - ACPI_REPORT_ERROR(("Unsupported initial type value %X\n", init_val->type)); + ACPI_ERROR((AE_INFO, + "Unsupported initial type value %X", + init_val->type)); acpi_ut_remove_reference(obj_desc); obj_desc = NULL; continue; @@ -334,10 +340,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, prefix_node = scope_info->scope.node; if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) != ACPI_DESC_TYPE_NAMED) { - ACPI_REPORT_ERROR(("%p is not a namespace node [%s]\n", - prefix_node, - acpi_ut_get_descriptor_name - (prefix_node))); + ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]", + prefix_node, + acpi_ut_get_descriptor_name(prefix_node))); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -427,7 +432,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, if (!this_node) { /* Current scope has no parent scope */ - ACPI_REPORT_ERROR(("ACPI path has too many parent prefixes (^) - reached beyond root node\n")); + ACPI_ERROR((AE_INFO, + "ACPI path has too many parent prefixes (^) - reached beyond root node")); return_ACPI_STATUS(AE_NOT_FOUND); } } @@ -598,7 +604,12 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, (this_node->type != type_to_check_for)) { /* Complain about a type mismatch */ - ACPI_REPORT_WARNING(("ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)\n", ACPI_CAST_PTR(char, &simple_name), acpi_ut_get_type_name(this_node->type), acpi_ut_get_type_name(type_to_check_for))); + ACPI_WARNING((AE_INFO, + "ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)", + ACPI_CAST_PTR(char, &simple_name), + acpi_ut_get_type_name(this_node->type), + acpi_ut_get_type_name + (type_to_check_for))); } /* diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index 3db950f5d5a0..9b871f38b61b 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c @@ -272,8 +272,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) /* Grandchildren should have all been deleted already */ if (child_node->child) { - ACPI_REPORT_ERROR(("Found a grandchild! P=%p C=%p\n", - parent_node, child_node)); + ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p", + parent_node, child_node)); } /* Now we can free this child object */ @@ -301,7 +301,9 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) /* There should be only one reference remaining on this node */ if (child_node->reference_count != 1) { - ACPI_REPORT_WARNING(("Existing references (%d) on node being deleted (%p)\n", child_node->reference_count, child_node)); + ACPI_WARNING((AE_INFO, + "Existing references (%d) on node being deleted (%p)", + child_node->reference_count, child_node)); } /* Now we can delete the node */ diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index 2f0b70e3e881..a2807317a84b 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c @@ -198,13 +198,13 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, /* Check the node type and name */ if (type > ACPI_TYPE_LOCAL_MAX) { - ACPI_REPORT_WARNING(("Invalid ACPI Object Type %08X\n", - type)); + ACPI_WARNING((AE_INFO, "Invalid ACPI Object Type %08X", + type)); } if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { - ACPI_REPORT_WARNING(("Invalid ACPI Name %08X\n", - this_node->name.integer)); + ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", + this_node->name.integer)); } acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index e3c667072e2f..19d7b94d40c3 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -373,7 +373,7 @@ acpi_ns_execute_control_method(struct acpi_parameter_info *info) info->obj_desc = acpi_ns_get_attached_object(info->node); if (!info->obj_desc) { - ACPI_REPORT_ERROR(("No attached method object\n")); + ACPI_ERROR((AE_INFO, "No attached method object")); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return_ACPI_STATUS(AE_NULL_OBJECT); diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index 6c117893f301..9f929e479fd8 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c @@ -93,8 +93,7 @@ acpi_status acpi_ns_initialize_objects(void) ACPI_UINT32_MAX, acpi_ns_init_one_object, &info, NULL); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("walk_namespace failed! %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace")); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, @@ -159,12 +158,11 @@ acpi_status acpi_ns_initialize_devices(void) (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("walk_namespace failed! %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace")); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "\n%hd Devices found containing: %hd _STA, %hd _INI methods\n", + "\n%hd Devices found - executed %hd _STA, %hd _INI methods\n", info.device_count, info.num_STA, info.num_INI)); return_ACPI_STATUS(status); @@ -289,7 +287,10 @@ acpi_ns_init_one_object(acpi_handle obj_handle, } if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("\nCould not execute arguments for [%4.4s] (%s), %s\n", acpi_ut_get_node_name(node), acpi_ut_get_type_name(type), acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not execute arguments for [%4.4s] (%s)", + acpi_ut_get_node_name(node), + acpi_ut_get_type_name(type))); } /* @@ -416,9 +417,8 @@ acpi_ns_init_one_device(acpi_handle obj_handle, #ifdef ACPI_DEBUG_OUTPUT char *scope_name = acpi_ns_get_external_pathname(ini_node); - ACPI_REPORT_WARNING(("%s._INI failed: %s\n", - scope_name, - acpi_format_exception(status))); + ACPI_WARNING((AE_INFO, "%s._INI failed: %s", + scope_name, acpi_format_exception(status))); ACPI_MEM_FREE(scope_name); #endif diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index 0b4a866ef5aa..4e0b0524c188 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -92,7 +92,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, /* Check validity of the AML start and length */ if (!table_desc->aml_start) { - ACPI_REPORT_ERROR(("Null AML pointer\n")); + ACPI_ERROR((AE_INFO, "Null AML pointer")); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -102,8 +102,8 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, /* Ignore table if there is no AML contained within */ if (!table_desc->aml_length) { - ACPI_REPORT_WARNING(("Zero-length AML block in table [%4.4s]\n", - table_desc->pointer->signature)); + ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]", + table_desc->pointer->signature)); return_ACPI_STATUS(AE_OK); } @@ -263,7 +263,7 @@ acpi_status acpi_ns_load_namespace(void) /* There must be at least a DSDT installed */ if (acpi_gbl_DSDT == NULL) { - ACPI_REPORT_ERROR(("DSDT is not in memory\n")); + ACPI_ERROR((AE_INFO, "DSDT is not in memory")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index 411e1f8b11d0..639f653b4b6b 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -110,7 +110,9 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, name_buffer[index] = AML_ROOT_PREFIX; if (index != 0) { - ACPI_REPORT_ERROR(("Could not construct pathname; index=%X, size=%X, Path=%s\n", (u32) index, (u32) size, &name_buffer[size])); + ACPI_ERROR((AE_INFO, + "Could not construct pathname; index=%X, size=%X, Path=%s", + (u32) index, (u32) size, &name_buffer[size])); } return; @@ -146,7 +148,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) name_buffer = ACPI_MEM_CALLOCATE(size); if (!name_buffer) { - ACPI_REPORT_ERROR(("Allocation failure\n")); + ACPI_ERROR((AE_INFO, "Allocation failure")); return_PTR(NULL); } diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c index 86113093f7b7..10ae6292bca4 100644 --- a/drivers/acpi/namespace/nsobject.c +++ b/drivers/acpi/namespace/nsobject.c @@ -84,22 +84,23 @@ acpi_ns_attach_object(struct acpi_namespace_node *node, if (!node) { /* Invalid handle */ - ACPI_REPORT_ERROR(("Null named_obj handle\n")); + ACPI_ERROR((AE_INFO, "Null named_obj handle")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { /* Null object */ - ACPI_REPORT_ERROR(("Null object, but type not ACPI_TYPE_ANY\n")); + ACPI_ERROR((AE_INFO, + "Null object, but type not ACPI_TYPE_ANY")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { /* Not a name handle */ - ACPI_REPORT_ERROR(("Invalid handle %p [%s]\n", - node, acpi_ut_get_descriptor_name(node))); + ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]", + node, acpi_ut_get_descriptor_name(node))); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -254,7 +255,7 @@ union acpi_operand_object *acpi_ns_get_attached_object(struct ACPI_FUNCTION_TRACE_PTR("ns_get_attached_object", node); if (!node) { - ACPI_REPORT_WARNING(("Null Node ptr\n")); + ACPI_WARNING((AE_INFO, "Null Node ptr")); return_PTR(NULL); } diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index f094a2eb8512..d64b78952f24 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -298,15 +298,17 @@ acpi_ns_search_and_enter(u32 target_name, /* Parameter validation */ if (!node || !target_name || !return_node) { - ACPI_REPORT_ERROR(("Null param: Node %p Name %X return_node %p\n", node, target_name, return_node)); + ACPI_ERROR((AE_INFO, + "Null param: Node %p Name %X return_node %p", + node, target_name, return_node)); return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Name must consist of printable characters */ if (!acpi_ut_valid_acpi_name(target_name)) { - ACPI_REPORT_ERROR(("Bad character in ACPI Name: %X\n", - target_name)); + ACPI_ERROR((AE_INFO, "Bad character in ACPI Name: %X", + target_name)); return_ACPI_STATUS(AE_BAD_CHARACTER); } diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index bc779fdd3caf..3e7cad549a38 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -85,7 +85,7 @@ acpi_ns_report_error(char *module_name, if (lookup_status == AE_BAD_CHARACTER) { /* There is a non-ascii character in the name */ - acpi_os_printf("[0x%4.4X] (NON-ASCII)\n", + acpi_os_printf("[0x%4.4X] (NON-ASCII)", *(ACPI_CAST_PTR(u32, internal_name))); } else { /* Convert path to external format */ @@ -106,7 +106,7 @@ acpi_ns_report_error(char *module_name, } } - acpi_os_printf("Namespace lookup failure, %s\n", + acpi_os_printf(" Namespace lookup failure, %s\n", acpi_format_exception(lookup_status)); } @@ -242,7 +242,7 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) ACPI_FUNCTION_TRACE("ns_get_type"); if (!node) { - ACPI_REPORT_WARNING(("Null Node parameter\n")); + ACPI_WARNING((AE_INFO, "Null Node parameter")); return_UINT32(ACPI_TYPE_ANY); } @@ -269,7 +269,7 @@ u32 acpi_ns_local(acpi_object_type type) if (!acpi_ut_valid_object_type(type)) { /* Type code out of range */ - ACPI_REPORT_WARNING(("Invalid Object Type %X\n", type)); + ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type)); return_UINT32(ACPI_NS_NORMAL); } @@ -621,7 +621,7 @@ acpi_ns_externalize_name(u32 internal_name_length, * with internal_name (invalid format). */ if (required_length > internal_name_length) { - ACPI_REPORT_ERROR(("Invalid internal name\n")); + ACPI_ERROR((AE_INFO, "Invalid internal name")); return_ACPI_STATUS(AE_BAD_PATHNAME); } @@ -797,7 +797,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type) if (!acpi_ut_valid_object_type(type)) { /* type code out of range */ - ACPI_REPORT_WARNING(("Invalid Object Type %X\n", type)); + ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type)); return_UINT32(ACPI_NS_NORMAL); } diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index de13add43efc..a95f636dc35d 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -112,7 +112,7 @@ acpi_evaluate_object_typed(acpi_handle handle, if (return_buffer->length == 0) { /* Error because caller specifically asked for a return value */ - ACPI_REPORT_ERROR(("No return value\n")); + ACPI_ERROR((AE_INFO, "No return value")); return_ACPI_STATUS(AE_NULL_OBJECT); } @@ -124,11 +124,11 @@ acpi_evaluate_object_typed(acpi_handle handle, /* Return object type does not match requested type */ - ACPI_REPORT_ERROR(("Incorrect return type [%s] requested [%s]\n", - acpi_ut_get_type_name(((union acpi_object *) - return_buffer->pointer)-> - type), - acpi_ut_get_type_name(return_type))); + ACPI_ERROR((AE_INFO, + "Incorrect return type [%s] requested [%s]", + acpi_ut_get_type_name(((union acpi_object *)return_buffer-> + pointer)->type), + acpi_ut_get_type_name(return_type))); if (must_free) { /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ @@ -235,9 +235,11 @@ acpi_evaluate_object(acpi_handle handle, * qualified names above, this is an error */ if (!pathname) { - ACPI_REPORT_ERROR(("Both Handle and Pathname are NULL\n")); + ACPI_ERROR((AE_INFO, + "Both Handle and Pathname are NULL")); } else { - ACPI_REPORT_ERROR(("Handle is NULL and Pathname is relative\n")); + ACPI_ERROR((AE_INFO, + "Handle is NULL and Pathname is relative")); } status = AE_BAD_PARAMETER; diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index 853e6d170c96..8cd8675a47c0 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c @@ -300,8 +300,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) status = acpi_ut_execute_CID(node, &cid_list); if (ACPI_SUCCESS(status)) { - size += ((acpi_size) cid_list->count - 1) * - sizeof(struct acpi_compatible_id); + size += cid_list->size; info->valid |= ACPI_VALID_CID; } diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index cc4a4903842a..ac5bbaedac1b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1062,9 +1062,9 @@ EXPORT_SYMBOL(max_cstate); * handle is a pointer to the spinlock_t. */ -acpi_native_uint acpi_os_acquire_lock(acpi_handle handle) +acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle) { - unsigned long flags; + acpi_cpu_flags flags; spin_lock_irqsave((spinlock_t *) handle, flags); return flags; } @@ -1073,9 +1073,9 @@ acpi_native_uint acpi_os_acquire_lock(acpi_handle handle) * Release a spinlock. See above. */ -void acpi_os_release_lock(acpi_handle handle, acpi_native_uint flags) +void acpi_os_release_lock(acpi_handle handle, acpi_cpu_flags flags) { - spin_unlock_irqrestore((spinlock_t *) handle, (unsigned long) flags); + spin_unlock_irqrestore((spinlock_t *) handle, flags); } #ifndef ACPI_USE_LOCAL_CACHE diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 3c37cd0ecd80..de573be52718 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -298,7 +298,9 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, acpi_ps_append_arg(arg, name_op); if (!method_desc) { - ACPI_REPORT_ERROR(("Control Method %p has no attached object\n", node)); + ACPI_ERROR((AE_INFO, + "Control Method %p has no attached object", + node)); return_ACPI_STATUS(AE_AML_INTERNAL); } @@ -348,7 +350,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, /* Final exception check (may have been changed from code above) */ if (ACPI_FAILURE(status)) { - ACPI_REPORT_NSERROR(path, status); + ACPI_ERROR_NAMESPACE(path, status); if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) { @@ -451,7 +453,7 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, default: - ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type)); + ACPI_ERROR((AE_INFO, "Invalid arg_type %X", arg_type)); return_VOID; } @@ -709,7 +711,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, default: - ACPI_REPORT_ERROR(("Invalid arg_type: %X\n", arg_type)); + ACPI_ERROR((AE_INFO, "Invalid arg_type: %X", arg_type)); status = AE_AML_OPERAND_TYPE; break; } diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index c66029b890b1..00b072e15d19 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c @@ -123,10 +123,12 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) && ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) { if (status == AE_AML_NO_RETURN_VALUE) { - ACPI_REPORT_ERROR(("Invoked method did not return a value, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Invoked method did not return a value")); } - ACPI_REPORT_ERROR(("get_predicate Failed, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "get_predicate Failed")); return_ACPI_STATUS(status); } @@ -184,7 +186,11 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) /* The opcode is unrecognized. Just skip unknown opcodes */ - ACPI_REPORT_ERROR(("Found unknown opcode %X at AML address %p offset %X, ignoring\n", walk_state->opcode, parser_state->aml, walk_state->aml_offset)); + ACPI_ERROR((AE_INFO, + "Found unknown opcode %X at AML address %p offset %X, ignoring", + walk_state->opcode, + parser_state->aml, + walk_state->aml_offset)); ACPI_DUMP_BUFFER(parser_state->aml, 128); @@ -271,7 +277,8 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) walk_state->descending_callback(walk_state, &op); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("During name lookup/catalog, %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "During name lookup/catalog")); goto close_this_op; } diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 3b540fe17a0c..a9f3229f4106 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -512,9 +512,9 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) } else if ((status != AE_OK) && (walk_state->method_desc)) { /* Either the method parse or actual execution failed */ - ACPI_REPORT_MTERROR("Method parse/execution failed", - walk_state->method_node, NULL, - status); + ACPI_ERROR_METHOD("Method parse/execution failed", + walk_state->method_node, NULL, + status); /* Check for possible multi-thread reentrancy problem */ @@ -558,7 +558,8 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) walk_state->method_desc->method. thread_count--; } else { - ACPI_REPORT_ERROR(("Invalid zero thread count in method\n")); + ACPI_ERROR((AE_INFO, + "Invalid zero thread count in method")); } } diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c index d387e2b01dbb..dd6f16726fc4 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/parser/pstree.c @@ -132,8 +132,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) if (op_info->class == AML_CLASS_UNKNOWN) { /* Invalid opcode */ - ACPI_REPORT_ERROR(("Invalid AML Opcode: 0x%2.2X\n", - op->common.aml_opcode)); + ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X", + op->common.aml_opcode)); return; } diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 1dfa6906d455..7d6481d9fbec 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -541,13 +541,13 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, for (table_index = 0; table_index < 4 && !name_found; table_index++) { - if ((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))) { + 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 */ diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 7f46ca0bf33a..8c128dea3252 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -207,14 +207,20 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* Each element of the top-level package must also be a package */ if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) { - ACPI_REPORT_ERROR(("(PRT[%X]) Need sub-package, found %s\n", index, acpi_ut_get_object_type_name(*top_object_list))); + ACPI_ERROR((AE_INFO, + "(PRT[%X]) Need sub-package, found %s", + index, + acpi_ut_get_object_type_name + (*top_object_list))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } /* Each sub-package must be of length 4 */ if ((*top_object_list)->package.count != 4) { - ACPI_REPORT_ERROR(("(PRT[%X]) Need package of length 4, found length %d\n", index, (*top_object_list)->package.count)); + ACPI_ERROR((AE_INFO, + "(PRT[%X]) Need package of length 4, found length %d", + index, (*top_object_list)->package.count)); return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT); } @@ -231,7 +237,10 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->address = obj_desc->integer.value; } else { - ACPI_REPORT_ERROR(("(PRT[%X].Address) Need Integer, found %s\n", index, acpi_ut_get_object_type_name(obj_desc))); + ACPI_ERROR((AE_INFO, + "(PRT[%X].Address) Need Integer, found %s", + index, + acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } @@ -241,65 +250,83 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->pin = (u32) obj_desc->integer.value; } else { - ACPI_REPORT_ERROR(("(PRT[%X].Pin) Need Integer, found %s\n", index, acpi_ut_get_object_type_name(obj_desc))); + ACPI_ERROR((AE_INFO, + "(PRT[%X].Pin) Need Integer, found %s", + index, + acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } - /* 3) Third subobject: Dereference the PRT.source_name */ - + /* + * 3) Third subobject: Dereference the PRT.source_name + * The name may be unresolved (slack mode), so allow a null object + */ obj_desc = sub_object_list[2]; - switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { - case ACPI_TYPE_LOCAL_REFERENCE: + if (obj_desc) { + switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { + case ACPI_TYPE_LOCAL_REFERENCE: - if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) { - ACPI_REPORT_ERROR(("(PRT[%X].Source) Need name, found reference op %X\n", index, obj_desc->reference.opcode)); + if (obj_desc->reference.opcode != + AML_INT_NAMEPATH_OP) { + ACPI_ERROR((AE_INFO, + "(PRT[%X].Source) Need name, found reference op %X", + index, + obj_desc->reference. + opcode)); + return_ACPI_STATUS(AE_BAD_DATA); + } + + node = obj_desc->reference.node; + + /* Use *remaining* length of the buffer as max for pathname */ + + path_buffer.length = output_buffer->length - + (u32) ((u8 *) user_prt->source - + (u8 *) output_buffer->pointer); + path_buffer.pointer = user_prt->source; + + status = + acpi_ns_handle_to_pathname((acpi_handle) + node, + &path_buffer); + + /* +1 to include null terminator */ + + user_prt->length += + (u32) ACPI_STRLEN(user_prt->source) + 1; + break; + + case ACPI_TYPE_STRING: + + ACPI_STRCPY(user_prt->source, + obj_desc->string.pointer); + + /* + * Add to the Length field the length of the string + * (add 1 for terminator) + */ + user_prt->length += obj_desc->string.length + 1; + break; + + case ACPI_TYPE_INTEGER: + /* + * If this is a number, then the Source Name is NULL, since the + * entire buffer was zeroed out, we can leave this alone. + * + * Add to the Length field the length of the u32 NULL + */ + user_prt->length += sizeof(u32); + break; + + default: + + ACPI_ERROR((AE_INFO, + "(PRT[%X].Source) Need Ref/String/Integer, found %s", + index, + acpi_ut_get_object_type_name + (obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } - - node = obj_desc->reference.node; - - /* Use *remaining* length of the buffer as max for pathname */ - - path_buffer.length = output_buffer->length - - (u32) ((u8 *) user_prt->source - - (u8 *) output_buffer->pointer); - path_buffer.pointer = user_prt->source; - - status = - acpi_ns_handle_to_pathname((acpi_handle) node, - &path_buffer); - - /* +1 to include null terminator */ - - user_prt->length += - (u32) ACPI_STRLEN(user_prt->source) + 1; - break; - - case ACPI_TYPE_STRING: - - ACPI_STRCPY(user_prt->source, obj_desc->string.pointer); - - /* - * Add to the Length field the length of the string - * (add 1 for terminator) - */ - user_prt->length += obj_desc->string.length + 1; - break; - - case ACPI_TYPE_INTEGER: - /* - * If this is a number, then the Source Name is NULL, since the - * entire buffer was zeroed out, we can leave this alone. - * - * Add to the Length field the length of the u32 NULL - */ - user_prt->length += sizeof(u32); - break; - - default: - - ACPI_REPORT_ERROR(("(PRT[%X].Source) Need Ref/String/Integer, found %s\n", index, acpi_ut_get_object_type_name(obj_desc))); - return_ACPI_STATUS(AE_BAD_DATA); } /* Now align the current length */ @@ -313,7 +340,10 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->source_index = (u32) obj_desc->integer.value; } else { - ACPI_REPORT_ERROR(("(PRT[%X].source_index) Need Integer, found %s\n", index, acpi_ut_get_object_type_name(obj_desc))); + ACPI_ERROR((AE_INFO, + "(PRT[%X].source_index) Need Integer, found %s", + index, + acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); } diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 98356e2482c5..e7de061cf883 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -692,7 +692,11 @@ void acpi_rs_dump_irq_list(u8 * route_table) static void acpi_rs_out_string(char *title, char *value) { - acpi_os_printf("%27s : %s\n", title, value); + acpi_os_printf("%27s : %s", title, value); + if (!*value) { + acpi_os_printf("[NULL NAMESTRING]"); + } + acpi_os_printf("\n"); } static void acpi_rs_out_integer8(char *title, u8 value) diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index e4778a51c17e..1434e786477e 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -94,7 +94,9 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) acpi_gbl_get_resource_dispatch [resource_index]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not convert AML resource (Type %X) to resource, %s\n", *aml, acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert AML resource (Type %X)", + *aml)); return_ACPI_STATUS(status); } @@ -156,7 +158,9 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Validate the (internal) Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { - ACPI_REPORT_ERROR(("Invalid descriptor type (%X) in resource list\n", resource->type)); + ACPI_ERROR((AE_INFO, + "Invalid descriptor type (%X) in resource list", + resource->type)); return_ACPI_STATUS(AE_BAD_DATA); } @@ -169,7 +173,9 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, acpi_gbl_set_resource_dispatch [resource->type]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not convert resource (type %X) to AML, %s\n", resource->type, acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert resource (type %X) to AML", + resource->type)); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 83bfe0dd3eba..ed866cf1c6d2 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -84,9 +84,11 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, ACPI_FUNCTION_TRACE("rs_get_resource"); if (((acpi_native_uint) resource) & 0x3) { - acpi_os_printf - ("**** GET: Misaligned resource pointer: %p Type %2.2X Len %X\n", - resource, resource->type, resource->length); + /* Each internal resource struct is expected to be 32-bit aligned */ + + ACPI_WARNING((AE_INFO, + "Misaligned resource pointer (get): %p Type %2.2X Len %X", + resource, resource->type, resource->length)); } /* Extract the resource Length field (does not include header length) */ @@ -274,15 +276,16 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, break; default: - acpi_os_printf - ("*** Invalid conversion sub-opcode\n"); + + ACPI_ERROR((AE_INFO, + "Invalid conversion sub-opcode")); return_ACPI_STATUS(AE_BAD_PARAMETER); } break; default: - acpi_os_printf("*** Invalid conversion opcode\n"); + ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -486,15 +489,16 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, break; default: - acpi_os_printf - ("*** Invalid conversion sub-opcode\n"); + + ACPI_ERROR((AE_INFO, + "Invalid conversion sub-opcode")); return_ACPI_STATUS(AE_BAD_PARAMETER); } break; default: - acpi_os_printf("*** Invalid conversion opcode\n"); + ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -523,7 +527,9 @@ if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) { * polarity/trigger interrupts are allowed (ACPI spec, section * "IRQ Format"), so 0x00 and 0x09 are illegal. */ - ACPI_REPORT_ERROR(("Invalid interrupt polarity/trigger in resource list, %X\n", aml->irq.flags)); + ACPI_ERROR((AE_INFO, + "Invalid interrupt polarity/trigger in resource list, %X", + aml->irq.flags)); return_ACPI_STATUS(AE_BAD_DATA); } @@ -535,7 +541,7 @@ if (temp8 < 1) { } if (resource->data.dma.transfer == 0x03) { - ACPI_REPORT_ERROR(("Invalid DMA.Transfer preference (3)\n")); + ACPI_ERROR((AE_INFO, "Invalid DMA.Transfer preference (3)")); return_ACPI_STATUS(AE_BAD_DATA); } #endif diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index 48290b7e6ba5..03b37d2223bc 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c @@ -501,8 +501,8 @@ acpi_status acpi_tb_convert_table_fadt(void) * at least as long as the version 1.0 FADT */ if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) { - ACPI_REPORT_ERROR(("FADT is invalid, too short: 0x%X\n", - acpi_gbl_FADT->length)); + ACPI_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X", + acpi_gbl_FADT->length)); return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); } @@ -517,7 +517,10 @@ acpi_status acpi_tb_convert_table_fadt(void) if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev2)) { /* Length is too short to be a V2.0 table */ - ACPI_REPORT_WARNING(("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n", acpi_gbl_FADT->length, acpi_gbl_FADT->revision)); + ACPI_WARNING((AE_INFO, + "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table", + acpi_gbl_FADT->length, + acpi_gbl_FADT->revision)); acpi_tb_convert_fadt1(local_fadt, (void *)acpi_gbl_FADT); @@ -582,13 +585,15 @@ acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info) /* Absolute minimum length is 24, but the ACPI spec says 64 */ if (acpi_gbl_FACS->length < 24) { - ACPI_REPORT_ERROR(("Invalid FACS table length: 0x%X\n", - acpi_gbl_FACS->length)); + ACPI_ERROR((AE_INFO, "Invalid FACS table length: 0x%X", + acpi_gbl_FACS->length)); return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); } if (acpi_gbl_FACS->length < 64) { - ACPI_REPORT_WARNING(("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n", acpi_gbl_FACS->length)); + ACPI_WARNING((AE_INFO, + "FACS is shorter than the ACPI specification allows: 0x%X, using anyway", + acpi_gbl_FACS->length)); } /* Copy fields to the new FACS */ diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 0fedf4b27ea5..09b4ee6dfd60 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c @@ -91,9 +91,9 @@ acpi_tb_get_table(struct acpi_pointer *address, status = acpi_tb_get_table_body(address, &header, table_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not get ACPI table (size %X), %s\n", - header.length, - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not get ACPI table (size %X)", + header.length)); return_ACPI_STATUS(status); } @@ -148,7 +148,6 @@ acpi_tb_get_table_header(struct acpi_pointer *address, sizeof(struct acpi_table_header), (void *)&header); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not map memory at %8.8X%8.8X for length %X\n", ACPI_FORMAT_UINT64(address->pointer.physical), sizeof(struct acpi_table_header))); return_ACPI_STATUS(status); } @@ -161,8 +160,8 @@ acpi_tb_get_table_header(struct acpi_pointer *address, default: - ACPI_REPORT_ERROR(("Invalid address flags %X\n", - address->pointer_type)); + ACPI_ERROR((AE_INFO, "Invalid address flags %X", + address->pointer_type)); return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -253,8 +252,8 @@ acpi_tb_table_override(struct acpi_table_header *header, if (ACPI_FAILURE(status)) { /* Some severe error from the OSL, but we basically ignore it */ - ACPI_REPORT_ERROR(("Could not override ACPI table, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not override ACPI table")); return_ACPI_STATUS(status); } @@ -273,15 +272,14 @@ acpi_tb_table_override(struct acpi_table_header *header, status = acpi_tb_get_this_table(&address, new_table, table_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not copy override ACPI table, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table")); return_ACPI_STATUS(status); } /* Copy the table info */ - ACPI_REPORT_INFO(("Table [%4.4s] replaced by host OS\n", - table_info->pointer->signature)); + ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS", + table_info->pointer->signature)); return_ACPI_STATUS(AE_OK); } @@ -327,7 +325,9 @@ acpi_tb_get_this_table(struct acpi_pointer *address, full_table = ACPI_MEM_ALLOCATE(header->length); if (!full_table) { - ACPI_REPORT_ERROR(("Could not allocate table memory for [%4.4s] length %X\n", header->signature, header->length)); + ACPI_ERROR((AE_INFO, + "Could not allocate table memory for [%4.4s] length %X", + header->signature, header->length)); return_ACPI_STATUS(AE_NO_MEMORY); } @@ -351,7 +351,12 @@ acpi_tb_get_this_table(struct acpi_pointer *address, (acpi_size) header->length, (void *)&full_table); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n", header->signature, ACPI_FORMAT_UINT64(address->pointer.physical), header->length)); + ACPI_ERROR((AE_INFO, + "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", + header->signature, + ACPI_FORMAT_UINT64(address->pointer. + physical), + header->length)); return (status); } @@ -362,8 +367,8 @@ acpi_tb_get_this_table(struct acpi_pointer *address, default: - ACPI_REPORT_ERROR(("Invalid address flags %X\n", - address->pointer_type)); + ACPI_ERROR((AE_INFO, "Invalid address flags %X", + address->pointer_type)); return_ACPI_STATUS(AE_BAD_PARAMETER); } diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c index 496f336b3e3a..134e5dce0bc1 100644 --- a/drivers/acpi/tables/tbgetall.c +++ b/drivers/acpi/tables/tbgetall.c @@ -152,7 +152,9 @@ acpi_tb_get_secondary_table(struct acpi_pointer *address, /* Signature must match request */ if (ACPI_STRNCMP(header.signature, signature, ACPI_NAME_SIZE)) { - ACPI_REPORT_ERROR(("Incorrect table signature - wanted [%s] found [%4.4s]\n", signature, header.signature)); + ACPI_ERROR((AE_INFO, + "Incorrect table signature - wanted [%s] found [%4.4s]", + signature, header.signature)); return_ACPI_STATUS(AE_BAD_SIGNATURE); } @@ -231,14 +233,18 @@ acpi_status acpi_tb_get_required_tables(void) */ status = acpi_tb_get_primary_table(&address, &table_info); if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) { - ACPI_REPORT_WARNING(("%s, while getting table at %8.8X%8.8X\n", acpi_format_exception(status), ACPI_FORMAT_UINT64(address.pointer.value))); + ACPI_WARNING((AE_INFO, + "%s, while getting table at %8.8X%8.8X", + acpi_format_exception(status), + ACPI_FORMAT_UINT64(address.pointer. + value))); } } /* We must have a FADT to continue */ if (!acpi_gbl_FADT) { - ACPI_REPORT_ERROR(("No FADT present in RSDT/XSDT\n")); + ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -248,7 +254,8 @@ acpi_status acpi_tb_get_required_tables(void) */ status = acpi_tb_convert_table_fadt(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not convert FADT to internal common format\n")); + ACPI_ERROR((AE_INFO, + "Could not convert FADT to internal common format")); return_ACPI_STATUS(status); } @@ -258,8 +265,8 @@ acpi_status acpi_tb_get_required_tables(void) status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not get/install the FACS, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not get/install the FACS")); return_ACPI_STATUS(status); } @@ -278,7 +285,7 @@ acpi_status acpi_tb_get_required_tables(void) status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not get/install the DSDT\n")); + ACPI_ERROR((AE_INFO, "Could not get/install the DSDT")); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index e1c9faa3982e..7ffd0fddb4e5 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -128,8 +128,8 @@ acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not acquire table mutex, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not acquire table mutex")); return_ACPI_STATUS(status); } @@ -146,9 +146,9 @@ acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) status = acpi_tb_init_table_descriptor(table_info->type, table_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not install table [%4.4s], %s\n", - table_info->pointer->signature, - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not install table [%4.4s]", + table_info->pointer->signature)); } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n", diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index 178309026850..4d308220225d 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c @@ -192,16 +192,21 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) if (no_match) { /* Invalid RSDT or XSDT signature */ - ACPI_REPORT_ERROR(("Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:\n")); + ACPI_ERROR((AE_INFO, + "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:")); ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20); - ACPI_REPORT_ERROR(("RSDT/XSDT signature at %X (%p) is invalid\n", acpi_gbl_RSDP->rsdt_physical_address, (void *)(acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address)); + ACPI_ERROR((AE_INFO, + "RSDT/XSDT signature at %X (%p) is invalid", + acpi_gbl_RSDP->rsdt_physical_address, + (void *)(acpi_native_uint) acpi_gbl_RSDP-> + rsdt_physical_address)); if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { - ACPI_REPORT_ERROR(("Looking for RSDT\n")) + ACPI_ERROR((AE_INFO, "Looking for RSDT")); } else { - ACPI_REPORT_ERROR(("Looking for XSDT\n")) + ACPI_ERROR((AE_INFO, "Looking for XSDT")); } ACPI_DUMP_BUFFER((char *)table_ptr, 48); @@ -238,9 +243,8 @@ acpi_status acpi_tb_get_table_rsdt(void) table_info.type = ACPI_TABLE_XSDT; status = acpi_tb_get_table(&address, &table_info); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not get the RSDT/XSDT, %s\n", - acpi_format_exception(status))); - + ACPI_EXCEPTION((AE_INFO, status, + "Could not get the RSDT/XSDT")); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 38c6749e43d5..bc571592f087 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -149,8 +149,8 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) /* Verify that this is a valid address */ if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) { - ACPI_REPORT_ERROR(("Cannot read table header at %p\n", - table_header)); + ACPI_ERROR((AE_INFO, + "Cannot read table header at %p", table_header)); return (AE_BAD_ADDRESS); } @@ -159,10 +159,12 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) ACPI_MOVE_32_TO_32(&signature, table_header->signature); if (!acpi_ut_valid_acpi_name(signature)) { - ACPI_REPORT_ERROR(("Table signature at %p [%p] has invalid characters\n", table_header, &signature)); + ACPI_ERROR((AE_INFO, + "Table signature at %p [%p] has invalid characters", + table_header, &signature)); - ACPI_REPORT_WARNING(("Invalid table signature found: [%4.4s]\n", - ACPI_CAST_PTR(char, &signature))); + ACPI_WARNING((AE_INFO, "Invalid table signature found: [%4.4s]", + ACPI_CAST_PTR(char, &signature))); ACPI_DUMP_BUFFER(table_header, sizeof(struct acpi_table_header)); @@ -172,9 +174,13 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) /* Validate the table length */ if (table_header->length < sizeof(struct acpi_table_header)) { - ACPI_REPORT_ERROR(("Invalid length in table header %p name %4.4s\n", table_header, (char *)&signature)); + ACPI_ERROR((AE_INFO, + "Invalid length in table header %p name %4.4s", + table_header, (char *)&signature)); - ACPI_REPORT_WARNING(("Invalid table header length (0x%X) found\n", (u32) table_header->length)); + ACPI_WARNING((AE_INFO, + "Invalid table header length (0x%X) found", + (u32) table_header->length)); ACPI_DUMP_BUFFER(table_header, sizeof(struct acpi_table_header)); @@ -213,7 +219,10 @@ acpi_tb_verify_table_checksum(struct acpi_table_header * table_header) /* Return the appropriate exception */ if (checksum) { - ACPI_REPORT_WARNING(("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n", table_header->signature, (u32) table_header->checksum, (u32) checksum)); + ACPI_WARNING((AE_INFO, + "Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)", + table_header->signature, + (u32) table_header->checksum, (u32) checksum)); status = AE_BAD_CHECKSUM; } @@ -286,7 +295,7 @@ acpi_tb_handle_to_object(u16 table_id, } } - ACPI_REPORT_ERROR(("table_id=%X does not exist\n", table_id)); + ACPI_ERROR((AE_INFO, "table_id=%X does not exist", table_id)); return (AE_BAD_PARAMETER); } #endif diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 83a9ca8cb98c..9fe53c9d5b9a 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -75,8 +75,7 @@ acpi_status acpi_load_tables(void) status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, &rsdp_address); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not get RSDP, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); goto error_exit; } @@ -86,8 +85,7 @@ acpi_status acpi_load_tables(void) status = acpi_tb_verify_rsdp(&rsdp_address); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("RSDP Failed validation: %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); goto error_exit; } @@ -95,8 +93,7 @@ acpi_status acpi_load_tables(void) status = acpi_tb_get_table_rsdt(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not load RSDT: %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); goto error_exit; } @@ -104,7 +101,8 @@ acpi_status acpi_load_tables(void) status = acpi_tb_get_required_tables(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not get all required tables (DSDT/FADT/FACS): %s\n", acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not get all required tables (DSDT/FADT/FACS)")); goto error_exit; } @@ -114,17 +112,14 @@ acpi_status acpi_load_tables(void) status = acpi_ns_load_namespace(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not load namespace: %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); goto error_exit; } return_ACPI_STATUS(AE_OK); error_exit: - ACPI_REPORT_ERROR(("Could not load tables: %s\n", - acpi_format_exception(status))); - + ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index 6538ed818f5b..a62db6af83c9 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c @@ -396,8 +396,8 @@ acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) status = acpi_tb_find_rsdp(&table_info, flags); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("RSDP structure not found, %s Flags=%X\n", - acpi_format_exception(status), flags)); + ACPI_EXCEPTION((AE_INFO, status, + "RSDP structure not found - Flags=%X", flags)); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } @@ -502,7 +502,10 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) ACPI_EBDA_PTR_LENGTH, (void *)&table_ptr); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not map memory at %8.8X for length %X\n", ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH)); return_ACPI_STATUS(status); } @@ -526,7 +529,10 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) ACPI_EBDA_WINDOW_SIZE, (void *)&table_ptr); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not map memory at %8.8X for length %X\n", physical_address, ACPI_EBDA_WINDOW_SIZE)); + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + physical_address, + ACPI_EBDA_WINDOW_SIZE)); return_ACPI_STATUS(status); } @@ -556,7 +562,10 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) (void *)&table_ptr); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not map memory at %8.8X for length %X\n", ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE)); return_ACPI_STATUS(status); } @@ -625,7 +634,7 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) /* A valid RSDP was not found */ - ACPI_REPORT_ERROR(("No valid RSDP was found\n")); + ACPI_ERROR((AE_INFO, "No valid RSDP was found")); return_ACPI_STATUS(AE_NOT_FOUND); } diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 0efcbdf7e620..03b0044974c2 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c @@ -301,8 +301,8 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) /* Check for an inadvertent size of zero bytes */ if (!size) { - _ACPI_REPORT_ERROR(module, line, - ("ut_allocate: Attempt to allocate zero bytes, allocating 1 byte\n")); + ACPI_ERROR((module, line, + "ut_allocate: Attempt to allocate zero bytes, allocating 1 byte")); size = 1; } @@ -310,9 +310,9 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) if (!allocation) { /* Report allocation error */ - _ACPI_REPORT_ERROR(module, line, - ("ut_allocate: Could not allocate size %X\n", - (u32) size)); + ACPI_ERROR((module, line, + "ut_allocate: Could not allocate size %X", + (u32) size)); return_PTR(NULL); } @@ -344,8 +344,8 @@ void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line) /* Check for an inadvertent size of zero bytes */ if (!size) { - _ACPI_REPORT_ERROR(module, line, - ("ut_callocate: Attempt to allocate zero bytes, allocating 1 byte\n")); + ACPI_ERROR((module, line, + "Attempt to allocate zero bytes, allocating 1 byte")); size = 1; } @@ -353,9 +353,8 @@ void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line) if (!allocation) { /* Report allocation error */ - _ACPI_REPORT_ERROR(module, line, - ("ut_callocate: Could not allocate size %X\n", - (u32) size)); + ACPI_ERROR((module, line, + "Could not allocate size %X", (u32) size)); return_PTR(NULL); } @@ -480,9 +479,8 @@ void *acpi_ut_callocate_and_track(acpi_size size, if (!allocation) { /* Report allocation error */ - _ACPI_REPORT_ERROR(module, line, - ("ut_callocate: Could not allocate size %X\n", - (u32) size)); + ACPI_ERROR((module, line, + "Could not allocate size %X", (u32) size)); return (NULL); } @@ -524,8 +522,7 @@ acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line) ACPI_FUNCTION_TRACE_PTR("ut_free", allocation); if (NULL == allocation) { - _ACPI_REPORT_ERROR(module, line, - ("acpi_ut_free: Attempt to delete a NULL address\n")); + ACPI_ERROR((module, line, "Attempt to delete a NULL address")); return_VOID; } @@ -540,14 +537,11 @@ acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line) status = acpi_ut_remove_allocation(debug_block, component, module, line); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not free memory, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "Could not free memory")); } acpi_os_free(debug_block); - ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation)); - return_VOID; } @@ -624,10 +618,12 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, */ element = acpi_ut_find_allocation(allocation); if (element) { - ACPI_REPORT_ERROR(("ut_track_allocation: Allocation already present in list! (%p)\n", allocation)); + ACPI_ERROR((AE_INFO, + "ut_track_allocation: Allocation already present in list! (%p)", + allocation)); - ACPI_REPORT_ERROR(("Element %p Address %p\n", - element, allocation)); + ACPI_ERROR((AE_INFO, "Element %p Address %p", + element, allocation)); goto unlock_and_exit; } @@ -687,8 +683,8 @@ acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation, if (NULL == mem_list->list_head) { /* No allocations! */ - _ACPI_REPORT_ERROR(module, line, - ("ut_remove_allocation: Empty allocation list, nothing to free!\n")); + ACPI_ERROR((module, line, + "Empty allocation list, nothing to free!")); return_ACPI_STATUS(AE_OK); } @@ -863,10 +859,11 @@ void acpi_ut_dump_allocations(u32 component, char *module) /* Print summary */ if (!num_outstanding) { - ACPI_REPORT_INFO(("No outstanding allocations\n")); + ACPI_INFO((AE_INFO, "No outstanding allocations")); } else { - ACPI_REPORT_ERROR(("%d(%X) Outstanding allocations\n", - num_outstanding, num_outstanding)); + ACPI_ERROR((AE_INFO, + "%d(%X) Outstanding allocations", + num_outstanding, num_outstanding)); } return_VOID; diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 1a4da006822a..df2d32096b72 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c @@ -606,7 +606,8 @@ acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object, /* * Packages as external input to control methods are not supported, */ - ACPI_REPORT_ERROR(("Packages as parameters not implemented!\n")); + ACPI_ERROR((AE_INFO, + "Packages as parameters not implemented!")); return_ACPI_STATUS(AE_NOT_IMPLEMENTED); } @@ -869,7 +870,7 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, count + 1) * sizeof(void *)); if (!dest_obj->package.elements) { - ACPI_REPORT_ERROR(("Package allocation failure\n")); + ACPI_ERROR((AE_INFO, "Package allocation failure")); return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 1079a1a1f195..1db9695b0029 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c @@ -363,7 +363,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) default: - ACPI_REPORT_ERROR(("Unknown action (%X)\n", action)); + ACPI_ERROR((AE_INFO, "Unknown action (%X)", action)); break; } @@ -373,7 +373,9 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) */ if (count > ACPI_MAX_REFERENCE_COUNT) { - ACPI_REPORT_WARNING(("Large Reference Count (%X) in object %p\n\n", count, object)); + ACPI_WARNING((AE_INFO, + "Large Reference Count (%X) in object %p", + count, object)); } return; @@ -532,8 +534,8 @@ acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action) error_exit: - ACPI_REPORT_ERROR(("Could not update object reference count, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Could not update object reference count")); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index f4dc374a0eec..106cc97cb4af 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c @@ -154,8 +154,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_ut_get_node_name(prefix_node), path)); } else { - ACPI_REPORT_MTERROR("Method execution failed", - prefix_node, path, status); + ACPI_ERROR_METHOD("Method execution failed", + prefix_node, path, status); } return_ACPI_STATUS(status); @@ -165,8 +165,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, if (!info.return_object) { if (expected_return_btypes) { - ACPI_REPORT_MTERROR("No object was returned from", - prefix_node, path, AE_NOT_EXIST); + ACPI_ERROR_METHOD("No object was returned from", + prefix_node, path, AE_NOT_EXIST); return_ACPI_STATUS(AE_NOT_EXIST); } @@ -211,10 +211,14 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, /* Is the return object one of the expected types? */ if (!(expected_return_btypes & return_btype)) { - ACPI_REPORT_MTERROR("Return object type is incorrect", - prefix_node, path, AE_TYPE); + ACPI_ERROR_METHOD("Return object type is incorrect", + prefix_node, path, AE_TYPE); - ACPI_REPORT_ERROR(("Type returned from %s was incorrect: %s, expected Btypes: %X\n", path, acpi_ut_get_object_type_name(info.return_object), expected_return_btypes)); + ACPI_ERROR((AE_INFO, + "Type returned from %s was incorrect: %s, expected Btypes: %X", + path, + acpi_ut_get_object_type_name(info.return_object), + expected_return_btypes)); /* On error exit, we must delete the return object */ diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 87ca9a0a8b76..ffd13383a325 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -121,8 +121,8 @@ const char *acpi_format_exception(acpi_status status) if (!exception) { /* Exception code was not recognized */ - ACPI_REPORT_ERROR(("Unknown exception code: 0x%8.8X\n", - status)); + ACPI_ERROR((AE_INFO, + "Unknown exception code: 0x%8.8X", status)); exception = "UNKNOWN_STATUS_CODE"; } diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c index 7565ba6f90d5..ba771b4f39bc 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/utilities/utinit.c @@ -72,9 +72,9 @@ static void acpi_ut_fadt_register_error(char *register_name, u32 value, acpi_size offset) { - ACPI_REPORT_WARNING(("Invalid FADT value %s=%X at offset %X FADT=%p\n", - register_name, value, (u32) offset, - acpi_gbl_FADT)); + ACPI_WARNING((AE_INFO, + "Invalid FADT value %s=%X at offset %X FADT=%p", + register_name, value, (u32) offset, acpi_gbl_FADT)); } /****************************************************************************** @@ -221,7 +221,7 @@ void acpi_ut_subsystem_shutdown(void) /* Just exit if subsystem is already shutdown */ if (acpi_gbl_shutdown) { - ACPI_REPORT_ERROR(("ACPI Subsystem is already terminated\n")); + ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); return_VOID; } diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c index 06214201329d..4a3360484e72 100644 --- a/drivers/acpi/utilities/utmath.c +++ b/drivers/acpi/utilities/utmath.c @@ -82,7 +82,7 @@ acpi_ut_short_divide(acpi_integer dividend, /* Always check for a zero divisor */ if (divisor == 0) { - ACPI_REPORT_ERROR(("Divide by zero\n")); + ACPI_ERROR((AE_INFO, "Divide by zero")); return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO); } @@ -144,7 +144,7 @@ acpi_ut_divide(acpi_integer in_dividend, /* Always check for a zero divisor */ if (in_divisor == 0) { - ACPI_REPORT_ERROR(("Divide by zero\n")); + ACPI_ERROR((AE_INFO, "Divide by zero")); return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO); } @@ -266,7 +266,7 @@ acpi_ut_short_divide(acpi_integer in_dividend, /* Always check for a zero divisor */ if (divisor == 0) { - ACPI_REPORT_ERROR(("Divide by zero\n")); + ACPI_ERROR((AE_INFO, "Divide by zero")); return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO); } @@ -292,7 +292,7 @@ acpi_ut_divide(acpi_integer in_dividend, /* Always check for a zero divisor */ if (in_divisor == 0) { - ACPI_REPORT_ERROR(("Divide by zero\n")); + ACPI_ERROR((AE_INFO, "Divide by zero")); return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO); } diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index a77ffcd5570f..7364f5f8c9cd 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -72,8 +72,8 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) /* Guard against multiple allocations of ID to the same location */ if (*owner_id) { - ACPI_REPORT_ERROR(("Owner ID [%2.2X] already exists\n", - *owner_id)); + ACPI_ERROR((AE_INFO, "Owner ID [%2.2X] already exists", + *owner_id)); return_ACPI_STATUS(AE_ALREADY_EXISTS); } @@ -143,7 +143,8 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) * methods, or there may be a bug where the IDs are not released. */ status = AE_OWNER_ID_LIMIT; - ACPI_REPORT_ERROR(("Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT\n")); + ACPI_ERROR((AE_INFO, + "Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT")); exit: (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); @@ -180,7 +181,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) /* Zero is not a valid owner_iD */ if (owner_id == 0) { - ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id)); + ACPI_ERROR((AE_INFO, "Invalid owner_id: %2.2X", owner_id)); return_VOID; } @@ -205,8 +206,9 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) if (acpi_gbl_owner_id_mask[index] & bit) { acpi_gbl_owner_id_mask[index] ^= bit; } else { - ACPI_REPORT_ERROR(("Release of non-allocated owner_id: %2.2X\n", - owner_id + 1)); + ACPI_ERROR((AE_INFO, + "Release of non-allocated owner_id: %2.2X", + owner_id + 1)); } (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); @@ -837,7 +839,71 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) /******************************************************************************* * - * FUNCTION: acpi_ut_report_error + * FUNCTION: acpi_ut_error, acpi_ut_warning, acpi_ut_info + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print message with module/line/version info + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_error(char *module_name, u32 line_number, char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_exception(char *module_name, + u32 line_number, acpi_status status, char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name, + line_number, acpi_format_exception(status)); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_info(char *module_name, u32 line_number, char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_report_error, Warning, Info * * PARAMETERS: module_name - Caller's module name (for error output) * line_number - Caller's line number (for error output) @@ -846,6 +912,8 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) * * DESCRIPTION: Print error message * + * Note: Legacy only, should be removed when no longer used by drivers. + * ******************************************************************************/ void acpi_ut_report_error(char *module_name, u32 line_number) @@ -854,38 +922,12 @@ void acpi_ut_report_error(char *module_name, u32 line_number) acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); } -/******************************************************************************* - * - * FUNCTION: acpi_ut_report_warning - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * - * RETURN: None - * - * DESCRIPTION: Print warning message - * - ******************************************************************************/ - void acpi_ut_report_warning(char *module_name, u32 line_number) { acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); } -/******************************************************************************* - * - * FUNCTION: acpi_ut_report_info - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * - * RETURN: None - * - * DESCRIPTION: Print information message - * - ******************************************************************************/ - void acpi_ut_report_info(char *module_name, u32 line_number) { diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c index ffaff55270b1..45a7244df924 100644 --- a/drivers/acpi/utilities/utmutex.c +++ b/drivers/acpi/utilities/utmutex.c @@ -216,12 +216,20 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) for (i = mutex_id; i < MAX_MUTEX; i++) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { - ACPI_REPORT_ERROR(("Mutex [%s] already acquired by this thread [%X]\n", acpi_ut_get_mutex_name(mutex_id), this_thread_id)); + ACPI_ERROR((AE_INFO, + "Mutex [%s] already acquired by this thread [%X]", + acpi_ut_get_mutex_name + (mutex_id), + this_thread_id)); return (AE_ALREADY_ACQUIRED); } - ACPI_REPORT_ERROR(("Invalid acquire order: Thread %X owns [%s], wants [%s]\n", this_thread_id, acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(mutex_id))); + ACPI_ERROR((AE_INFO, + "Invalid acquire order: Thread %X owns [%s], wants [%s]", + this_thread_id, + acpi_ut_get_mutex_name(i), + acpi_ut_get_mutex_name(mutex_id))); return (AE_ACQUIRE_DEADLOCK); } @@ -244,7 +252,9 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) acpi_gbl_mutex_info[mutex_id].use_count++; acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; } else { - ACPI_REPORT_ERROR(("Thread %X could not acquire Mutex [%X] %s\n", this_thread_id, mutex_id, acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Thread %X could not acquire Mutex [%X]", + this_thread_id, mutex_id)); } return (status); @@ -282,7 +292,9 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) * Mutex must be acquired in order to release it! */ if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) { - ACPI_REPORT_ERROR(("Mutex [%X] is not acquired, cannot release\n", mutex_id)); + ACPI_ERROR((AE_INFO, + "Mutex [%X] is not acquired, cannot release", + mutex_id)); return (AE_NOT_ACQUIRED); } @@ -303,7 +315,10 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) continue; } - ACPI_REPORT_ERROR(("Invalid release order: owns [%s], releasing [%s]\n", acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(mutex_id))); + ACPI_ERROR((AE_INFO, + "Invalid release order: owns [%s], releasing [%s]", + acpi_ut_get_mutex_name(i), + acpi_ut_get_mutex_name(mutex_id))); return (AE_RELEASE_DEADLOCK); } @@ -319,7 +334,9 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) acpi_os_signal_semaphore(acpi_gbl_mutex_info[mutex_id].mutex, 1); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Thread %X could not release Mutex [%X] %s\n", this_thread_id, mutex_id, acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "Thread %X could not release Mutex [%X]", + this_thread_id, mutex_id)); } else { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index 1b6b21577805..7ee2d1d98071 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -177,8 +177,8 @@ union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size) buffer = ACPI_MEM_CALLOCATE(buffer_size); if (!buffer) { - ACPI_REPORT_ERROR(("Could not allocate size %X\n", - (u32) buffer_size)); + ACPI_ERROR((AE_INFO, "Could not allocate size %X", + (u32) buffer_size)); acpi_ut_remove_reference(buffer_desc); return_PTR(NULL); } @@ -229,8 +229,8 @@ union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size) */ string = ACPI_MEM_CALLOCATE(string_size + 1); if (!string) { - ACPI_REPORT_ERROR(("Could not allocate size %X\n", - (u32) string_size)); + ACPI_ERROR((AE_INFO, "Could not allocate size %X", + (u32) string_size)); acpi_ut_remove_reference(string_desc); return_PTR(NULL); } @@ -312,8 +312,8 @@ void *acpi_ut_allocate_object_desc_dbg(char *module_name, object = acpi_os_acquire_object(acpi_gbl_operand_cache); if (!object) { - _ACPI_REPORT_ERROR(module_name, line_number, - ("Could not allocate an object descriptor\n")); + ACPI_ERROR((module_name, line_number, + "Could not allocate an object descriptor")); return_PTR(NULL); } @@ -347,9 +347,9 @@ void acpi_ut_delete_object_desc(union acpi_operand_object *object) /* Object must be an union acpi_operand_object */ if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { - ACPI_REPORT_ERROR(("%p is not an ACPI Operand object [%s]\n", - object, - acpi_ut_get_descriptor_name(object))); + ACPI_ERROR((AE_INFO, + "%p is not an ACPI Operand object [%s]", object, + acpi_ut_get_descriptor_name(object))); return_VOID; } @@ -451,7 +451,10 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, * Notably, Locals and Args are not supported, but this may be * required eventually. */ - ACPI_REPORT_ERROR(("Unsupported Reference opcode=%X in object %p\n", internal_object->reference.opcode, internal_object)); + ACPI_ERROR((AE_INFO, + "Unsupported Reference opcode=%X in object %p", + internal_object->reference.opcode, + internal_object)); status = AE_TYPE; break; } @@ -459,9 +462,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, default: - ACPI_REPORT_ERROR(("Unsupported type=%X in object %p\n", - ACPI_GET_OBJECT_TYPE(internal_object), - internal_object)); + ACPI_ERROR((AE_INFO, "Unsupported type=%X in object %p", + ACPI_GET_OBJECT_TYPE(internal_object), + internal_object)); status = AE_TYPE; break; } diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index 36bf9e4bf529..16461317113f 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c @@ -486,6 +486,7 @@ u32 acpi_ut_get_descriptor_length(void *aml) * RETURN: Status, pointer to the end tag * * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template + * Note: allows a buffer length of zero. * ******************************************************************************/ @@ -504,6 +505,13 @@ acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc, aml = obj_desc->buffer.pointer; end_aml = aml + obj_desc->buffer.length; + /* Allow a buffer length of zero */ + + if (!obj_desc->buffer.length) { + *end_tag = aml; + return_ACPI_STATUS(AE_OK); + } + /* Walk the resource template, one descriptor per iteration */ while (aml < end_aml) { @@ -518,6 +526,14 @@ acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc, if (acpi_ut_get_resource_type(aml) == ACPI_RESOURCE_NAME_END_TAG) { + /* + * There must be at least one more byte in the buffer for + * the 2nd byte of the end_tag + */ + if ((aml + 1) >= end_aml) { + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); + } + /* Return the pointer to the end_tag */ *end_tag = aml; diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index b4bc94883200..308a960871be 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c @@ -75,8 +75,7 @@ acpi_status acpi_initialize_subsystem(void) status = acpi_os_initialize(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("OSL failed to initialize, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization")); return_ACPI_STATUS(status); } @@ -88,8 +87,8 @@ acpi_status acpi_initialize_subsystem(void) status = acpi_ut_mutex_initialize(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Global mutex creation failure, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "During Global Mutex creation")); return_ACPI_STATUS(status); } @@ -99,15 +98,14 @@ acpi_status acpi_initialize_subsystem(void) */ status = acpi_ns_root_initialize(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Namespace initialization failure, %s\n", - acpi_format_exception(status))); + ACPI_EXCEPTION((AE_INFO, status, + "During Namespace initialization")); return_ACPI_STATUS(status); } /* If configured, initialize the AML debugger */ ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); - return_ACPI_STATUS(status); } @@ -154,7 +152,7 @@ acpi_status acpi_enable_subsystem(u32 flags) status = acpi_enable(); if (ACPI_FAILURE(status)) { - ACPI_REPORT_WARNING(("acpi_enable failed\n")); + ACPI_WARNING((AE_INFO, "acpi_enable failed")); return_ACPI_STATUS(status); } } diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 675a32f78329..e27dc8f29972 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20060113 +#define ACPI_CA_VERSION 0x20060127 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, @@ -83,7 +83,7 @@ #define ACPI_MAX_OBJECT_CACHE_DEPTH 96 /* Interpreter operand objects */ /* - * Should the subystem abort the loading of an ACPI table if the + * Should the subsystem abort the loading of an ACPI table if the * table checksum is incorrect? */ #define ACPI_CHECKSUM_ABORT FALSE diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index 97f8e4185e4f..8361820d2970 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -416,13 +416,13 @@ struct acpi_field_info { #define ACPI_CONTROL_PREDICATE_FALSE 0xC3 #define ACPI_CONTROL_PREDICATE_TRUE 0xC4 -#define ACPI_STATE_COMMON /* Two 32-bit fields and a pointer */\ - u8 data_type; /* To differentiate various internal objs */\ +#define ACPI_STATE_COMMON /* Two 32-bit fields and a pointer */\ + u8 data_type; /* To differentiate various internal objs */\ u8 flags; \ u16 value; \ u16 state; \ u16 reserved; \ - void *next; \ + void *next; struct acpi_common_state { ACPI_STATE_COMMON}; @@ -575,8 +575,7 @@ union acpi_parse_value { char aml_op_name[16]) /* Op name (debug only) */\ /* NON-DEBUG members below: */\ struct acpi_namespace_node *node; /* For use by interpreter */\ - union acpi_parse_value value; /* Value or args associated with the opcode */\ - + union acpi_parse_value value; /* Value or args associated with the opcode */ #define ACPI_DASM_BUFFER 0x00 #define ACPI_DASM_RESOURCE 0x01 diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 49ba151766de..f2be2a881730 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -341,8 +341,12 @@ /* * Rounding macros (Power of two boundaries only) */ -#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & (~(((acpi_native_uint) boundary)-1))) -#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + (((acpi_native_uint) boundary)-1)) & (~(((acpi_native_uint) boundary)-1))) +#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & \ + (~(((acpi_native_uint) boundary)-1))) + +#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + \ + (((acpi_native_uint) boundary)-1)) & \ + (~(((acpi_native_uint) boundary)-1))) #define ACPI_ROUND_DOWN_TO_32_BITS(a) ACPI_ROUND_DOWN(a,4) #define ACPI_ROUND_DOWN_TO_64_BITS(a) ACPI_ROUND_DOWN(a,8) @@ -379,10 +383,11 @@ /* Generate a UUID */ -#define ACPI_INIT_UUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) (a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \ - (b) & 0xFF, ((b) >> 8) & 0xFF, \ - (c) & 0xFF, ((c) >> 8) & 0xFF, \ - (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) +#define ACPI_INIT_UUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ + (a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \ + (b) & 0xFF, ((b) >> 8) & 0xFF, \ + (c) & 0xFF, ((c) >> 8) & 0xFF, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) /* * An struct acpi_namespace_node * can appear in some contexts, @@ -442,13 +447,12 @@ #define GET_CURRENT_ARG_TYPE(list) (list & ((u32) 0x1F)) #define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) +#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES) /* * Module name is include in both debug and non-debug versions primarily for * error messages. The __FILE__ macro is not very useful for this, because it * often includes the entire pathname to the module */ -#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES) - #define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_acpi_module_name = name; #else #define ACPI_MODULE_NAME(name) @@ -458,45 +462,31 @@ * Ascii error messages can be configured out */ #ifndef ACPI_NO_ERROR_MESSAGES - -#define ACPI_PARAM_LIST(pl) pl -#define ACPI_LOCATION_INFO _acpi_module_name, __LINE__ +#define AE_INFO _acpi_module_name, __LINE__ /* - * Error reporting. Callers module and line number are inserted automatically - * These macros are used for both the debug and non-debug versions of the code + * Error reporting. Callers module and line number are inserted by AE_INFO, + * the plist contains a set of parens to allow variable-length lists. + * These macros are used for both the debug and non-debug versions of the code. */ -#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info (ACPI_LOCATION_INFO); \ - acpi_os_printf ACPI_PARAM_LIST (fp);} -#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error (ACPI_LOCATION_INFO); \ - acpi_os_printf ACPI_PARAM_LIST (fp);} -#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning (ACPI_LOCATION_INFO); \ - acpi_os_printf ACPI_PARAM_LIST (fp);} -#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error (ACPI_LOCATION_INFO, \ - s, e); -#define ACPI_REPORT_MTERROR(s,n,p,e) acpi_ns_report_method_error (ACPI_LOCATION_INFO, \ - s, n, p, e); +#define ACPI_INFO(plist) acpi_ut_info plist +#define ACPI_WARNING(plist) acpi_ut_warning plist +#define ACPI_EXCEPTION(plist) acpi_ut_exception plist +#define ACPI_ERROR(plist) acpi_ut_error plist +#define ACPI_ERROR_NAMESPACE(s,e) acpi_ns_report_error (AE_INFO, s, e); +#define ACPI_ERROR_METHOD(s,n,p,e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); -/* Error reporting. These versions pass thru the module and lineno */ - -#define _ACPI_REPORT_INFO(a,b,fp) {acpi_ut_report_info (a,b); \ - acpi_os_printf ACPI_PARAM_LIST (fp);} -#define _ACPI_REPORT_ERROR(a,b,fp) {acpi_ut_report_error (a,b); \ - acpi_os_printf ACPI_PARAM_LIST (fp);} -#define _ACPI_REPORT_WARNING(a,b,fp) {acpi_ut_report_warning (a,b); \ - acpi_os_printf ACPI_PARAM_LIST (fp);} #else /* No error messages */ -#define ACPI_REPORT_INFO(fp) -#define ACPI_REPORT_ERROR(fp) -#define ACPI_REPORT_WARNING(fp) -#define ACPI_REPORT_NSERROR(s,e) -#define ACPI_REPORT_MTERROR(s,n,p,e) -#define _ACPI_REPORT_INFO(a,b,c,fp) -#define _ACPI_REPORT_ERROR(a,b,c,fp) -#define _ACPI_REPORT_WARNING(a,b,c,fp) +#define ACPI_INFO(plist) +#define ACPI_WARNING(plist) +#define ACPI_EXCEPTION(plist) +#define ACPI_ERROR(plist) +#define ACPI_ERROR_NAMESPACE(s,e) +#define ACPI_ERROR_METHOD(s,n,p,e) + #endif /* @@ -538,7 +528,7 @@ #endif #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ - acpi_ut_trace(ACPI_DEBUG_PARAMETERS) + acpi_ut_trace(ACPI_DEBUG_PARAMETERS) #define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \ acpi_ut_trace_ptr(ACPI_DEBUG_PARAMETERS,(void *)b) #define ACPI_FUNCTION_TRACE_U32(a,b) ACPI_FUNCTION_NAME(a) \ @@ -632,18 +622,6 @@ #define ACPI_DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d) #define ACPI_DUMP_RESOURCE_LIST(a) acpi_rs_dump_resource_list(a) #define ACPI_DUMP_BUFFER(a,b) acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT) -#define ACPI_BREAK_MSG(a) acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a)) - -/* - * Generate INT3 on ACPI_ERROR (Debug only!) - */ -#define ACPI_ERROR_BREAK -#ifdef ACPI_ERROR_BREAK -#define ACPI_BREAK_ON_ERROR(lvl) if ((lvl)&ACPI_ERROR) \ - acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,"Fatal error encountered\n") -#else -#define ACPI_BREAK_ON_ERROR(lvl) -#endif /* * Master debug print macros @@ -651,8 +629,8 @@ * 1) Debug print for the current component is enabled * 2) Debug error level or trace level for the print statement is enabled */ -#define ACPI_DEBUG_PRINT(pl) acpi_ut_debug_print ACPI_PARAM_LIST(pl) -#define ACPI_DEBUG_PRINT_RAW(pl) acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl) +#define ACPI_DEBUG_PRINT(plist) acpi_ut_debug_print plist +#define ACPI_DEBUG_PRINT_RAW(plist) acpi_ut_debug_print_raw plist #else /* @@ -681,7 +659,6 @@ #define ACPI_DUMP_BUFFER(a,b) #define ACPI_DEBUG_PRINT(pl) #define ACPI_DEBUG_PRINT_RAW(pl) -#define ACPI_BREAK_MSG(a) #define return_VOID return #define return_ACPI_STATUS(s) return(s) diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h index 1bd411962c77..d130cfed8d55 100644 --- a/include/acpi/acobject.h +++ b/include/acpi/acobject.h @@ -69,7 +69,7 @@ u8 type; /* acpi_object_type */\ u16 reference_count; /* For object deletion management */\ union acpi_operand_object *next_object; /* Objects linked to parent NS node */\ - u8 flags; \ + u8 flags; /* Values for flag byte above */ diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 768f63f391cd..970e9a6372c3 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -108,9 +108,9 @@ acpi_status acpi_os_create_lock(acpi_handle * out_handle); void acpi_os_delete_lock(acpi_handle handle); -acpi_native_uint acpi_os_acquire_lock(acpi_handle handle); +acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle); -void acpi_os_release_lock(acpi_handle handle, acpi_native_uint flags); +void acpi_os_release_lock(acpi_handle handle, acpi_cpu_flags flags); /* * Memory allocation and mapping diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 74819e9b4699..7ca89cde706e 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -237,17 +237,22 @@ typedef char *acpi_physical_address; #error unknown ACPI_MACHINE_WIDTH #endif +/* Variable-width type, used instead of clib size_t */ + +typedef acpi_native_uint acpi_size; + /******************************************************************************* * * OS- or compiler-dependent types * + * If the defaults below are not appropriate for the host system, they can + * be defined in the compiler-specific or OS-specific header, and this will + * take precedence. + * ******************************************************************************/ -/* - * If acpi_uintptr_t was not defined in the OS- or compiler-dependent header, - * define it now (use C99 uintptr_t for pointer casting if available, - * "void *" otherwise) - */ +/* Use C99 uintptr_t for pointer casting if available, "void *" otherwise */ + #ifndef acpi_uintptr_t #define acpi_uintptr_t void * #endif @@ -261,9 +266,31 @@ typedef char *acpi_physical_address; #define acpi_cache_t struct acpi_memory_list #endif -/* Variable-width type, used instead of clib size_t */ +/* + * Allow the CPU flags word to be defined per-OS to simplify the use of the + * lock and unlock OSL interfaces. + */ +#ifndef acpi_cpu_flags +#define acpi_cpu_flags acpi_native_uint +#endif -typedef acpi_native_uint acpi_size; +/* + * ACPI_PRINTF_LIKE is used to tag functions as "printf-like" because + * some compilers can catch printf format string problems + */ +#ifndef ACPI_PRINTF_LIKE +#define ACPI_PRINTF_LIKE(c) +#endif + +/* + * Some compilers complain about unused variables. Sometimes we don't want to + * use all the variables (for example, _acpi_module_name). This allows us + * to to tell the compiler in a per-variable manner that a variable + * is unused + */ +#ifndef ACPI_UNUSED_VAR +#define ACPI_UNUSED_VAR +#endif /******************************************************************************* * diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index 10f6625f6390..0927765df6aa 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -275,20 +275,22 @@ acpi_ut_ptr_exit(u32 line_number, const char *function_name, char *module_name, u32 component_id, u8 * ptr); +void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id); + void acpi_ut_report_error(char *module_name, u32 line_number); void acpi_ut_report_info(char *module_name, u32 line_number); void acpi_ut_report_warning(char *module_name, u32 line_number); -void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id); +/* Error and message reporting interfaces */ void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print(u32 requested_debug_level, u32 line_number, const char *function_name, char *module_name, - u32 component_id, char *format, ...) ACPI_PRINTF_LIKE_FUNC; + u32 component_id, char *format, ...) ACPI_PRINTF_LIKE(6); void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print_raw(u32 requested_debug_level, @@ -296,7 +298,24 @@ acpi_ut_debug_print_raw(u32 requested_debug_level, const char *function_name, char *module_name, u32 component_id, - char *format, ...) ACPI_PRINTF_LIKE_FUNC; + char *format, ...) ACPI_PRINTF_LIKE(6); + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_error(char *module_name, + u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_exception(char *module_name, + u32 line_number, + acpi_status status, char *format, ...) ACPI_PRINTF_LIKE(4); + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_warning(char *module_name, + u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_info(char *module_name, + u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); /* * utdelete - Object deletion and reference counts diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 31b0f18342f6..223ec6467108 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -149,6 +149,9 @@ #elif defined(NETWARE) #include "acnetware.h" +#elif defined(__sun) +#include "acsolaris.h" + #else /* All other environments */ @@ -158,13 +161,6 @@ #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long -/* - * This macro is used to tag functions as "printf-like" because - * some compilers can catch printf format string problems. MSVC - * doesn't, so this is proprocessed away. - */ -#define ACPI_PRINTF_LIKE_FUNC - #endif /* diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index ea2a6322f64d..da80933963db 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h @@ -48,12 +48,14 @@ #define ACPI_GET_FUNCTION_NAME __FUNCTION__ -/* This macro is used to tag functions as "printf-like" because +/* + * This macro is used to tag functions as "printf-like" because * some compilers (like GCC) can catch printf format string problems. */ -#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 6, 7))) +#define ACPI_PRINTF_LIKE(c) __attribute__ ((__format__ (__printf__, c, c+1))) -/* Some compilers complain about unused variables. Sometimes we don't want to +/* + * Some compilers complain about unused variables. Sometimes we don't want to * use all the variables (for example, _acpi_module_name). This allows us * to to tell the compiler warning in a per-variable manner that a variable * is unused. diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index c21c27fe7e1e..2e6d54569ee8 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -102,4 +102,6 @@ #include "acgcc.h" +#define acpi_cpu_flags unsigned long + #endif /* __ACLINUX_H__ */ From d99ca4180fe44ae7f409fc73f1a09f270b8d458a Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 26 Jan 2006 16:20:02 -0700 Subject: [PATCH 178/695] [SCSI] scsi_transport_sas.c: display port identifier This patch displays the port identifier on the folder attribute; located in the middle digit. /sys/class/sas_rphy/rphy-%x:%x:%x The port identifier is basically the unique identifier for each sas domain. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_sas.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index a3e0b7bc2d7b..210dab5879fa 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -377,7 +377,7 @@ static void sas_phy_release(struct device *dev) /** * sas_phy_alloc -- allocates and initialize a SAS PHY structure * @parent: Parent device - * @number: Port number + * @number: Phy index * * Allocates an SAS PHY structure. It will be added in the device tree * below the device specified by @parent, which has to be either a Scsi_Host @@ -595,8 +595,8 @@ struct sas_rphy *sas_rphy_alloc(struct sas_phy *parent) device_initialize(&rphy->dev); rphy->dev.parent = get_device(&parent->dev); rphy->dev.release = sas_rphy_release; - sprintf(rphy->dev.bus_id, "rphy-%d:%d", - shost->host_no, parent->number); + sprintf(rphy->dev.bus_id, "rphy-%d:%d-%d", + shost->host_no, parent->port_identifier, parent->number); transport_setup_device(&rphy->dev); return rphy; From c73787eecdbe4691d4e3f989052db8b552e1ac34 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 26 Jan 2006 16:20:06 -0700 Subject: [PATCH 179/695] [SCSI] fusion: add support for raid hot add/del support RAID event support. This will hot add and remove raid volumes when managment application creates and deletes the volumes. The driver is basically responding to firmware asyn events, and reporting the changes to the above layers. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptsas.c | 198 ++++++++++++++++++++++++++++---- 1 file changed, 173 insertions(+), 25 deletions(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 5a06d8d8694e..8e77837c07ec 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -89,6 +89,8 @@ static int mptsasMgmtCtx = -1; enum mptsas_hotplug_action { MPTSAS_ADD_DEVICE, MPTSAS_DEL_DEVICE, + MPTSAS_ADD_RAID, + MPTSAS_DEL_RAID, }; struct mptsas_hotplug_event { @@ -114,6 +116,7 @@ struct mptsas_hotplug_event { struct mptsas_devinfo { u16 handle; /* unique id to address this device */ + u16 handle_parent; /* unique id to address parent device */ u8 phy_id; /* phy number of parent device */ u8 port_id; /* sas physical port this device is assoc'd with */ @@ -714,6 +717,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, mptsas_print_device_pg0(buffer); device_info->handle = le16_to_cpu(buffer->DevHandle); + device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle); device_info->phy_id = buffer->PhyNum; device_info->port_id = buffer->PhysicalPort; device_info->id = buffer->TargetID; @@ -863,6 +867,26 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, return error; } +/* + * Returns true if there is a scsi end device + */ +static inline int +mptsas_is_end_device(struct mptsas_devinfo * attached) +{ + if ((attached->handle) && + (attached->device_info & + MPI_SAS_DEVICE_INFO_END_DEVICE) && + ((attached->device_info & + MPI_SAS_DEVICE_INFO_SSP_TARGET) | + (attached->device_info & + MPI_SAS_DEVICE_INFO_STP_TARGET) | + (attached->device_info & + MPI_SAS_DEVICE_INFO_SATA_DEVICE))) + return 1; + else + return 0; +} + static void mptsas_parse_device_info(struct sas_identify *identify, struct mptsas_devinfo *device_info) @@ -1227,7 +1251,7 @@ mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id) } static struct mptsas_phyinfo * -mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) +mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) { struct mptsas_portinfo *port_info; struct mptsas_phyinfo *phy_info = NULL; @@ -1239,12 +1263,12 @@ mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) */ mutex_lock(&ioc->sas_topology_mutex); list_for_each_entry(port_info, &ioc->sas_topology, list) { - for (i = 0; i < port_info->num_phys; i++) { - if (port_info->phy_info[i].attached.handle == handle) { - phy_info = &port_info->phy_info[i]; - break; - } - } + for (i = 0; i < port_info->num_phys; i++) + if (mptsas_is_end_device(&port_info->phy_info[i].attached)) + if (port_info->phy_info[i].attached.id == id) { + phy_info = &port_info->phy_info[i]; + break; + } } mutex_unlock(&ioc->sas_topology_mutex); @@ -1258,36 +1282,58 @@ mptsas_hotplug_work(void *arg) MPT_ADAPTER *ioc = ev->ioc; struct mptsas_phyinfo *phy_info; struct sas_rphy *rphy; + struct scsi_device *sdev; char *ds = NULL; - - if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) - ds = "ssp"; - if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) - ds = "stp"; - if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) - ds = "sata"; + struct mptsas_devinfo sas_device; switch (ev->event_type) { case MPTSAS_DEL_DEVICE: - printk(MYIOC_s_INFO_FMT - "removing %s device, channel %d, id %d, phy %d\n", - ioc->name, ds, ev->channel, ev->id, ev->phy_id); - phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle); + phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id); if (!phy_info) { printk("mptsas: remove event for non-existant PHY.\n"); break; } + if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) + ds = "ssp"; + if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) + ds = "stp"; + if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) + ds = "sata"; + + printk(MYIOC_s_INFO_FMT + "removing %s device, channel %d, id %d, phy %d\n", + ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); + if (phy_info->rphy) { sas_rphy_delete(phy_info->rphy); phy_info->rphy = NULL; } break; case MPTSAS_ADD_DEVICE: - printk(MYIOC_s_INFO_FMT - "attaching %s device, channel %d, id %d, phy %d\n", - ioc->name, ds, ev->channel, ev->id, ev->phy_id); + + /* + * When there is no sas address, + * RAID volumes are being deleted, + * and hidden phy disk are being added. + * We don't know the SAS data yet, + * so lookup sas device page to get + * pertaining info + */ + if (!ev->sas_address) { + if (mptsas_sas_device_pg0(ioc, + &sas_device, ev->id, + (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << + MPI_SAS_DEVICE_PGAD_FORM_SHIFT))) + break; + ev->handle = sas_device.handle; + ev->parent_handle = sas_device.handle_parent; + ev->channel = sas_device.channel; + ev->phy_id = sas_device.phy_id; + ev->sas_address = sas_device.sas_address; + ev->device_info = sas_device.device_info; + } phy_info = mptsas_find_phyinfo_by_parent(ioc, ev->parent_handle, ev->phy_id); @@ -1310,10 +1356,23 @@ mptsas_hotplug_work(void *arg) phy_info->attached.sas_address = ev->sas_address; phy_info->attached.device_info = ev->device_info; + if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) + ds = "ssp"; + if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) + ds = "stp"; + if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) + ds = "sata"; + + printk(MYIOC_s_INFO_FMT + "attaching %s device, channel %d, id %d, phy %d\n", + ioc->name, ds, ev->channel, ev->id, ev->phy_id); + + rphy = sas_rphy_alloc(phy_info->phy); if (!rphy) break; /* non-fatal: an rphy can be added later */ + rphy->scsi_target_id = phy_info->attached.id; mptsas_parse_device_info(&rphy->identify, &phy_info->attached); if (sas_rphy_add(rphy)) { sas_rphy_free(rphy); @@ -1322,6 +1381,40 @@ mptsas_hotplug_work(void *arg) phy_info->rphy = rphy; break; + case MPTSAS_ADD_RAID: + sdev = scsi_device_lookup( + ioc->sh, + ioc->num_ports, + ev->id, + 0); + if (sdev) { + scsi_device_put(sdev); + break; + } + printk(MYIOC_s_INFO_FMT + "attaching device, channel %d, id %d\n", + ioc->name, ioc->num_ports, ev->id); + scsi_add_device(ioc->sh, + ioc->num_ports, + ev->id, + 0); + mpt_findImVolumes(ioc); + break; + case MPTSAS_DEL_RAID: + sdev = scsi_device_lookup( + ioc->sh, + ioc->num_ports, + ev->id, + 0); + if (!sdev) + break; + printk(MYIOC_s_INFO_FMT + "removing device, channel %d, id %d\n", + ioc->name, ioc->num_ports, ev->id); + scsi_remove_device(sdev); + scsi_device_put(sdev); + mpt_findImVolumes(ioc); + break; } kfree(ev); @@ -1372,23 +1465,78 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, schedule_work(&ev->work); } +static void +mptscsih_send_raid_event(MPT_ADAPTER *ioc, + EVENT_DATA_RAID *raid_event_data) +{ + struct mptsas_hotplug_event *ev; + RAID_VOL0_STATUS * volumeStatus; + + if (ioc->bus_type != SAS) + return; + + ev = kmalloc(sizeof(*ev), GFP_ATOMIC); + if (!ev) { + printk(KERN_WARNING "mptsas: lost hotplug event\n"); + return; + } + + memset(ev,0,sizeof(struct mptsas_hotplug_event)); + INIT_WORK(&ev->work, mptsas_hotplug_work, ev); + ev->ioc = ioc; + ev->id = raid_event_data->VolumeID; + + switch (raid_event_data->ReasonCode) { + case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: + ev->event_type = MPTSAS_ADD_DEVICE; + break; + case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: + ev->event_type = MPTSAS_DEL_DEVICE; + break; + case MPI_EVENT_RAID_RC_VOLUME_DELETED: + ev->event_type = MPTSAS_DEL_RAID; + break; + case MPI_EVENT_RAID_RC_VOLUME_CREATED: + ev->event_type = MPTSAS_ADD_RAID; + break; + case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: + volumeStatus = (RAID_VOL0_STATUS *) & + raid_event_data->SettingsStatus; + ev->event_type = (volumeStatus->State == + MPI_RAIDVOL0_STATUS_STATE_FAILED) ? + MPTSAS_DEL_RAID : MPTSAS_ADD_RAID; + break; + default: + break; + } + schedule_work(&ev->work); +} + static int mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) { + int rc=1; u8 event = le32_to_cpu(reply->Event) & 0xFF; if (!ioc->sh) - return 1; + goto out; switch (event) { case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: mptscsih_send_sas_event(ioc, (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data); - return 1; /* currently means nothing really */ - + break; + case MPI_EVENT_INTEGRATED_RAID: + mptscsih_send_raid_event(ioc, + (EVENT_DATA_RAID *)reply->Data); + break; default: - return mptscsih_event_process(ioc, reply); + rc = mptscsih_event_process(ioc, reply); + break; } + out: + + return rc; } static int From 7d3eecf7b2195c64d26f7e7d105d00e5a6dd702e Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Wed, 25 Jan 2006 18:05:12 -0700 Subject: [PATCH 180/695] [SCSI] fusion: target reset when drive is being removed The issuing of the target reset used in device hot removal case so the firmware queue is flushed out off outstanding commands. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptsas.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 8e77837c07ec..190bd940bb01 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -324,6 +324,7 @@ mptsas_slave_destroy(struct scsi_device *sdev) struct sas_rphy *rphy; struct mptsas_portinfo *p; int i; + VirtDevice *vdev; /* * Handle hotplug removal case. @@ -347,8 +348,29 @@ mptsas_slave_destroy(struct scsi_device *sdev) out: mutex_unlock(&hd->ioc->sas_topology_mutex); /* - * TODO: Issue target reset to flush firmware outstanding commands. + * Issue target reset to flush firmware outstanding commands. */ + vdev = sdev->hostdata; + if (vdev->configured_lun){ + if (mptscsih_TMHandler(hd, + MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, + vdev->bus_id, + vdev->target_id, + 0, 0, 5 /* 5 second timeout */) + < 0){ + + /* The TM request failed! + * Fatal error case. + */ + printk(MYIOC_s_WARN_FMT + "Error processing TaskMgmt id=%d TARGET_RESET\n", + hd->ioc->name, + vdev->target_id); + + hd->tmPending = 0; + hd->tmState = TM_STATE_NONE; + } + } mptscsih_slave_destroy(sdev); } From 79de278e86121cd4473c276409f834aee87f3195 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Wed, 25 Jan 2006 18:05:15 -0700 Subject: [PATCH 181/695] [SCSI] fusion: move sas persistent event handling over to the mptsas module This moves code intented for SAS from the generic mptscsih module over to the mptsas module. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 1 + drivers/message/fusion/mptsas.c | 16 ++++++++++++++++ drivers/message/fusion/mptscsih.c | 19 ------------------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 47053ac65068..5c2ce949fe80 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -631,6 +631,7 @@ typedef struct _MPT_ADAPTER struct mutex sas_topology_mutex; MPT_SAS_MGMT sas_mgmt; int num_ports; + struct work_struct mptscsih_persistTask; struct list_head fc_rports; spinlock_t fc_rport_lock; /* list and ri flags */ diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 190bd940bb01..90660bfa148c 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1534,6 +1534,16 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, schedule_work(&ev->work); } +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* work queue thread to clear the persitency table */ +static void +mptscsih_sas_persist_clear_table(void * arg) +{ + MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; + + mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); +} + static int mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) { @@ -1552,6 +1562,12 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) mptscsih_send_raid_event(ioc, (EVENT_DATA_RAID *)reply->Data); break; + case MPI_EVENT_PERSISTENT_TABLE_FULL: + INIT_WORK(&ioc->mptscsih_persistTask, + mptscsih_sas_persist_clear_table, + (void *)ioc); + schedule_work(&ioc->mptscsih_persistTask); + break; default: rc = mptscsih_event_process(ioc, reply); break; diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index cdac5578fdf2..56c3d1f78f05 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -162,8 +162,6 @@ static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget); static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); -static struct work_struct mptscsih_persistTask; - #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); static void mptscsih_domainValidation(void *hd); @@ -2584,16 +2582,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) return 1; /* currently means nothing really */ } -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* work queue thread to clear the persitency table */ -static void -mptscsih_sas_persist_clear_table(void * arg) -{ - MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; - - mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); -} - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) @@ -2656,13 +2644,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) break; } - /* Persistent table is full. */ - case MPI_EVENT_PERSISTENT_TABLE_FULL: - INIT_WORK(&mptscsih_persistTask, - mptscsih_sas_persist_clear_table,(void *)ioc); - schedule_work(&mptscsih_persistTask); - break; - case MPI_EVENT_NONE: /* 00 */ case MPI_EVENT_LOG_DATA: /* 01 */ case MPI_EVENT_STATE_CHANGE: /* 02 */ From 3bc7bf1d1294642f87c4f7df04c048dafa38ad51 Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Wed, 25 Jan 2006 18:05:18 -0700 Subject: [PATCH 182/695] [SCSI] fusion: FC rport code fixes This fix's problems with recent fc submission regarding i/o being redirected to the wrong target. Signed-off-by: Michael Reed Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/Makefile | 2 + drivers/message/fusion/mptbase.h | 9 +- drivers/message/fusion/mptfc.c | 203 +++++++++++++++++++++---------- 3 files changed, 151 insertions(+), 63 deletions(-) diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 8a2e2657f4c2..33ace373241c 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile @@ -29,6 +29,8 @@ # For mptctl: #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL # +# For mptfc: +#CFLAGS_mptfc.o += -DMPT_DEBUG_FC #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 5c2ce949fe80..47f12b9e58cd 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -510,9 +510,10 @@ struct mptfc_rport_info { struct list_head list; struct fc_rport *rport; - VirtDevice *vdev; + struct scsi_target *starget; FCDevicePage0_t pg0; u8 flags; + u8 remap_needed; }; /* @@ -804,6 +805,12 @@ typedef struct _mpt_sge { #define dreplyprintk(x) #endif +#ifdef DMPT_DEBUG_FC +#define dfcprintk(x) printk x +#else +#define dfcprintk(x) +#endif + #ifdef MPT_DEBUG_TM #define dtmprintk(x) printk x #define DBG_DUMP_TM_REQUEST_FRAME(mfp) \ diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index b102c7666d0e..c3a3499bce2a 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -93,10 +93,11 @@ static int mptfcDoneCtx = -1; static int mptfcTaskCtx = -1; static int mptfcInternalCtx = -1; /* Used only for internal commands */ -int mptfc_slave_alloc(struct scsi_device *device); +static int mptfc_target_alloc(struct scsi_target *starget); +static int mptfc_slave_alloc(struct scsi_device *sdev); static int mptfc_qcmd(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)); - + void (*done)(struct scsi_cmnd *)); +static void mptfc_target_destroy(struct scsi_target *starget); static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout); static void __devexit mptfc_remove(struct pci_dev *pdev); @@ -107,10 +108,10 @@ static struct scsi_host_template mptfc_driver_template = { .name = "MPT FC Host", .info = mptscsih_info, .queuecommand = mptfc_qcmd, - .target_alloc = mptscsih_target_alloc, + .target_alloc = mptfc_target_alloc, .slave_alloc = mptfc_slave_alloc, .slave_configure = mptscsih_slave_configure, - .target_destroy = mptscsih_target_destroy, + .target_destroy = mptfc_target_destroy, .slave_destroy = mptscsih_slave_destroy, .change_queue_depth = mptscsih_change_queue_depth, .eh_abort_handler = mptscsih_abort, @@ -347,15 +348,34 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid) return 0; } +static void +mptfc_remap_sdev(struct scsi_device *sdev, void *arg) +{ + VirtDevice *vdev; + VirtTarget *vtarget; + struct scsi_target *starget; + + starget = scsi_target(sdev); + if (starget->hostdata == arg) { + vtarget = arg; + vdev = sdev->hostdata; + if (vdev) { + vdev->bus_id = vtarget->bus_id; + vdev->target_id = vtarget->target_id; + } + } +} + static void mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) { struct fc_rport_identifiers rport_ids; struct fc_rport *rport; struct mptfc_rport_info *ri; - int match = 0; - u64 port_name; + int new_ri = 1; + u64 pn; unsigned long flags; + VirtTarget *vtarget; if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0) return; @@ -363,14 +383,14 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) /* scan list looking for a match */ spin_lock_irqsave(&ioc->fc_rport_lock, flags); list_for_each_entry(ri, &ioc->fc_rports, list) { - port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; - if (port_name == rport_ids.port_name) { /* match */ + pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; + if (pn == rport_ids.port_name) { /* match */ list_move_tail(&ri->list, &ioc->fc_rports); - match = 1; + new_ri = 0; break; } } - if (!match) { /* allocate one */ + if (new_ri) { /* allocate one */ spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); if (!ri) @@ -382,40 +402,43 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) ri->pg0 = *pg0; /* add/update pg0 data */ ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING; + /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */ if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) { ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED; spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); - rport = fc_remote_port_add(ioc->sh,channel, &rport_ids); + rport = fc_remote_port_add(ioc->sh, channel, &rport_ids); spin_lock_irqsave(&ioc->fc_rport_lock, flags); if (rport) { - if (*((struct mptfc_rport_info **)rport->dd_data) != ri) { - ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV; - ri->vdev = NULL; - ri->rport = rport; - *((struct mptfc_rport_info **)rport->dd_data) = ri; - } - rport->dev_loss_tmo = mptfc_dev_loss_tmo; + ri->rport = rport; + if (new_ri) /* may have been reset by user */ + rport->dev_loss_tmo = mptfc_dev_loss_tmo; + *((struct mptfc_rport_info **)rport->dd_data) = ri; /* * if already mapped, remap here. If not mapped, - * slave_alloc will allocate vdev and map + * target_alloc will allocate vtarget and map, + * slave_alloc will fill in vdev from vtarget. */ - if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) { - ri->vdev->target_id = ri->pg0.CurrentTargetID; - ri->vdev->bus_id = ri->pg0.CurrentBus; - ri->vdev->vtarget->target_id = ri->vdev->target_id; - ri->vdev->vtarget->bus_id = ri->vdev->bus_id; + if (ri->starget) { + vtarget = ri->starget->hostdata; + if (vtarget) { + vtarget->target_id = pg0->CurrentTargetID; + vtarget->bus_id = pg0->CurrentBus; + starget_for_each_device(ri->starget, + vtarget,mptfc_remap_sdev); + } + ri->remap_needed = 0; } - #ifdef MPT_DEBUG - printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " + dfcprintk ((MYIOC_s_INFO_FMT + "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " "rport tid %d, tmo %d\n", - ioc->sh->host_no, + ioc->name, + oc->sh->host_no, pg0->PortIdentifier, pg0->WWNN, pg0->WWPN, pg0->CurrentTargetID, ri->rport->scsi_target_id, - ri->rport->dev_loss_tmo); - #endif + ri->rport->dev_loss_tmo)); } else { list_del(&ri->list); kfree(ri); @@ -426,6 +449,65 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) } +/* + * OS entry point to allow for host driver to free allocated memory + * Called if no device present or device being unloaded + */ +static void +mptfc_target_destroy(struct scsi_target *starget) +{ + struct fc_rport *rport; + struct mptfc_rport_info *ri; + + rport = starget_to_rport(starget); + if (rport) { + ri = *((struct mptfc_rport_info **)rport->dd_data); + if (ri) /* better be! */ + ri->starget = NULL; + } + if (starget->hostdata) + kfree(starget->hostdata); + starget->hostdata = NULL; +} + +/* + * OS entry point to allow host driver to alloc memory + * for each scsi target. Called once per device the bus scan. + * Return non-zero if allocation fails. + */ +static int +mptfc_target_alloc(struct scsi_target *starget) +{ + VirtTarget *vtarget; + struct fc_rport *rport; + struct mptfc_rport_info *ri; + int rc; + + vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); + if (!vtarget) + return -ENOMEM; + starget->hostdata = vtarget; + + rc = -ENODEV; + rport = starget_to_rport(starget); + if (rport) { + ri = *((struct mptfc_rport_info **)rport->dd_data); + if (ri) { /* better be! */ + vtarget->target_id = ri->pg0.CurrentTargetID; + vtarget->bus_id = ri->pg0.CurrentBus; + ri->starget = starget; + ri->remap_needed = 0; + rc = 0; + } + } + if (rc != 0) { + kfree(vtarget); + starget->hostdata = NULL; + } + + return rc; +} + /* * OS entry point to allow host driver to alloc memory * for each scsi device. Called once per device the bus scan. @@ -440,7 +522,6 @@ mptfc_slave_alloc(struct scsi_device *sdev) VirtDevice *vdev; struct scsi_target *starget; struct fc_rport *rport; - struct mptfc_rport_info *ri; unsigned long flags; @@ -451,55 +532,44 @@ mptfc_slave_alloc(struct scsi_device *sdev) hd = (MPT_SCSI_HOST *)sdev->host->hostdata; - vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); + vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); if (!vdev) { printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", hd->ioc->name, sizeof(VirtDevice)); return -ENOMEM; } - memset(vdev, 0, sizeof(VirtDevice)); spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags); - if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) { - spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); - kfree(vdev); - return -ENODEV; - } - sdev->hostdata = vdev; starget = scsi_target(sdev); vtarget = starget->hostdata; + if (vtarget->num_luns == 0) { + vtarget->ioc_id = hd->ioc->id; vtarget->tflags = MPT_TARGET_FLAGS_Q_YES | MPT_TARGET_FLAGS_VALID_INQUIRY; hd->Targets[sdev->id] = vtarget; } - vtarget->target_id = vdev->target_id; - vtarget->bus_id = vdev->bus_id; - vdev->vtarget = vtarget; vdev->ioc_id = hd->ioc->id; vdev->lun = sdev->lun; - vdev->target_id = ri->pg0.CurrentTargetID; - vdev->bus_id = ri->pg0.CurrentBus; - - ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV; - ri->vdev = vdev; + vdev->target_id = vtarget->target_id; + vdev->bus_id = vtarget->bus_id; spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); vtarget->num_luns++; -#ifdef MPT_DEBUG - printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " + dfcprintk ((MYIOC_s_INFO_FMT + "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " "CurrentTargetID %d, %x %llx %llx\n", - sdev->host->host_no, - vtarget->num_luns, - sdev->id, ri->pg0.CurrentTargetID, - ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN); -#endif + ioc->name, + sdev->host->host_no, + vtarget->num_luns, + sdev->id, ri->pg0.CurrentTargetID, + ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN)); return 0; } @@ -507,6 +577,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) static int mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { + struct mptfc_rport_info *ri; struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); int err; @@ -516,6 +587,10 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) done(SCpnt); return 0; } + ri = *((struct mptfc_rport_info **)rport->dd_data); + if (unlikely(ri->remap_needed)) + return SCSI_MLQUEUE_HOST_BUSY; + return mptscsih_qcmd(SCpnt,done); } @@ -591,16 +666,20 @@ mptfc_rescan_devices(void *arg) ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| MPT_RPORT_INFO_FLAGS_MISSING); + ri->remap_needed = 1; fc_remote_port_delete(ri->rport); /* * remote port not really deleted 'cause * binding is by WWPN and driver only - * registers FCP_TARGETs + * registers FCP_TARGETs but cannot trust + * data structures. */ - #ifdef MPT_DEBUG - printk ("mptfc_rescan.%d: %llx deleted\n", - ioc->sh->host_no, ri->pg0.WWPN); - #endif + ri->rport = NULL; + dfcprintk ((MYIOC_s_INFO_FMT + "mptfc_rescan.%d: %llx deleted\n", + ioc->name, + ioc->sh->host_no, + ri->pg0.WWPN)); } } spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); @@ -872,9 +951,8 @@ mptfc_init(void) } error = pci_register_driver(&mptfc_driver); - if (error) { + if (error) fc_release_transport(mptfc_transport_template); - } return error; } @@ -885,7 +963,8 @@ mptfc_init(void) * @pdev: Pointer to pci_dev structure * */ -static void __devexit mptfc_remove(struct pci_dev *pdev) +static void __devexit +mptfc_remove(struct pci_dev *pdev) { MPT_ADAPTER *ioc = pci_get_drvdata(pdev); struct mptfc_rport_info *p, *n; From fda4c2c8d0c9e22e3b9eeb6d75706d876af988f8 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Wed, 25 Jan 2006 18:05:21 -0700 Subject: [PATCH 183/695] [SCSI] fusion: bump version Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 47f12b9e58cd..8e28a022e781 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -76,8 +76,8 @@ #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.03.06" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.06" +#define MPT_LINUX_VERSION_COMMON "3.03.07" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.07" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ From 663e1aa12f9fc338fccee09f98d9f5bf68517f72 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 29 Jan 2006 12:10:24 -0600 Subject: [PATCH 184/695] [SCSI] fusion: fix compile The prior fusion patches moved an invocation of a function, mptscsih_TMHandler(), static to mptscsih.c into mptsas.c Make the function unstatic, move the header to mptscsih.h and export it. Signed-off-by: James Bottomley --- drivers/message/fusion/mptscsih.c | 4 ++-- drivers/message/fusion/mptscsih.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 56c3d1f78f05..aa9cde807632 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -144,7 +144,6 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); -static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); @@ -1528,7 +1527,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) * * Returns 0 for SUCCESS or -1 if FAILED. */ -static int +int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) { MPT_ADAPTER *ioc; @@ -5601,5 +5600,6 @@ EXPORT_SYMBOL(mptscsih_event_process); EXPORT_SYMBOL(mptscsih_ioc_reset); EXPORT_SYMBOL(mptscsih_change_queue_depth); EXPORT_SYMBOL(mptscsih_timer_expired); +EXPORT_SYMBOL(mptscsih_TMHandler); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index d3cba12f4bd9..44b248d51ea3 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -108,3 +108,4 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); extern void mptscsih_timer_expired(unsigned long data); +extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); From 2628ed2b1aa3fd115bb8e14925e180e9ecd07055 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 24 Jan 2006 10:41:45 +0100 Subject: [PATCH 185/695] [SCSI] aic7xxx: Update aicasm This patchset updates aicasm code with the latest fixes from adaptec. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aicasm/aicasm.c | 23 +++-- drivers/scsi/aic7xxx/aicasm/aicasm_gram.y | 19 +++- .../scsi/aic7xxx/aicasm/aicasm_insformat.h | 88 ++++++++++++++++++- drivers/scsi/aic7xxx/aicasm/aicasm_scan.l | 27 ++++-- 4 files changed, 140 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c index f936b691232f..924102720b14 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm.c +++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c @@ -37,7 +37,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#23 $ * * $FreeBSD$ */ @@ -609,10 +609,10 @@ output_listing(char *ifilename) while (line < cur_instr->srcline) { fgets(buf, sizeof(buf), ifile); - fprintf(listfile, "\t\t%s", buf); + fprintf(listfile, " \t%s", buf); line++; } - fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr, + fprintf(listfile, "%04x %02x%02x%02x%02x", instrptr, #ifdef __LITTLE_ENDIAN cur_instr->format.bytes[0], cur_instr->format.bytes[1], @@ -624,14 +624,23 @@ output_listing(char *ifilename) cur_instr->format.bytes[1], cur_instr->format.bytes[0]); #endif - fgets(buf, sizeof(buf), ifile); - fprintf(listfile, "\t%s", buf); - line++; + /* + * Macro expansions can cause several instructions + * to be output for a single source line. Only + * advance the line once in these cases. + */ + if (line == cur_instr->srcline) { + fgets(buf, sizeof(buf), ifile); + fprintf(listfile, "\t%s", buf); + line++; + } else { + fprintf(listfile, "\n"); + } instrptr++; } /* Dump the remainder of the file */ while(fgets(buf, sizeof(buf), ifile) != NULL) - fprintf(listfile, "\t\t%s", buf); + fprintf(listfile, " %s", buf); fclose(ifile); } diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y index 67e046d96625..c328596def3c 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y @@ -38,7 +38,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#30 $ * * $FreeBSD$ */ @@ -157,6 +157,8 @@ static int is_download_const(expression_t *immed); %token T_END_CS +%token T_PAD_PAGE + %token T_FIELD %token T_ENUM @@ -189,6 +191,10 @@ static int is_download_const(expression_t *immed); %token T_OR +/* 16 bit extensions */ +%token T_OR16 T_AND16 T_XOR16 T_ADD16 +%token T_ADC16 T_MVI16 T_TEST16 T_CMP16 T_CMPXCHG + %token T_RET %token T_NOP @@ -207,7 +213,7 @@ static int is_download_const(expression_t *immed); %type expression immediate immediate_or_a -%type export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne +%type export ret f1_opcode f2_opcode f4_opcode jmp_jc_jnc_call jz_jnz je_jne %type mode_value mode_list macro_arglist @@ -1304,6 +1310,15 @@ f2_opcode: | T_ROR { $$ = AIC_OP_ROR; } ; +f4_opcode: + T_OR16 { $$ = AIC_OP_OR16; } +| T_AND16 { $$ = AIC_OP_AND16; } +| T_XOR16 { $$ = AIC_OP_XOR16; } +| T_ADD16 { $$ = AIC_OP_ADD16; } +| T_ADC16 { $$ = AIC_OP_ADC16; } +| T_MVI16 { $$ = AIC_OP_MVI16; } +; + code: f2_opcode destination ',' expression opt_source ret ';' { diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h index e64f802bbaaa..9df9e2ce3538 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h @@ -37,13 +37,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#11 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#12 $ * * $FreeBSD$ */ #include +/* 8bit ALU logic operations */ struct ins_format1 { #ifdef __LITTLE_ENDIAN uint32_t immediate : 8, @@ -62,6 +63,7 @@ struct ins_format1 { #endif }; +/* 8bit ALU shift/rotate operations */ struct ins_format2 { #ifdef __LITTLE_ENDIAN uint32_t shift_control : 8, @@ -80,6 +82,7 @@ struct ins_format2 { #endif }; +/* 8bit branch control operations */ struct ins_format3 { #ifdef __LITTLE_ENDIAN uint32_t immediate : 8, @@ -96,10 +99,68 @@ struct ins_format3 { #endif }; +/* 16bit ALU logic operations */ +struct ins_format4 { +#ifdef __LITTLE_ENDIAN + uint32_t opcode_ext : 8, + source : 9, + destination : 9, + ret : 1, + opcode : 4, + parity : 1; +#else + uint32_t parity : 1, + opcode : 4, + ret : 1, + destination : 9, + source : 9, + opcode_ext : 8; +#endif +}; + +/* 16bit branch control operations */ +struct ins_format5 { +#ifdef __LITTLE_ENDIAN + uint32_t opcode_ext : 8, + source : 9, + address : 10, + opcode : 4, + parity : 1; +#else + uint32_t parity : 1, + opcode : 4, + address : 10, + source : 9, + opcode_ext : 8; +#endif +}; + +/* Far branch operations */ +struct ins_format6 { +#ifdef __LITTLE_ENDIAN + uint32_t page : 3, + opcode_ext : 5, + source : 9, + address : 10, + opcode : 4, + parity : 1; +#else + uint32_t parity : 1, + opcode : 4, + address : 10, + source : 9, + opcode_ext : 5, + page : 3; +#endif +}; + union ins_formats { struct ins_format1 format1; struct ins_format2 format2; struct ins_format3 format3; + struct ins_format4 format4; + struct ins_format5 format5; + struct ins_format6 format6; uint8_t bytes[4]; uint32_t integer; }; @@ -118,6 +179,8 @@ struct instruction { #define AIC_OP_ROL 0x5 #define AIC_OP_BMOV 0x6 +#define AIC_OP_MVI16 0x7 + #define AIC_OP_JMP 0x8 #define AIC_OP_JC 0x9 #define AIC_OP_JNC 0xa @@ -131,3 +194,26 @@ struct instruction { #define AIC_OP_SHL 0x10 #define AIC_OP_SHR 0x20 #define AIC_OP_ROR 0x30 + +/* 16bit Ops. Low byte main opcode. High byte extended opcode. */ +#define AIC_OP_OR16 0x8005 +#define AIC_OP_AND16 0x8105 +#define AIC_OP_XOR16 0x8205 +#define AIC_OP_ADD16 0x8305 +#define AIC_OP_ADC16 0x8405 +#define AIC_OP_JNE16 0x8805 +#define AIC_OP_JNZ16 0x8905 +#define AIC_OP_JE16 0x8C05 +#define AIC_OP_JZ16 0x8B05 +#define AIC_OP_JMP16 0x9005 +#define AIC_OP_JC16 0x9105 +#define AIC_OP_JNC16 0x9205 +#define AIC_OP_CALL16 0x9305 +#define AIC_OP_CALL16 0x9305 + +/* Page extension is low three bits of second opcode byte. */ +#define AIC_OP_JMPF 0xA005 +#define AIC_OP_CALLF 0xB005 +#define AIC_OP_JCF 0xC005 +#define AIC_OP_JNCF 0xD005 +#define AIC_OP_CMPXCHG 0xE005 diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l index 45c0b233d0bc..7c3983f868a9 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l @@ -38,7 +38,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#19 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#20 $ * * $FreeBSD$ */ @@ -132,7 +132,7 @@ if[ \t]*\( { *string_buf_ptr++ = *yptr++; } } - +else { return T_ELSE; } VERSION { return T_VERSION; } PREFIX { return T_PREFIX; } PATCH_ARG_LIST { return T_PATCH_ARG_LIST; } @@ -173,10 +173,6 @@ RW|RO|WO { yylval.value = WO; return T_MODE; } -BEGIN_CRITICAL { return T_BEGIN_CS; } -END_CRITICAL { return T_END_CS; } -SET_SRC_MODE { return T_SET_SRC_MODE; } -SET_DST_MODE { return T_SET_DST_MODE; } field { return T_FIELD; } enum { return T_ENUM; } mask { return T_MASK; } @@ -192,6 +188,13 @@ none { return T_NONE; } sindex { return T_SINDEX; } A { return T_A; } + /* Instruction Formatting */ +PAD_PAGE { return T_PAD_PAGE; } +BEGIN_CRITICAL { return T_BEGIN_CS; } +END_CRITICAL { return T_END_CS; } +SET_SRC_MODE { return T_SET_SRC_MODE; } +SET_DST_MODE { return T_SET_DST_MODE; } + /* Opcodes */ shl { return T_SHL; } shr { return T_SHR; } @@ -223,7 +226,17 @@ and { return T_AND; } or { return T_OR; } ret { return T_RET; } nop { return T_NOP; } -else { return T_ELSE; } + + /* ARP2 16bit extensions */ +or16 { return T_OR16; } +and16 { return T_AND16; } +xor16 { return T_XOR16; } +add16 { return T_ADD16; } +adc16 { return T_ADC16; } +mvi16 { return T_MVI16; } +test16 { return T_TEST16; } +cmp16 { return T_CMP16; } +cmpxchg { return T_CMPXCHG; } /* Allowed Symbols */ \<\< { return T_EXPR_LSHIFT; } From 53467e636b7beb350c307cc88323aae4676577f2 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 24 Jan 2006 10:43:26 +0100 Subject: [PATCH 186/695] [SCSI] aic79xx: sequencer fixes This patch updates the aic79xx sequencer with latest fixes from adaptec. The sequencer code now corresponds with adaptec version 2.0.15. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx.reg | 29 +- drivers/scsi/aic7xxx/aic79xx.seq | 143 ++- drivers/scsi/aic7xxx/aic79xx_core.c | 260 ++++-- drivers/scsi/aic7xxx/aic79xx_inline.h | 7 +- drivers/scsi/aic7xxx/aic79xx_osm.h | 2 +- drivers/scsi/aic7xxx/aic79xx_osm_pci.c | 17 +- drivers/scsi/aic7xxx/aic79xx_reg.h_shipped | 27 +- .../scsi/aic7xxx/aic79xx_reg_print.c_shipped | 21 +- drivers/scsi/aic7xxx/aic79xx_seq.h_shipped | 881 +++++++++--------- 9 files changed, 834 insertions(+), 553 deletions(-) diff --git a/drivers/scsi/aic7xxx/aic79xx.reg b/drivers/scsi/aic7xxx/aic79xx.reg index 3a3204703b15..be14e2ecb8f7 100644 --- a/drivers/scsi/aic7xxx/aic79xx.reg +++ b/drivers/scsi/aic7xxx/aic79xx.reg @@ -1,7 +1,7 @@ /* * Aic79xx register and scratch ram definitions. * - * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 1994-2001, 2004 Justin T. Gibbs. * Copyright (c) 2000-2002 Adaptec Inc. * All rights reserved. * @@ -39,7 +39,7 @@ * * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#76 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $" /* * This file is processed by the aic7xxx_asm utility for use in assembling @@ -3715,8 +3715,9 @@ scratch_ram { SEQ_FLAGS2 { size 1 - field TARGET_MSG_PENDING 0x02 - field SELECTOUT_QFROZEN 0x04 + field PENDING_MK_MESSAGE 0x01 + field TARGET_MSG_PENDING 0x02 + field SELECTOUT_QFROZEN 0x04 } ALLOCFIFO_SCBPTR { @@ -3777,6 +3778,26 @@ scratch_ram { CMDSIZE_TABLE { size 8 } + /* + * When an SCB with the MK_MESSAGE flag is + * queued to the controller, it cannot enter + * the waiting for selection list until the + * selections for any previously queued + * commands to that target complete. During + * the wait, the MK_MESSAGE SCB is queued + * here. + */ + MK_MESSAGE_SCB { + size 2 + } + /* + * Saved SCSIID of MK_MESSAGE_SCB to avoid + * an extra SCBPTR operation when deciding + * if the MK_MESSAGE_SCB can be run. + */ + MK_MESSAGE_SCSIID { + size 1 + } } /************************* Hardware SCB Definition ****************************/ diff --git a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq index bef1f9d369b6..58bc17591b54 100644 --- a/drivers/scsi/aic7xxx/aic79xx.seq +++ b/drivers/scsi/aic7xxx/aic79xx.seq @@ -1,7 +1,7 @@ /* * Adaptec U320 device driver firmware for Linux and FreeBSD. * - * Copyright (c) 1994-2001 Justin T. Gibbs. + * Copyright (c) 1994-2001, 2004 Justin T. Gibbs. * Copyright (c) 2000-2002 Adaptec Inc. * All rights reserved. * @@ -40,7 +40,7 @@ * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $" PATCH_ARG_LIST = "struct ahd_softc *ahd" PREFIX = "ahd_" @@ -110,10 +110,8 @@ check_waiting_list: * one last time. */ test SSTAT0, SELDO jnz select_out; -END_CRITICAL; call start_selection; idle_loop_checkbus: -BEGIN_CRITICAL; test SSTAT0, SELDO jnz select_out; END_CRITICAL; test SSTAT0, SELDI jnz select_in; @@ -294,7 +292,6 @@ fetch_new_scb_inprog: test CCSCBCTL, ARRDONE jz return; fetch_new_scb_done: and CCSCBCTL, ~(CCARREN|CCSCBEN); - bmov REG0, SCBPTR, 2; clr A; add CMDS_PENDING, 1; adc CMDS_PENDING[1], A; @@ -316,43 +313,117 @@ fetch_new_scb_done: clr SCB_FIFO_USE_COUNT; /* Update the next SCB address to download. */ bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4; + /* + * NULL out the SCB links since these fields + * occupy the same location as SCB_NEXT_SCB_BUSADDR. + */ mvi SCB_NEXT[1], SCB_LIST_NULL; mvi SCB_NEXT2[1], SCB_LIST_NULL; /* Increment our position in the QINFIFO. */ mov NONE, SNSCB_QOFF; + /* - * SCBs that want to send messages are always - * queued independently. This ensures that they - * are at the head of the SCB list to select out - * to a target and we will see the MK_MESSAGE flag. + * Save SCBID of this SCB in REG0 since + * SCBPTR will be clobbered during target + * list updates. We also record the SCB's + * flags so that we can refer to them even + * after SCBPTR has been changed. + */ + bmov REG0, SCBPTR, 2; + mov A, SCB_CONTROL; + + /* + * Find the tail SCB of the execution queue + * for this target. */ - test SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb; shr SINDEX, 3, SCB_SCSIID; and SINDEX, ~0x1; mvi SINDEX[1], (WAITING_SCB_TAILS >> 8); bmov DINDEX, SINDEX, 2; bmov SCBPTR, SINDIR, 2; + + /* + * Update the tail to point to the new SCB. + */ bmov DINDIR, REG0, 2; + + /* + * If the queue was empty, queue this SCB as + * the first for this target. + */ cmp SCBPTR[1], SCB_LIST_NULL je first_new_target_scb; + + /* + * SCBs that want to send messages must always be + * at the head of their per-target queue so that + * ATN can be asserted even if the current + * negotiation agreement is packetized. If the + * target queue is empty, the SCB can be queued + * immediately. If the queue is not empty, we must + * wait for it to empty before entering this SCB + * into the waiting for selection queue. Otherwise + * our batching and round-robin selection scheme + * could allow commands to be queued out of order. + * To simplify the implementation, we stop pulling + * new commands from the host until the MK_MESSAGE + * SCB can be queued to the waiting for selection + * list. + */ + test A, MK_MESSAGE jz batch_scb; + + /* + * If the last SCB is also a MK_MESSAGE SCB, then + * order is preserved even if we batch. + */ + test SCB_CONTROL, MK_MESSAGE jz batch_scb; + + /* + * Defer this SCB and stop fetching new SCBs until + * it can be queued. Since the SCB_SCSIID of the + * tail SCB must be the same as that of the newly + * queued SCB, there is no need to restore the SCBID + * here. + */ + or SEQ_FLAGS2, PENDING_MK_MESSAGE; + bmov MK_MESSAGE_SCB, REG0, 2; + mov MK_MESSAGE_SCSIID, SCB_SCSIID ret; + +batch_scb: + /* + * Otherwise just update the previous tail SCB to + * point to the new tail. + */ bmov SCB_NEXT, REG0, 2 ret; + first_new_target_scb: + /* + * Append SCB to the tail of the waiting for + * selection list. + */ cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb; bmov SCBPTR, WAITING_TID_TAIL, 2; bmov SCB_NEXT2, REG0, 2; bmov WAITING_TID_TAIL, REG0, 2 ret; first_new_scb: + /* + * Whole list is empty, so the head of + * the list must be initialized too. + */ bmov WAITING_TID_HEAD, REG0, 2; bmov WAITING_TID_TAIL, REG0, 2 ret; END_CRITICAL; scbdma_idle: /* - * Give precedence to downloading new SCBs to execute - * unless select-outs are currently frozen. + * Don't bother downloading new SCBs to execute + * if select-outs are currently frozen or we have + * a MK_MESSAGE SCB waiting to enter the queue. */ - test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2; + test SEQ_FLAGS2, SELECTOUT_QFROZEN|PENDING_MK_MESSAGE + jnz scbdma_no_new_scbs; BEGIN_CRITICAL; test QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb; +scbdma_no_new_scbs: cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb; cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return; /* FALLTHROUGH */ @@ -671,27 +742,41 @@ curscb_ww_done: } /* - * Requeue any SCBs not sent, to the tail of the waiting Q. + * The whole list made it. Clear our tail pointer to indicate + * that the per-target selection queue is now empty. */ - cmp SCB_NEXT[1], SCB_LIST_NULL je select_out_list_done; + cmp SCB_NEXT[1], SCB_LIST_NULL je select_out_clear_tail; /* + * Requeue any SCBs not sent, to the tail of the waiting Q. * We know that neither the per-TID list nor the list of - * TIDs is empty. Use this knowledge to our advantage. + * TIDs is empty. Use this knowledge to our advantage and + * queue the remainder to the tail of the global execution + * queue. */ bmov REG0, SCB_NEXT, 2; +select_out_queue_remainder: bmov SCBPTR, WAITING_TID_TAIL, 2; bmov SCB_NEXT2, REG0, 2; bmov WAITING_TID_TAIL, REG0, 2; jmp select_out_inc_tid_q; -select_out_list_done: +select_out_clear_tail: /* - * The whole list made it. Just clear our TID's tail pointer - * unless we were queued independently due to our need to - * send a message. + * Queue any pending MK_MESSAGE SCB for this target now + * that the queue is empty. + */ + test SEQ_FLAGS2, PENDING_MK_MESSAGE jz select_out_no_mk_message_scb; + mov A, MK_MESSAGE_SCSIID; + cmp SCB_SCSIID, A jne select_out_no_mk_message_scb; + and SEQ_FLAGS2, ~PENDING_MK_MESSAGE; + bmov REG0, MK_MESSAGE_SCB, 2; + jmp select_out_queue_remainder; + +select_out_no_mk_message_scb: + /* + * Clear this target's execution tail and increment the queue. */ - test SCB_CONTROL, MK_MESSAGE jnz select_out_inc_tid_q; shr DINDEX, 3, SCB_SCSIID; or DINDEX, 1; /* Want only the second byte */ mvi DINDEX[1], ((WAITING_SCB_TAILS) >> 8); @@ -703,8 +788,8 @@ select_out_inc_tid_q: mvi WAITING_TID_TAIL[1], SCB_LIST_NULL; bmov SCBPTR, CURRSCB, 2; mvi CLRSINT0, CLRSELDO; - test LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase; - test LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase; + test LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_mode_cleared; + test LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_mode_cleared; /* * If this is a packetized connection, return to our @@ -2127,6 +2212,18 @@ SET_DST_MODE M_DFF0; mvi DFFSXFRCTL, CLRCHN; unexpected_nonpkt_mode_cleared: mvi CLRSINT2, CLRNONPACKREQ; + if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { + /* + * Test to ensure that the bus has not + * already gone free prior to clearing + * any stale busfree status. This avoids + * a window whereby a busfree just after + * a selection could be missed. + */ + test SCSISIGI, BSYI jz . + 2; + mvi CLRSINT1,CLRBUSFREE; + or SIMODE1, ENBUSFREE; + } test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase; SET_SEQINTCODE(ENTERING_NONPACK) jmp ITloop; diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index db8f5ce99ee3..dfd4cc93c05c 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -37,7 +37,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#247 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#250 $ */ #ifdef __linux__ @@ -197,7 +197,8 @@ static int ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, int lun, u_int tag, role_t role, uint32_t status, ahd_search_action action, - u_int *list_head, u_int tid); + u_int *list_head, u_int *list_tail, + u_int tid); static void ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev, u_int tid_cur, u_int tid_next); @@ -1660,7 +1661,8 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) * so just clear the error. */ ahd_outb(ahd, CLRLQIINT1, CLRLQICRCI_NLQ); - } else if ((status & BUSFREE) != 0) { + } else if ((status & BUSFREE) != 0 + || (lqistat1 & LQOBUSFREE) != 0) { u_int lqostat1; int restart; int clear_fifo; @@ -2025,10 +2027,6 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime) u_int waiting_t; u_int next; - if ((busfreetime & BUSFREE_LQO) == 0) - printf("%s: Warning, BUSFREE time is 0x%x. " - "Expected BUSFREE_LQO.\n", - ahd_name(ahd), busfreetime); /* * The LQO manager detected an unexpected busfree * either: @@ -2251,8 +2249,14 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) struct ahd_tmode_tstate *tstate; /* - * PPR Rejected. Try non-ppr negotiation - * and retry command. + * PPR Rejected. + * + * If the previous negotiation was packetized, + * this could be because the device has been + * reset without our knowledge. Force our + * current negotiation to async and retry the + * negotiation. Otherwise retry the command + * with non-ppr negotiation. */ #ifdef AHD_DEBUG if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) @@ -2261,11 +2265,34 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, devinfo.our_scsiid, devinfo.target, &tstate); - tinfo->curr.transport_version = 2; - tinfo->goal.transport_version = 2; - tinfo->goal.ppr_options = 0; - ahd_qinfifo_requeue_tail(ahd, scb); - printerror = 0; + if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ)!=0) { + ahd_set_width(ahd, &devinfo, + MSG_EXT_WDTR_BUS_8_BIT, + AHD_TRANS_CUR, + /*paused*/TRUE); + ahd_set_syncrate(ahd, &devinfo, + /*period*/0, /*offset*/0, + /*ppr_options*/0, + AHD_TRANS_CUR, + /*paused*/TRUE); + /* + * The expect PPR busfree handler below + * will effect the retry and necessary + * abort. + */ + } else { + tinfo->curr.transport_version = 2; + tinfo->goal.transport_version = 2; + tinfo->goal.ppr_options = 0; + /* + * Remove any SCBs in the waiting for selection + * queue that may also be for this target so + * that command ordering is preserved. + */ + ahd_freeze_devq(ahd, scb); + ahd_qinfifo_requeue_tail(ahd, scb); + printerror = 0; + } } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) && ppr_busfree == 0) { /* @@ -2280,6 +2307,12 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) MSG_EXT_WDTR_BUS_8_BIT, AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); + /* + * Remove any SCBs in the waiting for selection + * queue that may also be for this target so that + * command ordering is preserved. + */ + ahd_freeze_devq(ahd, scb); ahd_qinfifo_requeue_tail(ahd, scb); printerror = 0; } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) @@ -2297,6 +2330,12 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); + /* + * Remove any SCBs in the waiting for selection + * queue that may also be for this target so that + * command ordering is preserved. + */ + ahd_freeze_devq(ahd, scb); ahd_qinfifo_requeue_tail(ahd, scb); printerror = 0; } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 @@ -2369,14 +2408,14 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) */ printf("%s: ", ahd_name(ahd)); } - if (lastphase != P_BUSFREE) - ahd_force_renegotiation(ahd, &devinfo); printf("Unexpected busfree %s, %d SCBs aborted, " "PRGMCNT == 0x%x\n", ahd_lookup_phase_entry(lastphase)->phasemsg, aborted, ahd_inw(ahd, PRGMCNT)); ahd_dump_card_state(ahd); + if (lastphase != P_BUSFREE) + ahd_force_renegotiation(ahd, &devinfo); } /* Always restart the sequencer. */ return (1); @@ -3315,7 +3354,6 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) { struct scb *pending_scb; int pending_scb_count; - u_int scb_tag; int paused; u_int saved_scbptr; ahd_mode_state saved_modes; @@ -3333,7 +3371,6 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) pending_scb_count = 0; LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { struct ahd_devinfo devinfo; - struct hardware_scb *pending_hscb; struct ahd_initiator_tinfo *tinfo; struct ahd_tmode_tstate *tstate; @@ -3341,11 +3378,10 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, devinfo.our_scsiid, devinfo.target, &tstate); - pending_hscb = pending_scb->hscb; if ((tstate->auto_negotiate & devinfo.target_mask) == 0 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) { pending_scb->flags &= ~SCB_AUTO_NEGOTIATE; - pending_hscb->control &= ~MK_MESSAGE; + pending_scb->hscb->control &= ~MK_MESSAGE; } ahd_sync_scb(ahd, pending_scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); @@ -3377,18 +3413,15 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); saved_scbptr = ahd_get_scbptr(ahd); /* Ensure that the hscbs down on the card match the new information */ - for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) { - struct hardware_scb *pending_hscb; + LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + u_int scb_tag; u_int control; - pending_scb = ahd_lookup_scb(ahd, scb_tag); - if (pending_scb == NULL) - continue; + scb_tag = SCB_GET_TAG(pending_scb); ahd_set_scbptr(ahd, scb_tag); - pending_hscb = pending_scb->hscb; control = ahd_inb_scbram(ahd, SCB_CONTROL); control &= ~MK_MESSAGE; - control |= pending_hscb->control & MK_MESSAGE; + control |= pending_scb->hscb->control & MK_MESSAGE; ahd_outb(ahd, SCB_CONTROL, control); } ahd_set_scbptr(ahd, saved_scbptr); @@ -6500,13 +6533,14 @@ ahd_chip_init(struct ahd_softc *ahd) | ENLQIOVERI_LQ|ENLQIOVERI_NLQ); ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC); /* - * An interrupt from LQOBUSFREE is made redundant by the - * BUSFREE interrupt. We choose to have the sequencer catch - * LQOPHCHGINPKT errors manually for the command phase at the - * start of a packetized selection case. - ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE|ENLQOPHACHGINPKT); + * We choose to have the sequencer catch LQOPHCHGINPKT errors + * manually for the command phase at the start of a packetized + * selection case. ENLQOBUSFREE should be made redundant by + * the BUSFREE interrupt, but it seems that some LQOBUSFREE + * events fail to assert the BUSFREE interrupt so we must + * also enable LQOBUSFREE interrupts. */ - ahd_outb(ahd, LQOMODE1, 0); + ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE); /* * Setup sequencer interrupt handlers. @@ -6617,6 +6651,8 @@ ahd_chip_init(struct ahd_softc *ahd) /* We don't have any waiting selections */ ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL); ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL); + ahd_outw(ahd, MK_MESSAGE_SCB, SCB_LIST_NULL); + ahd_outw(ahd, MK_MESSAGE_SCSIID, 0xFF); for (i = 0; i < AHD_NUM_TARGETS; i++) ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL); @@ -7260,12 +7296,28 @@ ahd_reset_cmds_pending(struct ahd_softc *ahd) ahd->flags &= ~AHD_UPDATE_PEND_CMDS; } +void +ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status) +{ + cam_status ostat; + cam_status cstat; + + ostat = ahd_get_transaction_status(scb); + if (ostat == CAM_REQ_INPROG) + ahd_set_transaction_status(scb, status); + cstat = ahd_get_transaction_status(scb); + if (cstat != CAM_REQ_CMP) + ahd_freeze_scb(scb); + ahd_done(ahd, scb); +} + int ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, int lun, u_int tag, role_t role, uint32_t status, ahd_search_action action) { struct scb *scb; + struct scb *mk_msg_scb; struct scb *prev_scb; ahd_mode_state saved_modes; u_int qinstart; @@ -7274,6 +7326,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, u_int tid_next; u_int tid_prev; u_int scbid; + u_int seq_flags2; u_int savedscbptr; uint32_t busaddr; int found; @@ -7329,23 +7382,10 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, found++; switch (action) { case SEARCH_COMPLETE: - { - cam_status ostat; - cam_status cstat; - - ostat = ahd_get_transaction_status(scb); - if (ostat == CAM_REQ_INPROG) - ahd_set_transaction_status(scb, - status); - cstat = ahd_get_transaction_status(scb); - if (cstat != CAM_REQ_CMP) - ahd_freeze_scb(scb); if ((scb->flags & SCB_ACTIVE) == 0) printf("Inactive SCB in qinfifo\n"); - ahd_done(ahd, scb); - + ahd_done_with_status(ahd, scb, status); /* FALLTHROUGH */ - } case SEARCH_REMOVE: break; case SEARCH_PRINT: @@ -7375,21 +7415,24 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, * looking for matches. */ ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + seq_flags2 = ahd_inb(ahd, SEQ_FLAGS2); + if ((seq_flags2 & PENDING_MK_MESSAGE) != 0) { + scbid = ahd_inw(ahd, MK_MESSAGE_SCB); + mk_msg_scb = ahd_lookup_scb(ahd, scbid); + } else + mk_msg_scb = NULL; savedscbptr = ahd_get_scbptr(ahd); tid_next = ahd_inw(ahd, WAITING_TID_HEAD); tid_prev = SCB_LIST_NULL; targets = 0; for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) { u_int tid_head; + u_int tid_tail; - /* - * We limit based on the number of SCBs since - * MK_MESSAGE SCBs are not in the per-tid lists. - */ targets++; - if (targets > AHD_SCB_MAX) { + if (targets > AHD_NUM_TARGETS) panic("TID LIST LOOP"); - } + if (scbid >= ahd->scb_data.numscbs) { printf("%s: Waiting TID List inconsistency. " "SCB index == 0x%x, yet numscbs == 0x%x.", @@ -7419,8 +7462,71 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, tid_head = scbid; found += ahd_search_scb_list(ahd, target, channel, lun, tag, role, status, - action, &tid_head, + action, &tid_head, &tid_tail, SCB_GET_TARGET(ahd, scb)); + /* + * Check any MK_MESSAGE SCB that is still waiting to + * enter this target's waiting for selection queue. + */ + if (mk_msg_scb != NULL + && ahd_match_scb(ahd, mk_msg_scb, target, channel, + lun, tag, role)) { + + /* + * We found an scb that needs to be acted on. + */ + found++; + switch (action) { + case SEARCH_COMPLETE: + if ((mk_msg_scb->flags & SCB_ACTIVE) == 0) + printf("Inactive SCB pending MK_MSG\n"); + ahd_done_with_status(ahd, mk_msg_scb, status); + /* FALLTHROUGH */ + case SEARCH_REMOVE: + { + u_int tail_offset; + + printf("Removing MK_MSG scb\n"); + + /* + * Reset our tail to the tail of the + * main per-target list. + */ + tail_offset = WAITING_SCB_TAILS + + (2 * SCB_GET_TARGET(ahd, mk_msg_scb)); + ahd_outw(ahd, tail_offset, tid_tail); + + seq_flags2 &= ~PENDING_MK_MESSAGE; + ahd_outb(ahd, SEQ_FLAGS2, seq_flags2); + ahd_outw(ahd, CMDS_PENDING, + ahd_inw(ahd, CMDS_PENDING)-1); + mk_msg_scb = NULL; + break; + } + case SEARCH_PRINT: + printf(" 0x%x", SCB_GET_TAG(scb)); + /* FALLTHROUGH */ + case SEARCH_COUNT: + break; + } + } + + if (mk_msg_scb != NULL + && SCBID_IS_NULL(tid_head) + && ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD, + SCB_LIST_NULL, ROLE_UNKNOWN)) { + + /* + * When removing the last SCB for a target + * queue with a pending MK_MESSAGE scb, we + * must queue the MK_MESSAGE scb. + */ + printf("Queueing mk_msg_scb\n"); + tid_head = ahd_inw(ahd, MK_MESSAGE_SCB); + seq_flags2 &= ~PENDING_MK_MESSAGE; + ahd_outb(ahd, SEQ_FLAGS2, seq_flags2); + mk_msg_scb = NULL; + } if (tid_head != scbid) ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next); if (!SCBID_IS_NULL(tid_head)) @@ -7428,6 +7534,8 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, if (action == SEARCH_PRINT) printf(")\n"); } + + /* Restore saved state. */ ahd_set_scbptr(ahd, savedscbptr); ahd_restore_modes(ahd, saved_modes); return (found); @@ -7436,7 +7544,8 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, static int ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, int lun, u_int tag, role_t role, uint32_t status, - ahd_search_action action, u_int *list_head, u_int tid) + ahd_search_action action, u_int *list_head, + u_int *list_tail, u_int tid) { struct scb *scb; u_int scbid; @@ -7448,6 +7557,7 @@ ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, found = 0; prev = SCB_LIST_NULL; next = *list_head; + *list_tail = SCB_LIST_NULL; for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) { if (scbid >= ahd->scb_data.numscbs) { printf("%s:SCB List inconsistency. " @@ -7463,6 +7573,7 @@ ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, panic("Waiting List traversal\n"); } ahd_set_scbptr(ahd, scbid); + *list_tail = scbid; next = ahd_inw_scbram(ahd, SCB_NEXT); if (ahd_match_scb(ahd, scb, target, channel, lun, SCB_LIST_NULL, role) == 0) { @@ -7472,24 +7583,14 @@ ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, found++; switch (action) { case SEARCH_COMPLETE: - { - cam_status ostat; - cam_status cstat; - - ostat = ahd_get_transaction_status(scb); - if (ostat == CAM_REQ_INPROG) - ahd_set_transaction_status(scb, status); - cstat = ahd_get_transaction_status(scb); - if (cstat != CAM_REQ_CMP) - ahd_freeze_scb(scb); if ((scb->flags & SCB_ACTIVE) == 0) printf("Inactive SCB in Waiting List\n"); - ahd_done(ahd, scb); + ahd_done_with_status(ahd, scb, status); /* FALLTHROUGH */ - } case SEARCH_REMOVE: ahd_rem_wscb(ahd, scbid, prev, next, tid); - if (prev == SCB_LIST_NULL) + *list_tail = prev; + if (SCBID_IS_NULL(prev)) *list_head = next; break; case SEARCH_PRINT: @@ -7558,14 +7659,17 @@ ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, } /* - * SCBs that had MK_MESSAGE set in them will not - * be queued to the per-target lists, so don't - * blindly clear the tail pointer. + * SCBs that have MK_MESSAGE set in them may + * cause the tail pointer to be updated without + * setting the next pointer of the previous tail. + * Only clear the tail if the removed SCB was + * the tail. */ tail_offset = WAITING_SCB_TAILS + (2 * tid); if (SCBID_IS_NULL(next) && ahd_inw(ahd, tail_offset) == scbid) ahd_outw(ahd, tail_offset, prev); + ahd_add_scb_to_free_list(ahd, scbid); return (next); } @@ -8793,6 +8897,9 @@ ahd_dump_card_state(struct ahd_softc *ahd) * Mode independent registers. */ cur_col = 0; + ahd_intstat_print(ahd_inb(ahd, INTSTAT), &cur_col, 50); + ahd_seloid_print(ahd_inb(ahd, SELOID), &cur_col, 50); + ahd_selid_print(ahd_inb(ahd, SELID), &cur_col, 50); ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50); ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50); ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50); @@ -8808,6 +8915,12 @@ ahd_dump_card_state(struct ahd_softc *ahd) ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50); ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50); ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50); + ahd_qfreeze_count_print(ahd_inw(ahd, QFREEZE_COUNT), &cur_col, 50); + ahd_kernel_qfreeze_count_print(ahd_inw(ahd, KERNEL_QFREEZE_COUNT), + &cur_col, 50); + ahd_mk_message_scb_print(ahd_inw(ahd, MK_MESSAGE_SCB), &cur_col, 50); + ahd_mk_message_scsiid_print(ahd_inb(ahd, MK_MESSAGE_SCSIID), + &cur_col, 50); ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50); ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50); ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50); @@ -8915,7 +9028,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); fifo_scbptr = ahd_get_scbptr(ahd); - printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n", + printf("\n\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n", ahd_name(ahd), i, (dffstat & (FIFO0FREE << i)) ? "Free" : "Active", ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr); @@ -8970,6 +9083,9 @@ ahd_dump_card_state(struct ahd_softc *ahd) printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n", ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT), ahd_inb(ahd, MAXCMDCNT)); + printf("%s: SAVED_SCSIID = 0x%x SAVED_LUN = 0x%x\n", + ahd_name(ahd), ahd_inb(ahd, SAVED_SCSIID), + ahd_inb(ahd, SAVED_LUN)); ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50); printf("\n"); ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h index 91c4f7f484b1..8ad3ce945b9e 100644 --- a/drivers/scsi/aic7xxx/aic79xx_inline.h +++ b/drivers/scsi/aic7xxx/aic79xx_inline.h @@ -37,7 +37,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#58 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#59 $ * * $FreeBSD$ */ @@ -804,9 +804,10 @@ ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb) uint64_t host_dataptr; host_dataptr = ahd_le64toh(scb->hscb->dataptr); - printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n", + printf("%s: Queueing SCB %d:0x%x bus addr 0x%x - 0x%x%x/0x%x\n", ahd_name(ahd), - SCB_GET_TAG(scb), ahd_le32toh(scb->hscb->hscb_busaddr), + SCB_GET_TAG(scb), scb->hscb->scsiid, + ahd_le32toh(scb->hscb->hscb_busaddr), (u_int)((host_dataptr >> 32) & 0xFFFFFFFF), (u_int)(host_dataptr & 0xFFFFFFFF), ahd_le32toh(scb->hscb->datacnt)); diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index cb74fccc8100..854fc57c304c 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#137 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#166 $ * */ #ifndef _AIC79XX_LINUX_H_ diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index bf360ae021ab..ebbf7e4ff4cc 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c @@ -220,10 +220,10 @@ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base, *base2 = pci_resource_start(ahd->dev_softc, 3); if (*base == 0 || *base2 == 0) return (ENOMEM); - if (request_region(*base, 256, "aic79xx") == 0) + if (!request_region(*base, 256, "aic79xx")) return (ENOMEM); - if (request_region(*base2, 256, "aic79xx") == 0) { - release_region(*base2, 256); + if (!request_region(*base2, 256, "aic79xx")) { + release_region(*base, 256); return (ENOMEM); } return (0); @@ -237,7 +237,7 @@ ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, u_long start; u_long base_page; u_long base_offset; - int error; + int error = 0; if (aic79xx_allow_memio == 0) return (ENOMEM); @@ -245,16 +245,15 @@ ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) != 0) return (ENOMEM); - error = 0; start = pci_resource_start(ahd->dev_softc, 1); base_page = start & PAGE_MASK; base_offset = start - base_page; if (start != 0) { *bus_addr = start; - if (request_mem_region(start, 0x1000, "aic79xx") == 0) + if (!request_mem_region(start, 0x1000, "aic79xx")) error = ENOMEM; - if (error == 0) { - *maddr = ioremap_nocache(base_page, base_offset + 256); + if (!error) { + *maddr = ioremap_nocache(base_page, base_offset + 512); if (*maddr == NULL) { error = ENOMEM; release_mem_region(start, 0x1000); @@ -344,7 +343,7 @@ ahd_pci_map_int(struct ahd_softc *ahd) error = request_irq(ahd->dev_softc->irq, ahd_linux_isr, SA_SHIRQ, "aic79xx", ahd); - if (error == 0) + if (!error) ahd->platform_data->irq = ahd->dev_softc->irq; return (-error); diff --git a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped index 8763b158856b..2068e00d2c75 100644 --- a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped +++ b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped @@ -2,8 +2,8 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#76 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $ */ typedef int (ahd_reg_print_t)(u_int, u_int *, u_int); typedef struct ahd_reg_parse_entry { @@ -2203,6 +2203,20 @@ ahd_reg_print_t ahd_cmdsize_table_print; ahd_print_register(NULL, 0, "CMDSIZE_TABLE", 0x158, regvalue, cur_col, wrap) #endif +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_mk_message_scb_print; +#else +#define ahd_mk_message_scb_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MK_MESSAGE_SCB", 0x160, regvalue, cur_col, wrap) +#endif + +#if AIC_DEBUG_REGISTERS +ahd_reg_print_t ahd_mk_message_scsiid_print; +#else +#define ahd_mk_message_scsiid_print(regvalue, cur_col, wrap) \ + ahd_print_register(NULL, 0, "MK_MESSAGE_SCSIID", 0x162, regvalue, cur_col, wrap) +#endif + #if AIC_DEBUG_REGISTERS ahd_reg_print_t ahd_scb_base_print; #else @@ -3638,6 +3652,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; #define SEQ_FLAGS2 0x14d #define SELECTOUT_QFROZEN 0x04 #define TARGET_MSG_PENDING 0x02 +#define PENDING_MK_MESSAGE 0x01 #define ALLOCFIFO_SCBPTR 0x14e @@ -3655,6 +3670,10 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; #define CMDSIZE_TABLE 0x158 +#define MK_MESSAGE_SCB 0x160 + +#define MK_MESSAGE_SCSIID 0x162 + #define SCB_BASE 0x180 #define SCB_RESIDUAL_DATACNT 0x180 @@ -3800,5 +3819,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; /* Exported Labels */ -#define LABEL_seq_isr 0x285 -#define LABEL_timer_isr 0x281 +#define LABEL_seq_isr 0x28f +#define LABEL_timer_isr 0x28b diff --git a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped index a4137c985376..db38a61a8cb4 100644 --- a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped +++ b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped @@ -2,8 +2,8 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#118 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#75 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $ */ #include "aic79xx_osm.h" @@ -3382,6 +3382,7 @@ ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap) } static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = { + { "PENDING_MK_MESSAGE", 0x01, 0x01 }, { "TARGET_MSG_PENDING", 0x02, 0x02 }, { "SELECTOUT_QFROZEN", 0x04, 0x04 } }; @@ -3389,7 +3390,7 @@ static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = { int ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap) { - return (ahd_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2", + return (ahd_print_register(SEQ_FLAGS2_parse_table, 3, "SEQ_FLAGS2", 0x14d, regvalue, cur_col, wrap)); } @@ -3449,6 +3450,20 @@ ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap) 0x158, regvalue, cur_col, wrap)); } +int +ahd_mk_message_scb_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MK_MESSAGE_SCB", + 0x160, regvalue, cur_col, wrap)); +} + +int +ahd_mk_message_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap) +{ + return (ahd_print_register(NULL, 0, "MK_MESSAGE_SCSIID", + 0x162, regvalue, cur_col, wrap)); +} + int ahd_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap) { diff --git a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped index b1e5365be230..11bed07e90b7 100644 --- a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped +++ b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped @@ -2,17 +2,17 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#76 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $ */ static uint8_t seqprog[] = { 0xff, 0x02, 0x06, 0x78, - 0x00, 0xea, 0x64, 0x59, + 0x00, 0xea, 0x6e, 0x59, 0x01, 0xea, 0x04, 0x30, 0xff, 0x04, 0x0c, 0x78, - 0x19, 0xea, 0x64, 0x59, + 0x19, 0xea, 0x6e, 0x59, 0x19, 0xea, 0x04, 0x00, - 0x33, 0xea, 0x5e, 0x59, + 0x33, 0xea, 0x68, 0x59, 0x33, 0xea, 0x00, 0x00, 0x60, 0x3a, 0x3a, 0x68, 0x04, 0x4d, 0x35, 0x78, @@ -33,15 +33,15 @@ static uint8_t seqprog[] = { 0xff, 0xea, 0x62, 0x02, 0x00, 0xe2, 0x3a, 0x40, 0xff, 0x21, 0x3b, 0x70, - 0x40, 0x4b, 0xaa, 0x69, - 0x00, 0xe2, 0x68, 0x59, - 0x40, 0x4b, 0xaa, 0x69, - 0x20, 0x4b, 0x96, 0x69, + 0x40, 0x4b, 0xb4, 0x69, + 0x00, 0xe2, 0x72, 0x59, + 0x40, 0x4b, 0xb4, 0x69, + 0x20, 0x4b, 0xa0, 0x69, 0xfc, 0x42, 0x44, 0x78, 0x10, 0x40, 0x44, 0x78, - 0x00, 0xe2, 0xfc, 0x5d, + 0x00, 0xe2, 0x10, 0x5e, 0x20, 0x4d, 0x48, 0x78, - 0x00, 0xe2, 0xfc, 0x5d, + 0x00, 0xe2, 0x10, 0x5e, 0x30, 0x3f, 0xc0, 0x09, 0x30, 0xe0, 0x50, 0x60, 0x7f, 0x4a, 0x94, 0x08, @@ -51,7 +51,7 @@ static uint8_t seqprog[] = { 0x00, 0xe2, 0x76, 0x58, 0x00, 0xe2, 0x86, 0x58, 0x00, 0xe2, 0x06, 0x40, - 0x33, 0xea, 0x5e, 0x59, + 0x33, 0xea, 0x68, 0x59, 0x33, 0xea, 0x00, 0x00, 0x01, 0x52, 0x84, 0x78, 0x02, 0x58, 0x50, 0x31, @@ -59,26 +59,26 @@ static uint8_t seqprog[] = { 0xff, 0x97, 0x6f, 0x78, 0x50, 0x4b, 0x6a, 0x68, 0xbf, 0x3a, 0x74, 0x08, - 0x14, 0xea, 0x64, 0x59, + 0x14, 0xea, 0x6e, 0x59, 0x14, 0xea, 0x04, 0x00, 0x08, 0x92, 0x25, 0x03, 0xff, 0x90, 0x5f, 0x68, - 0x00, 0xe2, 0x76, 0x5b, + 0x00, 0xe2, 0x8a, 0x5b, 0x00, 0xe2, 0x5e, 0x40, - 0x00, 0xea, 0x5e, 0x59, + 0x00, 0xea, 0x68, 0x59, 0x01, 0xea, 0x00, 0x30, 0x80, 0xf9, 0x7e, 0x68, - 0x00, 0xe2, 0x5c, 0x59, - 0x11, 0xea, 0x5e, 0x59, + 0x00, 0xe2, 0x66, 0x59, + 0x11, 0xea, 0x68, 0x59, 0x11, 0xea, 0x00, 0x00, - 0x80, 0xf9, 0x5c, 0x79, + 0x80, 0xf9, 0x66, 0x79, 0xff, 0xea, 0xd4, 0x0d, - 0x22, 0xea, 0x5e, 0x59, + 0x22, 0xea, 0x68, 0x59, 0x22, 0xea, 0x00, 0x00, 0x10, 0x16, 0x90, 0x78, 0x10, 0x16, 0x2c, 0x00, 0x01, 0x0b, 0xae, 0x32, - 0x18, 0xad, 0x12, 0x79, + 0x18, 0xad, 0x1c, 0x79, 0x04, 0xad, 0xdc, 0x68, 0x80, 0xad, 0x84, 0x78, 0x10, 0xad, 0xaa, 0x78, @@ -118,7 +118,6 @@ static uint8_t seqprog[] = { 0x80, 0x18, 0x30, 0x04, 0x40, 0xad, 0x84, 0x78, 0xe7, 0xad, 0x5a, 0x09, - 0x02, 0xa8, 0x40, 0x31, 0xff, 0xea, 0xc0, 0x09, 0x01, 0x54, 0xa9, 0x1a, 0x00, 0x55, 0xab, 0x22, @@ -128,24 +127,30 @@ static uint8_t seqprog[] = { 0xff, 0xea, 0x5a, 0x03, 0xff, 0xea, 0x5e, 0x03, 0x01, 0x10, 0xd4, 0x31, - 0x10, 0x92, 0x07, 0x69, + 0x02, 0xa8, 0x40, 0x31, + 0x01, 0x92, 0xc1, 0x31, 0x3d, 0x93, 0xc5, 0x29, 0xfe, 0xe2, 0xc4, 0x09, 0x01, 0xea, 0xc6, 0x01, 0x02, 0xe2, 0xc8, 0x31, 0x02, 0xec, 0x50, 0x31, 0x02, 0xa0, 0xda, 0x31, - 0xff, 0xa9, 0x06, 0x71, + 0xff, 0xa9, 0x10, 0x71, + 0x10, 0xe0, 0x0e, 0x79, + 0x10, 0x92, 0x0f, 0x79, + 0x01, 0x4d, 0x9b, 0x02, + 0x02, 0xa0, 0xc0, 0x32, + 0x01, 0x93, 0xc5, 0x36, 0x02, 0xa0, 0x58, 0x37, - 0xff, 0x21, 0x0f, 0x71, + 0xff, 0x21, 0x19, 0x71, 0x02, 0x22, 0x51, 0x31, 0x02, 0xa0, 0x5c, 0x33, 0x02, 0xa0, 0x44, 0x36, 0x02, 0xa0, 0x40, 0x32, 0x02, 0xa0, 0x44, 0x36, - 0x04, 0x4d, 0x17, 0x69, - 0x40, 0x16, 0x48, 0x69, - 0xff, 0x2d, 0x4d, 0x61, + 0x05, 0x4d, 0x21, 0x69, + 0x40, 0x16, 0x52, 0x69, + 0xff, 0x2d, 0x57, 0x61, 0xff, 0x29, 0x85, 0x70, 0x02, 0x28, 0x55, 0x32, 0x01, 0xea, 0x5a, 0x01, @@ -159,22 +164,22 @@ static uint8_t seqprog[] = { 0x01, 0x56, 0xad, 0x1a, 0xff, 0x54, 0xa9, 0x1a, 0xff, 0x55, 0xab, 0x22, - 0xff, 0x8d, 0x41, 0x71, - 0x80, 0xac, 0x40, 0x71, - 0x20, 0x16, 0x40, 0x69, + 0xff, 0x8d, 0x4b, 0x71, + 0x80, 0xac, 0x4a, 0x71, + 0x20, 0x16, 0x4a, 0x69, 0x00, 0xac, 0xc4, 0x19, - 0x07, 0xe2, 0x40, 0xf9, + 0x07, 0xe2, 0x4a, 0xf9, 0x02, 0x8c, 0x51, 0x31, - 0x00, 0xe2, 0x24, 0x41, + 0x00, 0xe2, 0x2e, 0x41, 0x01, 0xac, 0x08, 0x31, 0x09, 0xea, 0x5a, 0x01, 0x02, 0x8c, 0x51, 0x32, 0xff, 0xea, 0x1a, 0x07, 0x04, 0x24, 0xf9, 0x30, - 0x1d, 0xea, 0x52, 0x41, + 0x1d, 0xea, 0x5c, 0x41, 0x02, 0x2c, 0x51, 0x31, 0x04, 0xa8, 0xf9, 0x30, - 0x19, 0xea, 0x52, 0x41, + 0x19, 0xea, 0x5c, 0x41, 0x06, 0xea, 0x08, 0x81, 0x01, 0xe2, 0x5a, 0x35, 0x02, 0xf2, 0xf0, 0x31, @@ -190,27 +195,27 @@ static uint8_t seqprog[] = { 0x02, 0x20, 0xb9, 0x30, 0x02, 0x20, 0x51, 0x31, 0x4c, 0x93, 0xd7, 0x28, - 0x10, 0x92, 0x77, 0x79, + 0x10, 0x92, 0x81, 0x79, 0x01, 0x6b, 0xc0, 0x30, 0x02, 0x64, 0xc8, 0x00, 0x40, 0x3a, 0x74, 0x04, 0x00, 0xe2, 0x76, 0x58, - 0x33, 0xea, 0x5e, 0x59, + 0x33, 0xea, 0x68, 0x59, 0x33, 0xea, 0x00, 0x00, 0x30, 0x3f, 0xc0, 0x09, - 0x30, 0xe0, 0x78, 0x61, - 0x20, 0x3f, 0x8e, 0x69, - 0x10, 0x3f, 0x78, 0x79, + 0x30, 0xe0, 0x82, 0x61, + 0x20, 0x3f, 0x98, 0x69, + 0x10, 0x3f, 0x82, 0x79, 0x02, 0xea, 0x7e, 0x00, - 0x00, 0xea, 0x5e, 0x59, + 0x00, 0xea, 0x68, 0x59, 0x01, 0xea, 0x00, 0x30, 0x02, 0x4e, 0x51, 0x35, 0x01, 0xea, 0x7e, 0x00, - 0x11, 0xea, 0x5e, 0x59, + 0x11, 0xea, 0x68, 0x59, 0x11, 0xea, 0x00, 0x00, 0x02, 0x4e, 0x51, 0x35, 0xc0, 0x4a, 0x94, 0x00, - 0x04, 0x41, 0x9c, 0x79, + 0x04, 0x41, 0xa6, 0x79, 0x08, 0xea, 0x98, 0x00, 0x08, 0x57, 0xae, 0x00, 0x08, 0x3c, 0x78, 0x00, @@ -218,12 +223,12 @@ static uint8_t seqprog[] = { 0x0f, 0x67, 0xc0, 0x09, 0x00, 0x3a, 0x75, 0x02, 0x20, 0xea, 0x96, 0x00, - 0x00, 0xe2, 0x14, 0x42, + 0x00, 0xe2, 0x28, 0x42, 0xc0, 0x4a, 0x94, 0x00, - 0x40, 0x3a, 0xc8, 0x69, + 0x40, 0x3a, 0xd2, 0x69, 0x02, 0x55, 0x06, 0x68, - 0x02, 0x56, 0xc8, 0x69, - 0xff, 0x5b, 0xc8, 0x61, + 0x02, 0x56, 0xd2, 0x69, + 0xff, 0x5b, 0xd2, 0x61, 0x02, 0x20, 0x51, 0x31, 0x80, 0xea, 0xb2, 0x01, 0x44, 0xea, 0x00, 0x00, @@ -231,40 +236,45 @@ static uint8_t seqprog[] = { 0x33, 0xea, 0x00, 0x00, 0xff, 0xea, 0xb2, 0x09, 0xff, 0xe0, 0xc0, 0x19, - 0xff, 0xe0, 0xca, 0x79, + 0xff, 0xe0, 0xd4, 0x79, 0x02, 0xac, 0x51, 0x31, - 0x00, 0xe2, 0xc0, 0x41, + 0x00, 0xe2, 0xca, 0x41, 0x02, 0x5e, 0x50, 0x31, 0x02, 0xa8, 0xb8, 0x30, 0x02, 0x5c, 0x50, 0x31, - 0xff, 0xad, 0xdb, 0x71, + 0xff, 0xad, 0xe5, 0x71, 0x02, 0xac, 0x41, 0x31, 0x02, 0x22, 0x51, 0x31, 0x02, 0xa0, 0x5c, 0x33, 0x02, 0xa0, 0x44, 0x32, - 0x00, 0xe2, 0xe4, 0x41, - 0x10, 0x92, 0xe5, 0x69, + 0x00, 0xe2, 0xf8, 0x41, + 0x01, 0x4d, 0xf1, 0x79, + 0x01, 0x62, 0xc1, 0x31, + 0x00, 0x93, 0xf1, 0x61, + 0xfe, 0x4d, 0x9b, 0x0a, + 0x02, 0x60, 0x41, 0x31, + 0x00, 0xe2, 0xdc, 0x41, 0x3d, 0x93, 0xc9, 0x29, 0x01, 0xe4, 0xc8, 0x01, 0x01, 0xea, 0xca, 0x01, 0xff, 0xea, 0xda, 0x01, 0x02, 0x20, 0x51, 0x31, 0x02, 0xae, 0x41, 0x32, - 0xff, 0x21, 0xed, 0x61, + 0xff, 0x21, 0x01, 0x62, 0xff, 0xea, 0x46, 0x02, 0x02, 0x5c, 0x50, 0x31, 0x40, 0xea, 0x96, 0x00, - 0x02, 0x56, 0x04, 0x6e, - 0x01, 0x55, 0x04, 0x6e, - 0x10, 0x92, 0xf9, 0x79, - 0x10, 0x40, 0x02, 0x6a, - 0x01, 0x56, 0x02, 0x7a, + 0x02, 0x56, 0x20, 0x6e, + 0x01, 0x55, 0x20, 0x6e, + 0x10, 0x92, 0x0d, 0x7a, + 0x10, 0x40, 0x16, 0x6a, + 0x01, 0x56, 0x16, 0x7a, 0xff, 0x97, 0x07, 0x78, - 0x13, 0xea, 0x64, 0x59, + 0x13, 0xea, 0x6e, 0x59, 0x13, 0xea, 0x04, 0x00, 0x00, 0xe2, 0x06, 0x40, 0xbf, 0x3a, 0x74, 0x08, - 0x04, 0x41, 0x08, 0x7a, + 0x04, 0x41, 0x1c, 0x7a, 0x08, 0xea, 0x98, 0x00, 0x08, 0x57, 0xae, 0x00, 0x01, 0x93, 0x75, 0x32, @@ -272,108 +282,108 @@ static uint8_t seqprog[] = { 0x40, 0xea, 0x72, 0x02, 0x08, 0x3c, 0x78, 0x00, 0x80, 0xea, 0x6e, 0x02, - 0x00, 0xe2, 0xe2, 0x5b, + 0x00, 0xe2, 0xf6, 0x5b, 0x01, 0x3c, 0xc1, 0x31, - 0x9f, 0xe0, 0x84, 0x7c, - 0x80, 0xe0, 0x28, 0x72, - 0xa0, 0xe0, 0x64, 0x72, - 0xc0, 0xe0, 0x5a, 0x72, - 0xe0, 0xe0, 0x94, 0x72, - 0x01, 0xea, 0x64, 0x59, + 0x9f, 0xe0, 0x98, 0x7c, + 0x80, 0xe0, 0x3c, 0x72, + 0xa0, 0xe0, 0x78, 0x72, + 0xc0, 0xe0, 0x6e, 0x72, + 0xe0, 0xe0, 0xa8, 0x72, + 0x01, 0xea, 0x6e, 0x59, 0x01, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x14, 0x42, - 0x80, 0x39, 0x2f, 0x7a, - 0x03, 0xea, 0x64, 0x59, + 0x00, 0xe2, 0x28, 0x42, + 0x80, 0x39, 0x43, 0x7a, + 0x03, 0xea, 0x6e, 0x59, 0x03, 0xea, 0x04, 0x00, - 0xee, 0x00, 0x36, 0x6a, + 0xee, 0x00, 0x4a, 0x6a, 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x5e, 0x59, + 0x33, 0xea, 0x68, 0x59, 0x33, 0xea, 0x00, 0x00, 0x02, 0xa8, 0x9c, 0x32, - 0x00, 0xe2, 0x7e, 0x59, + 0x00, 0xe2, 0x88, 0x59, 0xef, 0x96, 0xd5, 0x19, - 0x00, 0xe2, 0x46, 0x52, + 0x00, 0xe2, 0x5a, 0x52, 0x09, 0x80, 0xe1, 0x30, 0x02, 0xea, 0x36, 0x00, 0xa8, 0xea, 0x32, 0x00, - 0x00, 0xe2, 0x4c, 0x42, + 0x00, 0xe2, 0x60, 0x42, 0x01, 0x96, 0xd1, 0x30, 0x10, 0x80, 0x89, 0x31, 0x20, 0xea, 0x32, 0x00, 0xbf, 0x39, 0x73, 0x0a, - 0x10, 0x4c, 0x56, 0x6a, - 0x20, 0x19, 0x4e, 0x6a, - 0x20, 0x19, 0x52, 0x6a, - 0x02, 0x4d, 0x14, 0x6a, + 0x10, 0x4c, 0x6a, 0x6a, + 0x20, 0x19, 0x62, 0x6a, + 0x20, 0x19, 0x66, 0x6a, + 0x02, 0x4d, 0x28, 0x6a, 0x40, 0x39, 0x73, 0x02, - 0x00, 0xe2, 0x14, 0x42, - 0x80, 0x39, 0xd5, 0x6a, + 0x00, 0xe2, 0x28, 0x42, + 0x80, 0x39, 0xe9, 0x6a, 0x01, 0x44, 0x10, 0x33, 0x08, 0x92, 0x25, 0x03, - 0x00, 0xe2, 0x14, 0x42, + 0x00, 0xe2, 0x28, 0x42, 0x10, 0xea, 0x80, 0x00, 0x01, 0x37, 0xc5, 0x31, - 0x80, 0xe2, 0x80, 0x62, - 0x10, 0x92, 0xa5, 0x6a, + 0x80, 0xe2, 0x94, 0x62, + 0x10, 0x92, 0xb9, 0x6a, 0xc0, 0x94, 0xc5, 0x01, - 0x40, 0x92, 0x71, 0x6a, + 0x40, 0x92, 0x85, 0x6a, 0xbf, 0xe2, 0xc4, 0x09, - 0x20, 0x92, 0x85, 0x7a, + 0x20, 0x92, 0x99, 0x7a, 0x01, 0xe2, 0x88, 0x30, - 0x00, 0xe2, 0xe2, 0x5b, - 0xa0, 0x3c, 0x8d, 0x62, + 0x00, 0xe2, 0xf6, 0x5b, + 0xa0, 0x3c, 0xa1, 0x62, 0x23, 0x92, 0x89, 0x08, - 0x00, 0xe2, 0xe2, 0x5b, - 0xa0, 0x3c, 0x8d, 0x62, - 0x00, 0xa8, 0x84, 0x42, - 0xff, 0xe2, 0x84, 0x62, - 0x00, 0xe2, 0xa4, 0x42, + 0x00, 0xe2, 0xf6, 0x5b, + 0xa0, 0x3c, 0xa1, 0x62, + 0x00, 0xa8, 0x98, 0x42, + 0xff, 0xe2, 0x98, 0x62, + 0x00, 0xe2, 0xb8, 0x42, 0x40, 0xea, 0x98, 0x00, 0x01, 0xe2, 0x88, 0x30, - 0x00, 0xe2, 0xe2, 0x5b, - 0xa0, 0x3c, 0x63, 0x72, + 0x00, 0xe2, 0xf6, 0x5b, + 0xa0, 0x3c, 0x77, 0x72, 0x40, 0xea, 0x98, 0x00, 0x01, 0x37, 0x95, 0x32, 0x08, 0xea, 0x6e, 0x02, - 0x00, 0xe2, 0x14, 0x42, - 0xe0, 0xea, 0xfe, 0x5b, - 0x80, 0xe0, 0xe0, 0x6a, - 0x04, 0xe0, 0x92, 0x73, - 0x02, 0xe0, 0xc4, 0x73, - 0x00, 0xea, 0x3e, 0x73, - 0x03, 0xe0, 0xd4, 0x73, - 0x23, 0xe0, 0xb6, 0x72, - 0x08, 0xe0, 0xdc, 0x72, - 0x00, 0xe2, 0xe2, 0x5b, - 0x07, 0xea, 0x64, 0x59, + 0x00, 0xe2, 0x28, 0x42, + 0xe0, 0xea, 0x12, 0x5c, + 0x80, 0xe0, 0xf4, 0x6a, + 0x04, 0xe0, 0xa6, 0x73, + 0x02, 0xe0, 0xd8, 0x73, + 0x00, 0xea, 0x52, 0x73, + 0x03, 0xe0, 0xe8, 0x73, + 0x23, 0xe0, 0xca, 0x72, + 0x08, 0xe0, 0xf0, 0x72, + 0x00, 0xe2, 0xf6, 0x5b, + 0x07, 0xea, 0x6e, 0x59, 0x07, 0xea, 0x04, 0x00, - 0x08, 0x48, 0x15, 0x72, - 0x04, 0x48, 0xb3, 0x62, + 0x08, 0x48, 0x29, 0x72, + 0x04, 0x48, 0xc7, 0x62, 0x01, 0x49, 0x89, 0x30, - 0x00, 0xe2, 0xa4, 0x42, + 0x00, 0xe2, 0xb8, 0x42, 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0xa4, 0x42, + 0x00, 0xe2, 0xb8, 0x42, 0x01, 0x00, 0x6c, 0x32, - 0x33, 0xea, 0x5e, 0x59, + 0x33, 0xea, 0x68, 0x59, 0x33, 0xea, 0x00, 0x00, 0x4c, 0x3a, 0xc1, 0x28, 0x01, 0x64, 0xc0, 0x31, - 0x00, 0x36, 0x5f, 0x59, + 0x00, 0x36, 0x69, 0x59, 0x01, 0x36, 0x01, 0x30, - 0x01, 0xe0, 0xda, 0x7a, - 0xa0, 0xea, 0xf4, 0x5b, - 0x01, 0xa0, 0xda, 0x62, - 0x01, 0x84, 0xcf, 0x7a, - 0x01, 0x95, 0xdd, 0x6a, - 0x05, 0xea, 0x64, 0x59, + 0x01, 0xe0, 0xee, 0x7a, + 0xa0, 0xea, 0x08, 0x5c, + 0x01, 0xa0, 0xee, 0x62, + 0x01, 0x84, 0xe3, 0x7a, + 0x01, 0x95, 0xf1, 0x6a, + 0x05, 0xea, 0x6e, 0x59, 0x05, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xdc, 0x42, - 0x03, 0xea, 0x64, 0x59, + 0x00, 0xe2, 0xf0, 0x42, + 0x03, 0xea, 0x6e, 0x59, 0x03, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xdc, 0x42, - 0x07, 0xea, 0x06, 0x5c, + 0x00, 0xe2, 0xf0, 0x42, + 0x07, 0xea, 0x1a, 0x5c, 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0x14, 0x42, + 0x00, 0xe2, 0x28, 0x42, 0x3f, 0xe0, 0x76, 0x0a, 0xc0, 0x3a, 0xc1, 0x09, 0x00, 0x3b, 0x51, 0x01, @@ -384,54 +394,54 @@ static uint8_t seqprog[] = { 0x01, 0xea, 0xc6, 0x01, 0x02, 0xe2, 0xc8, 0x31, 0x02, 0xec, 0x40, 0x31, - 0xff, 0xa1, 0xfc, 0x72, + 0xff, 0xa1, 0x10, 0x73, 0x02, 0xe8, 0xda, 0x31, 0x02, 0xa0, 0x50, 0x31, - 0x00, 0xe2, 0x1e, 0x43, + 0x00, 0xe2, 0x32, 0x43, 0x80, 0x39, 0x73, 0x02, 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0xe2, 0x5b, + 0x00, 0xe2, 0xf6, 0x5b, 0x01, 0x39, 0x73, 0x02, - 0xe0, 0x3c, 0x39, 0x63, + 0xe0, 0x3c, 0x4d, 0x63, 0x02, 0x39, 0x73, 0x02, - 0x20, 0x46, 0x32, 0x63, + 0x20, 0x46, 0x46, 0x63, 0xff, 0xea, 0x52, 0x09, - 0xa8, 0xea, 0xf4, 0x5b, - 0x04, 0x92, 0x19, 0x7b, + 0xa8, 0xea, 0x08, 0x5c, + 0x04, 0x92, 0x2d, 0x7b, 0x01, 0x3a, 0xc1, 0x31, - 0x00, 0x93, 0x19, 0x63, + 0x00, 0x93, 0x2d, 0x63, 0x01, 0x3b, 0xc1, 0x31, - 0x00, 0x94, 0x23, 0x73, + 0x00, 0x94, 0x37, 0x73, 0x01, 0xa9, 0x52, 0x11, - 0xff, 0xa9, 0x0e, 0x6b, - 0x00, 0xe2, 0x32, 0x43, + 0xff, 0xa9, 0x22, 0x6b, + 0x00, 0xe2, 0x46, 0x43, 0x10, 0x39, 0x73, 0x02, - 0x04, 0x92, 0x33, 0x7b, + 0x04, 0x92, 0x47, 0x7b, 0xfb, 0x92, 0x25, 0x0b, 0xff, 0xea, 0x72, 0x0a, - 0x01, 0xa4, 0x2d, 0x6b, + 0x01, 0xa4, 0x41, 0x6b, 0x02, 0xa8, 0x9c, 0x32, - 0x00, 0xe2, 0x7e, 0x59, - 0x10, 0x92, 0xdd, 0x7a, - 0xff, 0xea, 0x06, 0x5c, - 0x00, 0xe2, 0xdc, 0x42, - 0x04, 0xea, 0x64, 0x59, + 0x00, 0xe2, 0x88, 0x59, + 0x10, 0x92, 0xf1, 0x7a, + 0xff, 0xea, 0x1a, 0x5c, + 0x00, 0xe2, 0xf0, 0x42, + 0x04, 0xea, 0x6e, 0x59, 0x04, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xdc, 0x42, - 0x04, 0xea, 0x64, 0x59, + 0x00, 0xe2, 0xf0, 0x42, + 0x04, 0xea, 0x6e, 0x59, 0x04, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x14, 0x42, - 0x08, 0x92, 0xd5, 0x7a, - 0xc0, 0x39, 0x49, 0x7b, - 0x80, 0x39, 0xd5, 0x6a, - 0xff, 0x88, 0x49, 0x6b, - 0x40, 0x39, 0xd5, 0x6a, - 0x10, 0x92, 0x4f, 0x7b, - 0x0a, 0xea, 0x64, 0x59, + 0x00, 0xe2, 0x28, 0x42, + 0x08, 0x92, 0xe9, 0x7a, + 0xc0, 0x39, 0x5d, 0x7b, + 0x80, 0x39, 0xe9, 0x6a, + 0xff, 0x88, 0x5d, 0x6b, + 0x40, 0x39, 0xe9, 0x6a, + 0x10, 0x92, 0x63, 0x7b, + 0x0a, 0xea, 0x6e, 0x59, 0x0a, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x6e, 0x5b, - 0x00, 0xe2, 0xae, 0x43, - 0x50, 0x4b, 0x56, 0x6b, + 0x00, 0xe2, 0x82, 0x5b, + 0x00, 0xe2, 0xc2, 0x43, + 0x50, 0x4b, 0x6a, 0x6b, 0xbf, 0x3a, 0x74, 0x08, 0x01, 0xe0, 0xf4, 0x31, 0xff, 0xea, 0xc0, 0x09, @@ -441,31 +451,31 @@ static uint8_t seqprog[] = { 0x01, 0xfa, 0xc0, 0x35, 0x02, 0xa8, 0x90, 0x32, 0x02, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x5e, 0x59, + 0x33, 0xea, 0x68, 0x59, 0x33, 0xea, 0x00, 0x00, 0x02, 0x48, 0x51, 0x31, 0xff, 0x90, 0x85, 0x68, - 0xff, 0x88, 0x7b, 0x6b, - 0x01, 0xa4, 0x77, 0x6b, - 0x02, 0xa4, 0x7f, 0x6b, - 0x01, 0x84, 0x7f, 0x7b, + 0xff, 0x88, 0x8f, 0x6b, + 0x01, 0xa4, 0x8b, 0x6b, + 0x02, 0xa4, 0x93, 0x6b, + 0x01, 0x84, 0x93, 0x7b, 0x02, 0x28, 0x19, 0x33, 0x02, 0xa8, 0x50, 0x36, - 0xff, 0x88, 0x7f, 0x73, - 0x00, 0xe2, 0x52, 0x5b, + 0xff, 0x88, 0x93, 0x73, + 0x00, 0xe2, 0x66, 0x5b, 0x02, 0xa8, 0x20, 0x33, 0x04, 0xa4, 0x49, 0x03, 0xff, 0xea, 0x1a, 0x03, - 0xff, 0x2d, 0x8b, 0x63, + 0xff, 0x2d, 0x9f, 0x63, 0x02, 0xa8, 0x58, 0x32, 0x02, 0xa8, 0x5c, 0x36, 0x02, 0xa8, 0x40, 0x31, 0x02, 0x2e, 0x51, 0x31, 0x02, 0xa0, 0x18, 0x33, 0x02, 0xa0, 0x5c, 0x36, - 0xc0, 0x39, 0xd5, 0x6a, + 0xc0, 0x39, 0xe9, 0x6a, 0x04, 0x92, 0x25, 0x03, - 0x20, 0x92, 0xaf, 0x6b, + 0x20, 0x92, 0xc3, 0x6b, 0x02, 0xa8, 0x40, 0x31, 0xc0, 0x3a, 0xc1, 0x09, 0x00, 0x3b, 0x51, 0x01, @@ -480,60 +490,60 @@ static uint8_t seqprog[] = { 0xf7, 0x57, 0xae, 0x08, 0x08, 0xea, 0x98, 0x00, 0x01, 0x44, 0xd4, 0x31, - 0xee, 0x00, 0xb8, 0x6b, + 0xee, 0x00, 0xcc, 0x6b, 0x02, 0xea, 0xb4, 0x00, 0xc0, 0xea, 0x72, 0x02, - 0x09, 0x4c, 0xba, 0x7b, + 0x09, 0x4c, 0xce, 0x7b, 0x01, 0xea, 0x78, 0x02, 0x08, 0x4c, 0x06, 0x68, - 0x0b, 0xea, 0x64, 0x59, + 0x0b, 0xea, 0x6e, 0x59, 0x0b, 0xea, 0x04, 0x00, 0x01, 0x44, 0xd4, 0x31, - 0x20, 0x39, 0x15, 0x7a, - 0x00, 0xe2, 0xcc, 0x5b, - 0x00, 0xe2, 0x14, 0x42, - 0x01, 0x84, 0xd1, 0x7b, + 0x20, 0x39, 0x29, 0x7a, + 0x00, 0xe2, 0xe0, 0x5b, + 0x00, 0xe2, 0x28, 0x42, + 0x01, 0x84, 0xe5, 0x7b, 0x01, 0xa4, 0x49, 0x07, 0x08, 0x60, 0x30, 0x33, 0x08, 0x80, 0x41, 0x37, 0xdf, 0x39, 0x73, 0x0a, - 0xee, 0x00, 0xde, 0x6b, + 0xee, 0x00, 0xf2, 0x6b, 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x5e, 0x59, + 0x33, 0xea, 0x68, 0x59, 0x33, 0xea, 0x00, 0x00, - 0x00, 0xe2, 0x7e, 0x59, - 0x00, 0xe2, 0xdc, 0x42, - 0xff, 0x42, 0xee, 0x6b, - 0x01, 0x41, 0xe2, 0x6b, - 0x02, 0x41, 0xe2, 0x7b, - 0xff, 0x42, 0xee, 0x6b, - 0x01, 0x41, 0xe2, 0x6b, - 0x02, 0x41, 0xe2, 0x7b, - 0xff, 0x42, 0xee, 0x7b, - 0x04, 0x4c, 0xe2, 0x6b, + 0x00, 0xe2, 0x88, 0x59, + 0x00, 0xe2, 0xf0, 0x42, + 0xff, 0x42, 0x02, 0x6c, + 0x01, 0x41, 0xf6, 0x6b, + 0x02, 0x41, 0xf6, 0x7b, + 0xff, 0x42, 0x02, 0x6c, + 0x01, 0x41, 0xf6, 0x6b, + 0x02, 0x41, 0xf6, 0x7b, + 0xff, 0x42, 0x02, 0x7c, + 0x04, 0x4c, 0xf6, 0x6b, 0xe0, 0x41, 0x78, 0x0e, 0x01, 0x44, 0xd4, 0x31, - 0xff, 0x42, 0xf6, 0x7b, - 0x04, 0x4c, 0xf6, 0x6b, + 0xff, 0x42, 0x0a, 0x7c, + 0x04, 0x4c, 0x0a, 0x6c, 0xe0, 0x41, 0x78, 0x0a, - 0xe0, 0x3c, 0x15, 0x62, + 0xe0, 0x3c, 0x29, 0x62, 0xff, 0xea, 0xca, 0x09, 0x01, 0xe2, 0xc8, 0x31, 0x01, 0x46, 0xda, 0x35, 0x01, 0x44, 0xd4, 0x35, 0x10, 0xea, 0x80, 0x00, 0x01, 0xe2, 0x6e, 0x36, - 0x04, 0xa6, 0x0e, 0x7c, + 0x04, 0xa6, 0x22, 0x7c, 0xff, 0xea, 0x5a, 0x09, 0xff, 0xea, 0x4c, 0x0d, - 0x01, 0xa6, 0x3a, 0x6c, + 0x01, 0xa6, 0x4e, 0x6c, 0x10, 0xad, 0x84, 0x78, - 0x80, 0xad, 0x32, 0x6c, + 0x80, 0xad, 0x46, 0x6c, 0x08, 0xad, 0x84, 0x68, - 0x20, 0x19, 0x26, 0x7c, + 0x20, 0x19, 0x3a, 0x7c, 0x80, 0xea, 0xb2, 0x01, 0x11, 0x00, 0x00, 0x10, - 0x02, 0xa6, 0x22, 0x7c, + 0x02, 0xa6, 0x36, 0x7c, 0xff, 0xea, 0xb2, 0x0d, 0x11, 0x00, 0x00, 0x10, 0xff, 0xea, 0xb2, 0x09, @@ -561,7 +571,7 @@ static uint8_t seqprog[] = { 0x00, 0x86, 0x0d, 0x23, 0x00, 0x87, 0x0f, 0x23, 0x01, 0x84, 0xc5, 0x31, - 0x80, 0x83, 0x5d, 0x7c, + 0x80, 0x83, 0x71, 0x7c, 0x02, 0xe2, 0xc4, 0x01, 0xff, 0xea, 0x4c, 0x09, 0x01, 0xe2, 0x36, 0x30, @@ -572,75 +582,75 @@ static uint8_t seqprog[] = { 0xfe, 0xa6, 0x4c, 0x0d, 0x0b, 0x98, 0xe1, 0x30, 0xfd, 0xa4, 0x49, 0x09, - 0x80, 0xa3, 0x71, 0x7c, + 0x80, 0xa3, 0x85, 0x7c, 0x02, 0xa4, 0x48, 0x01, 0x01, 0xa4, 0x36, 0x30, 0xa8, 0xea, 0x32, 0x00, 0xfd, 0xa4, 0x49, 0x0b, 0x05, 0xa3, 0x07, 0x33, - 0x80, 0x83, 0x7d, 0x6c, + 0x80, 0x83, 0x91, 0x6c, 0x02, 0xea, 0x4c, 0x05, 0xff, 0xea, 0x4c, 0x0d, - 0x00, 0xe2, 0x56, 0x59, - 0x02, 0xa6, 0x10, 0x6c, + 0x00, 0xe2, 0x60, 0x59, + 0x02, 0xa6, 0x24, 0x6c, 0x80, 0xf9, 0xf2, 0x05, - 0xc0, 0x39, 0x8b, 0x7c, - 0x03, 0xea, 0x64, 0x59, + 0xc0, 0x39, 0x9f, 0x7c, + 0x03, 0xea, 0x6e, 0x59, 0x03, 0xea, 0x04, 0x00, - 0x20, 0x39, 0xaf, 0x7c, - 0x01, 0x84, 0x95, 0x6c, - 0x06, 0xea, 0x64, 0x59, + 0x20, 0x39, 0xc3, 0x7c, + 0x01, 0x84, 0xa9, 0x6c, + 0x06, 0xea, 0x6e, 0x59, 0x06, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xb2, 0x44, + 0x00, 0xe2, 0xc6, 0x44, 0x01, 0x00, 0x6c, 0x32, - 0xee, 0x00, 0x9e, 0x6c, + 0xee, 0x00, 0xb2, 0x6c, 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x5e, 0x59, + 0x33, 0xea, 0x68, 0x59, 0x33, 0xea, 0x00, 0x00, 0x80, 0x3d, 0x7a, 0x00, - 0xfc, 0x42, 0xa0, 0x7c, + 0xfc, 0x42, 0xb4, 0x7c, 0x7f, 0x3d, 0x7a, 0x08, - 0x00, 0x36, 0x5f, 0x59, + 0x00, 0x36, 0x69, 0x59, 0x01, 0x36, 0x01, 0x30, - 0x09, 0xea, 0x64, 0x59, + 0x09, 0xea, 0x6e, 0x59, 0x09, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x14, 0x42, - 0x01, 0xa4, 0x95, 0x6c, - 0x00, 0xe2, 0x68, 0x5c, + 0x00, 0xe2, 0x28, 0x42, + 0x01, 0xa4, 0xa9, 0x6c, + 0x00, 0xe2, 0x7c, 0x5c, 0x20, 0x39, 0x73, 0x02, 0x01, 0x00, 0x6c, 0x32, - 0x02, 0xa6, 0xba, 0x7c, - 0x00, 0xe2, 0x7e, 0x5c, + 0x02, 0xa6, 0xce, 0x7c, + 0x00, 0xe2, 0x92, 0x5c, 0x00, 0xe2, 0x76, 0x58, 0x00, 0xe2, 0x86, 0x58, 0x00, 0xe2, 0x5a, 0x58, - 0x00, 0x36, 0x5f, 0x59, + 0x00, 0x36, 0x69, 0x59, 0x01, 0x36, 0x01, 0x30, - 0x20, 0x19, 0xba, 0x6c, - 0x00, 0xe2, 0xea, 0x5c, - 0x04, 0x19, 0xd4, 0x6c, + 0x20, 0x19, 0xce, 0x6c, + 0x00, 0xe2, 0xfe, 0x5c, + 0x04, 0x19, 0xe8, 0x6c, 0x02, 0x19, 0x32, 0x00, - 0x01, 0x84, 0xd5, 0x7c, - 0x01, 0x1b, 0xce, 0x7c, - 0x01, 0x1a, 0xd4, 0x6c, - 0x00, 0xe2, 0x84, 0x44, - 0x80, 0x4b, 0xda, 0x6c, - 0x01, 0x4c, 0xd6, 0x7c, - 0x03, 0x42, 0x84, 0x6c, - 0x00, 0xe2, 0x0a, 0x5c, + 0x01, 0x84, 0xe9, 0x7c, + 0x01, 0x1b, 0xe2, 0x7c, + 0x01, 0x1a, 0xe8, 0x6c, + 0x00, 0xe2, 0x98, 0x44, + 0x80, 0x4b, 0xee, 0x6c, + 0x01, 0x4c, 0xea, 0x7c, + 0x03, 0x42, 0x98, 0x6c, + 0x00, 0xe2, 0x1e, 0x5c, 0x80, 0xf9, 0xf2, 0x01, - 0x04, 0x39, 0x15, 0x7a, - 0x00, 0xe2, 0x14, 0x42, - 0x08, 0x5d, 0xf2, 0x6c, + 0x04, 0x39, 0x29, 0x7a, + 0x00, 0xe2, 0x28, 0x42, + 0x08, 0x5d, 0x06, 0x6d, 0x00, 0xe2, 0x76, 0x58, - 0x00, 0x36, 0x5f, 0x59, + 0x00, 0x36, 0x69, 0x59, 0x01, 0x36, 0x01, 0x30, - 0x02, 0x1b, 0xe2, 0x7c, - 0x08, 0x5d, 0xf0, 0x7c, + 0x02, 0x1b, 0xf6, 0x7c, + 0x08, 0x5d, 0x04, 0x7d, 0x03, 0x68, 0x00, 0x37, 0x01, 0x84, 0x09, 0x07, - 0x80, 0x1b, 0xfc, 0x7c, - 0x80, 0x84, 0xfd, 0x6c, + 0x80, 0x1b, 0x10, 0x7d, + 0x80, 0x84, 0x11, 0x6d, 0xff, 0x85, 0x0b, 0x1b, 0xff, 0x86, 0x0d, 0x23, 0xff, 0x87, 0x0f, 0x23, @@ -652,161 +662,164 @@ static uint8_t seqprog[] = { 0xf9, 0xd9, 0xb2, 0x0d, 0x01, 0xd9, 0xb2, 0x05, 0x01, 0x52, 0x48, 0x31, - 0x20, 0xa4, 0x26, 0x7d, - 0x20, 0x5b, 0x26, 0x7d, - 0x80, 0xf9, 0x34, 0x7d, + 0x20, 0xa4, 0x3a, 0x7d, + 0x20, 0x5b, 0x3a, 0x7d, + 0x80, 0xf9, 0x48, 0x7d, 0x02, 0xea, 0xb4, 0x00, 0x11, 0x00, 0x00, 0x10, - 0x04, 0x19, 0x40, 0x7d, + 0x04, 0x19, 0x54, 0x7d, 0xdf, 0x19, 0x32, 0x08, - 0x60, 0x5b, 0x40, 0x6d, - 0x01, 0x4c, 0x1a, 0x7d, + 0x60, 0x5b, 0x54, 0x6d, + 0x01, 0x4c, 0x2e, 0x7d, 0x20, 0x19, 0x32, 0x00, 0x01, 0xd9, 0xb2, 0x05, 0x02, 0xea, 0xb4, 0x00, 0x01, 0xd9, 0xb2, 0x05, - 0x10, 0x5b, 0x38, 0x6d, - 0x08, 0x5b, 0x42, 0x6d, - 0x20, 0x5b, 0x32, 0x6d, - 0x02, 0x5b, 0x62, 0x6d, - 0x0e, 0xea, 0x64, 0x59, + 0x10, 0x5b, 0x4c, 0x6d, + 0x08, 0x5b, 0x56, 0x6d, + 0x20, 0x5b, 0x46, 0x6d, + 0x02, 0x5b, 0x76, 0x6d, + 0x0e, 0xea, 0x6e, 0x59, 0x0e, 0xea, 0x04, 0x00, - 0x80, 0xf9, 0x22, 0x6d, + 0x80, 0xf9, 0x36, 0x6d, 0xdf, 0x5c, 0xb8, 0x08, 0x01, 0xd9, 0xb2, 0x05, - 0x01, 0xa4, 0x1d, 0x6e, - 0x00, 0xe2, 0x68, 0x5c, - 0x00, 0xe2, 0x6c, 0x5d, + 0x01, 0xa4, 0x37, 0x6e, + 0x00, 0xe2, 0x7c, 0x5c, + 0x00, 0xe2, 0x80, 0x5d, 0x01, 0x90, 0x21, 0x1b, 0x01, 0xd9, 0xb2, 0x05, - 0x00, 0xe2, 0x52, 0x5b, + 0x00, 0xe2, 0x66, 0x5b, 0xf3, 0x96, 0xd5, 0x19, - 0x00, 0xe2, 0x50, 0x55, - 0x80, 0x96, 0x51, 0x6d, - 0x0f, 0xea, 0x64, 0x59, + 0x00, 0xe2, 0x64, 0x55, + 0x80, 0x96, 0x65, 0x6d, + 0x0f, 0xea, 0x6e, 0x59, 0x0f, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x58, 0x45, + 0x00, 0xe2, 0x6c, 0x45, 0x04, 0x8c, 0xe1, 0x30, 0x01, 0xea, 0xf2, 0x00, 0x02, 0xea, 0x36, 0x00, 0xa8, 0xea, 0x32, 0x00, - 0xff, 0x97, 0x5f, 0x7d, - 0x14, 0xea, 0x64, 0x59, + 0xff, 0x97, 0x73, 0x7d, + 0x14, 0xea, 0x6e, 0x59, 0x14, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xce, 0x5d, + 0x00, 0xe2, 0xe2, 0x5d, 0x01, 0xd9, 0xb2, 0x05, 0x09, 0x80, 0xe1, 0x30, 0x02, 0xea, 0x36, 0x00, 0xa8, 0xea, 0x32, 0x00, - 0x00, 0xe2, 0xc6, 0x5d, + 0x00, 0xe2, 0xda, 0x5d, 0x01, 0xd9, 0xb2, 0x05, - 0x02, 0xa6, 0x7c, 0x7d, - 0x00, 0xe2, 0x56, 0x59, - 0x20, 0x5b, 0x8a, 0x6d, - 0xfc, 0x42, 0x76, 0x7d, - 0x10, 0x40, 0x78, 0x6d, - 0x20, 0x4d, 0x7a, 0x7d, - 0x08, 0x5d, 0x8a, 0x6d, - 0x02, 0xa6, 0x10, 0x6c, - 0x00, 0xe2, 0x56, 0x59, - 0x20, 0x5b, 0x8a, 0x6d, - 0x01, 0x1b, 0xaa, 0x6d, - 0xfc, 0x42, 0x86, 0x7d, - 0x10, 0x40, 0x88, 0x6d, + 0x02, 0xa6, 0x90, 0x7d, + 0x00, 0xe2, 0x60, 0x59, + 0x20, 0x5b, 0x9e, 0x6d, + 0xfc, 0x42, 0x8a, 0x7d, + 0x10, 0x40, 0x8c, 0x6d, + 0x20, 0x4d, 0x8e, 0x7d, + 0x08, 0x5d, 0x9e, 0x6d, + 0x02, 0xa6, 0x24, 0x6c, + 0x00, 0xe2, 0x60, 0x59, + 0x20, 0x5b, 0x9e, 0x6d, + 0x01, 0x1b, 0xbe, 0x6d, + 0xfc, 0x42, 0x9a, 0x7d, + 0x10, 0x40, 0x9c, 0x6d, 0x20, 0x4d, 0x84, 0x78, 0x08, 0x5d, 0x84, 0x78, 0x02, 0x19, 0x32, 0x00, 0x01, 0x5b, 0x40, 0x31, - 0x00, 0xe2, 0xea, 0x5c, - 0x00, 0xe2, 0xcc, 0x5b, + 0x00, 0xe2, 0xfe, 0x5c, + 0x00, 0xe2, 0xe0, 0x5b, 0x20, 0xea, 0xb6, 0x00, - 0x00, 0xe2, 0x0a, 0x5c, + 0x00, 0xe2, 0x1e, 0x5c, 0x20, 0x5c, 0xb8, 0x00, - 0x04, 0x19, 0xa0, 0x6d, - 0x01, 0x1a, 0xa0, 0x6d, - 0x00, 0xe2, 0x56, 0x59, + 0x04, 0x19, 0xb4, 0x6d, + 0x01, 0x1a, 0xb4, 0x6d, + 0x00, 0xe2, 0x60, 0x59, 0x01, 0x1a, 0x84, 0x78, 0x80, 0xf9, 0xf2, 0x01, - 0x20, 0xa0, 0x04, 0x7e, + 0x20, 0xa0, 0x18, 0x7e, 0xff, 0x90, 0x21, 0x1b, - 0x08, 0x92, 0x63, 0x6b, + 0x08, 0x92, 0x77, 0x6b, 0x02, 0xea, 0xb4, 0x04, 0x01, 0xa4, 0x49, 0x03, - 0x40, 0x5b, 0xba, 0x6d, - 0x00, 0xe2, 0x56, 0x59, - 0x40, 0x5b, 0xba, 0x6d, - 0x04, 0x5d, 0x1e, 0x7e, - 0x01, 0x1a, 0x1e, 0x7e, + 0x40, 0x5b, 0xce, 0x6d, + 0x00, 0xe2, 0x60, 0x59, + 0x40, 0x5b, 0xce, 0x6d, + 0x04, 0x5d, 0x38, 0x7e, + 0x01, 0x1a, 0x38, 0x7e, 0x20, 0x4d, 0x84, 0x78, - 0x40, 0x5b, 0x04, 0x7e, - 0x04, 0x5d, 0x1e, 0x7e, - 0x01, 0x1a, 0x1e, 0x7e, + 0x40, 0x5b, 0x18, 0x7e, + 0x04, 0x5d, 0x38, 0x7e, + 0x01, 0x1a, 0x38, 0x7e, 0x80, 0xf9, 0xf2, 0x01, 0xff, 0x90, 0x21, 0x1b, - 0x08, 0x92, 0x63, 0x6b, + 0x08, 0x92, 0x77, 0x6b, 0x02, 0xea, 0xb4, 0x04, - 0x00, 0xe2, 0x56, 0x59, + 0x00, 0xe2, 0x60, 0x59, 0x01, 0x1b, 0x84, 0x78, 0x80, 0xf9, 0xf2, 0x01, 0x02, 0xea, 0xb4, 0x04, - 0x00, 0xe2, 0x56, 0x59, - 0x01, 0x1b, 0xe2, 0x6d, - 0x40, 0x5b, 0xf0, 0x7d, - 0x01, 0x1b, 0xe2, 0x6d, + 0x00, 0xe2, 0x60, 0x59, + 0x01, 0x1b, 0xf6, 0x6d, + 0x40, 0x5b, 0x04, 0x7e, + 0x01, 0x1b, 0xf6, 0x6d, 0x02, 0x19, 0x32, 0x00, 0x01, 0x1a, 0x84, 0x78, 0x80, 0xf9, 0xf2, 0x01, 0xff, 0xea, 0x10, 0x03, 0x08, 0x92, 0x25, 0x03, - 0x00, 0xe2, 0x62, 0x43, - 0x01, 0x1a, 0xec, 0x7d, - 0x40, 0x5b, 0xe8, 0x7d, - 0x01, 0x1a, 0xd6, 0x6d, + 0x00, 0xe2, 0x76, 0x43, + 0x01, 0x1a, 0x00, 0x7e, + 0x40, 0x5b, 0xfc, 0x7d, + 0x01, 0x1a, 0xea, 0x6d, 0xfc, 0x42, 0x84, 0x78, - 0x01, 0x1a, 0xf0, 0x6d, - 0x10, 0xea, 0x64, 0x59, + 0x01, 0x1a, 0x04, 0x6e, + 0x10, 0xea, 0x6e, 0x59, 0x10, 0xea, 0x04, 0x00, 0xfc, 0x42, 0x84, 0x78, - 0x10, 0x40, 0xf6, 0x6d, + 0x10, 0x40, 0x0a, 0x6e, 0x20, 0x4d, 0x84, 0x78, - 0x40, 0x5b, 0xd6, 0x6d, + 0x40, 0x5b, 0xea, 0x6d, 0x01, 0x1a, 0x84, 0x78, 0x01, 0x90, 0x21, 0x1b, 0x30, 0x3f, 0xc0, 0x09, 0x30, 0xe0, 0x84, 0x60, 0x40, 0x4b, 0x84, 0x68, 0xff, 0xea, 0x52, 0x01, - 0xee, 0x00, 0x0c, 0x6e, + 0xee, 0x00, 0x20, 0x6e, 0x80, 0xf9, 0xf2, 0x01, 0xff, 0x90, 0x21, 0x1b, 0x02, 0xea, 0xb4, 0x00, 0x20, 0xea, 0x9a, 0x00, - 0xf3, 0x42, 0x16, 0x6e, - 0x12, 0xea, 0x64, 0x59, + 0x04, 0x41, 0x26, 0x7e, + 0x08, 0xea, 0x98, 0x00, + 0x08, 0x57, 0xae, 0x00, + 0xf3, 0x42, 0x30, 0x6e, + 0x12, 0xea, 0x6e, 0x59, 0x12, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x14, 0x42, - 0x0d, 0xea, 0x64, 0x59, + 0x00, 0xe2, 0x28, 0x42, + 0x0d, 0xea, 0x6e, 0x59, 0x0d, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x14, 0x42, + 0x00, 0xe2, 0x28, 0x42, 0x01, 0x90, 0x21, 0x1b, - 0x11, 0xea, 0x64, 0x59, + 0x11, 0xea, 0x6e, 0x59, 0x11, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x52, 0x5b, + 0x00, 0xe2, 0x66, 0x5b, 0x08, 0x5a, 0xb4, 0x00, - 0x00, 0xe2, 0x44, 0x5e, + 0x00, 0xe2, 0x5e, 0x5e, 0xa8, 0xea, 0x32, 0x00, - 0x00, 0xe2, 0x56, 0x59, - 0x80, 0x1a, 0x32, 0x7e, - 0x00, 0xe2, 0x44, 0x5e, + 0x00, 0xe2, 0x60, 0x59, + 0x80, 0x1a, 0x4c, 0x7e, + 0x00, 0xe2, 0x5e, 0x5e, 0x80, 0x19, 0x32, 0x00, - 0x40, 0x5b, 0x38, 0x6e, - 0x08, 0x5a, 0x38, 0x7e, + 0x40, 0x5b, 0x52, 0x6e, + 0x08, 0x5a, 0x52, 0x7e, 0x20, 0x4d, 0x84, 0x78, 0x02, 0x84, 0x09, 0x03, - 0x40, 0x5b, 0x04, 0x7e, + 0x40, 0x5b, 0x18, 0x7e, 0xff, 0x90, 0x21, 0x1b, 0x80, 0xf9, 0xf2, 0x01, - 0x08, 0x92, 0x63, 0x6b, + 0x08, 0x92, 0x77, 0x6b, 0x02, 0xea, 0xb4, 0x04, 0x01, 0x40, 0xe1, 0x30, 0x05, 0x41, 0xe3, 0x98, @@ -1039,138 +1052,138 @@ static struct patch { { ahd_patch0_func, 64, 1, 1 }, { ahd_patch2_func, 67, 1, 2 }, { ahd_patch0_func, 68, 1, 1 }, - { ahd_patch4_func, 116, 1, 1 }, - { ahd_patch2_func, 175, 3, 1 }, - { ahd_patch1_func, 178, 2, 1 }, - { ahd_patch5_func, 180, 1, 1 }, - { ahd_patch2_func, 189, 1, 2 }, - { ahd_patch0_func, 190, 1, 1 }, - { ahd_patch6_func, 191, 2, 2 }, - { ahd_patch0_func, 193, 6, 3 }, - { ahd_patch2_func, 196, 1, 2 }, - { ahd_patch0_func, 197, 1, 1 }, - { ahd_patch2_func, 200, 1, 2 }, - { ahd_patch0_func, 201, 1, 1 }, - { ahd_patch3_func, 203, 1, 1 }, - { ahd_patch7_func, 204, 3, 1 }, - { ahd_patch3_func, 213, 1, 1 }, - { ahd_patch5_func, 214, 16, 2 }, - { ahd_patch0_func, 230, 1, 1 }, - { ahd_patch8_func, 250, 2, 1 }, - { ahd_patch1_func, 254, 1, 2 }, - { ahd_patch0_func, 255, 1, 1 }, - { ahd_patch7_func, 258, 3, 1 }, - { ahd_patch1_func, 273, 1, 2 }, - { ahd_patch0_func, 274, 1, 1 }, - { ahd_patch1_func, 277, 1, 2 }, - { ahd_patch0_func, 278, 1, 1 }, - { ahd_patch2_func, 281, 1, 2 }, - { ahd_patch0_func, 282, 1, 1 }, - { ahd_patch9_func, 295, 2, 2 }, - { ahd_patch0_func, 297, 1, 1 }, - { ahd_patch1_func, 339, 1, 2 }, - { ahd_patch0_func, 340, 1, 1 }, - { ahd_patch2_func, 348, 1, 2 }, - { ahd_patch0_func, 349, 1, 1 }, - { ahd_patch2_func, 352, 1, 2 }, - { ahd_patch0_func, 353, 1, 1 }, - { ahd_patch1_func, 359, 1, 2 }, - { ahd_patch0_func, 360, 1, 1 }, - { ahd_patch1_func, 362, 1, 2 }, + { ahd_patch4_func, 115, 1, 1 }, + { ahd_patch2_func, 180, 3, 1 }, + { ahd_patch1_func, 183, 2, 1 }, + { ahd_patch5_func, 185, 1, 1 }, + { ahd_patch2_func, 194, 1, 2 }, + { ahd_patch0_func, 195, 1, 1 }, + { ahd_patch6_func, 196, 2, 2 }, + { ahd_patch0_func, 198, 6, 3 }, + { ahd_patch2_func, 201, 1, 2 }, + { ahd_patch0_func, 202, 1, 1 }, + { ahd_patch2_func, 205, 1, 2 }, + { ahd_patch0_func, 206, 1, 1 }, + { ahd_patch3_func, 208, 1, 1 }, + { ahd_patch7_func, 209, 3, 1 }, + { ahd_patch3_func, 218, 1, 1 }, + { ahd_patch5_func, 219, 16, 2 }, + { ahd_patch0_func, 235, 1, 1 }, + { ahd_patch8_func, 260, 2, 1 }, + { ahd_patch1_func, 264, 1, 2 }, + { ahd_patch0_func, 265, 1, 1 }, + { ahd_patch7_func, 268, 3, 1 }, + { ahd_patch1_func, 283, 1, 2 }, + { ahd_patch0_func, 284, 1, 1 }, + { ahd_patch1_func, 287, 1, 2 }, + { ahd_patch0_func, 288, 1, 1 }, + { ahd_patch2_func, 291, 1, 2 }, + { ahd_patch0_func, 292, 1, 1 }, + { ahd_patch9_func, 305, 2, 2 }, + { ahd_patch0_func, 307, 1, 1 }, + { ahd_patch1_func, 349, 1, 2 }, + { ahd_patch0_func, 350, 1, 1 }, + { ahd_patch2_func, 358, 1, 2 }, + { ahd_patch0_func, 359, 1, 1 }, + { ahd_patch2_func, 362, 1, 2 }, { ahd_patch0_func, 363, 1, 1 }, - { ahd_patch10_func, 382, 1, 1 }, - { ahd_patch10_func, 385, 1, 1 }, - { ahd_patch10_func, 387, 1, 1 }, - { ahd_patch10_func, 399, 1, 1 }, - { ahd_patch1_func, 409, 1, 2 }, - { ahd_patch0_func, 410, 1, 1 }, - { ahd_patch1_func, 412, 1, 2 }, - { ahd_patch0_func, 413, 1, 1 }, - { ahd_patch1_func, 421, 1, 2 }, - { ahd_patch0_func, 422, 1, 1 }, - { ahd_patch2_func, 435, 1, 2 }, - { ahd_patch0_func, 436, 1, 1 }, - { ahd_patch11_func, 472, 1, 1 }, - { ahd_patch1_func, 480, 1, 2 }, - { ahd_patch0_func, 481, 1, 1 }, - { ahd_patch2_func, 493, 1, 2 }, - { ahd_patch0_func, 494, 1, 1 }, - { ahd_patch12_func, 497, 6, 2 }, - { ahd_patch0_func, 503, 1, 1 }, - { ahd_patch13_func, 524, 7, 1 }, - { ahd_patch14_func, 533, 1, 1 }, - { ahd_patch15_func, 542, 1, 1 }, - { ahd_patch16_func, 543, 1, 2 }, - { ahd_patch0_func, 544, 1, 1 }, - { ahd_patch17_func, 547, 1, 1 }, - { ahd_patch16_func, 548, 1, 1 }, - { ahd_patch18_func, 559, 1, 2 }, - { ahd_patch0_func, 560, 1, 1 }, - { ahd_patch1_func, 579, 1, 2 }, - { ahd_patch0_func, 580, 1, 1 }, - { ahd_patch1_func, 583, 1, 2 }, - { ahd_patch0_func, 584, 1, 1 }, - { ahd_patch2_func, 589, 1, 2 }, + { ahd_patch1_func, 369, 1, 2 }, + { ahd_patch0_func, 370, 1, 1 }, + { ahd_patch1_func, 372, 1, 2 }, + { ahd_patch0_func, 373, 1, 1 }, + { ahd_patch10_func, 392, 1, 1 }, + { ahd_patch10_func, 395, 1, 1 }, + { ahd_patch10_func, 397, 1, 1 }, + { ahd_patch10_func, 409, 1, 1 }, + { ahd_patch1_func, 419, 1, 2 }, + { ahd_patch0_func, 420, 1, 1 }, + { ahd_patch1_func, 422, 1, 2 }, + { ahd_patch0_func, 423, 1, 1 }, + { ahd_patch1_func, 431, 1, 2 }, + { ahd_patch0_func, 432, 1, 1 }, + { ahd_patch2_func, 445, 1, 2 }, + { ahd_patch0_func, 446, 1, 1 }, + { ahd_patch11_func, 482, 1, 1 }, + { ahd_patch1_func, 490, 1, 2 }, + { ahd_patch0_func, 491, 1, 1 }, + { ahd_patch2_func, 503, 1, 2 }, + { ahd_patch0_func, 504, 1, 1 }, + { ahd_patch12_func, 507, 6, 2 }, + { ahd_patch0_func, 513, 1, 1 }, + { ahd_patch13_func, 534, 7, 1 }, + { ahd_patch14_func, 543, 1, 1 }, + { ahd_patch15_func, 552, 1, 1 }, + { ahd_patch16_func, 553, 1, 2 }, + { ahd_patch0_func, 554, 1, 1 }, + { ahd_patch17_func, 557, 1, 1 }, + { ahd_patch16_func, 558, 1, 1 }, + { ahd_patch18_func, 569, 1, 2 }, + { ahd_patch0_func, 570, 1, 1 }, + { ahd_patch1_func, 589, 1, 2 }, { ahd_patch0_func, 590, 1, 1 }, - { ahd_patch2_func, 594, 1, 2 }, - { ahd_patch0_func, 595, 1, 1 }, - { ahd_patch1_func, 596, 1, 2 }, - { ahd_patch0_func, 597, 1, 1 }, - { ahd_patch2_func, 608, 1, 2 }, - { ahd_patch0_func, 609, 1, 1 }, - { ahd_patch19_func, 613, 1, 1 }, - { ahd_patch20_func, 618, 1, 1 }, - { ahd_patch21_func, 619, 2, 1 }, - { ahd_patch20_func, 623, 1, 2 }, - { ahd_patch0_func, 624, 1, 1 }, - { ahd_patch2_func, 627, 1, 2 }, - { ahd_patch0_func, 628, 1, 1 }, - { ahd_patch2_func, 643, 1, 2 }, - { ahd_patch0_func, 644, 1, 1 }, - { ahd_patch13_func, 645, 14, 1 }, - { ahd_patch1_func, 663, 1, 2 }, - { ahd_patch0_func, 664, 1, 1 }, - { ahd_patch13_func, 665, 1, 1 }, - { ahd_patch1_func, 677, 1, 2 }, - { ahd_patch0_func, 678, 1, 1 }, - { ahd_patch1_func, 685, 1, 2 }, - { ahd_patch0_func, 686, 1, 1 }, - { ahd_patch19_func, 709, 1, 1 }, - { ahd_patch19_func, 747, 1, 1 }, - { ahd_patch1_func, 758, 1, 2 }, - { ahd_patch0_func, 759, 1, 1 }, - { ahd_patch1_func, 776, 1, 2 }, - { ahd_patch0_func, 777, 1, 1 }, - { ahd_patch1_func, 779, 1, 2 }, - { ahd_patch0_func, 780, 1, 1 }, - { ahd_patch1_func, 783, 1, 2 }, - { ahd_patch0_func, 784, 1, 1 }, - { ahd_patch22_func, 786, 1, 2 }, - { ahd_patch0_func, 787, 2, 1 }, - { ahd_patch23_func, 790, 4, 2 }, - { ahd_patch0_func, 794, 1, 1 }, - { ahd_patch23_func, 802, 11, 1 } + { ahd_patch1_func, 593, 1, 2 }, + { ahd_patch0_func, 594, 1, 1 }, + { ahd_patch2_func, 599, 1, 2 }, + { ahd_patch0_func, 600, 1, 1 }, + { ahd_patch2_func, 604, 1, 2 }, + { ahd_patch0_func, 605, 1, 1 }, + { ahd_patch1_func, 606, 1, 2 }, + { ahd_patch0_func, 607, 1, 1 }, + { ahd_patch2_func, 618, 1, 2 }, + { ahd_patch0_func, 619, 1, 1 }, + { ahd_patch19_func, 623, 1, 1 }, + { ahd_patch20_func, 628, 1, 1 }, + { ahd_patch21_func, 629, 2, 1 }, + { ahd_patch20_func, 633, 1, 2 }, + { ahd_patch0_func, 634, 1, 1 }, + { ahd_patch2_func, 637, 1, 2 }, + { ahd_patch0_func, 638, 1, 1 }, + { ahd_patch2_func, 653, 1, 2 }, + { ahd_patch0_func, 654, 1, 1 }, + { ahd_patch13_func, 655, 14, 1 }, + { ahd_patch1_func, 673, 1, 2 }, + { ahd_patch0_func, 674, 1, 1 }, + { ahd_patch13_func, 675, 1, 1 }, + { ahd_patch1_func, 687, 1, 2 }, + { ahd_patch0_func, 688, 1, 1 }, + { ahd_patch1_func, 695, 1, 2 }, + { ahd_patch0_func, 696, 1, 1 }, + { ahd_patch19_func, 719, 1, 1 }, + { ahd_patch19_func, 757, 1, 1 }, + { ahd_patch1_func, 768, 1, 2 }, + { ahd_patch0_func, 769, 1, 1 }, + { ahd_patch7_func, 785, 3, 1 }, + { ahd_patch1_func, 789, 1, 2 }, + { ahd_patch0_func, 790, 1, 1 }, + { ahd_patch1_func, 792, 1, 2 }, + { ahd_patch0_func, 793, 1, 1 }, + { ahd_patch1_func, 796, 1, 2 }, + { ahd_patch0_func, 797, 1, 1 }, + { ahd_patch22_func, 799, 1, 2 }, + { ahd_patch0_func, 800, 2, 1 }, + { ahd_patch23_func, 803, 4, 2 }, + { ahd_patch0_func, 807, 1, 1 }, + { ahd_patch23_func, 815, 11, 1 } }; static struct cs { uint16_t begin; uint16_t end; } critical_sections[] = { - { 17, 28 }, - { 29, 30 }, + { 17, 30 }, { 47, 58 }, { 61, 63 }, { 65, 66 }, { 72, 92 }, - { 110, 137 }, - { 138, 175 }, - { 180, 188 }, - { 213, 264 }, - { 425, 433 }, - { 443, 445 }, - { 448, 457 }, - { 709, 739 }, - { 749, 753 } + { 110, 142 }, + { 143, 180 }, + { 185, 193 }, + { 218, 274 }, + { 435, 443 }, + { 453, 455 }, + { 458, 467 }, + { 719, 749 }, + { 759, 763 } }; static const int num_critical_sections = sizeof(critical_sections) From 3fb086126462c2de06dddaec58981d8827be100d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 24 Jan 2006 10:44:38 +0100 Subject: [PATCH 187/695] [SCSI] aic79xx: SLOWCRC fix This patch introduces the SLOWCRC handling for certain buggy chipsets. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx.h | 3 ++- drivers/scsi/aic7xxx/aic79xx_core.c | 21 +++++++++++++++++++++ drivers/scsi/aic7xxx/aic79xx_osm.c | 17 +++++++++++++++++ drivers/scsi/aic7xxx/aic79xx_pci.c | 11 +++++++++-- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index 2cfdbef447db..1d11f7e77564 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h @@ -37,7 +37,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#108 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#109 $ * * $FreeBSD$ */ @@ -222,6 +222,7 @@ typedef enum { typedef enum { AHD_FENONE = 0x00000, AHD_WIDE = 0x00001,/* Wide Channel */ + AHD_AIC79XXB_SLOWCRC = 0x00002,/* SLOWCRC bit should be set */ AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */ AHD_TARGETMODE = 0x01000,/* Has tested target mode support */ AHD_MULTIROLE = 0x02000,/* Space for two roles at a time */ diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index dfd4cc93c05c..6114b3e72caa 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -3331,6 +3331,15 @@ ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, if (tinfo->width == MSG_EXT_WDTR_BUS_16_BIT) con_opts |= WIDEXFER; + /* + * Slow down our CRC interval to be + * compatible with packetized U320 devices + * that can't handle a CRC at full speed + */ + if (ahd->features & AHD_AIC79XXB_SLOWCRC) { + con_opts |= ENSLOWCRC; + } + /* * During packetized transfers, the target will * give us the oportunity to send command packets @@ -6740,6 +6749,18 @@ ahd_chip_init(struct ahd_softc *ahd) ahd_loadseq(ahd); ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + + if (ahd->features & AHD_AIC79XXB_SLOWCRC) { + u_int negodat3 = ahd_inb(ahd, NEGCONOPTS); + + negodat3 |= ENSLOWCRC; + ahd_outb(ahd, NEGCONOPTS, negodat3); + negodat3 = ahd_inb(ahd, NEGCONOPTS); + if (!(negodat3 & ENSLOWCRC)) + printf("aic79xx: failed to set the SLOWCRC bit\n"); + else + printf("aic79xx: SLOWCRC bit set\n"); + } } /* diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 2567e29960bd..815c06312c88 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -314,6 +314,21 @@ static uint32_t aic79xx_seltime; */ uint32_t aic79xx_periodic_otag; +/* Some storage boxes are using an LSI chip which has a bug making it + * impossible to use aic79xx Rev B chip in 320 speeds. The following + * storage boxes have been reported to be buggy: + * EonStor 3U 16-Bay: U16U-G3A3 + * EonStor 2U 12-Bay: U12U-G3A3 + * SentinelRAID: 2500F R5 / R6 + * SentinelRAID: 2500F R1 + * SentinelRAID: 2500F/1500F + * SentinelRAID: 150F + * + * To get around this LSI bug, you can set your board to 160 mode + * or you can enable the SLOWCRC bit. + */ +uint32_t aic79xx_slowcrc; + /* * Module information and settable options. */ @@ -343,6 +358,7 @@ MODULE_PARM_DESC(aic79xx, " amplitude: Set the signal amplitude (0-7).\n" " seltime: Selection Timeout:\n" " (0/256ms,1/128ms,2/64ms,3/32ms)\n" +" slowcrc Turn on the SLOWCRC bit (Rev B only)\n" "\n" " Sample /etc/modprobe.conf line:\n" " Enable verbose logging\n" @@ -1003,6 +1019,7 @@ aic79xx_setup(char *s) { "slewrate", NULL }, { "precomp", NULL }, { "amplitude", NULL }, + { "slowcrc", &aic79xx_slowcrc }, }; end = strchr(s, '\0'); diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c index 196a6344b037..757242e522c2 100644 --- a/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_pci.c @@ -38,7 +38,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#89 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#92 $ */ #ifdef __linux__ @@ -950,12 +950,19 @@ ahd_aic790X_setup(struct ahd_softc *ahd) if ((ahd->flags & AHD_HP_BOARD) == 0) AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA); } else { + /* This is revision B and newer. */ + extern uint32_t aic79xx_slowcrc; u_int devconfig1; ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS - | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY; + | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY + | AHD_BUSFREEREV_BUG; ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG; + /* If the user requested the the SLOWCRC bit to be set. */ + if (aic79xx_slowcrc) + ahd->features |= AHD_AIC79XXB_SLOWCRC; + /* * Some issues have been resolved in the 7901B. */ From d60256b1b3ceb79cb06a5dd5e259b23bd27d4c61 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 24 Jan 2006 10:45:35 +0100 Subject: [PATCH 188/695] [SCSI] aic7xxx: update documentation This patch updates the documentation for aic7xxx and aic79xx with fixes from the adaptec driver. Signed-off-by: James Bottomley --- Documentation/scsi/aic79xx.txt | 93 ++++++++++++++-------------------- Documentation/scsi/aic7xxx.txt | 86 ++++++++++++------------------- 2 files changed, 68 insertions(+), 111 deletions(-) diff --git a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt index 0aeef740a95a..382b439b439e 100644 --- a/Documentation/scsi/aic79xx.txt +++ b/Documentation/scsi/aic79xx.txt @@ -1,5 +1,5 @@ ==================================================================== -= Adaptec Ultra320 Family Manager Set v1.3.11 = += Adaptec Ultra320 Family Manager Set = = = = README for = = The Linux Operating System = @@ -63,6 +63,11 @@ The following information is available in this file: 68-pin) 2. Version History + 3.0 (December 1st, 2005) + - Updated driver to use SCSI transport class infrastructure + - Upported sequencer and core fixes from adaptec released + version 2.0.15 of the driver. + 1.3.11 (July 11, 2003) - Fix several deadlock issues. - Add 29320ALP and 39320B Id's. @@ -194,7 +199,7 @@ The following information is available in this file: supported) - Support for the PCI-X standard up to 133MHz - Support for the PCI v2.2 standard - - Domain Validation + - Domain Validation 2.2. Operating System Support: - Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1 @@ -411,77 +416,53 @@ The following information is available in this file: http://www.adaptec.com. -5. Contacting Adaptec +5. Adaptec Customer Support A Technical Support Identification (TSID) Number is required for Adaptec technical support. - The 12-digit TSID can be found on the white barcode-type label - included inside the box with your product. The TSID helps us + included inside the box with your product. The TSID helps us provide more efficient service by accurately identifying your product and support status. + Support Options - Search the Adaptec Support Knowledgebase (ASK) at http://ask.adaptec.com for articles, troubleshooting tips, and - frequently asked questions for your product. + frequently asked questions about your product. - For support via Email, submit your question to Adaptec's - Technical Support Specialists at http://ask.adaptec.com. + Technical Support Specialists at http://ask.adaptec.com/. North America - - Visit our Web site at http://www.adaptec.com. - - To speak with a Fibre Channel/RAID/External Storage Technical - Support Specialist, call 1-321-207-2000, - Hours: Monday-Friday, 3:00 A.M. to 5:00 P.M., PST. - (Not open on holidays) - - For Technical Support in all other technologies including - SCSI, call 1-408-934-7274, - Hours: Monday-Friday, 6:00 A.M. to 5:00 P.M., PST. - (Not open on holidays) - - For after hours support, call 1-800-416-8066 ($99/call, - $149/call on holidays) - - To order Adaptec products including software and cables, call - 1-800-442-7274 or 1-408-957-7274. You can also visit our - online store at http://www.adaptecstore.com + - Visit our Web site at http://www.adaptec.com/. + - For information about Adaptec's support options, call + 408-957-2550, 24 hours a day, 7 days a week. + - To speak with a Technical Support Specialist, + * For hardware products, call 408-934-7274, + Monday to Friday, 3:00 am to 5:00 pm, PDT. + * For RAID and Fibre Channel products, call 321-207-2000, + Monday to Friday, 3:00 am to 5:00 pm, PDT. + To expedite your service, have your computer with you. + - To order Adaptec products, including accessories and cables, + call 408-957-7274. To order cables online go to + http://www.adaptec.com/buy-cables/. Europe - - Visit our Web site at http://www.adaptec-europe.com. - - English and French: To speak with a Technical Support - Specialist, call one of the following numbers: - - English: +32-2-352-3470 - - French: +32-2-352-3460 - Hours: Monday-Thursday, 10:00 to 12:30, 13:30 to 17:30 CET - Friday, 10:00 to 12:30, 13:30 to 16:30 CET - - German: To speak with a Technical Support Specialist, - call +49-89-456-40660 - Hours: Monday-Thursday, 09:30 to 12:30, 13:30 to 16:30 CET - Friday, 09:30 to 12:30, 13:30 to 15:00 CET - - To order Adaptec products, including accessories and cables: - - UK: +0800-96-65-26 or fax +0800-731-02-95 - - Other European countries: +32-11-300-379 - - Australia and New Zealand - - Visit our Web site at http://www.adaptec.com.au. - - To speak with a Technical Support Specialist, call - +612-9416-0698 - Hours: Monday-Friday, 10:00 A.M. to 4:30 P.M., EAT - (Not open on holidays) + - Visit our Web site at http://www.adaptec-europe.com/. + - To speak with a Technical Support Specialist, call, or email, + * German: +49 89 4366 5522, Monday-Friday, 9:00-17:00 CET, + http://ask-de.adaptec.com/. + * French: +49 89 4366 5533, Monday-Friday, 9:00-17:00 CET, + http://ask-fr.adaptec.com/. + * English: +49 89 4366 5544, Monday-Friday, 9:00-17:00 GMT, + http://ask.adaptec.com/. + - You can order Adaptec cables online at + http://www.adaptec.com/buy-cables/. Japan + - Visit our web site at http://www.adaptec.co.jp/. - To speak with a Technical Support Specialist, call - +81-3-5308-6120 - Hours: Monday-Friday, 9:00 a.m. to 12:00 p.m., 1:00 p.m. to - 6:00 p.m. TSC - - Hong Kong and China - - To speak with a Technical Support Specialist, call - +852-2869-7200 - Hours: Monday-Friday, 10:00 to 17:00. - - Fax Technical Support at +852-2869-7100. - - Singapore - - To speak with a Technical Support Specialist, call - +65-245-7470 - Hours: Monday-Friday, 10:00 to 17:00. - - Fax Technical Support at +852-2869-7100 + +81 3 5308 6120, Monday-Friday, 9:00 a.m. to 12:00 p.m., + 1:00 p.m. to 6:00 p.m. ------------------------------------------------------------------- /* diff --git a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt index 47e74ddc4bc9..3481fcded4c2 100644 --- a/Documentation/scsi/aic7xxx.txt +++ b/Documentation/scsi/aic7xxx.txt @@ -309,81 +309,57 @@ The following information is available in this file: ----------------------------------------------------------------- Example: - 'options aic7xxx aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1" + 'options aic7xxx aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1' enables verbose logging, Disable EISA/VLB probing, and set tag depth on Controller 1/Target 2 to 10 tags. -3. Contacting Adaptec +4. Adaptec Customer Support A Technical Support Identification (TSID) Number is required for Adaptec technical support. - The 12-digit TSID can be found on the white barcode-type label - included inside the box with your product. The TSID helps us + included inside the box with your product. The TSID helps us provide more efficient service by accurately identifying your product and support status. + Support Options - Search the Adaptec Support Knowledgebase (ASK) at http://ask.adaptec.com for articles, troubleshooting tips, and - frequently asked questions for your product. + frequently asked questions about your product. - For support via Email, submit your question to Adaptec's - Technical Support Specialists at http://ask.adaptec.com. + Technical Support Specialists at http://ask.adaptec.com/. North America - - Visit our Web site at http://www.adaptec.com. - - To speak with a Fibre Channel/RAID/External Storage Technical - Support Specialist, call 1-321-207-2000, - Hours: Monday-Friday, 3:00 A.M. to 5:00 P.M., PST. - (Not open on holidays) - - For Technical Support in all other technologies including - SCSI, call 1-408-934-7274, - Hours: Monday-Friday, 6:00 A.M. to 5:00 P.M., PST. - (Not open on holidays) - - For after hours support, call 1-800-416-8066 ($99/call, - $149/call on holidays) - - To order Adaptec products including software and cables, call - 1-800-442-7274 or 1-408-957-7274. You can also visit our - online store at http://www.adaptecstore.com + - Visit our Web site at http://www.adaptec.com/. + - For information about Adaptec's support options, call + 408-957-2550, 24 hours a day, 7 days a week. + - To speak with a Technical Support Specialist, + * For hardware products, call 408-934-7274, + Monday to Friday, 3:00 am to 5:00 pm, PDT. + * For RAID and Fibre Channel products, call 321-207-2000, + Monday to Friday, 3:00 am to 5:00 pm, PDT. + To expedite your service, have your computer with you. + - To order Adaptec products, including accessories and cables, + call 408-957-7274. To order cables online go to + http://www.adaptec.com/buy-cables/. Europe - - Visit our Web site at http://www.adaptec-europe.com. - - English and French: To speak with a Technical Support - Specialist, call one of the following numbers: - - English: +32-2-352-3470 - - French: +32-2-352-3460 - Hours: Monday-Thursday, 10:00 to 12:30, 13:30 to 17:30 CET - Friday, 10:00 to 12:30, 13:30 to 16:30 CET - - German: To speak with a Technical Support Specialist, - call +49-89-456-40660 - Hours: Monday-Thursday, 09:30 to 12:30, 13:30 to 16:30 CET - Friday, 09:30 to 12:30, 13:30 to 15:00 CET - - To order Adaptec products, including accessories and cables: - - UK: +0800-96-65-26 or fax +0800-731-02-95 - - Other European countries: +32-11-300-379 - - Australia and New Zealand - - Visit our Web site at http://www.adaptec.com.au. - - To speak with a Technical Support Specialist, call - +612-9416-0698 - Hours: Monday-Friday, 10:00 A.M. to 4:30 P.M., EAT - (Not open on holidays) + - Visit our Web site at http://www.adaptec-europe.com/. + - To speak with a Technical Support Specialist, call, or email, + * German: +49 89 4366 5522, Monday-Friday, 9:00-17:00 CET, + http://ask-de.adaptec.com/. + * French: +49 89 4366 5533, Monday-Friday, 9:00-17:00 CET, + http://ask-fr.adaptec.com/. + * English: +49 89 4366 5544, Monday-Friday, 9:00-17:00 GMT, + http://ask.adaptec.com/. + - You can order Adaptec cables online at + http://www.adaptec.com/buy-cables/. Japan + - Visit our web site at http://www.adaptec.co.jp/. - To speak with a Technical Support Specialist, call - +81-3-5308-6120 - Hours: Monday-Friday, 9:00 a.m. to 12:00 p.m., 1:00 p.m. to - 6:00 p.m. TSC - - Hong Kong and China - - To speak with a Technical Support Specialist, call - +852-2869-7200 - Hours: Monday-Friday, 10:00 to 17:00. - - Fax Technical Support at +852-2869-7100. - - Singapore - - To speak with a Technical Support Specialist, call - +65-245-7470 - Hours: Monday-Friday, 10:00 to 17:00. - - Fax Technical Support at +852-2869-7100 + +81 3 5308 6120, Monday-Friday, 9:00 a.m. to 12:00 p.m., + 1:00 p.m. to 6:00 p.m. ------------------------------------------------------------------- /* From eb221849540b7f4165c58b6c79d98b97ac902fdb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 30 Jan 2006 16:10:31 +0100 Subject: [PATCH 189/695] [SCSI] aic79xx: Fix timer handling Fix the timer handling in aic79xx to use the SCSI-ML provided handling instead of implementing our own. It also fixes a deadlock in the command recovery code. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/Kconfig.aic79xx | 4 ++-- drivers/scsi/aic7xxx/aic79xx_core.c | 5 ----- drivers/scsi/aic7xxx/aic79xx_osm.c | 26 +++++++++++++++----------- drivers/scsi/aic7xxx/aic79xx_osm.h | 8 -------- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx index 69ed77fcb71f..7955ebe8e1e8 100644 --- a/drivers/scsi/aic7xxx/Kconfig.aic79xx +++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx @@ -37,13 +37,13 @@ config AIC79XX_CMDS_PER_DEVICE config AIC79XX_RESET_DELAY_MS int "Initial bus reset delay in milli-seconds" depends on SCSI_AIC79XX - default "15000" + default "5000" ---help--- The number of milliseconds to delay after an initial bus reset. The bus settle delay following all error recovery actions is dictated by the SCSI layer and is not affected by this value. - Default: 15000 (15 seconds) + Default: 5000 (5 seconds) config AIC79XX_BUILD_FIRMWARE bool "Build Adapter Firmware with Kernel Build" diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 6114b3e72caa..342f77966a5b 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -8273,11 +8273,6 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) ahd_setup_data_scb(ahd, scb); scb->flags |= SCB_SENSE; ahd_queue_scb(ahd, scb); - /* - * Ensure we have enough time to actually - * retrieve the sense. - */ - ahd_scb_timer_reset(scb, 5 * 1000000); break; } case SCSI_STATUS_OK: diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 815c06312c88..7254ea535a16 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -1089,7 +1089,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa return (ENOMEM); *((struct ahd_softc **)host->hostdata) = ahd; - ahd_lock(ahd, &s); ahd->platform_data->host = host; host->can_queue = AHD_MAX_QUEUE; host->cmd_per_lun = 2; @@ -1100,7 +1099,9 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa host->max_lun = AHD_NUM_LUNS; host->max_channel = 0; host->sg_tablesize = AHD_NSEG; + ahd_lock(ahd, &s); ahd_set_unit(ahd, ahd_linux_unit++); + ahd_unlock(ahd, &s); sprintf(buf, "scsi%d", host->host_no); new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); if (new_name != NULL) { @@ -1110,7 +1111,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa host->unique_id = ahd->unit; ahd_linux_initialize_scsi_bus(ahd); ahd_intr_enable(ahd, TRUE); - ahd_unlock(ahd, &s); host->transportt = ahd_linux_transport_template; @@ -1144,6 +1144,7 @@ ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd) { u_int target_id; u_int numtarg; + unsigned long s; target_id = 0; numtarg = 0; @@ -1156,6 +1157,8 @@ ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd) else numtarg = (ahd->features & AHD_WIDE) ? 16 : 8; + ahd_lock(ahd, &s); + /* * Force negotiation to async for all targets that * will not see an initial bus reset. @@ -1172,16 +1175,12 @@ ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd) ahd_update_neg_request(ahd, &devinfo, tstate, tinfo, AHD_NEG_ALWAYS); } + ahd_unlock(ahd, &s); /* Give the bus some time to recover */ if ((ahd->flags & AHD_RESET_BUS_A) != 0) { ahd_freeze_simq(ahd); - init_timer(&ahd->platform_data->reset_timer); - ahd->platform_data->reset_timer.data = (u_long)ahd; - ahd->platform_data->reset_timer.expires = - jiffies + (AIC79XX_RESET_DELAY * HZ)/1000; - ahd->platform_data->reset_timer.function = - (ahd_linux_callback_t *)ahd_release_simq; - add_timer(&ahd->platform_data->reset_timer); + msleep(AIC79XX_RESET_DELAY); + ahd_release_simq(ahd); } } @@ -2050,6 +2049,9 @@ ahd_linux_sem_timeout(u_long arg) void ahd_freeze_simq(struct ahd_softc *ahd) { + unsigned long s; + + ahd_lock(ahd, &s); ahd->platform_data->qfrozen++; if (ahd->platform_data->qfrozen == 1) { scsi_block_requests(ahd->platform_data->host); @@ -2057,6 +2059,7 @@ ahd_freeze_simq(struct ahd_softc *ahd) CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_INITIATOR, CAM_REQUEUE_REQ); } + ahd_unlock(ahd, &s); } void @@ -2361,8 +2364,9 @@ done: ahd_name(ahd), dev->active); retval = FAILED; } - } - ahd_unlock(ahd, &flags); + } else + ahd_unlock(ahd, &flags); + return (retval); } diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 854fc57c304c..9cb101345107 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -228,7 +228,6 @@ typedef struct timer_list ahd_timer_t; typedef void ahd_linux_callback_t (u_long); static __inline void ahd_timer_reset(ahd_timer_t *timer, int usec, ahd_callback_t *func, void *arg); -static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec); static __inline void ahd_timer_reset(ahd_timer_t *timer, int usec, ahd_callback_t *func, void *arg) @@ -243,12 +242,6 @@ ahd_timer_reset(ahd_timer_t *timer, int usec, ahd_callback_t *func, void *arg) add_timer(timer); } -static __inline void -ahd_scb_timer_reset(struct scb *scb, u_int usec) -{ - mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000); -} - /***************************** SMP support ************************************/ #include @@ -389,7 +382,6 @@ struct ahd_platform_data { spinlock_t spin_lock; u_int qfrozen; - struct timer_list reset_timer; struct semaphore eh_sem; struct Scsi_Host *host; /* pointer to scsi host */ #define AHD_LINUX_NOIRQ ((uint32_t)~0) From d8e925dc8850c01e36e6b2acb08ed0fbdc38b9f1 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Mon, 16 Jan 2006 18:53:06 -0700 Subject: [PATCH 190/695] [SCSI] fusion: spi bus reset when driver loads This patch is for spi. This issues bus reset when driver loads. Handling cases when initator has negotiated for packetized, and target negotiated for non-packetized; effectly this bus reset is getting both target and initiator on the same sheet of music. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 8 ++++++++ drivers/message/fusion/mptspi.c | 10 +++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index d890b2b8a93e..2806662a9cf9 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -4598,6 +4598,14 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; MpiDeviceInfo_t *pdevice = NULL; + /* + * Save "Set to Avoid SCSI Bus Resets" flag + */ + ioc->spi_data.bus_reset = + (le32_to_cpu(pPP2->PortFlags) & + MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ? + 0 : 1 ; + /* Save the Port Page 2 data * (reformat into a 32bit quantity) */ diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 7dce29277cb7..f148dfa39117 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -384,6 +384,14 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_mptspi_probe; } + /* + * issue internal bus reset + */ + if (ioc->spi_data.bus_reset) + mptscsih_TMHandler(hd, + MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, + 0, 0, 0, 0, 5); + scsi_scan_host(sh); return 0; @@ -445,7 +453,7 @@ static void __exit mptspi_exit(void) { pci_unregister_driver(&mptspi_driver); - + mpt_reset_deregister(mptspiDoneCtx); dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n")); From 432b4c8b443af1b60cef7fcf90e8179cd8924f0a Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Mon, 16 Jan 2006 18:53:11 -0700 Subject: [PATCH 191/695] [SCSI] fusion: mptsas, increase discovery timout to 300 seconds Increase the port enable timeout only for SAS from 30 to 300 seconds. A customer request for the handling large topologies. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 2806662a9cf9..780e8be9066e 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -2770,13 +2770,16 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) /* RAID FW may take a long time to enable */ - if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) - > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) { - rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, - reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag); + if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) + > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) || + (ioc->bus_type == SAS)) { + rc = mpt_handshake_req_reply_wait(ioc, req_sz, + (u32*)&port_enable, reply_sz, (u16*)&reply_buf, + 300 /*seconds*/, sleepFlag); } else { - rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, - reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag); + rc = mpt_handshake_req_reply_wait(ioc, req_sz, + (u32*)&port_enable, reply_sz, (u16*)&reply_buf, + 30 /*seconds*/, sleepFlag); } return rc; } From d66c7a0f46ce53f1252e03fe372e39dc2dfff1ea Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Jan 2006 13:43:14 +0000 Subject: [PATCH 192/695] [SCSI] fusion: setting timeouts in eh threads appropiatley for fc/sas/spi On Mon, Jan 16, 2006 at 06:53:13PM -0700, Moore, Eric wrote: > The task managment request timeout in the eh threads was set > for U320 timing, which is between 2-5 seconds. > This is too small for FC and SAS. > According to the firmware engineers, Fibre needs to be 40 seconds > and SAS needs to be 10 seconds. The timeout selection should probably be done in a little helper instead of duplicated in a few places. Updated patch below. Signed-off-by: James Bottomley --- drivers/message/fusion/mptscsih.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index aa9cde807632..05832a8c5f0b 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1718,6 +1718,20 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun return retval; } +static int +mptscsih_get_tm_timeout(MPT_ADAPTER *ioc) +{ + switch (ioc->bus_type) { + case FC: + return 40; + case SAS: + return 10; + case SPI: + default: + return 2; + } +} + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant @@ -1789,7 +1803,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) vdev = SCpnt->device->hostdata; retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, vdev->bus_id, vdev->target_id, vdev->lun, - ctx2abort, 2 /* 2 second timeout */); + ctx2abort, mptscsih_get_tm_timeout(ioc)); printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", hd->ioc->name, @@ -1840,7 +1854,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) vdev = SCpnt->device->hostdata; retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, vdev->bus_id, vdev->target_id, - 0, 0, 5 /* 5 second timeout */); + 0, 0, mptscsih_get_tm_timeout(hd->ioc)); printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", hd->ioc->name, @@ -1890,7 +1904,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) vdev = SCpnt->device->hostdata; retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, - vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */); + vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", hd->ioc->name, From 928496ac317cff0eaf70aef2d5039a2f66966247 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Mon, 16 Jan 2006 18:53:16 -0700 Subject: [PATCH 193/695] [SCSI] fusion: increase reply frame size from 0x40 to 0x50 bytes Increasing the reply frame size by 16 bytes, to be in sync with the other fusion drivers. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 8e28a022e781..ea2649ecad1f 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -123,7 +123,7 @@ #define MPT_MAX_FRAME_SIZE 128 #define MPT_DEFAULT_FRAME_SIZE 128 -#define MPT_REPLY_FRAME_SIZE 0x40 /* Must be a multiple of 8 */ +#define MPT_REPLY_FRAME_SIZE 0x50 /* Must be a multiple of 8 */ #define MPT_SG_REQ_128_SCALE 1 #define MPT_SG_REQ_96_SCALE 2 From ece50914d5ce5c238e07d644e58701c173c48b7d Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Mon, 16 Jan 2006 18:53:19 -0700 Subject: [PATCH 194/695] [SCSI] fusion: add verbose messages for RAID actions A customer request to send raid asyn actions from firmware to the event syslog. This shows when raid volumes go degraded, or complete resync, or volumes created/deleted, etc. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 136 +++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 780e8be9066e..2ef64b9ada88 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -4389,6 +4389,138 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) return 0; } +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ + +static void +mptbase_raid_process_event_data(MPT_ADAPTER *ioc, + MpiEventDataRaid_t * pRaidEventData) +{ + int volume; + int reason; + int disk; + int status; + int flags; + int state; + + volume = pRaidEventData->VolumeID; + reason = pRaidEventData->ReasonCode; + disk = pRaidEventData->PhysDiskNum; + status = le32_to_cpu(pRaidEventData->SettingsStatus); + flags = (status >> 0) & 0xff; + state = (status >> 8) & 0xff; + + if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { + return; + } + + if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && + reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || + (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { + printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n", + ioc->name, disk); + } else { + printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", + ioc->name, volume); + } + + switch(reason) { + case MPI_EVENT_RAID_RC_VOLUME_CREATED: + printk(MYIOC_s_INFO_FMT " volume has been created\n", + ioc->name); + break; + + case MPI_EVENT_RAID_RC_VOLUME_DELETED: + + printk(MYIOC_s_INFO_FMT " volume has been deleted\n", + ioc->name); + break; + + case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED: + printk(MYIOC_s_INFO_FMT " volume settings have been changed\n", + ioc->name); + break; + + case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: + printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n", + ioc->name, + state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL + ? "optimal" + : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED + ? "degraded" + : state == MPI_RAIDVOL0_STATUS_STATE_FAILED + ? "failed" + : "state unknown", + flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED + ? ", enabled" : "", + flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED + ? ", quiesced" : "", + flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS + ? ", resync in progress" : "" ); + break; + + case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED: + printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n", + ioc->name, disk); + break; + + case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: + printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n", + ioc->name); + break; + + case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: + printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n", + ioc->name); + break; + + case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED: + printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n", + ioc->name); + break; + + case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: + printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n", + ioc->name, + state == MPI_PHYSDISK0_STATUS_ONLINE + ? "online" + : state == MPI_PHYSDISK0_STATUS_MISSING + ? "missing" + : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE + ? "not compatible" + : state == MPI_PHYSDISK0_STATUS_FAILED + ? "failed" + : state == MPI_PHYSDISK0_STATUS_INITIALIZING + ? "initializing" + : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED + ? "offline requested" + : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED + ? "failed requested" + : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE + ? "offline" + : "state unknown", + flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC + ? ", out of sync" : "", + flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED + ? ", quiesced" : "" ); + break; + + case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED: + printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n", + ioc->name, disk); + break; + + case MPI_EVENT_RAID_RC_SMART_DATA: + printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n", + ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ); + break; + + case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED: + printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n", + ioc->name, disk); + break; + } +} + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * GetIoUnitPage2 - Retrieve BIOS version and boot order information. @@ -5978,6 +6110,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply } } break; + case MPI_EVENT_INTEGRATED_RAID: + mptbase_raid_process_event_data(ioc, + (MpiEventDataRaid_t *)pEventReply->Data); + break; default: break; } From 7e55147fe3203b72e80186c45df9bf0fd6cd97c9 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Mon, 16 Jan 2006 18:53:21 -0700 Subject: [PATCH 195/695] [SCSI] fusion: overrun tape fix Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptscsih.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 05832a8c5f0b..4513ee7b7eab 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -727,6 +727,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) break; + case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ + sc->resid=0; case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ if (scsi_status == MPI_SCSI_STATUS_BUSY) @@ -786,7 +788,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */ case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */ case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ - case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ default: From 4ddce14e753fd4fe7445fa046a3aee155c2e48f4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Jan 2006 13:44:29 +0000 Subject: [PATCH 196/695] [SCSI] fusion: add MSI support On Mon, Jan 16, 2006 at 06:53:24PM -0700, Moore, Eric wrote: > Adding MSI support, and command line for enabling > it. By default, the command line option has MSI disabled. mpt_msi_enable is initialized to 0 implicitly, no need to do that. Also replace if (mpt_msi_enable == 1) tests with just if (mpt_msi_enable). Updated patch below: Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 2ef64b9ada88..e352b000c7d1 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -81,6 +81,10 @@ MODULE_LICENSE("GPL"); /* * cmd line parameters */ +static int mpt_msi_enable; +module_param(mpt_msi_enable, int, 0); +MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); + #ifdef MFCNT static int mfcounter = 0; #define PRINT_MF_COUNT 20000 @@ -1444,6 +1448,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->pci_irq = -1; if (pdev->irq) { + if (mpt_msi_enable && !pci_enable_msi(pdev)) + printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name); + r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); if (r < 0) { @@ -1483,6 +1490,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) list_del(&ioc->list); free_irq(ioc->pci_irq, ioc); + if (mpt_msi_enable) + pci_disable_msi(pdev); iounmap(mem); kfree(ioc); pci_set_drvdata(pdev, NULL); @@ -2136,6 +2145,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) if (ioc->pci_irq != -1) { free_irq(ioc->pci_irq, ioc); + if (mpt_msi_enable) + pci_disable_msi(ioc->pcidev); ioc->pci_irq = -1; } From 9f63bb73eb52df43f46ce2284759709fc40f4f52 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Mon, 16 Jan 2006 18:53:26 -0700 Subject: [PATCH 197/695] [SCSI] fusion: add task managment response code info Adding verbose message returned from firmware when a task mangment request fails. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptscsih.c | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 4513ee7b7eab..d6ccd6aa4348 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -2027,6 +2027,42 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ) return status; } +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +static void +mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code) +{ + char *desc; + + switch (response_code) { + case MPI_SCSITASKMGMT_RSP_TM_COMPLETE: + desc = "The task completed."; + break; + case MPI_SCSITASKMGMT_RSP_INVALID_FRAME: + desc = "The IOC received an invalid frame status."; + break; + case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED: + desc = "The task type is not supported."; + break; + case MPI_SCSITASKMGMT_RSP_TM_FAILED: + desc = "The requested task failed."; + break; + case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED: + desc = "The task completed successfully."; + break; + case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN: + desc = "The LUN request is invalid."; + break; + case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC: + desc = "The task is in the IOC queue and has not been sent to target."; + break; + default: + desc = "unknown"; + break; + } + printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n", + ioc->name, response_code, desc); +} + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver @@ -2076,6 +2112,11 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ tmType = pScsiTmReq->TaskType; + if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && + pScsiTmReply->ResponseCode) + mptscsih_taskmgmt_response_code(ioc, + pScsiTmReply->ResponseCode); + dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); From 23f236ed2748fca0bcba304f4f9e3eacda51e91c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 30 Jan 2006 19:00:43 +0100 Subject: [PATCH 198/695] [SCSI] mptsas: don't complain on bogus slave_alloc calls When people use the userspace scanning facilities on SAS hardware the LLDD gets bogus slave_alloc calls. Just fail those gracefully instead of printing a warning in mptsas and another one in the midlayer. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/message/fusion/mptsas.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 90660bfa148c..2512d0e6155e 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -304,9 +304,8 @@ mptsas_slave_alloc(struct scsi_device *sdev) } mutex_unlock(&hd->ioc->sas_topology_mutex); - printk("No matching SAS device found!!\n"); kfree(vdev); - return -ENODEV; + return -ENXIO; out: vtarget->ioc_id = vdev->ioc_id; From 335a94124470dd5be6c42378d1b7f7af9a80919e Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Tue, 17 Jan 2006 17:06:23 -0700 Subject: [PATCH 199/695] [SCSI] fusion: unloading the driver results in panic - fix The ioc->alt_ioc->alt_ioc pointer is not getting cleared during driver unload time. This dangling pointer can result in panic in certain circumstances, such as error recovery, or firmware download in flashless environments. This only impacts dual functions controllers, such as 1030. Please apply. This patch also includes a small cosmetic name change for mpt_spi_log_info. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index e352b000c7d1..9a2c7605d49c 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -178,7 +178,7 @@ static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); -static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info); +static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); /* module entry point */ @@ -317,7 +317,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) if (ioc->bus_type == FC) mpt_fc_log_info(ioc, log_info); else if (ioc->bus_type == SPI) - mpt_sp_log_info(ioc, log_info); + mpt_spi_log_info(ioc, log_info); else if (ioc->bus_type == SAS) mpt_sas_log_info(ioc, log_info); } @@ -1492,6 +1492,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) free_irq(ioc->pci_irq, ioc); if (mpt_msi_enable) pci_disable_msi(pdev); + if (ioc->alt_ioc) + ioc->alt_ioc->alt_ioc = NULL; iounmap(mem); kfree(ioc); pci_set_drvdata(pdev, NULL); @@ -2168,6 +2170,10 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) sz_last = ioc->alloc_total; dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); + + if (ioc->alt_ioc) + ioc->alt_ioc->alt_ioc = NULL; + kfree(ioc); } @@ -6204,7 +6210,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* - * mpt_sp_log_info - Log information returned from SCSI Parallel IOC. + * mpt_spi_log_info - Log information returned from SCSI Parallel IOC. * @ioc: Pointer to MPT_ADAPTER structure * @mr: Pointer to MPT reply frame * @log_info: U32 LogInfo word from the IOC @@ -6212,7 +6218,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) * Refer to lsi/sp_log.h. */ static void -mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info) +mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) { u32 info = log_info & 0x00FF0000; char *desc = "unknown"; From a69ac3248513ff0fbbdd8f316136036b3b8067a9 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Tue, 17 Jan 2006 17:06:26 -0700 Subject: [PATCH 200/695] [SCSI] fusion: unloading the driver - only set asyn narrow for configured devices This patch inhibits sending spi negotiation parameters for non-configured devices from the slave_destroy function. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptscsih.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index d6ccd6aa4348..2e1c9ff4b028 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -158,7 +158,7 @@ static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); -static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget); +static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice); static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION @@ -2308,7 +2308,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev) vtarget->luns[0] &= ~(1 << vdevice->lun); vtarget->num_luns--; if (vtarget->num_luns == 0) { - mptscsih_negotiate_to_asyn_narrow(hd, vtarget); + mptscsih_negotiate_to_asyn_narrow(hd, vdevice); if (hd->ioc->bus_type == SPI) { if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) { hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; @@ -3899,8 +3899,9 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) * */ static void -mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) +mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice) { + VirtTarget *vtarget = vdevice->vtarget; MPT_ADAPTER *ioc= hd->ioc; SCSIDevicePage1_t *pcfg1Data; CONFIGPARMS cfg; @@ -3910,7 +3911,8 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) int requested, configuration, data,i; u8 flags, factor; - if (ioc->bus_type != SPI) + if ((ioc->bus_type != SPI) || + (!vdevice->configured_lun)) return; if (!ioc->spi_data.sdp1length) @@ -3946,7 +3948,7 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) } mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, &configuration, flags); - dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " + dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC " "offset=0 negoFlags=%x request=%x config=%x\n", id, flags, requested, configuration)); pcfg1Data->RequestedParameters = cpu_to_le32(requested); @@ -3959,7 +3961,7 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) flags = vtarget->negoFlags; mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, &configuration, flags); - dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " + dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC " "offset=0 negoFlags=%x request=%x config=%x\n", vtarget->target_id, flags, requested, configuration)); pcfg1Data->RequestedParameters = cpu_to_le32(requested); From 2254c86db124a37057116ad20a8de7b8483b6f44 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Tue, 17 Jan 2006 17:06:29 -0700 Subject: [PATCH 201/695] [SCSI] fusion: add message sanity check This adds a sanity check in the interrupt routine insures incoming message frames are a valid message frames. The code for setting 0xdeadbeaf in the freed message frames, apparently was already submitted by Christoph in previous patch submission. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptscsih.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 2e1c9ff4b028..05789e505464 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -560,11 +560,24 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) MPT_SCSI_HOST *hd; SCSIIORequest_t *pScsiReq; SCSIIOReply_t *pScsiReply; - u16 req_idx; + u16 req_idx, req_idx_MR; hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); + req_idx_MR = (mr != NULL) ? + le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx; + if ((req_idx != req_idx_MR) || + (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) { + printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n", + ioc->name); + printk (MYIOC_s_ERR_FMT + "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n", + ioc->name, req_idx, req_idx_MR, mf, mr, + hd->ScsiLookup[req_idx_MR]); + return 0; + } + sc = hd->ScsiLookup[req_idx]; if (sc == NULL) { MPIHeader_t *hdr = (MPIHeader_t *)mf; From a5b3c86e4bfb5689d68932105d3fdd1477c9c281 Mon Sep 17 00:00:00 2001 From: Jack Hammer Date: Tue, 31 Jan 2006 13:17:55 -0500 Subject: [PATCH 202/695] [SCSI] ServeRAID: prevent seeing DADSI devices A critical thing the ServeRAID driver MUST do is hide the physical DASDI devices from the OS. It does this by intercepting the INQUIRY commands. In recent 2.6.15 testing, I discovered this to be failing. The cause was the driver assuming that the INQUIRY response data was in a simple single buffer, when it was actually a 1 element scatter gather list. This patch makes ips always look at the correct data when examining an INQUIRY response. Signed-off-by: Jack Hammer Signed-off-by: James Bottomley --- drivers/scsi/ips.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 32d592befca6..86c546164da9 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -3499,6 +3499,7 @@ ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp) int device_error; uint32_t transfer_len; IPS_DCDB_TABLE_TAPE *tapeDCDB; + IPS_SCSI_INQ_DATA inquiryData; METHOD_TRACE("ips_map_status", 1); @@ -3557,13 +3558,13 @@ ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp) errcode = DID_OK; /* Restrict access to physical DASD */ - if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && - ((((char *) scb->scsi_cmd-> - buffer)[0] & 0x1f) == TYPE_DISK)) { - /* underflow -- no error */ - /* restrict access to physical DASD */ - errcode = DID_TIME_OUT; - break; + if (scb->scsi_cmd->cmnd[0] == INQUIRY) { + ips_scmd_buf_read(scb->scsi_cmd, + &inquiryData, sizeof (inquiryData)); + if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) { + errcode = DID_TIME_OUT; + break; + } } } else errcode = DID_ERROR; @@ -4135,6 +4136,7 @@ ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus) uint8_t basic_status; uint8_t ext_status; int errcode; + IPS_SCSI_INQ_DATA inquiryData; METHOD_TRACE("ips_chkstatus", 1); @@ -4255,11 +4257,11 @@ ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus) scb->scsi_cmd->result = errcode << 16; } else { /* bus == 0 */ /* restrict access to physical drives */ - if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && - ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == - TYPE_DISK)) { - - scb->scsi_cmd->result = DID_TIME_OUT << 16; + if (scb->scsi_cmd->cmnd[0] == INQUIRY) { + ips_scmd_buf_read(scb->scsi_cmd, + &inquiryData, sizeof (inquiryData)); + if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) + scb->scsi_cmd->result = DID_TIME_OUT << 16; } } /* else */ } else { /* recovered error / success */ From dd1c1853e2742f4938b271dbe0cee735e2ffa3d9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 31 Jan 2006 13:11:41 -0800 Subject: [PATCH 203/695] Fix ipv4/igmp.c compile with gcc-4 and IP_MULTICAST Modern versions of gcc do not like case statements at the end of a block statement: you need at least an empty statement. Using just a "break;" is preferred for visual style. Signed-off-by: Linus Torvalds --- net/ipv4/igmp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index f70ba622c856..0b4e95f93dad 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -970,6 +970,7 @@ int igmp_rcv(struct sk_buff *skb) case IGMP_MTRACE_RESP: break; default: + break; } drop: From 3fa97c9db4f6f93f41f7a40d08872dbfd8dc907e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 31 Jan 2006 16:34:26 -0800 Subject: [PATCH 204/695] [PATCH] "Fix uidhash_lock <-> RXU deadlock" fix I get storms of warnings from local_bh_enable(). Better-tested patches, please. Cc: Ingo Molnar Cc: "Paul E. McKenney" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/user.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/kernel/user.c b/kernel/user.c index d1ae2349347e..d9deae43a9ab 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -33,6 +33,10 @@ static struct list_head uidhash_table[UIDHASH_SZ]; * The uidhash_lock is mostly taken from process context, but it is * occasionally also taken from softirq/tasklet context, when * task-structs get RCU-freed. Hence all locking must be softirq-safe. + * But free_uid() is also called with local interrupts disabled, and running + * local_bh_enable() with local interrupts disabled is an error - we'll run + * softirq callbacks, and they can unconditionally enable interrupts, and + * the caller of free_uid() didn't expect that.. */ static DEFINE_SPINLOCK(uidhash_lock); @@ -89,16 +93,19 @@ static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *has struct user_struct *find_user(uid_t uid) { struct user_struct *ret; + unsigned long flags; - spin_lock_bh(&uidhash_lock); + spin_lock_irqsave(&uidhash_lock, flags); ret = uid_hash_find(uid, uidhashentry(uid)); - spin_unlock_bh(&uidhash_lock); + spin_unlock_irqrestore(&uidhash_lock, flags); return ret; } void free_uid(struct user_struct *up) { - local_bh_disable(); + unsigned long flags; + + local_irq_save(flags); if (up && atomic_dec_and_lock(&up->__count, &uidhash_lock)) { uid_hash_remove(up); key_put(up->uid_keyring); @@ -106,7 +113,7 @@ void free_uid(struct user_struct *up) kmem_cache_free(uid_cachep, up); spin_unlock(&uidhash_lock); } - local_bh_enable(); + local_irq_restore(flags); } struct user_struct * alloc_uid(uid_t uid) @@ -114,9 +121,9 @@ struct user_struct * alloc_uid(uid_t uid) struct list_head *hashent = uidhashentry(uid); struct user_struct *up; - spin_lock_bh(&uidhash_lock); + spin_lock_irq(&uidhash_lock); up = uid_hash_find(uid, hashent); - spin_unlock_bh(&uidhash_lock); + spin_unlock_irq(&uidhash_lock); if (!up) { struct user_struct *new; @@ -146,7 +153,7 @@ struct user_struct * alloc_uid(uid_t uid) * Before adding this, check whether we raced * on adding the same user already.. */ - spin_lock_bh(&uidhash_lock); + spin_lock_irq(&uidhash_lock); up = uid_hash_find(uid, hashent); if (up) { key_put(new->uid_keyring); @@ -156,7 +163,7 @@ struct user_struct * alloc_uid(uid_t uid) uid_hash_insert(new, hashent); up = new; } - spin_unlock_bh(&uidhash_lock); + spin_unlock_irq(&uidhash_lock); } return up; @@ -192,9 +199,9 @@ static int __init uid_cache_init(void) INIT_LIST_HEAD(uidhash_table + n); /* Insert the root user immediately (init already runs as root) */ - spin_lock_bh(&uidhash_lock); + spin_lock_irq(&uidhash_lock); uid_hash_insert(&root_user, uidhashentry(0)); - spin_unlock_bh(&uidhash_lock); + spin_unlock_irq(&uidhash_lock); return 0; } From 7fb76aa07facce5cb9c8d26a0de09001a31eed0c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 17:09:20 -0800 Subject: [PATCH 205/695] [SUNGEM]: Unbreak Sun GEM chips. Revert: 40727198bfb2ce5842a6e8c7f89cf8a40ff7bf14 These PHY changes hang the sungem driver on startup with Sun chips on sparc64. Hopefully we can redo these changes in a way that doesn't break non-Apple systems. Signed-off-by: David S. Miller --- arch/powerpc/platforms/powermac/feature.c | 6 +-- drivers/net/sungem.c | 57 +++++++++++------------ 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 2296f3d46ca8..558dd0692092 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -910,18 +910,16 @@ core99_gmac_phy_reset(struct device_node *node, long param, long value) macio->type != macio_intrepid) return -ENODEV; - printk(KERN_DEBUG "Hard reset of PHY chip ...\n"); - LOCK(flags); MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE); (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET); UNLOCK(flags); - msleep(10); + mdelay(10); LOCK(flags); MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */ KEYLARGO_GPIO_OUTOUT_DATA); UNLOCK(flags); - msleep(10); + mdelay(10); return 0; } diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 55f3b856236e..28ce47a02408 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -1653,40 +1653,36 @@ static void gem_init_rings(struct gem *gp) /* Init PHY interface and start link poll state machine */ static void gem_init_phy(struct gem *gp) { - u32 mif_cfg; + u32 mifcfg; /* Revert MIF CFG setting done on stop_phy */ - mif_cfg = readl(gp->regs + MIF_CFG); - mif_cfg &= ~(MIF_CFG_PSELECT|MIF_CFG_POLL|MIF_CFG_BBMODE|MIF_CFG_MDI1); - mif_cfg |= MIF_CFG_MDI0; - writel(mif_cfg, gp->regs + MIF_CFG); - writel(PCS_DMODE_MGM, gp->regs + PCS_DMODE); - writel(MAC_XIFCFG_OE, gp->regs + MAC_XIFCFG); + mifcfg = readl(gp->regs + MIF_CFG); + mifcfg &= ~MIF_CFG_BBMODE; + writel(mifcfg, gp->regs + MIF_CFG); if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) { int i; - u16 ctrl; -#ifdef CONFIG_PPC_PMAC - pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0); -#endif - - /* Some PHYs used by apple have problem getting back - * to us, we do an additional reset here + /* Those delay sucks, the HW seem to love them though, I'll + * serisouly consider breaking some locks here to be able + * to schedule instead */ - phy_write(gp, MII_BMCR, BMCR_RESET); - for (i = 0; i < 50; i++) { - if ((phy_read(gp, MII_BMCR) & BMCR_RESET) == 0) + for (i = 0; i < 3; i++) { +#ifdef CONFIG_PPC_PMAC + pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0); + msleep(20); +#endif + /* Some PHYs used by apple have problem getting back to us, + * we do an additional reset here + */ + phy_write(gp, MII_BMCR, BMCR_RESET); + msleep(20); + if (phy_read(gp, MII_BMCR) != 0xffff) break; - msleep(10); + if (i == 2) + printk(KERN_WARNING "%s: GMAC PHY not responding !\n", + gp->dev->name); } - if (i == 50) - printk(KERN_WARNING "%s: GMAC PHY not responding !\n", - gp->dev->name); - /* Make sure isolate is off */ - ctrl = phy_read(gp, MII_BMCR); - if (ctrl & BMCR_ISOLATE) - phy_write(gp, MII_BMCR, ctrl & ~BMCR_ISOLATE); } if (gp->pdev->vendor == PCI_VENDOR_ID_SUN && @@ -2123,7 +2119,7 @@ static void gem_reinit_chip(struct gem *gp) /* Must be invoked with no lock held. */ static void gem_stop_phy(struct gem *gp, int wol) { - u32 mif_cfg; + u32 mifcfg; unsigned long flags; /* Let the chip settle down a bit, it seems that helps @@ -2134,9 +2130,9 @@ static void gem_stop_phy(struct gem *gp, int wol) /* Make sure we aren't polling PHY status change. We * don't currently use that feature though */ - mif_cfg = readl(gp->regs + MIF_CFG); - mif_cfg &= ~MIF_CFG_POLL; - writel(mif_cfg, gp->regs + MIF_CFG); + mifcfg = readl(gp->regs + MIF_CFG); + mifcfg &= ~MIF_CFG_POLL; + writel(mifcfg, gp->regs + MIF_CFG); if (wol && gp->has_wol) { unsigned char *e = &gp->dev->dev_addr[0]; @@ -2186,8 +2182,7 @@ static void gem_stop_phy(struct gem *gp, int wol) /* According to Apple, we must set the MDIO pins to this begnign * state or we may 1) eat more current, 2) damage some PHYs */ - mif_cfg = 0; - writel(mif_cfg | MIF_CFG_BBMODE, gp->regs + MIF_CFG); + writel(mifcfg | MIF_CFG_BBMODE, gp->regs + MIF_CFG); writel(0, gp->regs + MIF_BBCLK); writel(0, gp->regs + MIF_BBDATA); writel(0, gp->regs + MIF_BBOENAB); From 3a69c7dc6f3d58aeb9ce5051fc7060d55e05c003 Mon Sep 17 00:00:00 2001 From: Yingping Lu Date: Wed, 1 Feb 2006 12:14:34 +1100 Subject: [PATCH 206/695] [XFS] Interim solution for attribute insertion failure during file creation due to ENOSPC. The current solution removes the inode when the attribute insertion fails. Long term solution would be to make the inode creation and attribute insertion atomic. SGI-PV: 947610 SGI-Modid: xfs-linux-melb:xfs-kern:205193a Signed-off-by: Yingping Lu Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_iops.c | 50 ++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 76c6df34d0db..eda7919b70a1 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -262,6 +262,31 @@ has_fs_struct(struct task_struct *task) return (task->fs != init_task.fs); } +STATIC inline void +cleanup_inode( + vnode_t *dvp, + vnode_t *vp, + struct dentry *dentry, + int mode) +{ + struct dentry teardown = {}; + int err2; + + /* Oh, the horror. + * If we can't add the ACL or we fail in + * linvfs_init_security we must back out. + * ENOSPC can hit here, among other things. + */ + teardown.d_inode = LINVFS_GET_IP(vp); + teardown.d_name = dentry->d_name; + + if (S_ISDIR(mode)) + VOP_RMDIR(dvp, &teardown, NULL, err2); + else + VOP_REMOVE(dvp, &teardown, NULL, err2); + VN_RELE(vp); +} + STATIC int linvfs_mknod( struct inode *dir, @@ -316,30 +341,19 @@ linvfs_mknod( } if (!error) + { error = linvfs_init_security(vp, dir); + if (error) + cleanup_inode(dvp, vp, dentry, mode); + } if (default_acl) { if (!error) { error = _ACL_INHERIT(vp, &va, default_acl); - if (!error) { + if (!error) VMODIFY(vp); - } else { - struct dentry teardown = {}; - int err2; - - /* Oh, the horror. - * If we can't add the ACL we must back out. - * ENOSPC can hit here, among other things. - */ - teardown.d_inode = ip = LINVFS_GET_IP(vp); - teardown.d_name = dentry->d_name; - - if (S_ISDIR(mode)) - VOP_RMDIR(dvp, &teardown, NULL, err2); - else - VOP_REMOVE(dvp, &teardown, NULL, err2); - VN_RELE(vp); - } + else + cleanup_inode(dvp, vp, dentry, mode); } _ACL_FREE(default_acl); } From fad3aa1e8e2e4123a19b926fefd91ec63dd56497 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Wed, 1 Feb 2006 12:14:52 +1100 Subject: [PATCH 207/695] [XFS] Fix regression in xfs_buf_rele dealing with non-hashed buffers, as occur during log replay. Novell bug 145204, Fedora bug 177848. SGI-PV: 948860 SGI-Modid: xfs-linux-melb:xfs-kern:25064a Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_buf.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index e44b7c1a3a36..a36a8e3b703f 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -822,6 +822,13 @@ xfs_buf_rele( XB_TRACE(bp, "rele", bp->b_relse); + if (unlikely(!hash)) { + ASSERT(!bp->b_relse); + if (atomic_dec_and_test(&bp->b_hold)) + xfs_buf_free(bp); + return; + } + if (atomic_dec_and_lock(&bp->b_hold, &hash->bh_lock)) { if (bp->b_relse) { atomic_inc(&bp->b_hold); From 401feafa621ba98ecaeed5db1a53ab878943c225 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 24 Jan 2006 07:15:30 -0800 Subject: [PATCH 208/695] [PATCH] USB: fix EHCI early handoff issues This moves the previously widely-used ehci-pci.c BIOS handoff code into the pci-quirks.c file, replacing the less widely used "early handoff" version that seems to cause problems lately. One notable change: the "early handoff" version always enabled an SMI IRQ ... and did so even if the pre-Linux code said it was not using EHCI (and not expecting EHCI SMIs). Looks like a goof in a workaround for some unknown BIOS version. This merged version only forcibly enables those IRQs when pre-Linux code says it's using EHCI. And now it always forces them off "just in case". Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-pci.c | 63 +------------------ drivers/usb/host/pci-quirks.c | 112 +++++++++++++++++++++------------- 2 files changed, 74 insertions(+), 101 deletions(-) diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 08ca0f849dab..286b2f4acdc2 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -24,40 +24,6 @@ /*-------------------------------------------------------------------------*/ -/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... - * off the controller (maybe it can boot from highspeed USB disks). - */ -static int bios_handoff(struct ehci_hcd *ehci, int where, u32 cap) -{ - struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); - - /* always say Linux will own the hardware */ - pci_write_config_byte(pdev, where + 3, 1); - - /* maybe wait a while for BIOS to respond */ - if (cap & (1 << 16)) { - int msec = 5000; - - do { - msleep(10); - msec -= 10; - pci_read_config_dword(pdev, where, &cap); - } while ((cap & (1 << 16)) && msec); - if (cap & (1 << 16)) { - ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", - where, cap); - // some BIOS versions seem buggy... - // return 1; - ehci_warn(ehci, "continuing after BIOS bug...\n"); - /* disable all SMIs, and clear "BIOS owns" flag */ - pci_write_config_dword(pdev, where + 4, 0); - pci_write_config_byte(pdev, where + 2, 0); - } else - ehci_dbg(ehci, "BIOS handoff succeeded\n"); - } - return 0; -} - /* called after powerup, by probe or system-pm "wakeup" */ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) { @@ -84,32 +50,9 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) } } - temp = HCC_EXT_CAPS(readl(&ehci->caps->hcc_params)); - - /* EHCI 0.96 and later may have "extended capabilities" */ - while (temp && count--) { - u32 cap; - - pci_read_config_dword(pdev, temp, &cap); - ehci_dbg(ehci, "capability %04x at %02x\n", cap, temp); - switch (cap & 0xff) { - case 1: /* BIOS/SMM/... handoff */ - if (bios_handoff(ehci, temp, cap) != 0) - return -EOPNOTSUPP; - break; - case 0: /* illegal reserved capability */ - ehci_dbg(ehci, "illegal capability!\n"); - cap = 0; - /* FALLTHROUGH */ - default: /* unknown */ - break; - } - temp = (cap >> 8) & 0xff; - } - if (!count) { - ehci_err(ehci, "bogus capabilities ... PCI problems!\n"); - return -EIO; - } + /* we expect static quirk code to handle the "extended capabilities" + * (currently just BIOS handoff) allowed starting with EHCI 0.96 + */ /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */ retval = pci_set_mwi(pdev); diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 3ef2c0cdf1db..e9e5bc178cef 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -190,7 +190,7 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) msleep(10); } if (wait_time <= 0) - printk(KERN_WARNING "%s %s: early BIOS handoff " + printk(KERN_WARNING "%s %s: BIOS handoff " "failed (BIOS bug ?)\n", pdev->dev.bus_id, "OHCI"); @@ -212,8 +212,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) { int wait_time, delta; void __iomem *base, *op_reg_base; - u32 hcc_params, val, temp; - u8 cap_length; + u32 hcc_params, val; + u8 offset, cap_length; + int count = 256/4; if (!mmio_resource_enabled(pdev, 0)) return; @@ -224,51 +225,80 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) cap_length = readb(base); op_reg_base = base + cap_length; - hcc_params = readl(base + EHCI_HCC_PARAMS); - hcc_params = (hcc_params >> 8) & 0xff; - if (hcc_params) { - pci_read_config_dword(pdev, - hcc_params + EHCI_USBLEGSUP, - &val); - if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { - /* - * Ok, BIOS is in smm mode, try to hand off... - */ - pci_read_config_dword(pdev, - hcc_params + EHCI_USBLEGCTLSTS, - &temp); - pci_write_config_dword(pdev, - hcc_params + EHCI_USBLEGCTLSTS, - temp | EHCI_USBLEGCTLSTS_SOOE); - val |= EHCI_USBLEGSUP_OS; - pci_write_config_dword(pdev, - hcc_params + EHCI_USBLEGSUP, - val); - wait_time = 500; - do { - msleep(10); - wait_time -= 10; - pci_read_config_dword(pdev, - hcc_params + EHCI_USBLEGSUP, - &val); - } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); - if (!wait_time) { - /* - * well, possibly buggy BIOS... + /* EHCI 0.96 and later may have "extended capabilities" + * spec section 5.1 explains the bios handoff, e.g. for + * booting from USB disk or using a usb keyboard + */ + hcc_params = readl(base + EHCI_HCC_PARAMS); + offset = (hcc_params >> 8) & 0xff; + while (offset && count--) { + u32 cap; + int msec; + + pci_read_config_dword(pdev, offset, &cap); + switch (cap & 0xff) { + case 1: /* BIOS/SMM/... handoff support */ + if ((cap & EHCI_USBLEGSUP_BIOS)) { + pr_debug("%s %s: BIOS handoff\n", + pdev->dev.bus_id, "EHCI"); + + /* BIOS workaround (?): be sure the + * pre-Linux code receives the SMI */ - printk(KERN_WARNING "%s %s: early BIOS handoff " + pci_read_config_dword(pdev, + offset + EHCI_USBLEGCTLSTS, + &val); + pci_write_config_dword(pdev, + offset + EHCI_USBLEGCTLSTS, + val | EHCI_USBLEGCTLSTS_SOOE); + } + + /* always say Linux will own the hardware + * by setting EHCI_USBLEGSUP_OS. + */ + pci_write_config_byte(pdev, offset + 3, 1); + + /* if boot firmware now owns EHCI, spin till + * it hands it over. + */ + msec = 5000; + while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { + msleep(10); + msec -= 10; + pci_read_config_dword(pdev, offset, &cap); + } + + if (cap & EHCI_USBLEGSUP_BIOS) { + /* well, possibly buggy BIOS... try to shut + * it down, and hope nothing goes too wrong + */ + printk(KERN_WARNING "%s %s: BIOS handoff " "failed (BIOS bug ?)\n", pdev->dev.bus_id, "EHCI"); - pci_write_config_dword(pdev, - hcc_params + EHCI_USBLEGSUP, - EHCI_USBLEGSUP_OS); - pci_write_config_dword(pdev, - hcc_params + EHCI_USBLEGCTLSTS, - 0); + pci_write_config_byte(pdev, offset + 2, 0); } + + /* just in case, always disable EHCI SMIs */ + pci_write_config_dword(pdev, + offset + EHCI_USBLEGCTLSTS, + 0); + break; + case 0: /* illegal reserved capability */ + cap = 0; + /* FALLTHROUGH */ + default: + printk(KERN_WARNING "%s %s: unrecognized " + "capability %02x\n", + pdev->dev.bus_id, "EHCI", + cap & 0xff); + break; } + offset = (cap >> 8) & 0xff; } + if (!count) + printk(KERN_DEBUG "%s %s: capability loop?\n", + pdev->dev.bus_id, "EHCI"); /* * halt EHCI & disable its interrupts in any case From b6daf7f50836c8ed12d8b0ec0113e415f04e8530 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 24 Jan 2006 17:42:24 -0800 Subject: [PATCH 209/695] [PATCH] USB: fix ehci early handoff issues warning Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-pci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 286b2f4acdc2..3a6687df5594 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -29,7 +29,6 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) { u32 temp; int retval; - unsigned count = 256/4; /* optional debug port, normally in the first BAR */ temp = pci_find_capability(pdev, 0x0a); From 65b4fe553bf43018c06740f3d1f6caf42cf95924 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Wed, 28 Dec 2005 14:22:17 -0800 Subject: [PATCH 210/695] [PATCH] USB: ub 03 Oops with CFQ The blk_cleanup_queue does not necesserily destroy the queue. When we destroy the corresponding ub_dev, it may leave the queue spinlock pointer dangling. This patch moves spinlocks from ub_dev to static memory. The locking scheme is not changed. These spinlocks are still separate from the ub_lock. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/block/ub.c | 68 ++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/drivers/block/ub.c b/drivers/block/ub.c index a05fe5843e6c..db4943c53d36 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -355,7 +355,7 @@ struct ub_lun { * The USB device instance. */ struct ub_dev { - spinlock_t lock; + spinlock_t *lock; atomic_t poison; /* The USB device is disconnected */ int openc; /* protected by ub_lock! */ /* kref is too implicit for our taste */ @@ -452,6 +452,10 @@ MODULE_DEVICE_TABLE(usb, ub_usb_ids); #define UB_MAX_HOSTS 26 static char ub_hostv[UB_MAX_HOSTS]; +#define UB_QLOCK_NUM 5 +static spinlock_t ub_qlockv[UB_QLOCK_NUM]; +static int ub_qlock_next = 0; + static DEFINE_SPINLOCK(ub_lock); /* Locks globals and ->openc */ /* @@ -531,7 +535,7 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, return 0; cnt = 0; - spin_lock_irqsave(&sc->lock, flags); + spin_lock_irqsave(sc->lock, flags); cnt += sprintf(page + cnt, "poison %d reset %d\n", @@ -579,7 +583,7 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, if (++nc == SCMD_TRACE_SZ) nc = 0; } - spin_unlock_irqrestore(&sc->lock, flags); + spin_unlock_irqrestore(sc->lock, flags); return cnt; } @@ -626,6 +630,24 @@ static void ub_id_put(int id) spin_unlock_irqrestore(&ub_lock, flags); } +/* + * This is necessitated by the fact that blk_cleanup_queue does not + * necesserily destroy the queue. Instead, it may merely decrease q->refcnt. + * Since our blk_init_queue() passes a spinlock common with ub_dev, + * we have life time issues when ub_cleanup frees ub_dev. + */ +static spinlock_t *ub_next_lock(void) +{ + unsigned long flags; + spinlock_t *ret; + + spin_lock_irqsave(&ub_lock, flags); + ret = &ub_qlockv[ub_qlock_next]; + ub_qlock_next = (ub_qlock_next + 1) % UB_QLOCK_NUM; + spin_unlock_irqrestore(&ub_lock, flags); + return ret; +} + /* * Downcount for deallocation. This rides on two assumptions: * - once something is poisoned, its refcount cannot grow @@ -1083,9 +1105,9 @@ static void ub_urb_timeout(unsigned long arg) struct ub_dev *sc = (struct ub_dev *) arg; unsigned long flags; - spin_lock_irqsave(&sc->lock, flags); + spin_lock_irqsave(sc->lock, flags); usb_unlink_urb(&sc->work_urb); - spin_unlock_irqrestore(&sc->lock, flags); + spin_unlock_irqrestore(sc->lock, flags); } /* @@ -1108,10 +1130,10 @@ static void ub_scsi_action(unsigned long _dev) struct ub_dev *sc = (struct ub_dev *) _dev; unsigned long flags; - spin_lock_irqsave(&sc->lock, flags); + spin_lock_irqsave(sc->lock, flags); del_timer(&sc->work_timer); ub_scsi_dispatch(sc); - spin_unlock_irqrestore(&sc->lock, flags); + spin_unlock_irqrestore(sc->lock, flags); } static void ub_scsi_dispatch(struct ub_dev *sc) @@ -1754,7 +1776,7 @@ static void ub_reset_task(void *arg) * queues of resets or anything. We do need a spinlock though, * to interact with block layer. */ - spin_lock_irqsave(&sc->lock, flags); + spin_lock_irqsave(sc->lock, flags); sc->reset = 0; tasklet_schedule(&sc->tasklet); list_for_each(p, &sc->luns) { @@ -1762,7 +1784,7 @@ static void ub_reset_task(void *arg) blk_start_queue(lun->disk->queue); } wake_up(&sc->reset_wait); - spin_unlock_irqrestore(&sc->lock, flags); + spin_unlock_irqrestore(sc->lock, flags); } /* @@ -1990,11 +2012,11 @@ static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun) cmd->done = ub_probe_done; cmd->back = &compl; - spin_lock_irqsave(&sc->lock, flags); + spin_lock_irqsave(sc->lock, flags); cmd->tag = sc->tagcnt++; rc = ub_submit_scsi(sc, cmd); - spin_unlock_irqrestore(&sc->lock, flags); + spin_unlock_irqrestore(sc->lock, flags); if (rc != 0) { printk("ub: testing ready: submit error (%d)\n", rc); /* P3 */ @@ -2052,11 +2074,11 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, cmd->done = ub_probe_done; cmd->back = &compl; - spin_lock_irqsave(&sc->lock, flags); + spin_lock_irqsave(sc->lock, flags); cmd->tag = sc->tagcnt++; rc = ub_submit_scsi(sc, cmd); - spin_unlock_irqrestore(&sc->lock, flags); + spin_unlock_irqrestore(sc->lock, flags); if (rc != 0) { printk("ub: reading capacity: submit error (%d)\n", rc); /* P3 */ @@ -2333,7 +2355,7 @@ static int ub_probe(struct usb_interface *intf, if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL) goto err_core; memset(sc, 0, sizeof(struct ub_dev)); - spin_lock_init(&sc->lock); + sc->lock = ub_next_lock(); INIT_LIST_HEAD(&sc->luns); usb_init_urb(&sc->work_urb); tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); @@ -2483,7 +2505,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) disk->driverfs_dev = &sc->intf->dev; rc = -ENOMEM; - if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL) + if ((q = blk_init_queue(ub_request_fn, sc->lock)) == NULL) goto err_blkqinit; disk->queue = q; @@ -2554,7 +2576,7 @@ static void ub_disconnect(struct usb_interface *intf) * and the whole queue drains. So, we just use this code to * print warnings. */ - spin_lock_irqsave(&sc->lock, flags); + spin_lock_irqsave(sc->lock, flags); { struct ub_scsi_cmd *cmd; int cnt = 0; @@ -2571,7 +2593,7 @@ static void ub_disconnect(struct usb_interface *intf) "%d was queued after shutdown\n", sc->name, cnt); } } - spin_unlock_irqrestore(&sc->lock, flags); + spin_unlock_irqrestore(sc->lock, flags); /* * Unregister the upper layer. @@ -2590,19 +2612,15 @@ static void ub_disconnect(struct usb_interface *intf) } /* - * Taking a lock on a structure which is about to be freed - * is very nonsensual. Here it is largely a way to do a debug freeze, - * and a bracket which shows where the nonsensual code segment ends. - * * Testing for -EINPROGRESS is always a bug, so we are bending * the rules a little. */ - spin_lock_irqsave(&sc->lock, flags); + spin_lock_irqsave(sc->lock, flags); if (sc->work_urb.status == -EINPROGRESS) { /* janitors: ignore */ printk(KERN_WARNING "%s: " "URB is active after disconnect\n", sc->name); } - spin_unlock_irqrestore(&sc->lock, flags); + spin_unlock_irqrestore(sc->lock, flags); /* * There is virtually no chance that other CPU runs times so long @@ -2636,6 +2654,10 @@ static struct usb_driver ub_driver = { static int __init ub_init(void) { int rc; + int i; + + for (i = 0; i < UB_QLOCK_NUM; i++) + spin_lock_init(&ub_qlockv[i]); if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) goto err_regblkdev; From b31f821c6dee6f3ecfca6b2583a6552538fb91bf Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Thu, 5 Jan 2006 00:14:02 -0800 Subject: [PATCH 211/695] [PATCH] USB: ub 04 Loss of timer and a hang If SCSI commands are submitted while other commands are still processed, the dispatch loop turns, and we stop the work_timer. Then, if URB fails to complete, ub hangs until the device is unplugged. This does not happen often, becase we only allow one SCSI command per block device, but does happen (on multi-LUN devices, for example). The fix is to stop timer only when we actually going to change the state. The nicest code would be to have the timer stopped in URB callback, but this is impossible, because it can be called from inside a timer, through the urb_unlink. Then we get BUG in timer.c:cascade(). So, we do it a little dirtier. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/block/ub.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/ub.c b/drivers/block/ub.c index db4943c53d36..c3600cb36365 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -1106,7 +1106,8 @@ static void ub_urb_timeout(unsigned long arg) unsigned long flags; spin_lock_irqsave(sc->lock, flags); - usb_unlink_urb(&sc->work_urb); + if (!ub_is_completed(&sc->work_done)) + usb_unlink_urb(&sc->work_urb); spin_unlock_irqrestore(sc->lock, flags); } @@ -1131,7 +1132,6 @@ static void ub_scsi_action(unsigned long _dev) unsigned long flags; spin_lock_irqsave(sc->lock, flags); - del_timer(&sc->work_timer); ub_scsi_dispatch(sc); spin_unlock_irqrestore(sc->lock, flags); } @@ -1155,6 +1155,7 @@ static void ub_scsi_dispatch(struct ub_dev *sc) } else { if (!ub_is_completed(&sc->work_done)) break; + del_timer(&sc->work_timer); ub_scsi_urb_compl(sc, cmd); } } From 2c2e4a2e07f4c16486dd2ac859eb9c558b1c9935 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Thu, 5 Jan 2006 00:26:30 -0800 Subject: [PATCH 212/695] [PATCH] USB: ub 05 Bulk reset For crying out loud, they have devices which do not like port resets. So, do what usb-storage does and try both bulk and port resets. We start with a port reset (which usb-storage does at the end of transport), then do a Bulk reset, then a port reset again. This seems to work for me. The code is getting dirtier and dirtier here, but I swear that I'll do something about it (see those two new XXX). Honest. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/block/ub.c | 66 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/drivers/block/ub.c b/drivers/block/ub.c index c3600cb36365..f04d864770ad 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -14,7 +14,6 @@ * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries * -- verify the 13 conditions and do bulk resets * -- kill last_pipe and simply do two-state clearing on both pipes - * -- verify protocol (bulk) from USB descriptors (maybe...) * -- highmem * -- move top_sense and work_bcs into separate allocations (if they survive) * for cache purists and esoteric architectures. @@ -420,11 +419,13 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd); static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int stalled_pipe); static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); -static void ub_reset_enter(struct ub_dev *sc); +static void ub_reset_enter(struct ub_dev *sc, int try); static void ub_reset_task(void *arg); static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, struct ub_capacity *ret); +static int ub_sync_reset(struct ub_dev *sc); +static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe); static int ub_probe_lun(struct ub_dev *sc, int lnum); /* @@ -983,7 +984,7 @@ static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, if (atomic_read(&sc->poison)) return -ENXIO; - ub_reset_enter(sc); + ub_reset_enter(sc, urq->current_try); if (urq->current_try >= 3) return -EIO; @@ -1019,8 +1020,6 @@ static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, * No exceptions. * * Host is assumed locked. - * - * XXX We only support Bulk for the moment. */ static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd) { @@ -1703,16 +1702,18 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) /* * Reset management + * XXX Move usb_reset_device to khubd. Hogging kevent is not a good thing. + * XXX Make usb_sync_reset asynchronous. */ -static void ub_reset_enter(struct ub_dev *sc) +static void ub_reset_enter(struct ub_dev *sc, int try) { if (sc->reset) { /* This happens often on multi-LUN devices. */ return; } - sc->reset = 1; + sc->reset = try + 1; #if 0 /* Not needed because the disconnect waits for us. */ unsigned long flags; @@ -1750,6 +1751,11 @@ static void ub_reset_task(void *arg) if (atomic_read(&sc->poison)) { printk(KERN_NOTICE "%s: Not resetting disconnected device\n", sc->name); /* P3 This floods. Remove soon. XXX */ + } else if ((sc->reset & 1) == 0) { + ub_sync_reset(sc); + msleep(700); /* usb-storage sleeps 6s (!) */ + ub_probe_clear_stall(sc, sc->recv_bulk_pipe); + ub_probe_clear_stall(sc, sc->send_bulk_pipe); } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) { printk(KERN_NOTICE "%s: Not resetting multi-interface device\n", sc->name); /* P3 This floods. Remove soon. XXX */ @@ -2140,6 +2146,52 @@ static void ub_probe_timeout(unsigned long arg) complete(cop); } +/* + * Reset with a Bulk reset. + */ +static int ub_sync_reset(struct ub_dev *sc) +{ + int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber; + struct usb_ctrlrequest *cr; + struct completion compl; + struct timer_list timer; + int rc; + + init_completion(&compl); + + cr = &sc->work_cr; + cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE; + cr->bRequest = US_BULK_RESET_REQUEST; + cr->wValue = cpu_to_le16(0); + cr->wIndex = cpu_to_le16(ifnum); + cr->wLength = cpu_to_le16(0); + + usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, + (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); + sc->work_urb.actual_length = 0; + sc->work_urb.error_count = 0; + sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { + printk(KERN_WARNING + "%s: Unable to submit a bulk reset (%d)\n", sc->name, rc); + return rc; + } + + init_timer(&timer); + timer.function = ub_probe_timeout; + timer.data = (unsigned long) &compl; + timer.expires = jiffies + UB_CTRL_TIMEOUT; + add_timer(&timer); + + wait_for_completion(&compl); + + del_timer_sync(&timer); + usb_kill_urb(&sc->work_urb); + + return sc->work_urb.status; +} + /* * Get number of LUNs by the way of Bulk GetMaxLUN command. */ From 641adaaee18aacc4f4ba77850c2257373f1736d1 Mon Sep 17 00:00:00 2001 From: Louis Nyffenegger Date: Thu, 5 Jan 2006 17:20:37 +0100 Subject: [PATCH 213/695] [PATCH] USB: new id for ftdi_sio.c and ftdi_sio.h this patch includes the Vendor Id for a optic fiber to USB device named TTUSB from thought Technology. It's just add the vendor Id to ftdi_sio.h and add the Vendor ID and model Id to table_combined. Signed-off-by: Louis Nyffenegger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 10bc1bf23b35..58394495d220 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -480,6 +480,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 00d45f8600de..255ea1f19a44 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -31,9 +31,14 @@ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ + /* www.irtrans.de device */ #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ + +/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ +#define FTDI_TTUSB_PID 0xFF20 /* Product Id */ + /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ /* they use the ftdi chipset for the USB interface and the vendor id is the same */ #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ From a94b52ac84828e193d18c96c1334c9997b524a35 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2006 17:11:40 +0000 Subject: [PATCH 214/695] [PATCH] USB: ftdi_sio: new IDs for Westrex devices This patch adds two new devices to the ftdi_sio driver's device ID table. The device IDs were supplied by Cory Lee to support two POS printers made by Westrex International (Model 777 and Model 8900F). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio.h | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 58394495d220..f6a7b42cc118 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -481,6 +481,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 255ea1f19a44..07d4833c42e1 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -370,6 +370,12 @@ #define POSIFLEX_VID 0x0d3a /* Vendor ID */ #define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ +/* + * Westrex International devices submitted by Cory Lee + */ +#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ +#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ From ce40d290c111c3d418ef444f82c349de134a0a74 Mon Sep 17 00:00:00 2001 From: Wouter Paesen Date: Tue, 3 Jan 2006 14:30:31 +0100 Subject: [PATCH 215/695] [PATCH] USB: ftdi_sio: new PID for PCDJ DAC2 The attached patch adds a new PID for the ftdi_sio driver. It will enable support for PC-DJ's DAC-2 controller module (more information on http://www.pcdjhardware.com/DAC2.asp) Signed-off-by: Wouter Paesen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f6a7b42cc118..ef20d83a81b8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -483,6 +483,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 07d4833c42e1..09807afaf583 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -55,6 +55,12 @@ /* (the VID is the standard ftdi vid (FTDI_VID) */ #define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ +/* + * PCDJ use ftdi based dj-controllers. The following PID is for their DAC-2 device + * http://www.pcdjhardware.com/DAC2.asp (PID sent by Wouter Paesen) + * (the VID is the standard ftdi vid (FTDI_VID) */ +#define FTDI_PCDJ_DAC2_PID 0xFA88 + /* * The following are the values for the Matrix Orbital LCD displays, * which are the FT232BM ( similar to the 8U232AM ) From 09c280a24650ff74e713742e94120fdf7765cda8 Mon Sep 17 00:00:00 2001 From: Rui Santos Date: Mon, 9 Jan 2006 13:12:40 +0000 Subject: [PATCH 216/695] [PATCH] USB: ftdi: Two new ATIK based USB astronomical CCD cameras Documentation: Specify grayscale specification on ATIK-ATK16 and ATIK-ATK16HR comments. New: Add ProductID and VendorID for devices ATIK-ATK16C and ATIK-ATK16HRC. These devices are also USB Astronomical CCD cameras that work through an FTDI 245BM chip, share the same base hardware but, it has a colour CCD chip instead of a grayscale one. Signed-off-by: Rui Santos Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio.h | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ef20d83a81b8..f2b4ca8692d8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -476,7 +476,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) }, { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 09807afaf583..ca40f16370f1 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -226,8 +226,10 @@ * Definitions for ATIK Instruments astronomical USB based cameras * Check it at http://www.atik-instruments.com/ */ -#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Camera */ -#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Camera */ +#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ +#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ +#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ +#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ /* * Protego product ids From 8e2ce4f92a0f34e8c3316ec58fd6eb6aa282448e Mon Sep 17 00:00:00 2001 From: Henk Date: Fri, 30 Dec 2005 19:41:11 +0100 Subject: [PATCH 217/695] [PATCH] drivers/usb/input/yealink.c: Cleanup device matching code This should fix things mentioned below: "I was curious why my firewall was loading a 'phone driver'. It turns out that the probing in the yealink driver is a little too assuming.. static struct usb_device_id usb_table [] = { { USB_INTERFACE_INFO(USB_CLASS_HID, 0, 0) }, { } }; So it picked up my UPS, and loaded the driver. Whilst no harm came, because it later checks the vendor/product IDs, this driver should probably be rewritten to only probe for the device IDs it actually knows about. Dave" Signed-off-by: Henk Vergonet Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/yealink.c | 46 +++++++++++++++---------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index 1bfc105ad4d6..067be34b4241 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c @@ -59,7 +59,7 @@ #include "map_to_7segment.h" #include "yealink.h" -#define DRIVER_VERSION "yld-20050816" +#define DRIVER_VERSION "yld-20051230" #define DRIVER_AUTHOR "Henk Vergonet" #define DRIVER_DESC "Yealink phone driver" @@ -786,16 +786,25 @@ static struct attribute_group yld_attr_group = { * Linux interface and usb initialisation ******************************************************************************/ -static const struct yld_device { - u16 idVendor; - u16 idProduct; +struct driver_info { char *name; -} yld_device[] = { - { 0x6993, 0xb001, "Yealink usb-p1k" }, }; -static struct usb_device_id usb_table [] = { - { USB_INTERFACE_INFO(USB_CLASS_HID, 0, 0) }, +static const struct driver_info info_P1K = { + .name = "Yealink usb-p1k", +}; + +static const struct usb_device_id usb_table [] = { + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x6993, + .idProduct = 0xb001, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .driver_info = (kernel_ulong_t)&info_P1K + }, { } }; @@ -842,33 +851,16 @@ static void usb_disconnect(struct usb_interface *intf) usb_cleanup(yld, 0); } -static int usb_match(struct usb_device *udev) -{ - int i; - u16 idVendor = le16_to_cpu(udev->descriptor.idVendor); - u16 idProduct = le16_to_cpu(udev->descriptor.idProduct); - - for (i = 0; i < ARRAY_SIZE(yld_device); i++) { - if ((idVendor == yld_device[i].idVendor) && - (idProduct == yld_device[i].idProduct)) - return i; - } - return -ENODEV; -} - static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev (intf); + struct driver_info *nfo = (struct driver_info *)id->driver_info; struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct yealink_dev *yld; struct input_dev *input_dev; int ret, pipe, i; - i = usb_match(udev); - if (i < 0) - return -ENODEV; - interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; if (!(endpoint->bEndpointAddress & USB_DIR_IN)) @@ -948,7 +940,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) strlcat(yld->phys, "/input0", sizeof(yld->phys)); /* register settings for the input device */ - input_dev->name = yld_device[i].name; + input_dev->name = nfo->name; input_dev->phys = yld->phys; usb_to_input_id(udev, &input_dev->id); input_dev->cdev.dev = &intf->dev; From abb02fdf83f981f2511b3772db6e106845c70ad9 Mon Sep 17 00:00:00 2001 From: Matthew Dharm Date: Fri, 30 Dec 2005 19:06:53 -0800 Subject: [PATCH 218/695] [PATCH] USB: usb-storage: Add support for Rio Karma This patch from Bob Copeland adds support for the Rio Karma portable digital audio player to the usb-storage driver. The only thing needed to support this device is a one-time (per plugin) init command which is sent to the device. Signed-off-by: Bob Copeland Signed-off-by: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/initializers.c | 73 ++++++++++++++++++++++++++++++ drivers/usb/storage/initializers.h | 1 + drivers/usb/storage/unusual_devs.h | 5 ++ 3 files changed, 79 insertions(+) diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 5b06f9240d05..ab173b30076e 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -45,6 +45,12 @@ #include "debug.h" #include "transport.h" +#define RIO_MSC 0x08 +#define RIOP_INIT "RIOP\x00\x01\x08" +#define RIOP_INIT_LEN 7 +#define RIO_SEND_LEN 40 +#define RIO_RECV_LEN 0x200 + /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target * mode */ int usb_stor_euscsi_init(struct us_data *us) @@ -91,3 +97,70 @@ int usb_stor_ucr61s2b_init(struct us_data *us) return (res ? -1 : 0); } + +/* Place the Rio Karma into mass storage mode. + * + * The initialization begins by sending 40 bytes starting + * RIOP\x00\x01\x08\x00, which the device will ack with a 512-byte + * packet with the high four bits set and everything else null. + * + * Next, we send RIOP\x80\x00\x08\x00. Each time, a 512 byte response + * must be read, but we must loop until byte 5 in the response is 0x08, + * indicating success. */ +int rio_karma_init(struct us_data *us) +{ + int result, partial; + char *recv; + unsigned long timeout; + + // us->iobuf is big enough to hold cmd but not receive + if (!(recv = kmalloc(RIO_RECV_LEN, GFP_KERNEL))) + goto die_nomem; + + US_DEBUGP("Initializing Karma...\n"); + + memset(us->iobuf, 0, RIO_SEND_LEN); + memcpy(us->iobuf, RIOP_INIT, RIOP_INIT_LEN); + + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, + us->iobuf, RIO_SEND_LEN, &partial); + if (result != USB_STOR_XFER_GOOD) + goto die; + + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + recv, RIO_RECV_LEN, &partial); + if (result != USB_STOR_XFER_GOOD) + goto die; + + us->iobuf[4] = 0x80; + us->iobuf[5] = 0; + timeout = jiffies + msecs_to_jiffies(3000); + for (;;) { + US_DEBUGP("Sending init command\n"); + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, + us->iobuf, RIO_SEND_LEN, &partial); + if (result != USB_STOR_XFER_GOOD) + goto die; + + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + recv, RIO_RECV_LEN, &partial); + if (result != USB_STOR_XFER_GOOD) + goto die; + + if (recv[5] == RIO_MSC) + break; + if (time_after(jiffies, timeout)) + goto die; + msleep(10); + } + US_DEBUGP("Karma initialized.\n"); + kfree(recv); + return 0; + +die: + kfree(recv); +die_nomem: + US_DEBUGP("Could not initialize karma.\n"); + return USB_STOR_TRANSPORT_FAILED; +} + diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 4c1b2bd2e2e4..f9907a5cf129 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h @@ -48,3 +48,4 @@ int usb_stor_euscsi_init(struct us_data *us); /* This function is required to activate all four slots on the UCR-61S2B * flash reader */ int usb_stor_ucr61s2b_init(struct us_data *us); +int rio_karma_init(struct us_data *us); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index dc301e567cfc..5e2afd4a27bc 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -145,6 +145,11 @@ UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100, US_SC_DEVICE, US_PR_BULK, NULL, US_FL_NEED_OVERRIDE ), +UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, + "Rio", + "Rio Karma", + US_SC_SCSI, US_PR_BULK, rio_karma_init, 0), + /* Patch submitted by Philipp Friedrich */ UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, "Kyocera", From 8e695cdbffe66f5d3142a363f47053be9f83a90d Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 7 Jan 2006 21:35:20 +0100 Subject: [PATCH 219/695] [PATCH] USB: cleanup of usblp this fixes -potential hang by disconnecting through usbfs -kzalloc -general cleanup -micro optimisation in interrupt handlers It compiles and I am printing. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usblp.c | 71 +++++++++++++-------------------------- 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index dba4cc026077..d34848ac30b0 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -7,6 +7,7 @@ * Copyright (c) 2000 Vojtech Pavlik # Copyright (c) 2001 Pete Zaitcev # Copyright (c) 2001 David Paschal + * Copyright (c) 2006 Oliver Neukum * * USB Printer Device Class driver for USB printers and printer cables * @@ -273,13 +274,16 @@ static void usblp_bulk_read(struct urb *urb, struct pt_regs *regs) { struct usblp *usblp = urb->context; - if (!usblp || !usblp->dev || !usblp->used || !usblp->present) + if (unlikely(!usblp || !usblp->dev || !usblp->used)) return; + if (unlikely(!usblp->present)) + goto unplug; if (unlikely(urb->status)) warn("usblp%d: nonzero read/write bulk status received: %d", usblp->minor, urb->status); usblp->rcomplete = 1; +unplug: wake_up_interruptible(&usblp->wait); } @@ -287,13 +291,15 @@ static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs) { struct usblp *usblp = urb->context; - if (!usblp || !usblp->dev || !usblp->used || !usblp->present) + if (unlikely(!usblp || !usblp->dev || !usblp->used)) return; - + if (unlikely(!usblp->present)) + goto unplug; if (unlikely(urb->status)) warn("usblp%d: nonzero read/write bulk status received: %d", usblp->minor, urb->status); usblp->wcomplete = 1; +unplug: wake_up_interruptible(&usblp->wait); } @@ -627,9 +633,8 @@ done: static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - DECLARE_WAITQUEUE(wait, current); struct usblp *usblp = file->private_data; - int timeout, err = 0, transfer_length = 0; + int timeout, rv, err = 0, transfer_length = 0; size_t writecount = 0; while (writecount < count) { @@ -641,24 +646,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t } timeout = USBLP_WRITE_TIMEOUT; - add_wait_queue(&usblp->wait, &wait); - while ( 1==1 ) { - if (signal_pending(current)) { - remove_wait_queue(&usblp->wait, &wait); - return writecount ? writecount : -EINTR; - } - set_current_state(TASK_INTERRUPTIBLE); - if (timeout && !usblp->wcomplete) { - timeout = schedule_timeout(timeout); - } else { - set_current_state(TASK_RUNNING); - break; - } - } - remove_wait_queue(&usblp->wait, &wait); + rv = wait_event_interruptible_timeout(usblp->wait, usblp->wcomplete || !usblp->present , timeout); + if (rv < 0) + return writecount ? writecount : -EINTR; } - down (&usblp->sem); if (!usblp->present) { up (&usblp->sem); @@ -724,7 +716,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct usblp *usblp = file->private_data; - DECLARE_WAITQUEUE(wait, current); + int rv; if (!usblp->bidir) return -EINVAL; @@ -742,26 +734,13 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, count = -EAGAIN; goto done; } - - add_wait_queue(&usblp->wait, &wait); - while (1==1) { - if (signal_pending(current)) { - count = -EINTR; - remove_wait_queue(&usblp->wait, &wait); - goto done; - } - up (&usblp->sem); - set_current_state(TASK_INTERRUPTIBLE); - if (!usblp->rcomplete) { - schedule(); - } else { - set_current_state(TASK_RUNNING); - down(&usblp->sem); - break; - } - down (&usblp->sem); + up(&usblp->sem); + rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); + down(&usblp->sem); + if (rv < 0) { + count = -EINTR; + goto done; } - remove_wait_queue(&usblp->wait, &wait); } if (!usblp->present) { @@ -874,11 +853,10 @@ static int usblp_probe(struct usb_interface *intf, /* Malloc and start initializing usblp structure so we can use it * directly. */ - if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) { + if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) { err("out of memory for usblp"); goto abort; } - memset(usblp, 0, sizeof(struct usblp)); usblp->dev = dev; init_MUTEX (&usblp->sem); init_waitqueue_head(&usblp->wait); @@ -1214,10 +1192,9 @@ static int __init usblp_init(void) { int retval; retval = usb_register(&usblp_driver); - if (retval) - goto out; - info(DRIVER_VERSION ": " DRIVER_DESC); -out: + if (!retval) + info(DRIVER_VERSION ": " DRIVER_DESC); + return retval; } From 86067eead5a6c6fa413ef5cb59f7129f5ed80292 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sun, 8 Jan 2006 12:39:13 +0100 Subject: [PATCH 220/695] [PATCH] USB: fix oops in acm disconnect this fixes an oops with disconnection in acm. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index b9fd39fd1b5b..97bdeb1c2181 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1014,8 +1014,13 @@ static void acm_disconnect(struct usb_interface *intf) } down(&open_sem); + if (!usb_get_intfdata(intf)) { + up(&open_sem); + return; + } acm->dev = NULL; - usb_set_intfdata (intf, NULL); + usb_set_intfdata(acm->control, NULL); + usb_set_intfdata(acm->data, NULL); tasklet_disable(&acm->urb_task); @@ -1036,7 +1041,7 @@ static void acm_disconnect(struct usb_interface *intf) for (i = 0; i < ACM_NRB; i++) usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); - usb_driver_release_interface(&acm_driver, acm->data); + usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf); if (!acm->used) { acm_tty_unregister(acm); From ec7dc8d254985dc4a31858c2c7c7029290e223dd Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Mon, 26 Dec 2005 23:04:24 -0800 Subject: [PATCH 221/695] [PATCH] USB: usb-storage support for SONY DSC-T5 still camera I've been offered a nice Sony DSC-T5 digital camera, with a USB connection. Unfortunately it is not recognized by Linux 2.6.14.4's usb-storage. With the following change I'm able to mount and read my pictures: Signed-off-by: Phil Dibowitz --- drivers/usb/storage/unusual_devs.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 5e2afd4a27bc..ee958f986eb8 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -429,11 +429,11 @@ UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450, US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ), /* This entry is needed because the device reports Sub=ff */ -UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0500, - "Sony", - "DSC-T1", - US_SC_8070, US_PR_DEVICE, NULL, - US_FL_SINGLE_LUN ), +UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0600, + "Sony", + "DSC-T1/T5", + US_SC_8070, US_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), /* Reported by wim@geeks.nl */ From a966f3e7512084f916049579067f532908ba3a49 Mon Sep 17 00:00:00 2001 From: Luca Risolia Date: Thu, 5 Jan 2006 18:14:04 +0000 Subject: [PATCH 222/695] [PATCH] USB: SN9C10x driver updates and bugfixes SN9C10x driver updates and bugfixes. Changes: + new, - removed, * cleanup, @ bugfix: @ fix poll() @ Remove bad get_ctrl()'s * Reduce ioctl stack usage * Remove final ";" from some macro definitions * Better support for SN9C103 + Add sn9c102_write_regs() + Add 0x0c45/0x602d to the list of SN9C10x based devices + Add support for OV7630 image sensors + Provide support for the built-in microphone interface of the SN9C103 + Documentation updates + Add 0x0c45/0x602e to the list of SN9C10x based devices Signed-off-by: Luca Risolia Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/sn9c102.txt | 86 +- drivers/usb/media/sn9c102.h | 31 +- drivers/usb/media/sn9c102_core.c | 1823 +++++++++++++----------- drivers/usb/media/sn9c102_hv7131d.c | 2 +- drivers/usb/media/sn9c102_mi0343.c | 2 +- drivers/usb/media/sn9c102_ov7630.c | 8 +- drivers/usb/media/sn9c102_pas106b.c | 2 +- drivers/usb/media/sn9c102_sensor.h | 69 +- drivers/usb/media/sn9c102_tas5110c1b.c | 2 +- drivers/usb/media/sn9c102_tas5130d1b.c | 2 +- 10 files changed, 1121 insertions(+), 906 deletions(-) diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt index 3f8a119db31b..541b17fd27f6 100644 --- a/Documentation/usb/sn9c102.txt +++ b/Documentation/usb/sn9c102.txt @@ -17,16 +17,15 @@ Index 7. Module parameters 8. Optional device control through "sysfs" 9. Supported devices -10. How to add plug-in's for new image sensors -11. Notes for V4L2 application developers -12. Video frame formats -13. Contact information -14. Credits +10. Notes for V4L2 application developers +11. Video frame formats +12. Contact information +13. Credits 1. Copyright ============ -Copyright (C) 2004-2005 by Luca Risolia +Copyright (C) 2004-2006 by Luca Risolia 2. Disclaimer @@ -54,9 +53,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 4. Overview and features ======================== -This driver attempts to support the video and audio streaming capabilities of -the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 PC Camera -Controllers. +This driver attempts to support the video interface of the devices mounting the +SONiX SN9C101, SN9C102 and SN9C103 PC Camera Controllers. It's worth to note that SONiX has never collaborated with the author during the development of this project, despite several requests for enough detailed @@ -78,6 +76,7 @@ Some of the features of the driver are: - available mmap or read/poll methods for video streaming through isochronous data transfers; - automatic detection of image sensor; +- support for built-in microphone interface; - support for any window resolutions and optional panning within the maximum pixel area of image sensor; - image downscaling with arbitrary scaling factors from 1, 2 and 4 in both @@ -96,7 +95,7 @@ Some of the features of the driver are: parameters" paragraph); - up to 64 cameras can be handled at the same time; they can be connected and disconnected from the host many times without turning off the computer, if - your system supports hotplugging; + the system supports hotplugging; - no known bugs. @@ -125,6 +124,21 @@ necessary: CONFIG_USB_UHCI_HCD=m CONFIG_USB_OHCI_HCD=m +The SN9C103 controller also provides a built-in microphone interface. It is +supported by the USB Audio driver thanks to the ALSA API: + + # Sound + # + CONFIG_SOUND=y + + # Advanced Linux Sound Architecture + # + CONFIG_SND=m + + # USB devices + # + CONFIG_SND_USB_AUDIO=m + And finally: # USB Multimedia devices @@ -153,7 +167,7 @@ analyze kernel messages and verify that the loading process has gone well: Module parameters are listed below: ------------------------------------------------------------------------------- Name: video_nr -Type: int array (min = 0, max = 64) +Type: short array (min = 0, max = 64) Syntax: <-1|n[,...]> Description: Specify V4L2 minor mode number: -1 = use next available @@ -165,19 +179,19 @@ Description: Specify V4L2 minor mode number: other camera. Default: -1 ------------------------------------------------------------------------------- -Name: force_munmap; +Name: force_munmap Type: bool array (min = 0, max = 64) Syntax: <0|1[,...]> Description: Force the application to unmap previously mapped buffer memory before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not all the applications support this feature. This parameter is specific for each detected camera. - 0 = do not force memory unmapping" - 1 = force memory unmapping (save memory)" + 0 = do not force memory unmapping + 1 = force memory unmapping (save memory) Default: 0 ------------------------------------------------------------------------------- Name: debug -Type: int +Type: ushort Syntax: Description: Debugging information level, from 0 to 3: 0 = none (use carefully) @@ -187,7 +201,7 @@ Description: Debugging information level, from 0 to 3: Level 3 is useful for testing only, when only one device is used. It also shows some more informations about the hardware being detected. This parameter can be changed at - runtime thanks to the /sys filesystem. + runtime thanks to the /sys filesystem interface. Default: 2 ------------------------------------------------------------------------------- @@ -236,7 +250,7 @@ serialized. The sysfs interface also provides the "frame_header" entry, which exports the frame header of the most recent requested and captured video frame. The header -is 12-bytes long and is appended to every video frame by the SN9C10x +is always 18-bytes long and is appended to every video frame by the SN9C10x controllers. As an example, this additional information can be used by the user application for implementing auto-exposure features via software. @@ -250,7 +264,8 @@ Byte # Value Description 0x03 0xC4 Frame synchronisation pattern. 0x04 0xC4 Frame synchronisation pattern. 0x05 0x96 Frame synchronisation pattern. -0x06 0x00 or 0x01 Unknown meaning. The exact value depends on the chip. +0x06 0xXX Unknown meaning. The exact value depends on the chip; + possible values are 0x00, 0x01 and 0x20. 0x07 0xXX Variable value, whose bits are ff00uzzc, where ff is a frame counter, u is unknown, zz is a size indicator (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for @@ -267,12 +282,23 @@ Byte # Value Description times the area outside of the specified AE area. For images that are not pure white, the value scales down according to relative whiteness. + according to relative whiteness. + +The following bytes are used by the SN9C103 bridge only: + +0x0C 0xXX Unknown meaning +0x0D 0xXX Unknown meaning +0x0E 0xXX Unknown meaning +0x0F 0xXX Unknown meaning +0x10 0xXX Unknown meaning +0x11 0xXX Unknown meaning The AE area (sx, sy, ex, ey) in the active window can be set by programming the registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C10x controllers, where one unit corresponds to 32 pixels. -[1] The frame header has been documented by Bertrik Sikken. +[1] Part of the meaning of the frame header has been documented by Bertrik + Sikken. 9. Supported devices @@ -298,6 +324,7 @@ Vendor ID Product ID 0x0c45 0x602b 0x0c45 0x602c 0x0c45 0x602d +0x0c45 0x602e 0x0c45 0x6030 0x0c45 0x6080 0x0c45 0x6082 @@ -348,18 +375,7 @@ appreciated. Non-available hardware will not be supported by the author of this driver. -10. How to add plug-in's for new image sensors -============================================== -It should be easy to write plug-in's for new sensors by using the small API -that has been created for this purpose, which is present in "sn9c102_sensor.h" -(documentation is included there). As an example, have a look at the code in -"sn9c102_pas106b.c", which uses the mentioned interface. - -At the moment, possible unsupported image sensors are: CIS-VF10 (VGA), -OV7620 (VGA), OV7630 (VGA). - - -11. Notes for V4L2 application developers +10. Notes for V4L2 application developers ========================================= This driver follows the V4L2 API specifications. In particular, it enforces two rules: @@ -394,7 +410,7 @@ initialized (as described in the documentation of the API for the image sensors supplied by this driver). -12. Video frame formats [1] +11. Video frame formats [1] ======================= The SN9C10x PC Camera Controllers can send images in two possible video formats over the USB: either native "Sequential RGB Bayer" or Huffman @@ -455,7 +471,7 @@ The following Huffman codes have been found: documented by Bertrik Sikken. -13. Contact information +12. Contact information ======================= The author may be contacted by e-mail at . @@ -464,7 +480,7 @@ GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. -14. Credits +13. Credits =========== Many thanks to following persons for their contribute (listed in alphabetical order): @@ -480,5 +496,5 @@ order): - Bertrik Sikken, who reverse-engineered and documented the Huffman compression algorithm used in the SN9C10x controllers and implemented the first decoder; - Mizuno Takafumi for the donation of a webcam; -- An "anonymous" donator (who didn't want his name to be revealed) for the +- an "anonymous" donator (who didn't want his name to be revealed) for the donation of a webcam. diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h index e5cea0e2eb57..967c6b6bc0fa 100644 --- a/drivers/usb/media/sn9c102.h +++ b/drivers/usb/media/sn9c102.h @@ -1,7 +1,7 @@ /*************************************************************************** * V4L2 driver for SN9C10x PC Camera Controllers * * * - * Copyright (C) 2004-2005 by Luca Risolia * + * Copyright (C) 2004-2006 by Luca Risolia * * * * 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 * @@ -53,11 +53,11 @@ /*****************************************************************************/ #define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" -#define SN9C102_MODULE_AUTHOR "(C) 2004-2005 Luca Risolia" +#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" #define SN9C102_AUTHOR_EMAIL "" #define SN9C102_MODULE_LICENSE "GPL" -#define SN9C102_MODULE_VERSION "1:1.24a" -#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24) +#define SN9C102_MODULE_VERSION "1:1.25" +#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 25) enum sn9c102_bridge { BRIDGE_SN9C101 = 0x01, @@ -102,12 +102,13 @@ enum sn9c102_stream_state { STREAM_ON, }; +typedef char sn9c103_sof_header_t[18]; typedef char sn9c102_sof_header_t[12]; typedef char sn9c102_eof_header_t[4]; struct sn9c102_sysfs_attr { u8 reg, i2c_reg; - sn9c102_sof_header_t frame_header; + sn9c103_sof_header_t frame_header; }; struct sn9c102_module_param { @@ -140,8 +141,8 @@ struct sn9c102_device { struct v4l2_jpegcompression compression; struct sn9c102_sysfs_attr sysfs; - sn9c102_sof_header_t sof_header; - u16 reg[32]; + sn9c103_sof_header_t sof_header; + u16 reg[63]; struct sn9c102_module_param module_param; @@ -170,7 +171,7 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, #undef KDBG #ifdef SN9C102_DEBUG # define DBG(level, fmt, args...) \ -{ \ +do { \ if (debug >= (level)) { \ if ((level) == 1) \ dev_err(&cam->dev, fmt "\n", ## args); \ @@ -180,9 +181,9 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ __FUNCTION__, __LINE__ , ## args); \ } \ -} +} while (0) # define KDBG(level, fmt, args...) \ -{ \ +do { \ if (debug >= (level)) { \ if ((level) == 1 || (level) == 2) \ pr_info("sn9c102: " fmt "\n", ## args); \ @@ -190,17 +191,17 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \ __LINE__ , ## args); \ } \ -} +} while (0) #else -# define KDBG(level, fmt, args...) do {;} while(0); -# define DBG(level, fmt, args...) do {;} while(0); +# define KDBG(level, fmt, args...) do {;} while(0) +# define DBG(level, fmt, args...) do {;} while(0) #endif #undef PDBG #define PDBG(fmt, args...) \ -dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args); +dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args) #undef PDBGG -#define PDBGG(fmt, args...) do {;} while(0); /* placeholder */ +#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ #endif /* _SN9C102_H_ */ diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index 8d1a1c357d5a..6090439663ee 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c @@ -1,7 +1,7 @@ /*************************************************************************** * V4L2 driver for SN9C10x PC Camera Controllers * * * - * Copyright (C) 2004-2005 by Luca Risolia * + * Copyright (C) 2004-2006 by Luca Risolia * * * * 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 * @@ -70,10 +70,10 @@ static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] = SN9C102_FORCE_MUNMAP}; module_param_array(force_munmap, bool, NULL, 0444); MODULE_PARM_DESC(force_munmap, - "\n<0|1[,...]> Force the application to unmap previously " - "\nmapped buffer memory before calling any VIDIOC_S_CROP or " - "\nVIDIOC_S_FMT ioctl's. Not all the applications support " - "\nthis feature. This parameter is specific for each " + "\n<0|1[,...]> Force the application to unmap previously" + "\nmapped buffer memory before calling any VIDIOC_S_CROP or" + "\nVIDIOC_S_FMT ioctl's. Not all the applications support" + "\nthis feature. This parameter is specific for each" "\ndetected camera." "\n 0 = do not force memory unmapping" "\n 1 = force memory unmapping (save memory)" @@ -102,6 +102,9 @@ static sn9c102_sof_header_t sn9c102_sof_header[] = { {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01}, }; +static sn9c103_sof_header_t sn9c103_sof_header[] = { + {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x20}, +}; static sn9c102_eof_header_t sn9c102_eof_header[] = { {0x00, 0x00, 0x00, 0x00}, @@ -202,6 +205,7 @@ static void sn9c102_release_buffers(struct sn9c102_device* cam) cam->nbuffers * PAGE_ALIGN(cam->frame[0].buf.length)); cam->nbuffers = 0; } + cam->frame_current = NULL; } @@ -219,6 +223,19 @@ static void sn9c102_empty_framequeues(struct sn9c102_device* cam) } +static void sn9c102_requeue_outqueue(struct sn9c102_device* cam) +{ + struct sn9c102_frame_t *i; + + list_for_each_entry(i, &cam->outqueue, frame) { + i->state = F_QUEUED; + list_add(&i->frame, &cam->inqueue); + } + + INIT_LIST_HEAD(&cam->outqueue); +} + + static void sn9c102_queue_unusedframes(struct sn9c102_device* cam) { unsigned long lock_flags; @@ -235,19 +252,46 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam) /*****************************************************************************/ +int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index) +{ + struct usb_device* udev = cam->usbdev; + int i, res; + + if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg)) + return -1; + + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, + index, 0, buff, sizeof(buff), + SN9C102_CTRL_TIMEOUT*sizeof(buff)); + if (res < 0) { + DBG(3, "Failed to write registers (index 0x%02X, error %d)", + index, res); + return -1; + } + + for (i = 0; i < sizeof(buff); i++) + cam->reg[index+i] = buff[i]; + + return 0; +} + + int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index) { struct usb_device* udev = cam->usbdev; u8* buff = cam->control_buffer; int res; + if (index >= ARRAY_SIZE(cam->reg)) + return -1; + *buff = value; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); if (res < 0) { DBG(3, "Failed to write a register (value 0x%02X, index " - "0x%02X, error %d)", value, index, res) + "0x%02X, error %d)", value, index, res); return -1; } @@ -268,7 +312,7 @@ static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index) index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); if (res < 0) DBG(3, "Failed to read a register (index 0x%02X, error %d)", - index, res) + index, res); return (res >= 0) ? (int)(*buff) : -1; } @@ -276,8 +320,8 @@ static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index) int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index) { - if (index > 0x1f) - return -EINVAL; + if (index >= ARRAY_SIZE(cam->reg)) + return -1; return cam->reg[index]; } @@ -367,10 +411,10 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, err += sn9c102_i2c_detect_read_error(cam, sensor); PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1, - data[4]) + data[4]); if (err) { - DBG(3, "I2C read failed for %s image sensor", sensor->name) + DBG(3, "I2C read failed for %s image sensor", sensor->name); return -1; } @@ -410,11 +454,11 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, err += sn9c102_i2c_detect_write_error(cam, sensor); if (err) - DBG(3, "I2C write failed for %s image sensor", sensor->name) + DBG(3, "I2C write failed for %s image sensor", sensor->name); PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, " "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X", - n, data0, data1, data2, data3, data4, data5) + n, data0, data1, data2, data3, data4, data5); return err ? -1 : 0; } @@ -461,13 +505,27 @@ int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value) static void* sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) { - size_t soflen = sizeof(sn9c102_sof_header_t), i; - u8 j, n = sizeof(sn9c102_sof_header) / soflen; + size_t soflen = 0, i; + u8 j, n = 0; - for (i = 0; (len >= soflen) && (i <= len - soflen); i++) + switch (cam->bridge) { + case BRIDGE_SN9C101: + case BRIDGE_SN9C102: + soflen = sizeof(sn9c102_sof_header_t); + n = sizeof(sn9c102_sof_header) / soflen; + break; + case BRIDGE_SN9C103: + soflen = sizeof(sn9c103_sof_header_t); + n = sizeof(sn9c103_sof_header) / soflen; + } + + for (i = 0; (len >= soflen) && (i <= len - soflen); i++) for (j = 0; j < n; j++) - /* It's enough to compare 7 bytes */ - if (!memcmp(mem + i, sn9c102_sof_header[j], 7)) { + /* The invariable part of the header is 6 bytes long */ + if ((cam->bridge != BRIDGE_SN9C103 && + !memcmp(mem + i, sn9c102_sof_header[j], 6)) || + (cam->bridge == BRIDGE_SN9C103 && + !memcmp(mem + i, sn9c103_sof_header[j], 6))) { memcpy(cam->sof_header, mem + i, soflen); /* Skip the header */ return mem + i + soflen; @@ -499,8 +557,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs) { struct sn9c102_device* cam = urb->context; struct sn9c102_frame_t** f; - size_t imagesize; - unsigned long lock_flags; + size_t imagesize, soflen; u8 i; int err = 0; @@ -513,7 +570,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs) cam->stream = STREAM_OFF; if ((*f)) (*f)->state = F_QUEUED; - DBG(3, "Stream interrupted") + DBG(3, "Stream interrupted"); wake_up_interruptible(&cam->wait_stream); } @@ -536,6 +593,10 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs) cam->sensor->pix_format.height * cam->sensor->pix_format.priv) / 8; + soflen = (cam->bridge) == BRIDGE_SN9C103 ? + sizeof(sn9c103_sof_header_t) : + sizeof(sn9c102_sof_header_t); + for (i = 0; i < urb->number_of_packets; i++) { unsigned int img, len, status; void *pos, *sof, *eof; @@ -545,19 +606,12 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs) pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer; if (status) { - DBG(3, "Error in isochronous frame") + DBG(3, "Error in isochronous frame"); (*f)->state = F_ERROR; continue; } - PDBGG("Isochrnous frame: length %u, #%u i", len, i) - - /* - NOTE: It is probably correct to assume that SOF and EOF - headers do not occur between two consecutive packets, - but who knows..Whatever is the truth, this assumption - doesn't introduce bugs. - */ + PDBGG("Isochrnous frame: length %u, #%u i", len, i); redo: sof = sn9c102_find_sof_header(cam, pos, len); @@ -575,10 +629,10 @@ end_of_frame: imagesize; img = imagesize - (*f)->buf.bytesused; DBG(3, "Expected EOF not found: " - "video frame cut") + "video frame cut"); if (eof) DBG(3, "Exceeded limit: +%u " - "bytes", (unsigned)(b)) + "bytes", (unsigned)(b)); } memcpy((*f)->bufmem + (*f)->buf.bytesused, pos, @@ -595,8 +649,7 @@ end_of_frame: u32 b = (*f)->buf.bytesused; (*f)->state = F_DONE; (*f)->buf.sequence= ++cam->frame_count; - spin_lock_irqsave(&cam->queue_lock, - lock_flags); + spin_lock(&cam->queue_lock); list_move_tail(&(*f)->frame, &cam->outqueue); if (!list_empty(&cam->inqueue)) @@ -606,13 +659,11 @@ end_of_frame: frame ); else (*f) = NULL; - spin_unlock_irqrestore(&cam->queue_lock - , lock_flags); + spin_unlock(&cam->queue_lock); memcpy(cam->sysfs.frame_header, - cam->sof_header, - sizeof(sn9c102_sof_header_t)); - DBG(3, "Video frame captured: " - "%lu bytes", (unsigned long)(b)) + cam->sof_header, soflen); + DBG(3, "Video frame captured: %lu " + "bytes", (unsigned long)(b)); if (!(*f)) goto resubmit_urb; @@ -621,18 +672,19 @@ end_of_frame: (*f)->state = F_ERROR; DBG(3, "Not expected EOF after %lu " "bytes of image data", - (unsigned long)((*f)->buf.bytesused)) + (unsigned long) + ((*f)->buf.bytesused)); } if (sof) /* (1) */ goto start_of_frame; } else if (eof) { - DBG(3, "EOF without SOF") + DBG(3, "EOF without SOF"); continue; } else { - PDBGG("Ignoring pointless isochronous frame") + PDBGG("Ignoring pointless isochronous frame"); continue; } @@ -642,7 +694,7 @@ start_of_frame: (*f)->buf.bytesused = 0; len -= (sof - pos); pos = sof; - DBG(3, "SOF detected: new video frame") + DBG(3, "SOF detected: new video frame"); if (len) goto redo; @@ -653,12 +705,13 @@ start_of_frame: else { if (cam->sensor->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) { - eof = sof-sizeof(sn9c102_sof_header_t); + eof = sof - soflen; goto end_of_frame; } else { DBG(3, "SOF before expected EOF after " "%lu bytes of image data", - (unsigned long)((*f)->buf.bytesused)) + (unsigned long) + ((*f)->buf.bytesused)); goto start_of_frame; } } @@ -670,7 +723,7 @@ resubmit_urb: err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0 && err != -EPERM) { cam->state |= DEV_MISCONFIGURED; - DBG(1, "usb_submit_urb() failed") + DBG(1, "usb_submit_urb() failed"); } wake_up_interruptible(&cam->wait_frame); @@ -681,9 +734,13 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) { struct usb_device *udev = cam->usbdev; struct urb* urb; - const unsigned int wMaxPacketSize[] = {0, 128, 256, 384, 512, - 680, 800, 900, 1023}; - const unsigned int psz = wMaxPacketSize[SN9C102_ALTERNATE_SETTING]; + const unsigned int sn9c102_wMaxPacketSize[] = {0, 128, 256, 384, 512, + 680, 800, 900, 1023}; + const unsigned int sn9c103_wMaxPacketSize[] = {0, 128, 256, 384, 512, + 680, 800, 900, 1003}; + const unsigned int psz = (cam->bridge == BRIDGE_SN9C103) ? + sn9c103_wMaxPacketSize[SN9C102_ALTERNATE_SETTING] : + sn9c102_wMaxPacketSize[SN9C102_ALTERNATE_SETTING]; s8 i, j; int err = 0; @@ -692,7 +749,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) GFP_KERNEL); if (!cam->transfer_buffer[i]) { err = -ENOMEM; - DBG(1, "Not enough memory") + DBG(1, "Not enough memory"); goto free_buffers; } } @@ -702,7 +759,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) cam->urb[i] = urb; if (!urb) { err = -ENOMEM; - DBG(1, "usb_alloc_urb() failed") + DBG(1, "usb_alloc_urb() failed"); goto free_urbs; } urb->dev = udev; @@ -725,14 +782,14 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01); if (err) { err = -EIO; - DBG(1, "I/O hardware error") + DBG(1, "I/O hardware error"); goto free_urbs; } } err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING); if (err) { - DBG(1, "usb_set_interface() failed") + DBG(1, "usb_set_interface() failed"); goto free_urbs; } @@ -743,7 +800,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) if (err) { for (j = i-1; j >= 0; j--) usb_kill_urb(cam->urb[j]); - DBG(1, "usb_submit_urb() failed, error %d", err) + DBG(1, "usb_submit_urb() failed, error %d", err); goto free_urbs; } } @@ -779,7 +836,7 @@ static int sn9c102_stop_transfer(struct sn9c102_device* cam) err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */ if (err) - DBG(3, "usb_set_interface() failed") + DBG(3, "usb_set_interface() failed"); return err; } @@ -799,7 +856,7 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam) else if (err) { cam->state |= DEV_MISCONFIGURED; DBG(1, "The camera is misconfigured. To use it, close and " - "open /dev/video%d again.", cam->v4ldev->minor) + "open /dev/video%d again.", cam->v4ldev->minor); return err; } @@ -885,8 +942,8 @@ sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len) cam->sysfs.reg = index; - DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg) - DBG(3, "Written bytes: %zd", count) + DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg); + DBG(3, "Written bytes: %zd", count); up(&sn9c102_sysfs_lock); @@ -916,7 +973,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf) count = sprintf(buf, "%d\n", val); - DBG(3, "Read bytes: %zd", count) + DBG(3, "Read bytes: %zd", count); up(&sn9c102_sysfs_lock); @@ -954,8 +1011,8 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len) } DBG(2, "Written SN9C10X reg. 0x%02X, val. 0x%02X", - cam->sysfs.reg, value) - DBG(3, "Written bytes: %zd", count) + cam->sysfs.reg, value); + DBG(3, "Written bytes: %zd", count); up(&sn9c102_sysfs_lock); @@ -979,7 +1036,7 @@ static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf) count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg); - DBG(3, "Read bytes: %zd", count) + DBG(3, "Read bytes: %zd", count); up(&sn9c102_sysfs_lock); @@ -1011,8 +1068,8 @@ sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len) cam->sysfs.i2c_reg = index; - DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg) - DBG(3, "Written bytes: %zd", count) + DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg); + DBG(3, "Written bytes: %zd", count); up(&sn9c102_sysfs_lock); @@ -1047,7 +1104,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf) count = sprintf(buf, "%d\n", val); - DBG(3, "Read bytes: %zd", count) + DBG(3, "Read bytes: %zd", count); up(&sn9c102_sysfs_lock); @@ -1090,8 +1147,8 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len) } DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X", - cam->sysfs.i2c_reg, value) - DBG(3, "Written bytes: %zd", count) + cam->sysfs.i2c_reg, value); + DBG(3, "Written bytes: %zd", count); up(&sn9c102_sysfs_lock); @@ -1193,7 +1250,7 @@ static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf) count = sizeof(cam->sysfs.frame_header); memcpy(buf, cam->sysfs.frame_header, count); - DBG(3, "Frame header, read bytes: %zd", count) + DBG(3, "Frame header, read bytes: %zd", count); return count; } @@ -1227,7 +1284,7 @@ static void sn9c102_create_sysfs(struct sn9c102_device* cam) video_device_create_file(v4ldev, &class_device_attr_blue); video_device_create_file(v4ldev, &class_device_attr_red); } - if (cam->sensor->sysfs_ops) { + if (cam->sensor && cam->sensor->sysfs_ops) { video_device_create_file(v4ldev, &class_device_attr_i2c_reg); video_device_create_file(v4ldev, &class_device_attr_i2c_val); } @@ -1281,7 +1338,7 @@ static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale) if (err) return -EIO; - PDBGG("Scaling factor: %u", scale) + PDBGG("Scaling factor: %u", scale); return 0; } @@ -1304,7 +1361,7 @@ static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect) return -EIO; PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size " - "%u %u %u %u", h_start, v_start, h_size, v_size) + "%u %u %u %u", h_start, v_start, h_size, v_size); return 0; } @@ -1336,7 +1393,7 @@ static int sn9c102_init(struct sn9c102_device* cam) if (s->init) { err = s->init(cam); if (err) { - DBG(3, "Sensor initialization failed") + DBG(3, "Sensor initialization failed"); return err; } } @@ -1353,13 +1410,13 @@ static int sn9c102_init(struct sn9c102_device* cam) if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) DBG(3, "Compressed video format is active, quality %d", - cam->compression.quality) + cam->compression.quality); else - DBG(3, "Uncompressed video format is active") + DBG(3, "Uncompressed video format is active"); if (s->set_crop) if ((err = s->set_crop(cam, rect))) { - DBG(3, "set_crop() failed") + DBG(3, "set_crop() failed"); return err; } @@ -1372,11 +1429,11 @@ static int sn9c102_init(struct sn9c102_device* cam) err = s->set_ctrl(cam, &ctrl); if (err) { DBG(3, "Set %s control failed", - s->qctrl[i].name) + s->qctrl[i].name); return err; } DBG(3, "Image sensor supports '%s' control", - s->qctrl[i].name) + s->qctrl[i].name); } } @@ -1392,7 +1449,7 @@ static int sn9c102_init(struct sn9c102_device* cam) cam->state |= DEV_INITIALIZED; } - DBG(2, "Initialization succeeded") + DBG(2, "Initialization succeeded"); return 0; } @@ -1401,7 +1458,7 @@ static void sn9c102_release_resources(struct sn9c102_device* cam) { down(&sn9c102_sysfs_lock); - DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor) + DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); @@ -1432,7 +1489,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp) } if (cam->users) { - DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor) + DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); if ((filp->f_flags & O_NONBLOCK) || (filp->f_flags & O_NDELAY)) { err = -EWOULDBLOCK; @@ -1458,7 +1515,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp) err = sn9c102_init(cam); if (err) { DBG(1, "Initialization failed again. " - "I will retry on next open().") + "I will retry on next open()."); goto out; } cam->state &= ~DEV_MISCONFIGURED; @@ -1475,7 +1532,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp) cam->frame_count = 0; sn9c102_empty_framequeues(cam); - DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor) + DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); out: up(&cam->dev_sem); @@ -1504,7 +1561,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp) cam->users--; wake_up_interruptible_nr(&cam->open, 1); - DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor) + DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); up(&cam->dev_sem); @@ -1524,32 +1581,38 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) return -ERESTARTSYS; if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present") + DBG(1, "Device not present"); up(&cam->fileop_sem); return -ENODEV; } if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it again.") + DBG(1, "The camera is misconfigured. Close and open it " + "again."); up(&cam->fileop_sem); return -EIO; } if (cam->io == IO_MMAP) { DBG(3, "Close and open the device again to choose " - "the read method") + "the read method"); up(&cam->fileop_sem); return -EINVAL; } if (cam->io == IO_NONE) { if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) { - DBG(1, "read() failed, not enough memory") + DBG(1, "read() failed, not enough memory"); up(&cam->fileop_sem); return -ENOMEM; } cam->io = IO_READ; cam->stream = STREAM_ON; + } + + if (list_empty(&cam->inqueue)) { + if (!list_empty(&cam->outqueue)) + sn9c102_empty_framequeues(cam); sn9c102_queue_unusedframes(cam); } @@ -1584,6 +1647,16 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame); + if (count > f->buf.bytesused) + count = f->buf.bytesused; + + if (copy_to_user(buf, f->bufmem, count)) { + err = -EFAULT; + goto exit; + } + *f_pos += count; + +exit: spin_lock_irqsave(&cam->queue_lock, lock_flags); list_for_each_entry(i, &cam->outqueue, frame) i->state = F_UNUSED; @@ -1592,16 +1665,8 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) sn9c102_queue_unusedframes(cam); - if (count > f->buf.bytesused) - count = f->buf.bytesused; - - if (copy_to_user(buf, f->bufmem, count)) { - up(&cam->fileop_sem); - return -EFAULT; - } - *f_pos += count; - - PDBGG("Frame #%lu, bytes read: %zu", (unsigned long)f->buf.index,count) + PDBGG("Frame #%lu, bytes read: %zu", + (unsigned long)f->buf.index, count); up(&cam->fileop_sem); @@ -1612,33 +1677,42 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) { struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); + struct sn9c102_frame_t* f; + unsigned long lock_flags; unsigned int mask = 0; if (down_interruptible(&cam->fileop_sem)) return POLLERR; if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present") + DBG(1, "Device not present"); goto error; } if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it again.") + DBG(1, "The camera is misconfigured. Close and open it " + "again."); goto error; } if (cam->io == IO_NONE) { if (!sn9c102_request_buffers(cam, cam->nreadbuffers, IO_READ)) { - DBG(1, "poll() failed, not enough memory") + DBG(1, "poll() failed, not enough memory"); goto error; } cam->io = IO_READ; cam->stream = STREAM_ON; } - if (cam->io == IO_READ) + if (cam->io == IO_READ) { + spin_lock_irqsave(&cam->queue_lock, lock_flags); + list_for_each_entry(f, &cam->outqueue, frame) + f->state = F_UNUSED; + INIT_LIST_HEAD(&cam->outqueue); + spin_unlock_irqrestore(&cam->queue_lock, lock_flags); sn9c102_queue_unusedframes(cam); + } poll_wait(filp, &cam->wait_frame, wait); @@ -1689,13 +1763,14 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) return -ERESTARTSYS; if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present") + DBG(1, "Device not present"); up(&cam->fileop_sem); return -ENODEV; } if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it again.") + DBG(1, "The camera is misconfigured. Close and open it " + "again."); up(&cam->fileop_sem); return -EIO; } @@ -1742,6 +1817,782 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) return 0; } +/*****************************************************************************/ + +static int +sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_capability cap = { + .driver = "sn9c102", + .version = SN9C102_MODULE_VERSION_CODE, + .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING, + }; + + strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); + if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) + strlcpy(cap.bus_info, cam->dev.bus_id, sizeof(cap.bus_info)); + + if (copy_to_user(arg, &cap, sizeof(cap))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_input i; + + if (copy_from_user(&i, arg, sizeof(i))) + return -EFAULT; + + if (i.index) + return -EINVAL; + + memset(&i, 0, sizeof(i)); + strcpy(i.name, "USB"); + + if (copy_to_user(arg, &i, sizeof(i))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_gs_input(struct sn9c102_device* cam, void __user * arg) +{ + int index; + + if (copy_from_user(&index, arg, sizeof(index))) + return -EFAULT; + + if (index != 0) + return -EINVAL; + + return 0; +} + + +static int +sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg) +{ + struct sn9c102_sensor* s = cam->sensor; + struct v4l2_queryctrl qc; + u8 i; + + if (copy_from_user(&qc, arg, sizeof(qc))) + return -EFAULT; + + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (qc.id && qc.id == s->qctrl[i].id) { + memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); + if (copy_to_user(arg, &qc, sizeof(qc))) + return -EFAULT; + return 0; + } + + return -EINVAL; +} + + +static int +sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg) +{ + struct sn9c102_sensor* s = cam->sensor; + struct v4l2_control ctrl; + int err = 0; + u8 i; + + if (!s->get_ctrl && !s->set_ctrl) + return -EINVAL; + + if (copy_from_user(&ctrl, arg, sizeof(ctrl))) + return -EFAULT; + + if (!s->get_ctrl) { + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (ctrl.id && ctrl.id == s->qctrl[i].id) { + ctrl.value = s->_qctrl[i].default_value; + goto exit; + } + return -EINVAL; + } else + err = s->get_ctrl(cam, &ctrl); + +exit: + if (copy_to_user(arg, &ctrl, sizeof(ctrl))) + return -EFAULT; + + return err; +} + + +static int +sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg) +{ + struct sn9c102_sensor* s = cam->sensor; + struct v4l2_control ctrl; + u8 i; + int err = 0; + + if (!s->set_ctrl) + return -EINVAL; + + if (copy_from_user(&ctrl, arg, sizeof(ctrl))) + return -EFAULT; + + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (ctrl.id == s->qctrl[i].id) { + if (ctrl.value < s->qctrl[i].minimum || + ctrl.value > s->qctrl[i].maximum) + return -ERANGE; + ctrl.value -= ctrl.value % s->qctrl[i].step; + break; + } + + if ((err = s->set_ctrl(cam, &ctrl))) + return err; + + s->_qctrl[i].default_value = ctrl.value; + + PDBGG("VIDIOC_S_CTRL: id %lu, value %lu", + (unsigned long)ctrl.id, (unsigned long)ctrl.value); + + return 0; +} + + +static int +sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_cropcap* cc = &(cam->sensor->cropcap); + + cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cc->pixelaspect.numerator = 1; + cc->pixelaspect.denominator = 1; + + if (copy_to_user(arg, cc, sizeof(*cc))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg) +{ + struct sn9c102_sensor* s = cam->sensor; + struct v4l2_crop crop = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + }; + + memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect)); + + if (copy_to_user(arg, &crop, sizeof(crop))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) +{ + struct sn9c102_sensor* s = cam->sensor; + struct v4l2_crop crop; + struct v4l2_rect* rect; + struct v4l2_rect* bounds = &(s->cropcap.bounds); + struct v4l2_pix_format* pix_format = &(s->pix_format); + u8 scale; + const enum sn9c102_stream_state stream = cam->stream; + const u32 nbuffers = cam->nbuffers; + u32 i; + int err = 0; + + if (copy_from_user(&crop, arg, sizeof(crop))) + return -EFAULT; + + rect = &(crop.c); + + if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (cam->module_param.force_munmap) + for (i = 0; i < cam->nbuffers; i++) + if (cam->frame[i].vma_use_count) { + DBG(3, "VIDIOC_S_CROP failed. " + "Unmap the buffers first."); + return -EINVAL; + } + + /* Preserve R,G or B origin */ + rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L; + rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L; + + if (rect->width < 16) + rect->width = 16; + if (rect->height < 16) + rect->height = 16; + if (rect->width > bounds->width) + rect->width = bounds->width; + if (rect->height > bounds->height) + rect->height = bounds->height; + if (rect->left < bounds->left) + rect->left = bounds->left; + if (rect->top < bounds->top) + rect->top = bounds->top; + if (rect->left + rect->width > bounds->left + bounds->width) + rect->left = bounds->left+bounds->width - rect->width; + if (rect->top + rect->height > bounds->top + bounds->height) + rect->top = bounds->top+bounds->height - rect->height; + + rect->width &= ~15L; + rect->height &= ~15L; + + if (SN9C102_PRESERVE_IMGSCALE) { + /* Calculate the actual scaling factor */ + u32 a, b; + a = rect->width * rect->height; + b = pix_format->width * pix_format->height; + scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1; + } else + scale = 1; + + if (cam->stream == STREAM_ON) + if ((err = sn9c102_stream_interrupt(cam))) + return err; + + if (copy_to_user(arg, &crop, sizeof(crop))) { + cam->stream = stream; + return -EFAULT; + } + + if (cam->module_param.force_munmap || cam->io == IO_READ) + sn9c102_release_buffers(cam); + + err = sn9c102_set_crop(cam, rect); + if (s->set_crop) + err += s->set_crop(cam, rect); + err += sn9c102_set_scale(cam, scale); + + if (err) { /* atomic, no rollback in ioctl() */ + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " + "use the camera, close and open /dev/video%d again.", + cam->v4ldev->minor); + return -EIO; + } + + s->pix_format.width = rect->width/scale; + s->pix_format.height = rect->height/scale; + memcpy(&(s->_rect), rect, sizeof(*rect)); + + if ((cam->module_param.force_munmap || cam->io == IO_READ) && + nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) { + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " + "use the camera, close and open /dev/video%d again.", + cam->v4ldev->minor); + return -ENOMEM; + } + + if (cam->io == IO_READ) + sn9c102_empty_framequeues(cam); + else if (cam->module_param.force_munmap) + sn9c102_requeue_outqueue(cam); + + cam->stream = stream; + + return 0; +} + + +static int +sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_fmtdesc fmtd; + + if (copy_from_user(&fmtd, arg, sizeof(fmtd))) + return -EFAULT; + + if (fmtd.index == 0) { + strcpy(fmtd.description, "bayer rgb"); + fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8; + } else if (fmtd.index == 1) { + strcpy(fmtd.description, "compressed"); + fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X; + fmtd.flags = V4L2_FMT_FLAG_COMPRESSED; + } else + return -EINVAL; + + fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + memset(&fmtd.reserved, 0, sizeof(fmtd.reserved)); + + if (copy_to_user(arg, &fmtd, sizeof(fmtd))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_format format; + struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); + + if (copy_from_user(&format, arg, sizeof(format))) + return -EFAULT; + + if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X) + ? 0 : (pfmt->width * pfmt->priv) / 8; + pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); + pfmt->field = V4L2_FIELD_NONE; + memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt)); + + if (copy_to_user(arg, &format, sizeof(format))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, + void __user * arg) +{ + struct sn9c102_sensor* s = cam->sensor; + struct v4l2_format format; + struct v4l2_pix_format* pix; + struct v4l2_pix_format* pfmt = &(s->pix_format); + struct v4l2_rect* bounds = &(s->cropcap.bounds); + struct v4l2_rect rect; + u8 scale; + const enum sn9c102_stream_state stream = cam->stream; + const u32 nbuffers = cam->nbuffers; + u32 i; + int err = 0; + + if (copy_from_user(&format, arg, sizeof(format))) + return -EFAULT; + + pix = &(format.fmt.pix); + + if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memcpy(&rect, &(s->_rect), sizeof(rect)); + + { /* calculate the actual scaling factor */ + u32 a, b; + a = rect.width * rect.height; + b = pix->width * pix->height; + scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1; + } + + rect.width = scale * pix->width; + rect.height = scale * pix->height; + + if (rect.width < 16) + rect.width = 16; + if (rect.height < 16) + rect.height = 16; + if (rect.width > bounds->left + bounds->width - rect.left) + rect.width = bounds->left + bounds->width - rect.left; + if (rect.height > bounds->top + bounds->height - rect.top) + rect.height = bounds->top + bounds->height - rect.top; + + rect.width &= ~15L; + rect.height &= ~15L; + + { /* adjust the scaling factor */ + u32 a, b; + a = rect.width * rect.height; + b = pix->width * pix->height; + scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1; + } + + pix->width = rect.width / scale; + pix->height = rect.height / scale; + + if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X && + pix->pixelformat != V4L2_PIX_FMT_SBGGR8) + pix->pixelformat = pfmt->pixelformat; + pix->priv = pfmt->priv; /* bpp */ + pix->colorspace = pfmt->colorspace; + pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) + ? 0 : (pix->width * pix->priv) / 8; + pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8); + pix->field = V4L2_FIELD_NONE; + + if (cmd == VIDIOC_TRY_FMT) { + if (copy_to_user(arg, &format, sizeof(format))) + return -EFAULT; + return 0; + } + + if (cam->module_param.force_munmap) + for (i = 0; i < cam->nbuffers; i++) + if (cam->frame[i].vma_use_count) { + DBG(3, "VIDIOC_S_FMT failed. Unmap the " + "buffers first."); + return -EINVAL; + } + + if (cam->stream == STREAM_ON) + if ((err = sn9c102_stream_interrupt(cam))) + return err; + + if (copy_to_user(arg, &format, sizeof(format))) { + cam->stream = stream; + return -EFAULT; + } + + if (cam->module_param.force_munmap || cam->io == IO_READ) + sn9c102_release_buffers(cam); + + err += sn9c102_set_pix_format(cam, pix); + err += sn9c102_set_crop(cam, &rect); + if (s->set_pix_format) + err += s->set_pix_format(cam, pix); + if (s->set_crop) + err += s->set_crop(cam, &rect); + err += sn9c102_set_scale(cam, scale); + + if (err) { /* atomic, no rollback in ioctl() */ + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " + "use the camera, close and open /dev/video%d again.", + cam->v4ldev->minor); + return -EIO; + } + + memcpy(pfmt, pix, sizeof(*pix)); + memcpy(&(s->_rect), &rect, sizeof(rect)); + + if ((cam->module_param.force_munmap || cam->io == IO_READ) && + nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) { + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " + "use the camera, close and open /dev/video%d again.", + cam->v4ldev->minor); + return -ENOMEM; + } + + if (cam->io == IO_READ) + sn9c102_empty_framequeues(cam); + else if (cam->module_param.force_munmap) + sn9c102_requeue_outqueue(cam); + + cam->stream = stream; + + return 0; +} + + +static int +sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg) +{ + if (copy_to_user(arg, &cam->compression, + sizeof(cam->compression))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_jpegcompression jc; + const enum sn9c102_stream_state stream = cam->stream; + int err = 0; + + if (copy_from_user(&jc, arg, sizeof(jc))) + return -EFAULT; + + if (jc.quality != 0 && jc.quality != 1) + return -EINVAL; + + if (cam->stream == STREAM_ON) + if ((err = sn9c102_stream_interrupt(cam))) + return err; + + err += sn9c102_set_compression(cam, &jc); + if (err) { /* atomic, no rollback in ioctl() */ + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " + "problems. To use the camera, close and open " + "/dev/video%d again.", cam->v4ldev->minor); + return -EIO; + } + + cam->compression.quality = jc.quality; + + cam->stream = stream; + + return 0; +} + + +static int +sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_requestbuffers rb; + u32 i; + int err; + + if (copy_from_user(&rb, arg, sizeof(rb))) + return -EFAULT; + + if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + rb.memory != V4L2_MEMORY_MMAP) + return -EINVAL; + + if (cam->io == IO_READ) { + DBG(3, "Close and open the device again to choose the mmap " + "I/O method"); + return -EINVAL; + } + + for (i = 0; i < cam->nbuffers; i++) + if (cam->frame[i].vma_use_count) { + DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are " + "still mapped."); + return -EINVAL; + } + + if (cam->stream == STREAM_ON) + if ((err = sn9c102_stream_interrupt(cam))) + return err; + + sn9c102_empty_framequeues(cam); + + sn9c102_release_buffers(cam); + if (rb.count) + rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP); + + if (copy_to_user(arg, &rb, sizeof(rb))) { + sn9c102_release_buffers(cam); + cam->io = IO_NONE; + return -EFAULT; + } + + cam->io = rb.count ? IO_MMAP : IO_NONE; + + return 0; +} + + +static int +sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_buffer b; + + if (copy_from_user(&b, arg, sizeof(b))) + return -EFAULT; + + if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + b.index >= cam->nbuffers || cam->io != IO_MMAP) + return -EINVAL; + + memcpy(&b, &cam->frame[b.index].buf, sizeof(b)); + + if (cam->frame[b.index].vma_use_count) + b.flags |= V4L2_BUF_FLAG_MAPPED; + + if (cam->frame[b.index].state == F_DONE) + b.flags |= V4L2_BUF_FLAG_DONE; + else if (cam->frame[b.index].state != F_UNUSED) + b.flags |= V4L2_BUF_FLAG_QUEUED; + + if (copy_to_user(arg, &b, sizeof(b))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_buffer b; + unsigned long lock_flags; + + if (copy_from_user(&b, arg, sizeof(b))) + return -EFAULT; + + if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + b.index >= cam->nbuffers || cam->io != IO_MMAP) + return -EINVAL; + + if (cam->frame[b.index].state != F_UNUSED) + return -EINVAL; + + cam->frame[b.index].state = F_QUEUED; + + spin_lock_irqsave(&cam->queue_lock, lock_flags); + list_add_tail(&cam->frame[b.index].frame, &cam->inqueue); + spin_unlock_irqrestore(&cam->queue_lock, lock_flags); + + PDBGG("Frame #%lu queued", (unsigned long)b.index); + + return 0; +} + + +static int +sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp, + void __user * arg) +{ + struct v4l2_buffer b; + struct sn9c102_frame_t *f; + unsigned long lock_flags; + int err = 0; + + if (copy_from_user(&b, arg, sizeof(b))) + return -EFAULT; + + if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) + return -EINVAL; + + if (list_empty(&cam->outqueue)) { + if (cam->stream == STREAM_OFF) + return -EINVAL; + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + err = wait_event_interruptible + ( cam->wait_frame, + (!list_empty(&cam->outqueue)) || + (cam->state & DEV_DISCONNECTED) || + (cam->state & DEV_MISCONFIGURED) ); + if (err) + return err; + if (cam->state & DEV_DISCONNECTED) + return -ENODEV; + if (cam->state & DEV_MISCONFIGURED) + return -EIO; + } + + spin_lock_irqsave(&cam->queue_lock, lock_flags); + f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame); + list_del(cam->outqueue.next); + spin_unlock_irqrestore(&cam->queue_lock, lock_flags); + + f->state = F_UNUSED; + + memcpy(&b, &f->buf, sizeof(b)); + if (f->vma_use_count) + b.flags |= V4L2_BUF_FLAG_MAPPED; + + if (copy_to_user(arg, &b, sizeof(b))) + return -EFAULT; + + PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index); + + return 0; +} + + +static int +sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg) +{ + int type; + + if (copy_from_user(&type, arg, sizeof(type))) + return -EFAULT; + + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) + return -EINVAL; + + if (list_empty(&cam->inqueue)) + return -EINVAL; + + cam->stream = STREAM_ON; + + DBG(3, "Stream on"); + + return 0; +} + + +static int +sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg) +{ + int type, err; + + if (copy_from_user(&type, arg, sizeof(type))) + return -EFAULT; + + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) + return -EINVAL; + + if (cam->stream == STREAM_ON) + if ((err = sn9c102_stream_interrupt(cam))) + return err; + + sn9c102_empty_framequeues(cam); + + DBG(3, "Stream off"); + + return 0; +} + + +static int +sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_streamparm sp; + + if (copy_from_user(&sp, arg, sizeof(sp))) + return -EFAULT; + + if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + sp.parm.capture.extendedmode = 0; + sp.parm.capture.readbuffers = cam->nreadbuffers; + + if (copy_to_user(arg, &sp, sizeof(sp))) + return -EFAULT; + + return 0; +} + + +static int +sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg) +{ + struct v4l2_streamparm sp; + + if (copy_from_user(&sp, arg, sizeof(sp))) + return -EFAULT; + + if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + sp.parm.capture.extendedmode = 0; + + if (sp.parm.capture.readbuffers == 0) + sp.parm.capture.readbuffers = cam->nreadbuffers; + + if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES) + sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES; + + if (copy_to_user(arg, &sp, sizeof(sp))) + return -EFAULT; + + cam->nreadbuffers = sp.parm.capture.readbuffers; + + return 0; +} + static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, unsigned int cmd, void __user * arg) @@ -1751,729 +2602,75 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, switch (cmd) { case VIDIOC_QUERYCAP: - { - struct v4l2_capability cap = { - .driver = "sn9c102", - .version = SN9C102_MODULE_VERSION_CODE, - .capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING, - }; - - strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); - if (usb_make_path(cam->usbdev, cap.bus_info, - sizeof(cap.bus_info)) < 0) - strlcpy(cap.bus_info, cam->dev.bus_id, - sizeof(cap.bus_info)); - - if (copy_to_user(arg, &cap, sizeof(cap))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_querycap(cam, arg); case VIDIOC_ENUMINPUT: - { - struct v4l2_input i; - - if (copy_from_user(&i, arg, sizeof(i))) - return -EFAULT; - - if (i.index) - return -EINVAL; - - memset(&i, 0, sizeof(i)); - strcpy(i.name, "USB"); - - if (copy_to_user(arg, &i, sizeof(i))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_enuminput(cam, arg); case VIDIOC_G_INPUT: case VIDIOC_S_INPUT: - { - int index; - - if (copy_from_user(&index, arg, sizeof(index))) - return -EFAULT; - - if (index != 0) - return -EINVAL; - - return 0; - } + return sn9c102_vidioc_gs_input(cam, arg); case VIDIOC_QUERYCTRL: - { - struct sn9c102_sensor* s = cam->sensor; - struct v4l2_queryctrl qc; - u8 i; - - if (copy_from_user(&qc, arg, sizeof(qc))) - return -EFAULT; - - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (qc.id && qc.id == s->qctrl[i].id) { - memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); - if (copy_to_user(arg, &qc, sizeof(qc))) - return -EFAULT; - return 0; - } - - return -EINVAL; - } + return sn9c102_vidioc_query_ctrl(cam, arg); case VIDIOC_G_CTRL: - { - struct sn9c102_sensor* s = cam->sensor; - struct v4l2_control ctrl; - int err = 0; - - if (!s->get_ctrl) - return -EINVAL; - - if (copy_from_user(&ctrl, arg, sizeof(ctrl))) - return -EFAULT; - - err = s->get_ctrl(cam, &ctrl); - - if (copy_to_user(arg, &ctrl, sizeof(ctrl))) - return -EFAULT; - - return err; - } + return sn9c102_vidioc_g_ctrl(cam, arg); case VIDIOC_S_CTRL_OLD: case VIDIOC_S_CTRL: - { - struct sn9c102_sensor* s = cam->sensor; - struct v4l2_control ctrl; - u8 i; - int err = 0; - - if (!s->set_ctrl) - return -EINVAL; - - if (copy_from_user(&ctrl, arg, sizeof(ctrl))) - return -EFAULT; - - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (ctrl.id == s->qctrl[i].id) { - if (ctrl.value < s->qctrl[i].minimum || - ctrl.value > s->qctrl[i].maximum) - return -ERANGE; - ctrl.value -= ctrl.value % s->qctrl[i].step; - break; - } - - if ((err = s->set_ctrl(cam, &ctrl))) - return err; - - s->_qctrl[i].default_value = ctrl.value; - - PDBGG("VIDIOC_S_CTRL: id %lu, value %lu", - (unsigned long)ctrl.id, (unsigned long)ctrl.value) - - return 0; - } + return sn9c102_vidioc_s_ctrl(cam, arg); + case VIDIOC_CROPCAP_OLD: case VIDIOC_CROPCAP: - { - struct v4l2_cropcap* cc = &(cam->sensor->cropcap); - - cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cc->pixelaspect.numerator = 1; - cc->pixelaspect.denominator = 1; - - if (copy_to_user(arg, cc, sizeof(*cc))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_cropcap(cam, arg); case VIDIOC_G_CROP: - { - struct sn9c102_sensor* s = cam->sensor; - struct v4l2_crop crop = { - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - }; - - memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect)); - - if (copy_to_user(arg, &crop, sizeof(crop))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_g_crop(cam, arg); case VIDIOC_S_CROP: - { - struct sn9c102_sensor* s = cam->sensor; - struct v4l2_crop crop; - struct v4l2_rect* rect; - struct v4l2_rect* bounds = &(s->cropcap.bounds); - struct v4l2_pix_format* pix_format = &(s->pix_format); - u8 scale; - const enum sn9c102_stream_state stream = cam->stream; - const u32 nbuffers = cam->nbuffers; - u32 i; - int err = 0; - - if (copy_from_user(&crop, arg, sizeof(crop))) - return -EFAULT; - - rect = &(crop.c); - - if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (cam->module_param.force_munmap) - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_S_CROP failed. " - "Unmap the buffers first.") - return -EINVAL; - } - - /* Preserve R,G or B origin */ - rect->left = (s->_rect.left & 1L) ? - rect->left | 1L : rect->left & ~1L; - rect->top = (s->_rect.top & 1L) ? - rect->top | 1L : rect->top & ~1L; - - if (rect->width < 16) - rect->width = 16; - if (rect->height < 16) - rect->height = 16; - if (rect->width > bounds->width) - rect->width = bounds->width; - if (rect->height > bounds->height) - rect->height = bounds->height; - if (rect->left < bounds->left) - rect->left = bounds->left; - if (rect->top < bounds->top) - rect->top = bounds->top; - if (rect->left + rect->width > bounds->left + bounds->width) - rect->left = bounds->left+bounds->width - rect->width; - if (rect->top + rect->height > bounds->top + bounds->height) - rect->top = bounds->top+bounds->height - rect->height; - - rect->width &= ~15L; - rect->height &= ~15L; - - if (SN9C102_PRESERVE_IMGSCALE) { - /* Calculate the actual scaling factor */ - u32 a, b; - a = rect->width * rect->height; - b = pix_format->width * pix_format->height; - scale = b ? (u8)((a / b) < 4 ? 1 : - ((a / b) < 16 ? 2 : 4)) : 1; - } else - scale = 1; - - if (cam->stream == STREAM_ON) - if ((err = sn9c102_stream_interrupt(cam))) - return err; - - if (copy_to_user(arg, &crop, sizeof(crop))) { - cam->stream = stream; - return -EFAULT; - } - - if (cam->module_param.force_munmap || cam->io == IO_READ) - sn9c102_release_buffers(cam); - - err = sn9c102_set_crop(cam, rect); - if (s->set_crop) - err += s->set_crop(cam, rect); - err += sn9c102_set_scale(cam, scale); - - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_CROP failed because of hardware " - "problems. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->minor) - return -EIO; - } - - s->pix_format.width = rect->width/scale; - s->pix_format.height = rect->height/scale; - memcpy(&(s->_rect), rect, sizeof(*rect)); - - if ((cam->module_param.force_munmap || cam->io == IO_READ) && - nbuffers != sn9c102_request_buffers(cam, nbuffers, - cam->io)) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_CROP failed because of not enough " - "memory. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->minor) - return -ENOMEM; - } - - cam->stream = stream; - - return 0; - } + return sn9c102_vidioc_s_crop(cam, arg); case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc fmtd; - - if (copy_from_user(&fmtd, arg, sizeof(fmtd))) - return -EFAULT; - - if (fmtd.index == 0) { - strcpy(fmtd.description, "bayer rgb"); - fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8; - } else if (fmtd.index == 1) { - strcpy(fmtd.description, "compressed"); - fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X; - fmtd.flags = V4L2_FMT_FLAG_COMPRESSED; - } else - return -EINVAL; - - fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memset(&fmtd.reserved, 0, sizeof(fmtd.reserved)); - - if (copy_to_user(arg, &fmtd, sizeof(fmtd))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_enum_fmt(cam, arg); case VIDIOC_G_FMT: - { - struct v4l2_format format; - struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); - - if (copy_from_user(&format, arg, sizeof(format))) - return -EFAULT; - - if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X) - ? 0 : (pfmt->width * pfmt->priv) / 8; - pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); - pfmt->field = V4L2_FIELD_NONE; - memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt)); - - if (copy_to_user(arg, &format, sizeof(format))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_g_fmt(cam, arg); case VIDIOC_TRY_FMT: case VIDIOC_S_FMT: - { - struct sn9c102_sensor* s = cam->sensor; - struct v4l2_format format; - struct v4l2_pix_format* pix; - struct v4l2_pix_format* pfmt = &(s->pix_format); - struct v4l2_rect* bounds = &(s->cropcap.bounds); - struct v4l2_rect rect; - u8 scale; - const enum sn9c102_stream_state stream = cam->stream; - const u32 nbuffers = cam->nbuffers; - u32 i; - int err = 0; - - if (copy_from_user(&format, arg, sizeof(format))) - return -EFAULT; - - pix = &(format.fmt.pix); - - if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - memcpy(&rect, &(s->_rect), sizeof(rect)); - - { /* calculate the actual scaling factor */ - u32 a, b; - a = rect.width * rect.height; - b = pix->width * pix->height; - scale = b ? (u8)((a / b) < 4 ? 1 : - ((a / b) < 16 ? 2 : 4)) : 1; - } - - rect.width = scale * pix->width; - rect.height = scale * pix->height; - - if (rect.width < 16) - rect.width = 16; - if (rect.height < 16) - rect.height = 16; - if (rect.width > bounds->left + bounds->width - rect.left) - rect.width = bounds->left + bounds->width - rect.left; - if (rect.height > bounds->top + bounds->height - rect.top) - rect.height = bounds->top + bounds->height - rect.top; - - rect.width &= ~15L; - rect.height &= ~15L; - - { /* adjust the scaling factor */ - u32 a, b; - a = rect.width * rect.height; - b = pix->width * pix->height; - scale = b ? (u8)((a / b) < 4 ? 1 : - ((a / b) < 16 ? 2 : 4)) : 1; - } - - pix->width = rect.width / scale; - pix->height = rect.height / scale; - - if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X && - pix->pixelformat != V4L2_PIX_FMT_SBGGR8) - pix->pixelformat = pfmt->pixelformat; - pix->priv = pfmt->priv; /* bpp */ - pix->colorspace = pfmt->colorspace; - pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) - ? 0 : (pix->width * pix->priv) / 8; - pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8); - pix->field = V4L2_FIELD_NONE; - - if (cmd == VIDIOC_TRY_FMT) { - if (copy_to_user(arg, &format, sizeof(format))) - return -EFAULT; - return 0; - } - - if (cam->module_param.force_munmap) - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_S_FMT failed. " - "Unmap the buffers first.") - return -EINVAL; - } - - if (cam->stream == STREAM_ON) - if ((err = sn9c102_stream_interrupt(cam))) - return err; - - if (copy_to_user(arg, &format, sizeof(format))) { - cam->stream = stream; - return -EFAULT; - } - - if (cam->module_param.force_munmap || cam->io == IO_READ) - sn9c102_release_buffers(cam); - - err += sn9c102_set_pix_format(cam, pix); - err += sn9c102_set_crop(cam, &rect); - if (s->set_pix_format) - err += s->set_pix_format(cam, pix); - if (s->set_crop) - err += s->set_crop(cam, &rect); - err += sn9c102_set_scale(cam, scale); - - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_FMT failed because of hardware " - "problems. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->minor) - return -EIO; - } - - memcpy(pfmt, pix, sizeof(*pix)); - memcpy(&(s->_rect), &rect, sizeof(rect)); - - if ((cam->module_param.force_munmap || cam->io == IO_READ) && - nbuffers != sn9c102_request_buffers(cam, nbuffers, - cam->io)) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_FMT failed because of not enough " - "memory. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->minor) - return -ENOMEM; - } - - cam->stream = stream; - - return 0; - } + return sn9c102_vidioc_try_s_fmt(cam, cmd, arg); case VIDIOC_G_JPEGCOMP: - { - if (copy_to_user(arg, &cam->compression, - sizeof(cam->compression))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_g_jpegcomp(cam, arg); case VIDIOC_S_JPEGCOMP: - { - struct v4l2_jpegcompression jc; - const enum sn9c102_stream_state stream = cam->stream; - int err = 0; - - if (copy_from_user(&jc, arg, sizeof(jc))) - return -EFAULT; - - if (jc.quality != 0 && jc.quality != 1) - return -EINVAL; - - if (cam->stream == STREAM_ON) - if ((err = sn9c102_stream_interrupt(cam))) - return err; - - err += sn9c102_set_compression(cam, &jc); - if (err) { /* atomic, no rollback in ioctl() */ - cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " - "problems. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->minor) - return -EIO; - } - - cam->compression.quality = jc.quality; - - cam->stream = stream; - - return 0; - } + return sn9c102_vidioc_s_jpegcomp(cam, arg); case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers rb; - u32 i; - int err; - - if (copy_from_user(&rb, arg, sizeof(rb))) - return -EFAULT; - - if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - rb.memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - if (cam->io == IO_READ) { - DBG(3, "Close and open the device again to choose " - "the mmap I/O method") - return -EINVAL; - } - - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].vma_use_count) { - DBG(3, "VIDIOC_REQBUFS failed. " - "Previous buffers are still mapped.") - return -EINVAL; - } - - if (cam->stream == STREAM_ON) - if ((err = sn9c102_stream_interrupt(cam))) - return err; - - sn9c102_empty_framequeues(cam); - - sn9c102_release_buffers(cam); - if (rb.count) - rb.count = sn9c102_request_buffers(cam, rb.count, - IO_MMAP); - - if (copy_to_user(arg, &rb, sizeof(rb))) { - sn9c102_release_buffers(cam); - cam->io = IO_NONE; - return -EFAULT; - } - - cam->io = rb.count ? IO_MMAP : IO_NONE; - - return 0; - } + return sn9c102_vidioc_reqbufs(cam, arg); case VIDIOC_QUERYBUF: - { - struct v4l2_buffer b; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b.index >= cam->nbuffers || cam->io != IO_MMAP) - return -EINVAL; - - memcpy(&b, &cam->frame[b.index].buf, sizeof(b)); - - if (cam->frame[b.index].vma_use_count) - b.flags |= V4L2_BUF_FLAG_MAPPED; - - if (cam->frame[b.index].state == F_DONE) - b.flags |= V4L2_BUF_FLAG_DONE; - else if (cam->frame[b.index].state != F_UNUSED) - b.flags |= V4L2_BUF_FLAG_QUEUED; - - if (copy_to_user(arg, &b, sizeof(b))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_querybuf(cam, arg); case VIDIOC_QBUF: - { - struct v4l2_buffer b; - unsigned long lock_flags; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b.index >= cam->nbuffers || cam->io != IO_MMAP) - return -EINVAL; - - if (cam->frame[b.index].state != F_UNUSED) - return -EINVAL; - - cam->frame[b.index].state = F_QUEUED; - - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_add_tail(&cam->frame[b.index].frame, &cam->inqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - - PDBGG("Frame #%lu queued", (unsigned long)b.index) - - return 0; - } + return sn9c102_vidioc_qbuf(cam, arg); case VIDIOC_DQBUF: - { - struct v4l2_buffer b; - struct sn9c102_frame_t *f; - unsigned long lock_flags; - int err = 0; - - if (copy_from_user(&b, arg, sizeof(b))) - return -EFAULT; - - if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP) - return -EINVAL; - - if (list_empty(&cam->outqueue)) { - if (cam->stream == STREAM_OFF) - return -EINVAL; - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - err = wait_event_interruptible - ( cam->wait_frame, - (!list_empty(&cam->outqueue)) || - (cam->state & DEV_DISCONNECTED) || - (cam->state & DEV_MISCONFIGURED) ); - if (err) - return err; - if (cam->state & DEV_DISCONNECTED) - return -ENODEV; - if (cam->state & DEV_MISCONFIGURED) - return -EIO; - } - - spin_lock_irqsave(&cam->queue_lock, lock_flags); - f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, - frame); - list_del(cam->outqueue.next); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - - f->state = F_UNUSED; - - memcpy(&b, &f->buf, sizeof(b)); - if (f->vma_use_count) - b.flags |= V4L2_BUF_FLAG_MAPPED; - - if (copy_to_user(arg, &b, sizeof(b))) - return -EFAULT; - - PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index) - - return 0; - } + return sn9c102_vidioc_dqbuf(cam, filp, arg); case VIDIOC_STREAMON: - { - int type; - - if (copy_from_user(&type, arg, sizeof(type))) - return -EFAULT; - - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) - return -EINVAL; - - if (list_empty(&cam->inqueue)) - return -EINVAL; - - cam->stream = STREAM_ON; - - DBG(3, "Stream on") - - return 0; - } + return sn9c102_vidioc_streamon(cam, arg); case VIDIOC_STREAMOFF: - { - int type, err; - - if (copy_from_user(&type, arg, sizeof(type))) - return -EFAULT; - - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) - return -EINVAL; - - if (cam->stream == STREAM_ON) - if ((err = sn9c102_stream_interrupt(cam))) - return err; - - sn9c102_empty_framequeues(cam); - - DBG(3, "Stream off") - - return 0; - } + return sn9c102_vidioc_streamoff(cam, arg); case VIDIOC_G_PARM: - { - struct v4l2_streamparm sp; - - if (copy_from_user(&sp, arg, sizeof(sp))) - return -EFAULT; - - if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - sp.parm.capture.extendedmode = 0; - sp.parm.capture.readbuffers = cam->nreadbuffers; - - if (copy_to_user(arg, &sp, sizeof(sp))) - return -EFAULT; - - return 0; - } + return sn9c102_vidioc_g_parm(cam, arg); case VIDIOC_S_PARM_OLD: case VIDIOC_S_PARM: - { - struct v4l2_streamparm sp; - - if (copy_from_user(&sp, arg, sizeof(sp))) - return -EFAULT; - - if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - sp.parm.capture.extendedmode = 0; - - if (sp.parm.capture.readbuffers == 0) - sp.parm.capture.readbuffers = cam->nreadbuffers; - - if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES) - sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES; - - if (copy_to_user(arg, &sp, sizeof(sp))) - return -EFAULT; - - cam->nreadbuffers = sp.parm.capture.readbuffers; - - return 0; - } + return sn9c102_vidioc_s_parm(cam, arg); case VIDIOC_G_STD: case VIDIOC_S_STD: @@ -2499,13 +2696,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, return -ERESTARTSYS; if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present") + DBG(1, "Device not present"); up(&cam->fileop_sem); return -ENODEV; } if (cam->state & DEV_MISCONFIGURED) { - DBG(1, "The camera is misconfigured. Close and open it again.") + DBG(1, "The camera is misconfigured. Close and open it " + "again."); up(&cam->fileop_sem); return -EIO; } @@ -2517,9 +2715,10 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, return err; } +/*****************************************************************************/ static struct file_operations sn9c102_fops = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, .open = sn9c102_open, .release = sn9c102_release, .ioctl = sn9c102_ioctl, @@ -2538,36 +2737,23 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) struct usb_device *udev = interface_to_usbdev(intf); struct sn9c102_device* cam; static unsigned int dev_nr = 0; - unsigned int i, n; + unsigned int i; int err = 0, r; - n = ARRAY_SIZE(sn9c102_id_table); - for (i = 0; i < n-1; i++) - if (le16_to_cpu(udev->descriptor.idVendor) == - sn9c102_id_table[i].idVendor && - le16_to_cpu(udev->descriptor.idProduct) == - sn9c102_id_table[i].idProduct) - break; - if (i == n-1) - return -ENODEV; - if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL))) return -ENOMEM; - memset(cam, 0, sizeof(*cam)); cam->usbdev = udev; - memcpy(&cam->dev, &udev->dev, sizeof(struct device)); if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) { - DBG(1, "kmalloc() failed") + DBG(1, "kmalloc() failed"); err = -ENOMEM; goto fail; } - memset(cam->control_buffer, 0, 8); if (!(cam->v4ldev = video_device_alloc())) { - DBG(1, "video_device_alloc() failed") + DBG(1, "video_device_alloc() failed"); err = -ENOMEM; goto fail; } @@ -2577,25 +2763,22 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) r = sn9c102_read_reg(cam, 0x00); if (r < 0 || r != 0x10) { DBG(1, "Sorry, this is not a SN9C10x based camera " - "(vid/pid 0x%04X/0x%04X)", - sn9c102_id_table[i].idVendor,sn9c102_id_table[i].idProduct) + "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct); err = -ENODEV; goto fail; } - cam->bridge = (sn9c102_id_table[i].idProduct & 0xffc0) == 0x6080 ? + cam->bridge = (id->idProduct & 0xffc0) == 0x6080 ? BRIDGE_SN9C103 : BRIDGE_SN9C102; switch (cam->bridge) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: DBG(2, "SN9C10[12] PC Camera Controller detected " - "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor, - sn9c102_id_table[i].idProduct) + "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct); break; case BRIDGE_SN9C103: DBG(2, "SN9C103 PC Camera Controller detected " - "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor, - sn9c102_id_table[i].idProduct) + "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct); break; } @@ -2606,17 +2789,17 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } if (!err && cam->sensor) { - DBG(2, "%s image sensor detected", cam->sensor->name) + DBG(2, "%s image sensor detected", cam->sensor->name); DBG(3, "Support for %s maintained by %s", - cam->sensor->name, cam->sensor->maintainer) + cam->sensor->name, cam->sensor->maintainer); } else { - DBG(1, "No supported image sensor detected") + DBG(1, "No supported image sensor detected"); err = -ENODEV; goto fail; } if (sn9c102_init(cam)) { - DBG(1, "Initialization failed. I will retry on open().") + DBG(1, "Initialization failed. I will retry on open()."); cam->state |= DEV_MISCONFIGURED; } @@ -2634,23 +2817,23 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, video_nr[dev_nr]); if (err) { - DBG(1, "V4L2 device registration failed") + DBG(1, "V4L2 device registration failed"); if (err == -ENFILE && video_nr[dev_nr] == -1) - DBG(1, "Free /dev/videoX node not found") + DBG(1, "Free /dev/videoX node not found"); video_nr[dev_nr] = -1; dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; up(&cam->dev_sem); goto fail; } - DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor) + DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); cam->module_param.force_munmap = force_munmap[dev_nr]; dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; sn9c102_create_sysfs(cam); - DBG(2, "Optional device control through 'sysfs' interface ready") + DBG(2, "Optional device control through 'sysfs' interface ready"); usb_set_intfdata(intf, cam); @@ -2680,14 +2863,14 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf) down(&cam->dev_sem); - DBG(2, "Disconnecting %s...", cam->v4ldev->name) + DBG(2, "Disconnecting %s...", cam->v4ldev->name); wake_up_interruptible_all(&cam->open); if (cam->users) { DBG(2, "Device /dev/video%d is open! Deregistration and " "memory deallocation are deferred on close.", - cam->v4ldev->minor) + cam->v4ldev->minor); cam->state |= DEV_MISCONFIGURED; sn9c102_stop_transfer(cam); cam->state |= DEV_DISCONNECTED; @@ -2720,11 +2903,11 @@ static int __init sn9c102_module_init(void) { int err = 0; - KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION) - KDBG(3, SN9C102_MODULE_AUTHOR) + KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION); + KDBG(3, SN9C102_MODULE_AUTHOR); if ((err = usb_register(&sn9c102_usb_driver))) - KDBG(1, "usb_register() failed") + KDBG(1, "usb_register() failed"); return err; } diff --git a/drivers/usb/media/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c index 18070d5333cf..46c12ec3ca62 100644 --- a/drivers/usb/media/sn9c102_hv7131d.c +++ b/drivers/usb/media/sn9c102_hv7131d.c @@ -2,7 +2,7 @@ * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera * * Controllers * * * - * Copyright (C) 2004-2005 by Luca Risolia * + * Copyright (C) 2004-2006 by Luca Risolia * * * * 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 * diff --git a/drivers/usb/media/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c index 86676abf3547..d9aa7a61095d 100644 --- a/drivers/usb/media/sn9c102_mi0343.c +++ b/drivers/usb/media/sn9c102_mi0343.c @@ -2,7 +2,7 @@ * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera * * Controllers * * * - * Copyright (C) 2004-2005 by Luca Risolia * + * Copyright (C) 2004-2006 by Luca Risolia * * * * 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 * diff --git a/drivers/usb/media/sn9c102_ov7630.c b/drivers/usb/media/sn9c102_ov7630.c index d27c5aedeaf8..4a36519b5af4 100644 --- a/drivers/usb/media/sn9c102_ov7630.c +++ b/drivers/usb/media/sn9c102_ov7630.c @@ -2,7 +2,7 @@ * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera * * Controllers * * * - * Copyright (C) 2005 by Luca Risolia * + * Copyright (C) 2005-2006 by Luca Risolia * * * * 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 * @@ -375,8 +375,10 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam) sn9c102_attach_sensor(cam, &ov7630); - if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f && - le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c) + if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c && + le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602d && + le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f && + le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x60b0) return -ENODEV; err += sn9c102_write_reg(cam, 0x01, 0x01); diff --git a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c index 48e3ec39d4e2..b1dee78abe04 100644 --- a/drivers/usb/media/sn9c102_pas106b.c +++ b/drivers/usb/media/sn9c102_pas106b.c @@ -2,7 +2,7 @@ * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera * * Controllers * * * - * Copyright (C) 2004-2005 by Luca Risolia * + * Copyright (C) 2004-2006 by Luca Risolia * * * * 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 * diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h index a45166c3488c..a0e561b2c852 100644 --- a/drivers/usb/media/sn9c102_sensor.h +++ b/drivers/usb/media/sn9c102_sensor.h @@ -1,7 +1,7 @@ /*************************************************************************** * API for image sensors connected to the SN9C10x PC Camera Controllers * * * - * Copyright (C) 2004-2005 by Luca Risolia * + * Copyright (C) 2004-2006 by Luca Risolia * * * * 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 * @@ -92,7 +92,18 @@ extern void sn9c102_attach_sensor(struct sn9c102_device* cam, struct sn9c102_sensor* sensor); -/* Each SN9C10X camera has proper PID/VID identifiers. Add them here in case.*/ +/* + Each SN9C10x camera has proper PID/VID identifiers. + SN9C103 supports multiple interfaces, but we only handle the video class + interface. +*/ +#define SN9C102_USB_DEVICE(vend, prod, intclass) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ + USB_DEVICE_ID_MATCH_INT_CLASS, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bInterfaceClass = (intclass) + #define SN9C102_ID_TABLE \ static const struct usb_device_id sn9c102_id_table[] = { \ { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \ @@ -107,33 +118,34 @@ static const struct usb_device_id sn9c102_id_table[] = { \ { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \ { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \ { USB_DEVICE(0x0c45, 0x602d), }, \ + { USB_DEVICE(0x0c45, 0x602e), }, /* OV7630 */ \ { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \ - { USB_DEVICE(0x0c45, 0x6080), }, \ - { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \ - { USB_DEVICE(0x0c45, 0x6083), }, /* HV7131[D|E1] */ \ - { USB_DEVICE(0x0c45, 0x6088), }, \ - { USB_DEVICE(0x0c45, 0x608a), }, \ - { USB_DEVICE(0x0c45, 0x608b), }, \ - { USB_DEVICE(0x0c45, 0x608c), }, /* HV7131x */ \ - { USB_DEVICE(0x0c45, 0x608e), }, /* CIS-VF10 */ \ - { USB_DEVICE(0x0c45, 0x608f), }, /* OV7630 */ \ - { USB_DEVICE(0x0c45, 0x60a0), }, \ - { USB_DEVICE(0x0c45, 0x60a2), }, \ - { USB_DEVICE(0x0c45, 0x60a3), }, \ - { USB_DEVICE(0x0c45, 0x60a8), }, /* PAS106B */ \ - { USB_DEVICE(0x0c45, 0x60aa), }, /* TAS5130D1B */ \ - { USB_DEVICE(0x0c45, 0x60ab), }, /* TAS5110C1B */ \ - { USB_DEVICE(0x0c45, 0x60ac), }, \ - { USB_DEVICE(0x0c45, 0x60ae), }, \ - { USB_DEVICE(0x0c45, 0x60af), }, /* PAS202BCB */ \ - { USB_DEVICE(0x0c45, 0x60b0), }, \ - { USB_DEVICE(0x0c45, 0x60b2), }, \ - { USB_DEVICE(0x0c45, 0x60b3), }, \ - { USB_DEVICE(0x0c45, 0x60b8), }, \ - { USB_DEVICE(0x0c45, 0x60ba), }, \ - { USB_DEVICE(0x0c45, 0x60bb), }, \ - { USB_DEVICE(0x0c45, 0x60bc), }, \ - { USB_DEVICE(0x0c45, 0x60be), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x6080, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x6082, 0xff), }, /* MI0343 & MI0360 */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x6083, 0xff), }, /* HV7131[D|E1] */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x6088, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x608a, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x608b, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131x */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x608e, 0xff), }, /* CIS-VF10 */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x608f, 0xff), }, /* OV7630 */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x60a0, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60a2, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60a3, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60a8, 0xff), }, /* PAS106B */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x60aa, 0xff), }, /* TAS5130D1B */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x60ab, 0xff), }, /* TAS5110C1B */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x60ac, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60ae, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60af, 0xff), }, /* PAS202BCB */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x60b0, 0xff), }, /* OV7630 (?) */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x60b2, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60b3, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60b8, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60ba, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60bb, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60bc, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x60be, 0xff), }, \ { } \ }; @@ -177,6 +189,7 @@ extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value); extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address); /* I/O on registers in the bridge. Could be used by the sensor methods too */ +extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index); extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index); extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c index 8775999b5aff..32ddf236cafe 100644 --- a/drivers/usb/media/sn9c102_tas5110c1b.c +++ b/drivers/usb/media/sn9c102_tas5110c1b.c @@ -2,7 +2,7 @@ * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera * * Controllers * * * - * Copyright (C) 2004-2005 by Luca Risolia * + * Copyright (C) 2004-2006 by Luca Risolia * * * * 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 * diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c index 927eafdd8c73..a0728f0ae00c 100644 --- a/drivers/usb/media/sn9c102_tas5130d1b.c +++ b/drivers/usb/media/sn9c102_tas5130d1b.c @@ -2,7 +2,7 @@ * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera * * Controllers * * * - * Copyright (C) 2004-2005 by Luca Risolia * + * Copyright (C) 2004-2006 by Luca Risolia * * * * 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 * From 5732ce8424527ec271e8fa43709948852aa3fc0a Mon Sep 17 00:00:00 2001 From: David Hollis Date: Thu, 5 Jan 2006 14:39:49 -0500 Subject: [PATCH 223/695] [PATCH] USB: asix - Add device IDs for 0G0 Cable Ethernet Add device IDs for the 0G0 Cable Ethernet device as reported by Charles Lepple . Signed-off-by: David Hollis Signed-off-by: Greg Kroah-Hartman --- drivers/usb/net/asix.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 541181695040..3094970615cb 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c @@ -916,6 +916,10 @@ static const struct usb_device_id products [] = { // Linksys USB200M Rev 2 USB_DEVICE (0x13b1, 0x0018), .driver_info = (unsigned long) &ax88772_info, +}, { + // 0Q0 cable ethernet + USB_DEVICE (0x1557, 0x7720), + .driver_info = (unsigned long) &ax88772_info, }, { }, // END }; From a001100d8e4bf8ad98663d3ec1b91e4161267937 Mon Sep 17 00:00:00 2001 From: Juergen Schindele Date: Mon, 9 Jan 2006 08:51:48 +0100 Subject: [PATCH 224/695] [PATCH] USB: touchkitusb.c (eGalax driver) fix This patch corrects the URB initialisation for transfers like this is done in other drivers too. Without this patch no data was transmitted on a PXA270 OHCI platform. May apply to others too. Signed-off-by: Juergen Schindele Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/touchkitusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 3b3c7b4120a2..697c5e573a11 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c @@ -337,6 +337,9 @@ static int touchkit_probe(struct usb_interface *intf, touchkit->data, TOUCHKIT_REPORT_DATA_SIZE, touchkit_irq, touchkit, endpoint->bInterval); + touchkit->irq->transfer_dma = touchkit->data_dma; + touchkit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + input_register_device(touchkit->input); usb_set_intfdata(intf, touchkit); From 838b42814c640ddcc378ba29cd31ffd64fb36bc5 Mon Sep 17 00:00:00 2001 From: Martin Gingras Date: Mon, 9 Jan 2006 12:35:41 -0500 Subject: [PATCH 225/695] [PATCH] USB: pl2303: Added support for CA-42 clone cable Added support for CA-42 clone cable (www.ca-42.com) Signed-off-by: Martin Gingras Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 3 ++- drivers/usb/serial/pl2303.h | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 0eb883f44ada..58ef1d0d9cc7 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -73,7 +73,8 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, - { USB_DEVICE( NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) }, + { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) }, + { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID ) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 21d434d81813..20914ce42369 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -64,3 +64,7 @@ /* Nokia CA-42 Cable */ #define NOKIA_CA42_VENDOR_ID 0x078b #define NOKIA_CA42_PRODUCT_ID 0x1234 + +/* CA-42 CLONE Cable www.ca-42.com chipset: Prolific Technology Inc */ +#define CA_42_CA42_VENDOR_ID 0x10b5 +#define CA_42_CA42_PRODUCT_ID 0xac70 From 6cceb05f8df6e28ab90f44bdeba50d33928cdee5 Mon Sep 17 00:00:00 2001 From: Denis MONTERRAT Date: Thu, 19 Jan 2006 14:52:38 +0100 Subject: [PATCH 226/695] [PATCH] USB: add new pl2303 device ids Signed-off-by: FALIPOU F Developer Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 1 + drivers/usb/serial/pl2303.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 58ef1d0d9cc7..e8e575e037c1 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -75,6 +75,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) }, { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID ) }, + { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 20914ce42369..1807087a76e3 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -68,3 +68,6 @@ /* CA-42 CLONE Cable www.ca-42.com chipset: Prolific Technology Inc */ #define CA_42_CA42_VENDOR_ID 0x10b5 #define CA_42_CA42_PRODUCT_ID 0xac70 + +#define SAGEM_VENDOR_ID 0x079b +#define SAGEM_PRODUCT_ID 0x0027 From e988fc8a56bb3f76624dd7b0fb13ae3eaccefa59 Mon Sep 17 00:00:00 2001 From: Craig Shelley Date: Fri, 20 Jan 2006 00:06:19 +0000 Subject: [PATCH 227/695] [PATCH] USB: cp2101 Add new device IDs The attached patch adds four new device IDs for the CP2101 driver. Also 3 tab characters have been removed from device ID table. Signed-off-by: Craig Shelley Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp2101.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index da46b351e188..dc7a069503e0 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -32,7 +32,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.05" +#define DRIVER_VERSION "v0.06" #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" /* @@ -55,11 +55,15 @@ static int debug; static struct usb_device_id id_table [] = { { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ - { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ - { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ - { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ - { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ + { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ + { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ + { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ + { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ + { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ + { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ + { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { } /* Terminating Entry */ }; From cd6fcc555fe278263880abdb93352ab205099db9 Mon Sep 17 00:00:00 2001 From: Luca Risolia Date: Fri, 13 Jan 2006 17:19:43 +0000 Subject: [PATCH 228/695] [PATCH] USB: SN9C10x driver updates SN9C10x driver updates: - Use kzalloc() instead of kmalloc() - Move some macro definitions from sn9c102.h to sn9c102_core.c - Use vfree() and vmalloc_32() instead of rvfree() and rvmalloc() - Fix mmap() sys call - Documentation updates Signed-off-by: Luca Risolia Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/sn9c102.txt | 9 ++- drivers/usb/media/sn9c102.h | 27 ++++----- drivers/usb/media/sn9c102_core.c | 92 ++++++++++-------------------- drivers/usb/media/sn9c102_sensor.h | 16 ++---- 4 files changed, 54 insertions(+), 90 deletions(-) diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt index 541b17fd27f6..c6b76414172c 100644 --- a/Documentation/usb/sn9c102.txt +++ b/Documentation/usb/sn9c102.txt @@ -111,6 +111,12 @@ corresponding modules must be compiled: # CONFIG_VIDEO_DEV=m +To enable advanced debugging functionality on the device through /sysfs: + + # Multimedia devices + # + CONFIG_VIDEO_ADV_DEBUG=y + # USB support # CONFIG_USB=m @@ -208,7 +214,8 @@ Default: 2 8. Optional device control through "sysfs" [1] ========================================== -It is possible to read and write both the SN9C10x and the image sensor +If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled, +it is possible to read and write both the SN9C10x and the image sensor registers by using the "sysfs" filesystem interface. Every time a supported device is recognized, a write-only file named "green" is diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h index 967c6b6bc0fa..17d60c1eea7e 100644 --- a/drivers/usb/media/sn9c102.h +++ b/drivers/usb/media/sn9c102.h @@ -23,7 +23,8 @@ #include #include -#include +#include +#include #include #include #include @@ -52,13 +53,6 @@ /*****************************************************************************/ -#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" -#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" -#define SN9C102_AUTHOR_EMAIL "" -#define SN9C102_MODULE_LICENSE "GPL" -#define SN9C102_MODULE_VERSION "1:1.25" -#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 25) - enum sn9c102_bridge { BRIDGE_SN9C101 = 0x01, BRIDGE_SN9C102 = 0x02, @@ -119,8 +113,6 @@ static DECLARE_MUTEX(sn9c102_sysfs_lock); static DECLARE_RWSEM(sn9c102_disconnect); struct sn9c102_device { - struct device dev; - struct video_device* v4ldev; enum sn9c102_bridge bridge; @@ -161,7 +153,6 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, struct sn9c102_sensor* sensor) { cam->sensor = sensor; - cam->sensor->dev = &cam->dev; cam->sensor->usbdev = cam->usbdev; } @@ -174,14 +165,19 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, do { \ if (debug >= (level)) { \ if ((level) == 1) \ - dev_err(&cam->dev, fmt "\n", ## args); \ + dev_err(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) == 2) \ - dev_info(&cam->dev, fmt "\n", ## args); \ + dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) >= 3) \ - dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ + dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ __FUNCTION__, __LINE__ , ## args); \ } \ } while (0) +# define V4LDBG(level, name, cmd) \ +do { \ + if (debug >= (level)) \ + v4l_print_ioctl(name, cmd); \ +} while (0) # define KDBG(level, fmt, args...) \ do { \ if (debug >= (level)) { \ @@ -193,8 +189,9 @@ do { \ } \ } while (0) #else -# define KDBG(level, fmt, args...) do {;} while(0) # define DBG(level, fmt, args...) do {;} while(0) +# define V4LDBG(level, name, cmd) do {;} while(0) +# define KDBG(level, fmt, args...) do {;} while(0) #endif #undef PDBG diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index 6090439663ee..c81397e4714b 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c @@ -45,6 +45,15 @@ /*****************************************************************************/ +#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" +#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" +#define SN9C102_AUTHOR_EMAIL "" +#define SN9C102_MODULE_LICENSE "GPL" +#define SN9C102_MODULE_VERSION "1:1.26" +#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 26) + +/*****************************************************************************/ + MODULE_DEVICE_TABLE(usb, sn9c102_id_table); MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL); @@ -115,50 +124,6 @@ static sn9c102_eof_header_t sn9c102_eof_header[] = { /*****************************************************************************/ -static void* rvmalloc(size_t size) -{ - void* mem; - unsigned long adr; - - size = PAGE_ALIGN(size); - - mem = vmalloc_32((unsigned long)size); - if (!mem) - return NULL; - - memset(mem, 0, size); - - adr = (unsigned long)mem; - while (size > 0) { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - return mem; -} - - -static void rvfree(void* mem, size_t size) -{ - unsigned long adr; - - if (!mem) - return; - - size = PAGE_ALIGN(size); - - adr = (unsigned long)mem; - while (size > 0) { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vfree(mem); -} - - static u32 sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, enum sn9c102_io_method io) @@ -177,7 +142,7 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, cam->nbuffers = count; while (cam->nbuffers > 0) { - if ((buff = rvmalloc(cam->nbuffers * PAGE_ALIGN(imagesize)))) + if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize)))) break; cam->nbuffers--; } @@ -201,8 +166,7 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, static void sn9c102_release_buffers(struct sn9c102_device* cam) { if (cam->nbuffers) { - rvfree(cam->frame[0].bufmem, - cam->nbuffers * PAGE_ALIGN(cam->frame[0].buf.length)); + vfree(cam->frame[0].bufmem); cam->nbuffers = 0; } cam->frame_current = NULL; @@ -745,7 +709,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) int err = 0; for (i = 0; i < SN9C102_URBS; i++) { - cam->transfer_buffer[i] = kmalloc(SN9C102_ISO_PACKETS * psz, + cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz, GFP_KERNEL); if (!cam->transfer_buffer[i]) { err = -ENOMEM; @@ -865,6 +829,7 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam) /*****************************************************************************/ +#ifdef CONFIG_VIDEO_ADV_DEBUG static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count) { char str[5]; @@ -1289,6 +1254,7 @@ static void sn9c102_create_sysfs(struct sn9c102_device* cam) video_device_create_file(v4ldev, &class_device_attr_i2c_val); } } +#endif /* CONFIG_VIDEO_ADV_DEBUG */ /*****************************************************************************/ @@ -1754,9 +1720,8 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) { struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start, - pos, - page; + start = vma->vm_start; + void *pos; u32 i; if (down_interruptible(&cam->fileop_sem)) @@ -1790,15 +1755,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) return -EINVAL; } - /* VM_IO is eventually going to replace PageReserved altogether */ vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ + vma->vm_flags |= VM_RESERVED; - pos = (unsigned long)cam->frame[i].bufmem; + pos = cam->frame[i].bufmem; while (size > 0) { /* size is page-aligned */ - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, - vma->vm_page_prot)) { + if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { up(&cam->fileop_sem); return -EAGAIN; } @@ -1831,7 +1793,8 @@ sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg) strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) - strlcpy(cap.bus_info, cam->dev.bus_id, sizeof(cap.bus_info)); + strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, + sizeof(cap.bus_info)); if (copy_to_user(arg, &cap, sizeof(cap))) return -EFAULT; @@ -1852,7 +1815,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) return -EINVAL; memset(&i, 0, sizeof(i)); - strcpy(i.name, "USB"); + strcpy(i.name, "Camera"); if (copy_to_user(arg, &i, sizeof(i))) return -EFAULT; @@ -2708,6 +2671,8 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, return -EIO; } + V4LDBG(3, "sn9c102", cmd); + err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); up(&cam->fileop_sem); @@ -2740,13 +2705,12 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) unsigned int i; int err = 0, r; - if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL))) + if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL))) return -ENOMEM; cam->usbdev = udev; - memcpy(&cam->dev, &udev->dev, sizeof(struct device)); - if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) { + if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) { DBG(1, "kmalloc() failed"); err = -ENOMEM; goto fail; @@ -2806,7 +2770,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) strcpy(cam->v4ldev->name, "SN9C10x PC Camera"); cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; - cam->v4ldev->hardware = VID_HARDWARE_SN9C102; + cam->v4ldev->hardware = 0; cam->v4ldev->fops = &sn9c102_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; @@ -2832,8 +2796,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; +#ifdef CONFIG_VIDEO_ADV_DEBUG sn9c102_create_sysfs(cam); DBG(2, "Optional device control through 'sysfs' interface ready"); +#endif usb_set_intfdata(intf, cam); diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h index a0e561b2c852..7d953b24f2f2 100644 --- a/drivers/usb/media/sn9c102_sensor.h +++ b/drivers/usb/media/sn9c102_sensor.h @@ -196,10 +196,11 @@ extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); /* NOTE: there are no exported debugging functions. To uniform the output you must use the dev_info()/dev_warn()/dev_err() macros defined in device.h, - already included here, the argument being the struct device 'dev' of the - sensor structure. Do NOT use these macros before the sensor is attached or - the kernel will crash! However, you should not need to notify the user about - common errors or other messages, since this is done by the master module. + already included here, the argument being the struct device '&usbdev->dev' + of the sensor structure. Do NOT use these macros before the sensor is + attached or the kernel will crash! However, you should not need to notify + the user about common errors or other messages, since this is done by the + master module. */ /*****************************************************************************/ @@ -358,13 +359,6 @@ struct sn9c102_sensor { error code without rolling back. */ - const struct device* dev; - /* - This is the argument for dev_err(), dev_info() and dev_warn(). It - is used for debugging purposes. You must not access the struct - before the sensor is attached. - */ - const struct usb_device* usbdev; /* Points to the usb_device struct after the sensor is attached. From 7ce08c93e388922e25a96a7d9895784182e4c72c Mon Sep 17 00:00:00 2001 From: Luca Risolia Date: Wed, 11 Jan 2006 02:06:59 +0000 Subject: [PATCH 229/695] [PATCH] USB: Add ET61X[12]51 Video4Linux2 driver This patch adds a Video4Linux2 driver giving support to ET61X151 and ET61X251 PC Camera Controllers made by Etoms Electronics. Signed-off-by: Luca Risolia Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/et61x251.txt | 306 +++ MAINTAINERS | 10 + drivers/usb/Makefile | 1 + drivers/usb/media/Kconfig | 17 +- drivers/usb/media/Makefile | 2 + drivers/usb/media/et61x251.h | 220 ++ drivers/usb/media/et61x251_core.c | 2605 +++++++++++++++++++++++ drivers/usb/media/et61x251_sensor.h | 115 + drivers/usb/media/et61x251_tas5130d1b.c | 137 ++ include/linux/videodev2.h | 1 + 10 files changed, 3412 insertions(+), 2 deletions(-) create mode 100644 Documentation/usb/et61x251.txt create mode 100644 drivers/usb/media/et61x251.h create mode 100644 drivers/usb/media/et61x251_core.c create mode 100644 drivers/usb/media/et61x251_sensor.h create mode 100644 drivers/usb/media/et61x251_tas5130d1b.c diff --git a/Documentation/usb/et61x251.txt b/Documentation/usb/et61x251.txt new file mode 100644 index 000000000000..b44dda407ce2 --- /dev/null +++ b/Documentation/usb/et61x251.txt @@ -0,0 +1,306 @@ + + ET61X[12]51 PC Camera Controllers + Driver for Linux + ================================= + + - Documentation - + + +Index +===== +1. Copyright +2. Disclaimer +3. License +4. Overview and features +5. Module dependencies +6. Module loading +7. Module parameters +8. Optional device control through "sysfs" +9. Supported devices +10. Notes for V4L2 application developers +11. Contact information + + +1. Copyright +============ +Copyright (C) 2006 by Luca Risolia + + +2. Disclaimer +============= +Etoms is a trademark of Etoms Electronics Corp. +This software is not developed or sponsored by Etoms Electronics. + + +3. License +========== +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., 675 Mass Ave, Cambridge, MA 02139, USA. + + +4. Overview and features +======================== +This driver supports the video interface of the devices mounting the ET61X151 +or ET61X251 PC Camera Controllers. + +It's worth to note that Etoms Electronics has never collaborated with the +author during the development of this project; despite several requests, +Etoms Electronics also refused to release enough detailed specifications of +the video compression engine. + +The driver relies on the Video4Linux2 and USB core modules. It has been +designed to run properly on SMP systems as well. + +The latest version of the ET61X[12]51 driver can be found at the following URL: +http://www.linux-projects.org/ + +Some of the features of the driver are: + +- full compliance with the Video4Linux2 API (see also "Notes for V4L2 + application developers" paragraph); +- available mmap or read/poll methods for video streaming through isochronous + data transfers; +- automatic detection of image sensor; +- support for any window resolutions and optional panning within the maximum + pixel area of image sensor; +- image downscaling with arbitrary scaling factors from 1 and 2 in both + directions (see "Notes for V4L2 application developers" paragraph); +- two different video formats for uncompressed or compressed data in low or + high compression quality (see also "Notes for V4L2 application developers" + paragraph); +- full support for the capabilities of every possible image sensors that can + be connected to the ET61X[12]51 bridges, including, for istance, red, green, + blue and global gain adjustments and exposure control (see "Supported + devices" paragraph for details); +- use of default color settings for sunlight conditions; +- dynamic I/O interface for both ET61X[12]51 and image sensor control (see + "Optional device control through 'sysfs'" paragraph); +- dynamic driver control thanks to various module parameters (see "Module + parameters" paragraph); +- up to 64 cameras can be handled at the same time; they can be connected and + disconnected from the host many times without turning off the computer, if + the system supports hotplugging; +- no known bugs. + + +5. Module dependencies +====================== +For it to work properly, the driver needs kernel support for Video4Linux and +USB. + +The following options of the kernel configuration file must be enabled and +corresponding modules must be compiled: + + # Multimedia devices + # + CONFIG_VIDEO_DEV=m + +To enable advanced debugging functionality on the device through /sysfs: + + # Multimedia devices + # + CONFIG_VIDEO_ADV_DEBUG=y + + # USB support + # + CONFIG_USB=m + +In addition, depending on the hardware being used, the modules below are +necessary: + + # USB Host Controller Drivers + # + CONFIG_USB_EHCI_HCD=m + CONFIG_USB_UHCI_HCD=m + CONFIG_USB_OHCI_HCD=m + +And finally: + + # USB Multimedia devices + # + CONFIG_USB_ET61X251=m + + +6. Module loading +================= +To use the driver, it is necessary to load the "et61x251" module into memory +after every other module required: "videodev", "usbcore" and, depending on +the USB host controller you have, "ehci-hcd", "uhci-hcd" or "ohci-hcd". + +Loading can be done as shown below: + + [root@localhost home]# modprobe et61x251 + +At this point the devices should be recognized. You can invoke "dmesg" to +analyze kernel messages and verify that the loading process has gone well: + + [user@localhost home]$ dmesg + + +7. Module parameters +==================== +Module parameters are listed below: +------------------------------------------------------------------------------- +Name: video_nr +Type: short array (min = 0, max = 64) +Syntax: <-1|n[,...]> +Description: Specify V4L2 minor mode number: + -1 = use next available + n = use minor number n + You can specify up to 64 cameras this way. + For example: + video_nr=-1,2,-1 would assign minor number 2 to the second + registered camera and use auto for the first one and for every + other camera. +Default: -1 +------------------------------------------------------------------------------- +Name: force_munmap +Type: bool array (min = 0, max = 64) +Syntax: <0|1[,...]> +Description: Force the application to unmap previously mapped buffer memory + before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not + all the applications support this feature. This parameter is + specific for each detected camera. + 0 = do not force memory unmapping + 1 = force memory unmapping (save memory) +Default: 0 +------------------------------------------------------------------------------- +Name: debug +Type: ushort +Syntax: +Description: Debugging information level, from 0 to 3: + 0 = none (use carefully) + 1 = critical errors + 2 = significant informations + 3 = more verbose messages + Level 3 is useful for testing only, when only one device + is used at the same time. It also shows some more informations + about the hardware being detected. This module parameter can be + changed at runtime thanks to the /sys filesystem interface. +Default: 2 +------------------------------------------------------------------------------- + + +8. Optional device control through "sysfs" +========================================== +If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled, +it is possible to read and write both the ET61X[12]51 and the image sensor +registers by using the "sysfs" filesystem interface. + +There are four files in the /sys/class/video4linux/videoX directory for each +registered camera: "reg", "val", "i2c_reg" and "i2c_val". The first two files +control the ET61X[12]51 bridge, while the other two control the sensor chip. +"reg" and "i2c_reg" hold the values of the current register index where the +following reading/writing operations are addressed at through "val" and +"i2c_val". Their use is not intended for end-users, unless you know what you +are doing. Remember that you must be logged in as root before writing to them. + +As an example, suppose we were to want to read the value contained in the +register number 1 of the sensor register table - which is usually the product +identifier - of the camera registered as "/dev/video0": + + [root@localhost #] cd /sys/class/video4linux/video0 + [root@localhost #] echo 1 > i2c_reg + [root@localhost #] cat i2c_val + +Note that if the sensor registers can not be read, "cat" will fail. +To avoid race conditions, all the I/O accesses to the files are serialized. + + +9. Supported devices +==================== +None of the names of the companies as well as their products will be mentioned +here. They have never collaborated with the author, so no advertising. + +From the point of view of a driver, what unambiguously identify a device are +its vendor and product USB identifiers. Below is a list of known identifiers of +devices mounting the ET61X[12]51 PC camera controllers: + +Vendor ID Product ID +--------- ---------- +0x102c 0x6151 +0x102c 0x6251 +0x102c 0x6253 +0x102c 0x6254 +0x102c 0x6255 +0x102c 0x6256 +0x102c 0x6257 +0x102c 0x6258 +0x102c 0x6259 +0x102c 0x625a +0x102c 0x625b +0x102c 0x625c +0x102c 0x625d +0x102c 0x625e +0x102c 0x625f +0x102c 0x6260 +0x102c 0x6261 +0x102c 0x6262 +0x102c 0x6263 +0x102c 0x6264 +0x102c 0x6265 +0x102c 0x6266 +0x102c 0x6267 +0x102c 0x6268 +0x102c 0x6269 + +The following image sensors are supported: + +Model Manufacturer +----- ------------ +TAS5130D1B Taiwan Advanced Sensor Corporation + +All the available control settings of each image sensor are supported through +the V4L2 interface. + + +10. Notes for V4L2 application developers +======================================== +This driver follows the V4L2 API specifications. In particular, it enforces two +rules: + +- exactly one I/O method, either "mmap" or "read", is associated with each +file descriptor. Once it is selected, the application must close and reopen the +device to switch to the other I/O method; + +- although it is not mandatory, previously mapped buffer memory should always +be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's. +The same number of buffers as before will be allocated again to match the size +of the new video frames, so you have to map the buffers again before any I/O +attempts on them. + +Consistently with the hardware limits, this driver also supports image +downscaling with arbitrary scaling factors from 1 and 2 in both directions. +However, the V4L2 API specifications don't correctly define how the scaling +factor can be chosen arbitrarily by the "negotiation" of the "source" and +"target" rectangles. To work around this flaw, we have added the convention +that, during the negotiation, whenever the "VIDIOC_S_CROP" ioctl is issued, the +scaling factor is restored to 1. + +This driver supports two different video formats: the first one is the "8-bit +Sequential Bayer" format and can be used to obtain uncompressed video data +from the device through the current I/O method, while the second one provides +"raw" compressed video data (without frame headers not related to the +compressed data). The current compression quality may vary from 0 to 1 and can +be selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP +V4L2 ioctl's. + + +11. Contact information +======================= +The author may be contacted by e-mail at . + +GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is +'FCE635A4'; the public 1024-bit key should be available at any keyserver; +the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. diff --git a/MAINTAINERS b/MAINTAINERS index a37a2b38a557..42955fe1ffa0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2673,6 +2673,14 @@ M: dbrownell@users.sourceforge.net L: linux-usb-devel@lists.sourceforge.net S: Maintained +USB ET61X[12]51 DRIVER +P: Luca Risolia +M: luca.risolia@studio.unibo.it +L: linux-usb-devel@lists.sourceforge.net +L: video4linux-list@redhat.com +W: http://www.linux-projects.org +S: Maintained + USB HID/HIDBP DRIVERS P: Vojtech Pavlik M: vojtech@suse.cz @@ -2836,6 +2844,7 @@ USB SN9C10x DRIVER P: Luca Risolia M: luca.risolia@studio.unibo.it L: linux-usb-devel@lists.sourceforge.net +L: video4linux-list@redhat.com W: http://www.linux-projects.org S: Maintained @@ -2865,6 +2874,7 @@ USB W996[87]CF DRIVER P: Luca Risolia M: luca.risolia@studio.unibo.it L: linux-usb-devel@lists.sourceforge.net +L: video4linux-list@redhat.com W: http://www.linux-projects.org S: Maintained diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 3639c3f8d357..36e476dd9123 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_USB_XPAD) += input/ obj-$(CONFIG_USB_DABUSB) += media/ obj-$(CONFIG_USB_DSBR) += media/ +obj-$(CONFIG_USB_ET61X251) += media/ obj-$(CONFIG_USB_IBMCAM) += media/ obj-$(CONFIG_USB_KONICAWC) += media/ obj-$(CONFIG_USB_OV511) += media/ diff --git a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig index 21232ee2974c..0d3d2cc5d7be 100644 --- a/drivers/usb/media/Kconfig +++ b/drivers/usb/media/Kconfig @@ -53,6 +53,21 @@ config USB_DSBR To compile this driver as a module, choose M here: the module will be called dsbr100. +config USB_ET61X251 + tristate "USB ET61X[12]51 PC Camera Controller support" + depends on USB && VIDEO_DEV + ---help--- + Say Y here if you want support for cameras based on Etoms ET61X151 + or ET61X251 PC Camera Controllers. + + See for more informations. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" to use this driver. + + To compile this driver as a module, choose M here: the + module will be called et61x251. + config USB_IBMCAM tristate "USB IBM (Xirlink) C-it Camera support" depends on USB && VIDEO_DEV @@ -209,5 +224,3 @@ config USB_PWC To compile this driver as a module, choose M here: the module will be called pwc. - - diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile index d83adffa925f..3957aa1be0f2 100644 --- a/drivers/usb/media/Makefile +++ b/drivers/usb/media/Makefile @@ -3,9 +3,11 @@ # sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o +et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o obj-$(CONFIG_USB_DABUSB) += dabusb.o obj-$(CONFIG_USB_DSBR) += dsbr100.o +obj-$(CONFIG_USB_ET61X251) += et61x251.o obj-$(CONFIG_USB_IBMCAM) += ibmcam.o usbvideo.o ultracam.o obj-$(CONFIG_USB_KONICAWC) += konicawc.o usbvideo.o obj-$(CONFIG_USB_OV511) += ov511.o diff --git a/drivers/usb/media/et61x251.h b/drivers/usb/media/et61x251.h new file mode 100644 index 000000000000..652238f329f3 --- /dev/null +++ b/drivers/usb/media/et61x251.h @@ -0,0 +1,220 @@ +/*************************************************************************** + * V4L2 driver for ET61X[12]51 PC Camera Controllers * + * * + * Copyright (C) 2006 by Luca Risolia * + * * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * + ***************************************************************************/ + +#ifndef _ET61X251_H_ +#define _ET61X251_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "et61x251_sensor.h" + +/*****************************************************************************/ + +#define ET61X251_DEBUG +#define ET61X251_DEBUG_LEVEL 2 +#define ET61X251_MAX_DEVICES 64 +#define ET61X251_PRESERVE_IMGSCALE 0 +#define ET61X251_FORCE_MUNMAP 0 +#define ET61X251_MAX_FRAMES 32 +#define ET61X251_COMPRESSION_QUALITY 0 +#define ET61X251_URBS 2 +#define ET61X251_ISO_PACKETS 7 +#define ET61X251_ALTERNATE_SETTING 13 +#define ET61X251_URB_TIMEOUT msecs_to_jiffies(2 * ET61X251_ISO_PACKETS) +#define ET61X251_CTRL_TIMEOUT 100 + +/*****************************************************************************/ + +static const struct usb_device_id et61x251_id_table[] = { + { USB_DEVICE(0x102c, 0x6151), }, + { USB_DEVICE(0x102c, 0x6251), }, + { USB_DEVICE(0x102c, 0x6253), }, + { USB_DEVICE(0x102c, 0x6254), }, + { USB_DEVICE(0x102c, 0x6255), }, + { USB_DEVICE(0x102c, 0x6256), }, + { USB_DEVICE(0x102c, 0x6257), }, + { USB_DEVICE(0x102c, 0x6258), }, + { USB_DEVICE(0x102c, 0x6259), }, + { USB_DEVICE(0x102c, 0x625a), }, + { USB_DEVICE(0x102c, 0x625b), }, + { USB_DEVICE(0x102c, 0x625c), }, + { USB_DEVICE(0x102c, 0x625d), }, + { USB_DEVICE(0x102c, 0x625e), }, + { USB_DEVICE(0x102c, 0x625f), }, + { USB_DEVICE(0x102c, 0x6260), }, + { USB_DEVICE(0x102c, 0x6261), }, + { USB_DEVICE(0x102c, 0x6262), }, + { USB_DEVICE(0x102c, 0x6263), }, + { USB_DEVICE(0x102c, 0x6264), }, + { USB_DEVICE(0x102c, 0x6265), }, + { USB_DEVICE(0x102c, 0x6266), }, + { USB_DEVICE(0x102c, 0x6267), }, + { USB_DEVICE(0x102c, 0x6268), }, + { USB_DEVICE(0x102c, 0x6269), }, + { } +}; + +ET61X251_SENSOR_TABLE + +/*****************************************************************************/ + +enum et61x251_frame_state { + F_UNUSED, + F_QUEUED, + F_GRABBING, + F_DONE, + F_ERROR, +}; + +struct et61x251_frame_t { + void* bufmem; + struct v4l2_buffer buf; + enum et61x251_frame_state state; + struct list_head frame; + unsigned long vma_use_count; +}; + +enum et61x251_dev_state { + DEV_INITIALIZED = 0x01, + DEV_DISCONNECTED = 0x02, + DEV_MISCONFIGURED = 0x04, +}; + +enum et61x251_io_method { + IO_NONE, + IO_READ, + IO_MMAP, +}; + +enum et61x251_stream_state { + STREAM_OFF, + STREAM_INTERRUPT, + STREAM_ON, +}; + +struct et61x251_sysfs_attr { + u8 reg, i2c_reg; +}; + +struct et61x251_module_param { + u8 force_munmap; +}; + +static DECLARE_MUTEX(et61x251_sysfs_lock); +static DECLARE_RWSEM(et61x251_disconnect); + +struct et61x251_device { + struct video_device* v4ldev; + + struct et61x251_sensor* sensor; + + struct usb_device* usbdev; + struct urb* urb[ET61X251_URBS]; + void* transfer_buffer[ET61X251_URBS]; + u8* control_buffer; + + struct et61x251_frame_t *frame_current, frame[ET61X251_MAX_FRAMES]; + struct list_head inqueue, outqueue; + u32 frame_count, nbuffers, nreadbuffers; + + enum et61x251_io_method io; + enum et61x251_stream_state stream; + + struct v4l2_jpegcompression compression; + + struct et61x251_sysfs_attr sysfs; + struct et61x251_module_param module_param; + + enum et61x251_dev_state state; + u8 users; + + struct semaphore dev_sem, fileop_sem; + spinlock_t queue_lock; + wait_queue_head_t open, wait_frame, wait_stream; +}; + +/*****************************************************************************/ + +void +et61x251_attach_sensor(struct et61x251_device* cam, + struct et61x251_sensor* sensor) +{ + cam->sensor = sensor; + cam->sensor->usbdev = cam->usbdev; +} + +/*****************************************************************************/ + +#undef DBG +#undef KDBG +#ifdef ET61X251_DEBUG +# define DBG(level, fmt, args...) \ +do { \ + if (debug >= (level)) { \ + if ((level) == 1) \ + dev_err(&cam->usbdev->dev, fmt "\n", ## args); \ + else if ((level) == 2) \ + dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ + else if ((level) >= 3) \ + dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ + __FUNCTION__, __LINE__ , ## args); \ + } \ +} while (0) +# define KDBG(level, fmt, args...) \ +do { \ + if (debug >= (level)) { \ + if ((level) == 1 || (level) == 2) \ + pr_info("et61x251: " fmt "\n", ## args); \ + else if ((level) == 3) \ + pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \ + __LINE__ , ## args); \ + } \ +} while (0) +# define V4LDBG(level, name, cmd) \ +do { \ + if (debug >= (level)) \ + v4l_print_ioctl(name, cmd); \ +} while (0) +#else +# define DBG(level, fmt, args...) do {;} while(0) +# define KDBG(level, fmt, args...) do {;} while(0) +# define V4LDBG(level, name, cmd) do {;} while(0) +#endif + +#undef PDBG +#define PDBG(fmt, args...) \ +dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args) + +#undef PDBGG +#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ + +#endif /* _ET61X251_H_ */ diff --git a/drivers/usb/media/et61x251_core.c b/drivers/usb/media/et61x251_core.c new file mode 100644 index 000000000000..2c0171a5ad62 --- /dev/null +++ b/drivers/usb/media/et61x251_core.c @@ -0,0 +1,2605 @@ +/*************************************************************************** + * V4L2 driver for ET61X[12]51 PC Camera Controllers * + * * + * Copyright (C) 2006 by Luca Risolia * + * * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "et61x251.h" + +/*****************************************************************************/ + +#define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \ + "PC Camera Controllers" +#define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia" +#define ET61X251_AUTHOR_EMAIL "" +#define ET61X251_MODULE_LICENSE "GPL" +#define ET61X251_MODULE_VERSION "1:1.01" +#define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 1) + +/*****************************************************************************/ + +MODULE_DEVICE_TABLE(usb, et61x251_id_table); + +MODULE_AUTHOR(ET61X251_MODULE_AUTHOR " " ET61X251_AUTHOR_EMAIL); +MODULE_DESCRIPTION(ET61X251_MODULE_NAME); +MODULE_VERSION(ET61X251_MODULE_VERSION); +MODULE_LICENSE(ET61X251_MODULE_LICENSE); + +static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1}; +module_param_array(video_nr, short, NULL, 0444); +MODULE_PARM_DESC(video_nr, + "\n<-1|n[,...]> Specify V4L2 minor mode number." + "\n -1 = use next available (default)" + "\n n = use minor number n (integer >= 0)" + "\nYou can specify up to " + __MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way." + "\nFor example:" + "\nvideo_nr=-1,2,-1 would assign minor number 2 to" + "\nthe second registered camera and use auto for the first" + "\none and for every other camera." + "\n"); + +static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] = + ET61X251_FORCE_MUNMAP}; +module_param_array(force_munmap, bool, NULL, 0444); +MODULE_PARM_DESC(force_munmap, + "\n<0|1[,...]> Force the application to unmap previously" + "\nmapped buffer memory before calling any VIDIOC_S_CROP or" + "\nVIDIOC_S_FMT ioctl's. Not all the applications support" + "\nthis feature. This parameter is specific for each" + "\ndetected camera." + "\n 0 = do not force memory unmapping" + "\n 1 = force memory unmapping (save memory)" + "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." + "\n"); + +#ifdef ET61X251_DEBUG +static unsigned short debug = ET61X251_DEBUG_LEVEL; +module_param(debug, ushort, 0644); +MODULE_PARM_DESC(debug, + "\n Debugging information level, from 0 to 3:" + "\n0 = none (use carefully)" + "\n1 = critical errors" + "\n2 = significant informations" + "\n3 = more verbose messages" + "\nLevel 3 is useful for testing only, when only " + "one device is used." + "\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"." + "\n"); +#endif + +/*****************************************************************************/ + +static u32 +et61x251_request_buffers(struct et61x251_device* cam, u32 count, + enum et61x251_io_method io) +{ + struct v4l2_pix_format* p = &(cam->sensor->pix_format); + struct v4l2_rect* r = &(cam->sensor->cropcap.bounds); + const size_t imagesize = cam->module_param.force_munmap || + io == IO_READ ? + (p->width * p->height * p->priv) / 8 : + (r->width * r->height * p->priv) / 8; + void* buff = NULL; + u32 i; + + if (count > ET61X251_MAX_FRAMES) + count = ET61X251_MAX_FRAMES; + + cam->nbuffers = count; + while (cam->nbuffers > 0) { + if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize)))) + break; + cam->nbuffers--; + } + + for (i = 0; i < cam->nbuffers; i++) { + cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize); + cam->frame[i].buf.index = i; + cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize); + cam->frame[i].buf.length = imagesize; + cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cam->frame[i].buf.sequence = 0; + cam->frame[i].buf.field = V4L2_FIELD_NONE; + cam->frame[i].buf.memory = V4L2_MEMORY_MMAP; + cam->frame[i].buf.flags = 0; + } + + return cam->nbuffers; +} + + +static void et61x251_release_buffers(struct et61x251_device* cam) +{ + if (cam->nbuffers) { + vfree(cam->frame[0].bufmem); + cam->nbuffers = 0; + } + cam->frame_current = NULL; +} + + +static void et61x251_empty_framequeues(struct et61x251_device* cam) +{ + u32 i; + + INIT_LIST_HEAD(&cam->inqueue); + INIT_LIST_HEAD(&cam->outqueue); + + for (i = 0; i < ET61X251_MAX_FRAMES; i++) { + cam->frame[i].state = F_UNUSED; + cam->frame[i].buf.bytesused = 0; + } +} + + +static void et61x251_requeue_outqueue(struct et61x251_device* cam) +{ + struct et61x251_frame_t *i; + + list_for_each_entry(i, &cam->outqueue, frame) { + i->state = F_QUEUED; + list_add(&i->frame, &cam->inqueue); + } + + INIT_LIST_HEAD(&cam->outqueue); +} + + +static void et61x251_queue_unusedframes(struct et61x251_device* cam) +{ + unsigned long lock_flags; + u32 i; + + for (i = 0; i < cam->nbuffers; i++) + if (cam->frame[i].state == F_UNUSED) { + cam->frame[i].state = F_QUEUED; + spin_lock_irqsave(&cam->queue_lock, lock_flags); + list_add_tail(&cam->frame[i].frame, &cam->inqueue); + spin_unlock_irqrestore(&cam->queue_lock, lock_flags); + } +} + +/*****************************************************************************/ + +int et61x251_write_reg(struct et61x251_device* cam, u8 value, u16 index) +{ + struct usb_device* udev = cam->usbdev; + u8* buff = cam->control_buffer; + int res; + + *buff = value; + + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, index, buff, 1, ET61X251_CTRL_TIMEOUT); + if (res < 0) { + DBG(3, "Failed to write a register (value 0x%02X, index " + "0x%02X, error %d)", value, index, res); + return -1; + } + + return 0; +} + + +int et61x251_read_reg(struct et61x251_device* cam, u16 index) +{ + struct usb_device* udev = cam->usbdev; + u8* buff = cam->control_buffer; + int res; + + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1, + 0, index, buff, 1, ET61X251_CTRL_TIMEOUT); + if (res < 0) + DBG(3, "Failed to read a register (index 0x%02X, error %d)", + index, res); + + return (res >= 0) ? (int)(*buff) : -1; +} + + +static int +et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor) +{ + int i, r; + + for (i = 1; i <= 8; i++) { + if (sensor->interface == ET61X251_I2C_3WIRES) { + r = et61x251_read_reg(cam, 0x8e); + if (!(r & 0x02) && (r >= 0)) + return 0; + } else { + r = et61x251_read_reg(cam, 0x8b); + if (!(r & 0x01) && (r >= 0)) + return 0; + } + if (r < 0) + return -EIO; + udelay(8*8); /* minimum for sensors at 400kHz */ + } + + return -EBUSY; +} + + +int +et61x251_i2c_try_read(struct et61x251_device* cam, + struct et61x251_sensor* sensor, u8 address) +{ + struct usb_device* udev = cam->usbdev; + u8* data = cam->control_buffer; + int err = 0, res; + + data[0] = address; + data[1] = cam->sensor->i2c_slave_id; + data[2] = cam->sensor->rsta | 0x10; + data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02); + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT); + if (res < 0) + err += res; + + err += et61x251_i2c_wait(cam, sensor); + + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1, + 0, 0x80, data, 8, ET61X251_CTRL_TIMEOUT); + if (res < 0) + err += res; + + if (err) + DBG(3, "I2C read failed for %s image sensor", sensor->name); + + PDBGG("I2C read: address 0x%02X, value: 0x%02X", address, data[0]); + + return err ? -1 : (int)data[0]; +} + + +int +et61x251_i2c_try_write(struct et61x251_device* cam, + struct et61x251_sensor* sensor, u8 address, u8 value) +{ + struct usb_device* udev = cam->usbdev; + u8* data = cam->control_buffer; + int err = 0, res; + + data[0] = address; + data[1] = cam->sensor->i2c_slave_id; + data[2] = cam->sensor->rsta | 0x12; + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); + if (res < 0) + err += res; + + data[0] = value; + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT); + if (res < 0) + err += res; + + err += et61x251_i2c_wait(cam, sensor); + + if (err) + DBG(3, "I2C write failed for %s image sensor", sensor->name); + + PDBGG("I2C write: address 0x%02X, value: 0x%02X", address, value); + + return err ? -1 : 0; +} + + +int +et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2, + u8 data3, u8 data4, u8 data5, u8 data6, u8 data7, + u8 data8, u8 address) +{ + struct usb_device* udev = cam->usbdev; + u8* data = cam->control_buffer; + int err = 0, res; + + if (!cam->sensor) + return -1; + + data[0] = data2; + data[1] = data3; + data[2] = data4; + data[3] = data5; + data[4] = data6; + data[5] = data7; + data[6] = data8; + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x81, data, n-1, ET61X251_CTRL_TIMEOUT); + if (res < 0) + err += res; + + data[0] = address; + data[1] = cam->sensor->i2c_slave_id; + data[2] = cam->sensor->rsta | 0x02 | (n << 4); + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); + if (res < 0) + err += res; + + /* Start writing through the serial interface */ + data[0] = data1; + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT); + if (res < 0) + err += res; + + err += et61x251_i2c_wait(cam, cam->sensor); + + if (err) + DBG(3, "I2C raw write failed for %s image sensor", + cam->sensor->name); + + PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, " + "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X," + " data6 = 0x%02X, data7 = 0x%02X, data8 = 0x%02X", n, address, + data1, data2, data3, data4, data5, data6, data7, data8); + + return err ? -1 : 0; + +} + + +int et61x251_i2c_read(struct et61x251_device* cam, u8 address) +{ + if (!cam->sensor) + return -1; + + return et61x251_i2c_try_read(cam, cam->sensor, address); +} + + +int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value) +{ + if (!cam->sensor) + return -1; + + return et61x251_i2c_try_write(cam, cam->sensor, address, value); +} + +/*****************************************************************************/ + +static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs) +{ + struct et61x251_device* cam = urb->context; + struct et61x251_frame_t** f; + size_t imagesize; + u8 i; + int err = 0; + + if (urb->status == -ENOENT) + return; + + f = &cam->frame_current; + + if (cam->stream == STREAM_INTERRUPT) { + cam->stream = STREAM_OFF; + if ((*f)) + (*f)->state = F_QUEUED; + DBG(3, "Stream interrupted"); + wake_up_interruptible(&cam->wait_stream); + } + + if (cam->state & DEV_DISCONNECTED) + return; + + if (cam->state & DEV_MISCONFIGURED) { + wake_up_interruptible(&cam->wait_frame); + return; + } + + if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue)) + goto resubmit_urb; + + if (!(*f)) + (*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t, + frame); + + imagesize = (cam->sensor->pix_format.width * + cam->sensor->pix_format.height * + cam->sensor->pix_format.priv) / 8; + + for (i = 0; i < urb->number_of_packets; i++) { + unsigned int len, status; + void *pos; + u8* b1, * b2, sof; + const u8 VOID_BYTES = 6; + size_t imglen; + + len = urb->iso_frame_desc[i].actual_length; + status = urb->iso_frame_desc[i].status; + pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer; + + if (status) { + DBG(3, "Error in isochronous frame"); + (*f)->state = F_ERROR; + continue; + } + + b1 = pos++; + b2 = pos++; + sof = ((*b1 & 0x3f) == 63); + imglen = ((*b1 & 0xc0) << 2) | *b2; + + PDBGG("Isochrnous frame: length %u, #%u i, image length %zu", + len, i, imglen); + + if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) +start_of_frame: + if (sof) { + (*f)->state = F_GRABBING; + (*f)->buf.bytesused = 0; + do_gettimeofday(&(*f)->buf.timestamp); + pos += 22; + DBG(3, "SOF detected: new video frame"); + } + + if ((*f)->state == F_GRABBING) { + if (sof && (*f)->buf.bytesused) { + if (cam->sensor->pix_format.pixelformat == + V4L2_PIX_FMT_ET61X251) + goto end_of_frame; + else { + DBG(3, "Not expected SOF detected " + "after %lu bytes", + (unsigned long)(*f)->buf.bytesused); + (*f)->state = F_ERROR; + continue; + } + } + + if ((*f)->buf.bytesused + imglen > imagesize) { + DBG(3, "Video frame size exceeded"); + (*f)->state = F_ERROR; + continue; + } + + pos += VOID_BYTES; + + memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, imglen); + (*f)->buf.bytesused += imglen; + + if ((*f)->buf.bytesused == imagesize) { + u32 b; +end_of_frame: + b = (*f)->buf.bytesused; + (*f)->state = F_DONE; + (*f)->buf.sequence= ++cam->frame_count; + spin_lock(&cam->queue_lock); + list_move_tail(&(*f)->frame, &cam->outqueue); + if (!list_empty(&cam->inqueue)) + (*f) = list_entry(cam->inqueue.next, + struct et61x251_frame_t, + frame); + else + (*f) = NULL; + spin_unlock(&cam->queue_lock); + DBG(3, "Video frame captured: : %lu bytes", + (unsigned long)(b)); + + if (!(*f)) + goto resubmit_urb; + + if (sof && + cam->sensor->pix_format.pixelformat == + V4L2_PIX_FMT_ET61X251) + goto start_of_frame; + } + } + } + +resubmit_urb: + urb->dev = cam->usbdev; + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0 && err != -EPERM) { + cam->state |= DEV_MISCONFIGURED; + DBG(1, "usb_submit_urb() failed"); + } + + wake_up_interruptible(&cam->wait_frame); +} + + +static int et61x251_start_transfer(struct et61x251_device* cam) +{ + struct usb_device *udev = cam->usbdev; + struct urb* urb; + const unsigned int wMaxPacketSize[] = {0, 256, 384, 512, 640, 768, 832, + 864, 896, 920, 956, 980, 1000, + 1022}; + const unsigned int psz = wMaxPacketSize[ET61X251_ALTERNATE_SETTING]; + s8 i, j; + int err = 0; + + for (i = 0; i < ET61X251_URBS; i++) { + cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz, + GFP_KERNEL); + if (!cam->transfer_buffer[i]) { + err = -ENOMEM; + DBG(1, "Not enough memory"); + goto free_buffers; + } + } + + for (i = 0; i < ET61X251_URBS; i++) { + urb = usb_alloc_urb(ET61X251_ISO_PACKETS, GFP_KERNEL); + cam->urb[i] = urb; + if (!urb) { + err = -ENOMEM; + DBG(1, "usb_alloc_urb() failed"); + goto free_urbs; + } + urb->dev = udev; + urb->context = cam; + urb->pipe = usb_rcvisocpipe(udev, 1); + urb->transfer_flags = URB_ISO_ASAP; + urb->number_of_packets = ET61X251_ISO_PACKETS; + urb->complete = et61x251_urb_complete; + urb->transfer_buffer = cam->transfer_buffer[i]; + urb->transfer_buffer_length = psz * ET61X251_ISO_PACKETS; + urb->interval = 1; + for (j = 0; j < ET61X251_ISO_PACKETS; j++) { + urb->iso_frame_desc[j].offset = psz * j; + urb->iso_frame_desc[j].length = psz; + } + } + + err = et61x251_write_reg(cam, 0x01, 0x03); + err = et61x251_write_reg(cam, 0x00, 0x03); + err = et61x251_write_reg(cam, 0x08, 0x03); + if (err) { + err = -EIO; + DBG(1, "I/O hardware error"); + goto free_urbs; + } + + err = usb_set_interface(udev, 0, ET61X251_ALTERNATE_SETTING); + if (err) { + DBG(1, "usb_set_interface() failed"); + goto free_urbs; + } + + cam->frame_current = NULL; + + for (i = 0; i < ET61X251_URBS; i++) { + err = usb_submit_urb(cam->urb[i], GFP_KERNEL); + if (err) { + for (j = i-1; j >= 0; j--) + usb_kill_urb(cam->urb[j]); + DBG(1, "usb_submit_urb() failed, error %d", err); + goto free_urbs; + } + } + + return 0; + +free_urbs: + for (i = 0; (i < ET61X251_URBS) && cam->urb[i]; i++) + usb_free_urb(cam->urb[i]); + +free_buffers: + for (i = 0; (i < ET61X251_URBS) && cam->transfer_buffer[i]; i++) + kfree(cam->transfer_buffer[i]); + + return err; +} + + +static int et61x251_stop_transfer(struct et61x251_device* cam) +{ + struct usb_device *udev = cam->usbdev; + s8 i; + int err = 0; + + if (cam->state & DEV_DISCONNECTED) + return 0; + + for (i = ET61X251_URBS-1; i >= 0; i--) { + usb_kill_urb(cam->urb[i]); + usb_free_urb(cam->urb[i]); + kfree(cam->transfer_buffer[i]); + } + + err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */ + if (err) + DBG(3, "usb_set_interface() failed"); + + return err; +} + + +static int et61x251_stream_interrupt(struct et61x251_device* cam) +{ + int err = 0; + + cam->stream = STREAM_INTERRUPT; + err = wait_event_timeout(cam->wait_stream, + (cam->stream == STREAM_OFF) || + (cam->state & DEV_DISCONNECTED), + ET61X251_URB_TIMEOUT); + if (cam->state & DEV_DISCONNECTED) + return -ENODEV; + else if (err) { + cam->state |= DEV_MISCONFIGURED; + DBG(1, "URB timeout reached. The camera is misconfigured. To " + "use it, close and open /dev/video%d again.", + cam->v4ldev->minor); + return err; + } + + return 0; +} + +/*****************************************************************************/ + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count) +{ + char str[5]; + char* endp; + unsigned long val; + + if (len < 4) { + strncpy(str, buff, len); + str[len+1] = '\0'; + } else { + strncpy(str, buff, 4); + str[4] = '\0'; + } + + val = simple_strtoul(str, &endp, 0); + + *count = 0; + if (val <= 0xff) + *count = (ssize_t)(endp - str); + if ((*count) && (len == *count+1) && (buff[*count] == '\n')) + *count += 1; + + return (u8)val; +} + +/* + NOTE 1: being inside one of the following methods implies that the v4l + device exists for sure (see kobjects and reference counters) + NOTE 2: buffers are PAGE_SIZE long +*/ + +static ssize_t et61x251_show_reg(struct class_device* cd, char* buf) +{ + struct et61x251_device* cam; + ssize_t count; + + if (down_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&et61x251_sysfs_lock); + return -ENODEV; + } + + count = sprintf(buf, "%u\n", cam->sysfs.reg); + + up(&et61x251_sysfs_lock); + + return count; +} + + +static ssize_t +et61x251_store_reg(struct class_device* cd, const char* buf, size_t len) +{ + struct et61x251_device* cam; + u8 index; + ssize_t count; + + if (down_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&et61x251_sysfs_lock); + return -ENODEV; + } + + index = et61x251_strtou8(buf, len, &count); + if (index > 0x8e || !count) { + up(&et61x251_sysfs_lock); + return -EINVAL; + } + + cam->sysfs.reg = index; + + DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg); + DBG(3, "Written bytes: %zd", count); + + up(&et61x251_sysfs_lock); + + return count; +} + + +static ssize_t et61x251_show_val(struct class_device* cd, char* buf) +{ + struct et61x251_device* cam; + ssize_t count; + int val; + + if (down_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&et61x251_sysfs_lock); + return -ENODEV; + } + + if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) { + up(&et61x251_sysfs_lock); + return -EIO; + } + + count = sprintf(buf, "%d\n", val); + + DBG(3, "Read bytes: %zd", count); + + up(&et61x251_sysfs_lock); + + return count; +} + + +static ssize_t +et61x251_store_val(struct class_device* cd, const char* buf, size_t len) +{ + struct et61x251_device* cam; + u8 value; + ssize_t count; + int err; + + if (down_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&et61x251_sysfs_lock); + return -ENODEV; + } + + value = et61x251_strtou8(buf, len, &count); + if (!count) { + up(&et61x251_sysfs_lock); + return -EINVAL; + } + + err = et61x251_write_reg(cam, value, cam->sysfs.reg); + if (err) { + up(&et61x251_sysfs_lock); + return -EIO; + } + + DBG(2, "Written ET61X[12]51 reg. 0x%02X, val. 0x%02X", + cam->sysfs.reg, value); + DBG(3, "Written bytes: %zd", count); + + up(&et61x251_sysfs_lock); + + return count; +} + + +static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf) +{ + struct et61x251_device* cam; + ssize_t count; + + if (down_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&et61x251_sysfs_lock); + return -ENODEV; + } + + count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg); + + DBG(3, "Read bytes: %zd", count); + + up(&et61x251_sysfs_lock); + + return count; +} + + +static ssize_t +et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len) +{ + struct et61x251_device* cam; + u8 index; + ssize_t count; + + if (down_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&et61x251_sysfs_lock); + return -ENODEV; + } + + index = et61x251_strtou8(buf, len, &count); + if (!count) { + up(&et61x251_sysfs_lock); + return -EINVAL; + } + + cam->sysfs.i2c_reg = index; + + DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg); + DBG(3, "Written bytes: %zd", count); + + up(&et61x251_sysfs_lock); + + return count; +} + + +static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf) +{ + struct et61x251_device* cam; + ssize_t count; + int val; + + if (down_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&et61x251_sysfs_lock); + return -ENODEV; + } + + if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) { + up(&et61x251_sysfs_lock); + return -ENOSYS; + } + + if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) { + up(&et61x251_sysfs_lock); + return -EIO; + } + + count = sprintf(buf, "%d\n", val); + + DBG(3, "Read bytes: %zd", count); + + up(&et61x251_sysfs_lock); + + return count; +} + + +static ssize_t +et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len) +{ + struct et61x251_device* cam; + u8 value; + ssize_t count; + int err; + + if (down_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&et61x251_sysfs_lock); + return -ENODEV; + } + + if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) { + up(&et61x251_sysfs_lock); + return -ENOSYS; + } + + value = et61x251_strtou8(buf, len, &count); + if (!count) { + up(&et61x251_sysfs_lock); + return -EINVAL; + } + + err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value); + if (err) { + up(&et61x251_sysfs_lock); + return -EIO; + } + + DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X", + cam->sysfs.i2c_reg, value); + DBG(3, "Written bytes: %zd", count); + + up(&et61x251_sysfs_lock); + + return count; +} + + +static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, + et61x251_show_reg, et61x251_store_reg); +static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR, + et61x251_show_val, et61x251_store_val); +static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR, + et61x251_show_i2c_reg, et61x251_store_i2c_reg); +static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, + et61x251_show_i2c_val, et61x251_store_i2c_val); + + +static void et61x251_create_sysfs(struct et61x251_device* cam) +{ + struct video_device *v4ldev = cam->v4ldev; + + video_device_create_file(v4ldev, &class_device_attr_reg); + video_device_create_file(v4ldev, &class_device_attr_val); + if (cam->sensor && cam->sensor->sysfs_ops) { + video_device_create_file(v4ldev, &class_device_attr_i2c_reg); + video_device_create_file(v4ldev, &class_device_attr_i2c_val); + } +} +#endif /* CONFIG_VIDEO_ADV_DEBUG */ + +/*****************************************************************************/ + +static int +et61x251_set_pix_format(struct et61x251_device* cam, + struct v4l2_pix_format* pix) +{ + int r, err = 0; + + if ((r = et61x251_read_reg(cam, 0x12)) < 0) + err += r; + if (pix->pixelformat == V4L2_PIX_FMT_ET61X251) + err += et61x251_write_reg(cam, r & 0xfd, 0x12); + else + err += et61x251_write_reg(cam, r | 0x02, 0x12); + + return err ? -EIO : 0; +} + + +static int +et61x251_set_compression(struct et61x251_device* cam, + struct v4l2_jpegcompression* compression) +{ + int r, err = 0; + + if ((r = et61x251_read_reg(cam, 0x12)) < 0) + err += r; + if (compression->quality == 0) + err += et61x251_write_reg(cam, r & 0xfb, 0x12); + else + err += et61x251_write_reg(cam, r | 0x04, 0x12); + + return err ? -EIO : 0; +} + + +static int et61x251_set_scale(struct et61x251_device* cam, u8 scale) +{ + int r = 0, err = 0; + + r = et61x251_read_reg(cam, 0x12); + if (r < 0) + err += r; + + if (scale == 1) + err += et61x251_write_reg(cam, r & ~0x01, 0x12); + else if (scale == 2) + err += et61x251_write_reg(cam, r | 0x01, 0x12); + + if (err) + return -EIO; + + PDBGG("Scaling factor: %u", scale); + + return 0; +} + + +static int +et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect) +{ + struct et61x251_sensor* s = cam->sensor; + u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left + + s->active_pixel.left), + fmw_sy = (u16)(rect->top - s->cropcap.bounds.top + + s->active_pixel.top), + fmw_length = (u16)(rect->width), + fmw_height = (u16)(rect->height); + int err = 0; + + err += et61x251_write_reg(cam, fmw_sx & 0xff, 0x69); + err += et61x251_write_reg(cam, fmw_sy & 0xff, 0x6a); + err += et61x251_write_reg(cam, fmw_length & 0xff, 0x6b); + err += et61x251_write_reg(cam, fmw_height & 0xff, 0x6c); + err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6) + | ((fmw_length & 0x300) >> 4) + | ((fmw_height & 0x300) >> 2), 0x6d); + if (err) + return -EIO; + + PDBGG("fmw_sx, fmw_sy, fmw_length, fmw_height: %u %u %u %u", + fmw_sx, fmw_sy, fmw_length, fmw_height); + + return 0; +} + + +static int et61x251_init(struct et61x251_device* cam) +{ + struct et61x251_sensor* s = cam->sensor; + struct v4l2_control ctrl; + struct v4l2_queryctrl *qctrl; + struct v4l2_rect* rect; + u8 i = 0; + int err = 0; + + if (!(cam->state & DEV_INITIALIZED)) { + init_waitqueue_head(&cam->open); + qctrl = s->qctrl; + rect = &(s->cropcap.defrect); + cam->compression.quality = ET61X251_COMPRESSION_QUALITY; + } else { /* use current values */ + qctrl = s->_qctrl; + rect = &(s->_rect); + } + + err += et61x251_set_scale(cam, rect->width / s->pix_format.width); + err += et61x251_set_crop(cam, rect); + if (err) + return err; + + if (s->init) { + err = s->init(cam); + if (err) { + DBG(3, "Sensor initialization failed"); + return err; + } + } + + err += et61x251_set_compression(cam, &cam->compression); + err += et61x251_set_pix_format(cam, &s->pix_format); + if (s->set_pix_format) + err += s->set_pix_format(cam, &s->pix_format); + if (err) + return err; + + if (s->pix_format.pixelformat == V4L2_PIX_FMT_ET61X251) + DBG(3, "Compressed video format is active, quality %d", + cam->compression.quality); + else + DBG(3, "Uncompressed video format is active"); + + if (s->set_crop) + if ((err = s->set_crop(cam, rect))) { + DBG(3, "set_crop() failed"); + return err; + } + + if (s->set_ctrl) { + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (s->qctrl[i].id != 0 && + !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { + ctrl.id = s->qctrl[i].id; + ctrl.value = qctrl[i].default_value; + err = s->set_ctrl(cam, &ctrl); + if (err) { + DBG(3, "Set %s control failed", + s->qctrl[i].name); + return err; + } + DBG(3, "Image sensor supports '%s' control", + s->qctrl[i].name); + } + } + + if (!(cam->state & DEV_INITIALIZED)) { + init_MUTEX(&cam->fileop_sem); + spin_lock_init(&cam->queue_lock); + init_waitqueue_head(&cam->wait_frame); + init_waitqueue_head(&cam->wait_stream); + cam->nreadbuffers = 2; + memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); + memcpy(&(s->_rect), &(s->cropcap.defrect), + sizeof(struct v4l2_rect)); + cam->state |= DEV_INITIALIZED; + } + + DBG(2, "Initialization succeeded"); + return 0; +} + + +static void et61x251_release_resources(struct et61x251_device* cam) +{ + down(&et61x251_sysfs_lock); + + DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); + video_set_drvdata(cam->v4ldev, NULL); + video_unregister_device(cam->v4ldev); + + up(&et61x251_sysfs_lock); + + kfree(cam->control_buffer); +} + +/*****************************************************************************/ + +static int et61x251_open(struct inode* inode, struct file* filp) +{ + struct et61x251_device* cam; + int err = 0; + + /* + This is the only safe way to prevent race conditions with + disconnect + */ + if (!down_read_trylock(&et61x251_disconnect)) + return -ERESTARTSYS; + + cam = video_get_drvdata(video_devdata(filp)); + + if (down_interruptible(&cam->dev_sem)) { + up_read(&et61x251_disconnect); + return -ERESTARTSYS; + } + + if (cam->users) { + DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); + if ((filp->f_flags & O_NONBLOCK) || + (filp->f_flags & O_NDELAY)) { + err = -EWOULDBLOCK; + goto out; + } + up(&cam->dev_sem); + err = wait_event_interruptible_exclusive(cam->open, + cam->state & DEV_DISCONNECTED + || !cam->users); + if (err) { + up_read(&et61x251_disconnect); + return err; + } + if (cam->state & DEV_DISCONNECTED) { + up_read(&et61x251_disconnect); + return -ENODEV; + } + down(&cam->dev_sem); + } + + + if (cam->state & DEV_MISCONFIGURED) { + err = et61x251_init(cam); + if (err) { + DBG(1, "Initialization failed again. " + "I will retry on next open()."); + goto out; + } + cam->state &= ~DEV_MISCONFIGURED; + } + + if ((err = et61x251_start_transfer(cam))) + goto out; + + filp->private_data = cam; + cam->users++; + cam->io = IO_NONE; + cam->stream = STREAM_OFF; + cam->nbuffers = 0; + cam->frame_count = 0; + et61x251_empty_framequeues(cam); + + DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); + +out: + up(&cam->dev_sem); + up_read(&et61x251_disconnect); + return err; +} + + +static int et61x251_release(struct inode* inode, struct file* filp) +{ + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + + down(&cam->dev_sem); /* prevent disconnect() to be called */ + + et61x251_stop_transfer(cam); + + et61x251_release_buffers(cam); + + if (cam->state & DEV_DISCONNECTED) { + et61x251_release_resources(cam); + up(&cam->dev_sem); + kfree(cam); + return 0; + } + + cam->users--; + wake_up_interruptible_nr(&cam->open, 1); + + DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); + + up(&cam->dev_sem); + + return 0; +} + + +static ssize_t +et61x251_read(struct file* filp, char __user * buf, + size_t count, loff_t* f_pos) +{ + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + struct et61x251_frame_t* f, * i; + unsigned long lock_flags; + int err = 0; + + if (down_interruptible(&cam->fileop_sem)) + return -ERESTARTSYS; + + if (cam->state & DEV_DISCONNECTED) { + DBG(1, "Device not present"); + up(&cam->fileop_sem); + return -ENODEV; + } + + if (cam->state & DEV_MISCONFIGURED) { + DBG(1, "The camera is misconfigured. Close and open it " + "again."); + up(&cam->fileop_sem); + return -EIO; + } + + if (cam->io == IO_MMAP) { + DBG(3, "Close and open the device again to choose the read " + "method"); + up(&cam->fileop_sem); + return -EINVAL; + } + + if (cam->io == IO_NONE) { + if (!et61x251_request_buffers(cam, cam->nreadbuffers, + IO_READ)) { + DBG(1, "read() failed, not enough memory"); + up(&cam->fileop_sem); + return -ENOMEM; + } + cam->io = IO_READ; + cam->stream = STREAM_ON; + } + + if (list_empty(&cam->inqueue)) { + if (!list_empty(&cam->outqueue)) + et61x251_empty_framequeues(cam); + et61x251_queue_unusedframes(cam); + } + + if (!count) { + up(&cam->fileop_sem); + return 0; + } + + if (list_empty(&cam->outqueue)) { + if (filp->f_flags & O_NONBLOCK) { + up(&cam->fileop_sem); + return -EAGAIN; + } + err = wait_event_interruptible + ( cam->wait_frame, + (!list_empty(&cam->outqueue)) || + (cam->state & DEV_DISCONNECTED) || + (cam->state & DEV_MISCONFIGURED) ); + if (err) { + up(&cam->fileop_sem); + return err; + } + if (cam->state & DEV_DISCONNECTED) { + up(&cam->fileop_sem); + return -ENODEV; + } + if (cam->state & DEV_MISCONFIGURED) { + up(&cam->fileop_sem); + return -EIO; + } + } + + f = list_entry(cam->outqueue.prev, struct et61x251_frame_t, frame); + + if (count > f->buf.bytesused) + count = f->buf.bytesused; + + if (copy_to_user(buf, f->bufmem, count)) { + err = -EFAULT; + goto exit; + } + *f_pos += count; + +exit: + spin_lock_irqsave(&cam->queue_lock, lock_flags); + list_for_each_entry(i, &cam->outqueue, frame) + i->state = F_UNUSED; + INIT_LIST_HEAD(&cam->outqueue); + spin_unlock_irqrestore(&cam->queue_lock, lock_flags); + + et61x251_queue_unusedframes(cam); + + PDBGG("Frame #%lu, bytes read: %zu", + (unsigned long)f->buf.index, count); + + up(&cam->fileop_sem); + + return err ? err : count; +} + + +static unsigned int et61x251_poll(struct file *filp, poll_table *wait) +{ + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + struct et61x251_frame_t* f; + unsigned long lock_flags; + unsigned int mask = 0; + + if (down_interruptible(&cam->fileop_sem)) + return POLLERR; + + if (cam->state & DEV_DISCONNECTED) { + DBG(1, "Device not present"); + goto error; + } + + if (cam->state & DEV_MISCONFIGURED) { + DBG(1, "The camera is misconfigured. Close and open it " + "again."); + goto error; + } + + if (cam->io == IO_NONE) { + if (!et61x251_request_buffers(cam, cam->nreadbuffers, + IO_READ)) { + DBG(1, "poll() failed, not enough memory"); + goto error; + } + cam->io = IO_READ; + cam->stream = STREAM_ON; + } + + if (cam->io == IO_READ) { + spin_lock_irqsave(&cam->queue_lock, lock_flags); + list_for_each_entry(f, &cam->outqueue, frame) + f->state = F_UNUSED; + INIT_LIST_HEAD(&cam->outqueue); + spin_unlock_irqrestore(&cam->queue_lock, lock_flags); + et61x251_queue_unusedframes(cam); + } + + poll_wait(filp, &cam->wait_frame, wait); + + if (!list_empty(&cam->outqueue)) + mask |= POLLIN | POLLRDNORM; + + up(&cam->fileop_sem); + + return mask; + +error: + up(&cam->fileop_sem); + return POLLERR; +} + + +static void et61x251_vm_open(struct vm_area_struct* vma) +{ + struct et61x251_frame_t* f = vma->vm_private_data; + f->vma_use_count++; +} + + +static void et61x251_vm_close(struct vm_area_struct* vma) +{ + /* NOTE: buffers are not freed here */ + struct et61x251_frame_t* f = vma->vm_private_data; + f->vma_use_count--; +} + + +static struct vm_operations_struct et61x251_vm_ops = { + .open = et61x251_vm_open, + .close = et61x251_vm_close, +}; + + +static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) +{ + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + unsigned long size = vma->vm_end - vma->vm_start, + start = vma->vm_start; + void *pos; + u32 i; + + if (down_interruptible(&cam->fileop_sem)) + return -ERESTARTSYS; + + if (cam->state & DEV_DISCONNECTED) { + DBG(1, "Device not present"); + up(&cam->fileop_sem); + return -ENODEV; + } + + if (cam->state & DEV_MISCONFIGURED) { + DBG(1, "The camera is misconfigured. Close and open it " + "again."); + up(&cam->fileop_sem); + return -EIO; + } + + if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || + size != PAGE_ALIGN(cam->frame[0].buf.length)) { + up(&cam->fileop_sem); + return -EINVAL; + } + + for (i = 0; i < cam->nbuffers; i++) { + if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff) + break; + } + if (i == cam->nbuffers) { + up(&cam->fileop_sem); + return -EINVAL; + } + + vma->vm_flags |= VM_IO; + vma->vm_flags |= VM_RESERVED; + + pos = cam->frame[i].bufmem; + while (size > 0) { /* size is page-aligned */ + if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { + up(&cam->fileop_sem); + return -EAGAIN; + } + start += PAGE_SIZE; + pos += PAGE_SIZE; + size -= PAGE_SIZE; + } + + vma->vm_ops = &et61x251_vm_ops; + vma->vm_private_data = &cam->frame[i]; + + et61x251_vm_open(vma); + + up(&cam->fileop_sem); + + return 0; +} + +/*****************************************************************************/ + +static int +et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_capability cap = { + .driver = "et61x251", + .version = ET61X251_MODULE_VERSION_CODE, + .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING, + }; + + strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); + if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) + strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, + sizeof(cap.bus_info)); + + if (copy_to_user(arg, &cap, sizeof(cap))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_input i; + + if (copy_from_user(&i, arg, sizeof(i))) + return -EFAULT; + + if (i.index) + return -EINVAL; + + memset(&i, 0, sizeof(i)); + strcpy(i.name, "Camera"); + + if (copy_to_user(arg, &i, sizeof(i))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_gs_input(struct et61x251_device* cam, void __user * arg) +{ + int index; + + if (copy_from_user(&index, arg, sizeof(index))) + return -EFAULT; + + if (index != 0) + return -EINVAL; + + return 0; +} + + +static int +et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg) +{ + struct et61x251_sensor* s = cam->sensor; + struct v4l2_queryctrl qc; + u8 i; + + if (copy_from_user(&qc, arg, sizeof(qc))) + return -EFAULT; + + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (qc.id && qc.id == s->qctrl[i].id) { + memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); + if (copy_to_user(arg, &qc, sizeof(qc))) + return -EFAULT; + return 0; + } + + return -EINVAL; +} + + +static int +et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg) +{ + struct et61x251_sensor* s = cam->sensor; + struct v4l2_control ctrl; + int err = 0; + u8 i; + + if (!s->get_ctrl && !s->set_ctrl) + return -EINVAL; + + if (copy_from_user(&ctrl, arg, sizeof(ctrl))) + return -EFAULT; + + if (!s->get_ctrl) { + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (ctrl.id == s->qctrl[i].id) { + ctrl.value = s->_qctrl[i].default_value; + goto exit; + } + return -EINVAL; + } else + err = s->get_ctrl(cam, &ctrl); + +exit: + if (copy_to_user(arg, &ctrl, sizeof(ctrl))) + return -EFAULT; + + return err; +} + + +static int +et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg) +{ + struct et61x251_sensor* s = cam->sensor; + struct v4l2_control ctrl; + u8 i; + int err = 0; + + if (!s->set_ctrl) + return -EINVAL; + + if (copy_from_user(&ctrl, arg, sizeof(ctrl))) + return -EFAULT; + + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (ctrl.id == s->qctrl[i].id) { + if (ctrl.value < s->qctrl[i].minimum || + ctrl.value > s->qctrl[i].maximum) + return -ERANGE; + ctrl.value -= ctrl.value % s->qctrl[i].step; + break; + } + + if ((err = s->set_ctrl(cam, &ctrl))) + return err; + + s->_qctrl[i].default_value = ctrl.value; + + return 0; +} + + +static int +et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_cropcap* cc = &(cam->sensor->cropcap); + + cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cc->pixelaspect.numerator = 1; + cc->pixelaspect.denominator = 1; + + if (copy_to_user(arg, cc, sizeof(*cc))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg) +{ + struct et61x251_sensor* s = cam->sensor; + struct v4l2_crop crop = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + }; + + memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect)); + + if (copy_to_user(arg, &crop, sizeof(crop))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) +{ + struct et61x251_sensor* s = cam->sensor; + struct v4l2_crop crop; + struct v4l2_rect* rect; + struct v4l2_rect* bounds = &(s->cropcap.bounds); + struct v4l2_pix_format* pix_format = &(s->pix_format); + u8 scale; + const enum et61x251_stream_state stream = cam->stream; + const u32 nbuffers = cam->nbuffers; + u32 i; + int err = 0; + + if (copy_from_user(&crop, arg, sizeof(crop))) + return -EFAULT; + + rect = &(crop.c); + + if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (cam->module_param.force_munmap) + for (i = 0; i < cam->nbuffers; i++) + if (cam->frame[i].vma_use_count) { + DBG(3, "VIDIOC_S_CROP failed. " + "Unmap the buffers first."); + return -EINVAL; + } + + /* Preserve R,G or B origin */ + rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L; + rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L; + + if (rect->width < 4) + rect->width = 4; + if (rect->height < 4) + rect->height = 4; + if (rect->width > bounds->width) + rect->width = bounds->width; + if (rect->height > bounds->height) + rect->height = bounds->height; + if (rect->left < bounds->left) + rect->left = bounds->left; + if (rect->top < bounds->top) + rect->top = bounds->top; + if (rect->left + rect->width > bounds->left + bounds->width) + rect->left = bounds->left+bounds->width - rect->width; + if (rect->top + rect->height > bounds->top + bounds->height) + rect->top = bounds->top+bounds->height - rect->height; + + rect->width &= ~3L; + rect->height &= ~3L; + + if (ET61X251_PRESERVE_IMGSCALE) { + /* Calculate the actual scaling factor */ + u32 a, b; + a = rect->width * rect->height; + b = pix_format->width * pix_format->height; + scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1; + } else + scale = 1; + + if (cam->stream == STREAM_ON) + if ((err = et61x251_stream_interrupt(cam))) + return err; + + if (copy_to_user(arg, &crop, sizeof(crop))) { + cam->stream = stream; + return -EFAULT; + } + + if (cam->module_param.force_munmap || cam->io == IO_READ) + et61x251_release_buffers(cam); + + err = et61x251_set_crop(cam, rect); + if (s->set_crop) + err += s->set_crop(cam, rect); + err += et61x251_set_scale(cam, scale); + + if (err) { /* atomic, no rollback in ioctl() */ + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " + "use the camera, close and open /dev/video%d again.", + cam->v4ldev->minor); + return -EIO; + } + + s->pix_format.width = rect->width/scale; + s->pix_format.height = rect->height/scale; + memcpy(&(s->_rect), rect, sizeof(*rect)); + + if ((cam->module_param.force_munmap || cam->io == IO_READ) && + nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " + "use the camera, close and open /dev/video%d again.", + cam->v4ldev->minor); + return -ENOMEM; + } + + if (cam->io == IO_READ) + et61x251_empty_framequeues(cam); + else if (cam->module_param.force_munmap) + et61x251_requeue_outqueue(cam); + + cam->stream = stream; + + return 0; +} + + +static int +et61x251_vidioc_enum_fmt(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_fmtdesc fmtd; + + if (copy_from_user(&fmtd, arg, sizeof(fmtd))) + return -EFAULT; + + if (fmtd.index == 0) { + strcpy(fmtd.description, "bayer rgb"); + fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8; + } else if (fmtd.index == 1) { + strcpy(fmtd.description, "compressed"); + fmtd.pixelformat = V4L2_PIX_FMT_ET61X251; + fmtd.flags = V4L2_FMT_FLAG_COMPRESSED; + } else + return -EINVAL; + + fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + memset(&fmtd.reserved, 0, sizeof(fmtd.reserved)); + + if (copy_to_user(arg, &fmtd, sizeof(fmtd))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_format format; + struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); + + if (copy_from_user(&format, arg, sizeof(format))) + return -EFAULT; + + if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251) + ? 0 : (pfmt->width * pfmt->priv) / 8; + pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); + pfmt->field = V4L2_FIELD_NONE; + memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt)); + + if (copy_to_user(arg, &format, sizeof(format))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, + void __user * arg) +{ + struct et61x251_sensor* s = cam->sensor; + struct v4l2_format format; + struct v4l2_pix_format* pix; + struct v4l2_pix_format* pfmt = &(s->pix_format); + struct v4l2_rect* bounds = &(s->cropcap.bounds); + struct v4l2_rect rect; + u8 scale; + const enum et61x251_stream_state stream = cam->stream; + const u32 nbuffers = cam->nbuffers; + u32 i; + int err = 0; + + if (copy_from_user(&format, arg, sizeof(format))) + return -EFAULT; + + pix = &(format.fmt.pix); + + if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memcpy(&rect, &(s->_rect), sizeof(rect)); + + { /* calculate the actual scaling factor */ + u32 a, b; + a = rect.width * rect.height; + b = pix->width * pix->height; + scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1; + } + + rect.width = scale * pix->width; + rect.height = scale * pix->height; + + if (rect.width < 4) + rect.width = 4; + if (rect.height < 4) + rect.height = 4; + if (rect.width > bounds->left + bounds->width - rect.left) + rect.width = bounds->left + bounds->width - rect.left; + if (rect.height > bounds->top + bounds->height - rect.top) + rect.height = bounds->top + bounds->height - rect.top; + + rect.width &= ~3L; + rect.height &= ~3L; + + { /* adjust the scaling factor */ + u32 a, b; + a = rect.width * rect.height; + b = pix->width * pix->height; + scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1; + } + + pix->width = rect.width / scale; + pix->height = rect.height / scale; + + if (pix->pixelformat != V4L2_PIX_FMT_ET61X251 && + pix->pixelformat != V4L2_PIX_FMT_SBGGR8) + pix->pixelformat = pfmt->pixelformat; + pix->priv = pfmt->priv; /* bpp */ + pix->colorspace = pfmt->colorspace; + pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251) + ? 0 : (pix->width * pix->priv) / 8; + pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8); + pix->field = V4L2_FIELD_NONE; + + if (cmd == VIDIOC_TRY_FMT) { + if (copy_to_user(arg, &format, sizeof(format))) + return -EFAULT; + return 0; + } + + if (cam->module_param.force_munmap) + for (i = 0; i < cam->nbuffers; i++) + if (cam->frame[i].vma_use_count) { + DBG(3, "VIDIOC_S_FMT failed. " + "Unmap the buffers first."); + return -EINVAL; + } + + if (cam->stream == STREAM_ON) + if ((err = et61x251_stream_interrupt(cam))) + return err; + + if (copy_to_user(arg, &format, sizeof(format))) { + cam->stream = stream; + return -EFAULT; + } + + if (cam->module_param.force_munmap || cam->io == IO_READ) + et61x251_release_buffers(cam); + + err += et61x251_set_pix_format(cam, pix); + err += et61x251_set_crop(cam, &rect); + if (s->set_pix_format) + err += s->set_pix_format(cam, pix); + if (s->set_crop) + err += s->set_crop(cam, &rect); + err += et61x251_set_scale(cam, scale); + + if (err) { /* atomic, no rollback in ioctl() */ + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " + "use the camera, close and open /dev/video%d again.", + cam->v4ldev->minor); + return -EIO; + } + + memcpy(pfmt, pix, sizeof(*pix)); + memcpy(&(s->_rect), &rect, sizeof(rect)); + + if ((cam->module_param.force_munmap || cam->io == IO_READ) && + nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " + "use the camera, close and open /dev/video%d again.", + cam->v4ldev->minor); + return -ENOMEM; + } + + if (cam->io == IO_READ) + et61x251_empty_framequeues(cam); + else if (cam->module_param.force_munmap) + et61x251_requeue_outqueue(cam); + + cam->stream = stream; + + return 0; +} + + +static int +et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg) +{ + if (copy_to_user(arg, &cam->compression, + sizeof(cam->compression))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_jpegcompression jc; + const enum et61x251_stream_state stream = cam->stream; + int err = 0; + + if (copy_from_user(&jc, arg, sizeof(jc))) + return -EFAULT; + + if (jc.quality != 0 && jc.quality != 1) + return -EINVAL; + + if (cam->stream == STREAM_ON) + if ((err = et61x251_stream_interrupt(cam))) + return err; + + err += et61x251_set_compression(cam, &jc); + if (err) { /* atomic, no rollback in ioctl() */ + cam->state |= DEV_MISCONFIGURED; + DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " + "problems. To use the camera, close and open " + "/dev/video%d again.", cam->v4ldev->minor); + return -EIO; + } + + cam->compression.quality = jc.quality; + + cam->stream = stream; + + return 0; +} + + +static int +et61x251_vidioc_reqbufs(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_requestbuffers rb; + u32 i; + int err; + + if (copy_from_user(&rb, arg, sizeof(rb))) + return -EFAULT; + + if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + rb.memory != V4L2_MEMORY_MMAP) + return -EINVAL; + + if (cam->io == IO_READ) { + DBG(3, "Close and open the device again to choose the mmap " + "I/O method"); + return -EINVAL; + } + + for (i = 0; i < cam->nbuffers; i++) + if (cam->frame[i].vma_use_count) { + DBG(3, "VIDIOC_REQBUFS failed. " + "Previous buffers are still mapped."); + return -EINVAL; + } + + if (cam->stream == STREAM_ON) + if ((err = et61x251_stream_interrupt(cam))) + return err; + + et61x251_empty_framequeues(cam); + + et61x251_release_buffers(cam); + if (rb.count) + rb.count = et61x251_request_buffers(cam, rb.count, IO_MMAP); + + if (copy_to_user(arg, &rb, sizeof(rb))) { + et61x251_release_buffers(cam); + cam->io = IO_NONE; + return -EFAULT; + } + + cam->io = rb.count ? IO_MMAP : IO_NONE; + + return 0; +} + + +static int +et61x251_vidioc_querybuf(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_buffer b; + + if (copy_from_user(&b, arg, sizeof(b))) + return -EFAULT; + + if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + b.index >= cam->nbuffers || cam->io != IO_MMAP) + return -EINVAL; + + memcpy(&b, &cam->frame[b.index].buf, sizeof(b)); + + if (cam->frame[b.index].vma_use_count) + b.flags |= V4L2_BUF_FLAG_MAPPED; + + if (cam->frame[b.index].state == F_DONE) + b.flags |= V4L2_BUF_FLAG_DONE; + else if (cam->frame[b.index].state != F_UNUSED) + b.flags |= V4L2_BUF_FLAG_QUEUED; + + if (copy_to_user(arg, &b, sizeof(b))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_qbuf(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_buffer b; + unsigned long lock_flags; + + if (copy_from_user(&b, arg, sizeof(b))) + return -EFAULT; + + if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + b.index >= cam->nbuffers || cam->io != IO_MMAP) + return -EINVAL; + + if (cam->frame[b.index].state != F_UNUSED) + return -EINVAL; + + cam->frame[b.index].state = F_QUEUED; + + spin_lock_irqsave(&cam->queue_lock, lock_flags); + list_add_tail(&cam->frame[b.index].frame, &cam->inqueue); + spin_unlock_irqrestore(&cam->queue_lock, lock_flags); + + PDBGG("Frame #%lu queued", (unsigned long)b.index); + + return 0; +} + + +static int +et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp, + void __user * arg) +{ + struct v4l2_buffer b; + struct et61x251_frame_t *f; + unsigned long lock_flags; + int err = 0; + + if (copy_from_user(&b, arg, sizeof(b))) + return -EFAULT; + + if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP) + return -EINVAL; + + if (list_empty(&cam->outqueue)) { + if (cam->stream == STREAM_OFF) + return -EINVAL; + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + err = wait_event_interruptible + ( cam->wait_frame, + (!list_empty(&cam->outqueue)) || + (cam->state & DEV_DISCONNECTED) || + (cam->state & DEV_MISCONFIGURED) ); + if (err) + return err; + if (cam->state & DEV_DISCONNECTED) + return -ENODEV; + if (cam->state & DEV_MISCONFIGURED) + return -EIO; + } + + spin_lock_irqsave(&cam->queue_lock, lock_flags); + f = list_entry(cam->outqueue.next, struct et61x251_frame_t, frame); + list_del(cam->outqueue.next); + spin_unlock_irqrestore(&cam->queue_lock, lock_flags); + + f->state = F_UNUSED; + + memcpy(&b, &f->buf, sizeof(b)); + if (f->vma_use_count) + b.flags |= V4L2_BUF_FLAG_MAPPED; + + if (copy_to_user(arg, &b, sizeof(b))) + return -EFAULT; + + PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index); + + return 0; +} + + +static int +et61x251_vidioc_streamon(struct et61x251_device* cam, void __user * arg) +{ + int type; + + if (copy_from_user(&type, arg, sizeof(type))) + return -EFAULT; + + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) + return -EINVAL; + + if (list_empty(&cam->inqueue)) + return -EINVAL; + + cam->stream = STREAM_ON; + + DBG(3, "Stream on"); + + return 0; +} + + +static int +et61x251_vidioc_streamoff(struct et61x251_device* cam, void __user * arg) +{ + int type, err; + + if (copy_from_user(&type, arg, sizeof(type))) + return -EFAULT; + + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) + return -EINVAL; + + if (cam->stream == STREAM_ON) + if ((err = et61x251_stream_interrupt(cam))) + return err; + + et61x251_empty_framequeues(cam); + + DBG(3, "Stream off"); + + return 0; +} + + +static int +et61x251_vidioc_g_parm(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_streamparm sp; + + if (copy_from_user(&sp, arg, sizeof(sp))) + return -EFAULT; + + if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + sp.parm.capture.extendedmode = 0; + sp.parm.capture.readbuffers = cam->nreadbuffers; + + if (copy_to_user(arg, &sp, sizeof(sp))) + return -EFAULT; + + return 0; +} + + +static int +et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg) +{ + struct v4l2_streamparm sp; + + if (copy_from_user(&sp, arg, sizeof(sp))) + return -EFAULT; + + if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + sp.parm.capture.extendedmode = 0; + + if (sp.parm.capture.readbuffers == 0) + sp.parm.capture.readbuffers = cam->nreadbuffers; + + if (sp.parm.capture.readbuffers > ET61X251_MAX_FRAMES) + sp.parm.capture.readbuffers = ET61X251_MAX_FRAMES; + + if (copy_to_user(arg, &sp, sizeof(sp))) + return -EFAULT; + + cam->nreadbuffers = sp.parm.capture.readbuffers; + + return 0; +} + + +static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, + unsigned int cmd, void __user * arg) +{ + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + + switch (cmd) { + + case VIDIOC_QUERYCAP: + return et61x251_vidioc_querycap(cam, arg); + + case VIDIOC_ENUMINPUT: + return et61x251_vidioc_enuminput(cam, arg); + + case VIDIOC_G_INPUT: + case VIDIOC_S_INPUT: + return et61x251_vidioc_gs_input(cam, arg); + + case VIDIOC_QUERYCTRL: + return et61x251_vidioc_query_ctrl(cam, arg); + + case VIDIOC_G_CTRL: + return et61x251_vidioc_g_ctrl(cam, arg); + + case VIDIOC_S_CTRL_OLD: + case VIDIOC_S_CTRL: + return et61x251_vidioc_s_ctrl(cam, arg); + + case VIDIOC_CROPCAP_OLD: + case VIDIOC_CROPCAP: + return et61x251_vidioc_cropcap(cam, arg); + + case VIDIOC_G_CROP: + return et61x251_vidioc_g_crop(cam, arg); + + case VIDIOC_S_CROP: + return et61x251_vidioc_s_crop(cam, arg); + + case VIDIOC_ENUM_FMT: + return et61x251_vidioc_enum_fmt(cam, arg); + + case VIDIOC_G_FMT: + return et61x251_vidioc_g_fmt(cam, arg); + + case VIDIOC_TRY_FMT: + case VIDIOC_S_FMT: + return et61x251_vidioc_try_s_fmt(cam, cmd, arg); + + case VIDIOC_G_JPEGCOMP: + return et61x251_vidioc_g_jpegcomp(cam, arg); + + case VIDIOC_S_JPEGCOMP: + return et61x251_vidioc_s_jpegcomp(cam, arg); + + case VIDIOC_REQBUFS: + return et61x251_vidioc_reqbufs(cam, arg); + + case VIDIOC_QUERYBUF: + return et61x251_vidioc_querybuf(cam, arg); + + case VIDIOC_QBUF: + return et61x251_vidioc_qbuf(cam, arg); + + case VIDIOC_DQBUF: + return et61x251_vidioc_dqbuf(cam, filp, arg); + + case VIDIOC_STREAMON: + return et61x251_vidioc_streamon(cam, arg); + + case VIDIOC_STREAMOFF: + return et61x251_vidioc_streamoff(cam, arg); + + case VIDIOC_G_PARM: + return et61x251_vidioc_g_parm(cam, arg); + + case VIDIOC_S_PARM_OLD: + case VIDIOC_S_PARM: + return et61x251_vidioc_s_parm(cam, arg); + + case VIDIOC_G_STD: + case VIDIOC_S_STD: + case VIDIOC_QUERYSTD: + case VIDIOC_ENUMSTD: + case VIDIOC_QUERYMENU: + return -EINVAL; + + default: + return -EINVAL; + + } +} + + +static int et61x251_ioctl(struct inode* inode, struct file* filp, + unsigned int cmd, unsigned long arg) +{ + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + int err = 0; + + if (down_interruptible(&cam->fileop_sem)) + return -ERESTARTSYS; + + if (cam->state & DEV_DISCONNECTED) { + DBG(1, "Device not present"); + up(&cam->fileop_sem); + return -ENODEV; + } + + if (cam->state & DEV_MISCONFIGURED) { + DBG(1, "The camera is misconfigured. Close and open it " + "again."); + up(&cam->fileop_sem); + return -EIO; + } + + V4LDBG(3, "et61x251", cmd); + + err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); + + up(&cam->fileop_sem); + + return err; +} + + +static struct file_operations et61x251_fops = { + .owner = THIS_MODULE, + .open = et61x251_open, + .release = et61x251_release, + .ioctl = et61x251_ioctl, + .read = et61x251_read, + .poll = et61x251_poll, + .mmap = et61x251_mmap, + .llseek = no_llseek, +}; + +/*****************************************************************************/ + +/* It exists a single interface only. We do not need to validate anything. */ +static int +et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct et61x251_device* cam; + static unsigned int dev_nr = 0; + unsigned int i; + int err = 0; + + if (!(cam = kzalloc(sizeof(struct et61x251_device), GFP_KERNEL))) + return -ENOMEM; + + cam->usbdev = udev; + + if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) { + DBG(1, "kmalloc() failed"); + err = -ENOMEM; + goto fail; + } + + if (!(cam->v4ldev = video_device_alloc())) { + DBG(1, "video_device_alloc() failed"); + err = -ENOMEM; + goto fail; + } + + init_MUTEX(&cam->dev_sem); + + DBG(2, "ET61X[12]51 PC Camera Controller detected " + "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); + + for (i = 0; et61x251_sensor_table[i]; i++) { + err = et61x251_sensor_table[i](cam); + if (!err) + break; + } + + if (!err && cam->sensor) + DBG(2, "%s image sensor detected", cam->sensor->name); + else { + DBG(1, "No supported image sensor detected"); + err = -ENODEV; + goto fail; + } + + if (et61x251_init(cam)) { + DBG(1, "Initialization failed. I will retry on open()."); + cam->state |= DEV_MISCONFIGURED; + } + + strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); + cam->v4ldev->owner = THIS_MODULE; + cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; + cam->v4ldev->hardware = 0; + cam->v4ldev->fops = &et61x251_fops; + cam->v4ldev->minor = video_nr[dev_nr]; + cam->v4ldev->release = video_device_release; + video_set_drvdata(cam->v4ldev, cam); + + down(&cam->dev_sem); + + err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, + video_nr[dev_nr]); + if (err) { + DBG(1, "V4L2 device registration failed"); + if (err == -ENFILE && video_nr[dev_nr] == -1) + DBG(1, "Free /dev/videoX node not found"); + video_nr[dev_nr] = -1; + dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; + up(&cam->dev_sem); + goto fail; + } + + DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); + + cam->module_param.force_munmap = force_munmap[dev_nr]; + + dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + et61x251_create_sysfs(cam); + DBG(2, "Optional device control through 'sysfs' interface ready"); +#endif + + usb_set_intfdata(intf, cam); + + up(&cam->dev_sem); + + return 0; + +fail: + if (cam) { + kfree(cam->control_buffer); + if (cam->v4ldev) + video_device_release(cam->v4ldev); + kfree(cam); + } + return err; +} + + +static void et61x251_usb_disconnect(struct usb_interface* intf) +{ + struct et61x251_device* cam = usb_get_intfdata(intf); + + if (!cam) + return; + + down_write(&et61x251_disconnect); + + down(&cam->dev_sem); + + DBG(2, "Disconnecting %s...", cam->v4ldev->name); + + wake_up_interruptible_all(&cam->open); + + if (cam->users) { + DBG(2, "Device /dev/video%d is open! Deregistration and " + "memory deallocation are deferred on close.", + cam->v4ldev->minor); + cam->state |= DEV_MISCONFIGURED; + et61x251_stop_transfer(cam); + cam->state |= DEV_DISCONNECTED; + wake_up_interruptible(&cam->wait_frame); + wake_up_interruptible(&cam->wait_stream); + } else { + cam->state |= DEV_DISCONNECTED; + et61x251_release_resources(cam); + } + + up(&cam->dev_sem); + + if (!cam->users) + kfree(cam); + + up_write(&et61x251_disconnect); +} + + +static struct usb_driver et61x251_usb_driver = { + .name = "et61x251", + .id_table = et61x251_id_table, + .probe = et61x251_usb_probe, + .disconnect = et61x251_usb_disconnect, +}; + +/*****************************************************************************/ + +static int __init et61x251_module_init(void) +{ + int err = 0; + + KDBG(2, ET61X251_MODULE_NAME " v" ET61X251_MODULE_VERSION); + KDBG(3, ET61X251_MODULE_AUTHOR); + + if ((err = usb_register(&et61x251_usb_driver))) + KDBG(1, "usb_register() failed"); + + return err; +} + + +static void __exit et61x251_module_exit(void) +{ + usb_deregister(&et61x251_usb_driver); +} + + +module_init(et61x251_module_init); +module_exit(et61x251_module_exit); diff --git a/drivers/usb/media/et61x251_sensor.h b/drivers/usb/media/et61x251_sensor.h new file mode 100644 index 000000000000..b9df91062fc0 --- /dev/null +++ b/drivers/usb/media/et61x251_sensor.h @@ -0,0 +1,115 @@ +/*************************************************************************** + * API for image sensors connected to ET61X[12]51 PC Camera Controllers * + * * + * Copyright (C) 2006 by Luca Risolia * + * * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * + ***************************************************************************/ + +#ifndef _ET61X251_SENSOR_H_ +#define _ET61X251_SENSOR_H_ + +#include +#include +#include +#include +#include +#include + +struct et61x251_device; +struct et61x251_sensor; + +/*****************************************************************************/ + +extern int et61x251_probe_tas5130d1b(struct et61x251_device* cam); + +#define ET61X251_SENSOR_TABLE \ +/* Weak detections must go at the end of the list */ \ +static int (*et61x251_sensor_table[])(struct et61x251_device*) = { \ + &et61x251_probe_tas5130d1b, \ + NULL, \ +}; + +extern void +et61x251_attach_sensor(struct et61x251_device* cam, + struct et61x251_sensor* sensor); + +/*****************************************************************************/ + +extern int et61x251_write_reg(struct et61x251_device*, u8 value, u16 index); +extern int et61x251_read_reg(struct et61x251_device*, u16 index); +extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value); +extern int et61x251_i2c_read(struct et61x251_device*, u8 address); +extern int et61x251_i2c_try_write(struct et61x251_device*, + struct et61x251_sensor*, u8 address, + u8 value); +extern int et61x251_i2c_try_read(struct et61x251_device*, + struct et61x251_sensor*, u8 address); +extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1, + u8 data2, u8 data3, u8 data4, u8 data5, + u8 data6, u8 data7, u8 data8, u8 address); + +/*****************************************************************************/ + +enum et61x251_i2c_sysfs_ops { + ET61X251_I2C_READ = 0x01, + ET61X251_I2C_WRITE = 0x02, +}; + +enum et61x251_i2c_interface { + ET61X251_I2C_2WIRES, + ET61X251_I2C_3WIRES, +}; + +/* Repeat start condition when RSTA is high */ +enum et61x251_i2c_rsta { + ET61X251_I2C_RSTA_STOP = 0x00, /* stop then start */ + ET61X251_I2C_RSTA_REPEAT = 0x01, /* repeat start */ +}; + +#define ET61X251_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10 + +struct et61x251_sensor { + char name[32]; + + enum et61x251_i2c_sysfs_ops sysfs_ops; + + enum et61x251_i2c_interface interface; + u8 i2c_slave_id; + enum et61x251_i2c_rsta rsta; + struct v4l2_rect active_pixel; /* left and top define FVSX and FVSY */ + + struct v4l2_queryctrl qctrl[ET61X251_MAX_CTRLS]; + struct v4l2_cropcap cropcap; + struct v4l2_pix_format pix_format; + + int (*init)(struct et61x251_device* cam); + int (*get_ctrl)(struct et61x251_device* cam, + struct v4l2_control* ctrl); + int (*set_ctrl)(struct et61x251_device* cam, + const struct v4l2_control* ctrl); + int (*set_crop)(struct et61x251_device* cam, + const struct v4l2_rect* rect); + int (*set_pix_format)(struct et61x251_device* cam, + const struct v4l2_pix_format* pix); + + const struct usb_device* usbdev; + + /* Private */ + struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS]; + struct v4l2_rect _rect; +}; + +#endif /* _ET61X251_SENSOR_H_ */ diff --git a/drivers/usb/media/et61x251_tas5130d1b.c b/drivers/usb/media/et61x251_tas5130d1b.c new file mode 100644 index 000000000000..65f1ae9cf2b3 --- /dev/null +++ b/drivers/usb/media/et61x251_tas5130d1b.c @@ -0,0 +1,137 @@ +/*************************************************************************** + * Plug-in for TAS5130D1B image sensor connected to the ET61X[12]51 * + * PC Camera Controllers * + * * + * Copyright (C) 2006 by Luca Risolia * + * * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * + ***************************************************************************/ + +#include "et61x251_sensor.h" + + +static int tas5130d1b_init(struct et61x251_device* cam) +{ + int err = 0; + + err += et61x251_write_reg(cam, 0x14, 0x01); + err += et61x251_write_reg(cam, 0x1b, 0x02); + err += et61x251_write_reg(cam, 0x02, 0x12); + err += et61x251_write_reg(cam, 0x0e, 0x60); + err += et61x251_write_reg(cam, 0x80, 0x61); + err += et61x251_write_reg(cam, 0xf0, 0x62); + err += et61x251_write_reg(cam, 0x03, 0x63); + err += et61x251_write_reg(cam, 0x14, 0x64); + err += et61x251_write_reg(cam, 0xf4, 0x65); + err += et61x251_write_reg(cam, 0x01, 0x66); + err += et61x251_write_reg(cam, 0x05, 0x67); + err += et61x251_write_reg(cam, 0x8f, 0x68); + err += et61x251_write_reg(cam, 0x0f, 0x8d); + err += et61x251_write_reg(cam, 0x08, 0x8e); + + return err; +} + + +static int tas5130d1b_set_ctrl(struct et61x251_device* cam, + const struct v4l2_control* ctrl) +{ + int err = 0; + + switch (ctrl->id) { + case V4L2_CID_GAIN: + err += et61x251_i2c_raw_write(cam, 2, 0x20, + 0xf6-ctrl->value, 0, 0, 0, + 0, 0, 0, 0); + break; + case V4L2_CID_EXPOSURE: + err += et61x251_i2c_raw_write(cam, 2, 0x40, + 0x47-ctrl->value, 0, 0, 0, + 0, 0, 0, 0); + break; + default: + return -EINVAL; + } + + return err ? -EIO : 0; +} + + +static struct et61x251_sensor tas5130d1b = { + .name = "TAS5130D1B", + .interface = ET61X251_I2C_3WIRES, + .rsta = ET61X251_I2C_RSTA_STOP, + .active_pixel = { + .left = 106, + .top = 13, + }, + .init = &tas5130d1b_init, + .qctrl = { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "global gain", + .minimum = 0x00, + .maximum = 0xf6, + .step = 0x02, + .default_value = 0x0d, + .flags = 0, + }, + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "exposure", + .minimum = 0x00, + .maximum = 0x47, + .step = 0x01, + .default_value = 0x23, + .flags = 0, + }, + }, + .set_ctrl = &tas5130d1b_set_ctrl, + .cropcap = { + .bounds = { + .left = 0, + .top = 0, + .width = 640, + .height = 480, + }, + .defrect = { + .left = 0, + .top = 0, + .width = 640, + .height = 480, + }, + }, + .pix_format = { + .width = 640, + .height = 480, + .pixelformat = V4L2_PIX_FMT_SBGGR8, + .priv = 8, + }, +}; + + +int et61x251_probe_tas5130d1b(struct et61x251_device* cam) +{ + /* This sensor has no identifiers, so let's attach it anyway */ + et61x251_attach_sensor(cam, &tas5130d1b); + + /* Sensor detection is based on USB pid/vid */ + if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6251) + return -ENODEV; + + return 0; +} diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index ce40675324bd..6f6c69777648 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -315,6 +315,7 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */ #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */ #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */ +#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5') /* ET61X251 compression */ /* * F O R M A T E N U M E R A T I O N From 0ec3c7e856319b600311750d784262caa8ed94b9 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Tue, 17 Jan 2006 11:15:13 +0100 Subject: [PATCH 230/695] [PATCH] USBATM: trivial modifications Formatting, changes to variable names, comments, log level changes, printk rate limiting. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 69 +++++++++++++------------ drivers/usb/atm/speedtch.c | 53 ++++++++++--------- drivers/usb/atm/usbatm.c | 101 ++++++++++++++++++++++--------------- drivers/usb/atm/usbatm.h | 25 ++++++--- drivers/usb/atm/xusbatm.c | 23 +++++---- 5 files changed, 153 insertions(+), 118 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index af0a41e7870e..139be1207d22 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -352,7 +352,6 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, struct atm_dev *atm_dev) { struct cxacru_data *instance = usbatm_instance->driver_data; - struct device *dev = &usbatm_instance->usb_intf->dev; /* struct atm_dev *atm_dev = usbatm_instance->atm_dev; */ @@ -364,14 +363,14 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0, atm_dev->esi, sizeof(atm_dev->esi)); if (ret < 0) { - dev_err(dev, "cxacru_atm_start: CARD_GET_MAC_ADDRESS returned %d\n", ret); + atm_err(usbatm_instance, "cxacru_atm_start: CARD_GET_MAC_ADDRESS returned %d\n", ret); return ret; } /* start ADSL */ ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); if (ret < 0) { - dev_err(dev, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret); + atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret); return ret; } @@ -383,13 +382,13 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, static void cxacru_poll_status(struct cxacru_data *instance) { u32 buf[CXINF_MAX] = {}; - struct device *dev = &instance->usbatm->usb_intf->dev; - struct atm_dev *atm_dev = instance->usbatm->atm_dev; + struct usbatm_data *usbatm = instance->usbatm; + struct atm_dev *atm_dev = usbatm->atm_dev; int ret; ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX); if (ret < 0) { - dev_warn(dev, "poll status: error %d\n", ret); + atm_warn(usbatm, "poll status: error %d\n", ret); goto reschedule; } @@ -400,50 +399,50 @@ static void cxacru_poll_status(struct cxacru_data *instance) switch (instance->line_status) { case 0: atm_dev->signal = ATM_PHY_SIG_LOST; - dev_info(dev, "ADSL line: down\n"); + atm_info(usbatm, "ADSL line: down\n"); break; case 1: atm_dev->signal = ATM_PHY_SIG_LOST; - dev_info(dev, "ADSL line: attemtping to activate\n"); + atm_info(usbatm, "ADSL line: attempting to activate\n"); break; case 2: atm_dev->signal = ATM_PHY_SIG_LOST; - dev_info(dev, "ADSL line: training\n"); + atm_info(usbatm, "ADSL line: training\n"); break; case 3: atm_dev->signal = ATM_PHY_SIG_LOST; - dev_info(dev, "ADSL line: channel analysis\n"); + atm_info(usbatm, "ADSL line: channel analysis\n"); break; case 4: atm_dev->signal = ATM_PHY_SIG_LOST; - dev_info(dev, "ADSL line: exchange\n"); + atm_info(usbatm, "ADSL line: exchange\n"); break; case 5: atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424; atm_dev->signal = ATM_PHY_SIG_FOUND; - dev_info(dev, "ADSL line: up (%d kb/s down | %d kb/s up)\n", + atm_info(usbatm, "ADSL line: up (%d kb/s down | %d kb/s up)\n", buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]); break; case 6: atm_dev->signal = ATM_PHY_SIG_LOST; - dev_info(dev, "ADSL line: waiting\n"); + atm_info(usbatm, "ADSL line: waiting\n"); break; case 7: atm_dev->signal = ATM_PHY_SIG_LOST; - dev_info(dev, "ADSL line: initializing\n"); + atm_info(usbatm, "ADSL line: initializing\n"); break; default: atm_dev->signal = ATM_PHY_SIG_UNKNOWN; - dev_info(dev, "Unknown line state %02x\n", instance->line_status); + atm_info(usbatm, "Unknown line state %02x\n", instance->line_status); break; } reschedule: @@ -504,8 +503,8 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, { int ret; int off; - struct usb_device *usb_dev = instance->usbatm->usb_dev; - struct device *dev = &instance->usbatm->usb_intf->dev; + struct usbatm_data *usbatm = instance->usbatm; + struct usb_device *usb_dev = usbatm->usb_dev; u16 signature[] = { usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct }; u32 val; @@ -515,7 +514,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, val = cpu_to_le32(instance->modem_type->pll_f_clk); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4); if (ret) { - dev_err(dev, "FirmwarePllFClkValue failed: %d\n", ret); + usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret); return; } @@ -523,7 +522,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, val = cpu_to_le32(instance->modem_type->pll_b_clk); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4); if (ret) { - dev_err(dev, "FirmwarePllBClkValue failed: %d\n", ret); + usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret); return; } @@ -531,14 +530,14 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, val = cpu_to_le32(SDRAM_ENA); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4); if (ret) { - dev_err(dev, "Enable SDRAM failed: %d\n", ret); + usb_err(usbatm, "Enable SDRAM failed: %d\n", ret); return; } /* Firmware */ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); if (ret) { - dev_err(dev, "Firmware upload failed: %d\n", ret); + usb_err(usbatm, "Firmware upload failed: %d\n", ret); return; } @@ -546,7 +545,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, if (instance->modem_type->boot_rom_patch) { ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); if (ret) { - dev_err(dev, "Boot ROM patching failed: %d\n", ret); + usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); return; } } @@ -554,7 +553,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, /* Signature */ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4); if (ret) { - dev_err(dev, "Signature storing failed: %d\n", ret); + usb_err(usbatm, "Signature storing failed: %d\n", ret); return; } @@ -566,7 +565,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0); } if (ret) { - dev_err(dev, "Passing control to firmware failed: %d\n", ret); + usb_err(usbatm, "Passing control to firmware failed: %d\n", ret); return; } @@ -580,7 +579,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0); if (ret < 0) { - dev_err(dev, "modem failed to initialize: %d\n", ret); + usb_err(usbatm, "modem failed to initialize: %d\n", ret); return; } @@ -597,7 +596,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET, (u8 *) buf, len, NULL, 0); if (ret < 0) { - dev_err(dev, "load config data failed: %d\n", ret); + usb_err(usbatm, "load config data failed: %d\n", ret); return; } } @@ -608,18 +607,19 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, static int cxacru_find_firmware(struct cxacru_data *instance, char* phase, const struct firmware **fw_p) { - struct device *dev = &instance->usbatm->usb_intf->dev; + struct usbatm_data *usbatm = instance->usbatm; + struct device *dev = &usbatm->usb_intf->dev; char buf[16]; sprintf(buf, "cxacru-%s.bin", phase); dbg("cxacru_find_firmware: looking for %s", buf); if (request_firmware(fw_p, buf, dev)) { - dev_dbg(dev, "no stage %s firmware found\n", phase); + usb_dbg(usbatm, "no stage %s firmware found\n", phase); return -ENOENT; } - dev_info(dev, "found firmware %s\n", buf); + usb_info(usbatm, "found firmware %s\n", buf); return 0; } @@ -627,20 +627,19 @@ static int cxacru_find_firmware(struct cxacru_data *instance, static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, struct usb_interface *usb_intf) { - struct device *dev = &usbatm_instance->usb_intf->dev; const struct firmware *fw, *bp, *cf; struct cxacru_data *instance = usbatm_instance->driver_data; int ret = cxacru_find_firmware(instance, "fw", &fw); if (ret) { - dev_warn(dev, "firmware (cxacru-fw.bin) unavailable (hotplug misconfiguration?)\n"); + usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n"); return ret; } if (instance->modem_type->boot_rom_patch) { ret = cxacru_find_firmware(instance, "bp", &bp); if (ret) { - dev_warn(dev, "boot ROM patch (cxacru-bp.bin) unavailable (hotplug misconfiguration?)\n"); + usb_warn(usbatm_instance, "boot ROM patch (cxacru-bp.bin) unavailable (system misconfigured?)\n"); release_firmware(fw); return ret; } @@ -787,12 +786,12 @@ static const struct usb_device_id cxacru_usb_ids[] = { { /* V = Conexant P = ADSL modem (Hasbani project) */ USB_DEVICE(0x0572, 0xcb00), .driver_info = (unsigned long) &cxacru_cb00 }, - { /* V = Conexant P = ADSL modem (Well PTI-800 */ - USB_DEVICE(0x0572, 0xcb02), .driver_info = (unsigned long) &cxacru_cb00 - }, { /* V = Conexant P = ADSL modem */ USB_DEVICE(0x0572, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00 }, + { /* V = Conexant P = ADSL modem (Well PTI-800) */ + USB_DEVICE(0x0572, 0xcb02), .driver_info = (unsigned long) &cxacru_cb00 + }, { /* V = Conexant P = ADSL modem */ USB_DEVICE(0x0572, 0xcb06), .driver_info = (unsigned long) &cxacru_cb00 }, diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index c1b47d74e206..211d467311e2 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -205,7 +205,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, buffer, 0x200, &actual_length, 2000); if (ret < 0 && ret != -ETIMEDOUT) - usb_dbg(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret); + usb_warn(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret); else usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret); } @@ -219,7 +219,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, buffer, thislen, &actual_length, DATA_TIMEOUT); if (ret < 0) { - usb_dbg(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret); + usb_err(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret); goto out_free; } usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size); @@ -232,7 +232,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, buffer, 0x200, &actual_length, DATA_TIMEOUT); if (ret < 0) { - usb_dbg(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret); + usb_err(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret); goto out_free; } usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length); @@ -246,7 +246,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, buffer, thislen, &actual_length, DATA_TIMEOUT); if (ret < 0) { - usb_dbg(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret); + usb_err(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret); goto out_free; } } @@ -259,7 +259,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, buffer, 0x200, &actual_length, DATA_TIMEOUT); if (ret < 0) { - usb_dbg(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret); + usb_err(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret); goto out_free; } @@ -285,8 +285,8 @@ out: return ret; } -static int speedtch_find_firmware(struct usb_interface *intf, int phase, - const struct firmware **fw_p) +static int speedtch_find_firmware(struct usbatm_data *usbatm, struct usb_interface *intf, + int phase, const struct firmware **fw_p) { struct device *dev = &intf->dev; const u16 bcdDevice = le16_to_cpu(interface_to_usbdev(intf)->descriptor.bcdDevice); @@ -295,24 +295,24 @@ static int speedtch_find_firmware(struct usb_interface *intf, int phase, char buf[24]; sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision); - dev_dbg(dev, "%s: looking for %s\n", __func__, buf); + usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); if (request_firmware(fw_p, buf, dev)) { sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision); - dev_dbg(dev, "%s: looking for %s\n", __func__, buf); + usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); if (request_firmware(fw_p, buf, dev)) { sprintf(buf, "speedtch-%d.bin", phase); - dev_dbg(dev, "%s: looking for %s\n", __func__, buf); + usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); if (request_firmware(fw_p, buf, dev)) { - dev_warn(dev, "no stage %d firmware found!\n", phase); + usb_err(usbatm, "%s: no stage %d firmware found!\n", __func__, phase); return -ENOENT; } } } - dev_info(dev, "found stage %d firmware %s\n", phase, buf); + usb_info(usbatm, "found stage %d firmware %s\n", phase, buf); return 0; } @@ -323,15 +323,16 @@ static int speedtch_heavy_init(struct usbatm_data *usbatm, struct usb_interface struct speedtch_instance_data *instance = usbatm->driver_data; int ret; - if ((ret = speedtch_find_firmware(intf, 1, &fw1)) < 0) - return ret; + if ((ret = speedtch_find_firmware(usbatm, intf, 1, &fw1)) < 0) + return ret; - if ((ret = speedtch_find_firmware(intf, 2, &fw2)) < 0) { + if ((ret = speedtch_find_firmware(usbatm, intf, 2, &fw2)) < 0) { release_firmware(fw1); return ret; } - ret = speedtch_upload_firmware(instance, fw1, fw2); + if ((ret = speedtch_upload_firmware(instance, fw1, fw2)) < 0) + usb_err(usbatm, "%s: firmware upload failed (%d)!\n", __func__, ret); release_firmware(fw2); release_firmware(fw1); @@ -428,7 +429,9 @@ static void speedtch_check_status(struct speedtch_instance_data *instance) int down_speed, up_speed, ret; unsigned char status; +#ifdef VERBOSE_DEBUG atm_dbg(usbatm, "%s entered\n", __func__); +#endif ret = speedtch_read_status(instance); if (ret < 0) { @@ -441,9 +444,9 @@ static void speedtch_check_status(struct speedtch_instance_data *instance) status = buf[OFFSET_7]; - atm_dbg(usbatm, "%s: line state %02x\n", __func__, status); - if ((status != instance->last_status) || !status) { + atm_dbg(usbatm, "%s: line state 0x%02x\n", __func__, status); + switch (status) { case 0: atm_dev->signal = ATM_PHY_SIG_LOST; @@ -484,7 +487,7 @@ static void speedtch_check_status(struct speedtch_instance_data *instance) default: atm_dev->signal = ATM_PHY_SIG_UNKNOWN; - atm_info(usbatm, "Unknown line state %02x\n", status); + atm_info(usbatm, "unknown line state %02x\n", status); break; } @@ -690,8 +693,10 @@ static int speedtch_bind(struct usbatm_data *usbatm, usb_dbg(usbatm, "%s entered\n", __func__); + /* sanity checks */ + if (usb_dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { - usb_dbg(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass); + usb_err(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass); return -ENODEV; } @@ -704,7 +709,7 @@ static int speedtch_bind(struct usbatm_data *usbatm, ret = usb_driver_claim_interface(&speedtch_usb_driver, cur_intf, usbatm); if (ret < 0) { - usb_dbg(usbatm, "%s: failed to claim interface %d (%d)\n", __func__, i, ret); + usb_err(usbatm, "%s: failed to claim interface %2d (%d)!\n", __func__, i, ret); speedtch_release_interfaces(usb_dev, i); return ret; } @@ -714,7 +719,7 @@ static int speedtch_bind(struct usbatm_data *usbatm, instance = kmalloc(sizeof(*instance), GFP_KERNEL); if (!instance) { - usb_dbg(usbatm, "%s: no memory for instance data!\n", __func__); + usb_err(usbatm, "%s: no memory for instance data!\n", __func__); ret = -ENOMEM; goto fail_release; } @@ -754,8 +759,10 @@ static int speedtch_bind(struct usbatm_data *usbatm, usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, need_heavy_init ? "not" : "already"); if (*need_heavy_init) - if ((ret = usb_reset_device(usb_dev)) < 0) + if ((ret = usb_reset_device(usb_dev)) < 0) { + usb_err(usbatm, "%s: device reset failed (%d)!\n", __func__, ret); goto fail_free; + } usbatm->driver_data = instance; diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 7af1883d4bf9..779f86ecdd76 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -166,10 +166,10 @@ struct usbatm_control { /* ATM */ -static void usbatm_atm_dev_close(struct atm_dev *dev); +static void usbatm_atm_dev_close(struct atm_dev *atm_dev); static int usbatm_atm_open(struct atm_vcc *vcc); static void usbatm_atm_close(struct atm_vcc *vcc); -static int usbatm_atm_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg); +static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user * arg); static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb); static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *page); @@ -234,8 +234,9 @@ static int usbatm_submit_urb(struct urb *urb) ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { - atm_dbg(channel->usbatm, "%s: urb 0x%p submission failed (%d)!\n", - __func__, urb, ret); + if (printk_ratelimit()) + atm_warn(channel->usbatm, "%s: urb 0x%p submission failed (%d)!\n", + __func__, urb, ret); /* consider all errors transient and return the buffer back to the queue */ urb->status = -EAGAIN; @@ -269,10 +270,13 @@ static void usbatm_complete(struct urb *urb, struct pt_regs *regs) spin_unlock_irqrestore(&channel->lock, flags); - if (unlikely(urb->status)) + if (unlikely(urb->status)) { + if (printk_ratelimit()) + atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", + __func__, urb, urb->status); /* throttle processing in case of an error */ mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS)); - else + } else tasklet_schedule(&channel->tasklet); } @@ -284,11 +288,11 @@ static void usbatm_complete(struct urb *urb, struct pt_regs *regs) static inline struct usbatm_vcc_data *usbatm_find_vcc(struct usbatm_data *instance, short vpi, int vci) { - struct usbatm_vcc_data *vcc; + struct usbatm_vcc_data *vcc_data; - list_for_each_entry(vcc, &instance->vcc_list, list) - if ((vcc->vci == vci) && (vcc->vpi == vpi)) - return vcc; + list_for_each_entry(vcc_data, &instance->vcc_list, list) + if ((vcc_data->vci == vci) && (vcc_data->vpi == vpi)) + return vcc_data; return NULL; } @@ -317,7 +321,7 @@ static void usbatm_extract_cells(struct usbatm_data *instance, cached_vcc = usbatm_find_vcc(instance, vpi, vci); if (!cached_vcc) - atm_dbg(instance, "%s: unknown vpi/vci (%hd/%d)!\n", __func__, vpi, vci); + atm_rldbg(instance, "%s: unknown vpi/vci (%hd/%d)!\n", __func__, vpi, vci); } if (!cached_vcc) @@ -327,7 +331,9 @@ static void usbatm_extract_cells(struct usbatm_data *instance, /* OAM F5 end-to-end */ if (pti == ATM_PTI_E2EF5) { - atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", __func__, vpi, vci); + if (printk_ratelimit()) + atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", + __func__, vpi, vci); atomic_inc(&vcc->stats->rx_err); continue; } @@ -335,7 +341,7 @@ static void usbatm_extract_cells(struct usbatm_data *instance, sarb = cached_vcc->sarb; if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) { - atm_dbg(instance, "%s: buffer overrun (sarb->len %u, vcc: 0x%p)!\n", + atm_rldbg(instance, "%s: buffer overrun (sarb->len %u, vcc: 0x%p)!\n", __func__, sarb->len, vcc); /* discard cells already received */ skb_trim(sarb, 0); @@ -354,7 +360,7 @@ static void usbatm_extract_cells(struct usbatm_data *instance, /* guard against overflow */ if (length > ATM_MAX_AAL5_PDU) { - atm_dbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n", + atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n", __func__, length, vcc); atomic_inc(&vcc->stats->rx_err); goto out; @@ -363,14 +369,14 @@ static void usbatm_extract_cells(struct usbatm_data *instance, pdu_length = usbatm_pdu_length(length); if (sarb->len < pdu_length) { - atm_dbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n", + atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n", __func__, pdu_length, sarb->len, vcc); atomic_inc(&vcc->stats->rx_err); goto out; } if (crc32_be(~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) { - atm_dbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n", + atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n", __func__, vcc); atomic_inc(&vcc->stats->rx_err); goto out; @@ -379,7 +385,9 @@ static void usbatm_extract_cells(struct usbatm_data *instance, vdbg("%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", __func__, length, pdu_length, vcc); if (!(skb = dev_alloc_skb(length))) { - atm_dbg(instance, "%s: no memory for skb (length: %u)!\n", __func__, length); + if (printk_ratelimit()) + atm_err(instance, "%s: no memory for skb (length: %u)!\n", + __func__, length); atomic_inc(&vcc->stats->rx_drop); goto out; } @@ -387,7 +395,8 @@ static void usbatm_extract_cells(struct usbatm_data *instance, vdbg("%s: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", __func__, skb, skb->truesize); if (!atm_charge(vcc, skb->truesize)) { - atm_dbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n", __func__, skb->truesize); + atm_rldbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n", + __func__, skb->truesize); dev_kfree_skb(skb); goto out; /* atm_charge increments rx_drop */ } @@ -600,13 +609,13 @@ static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) } if (vcc->qos.aal != ATM_AAL5) { - atm_dbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal); + atm_rldbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal); err = -EINVAL; goto fail; } if (skb->len > ATM_MAX_AAL5_PDU) { - atm_dbg(instance, "%s: packet too long (%d vs %d)!\n", + atm_rldbg(instance, "%s: packet too long (%d vs %d)!\n", __func__, skb->len, ATM_MAX_AAL5_PDU); err = -EINVAL; goto fail; @@ -665,16 +674,16 @@ static void usbatm_put_instance(struct usbatm_data *instance) ** ATM ** **********/ -static void usbatm_atm_dev_close(struct atm_dev *dev) +static void usbatm_atm_dev_close(struct atm_dev *atm_dev) { - struct usbatm_data *instance = dev->dev_data; + struct usbatm_data *instance = atm_dev->dev_data; dbg("%s", __func__); if (!instance) return; - dev->dev_data = NULL; + atm_dev->dev_data = NULL; /* catch bugs */ usbatm_put_instance(instance); /* taken in usbatm_atm_init */ } @@ -735,13 +744,18 @@ static int usbatm_atm_open(struct atm_vcc *vcc) atm_dbg(instance, "%s: vpi %hd, vci %d\n", __func__, vpi, vci); /* only support AAL5 */ - if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) - || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) { - atm_dbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal); + if ((vcc->qos.aal != ATM_AAL5)) { + atm_warn(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal); return -EINVAL; } - down(&instance->serialize); /* vs self, usbatm_atm_close */ + /* sanity checks */ + if ((vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) { + atm_dbg(instance, "%s: max_sdu %d out of range!\n", __func__, vcc->qos.rxtp.max_sdu); + return -EINVAL; + } + + down(&instance->serialize); /* vs self, usbatm_atm_close, usbatm_usb_disconnect */ if (usbatm_find_vcc(instance, vpi, vci)) { atm_dbg(instance, "%s: %hd/%d already in use!\n", __func__, vpi, vci); @@ -750,7 +764,7 @@ static int usbatm_atm_open(struct atm_vcc *vcc) } if (!(new = kmalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) { - atm_dbg(instance, "%s: no memory for vcc_data!\n", __func__); + atm_err(instance, "%s: no memory for vcc_data!\n", __func__); ret = -ENOMEM; goto fail; } @@ -762,7 +776,7 @@ static int usbatm_atm_open(struct atm_vcc *vcc) new->sarb = alloc_skb(usbatm_pdu_length(vcc->qos.rxtp.max_sdu), GFP_KERNEL); if (!new->sarb) { - atm_dbg(instance, "%s: no memory for SAR buffer!\n", __func__); + atm_err(instance, "%s: no memory for SAR buffer!\n", __func__); ret = -ENOMEM; goto fail; } @@ -806,7 +820,7 @@ static void usbatm_atm_close(struct atm_vcc *vcc) usbatm_cancel_send(instance, vcc); - down(&instance->serialize); /* vs self, usbatm_atm_open */ + down(&instance->serialize); /* vs self, usbatm_atm_open, usbatm_usb_disconnect */ tasklet_disable(&instance->rx_channel.tasklet); list_del(&vcc_data->list); @@ -829,7 +843,7 @@ static void usbatm_atm_close(struct atm_vcc *vcc) atm_dbg(instance, "%s successful\n", __func__); } -static int usbatm_atm_ioctl(struct atm_dev *dev, unsigned int cmd, +static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user * arg) { switch (cmd) { @@ -845,10 +859,13 @@ static int usbatm_atm_init(struct usbatm_data *instance) struct atm_dev *atm_dev; int ret, i; - /* ATM init */ + /* ATM init. The ATM initialization scheme suffers from an intrinsic race + * condition: callbacks we register can be executed at once, before we have + * initialized the struct atm_dev. To protect against this, all callbacks + * abort if atm_dev->dev_data is NULL. */ atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL); if (!atm_dev) { - usb_dbg(instance, "%s: failed to register ATM device!\n", __func__); + usb_err(instance, "%s: failed to register ATM device!\n", __func__); return -1; } @@ -862,12 +879,13 @@ static int usbatm_atm_init(struct usbatm_data *instance) atm_dev->link_rate = 128 * 1000 / 424; if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { - atm_dbg(instance, "%s: atm_start failed: %d!\n", __func__, ret); + atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); goto fail; } - /* ready for ATM callbacks */ usbatm_get_instance(instance); /* dropped in usbatm_atm_dev_close */ + + /* ready for ATM callbacks */ mb(); atm_dev->dev_data = instance; @@ -915,7 +933,7 @@ static int usbatm_heavy_init(struct usbatm_data *instance) int ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_KERNEL); if (ret < 0) { - usb_dbg(instance, "%s: failed to create kernel_thread (%d)!\n", __func__, ret); + usb_err(instance, "%s: failed to create kernel_thread (%d)!\n", __func__, ret); return ret; } @@ -953,7 +971,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, int i, length; int need_heavy; - dev_dbg(dev, "%s: trying driver %s with vendor=0x%x, product=0x%x, ifnum %d\n", + dev_dbg(dev, "%s: trying driver %s with vendor=%04x, product=%04x, ifnum %2d\n", __func__, driver->driver_name, le16_to_cpu(usb_dev->descriptor.idVendor), le16_to_cpu(usb_dev->descriptor.idProduct), @@ -962,7 +980,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, /* instance init */ instance = kzalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL); if (!instance) { - dev_dbg(dev, "%s: no memory for instance data!\n", __func__); + dev_err(dev, "%s: no memory for instance data!\n", __func__); return -ENOMEM; } @@ -998,7 +1016,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, bind: need_heavy = 1; if (driver->bind && (error = driver->bind(instance, intf, id, &need_heavy)) < 0) { - dev_dbg(dev, "%s: bind failed: %d!\n", __func__, error); + dev_err(dev, "%s: bind failed: %d!\n", __func__, error); goto fail_free; } @@ -1044,7 +1062,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, urb = usb_alloc_urb(iso_packets, GFP_KERNEL); if (!urb) { - dev_dbg(dev, "%s: no memory for urb %d!\n", __func__, i); + dev_err(dev, "%s: no memory for urb %d!\n", __func__, i); goto fail_unbind; } @@ -1052,9 +1070,10 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, buffer = kmalloc(channel->buf_size, GFP_KERNEL); if (!buffer) { - dev_dbg(dev, "%s: no memory for buffer %d!\n", __func__, i); + dev_err(dev, "%s: no memory for buffer %d!\n", __func__, i); goto fail_unbind; } + /* zero the tx padding to avoid leaking information */ memset(buffer, 0, channel->buf_size); usb_fill_bulk_urb(urb, instance->usb_dev, channel->endpoint, diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index 1adacd60d713..ebb79da4cb15 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -24,22 +24,21 @@ #ifndef _USBATM_H_ #define _USBATM_H_ -#include - -/* -#define VERBOSE_DEBUG -*/ - #include #include #include #include #include +#include #include #include #include #include +/* +#define VERBOSE_DEBUG +*/ + #ifdef DEBUG #define UDSL_ASSERT(x) BUG_ON(!(x)) #else @@ -52,8 +51,13 @@ dev_info(&(instance)->usb_intf->dev , format , ## arg) #define usb_warn(instance, format, arg...) \ dev_warn(&(instance)->usb_intf->dev , format , ## arg) +#ifdef DEBUG #define usb_dbg(instance, format, arg...) \ - dev_dbg(&(instance)->usb_intf->dev , format , ## arg) + dev_printk(KERN_DEBUG , &(instance)->usb_intf->dev , format , ## arg) +#else +#define usb_dbg(instance, format, arg...) \ + do {} while (0) +#endif /* FIXME: move to dev_* once ATM is driver model aware */ #define atm_printk(level, instance, format, arg...) \ @@ -69,9 +73,14 @@ #ifdef DEBUG #define atm_dbg(instance, format, arg...) \ atm_printk(KERN_DEBUG, instance , format , ## arg) +#define atm_rldbg(instance, format, arg...) \ + if (printk_ratelimit()) \ + atm_printk(KERN_DEBUG, instance , format , ## arg) #else #define atm_dbg(instance, format, arg...) \ do {} while (0) +#define atm_rldbg(instance, format, arg...) \ + do {} while (0) #endif @@ -171,7 +180,7 @@ struct usbatm_data { struct usbatm_channel tx_channel; struct sk_buff_head sndqueue; - struct sk_buff *current_skb; /* being emptied */ + struct sk_buff *current_skb; /* being emptied */ struct urb *urbs[0]; }; diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index 5c76e3aaaa5e..8f55642f376f 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c @@ -61,7 +61,7 @@ static int usb_intf_has_ep(const struct usb_interface *intf, u8 ep) return 0; } -static int xusbatm_bind(struct usbatm_data *usbatm_instance, +static int xusbatm_bind(struct usbatm_data *usbatm, struct usb_interface *intf, const struct usb_device_id *id, int *need_heavy_init) { @@ -72,14 +72,14 @@ static int xusbatm_bind(struct usbatm_data *usbatm_instance, u8 searched_ep = rx_ep_present ? tx_endpoint[drv_ix] : rx_endpoint[drv_ix]; int i, ret; - usb_dbg(usbatm_instance, "%s: binding driver %d: vendor %#x product %#x" - " rx: ep %#x padd %d tx: ep %#x padd %d\n", + usb_dbg(usbatm, "%s: binding driver %d: vendor %04x product %04x" + " rx: ep %02x padd %d tx: ep %02x padd %d\n", __func__, drv_ix, vendor[drv_ix], product[drv_ix], rx_endpoint[drv_ix], rx_padding[drv_ix], tx_endpoint[drv_ix], tx_padding[drv_ix]); if (!rx_ep_present && !tx_ep_present) { - usb_dbg(usbatm_instance, "%s: intf #%d has neither rx (%#x) nor tx (%#x) endpoint\n", + usb_dbg(usbatm, "%s: intf #%d has neither rx (%#x) nor tx (%#x) endpoint\n", __func__, intf->altsetting->desc.bInterfaceNumber, rx_endpoint[drv_ix], tx_endpoint[drv_ix]); return -ENODEV; @@ -93,25 +93,26 @@ static int xusbatm_bind(struct usbatm_data *usbatm_instance, if (cur_if != intf && usb_intf_has_ep(cur_if, searched_ep)) { ret = usb_driver_claim_interface(&xusbatm_usb_driver, - cur_if, usbatm_instance); + cur_if, usbatm); if (!ret) - usb_err(usbatm_instance, "%s: failed to claim interface #%d (%d)\n", + usb_err(usbatm, "%s: failed to claim interface #%d (%d)\n", __func__, cur_if->altsetting->desc.bInterfaceNumber, ret); return ret; } } - usb_err(usbatm_instance, "%s: no interface has endpoint %#x\n", + usb_err(usbatm, "%s: no interface has endpoint %#x\n", __func__, searched_ep); return -ENODEV; } -static void xusbatm_unbind(struct usbatm_data *usbatm_instance, +static void xusbatm_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) { struct usb_device *usb_dev = interface_to_usbdev(intf); int i; - usb_dbg(usbatm_instance, "%s entered\n", __func__); + + usb_dbg(usbatm, "%s entered\n", __func__); for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *cur_if = usb_dev->actconfig->interface[i]; @@ -120,10 +121,10 @@ static void xusbatm_unbind(struct usbatm_data *usbatm_instance, } } -static int xusbatm_atm_start(struct usbatm_data *usbatm_instance, +static int xusbatm_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_dev) { - atm_dbg(usbatm_instance, "%s entered\n", __func__); + atm_dbg(usbatm, "%s entered\n", __func__); /* use random MAC as we've no way to get it from the device */ random_ether_addr(atm_dev->esi); From 35644b0cce0ab8735944dcbfceb19e9e65da9a3d Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Tue, 17 Jan 2006 11:16:13 +0100 Subject: [PATCH 231/695] [PATCH] USBATM: add flags field Have minidrivers and the core signal special requirements using a flags field in struct usbatm_data. For the moment this is only used to replace the need_heavy_init bind parameter, but there'll be new flags in later patches. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 5 ++--- drivers/usb/atm/speedtch.c | 9 ++++----- drivers/usb/atm/ueagle-atm.c | 4 ++-- drivers/usb/atm/usbatm.c | 6 ++---- drivers/usb/atm/usbatm.h | 13 ++++++++----- drivers/usb/atm/xusbatm.c | 3 +-- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 139be1207d22..fc130b2171aa 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -666,8 +666,7 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, } static int cxacru_bind(struct usbatm_data *usbatm_instance, - struct usb_interface *intf, const struct usb_device_id *id, - int *need_heavy_init) + struct usb_interface *intf, const struct usb_device_id *id) { struct cxacru_data *instance; struct usb_device *usb_dev = interface_to_usbdev(intf); @@ -726,7 +725,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, usbatm_instance->driver_data = instance; - *need_heavy_init = cxacru_card_status(instance); + usbatm_instance->flags = (cxacru_card_status(instance) ? 0 : UDSL_SKIP_HEAVY_INIT); return 0; diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 211d467311e2..7b60d159dbed 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -681,8 +681,7 @@ static void speedtch_release_interfaces(struct usb_device *usb_dev, int num_inte static int speedtch_bind(struct usbatm_data *usbatm, struct usb_interface *intf, - const struct usb_device_id *id, - int *need_heavy_init) + const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(intf); struct usb_interface *cur_intf; @@ -754,11 +753,11 @@ static int speedtch_bind(struct usbatm_data *usbatm, 0x12, 0xc0, 0x07, 0x00, instance->scratch_buffer + OFFSET_7, SIZE_7, 500); - *need_heavy_init = (ret != SIZE_7); + usbatm->flags = (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0); - usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, need_heavy_init ? "not" : "already"); + usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not"); - if (*need_heavy_init) + if (!(usbatm->flags & UDSL_SKIP_HEAVY_INIT)) if ((ret = usb_reset_device(usb_dev)) < 0) { usb_err(usbatm, "%s: device reset failed (%d)!\n", __func__, ret); goto fail_free; diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 7d2a679989ed..3ba896291eb4 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1617,7 +1617,7 @@ static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf) } static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, - const struct usb_device_id *id, int *heavy) + const struct usb_device_id *id) { struct usb_device *usb = interface_to_usbdev(intf); struct uea_softc *sc; @@ -1629,7 +1629,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, if (ifnum != UEA_INTR_IFACE_NO) return -ENODEV; - *heavy = sync_wait[modem_index]; + usbatm_instance->flags = (sync_wait[modem_index] ? 0 : UDSL_SKIP_HEAVY_INIT); /* interface 1 is for outbound traffic */ ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO); diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 779f86ecdd76..2eb8552dac12 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -969,7 +969,6 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, char *buf; int error = -ENOMEM; int i, length; - int need_heavy; dev_dbg(dev, "%s: trying driver %s with vendor=%04x, product=%04x, ifnum %2d\n", __func__, driver->driver_name, @@ -1014,8 +1013,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, snprintf(buf, length, ")"); bind: - need_heavy = 1; - if (driver->bind && (error = driver->bind(instance, intf, id, &need_heavy)) < 0) { + if (driver->bind && (error = driver->bind(instance, intf, id)) < 0) { dev_err(dev, "%s: bind failed: %d!\n", __func__, error); goto fail_free; } @@ -1098,7 +1096,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb); } - if (need_heavy && driver->heavy_init) { + if (!(instance->flags & UDSL_SKIP_HEAVY_INIT) && driver->heavy_init) { error = usbatm_heavy_init(instance); } else { complete(&instance->thread_exited); /* pretend that heavy_init was run */ diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index ebb79da4cb15..b29eb807f203 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -84,6 +84,11 @@ #endif +/* flags, set by mini-driver in bind() */ + +#define UDSL_SKIP_HEAVY_INIT (1<<0) + + /* mini driver */ struct usbatm_data; @@ -99,12 +104,9 @@ struct usbatm_driver { const char *driver_name; - /* - * init device ... can sleep, or cause probe() failure. Drivers with a heavy_init - * method can avoid having it called by setting need_heavy_init to zero. - */ + /* init device ... can sleep, or cause probe() failure */ int (*bind) (struct usbatm_data *, struct usb_interface *, - const struct usb_device_id *id, int *need_heavy_init); + const struct usb_device_id *id); /* additional device initialization that is too slow to be done in probe() */ int (*heavy_init) (struct usbatm_data *, struct usb_interface *); @@ -152,6 +154,7 @@ struct usbatm_data { struct usbatm_driver *driver; void *driver_data; char driver_name[16]; + unsigned int flags; /* set by mini-driver in bind() */ /* USB device */ struct usb_device *usb_dev; diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index 8f55642f376f..172c82174397 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c @@ -62,8 +62,7 @@ static int usb_intf_has_ep(const struct usb_interface *intf, u8 ep) } static int xusbatm_bind(struct usbatm_data *usbatm, - struct usb_interface *intf, const struct usb_device_id *id, - int *need_heavy_init) + struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(intf); int drv_ix = id - xusbatm_usb_ids; From 0dfcd3e4444e88285ee7c199d0cbda21551d8c5d Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 09:36:20 +0100 Subject: [PATCH 232/695] [PATCH] USBATM: remove .owner Remove the unused .owner field in struct usbatm_driver. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 1 - drivers/usb/atm/speedtch.c | 1 - drivers/usb/atm/ueagle-atm.c | 3 +-- drivers/usb/atm/usbatm.h | 2 -- drivers/usb/atm/xusbatm.c | 1 - 5 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index fc130b2171aa..0b02a6d9f243 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -833,7 +833,6 @@ static const struct usb_device_id cxacru_usb_ids[] = { MODULE_DEVICE_TABLE(usb, cxacru_usb_ids); static struct usbatm_driver cxacru_driver = { - .owner = THIS_MODULE, .driver_name = cxacru_driver_name, .bind = cxacru_bind, .heavy_init = cxacru_heavy_init, diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 7b60d159dbed..1aca0b08f192 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -793,7 +793,6 @@ static void speedtch_unbind(struct usbatm_data *usbatm, struct usb_interface *in ***********/ static struct usbatm_driver speedtch_usbatm_driver = { - .owner = THIS_MODULE, .driver_name = speedtch_driver_name, .bind = speedtch_bind, .heavy_init = speedtch_heavy_init, diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 3ba896291eb4..aa072ad953a6 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1629,7 +1629,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, if (ifnum != UEA_INTR_IFACE_NO) return -ENODEV; - usbatm_instance->flags = (sync_wait[modem_index] ? 0 : UDSL_SKIP_HEAVY_INIT); + usbatm->flags = (sync_wait[modem_index] ? 0 : UDSL_SKIP_HEAVY_INIT); /* interface 1 is for outbound traffic */ ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO); @@ -1701,7 +1701,6 @@ static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) static struct usbatm_driver uea_usbatm_driver = { .driver_name = "ueagle-atm", - .owner = THIS_MODULE, .bind = uea_bind, .atm_start = uea_atm_open, .unbind = uea_unbind, diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index b29eb807f203..4b923a83555e 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -100,8 +100,6 @@ struct usbatm_data; */ struct usbatm_driver { - struct module *owner; - const char *driver_name; /* init device ... can sleep, or cause probe() failure */ diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index 172c82174397..ad5d3ff88dd9 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c @@ -166,7 +166,6 @@ static int __init xusbatm_init(void) xusbatm_usb_ids[i].idProduct = product[i]; - xusbatm_drivers[i].owner = THIS_MODULE; xusbatm_drivers[i].driver_name = xusbatm_driver_name; xusbatm_drivers[i].bind = xusbatm_bind; xusbatm_drivers[i].unbind = xusbatm_unbind; From 9a734efec36c991a74610c6c81d28d4222e1c02b Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 09:38:22 +0100 Subject: [PATCH 233/695] [PATCH] USBATM: kzalloc conversion Convert kmalloc + memset to kzalloc. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 4 +--- drivers/usb/atm/speedtch.c | 4 +--- drivers/usb/atm/usbatm.c | 8 +++----- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 0b02a6d9f243..675fdbd5967e 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -673,14 +673,12 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, int ret; /* instance init */ - instance = kmalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc(sizeof(*instance), GFP_KERNEL); if (!instance) { dbg("cxacru_bind: no memory for instance data"); return -ENOMEM; } - memset(instance, 0, sizeof(*instance)); - instance->usbatm = usbatm_instance; instance->modem_type = (struct cxacru_modem_type *) id->driver_info; diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 1aca0b08f192..43ec758b92b5 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -715,7 +715,7 @@ static int speedtch_bind(struct usbatm_data *usbatm, } } - instance = kmalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc(sizeof(*instance), GFP_KERNEL); if (!instance) { usb_err(usbatm, "%s: no memory for instance data!\n", __func__); @@ -723,8 +723,6 @@ static int speedtch_bind(struct usbatm_data *usbatm, goto fail_release; } - memset(instance, 0, sizeof(struct speedtch_instance_data)); - instance->usbatm = usbatm; INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 2eb8552dac12..3ed5f02c36d3 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -763,13 +763,12 @@ static int usbatm_atm_open(struct atm_vcc *vcc) goto fail; } - if (!(new = kmalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) { + if (!(new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) { atm_err(instance, "%s: no memory for vcc_data!\n", __func__); ret = -ENOMEM; goto fail; } - memset(new, 0, sizeof(struct usbatm_vcc_data)); new->vcc = vcc; new->vpi = vpi; new->vci = vci; @@ -1066,13 +1065,12 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, instance->urbs[i] = urb; - buffer = kmalloc(channel->buf_size, GFP_KERNEL); + /* zero the tx padding to avoid leaking information */ + buffer = kzalloc(channel->buf_size, GFP_KERNEL); if (!buffer) { dev_err(dev, "%s: no memory for buffer %d!\n", __func__, i); goto fail_unbind; } - /* zero the tx padding to avoid leaking information */ - memset(buffer, 0, channel->buf_size); usb_fill_bulk_urb(urb, instance->usb_dev, channel->endpoint, buffer, channel->buf_size, usbatm_complete, channel); From 233c08e0ff303e659a9003d49b15608f59f08a64 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 09:48:36 +0100 Subject: [PATCH 234/695] [PATCH] USBATM: xusbatm rewrite The xusbatm driver is for otherwise unsupported modems. All it does is grab hold of a user-specified set of interfaces - the generic usbatm core methods (hopefully) do the rest. As Aurelio Arroyo discovered when he tried to use xusbatm (big mistake!), the interface grabbing logic was completely borked. Here is a rewrite that works. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/xusbatm.c | 114 +++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 37 deletions(-) diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index ad5d3ff88dd9..83848ee2c6fe 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c @@ -41,6 +41,8 @@ XUSBATM_PARM(rx_endpoint, unsigned char, byte, "rx endpoint number"); XUSBATM_PARM(tx_endpoint, unsigned char, byte, "tx endpoint number"); XUSBATM_PARM(rx_padding, unsigned char, byte, "rx padding (default 0)"); XUSBATM_PARM(tx_padding, unsigned char, byte, "tx padding (default 0)"); +XUSBATM_PARM(rx_altsetting, unsigned char, byte, "rx altsetting (default 0)"); +XUSBATM_PARM(tx_altsetting, unsigned char, byte, "rx altsetting (default 0)"); static const char xusbatm_driver_name[] = "xusbatm"; @@ -48,61 +50,94 @@ static struct usbatm_driver xusbatm_drivers[XUSBATM_DRIVERS_MAX]; static struct usb_device_id xusbatm_usb_ids[XUSBATM_DRIVERS_MAX + 1]; static struct usb_driver xusbatm_usb_driver; -static int usb_intf_has_ep(const struct usb_interface *intf, u8 ep) +static struct usb_interface *xusbatm_find_intf (struct usb_device *usb_dev, int altsetting, u8 ep) { + struct usb_host_interface *alt; + struct usb_interface *intf; int i, j; - for (i = 0; i < intf->num_altsetting; i++) { - struct usb_host_interface *alt = intf->altsetting; - for (j = 0; j < alt->desc.bNumEndpoints; j++) - if ((alt->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) == ep) - return 1; + for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) + if ((intf = usb_dev->actconfig->interface[i]) && (alt = usb_altnum_to_altsetting(intf, altsetting))) + for (j = 0; j < alt->desc.bNumEndpoints; j++) + if (alt->endpoint[j].desc.bEndpointAddress == ep) + return intf; + return NULL; +} + +static int xusbatm_capture_intf (struct usbatm_data *usbatm, struct usb_device *usb_dev, + struct usb_interface *intf, int altsetting, int claim) +{ + int ifnum = intf->altsetting->desc.bInterfaceNumber; + int ret; + + if (claim && (ret = usb_driver_claim_interface(&xusbatm_usb_driver, intf, usbatm))) { + usb_err(usbatm, "%s: failed to claim interface %2d (%d)!\n", __func__, ifnum, ret); + return ret; + } + if ((ret = usb_set_interface(usb_dev, ifnum, altsetting))) { + usb_err(usbatm, "%s: altsetting %2d for interface %2d failed (%d)!\n", __func__, altsetting, ifnum, ret); + return ret; } return 0; } +static void xusbatm_release_intf (struct usb_device *usb_dev, struct usb_interface *intf, int claimed) +{ + if (claimed) { + usb_set_intfdata(intf, NULL); + usb_driver_release_interface(&xusbatm_usb_driver, intf); + } +} + static int xusbatm_bind(struct usbatm_data *usbatm, struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(intf); int drv_ix = id - xusbatm_usb_ids; - int rx_ep_present = usb_intf_has_ep(intf, rx_endpoint[drv_ix]); - int tx_ep_present = usb_intf_has_ep(intf, tx_endpoint[drv_ix]); - u8 searched_ep = rx_ep_present ? tx_endpoint[drv_ix] : rx_endpoint[drv_ix]; - int i, ret; + int rx_alt = rx_altsetting[drv_ix]; + int tx_alt = tx_altsetting[drv_ix]; + struct usb_interface *rx_intf = xusbatm_find_intf(usb_dev, rx_alt, rx_endpoint[drv_ix]); + struct usb_interface *tx_intf = xusbatm_find_intf(usb_dev, tx_alt, tx_endpoint[drv_ix]); + int ret; usb_dbg(usbatm, "%s: binding driver %d: vendor %04x product %04x" - " rx: ep %02x padd %d tx: ep %02x padd %d\n", + " rx: ep %02x padd %d alt %2d tx: ep %02x padd %d alt %2d\n", __func__, drv_ix, vendor[drv_ix], product[drv_ix], - rx_endpoint[drv_ix], rx_padding[drv_ix], - tx_endpoint[drv_ix], tx_padding[drv_ix]); + rx_endpoint[drv_ix], rx_padding[drv_ix], rx_alt, + tx_endpoint[drv_ix], tx_padding[drv_ix], tx_alt); - if (!rx_ep_present && !tx_ep_present) { - usb_dbg(usbatm, "%s: intf #%d has neither rx (%#x) nor tx (%#x) endpoint\n", - __func__, intf->altsetting->desc.bInterfaceNumber, - rx_endpoint[drv_ix], tx_endpoint[drv_ix]); + if (!rx_intf || !tx_intf) { + if (!rx_intf) + usb_dbg(usbatm, "%s: no interface contains endpoint %02x in altsetting %2d\n", + __func__, rx_endpoint[drv_ix], rx_alt); + if (!tx_intf) + usb_dbg(usbatm, "%s: no interface contains endpoint %02x in altsetting %2d\n", + __func__, tx_endpoint[drv_ix], tx_alt); return -ENODEV; } - if (rx_ep_present && tx_ep_present) - return 0; + if ((rx_intf != intf) && (tx_intf != intf)) + return -ENODEV; - for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) { - struct usb_interface *cur_if = usb_dev->actconfig->interface[i]; - - if (cur_if != intf && usb_intf_has_ep(cur_if, searched_ep)) { - ret = usb_driver_claim_interface(&xusbatm_usb_driver, - cur_if, usbatm); - if (!ret) - usb_err(usbatm, "%s: failed to claim interface #%d (%d)\n", - __func__, cur_if->altsetting->desc.bInterfaceNumber, ret); - return ret; - } + if ((rx_intf == tx_intf) && (rx_alt != tx_alt)) { + usb_err(usbatm, "%s: altsettings clash on interface %2d (%2d vs %2d)!\n", __func__, + rx_intf->altsetting->desc.bInterfaceNumber, rx_alt, tx_alt); + return -EINVAL; } - usb_err(usbatm, "%s: no interface has endpoint %#x\n", - __func__, searched_ep); - return -ENODEV; + usb_dbg(usbatm, "%s: rx If#=%2d; tx If#=%2d\n", __func__, + rx_intf->altsetting->desc.bInterfaceNumber, + tx_intf->altsetting->desc.bInterfaceNumber); + + if ((ret = xusbatm_capture_intf(usbatm, usb_dev, rx_intf, rx_alt, rx_intf != intf))) + return ret; + + if ((tx_intf != rx_intf) && (ret = xusbatm_capture_intf(usbatm, usb_dev, tx_intf, tx_alt, tx_intf != intf))) { + xusbatm_release_intf(usb_dev, rx_intf, rx_intf != intf); + return ret; + } + + return 0; } static void xusbatm_unbind(struct usbatm_data *usbatm, @@ -114,9 +149,12 @@ static void xusbatm_unbind(struct usbatm_data *usbatm, usb_dbg(usbatm, "%s entered\n", __func__); for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) { - struct usb_interface *cur_if = usb_dev->actconfig->interface[i]; - usb_set_intfdata(cur_if, NULL); - usb_driver_release_interface(&xusbatm_usb_driver, cur_if); + struct usb_interface *cur_intf = usb_dev->actconfig->interface[i]; + + if (cur_intf && (usb_get_intfdata(cur_intf) == usbatm)) { + usb_set_intfdata(cur_intf, NULL); + usb_driver_release_interface(&xusbatm_usb_driver, cur_intf); + } } } @@ -161,11 +199,13 @@ static int __init xusbatm_init(void) } for (i = 0; i < num_vendor; i++) { + rx_endpoint[i] |= USB_DIR_IN; + tx_endpoint[i] &= USB_ENDPOINT_NUMBER_MASK; + xusbatm_usb_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE; xusbatm_usb_ids[i].idVendor = vendor[i]; xusbatm_usb_ids[i].idProduct = product[i]; - xusbatm_drivers[i].driver_name = xusbatm_driver_name; xusbatm_drivers[i].bind = xusbatm_bind; xusbatm_drivers[i].unbind = xusbatm_unbind; From 0e42a627ec3d8defa0c43cff94b8f2080a070716 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 10:05:15 +0100 Subject: [PATCH 235/695] [PATCH] USBATM: shutdown open connections when disconnected This patch causes vcc_release_async to be applied to any open vcc's when the modem is disconnected. This signals a socket shutdown, letting the socket user know that the game is up. I wrote this patch because of reports that pppd would keep connections open forever when the modem is disconnected. This patch does not fix that problem, but it's a step in the right direction. It doesn't help because the pppoatm module doesn't yet monitor state changes on the ATM socket, so simply never realises that the ATM connection has gone down (meaning it doesn't tell the ppp layer). But at least there is a socket state change now. Unfortunately this patch may create problems for those rare users like me who use routed IP or some other non-ppp connection method that goes via the ATM ARP daemon: the daemon is buggy, and with this patch will crash when the modem is disconnected. Users with a buggy atmarpd can simply restart it after disconnecting the modem. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/usbatm.c | 66 ++++++++++++++++++++++++++++------------ drivers/usb/atm/usbatm.h | 1 + 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 3ed5f02c36d3..e660a1ebf12b 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -602,8 +602,12 @@ static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) vdbg("%s called (skb 0x%p, len %u)", __func__, skb, skb->len); - if (!instance) { - dbg("%s: NULL data!", __func__); + /* racy disconnection check - fine */ + if (!instance || instance->disconnected) { +#ifdef DEBUG + if (printk_ratelimit()) + printk(KERN_DEBUG "%s: %s!\n", __func__, instance ? "disconnected" : "NULL instance"); +#endif err = -ENODEV; goto fail; } @@ -715,15 +719,19 @@ static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *pag atomic_read(&atm_dev->stats.aal5.rx_err), atomic_read(&atm_dev->stats.aal5.rx_drop)); - if (!left--) - switch (atm_dev->signal) { - case ATM_PHY_SIG_FOUND: - return sprintf(page, "Line up\n"); - case ATM_PHY_SIG_LOST: - return sprintf(page, "Line down\n"); - default: - return sprintf(page, "Line state unknown\n"); - } + if (!left--) { + if (instance->disconnected) + return sprintf(page, "Disconnected\n"); + else + switch (atm_dev->signal) { + case ATM_PHY_SIG_FOUND: + return sprintf(page, "Line up\n"); + case ATM_PHY_SIG_LOST: + return sprintf(page, "Line down\n"); + default: + return sprintf(page, "Line state unknown\n"); + } + } return 0; } @@ -757,6 +765,12 @@ static int usbatm_atm_open(struct atm_vcc *vcc) down(&instance->serialize); /* vs self, usbatm_atm_close, usbatm_usb_disconnect */ + if (instance->disconnected) { + atm_dbg(instance, "%s: disconnected!\n", __func__); + ret = -ENODEV; + goto fail; + } + if (usbatm_find_vcc(instance, vpi, vci)) { atm_dbg(instance, "%s: %hd/%d already in use!\n", __func__, vpi, vci); ret = -EADDRINUSE; @@ -845,6 +859,13 @@ static void usbatm_atm_close(struct atm_vcc *vcc) static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user * arg) { + struct usbatm_data *instance = atm_dev->dev_data; + + if (!instance || instance->disconnected) { + dbg("%s: %s!", __func__, instance ? "disconnected" : "NULL instance"); + return -ENODEV; + } + switch (cmd) { case ATM_QUERYLOOP: return put_user(ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0; @@ -1129,6 +1150,7 @@ void usbatm_usb_disconnect(struct usb_interface *intf) { struct device *dev = &intf->dev; struct usbatm_data *instance = usb_get_intfdata(intf); + struct usbatm_vcc_data *vcc_data; int i; dev_dbg(dev, "%s entered\n", __func__); @@ -1141,12 +1163,18 @@ void usbatm_usb_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); down(&instance->serialize); + instance->disconnected = 1; if (instance->thread_pid >= 0) kill_proc(instance->thread_pid, SIGTERM, 1); up(&instance->serialize); wait_for_completion(&instance->thread_exited); + down(&instance->serialize); + list_for_each_entry(vcc_data, &instance->vcc_list, list) + vcc_release_async(vcc_data->vcc, -EPIPE); + up(&instance->serialize); + tasklet_disable(&instance->rx_channel.tasklet); tasklet_disable(&instance->tx_channel.tasklet); @@ -1156,6 +1184,14 @@ void usbatm_usb_disconnect(struct usb_interface *intf) del_timer_sync(&instance->rx_channel.delay); del_timer_sync(&instance->tx_channel.delay); + /* turn usbatm_[rt]x_process into something close to a no-op */ + /* no need to take the spinlock */ + INIT_LIST_HEAD(&instance->rx_channel.list); + INIT_LIST_HEAD(&instance->tx_channel.list); + + tasklet_enable(&instance->rx_channel.tasklet); + tasklet_enable(&instance->tx_channel.tasklet); + if (instance->atm_dev && instance->driver->atm_stop) instance->driver->atm_stop(instance, instance->atm_dev); @@ -1164,14 +1200,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf) instance->driver_data = NULL; - /* turn usbatm_[rt]x_process into noop */ - /* no need to take the spinlock */ - INIT_LIST_HEAD(&instance->rx_channel.list); - INIT_LIST_HEAD(&instance->tx_channel.list); - - tasklet_enable(&instance->rx_channel.tasklet); - tasklet_enable(&instance->tx_channel.tasklet); - for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) { kfree(instance->urbs[i]->transfer_buffer); usb_free_urb(instance->urbs[i]); diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index 4b923a83555e..1a31cf87bb1f 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -168,6 +168,7 @@ struct usbatm_data { struct kref refcount; struct semaphore serialize; + int disconnected; /* heavy init */ int thread_pid; From 72ef8ab43f5a82e9e2dea247702bf433d6509f87 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 10:07:08 +0100 Subject: [PATCH 236/695] [PATCH] USBATM: return correct error code when out of memory We weren't always returning -ENOMEM. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/usbatm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index e660a1ebf12b..103764df47ea 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -1081,6 +1081,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, urb = usb_alloc_urb(iso_packets, GFP_KERNEL); if (!urb) { dev_err(dev, "%s: no memory for urb %d!\n", __func__, i); + error = -ENOMEM; goto fail_unbind; } @@ -1090,6 +1091,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, buffer = kzalloc(channel->buf_size, GFP_KERNEL); if (!buffer) { dev_err(dev, "%s: no memory for buffer %d!\n", __func__, i); + error = -ENOMEM; goto fail_unbind; } From 227d77611b31df5d9afa572b984f73640f54d490 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 10:13:19 +0100 Subject: [PATCH 237/695] [PATCH] USBATM: use dev_kfree_skb_any rather than dev_kfree_skb In one spot (usbatm_cancel_send) we were calling dev_kfree_skb with irqs disabled. This mistake is just too easy to make, so systematically use dev_kfree_skb_any rather than dev_kfree_skb. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/usbatm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 103764df47ea..98b74b9dcdd2 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -199,7 +200,7 @@ static inline void usbatm_pop(struct atm_vcc *vcc, struct sk_buff *skb) if (vcc->pop) vcc->pop(vcc, skb); else - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); } @@ -397,7 +398,7 @@ static void usbatm_extract_cells(struct usbatm_data *instance, if (!atm_charge(vcc, skb->truesize)) { atm_rldbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n", __func__, skb->truesize); - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); goto out; /* atm_charge increments rx_drop */ } From 6f7494759870ec6fbb066f7202c5585fe36fbe82 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 10:52:38 +0100 Subject: [PATCH 238/695] [PATCH] USBATM: measure buffer size in bytes; force valid sizes Change the module parameters rcv_buf_size and snd_buf_size to specify buffer sizes in bytes rather than ATM cells. Since there is some danger that users may not notice this change, the parameters are renamed to rcv_buf_bytes etc. The transmit buffer needs to be a multiple of the ATM cell size in length, while the receive buffer should be a multiple of the endpoint maxpacket size (this wasn't enforced before, which causes trouble with isochronous transfers), so enforce these restrictions. Now that the usbatm probe method inspects the endpoint maxpacket size, minidriver bind routines need to set the correct alternate setting for the interface in their bind routine. This is the reason for the speedtch changes. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/speedtch.c | 30 ++++++++++--- drivers/usb/atm/usbatm.c | 90 +++++++++++++++++++++++++------------- 2 files changed, 84 insertions(+), 36 deletions(-) diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 43ec758b92b5..0e981672f149 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -89,6 +89,7 @@ MODULE_PARM_DESC(sw_buffering, "Enable software buffering (default: " __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); +#define INTERFACE_DATA 1 #define ENDPOINT_INT 0x81 #define ENDPOINT_DATA 0x07 #define ENDPOINT_FIRMWARE 0x05 @@ -98,6 +99,8 @@ MODULE_PARM_DESC(sw_buffering, struct speedtch_instance_data { struct usbatm_data *usbatm; + unsigned int altsetting; + struct work_struct status_checker; unsigned char last_status; @@ -270,6 +273,11 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, because we're in our own kernel thread anyway. */ msleep_interruptible(1000); + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { + usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret); + goto out_free; + } + /* Enable software buffering, if requested */ if (sw_buffering) speedtch_set_swbuff(instance, 1); @@ -586,11 +594,6 @@ static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_de atm_dbg(usbatm, "%s entered\n", __func__); - if ((ret = usb_set_interface(usb_dev, 1, altsetting)) < 0) { - atm_dbg(usbatm, "%s: usb_set_interface returned %d!\n", __func__, ret); - return ret; - } - /* Set MAC address, it is stored in the serial number */ memset(atm_dev->esi, 0, sizeof(atm_dev->esi)); if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { @@ -725,6 +728,23 @@ static int speedtch_bind(struct usbatm_data *usbatm, instance->usbatm = usbatm; + /* altsetting may change at any moment, so take a snapshot */ + instance->altsetting = altsetting; + + if (instance->altsetting) + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { + usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->altsetting, ret); + instance->altsetting = 0; /* fall back to default */ + } + + if (!instance->altsetting) { + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ALTSETTING)) < 0) { + usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ALTSETTING, ret); + goto fail_free; + } + instance->altsetting = DEFAULT_ALTSETTING; + } + INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); instance->status_checker.timer.function = speedtch_status_poll; diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 98b74b9dcdd2..1d829c29c86d 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -99,12 +99,11 @@ static const char usbatm_driver_name[] = "usbatm"; #define UDSL_MAX_RCV_URBS 16 #define UDSL_MAX_SND_URBS 16 -#define UDSL_MAX_RCV_BUF_SIZE 1024 /* ATM cells */ -#define UDSL_MAX_SND_BUF_SIZE 1024 /* ATM cells */ +#define UDSL_MAX_BUF_SIZE 64 * 1024 /* bytes */ #define UDSL_DEFAULT_RCV_URBS 4 #define UDSL_DEFAULT_SND_URBS 4 -#define UDSL_DEFAULT_RCV_BUF_SIZE 64 /* ATM cells */ -#define UDSL_DEFAULT_SND_BUF_SIZE 64 /* ATM cells */ +#define UDSL_DEFAULT_RCV_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ +#define UDSL_DEFAULT_SND_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ #define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD) @@ -112,8 +111,8 @@ static const char usbatm_driver_name[] = "usbatm"; static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS; static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS; -static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE; -static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE; +static unsigned int rcv_buf_bytes = UDSL_DEFAULT_RCV_BUF_SIZE; +static unsigned int snd_buf_bytes = UDSL_DEFAULT_SND_BUF_SIZE; module_param(num_rcv_urbs, uint, S_IRUGO); MODULE_PARM_DESC(num_rcv_urbs, @@ -127,15 +126,15 @@ MODULE_PARM_DESC(num_snd_urbs, __MODULE_STRING(UDSL_MAX_SND_URBS) ", default: " __MODULE_STRING(UDSL_DEFAULT_SND_URBS) ")"); -module_param(rcv_buf_size, uint, S_IRUGO); -MODULE_PARM_DESC(rcv_buf_size, - "Size of the buffers used for reception in ATM cells (range: 1-" - __MODULE_STRING(UDSL_MAX_RCV_BUF_SIZE) ", default: " +module_param(rcv_buf_bytes, uint, S_IRUGO); +MODULE_PARM_DESC(rcv_buf_bytes, + "Size of the buffers used for reception, in bytes (range: 1-" + __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: " __MODULE_STRING(UDSL_DEFAULT_RCV_BUF_SIZE) ")"); -module_param(snd_buf_size, uint, S_IRUGO); -MODULE_PARM_DESC(snd_buf_size, - "Size of the buffers used for transmission in ATM cells (range: 1-" +module_param(snd_buf_bytes, uint, S_IRUGO); +MODULE_PARM_DESC(snd_buf_bytes, + "Size of the buffers used for transmission, in bytes (range: 1-" __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: " __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")"); @@ -430,14 +429,14 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance, { struct usbatm_control *ctrl = UDSL_SKB(skb); struct atm_vcc *vcc = ctrl->atm.vcc; - unsigned int num_written; + unsigned int bytes_written; unsigned int stride = instance->tx_channel.stride; vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space); UDSL_ASSERT(!(avail_space % stride)); - for (num_written = 0; num_written < avail_space && ctrl->len; - num_written += stride, target += stride) { + for (bytes_written = 0; bytes_written < avail_space && ctrl->len; + bytes_written += stride, target += stride) { unsigned int data_len = min_t(unsigned int, skb->len, ATM_CELL_PAYLOAD); unsigned int left = ATM_CELL_PAYLOAD - data_len; u8 *ptr = target; @@ -480,7 +479,7 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance, ctrl->crc = crc32_be(ctrl->crc, ptr, left); } - return num_written; + return bytes_written; } @@ -524,7 +523,7 @@ static void usbatm_tx_process(unsigned long data) struct sk_buff *skb = instance->current_skb; struct urb *urb = NULL; const unsigned int buf_size = instance->tx_channel.buf_size; - unsigned int num_written = 0; + unsigned int bytes_written = 0; u8 *buffer = NULL; if (!skb) @@ -536,16 +535,16 @@ static void usbatm_tx_process(unsigned long data) if (!urb) break; /* no more senders */ buffer = urb->transfer_buffer; - num_written = (urb->status == -EAGAIN) ? + bytes_written = (urb->status == -EAGAIN) ? urb->transfer_buffer_length : 0; } - num_written += usbatm_write_cells(instance, skb, - buffer + num_written, - buf_size - num_written); + bytes_written += usbatm_write_cells(instance, skb, + buffer + bytes_written, + buf_size - bytes_written); vdbg("%s: wrote %u bytes from skb 0x%p to urb 0x%p", - __func__, num_written, skb, urb); + __func__, bytes_written, skb, urb); if (!UDSL_SKB(skb)->len) { struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc; @@ -556,8 +555,8 @@ static void usbatm_tx_process(unsigned long data) skb = skb_dequeue(&instance->sndqueue); } - if (num_written == buf_size || (!skb && num_written)) { - urb->transfer_buffer_length = num_written; + if (bytes_written == buf_size || (!skb && bytes_written)) { + urb->transfer_buffer_length = bytes_written; if (usbatm_submit_urb(urb)) break; @@ -990,6 +989,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, char *buf; int error = -ENOMEM; int i, length; + unsigned int maxpacket, num_packets; dev_dbg(dev, "%s: trying driver %s with vendor=%04x, product=%04x, ifnum %2d\n", __func__, driver->driver_name, @@ -1058,10 +1058,38 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out); instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding; instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding; - instance->rx_channel.buf_size = rcv_buf_size * instance->rx_channel.stride; - instance->tx_channel.buf_size = snd_buf_size * instance->tx_channel.stride; instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance; + /* tx buffer size must be a positive multiple of the stride */ + instance->tx_channel.buf_size = max (instance->tx_channel.stride, + snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride)); + + /* rx buffer size must be a positive multiple of the endpoint maxpacket */ + maxpacket = usb_maxpacket(usb_dev, instance->rx_channel.endpoint, 0); + + if ((maxpacket < 1) || (maxpacket > UDSL_MAX_BUF_SIZE)) { + dev_err(dev, "%s: invalid endpoint %02x!\n", __func__, + usb_pipeendpoint(instance->rx_channel.endpoint)); + error = -EINVAL; + goto fail_unbind; + } + + num_packets = max (1U, (rcv_buf_bytes + maxpacket / 2) / maxpacket); /* round */ + + if (num_packets * maxpacket > UDSL_MAX_BUF_SIZE) + num_packets--; + + instance->rx_channel.buf_size = num_packets * maxpacket; + +#ifdef DEBUG + for (i = 0; i < 2; i++) { + struct usbatm_channel *channel = i ? + &instance->tx_channel : &instance->rx_channel; + + dev_dbg(dev, "%s: using %d byte buffer for %s channel 0x%p\n", __func__, channel->buf_size, i ? "tx" : "rx", channel); + } +#endif + skb_queue_head_init(&instance->sndqueue); for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) { @@ -1232,10 +1260,10 @@ static int __init usbatm_usb_init(void) if ((num_rcv_urbs > UDSL_MAX_RCV_URBS) || (num_snd_urbs > UDSL_MAX_SND_URBS) - || (rcv_buf_size < 1) - || (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE) - || (snd_buf_size < 1) - || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE)) + || (rcv_buf_bytes < 1) + || (rcv_buf_bytes > UDSL_MAX_BUF_SIZE) + || (snd_buf_bytes < 1) + || (snd_buf_bytes > UDSL_MAX_BUF_SIZE)) return -EINVAL; return 0; From 80aae7a17afd21f7ba900dd566fb23a2444021f8 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 10:59:23 +0100 Subject: [PATCH 239/695] [PATCH] USBATM: allow isochronous transfer While the usbatm core has had some support for using isoc urbs for some time, there was no way for users to turn it on. While use of isoc transfer should still be considered experimental, it now works well enough to let users turn it on. Minidrivers signal to the core that they want to use isoc transfer by setting the new UDSL_USE_ISOC flag. The speedtch minidriver gets a new module parameter enable_isoc (defaults to false), plus some logic that checks for the existence of an isoc receive endpoint (not all speedtouch modems have one). Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 4 +- drivers/usb/atm/speedtch.c | 82 +++++++++++++++++++++++++++++------- drivers/usb/atm/ueagle-atm.c | 4 +- drivers/usb/atm/usbatm.c | 30 ++++++------- drivers/usb/atm/usbatm.h | 7 ++- drivers/usb/atm/xusbatm.c | 4 +- 6 files changed, 92 insertions(+), 39 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 675fdbd5967e..70a96e98152c 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -836,8 +836,8 @@ static struct usbatm_driver cxacru_driver = { .heavy_init = cxacru_heavy_init, .unbind = cxacru_unbind, .atm_start = cxacru_atm_start, - .in = CXACRU_EP_DATA, - .out = CXACRU_EP_DATA, + .bulk_in = CXACRU_EP_DATA, + .bulk_out = CXACRU_EP_DATA, .rx_padding = 3, .tx_padding = 11, }; diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 0e981672f149..8c1c560cf051 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include #include "usbatm.h" @@ -66,24 +68,33 @@ static const char speedtch_driver_name[] = "speedtch"; #define RESUBMIT_DELAY 1000 /* milliseconds */ -#define DEFAULT_ALTSETTING 1 +#define DEFAULT_BULK_ALTSETTING 1 +#define DEFAULT_ISOC_ALTSETTING 2 #define DEFAULT_DL_512_FIRST 0 +#define DEFAULT_ENABLE_ISOC 0 #define DEFAULT_SW_BUFFERING 0 -static int altsetting = DEFAULT_ALTSETTING; +static unsigned int altsetting = 0; /* zero means: use the default */ static int dl_512_first = DEFAULT_DL_512_FIRST; +static int enable_isoc = DEFAULT_ENABLE_ISOC; static int sw_buffering = DEFAULT_SW_BUFFERING; -module_param(altsetting, int, S_IRUGO | S_IWUSR); +module_param(altsetting, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(altsetting, - "Alternative setting for data interface (default: " - __MODULE_STRING(DEFAULT_ALTSETTING) ")"); + "Alternative setting for data interface (bulk_default: " + __MODULE_STRING(DEFAULT_BULK_ALTSETTING) "; isoc_default: " + __MODULE_STRING(DEFAULT_ISOC_ALTSETTING) ")"); module_param(dl_512_first, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(dl_512_first, "Read 512 bytes before sending firmware (default: " __MODULE_STRING(DEFAULT_DL_512_FIRST) ")"); +module_param(enable_isoc, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(enable_isoc, + "Use isochronous transfers if available (default: " + __MODULE_STRING(DEFAULT_ENABLE_ISOC) ")"); + module_param(sw_buffering, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(sw_buffering, "Enable software buffering (default: " @@ -91,7 +102,8 @@ MODULE_PARM_DESC(sw_buffering, #define INTERFACE_DATA 1 #define ENDPOINT_INT 0x81 -#define ENDPOINT_DATA 0x07 +#define ENDPOINT_BULK_DATA 0x07 +#define ENDPOINT_ISOC_DATA 0x07 #define ENDPOINT_FIRMWARE 0x05 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) @@ -687,11 +699,12 @@ static int speedtch_bind(struct usbatm_data *usbatm, const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(intf); - struct usb_interface *cur_intf; + struct usb_interface *cur_intf, *data_intf; struct speedtch_instance_data *instance; int ifnum = intf->altsetting->desc.bInterfaceNumber; int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; int i, ret; + int use_isoc; usb_dbg(usbatm, "%s entered\n", __func__); @@ -702,6 +715,11 @@ static int speedtch_bind(struct usbatm_data *usbatm, return -ENODEV; } + if (!(data_intf = usb_ifnum_to_if(usb_dev, INTERFACE_DATA))) { + usb_err(usbatm, "%s: data interface not found!\n", __func__); + return -ENODEV; + } + /* claim all interfaces */ for (i=0; i < num_interfaces; i++) { @@ -728,8 +746,9 @@ static int speedtch_bind(struct usbatm_data *usbatm, instance->usbatm = usbatm; - /* altsetting may change at any moment, so take a snapshot */ + /* altsetting and enable_isoc may change at any moment, so take a snapshot */ instance->altsetting = altsetting; + use_isoc = enable_isoc; if (instance->altsetting) if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { @@ -737,13 +756,43 @@ static int speedtch_bind(struct usbatm_data *usbatm, instance->altsetting = 0; /* fall back to default */ } - if (!instance->altsetting) { - if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ALTSETTING)) < 0) { - usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ALTSETTING, ret); + if (!instance->altsetting && use_isoc) + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) { + usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret); + use_isoc = 0; /* fall back to bulk */ + } + + if (use_isoc) { + const struct usb_host_interface *desc = data_intf->cur_altsetting; + const __u8 target_address = USB_DIR_IN | usbatm->driver->isoc_in; + int i; + + use_isoc = 0; /* fall back to bulk if endpoint not found */ + + for (i=0; idesc.bNumEndpoints; i++) { + const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc; + + if ((endpoint_desc->bEndpointAddress == target_address)) { + use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC; + break; + } + } + + if (!use_isoc) + usb_info(usbatm, "isochronous transfer not supported - using bulk\n"); + } + + if (!use_isoc && !instance->altsetting) + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) { + usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret); goto fail_free; } - instance->altsetting = DEFAULT_ALTSETTING; - } + + if (!instance->altsetting) + instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; + + usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); @@ -771,7 +820,7 @@ static int speedtch_bind(struct usbatm_data *usbatm, 0x12, 0xc0, 0x07, 0x00, instance->scratch_buffer + OFFSET_7, SIZE_7, 500); - usbatm->flags = (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0); + usbatm->flags |= (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0); usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not"); @@ -817,8 +866,9 @@ static struct usbatm_driver speedtch_usbatm_driver = { .unbind = speedtch_unbind, .atm_start = speedtch_atm_start, .atm_stop = speedtch_atm_stop, - .in = ENDPOINT_DATA, - .out = ENDPOINT_DATA + .bulk_in = ENDPOINT_BULK_DATA, + .bulk_out = ENDPOINT_BULK_DATA, + .isoc_in = ENDPOINT_ISOC_DATA }; static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index aa072ad953a6..956cd9e82dee 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1705,8 +1705,8 @@ static struct usbatm_driver uea_usbatm_driver = { .atm_start = uea_atm_open, .unbind = uea_unbind, .heavy_init = uea_heavy, - .in = UEA_BULK_DATA_PIPE, - .out = UEA_BULK_DATA_PIPE, + .bulk_in = UEA_BULK_DATA_PIPE, + .bulk_out = UEA_BULK_DATA_PIPE, }; static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 1d829c29c86d..923f2d9269bc 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -1049,17 +1049,23 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, init_completion(&instance->thread_exited); INIT_LIST_HEAD(&instance->vcc_list); + skb_queue_head_init(&instance->sndqueue); usbatm_init_channel(&instance->rx_channel); usbatm_init_channel(&instance->tx_channel); tasklet_init(&instance->rx_channel.tasklet, usbatm_rx_process, (unsigned long)instance); tasklet_init(&instance->tx_channel.tasklet, usbatm_tx_process, (unsigned long)instance); - instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->in); - instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out); instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding; instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding; instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance; + if ((instance->flags & UDSL_USE_ISOC) && driver->isoc_in) + instance->rx_channel.endpoint = usb_rcvisocpipe(usb_dev, driver->isoc_in); + else + instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->bulk_in); + + instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->bulk_out); + /* tx buffer size must be a positive multiple of the stride */ instance->tx_channel.buf_size = max (instance->tx_channel.stride, snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride)); @@ -1080,6 +1086,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, num_packets--; instance->rx_channel.buf_size = num_packets * maxpacket; + instance->rx_channel.packet_size = maxpacket; #ifdef DEBUG for (i = 0; i < 2; i++) { @@ -1090,22 +1097,16 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, } #endif - skb_queue_head_init(&instance->sndqueue); + /* initialize urbs */ for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) { - struct urb *urb; u8 *buffer; - unsigned int iso_packets = 0, iso_size = 0; struct usbatm_channel *channel = i < num_rcv_urbs ? &instance->rx_channel : &instance->tx_channel; + struct urb *urb; + unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0; - if (usb_pipeisoc(channel->endpoint)) { - /* don't expect iso out endpoints */ - iso_size = usb_maxpacket(instance->usb_dev, channel->endpoint, 0); - iso_size -= iso_size % channel->stride; /* alignment */ - BUG_ON(!iso_size); - iso_packets = (channel->buf_size - 1) / iso_size + 1; - } + UDSL_ASSERT(!usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint)); urb = usb_alloc_urb(iso_packets, GFP_KERNEL); if (!urb) { @@ -1132,9 +1133,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = iso_packets; for (j = 0; j < iso_packets; j++) { - urb->iso_frame_desc[j].offset = iso_size * j; - urb->iso_frame_desc[j].length = min_t(int, iso_size, - channel->buf_size - urb->iso_frame_desc[j].offset); + urb->iso_frame_desc[j].offset = channel->packet_size * j; + urb->iso_frame_desc[j].length = channel->packet_size; } } diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index 1a31cf87bb1f..0e2caa0967c1 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -87,6 +87,7 @@ /* flags, set by mini-driver in bind() */ #define UDSL_SKIP_HEAVY_INIT (1<<0) +#define UDSL_USE_ISOC (1<<1) /* mini driver */ @@ -118,8 +119,9 @@ struct usbatm_driver { /* cleanup ATM device ... can sleep, but can't fail */ void (*atm_stop) (struct usbatm_data *, struct atm_dev *); - int in; /* rx endpoint */ - int out; /* tx endpoint */ + int bulk_in; /* bulk rx endpoint */ + int isoc_in; /* isochronous rx endpoint */ + int bulk_out; /* bulk tx endpoint */ unsigned rx_padding; unsigned tx_padding; @@ -134,6 +136,7 @@ struct usbatm_channel { int endpoint; /* usb pipe */ unsigned int stride; /* ATM cell size + padding */ unsigned int buf_size; /* urb buffer size */ + unsigned int packet_size; /* endpoint maxpacket */ spinlock_t lock; struct list_head list; struct tasklet_struct tasklet; diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index 83848ee2c6fe..42d6823b82b3 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c @@ -210,8 +210,8 @@ static int __init xusbatm_init(void) xusbatm_drivers[i].bind = xusbatm_bind; xusbatm_drivers[i].unbind = xusbatm_unbind; xusbatm_drivers[i].atm_start = xusbatm_atm_start; - xusbatm_drivers[i].in = rx_endpoint[i]; - xusbatm_drivers[i].out = tx_endpoint[i]; + xusbatm_drivers[i].bulk_in = rx_endpoint[i]; + xusbatm_drivers[i].bulk_out = tx_endpoint[i]; xusbatm_drivers[i].rx_padding = rx_padding[i]; xusbatm_drivers[i].tx_padding = tx_padding[i]; } From e3fb2f641f421662ebda48763f2f03cb9bd29e82 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 11:06:46 +0100 Subject: [PATCH 240/695] [PATCH] USBATM: handle urbs containing partial cells The receive logic has always assumed that urbs contain an integral number of ATM cells, which is a bit naughty, though it never caused any problems with bulk transfers. Isochronous urbs spank us soundly for this. Fixed thanks to this patch, mostly by Stanislaw Gruszka. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/usbatm.c | 295 +++++++++++++++++++++++++-------------- drivers/usb/atm/usbatm.h | 7 + 2 files changed, 194 insertions(+), 108 deletions(-) diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 923f2d9269bc..341430fbaf9c 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -296,125 +296,158 @@ static inline struct usbatm_vcc_data *usbatm_find_vcc(struct usbatm_data *instan return NULL; } -static void usbatm_extract_cells(struct usbatm_data *instance, - unsigned char *source, unsigned int avail_data) +static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char *source) { - struct usbatm_vcc_data *cached_vcc = NULL; struct atm_vcc *vcc; struct sk_buff *sarb; - unsigned int stride = instance->rx_channel.stride; - int vci, cached_vci = 0; - short vpi, cached_vpi = 0; - u8 pti; + short vpi = ((source[0] & 0x0f) << 4) | (source[1] >> 4); + int vci = ((source[1] & 0x0f) << 12) | (source[2] << 4) | (source[3] >> 4); + u8 pti = ((source[3] & 0xe) >> 1); - for (; avail_data >= stride; avail_data -= stride, source += stride) { - vpi = ((source[0] & 0x0f) << 4) | (source[1] >> 4); - vci = ((source[1] & 0x0f) << 12) | (source[2] << 4) | (source[3] >> 4); - pti = ((source[3] & 0xe) >> 1); + vdbg("%s: vpi %hd, vci %d, pti %d", __func__, vpi, vci, pti); - vdbg("%s: vpi %hd, vci %d, pti %d", __func__, vpi, vci, pti); + if ((vci != instance->cached_vci) || (vpi != instance->cached_vpi)) { + instance->cached_vpi = vpi; + instance->cached_vci = vci; - if ((vci != cached_vci) || (vpi != cached_vpi)) { - cached_vpi = vpi; - cached_vci = vci; + instance->cached_vcc = usbatm_find_vcc(instance, vpi, vci); - cached_vcc = usbatm_find_vcc(instance, vpi, vci); + if (!instance->cached_vcc) + atm_rldbg(instance, "%s: unknown vpi/vci (%hd/%d)!\n", __func__, vpi, vci); + } - if (!cached_vcc) - atm_rldbg(instance, "%s: unknown vpi/vci (%hd/%d)!\n", __func__, vpi, vci); - } + if (!instance->cached_vcc) + return; - if (!cached_vcc) - continue; + vcc = instance->cached_vcc->vcc; - vcc = cached_vcc->vcc; + /* OAM F5 end-to-end */ + if (pti == ATM_PTI_E2EF5) { + if (printk_ratelimit()) + atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", + __func__, vpi, vci); + atomic_inc(&vcc->stats->rx_err); + return; + } - /* OAM F5 end-to-end */ - if (pti == ATM_PTI_E2EF5) { - if (printk_ratelimit()) - atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", - __func__, vpi, vci); + sarb = instance->cached_vcc->sarb; + + if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) { + atm_rldbg(instance, "%s: buffer overrun (sarb->len %u, vcc: 0x%p)!\n", + __func__, sarb->len, vcc); + /* discard cells already received */ + skb_trim(sarb, 0); + UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end); + } + + memcpy(sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD); + __skb_put(sarb, ATM_CELL_PAYLOAD); + + if (pti & 1) { + struct sk_buff *skb; + unsigned int length; + unsigned int pdu_length; + + length = (source[ATM_CELL_SIZE - 6] << 8) + source[ATM_CELL_SIZE - 5]; + + /* guard against overflow */ + if (length > ATM_MAX_AAL5_PDU) { + atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n", + __func__, length, vcc); atomic_inc(&vcc->stats->rx_err); - continue; + goto out; } - sarb = cached_vcc->sarb; + pdu_length = usbatm_pdu_length(length); - if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) { - atm_rldbg(instance, "%s: buffer overrun (sarb->len %u, vcc: 0x%p)!\n", - __func__, sarb->len, vcc); - /* discard cells already received */ - skb_trim(sarb, 0); - UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end); + if (sarb->len < pdu_length) { + atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n", + __func__, pdu_length, sarb->len, vcc); + atomic_inc(&vcc->stats->rx_err); + goto out; } - memcpy(sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD); - __skb_put(sarb, ATM_CELL_PAYLOAD); - - if (pti & 1) { - struct sk_buff *skb; - unsigned int length; - unsigned int pdu_length; - - length = (source[ATM_CELL_SIZE - 6] << 8) + source[ATM_CELL_SIZE - 5]; - - /* guard against overflow */ - if (length > ATM_MAX_AAL5_PDU) { - atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n", - __func__, length, vcc); - atomic_inc(&vcc->stats->rx_err); - goto out; - } - - pdu_length = usbatm_pdu_length(length); - - if (sarb->len < pdu_length) { - atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n", - __func__, pdu_length, sarb->len, vcc); - atomic_inc(&vcc->stats->rx_err); - goto out; - } - - if (crc32_be(~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) { - atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n", - __func__, vcc); - atomic_inc(&vcc->stats->rx_err); - goto out; - } - - vdbg("%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", __func__, length, pdu_length, vcc); - - if (!(skb = dev_alloc_skb(length))) { - if (printk_ratelimit()) - atm_err(instance, "%s: no memory for skb (length: %u)!\n", - __func__, length); - atomic_inc(&vcc->stats->rx_drop); - goto out; - } - - vdbg("%s: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", __func__, skb, skb->truesize); - - if (!atm_charge(vcc, skb->truesize)) { - atm_rldbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n", - __func__, skb->truesize); - dev_kfree_skb_any(skb); - goto out; /* atm_charge increments rx_drop */ - } - - memcpy(skb->data, sarb->tail - pdu_length, length); - __skb_put(skb, length); - - vdbg("%s: sending skb 0x%p, skb->len %u, skb->truesize %u", - __func__, skb, skb->len, skb->truesize); - - PACKETDEBUG(skb->data, skb->len); - - vcc->push(vcc, skb); - - atomic_inc(&vcc->stats->rx); - out: - skb_trim(sarb, 0); + if (crc32_be(~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) { + atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n", + __func__, vcc); + atomic_inc(&vcc->stats->rx_err); + goto out; } + + vdbg("%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", __func__, length, pdu_length, vcc); + + if (!(skb = dev_alloc_skb(length))) { + if (printk_ratelimit()) + atm_err(instance, "%s: no memory for skb (length: %u)!\n", + __func__, length); + atomic_inc(&vcc->stats->rx_drop); + goto out; + } + + vdbg("%s: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", __func__, skb, skb->truesize); + + if (!atm_charge(vcc, skb->truesize)) { + atm_rldbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n", + __func__, skb->truesize); + dev_kfree_skb_any(skb); + goto out; /* atm_charge increments rx_drop */ + } + + memcpy(skb->data, sarb->tail - pdu_length, length); + __skb_put(skb, length); + + vdbg("%s: sending skb 0x%p, skb->len %u, skb->truesize %u", + __func__, skb, skb->len, skb->truesize); + + PACKETDEBUG(skb->data, skb->len); + + vcc->push(vcc, skb); + + atomic_inc(&vcc->stats->rx); + out: + skb_trim(sarb, 0); + } +} + +static void usbatm_extract_cells(struct usbatm_data *instance, + unsigned char *source, unsigned int avail_data) +{ + unsigned int stride = instance->rx_channel.stride; + unsigned int buf_usage = instance->buf_usage; + + /* extract cells from incoming data, taking into account that + * the length of avail data may not be a multiple of stride */ + + if (buf_usage > 0) { + /* we have a partially received atm cell */ + unsigned char *cell_buf = instance->cell_buf; + unsigned int space_left = stride - buf_usage; + + UDSL_ASSERT(buf_usage <= stride); + + if (avail_data >= space_left) { + /* add new data and process cell */ + memcpy(cell_buf + buf_usage, source, space_left); + source += space_left; + avail_data -= space_left; + usbatm_extract_one_cell(instance, cell_buf); + instance->buf_usage = 0; + } else { + /* not enough data to fill the cell */ + memcpy(cell_buf + buf_usage, source, avail_data); + instance->buf_usage = buf_usage + avail_data; + return; + } + } + + for (; avail_data >= stride; avail_data -= stride, source += stride) + usbatm_extract_one_cell(instance, source); + + if (avail_data > 0) { + /* length was not a multiple of stride - + * save remaining data for next call */ + memcpy(instance->cell_buf, source, avail_data); + instance->buf_usage = avail_data; } } @@ -496,16 +529,40 @@ static void usbatm_rx_process(unsigned long data) vdbg("%s: processing urb 0x%p", __func__, urb); if (usb_pipeisoc(urb->pipe)) { + unsigned char *merge_start = NULL; + unsigned int merge_length = 0; + const unsigned int packet_size = instance->rx_channel.packet_size; int i; - for (i = 0; i < urb->number_of_packets; i++) - if (!urb->iso_frame_desc[i].status) - usbatm_extract_cells(instance, - (u8 *)urb->transfer_buffer + urb->iso_frame_desc[i].offset, - urb->iso_frame_desc[i].actual_length); - } - else + + for (i = 0; i < urb->number_of_packets; i++) { + if (!urb->iso_frame_desc[i].status) { + unsigned int actual_length = urb->iso_frame_desc[i].actual_length; + + UDSL_ASSERT(actual_length <= packet_size); + + if (!merge_length) + merge_start = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset; + merge_length += actual_length; + if (merge_length && (actual_length < packet_size)) { + usbatm_extract_cells(instance, merge_start, merge_length); + merge_length = 0; + } + } else { + atm_rldbg(instance, "%s: status %d in frame %d!\n", __func__, urb->status, i); + if (merge_length) + usbatm_extract_cells(instance, merge_start, merge_length); + merge_length = 0; + instance->buf_usage = 0; + } + } + + if (merge_length) + usbatm_extract_cells(instance, merge_start, merge_length); + } else if (!urb->status) usbatm_extract_cells(instance, urb->transfer_buffer, urb->actual_length); + else + instance->buf_usage = 0; if (usbatm_submit_urb(urb)) return; @@ -797,6 +854,9 @@ static int usbatm_atm_open(struct atm_vcc *vcc) vcc->dev_data = new; tasklet_disable(&instance->rx_channel.tasklet); + instance->cached_vcc = new; + instance->cached_vpi = vpi; + instance->cached_vci = vci; list_add(&new->list, &instance->vcc_list); tasklet_enable(&instance->rx_channel.tasklet); @@ -836,6 +896,11 @@ static void usbatm_atm_close(struct atm_vcc *vcc) down(&instance->serialize); /* vs self, usbatm_atm_open, usbatm_usb_disconnect */ tasklet_disable(&instance->rx_channel.tasklet); + if (instance->cached_vcc == vcc_data) { + instance->cached_vcc = NULL; + instance->cached_vpi = ATM_VPI_UNSPEC; + instance->cached_vci = ATM_VCI_UNSPEC; + } list_del(&vcc_data->list); tasklet_enable(&instance->rx_channel.tasklet); @@ -1146,6 +1211,16 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb); } + instance->cached_vpi = ATM_VPI_UNSPEC; + instance->cached_vci = ATM_VCI_UNSPEC; + instance->cell_buf = kmalloc(instance->rx_channel.stride, GFP_KERNEL); + + if (!instance->cell_buf) { + dev_err(dev, "%s: no memory for cell buffer!\n", __func__); + error = -ENOMEM; + goto fail_unbind; + } + if (!(instance->flags & UDSL_SKIP_HEAVY_INIT) && driver->heavy_init) { error = usbatm_heavy_init(instance); } else { @@ -1165,6 +1240,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, if (instance->driver->unbind) instance->driver->unbind(instance, intf); fail_free: + kfree(instance->cell_buf); + for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) { if (instance->urbs[i]) kfree(instance->urbs[i]->transfer_buffer); @@ -1236,6 +1313,8 @@ void usbatm_usb_disconnect(struct usb_interface *intf) usb_free_urb(instance->urbs[i]); } + kfree(instance->cell_buf); + /* ATM finalize */ if (instance->atm_dev) atm_dev_deregister(instance->atm_dev); diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index 0e2caa0967c1..bdff534b941d 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -187,6 +187,13 @@ struct usbatm_data { struct sk_buff_head sndqueue; struct sk_buff *current_skb; /* being emptied */ + struct usbatm_vcc_data *cached_vcc; + int cached_vci; + short cached_vpi; + + unsigned char *cell_buf; /* holds partial rx cell */ + unsigned int buf_usage; + struct urb *urbs[0]; }; From 9b0e54addf3ea8488c7b57166fb38feeb8ea28fd Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 11:08:05 +0100 Subject: [PATCH 241/695] [PATCH] USBATM: bump version numbers Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/speedtch.c | 2 +- drivers/usb/atm/usbatm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 8c1c560cf051..7860c8a5800d 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -42,7 +42,7 @@ #include "usbatm.h" #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands " -#define DRIVER_VERSION "1.9" +#define DRIVER_VERSION "1.10" #define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION static const char speedtch_driver_name[] = "speedtch"; diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 341430fbaf9c..c925e3a42672 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -92,7 +92,7 @@ static int usbatm_print_packet(const unsigned char *data, int len); #endif #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands " -#define DRIVER_VERSION "1.9" +#define DRIVER_VERSION "1.10" #define DRIVER_DESC "Generic USB ATM/DSL I/O, version " DRIVER_VERSION static const char usbatm_driver_name[] = "usbatm"; From a3673d3cd1cdeec6b503ffa418ca2d5aeff82fd7 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 13 Jan 2006 11:12:58 +0100 Subject: [PATCH 242/695] [PATCH] USBATM: -EILSEQ workaround Don't throttle on -EILSEQ urb status if requested by a minidriver. It seems the ueagle modems are buggy, giving -EILSEQ when they have no data to send. The ueagle change will be sent separately by the ueagle guys. Patch by Matthieu Castet. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/usbatm.c | 5 ++++- drivers/usb/atm/usbatm.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index c925e3a42672..5d339af16248 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -270,7 +270,10 @@ static void usbatm_complete(struct urb *urb, struct pt_regs *regs) spin_unlock_irqrestore(&channel->lock, flags); - if (unlikely(urb->status)) { + if (unlikely(urb->status) && + (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || + urb->status != -EILSEQ )) + { if (printk_ratelimit()) atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", __func__, urb, urb->status); diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index bdff534b941d..1cf4767007de 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -88,6 +88,7 @@ #define UDSL_SKIP_HEAVY_INIT (1<<0) #define UDSL_USE_ISOC (1<<1) +#define UDSL_IGNORE_EILSEQ (1<<2) /* mini driver */ From ab3c81ff639fbee4ab32af84c809d283b773084a Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 13 Jan 2006 15:52:55 +0100 Subject: [PATCH 243/695] [PATCH] USBATM: semaphore to mutex conversion This is the usbatm part of the Arjan, Jes and Ingo mass semaphore to mutex conversion, reworked to apply on top of the patches I just sent to you. This time, with correct attribution and signed-off lines. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 9 +++++---- drivers/usb/atm/ueagle-atm.c | 27 ++++++++++++++------------- drivers/usb/atm/usbatm.c | 28 ++++++++++++++-------------- drivers/usb/atm/usbatm.h | 3 ++- 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 70a96e98152c..04631dcbabbc 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -36,6 +36,7 @@ #include #include /* FIXME: linux/firmware.h should include it itself */ #include +#include #include "usbatm.h" @@ -160,7 +161,7 @@ struct cxacru_data { struct work_struct poll_work; /* contol handles */ - struct semaphore cm_serialize; + struct mutex cm_serialize; u8 *rcv_buf; u8 *snd_buf; struct urb *rcv_urb; @@ -219,7 +220,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, goto fail; } - down(&instance->cm_serialize); + mutex_lock(&instance->cm_serialize); /* submit reading urb before the writing one */ init_completion(&instance->rcv_done); @@ -288,7 +289,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, ret = offd; dbg("cm %#x", cm); fail: - up(&instance->cm_serialize); + mutex_unlock(&instance->cm_serialize); return ret; } @@ -717,7 +718,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, instance->snd_buf, PAGE_SIZE, cxacru_blocking_completion, &instance->snd_done, 4); - init_MUTEX(&instance->cm_serialize); + mutex_init(&instance->cm_serialize); INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance); diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 956cd9e82dee..4362cfd801b5 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include "usbatm.h" @@ -358,7 +359,7 @@ struct intr_pkt { #define INTR_PKT_SIZE 28 static struct usb_driver uea_driver; -static DECLARE_MUTEX(uea_semaphore); +static DEFINE_MUTEX(uea_mutex); static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; static int modem_index; @@ -1418,13 +1419,13 @@ static ssize_t read_status(struct device *dev, struct device_attribute *attr, int ret = -ENODEV; struct uea_softc *sc; - down(&uea_semaphore); + mutex_lock(&uea_mutex); sc = dev_to_uea(dev); if (!sc) goto out; ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state); out: - up(&uea_semaphore); + mutex_unlock(&uea_mutex); return ret; } @@ -1434,14 +1435,14 @@ static ssize_t reboot(struct device *dev, struct device_attribute *attr, int ret = -ENODEV; struct uea_softc *sc; - down(&uea_semaphore); + mutex_lock(&uea_mutex); sc = dev_to_uea(dev); if (!sc) goto out; sc->reset = 1; ret = count; out: - up(&uea_semaphore); + mutex_unlock(&uea_mutex); return ret; } @@ -1453,7 +1454,7 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at int ret = -ENODEV; struct uea_softc *sc; - down(&uea_semaphore); + mutex_lock(&uea_mutex); sc = dev_to_uea(dev); if (!sc) goto out; @@ -1473,7 +1474,7 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at break; } out: - up(&uea_semaphore); + mutex_unlock(&uea_mutex); return ret; } @@ -1485,7 +1486,7 @@ static ssize_t read_delin(struct device *dev, struct device_attribute *attr, int ret = -ENODEV; struct uea_softc *sc; - down(&uea_semaphore); + mutex_lock(&uea_mutex); sc = dev_to_uea(dev); if (!sc) goto out; @@ -1497,7 +1498,7 @@ static ssize_t read_delin(struct device *dev, struct device_attribute *attr, else ret = sprintf(buf, "GOOD\n"); out: - up(&uea_semaphore); + mutex_unlock(&uea_mutex); return ret; } @@ -1511,7 +1512,7 @@ static ssize_t read_##name(struct device *dev, \ int ret = -ENODEV; \ struct uea_softc *sc; \ \ - down(&uea_semaphore); \ + mutex_lock(&uea_mutex); \ sc = dev_to_uea(dev); \ if (!sc) \ goto out; \ @@ -1519,7 +1520,7 @@ static ssize_t read_##name(struct device *dev, \ if (reset) \ sc->stats.phy.name = 0; \ out: \ - up(&uea_semaphore); \ + mutex_unlock(&uea_mutex); \ return ret; \ } \ \ @@ -1737,9 +1738,9 @@ static void uea_disconnect(struct usb_interface *intf) * Pre-firmware device has one interface */ if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) { - down(&uea_semaphore); + mutex_lock(&uea_mutex); usbatm_usb_disconnect(intf); - up(&uea_semaphore); + mutex_unlock(&uea_mutex); uea_info(usb, "ADSL device removed\n"); } diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 5d339af16248..c1211fc037d9 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -823,7 +823,7 @@ static int usbatm_atm_open(struct atm_vcc *vcc) return -EINVAL; } - down(&instance->serialize); /* vs self, usbatm_atm_close, usbatm_usb_disconnect */ + mutex_lock(&instance->serialize); /* vs self, usbatm_atm_close, usbatm_usb_disconnect */ if (instance->disconnected) { atm_dbg(instance, "%s: disconnected!\n", __func__); @@ -867,7 +867,7 @@ static int usbatm_atm_open(struct atm_vcc *vcc) set_bit(ATM_VF_PARTIAL, &vcc->flags); set_bit(ATM_VF_READY, &vcc->flags); - up(&instance->serialize); + mutex_unlock(&instance->serialize); atm_dbg(instance, "%s: allocated vcc data 0x%p\n", __func__, new); @@ -875,7 +875,7 @@ static int usbatm_atm_open(struct atm_vcc *vcc) fail: kfree(new); - up(&instance->serialize); + mutex_unlock(&instance->serialize); return ret; } @@ -896,7 +896,7 @@ static void usbatm_atm_close(struct atm_vcc *vcc) usbatm_cancel_send(instance, vcc); - down(&instance->serialize); /* vs self, usbatm_atm_open, usbatm_usb_disconnect */ + mutex_lock(&instance->serialize); /* vs self, usbatm_atm_open, usbatm_usb_disconnect */ tasklet_disable(&instance->rx_channel.tasklet); if (instance->cached_vcc == vcc_data) { @@ -919,7 +919,7 @@ static void usbatm_atm_close(struct atm_vcc *vcc) clear_bit(ATM_VF_PARTIAL, &vcc->flags); clear_bit(ATM_VF_ADDR, &vcc->flags); - up(&instance->serialize); + mutex_unlock(&instance->serialize); atm_dbg(instance, "%s successful\n", __func__); } @@ -1009,9 +1009,9 @@ static int usbatm_do_heavy_init(void *arg) if (!ret) ret = usbatm_atm_init(instance); - down(&instance->serialize); + mutex_lock(&instance->serialize); instance->thread_pid = -1; - up(&instance->serialize); + mutex_unlock(&instance->serialize); complete_and_exit(&instance->thread_exited, ret); } @@ -1025,9 +1025,9 @@ static int usbatm_heavy_init(struct usbatm_data *instance) return ret; } - down(&instance->serialize); + mutex_lock(&instance->serialize); instance->thread_pid = ret; - up(&instance->serialize); + mutex_unlock(&instance->serialize); wait_for_completion(&instance->thread_started); @@ -1110,7 +1110,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, /* private fields */ kref_init(&instance->refcount); /* dropped in usbatm_usb_disconnect */ - init_MUTEX(&instance->serialize); + mutex_init(&instance->serialize); instance->thread_pid = -1; init_completion(&instance->thread_started); @@ -1273,18 +1273,18 @@ void usbatm_usb_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); - down(&instance->serialize); + mutex_lock(&instance->serialize); instance->disconnected = 1; if (instance->thread_pid >= 0) kill_proc(instance->thread_pid, SIGTERM, 1); - up(&instance->serialize); + mutex_unlock(&instance->serialize); wait_for_completion(&instance->thread_exited); - down(&instance->serialize); + mutex_lock(&instance->serialize); list_for_each_entry(vcc_data, &instance->vcc_list, list) vcc_release_async(vcc_data->vcc, -EPIPE); - up(&instance->serialize); + mutex_unlock(&instance->serialize); tasklet_disable(&instance->rx_channel.tasklet); tasklet_disable(&instance->tx_channel.tasklet); diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index 1cf4767007de..ff8551e93372 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -34,6 +34,7 @@ #include #include #include +#include /* #define VERBOSE_DEBUG @@ -171,7 +172,7 @@ struct usbatm_data { ********************************/ struct kref refcount; - struct semaphore serialize; + struct mutex serialize; int disconnected; /* heavy init */ From 3c9666cc18be1fc11698fc0181e124b44889cf37 Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Wed, 18 Jan 2006 07:38:19 +0100 Subject: [PATCH 244/695] [PATCH] UEAGLE : add iso support This patch adds the support for isochronous pipe. A new module parameter is added to select iso mode. It is set to iso by default because bulk mode doesn't work well at high speed rate (>3 Mbps for upload). We use UDSL_IGNORE_EILSEQ flags because ADI firmware doesn't reply to ISO IN when it has nothing to send [1]. [1] from cypress datasheet : The ISOSEND0 Bit (bit 7 in the USBPAIR Register) is used when the EZ-USB FX chip receives an isochronous IN token while the IN FIFO is empty. If ISOSEND0=0 (the default value), the USB core does not respond to the IN token. If ISOSEND0=1, the USB core sends a zero-length data packet in response to the IN token. The action to take depends on the overall system design. The ISOSEND0 Bit applies to all of the isochronous IN endpoints, IN-8 through IN-15. Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 4362cfd801b5..ea7dfe0c8275 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -68,7 +68,7 @@ #include "usbatm.h" -#define EAGLEUSBVERSION "ueagle 1.1" +#define EAGLEUSBVERSION "ueagle 1.2" /* @@ -364,11 +364,14 @@ static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; static int modem_index; static unsigned int debug; +static int use_iso[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = 1}; static int sync_wait[NB_MODEM]; static char *cmv_file[NB_MODEM]; module_param(debug, uint, 0644); MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); +module_param_array(use_iso, bool, NULL, 0644); +MODULE_PARM_DESC(use_iso, "use isochronous usb pipe for incoming traffic"); module_param_array(sync_wait, bool, NULL, 0644); MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); module_param_array(cmv_file, charp, NULL, 0644); @@ -936,6 +939,7 @@ static int uea_stat(struct uea_softc *sc) * ADI930 don't support it (-EPIPE error). */ if (UEA_CHIP_VERSION(sc) != ADI930 + && !use_iso[sc->modem_index] && sc->stats.phy.dsrate != (data >> 16) * 32) { /* Original timming from ADI(used in windows driver) * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits @@ -1659,6 +1663,25 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; sc->driver_info = id->driver_info; + /* ADI930 don't support iso */ + if (UEA_CHIP_VERSION(id) != ADI930 && use_iso[sc->modem_index]) { + int i; + + /* try set fastest alternate for inbound traffic interface */ + for (i = FASTEST_ISO_INTF; i > 0; i--) + if (usb_set_interface(usb, UEA_DS_IFACE_NO, i) == 0) + break; + + if (i > 0) { + uea_dbg(usb, "set alternate %d for 2 interface\n", i); + uea_info(usb, "using iso mode\n"); + usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ; + } else { + uea_err(usb, "setting any alternate failed for " + "2 interface, using bulk mode\n"); + } + } + ret = uea_boot(sc); if (ret < 0) { kfree(sc); @@ -1708,6 +1731,7 @@ static struct usbatm_driver uea_usbatm_driver = { .heavy_init = uea_heavy, .bulk_in = UEA_BULK_DATA_PIPE, .bulk_out = UEA_BULK_DATA_PIPE, + .isoc_in = UEA_ISO_DATA_PIPE, }; static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) From e40abaf6336ef3756277bab70db47a47da4aa325 Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Wed, 18 Jan 2006 07:38:37 +0100 Subject: [PATCH 245/695] [PATCH] UEAGLE : cosmetic this patch is purely cosmetic. There is : - indentation cleaning - unneeded cast removing - comments cleaning Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index ea7dfe0c8275..b0026ecc6a36 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -632,8 +632,7 @@ static int request_dsp(struct uea_softc *sc) dsp_name = FW_DIR "DSPep.bin"; } - ret = request_firmware(&sc->dsp_firm, - dsp_name, &sc->usb_dev->dev); + ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev); if (ret < 0) { uea_err(INS_TO_USBDEV(sc), "requesting firmware %s failed with error %d\n", @@ -748,7 +747,6 @@ static inline int wait_cmv_ack(struct uea_softc *sc) return ret; return (ret == 0) ? -ETIMEDOUT : 0; - } #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00 @@ -1189,8 +1187,7 @@ static int load_XILINX_firmware(struct uea_softc *sc) } } - /* finish to send the fpga - */ + /* finish to send the fpga */ ret = uea_request(sc, 0xe, 1, 0, NULL); if (ret < 0) { uea_err(INS_TO_USBDEV(sc), @@ -1198,9 +1195,7 @@ static int load_XILINX_firmware(struct uea_softc *sc) goto err1; } - /* - * Tell the modem we finish : de-assert reset - */ + /* Tell the modem we finish : de-assert reset */ value = 0; ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value); if (ret < 0) @@ -1214,6 +1209,7 @@ err0: return ret; } +/* The modem send us an ack. First with check if it right */ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) { uea_enters(INS_TO_USBDEV(sc)); @@ -1273,23 +1269,19 @@ bad1: */ static void uea_intr(struct urb *urb, struct pt_regs *regs) { - struct uea_softc *sc = (struct uea_softc *)urb->context; - struct intr_pkt *intr; + struct uea_softc *sc = urb->context; + struct intr_pkt *intr = urb->transfer_buffer; uea_enters(INS_TO_USBDEV(sc)); - if (urb->status < 0) { + if (unlikely(urb->status < 0)) { uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", urb->status); return; } - intr = (struct intr_pkt *) urb->transfer_buffer; - /* device-to-host interrupt */ if (intr->bType != 0x08 || sc->booting) { - uea_err(INS_TO_USBDEV(sc), "wrong intr\n"); - // rebooting ? - // sc->reset = 1; + uea_err(INS_TO_USBDEV(sc), "wrong interrupt\n"); goto resubmit; } @@ -1305,7 +1297,7 @@ static void uea_intr(struct urb *urb, struct pt_regs *regs) break; default: - uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n", + uea_err(INS_TO_USBDEV(sc), "unknown interrupt %u\n", le16_to_cpu(intr->wInterrupt)); } @@ -1384,7 +1376,7 @@ static void uea_stop(struct uea_softc *sc) int ret; uea_enters(INS_TO_USBDEV(sc)); ret = kthread_stop(sc->kthread); - uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); + uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); /* stop any pending boot process */ flush_scheduled_work(); @@ -1641,9 +1633,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, if (ret < 0) return ret; - /* ADI930 has only 2 interfaces and inbound traffic - * is on interface 1 - */ + /* ADI930 has only 2 interfaces and inbound traffic is on interface 1 */ if (UEA_CHIP_VERSION(id) != ADI930) { /* interface 2 is for inbound traffic */ ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO); From fdf290fd6d6a17b40055359263ed6003e87cb89b Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Wed, 18 Jan 2006 07:39:27 +0100 Subject: [PATCH 246/695] [PATCH] UEAGLE : cmv name bug (was cosmetic) this patch correct a possible bug with cmv_name being static. If there is 2 modems and the driver is scheduled when filling cmv_name this could result with garbage in cmv_name. We allocate cmv_name on the stack but with a small size in order to avoid that. Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index b0026ecc6a36..830d2c982670 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1013,7 +1013,7 @@ static int request_cmvs(struct uea_softc *sc, int ret, size; u8 *data; char *file; - static char cmv_name[256] = FW_DIR; + char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ if (cmv_file[sc->modem_index] == NULL) { if (UEA_CHIP_VERSION(sc) == ADI930) From 885e77430d2adddfab3f2ca65e4d3e9f5d489c50 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 17 Jan 2006 15:37:22 -0800 Subject: [PATCH 247/695] [PATCH] USB: add new auerswald device ids Add device support for a couple more Auerswald TK-devices. Via Thomas Jackle , typed in from http://bugzilla.kernel.org/show_bug.cgi?id=5908. Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/auerswald.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 449b2501acf3..ad2f4cccd388 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -2093,6 +2093,8 @@ static void auerswald_disconnect (struct usb_interface *intf) static struct usb_device_id auerswald_ids [] = { { USB_DEVICE (ID_AUERSWALD, 0x00C0) }, /* COMpact 2104 USB */ { USB_DEVICE (ID_AUERSWALD, 0x00DB) }, /* COMpact 4410/2206 USB */ + { USB_DEVICE (ID_AUERSWALD, 0x00DC) }, /* COMpact 4406 DSL */ + { USB_DEVICE (ID_AUERSWALD, 0x00DD) }, /* COMpact 2204 USB */ { USB_DEVICE (ID_AUERSWALD, 0x00F1) }, /* Comfort 2000 System Telephone */ { USB_DEVICE (ID_AUERSWALD, 0x00F2) }, /* Comfort 1200 System Telephone */ { } /* Terminating entry */ From dc41baf8181884770d77ce0cfc8ae9617cb8b02c Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Thu, 26 Jan 2006 07:44:31 +0100 Subject: [PATCH 248/695] [PATCH] USB HID: add blacklist entry for HP keyboard My earlier experiment (adding a clear-halt for the interrupt-in endpoint) failed. It turns out that it does cause problems for other devices. And it wasn't needed anyway; a simple blacklist entry was enough to get my HP keyboard working. This patch (as643) removes the clear-halt call and adds the blacklist entry. Signed-off-by: Alan Stern Signed-off-by: Vojtech Pavlik Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index a91e72c41415..617ce657f784 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1453,6 +1453,9 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_CHERRY 0x046a #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 +#define USB_VENDOR_ID_HP 0x03f0 +#define USB_DEVICE_ID_HP_USBHUB_KB 0x020c + /* * Alphabetically sorted blacklist by quirk type. */ @@ -1566,6 +1569,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET}, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, + { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, @@ -1828,9 +1832,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); - /* May be needed for some devices */ - usb_clear_halt(hid->dev, hid->urbin->pipe); - return hid; fail: From 0c7346229c48fa899a1837d9200894701ea81dac Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 22 Jan 2006 10:32:49 -0800 Subject: [PATCH 249/695] [PATCH] USB: EHCI, another full speed iso fix This patch adds a reinitializion for the uf variable that got modified by the preceding start-split bandwidth check. Signed-off-by: Clemens Ladisch Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 57e77374d228..fe0678624ec0 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1063,6 +1063,7 @@ sitd_slot_ok ( /* for IN, check CSPLIT */ if (stream->c_usecs) { + uf = uframe & 7; max_used = 100 - stream->c_usecs; do { tmp = 1 << uf; From 630aa3cfd5f0bae9547fe7dff175d7323d60140d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 23 Jan 2006 17:17:21 -0500 Subject: [PATCH 250/695] [PATCH] USB: UHCI: No FSBR until device is configured Some USB devices don't enumerate well with FSBR turned on. This patch keeps devices on the low-speed part of the schedule (which doesn't use FSBR) until they have been fully configured. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-q.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index b6076004a437..782398045f9f 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -672,9 +672,9 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur /* Low-speed transfers get a different queue, and won't hog the bus. * Also, some devices enumerate better without FSBR; the easiest way * to do that is to put URBs on the low-speed queue while the device - * is in the DEFAULT state. */ + * isn't in the CONFIGURED state. */ if (urb->dev->speed == USB_SPEED_LOW || - urb->dev->state == USB_STATE_DEFAULT) + urb->dev->state != USB_STATE_CONFIGURED) skelqh = uhci->skel_ls_control_qh; else { skelqh = uhci->skel_fs_control_qh; From 595b14cbccb2f9122bccfa6b55f2d9a380e9adeb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 18 Jan 2006 17:36:58 -0500 Subject: [PATCH 251/695] [PATCH] USB: remove some left over devfs droppings hanging around in the usb drivers As there is no more usb devfs support, these bits would just confuse people. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hiddev.c | 3 --- drivers/usb/misc/ldusb.c | 2 +- drivers/usb/usb-skeleton.c | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 4dff8473553d..77be6b9a820f 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -35,7 +35,6 @@ #include #include "hid.h" #include -#include #ifdef CONFIG_USB_DYNAMIC_MINORS #define HIDDEV_MINOR_BASE 0 @@ -832,12 +831,10 @@ static /* const */ struct usb_driver hiddev_driver = { int __init hiddev_init(void) { - devfs_mk_dir("usb/hid"); return usb_register(&hiddev_driver); } void hiddev_exit(void) { usb_deregister(&hiddev_driver); - devfs_remove("usb/hid"); } diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 981d8a5fbfd9..331d4ae949ed 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -593,7 +593,7 @@ static struct file_operations ld_usb_fops = { /* * usb class driver info in order to get a minor number from the usb core, - * and to have the device registered with devfs and the driver core + * and to have the device registered with the driver core */ static struct usb_class_driver ld_usb_class = { .name = "ldusb%d", diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 5d02f16b7d0e..4de9fb56ebfc 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -234,7 +234,7 @@ static struct file_operations skel_fops = { /* * usb class driver info in order to get a minor number from the usb core, - * and to have the device registered with devfs and the driver core + * and to have the device registered with the driver core */ static struct usb_class_driver skel_class = { .name = "skel%d", From 682d4c803f646d2ce09fde9ed7e99015598c3298 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 18 Jan 2006 23:55:08 -0800 Subject: [PATCH 252/695] [PATCH] USB: net2280 warning fix For some reason alpha doesn't include where other architectures do; this makes net2280 include it explicitly. Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/net2280.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index c32e1f7476da..67b13ab2f3f5 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include From e9aa795aaed0b861aaa5a8075748c9c34e2620ee Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Jan 2006 17:17:21 -0500 Subject: [PATCH 253/695] [PATCH] USB: add might_sleep() to usb_unlink_urb() to warn developers Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 081796726b95..dad4d8fd8180 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -468,6 +468,7 @@ int usb_unlink_urb(struct urb *urb) */ void usb_kill_urb(struct urb *urb) { + might_sleep(); if (!(urb && urb->dev && urb->dev->bus && urb->dev->bus->op)) return; spin_lock_irq(&urb->lock); From 0be930c546ad056cad5780ee9424a28cf979cb42 Mon Sep 17 00:00:00 2001 From: Olav Kongas Date: Tue, 27 Dec 2005 16:04:02 +0200 Subject: [PATCH 254/695] [PATCH] USB: isp116x-hcd: replace mdelay() by msleep() Replace mdelay() by msleep() in bus_suspend(); the rest of the system will gain 7ms. The related code is reorganized to minimize the number of locking/unlocking calls. The last hunk of the patch is the formatting change by Lindent. Signed-off-by: Olav Kongas Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp116x-hcd.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 584b8dc65119..972ce04889f8 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1420,20 +1420,22 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd) int ret = 0; spin_lock_irqsave(&isp116x->lock, flags); - val = isp116x_read_reg32(isp116x, HCCONTROL); + switch (val & HCCONTROL_HCFS) { case HCCONTROL_USB_OPER: + spin_unlock_irqrestore(&isp116x->lock, flags); val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); val |= HCCONTROL_USB_SUSPEND; if (device_may_wakeup(&hcd->self.root_hub->dev)) val |= HCCONTROL_RWE; /* Wait for usb transfers to finish */ - mdelay(2); + msleep(2); + spin_lock_irqsave(&isp116x->lock, flags); isp116x_write_reg32(isp116x, HCCONTROL, val); + spin_unlock_irqrestore(&isp116x->lock, flags); /* Wait for devices to suspend */ - mdelay(5); - case HCCONTROL_USB_SUSPEND: + msleep(5); break; case HCCONTROL_USB_RESUME: isp116x_write_reg32(isp116x, HCCONTROL, @@ -1441,12 +1443,11 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd) HCCONTROL_USB_RESET); case HCCONTROL_USB_RESET: ret = -EBUSY; + default: /* HCCONTROL_USB_SUSPEND */ + spin_unlock_irqrestore(&isp116x->lock, flags); break; - default: - ret = -EINVAL; } - spin_unlock_irqrestore(&isp116x->lock, flags); return ret; } @@ -1715,9 +1716,9 @@ static struct platform_driver isp116x_driver = { .remove = isp116x_remove, .suspend = isp116x_suspend, .resume = isp116x_resume, - .driver = { - .name = (char *)hcd_name, - }, + .driver = { + .name = (char *)hcd_name, + }, }; /*-----------------------------------------------------------------*/ From 979063692726fa40863345fb1b62daf2f795ddc0 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 3 Jan 2006 10:30:31 -0500 Subject: [PATCH 255/695] [PATCH] USB: gadgetfs: set "zero" flag for short control-IN response This patch (as622) makes gadgetfs set the "zero" flag for control-IN responses, when the length of the response is shorter than the length of the request. Signed-off-by: Alan Stern Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/inode.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 9a4edc5657aa..0aab7d24c768 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -135,6 +135,7 @@ struct dev_data { setup_out_ready : 1, setup_out_error : 1, setup_abort : 1; + unsigned setup_wLength; /* the rest is basically write-once */ struct usb_config_descriptor *config, *hs_config; @@ -942,6 +943,7 @@ static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) } req->complete = ep0_complete; req->length = len; + req->zero = 0; return 0; } @@ -1161,10 +1163,13 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) spin_unlock_irq (&dev->lock); if (copy_from_user (dev->req->buf, buf, len)) retval = -EFAULT; - else + else { + if (len < dev->setup_wLength) + dev->req->zero = 1; retval = usb_ep_queue ( dev->gadget->ep0, dev->req, GFP_KERNEL); + } if (retval < 0) { spin_lock_irq (&dev->lock); clean_req (dev->gadget->ep0, dev->req); @@ -1483,6 +1488,7 @@ unrecognized: delegate: dev->setup_in = (ctrl->bRequestType & USB_DIR_IN) ? 1 : 0; + dev->setup_wLength = w_length; dev->setup_out_ready = 0; dev->setup_out_error = 0; value = 0; From 52ea1619d5103f80ec0472a3eb653a04c15326f2 Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn / snakebyte Date: Wed, 4 Jan 2006 18:10:44 +0100 Subject: [PATCH 256/695] [PATCH] USB: Remove LINUX_VERSION_CODE check in pwc/pwc-ctrl.c this patch removes compatibility with 2.4 kernel, which makes the code much easier to read. Signed-off-by: Eric Sesterhenn Signed-off-by: Greg Kroah-Hartman --- drivers/usb/media/pwc/pwc-ctrl.c | 264 +++++++++++-------------------- 1 file changed, 89 insertions(+), 175 deletions(-) diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 359c4b2df735..3ebb6e9cdf92 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c @@ -1152,45 +1152,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) /* End of Add-Ons */ /* ************************************************* */ -/* Linux 2.5.something and 2.6 pass direct pointers to arguments of - ioctl() calls. With 2.4, you have to do tedious copy_from_user() - and copy_to_user() calls. With these macros we circumvent this, - and let me maintain only one source file. The functionality is - exactly the same otherwise. - */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - -/* define local variable for arg */ -#define ARG_DEF(ARG_type, ARG_name)\ - ARG_type *ARG_name = arg; -/* copy arg to local variable */ -#define ARG_IN(ARG_name) /* nothing */ -/* argument itself (referenced) */ -#define ARGR(ARG_name) (*ARG_name) -/* argument address */ -#define ARGA(ARG_name) ARG_name -/* copy local variable to arg */ -#define ARG_OUT(ARG_name) /* nothing */ - -#else - -#define ARG_DEF(ARG_type, ARG_name)\ - ARG_type ARG_name; -#define ARG_IN(ARG_name)\ - if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\ - ret = -EFAULT;\ - break;\ - } -#define ARGR(ARG_name) ARG_name -#define ARGA(ARG_name) &ARG_name -#define ARG_OUT(ARG_name)\ - if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\ - ret = -EFAULT;\ - break;\ - } - -#endif int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { @@ -1220,243 +1181,206 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) case VIDIOCPWCSCQUAL: { - ARG_DEF(int, qual) + int *qual = arg; - ARG_IN(qual) - if (ARGR(qual) < 0 || ARGR(qual) > 3) + if (*qual < 0 || *qual > 3) ret = -EINVAL; else - ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); + ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot); if (ret >= 0) - pdev->vcompression = ARGR(qual); + pdev->vcompression = *qual; break; } case VIDIOCPWCGCQUAL: { - ARG_DEF(int, qual) - - ARGR(qual) = pdev->vcompression; - ARG_OUT(qual) + int *qual = arg; + *qual = pdev->vcompression; break; } case VIDIOCPWCPROBE: { - ARG_DEF(struct pwc_probe, probe) - - strcpy(ARGR(probe).name, pdev->vdev->name); - ARGR(probe).type = pdev->type; - ARG_OUT(probe) + struct pwc_probe *probe = arg; + strcpy(probe->name, pdev->vdev->name); + probe->type = pdev->type; break; } case VIDIOCPWCGSERIAL: { - ARG_DEF(struct pwc_serial, serial) - - strcpy(ARGR(serial).serial, pdev->serial); - ARG_OUT(serial) + struct pwc_serial *serial = arg; + strcpy(serial->serial, pdev->serial); break; } case VIDIOCPWCSAGC: { - ARG_DEF(int, agc) - - ARG_IN(agc) - if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc))) + int *agc = arg; + if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc)) ret = -EINVAL; break; } case VIDIOCPWCGAGC: { - ARG_DEF(int, agc) + int *agc = arg; - if (pwc_get_agc(pdev, ARGA(agc))) + if (pwc_get_agc(pdev, agc)) ret = -EINVAL; - ARG_OUT(agc) break; } case VIDIOCPWCSSHUTTER: { - ARG_DEF(int, shutter_speed) - - ARG_IN(shutter_speed) - ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed)); + int *shutter_speed = arg; + ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed); break; } case VIDIOCPWCSAWB: { - ARG_DEF(struct pwc_whitebalance, wb) + struct pwc_whitebalance *wb = arg; - ARG_IN(wb) - ret = pwc_set_awb(pdev, ARGR(wb).mode); - if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) { - pwc_set_red_gain(pdev, ARGR(wb).manual_red); - pwc_set_blue_gain(pdev, ARGR(wb).manual_blue); + ret = pwc_set_awb(pdev, wb->mode); + if (ret >= 0 && wb->mode == PWC_WB_MANUAL) { + pwc_set_red_gain(pdev, wb->manual_red); + pwc_set_blue_gain(pdev, wb->manual_blue); } break; } case VIDIOCPWCGAWB: { - ARG_DEF(struct pwc_whitebalance, wb) + struct pwc_whitebalance *wb = arg; - memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance)); - ARGR(wb).mode = pwc_get_awb(pdev); - if (ARGR(wb).mode < 0) + memset(wb, 0, sizeof(struct pwc_whitebalance)); + wb->mode = pwc_get_awb(pdev); + if (wb->mode < 0) ret = -EINVAL; else { - if (ARGR(wb).mode == PWC_WB_MANUAL) { - ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red); + if (wb->mode == PWC_WB_MANUAL) { + ret = pwc_get_red_gain(pdev, &wb->manual_red); if (ret < 0) break; - ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue); + ret = pwc_get_blue_gain(pdev, &wb->manual_blue); if (ret < 0) break; } - if (ARGR(wb).mode == PWC_WB_AUTO) { - ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red); + if (wb->mode == PWC_WB_AUTO) { + ret = pwc_read_red_gain(pdev, &wb->read_red); if (ret < 0) break; - ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); + ret = pwc_read_blue_gain(pdev, &wb->read_blue); if (ret < 0) break; } } - ARG_OUT(wb) break; } case VIDIOCPWCSAWBSPEED: { - ARG_DEF(struct pwc_wb_speed, wbs) + struct pwc_wb_speed *wbs = arg; - if (ARGR(wbs).control_speed > 0) { - ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed); + if (wbs->control_speed > 0) { + ret = pwc_set_wb_speed(pdev, wbs->control_speed); } - if (ARGR(wbs).control_delay > 0) { - ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay); + if (wbs->control_delay > 0) { + ret = pwc_set_wb_delay(pdev, wbs->control_delay); } break; } case VIDIOCPWCGAWBSPEED: { - ARG_DEF(struct pwc_wb_speed, wbs) + struct pwc_wb_speed *wbs = arg; - ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed); + ret = pwc_get_wb_speed(pdev, &wbs->control_speed); if (ret < 0) break; - ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay); + ret = pwc_get_wb_delay(pdev, &wbs->control_delay); if (ret < 0) break; - ARG_OUT(wbs) break; } case VIDIOCPWCSLED: { - ARG_DEF(struct pwc_leds, leds) - - ARG_IN(leds) - ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off); + struct pwc_leds *leds = arg; + ret = pwc_set_leds(pdev, leds->led_on, leds->led_off); break; } case VIDIOCPWCGLED: { - ARG_DEF(struct pwc_leds, leds) - - ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off); - ARG_OUT(leds) + struct pwc_leds *leds = arg; + ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off); break; } case VIDIOCPWCSCONTOUR: { - ARG_DEF(int, contour) - - ARG_IN(contour) - ret = pwc_set_contour(pdev, ARGR(contour)); + int *contour = arg; + ret = pwc_set_contour(pdev, *contour); break; } case VIDIOCPWCGCONTOUR: { - ARG_DEF(int, contour) - - ret = pwc_get_contour(pdev, ARGA(contour)); - ARG_OUT(contour) + int *contour = arg; + ret = pwc_get_contour(pdev, contour); break; } case VIDIOCPWCSBACKLIGHT: { - ARG_DEF(int, backlight) - - ARG_IN(backlight) - ret = pwc_set_backlight(pdev, ARGR(backlight)); + int *backlight = arg; + ret = pwc_set_backlight(pdev, *backlight); break; } case VIDIOCPWCGBACKLIGHT: { - ARG_DEF(int, backlight) - - ret = pwc_get_backlight(pdev, ARGA(backlight)); - ARG_OUT(backlight) + int *backlight = arg; + ret = pwc_get_backlight(pdev, backlight); break; } case VIDIOCPWCSFLICKER: { - ARG_DEF(int, flicker) - - ARG_IN(flicker) - ret = pwc_set_flicker(pdev, ARGR(flicker)); + int *flicker = arg; + ret = pwc_set_flicker(pdev, *flicker); break; } case VIDIOCPWCGFLICKER: { - ARG_DEF(int, flicker) - - ret = pwc_get_flicker(pdev, ARGA(flicker)); - ARG_OUT(flicker) + int *flicker = arg; + ret = pwc_get_flicker(pdev, flicker); break; } case VIDIOCPWCSDYNNOISE: { - ARG_DEF(int, dynnoise) - - ARG_IN(dynnoise) - ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise)); + int *dynnoise = arg; + ret = pwc_set_dynamic_noise(pdev, *dynnoise); break; } case VIDIOCPWCGDYNNOISE: { - ARG_DEF(int, dynnoise) - - ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise)); - ARG_OUT(dynnoise); + int *dynnoise = arg; + ret = pwc_get_dynamic_noise(pdev, dynnoise); break; } case VIDIOCPWCGREALSIZE: { - ARG_DEF(struct pwc_imagesize, size) - - ARGR(size).width = pdev->image.x; - ARGR(size).height = pdev->image.y; - ARG_OUT(size) + struct pwc_imagesize *size = arg; + size->width = pdev->image.x; + size->height = pdev->image.y; break; } @@ -1464,10 +1388,9 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(int, flags) + int *flags = arg; - ARG_IN(flags) - ret = pwc_mpt_reset(pdev, ARGR(flags)); + ret = pwc_mpt_reset(pdev, *flags); if (ret >= 0) { pdev->pan_angle = 0; @@ -1485,10 +1408,8 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(struct pwc_mpt_range, range) - - ARGR(range) = pdev->angle_range; - ARG_OUT(range) + struct pwc_mpt_range *range = arg; + *range = pdev->angle_range; } else { @@ -1503,21 +1424,19 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(struct pwc_mpt_angles, angles) - - ARG_IN(angles) + struct pwc_mpt_angles *angles = arg; /* The camera can only set relative angles, so do some calculations when getting an absolute angle . */ - if (ARGR(angles).absolute) + if (angles->absolute) { - new_pan = ARGR(angles).pan; - new_tilt = ARGR(angles).tilt; + new_pan = angles->pan; + new_tilt = angles->tilt; } else { - new_pan = pdev->pan_angle + ARGR(angles).pan; - new_tilt = pdev->tilt_angle + ARGR(angles).tilt; + new_pan = pdev->pan_angle + angles->pan; + new_tilt = pdev->tilt_angle + angles->tilt; } /* check absolute ranges */ if (new_pan < pdev->angle_range.pan_min || @@ -1560,12 +1479,11 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(struct pwc_mpt_angles, angles) + struct pwc_mpt_angles *angles = arg; - ARGR(angles).absolute = 1; - ARGR(angles).pan = pdev->pan_angle; - ARGR(angles).tilt = pdev->tilt_angle; - ARG_OUT(angles) + angles->absolute = 1; + angles->pan = pdev->pan_angle; + angles->tilt = pdev->tilt_angle; } else { @@ -1578,10 +1496,8 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(struct pwc_mpt_status, status) - - ret = pwc_mpt_get_status(pdev, ARGA(status)); - ARG_OUT(status) + struct pwc_mpt_status *status = arg; + ret = pwc_mpt_get_status(pdev, status); } else { @@ -1592,24 +1508,22 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) case VIDIOCPWCGVIDCMD: { - ARG_DEF(struct pwc_video_command, cmd); + struct pwc_video_command *cmd = arg; - ARGR(cmd).type = pdev->type; - ARGR(cmd).release = pdev->release; - ARGR(cmd).command_len = pdev->cmd_len; - memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len); - ARGR(cmd).bandlength = pdev->vbandlength; - ARGR(cmd).frame_size = pdev->frame_size; - ARG_OUT(cmd) + cmd->type = pdev->type; + cmd->release = pdev->release; + cmd->command_len = pdev->cmd_len; + memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len); + cmd->bandlength = pdev->vbandlength; + cmd->frame_size = pdev->frame_size; break; } /* case VIDIOCPWCGVIDTABLE: { - ARG_DEF(struct pwc_table_init_buffer, table); - ARGR(table).len = pdev->cmd_len; - memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size); - ARG_OUT(table) + struct pwc_table_init_buffer *table = arg; + table->len = pdev->cmd_len; + memcpy(&table->buffer, pdev->decompress_data, pdev->decompressor->table_size); break; } */ From bf8b2b5345145d41d39035b80f36c8e17342d833 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 25 Dec 2005 19:27:18 -0800 Subject: [PATCH 257/695] [PATCH] USB EHCI: fix gfp_t sparse warning Fix sparse warning: drivers/usb/host/ehci-hcd.c:719:35: warning: incorrect type in argument 3 (different base types) drivers/usb/host/ehci-hcd.c:719:35: expected unsigned int [unsigned] mem_flags drivers/usb/host/ehci-hcd.c:719:35: got restricted unsigned int [usertype] mem_flags Signed-off-by: Randy Dunlap Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index fe0678624ec0..ebcca9700671 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1844,8 +1844,7 @@ done: #else static inline int -sitd_submit (struct ehci_hcd *ehci, struct urb *urb, - unsigned mem_flags) +sitd_submit (struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags) { ehci_dbg (ehci, "split iso support is disabled\n"); return -ENOSYS; From 7f2c01ab8ad50c74d174acdd814ddb53383bee93 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 9 Jan 2006 00:43:39 +0100 Subject: [PATCH 258/695] [PATCH] USB: drivers/usb/media/w9968cf.c: remove hooks for the vpp module - the w9968cf-vpp module is not intended for inclusion into the kernel - the upstream w9968cf package shipping the w9968cf-vpp module suggests to simply replace the w9968cf module shipped with the kernel Therefore, there seems to be no good reason spending some bytes of kernel memory for hooks for the w9968cf-vpp module. Signed-off-by: Adrian Bunk Signed-off-by: Luca Risolia Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/w9968cf.txt | 30 ++------ drivers/usb/media/w9968cf.c | 128 +------------------------------- drivers/usb/media/w9968cf.h | 1 - drivers/usb/media/w9968cf_vpp.h | 3 - 4 files changed, 6 insertions(+), 156 deletions(-) diff --git a/Documentation/usb/w9968cf.txt b/Documentation/usb/w9968cf.txt index 18a47738d56c..9d46cd0b19e3 100644 --- a/Documentation/usb/w9968cf.txt +++ b/Documentation/usb/w9968cf.txt @@ -57,16 +57,12 @@ based cameras should be supported as well. The driver is divided into two modules: the basic one, "w9968cf", is needed for the supported devices to work; the second one, "w9968cf-vpp", is an optional module, which provides some useful video post-processing functions like video -decoding, up-scaling and colour conversions. Once the driver is installed, -every time an application tries to open a recognized device, "w9968cf" checks -the presence of the "w9968cf-vpp" module and loads it automatically by default. +decoding, up-scaling and colour conversions. -Please keep in mind that official kernels do not include the second module for -performance purposes. However it is always recommended to download and install -the latest and complete release of the driver, replacing the existing one, if -present: it will be still even possible not to load the "w9968cf-vpp" module at -all, if you ever want to. Another important missing feature of the version in -the official Linux 2.4 kernels is the writeable /proc filesystem interface. +Note that the official kernels do neither include nor support the second +module for performance purposes. Therefore, it is always recommended to +download and install the latest and complete release of the driver, +replacing the existing one, if present. The latest and full-featured version of the W996[87]CF driver can be found at: http://www.linux-projects.org. Please refer to the documentation included in @@ -201,22 +197,6 @@ Note: The kernel must be compiled with the CONFIG_KMOD option enabled for the 'ovcamchip' module to be loaded and for this parameter to be present. ------------------------------------------------------------------------------- -Name: vppmod_load -Type: bool -Syntax: <0|1> -Description: Automatic 'w9968cf-vpp' module loading: 0 disabled, 1 enabled. - If enabled, every time an application attempts to open a - camera, 'insmod' searches for the video post-processing module - in the system and loads it automatically (if present). - The optional 'w9968cf-vpp' module adds extra image manipulation - capabilities to the 'w9968cf' module,like software up-scaling, - colour conversions and video decompression for very high frame - rates. -Default: 1 -Note: The kernel must be compiled with the CONFIG_KMOD option - enabled for the 'w9968cf-vpp' module to be loaded and for - this parameter to be present. -------------------------------------------------------------------------------- Name: simcams Type: int Syntax: diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index bff9434c8e55..9937fc64c8bf 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c @@ -62,7 +62,6 @@ MODULE_LICENSE(W9968CF_MODULE_LICENSE); MODULE_SUPPORTED_DEVICE("Video"); static int ovmod_load = W9968CF_OVMOD_LOAD; -static int vppmod_load = W9968CF_VPPMOD_LOAD; static unsigned short simcams = W9968CF_SIMCAMS; static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/ static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] = @@ -107,7 +106,6 @@ static unsigned int param_nv[24]; /* number of values per parameter */ #ifdef CONFIG_KMOD module_param(ovmod_load, bool, 0644); -module_param(vppmod_load, bool, 0444); #endif module_param(simcams, ushort, 0644); module_param_array(video_nr, short, ¶m_nv[0], 0444); @@ -150,18 +148,6 @@ MODULE_PARM_DESC(ovmod_load, "\ninto memory." "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"." "\n"); -MODULE_PARM_DESC(vppmod_load, - "\n<0|1> Automatic 'w9968cf-vpp' module loading." - "\n0 disabled, 1 enabled." - "\nIf enabled, every time an application attempts to open a" - "\ncamera, 'insmod' searches for the video post-processing" - "\nmodule in the system and loads it automatically (if" - "\npresent). The optional 'w9968cf-vpp' module adds extra" - "\n image manipulation functions to the 'w9968cf' module,like" - "\nsoftware up-scaling,colour conversions and video decoding" - "\nfor very high frame rates." - "\nDefault value is "__MODULE_STRING(W9968CF_VPPMOD_LOAD)"." - "\n"); #endif MODULE_PARM_DESC(simcams, "\n Number of cameras allowed to stream simultaneously." @@ -492,10 +478,6 @@ static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num); static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**); static void w9968cf_release_resources(struct w9968cf_device*); -/* Intermodule communication */ -static int w9968cf_vppmod_detect(struct w9968cf_device*); -static void w9968cf_vppmod_release(struct w9968cf_device*); - /**************************************************************************** @@ -2737,9 +2719,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp) cam->streaming = 0; cam->misconfigured = 0; - if (!w9968cf_vpp) - if ((err = w9968cf_vppmod_detect(cam))) - goto out; + w9968cf_adjust_configuration(cam); if ((err = w9968cf_allocate_memory(cam))) goto deallocate_memory; @@ -2766,7 +2746,6 @@ static int w9968cf_open(struct inode* inode, struct file* filp) deallocate_memory: w9968cf_deallocate_memory(cam); -out: DBG(2, "Failed to open the video device") up(&cam->dev_sem); up_read(&w9968cf_disconnect); @@ -2784,8 +2763,6 @@ static int w9968cf_release(struct inode* inode, struct file* filp) w9968cf_stop_transfer(cam); - w9968cf_vppmod_release(cam); - if (cam->disconnected) { w9968cf_release_resources(cam); up(&cam->dev_sem); @@ -3681,106 +3658,6 @@ static struct usb_driver w9968cf_usb_driver = { * Module init, exit and intermodule communication * ****************************************************************************/ -static int w9968cf_vppmod_detect(struct w9968cf_device* cam) -{ - if (!w9968cf_vpp) - if (vppmod_load) - request_module("w9968cf-vpp"); - - down(&w9968cf_vppmod_lock); - - if (!w9968cf_vpp) { - DBG(4, "Video post-processing module not detected") - w9968cf_adjust_configuration(cam); - goto out; - } - - if (!try_module_get(w9968cf_vpp->owner)) { - DBG(1, "Couldn't increment the reference count of " - "the video post-processing module") - up(&w9968cf_vppmod_lock); - return -ENOSYS; - } - - w9968cf_vpp->busy++; - - DBG(5, "Video post-processing module detected") - -out: - up(&w9968cf_vppmod_lock); - return 0; -} - - -static void w9968cf_vppmod_release(struct w9968cf_device* cam) -{ - down(&w9968cf_vppmod_lock); - - if (w9968cf_vpp && w9968cf_vpp->busy) { - module_put(w9968cf_vpp->owner); - w9968cf_vpp->busy--; - wake_up(&w9968cf_vppmod_wait); - DBG(5, "Video post-processing module released") - } - - up(&w9968cf_vppmod_lock); -} - - -int w9968cf_vppmod_register(struct w9968cf_vpp_t* vpp) -{ - down(&w9968cf_vppmod_lock); - - if (w9968cf_vpp) { - KDBG(1, "Video post-processing module already registered") - up(&w9968cf_vppmod_lock); - return -EINVAL; - } - - w9968cf_vpp = vpp; - w9968cf_vpp->busy = 0; - - KDBG(2, "Video post-processing module registered") - up(&w9968cf_vppmod_lock); - return 0; -} - - -int w9968cf_vppmod_deregister(struct w9968cf_vpp_t* vpp) -{ - down(&w9968cf_vppmod_lock); - - if (!w9968cf_vpp) { - up(&w9968cf_vppmod_lock); - return -EINVAL; - } - - if (w9968cf_vpp != vpp) { - KDBG(1, "Only the owner can unregister the video " - "post-processing module") - up(&w9968cf_vppmod_lock); - return -EINVAL; - } - - if (w9968cf_vpp->busy) { - KDBG(2, "Video post-processing module busy. Wait for it to be " - "released...") - up(&w9968cf_vppmod_lock); - wait_event(w9968cf_vppmod_wait, !w9968cf_vpp->busy); - w9968cf_vpp = NULL; - goto out; - } - - w9968cf_vpp = NULL; - - up(&w9968cf_vppmod_lock); - -out: - KDBG(2, "Video post-processing module unregistered") - return 0; -} - - static int __init w9968cf_module_init(void) { int err; @@ -3810,6 +3687,3 @@ static void __exit w9968cf_module_exit(void) module_init(w9968cf_module_init); module_exit(w9968cf_module_exit); - -EXPORT_SYMBOL(w9968cf_vppmod_register); -EXPORT_SYMBOL(w9968cf_vppmod_deregister); diff --git a/drivers/usb/media/w9968cf.h b/drivers/usb/media/w9968cf.h index 8acbfe205bc7..47a6ff794171 100644 --- a/drivers/usb/media/w9968cf.h +++ b/drivers/usb/media/w9968cf.h @@ -195,7 +195,6 @@ enum w9968cf_vpp_flag { }; static struct w9968cf_vpp_t* w9968cf_vpp; -static DECLARE_MUTEX(w9968cf_vppmod_lock); static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait); static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */ diff --git a/drivers/usb/media/w9968cf_vpp.h b/drivers/usb/media/w9968cf_vpp.h index 3f5317dc4c29..f3b91b782671 100644 --- a/drivers/usb/media/w9968cf_vpp.h +++ b/drivers/usb/media/w9968cf_vpp.h @@ -37,7 +37,4 @@ struct w9968cf_vpp_t { u8 busy; /* read-only flag: module is/is not in use */ }; -extern int w9968cf_vppmod_register(struct w9968cf_vpp_t*); -extern int w9968cf_vppmod_deregister(struct w9968cf_vpp_t*); - #endif /* _W9968CF_VPP_H_ */ From 532a3de17038ea3bf75814778a6c4a25d01eab74 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 6 Jan 2006 03:28:52 +0100 Subject: [PATCH 259/695] [PATCH] USB: drivers/usb/media/ov511.c: remove hooks for the decomp module - the decomp module is not intended for inclusion into the kernel - people using the decomp module from upstream will usually simply use the complete upstream 2.xx driver Therefore, there seems to be no good reason spending some bytes of kernel memory for hooks for this module. Signed-off-by: Adrian Bunk Signed-off-by: Mark McClelland Signed-off-by: Greg Kroah-Hartman --- drivers/usb/media/ov511.c | 196 +------------------------------------- 1 file changed, 2 insertions(+), 194 deletions(-) diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index 8af665bbe330..51e9cc06f7e3 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c @@ -204,22 +204,10 @@ MODULE_LICENSE("GPL"); static struct usb_driver ov511_driver; -static struct ov51x_decomp_ops *ov511_decomp_ops; -static struct ov51x_decomp_ops *ov511_mmx_decomp_ops; -static struct ov51x_decomp_ops *ov518_decomp_ops; -static struct ov51x_decomp_ops *ov518_mmx_decomp_ops; - /* Number of times to retry a failed I2C transaction. Increase this if you * are getting "Failed to read sensor ID..." */ static const int i2c_detect_tries = 5; -/* MMX support is present in kernel and CPU. Checked upon decomp module load. */ -#if defined(__i386__) || defined(__x86_64__) -#define ov51x_mmx_available (cpu_has_mmx) -#else -#define ov51x_mmx_available (0) -#endif - static struct usb_device_id device_table [] = { { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) }, { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) }, @@ -3012,93 +3000,18 @@ yuv420raw_to_yuv420p(struct ov511_frame *frame, * **********************************************************************/ -/* Chooses a decompression module, locks it, and sets ov->decomp_ops - * accordingly. Returns -ENXIO if decompressor is not available, otherwise - * returns 0 if no other error. - */ static int request_decompressor(struct usb_ov511 *ov) { - if (!ov) - return -ENODEV; - - if (ov->decomp_ops) { - err("ERROR: Decompressor already requested!"); - return -EINVAL; - } - - lock_kernel(); - - /* Try to get MMX, and fall back on no-MMX if necessary */ - if (ov->bclass == BCL_OV511) { - if (ov511_mmx_decomp_ops) { - PDEBUG(3, "Using OV511 MMX decompressor"); - ov->decomp_ops = ov511_mmx_decomp_ops; - } else if (ov511_decomp_ops) { - PDEBUG(3, "Using OV511 decompressor"); - ov->decomp_ops = ov511_decomp_ops; - } else { - err("No decompressor available"); - } - } else if (ov->bclass == BCL_OV518) { - if (ov518_mmx_decomp_ops) { - PDEBUG(3, "Using OV518 MMX decompressor"); - ov->decomp_ops = ov518_mmx_decomp_ops; - } else if (ov518_decomp_ops) { - PDEBUG(3, "Using OV518 decompressor"); - ov->decomp_ops = ov518_decomp_ops; - } else { - err("No decompressor available"); - } + if (ov->bclass == BCL_OV511 || ov->bclass == BCL_OV518) { + err("No decompressor available"); } else { err("Unknown bridge"); } - if (!ov->decomp_ops) - goto nosys; - - if (!ov->decomp_ops->owner) { - ov->decomp_ops = NULL; - goto nosys; - } - - if (!try_module_get(ov->decomp_ops->owner)) - goto nosys; - - unlock_kernel(); - return 0; - - nosys: - unlock_kernel(); return -ENOSYS; } -/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even - * if ov->decomp_ops is NULL. - */ -static void -release_decompressor(struct usb_ov511 *ov) -{ - int released = 0; /* Did we actually do anything? */ - - if (!ov) - return; - - lock_kernel(); - - if (ov->decomp_ops) { - module_put(ov->decomp_ops->owner); - released = 1; - } - - ov->decomp_ops = NULL; - - unlock_kernel(); - - if (released) - PDEBUG(3, "Decompressor released"); -} - static void decompress(struct usb_ov511 *ov, struct ov511_frame *frame, unsigned char *pIn0, unsigned char *pOut0) @@ -3107,31 +3020,6 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame, if (request_decompressor(ov)) return; - PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd); - - if (frame->format == VIDEO_PALETTE_GREY - && ov->decomp_ops->decomp_400) { - int ret = ov->decomp_ops->decomp_400( - pIn0, - pOut0, - frame->compbuf, - frame->rawwidth, - frame->rawheight, - frame->bytes_recvd); - PDEBUG(4, "DEBUG: decomp_400 returned %d", ret); - } else if (frame->format != VIDEO_PALETTE_GREY - && ov->decomp_ops->decomp_420) { - int ret = ov->decomp_ops->decomp_420( - pIn0, - pOut0, - frame->compbuf, - frame->rawwidth, - frame->rawheight, - frame->bytes_recvd); - PDEBUG(4, "DEBUG: decomp_420 returned %d", ret); - } else { - err("Decompressor does not support this format"); - } } /********************************************************************** @@ -4087,8 +3975,6 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) ov->user--; ov51x_stop_isoc(ov); - release_decompressor(ov); - if (ov->led_policy == LED_AUTO) ov51x_led_control(ov, 0); @@ -6021,82 +5907,6 @@ static struct usb_driver ov511_driver = { * ***************************************************************************/ -/* Returns 0 for success */ -int -ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518, - int mmx) -{ - if (ver != DECOMP_INTERFACE_VER) { - err("Decompression module has incompatible"); - err("interface version %d", ver); - err("Interface version %d is required", DECOMP_INTERFACE_VER); - return -EINVAL; - } - - if (!ops) - return -EFAULT; - - if (mmx && !ov51x_mmx_available) { - err("MMX not available on this system or kernel"); - return -EINVAL; - } - - lock_kernel(); - - if (ov518) { - if (mmx) { - if (ov518_mmx_decomp_ops) - goto err_in_use; - else - ov518_mmx_decomp_ops = ops; - } else { - if (ov518_decomp_ops) - goto err_in_use; - else - ov518_decomp_ops = ops; - } - } else { - if (mmx) { - if (ov511_mmx_decomp_ops) - goto err_in_use; - else - ov511_mmx_decomp_ops = ops; - } else { - if (ov511_decomp_ops) - goto err_in_use; - else - ov511_decomp_ops = ops; - } - } - - unlock_kernel(); - return 0; - -err_in_use: - unlock_kernel(); - return -EBUSY; -} - -void -ov511_deregister_decomp_module(int ov518, int mmx) -{ - lock_kernel(); - - if (ov518) { - if (mmx) - ov518_mmx_decomp_ops = NULL; - else - ov518_decomp_ops = NULL; - } else { - if (mmx) - ov511_mmx_decomp_ops = NULL; - else - ov511_decomp_ops = NULL; - } - - unlock_kernel(); -} - static int __init usb_ov511_init(void) { @@ -6123,5 +5933,3 @@ usb_ov511_exit(void) module_init(usb_ov511_init); module_exit(usb_ov511_exit); -EXPORT_SYMBOL(ov511_register_decomp_module); -EXPORT_SYMBOL(ov511_deregister_decomp_module); From de289fdf6f6c51b21c94283ffa219d31e583f327 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 6 Jan 2006 12:45:28 +0100 Subject: [PATCH 260/695] [PATCH] USB: remove extra newline in hid_init_reports The warn() macro in include/linux/usb.h adds a newline. Signed-off-by: Olaf Hering Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 617ce657f784..6f7a684c3e07 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1307,7 +1307,7 @@ void hid_init_reports(struct hid_device *hid) } if (err) - warn("timeout initializing reports\n"); + warn("timeout initializing reports"); } #define USB_VENDOR_ID_WACOM 0x056a From 05090fc969be0bd1e01c3798b17fe7947fad0efa Mon Sep 17 00:00:00 2001 From: Sergei Shtylylov Date: Thu, 5 Jan 2006 22:50:39 -0800 Subject: [PATCH 261/695] [PATCH] USB: Au1xx0: replace casual readl() with au_readl() in the drivers au_readl() does needed byteswapping, etc. Cc: Takashi Iwai Cc: Jaroslav Kysela Acked-by: Jordan Crouse Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-au1xxx.c | 2 +- sound/oss/au1550_ac97.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 77cd6ac07e3c..db280ca7b7a0 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -67,7 +67,7 @@ static void au1xxx_stop_hc(struct platform_device *dev) ": stopping Au1xxx OHCI USB Controller\n"); /* Disable clock */ - au_writel(readl((void *)USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); + au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); } diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index b963c550dae6..bdee0502f3e2 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -462,7 +462,7 @@ stop_dac(struct au1550_state *s) /* Wait for Transmit Busy to show disabled. */ do { - stat = readl((void *)PSC_AC97STAT); + stat = au_readl(PSC_AC97STAT); au_sync(); } while ((stat & PSC_AC97STAT_TB) != 0); @@ -491,7 +491,7 @@ stop_adc(struct au1550_state *s) /* Wait for Receive Busy to show disabled. */ do { - stat = readl((void *)PSC_AC97STAT); + stat = au_readl(PSC_AC97STAT); au_sync(); } while ((stat & PSC_AC97STAT_RB) != 0); @@ -541,7 +541,7 @@ set_xmit_slots(int num_channels) /* Wait for Device ready. */ do { - stat = readl((void *)PSC_AC97STAT); + stat = au_readl(PSC_AC97STAT); au_sync(); } while ((stat & PSC_AC97STAT_DR) == 0); } @@ -573,7 +573,7 @@ set_recv_slots(int num_channels) /* Wait for Device ready. */ do { - stat = readl((void *)PSC_AC97STAT); + stat = au_readl(PSC_AC97STAT); au_sync(); } while ((stat & PSC_AC97STAT_DR) == 0); } @@ -1995,7 +1995,7 @@ au1550_probe(void) /* Wait for PSC ready. */ do { - val = readl((void *)PSC_AC97STAT); + val = au_readl(PSC_AC97STAT); au_sync(); } while ((val & PSC_AC97STAT_SR) == 0); @@ -2018,7 +2018,7 @@ au1550_probe(void) /* Wait for Device ready. */ do { - val = readl((void *)PSC_AC97STAT); + val = au_readl(PSC_AC97STAT); au_sync(); } while ((val & PSC_AC97STAT_DR) == 0); From 5d68dfcf3a1c2c4a74e6f08362ade5b97637147d Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 19 Jan 2006 00:06:07 +0300 Subject: [PATCH 262/695] [PATCH] USB: arm26: fix compilation of drivers/usb/core/message.c drivers/usb/core/message.c:395: error: invalid use of undefined type `struct scatterlist' Signed-off-by: Alexey Dobriyan Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 319de03944e7..7135e542679d 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "hcd.h" /* for usbcore internals */ #include "usb.h" From 6d453b9e3007da2c6cd8b71883505c381f0e0004 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 17 Jan 2006 15:39:25 -0800 Subject: [PATCH 263/695] [PATCH] USB: libusual: fix warning on 64bit boxes We cast an int to a void * which not unreasonably makes gcc suspicious. We don't actually care what type "type" is so use unsigned long so it matches pointer length on all platforms. Signed-off-by: Alan Cox Acked-by: Pete Zaitcev Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/libusual.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c index b28151d1b609..b1ec4a718547 100644 --- a/drivers/usb/storage/libusual.c +++ b/drivers/usb/storage/libusual.c @@ -116,7 +116,7 @@ EXPORT_SYMBOL_GPL(usb_usual_check_type); static int usu_probe(struct usb_interface *intf, const struct usb_device_id *id) { - int type; + unsigned long type; int rc; unsigned long flags; From 877260bd2618d1a6e6acf63100bd9d009b7c2856 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 19 Jan 2006 23:59:12 -0800 Subject: [PATCH 264/695] [PATCH] USB: yealink printk warning fix drivers/usb/input/yealink.c: In function `usb_probe': drivers/usb/input/yealink.c:910: warning: int format, different type arg (arg 4) Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/yealink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index 067be34b4241..37d2f0ba0319 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c @@ -907,7 +907,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); if (ret != USB_PKT_LEN) - err("invalid payload size %d, expected %d", ret, USB_PKT_LEN); + err("invalid payload size %d, expected %zd", ret, USB_PKT_LEN); /* initialise irq urb */ usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data, From c02c4bb2058587d3c012ec08268fd93fdc654ae7 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 20 Jan 2006 14:44:12 -0800 Subject: [PATCH 265/695] [PATCH] USB: USB authentication states Another hook needed for wireless USB: there are states associated with the device authentication protocol. Wireless devices must authenticate using the host system's keystore. Note that wired connections could also use this authentication protocol, if for no other reason than to support the most secure "simple" key exchange protocols for wireless devices. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb_ch9.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h index ee21e6bf3867..a2aacfc7af2f 100644 --- a/include/linux/usb_ch9.h +++ b/include/linux/usb_ch9.h @@ -535,9 +535,11 @@ enum usb_device_state { */ USB_STATE_NOTATTACHED = 0, - /* the chapter 9 device states */ + /* chapter 9 and authentication (wireless) device states */ USB_STATE_ATTACHED, - USB_STATE_POWERED, + USB_STATE_POWERED, /* wired */ + USB_STATE_UNAUTHENTICATED, /* auth */ + USB_STATE_RECONNECTING, /* auth */ USB_STATE_DEFAULT, /* limited function */ USB_STATE_ADDRESS, USB_STATE_CONFIGURED, /* most functions */ From 69396dcfa3c50a6b8d2caaccf5d1496ecd5594be Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 20 Jan 2006 14:38:49 -0800 Subject: [PATCH 266/695] [PATCH] USB: gadget zero and dma-coherent buffers This makes sure that the correct length is reported when freeing a dma-coherent buffer; some platforms complain if that's wrong. It also makes two parameters readonly in sysfs, as they're not safe to change while tests are running. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/zero.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 2fc110d3ad5a..ae7a1c0f5748 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -165,8 +165,8 @@ static unsigned buflen = 4096; static unsigned qlen = 32; static unsigned pattern = 0; -module_param (buflen, uint, S_IRUGO|S_IWUSR); -module_param (qlen, uint, S_IRUGO|S_IWUSR); +module_param (buflen, uint, S_IRUGO); +module_param (qlen, uint, S_IRUGO); module_param (pattern, uint, S_IRUGO|S_IWUSR); /* @@ -1127,8 +1127,10 @@ zero_unbind (struct usb_gadget *gadget) DBG (dev, "unbind\n"); /* we've already been disconnected ... no i/o is active */ - if (dev->req) + if (dev->req) { + dev->req->length = USB_BUFSIZ; free_ep_req (gadget->ep0, dev->req); + } del_timer_sync (&dev->resume); kfree (dev); set_gadget_data (gadget, NULL); From 5d39a795bfa217b5f7637028c83ab5cb291f37bf Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 31 Jan 2006 17:35:35 -0800 Subject: [PATCH 267/695] [IPV4]: Always set fl.proto in ip_route_newports ip_route_newports uses the struct flowi from the struct rtable returned by ip_route_connect for the new route lookup and just replaces the port numbers if they have changed. If an IPsec policy exists which doesn't match port 0 the struct flowi won't have the proto field set and no xfrm lookup is done for the changed ports. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/net/route.h | 5 +++-- net/dccp/ipv4.c | 3 ++- net/ipv4/tcp_ipv4.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index e3e5436f8017..9c04f15090d2 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -170,8 +170,8 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst, return ip_route_output_flow(rp, &fl, sk, 0); } -static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport, - struct sock *sk) +static inline int ip_route_newports(struct rtable **rp, u8 protocol, + u16 sport, u16 dport, struct sock *sk) { if (sport != (*rp)->fl.fl_ip_sport || dport != (*rp)->fl.fl_ip_dport) { @@ -180,6 +180,7 @@ static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport, memcpy(&fl, &(*rp)->fl, sizeof(fl)); fl.fl_ip_sport = sport; fl.fl_ip_dport = dport; + fl.proto = protocol; ip_rt_put(*rp); *rp = NULL; return ip_route_output_flow(rp, &fl, sk, 0); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 00f983226672..dc0487b5bace 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -119,7 +119,8 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (err != 0) goto failure; - err = ip_route_newports(&rt, inet->sport, inet->dport, sk); + err = ip_route_newports(&rt, IPPROTO_DCCP, inet->sport, inet->dport, + sk); if (err != 0) goto failure; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 6ea353907af5..1ac35a65b2e5 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -236,7 +236,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (err) goto failure; - err = ip_route_newports(&rt, inet->sport, inet->dport, sk); + err = ip_route_newports(&rt, IPPROTO_TCP, inet->sport, inet->dport, sk); if (err) goto failure; From 3f4cfc2d11c9e29709e6f0f3add54039614d847a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 31 Jan 2006 17:44:07 -0800 Subject: [PATCH 268/695] [BRIDGE]: Fix device delete race. This is a simpler fix for the two races in bridge device removal. The Xen race of delif and notify is managed now by a new deleted flag. No need for barriers or other locking because of rtnl mutex. The del_timer_sync()'s are unnecessary, because br_stp_disable_port delete's the timers, and they will finish running before RCU callback. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 21 +++++++++++++++------ net/bridge/br_private.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index ba442883e877..da687c8dc6ff 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -104,6 +104,7 @@ static void destroy_nbp(struct net_bridge_port *p) { struct net_device *dev = p->dev; + dev->br_port = NULL; p->br = NULL; p->dev = NULL; dev_put(dev); @@ -118,13 +119,24 @@ static void destroy_nbp_rcu(struct rcu_head *head) destroy_nbp(p); } -/* called with RTNL */ +/* Delete port(interface) from bridge is done in two steps. + * via RCU. First step, marks device as down. That deletes + * all the timers and stops new packets from flowing through. + * + * Final cleanup doesn't occur until after all CPU's finished + * processing packets. + * + * Protected from multiple admin operations by RTNL mutex + */ static void del_nbp(struct net_bridge_port *p) { struct net_bridge *br = p->br; struct net_device *dev = p->dev; - dev->br_port = NULL; + /* Race between RTNL notify and RCU callback */ + if (p->deleted) + return; + dev_set_promiscuity(dev, -1); cancel_delayed_work(&p->carrier_check); @@ -132,16 +144,13 @@ static void del_nbp(struct net_bridge_port *p) spin_lock_bh(&br->lock); br_stp_disable_port(p); + p->deleted = 1; spin_unlock_bh(&br->lock); br_fdb_delete_by_port(br, p); list_del_rcu(&p->list); - del_timer_sync(&p->message_age_timer); - del_timer_sync(&p->forward_delay_timer); - del_timer_sync(&p->hold_timer); - call_rcu(&p->rcu, destroy_nbp_rcu); } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index c5bd631ffcd5..e330b17b6d81 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -68,6 +68,7 @@ struct net_bridge_port /* STP */ u8 priority; u8 state; + u8 deleted; u16 port_no; unsigned char topology_change_ack; unsigned char config_pending; From f9d9516db71eb3a8547948cdddc139eb1c1b9aee Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 31 Jan 2006 17:47:02 -0800 Subject: [PATCH 269/695] [NET]: Do not export inet_bind_bucket_create twice. inet_bind_bucket_create was exported twice. Keep the export in the file where inet_bind_bucket_create is defined. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- net/ipv4/tcp_ipv4.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1ac35a65b2e5..233bdf259965 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1845,7 +1845,6 @@ void __init tcp_v4_init(struct net_proto_family *ops) } EXPORT_SYMBOL(ipv4_specific); -EXPORT_SYMBOL(inet_bind_bucket_create); EXPORT_SYMBOL(tcp_hashinfo); EXPORT_SYMBOL(tcp_prot); EXPORT_SYMBOL(tcp_unhash); From 78b910429e2c037533d2a7bd9e95b4f94f905ef8 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 31 Jan 2006 17:51:44 -0800 Subject: [PATCH 270/695] [IPV6] tcp_v6_send_synack: release the destination This patch fix dst reference counting in tcp_v6_send_synack Analysis: Currently tcp_v6_send_synack is never called with a dst entry so dst always comes in as NULL. ip6_dst_lookup calls ip6_route_output which calls dst_hold before it returns the dst entry. Neither xfrm_lookup nor tcp_make_synack consume the dst entry so we still have a dst_entry with a bumped refrence count at the end of this function. Therefore we need to call dst_release just before we return just like tcp_v4_send_synack does. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 66d04004afda..ca9cf6853755 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -515,6 +515,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, done: if (opt && opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); + dst_release(dst); return err; } From 0cbd782507c502428c8ab3e91bee3940c19ac4d4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Jan 2006 17:53:37 -0800 Subject: [PATCH 271/695] [DCCP] ipv6: dccp_v6_send_response() has a DST leak too. It was copy&pasted from tcp_v6_send_synack() which has a DST leak recently fixed by Eric W. Biederman. So dccp_v6_send_response() needs the same fix too. Signed-off-by: David S. Miller --- net/dccp/ipv6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index df074259f9c3..80c4d048869e 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -468,6 +468,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, done: if (opt && opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); + dst_release(dst); return err; } From b4b2c0411e25c8bd001c683be52a2a5996ea689a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 29 Dec 2005 20:07:25 +0100 Subject: [PATCH 272/695] [PATCH] PCI: schedule PCI_LEGACY_PROC for removal PCI_LEGACY_PROC is deprecated since 2.5.53 in favor of lspci(8). Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- Documentation/feature-removal-schedule.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index b4a1ea762698..b8143bda187f 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -148,3 +148,10 @@ Why: The 8250 serial driver now has the ability to deal with the differences brother on Alchemy SOCs. The loss of features is not considered an issue. Who: Ralf Baechle + +--------------------------- + +What: Legacy /proc/pci interface (PCI_LEGACY_PROC) +When: March 2006 +Why: deprecated since 2.5.53 in favor of lspci(8) +Who: Adrian Bunk From 051d9897731abfac62c4d1a2efcef83a89bd4482 Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Sat, 3 Dec 2005 02:34:12 +0100 Subject: [PATCH 273/695] [PATCH] pci: Schedule removal of pci_module_init Scheduled the removal of pci_module_init. Signed-off-by: Richard Knutsson Signed-off-by: Greg Kroah-Hartman --- Documentation/feature-removal-schedule.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index b8143bda187f..4d4897c8ef96 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -155,3 +155,10 @@ What: Legacy /proc/pci interface (PCI_LEGACY_PROC) When: March 2006 Why: deprecated since 2.5.53 in favor of lspci(8) Who: Adrian Bunk + +--------------------------- + +What: pci_module_init(driver) +When: January 2007 +Why: Is replaced by pci_register_driver(pci_driver). +Who: Richard Knutsson and Greg Kroah-Hartman From b6ebb2659065b6e03605e7f0c69449bda382261a Mon Sep 17 00:00:00 2001 From: Jason Gaston Date: Mon, 9 Jan 2006 10:53:45 -0800 Subject: [PATCH 274/695] [PATCH] PCI: irq and pci_ids: patch for Intel ICH8 This patch adds the Intel ICH8 DID's to the irq.c and pci_ids.h files. Signed-off-by: Jason Gaston Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/irq.c | 5 +++++ include/linux/pci_ids.h | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index e715aa930036..3ca59cad05f3 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -539,6 +539,11 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH7_30: case PCI_DEVICE_ID_INTEL_ICH7_31: case PCI_DEVICE_ID_INTEL_ESB2_0: + case PCI_DEVICE_ID_INTEL_ICH8_0: + case PCI_DEVICE_ID_INTEL_ICH8_1: + case PCI_DEVICE_ID_INTEL_ICH8_2: + case PCI_DEVICE_ID_INTEL_ICH8_3: + case PCI_DEVICE_ID_INTEL_ICH8_4: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 4401a7e06057..9eb1983b8787 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2106,6 +2106,13 @@ #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd #define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de #define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df +#define PCI_DEVICE_ID_INTEL_ICH8_0 0x2810 +#define PCI_DEVICE_ID_INTEL_ICH8_1 0x2811 +#define PCI_DEVICE_ID_INTEL_ICH8_2 0x2812 +#define PCI_DEVICE_ID_INTEL_ICH8_3 0x2814 +#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815 +#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e +#define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 From f8d65713332cf6306889a3036142a17e01e3447e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 6 Jan 2006 03:25:37 +0100 Subject: [PATCH 275/695] [PATCH] PCI: drivers/pci/pci.c: #if 0 pci_find_ext_capability() This patch #if 0's the unused global function pci_find_ext_capability(). Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 2 ++ include/linux/pci.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d2a633efa10a..d2d187916643 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -163,6 +163,7 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap); } +#if 0 /** * pci_find_ext_capability - Find an extended capability * @dev: PCI device to query @@ -210,6 +211,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) return 0; } +#endif /* 0 */ /** * pci_find_parent_resource - return resource region of parent bus of given region diff --git a/include/linux/pci.h b/include/linux/pci.h index 0a44072383ec..fe1a2b02fc55 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -406,7 +406,6 @@ struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int devic struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); -int pci_find_ext_capability (struct pci_dev *dev, int cap); struct pci_bus * pci_find_next_bus(const struct pci_bus *from); struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); @@ -626,7 +625,6 @@ static inline int pci_register_driver(struct pci_driver *drv) { return 0;} static inline void pci_unregister_driver(struct pci_driver *drv) { } static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; } -static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; } static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; } /* Power management related routines */ From 8169b5d2384a0acd9ea3bb86bf5988cd7d62d03a Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Tue, 3 Jan 2006 18:51:46 -0800 Subject: [PATCH 276/695] [PATCH] PCI: make it easier to see that set_msi_affinity() is used I missed this usage in drivers/pci/msi.h: #ifdef CONFIG_SMP #define set_msi_irq_affinity set_msi_affinity #else #define set_msi_irq_affinity NULL #endif set_msi_affinity() is declared and exclusively used in msi.c. Here's a better way so (hopefully) history doesn't repeat itself. Signed-off-by: Grant Grundler Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 8 +++++--- drivers/pci/msi.h | 6 ------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 8e1ba0b7a8e4..48723d6fa60f 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -137,6 +137,8 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) break; } } +#else +#define set_msi_affinity NULL #endif /* CONFIG_SMP */ static void mask_MSI_irq(unsigned int vector) @@ -214,7 +216,7 @@ static struct hw_interrupt_type msix_irq_type = { .disable = mask_MSI_irq, .ack = mask_MSI_irq, .end = end_msi_irq_w_maskbit, - .set_affinity = set_msi_irq_affinity + .set_affinity = set_msi_affinity }; /* @@ -230,7 +232,7 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = { .disable = mask_MSI_irq, .ack = mask_MSI_irq, .end = end_msi_irq_w_maskbit, - .set_affinity = set_msi_irq_affinity + .set_affinity = set_msi_affinity }; /* @@ -246,7 +248,7 @@ static struct hw_interrupt_type msi_irq_wo_maskbit_type = { .disable = do_nothing, .ack = do_nothing, .end = end_msi_irq_wo_maskbit, - .set_affinity = set_msi_irq_affinity + .set_affinity = set_msi_affinity }; static void msi_data_init(struct msg_data *msi_data, diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index 402136a5c9e4..4ac52d441e47 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h @@ -22,12 +22,6 @@ extern int vector_irq[NR_VECTORS]; extern void (*interrupt[NR_IRQS])(void); extern int pci_vector_resources(int last, int nr_released); -#ifdef CONFIG_SMP -#define set_msi_irq_affinity set_msi_affinity -#else -#define set_msi_irq_affinity NULL -#endif - /* * MSI-X Address Register */ From 072888fa60af86c3159f9f3ed4e34364861bab3a Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 8 Jan 2006 20:11:59 +0100 Subject: [PATCH 277/695] [PATCH] PCI Hotplug: fix up coding style issues Signed-off-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_ibm.c | 21 +++++++++------------ drivers/pci/hotplug/ibmphp_core.c | 4 ++-- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 7e7f913ba7b9..317457dd4014 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -302,7 +302,7 @@ static int ibm_get_table_from_acpi(char **bufp) } package = (union acpi_object *) buffer.pointer; - if(!(package) || + if (!(package) || (package->type != ACPI_TYPE_PACKAGE) || !(package->package.elements)) { err("%s: Invalid APCI object\n", __FUNCTION__); @@ -405,7 +405,7 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, } info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0'; - if(info.current_status && (info.valid & ACPI_VALID_HID) && + if (info.current_status && (info.valid & ACPI_VALID_HID) && (!strcmp(info.hardware_id.value, IBM_HARDWARE_ID1) || !strcmp(info.hardware_id.value, IBM_HARDWARE_ID2))) { dbg("found hardware: %s, handle: %p\n", info.hardware_id.value, @@ -449,13 +449,11 @@ static int __init ibm_acpiphp_init(void) } ibm_note.device = device; - status = acpi_install_notify_handler( - ibm_acpi_handle, - ACPI_DEVICE_NOTIFY, - ibm_handle_events, + status = acpi_install_notify_handler(ibm_acpi_handle, + ACPI_DEVICE_NOTIFY, ibm_handle_events, &ibm_note); if (ACPI_FAILURE(status)) { - err("%s: Failed to register notification handler\n", + err("%s: Failed to register notification handler\n", __FUNCTION__); retval = -EBUSY; goto init_cleanup; @@ -482,14 +480,13 @@ static void __exit ibm_acpiphp_exit(void) if (acpiphp_unregister_attention(&ibm_attention_info)) err("%s: attention info deregistration failed", __FUNCTION__); - status = acpi_remove_notify_handler( + status = acpi_remove_notify_handler( ibm_acpi_handle, ACPI_DEVICE_NOTIFY, ibm_handle_events); - if (ACPI_FAILURE(status)) - err("%s: Notification handler removal failed\n", - __FUNCTION__); - // remove the /sys entries + if (ACPI_FAILURE(status)) + err("%s: Notification handler removal failed\n", __FUNCTION__); + /* remove the /sys entries */ if (sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr)) err("%s: removal of sysfs file apci_table failed\n", __FUNCTION__); diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index aabf1e70b528..dc59da675c08 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -235,12 +235,12 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) { int rc = 0; struct slot *pslot; - u8 cmd; + u8 cmd = 0x00; /* avoid compiler warning */ debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n", (ulong) hotplug_slot, value); ibmphp_lock_operations(); - cmd = 0x00; // avoid compiler warning + if (hotplug_slot) { switch (value) { From 654143ee3a73b2793350b039a135d9cd3101147b Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 9 Jan 2006 16:16:00 +0100 Subject: [PATCH 278/695] [PATCH] PCI Hotplug: fix up Kconfig help text Remove reference to pcihpfs that no longer exists. Signed-off-by: Pavel Machek --- drivers/pci/hotplug/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 2f1289eebb3c..222a1cc4aa28 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig @@ -11,8 +11,7 @@ config HOTPLUG_PCI ---help--- Say Y here if you have a motherboard with a PCI Hotplug controller. This allows you to add and remove PCI cards while the machine is - powered up and running. The file system pcihpfs must be mounted - in order to interact with any PCI Hotplug controllers. + powered up and running. To compile this driver as a module, choose M here: the module will be called pci_hotplug. From 8cea8e9303d45556cb606cc8d9e41f889ff600c0 Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Thu, 5 Jan 2006 22:47:29 -0800 Subject: [PATCH 279/695] [PATCH] PCI: restore 2 missing pci ids Somewhere between 2.6.14 and 2.6.15-rc3, some PCI ids were apparently removed. The ecc.c module, which is not a part of the kernel.org tree, but included in some distributions, fails to compile. Signed-off-by: Mark Rustad Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9eb1983b8787..7868a8ed1906 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2065,6 +2065,7 @@ #define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5 #define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6 #define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db +#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd #define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1 #define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2 #define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4 @@ -2156,6 +2157,7 @@ #define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 +#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 #define PCI_DEVICE_ID_INTEL_82451NX 0x84ca #define PCI_DEVICE_ID_INTEL_82454NX 0x84cb #define PCI_DEVICE_ID_INTEL_84460GX 0x84ea From 2181c971952ec2af56cd9cc68453f7ad5a0a38d6 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Sun, 15 Jan 2006 16:21:27 +1100 Subject: [PATCH 280/695] [PATCH] PCI: pci_ids: remove duplicates gathered during merge period pci_ids.h: remove duplicates. Compile tested allmodconfig. Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 7868a8ed1906..b0b908f583c5 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -394,14 +394,9 @@ #define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 #define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 #define PCI_DEVICE_ID_NS_87410 0xd001 -#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d #define PCI_DEVICE_ID_NS_CS5535_HOST_BRIDGE 0x0028 #define PCI_DEVICE_ID_NS_CS5535_ISA_BRIDGE 0x002b -#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d -#define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e -#define PCI_DEVICE_ID_NS_CS5535_USB 0x002f -#define PCI_DEVICE_ID_NS_CS5535_VIDEO 0x0030 #define PCI_VENDOR_ID_TSENG 0x100c #define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 @@ -511,8 +506,6 @@ #define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097 #define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A -#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A - #define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 #define PCI_DEVICE_ID_AMD_LX_AES 0x2082 From dd8c49966854a5245f3ed4769c9114e7afd819ef Mon Sep 17 00:00:00 2001 From: linas Date: Tue, 10 Jan 2006 15:15:47 -0600 Subject: [PATCH 281/695] [PATCH] PCI Hotplug/powerpc: module build break The RPAPHP hoplug driver will not build as a module, because it calls on pci_claim_resource(), which is not exported. This exports the symbol. Problem reported by Olaf Hering A grep indicates that building drivers/parisc/lba_pci.c would have trouble building as a module for the same reason. Signed-off-by: Linas Vepstas Signed-off-by: Greg Kroah-Hartman --- drivers/pci/setup-res.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 50d6685dcbcc..ea9277b7f899 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -112,6 +112,7 @@ pci_claim_resource(struct pci_dev *dev, int resource) return err; } +EXPORT_SYMBOL_GPL(pci_claim_resource); int pci_assign_resource(struct pci_dev *dev, int resno) { From 3c0c6441883be7676b795939e268b90d6acab360 Mon Sep 17 00:00:00 2001 From: linas Date: Thu, 12 Jan 2006 14:36:25 -0600 Subject: [PATCH 282/695] [PATCH] PCI Hotplug: PCI panic on dlpar add (add pci slot to running partition) Removing and then adding a PCI slot to a running partition results in a kernel panic. The current code attempts to add iospace for an entire root bus, which is inappropriate, and silently fails. When a pci device tries to use the iospace, a page fault is taken, as the iospace had not been mapped, and of course the page fault cannot be resolved. This only occurs for PCI adapters using pio, which may be why it hadn't been seen earlier (this seems to have been broken for a while). This patch has survived testing of dozens of slot add and removes. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 7d93dbaf628d..7f504b380f26 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -152,7 +152,7 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) pcibios_claim_one_bus(dev->bus); /* ioremap() for child bus, which may or may not succeed */ - (void) remap_bus_range(dev->bus); + remap_bus_range(dev->subordinate); /* Add new devices to global lists. Register in proc, sysfs. */ pci_bus_add_devices(phb->bus); From 53044f357448693f218cc4f053affe92ed414f9d Mon Sep 17 00:00:00 2001 From: "Keck, David" Date: Mon, 16 Jan 2006 15:22:36 -0600 Subject: [PATCH 283/695] [PATCH] PCI Hotplug: shpchp: AMD POGO errata fix This patch fixes the AMD POGO errata on the hotplug controller where the platform will lock up or reboot if PERR/SERR generation is enabled and a slot is sent an enable command. This fix disables PERR/SERR generation before a slot is sent the enable command by first saving related registers, turning off SERR/PERR generation, enabling the slot, then restoring the registers. Signed-off-by: David Keck Cc: Kristen Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 94 +++++++++++++++++++++++++++++++ drivers/pci/hotplug/shpchp_ctrl.c | 12 +++- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index ce0e9b6ce833..7d6f521d02ea 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -95,6 +95,7 @@ struct controller { u8 function; u8 slot_device_offset; u8 add_support; + u32 pcix_misc2_reg; /* for amd pogo errata */ enum pci_bus_speed speed; u32 first_slot; /* First physical slot number */ u8 slot_bus; /* Bus where the slots handled by this controller sit */ @@ -113,6 +114,26 @@ struct hotplug_params { /* Define AMD SHPC ID */ #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 +#define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 + +/* AMD PCIX bridge registers */ + +#define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C +#define PCIX_MISCII_OFFSET 0x48 +#define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 + +/* AMD PCIX_MISCII masks and offsets */ +#define PERRNONFATALENABLE_MASK 0x00040000 +#define PERRFATALENABLE_MASK 0x00080000 +#define PERRFLOODENABLE_MASK 0x00100000 +#define SERRNONFATALENABLE_MASK 0x00200000 +#define SERRFATALENABLE_MASK 0x00400000 + +/* AMD PCIX_MISC_BRIDGE_ERRORS masks and offsets */ +#define PERR_OBSERVED_MASK 0x00000001 + +/* AMD PCIX_MEM_BASE_LIMIT masks */ +#define RSE_MASK 0x40000000 #define INT_BUTTON_IGNORE 0 #define INT_PRESENCE_ON 1 @@ -333,6 +354,79 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) return retval; } +static inline void amd_pogo_errata_save_misc_reg(struct slot *p_slot) +{ + u32 pcix_misc2_temp; + + /* save MiscII register */ + pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp); + + p_slot->ctrl->pcix_misc2_reg = pcix_misc2_temp; + + /* clear SERR/PERR enable bits */ + pcix_misc2_temp &= ~SERRFATALENABLE_MASK; + pcix_misc2_temp &= ~SERRNONFATALENABLE_MASK; + pcix_misc2_temp &= ~PERRFLOODENABLE_MASK; + pcix_misc2_temp &= ~PERRFATALENABLE_MASK; + pcix_misc2_temp &= ~PERRNONFATALENABLE_MASK; + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); +} + +static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot) +{ + u32 pcix_misc2_temp; + u32 pcix_bridge_errors_reg; + u32 pcix_mem_base_reg; + u8 perr_set; + u8 rse_set; + + /* write-one-to-clear Bridge_Errors[ PERR_OBSERVED ] */ + pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISC_BRIDGE_ERRORS_OFFSET, &pcix_bridge_errors_reg); + perr_set = pcix_bridge_errors_reg & PERR_OBSERVED_MASK; + if (perr_set) { + dbg ("%s W1C: Bridge_Errors[ PERR_OBSERVED = %08X]\n",__FUNCTION__ , perr_set); + + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISC_BRIDGE_ERRORS_OFFSET, perr_set); + } + + /* write-one-to-clear Memory_Base_Limit[ RSE ] */ + pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MEM_BASE_LIMIT_OFFSET, &pcix_mem_base_reg); + rse_set = pcix_mem_base_reg & RSE_MASK; + if (rse_set) { + dbg ("%s W1C: Memory_Base_Limit[ RSE ]\n",__FUNCTION__ ); + + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MEM_BASE_LIMIT_OFFSET, rse_set); + } + /* restore MiscII register */ + pci_read_config_dword( p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp ); + + if (p_slot->ctrl->pcix_misc2_reg & SERRFATALENABLE_MASK) + pcix_misc2_temp |= SERRFATALENABLE_MASK; + else + pcix_misc2_temp &= ~SERRFATALENABLE_MASK; + + if (p_slot->ctrl->pcix_misc2_reg & SERRNONFATALENABLE_MASK) + pcix_misc2_temp |= SERRNONFATALENABLE_MASK; + else + pcix_misc2_temp &= ~SERRNONFATALENABLE_MASK; + + if (p_slot->ctrl->pcix_misc2_reg & PERRFLOODENABLE_MASK) + pcix_misc2_temp |= PERRFLOODENABLE_MASK; + else + pcix_misc2_temp &= ~PERRFLOODENABLE_MASK; + + if (p_slot->ctrl->pcix_misc2_reg & PERRFATALENABLE_MASK) + pcix_misc2_temp |= PERRFATALENABLE_MASK; + else + pcix_misc2_temp &= ~PERRFATALENABLE_MASK; + + if (p_slot->ctrl->pcix_misc2_reg & PERRNONFATALENABLE_MASK) + pcix_misc2_temp |= PERRNONFATALENABLE_MASK; + else + pcix_misc2_temp &= ~PERRNONFATALENABLE_MASK; + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); +} + #define SLOT_NAME_SIZE 10 static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 25ccb0e47593..643252d9bf3b 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -894,7 +894,17 @@ int shpchp_enable_slot (struct slot *p_slot) dbg("%s: p_slot->pwr_save %x\n", __FUNCTION__, p_slot->pwr_save); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - rc = board_added(p_slot); + if(((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD) || + (p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458)) + && p_slot->ctrl->num_slots == 1) { + /* handle amd pogo errata; this must be done before enable */ + amd_pogo_errata_save_misc_reg(p_slot); + rc = board_added(p_slot); + /* handle amd pogo errata; this must be done after enable */ + amd_pogo_errata_restore_misc_reg(p_slot); + } else + rc = board_added(p_slot); + if (rc) { p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); From 01657868be1c21b2b8b0e683ea24bdcc2331d522 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:18:26 -0600 Subject: [PATCH 284/695] [PATCH] powerpc/PCI hotplug: remove rpaphp_find_bus() The function rpaphp_find_pci_bus() has been migrated to pcibios_find_pci_bus() in arch/powerpc/platforms/pseries/pci_dlpar.c This patch removes the old version. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 6 ++--- drivers/pci/hotplug/rpaphp.h | 3 --- drivers/pci/hotplug/rpaphp_pci.c | 34 ++--------------------------- 3 files changed, 5 insertions(+), 38 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 7f504b380f26..bc17a13fc82e 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -174,7 +174,7 @@ static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) { struct pci_dev *dev; - if (rpaphp_find_pci_bus(dn)) + if (pcibios_find_pci_bus(dn)) return -EINVAL; /* Add pci bus */ @@ -221,7 +221,7 @@ static int dlpar_remove_phb(char *drc_name, struct device_node *dn) struct pci_dn *pdn; int rc = 0; - if (!rpaphp_find_pci_bus(dn)) + if (!pcibios_find_pci_bus(dn)) return -EINVAL; slot = find_slot(dn); @@ -366,7 +366,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) struct pci_bus *bus; struct slot *slot; - bus = rpaphp_find_pci_bus(dn); + bus = pcibios_find_pci_bus(dn); if (!bus) return -EINVAL; diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 57ea71a7bda5..b333a35dd221 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -88,13 +88,10 @@ extern int num_slots; /* function prototypes */ /* rpaphp_pci.c */ -extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn); -extern int rpaphp_claim_resource(struct pci_dev *dev, int resource); extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); extern void rpaphp_init_new_devs(struct pci_bus *bus); -extern void rpaphp_eeh_init_nodes(struct device_node *dn); extern int rpaphp_config_pci_adapter(struct pci_bus *bus); extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 396b54b0c847..f16d0f9240ee 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -32,36 +32,6 @@ #include "../pci.h" /* for pci_add_new_bus */ #include "rpaphp.h" -static struct pci_bus *find_bus_among_children(struct pci_bus *bus, - struct device_node *dn) -{ - struct pci_bus *child = NULL; - struct list_head *tmp; - struct device_node *busdn; - - busdn = pci_bus_to_OF_node(bus); - if (busdn == dn) - return bus; - - list_for_each(tmp, &bus->children) { - child = find_bus_among_children(pci_bus_b(tmp), dn); - if (child) - break; - } - return child; -} - -struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) -{ - struct pci_dn *pdn = dn->data; - - if (!pdn || !pdn->phb || !pdn->phb->bus) - return NULL; - - return find_bus_among_children(pdn->phb->bus, dn); -} -EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus); - static int rpaphp_get_sensor_state(struct slot *slot, int *state) { int rc; @@ -120,7 +90,7 @@ int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) /* config/unconfig adapter */ *value = slot->state; } else { - bus = rpaphp_find_pci_bus(slot->dn); + bus = pcibios_find_pci_bus(slot->dn); if (bus && !list_empty(&bus->devices)) *value = CONFIGURED; else @@ -370,7 +340,7 @@ static int setup_pci_slot(struct slot *slot) struct pci_bus *bus; BUG_ON(!dn); - bus = rpaphp_find_pci_bus(dn); + bus = pcibios_find_pci_bus(dn); if (!bus) { err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name); goto exit_rc; From eca845c71816669dace4bf1954d9ab276abb0002 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:20:26 -0600 Subject: [PATCH 285/695] [PATCH] powerpc/PCI hotplug: remove rpaphp_fixup_new_pci_devices() The function rpaphp_fixup_new_pci_devices() has been migrated to pcibios_fixup_new_pci_devices() in arch/powerpc/platforms/pseries/pci_dlpar.c This patch removes the old version. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 2 +- drivers/pci/hotplug/rpaphp.h | 1 - drivers/pci/hotplug/rpaphp_pci.c | 142 +--------------------------- 3 files changed, 2 insertions(+), 143 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index bc17a13fc82e..6c148106518e 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -146,7 +146,7 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) of_scan_pci_bridge(dn, dev); - rpaphp_init_new_devs(dev->subordinate); + pcibios_fixup_new_pci_devices(dev->subordinate,0); /* Claim new bus resources */ pcibios_claim_one_bus(dev->bus); diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index b333a35dd221..6aa91ef5cd70 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -91,7 +91,6 @@ extern int num_slots; extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern void rpaphp_init_new_devs(struct pci_bus *bus); extern int rpaphp_config_pci_adapter(struct pci_bus *bus); extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index f16d0f9240ee..1a12ebd10e34 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -101,140 +101,6 @@ exit: return rc; } -/* Must be called before pci_bus_add_devices */ -void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) -{ - struct pci_dev *dev; - - list_for_each_entry(dev, &bus->devices, bus_list) { - /* - * Skip already-present devices (which are on the - * global device list.) - */ - if (list_empty(&dev->global_list)) { - int i; - - /* Need to setup IOMMU tables */ - ppc_md.iommu_dev_setup(dev); - - if(fix_bus) - pcibios_fixup_device_resources(dev, bus); - pci_read_irq_line(dev); - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - - if (r->parent || !r->start || !r->flags) - continue; - pci_claim_resource(dev, i); - } - } - } -} - -static void rpaphp_eeh_add_bus_device(struct pci_bus *bus) -{ - struct pci_dev *dev; - - list_for_each_entry(dev, &bus->devices, bus_list) { - eeh_add_device_late(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - struct pci_bus *subbus = dev->subordinate; - if (subbus) - rpaphp_eeh_add_bus_device (subbus); - } - } -} - -static int rpaphp_pci_config_bridge(struct pci_dev *dev) -{ - u8 sec_busno; - struct pci_bus *child_bus; - struct pci_dev *child_dev; - - dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); - - /* get busno of downstream bus */ - pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); - - /* add to children of PCI bridge dev->bus */ - child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); - if (!child_bus) { - err("%s: could not add second bus\n", __FUNCTION__); - return -EIO; - } - sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); - /* do pci_scan_child_bus */ - pci_scan_child_bus(child_bus); - - list_for_each_entry(child_dev, &child_bus->devices, bus_list) { - eeh_add_device_late(child_dev); - } - - /* fixup new pci devices without touching bus struct */ - rpaphp_fixup_new_pci_devices(child_bus, 0); - - /* Make the discovered devices available */ - pci_bus_add_devices(child_bus); - return 0; -} - -void rpaphp_init_new_devs(struct pci_bus *bus) -{ - rpaphp_fixup_new_pci_devices(bus, 0); - rpaphp_eeh_add_bus_device(bus); -} -EXPORT_SYMBOL_GPL(rpaphp_init_new_devs); - -/***************************************************************************** - rpaphp_pci_config_slot() will configure all devices under the - given slot->dn and return the the first pci_dev. - *****************************************************************************/ -static struct pci_dev * -rpaphp_pci_config_slot(struct pci_bus *bus) -{ - struct device_node *dn = pci_bus_to_OF_node(bus); - struct pci_dev *dev = NULL; - int slotno; - int num; - - dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); - if (!dn || !dn->child) - return NULL; - - if (_machine == PLATFORM_PSERIES_LPAR) { - of_scan_bus(dn, bus); - if (list_empty(&bus->devices)) { - err("%s: No new device found\n", __FUNCTION__); - return NULL; - } - - rpaphp_init_new_devs(bus); - pci_bus_add_devices(bus); - dev = list_entry(&bus->devices, struct pci_dev, bus_list); - } else { - slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); - - /* pci_scan_slot should find all children */ - num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); - if (num) { - rpaphp_fixup_new_pci_devices(bus, 1); - pci_bus_add_devices(bus); - } - if (list_empty(&bus->devices)) { - err("%s: No new device found\n", __FUNCTION__); - return NULL; - } - list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) - rpaphp_pci_config_bridge(dev); - - rpaphp_eeh_add_bus_device(bus); - } - } - - return dev; -} - static void print_slot_pci_funcs(struct pci_bus *bus) { struct device_node *dn; @@ -253,19 +119,13 @@ static void print_slot_pci_funcs(struct pci_bus *bus) int rpaphp_config_pci_adapter(struct pci_bus *bus) { struct device_node *dn = pci_bus_to_OF_node(bus); - struct pci_dev *dev; int rc = -ENODEV; dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); if (!dn) goto exit; - eeh_add_device_tree_early(dn); - dev = rpaphp_pci_config_slot(bus); - if (!dev) { - err("%s: can't find any devices.\n", __FUNCTION__); - goto exit; - } + pcibios_add_pci_devices(bus); print_slot_pci_funcs(bus); rc = 0; exit: From 7fec77e4793f307b30846a3d4015d329ffc0b685 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:22:07 -0600 Subject: [PATCH 286/695] [PATCH] powerpc/PCI hotplug: merge config_pci_adapter Remove general baroqueness. The function rpaphp_config_pci_adapter() is really just one line of code, once all the dbg printks are removed. And its called in only one place. So replace the call by the one line. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp.h | 1 - drivers/pci/hotplug/rpaphp_pci.c | 35 ++++---------------------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 6aa91ef5cd70..89d705c7c502 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -92,7 +92,6 @@ extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern int rpaphp_config_pci_adapter(struct pci_bus *bus); extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); /* rpaphp_core.c */ diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 1a12ebd10e34..b93d9c964eea 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -116,24 +116,6 @@ static void print_slot_pci_funcs(struct pci_bus *bus) return; } -int rpaphp_config_pci_adapter(struct pci_bus *bus) -{ - struct device_node *dn = pci_bus_to_OF_node(bus); - int rc = -ENODEV; - - dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); - if (!dn) - goto exit; - - pcibios_add_pci_devices(bus); - print_slot_pci_funcs(bus); - rc = 0; -exit: - dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); - return rc; -} -EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter); - static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) { eeh_remove_device(dev); @@ -225,10 +207,7 @@ static int setup_pci_slot(struct slot *slot) if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { dbg("%s CONFIGURING pci adapter in slot[%s]\n", __FUNCTION__, slot->name); - if (rpaphp_config_pci_adapter(slot->bus)) { - err("%s: CONFIG pci adapter failed\n", __FUNCTION__); - goto exit_rc; - } + pcibios_add_pci_devices(slot->bus); } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) { err("%s: slot[%s]'s adapter_status is NOT_VALID.\n", @@ -274,16 +253,10 @@ int rpaphp_enable_pci_slot(struct slot *slot) /* if slot is not empty, enable the adapter */ if (state == PRESENT) { dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); - retval = rpaphp_config_pci_adapter(slot->bus); - if (!retval) { - slot->state = CONFIGURED; - info("%s: devices in slot[%s] configured\n", + pcibios_add_pci_devices(slot->bus); + slot->state = CONFIGURED; + info("%s: devices in slot[%s] configured\n", __FUNCTION__, slot->name); - } else { - slot->state = NOT_CONFIGURED; - dbg("%s: no pci_dev struct for adapter in slot[%s]\n", - __FUNCTION__, slot->name); - } } else if (state == EMPTY) { dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name); slot->state = EMPTY; From 8a85a70db8c65fd1703b4597f72fe6ee25642234 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:24:27 -0600 Subject: [PATCH 287/695] [PATCH] powerpc/PCI hotplug: remove remove_bus_device() The function rpaphp_eeh_remove_bus_device() is a dupe of eeh_remove_bus_device(). Remove it. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp_pci.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index b93d9c964eea..1f5e73be47c7 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -116,30 +116,12 @@ static void print_slot_pci_funcs(struct pci_bus *bus) return; } -static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) -{ - eeh_remove_device(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - struct pci_bus *bus = dev->subordinate; - struct list_head *ln; - if (!bus) - return; - for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { - struct pci_dev *pdev = pci_dev_b(ln); - if (pdev) - rpaphp_eeh_remove_bus_device(pdev); - } - - } - return; -} - int rpaphp_unconfig_pci_adapter(struct pci_bus *bus) { struct pci_dev *dev, *tmp; list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { - rpaphp_eeh_remove_bus_device(dev); + eeh_remove_bus_device(dev); pci_remove_bus_device(dev); } return 0; From 8fe64399cccf8dddcc4e5eaff270a12064f6fe9f Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:26:27 -0600 Subject: [PATCH 288/695] [PATCH] powerpc/PCI hotplug: de-convolute rpaphp_unconfig_pci_adap Remove general baroqueness. The function rpaphp_unconfig_pci_adapter() is really just three lines of code, once all the dbg printks are removed. And its called in only one place. So replace the call by the thre lines. Also, provide proper semaphore locking in the affected function disable_slot() Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 6 ++++- drivers/pci/hotplug/rpaphp.h | 2 -- drivers/pci/hotplug/rpaphp_core.c | 34 ++++++++++++++++------------- drivers/pci/hotplug/rpaphp_pci.c | 12 ---------- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 6c148106518e..15e853e5e689 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -380,7 +380,11 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) return -EIO; } } else { - rpaphp_unconfig_pci_adapter(bus); + struct pci_dev *dev, *tmp; + list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { + eeh_remove_bus_device(dev); + pci_remove_bus_device(dev); + } } if (unmap_bus_range(bus)) { diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 89d705c7c502..6e4f93ba6555 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -92,8 +92,6 @@ extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); - /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); extern int rpaphp_remove_slot(struct slot *slot); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index cf075c34b578..acf17645fd8a 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -412,27 +412,31 @@ exit: return retval; } -static int disable_slot(struct hotplug_slot *hotplug_slot) +static int __disable_slot(struct slot *slot) { - int retval = -EINVAL; - struct slot *slot = (struct slot *)hotplug_slot->private; + struct pci_dev *dev, *tmp; - dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name); + if (slot->state == NOT_CONFIGURED) + return -EINVAL; - if (slot->state == NOT_CONFIGURED) { - dbg("%s: %s is already disabled\n", __FUNCTION__, slot->name); - goto exit; + list_for_each_entry_safe(dev, tmp, &slot->bus->devices, bus_list) { + eeh_remove_bus_device(dev); + pci_remove_bus_device(dev); } - dbg("DISABLING SLOT %s\n", slot->name); - down(&rpaphp_sem); - retval = rpaphp_unconfig_pci_adapter(slot->bus); - up(&rpaphp_sem); slot->state = NOT_CONFIGURED; - info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, - slot->name); -exit: - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); + return 0; +} + +static int disable_slot(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot = (struct slot *)hotplug_slot->private; + int retval; + + down(&rpaphp_sem); + retval = __disable_slot (slot); + up(&rpaphp_sem); + return retval; } diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 1f5e73be47c7..ce7ebec05933 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -116,18 +116,6 @@ static void print_slot_pci_funcs(struct pci_bus *bus) return; } -int rpaphp_unconfig_pci_adapter(struct pci_bus *bus) -{ - struct pci_dev *dev, *tmp; - - list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { - eeh_remove_bus_device(dev); - pci_remove_bus_device(dev); - } - return 0; -} -EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter); - static int setup_pci_hotplug_slot_info(struct slot *slot) { struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info; From e06b80b78db96ca272db4ec0b26ce1092a1a9704 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:28:22 -0600 Subject: [PATCH 289/695] [PATCH] powerpc/PCI hotplug: merge rpaphp_enable_pci_slot() Remove general baroqueness. The function rpaphp_enable_pci_slot() has a fairly simple logic structure, once all of the debug printk's are removed. Its called from only one place, and that place also has a very simple structure once he printk's are removed. Merge the two together. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp.h | 1 + drivers/pci/hotplug/rpaphp_core.c | 38 +++++++++++++++++++++++-------- drivers/pci/hotplug/rpaphp_pci.c | 30 +----------------------- 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 6e4f93ba6555..095c9aacaa16 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -91,6 +91,7 @@ extern int num_slots; extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); +extern int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index acf17645fd8a..341fdd59090b 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -393,22 +393,40 @@ static void __exit rpaphp_exit(void) cleanup_slots(); } +static int __enable_slot(struct slot *slot) +{ + int state; + int retval; + + if (slot->state == CONFIGURED) + return 0; + + retval = rpaphp_get_sensor_state(slot, &state); + if (retval) + return retval; + + if (state == PRESENT) { + pcibios_add_pci_devices(slot->bus); + slot->state = CONFIGURED; + } else if (state == EMPTY) { + slot->state = EMPTY; + } else { + err("%s: slot[%s] is in invalid state\n", __FUNCTION__, slot->name); + slot->state = NOT_VALID; + return -EINVAL; + } + return 0; +} + static int enable_slot(struct hotplug_slot *hotplug_slot) { - int retval = 0; + int retval; struct slot *slot = (struct slot *)hotplug_slot->private; - if (slot->state == CONFIGURED) { - dbg("%s: %s is already enabled\n", __FUNCTION__, slot->name); - goto exit; - } - - dbg("ENABLING SLOT %s\n", slot->name); down(&rpaphp_sem); - retval = rpaphp_enable_pci_slot(slot); + retval = __enable_slot(slot); up(&rpaphp_sem); -exit: - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); + return retval; } diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index ce7ebec05933..d1297d070a75 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -32,7 +32,7 @@ #include "../pci.h" /* for pci_add_new_bus */ #include "rpaphp.h" -static int rpaphp_get_sensor_state(struct slot *slot, int *state) +int rpaphp_get_sensor_state(struct slot *slot, int *state) { int rc; int setlevel; @@ -212,31 +212,3 @@ exit_rc: return rc; } -int rpaphp_enable_pci_slot(struct slot *slot) -{ - int retval = 0, state; - - retval = rpaphp_get_sensor_state(slot, &state); - if (retval) - goto exit; - dbg("%s: sensor state[%d]\n", __FUNCTION__, state); - /* if slot is not empty, enable the adapter */ - if (state == PRESENT) { - dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); - pcibios_add_pci_devices(slot->bus); - slot->state = CONFIGURED; - info("%s: devices in slot[%s] configured\n", - __FUNCTION__, slot->name); - } else if (state == EMPTY) { - dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name); - slot->state = EMPTY; - } else { - err("%s: slot[%s] is in invalid state\n", __FUNCTION__, - slot->name); - slot->state = NOT_VALID; - retval = -EINVAL; - } -exit: - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); - return retval; -} From f6afbad82c6b7bab0198442592b110341fb419ba Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:31:01 -0600 Subject: [PATCH 290/695] [PATCH] powerpc/PCI hotplug: cleanup: add prefix Minor cleanup. Add the prefix rpaphp_* to several generic-sounding routines. Remove rpaphp_remove_slot(), which is a one-liner. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 4 ++-- drivers/pci/hotplug/rpaphp.h | 6 +++--- drivers/pci/hotplug/rpaphp_core.c | 14 +++++--------- drivers/pci/hotplug/rpaphp_pci.c | 4 ++-- drivers/pci/hotplug/rpaphp_slot.c | 16 ++++++++-------- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 15e853e5e689..d3aa9df1acd4 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -227,7 +227,7 @@ static int dlpar_remove_phb(char *drc_name, struct device_node *dn) slot = find_slot(dn); if (slot) { /* Remove hotplug slot */ - if (rpaphp_remove_slot(slot)) { + if (rpaphp_deregister_slot(slot)) { printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", __FUNCTION__, drc_name); @@ -373,7 +373,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) slot = find_slot(dn); if (slot) { /* Remove hotplug slot */ - if (rpaphp_remove_slot(slot)) { + if (rpaphp_deregister_slot(slot)) { printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", __FUNCTION__, drc_name); diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 095c9aacaa16..310b6186c0e5 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -89,7 +89,7 @@ extern int num_slots; /* rpaphp_pci.c */ extern int rpaphp_enable_pci_slot(struct slot *slot); -extern int register_pci_slot(struct slot *slot); +extern int rpaphp_register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); extern int rpaphp_get_sensor_state(struct slot *slot, int *state); @@ -102,8 +102,8 @@ extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, /* rpaphp_slot.c */ extern void dealloc_slot_struct(struct slot *slot); extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); -extern int register_slot(struct slot *slot); -extern int deregister_slot(struct slot *slot); +extern int rpaphp_register_slot(struct slot *slot); +extern int rpaphp_deregister_slot(struct slot *slot); extern int rpaphp_get_power_status(struct slot *slot, u8 * value); extern int rpaphp_set_attention_status(struct slot *slot, u8 status); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 341fdd59090b..c0e521c8f9ef 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -196,11 +196,6 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe return 0; } -int rpaphp_remove_slot(struct slot *slot) -{ - return deregister_slot(slot); -} - static int get_children_props(struct device_node *dn, int **drc_indexes, int **drc_names, int **drc_types, int **drc_power_domains) { @@ -307,13 +302,15 @@ static int is_php_dn(struct device_node *dn, int **indexes, int **names, return 0; } -/**************************************************************** +/** + * rpaphp_add_slot -- add hotplug or dlpar slot + * * rpaphp not only registers PCI hotplug slots(HOTPLUG), * but also logical DR slots(EMBEDDED). * HOTPLUG slot: An adapter can be physically added/removed. * EMBEDDED slot: An adapter can be logically removed/added * from/to a partition with the slot. - ***************************************************************/ + */ int rpaphp_add_slot(struct device_node *dn) { struct slot *slot; @@ -344,7 +341,7 @@ int rpaphp_add_slot(struct device_node *dn) dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", indexes[i + 1], name, type); - retval = register_pci_slot(slot); + retval = rpaphp_register_pci_slot(slot); } } exit: @@ -462,6 +459,5 @@ module_init(rpaphp_init); module_exit(rpaphp_exit); EXPORT_SYMBOL_GPL(rpaphp_add_slot); -EXPORT_SYMBOL_GPL(rpaphp_remove_slot); EXPORT_SYMBOL_GPL(rpaphp_slot_head); EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index d1297d070a75..6f6cbede5135 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -199,7 +199,7 @@ exit_rc: return -EINVAL; } -int register_pci_slot(struct slot *slot) +int rpaphp_register_pci_slot(struct slot *slot) { int rc = -EINVAL; @@ -207,7 +207,7 @@ int register_pci_slot(struct slot *slot) goto exit_rc; if (setup_pci_slot(slot)) goto exit_rc; - rc = register_slot(slot); + rc = rpaphp_register_slot(slot); exit_rc: return rc; } diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index daa89ae57123..04cc1e7275ce 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -35,16 +35,16 @@ static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) { - char *value; - int retval = -ENOENT; + char *value; + int retval = -ENOENT; struct slot *slot = (struct slot *)php_slot->private; if (!slot) return retval; - value = slot->location; - retval = sprintf (buf, "%s\n", value); - return retval; + value = slot->location; + retval = sprintf (buf, "%s\n", value); + return retval; } static struct hotplug_slot_attribute hotplug_slot_attr_location = { @@ -137,7 +137,7 @@ static int is_registered(struct slot *slot) return 0; } -int deregister_slot(struct slot *slot) +int rpaphp_deregister_slot(struct slot *slot) { int retval = 0; struct hotplug_slot *php_slot = slot->hotplug_slot; @@ -160,7 +160,7 @@ int deregister_slot(struct slot *slot) return retval; } -int register_slot(struct slot *slot) +int rpaphp_register_slot(struct slot *slot) { int retval; @@ -169,7 +169,7 @@ int register_slot(struct slot *slot) slot->power_domain, slot->type); /* should not try to register the same slot twice */ if (is_registered(slot)) { /* should't be here */ - err("register_slot: slot[%s] is already registered\n", slot->name); + err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); rpaphp_release_slot(slot->hotplug_slot); return -EAGAIN; } From b64a71ab5c9098a79ccb463af968933483458a0f Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:32:58 -0600 Subject: [PATCH 291/695] [PATCH] powerpc/PCI hotplug: minor cleanup forward decls Minor cleanup. Move structure initializer to bottom of file, this allows elimination of eyeball-strain-inducing forward declarations. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp_core.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index c0e521c8f9ef..6e79f5675b0d 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -56,25 +56,6 @@ MODULE_LICENSE("GPL"); module_param(debug, bool, 0644); -static int enable_slot(struct hotplug_slot *slot); -static int disable_slot(struct hotplug_slot *slot); -static int set_attention_status(struct hotplug_slot *slot, u8 value); -static int get_power_status(struct hotplug_slot *slot, u8 * value); -static int get_attention_status(struct hotplug_slot *slot, u8 * value); -static int get_adapter_status(struct hotplug_slot *slot, u8 * value); -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value); - -struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { - .owner = THIS_MODULE, - .enable_slot = enable_slot, - .disable_slot = disable_slot, - .set_attention_status = set_attention_status, - .get_power_status = get_power_status, - .get_attention_status = get_attention_status, - .get_adapter_status = get_adapter_status, - .get_max_bus_speed = get_max_bus_speed, -}; - static int rpaphp_get_attention_status(struct slot *slot) { return slot->hotplug_slot->info->attention_status; @@ -455,6 +436,17 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) return retval; } +struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { + .owner = THIS_MODULE, + .enable_slot = enable_slot, + .disable_slot = disable_slot, + .set_attention_status = set_attention_status, + .get_power_status = get_power_status, + .get_attention_status = get_attention_status, + .get_adapter_status = get_adapter_status, + .get_max_bus_speed = get_max_bus_speed, +}; + module_init(rpaphp_init); module_exit(rpaphp_exit); From 8737d6a90cd8b085c2ea9cb4c7443c87f86c3429 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:35:23 -0600 Subject: [PATCH 292/695] [PATCH] powerpc/PCI hotplug: shuffle error checking to better location. Error checking is scattered through various layers of the dlpar code, leading to a somewhat opaque code structure. This patch consolidates error checking in one routine, simplifying the code a tad. There's also some whitespace cleanup here too. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index d3aa9df1acd4..3eefe2cec72d 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -103,13 +103,13 @@ static struct slot *find_slot(struct device_node *dn) struct list_head *tmp, *n; struct slot *slot; - list_for_each_safe(tmp, n, &rpaphp_slot_head) { - slot = list_entry(tmp, struct slot, rpaphp_slot_list); - if (slot->dn == dn) - return slot; - } + list_for_each_safe(tmp, n, &rpaphp_slot_head) { + slot = list_entry(tmp, struct slot, rpaphp_slot_list); + if (slot->dn == dn) + return slot; + } - return NULL; + return NULL; } static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, @@ -126,9 +126,9 @@ static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, return NULL; } -static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) +static void dlpar_pci_add_bus(struct device_node *dn) { - struct pci_dn *pdn = dn->data; + struct pci_dn *pdn = PCI_DN(dn); struct pci_controller *phb = pdn->phb; struct pci_dev *dev = NULL; @@ -139,7 +139,7 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) if (!dev) { printk(KERN_ERR "%s: failed to create pci dev for %s\n", __FUNCTION__, dn->full_name); - return NULL; + return; } if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || @@ -156,35 +156,35 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) /* Add new devices to global lists. Register in proc, sysfs. */ pci_bus_add_devices(phb->bus); - - /* Confirm new bridge dev was created */ - dev = dlpar_find_new_dev(phb->bus, dn); - if (dev) { - if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { - printk(KERN_ERR "%s: unexpected header type %d\n", - __FUNCTION__, dev->hdr_type); - return NULL; - } - } - - return dev; } static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) { struct pci_dev *dev; + struct pci_controller *phb; if (pcibios_find_pci_bus(dn)) return -EINVAL; /* Add pci bus */ - dev = dlpar_pci_add_bus(dn); + dlpar_pci_add_bus(dn); + + /* Confirm new bridge dev was created */ + phb = PCI_DN(dn)->phb; + dev = dlpar_find_new_dev(phb->bus, dn); + if (!dev) { printk(KERN_ERR "%s: unable to add bus %s\n", __FUNCTION__, drc_name); return -EIO; } + if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { + printk(KERN_ERR "%s: unexpected header type %d, unable to add bus %s\n", + __FUNCTION__, dev->hdr_type, drc_name); + return -EIO; + } + /* Add hotplug slot */ if (rpaphp_add_slot(dn)) { printk(KERN_ERR "%s: unable to add hotplug slot %s\n", From 877be3f0304de16a77f11b2b47f1291b800d5479 Mon Sep 17 00:00:00 2001 From: Arthur Othieno Date: Wed, 18 Jan 2006 21:12:57 -0500 Subject: [PATCH 293/695] [PATCH] PCI: cyblafb: remove pci_module_init() return, really. Richard Knutsson did the original pci_module_init() cleanups: http://marc.theaimsgroup.com/?l=linux-kernel&m=113330872125068&w=2 http://marc.theaimsgroup.com/?l=linux-kernel&m=113330888507321&w=2 Greg, on it's way upstream, pci_module_init() return sneaked back in for cyblafb? http://marc.theaimsgroup.com/?l=linux-pci&m=113652969209562&w=2 http://marc.theaimsgroup.com/?l=linux-pci&m=113683930220421&w=2 Remove for good. Signed-off-by: Arthur Othieno Signed-off-by: Greg Kroah-Hartman --- drivers/video/cyblafb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c index 2b972461a030..0ae0a97b0fed 100644 --- a/drivers/video/cyblafb.c +++ b/drivers/video/cyblafb.c @@ -1665,7 +1665,6 @@ static int __devinit cyblafb_init(void) } #endif output("CyblaFB version %s initializing\n", VERSION); - return pci_module_init(&cyblafb_pci_driver); return pci_register_driver(&cyblafb_pci_driver); } From 3103039cc2a8dc6ababc29afac5c3cadbfa69af9 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 27 Jan 2006 02:03:50 +0100 Subject: [PATCH 294/695] [PATCH] PCI: handle bogus MCFG entries Handle more bogus MCFG entries Some Asus P4 boards seem to have broken MCFG tables with only a single entry for busses 0-0. Special case these and assume they mean all busses can be accessed. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/mmconfig.c | 15 +++++++++++++-- arch/x86_64/pci/mmconfig.c | 19 ++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 4bb4d4b0f73a..0ee8a983708c 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -36,8 +36,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) while (1) { ++cfg_num; if (cfg_num >= pci_mmcfg_config_num) { - /* Not found - fallback to type 1 */ - return 0; + break; } cfg = &pci_mmcfg_config[cfg_num]; if (cfg->pci_segment_group_number != seg) @@ -46,6 +45,18 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) (cfg->end_bus_number >= bus)) return cfg->base_address; } + + /* Handle more broken MCFG tables on Asus etc. + They only contain a single entry for bus 0-0. Assume + this applies to all busses. */ + cfg = &pci_mmcfg_config[0]; + if (pci_mmcfg_config_num == 1 && + cfg->pci_segment_group_number == 0 && + (cfg->start_bus_number | cfg->end_bus_number) == 0) + return cfg->base_address; + + /* Fall back to type 0 */ + return 0; } static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index f16c0d57c552..00d4ddbf980c 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -29,11 +29,8 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) while (1) { ++cfg_num; - if (cfg_num >= pci_mmcfg_config_num) { - /* Not found - fall back to type 1. This happens - e.g. on the internal devices of a K8 northbridge. */ - return NULL; - } + if (cfg_num >= pci_mmcfg_config_num) + break; cfg = pci_mmcfg_virt[cfg_num].cfg; if (cfg->pci_segment_group_number != seg) continue; @@ -41,6 +38,18 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) (cfg->end_bus_number >= bus)) return pci_mmcfg_virt[cfg_num].virt; } + + /* Handle more broken MCFG tables on Asus etc. + They only contain a single entry for bus 0-0. Assume + this applies to all busses. */ + cfg = &pci_mmcfg_config[0]; + if (pci_mmcfg_config_num == 1 && + cfg->pci_segment_group_number == 0 && + (cfg->start_bus_number | cfg->end_bus_number) == 0) + return cfg->base_address; + + /* Fall back to type 0 */ + return 0; } static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) From bd3f8f2b12bcf4ea25c89b84adeaafad232662c8 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Tue, 31 Jan 2006 19:10:23 -0800 Subject: [PATCH 295/695] [PATCH] Make sure to always check upper bits of tv_nsec in timespec_valid. Signed-off-by: Chris Wright Signed-off-by: Linus Torvalds --- include/linux/time.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/time.h b/include/linux/time.h index 614dd8465839..7b4dc36532bb 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -48,7 +48,7 @@ extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec); * Returns true if the timespec is norm, false if denorm: */ #define timespec_valid(ts) \ - (((ts)->tv_sec >= 0) && (((unsigned) (ts)->tv_nsec) < NSEC_PER_SEC)) + (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC)) /* * 64-bit nanosec type. Large enough to span 292+ years in nanosecond From 51c2bbfcdb10162b294f31e2b1c7106639caaec2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Jan 2006 15:20:03 +0100 Subject: [PATCH 296/695] [ALSA] via82xx - Add dxs entry for a FSC board Modules: VIA82xx driver Add dxs entry for a FSC board. Signed-off-by: Takashi Iwai --- sound/pci/via82xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index d59fe3e83f17..8d348f27f17a 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -2374,6 +2374,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */ { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */ + { .subvendor = 0x1734, .subdevice = 0x1093, .action = VIA_DXS_SRC }, /* FSC */ { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ { .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ From fe25ad8a84c798a82591e5ed14519c001500fa61 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Jan 2006 15:20:38 +0100 Subject: [PATCH 297/695] [ALSA] wavefront - Fix a compile warning Modules: Wavefront drivers Fix a gcc-4.1 compile warning regarding uninitialized variables. Signed-off-by: Takashi Iwai --- sound/isa/wavefront/wavefront_synth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index ed81eec6e732..68aa091e8961 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -866,7 +866,7 @@ wavefront_send_sample (snd_wavefront_t *dev, divided by 2. */ - u16 sample_short; + u16 sample_short = 0; u32 length; u16 __user *data_end = NULL; unsigned int i; From 91134859702e66e5946383f66e6eb50ba4325458 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Jan 2006 15:21:05 +0100 Subject: [PATCH 298/695] [ALSA] opti93x - Fix a compile warning Modules: Opti9xx drivers Fix a gcc-4.1 compile warning regarding uninitialized variables. Signed-off-by: Takashi Iwai --- sound/isa/opti9xx/opti92x-ad1848.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 1ea3944ef7ab..63d96be11b2b 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -1349,7 +1349,7 @@ static int snd_opti93x_pcm(struct snd_opti93x *codec, int device, struct snd_pcm int error; struct snd_pcm *pcm; - if ((error = snd_pcm_new(codec->card, "OPTi 82C93X", device, 1, 1, &pcm))) + if ((error = snd_pcm_new(codec->card, "OPTi 82C93X", device, 1, 1, &pcm)) < 0) return error; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_opti93x_playback_ops); From 68b8bc05213567cfc58d8bdb8917b36c314ba7fd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Jan 2006 15:21:28 +0100 Subject: [PATCH 299/695] [ALSA] serial-uart16550 - Fix a compile warning Modules: Generic drivers Fix a gcc-4.1 compile warning regarding uninitialized variables. Signed-off-by: Takashi Iwai --- sound/drivers/serial-u16550.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index 29676d800cae..112ddf705402 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c @@ -789,7 +789,7 @@ static int __init snd_uart16550_create(struct snd_card *card, if ((err = snd_uart16550_detect(uart)) <= 0) { printk(KERN_ERR "no UART detected at 0x%lx\n", iobase); - return err; + return -ENODEV; } if (irq >= 0 && irq != SNDRV_AUTO_IRQ) { From 50f794c8dcfd0e63f3034d7cfd41e563f35741aa Mon Sep 17 00:00:00 2001 From: Lukasz Stemach Date: Mon, 23 Jan 2006 15:22:13 +0100 Subject: [PATCH 300/695] [ALSA] cs4236 - Add PnP ids for Netfinity 3000 Modules: CS4236+ driver PnP ids for Netfinity 3000 builtin soundcard. This one works for me. This patch was submitted through kernel Bugzilla #4214. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/isa/cs423x/cs4236.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index edf9279bf9d9..4fa431040564 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -178,6 +178,8 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = { { .id = "CSC7632", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } }, /* SIC CrystalWave 32 (CS4232) */ { .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, + /* Netfinity 3000 on-board soundcard */ + { .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC010f" } } }, /* --- */ { .id = "" } /* end */ }; From e061bf1aa3af8a3f2ae7e1b5f8a110eae7936615 Mon Sep 17 00:00:00 2001 From: Sasha Khapyorsky Date: Mon, 23 Jan 2006 15:24:16 +0100 Subject: [PATCH 301/695] [ALSA] hda-codec - support for Agere's HDA soft modem Modules: HDA Codec driver This adds support for Agere's variant of Si3054/5 based HDA modem. Signed-off-by: Sasha Khapyorsky Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_si3054.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index 8f8840e6002b..250242cd6c70 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c @@ -297,6 +297,7 @@ static int patch_si3054(struct hda_codec *codec) struct hda_codec_preset snd_hda_preset_si3054[] = { { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, + { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, {} }; From d62c40e04cfcec3cef8093bd79d72fe86c8f2195 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Mon, 23 Jan 2006 15:26:27 +0100 Subject: [PATCH 302/695] [ALSA] hda-codec - add D975XBK support to sigmatel patch Modules: HDA Codec driver Add SigmaTel HDA support for the Intel D975XBK motherboard. Signed-off-by: Matt Porter Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4f78b58416a4..f2f9465d4df2 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -275,6 +275,9 @@ static struct hda_board_config stac922x_cfg_tbl[] = { { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x0013, .config = STAC_D945GTP5 }, /* Intel D955XBK - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0417, + .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ {} /* terminator */ }; From 3cc08dc6ea677ed4e843120aa070e145b6781a4b Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Mon, 23 Jan 2006 15:27:49 +0100 Subject: [PATCH 303/695] [ALSA] hda-codec - add sigmatel 927x codec support Modules: HDA Codec driver Adds support for the SigmaTel STAC927x HDA codec family. Signed-off-by: Matt Porter Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 149 +++++++++++++++++++++++++++++++-- 1 file changed, 142 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f2f9465d4df2..d5342d20bd81 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -50,10 +50,11 @@ struct sigmatel_spec { unsigned int surr_switch: 1; unsigned int line_switch: 1; unsigned int mic_switch: 1; + unsigned int alt_switch: 1; /* playback */ struct hda_multi_out multiout; - hda_nid_t dac_nids[4]; + hda_nid_t dac_nids[5]; /* capture */ hda_nid_t *adc_nids; @@ -73,7 +74,7 @@ struct sigmatel_spec { /* capture source */ struct hda_input_mux *input_mux; - unsigned int cur_mux[2]; + unsigned int cur_mux[3]; /* i/o switches */ unsigned int io_switch[2]; @@ -107,6 +108,14 @@ static hda_nid_t stac922x_mux_nids[2] = { 0x12, 0x13, }; +static hda_nid_t stac927x_adc_nids[3] = { + 0x07, 0x08, 0x09 +}; + +static hda_nid_t stac927x_mux_nids[3] = { + 0x15, 0x16, 0x17 +}; + static hda_nid_t stac9200_pin_nids[8] = { 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, }; @@ -116,6 +125,12 @@ static hda_nid_t stac922x_pin_nids[10] = { 0x0f, 0x10, 0x11, 0x15, 0x1b, }; +static hda_nid_t stac927x_pin_nids[14] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x21, 0x22, 0x23, +}; + static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -155,6 +170,12 @@ static struct hda_verb stac922x_core_init[] = { {} }; +static struct hda_verb stac927x_core_init[] = { + /* set master volume and direct control */ + { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + {} +}; + static struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), @@ -188,6 +209,21 @@ static struct snd_kcontrol_new stac922x_mixer[] = { { } /* end */ }; +static snd_kcontrol_new_t stac927x_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input Source", + .count = 1, + .info = stac92xx_mux_enum_info, + .get = stac92xx_mux_enum_get, + .put = stac92xx_mux_enum_put, + }, + HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT), + { } /* end */ +}; + static int stac92xx_build_controls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -281,6 +317,25 @@ static struct hda_board_config stac922x_cfg_tbl[] = { {} /* terminator */ }; +static unsigned int ref927x_pin_configs[14] = { + 0x01813122, 0x01a19021, 0x01014010, 0x01016011, + 0x01012012, 0x01011014, 0x40000100, 0x40000100, + 0x40000100, 0x40000100, 0x40000100, 0x01441030, + 0x01c41030, 0x40000100, +}; + +static unsigned int *stac927x_brd_tbl[] = { + ref927x_pin_configs, +}; + +static struct hda_board_config stac927x_cfg_tbl[] = { + { .modelname = "ref", + .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2668, /* DFI LanParty */ + .config = STAC_REF }, /* SigmaTel reference board */ + {} /* terminator */ +}; + static void stac92xx_set_config_regs(struct hda_codec *codec) { int i; @@ -412,11 +467,23 @@ static struct hda_pcm_stream stac92xx_pcm_analog_playback = { }, }; +static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .nid = 0x06, /* NID to query formats and rates */ + .ops = { + .open = stac92xx_playback_pcm_open, + .prepare = stac92xx_playback_pcm_prepare, + .cleanup = stac92xx_playback_pcm_cleanup + }, +}; + static struct hda_pcm_stream stac92xx_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, - .nid = 0x06, /* NID to query formats and rates */ + /* NID is set in stac92xx_build_pcms */ .ops = { .prepare = stac92xx_capture_pcm_prepare, .cleanup = stac92xx_capture_pcm_cleanup @@ -434,6 +501,14 @@ static int stac92xx_build_pcms(struct hda_codec *codec) info->name = "STAC92xx Analog"; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; + + if (spec->alt_switch) { + codec->num_pcms++; + info++; + info->name = "STAC92xx Analog Alt"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback; + } if (spec->multiout.dig_out_nid || spec->dig_in_nid) { codec->num_pcms++; @@ -592,6 +667,16 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf return 0; } +/* + * XXX The line_out pin widget connection list may not be set to the + * desired DAC nid. This is the case on 927x where ports A and B can + * be routed to several DACs. + * + * This requires an analysis of the line-out/hp pin configuration + * to provide a best fit for pin/DAC configurations that are routable. + * For now, 927x DAC4 is not supported and 927x DAC1 output to ports + * A and B is not supported. + */ /* fill in the dac_nids table from the parsed pin configuration */ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { @@ -757,7 +842,7 @@ static void stac92xx_auto_init_hp_out(struct hda_codec *codec) stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); } -static int stac922x_parse_auto_config(struct hda_codec *codec) +static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) { struct sigmatel_spec *spec = codec->spec; int err; @@ -781,11 +866,11 @@ static int stac922x_parse_auto_config(struct hda_codec *codec) spec->surr_switch = 1; if (spec->autocfg.dig_out_pin) { - spec->multiout.dig_out_nid = 0x08; + spec->multiout.dig_out_nid = dig_out; stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); } if (spec->autocfg.dig_in_pin) { - spec->dig_in_nid = 0x09; + spec->dig_in_nid = dig_in; stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); } @@ -1000,7 +1085,47 @@ static int patch_stac922x(struct hda_codec *codec) spec->multiout.dac_nids = spec->dac_nids; - err = stac922x_parse_auto_config(codec); + err = stac92xx_parse_auto_config(codec, 0x08, 0x09); + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + +static int patch_stac927x(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl); + if (spec->board_config < 0) + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); + else { + spec->num_pins = 14; + spec->pin_nids = stac927x_pin_nids; + spec->pin_configs = stac927x_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + spec->adc_nids = stac927x_adc_nids; + spec->mux_nids = stac927x_mux_nids; + spec->num_muxes = 3; + + spec->init = stac927x_core_init; + spec->mixer = stac927x_mixer; + + spec->multiout.dac_nids = spec->dac_nids; + + err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); if (err < 0) { stac92xx_free(codec); return err; @@ -1022,5 +1147,15 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, + { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, + { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, + { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, + { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x }, + { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x }, + { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x }, + { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x }, + { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, + { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, + { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, {} /* terminator */ }; From 802c00f2f3700423df06a1149c23cd60dd59159c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Jan 2006 15:31:11 +0100 Subject: [PATCH 304/695] [ALSA] via82xx - Add dxs entry for P4M800/VIA8237R Modules: VIA82xx driver Added the dxs entry for P4M800/VIA8237R, reported by OGAWA Hirofumi Signed-off-by: Takashi Iwai --- sound/pci/via82xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 8d348f27f17a..423741371191 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -2359,6 +2359,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */ { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */ { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */ + { .subvendor = 0x1462, .subdevice = 0xb012, .action = VIA_DXS_SRC }, /* P4M800/VIA8237R */ { .subvendor = 0x147b, .subdevice = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */ { .subvendor = 0x147b, .subdevice = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */ { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ From ad0651f97a3f8c5982921cb57fbedc877279e03d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Jan 2006 10:34:34 +0100 Subject: [PATCH 305/695] [ALSA] hda-codec - Fix max_channels computation for STAC92xx codecs Modules: HDA Codec driver Fix max_channels computation for STAC92xx codecs in the case only HP pin without line-out pins is detected in the default pin config. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d5342d20bd81..f7892a5b7757 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -691,7 +691,13 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct aut AC_VERB_GET_CONNECT_LIST, 0) & 0xff; } - spec->multiout.num_dacs = cfg->line_outs; + if (cfg->line_outs) + spec->multiout.num_dacs = cfg->line_outs; + else if (cfg->hp_pin) { + spec->multiout.dac_nids[0] = snd_hda_codec_read(codec, cfg->hp_pin, 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + spec->multiout.num_dacs = 1; + } return 0; } From fd56f2db9385a651d31fe86eb4cc6cacbb0c5a63 Mon Sep 17 00:00:00 2001 From: Jonathan Woithe Date: Tue, 24 Jan 2006 10:35:46 +0100 Subject: [PATCH 306/695] [ALSA] hda-codec - Fix init verb of ALC260 Modules: HDA Codec driver Fixed the wrong widget id for line-2 selector in the init verb of ALC260. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 543980d89b83..043513b94b1c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2475,7 +2475,7 @@ static struct hda_verb alc260_init_verbs[] = { /* LINE-2 is used for line-out in rear */ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* select line-out */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, /* LINE-OUT pin */ {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* enable HP */ From 89ac9c256495cbdbe130be5ed192c8911c89ed87 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Jan 2006 10:36:57 +0100 Subject: [PATCH 307/695] [ALSA] intel8x0 - Add MCP51 PCI ID Modules: Documentation,Intel8x0 driver Added MCP51 PCI ID to intel8x0 driver. Also, updated the supported chips in documentation. Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 10 +++++++++- sound/pci/intel8x0.c | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index d2578013e829..36b511c7cade 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -837,8 +837,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for AC'97 motherboards from Intel and compatibles. * Intel i810/810E, i815, i820, i830, i84x, MX440 + ICH5, ICH6, ICH7, ESB2 * SiS 7012 (SiS 735) - * NVidia NForce, NForce2 + * NVidia NForce, NForce2, NForce3, MCP04, CK804 + CK8, CK8S, MCP501 * AMD AMD768, AMD8111 * ALi m5455 @@ -868,6 +870,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. -------------------- Module for Intel ICH (i8x0) chipset MC97 modems. + * Intel i810/810E, i815, i820, i830, i84x, MX440 + ICH5, ICH6, ICH7 + * SiS 7013 (SiS 735) + * NVidia NForce, NForce2, NForce2s, NForce3 + * AMD AMD8111 + * ALi m5455 ac97_clock - AC'97 codec clock base (0 = auto-detect) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index b345894659bb..174237f4a22c 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -427,6 +427,7 @@ static struct pci_device_id snd_intel8x0_ids[] = { { 0x10de, 0x008a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8 */ { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */ { 0x10de, 0x00ea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8S */ + { 0x10de, 0x026b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* MCP51 */ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ From 1d79716ab07710465fa9fc1ae7328cc6095d2526 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 25 Jan 2006 14:30:44 +0100 Subject: [PATCH 308/695] [ALSA] Fix adding second dma channel Modules: OPL3SA2 driver,GUS Classic driver dma2 is a global array. sprintf below suggests there was a typo. Signed-off-by: Alexey Dobriyan Signed-off-by: Takashi Iwai --- sound/isa/gus/gusclassic.c | 2 +- sound/isa/opl3sa2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index d1165b96fa3f..91c219116d7a 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c @@ -195,7 +195,7 @@ static int __init snd_gusclassic_probe(struct platform_device *pdev) goto _err; } sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1); - if (dma2 >= 0) + if (xdma2 >= 0) sprintf(card->longname + strlen(card->longname), "&%d", xdma2); snd_card_set_dev(card, &pdev->dev); diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 9dc6b20e9a5c..9d8431978501 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -723,7 +723,7 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) } sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", card->shortname, chip->port, xirq, xdma1); - if (dma2 >= 0) + if (xdma2 >= 0) sprintf(card->longname + strlen(card->longname), "&%d", xdma2); return snd_card_register(card); From 869264c45a6a77d73ec6caa543616a10a9dfd951 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Wed, 25 Jan 2006 19:20:50 +0100 Subject: [PATCH 309/695] [ALSA] hda: sigmatel fixes Modules: HDA Codec driver * Fix init sequence so manually retaskable jacks don't get added to the line_out list. * Update intel mobo config defaults to specify surround outputs as line outs rather than speakers. Signed-off-by: Matt Porter Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f7892a5b7757..35c2823a0a2b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -277,14 +277,14 @@ static unsigned int ref922x_pin_configs[10] = { }; static unsigned int d945gtp3_pin_configs[10] = { - 0x0221401f, 0x01a19022, 0x01813021, 0x01114010, + 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x02a19120, 0x40000100, }; static unsigned int d945gtp5_pin_configs[10] = { - 0x0221401f, 0x01111012, 0x01813024, 0x01114010, - 0x01a19021, 0x01116011, 0x01452130, 0x40000100, + 0x0221401f, 0x01011012, 0x01813024, 0x01014010, + 0x01a19021, 0x01016011, 0x01452130, 0x40000100, 0x02a19320, 0x40000100, }; @@ -855,12 +855,14 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) return err; + if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) + return 0; /* can't find valid pin config */ + stac92xx_auto_init_multi_out(codec); + stac92xx_auto_init_hp_out(codec); if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) return err; if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) return err; - if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) - return 0; /* can't find valid pin config */ if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 || @@ -922,9 +924,6 @@ static int stac92xx_init(struct hda_codec *codec) snd_hda_sequence_write(codec, spec->init); - stac92xx_auto_init_multi_out(codec); - stac92xx_auto_init_hp_out(codec); - return 0; } From 44275f18ec22a31980469567052e932d1023971f Mon Sep 17 00:00:00 2001 From: Giuliano Pochini Date: Fri, 27 Jan 2006 12:02:05 +0100 Subject: [PATCH 310/695] [ALSA] fix typos in writing-an-alsa-driver Modules: Documentation Fixed typos in writing-an-alsa-driver document. Signed-off-by: Giuliano Pochini Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index e651ed8d1e6f..4251085d38d3 100644 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -5206,14 +5206,14 @@ struct _snd_pcm_runtime { You need to pass the snd_dma_pci_data(pci), where pci is the struct pci_dev pointer of the chip as well. - The snd_sg_buf_t instance is created as + The struct snd_sg_buf instance is created as substream->dma_private. You can cast the pointer like: dma_private; + struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private; ]]> From bae2bdb334c1ca5f4721e4fab1ca947f44455117 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Fri, 27 Jan 2006 12:05:02 +0100 Subject: [PATCH 311/695] [ALSA] patch_realtek.c: Add new model Modules: HDA Codec driver This little patch add the model for the motherboard K8N51 from Gigabyte to the known models of ALC boards. Signed-off-by: Arnaud Patard Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 043513b94b1c..906263e620aa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1668,6 +1668,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */ { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST }, { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */ + { .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */ { .modelname = "6stack-digout", .config = ALC880_6ST_DIG }, { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, From 1494a92f4c2b1d5abdaa1f823dd19f797bb137de Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2006 10:58:46 +0100 Subject: [PATCH 312/695] [ALSA] hda-codec - Fix typos in alc882 model table Modules: HDA Codec driver Fixed typos in alc882 model table. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 906263e620aa..b76755264730 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3417,12 +3417,12 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = { * configuration and preset */ static struct hda_board_config alc882_cfg_tbl[] = { - { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, - { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, + { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, + { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI */ { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */ { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */ - { .modelname = "auto", .config = ALC861_AUTO }, + { .modelname = "auto", .config = ALC882_AUTO }, {} }; From 3833a70585fd4b0f64e275ba0cc3f5e5038253fd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 1 Feb 2006 03:04:32 -0800 Subject: [PATCH 313/695] [PATCH] x86_64: compat_sys_futimesat fix We need to use the compat function here. Pointer out by Heiko Carstens Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/ia32/ia32entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index f05c2a802489..067c0f47bd0d 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -676,7 +676,7 @@ ia32_sys_call_table: .quad sys_mkdirat .quad sys_mknodat .quad sys_fchownat - .quad sys_futimesat + .quad compat_sys_futimesat .quad compat_sys_newfstatat /* 300 */ .quad sys_unlinkat .quad sys_renameat From 577bca9eff94193a06e426f8dbf6b3152247a209 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Wed, 1 Feb 2006 03:04:33 -0800 Subject: [PATCH 314/695] [PATCH] CONFIG_ISA does not make sense for CONFIG_PPC_PSERIES Older pSeries systems with serial ports dont get any console output after recent changes. CONFIG_ISA does not make sense for CONFIG_PPC_PSERIES because it enables lots of old drivers. Instead, remove the dependency on CONFIG_ISA from the serial port discovery code. Signed-off-by: Olaf Hering Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/legacy_serial.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index f970ace208d3..c7a799a09516 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -134,7 +134,6 @@ static int __init add_legacy_soc_port(struct device_node *np, return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags); } -#ifdef CONFIG_ISA static int __init add_legacy_isa_port(struct device_node *np, struct device_node *isa_brg) { @@ -168,7 +167,6 @@ static int __init add_legacy_isa_port(struct device_node *np, return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF); } -#endif #ifdef CONFIG_PCI static int __init add_legacy_pci_port(struct device_node *np, @@ -276,7 +274,6 @@ void __init find_legacy_serial_ports(void) of_node_put(soc); } -#ifdef CONFIG_ISA /* First fill our array with ISA ports */ for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { struct device_node *isa = of_get_parent(np); @@ -287,7 +284,6 @@ void __init find_legacy_serial_ports(void) } of_node_put(isa); } -#endif #ifdef CONFIG_PCI /* Next, try to locate PCI ports */ From 3a2ca64496cc1c9aeab1076e06d092b3ec74a43d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 1 Feb 2006 03:04:33 -0800 Subject: [PATCH 315/695] [PATCH] prototypes for *at functions & typo fix Here's the follow-up patch which introduces the prototypes for the new syscalls. There was also a typo in one of the new symbols. Signed-off-by: Ulrich Drepper Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-x86_64/ia32_unistd.h | 2 +- include/linux/syscalls.h | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h index e87cd83a0e86..9afc0c7d3661 100644 --- a/include/asm-x86_64/ia32_unistd.h +++ b/include/asm-x86_64/ia32_unistd.h @@ -300,7 +300,7 @@ #define __NR_ia32_inotify_add_watch 292 #define __NR_ia32_inotify_rm_watch 293 #define __NR_ia32_migrate_pages 294 -#define __NR_ia32_opanat 295 +#define __NR_ia32_openat 295 #define __NR_ia32_mkdirat 296 #define __NR_ia32_mknodat 297 #define __NR_ia32_fchownat 298 diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index e666d6070569..fdbd436b24cc 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -50,6 +50,8 @@ struct timezone; struct tms; struct utimbuf; struct mq_attr; +struct compat_stat; +struct compat_timeval; #include #include @@ -534,4 +536,35 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, asmlinkage long sys_spu_create(const char __user *name, unsigned int flags, mode_t mode); +asmlinkage long sys_mknodat(int dfd, const char __user * filename, int mode, + unsigned dev); +asmlinkage long sys_mkdirat(int dfd, const char __user * pathname, int mode); +asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag); +asmlinkage long sys_symlinkat(const char __user * oldname, + int newdfd, const char __user * newname); +asmlinkage long sys_linkat(int olddfd, const char __user *oldname, + int newdfd, const char __user *newname); +asmlinkage long sys_renameat(int olddfd, const char __user * oldname, + int newdfd, const char __user * newname); +asmlinkage long sys_futimesat(int dfd, char __user *filename, + struct timeval __user *utimes); +asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode); +asmlinkage long sys_fchmodat(int dfd, const char __user * filename, + mode_t mode); +asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, + gid_t group, int flag); +asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, + int mode); +asmlinkage long sys_newfstatat(int dfd, char __user *filename, + struct stat __user *statbuf, int flag); +asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf, + int bufsiz); +asmlinkage long compat_sys_futimesat(int dfd, char __user *filename, + struct compat_timeval __user *t); +asmlinkage long compat_sys_newfstatat(int dfd, char __user * filename, + struct compat_stat __user *statbuf, + int flag); +asmlinkage long compat_sys_openat(int dfd, const char __user *filename, + int flags, int mode); + #endif From 3fb803a990cd17546bd89c38e0e29a891f71ce7d Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 1 Feb 2006 03:04:34 -0800 Subject: [PATCH 316/695] [PATCH] knfsd: Restore recently broken ACL functionality to NFS server A recent patch to Allow run-time selection of NFS versions to export meant that NO nfsacl service versions were exported. This patch restored that functionality. Signed-off-by: Andreas Gruenbacher Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/nfsd/nfssvc.c | 76 +++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 89ed04696865..1d163b616915 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -64,6 +64,32 @@ struct nfsd_list { }; static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list); +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) +static struct svc_stat nfsd_acl_svcstats; +static struct svc_version * nfsd_acl_version[] = { + [2] = &nfsd_acl_version2, + [3] = &nfsd_acl_version3, +}; + +#define NFSD_ACL_MINVERS 2 +#define NFSD_ACL_NRVERS (sizeof(nfsd_acl_version)/sizeof(nfsd_acl_version[0])) +static struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS]; + +static struct svc_program nfsd_acl_program = { + .pg_prog = NFS_ACL_PROGRAM, + .pg_nvers = NFSD_ACL_NRVERS, + .pg_vers = nfsd_acl_versions, + .pg_name = "nfsd", + .pg_class = "nfsd", + .pg_stats = &nfsd_acl_svcstats, + .pg_authenticate = &svc_set_client, +}; + +static struct svc_stat nfsd_acl_svcstats = { + .program = &nfsd_acl_program, +}; +#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ + static struct svc_version * nfsd_version[] = { [2] = &nfsd_version2, #if defined(CONFIG_NFSD_V3) @@ -79,6 +105,9 @@ static struct svc_version * nfsd_version[] = { static struct svc_version *nfsd_versions[NFSD_NRVERS]; struct svc_program nfsd_program = { +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) + .pg_next = &nfsd_acl_program, +#endif .pg_prog = NFS_PROGRAM, /* program number */ .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */ .pg_vers = nfsd_versions, /* version table */ @@ -147,6 +176,26 @@ nfsd_svc(unsigned short port, int nrservs) nfsd_program.pg_vers[i] = nfsd_version[i]; } + +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) + found_one = 0; + + for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) { + if (NFSCTL_VERISSET(nfsd_versbits, i)) { + nfsd_acl_program.pg_vers[i] = + nfsd_acl_version[i]; + found_one = 1; + } else + nfsd_acl_program.pg_vers[i] = NULL; + } + + if (!found_one) { + for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) + nfsd_acl_program.pg_vers[i] = + nfsd_acl_version[i]; + } +#endif + atomic_set(&nfsd_busy, 0); error = -ENOMEM; nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE); @@ -411,30 +460,3 @@ nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp) nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1); return 1; } - -#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) -static struct svc_stat nfsd_acl_svcstats; -static struct svc_version * nfsd_acl_version[] = { - [2] = &nfsd_acl_version2, - [3] = &nfsd_acl_version3, -}; - -#define NFSD_ACL_NRVERS (sizeof(nfsd_acl_version)/sizeof(nfsd_acl_version[0])) -static struct svc_program nfsd_acl_program = { - .pg_prog = NFS_ACL_PROGRAM, - .pg_nvers = NFSD_ACL_NRVERS, - .pg_vers = nfsd_acl_version, - .pg_name = "nfsd", - .pg_class = "nfsd", - .pg_stats = &nfsd_acl_svcstats, - .pg_authenticate = &svc_set_client, -}; - -static struct svc_stat nfsd_acl_svcstats = { - .program = &nfsd_acl_program, -}; - -#define nfsd_acl_program_p &nfsd_acl_program -#else -#define nfsd_acl_program_p NULL -#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ From 389d1ea50849f84c3a9f8640fcb66827746b4ab4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 1 Feb 2006 03:04:35 -0800 Subject: [PATCH 317/695] [PATCH] CONFIG_DOUBLEFAULT Kconfig fix Move CONFIG_DOUBLEFAULT from the main Kconfig menu (!) into its proper place: the "Processor Type and features" submenu. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/Kconfig | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index cbde675bc95c..4e9e49a55ea8 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -47,15 +47,6 @@ config DMI source "init/Kconfig" -config DOUBLEFAULT - default y - bool "Enable doublefault exception handler" if EMBEDDED - help - This option allows trapping of rare doublefault exceptions that - would otherwise cause a system to silently reboot. Disabling this - option saves about 4k and might cause you much additional grey - hair. - menu "Processor type and features" choice @@ -711,6 +702,15 @@ config HOTPLUG_CPU Say N. +config DOUBLEFAULT + default y + bool "Enable doublefault exception handler" if EMBEDDED + help + This option allows trapping of rare doublefault exceptions that + would otherwise cause a system to silently reboot. Disabling this + option saves about 4k and might cause you much additional grey + hair. + endmenu From caf736085f2f0d22a992a855d9caae14973f7ea4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 1 Feb 2006 03:04:39 -0800 Subject: [PATCH 318/695] [PATCH] smbfs readdir vs signal fix An old patch designed to fix http://bugme.osdl.org/show_bug.cgi?id=4497, "getdents gives empty/random result upon signal". If smbfs's readdir() is interupted by a signal, smb_readdir() failed to noticed that and proceeded to treat the unread-into page as valid directory contents. Fix that up by handling the -ERESTARTSYS. Thanks to Stian Skjelstad for reporting and testing. Cc: Stian Skjelstad Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/smbfs/dir.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index c6c33e15143a..0424d06b147e 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -209,6 +209,8 @@ init_cache: ctl.valid = 1; read_really: result = server->ops->readdir(filp, dirent, filldir, &ctl); + if (result == -ERESTARTSYS && page) + ClearPageUptodate(page); if (ctl.idx == -1) goto invalid_cache; /* retry */ ctl.head.end = ctl.fpos - 1; @@ -217,7 +219,8 @@ finished: if (page) { cache->head = ctl.head; kunmap(page); - SetPageUptodate(page); + if (result != -ERESTARTSYS) + SetPageUptodate(page); unlock_page(page); page_cache_release(page); } From 9cd684551124e71630ab96d238747051463f5b56 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 1 Feb 2006 03:04:40 -0800 Subject: [PATCH 319/695] [PATCH] fuse: fix async read for legacy filesystems While asynchronous reads mean a performance improvement in most cases, if the filesystem assumed that reads are synchronous, then async reads may degrade performance (filesystem may receive reads out of order, which can confuse it's own readahead logic). With sshfs a 1.5 to 4 times slowdown can be measured. There's also a need for userspace filesystems to know whether asynchronous reads are supported by the kernel or not. To achive these, negotiate in the INIT request whether async reads will be used and the maximum readahead value. Update interface version to 7.6 If userspace uses a version earlier than 7.6, then disable async reads, and set maximum readahead value to the maximum read size, as done in previous versions. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/file.c | 9 +++++++-- fs/fuse/fuse_i.h | 3 +++ fs/fuse/inode.c | 14 ++++++++++++-- include/linux/fuse.h | 16 ++++++++++++++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index a7ef5e716f3c..296351615b00 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -335,9 +335,14 @@ static void fuse_send_readpages(struct fuse_req *req, struct file *file, loff_t pos = page_offset(req->pages[0]); size_t count = req->num_pages << PAGE_CACHE_SHIFT; req->out.page_zeroing = 1; - req->end = fuse_readpages_end; fuse_read_fill(req, file, inode, pos, count, FUSE_READ); - request_send_background(fc, req); + if (fc->async_read) { + req->end = fuse_readpages_end; + request_send_background(fc, req); + } else { + request_send(fc, req); + fuse_readpages_end(fc, req); + } } struct fuse_readpages_data { diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 46cf933aa3bf..4a83adfec968 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -272,6 +272,9 @@ struct fuse_conn { reply, before any other request, and never cleared */ unsigned conn_error : 1; + /** Do readpages asynchronously? Only set in INIT */ + unsigned async_read : 1; + /* * The following bitfields are only for optimization purposes * and hence races in setting them will not cause malfunction diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index c755a0440a66..879e6fba9480 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -473,6 +473,16 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION) fc->conn_error = 1; else { + unsigned long ra_pages; + + if (arg->minor >= 6) { + ra_pages = arg->max_readahead / PAGE_CACHE_SIZE; + if (arg->flags & FUSE_ASYNC_READ) + fc->async_read = 1; + } else + ra_pages = fc->max_read / PAGE_CACHE_SIZE; + + fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); fc->minor = arg->minor; fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; } @@ -496,6 +506,8 @@ static void fuse_send_init(struct fuse_conn *fc) arg->major = FUSE_KERNEL_VERSION; arg->minor = FUSE_KERNEL_MINOR_VERSION; + arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; + arg->flags |= FUSE_ASYNC_READ; req->in.h.opcode = FUSE_INIT; req->in.numargs = 1; req->in.args[0].size = sizeof(*arg); @@ -552,8 +564,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) fc->user_id = d.user_id; fc->group_id = d.group_id; fc->max_read = d.max_read; - if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages) - fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE; /* Used by get_root_inode() */ sb->s_fs_info = fc; diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 528959c52f1b..5425b60021e3 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -14,7 +14,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 5 +#define FUSE_KERNEL_MINOR_VERSION 6 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -58,6 +58,9 @@ struct fuse_kstatfs { __u32 spare[6]; }; +/** + * Bitmasks for fuse_setattr_in.valid + */ #define FATTR_MODE (1 << 0) #define FATTR_UID (1 << 1) #define FATTR_GID (1 << 2) @@ -75,6 +78,11 @@ struct fuse_kstatfs { #define FOPEN_DIRECT_IO (1 << 0) #define FOPEN_KEEP_CACHE (1 << 1) +/** + * INIT request/reply flags + */ +#define FUSE_ASYNC_READ (1 << 0) + enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ @@ -247,12 +255,16 @@ struct fuse_access_in { struct fuse_init_in { __u32 major; __u32 minor; + __u32 max_readahead; + __u32 flags; }; struct fuse_init_out { __u32 major; __u32 minor; - __u32 unused[3]; + __u32 max_readahead; + __u32 flags; + __u32 unused; __u32 max_write; }; From 88356e908521a84b2220c9e8850d1a356a851aa9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 1 Feb 2006 03:04:43 -0800 Subject: [PATCH 320/695] [PATCH] sound/ppc/pmac.c typo In 2.6.16-rc1 there is a small typo introduced by the 'Remove device_node addrs/n_addr' changes which prevents my Powerbook G4 sound from working: Advanced Linux Sound Architecture Driver Version 1.0.11rc2 (Wed Jan 04 08:57:20 2006 UTC). snd: can't request rsrc 0 (Sound Control: 0x80000000:80004fff) ALSA device list: No soundcards found. The patch below fixes it. Of course, the patch fixing the i2c issues ('i2c_smbus_write_i2c_block_data' patch) needs to be applied to in order for the sound to completly work. Signed-off-by: Stelian Pop Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/ppc/pmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index a642e4cfcf45..4988f873a7ba 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -1216,7 +1216,7 @@ int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) goto __error; } for (i = 0; i < 3; i ++) { - if (of_address_to_resource(np->parent, i, + if (of_address_to_resource(np, i, &chip->rsrc[i])) { printk(KERN_ERR "snd: can't translate rsrc " " %d (%s)\n", i, rnames[i]); From 6292d9aaf3047f1abd970bc64ab6d952eda258ac Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Wed, 1 Feb 2006 03:04:44 -0800 Subject: [PATCH 321/695] [PATCH] __cpuinit functions wrongly marked __meminit __meminit has overzelously been modified and crept its way into marking cpuup callbacks as __meminit. Signed-off-by: Ashok Raj Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index df54e2fc8ee0..44b4eb4202d9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1799,7 +1799,7 @@ void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn, memmap_init_zone((size), (nid), (zone), (start_pfn)) #endif -static int __meminit zone_batchsize(struct zone *zone) +static int __cpuinit zone_batchsize(struct zone *zone) { int batch; @@ -1893,7 +1893,7 @@ static struct per_cpu_pageset * Dynamically allocate memory for the * per cpu pageset array in struct zone. */ -static int __meminit process_zones(int cpu) +static int __cpuinit process_zones(int cpu) { struct zone *zone, *dzone; @@ -1934,7 +1934,7 @@ static inline void free_zone_pagesets(int cpu) } } -static int __meminit pageset_cpuup_callback(struct notifier_block *nfb, +static int __cpuinit pageset_cpuup_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { From b62735d9c6212de6fd1b5e96b41d978939fb0dd2 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Wed, 1 Feb 2006 03:04:45 -0800 Subject: [PATCH 322/695] [PATCH] ide-scsi: fix for IDE probe/remove ops changes Kernel 2.6.16-rc1 broke the ide-scsi driver: ide-scsi loads but fails to find any devices to bind to. It also triggers a message "Driver 'ide-scsi' needs updating - please use bus_type methods" from the driver core. The IDE core in 2.6.16-rc1 changed the location of an IDE driver's ->probe()/->remove()/->shutdown() methods: they are now in the ide_driver_t struct not in the gen_driver sub-struct. drivers/ide/ was updated for this change but ide-scsi.c wasn't. Hence the breakage. This patch repairs ide-scsi and also eliminates the driver core warning. Signed-off-by: Mikael Pettersson Cc: Russell King Cc: Greg KH Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/ide-scsi.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 3c688ef54660..0cf0e4c7ac0c 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -751,9 +751,8 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) idescsi_add_settings(drive); } -static int ide_scsi_remove(struct device *dev) +static void ide_scsi_remove(ide_drive_t *drive) { - ide_drive_t *drive = to_ide_device(dev); struct Scsi_Host *scsihost = drive->driver_data; struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); struct gendisk *g = scsi->disk; @@ -768,11 +767,9 @@ static int ide_scsi_remove(struct device *dev) scsi_remove_host(scsihost); ide_scsi_put(scsi); - - return 0; } -static int ide_scsi_probe(struct device *); +static int ide_scsi_probe(ide_drive_t *); #ifdef CONFIG_PROC_FS static ide_proc_entry_t idescsi_proc[] = { @@ -788,9 +785,9 @@ static ide_driver_t idescsi_driver = { .owner = THIS_MODULE, .name = "ide-scsi", .bus = &ide_bus_type, - .probe = ide_scsi_probe, - .remove = ide_scsi_remove, }, + .probe = ide_scsi_probe, + .remove = ide_scsi_remove, .version = IDESCSI_VERSION, .media = ide_scsi, .supports_dsc_overlap = 0, @@ -1119,9 +1116,8 @@ static struct scsi_host_template idescsi_template = { .proc_name = "ide-scsi", }; -static int ide_scsi_probe(struct device *dev) +static int ide_scsi_probe(ide_drive_t *drive) { - ide_drive_t *drive = to_ide_device(dev); idescsi_scsi_t *idescsi; struct Scsi_Host *host; struct gendisk *g; From cc0fa84a01d328a1ad70076b90f08281c4c79f92 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Wed, 1 Feb 2006 03:04:47 -0800 Subject: [PATCH 323/695] [PATCH] powerpc: enable irq's for platform functions. Make the platform function interrupt functions actually work. Calls irq_enable() for the first in the list, and irq_disable() for the last. Added *func to struct irq_client so the the user can pass just that to pmf_unregister_irq_client(). Signed-off-by: Ben Collins Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/platforms/powermac/pfunc_core.c | 13 ++++++++++--- include/asm-powerpc/pmac_pfunc.h | 5 ++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index c32c623001dc..356a739e52b2 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -862,21 +862,28 @@ int pmf_register_irq_client(struct device_node *target, spin_unlock_irqrestore(&pmf_lock, flags); return -ENODEV; } + if (list_empty(&func->irq_clients)) + func->dev->handlers->irq_enable(func); list_add(&client->link, &func->irq_clients); + client->func = func; spin_unlock_irqrestore(&pmf_lock, flags); return 0; } EXPORT_SYMBOL_GPL(pmf_register_irq_client); -void pmf_unregister_irq_client(struct device_node *np, - const char *name, - struct pmf_irq_client *client) +void pmf_unregister_irq_client(struct pmf_irq_client *client) { + struct pmf_function *func = client->func; unsigned long flags; + BUG_ON(func == NULL); + spin_lock_irqsave(&pmf_lock, flags); + client->func = NULL; list_del(&client->link); + if (list_empty(&func->irq_clients)) + func->dev->handlers->irq_disable(func); spin_unlock_irqrestore(&pmf_lock, flags); } EXPORT_SYMBOL_GPL(pmf_unregister_irq_client); diff --git a/include/asm-powerpc/pmac_pfunc.h b/include/asm-powerpc/pmac_pfunc.h index d9728c80f86d..cef61304ffc2 100644 --- a/include/asm-powerpc/pmac_pfunc.h +++ b/include/asm-powerpc/pmac_pfunc.h @@ -167,6 +167,7 @@ struct pmf_irq_client { void *data; struct module *owner; struct list_head link; + struct pmf_function *func; }; @@ -187,9 +188,7 @@ extern int pmf_register_irq_client(struct device_node *np, const char *name, struct pmf_irq_client *client); -extern void pmf_unregister_irq_client(struct device_node *np, - const char *name, - struct pmf_irq_client *client); +extern void pmf_unregister_irq_client(struct pmf_irq_client *client); /* * Called by the handlers when an irq happens From 70e51015768439a5c305a42fdaa0abe5cc109bcf Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 1 Feb 2006 03:04:48 -0800 Subject: [PATCH 324/695] [PATCH] tsunami_flash: fix "parse error before ';' token" Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/maps/tsunami_flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c index 9e21e6c02f80..0f915ac3102e 100644 --- a/drivers/mtd/maps/tsunami_flash.c +++ b/drivers/mtd/maps/tsunami_flash.c @@ -62,7 +62,7 @@ static void tsunami_flash_copy_to( static struct map_info tsunami_flash_map = { .name = "flash chip on the Tsunami TIG bus", .size = MAX_TIG_FLASH_SIZE, - .phys = NO_XIP; + .phys = NO_XIP, .bankwidth = 1, .read = tsunami_flash_read8, .copy_from = tsunami_flash_copy_from, From 4ff0c007b2854b9ca4dca3a104ee3e4c146c02d6 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 1 Feb 2006 03:04:48 -0800 Subject: [PATCH 325/695] [PATCH] lp486e: remove SLOW_DOWN_IO It's not used. Fix the following on alpha-eb66 as a side effect: In file included from drivers/net/lp486e.c:75: include/asm/io.h:20:1: warning: "SLOW_DOWN_IO" redefined drivers/net/lp486e.c:59:1: warning: this is the location of the previous definition Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/lp486e.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c index 6139f06d7d2b..94d5ea1ce8bd 100644 --- a/drivers/net/lp486e.c +++ b/drivers/net/lp486e.c @@ -56,8 +56,6 @@ PORT SIZE ACTION MEANING All other communication is through memory! */ -#define SLOW_DOWN_IO udelay(5) - #include #include #include From cb82a6cdf994d6656ad0a25ed28395af3416a27c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 1 Feb 2006 03:04:49 -0800 Subject: [PATCH 326/695] [PATCH] compat_sys_pselect7() fix fs/compat.c: In function `compat_sys_pselect7': fs/compat.c:1820: warning: passing arg 5 of `compat_core_sys_select' from incompatible pointer type Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/compat.c b/fs/compat.c index ff0bafcff720..cc58a20df57a 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1781,7 +1781,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, { compat_sigset_t ss32; sigset_t ksigmask, sigsaved; - long timeout = MAX_SCHEDULE_TIMEOUT; + s64 timeout = MAX_SCHEDULE_TIMEOUT; struct compat_timespec ts; int ret; From aa14edeb994f8f7e223d02ad14780bf2fa719f6d Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Wed, 1 Feb 2006 03:04:50 -0800 Subject: [PATCH 327/695] [PATCH] device-mapper snapshot: load metadata on creation Move snapshot metadata loading to happen when the table is created instead of when the device is resumed. Writes to the origin device don't trigger exceptions until each snapshot table becomes active when resume() is called on each snapshot. If you're using lvm2, for this patch to work properly you should update to lvm2 version 2.02.01 or later and device-mapper version 1.02.02 or later. Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-snap.c | 23 ++++++++++++----------- drivers/md/dm-snap.h | 4 +++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 87727d84dbba..ad9b61f16c5e 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -373,16 +373,11 @@ static inline ulong round_up(ulong n, ulong size) static void read_snapshot_metadata(struct dm_snapshot *s) { - if (s->have_metadata) - return; - if (s->store.read_metadata(&s->store)) { down_write(&s->lock); s->valid = 0; up_write(&s->lock); } - - s->have_metadata = 1; } /* @@ -471,7 +466,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) s->chunk_shift = ffs(chunk_size) - 1; s->valid = 1; - s->have_metadata = 0; + s->active = 0; s->last_percent = 0; init_rwsem(&s->lock); s->table = ti->table; @@ -506,7 +501,11 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad5; } + /* Metadata must only be loaded into one table at once */ + read_snapshot_metadata(s); + /* Add snapshot to the list of snapshots for this origin */ + /* Exceptions aren't triggered till snapshot_resume() is called */ if (register_snapshot(s)) { r = -EINVAL; ti->error = "Cannot register snapshot origin"; @@ -862,7 +861,9 @@ static void snapshot_resume(struct dm_target *ti) { struct dm_snapshot *s = (struct dm_snapshot *) ti->private; - read_snapshot_metadata(s); + down_write(&s->lock); + s->active = 1; + up_write(&s->lock); } static int snapshot_status(struct dm_target *ti, status_type_t type, @@ -932,8 +933,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) /* Do all the snapshots on this origin */ list_for_each_entry (snap, snapshots, list) { - /* Only deal with valid snapshots */ - if (!snap->valid) + /* Only deal with valid and active snapshots */ + if (!snap->valid || !snap->active) continue; /* Nothing to do if writing beyond end of snapshot */ @@ -1104,7 +1105,7 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result, static struct target_type origin_target = { .name = "snapshot-origin", - .version = {1, 0, 1}, + .version = {1, 1, 0}, .module = THIS_MODULE, .ctr = origin_ctr, .dtr = origin_dtr, @@ -1115,7 +1116,7 @@ static struct target_type origin_target = { static struct target_type snapshot_target = { .name = "snapshot", - .version = {1, 0, 1}, + .version = {1, 1, 0}, .module = THIS_MODULE, .ctr = snapshot_ctr, .dtr = snapshot_dtr, diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index 375aa24d4d7d..fdec1e2dc871 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h @@ -99,7 +99,9 @@ struct dm_snapshot { /* You can't use a snapshot if this is 0 (e.g. if full) */ int valid; - int have_metadata; + + /* Origin writes don't trigger exceptions until this is set */ + int active; /* Used for display of table */ char type; From a4fc4717fc55a3bcd3cfdafa285b7af164b83051 Mon Sep 17 00:00:00 2001 From: Patrick Caulfield Date: Wed, 1 Feb 2006 03:04:51 -0800 Subject: [PATCH 328/695] [PATCH] device-mapper log bitset: fix endian Clean up the code responsible for the on-disk mirror logs by using the set_le_bit test_le_bit functions of ext2. That makes the BE machines keep the bitmap internally in LE order - it does mean you can't use any other type of operations on the bitmap words but that looks to be OK in this instance. The efficiency tradeoff is very minimal as you would expect for something that ext2 uses. This allows us to remove bits_to_core(), bits_to_disk() and log->disk_bits. Also increment the mirror log disk version transparently to avoid sharing with older kernels that suffered from the 64-bit BE bug. Signed-off-by: Patrick Caulfield Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-log.c | 45 +++++++++++---------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index efe4adf78530..74039db846ba 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -112,7 +112,7 @@ void dm_destroy_dirty_log(struct dirty_log *log) /* * The on-disk version of the metadata. */ -#define MIRROR_DISK_VERSION 1 +#define MIRROR_DISK_VERSION 2 #define LOG_OFFSET 2 struct log_header { @@ -157,7 +157,6 @@ struct log_c { struct log_header *disk_header; struct io_region bits_location; - uint32_t *disk_bits; }; /* @@ -166,20 +165,20 @@ struct log_c { */ static inline int log_test_bit(uint32_t *bs, unsigned bit) { - return test_bit(bit, (unsigned long *) bs) ? 1 : 0; + return ext2_test_bit(bit, (unsigned long *) bs) ? 1 : 0; } static inline void log_set_bit(struct log_c *l, uint32_t *bs, unsigned bit) { - set_bit(bit, (unsigned long *) bs); + ext2_set_bit(bit, (unsigned long *) bs); l->touched = 1; } static inline void log_clear_bit(struct log_c *l, uint32_t *bs, unsigned bit) { - clear_bit(bit, (unsigned long *) bs); + ext2_clear_bit(bit, (unsigned long *) bs); l->touched = 1; } @@ -219,6 +218,11 @@ static int read_header(struct log_c *log) log->header.nr_regions = 0; } +#ifdef __LITTLE_ENDIAN + if (log->header.version == 1) + log->header.version = 2; +#endif + if (log->header.version != MIRROR_DISK_VERSION) { DMWARN("incompatible disk log version"); return -EINVAL; @@ -239,45 +243,24 @@ static inline int write_header(struct log_c *log) /*---------------------------------------------------------------- * Bits IO *--------------------------------------------------------------*/ -static inline void bits_to_core(uint32_t *core, uint32_t *disk, unsigned count) -{ - unsigned i; - - for (i = 0; i < count; i++) - core[i] = le32_to_cpu(disk[i]); -} - -static inline void bits_to_disk(uint32_t *core, uint32_t *disk, unsigned count) -{ - unsigned i; - - /* copy across the clean/dirty bitset */ - for (i = 0; i < count; i++) - disk[i] = cpu_to_le32(core[i]); -} - static int read_bits(struct log_c *log) { int r; unsigned long ebits; r = dm_io_sync_vm(1, &log->bits_location, READ, - log->disk_bits, &ebits); + log->clean_bits, &ebits); if (r) return r; - bits_to_core(log->clean_bits, log->disk_bits, - log->bitset_uint32_count); return 0; } static int write_bits(struct log_c *log) { unsigned long ebits; - bits_to_disk(log->clean_bits, log->disk_bits, - log->bitset_uint32_count); return dm_io_sync_vm(1, &log->bits_location, WRITE, - log->disk_bits, &ebits); + log->clean_bits, &ebits); } /*---------------------------------------------------------------- @@ -433,11 +416,6 @@ static int disk_ctr(struct dirty_log *log, struct dm_target *ti, size = dm_round_up(lc->bitset_uint32_count * sizeof(uint32_t), 1 << SECTOR_SHIFT); lc->bits_location.count = size >> SECTOR_SHIFT; - lc->disk_bits = vmalloc(size); - if (!lc->disk_bits) { - vfree(lc->disk_header); - goto bad; - } return 0; bad: @@ -451,7 +429,6 @@ static void disk_dtr(struct dirty_log *log) struct log_c *lc = (struct log_c *) log->context; dm_put_device(lc->ti, lc->log_dev); vfree(lc->disk_header); - vfree(lc->disk_bits); core_dtr(log); } From dab6a42915554f70220e5a2ff55c59c749582c7b Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Wed, 1 Feb 2006 03:04:52 -0800 Subject: [PATCH 329/695] [PATCH] device-mapper ioctl: reduce PF_MEMALLOC usage Reduce substantially the amount of code using PF_MEMALLOC, as envisaged in the original FIXME. If you're using lvm2, for this patch to work correctly you should update to lvm2 version 2.02.01 or later and device-mapper version 1.02.02 or later. Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-ioctl.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 1235135b384b..442e2be6052e 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1359,16 +1359,11 @@ static int ctl_ioctl(struct inode *inode, struct file *file, * Copy the parameters into kernel space. */ r = copy_params(user, ¶m); - if (r) { - current->flags &= ~PF_MEMALLOC; - return r; - } - /* - * FIXME: eventually we will remove the PF_MEMALLOC flag - * here. However the tools still do nasty things like - * 'load' while a device is suspended. - */ + current->flags &= ~PF_MEMALLOC; + + if (r) + return r; r = validate_params(cmd, param); if (r) @@ -1386,7 +1381,6 @@ static int ctl_ioctl(struct inode *inode, struct file *file, out: free_params(param); - current->flags &= ~PF_MEMALLOC; return r; } From 12f03a49cf0ab5e8511911142d28699499a572c4 Mon Sep 17 00:00:00 2001 From: Kevin Corry Date: Wed, 1 Feb 2006 03:04:52 -0800 Subject: [PATCH 330/695] [PATCH] device-mapper statistics: basic Record basic I/O statistics for mapped devices. Signed-off-by: Kevin Corry Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 8c16359f8b01..c47518386c91 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -573,10 +573,14 @@ static void __split_bio(struct mapped_device *md, struct bio *bio) static int dm_request(request_queue_t *q, struct bio *bio) { int r; + int rw = bio_data_dir(bio); struct mapped_device *md = q->queuedata; down_read(&md->io_lock); + disk_stat_inc(dm_disk(md), ios[rw]); + disk_stat_add(dm_disk(md), sectors[rw], bio_sectors(bio)); + /* * If we're suspended we have to queue * this io for later. From 3eaf840e0b0046f56602c524c7ba58a82f5526c5 Mon Sep 17 00:00:00 2001 From: "Jun'ichi \"Nick\" Nomura" Date: Wed, 1 Feb 2006 03:04:53 -0800 Subject: [PATCH 331/695] [PATCH] device-mapper disk statistics: timing Record I/O timing statistics The start time is added to struct dm_io, an existing structure allocated privately internally within dm and attached to each incoming bio. We export disk_round_stats() from block/ll_rw_blk.c instead of creating a private clone. Signed-off-by: Jun'ichi "Nick" Nomura Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- block/ll_rw_blk.c | 2 ++ drivers/md/dm.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index d38b4afa37ef..f9fc07efd2da 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -2579,6 +2579,8 @@ void disk_round_stats(struct gendisk *disk) disk->stamp = now; } +EXPORT_SYMBOL_GPL(disk_round_stats); + /* * queue lock must be held */ diff --git a/drivers/md/dm.c b/drivers/md/dm.c index c47518386c91..e9adeb9d172f 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -31,6 +31,7 @@ struct dm_io { int error; struct bio *bio; atomic_t io_count; + unsigned long start_time; }; /* @@ -244,6 +245,36 @@ static inline void free_tio(struct mapped_device *md, struct target_io *tio) mempool_free(tio, md->tio_pool); } +static void start_io_acct(struct dm_io *io) +{ + struct mapped_device *md = io->md; + + io->start_time = jiffies; + + preempt_disable(); + disk_round_stats(dm_disk(md)); + preempt_enable(); + dm_disk(md)->in_flight = atomic_inc_return(&md->pending); +} + +static int end_io_acct(struct dm_io *io) +{ + struct mapped_device *md = io->md; + struct bio *bio = io->bio; + unsigned long duration = jiffies - io->start_time; + int pending; + int rw = bio_data_dir(bio); + + preempt_disable(); + disk_round_stats(dm_disk(md)); + preempt_enable(); + dm_disk(md)->in_flight = pending = atomic_dec_return(&md->pending); + + disk_stat_add(dm_disk(md), ticks[rw], duration); + + return !pending; +} + /* * Add the bio to the list of deferred io. */ @@ -299,7 +330,7 @@ static void dec_pending(struct dm_io *io, int error) io->error = error; if (atomic_dec_and_test(&io->io_count)) { - if (atomic_dec_and_test(&io->md->pending)) + if (end_io_acct(io)) /* nudge anyone waiting on suspend queue */ wake_up(&io->md->wait); @@ -554,7 +585,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio) ci.sector_count = bio_sectors(bio); ci.idx = bio->bi_idx; - atomic_inc(&md->pending); + start_io_acct(ci.io); while (ci.sector_count) __clone_and_map(&ci); From 4aac0a63fe8d418a2b74e43708f59380ba379a3b Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Wed, 1 Feb 2006 03:04:55 -0800 Subject: [PATCH 332/695] [PATCH] device-mapper snapshot: barriers not supported The snapshot and origin targets are incapable of handling barriers and need to indicate this. Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-snap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index ad9b61f16c5e..f3759dd7828e 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -792,6 +792,9 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, if (!s->valid) return -EIO; + if (unlikely(bio_barrier(bio))) + return -EOPNOTSUPP; + /* * Write to snapshot - higher level takes care of RW/RO * flags so we should only get this if we are @@ -1058,6 +1061,9 @@ static int origin_map(struct dm_target *ti, struct bio *bio, struct dm_dev *dev = (struct dm_dev *) ti->private; bio->bi_bdev = dev->bdev; + if (unlikely(bio_barrier(bio))) + return -EOPNOTSUPP; + /* Only tell snapshots if this is a write */ return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : 1; } From 3ee247ebce93a526f482d6bc714ce796fa85a81a Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Wed, 1 Feb 2006 03:04:55 -0800 Subject: [PATCH 333/695] [PATCH] dm: dm-table warning fix drivers/md/dm-table.c:500: warning: comparison of distinct pointer types lacks a cast Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-table.c | 2 +- include/linux/device-mapper.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index a6f2dc66c3db..9b1e2f5ca630 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -508,7 +508,7 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start, if (q->merge_bvec_fn) rs->max_sectors = min_not_zero(rs->max_sectors, - (unsigned short)(PAGE_SIZE >> 9)); + (unsigned int) (PAGE_SIZE >> 9)); rs->max_phys_segments = min_not_zero(rs->max_phys_segments, diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 83c7d207b80e..51e0e95a421a 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -91,7 +91,7 @@ struct target_type { }; struct io_restrictions { - unsigned short max_sectors; + unsigned int max_sectors; unsigned short max_phys_segments; unsigned short max_hw_segments; unsigned short hardsect_size; From ce5f8d70ba6e3d7ffcaff86b2cf91a42c27f77af Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 1 Feb 2006 03:04:56 -0800 Subject: [PATCH 334/695] [PATCH] alpha: dma-mapping.h: add "struct scatterlist;" On alpha-jensen: CC drivers/base/platform.o In file included from include/linux/dma-mapping.h:24, from drivers/base/platform.c:16: include/asm/dma-mapping.h:36: warning: "struct scatterlist" declared inside parameter list include/asm/dma-mapping.h:36: warning: its scope is only this definition or declaration, which is probably not what you want Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-alpha/dma-mapping.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h index 9dc7256cf979..62d0d6681aa9 100644 --- a/include/asm-alpha/dma-mapping.h +++ b/include/asm-alpha/dma-mapping.h @@ -30,6 +30,7 @@ #else /* no PCI - no IOMMU. */ +struct scatterlist; void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp); int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, From 386093ef9a6c88576d8b418bf1c8616d5e410a20 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 1 Feb 2006 03:04:57 -0800 Subject: [PATCH 335/695] [PATCH] ipw2200: fix ->eeprom[EEPROM_VERSION] check priv->eeprom is a pointer. Signed-off-by: Alexey Dobriyan Acked-by: Yi Zhu Cc: James Ketrenos Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/wireless/ipw2200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 916b24c544e2..14beab4bc91c 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -2456,7 +2456,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv) copy. Otherwise let the firmware know to perform the operation on it's own */ - if ((priv->eeprom + EEPROM_VERSION) != 0) { + if (priv->eeprom[EEPROM_VERSION] != 0) { IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); /* write the eeprom data to sram */ From 94f91def998efe3b79780f3b39b6c87d390dbe4c Mon Sep 17 00:00:00 2001 From: Rocky Craig Date: Wed, 1 Feb 2006 03:04:58 -0800 Subject: [PATCH 336/695] [PATCH] IPMI: remove invalid acpi register spacing check At the 2.6.12 timeframe ipmi_si_intf.c was patched to provide default register spacings in try_init_acpi() if the register spacing was set to zero, similar to code in other routines. Unfortunately, another patch was simultaneously added that exits early from try_init_acpi() if the register spacings are set to zero, circumventing the new defaults. This patch removes the early exit code and some incorrect comments that aren't present in other common code snippets. Signed-off-by: Rocky Craig Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index c67ef3e47ad5..6ed213bd702c 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1580,11 +1580,6 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info) if (! is_new_interface(-1, addr_space, spmi->addr.address)) return -ENODEV; - if (! spmi->addr.register_bit_width) { - acpi_failure = 1; - return -ENODEV; - } - /* Figure out the interface type. */ switch (spmi->InterfaceType) { @@ -1634,9 +1629,6 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info) regspacings[intf_num] = spmi->addr.register_bit_width / 8; info->io.regspacing = spmi->addr.register_bit_width / 8; } else { - /* Some broken systems get this wrong and set the value - * to zero. Assume it is the default spacing. If that - * is wrong, too bad, the vendor should fix the tables. */ regspacings[intf_num] = DEFAULT_REGSPACING; info->io.regspacing = DEFAULT_REGSPACING; } From 7ee26aa04d4dbd5e006b2f184d6028c71384681f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 1 Feb 2006 03:04:59 -0800 Subject: [PATCH 337/695] [PATCH] tpm_infineon: fix printk format warning drivers/char/tpm/tpm_infineon.c:443: warning: format '%04x' expects type 'unsigned int', but argument 4 has type 'long unsigned int' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_infineon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 8198dbb7370f..ec7590951af5 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -441,7 +441,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, if ((ioh << 8 | iol) != tpm_inf.base) { dev_err(&dev->dev, - "Could not set IO-ports to %04x\n", + "Could not set IO-ports to 0x%lx\n", tpm_inf.base); release_region(tpm_inf.base, TPM_INF_PORT_LEN); return -EIO; From ed5a92700d3ce2646cb7763792a5f7ad1bade7e8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 1 Feb 2006 03:05:00 -0800 Subject: [PATCH 338/695] [PATCH] tpm_bios: needs more securityfs_ functions tpm_bios.c needs securityfs_xyz() functions. Does include/linux/security.h need stubs for these, or should char/tpm/Makefile just be modified to say: ifdef CONFIG_ACPI ifdef CONFIG_SECURITY obj-$(CONFIG_TCG_TPM) += tpm_bios.o endif endif drivers/char/tpm/tpm_bios.c:494: warning: implicit declaration of function 'securityfs_create_dir' drivers/char/tpm/tpm_bios.c:494: warning: assignment makes pointer from integer without a cast drivers/char/tpm/tpm_bios.c:499: warning: implicit declaration of function 'securityfs_create_file' drivers/char/tpm/tpm_bios.c:501: warning: assignment makes pointer from integer without a cast drivers/char/tpm/tpm_bios.c:508: warning: assignment makes pointer from integer without a cast drivers/char/tpm/tpm_bios.c:523: warning: implicit declaration of function 'securityfs_remove' *** Warning: "securityfs_create_file" [drivers/char/tpm/tpm_bios.ko] undefined! *** Warning: "securityfs_create_dir" [drivers/char/tpm/tpm_bios.ko] undefined! *** Warning: "securityfs_remove" [drivers/char/tpm/tpm_bios.ko] undefined! There are also some gcc and sparse warnings that could be fixed. (see http://www.xenotime.net/linux/doc/build-tpm.out) Signed-off-by: Randy Dunlap Cc: Serge Hallyn Cc: Greg KH Cc: Kylene Jo Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/security.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/linux/security.h b/include/linux/security.h index ef753654daa5..bb1da86747c7 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -2617,6 +2617,25 @@ static inline int security_netlink_recv (struct sk_buff *skb) return cap_netlink_recv (skb); } +static inline struct dentry *securityfs_create_dir(const char *name, + struct dentry *parent) +{ + return ERR_PTR(-ENODEV); +} + +static inline struct dentry *securityfs_create_file(const char *name, + mode_t mode, + struct dentry *parent, + void *data, + struct file_operations *fops) +{ + return ERR_PTR(-ENODEV); +} + +static inline void securityfs_remove(struct dentry *dentry) +{ +} + #endif /* CONFIG_SECURITY */ #ifdef CONFIG_SECURITY_NETWORK From ca4a031f6b43edb8745ebc0a1b7307c24719dae4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 1 Feb 2006 03:05:01 -0800 Subject: [PATCH 339/695] [PATCH] tpm_bios: securityfs error checking fix These functions return ERR_PTR()s on error, not NULL. Spotted by Randy. Cc: Serge Hallyn Cc: Kylene Jo Hall Cc: "Randy.Dunlap" Acked-by: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_bios.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index aedf7a8e6da7..9ffa5643e79d 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -487,26 +487,35 @@ struct file_operations tpm_binary_bios_measurements_ops = { .release = tpm_bios_measurements_release, }; +static int is_bad(void *p) +{ + if (!p) + return 1; + if (IS_ERR(p) && (PTR_ERR(p) != -ENODEV)) + return 1; + return 0; +} + struct dentry **tpm_bios_log_setup(char *name) { struct dentry **ret = NULL, *tpm_dir, *bin_file, *ascii_file; tpm_dir = securityfs_create_dir(name, NULL); - if (!tpm_dir) + if (is_bad(tpm_dir)) goto out; bin_file = securityfs_create_file("binary_bios_measurements", S_IRUSR | S_IRGRP, tpm_dir, NULL, &tpm_binary_bios_measurements_ops); - if (!bin_file) + if (is_bad(bin_file)) goto out_tpm; ascii_file = securityfs_create_file("ascii_bios_measurements", S_IRUSR | S_IRGRP, tpm_dir, NULL, &tpm_ascii_bios_measurements_ops); - if (!ascii_file) + if (is_bad(ascii_file)) goto out_bin; ret = kmalloc(3 * sizeof(struct dentry *), GFP_KERNEL); From 1c40f7d4f0a9d5242f19b02b00e3e5a8ee218a20 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 1 Feb 2006 03:05:02 -0800 Subject: [PATCH 340/695] [PATCH] tpm_bios indexing fix It generates warnings: drivers/char/tpm/tpm_bios.c: In function `get_event_name': drivers/char/tpm/tpm_bios.c:223: warning: cast from pointer to integer of different size drivers/char/tpm/tpm_bios.c:223: warning: cast from pointer to integer of different size drivers/char/tpm/tpm_bios.c:223: warning: cast from pointer to integer of different size drivers/char/tpm/tpm_bios.c:224: warning: cast from pointer to integer of different size drivers/char/tpm/tpm_bios.c:224: warning: cast from pointer to integer of different size drivers/char/tpm/tpm_bios.c:224: warning: cast from pointer to integer of different size and I'm not sure what the code is doing there, but it seems wrong. We're using the address of the buffer rather than the contents of it. The patch adds more nasty typecasting, but I think the whole arrangement could be done in a more typesafe manner. Cc: Kylene Jo Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_bios.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 9ffa5643e79d..1310189fd9f5 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -220,8 +220,8 @@ static int get_event_name(char *dest, struct tcpa_event *event, } break; case EVENT_TAG: - event_id = be32_to_cpu(event_entry); - event_data_size = be32_to_cpu(&event_entry[4]); + event_id = be32_to_cpu(*((u32 *)event_entry)); + event_data_size = be32_to_cpu(((u32 *)event_entry)[1]); /* ToDo Row data -> Base64 */ From 7bcee5b86a8d9f8a0f2c1848fd9abd675e09e969 Mon Sep 17 00:00:00 2001 From: Kylene Jo Hall Date: Wed, 1 Feb 2006 03:05:03 -0800 Subject: [PATCH 341/695] [PATCH] tpm: tpm-bios: fix module license issue Attempting to insert the tpm modules fails because the tpm_bios file is missing a license statement. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_bios.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 1310189fd9f5..22b645b93e02 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -547,3 +547,4 @@ void tpm_bios_log_teardown(struct dentry **lst) securityfs_remove(lst[i]); } EXPORT_SYMBOL_GPL(tpm_bios_log_teardown); +MODULE_LICENSE("GPL"); From 10296cb0b2b0b0eb312f81032216504a64ee675a Mon Sep 17 00:00:00 2001 From: Kylene Jo Hall Date: Wed, 1 Feb 2006 03:05:04 -0800 Subject: [PATCH 342/695] [PATCH] tpm: tpm_bios fix sparse warnings Fixing the sparse warnings on the acpi_os_map_memory calls pointed out by Randy. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_bios.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 22b645b93e02..047f213a480f 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -376,7 +376,7 @@ static int read_log(struct tpm_bios_log *log) { struct acpi_tcpa *buff; acpi_status status; - void *virt; + struct acpi_table_header *virt; if (log->bios_event_log != NULL) { printk(KERN_ERR @@ -413,7 +413,7 @@ static int read_log(struct tpm_bios_log *log) log->bios_event_log_end = log->bios_event_log + buff->log_max_len; - acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt); + acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt); memcpy(log->bios_event_log, virt, buff->log_max_len); From 295b117ef334bcc3c9596117cb0aa640054e35fc Mon Sep 17 00:00:00 2001 From: Kylene Jo Hall Date: Wed, 1 Feb 2006 03:05:04 -0800 Subject: [PATCH 343/695] [PATCH] tpm: tpm_bios remove unused variable Remove event_data_size since it was pointed out in tpm_bios-indexing- fix.patch that is was ugly and it wasn't actually being used. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_bios.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 047f213a480f..537aa45d8c67 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -191,7 +191,7 @@ static int get_event_name(char *dest, struct tcpa_event *event, const char *name = ""; char data[40] = ""; int i, n_len = 0, d_len = 0; - u32 event_id, event_data_size; + u32 event_id; switch(event->event_type) { case PREBOOT: @@ -221,7 +221,6 @@ static int get_event_name(char *dest, struct tcpa_event *event, break; case EVENT_TAG: event_id = be32_to_cpu(*((u32 *)event_entry)); - event_data_size = be32_to_cpu(((u32 *)event_entry)[1]); /* ToDo Row data -> Base64 */ From 1d0098b6e2055e4afb2ceadf11c4b9f43b671ccc Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 1 Feb 2006 03:05:05 -0800 Subject: [PATCH 344/695] [PATCH] mips: gdb-stub.c: fix parse error before ; token Signed-off-by: Alexey Dobriyan Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/gdb-stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c index 96d18c43dca0..d4f88e0af24c 100644 --- a/arch/mips/kernel/gdb-stub.c +++ b/arch/mips/kernel/gdb-stub.c @@ -178,7 +178,7 @@ int kgdb_enabled; */ static DEFINE_SPINLOCK(kgdb_lock); static raw_spinlock_t kgdb_cpulock[NR_CPUS] = { - [0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED; + [0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED, }; /* From e8730eabd45e47e392f230ab8720c4b8537901fc Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 1 Feb 2006 03:05:06 -0800 Subject: [PATCH 345/695] [PATCH] uml: compilation fix when MODE_SKAS disabled CC arch/um/sys-i386/ldt.o arch/um/sys-i386/ldt.c:19:21: proc_mm.h: No such file or directory make[1]: *** [arch/um/sys-i386/ldt.o] Error 1 Signed-off-by: Pekka Enberg Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/ldt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index 0cdfd4481d5e..1fa09a79a10b 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -16,7 +16,6 @@ #include "choose-mode.h" #include "kern.h" #include "mode_kern.h" -#include "proc_mm.h" #include "os.h" extern int modify_ldt(int func, void *ptr, unsigned long bytecount); @@ -90,6 +89,7 @@ out: #include "skas.h" #include "skas_ptrace.h" #include "asm/mmu_context.h" +#include "proc_mm.h" long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, void **addr, int done) From 853609b61ef88b414ffd1613741aa59894334320 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 1 Feb 2006 03:05:07 -0800 Subject: [PATCH 346/695] [PATCH] swsusp: use bytes as image size units Make swsusp use bytes as the image size units, which is needed for future compatibility. Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/power/interface.txt | 2 +- Documentation/power/swsusp.txt | 2 +- kernel/power/disk.c | 6 +++--- kernel/power/power.h | 4 ++-- kernel/power/swsusp.c | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt index bd4ffb5bd49a..4117802af0f8 100644 --- a/Documentation/power/interface.txt +++ b/Documentation/power/interface.txt @@ -44,7 +44,7 @@ it. /sys/power/image_size controls the size of the image created by the suspend-to-disk mechanism. It can be written a string representing a non-negative integer that will be used as an upper -limit of the image size, in megabytes. The suspend-to-disk mechanism will +limit of the image size, in bytes. The suspend-to-disk mechanism will do its best to ensure the image size will not exceed that number. However, if this turns out to be impossible, it will try to suspend anyway using the smallest image possible. In particular, if "0" is written to this file, the diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt index 08c79d4dc540..b28b7f04abb8 100644 --- a/Documentation/power/swsusp.txt +++ b/Documentation/power/swsusp.txt @@ -27,7 +27,7 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state echo platform > /sys/power/disk; echo disk > /sys/power/state -If you want to limit the suspend image size to N megabytes, do +If you want to limit the suspend image size to N bytes, do echo N > /sys/power/image_size diff --git a/kernel/power/disk.c b/kernel/power/disk.c index e24446f8d8cd..f2b3b0ea512a 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -367,14 +367,14 @@ power_attr(resume); static ssize_t image_size_show(struct subsystem * subsys, char *buf) { - return sprintf(buf, "%u\n", image_size); + return sprintf(buf, "%lu\n", image_size); } static ssize_t image_size_store(struct subsystem * subsys, const char * buf, size_t n) { - unsigned int size; + unsigned long size; - if (sscanf(buf, "%u", &size) == 1) { + if (sscanf(buf, "%lu", &size) == 1) { image_size = size; return n; } diff --git a/kernel/power/power.h b/kernel/power/power.h index 7e8492fd1423..61beb5e0e927 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -51,8 +51,8 @@ extern const void __nosave_begin, __nosave_end; extern unsigned int nr_copy_pages; extern struct pbe *pagedir_nosave; -/* Preferred image size in MB (default 500) */ -extern unsigned int image_size; +/* Preferred image size in bytes (default 500 MB) */ +extern unsigned long image_size; extern asmlinkage int swsusp_arch_suspend(void); extern asmlinkage int swsusp_arch_resume(void); diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 55a18d26abed..59c91c148e82 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c @@ -70,12 +70,12 @@ #include "power.h" /* - * Preferred image size in MB (tunable via /sys/power/image_size). + * Preferred image size in bytes (tunable via /sys/power/image_size). * When it is set to N, swsusp will do its best to ensure the image - * size will not exceed N MB, but if that is impossible, it will + * size will not exceed N bytes, but if that is impossible, it will * try to create the smallest image possible. */ -unsigned int image_size = 500; +unsigned long image_size = 500 * 1024 * 1024; #ifdef CONFIG_HIGHMEM unsigned int count_highmem_pages(void); @@ -590,7 +590,7 @@ int swsusp_shrink_memory(void) if (!tmp) return -ENOMEM; pages += tmp; - } else if (size > (image_size * 1024 * 1024) / PAGE_SIZE) { + } else if (size > image_size / PAGE_SIZE) { tmp = shrink_all_memory(SHRINK_BITE); pages += tmp; } From bc1978d404befacd272d0321ef749cc3192e488b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 1 Feb 2006 03:05:08 -0800 Subject: [PATCH 347/695] [PATCH] hrtimers: fixup itimer conversion The itimer conversion removed the locking which protects the timer and variables in the shared signal structure. Steven Rostedt found the problem in the latest -rt patches. Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/itimer.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/kernel/itimer.c b/kernel/itimer.c index c2c05c4ff28d..6433d0685506 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -49,9 +49,11 @@ int do_getitimer(int which, struct itimerval *value) switch (which) { case ITIMER_REAL: + spin_lock_irq(&tsk->sighand->siglock); value->it_value = itimer_get_remtime(&tsk->signal->real_timer); value->it_interval = ktime_to_timeval(tsk->signal->it_real_incr); + spin_unlock_irq(&tsk->sighand->siglock); break; case ITIMER_VIRTUAL: read_lock(&tasklist_lock); @@ -150,8 +152,14 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) switch (which) { case ITIMER_REAL: +again: + spin_lock_irq(&tsk->sighand->siglock); timer = &tsk->signal->real_timer; - hrtimer_cancel(timer); + /* We are sharing ->siglock with it_real_fn() */ + if (hrtimer_try_to_cancel(timer) < 0) { + spin_unlock_irq(&tsk->sighand->siglock); + goto again; + } if (ovalue) { ovalue->it_value = itimer_get_remtime(timer); ovalue->it_interval @@ -162,6 +170,7 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) expires = timeval_to_ktime(value->it_value); if (expires.tv64 != 0) hrtimer_start(timer, expires, HRTIMER_REL); + spin_unlock_irq(&tsk->sighand->siglock); break; case ITIMER_VIRTUAL: nval = timeval_to_cputime(&value->it_value); From b6557fbca805217588a412f391a65ceafcf1a1af Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 1 Feb 2006 03:05:09 -0800 Subject: [PATCH 348/695] [PATCH] hrtimers: fix possible use of NULL pointer in posix-timers Fixup the conversion of posix-timers to hrtimers. Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/posix-timers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 197208b3aa2a..3b606d361b52 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -290,7 +290,8 @@ void do_schedule_next_timer(struct siginfo *info) info->si_overrun = timr->it_overrun_last; } - unlock_timer(timr, flags); + if (timr) + unlock_timer(timr, flags); } int posix_timer_event(struct k_itimer *timr,int si_private) From a16a1c095a2392d49fafea22f3a508e268ef7167 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 1 Feb 2006 03:05:09 -0800 Subject: [PATCH 349/695] [PATCH] hrtimers: fix oldvalue return in setitimer This resolves bugzilla bug#5617. The oldvalue of the timer was read after the timer was cancelled, so the remaining time was always zero. Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/itimer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/itimer.c b/kernel/itimer.c index 6433d0685506..379be2f8c84c 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -155,16 +155,16 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) again: spin_lock_irq(&tsk->sighand->siglock); timer = &tsk->signal->real_timer; - /* We are sharing ->siglock with it_real_fn() */ - if (hrtimer_try_to_cancel(timer) < 0) { - spin_unlock_irq(&tsk->sighand->siglock); - goto again; - } if (ovalue) { ovalue->it_value = itimer_get_remtime(timer); ovalue->it_interval = ktime_to_timeval(tsk->signal->it_real_incr); } + /* We are sharing ->siglock with it_real_fn() */ + if (hrtimer_try_to_cancel(timer) < 0) { + spin_unlock_irq(&tsk->sighand->siglock); + goto again; + } tsk->signal->it_real_incr = timeval_to_ktime(value->it_interval); expires = timeval_to_ktime(value->it_value); From ff60a5dc4fa584d47022d2533bc5c53b80096fb5 Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Wed, 1 Feb 2006 03:05:10 -0800 Subject: [PATCH 350/695] [PATCH] hrtimers: fix posix-timer requeue race From: Steven Rostedtrostedt@goodmis.org CPU0 expires a posix-timer and runs the callback function. The signal is queued. After releasing the posix-timer lock and before returning to hrtimer_run_queue CPU0 gets interrupted. CPU1 delivers the queued signal and rearms the timer. CPU0 comes back to hrtimer_run_queue and sets the timer state to expired. The next modification of the timer can result in an oops, because the state information is wrong. Keep track of state = RUNNING and check if the state has been in the return path of hrtimer_run_queue. In case the state has been changed, ignore a restart request and do not touch the state variable. Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/hrtimer.h | 1 + kernel/hrtimer.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 089bfb1fa01a..c657f3d4924a 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -40,6 +40,7 @@ enum hrtimer_restart { enum hrtimer_state { HRTIMER_INACTIVE, /* Timer is inactive */ HRTIMER_EXPIRED, /* Timer is expired */ + HRTIMER_RUNNING, /* Timer is running the callback function */ HRTIMER_PENDING, /* Timer is pending */ }; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index f1c4155b49ac..f580dd9db286 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -550,6 +550,7 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base) fn = timer->function; data = timer->data; set_curr_timer(base, timer); + timer->state = HRTIMER_RUNNING; __remove_hrtimer(timer, base); spin_unlock_irq(&base->lock); @@ -565,6 +566,10 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base) spin_lock_irq(&base->lock); + /* Another CPU has added back the timer */ + if (timer->state != HRTIMER_RUNNING) + continue; + if (restart == HRTIMER_RESTART) enqueue_hrtimer(timer, base); else From 7978672c4d9a1e6a6081de3a9d9ba5e5b24904a0 Mon Sep 17 00:00:00 2001 From: George Anzinger Date: Wed, 1 Feb 2006 03:05:11 -0800 Subject: [PATCH 351/695] [PATCH] hrtimers: cleanups and simplifications Clean up the interface to hrtimers by changing the init code to pass the mode as well as the clock. This allow the init code to select the correct base and eliminates extra timer re-init code in posix-timers. We also simplify the restart interface nanosleep use. Signed-off-by: George Anzinger Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/hrtimer.h | 5 ++-- kernel/fork.c | 2 +- kernel/hrtimer.c | 61 +++++++++++++++++------------------------ kernel/posix-timers.c | 37 ++++++------------------- 4 files changed, 37 insertions(+), 68 deletions(-) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index c657f3d4924a..6361544bb6ae 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -101,9 +101,8 @@ struct hrtimer_base { /* Exported timer functions: */ /* Initialize timers: */ -extern void hrtimer_init(struct hrtimer *timer, const clockid_t which_clock); -extern void hrtimer_rebase(struct hrtimer *timer, const clockid_t which_clock); - +extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, + enum hrtimer_mode mode); /* Basic timer operations: */ extern int hrtimer_start(struct hrtimer *timer, ktime_t tim, diff --git a/kernel/fork.c b/kernel/fork.c index 4ae8cfc1c89c..7f0ab5ee948c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -802,7 +802,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts init_sigpending(&sig->shared_pending); INIT_LIST_HEAD(&sig->posix_timers); - hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC); + hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_REL); sig->it_real_incr.tv64 = 0; sig->real_timer.function = it_real_fn; sig->real_timer.data = tsk; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index f580dd9db286..efff9496b2fa 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -66,6 +66,12 @@ EXPORT_SYMBOL_GPL(ktime_get_real); /* * The timer bases: + * + * Note: If we want to add new timer bases, we have to skip the two + * clock ids captured by the cpu-timers. We do this by holding empty + * entries rather than doing math adjustment of the clock ids. + * This ensures that we capture erroneous accesses to these clock ids + * rather than moving them into the range of valid clock id's. */ #define MAX_HRTIMER_BASES 2 @@ -482,30 +488,26 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer) return rem; } -/** - * hrtimer_rebase - rebase an initialized hrtimer to a different base - * - * @timer: the timer to be rebased - * @clock_id: the clock to be used - */ -void hrtimer_rebase(struct hrtimer *timer, const clockid_t clock_id) -{ - struct hrtimer_base *bases; - - bases = per_cpu(hrtimer_bases, raw_smp_processor_id()); - timer->base = &bases[clock_id]; -} - /** * hrtimer_init - initialize a timer to the given clock * * @timer: the timer to be initialized * @clock_id: the clock to be used + * @mode: timer mode abs/rel */ -void hrtimer_init(struct hrtimer *timer, const clockid_t clock_id) +void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, + enum hrtimer_mode mode) { + struct hrtimer_base *bases; + memset(timer, 0, sizeof(struct hrtimer)); - hrtimer_rebase(timer, clock_id); + + bases = per_cpu(hrtimer_bases, raw_smp_processor_id()); + + if (clock_id == CLOCK_REALTIME && mode != HRTIMER_ABS) + clock_id = CLOCK_MONOTONIC; + + timer->base = &bases[clock_id]; } /** @@ -643,8 +645,7 @@ schedule_hrtimer_interruptible(struct hrtimer *timer, return schedule_hrtimer(timer, mode); } -static long __sched -nanosleep_restart(struct restart_block *restart, clockid_t clockid) +static long __sched nanosleep_restart(struct restart_block *restart) { struct timespec __user *rmtp; struct timespec tu; @@ -654,7 +655,7 @@ nanosleep_restart(struct restart_block *restart, clockid_t clockid) restart->fn = do_no_restart_syscall; - hrtimer_init(&timer, clockid); + hrtimer_init(&timer, (clockid_t) restart->arg3, HRTIMER_ABS); timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0; @@ -674,16 +675,6 @@ nanosleep_restart(struct restart_block *restart, clockid_t clockid) return -ERESTART_RESTARTBLOCK; } -static long __sched nanosleep_restart_mono(struct restart_block *restart) -{ - return nanosleep_restart(restart, CLOCK_MONOTONIC); -} - -static long __sched nanosleep_restart_real(struct restart_block *restart) -{ - return nanosleep_restart(restart, CLOCK_REALTIME); -} - long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, const enum hrtimer_mode mode, const clockid_t clockid) { @@ -692,7 +683,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, struct timespec tu; ktime_t rem; - hrtimer_init(&timer, clockid); + hrtimer_init(&timer, clockid, mode); timer.expires = timespec_to_ktime(*rqtp); @@ -700,7 +691,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, if (rem.tv64 <= 0) return 0; - /* Absolute timers do not update the rmtp value: */ + /* Absolute timers do not update the rmtp value and restart: */ if (mode == HRTIMER_ABS) return -ERESTARTNOHAND; @@ -710,11 +701,11 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, return -EFAULT; restart = ¤t_thread_info()->restart_block; - restart->fn = (clockid == CLOCK_MONOTONIC) ? - nanosleep_restart_mono : nanosleep_restart_real; + restart->fn = nanosleep_restart; restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF; restart->arg1 = timer.expires.tv64 >> 32; restart->arg2 = (unsigned long) rmtp; + restart->arg3 = (unsigned long) timer.base->index; return -ERESTART_RESTARTBLOCK; } @@ -741,10 +732,8 @@ static void __devinit init_hrtimers_cpu(int cpu) struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu); int i; - for (i = 0; i < MAX_HRTIMER_BASES; i++) { + for (i = 0; i < MAX_HRTIMER_BASES; i++, base++) spin_lock_init(&base->lock); - base++; - } } #ifdef CONFIG_HOTPLUG_CPU diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 3b606d361b52..28e72fd0029f 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -194,9 +194,7 @@ static inline int common_clock_set(const clockid_t which_clock, static int common_timer_create(struct k_itimer *new_timer) { - hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock); - new_timer->it.real.timer.data = new_timer; - new_timer->it.real.timer.function = posix_timer_fn; + hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0); return 0; } @@ -693,6 +691,7 @@ common_timer_set(struct k_itimer *timr, int flags, struct itimerspec *new_setting, struct itimerspec *old_setting) { struct hrtimer *timer = &timr->it.real.timer; + enum hrtimer_mode mode; if (old_setting) common_timer_get(timr, old_setting); @@ -714,14 +713,10 @@ common_timer_set(struct k_itimer *timr, int flags, if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec) return 0; - /* Posix madness. Only absolute CLOCK_REALTIME timers - * are affected by clock sets. So we must reiniatilize - * the timer. - */ - if (timr->it_clock == CLOCK_REALTIME && (flags & TIMER_ABSTIME)) - hrtimer_rebase(timer, CLOCK_REALTIME); - else - hrtimer_rebase(timer, CLOCK_MONOTONIC); + mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL; + hrtimer_init(&timr->it.real.timer, timr->it_clock, mode); + timr->it.real.timer.data = timr; + timr->it.real.timer.function = posix_timer_fn; timer->expires = timespec_to_ktime(new_setting->it_value); @@ -732,8 +727,7 @@ common_timer_set(struct k_itimer *timr, int flags, if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) return 0; - hrtimer_start(timer, timer->expires, (flags & TIMER_ABSTIME) ? - HRTIMER_ABS : HRTIMER_REL); + hrtimer_start(timer, timer->expires, mode); return 0; } @@ -948,21 +942,8 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp) static int common_nsleep(const clockid_t which_clock, int flags, struct timespec *tsave, struct timespec __user *rmtp) { - int mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL; - int clockid = which_clock; - - switch (which_clock) { - case CLOCK_REALTIME: - /* Posix madness. Only absolute timers on clock realtime - are affected by clock set. */ - if (mode != HRTIMER_ABS) - clockid = CLOCK_MONOTONIC; - case CLOCK_MONOTONIC: - break; - default: - return -EINVAL; - } - return hrtimer_nanosleep(tsave, rmtp, mode, clockid); + return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ? + HRTIMER_ABS : HRTIMER_REL, which_clock); } asmlinkage long From 66188fae3bf7f8dd951e2291d2a81888ed1b65de Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 1 Feb 2006 03:05:13 -0800 Subject: [PATCH 352/695] [PATCH] hrtimers: add back lost credit lines At some point we added credits to people who actively helped to bring k/hr-timers along. This was lost in the big code revamp. Add it back. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ktime.h | 6 ++++++ kernel/hrtimer.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 1bd6552cc341..6aca67a569a2 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -10,6 +10,12 @@ * * Started by: Thomas Gleixner and Ingo Molnar * + * Credits: + * + * Roman Zippel provided the ideas and primary code snippets of + * the ktime_t union and further simplifications of the original + * code. + * * For licencing details see kernel-base/COPYING */ #ifndef _LINUX_KTIME_H diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index efff9496b2fa..2b6e1757aedd 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -21,6 +21,12 @@ * Credits: * based on kernel/timer.c * + * Help, testing, suggestions, bugfixes, improvements were + * provided by: + * + * George Anzinger, Andrew Morton, Steven Rostedt, Roman Zippel + * et. al. + * * For licencing details see kernel-base/COPYING */ From 952bbc87f01f552ef091a62ea2a721b5b2670e74 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 1 Feb 2006 03:05:13 -0800 Subject: [PATCH 353/695] [PATCH] hrtimers: set correct initial expiry time for relative SIGEV_NONE timers The expiry time for relative timers with SIGEV_NONE set was never updated to the correct value. Pointed out by George Anzinger. Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/posix-timers.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 28e72fd0029f..aad6f138d5c9 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -724,8 +724,13 @@ common_timer_set(struct k_itimer *timr, int flags, timr->it.real.interval = timespec_to_ktime(new_setting->it_interval); /* SIGEV_NONE timers are not queued ! See common_timer_get */ - if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) + if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { + /* Setup correct expiry time for relative timers */ + if (mode == HRTIMER_REL) + timer->expires = ktime_add(timer->expires, + timer->base->get_time()); return 0; + } hrtimer_start(timer, timer->expires, mode); return 0; From 493f01d1d0699ddafc30067d33fcc18d0b95b624 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 1 Feb 2006 03:05:14 -0800 Subject: [PATCH 354/695] [PATCH] kernel/posix-timers.c: remove do_posix_clock_notimer_create() This function is neither used nor has any real contents. Signed-off-by: Adrian Bunk Acked-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/posix-timers.h | 1 - kernel/posix-timers.c | 6 ------ 2 files changed, 7 deletions(-) diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 54faf5236da0..95572c434bc9 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -84,7 +84,6 @@ struct k_clock { void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock); /* error handlers for timer_create, nanosleep and settime */ -int do_posix_clock_notimer_create(struct k_itimer *timer); int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *, struct timespec __user *); int do_posix_clock_nosettime(const clockid_t, struct timespec *tp); diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index aad6f138d5c9..216f574b5ffb 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -875,12 +875,6 @@ int do_posix_clock_nosettime(const clockid_t clockid, struct timespec *tp) } EXPORT_SYMBOL_GPL(do_posix_clock_nosettime); -int do_posix_clock_notimer_create(struct k_itimer *timer) -{ - return -EINVAL; -} -EXPORT_SYMBOL_GPL(do_posix_clock_notimer_create); - int do_posix_clock_nonanosleep(const clockid_t clock, int flags, struct timespec *t, struct timespec __user *r) { From f7589f28d7dd4586b4e90ac3b2a180409669053a Mon Sep 17 00:00:00 2001 From: Bryan O'Sullivan Date: Wed, 1 Feb 2006 03:05:15 -0800 Subject: [PATCH 355/695] [PATCH] Define BITS_PER_BYTE This can make the intent behind some arithmetic expressions clearer. Signed-off-by: Bryan O'Sullivan Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/types.h b/include/linux/types.h index 21b9ce803644..54ae2d59e71b 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -8,6 +8,8 @@ (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] + +#define BITS_PER_BYTE 8 #endif #include From c27a0d75b33c030965cc97d3d7f571107a673fb4 Mon Sep 17 00:00:00 2001 From: Bryan O'Sullivan Date: Wed, 1 Feb 2006 03:05:16 -0800 Subject: [PATCH 356/695] [PATCH] Introduce __iowrite32_copy This arch-independent routine copies data to a memory-mapped I/O region, using 32-bit accesses. The naming is double-underscored to make it clear that it does not guarantee write ordering, nor does it perform a memory barrier afterwards; the kernel doc also explicitly states this. This style of access is required by some devices. This change also introduces include/linux/io.h, at Andrew's suggestion. It only has one occupant at the moment, but is a logical destination for oft-replicated contents of include/asm-*/{io,iomap}.h to migrate to. Signed-off-by: Bryan O'Sullivan Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/io.h | 25 +++++++++++++++++++++++++ lib/Makefile | 2 +- lib/iomap_copy.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 include/linux/io.h create mode 100644 lib/iomap_copy.c diff --git a/include/linux/io.h b/include/linux/io.h new file mode 100644 index 000000000000..85533ec5aaa1 --- /dev/null +++ b/include/linux/io.h @@ -0,0 +1,25 @@ +/* + * Copyright 2006 PathScale, Inc. All Rights Reserved. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _LINUX_IO_H +#define _LINUX_IO_H + +#include + +void __iowrite32_copy(void __iomem *to, const void *from, size_t count); + +#endif /* _LINUX_IO_H */ diff --git a/lib/Makefile b/lib/Makefile index 8535f4d7d1c3..648b2c1242fd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,7 @@ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \ lib-y += kobject.o kref.o kobject_uevent.o klist.o -obj-y += sort.o parser.o halfmd4.o +obj-y += sort.o parser.o halfmd4.o iomap_copy.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c new file mode 100644 index 000000000000..a6b1e271d53c --- /dev/null +++ b/lib/iomap_copy.c @@ -0,0 +1,42 @@ +/* + * Copyright 2006 PathScale, Inc. All Rights Reserved. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +/** + * __iowrite32_copy - copy data to MMIO space, in 32-bit units + * @to: destination, in MMIO space (must be 32-bit aligned) + * @from: source (must be 32-bit aligned) + * @count: number of 32-bit quantities to copy + * + * Copy data from kernel space to MMIO space, in units of 32 bits at a + * time. Order of access is not guaranteed, nor is a memory barrier + * performed afterwards. + */ +void __attribute__((weak)) __iowrite32_copy(void __iomem *to, + const void *from, + size_t count) +{ + u32 __iomem *dst = to; + const u32 *src = from; + const u32 *end = src + count; + + while (src < end) + __raw_writel(*src++, dst++); +} +EXPORT_SYMBOL_GPL(__iowrite32_copy); From 0f07496144c270f10d0ad06b70b9c9387d5527fd Mon Sep 17 00:00:00 2001 From: Bryan O'Sullivan Date: Wed, 1 Feb 2006 03:05:17 -0800 Subject: [PATCH 357/695] [PATCH] Add faster __iowrite32_copy routine for x86_64 This assembly version is measurably faster than the generic version in lib/iomap_copy.c. Signed-off-by: Bryan O'Sullivan Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/lib/Makefile | 2 +- arch/x86_64/lib/iomap_copy.S | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 arch/x86_64/lib/iomap_copy.S diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile index bba5db6cebd6..ccef6ae747a3 100644 --- a/arch/x86_64/lib/Makefile +++ b/arch/x86_64/lib/Makefile @@ -4,7 +4,7 @@ CFLAGS_csum-partial.o := -funroll-loops -obj-y := io.o +obj-y := io.o iomap_copy.o lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ usercopy.o getuser.o putuser.o \ diff --git a/arch/x86_64/lib/iomap_copy.S b/arch/x86_64/lib/iomap_copy.S new file mode 100644 index 000000000000..8bbade5fea05 --- /dev/null +++ b/arch/x86_64/lib/iomap_copy.S @@ -0,0 +1,26 @@ +/* + * Copyright 2006 PathScale, Inc. All Rights Reserved. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * override generic version in lib/iomap_copy.c + */ + .globl __iowrite32_copy + .p2align 4 +__iowrite32_copy: + movl %edx,%ecx + rep movsd + ret From 2f7016d917faef8f1e016b4a7bd7f594694480b6 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Wed, 1 Feb 2006 03:05:18 -0800 Subject: [PATCH 358/695] [PATCH] sys_sched_getaffinity() & hotplug Change sched_getaffinity() so that it returns a bitmap that indicates the legally schedulable cpus that a task is allowed to run on. Without this patch, if CONFIG_HOTPLUG_CPU is enabled, sched_getaffinity() unconditionally returns (at least on IA64) a mask with NR_CPUS bits set. This conveys no useful infornmation except for a kernel compile option. This fixes a breakage we obseved running recent kernels. We have MPI jobs that use sched_getaffinity() to determine where to place their threads. Placing them on non-existant cpus is problematic :-) Signed-off-by: Jack Steiner Acked-by: Ingo Molnar Cc: Nathan Lynch Cc: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index ec7fd9cee306..f77f23f8f479 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4031,7 +4031,7 @@ long sched_getaffinity(pid_t pid, cpumask_t *mask) goto out_unlock; retval = 0; - cpus_and(*mask, p->cpus_allowed, cpu_possible_map); + cpus_and(*mask, p->cpus_allowed, cpu_online_map); out_unlock: read_unlock(&tasklist_lock); From bfaa1deeb982c985d8e0435e835baeaae63b57fd Mon Sep 17 00:00:00 2001 From: john stultz Date: Wed, 1 Feb 2006 03:05:19 -0800 Subject: [PATCH 359/695] [PATCH] disable lost tick compensation before TSCs are synced Avoid lost tick compensation early in boot before the TSCs are synchronized. Currently timekeeping is enabled before the TSCs are synchronized, thus when the TSCs are synched (reset to zero), it appears that a number of lost ticks have occurred. This can cause premature expiry of timers and in extreme cases can cause the soft lockup detection to fire. This resolves issues reported by Andy Whitcroft as well as bug #5366 reported by Tim Mann. Signed-off-by: John Stultz Acked-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/timers/timer_tsc.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 47675bbbb316..7c86e3c5f1c1 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c @@ -45,6 +45,15 @@ static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ static unsigned long long monotonic_base; static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; +/* Avoid compensating for lost ticks before TSCs are synched */ +static int detect_lost_ticks; +static int __init start_lost_tick_compensation(void) +{ + detect_lost_ticks = 1; + return 0; +} +late_initcall(start_lost_tick_compensation); + /* convert from cycles(64bits) => nanoseconds (64bits) * basic equation: * ns = cycles / (freq / ns_per_sec) @@ -196,7 +205,8 @@ static void mark_offset_tsc_hpet(void) /* lost tick compensation */ offset = hpet_readl(HPET_T0_CMP) - hpet_tick; - if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { + if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0)) + && detect_lost_ticks) { int lost_ticks = (offset - hpet_last) / hpet_tick; jiffies_64 += lost_ticks; } @@ -421,7 +431,7 @@ static void mark_offset_tsc(void) delta += delay_at_last_interrupt; lost = delta/(1000000/HZ); delay = delta%(1000000/HZ); - if (lost >= 2) { + if (lost >= 2 && detect_lost_ticks) { jiffies_64 += lost-1; /* sanity check to ensure we're not always losing ticks */ From bb3c190e8d43fcbf1210effb05dc660cb3ccf817 Mon Sep 17 00:00:00 2001 From: "V. Ananda Krishnan" Date: Wed, 1 Feb 2006 03:05:20 -0800 Subject: [PATCH 360/695] [PATCH] jsm: fix for high baud rates problem Scott Kilau Digi serial port console doesn't work when baud rates are set higher than 38400. So the lookup table and code in jsm_neo.c has been modified and tested. Please let me have the feed-back. Signed-off-by: V.Ananda Krishnan Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/jsm/jsm_neo.c | 83 ++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c index 6f22b42d9337..87e4e2cf8ce7 100644 --- a/drivers/serial/jsm/jsm_neo.c +++ b/drivers/serial/jsm/jsm_neo.c @@ -965,56 +965,47 @@ static void neo_param(struct jsm_channel *ch) baud = ch->ch_custom_speed; if (ch->ch_flags & CH_BAUD0) ch->ch_flags &= ~(CH_BAUD0); - } else { - int iindex = 0; - int jindex = 0; + } else { + int i; + unsigned int cflag; + static struct { + unsigned int rate; + unsigned int cflag; + } baud_rates[] = { + { 921600, B921600 }, + { 460800, B460800 }, + { 230400, B230400 }, + { 115200, B115200 }, + { 57600, B57600 }, + { 38400, B38400 }, + { 19200, B19200 }, + { 9600, B9600 }, + { 4800, B4800 }, + { 2400, B2400 }, + { 1200, B1200 }, + { 600, B600 }, + { 300, B300 }, + { 200, B200 }, + { 150, B150 }, + { 134, B134 }, + { 110, B110 }, + { 75, B75 }, + { 50, B50 }, + }; - const u64 bauds[4][16] = { - { - 0, 50, 75, 110, - 134, 150, 200, 300, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { - 0, 57600, 76800, 115200, - 131657, 153600, 230400, 460800, - 921600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 } - }; - - baud = C_BAUD(ch->uart_port.info->tty) & 0xff; - - if (ch->ch_c_cflag & CBAUDEX) - iindex = 1; - - jindex = baud; - - if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16)) - baud = bauds[iindex][jindex]; - else { - jsm_printk(IOCTL, DEBUG, &ch->ch_bd->pci_dev, - "baud indices were out of range (%d)(%d)", - iindex, jindex); - baud = 0; + cflag = C_BAUD(ch->uart_port.info->tty); + baud = 9600; + for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { + if (baud_rates[i].cflag == cflag) { + baud = baud_rates[i].rate; + break; } - - if (baud == 0) - baud = 9600; - - if (ch->ch_flags & CH_BAUD0) - ch->ch_flags &= ~(CH_BAUD0); } + if (ch->ch_flags & CH_BAUD0) + ch->ch_flags &= ~(CH_BAUD0); + } + if (ch->ch_c_cflag & PARENB) lcr |= UART_LCR_PARITY; From a8183ebb45324ef99f98a175623d67cdcec4466f Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 1 Feb 2006 03:05:21 -0800 Subject: [PATCH 361/695] [PATCH] fix saa7146 kobject register failure Whoops. kobject_register failed for hexium HV-PCI6/Orion (-13) [] kobject_register+0x31/0x47 [] bus_add_driver+0x4a/0xfd [] __pci_register_driver+0x82/0xa4 [] hexium_init_module+0xa/0x47 [hexium_orion] [] sys_init_module+0x167b/0x1822 [] do_sync_read+0xb8/0xf3 [] autoremove_wake_function+0x0/0x2d [] audit_syscall_entry+0x118/0x13f [] do_syscall_trace+0x104/0x14a [] syscall_call+0x7/0xb slashes in kobject names aren't allowed. Signed-off-by: Dave Jones Cc: Mauro Carvalho Chehab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/hexium_orion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 0b6c2096ec66..aad4a18aafd6 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c @@ -484,7 +484,7 @@ static struct saa7146_ext_vv vv_data = { }; static struct saa7146_extension extension = { - .name = "hexium HV-PCI6/Orion", + .name = "hexium HV-PCI6 Orion", .flags = 0, // SAA7146_USE_I2C_IRQ, .pci_tbl = &pci_tbl[0], From f7b8988ff50d99c99746f65f420364e91362c065 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 1 Feb 2006 03:05:21 -0800 Subject: [PATCH 362/695] [PATCH] swsusp: do not change log level during suspend/resume Prevent the kernel from setting the log level to 10 unconditionally during suspend/resume which was needed in the past for debugging, but generally is undesirable. Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/power/console.c | 12 +----------- kernel/power/power.h | 5 +++++ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/kernel/power/console.c b/kernel/power/console.c index 7ff375e7c95f..579d239d129f 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c @@ -9,18 +9,11 @@ #include #include "power.h" -static int new_loglevel = 10; -static int orig_loglevel; #ifdef SUSPEND_CONSOLE static int orig_fgconsole, orig_kmsg; -#endif int pm_prepare_console(void) { - orig_loglevel = console_loglevel; - console_loglevel = new_loglevel; - -#ifdef SUSPEND_CONSOLE acquire_console_sem(); orig_fgconsole = fg_console; @@ -41,18 +34,15 @@ int pm_prepare_console(void) } orig_kmsg = kmsg_redirect; kmsg_redirect = SUSPEND_CONSOLE; -#endif return 0; } void pm_restore_console(void) { - console_loglevel = orig_loglevel; -#ifdef SUSPEND_CONSOLE acquire_console_sem(); set_console(orig_fgconsole); release_console_sem(); kmsg_redirect = orig_kmsg; -#endif return; } +#endif diff --git a/kernel/power/power.h b/kernel/power/power.h index 61beb5e0e927..d8f0d1a76bae 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -42,8 +42,13 @@ static struct subsys_attribute _name##_attr = { \ extern struct subsystem power_subsys; +#ifdef SUSPEND_CONSOLE extern int pm_prepare_console(void); extern void pm_restore_console(void); +#else +static int pm_prepare_console(void) { return 0; } +static void pm_restore_console(void) {} +#endif /* References to section boundaries */ extern const void __nosave_begin, __nosave_end; From c125a1838a95604eb35b60259a8d678dc193f7e4 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 1 Feb 2006 03:05:22 -0800 Subject: [PATCH 363/695] [PATCH] powerpc: Add flattened device tree documentation The flattened device tree is the only supported way of booting ARCH=powerpc kernels on non Open Firmware machines. The documentation for the flattened tree format and contents has been discussed on mailing lists and lately has been living in the dtc git tree. Really, it ought to go in the kernel's Documentation directory for maximum visibility. Signed-off-by: David Gibson Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/powerpc/booting-without-of.txt | 1420 ++++++++++++++++++ 1 file changed, 1420 insertions(+) create mode 100644 Documentation/powerpc/booting-without-of.txt diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt new file mode 100644 index 000000000000..1284498e847c --- /dev/null +++ b/Documentation/powerpc/booting-without-of.txt @@ -0,0 +1,1420 @@ + Booting the Linux/ppc kernel without Open Firmware + -------------------------------------------------- + + +(c) 2005 Benjamin Herrenschmidt , + IBM Corp. +(c) 2005 Becky Bruce , + Freescale Semiconductor, FSL SOC and 32-bit additions + + May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet. + + May 19, 2005: Rev 0.2 - Add chapter III and bits & pieces here or + clarifies the fact that a lot of things are + optional, the kernel only requires a very + small device tree, though it is encouraged + to provide an as complete one as possible. + + May 24, 2005: Rev 0.3 - Precise that DT block has to be in RAM + - Misc fixes + - Define version 3 and new format version 16 + for the DT block (version 16 needs kernel + patches, will be fwd separately). + String block now has a size, and full path + is replaced by unit name for more + compactness. + linux,phandle is made optional, only nodes + that are referenced by other nodes need it. + "name" property is now automatically + deduced from the unit name + + June 1, 2005: Rev 0.4 - Correct confusion between OF_DT_END and + OF_DT_END_NODE in structure definition. + - Change version 16 format to always align + property data to 4 bytes. Since tokens are + already aligned, that means no specific + required alignement between property size + and property data. The old style variable + alignment would make it impossible to do + "simple" insertion of properties using + memove (thanks Milton for + noticing). Updated kernel patch as well + - Correct a few more alignement constraints + - Add a chapter about the device-tree + compiler and the textural representation of + the tree that can be "compiled" by dtc. + + + November 21, 2005: Rev 0.5 + - Additions/generalizations for 32-bit + - Changed to reflect the new arch/powerpc + structure + - Added chapter VI + + + ToDo: + - Add some definitions of interrupt tree (simple/complex) + - Add some definitions for pci host bridges + - Add some common address format examples + - Add definitions for standard properties and "compatible" + names for cells that are not already defined by the existing + OF spec. + - Compare FSL SOC use of PCI to standard and make sure no new + node definition required. + - Add more information about node definitions for SOC devices + that currently have no standard, like the FSL CPM. + + +I - Introduction +================ + +During the recent development of the Linux/ppc64 kernel, and more +specifically, the addition of new platform types outside of the old +IBM pSeries/iSeries pair, it was decided to enforce some strict rules +regarding the kernel entry and bootloader <-> kernel interfaces, in +order to avoid the degeneration that had become the ppc32 kernel entry +point and the way a new platform should be added to the kernel. The +legacy iSeries platform breaks those rules as it predates this scheme, +but no new board support will be accepted in the main tree that +doesn't follows them properly. In addition, since the advent of the +arch/powerpc merged architecture for ppc32 and ppc64, new 32-bit +platforms and 32-bit platforms which move into arch/powerpc will be +required to use these rules as well. + +The main requirement that will be defined in more detail below is +the presence of a device-tree whose format is defined after Open +Firmware specification. However, in order to make life easier +to embedded board vendors, the kernel doesn't require the device-tree +to represent every device in the system and only requires some nodes +and properties to be present. This will be described in detail in +section III, but, for example, the kernel does not require you to +create a node for every PCI device in the system. It is a requirement +to have a node for PCI host bridges in order to provide interrupt +routing informations and memory/IO ranges, among others. It is also +recommended to define nodes for on chip devices and other busses that +don't specifically fit in an existing OF specification. This creates a +great flexibility in the way the kernel can then probe those and match +drivers to device, without having to hard code all sorts of tables. It +also makes it more flexible for board vendors to do minor hardware +upgrades without significantly impacting the kernel code or cluttering +it with special cases. + + +1) Entry point for arch/powerpc +------------------------------- + + There is one and one single entry point to the kernel, at the start + of the kernel image. That entry point supports two calling + conventions: + + a) Boot from Open Firmware. If your firmware is compatible + with Open Firmware (IEEE 1275) or provides an OF compatible + client interface API (support for "interpret" callback of + forth words isn't required), you can enter the kernel with: + + r5 : OF callback pointer as defined by IEEE 1275 + bindings to powerpc. Only the 32 bit client interface + is currently supported + + r3, r4 : address & length of an initrd if any or 0 + + The MMU is either on or off; the kernel will run the + trampoline located in arch/powerpc/kernel/prom_init.c to + extract the device-tree and other information from open + firmware and build a flattened device-tree as described + in b). prom_init() will then re-enter the kernel using + the second method. This trampoline code runs in the + context of the firmware, which is supposed to handle all + exceptions during that time. + + b) Direct entry with a flattened device-tree block. This entry + point is called by a) after the OF trampoline and can also be + called directly by a bootloader that does not support the Open + Firmware client interface. It is also used by "kexec" to + implement "hot" booting of a new kernel from a previous + running one. This method is what I will describe in more + details in this document, as method a) is simply standard Open + Firmware, and thus should be implemented according to the + various standard documents defining it and its binding to the + PowerPC platform. The entry point definition then becomes: + + r3 : physical pointer to the device-tree block + (defined in chapter II) in RAM + + r4 : physical pointer to the kernel itself. This is + used by the assembly code to properly disable the MMU + in case you are entering the kernel with MMU enabled + and a non-1:1 mapping. + + r5 : NULL (as to differenciate with method a) + + Note about SMP entry: Either your firmware puts your other + CPUs in some sleep loop or spin loop in ROM where you can get + them out via a soft reset or some other means, in which case + you don't need to care, or you'll have to enter the kernel + with all CPUs. The way to do that with method b) will be + described in a later revision of this document. + + +2) Board support +---------------- + +64-bit kernels: + + Board supports (platforms) are not exclusive config options. An + arbitrary set of board supports can be built in a single kernel + image. The kernel will "know" what set of functions to use for a + given platform based on the content of the device-tree. Thus, you + should: + + a) add your platform support as a _boolean_ option in + arch/powerpc/Kconfig, following the example of PPC_PSERIES, + PPC_PMAC and PPC_MAPLE. The later is probably a good + example of a board support to start from. + + b) create your main platform file as + "arch/powerpc/platforms/myplatform/myboard_setup.c" and add it + to the Makefile under the condition of your CONFIG_ + option. This file will define a structure of type "ppc_md" + containing the various callbacks that the generic code will + use to get to your platform specific code + + c) Add a reference to your "ppc_md" structure in the + "machines" table in arch/powerpc/kernel/setup_64.c if you are + a 64-bit platform. + + d) request and get assigned a platform number (see PLATFORM_* + constants in include/asm-powerpc/processor.h + +32-bit embedded kernels: + + Currently, board support is essentially an exclusive config option. + The kernel is configured for a single platform. Part of the reason + for this is to keep kernels on embedded systems small and efficient; + part of this is due to the fact the code is already that way. In the + future, a kernel may support multiple platforms, but only if the + platforms feature the same core architectire. A single kernel build + cannot support both configurations with Book E and configurations + with classic Powerpc architectures. + + 32-bit embedded platforms that are moved into arch/powerpc using a + flattened device tree should adopt the merged tree practice of + setting ppc_md up dynamically, even though the kernel is currently + built with support for only a single platform at a time. This allows + unification of the setup code, and will make it easier to go to a + multiple-platform-support model in the future. + +NOTE: I believe the above will be true once Ben's done with the merge +of the boot sequences.... someone speak up if this is wrong! + + To add a 32-bit embedded platform support, follow the instructions + for 64-bit platforms above, with the exception that the Kconfig + option should be set up such that the kernel builds exclusively for + the platform selected. The processor type for the platform should + enable another config option to select the specific board + supported. + +NOTE: If ben doesn't merge the setup files, may need to change this to +point to setup_32.c + + + I will describe later the boot process and various callbacks that + your platform should implement. + + +II - The DT block format +======================== + + +This chapter defines the actual format of the flattened device-tree +passed to the kernel. The actual content of it and kernel requirements +are described later. You can find example of code manipulating that +format in various places, including arch/powerpc/kernel/prom_init.c +which will generate a flattened device-tree from the Open Firmware +representation, or the fs2dt utility which is part of the kexec tools +which will generate one from a filesystem representation. It is +expected that a bootloader like uboot provides a bit more support, +that will be discussed later as well. + +Note: The block has to be in main memory. It has to be accessible in +both real mode and virtual mode with no mapping other than main +memory. If you are writing a simple flash bootloader, it should copy +the block to RAM before passing it to the kernel. + + +1) Header +--------- + + The kernel is entered with r3 pointing to an area of memory that is + roughtly described in include/asm-powerpc/prom.h by the structure + boot_param_header: + +struct boot_param_header { + u32 magic; /* magic word OF_DT_HEADER */ + u32 totalsize; /* total size of DT block */ + u32 off_dt_struct; /* offset to structure */ + u32 off_dt_strings; /* offset to strings */ + u32 off_mem_rsvmap; /* offset to memory reserve map +*/ + u32 version; /* format version */ + u32 last_comp_version; /* last compatible version */ + + /* version 2 fields below */ + u32 boot_cpuid_phys; /* Which physical CPU id we're + booting on */ + /* version 3 fields below */ + u32 size_dt_strings; /* size of the strings block */ +}; + + Along with the constants: + +/* Definitions used by the flattened device tree */ +#define OF_DT_HEADER 0xd00dfeed /* 4: version, + 4: total size */ +#define OF_DT_BEGIN_NODE 0x1 /* Start node: full name +*/ +#define OF_DT_END_NODE 0x2 /* End node */ +#define OF_DT_PROP 0x3 /* Property: name off, + size, content */ +#define OF_DT_END 0x9 + + All values in this header are in big endian format, the various + fields in this header are defined more precisely below. All + "offset" values are in bytes from the start of the header; that is + from the value of r3. + + - magic + + This is a magic value that "marks" the beginning of the + device-tree block header. It contains the value 0xd00dfeed and is + defined by the constant OF_DT_HEADER + + - totalsize + + This is the total size of the DT block including the header. The + "DT" block should enclose all data structures defined in this + chapter (who are pointed to by offsets in this header). That is, + the device-tree structure, strings, and the memory reserve map. + + - off_dt_struct + + This is an offset from the beginning of the header to the start + of the "structure" part the device tree. (see 2) device tree) + + - off_dt_strings + + This is an offset from the beginning of the header to the start + of the "strings" part of the device-tree + + - off_mem_rsvmap + + This is an offset from the beginning of the header to the start + of the reserved memory map. This map is a list of pairs of 64 + bit integers. Each pair is a physical address and a size. The + + list is terminated by an entry of size 0. This map provides the + kernel with a list of physical memory areas that are "reserved" + and thus not to be used for memory allocations, especially during + early initialization. The kernel needs to allocate memory during + boot for things like un-flattening the device-tree, allocating an + MMU hash table, etc... Those allocations must be done in such a + way to avoid overriding critical things like, on Open Firmware + capable machines, the RTAS instance, or on some pSeries, the TCE + tables used for the iommu. Typically, the reserve map should + contain _at least_ this DT block itself (header,total_size). If + you are passing an initrd to the kernel, you should reserve it as + well. You do not need to reserve the kernel image itself. The map + should be 64 bit aligned. + + - version + + This is the version of this structure. Version 1 stops + here. Version 2 adds an additional field boot_cpuid_phys. + Version 3 adds the size of the strings block, allowing the kernel + to reallocate it easily at boot and free up the unused flattened + structure after expansion. Version 16 introduces a new more + "compact" format for the tree itself that is however not backward + compatible. You should always generate a structure of the highest + version defined at the time of your implementation. Currently + that is version 16, unless you explicitely aim at being backward + compatible. + + - last_comp_version + + Last compatible version. This indicates down to what version of + the DT block you are backward compatible. For example, version 2 + is backward compatible with version 1 (that is, a kernel build + for version 1 will be able to boot with a version 2 format). You + should put a 1 in this field if you generate a device tree of + version 1 to 3, or 0x10 if you generate a tree of version 0x10 + using the new unit name format. + + - boot_cpuid_phys + + This field only exist on version 2 headers. It indicate which + physical CPU ID is calling the kernel entry point. This is used, + among others, by kexec. If you are on an SMP system, this value + should match the content of the "reg" property of the CPU node in + the device-tree corresponding to the CPU calling the kernel entry + point (see further chapters for more informations on the required + device-tree contents) + + + So the typical layout of a DT block (though the various parts don't + need to be in that order) looks like this (addresses go from top to + bottom): + + + ------------------------------ + r3 -> | struct boot_param_header | + ------------------------------ + | (alignment gap) (*) | + ------------------------------ + | memory reserve map | + ------------------------------ + | (alignment gap) | + ------------------------------ + | | + | device-tree structure | + | | + ------------------------------ + | (alignment gap) | + ------------------------------ + | | + | device-tree strings | + | | + -----> ------------------------------ + | + | + --- (r3 + totalsize) + + (*) The alignment gaps are not necessarily present; their presence + and size are dependent on the various alignment requirements of + the individual data blocks. + + +2) Device tree generalities +--------------------------- + +This device-tree itself is separated in two different blocks, a +structure block and a strings block. Both need to be aligned to a 4 +byte boundary. + +First, let's quickly describe the device-tree concept before detailing +the storage format. This chapter does _not_ describe the detail of the +required types of nodes & properties for the kernel, this is done +later in chapter III. + +The device-tree layout is strongly inherited from the definition of +the Open Firmware IEEE 1275 device-tree. It's basically a tree of +nodes, each node having two or more named properties. A property can +have a value or not. + +It is a tree, so each node has one and only one parent except for the +root node who has no parent. + +A node has 2 names. The actual node name is generally contained in a +property of type "name" in the node property list whose value is a +zero terminated string and is mandatory for version 1 to 3 of the +format definition (as it is in Open Firmware). Version 0x10 makes it +optional as it can generate it from the unit name defined below. + +There is also a "unit name" that is used to differenciate nodes with +the same name at the same level, it is usually made of the node +name's, the "@" sign, and a "unit address", which definition is +specific to the bus type the node sits on. + +The unit name doesn't exist as a property per-se but is included in +the device-tree structure. It is typically used to represent "path" in +the device-tree. More details about the actual format of these will be +below. + +The kernel powerpc generic code does not make any formal use of the +unit address (though some board support code may do) so the only real +requirement here for the unit address is to ensure uniqueness of +the node unit name at a given level of the tree. Nodes with no notion +of address and no possible sibling of the same name (like /memory or +/cpus) may omit the unit address in the context of this specification, +or use the "@0" default unit address. The unit name is used to define +a node "full path", which is the concatenation of all parent node +unit names separated with "/". + +The root node doesn't have a defined name, and isn't required to have +a name property either if you are using version 3 or earlier of the +format. It also has no unit address (no @ symbol followed by a unit +address). The root node unit name is thus an empty string. The full +path to the root node is "/". + +Every node which actually represents an actual device (that is, a node +which isn't only a virtual "container" for more nodes, like "/cpus" +is) is also required to have a "device_type" property indicating the +type of node . + +Finally, every node that can be referenced from a property in another +node is required to have a "linux,phandle" property. Real open +firmware implementations provide a unique "phandle" value for every +node that the "prom_init()" trampoline code turns into +"linux,phandle" properties. However, this is made optional if the +flattened device tree is used directly. An example of a node +referencing another node via "phandle" is when laying out the +interrupt tree which will be described in a further version of this +document. + +This "linux, phandle" property is a 32 bit value that uniquely +identifies a node. You are free to use whatever values or system of +values, internal pointers, or whatever to generate these, the only +requirement is that every node for which you provide that property has +a unique value for it. + +Here is an example of a simple device-tree. In this example, an "o" +designates a node followed by the node unit name. Properties are +presented with their name followed by their content. "content" +represents an ASCII string (zero terminated) value, while +represents a 32 bit hexadecimal value. The various nodes in this +example will be discussed in a later chapter. At this point, it is +only meant to give you a idea of what a device-tree looks like. I have +purposefully kept the "name" and "linux,phandle" properties which +aren't necessary in order to give you a better idea of what the tree +looks like in practice. + + / o device-tree + |- name = "device-tree" + |- model = "MyBoardName" + |- compatible = "MyBoardFamilyName" + |- #address-cells = <2> + |- #size-cells = <2> + |- linux,phandle = <0> + | + o cpus + | | - name = "cpus" + | | - linux,phandle = <1> + | | - #address-cells = <1> + | | - #size-cells = <0> + | | + | o PowerPC,970@0 + | |- name = "PowerPC,970" + | |- device_type = "cpu" + | |- reg = <0> + | |- clock-frequency = <5f5e1000> + | |- linux,boot-cpu + | |- linux,phandle = <2> + | + o memory@0 + | |- name = "memory" + | |- device_type = "memory" + | |- reg = <00000000 00000000 00000000 20000000> + | |- linux,phandle = <3> + | + o chosen + |- name = "chosen" + |- bootargs = "root=/dev/sda2" + |- linux,platform = <00000600> + |- linux,phandle = <4> + +This tree is almost a minimal tree. It pretty much contains the +minimal set of required nodes and properties to boot a linux kernel; +that is, some basic model informations at the root, the CPUs, and the +physical memory layout. It also includes misc information passed +through /chosen, like in this example, the platform type (mandatory) +and the kernel command line arguments (optional). + +The /cpus/PowerPC,970@0/linux,boot-cpu property is an example of a +property without a value. All other properties have a value. The +significance of the #address-cells and #size-cells properties will be +explained in chapter IV which defines precisely the required nodes and +properties and their content. + + +3) Device tree "structure" block + +The structure of the device tree is a linearized tree structure. The +"OF_DT_BEGIN_NODE" token starts a new node, and the "OF_DT_END_NODE" +ends that node definition. Child nodes are simply defined before +"OF_DT_END_NODE" (that is nodes within the node). A 'token' is a 32 +bit value. The tree has to be "finished" with a OF_DT_END token + +Here's the basic structure of a single node: + + * token OF_DT_BEGIN_NODE (that is 0x00000001) + * for version 1 to 3, this is the node full path as a zero + terminated string, starting with "/". For version 16 and later, + this is the node unit name only (or an empty string for the + root node) + * [align gap to next 4 bytes boundary] + * for each property: + * token OF_DT_PROP (that is 0x00000003) + * 32 bit value of property value size in bytes (or 0 of no + * value) + * 32 bit value of offset in string block of property name + * property value data if any + * [align gap to next 4 bytes boundary] + * [child nodes if any] + * token OF_DT_END_NODE (that is 0x00000002) + +So the node content can be summmarised as a start token, a full path, +a list of properties, a list of child node and an end token. Every +child node is a full node structure itself as defined above. + +4) Device tree 'strings" block + +In order to save space, property names, which are generally redundant, +are stored separately in the "strings" block. This block is simply the +whole bunch of zero terminated strings for all property names +concatenated together. The device-tree property definitions in the +structure block will contain offset values from the beginning of the +strings block. + + +III - Required content of the device tree +========================================= + +WARNING: All "linux,*" properties defined in this document apply only +to a flattened device-tree. If your platform uses a real +implementation of Open Firmware or an implementation compatible with +the Open Firmware client interface, those properties will be created +by the trampoline code in the kernel's prom_init() file. For example, +that's where you'll have to add code to detect your board model and +set the platform number. However, when using the flatenned device-tree +entry point, there is no prom_init() pass, and thus you have to +provide those properties yourself. + + +1) Note about cells and address representation +---------------------------------------------- + +The general rule is documented in the various Open Firmware +documentations. If you chose to describe a bus with the device-tree +and there exist an OF bus binding, then you should follow the +specification. However, the kernel does not require every single +device or bus to be described by the device tree. + +In general, the format of an address for a device is defined by the +parent bus type, based on the #address-cells and #size-cells +property. In the absence of such a property, the parent's parent +values are used, etc... The kernel requires the root node to have +those properties defining addresses format for devices directly mapped +on the processor bus. + +Those 2 properties define 'cells' for representing an address and a +size. A "cell" is a 32 bit number. For example, if both contain 2 +like the example tree given above, then an address and a size are both +composed of 2 cells, and each is a 64 bit number (cells are +concatenated and expected to be in big endian format). Another example +is the way Apple firmware defines them, with 2 cells for an address +and one cell for a size. Most 32-bit implementations should define +#address-cells and #size-cells to 1, which represents a 32-bit value. +Some 32-bit processors allow for physical addresses greater than 32 +bits; these processors should define #address-cells as 2. + +"reg" properties are always a tuple of the type "address size" where +the number of cells of address and size is specified by the bus +#address-cells and #size-cells. When a bus supports various address +spaces and other flags relative to a given address allocation (like +prefetchable, etc...) those flags are usually added to the top level +bits of the physical address. For example, a PCI physical address is +made of 3 cells, the bottom two containing the actual address itself +while the top cell contains address space indication, flags, and pci +bus & device numbers. + +For busses that support dynamic allocation, it's the accepted practice +to then not provide the address in "reg" (keep it 0) though while +providing a flag indicating the address is dynamically allocated, and +then, to provide a separate "assigned-addresses" property that +contains the fully allocated addresses. See the PCI OF bindings for +details. + +In general, a simple bus with no address space bits and no dynamic +allocation is preferred if it reflects your hardware, as the existing +kernel address parsing functions will work out of the box. If you +define a bus type with a more complex address format, including things +like address space bits, you'll have to add a bus translator to the +prom_parse.c file of the recent kernels for your bus type. + +The "reg" property only defines addresses and sizes (if #size-cells +is +non-0) within a given bus. In order to translate addresses upward +(that is into parent bus addresses, and possibly into cpu physical +addresses), all busses must contain a "ranges" property. If the +"ranges" property is missing at a given level, it's assumed that +translation isn't possible. The format of the "ranges" proprety for a +bus is a list of: + + bus address, parent bus address, size + +"bus address" is in the format of the bus this bus node is defining, +that is, for a PCI bridge, it would be a PCI address. Thus, (bus +address, size) defines a range of addresses for child devices. "parent +bus address" is in the format of the parent bus of this bus. For +example, for a PCI host controller, that would be a CPU address. For a +PCI<->ISA bridge, that would be a PCI address. It defines the base +address in the parent bus where the beginning of that range is mapped. + +For a new 64 bit powerpc board, I recommend either the 2/2 format or +Apple's 2/1 format which is slightly more compact since sizes usually +fit in a single 32 bit word. New 32 bit powerpc boards should use a +1/1 format, unless the processor supports physical addresses greater +than 32-bits, in which case a 2/1 format is recommended. + + +2) Note about "compatible" properties +------------------------------------- + +These properties are optional, but recommended in devices and the root +node. The format of a "compatible" property is a list of concatenated +zero terminated strings. They allow a device to express its +compatibility with a family of similar devices, in some cases, +allowing a single driver to match against several devices regardless +of their actual names. + +3) Note about "name" properties +------------------------------- + +While earlier users of Open Firmware like OldWorld macintoshes tended +to use the actual device name for the "name" property, it's nowadays +considered a good practice to use a name that is closer to the device +class (often equal to device_type). For example, nowadays, ethernet +controllers are named "ethernet", an additional "model" property +defining precisely the chip type/model, and "compatible" property +defining the family in case a single driver can driver more than one +of these chips. However, the kernel doesn't generally put any +restriction on the "name" property; it is simply considered good +practice to follow the standard and its evolutions as closely as +possible. + +Note also that the new format version 16 makes the "name" property +optional. If it's absent for a node, then the node's unit name is then +used to reconstruct the name. That is, the part of the unit name +before the "@" sign is used (or the entire unit name if no "@" sign +is present). + +4) Note about node and property names and character set +------------------------------------------------------- + +While open firmware provides more flexibe usage of 8859-1, this +specification enforces more strict rules. Nodes and properties should +be comprised only of ASCII characters 'a' to 'z', '0' to +'9', ',', '.', '_', '+', '#', '?', and '-'. Node names additionally +allow uppercase characters 'A' to 'Z' (property names should be +lowercase. The fact that vendors like Apple don't respect this rule is +irrelevant here). Additionally, node and property names should always +begin with a character in the range 'a' to 'z' (or 'A' to 'Z' for node +names). + +The maximum number of characters for both nodes and property names +is 31. In the case of node names, this is only the leftmost part of +a unit name (the pure "name" property), it doesn't include the unit +address which can extend beyond that limit. + + +5) Required nodes and properties +-------------------------------- + These are all that are currently required. However, it is strongly + recommended that you expose PCI host bridges as documented in the + PCI binding to open firmware, and your interrupt tree as documented + in OF interrupt tree specification. + + a) The root node + + The root node requires some properties to be present: + + - model : this is your board name/model + - #address-cells : address representation for "root" devices + - #size-cells: the size representation for "root" devices + + Additionally, some recommended properties are: + + - compatible : the board "family" generally finds its way here, + for example, if you have 2 board models with a similar layout, + that typically get driven by the same platform code in the + kernel, you would use a different "model" property but put a + value in "compatible". The kernel doesn't directly use that + value (see /chosen/linux,platform for how the kernel choses a + platform type) but it is generally useful. + + The root node is also generally where you add additional properties + specific to your board like the serial number if any, that sort of + thing. it is recommended that if you add any "custom" property whose + name may clash with standard defined ones, you prefix them with your + vendor name and a comma. + + b) The /cpus node + + This node is the parent of all individual CPU nodes. It doesn't + have any specific requirements, though it's generally good practice + to have at least: + + #address-cells = <00000001> + #size-cells = <00000000> + + This defines that the "address" for a CPU is a single cell, and has + no meaningful size. This is not necessary but the kernel will assume + that format when reading the "reg" properties of a CPU node, see + below + + c) The /cpus/* nodes + + So under /cpus, you are supposed to create a node for every CPU on + the machine. There is no specific restriction on the name of the + CPU, though It's common practice to call it PowerPC,. For + example, Apple uses PowerPC,G5 while IBM uses PowerPC,970FX. + + Required properties: + + - device_type : has to be "cpu" + - reg : This is the physical cpu number, it's a single 32 bit cell + and is also used as-is as the unit number for constructing the + unit name in the full path. For example, with 2 CPUs, you would + have the full path: + /cpus/PowerPC,970FX@0 + /cpus/PowerPC,970FX@1 + (unit addresses do not require leading zeroes) + - d-cache-line-size : one cell, L1 data cache line size in bytes + - i-cache-line-size : one cell, L1 instruction cache line size in + bytes + - d-cache-size : one cell, size of L1 data cache in bytes + - i-cache-size : one cell, size of L1 instruction cache in bytes + - linux, boot-cpu : Should be defined if this cpu is the boot cpu. + + Recommended properties: + + - timebase-frequency : a cell indicating the frequency of the + timebase in Hz. This is not directly used by the generic code, + but you are welcome to copy/paste the pSeries code for setting + the kernel timebase/decrementer calibration based on this + value. + - clock-frequency : a cell indicating the CPU core clock frequency + in Hz. A new property will be defined for 64 bit values, but if + your frequency is < 4Ghz, one cell is enough. Here as well as + for the above, the common code doesn't use that property, but + you are welcome to re-use the pSeries or Maple one. A future + kernel version might provide a common function for this. + + You are welcome to add any property you find relevant to your board, + like some information about the mechanism used to soft-reset the + CPUs. For example, Apple puts the GPIO number for CPU soft reset + lines in there as a "soft-reset" property since they start secondary + CPUs by soft-resetting them. + + + d) the /memory node(s) + + To define the physical memory layout of your board, you should + create one or more memory node(s). You can either create a single + node with all memory ranges in its reg property, or you can create + several nodes, as you wish. The unit address (@ part) used for the + full path is the address of the first range of memory defined by a + given node. If you use a single memory node, this will typically be + @0. + + Required properties: + + - device_type : has to be "memory" + - reg : This property contains all the physical memory ranges of + your board. It's a list of addresses/sizes concatenated + together, with the number of cells of each defined by the + #address-cells and #size-cells of the root node. For example, + with both of these properties beeing 2 like in the example given + earlier, a 970 based machine with 6Gb of RAM could typically + have a "reg" property here that looks like: + + 00000000 00000000 00000000 80000000 + 00000001 00000000 00000001 00000000 + + That is a range starting at 0 of 0x80000000 bytes and a range + starting at 0x100000000 and of 0x100000000 bytes. You can see + that there is no memory covering the IO hole between 2Gb and + 4Gb. Some vendors prefer splitting those ranges into smaller + segments, but the kernel doesn't care. + + e) The /chosen node + + This node is a bit "special". Normally, that's where open firmware + puts some variable environment information, like the arguments, or + phandle pointers to nodes like the main interrupt controller, or the + default input/output devices. + + This specification makes a few of these mandatory, but also defines + some linux-specific properties that would be normally constructed by + the prom_init() trampoline when booting with an OF client interface, + but that you have to provide yourself when using the flattened format. + + Required properties: + + - linux,platform : This is your platform number as assigned by the + architecture maintainers + + Recommended properties: + + - bootargs : This zero-terminated string is passed as the kernel + command line + - linux,stdout-path : This is the full path to your standard + console device if any. Typically, if you have serial devices on + your board, you may want to put the full path to the one set as + the default console in the firmware here, for the kernel to pick + it up as it's own default console. If you look at the funciton + set_preferred_console() in arch/ppc64/kernel/setup.c, you'll see + that the kernel tries to find out the default console and has + knowledge of various types like 8250 serial ports. You may want + to extend this function to add your own. + - interrupt-controller : This is one cell containing a phandle + value that matches the "linux,phandle" property of your main + interrupt controller node. May be used for interrupt routing. + + + Note that u-boot creates and fills in the chosen node for platforms + that use it. + + f) the /soc node + + This node is used to represent a system-on-a-chip (SOC) and must be + present if the processor is a SOC. The top-level soc node contains + information that is global to all devices on the SOC. The node name + should contain a unit address for the SOC, which is the base address + of the memory-mapped register set for the SOC. The name of an soc + node should start with "soc", and the remainder of the name should + represent the part number for the soc. For example, the MPC8540's + soc node would be called "soc8540". + + Required properties: + + - device_type : Should be "soc" + - ranges : Should be defined as specified in 1) to describe the + translation of SOC addresses for memory mapped SOC registers. + + Recommended properties: + + - reg : This property defines the address and size of the + memory-mapped registers that are used for the SOC node itself. + It does not include the child device registers - these will be + defined inside each child node. The address specified in the + "reg" property should match the unit address of the SOC node. + - #address-cells : Address representation for "soc" devices. The + format of this field may vary depending on whether or not the + device registers are memory mapped. For memory mapped + registers, this field represents the number of cells needed to + represent the address of the registers. For SOCs that do not + use MMIO, a special address format should be defined that + contains enough cells to represent the required information. + See 1) above for more details on defining #address-cells. + - #size-cells : Size representation for "soc" devices + - #interrupt-cells : Defines the width of cells used to represent + interrupts. Typically this value is <2>, which includes a + 32-bit number that represents the interrupt number, and a + 32-bit number that represents the interrupt sense and level. + This field is only needed if the SOC contains an interrupt + controller. + + The SOC node may contain child nodes for each SOC device that the + platform uses. Nodes should not be created for devices which exist + on the SOC but are not used by a particular platform. See chapter VI + for more information on how to specify devices that are part of an +SOC. + + Example SOC node for the MPC8540: + + soc8540@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <00000000 e0000000 00100000> + reg = ; + } + + + +IV - "dtc", the device tree compiler +==================================== + + +dtc source code can be found at + + +WARNING: This version is still in early development stage; the +resulting device-tree "blobs" have not yet been validated with the +kernel. The current generated bloc lacks a useful reserve map (it will +be fixed to generate an empty one, it's up to the bootloader to fill +it up) among others. The error handling needs work, bugs are lurking, +etc... + +dtc basically takes a device-tree in a given format and outputs a +device-tree in another format. The currently supported formats are: + + Input formats: + ------------- + + - "dtb": "blob" format, that is a flattened device-tree block + with + header all in a binary blob. + - "dts": "source" format. This is a text file containing a + "source" for a device-tree. The format is defined later in this + chapter. + - "fs" format. This is a representation equivalent to the + output of /proc/device-tree, that is nodes are directories and + properties are files + + Output formats: + --------------- + + - "dtb": "blob" format + - "dts": "source" format + - "asm": assembly language file. This is a file that can be + sourced by gas to generate a device-tree "blob". That file can + then simply be added to your Makefile. Additionally, the + assembly file exports some symbols that can be use + + +The syntax of the dtc tool is + + dtc [-I ] [-O ] + [-o output-filename] [-V output_version] input_filename + + +The "output_version" defines what versio of the "blob" format will be +generated. Supported versions are 1,2,3 and 16. The default is +currently version 3 but that may change in the future to version 16. + +Additionally, dtc performs various sanity checks on the tree, like the +uniqueness of linux,phandle properties, validity of strings, etc... + +The format of the .dts "source" file is "C" like, supports C and C++ +style commments. + +/ { +} + +The above is the "device-tree" definition. It's the only statement +supported currently at the toplevel. + +/ { + property1 = "string_value"; /* define a property containing a 0 + * terminated string + */ + + property2 = <1234abcd>; /* define a property containing a + * numerical 32 bits value (hexadecimal) + */ + + property3 = <12345678 12345678 deadbeef>; + /* define a property containing 3 + * numerical 32 bits values (cells) in + * hexadecimal + */ + property4 = [0a 0b 0c 0d de ea ad be ef]; + /* define a property whose content is + * an arbitrary array of bytes + */ + + childnode@addresss { /* define a child node named "childnode" + * whose unit name is "childnode at + * address" + */ + + childprop = "hello\n"; /* define a property "childprop" of + * childnode (in this case, a string) + */ + }; +}; + +Nodes can contain other nodes etc... thus defining the hierarchical +structure of the tree. + +Strings support common escape sequences from C: "\n", "\t", "\r", +"\(octal value)", "\x(hex value)". + +It is also suggested that you pipe your source file through cpp (gcc +preprocessor) so you can use #include's, #define for constants, etc... + +Finally, various options are planned but not yet implemented, like +automatic generation of phandles, labels (exported to the asm file so +you can point to a property content and change it easily from whatever +you link the device-tree with), label or path instead of numeric value +in some cells to "point" to a node (replaced by a phandle at compile +time), export of reserve map address to the asm file, ability to +specify reserve map content at compile time, etc... + +We may provide a .h include file with common definitions of that +proves useful for some properties (like building PCI properties or +interrupt maps) though it may be better to add a notion of struct +definitions to the compiler... + + +V - Recommendations for a bootloader +==================================== + + +Here are some various ideas/recommendations that have been proposed +while all this has been defined and implemented. + + - The bootloader may want to be able to use the device-tree itself + and may want to manipulate it (to add/edit some properties, + like physical memory size or kernel arguments). At this point, 2 + choices can be made. Either the bootloader works directly on the + flattened format, or the bootloader has its own internal tree + representation with pointers (similar to the kernel one) and + re-flattens the tree when booting the kernel. The former is a bit + more difficult to edit/modify, the later requires probably a bit + more code to handle the tree structure. Note that the structure + format has been designed so it's relatively easy to "insert" + properties or nodes or delete them by just memmoving things + around. It contains no internal offsets or pointers for this + purpose. + + - An example of code for iterating nodes & retreiving properties + directly from the flattened tree format can be found in the kernel + file arch/ppc64/kernel/prom.c, look at scan_flat_dt() function, + it's usage in early_init_devtree(), and the corresponding various + early_init_dt_scan_*() callbacks. That code can be re-used in a + GPL bootloader, and as the author of that code, I would be happy + do discuss possible free licencing to any vendor who wishes to + integrate all or part of this code into a non-GPL bootloader. + + + +VI - System-on-a-chip devices and nodes +======================================= + +Many companies are now starting to develop system-on-a-chip +processors, where the processor core (cpu) and many peripheral devices +exist on a single piece of silicon. For these SOCs, an SOC node +should be used that defines child nodes for the devices that make +up the SOC. While platforms are not required to use this model in +order to boot the kernel, it is highly encouraged that all SOC +implementations define as complete a flat-device-tree as possible to +describe the devices on the SOC. This will allow for the +genericization of much of the kernel code. + + +1) Defining child nodes of an SOC +--------------------------------- + +Each device that is part of an SOC may have its own node entry inside +the SOC node. For each device that is included in the SOC, the unit +address property represents the address offset for this device's +memory-mapped registers in the parent's address space. The parent's +address space is defined by the "ranges" property in the top-level soc +node. The "reg" property for each node that exists directly under the +SOC node should contain the address mapping from the child address space +to the parent SOC address space and the size of the device's +memory-mapped register file. + +For many devices that may exist inside an SOC, there are predefined +specifications for the format of the device tree node. All SOC child +nodes should follow these specifications, except where noted in this +document. + +See appendix A for an example partial SOC node definition for the +MPC8540. + + +2) Specifying interrupt information for SOC devices +--------------------------------------------------- + +Each device that is part of an SOC and which generates interrupts +should have the following properties: + + - interrupt-parent : contains the phandle of the interrupt + controller which handles interrupts for this device + - interrupts : a list of tuples representing the interrupt + number and the interrupt sense and level for each interupt + for this device. + +This information is used by the kernel to build the interrupt table +for the interrupt controllers in the system. + +Sense and level information should be encoded as follows: + + Devices connected to openPIC-compatible controllers should encode + sense and polarity as follows: + + 0 = high to low edge sensitive type enabled + 1 = active low level sensitive type enabled + 2 = low to high edge sensitive type enabled + 3 = active high level sensitive type enabled + + ISA PIC interrupt controllers should adhere to the ISA PIC + encodings listed below: + + 0 = active low level sensitive type enabled + 1 = active high level sensitive type enabled + 2 = high to low edge sensitive type enabled + 3 = low to high edge sensitive type enabled + + + +3) Representing devices without a current OF specification +---------------------------------------------------------- + +Currently, there are many devices on SOCs that do not have a standard +representation pre-defined as part of the open firmware +specifications, mainly because the boards that contain these SOCs are +not currently booted using open firmware. This section contains +descriptions for the SOC devices for which new nodes have been +defined; this list will expand as more and more SOC-containing +platforms are moved over to use the flattened-device-tree model. + + a) MDIO IO device + + The MDIO is a bus to which the PHY devices are connected. For each + device that exists on this bus, a child node should be created. See + the definition of the PHY node below for an example of how to define + a PHY. + + Required properties: + - reg : Offset and length of the register set for the device + - device_type : Should be "mdio" + - compatible : Should define the compatible device type for the + mdio. Currently, this is most likely to be "gianfar" + + Example: + + mdio@24520 { + reg = <24520 20>; + + ethernet-phy@0 { + ...... + }; + }; + + + b) Gianfar-compatible ethernet nodes + + Required properties: + + - device_type : Should be "network" + - model : Model of the device. Can be "TSEC", "eTSEC", or "FEC" + - compatible : Should be "gianfar" + - reg : Offset and length of the register set for the device + - address : List of bytes representing the ethernet address of + this controller + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - phy-handle : The phandle for the PHY connected to this ethernet + controller. + + Example: + + ethernet@24000 { + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + address = [ 00 E0 0C 00 73 00 ]; + interrupts = ; + interrupt-parent = <40000>; + phy-handle = <2452000> + }; + + + + c) PHY nodes + + Required properties: + + - device_type : Should be "ethernet-phy" + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - reg : The ID number for the phy, usually a small integer + - linux,phandle : phandle for this node; likely referenced by an + ethernet controller node. + + + Example: + + ethernet-phy@0 { + linux,phandle = <2452000> + interrupt-parent = <40000>; + interrupts = <35 1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + + + d) Interrupt controllers + + Some SOC devices contain interrupt controllers that are different + from the standard Open PIC specification. The SOC device nodes for + these types of controllers should be specified just like a standard + OpenPIC controller. Sense and level information should be encoded + as specified in section 2) of this chapter for each device that + specifies an interrupt. + + Example : + + pic@40000 { + linux,phandle = <40000>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + reg = <40000 40000>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + + + e) I2C + + Required properties : + + - device_type : Should be "i2c" + - reg : Offset and length of the register set for the device + + Recommended properties : + + - compatible : Should be "fsl-i2c" for parts compatible with + Freescale I2C specifications. + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - dfsrr : boolean; if defined, indicates that this I2C device has + a digital filter sampling rate register + - fsl5200-clocking : boolean; if defined, indicated that this device + uses the FSL 5200 clocking mechanism. + + Example : + + i2c@3000 { + interrupt-parent = <40000>; + interrupts = <1b 3>; + reg = <3000 18>; + device_type = "i2c"; + compatible = "fsl-i2c"; + dfsrr; + }; + + + More devices will be defined as this spec matures. + + +Appendix A - Sample SOC node for MPC8540 +======================================== + +Note that the #address-cells and #size-cells for the SoC node +in this example have been explicitly listed; these are likely +not necessary as they are usually the same as the root node. + + soc8540@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <00000000 e0000000 00100000> + reg = ; + + mdio@24520 { + reg = <24520 20>; + device_type = "mdio"; + compatible = "gianfar"; + + ethernet-phy@0 { + linux,phandle = <2452000> + interrupt-parent = <40000>; + interrupts = <35 1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + + ethernet-phy@1 { + linux,phandle = <2452001> + interrupt-parent = <40000>; + interrupts = <35 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + + ethernet-phy@3 { + linux,phandle = <2452002> + interrupt-parent = <40000>; + interrupts = <35 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + + }; + + ethernet@24000 { + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + address = [ 00 E0 0C 00 73 00 ]; + interrupts = ; + interrupt-parent = <40000>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + address = [ 00 E0 0C 00 73 01 ]; + interrupts = <13 3 14 3 18 3>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + + ethernet@26000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "FEC"; + compatible = "gianfar"; + reg = <26000 1000>; + address = [ 00 E0 0C 00 73 02 ]; + interrupts = <19 3>; + interrupt-parent = <40000>; + phy-handle = <2452002>; + }; + + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; + clock-frequency = <0>; + interrupts = <1a 3>; + interrupt-parent = <40000>; + }; + + pic@40000 { + linux,phandle = <40000>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + reg = <40000 40000>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + + i2c@3000 { + interrupt-parent = <40000>; + interrupts = <1b 3>; + reg = <3000 18>; + device_type = "i2c"; + compatible = "fsl-i2c"; + dfsrr; + }; + + }; From 537421be79b94bcf620467f50dd9e38b739c2a00 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 1 Feb 2006 03:05:24 -0800 Subject: [PATCH 364/695] [PATCH] Mark CONFIG_UFS_FS_WRITE as BROKEN OpenBSD doesn't see "." correctly in directories created by Linux. Copying files over several KB will buy you infinite loop in __getblk_slow(). Copying files smaller than 1 KB seems to be OK. Sometimes files will be filled with zeros. Sometimes incorrectly copied file will reappear after next file with truncated size. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/Kconfig b/fs/Kconfig index ef78e3a42d32..93b5dc4082ff 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1327,7 +1327,7 @@ config UFS_FS config UFS_FS_WRITE bool "UFS file system write support (DANGEROUS)" - depends on UFS_FS && EXPERIMENTAL + depends on UFS_FS && EXPERIMENTAL && BROKEN help Say Y here if you want to try writing to UFS partitions. This is experimental, so you should back up your UFS partitions beforehand. From 8928862398fef04a137e5673ac5fa9e797960c87 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:25 -0800 Subject: [PATCH 365/695] [PATCH] Optimize off-node performance of zone reclaim Ensure that the performance of off node pages stays the same as before. Off node pagefault tests showed an 18% drop in performance without this patch. - Increase the timeout to 30 seconds to reduce the overhead. - Move all code possible out of the off node hot path for zone reclaim (Sorry Andrew, the struct initialization had to be sacrificed). The read_page_state() bit us there. - Check first for the timeout before any other checks. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 2e34b61a70c7..465bfa54dfd6 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1589,24 +1589,20 @@ int zone_reclaim_mode __read_mostly; /* * Mininum time between zone reclaim scans */ -#define ZONE_RECLAIM_INTERVAL HZ/2 +#define ZONE_RECLAIM_INTERVAL 30*HZ /* * Try to free up some pages from this zone through reclaim. */ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) { - int nr_pages = 1 << order; + int nr_pages; struct task_struct *p = current; struct reclaim_state reclaim_state; - struct scan_control sc = { - .gfp_mask = gfp_mask, - .may_writepage = 0, - .may_swap = 0, - .nr_mapped = read_page_state(nr_mapped), - .nr_scanned = 0, - .nr_reclaimed = 0, - .priority = 0 - }; + struct scan_control sc; + + if (time_before(jiffies, + zone->last_unsuccessful_zone_reclaim + ZONE_RECLAIM_INTERVAL)) + return 0; if (!(gfp_mask & __GFP_WAIT) || zone->zone_pgdat->node_id != numa_node_id() || @@ -1614,12 +1610,17 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) atomic_read(&zone->reclaim_in_progress) > 0) return 0; - if (time_before(jiffies, - zone->last_unsuccessful_zone_reclaim + ZONE_RECLAIM_INTERVAL)) - return 0; + sc.may_writepage = 0; + sc.may_swap = 0; + sc.nr_scanned = 0; + sc.nr_reclaimed = 0; + sc.priority = 0; + sc.nr_mapped = read_page_state(nr_mapped); + sc.gfp_mask = gfp_mask; disable_swap_token(); + nr_pages = 1 << order; if (nr_pages > SWAP_CLUSTER_MAX) sc.swap_cluster_max = nr_pages; else From 42c722d4cb4022e56ff200f3f5a58c0dfd7edac6 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:26 -0800 Subject: [PATCH 366/695] [PATCH] zone_reclaim: reclaim on memory only node support Zone reclaim is usually only run on the local node. Headless nodes do not have any local processors. This patch checks for headless nodes and performs zone reclaim on them. Signed-off-by: Christoph Lameter Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 465bfa54dfd6..0ca6007d655b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1599,17 +1599,23 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) struct task_struct *p = current; struct reclaim_state reclaim_state; struct scan_control sc; + cpumask_t mask; + int node_id; if (time_before(jiffies, zone->last_unsuccessful_zone_reclaim + ZONE_RECLAIM_INTERVAL)) return 0; if (!(gfp_mask & __GFP_WAIT) || - zone->zone_pgdat->node_id != numa_node_id() || zone->all_unreclaimable || atomic_read(&zone->reclaim_in_progress) > 0) return 0; + node_id = zone->zone_pgdat->node_id; + mask = node_to_cpumask(node_id); + if (!cpus_empty(mask) && node_id != numa_node_id()) + return 0; + sc.may_writepage = 0; sc.may_swap = 0; sc.nr_scanned = 0; From 79046ae07ae21245520ca0aab985ee6678a879f8 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 1 Feb 2006 03:05:26 -0800 Subject: [PATCH 367/695] [PATCH] GFP_ZONETYPES: add commentry on how to calculate GFP_ZONETYPES define using GFP_ZONEMASK and add commentry Add commentry explaining the optimisation that we can apply to GFP_ZONETYPES when the leftmost bit is a 'loaner', it can only be set in isolation. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 93a849f742db..88c30f844abf 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -91,6 +91,14 @@ struct per_cpu_pageset { * be 8 (2 ** 3) zonelists. GFP_ZONETYPES defines the number of possible * combinations of zone modifiers in "zone modifier space". * + * As an optimisation any zone modifier bits which are only valid when + * no other zone modifier bits are set (loners) should be placed in + * the highest order bits of this field. This allows us to reduce the + * extent of the zonelists thus saving space. For example in the case + * of three zone modifier bits, we could require up to eight zonelists. + * If the left most zone modifier is a "loner" then the highest valid + * zonelist would be four allowing us to allocate only five zonelists. + * * NOTE! Make sure this matches the zones in */ #define GFP_ZONEMASK 0x07 From ce2ea89ba101d976907128441ba3aca72a8804b9 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 1 Feb 2006 03:05:27 -0800 Subject: [PATCH 368/695] [PATCH] GFP_ZONETYPES: calculate from GFP_ZONEMASK GFP_ZONETYPES calculate from GFP_ZONEMASK GFP_ZONETYPES's value is directly related to the value of GFP_ZONEMASK. It takes one of two forms depending whether the top bit of GFP_ZONEMASK is a 'loner'. Supply both forms, enabling the loner. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 88c30f844abf..ebfc238cc243 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -98,11 +98,14 @@ struct per_cpu_pageset { * of three zone modifier bits, we could require up to eight zonelists. * If the left most zone modifier is a "loner" then the highest valid * zonelist would be four allowing us to allocate only five zonelists. + * Use the first form for GFP_ZONETYPES when the left most bit is not + * a "loner", otherwise use the second. * * NOTE! Make sure this matches the zones in */ #define GFP_ZONEMASK 0x07 -#define GFP_ZONETYPES 5 +/* #define GFP_ZONETYPES (GFP_ZONEMASK + 1) */ /* Non-loner */ +#define GFP_ZONETYPES ((GFP_ZONEMASK + 1) / 2 + 1) /* Loner */ /* * On machines where it is needed (eg PCs) we divide physical memory From 52a8363eae3872af15880292ff4e06d0fab36986 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:28 -0800 Subject: [PATCH 369/695] [PATCH] mm: improve function of sc->may_writepage Make sc->may_writepage control the writeout behavior of shrink_list. Remove the laptop_mode trick from shrink_list and instead set may_writepage in try_to_free_pages properly. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 0ca6007d655b..a29efb2c06c8 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -492,7 +492,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc) goto keep_locked; if (!may_enter_fs) goto keep_locked; - if (laptop_mode && !sc->may_writepage) + if (!sc->may_writepage) goto keep_locked; /* Page is dirty, try to write it out here */ @@ -1170,7 +1170,7 @@ int try_to_free_pages(struct zone **zones, gfp_t gfp_mask) int i; sc.gfp_mask = gfp_mask; - sc.may_writepage = 0; + sc.may_writepage = !laptop_mode; sc.may_swap = 1; inc_page_state(allocstall); @@ -1273,7 +1273,7 @@ loop_again: total_scanned = 0; total_reclaimed = 0; sc.gfp_mask = GFP_KERNEL; - sc.may_writepage = 0; + sc.may_writepage = !laptop_mode; sc.may_swap = 1; sc.nr_mapped = read_page_state(nr_mapped); From c84db23c6e587d3ab00a41c51fedf758e1f6ecd4 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:29 -0800 Subject: [PATCH 370/695] [PATCH] zone_reclaim: minor fixes - If we only reclaim nr_pages then its okay to stay on node. Switch from > to >= for the comparison. - vm_table[] entry for zone_reclaim_mode is a bit screwed up. - Add empty lines around shrink_zone to show that this is the central function to be called. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/sysctl.c | 3 ++- mm/vmscan.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index cb99a42f8b37..c74f03bc0144 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -878,7 +878,8 @@ static ctl_table vm_table[] = { .maxlen = sizeof(zone_reclaim_mode), .mode = 0644, .proc_handler = &proc_dointvec, - .strategy = &zero, + .strategy = &sysctl_intvec, + .extra1 = &zero, }, #endif { .ctl_name = 0 } diff --git a/mm/vmscan.c b/mm/vmscan.c index a29efb2c06c8..61ca0097c834 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1636,14 +1636,16 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) p->flags |= PF_MEMALLOC; reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; + shrink_zone(zone, &sc); + p->reclaim_state = NULL; current->flags &= ~PF_MEMALLOC; if (sc.nr_reclaimed == 0) zone->last_unsuccessful_zone_reclaim = jiffies; - return sc.nr_reclaimed > nr_pages; + return sc.nr_reclaimed >= nr_pages; } #endif From 9884fd8df195fe48d4e1be2279b419be96127cae Mon Sep 17 00:00:00 2001 From: Benjamin LaHaise Date: Wed, 1 Feb 2006 03:05:30 -0800 Subject: [PATCH 371/695] [PATCH] Use 32 bit division in slab_put_obj() Improve the performance of slab_put_obj(). Without the cast, gcc considers ptrdiff_t a 64 bit signed integer and ends up emitting code to use a full signed 128 bit divide on EM64T, which is substantially slower than a 32 bit unsigned divide. I noticed this when looking at the profile of a case where the slab balance is just on edge and thrashes back and forth freeing a block. Signed-off-by: Benjamin LaHaise Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 6f8495e2185b..88082ae15736 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1398,7 +1398,7 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp) struct slab *slabp = page_get_slab(virt_to_page(objp)); int objnr; - objnr = (objp - slabp->s_mem) / cachep->objsize; + objnr = (unsigned)(objp - slabp->s_mem) / cachep->objsize; if (objnr) { objp = slabp->s_mem + (objnr - 1) * cachep->objsize; realobj = (char *)objp + obj_dbghead(cachep); @@ -2341,7 +2341,7 @@ static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp, if (cachep->flags & SLAB_STORE_USER) *dbg_userword(cachep, objp) = caller; - objnr = (objp - slabp->s_mem) / cachep->objsize; + objnr = (unsigned)(objp - slabp->s_mem) / cachep->objsize; BUG_ON(objnr >= cachep->num); BUG_ON(objp != slabp->s_mem + objnr * cachep->objsize); @@ -2699,7 +2699,7 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, slabp = page_get_slab(virt_to_page(objp)); l3 = cachep->nodelists[node]; list_del(&slabp->list); - objnr = (objp - slabp->s_mem) / cachep->objsize; + objnr = (unsigned)(objp - slabp->s_mem) / cachep->objsize; check_spinlock_acquired_node(cachep, node); check_slabp(cachep, slabp); From 4e6a510a74145585f4111d60d1b5fd450d795dd8 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Wed, 1 Feb 2006 03:05:31 -0800 Subject: [PATCH 372/695] [PATCH] mm: hugepage accounting fix 2.6.15's hugepage faulting introduced huge_pages_needed accounting into hugetlbfs: to count how many pages are already in cache, for spot check on how far a new mapping may be allowed to extend the file. But it's muddled: each hugepage found covers HPAGE_SIZE, not PAGE_SIZE. Once pages were already in cache, it would overshoot, wrap its hugepages count backwards, and so fail a harmless repeat mapping with -ENOMEM. Fixes the problem found by Don Dupuis. Signed-off-by: Hugh Dickins Acked-By: Adam Litke Acked-by: William Irwin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/hugetlbfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index f568102da1e8..b35195289945 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -72,8 +72,8 @@ huge_pages_needed(struct address_space *mapping, struct vm_area_struct *vma) unsigned long start = vma->vm_start; unsigned long end = vma->vm_end; unsigned long hugepages = (end - start) >> HPAGE_SHIFT; - pgoff_t next = vma->vm_pgoff; - pgoff_t endpg = next + ((end - start) >> PAGE_SHIFT); + pgoff_t next = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT); + pgoff_t endpg = next + hugepages; pagevec_init(&pvec, 0); while (next < endpg) { From aa3f18b3391ac305baa01faead3fdf9147daf54b Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:32 -0800 Subject: [PATCH 373/695] [PATCH] zone_reclaim: do not unmap file backed pages zone_reclaim should leave that to the real swapper. We are only interested in evicting unmapped pages. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index 61ca0097c834..8277f93148b5 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -477,6 +477,12 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc) * processes. Try to unmap it here. */ if (page_mapped(page) && mapping) { + /* + * No unmapping if we do not swap + */ + if (!sc->may_swap) + goto keep_locked; + switch (try_to_unmap(page)) { case SWAP_FAIL: goto activate_locked; From a92f71263af9d0ab77c260f709c0c079656221aa Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:32 -0800 Subject: [PATCH 374/695] [PATCH] zone_reclaim: partial scans instead of full scan Instead of scanning all the pages in a zone, imitate real swap and scan only a portion of the pages and gradually scan more if we do not free up enough pages. This avoids a zone suddenly loosing all unused pagecache pages (we may after all access some of these again so they deserve another chance) but it still frees up large chunks of memory if a zone only contains unused pagecache pages. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 8277f93148b5..f8b94ea6f722 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1596,6 +1596,14 @@ int zone_reclaim_mode __read_mostly; * Mininum time between zone reclaim scans */ #define ZONE_RECLAIM_INTERVAL 30*HZ + +/* + * Priority for ZONE_RECLAIM. This determines the fraction of pages + * of a node considered for each zone_reclaim. 4 scans 1/16th of + * a zone. + */ +#define ZONE_RECLAIM_PRIORITY 4 + /* * Try to free up some pages from this zone through reclaim. */ @@ -1626,7 +1634,7 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) sc.may_swap = 0; sc.nr_scanned = 0; sc.nr_reclaimed = 0; - sc.priority = 0; + sc.priority = ZONE_RECLAIM_PRIORITY + 1; sc.nr_mapped = read_page_state(nr_mapped); sc.gfp_mask = gfp_mask; @@ -1643,7 +1651,15 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; - shrink_zone(zone, &sc); + /* + * Free memory by calling shrink zone with increasing priorities + * until we have enough memory freed. + */ + do { + sc.priority--; + shrink_zone(zone, &sc); + + } while (sc.nr_reclaimed < nr_pages && sc.priority > 0); p->reclaim_state = NULL; current->flags &= ~PF_MEMALLOC; From 2a11ff06d7d12be5d1bbcf592fff649b45ac2388 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:33 -0800 Subject: [PATCH 375/695] [PATCH] zone_reclaim: configurable off node allocation period. Currently the zone_reclaim code has a fixed window of 30 seconds of off node allocations should a local zone have no unused pagecache pages left. Reclaim will be attempted again after this timeout period to avoid repeated useless scans for memory. This is also useful to established sufficiently large off node allocation chunks to relieve the local node. It may be beneficial to adjust that time period for some special situations. For example if memory use was exceeding node capacity one may want to give up for longer periods of time. If memory spikes intermittendly then one may want to shorten the time period to reduce the number of off node allocations. This patch allows just that.... Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sysctl/vm.txt | 12 ++++++++++++ include/linux/swap.h | 1 + include/linux/sysctl.h | 3 ++- kernel/sysctl.c | 9 +++++++++ mm/vmscan.c | 4 ++-- 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 391dd64363e7..44518c023949 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -28,6 +28,7 @@ Currently, these files are in /proc/sys/vm: - block_dump - drop-caches - zone_reclaim_mode +- zone_reclaim_interval ============================================================== @@ -137,4 +138,15 @@ of memory should be used for caching files from disk. It may be beneficial to switch this on if one wants to do zone reclaim regardless of the numa distances in the system. +================================================================ + +zone_reclaim_interval: + +The time allowed for off node allocations after zone reclaim +has failed to reclaim enough pages to allow a local allocation. + +Time is set in seconds and set by default to 30 seconds. + +Reduce the interval if undesired off node allocations occur. However, too +frequent scans will have a negative impact onoff node allocation performance. diff --git a/include/linux/swap.h b/include/linux/swap.h index 4a99e4a7fbf3..e53fef7051e6 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -178,6 +178,7 @@ extern int vm_swappiness; #ifdef CONFIG_NUMA extern int zone_reclaim_mode; +extern int zone_reclaim_interval; extern int zone_reclaim(struct zone *, gfp_t, unsigned int); #else #define zone_reclaim_mode 0 diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 8352a7ce5895..32a4139c4ad8 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -182,7 +182,8 @@ enum VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */ VM_DROP_PAGECACHE=29, /* int: nuke lots of pagecache */ VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */ - VM_ZONE_RECLAIM_MODE=31,/* reclaim local zone memory before going off node */ + VM_ZONE_RECLAIM_MODE=31, /* reclaim local zone memory before going off node */ + VM_ZONE_RECLAIM_INTERVAL=32, /* time period to wait after reclaim failure */ }; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c74f03bc0144..71dd6f62efec 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -881,6 +881,15 @@ static ctl_table vm_table[] = { .strategy = &sysctl_intvec, .extra1 = &zero, }, + { + .ctl_name = VM_ZONE_RECLAIM_INTERVAL, + .procname = "zone_reclaim_interval", + .data = &zone_reclaim_interval, + .maxlen = sizeof(zone_reclaim_interval), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, + }, #endif { .ctl_name = 0 } }; diff --git a/mm/vmscan.c b/mm/vmscan.c index f8b94ea6f722..8760a4abfa1f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1595,7 +1595,7 @@ int zone_reclaim_mode __read_mostly; /* * Mininum time between zone reclaim scans */ -#define ZONE_RECLAIM_INTERVAL 30*HZ +int zone_reclaim_interval __read_mostly = 30*HZ; /* * Priority for ZONE_RECLAIM. This determines the fraction of pages @@ -1617,7 +1617,7 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) int node_id; if (time_before(jiffies, - zone->last_unsuccessful_zone_reclaim + ZONE_RECLAIM_INTERVAL)) + zone->last_unsuccessful_zone_reclaim + zone_reclaim_interval)) return 0; if (!(gfp_mask & __GFP_WAIT) || From 1b2ffb7896ad46067f5b9ebf7de1891d74a4cdef Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:34 -0800 Subject: [PATCH 376/695] [PATCH] Zone reclaim: Allow modification of zone reclaim behavior In some situations one may want zone_reclaim to behave differently. For example a process writing large amounts of memory will spew unto other nodes to cache the writes if many pages in a zone become dirty. This may impact the performance of processes running on other nodes. Allowing writes during reclaim puts a stop to that behavior and throttles the process by restricting the pages to the local zone. Similarly one may want to contain processes to local memory by enabling regular swap behavior during zone_reclaim. Off node memory allocation can then be controlled through memory policies and cpusets. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sysctl/vm.txt | 38 +++++++++++++++++++++++++++++-------- mm/vmscan.c | 9 +++++++-- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 44518c023949..4bca2a3d9174 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -127,17 +127,39 @@ the high water marks for each per cpu page list. zone_reclaim_mode: -This is set during bootup to 1 if it is determined that pages from -remote zones will cause a significant performance reduction. The +Zone_reclaim_mode allows to set more or less agressive approaches to +reclaim memory when a zone runs out of memory. If it is set to zero then no +zone reclaim occurs. Allocations will be satisfied from other zones / nodes +in the system. + +This is value ORed together of + +1 = Zone reclaim on +2 = Zone reclaim writes dirty pages out +4 = Zone reclaim swaps pages + +zone_reclaim_mode is set during bootup to 1 if it is determined that pages +from remote zones will cause a measurable performance reduction. The page allocator will then reclaim easily reusable pages (those page -cache pages that are currently not used) before going off node. +cache pages that are currently not used) before allocating off node pages. -The user can override this setting. It may be beneficial to switch -off zone reclaim if the system is used for a file server and all -of memory should be used for caching files from disk. +It may be beneficial to switch off zone reclaim if the system is +used for a file server and all of memory should be used for caching files +from disk. In that case the caching effect is more important than +data locality. + +Allowing zone reclaim to write out pages stops processes that are +writing large amounts of data from dirtying pages on other nodes. Zone +reclaim will write out dirty pages if a zone fills up and so effectively +throttle the process. This may decrease the performance of a single process +since it cannot use all of system memory to buffer the outgoing writes +anymore but it preserve the memory on other nodes so that the performance +of other processes running on other nodes will not be affected. + +Allowing regular swap effectively restricts allocations to the local +node unless explicitly overridden by memory policies or cpuset +configurations. -It may be beneficial to switch this on if one wants to do zone -reclaim regardless of the numa distances in the system. ================================================================ zone_reclaim_interval: diff --git a/mm/vmscan.c b/mm/vmscan.c index 8760a4abfa1f..9e2ef3624d77 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1592,6 +1592,11 @@ module_init(kswapd_init) */ int zone_reclaim_mode __read_mostly; +#define RECLAIM_OFF 0 +#define RECLAIM_ZONE (1<<0) /* Run shrink_cache on the zone */ +#define RECLAIM_WRITE (1<<1) /* Writeout pages during reclaim */ +#define RECLAIM_SWAP (1<<2) /* Swap pages out during reclaim */ + /* * Mininum time between zone reclaim scans */ @@ -1630,8 +1635,8 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) if (!cpus_empty(mask) && node_id != numa_node_id()) return 0; - sc.may_writepage = 0; - sc.may_swap = 0; + sc.may_writepage = !!(zone_reclaim_mode & RECLAIM_WRITE); + sc.may_swap = !!(zone_reclaim_mode & RECLAIM_SWAP); sc.nr_scanned = 0; sc.nr_reclaimed = 0; sc.priority = ZONE_RECLAIM_PRIORITY + 1; From 2a16e3f4b0c408b9e50297d2ec27e295d490267a Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:35 -0800 Subject: [PATCH 377/695] [PATCH] Reclaim slab during zone reclaim If large amounts of zone memory are used by empty slabs then zone_reclaim becomes uneffective. This patch shakes the slab a bit. The problem with this patch is that the slab reclaim is not containable to a zone. Thus slab reclaim may affect the whole system and be extremely slow. This also means that we cannot determine how many pages were freed in this zone. Thus we need to go off node for at least one allocation. The functionality is disabled by default. We could modify the shrinkers to take a zone parameter but that would be quite invasive. Better ideas are welcome. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sysctl/vm.txt | 6 ++++++ mm/vmscan.c | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 4bca2a3d9174..a46c10fcddfc 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -137,6 +137,7 @@ This is value ORed together of 1 = Zone reclaim on 2 = Zone reclaim writes dirty pages out 4 = Zone reclaim swaps pages +8 = Also do a global slab reclaim pass zone_reclaim_mode is set during bootup to 1 if it is determined that pages from remote zones will cause a measurable performance reduction. The @@ -160,6 +161,11 @@ Allowing regular swap effectively restricts allocations to the local node unless explicitly overridden by memory policies or cpuset configurations. +It may be advisable to allow slab reclaim if the system makes heavy +use of files and builds up large slab caches. However, the slab +shrink operation is global, may take a long time and free slabs +in all nodes of the system. + ================================================================ zone_reclaim_interval: diff --git a/mm/vmscan.c b/mm/vmscan.c index 9e2ef3624d77..aa4b80dbe3ad 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1596,6 +1596,7 @@ int zone_reclaim_mode __read_mostly; #define RECLAIM_ZONE (1<<0) /* Run shrink_cache on the zone */ #define RECLAIM_WRITE (1<<1) /* Writeout pages during reclaim */ #define RECLAIM_SWAP (1<<2) /* Swap pages out during reclaim */ +#define RECLAIM_SLAB (1<<3) /* Do a global slab shrink if the zone is out of memory */ /* * Mininum time between zone reclaim scans @@ -1666,6 +1667,19 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) } while (sc.nr_reclaimed < nr_pages && sc.priority > 0); + if (sc.nr_reclaimed < nr_pages && (zone_reclaim_mode & RECLAIM_SLAB)) { + /* + * shrink_slab does not currently allow us to determine + * how many pages were freed in the zone. So we just + * shake the slab and then go offnode for a single allocation. + * + * shrink_slab will free memory on all zones and may take + * a long time. + */ + shrink_slab(sc.nr_scanned, gfp_mask, order); + sc.nr_reclaimed = 1; /* Avoid getting the off node timeout */ + } + p->reclaim_state = NULL; current->flags &= ~PF_MEMALLOC; From b16664e44c54525be89dc07ad15a13b4eeec5634 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:36 -0800 Subject: [PATCH 378/695] [PATCH] Direct Migration V9: PageSwapCache checks Check for PageSwapCache after looking up and locking a swap page. The page migration code may change a swap pte to point to a different page under lock_page(). If that happens then the vm must retry the lookup operation in the swap space to find the correct page number. There are a couple of locations in the VM where a lock_page() is done on a swap page. In these locations we need to check afterwards if the page was migrated. If the page was migrated then the old page that was looked up before was freed and no longer has the PageSwapCache bit set. Signed-off-by: Hirokazu Takahashi Signed-off-by: Dave Hansen Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 7 +++++++ mm/shmem.c | 8 ++++++++ mm/swapfile.c | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/mm/memory.c b/mm/memory.c index 7a11ddd5060f..2bee1f21aa8a 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1871,6 +1871,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, goto out; entry = pte_to_swp_entry(orig_pte); +again: page = lookup_swap_cache(entry); if (!page) { swapin_readahead(entry, address, vma); @@ -1894,6 +1895,12 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, mark_page_accessed(page); lock_page(page); + if (!PageSwapCache(page)) { + /* Page migration has occured */ + unlock_page(page); + page_cache_release(page); + goto again; + } /* * Back out if somebody else already faulted in this pte. diff --git a/mm/shmem.c b/mm/shmem.c index ce501bce1c2e..f7ac7b812f92 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1028,6 +1028,14 @@ repeat: page_cache_release(swappage); goto repeat; } + if (!PageSwapCache(swappage)) { + /* Page migration has occured */ + shmem_swp_unmap(entry); + spin_unlock(&info->lock); + unlock_page(swappage); + page_cache_release(swappage); + goto repeat; + } if (PageWriteback(swappage)) { shmem_swp_unmap(entry); spin_unlock(&info->lock); diff --git a/mm/swapfile.c b/mm/swapfile.c index f1e69c30d203..9678182e0eef 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -646,6 +646,7 @@ static int try_to_unuse(unsigned int type) */ swap_map = &si->swap_map[i]; entry = swp_entry(type, i); +again: page = read_swap_cache_async(entry, NULL, 0); if (!page) { /* @@ -680,6 +681,12 @@ static int try_to_unuse(unsigned int type) wait_on_page_locked(page); wait_on_page_writeback(page); lock_page(page); + if (!PageSwapCache(page)) { + /* Page migration has occured */ + unlock_page(page); + page_cache_release(page); + goto again; + } wait_on_page_writeback(page); /* From a48d07afdf18212de22b959715b16793c5a6e57a Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:38 -0800 Subject: [PATCH 379/695] [PATCH] Direct Migration V9: migrate_pages() extension Add direct migration support with fall back to swap. Direct migration support on top of the swap based page migration facility. This allows the direct migration of anonymous pages and the migration of file backed pages by dropping the associated buffers (requires writeout). Fall back to swap out if necessary. The patch is based on lots of patches from the hotplug project but the code was restructured, documented and simplified as much as possible. Note that an additional patch that defines the migrate_page() method for filesystems is necessary in order to avoid writeback for anonymous and file backed pages. Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: Mike Kravetz Signed-off-by: Christoph Lameter Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/vm/page_migration | 129 ++++++++++++++++++ include/linux/rmap.h | 4 +- include/linux/swap.h | 2 + mm/rmap.c | 21 +-- mm/vmscan.c | 226 ++++++++++++++++++++++++++++++-- 5 files changed, 360 insertions(+), 22 deletions(-) create mode 100644 Documentation/vm/page_migration diff --git a/Documentation/vm/page_migration b/Documentation/vm/page_migration new file mode 100644 index 000000000000..c52820fcf500 --- /dev/null +++ b/Documentation/vm/page_migration @@ -0,0 +1,129 @@ +Page migration +-------------- + +Page migration allows the moving of the physical location of pages between +nodes in a numa system while the process is running. This means that the +virtual addresses that the process sees do not change. However, the +system rearranges the physical location of those pages. + +The main intend of page migration is to reduce the latency of memory access +by moving pages near to the processor where the process accessing that memory +is running. + +Page migration allows a process to manually relocate the node on which its +pages are located through the MF_MOVE and MF_MOVE_ALL options while setting +a new memory policy. The pages of process can also be relocated +from another process using the sys_migrate_pages() function call. The +migrate_pages function call takes two sets of nodes and moves pages of a +process that are located on the from nodes to the destination nodes. + +Manual migration is very useful if for example the scheduler has relocated +a process to a processor on a distant node. A batch scheduler or an +administrator may detect the situation and move the pages of the process +nearer to the new processor. At some point in the future we may have +some mechanism in the scheduler that will automatically move the pages. + +Larger installations usually partition the system using cpusets into +sections of nodes. Paul Jackson has equipped cpusets with the ability to +move pages when a task is moved to another cpuset. This allows automatic +control over locality of a process. If a task is moved to a new cpuset +then also all its pages are moved with it so that the performance of the +process does not sink dramatically (as is the case today). + +Page migration allows the preservation of the relative location of pages +within a group of nodes for all migration techniques which will preserve a +particular memory allocation pattern generated even after migrating a +process. This is necessary in order to preserve the memory latencies. +Processes will run with similar performance after migration. + +Page migration occurs in several steps. First a high level +description for those trying to use migrate_pages() and then +a low level description of how the low level details work. + +A. Use of migrate_pages() +------------------------- + +1. Remove pages from the LRU. + + Lists of pages to be migrated are generated by scanning over + pages and moving them into lists. This is done by + calling isolate_lru_page() or __isolate_lru_page(). + Calling isolate_lru_page increases the references to the page + so that it cannot vanish under us. + +2. Generate a list of newly allocates page to move the contents + of the first list to. + +3. The migrate_pages() function is called which attempts + to do the migration. It returns the moved pages in the + list specified as the third parameter and the failed + migrations in the fourth parameter. The first parameter + will contain the pages that could still be retried. + +4. The leftover pages of various types are returned + to the LRU using putback_to_lru_pages() or otherwise + disposed of. The pages will still have the refcount as + increased by isolate_lru_pages()! + +B. Operation of migrate_pages() +-------------------------------- + +migrate_pages does several passes over its list of pages. A page is moved +if all references to a page are removable at the time. + +Steps: + +1. Lock the page to be migrated + +2. Insure that writeback is complete. + +3. Make sure that the page has assigned swap cache entry if + it is an anonyous page. The swap cache reference is necessary + to preserve the information contain in the page table maps. + +4. Prep the new page that we want to move to. It is locked + and set to not being uptodate so that all accesses to the new + page immediately lock while we are moving references. + +5. All the page table references to the page are either dropped (file backed) + or converted to swap references (anonymous pages). This should decrease the + reference count. + +6. The radix tree lock is taken + +7. The refcount of the page is examined and we back out if references remain + otherwise we know that we are the only one referencing this page. + +8. The radix tree is checked and if it does not contain the pointer to this + page then we back out. + +9. The mapping is checked. If the mapping is gone then a truncate action may + be in progress and we back out. + +10. The new page is prepped with some settings from the old page so that accesses + to the new page will be discovered to have the correct settings. + +11. The radix tree is changed to point to the new page. + +12. The reference count of the old page is dropped because the reference has now + been removed. + +13. The radix tree lock is dropped. + +14. The page contents are copied to the new page. + +15. The remaining page flags are copied to the new page. + +16. The old page flags are cleared to indicate that the page does + not use any information anymore. + +17. Queued up writeback on the new page is triggered. + +18. If swap pte's were generated for the page then remove them again. + +19. The locks are dropped from the old and new page. + +20. The new page is moved to the LRU. + +Christoph Lameter, December 19, 2005. + diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 9d6fbeef2104..0f1ea2d6ed86 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -91,7 +91,7 @@ static inline void page_dup_rmap(struct page *page) * Called from mm/vmscan.c to handle paging out */ int page_referenced(struct page *, int is_locked); -int try_to_unmap(struct page *); +int try_to_unmap(struct page *, int ignore_refs); /* * Called from mm/filemap_xip.c to unmap empty zero page @@ -111,7 +111,7 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); #define anon_vma_link(vma) do {} while (0) #define page_referenced(page,l) TestClearPageReferenced(page) -#define try_to_unmap(page) SWAP_FAIL +#define try_to_unmap(page, refs) SWAP_FAIL #endif /* CONFIG_MMU */ diff --git a/include/linux/swap.h b/include/linux/swap.h index e53fef7051e6..d359fc022433 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -191,6 +191,8 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order) #ifdef CONFIG_MIGRATION extern int isolate_lru_page(struct page *p); extern int putback_lru_pages(struct list_head *l); +extern int migrate_page(struct page *, struct page *); +extern void migrate_page_copy(struct page *, struct page *); extern int migrate_pages(struct list_head *l, struct list_head *t, struct list_head *moved, struct list_head *failed); #else diff --git a/mm/rmap.c b/mm/rmap.c index d85a99d28c03..13fad5fcdf79 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -52,6 +52,7 @@ #include #include #include +#include #include @@ -541,7 +542,8 @@ void page_remove_rmap(struct page *page) * Subfunctions of try_to_unmap: try_to_unmap_one called * repeatedly from either try_to_unmap_anon or try_to_unmap_file. */ -static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) +static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, + int ignore_refs) { struct mm_struct *mm = vma->vm_mm; unsigned long address; @@ -564,7 +566,8 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) * skipped over this mm) then we should reactivate it. */ if ((vma->vm_flags & VM_LOCKED) || - ptep_clear_flush_young(vma, address, pte)) { + (ptep_clear_flush_young(vma, address, pte) + && !ignore_refs)) { ret = SWAP_FAIL; goto out_unmap; } @@ -698,7 +701,7 @@ static void try_to_unmap_cluster(unsigned long cursor, pte_unmap_unlock(pte - 1, ptl); } -static int try_to_unmap_anon(struct page *page) +static int try_to_unmap_anon(struct page *page, int ignore_refs) { struct anon_vma *anon_vma; struct vm_area_struct *vma; @@ -709,7 +712,7 @@ static int try_to_unmap_anon(struct page *page) return ret; list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { - ret = try_to_unmap_one(page, vma); + ret = try_to_unmap_one(page, vma, ignore_refs); if (ret == SWAP_FAIL || !page_mapped(page)) break; } @@ -726,7 +729,7 @@ static int try_to_unmap_anon(struct page *page) * * This function is only called from try_to_unmap for object-based pages. */ -static int try_to_unmap_file(struct page *page) +static int try_to_unmap_file(struct page *page, int ignore_refs) { struct address_space *mapping = page->mapping; pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); @@ -740,7 +743,7 @@ static int try_to_unmap_file(struct page *page) spin_lock(&mapping->i_mmap_lock); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { - ret = try_to_unmap_one(page, vma); + ret = try_to_unmap_one(page, vma, ignore_refs); if (ret == SWAP_FAIL || !page_mapped(page)) goto out; } @@ -825,16 +828,16 @@ out: * SWAP_AGAIN - we missed a mapping, try again later * SWAP_FAIL - the page is unswappable */ -int try_to_unmap(struct page *page) +int try_to_unmap(struct page *page, int ignore_refs) { int ret; BUG_ON(!PageLocked(page)); if (PageAnon(page)) - ret = try_to_unmap_anon(page); + ret = try_to_unmap_anon(page, ignore_refs); else - ret = try_to_unmap_file(page); + ret = try_to_unmap_file(page, ignore_refs); if (!page_mapped(page)) ret = SWAP_SUCCESS; diff --git a/mm/vmscan.c b/mm/vmscan.c index aa4b80dbe3ad..8f326ce2b690 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -483,7 +483,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc) if (!sc->may_swap) goto keep_locked; - switch (try_to_unmap(page)) { + switch (try_to_unmap(page, 0)) { case SWAP_FAIL: goto activate_locked; case SWAP_AGAIN: @@ -623,7 +623,7 @@ static int swap_page(struct page *page) struct address_space *mapping = page_mapping(page); if (page_mapped(page) && mapping) - if (try_to_unmap(page) != SWAP_SUCCESS) + if (try_to_unmap(page, 0) != SWAP_SUCCESS) goto unlock_retry; if (PageDirty(page)) { @@ -659,6 +659,154 @@ unlock_retry: retry: return -EAGAIN; } + +/* + * Page migration was first developed in the context of the memory hotplug + * project. The main authors of the migration code are: + * + * IWAMOTO Toshihiro + * Hirokazu Takahashi + * Dave Hansen + * Christoph Lameter + */ + +/* + * Remove references for a page and establish the new page with the correct + * basic settings to be able to stop accesses to the page. + */ +static int migrate_page_remove_references(struct page *newpage, + struct page *page, int nr_refs) +{ + struct address_space *mapping = page_mapping(page); + struct page **radix_pointer; + + /* + * Avoid doing any of the following work if the page count + * indicates that the page is in use or truncate has removed + * the page. + */ + if (!mapping || page_mapcount(page) + nr_refs != page_count(page)) + return 1; + + /* + * Establish swap ptes for anonymous pages or destroy pte + * maps for files. + * + * In order to reestablish file backed mappings the fault handlers + * will take the radix tree_lock which may then be used to stop + * processses from accessing this page until the new page is ready. + * + * A process accessing via a swap pte (an anonymous page) will take a + * page_lock on the old page which will block the process until the + * migration attempt is complete. At that time the PageSwapCache bit + * will be examined. If the page was migrated then the PageSwapCache + * bit will be clear and the operation to retrieve the page will be + * retried which will find the new page in the radix tree. Then a new + * direct mapping may be generated based on the radix tree contents. + * + * If the page was not migrated then the PageSwapCache bit + * is still set and the operation may continue. + */ + try_to_unmap(page, 1); + + /* + * Give up if we were unable to remove all mappings. + */ + if (page_mapcount(page)) + return 1; + + write_lock_irq(&mapping->tree_lock); + + radix_pointer = (struct page **)radix_tree_lookup_slot( + &mapping->page_tree, + page_index(page)); + + if (!page_mapping(page) || page_count(page) != nr_refs || + *radix_pointer != page) { + write_unlock_irq(&mapping->tree_lock); + return 1; + } + + /* + * Now we know that no one else is looking at the page. + * + * Certain minimal information about a page must be available + * in order for other subsystems to properly handle the page if they + * find it through the radix tree update before we are finished + * copying the page. + */ + get_page(newpage); + newpage->index = page->index; + newpage->mapping = page->mapping; + if (PageSwapCache(page)) { + SetPageSwapCache(newpage); + set_page_private(newpage, page_private(page)); + } + + *radix_pointer = newpage; + __put_page(page); + write_unlock_irq(&mapping->tree_lock); + + return 0; +} + +/* + * Copy the page to its new location + */ +void migrate_page_copy(struct page *newpage, struct page *page) +{ + copy_highpage(newpage, page); + + if (PageError(page)) + SetPageError(newpage); + if (PageReferenced(page)) + SetPageReferenced(newpage); + if (PageUptodate(page)) + SetPageUptodate(newpage); + if (PageActive(page)) + SetPageActive(newpage); + if (PageChecked(page)) + SetPageChecked(newpage); + if (PageMappedToDisk(page)) + SetPageMappedToDisk(newpage); + + if (PageDirty(page)) { + clear_page_dirty_for_io(page); + set_page_dirty(newpage); + } + + ClearPageSwapCache(page); + ClearPageActive(page); + ClearPagePrivate(page); + set_page_private(page, 0); + page->mapping = NULL; + + /* + * If any waiters have accumulated on the new page then + * wake them up. + */ + if (PageWriteback(newpage)) + end_page_writeback(newpage); +} + +/* + * Common logic to directly migrate a single page suitable for + * pages that do not use PagePrivate. + * + * Pages are locked upon entry and exit. + */ +int migrate_page(struct page *newpage, struct page *page) +{ + BUG_ON(PageWriteback(page)); /* Writeback must be complete */ + + if (migrate_page_remove_references(newpage, page, 2)) + return -EAGAIN; + + migrate_page_copy(newpage, page); + + return 0; +} + /* * migrate_pages * @@ -672,11 +820,6 @@ retry: * are movable anymore because t has become empty * or no retryable pages exist anymore. * - * SIMPLIFIED VERSION: This implementation of migrate_pages - * is only swapping out pages and never touches the second - * list. The direct migration patchset - * extends this function to avoid the use of swap. - * * Return: Number of pages not migrated when "to" ran empty. */ int migrate_pages(struct list_head *from, struct list_head *to, @@ -697,6 +840,9 @@ redo: retry = 0; list_for_each_entry_safe(page, page2, from, lru) { + struct page *newpage = NULL; + struct address_space *mapping; + cond_resched(); rc = 0; @@ -704,6 +850,9 @@ redo: /* page was freed from under us. So we are done. */ goto next; + if (to && list_empty(to)) + break; + /* * Skip locked pages during the first two passes to give the * functions holding the lock time to release the page. Later we @@ -740,12 +889,64 @@ redo: } } + if (!to) { + rc = swap_page(page); + goto next; + } + + newpage = lru_to_page(to); + lock_page(newpage); + /* - * Page is properly locked and writeback is complete. + * Pages are properly locked and writeback is complete. * Try to migrate the page. */ - rc = swap_page(page); - goto next; + mapping = page_mapping(page); + if (!mapping) + goto unlock_both; + + /* + * Trigger writeout if page is dirty + */ + if (PageDirty(page)) { + switch (pageout(page, mapping)) { + case PAGE_KEEP: + case PAGE_ACTIVATE: + goto unlock_both; + + case PAGE_SUCCESS: + unlock_page(newpage); + goto next; + + case PAGE_CLEAN: + ; /* try to migrate the page below */ + } + } + /* + * If we have no buffer or can release the buffer + * then do a simple migration. + */ + if (!page_has_buffers(page) || + try_to_release_page(page, GFP_KERNEL)) { + rc = migrate_page(newpage, page); + goto unlock_both; + } + + /* + * On early passes with mapped pages simply + * retry. There may be a lock held for some + * buffers that may go away. Later + * swap them out. + */ + if (pass > 4) { + unlock_page(newpage); + newpage = NULL; + rc = swap_page(page); + goto next; + } + +unlock_both: + unlock_page(newpage); unlock_page: unlock_page(page); @@ -758,7 +959,10 @@ next: list_move(&page->lru, failed); nr_failed++; } else { - /* Success */ + if (newpage) { + /* Successful migration. Return page to LRU */ + move_to_lru(newpage); + } list_move(&page->lru, moved); } } From a3351e525e4768c29aa5d22ef59b5b38e0361e53 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:39 -0800 Subject: [PATCH 380/695] [PATCH] Direct Migration V9: remove_from_swap() to remove swap ptes Add remove_from_swap remove_from_swap() allows the restoration of the pte entries that existed before page migration occurred for anonymous pages by walking the reverse maps. This reduces swap use and establishes regular pte's without the need for page faults. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rmap.h | 1 + include/linux/swap.h | 1 + mm/rmap.c | 29 +++++++++++++++++++++++++++++ mm/swapfile.c | 9 +++++++++ mm/vmscan.c | 9 +++++++++ 5 files changed, 49 insertions(+) diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 0f1ea2d6ed86..d6b9bcd1384c 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -92,6 +92,7 @@ static inline void page_dup_rmap(struct page *page) */ int page_referenced(struct page *, int is_locked); int try_to_unmap(struct page *, int ignore_refs); +void remove_from_swap(struct page *page); /* * Called from mm/filemap_xip.c to unmap empty zero page diff --git a/include/linux/swap.h b/include/linux/swap.h index d359fc022433..229b6d04b4b6 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -248,6 +248,7 @@ extern int remove_exclusive_swap_page(struct page *); struct backing_dev_info; extern spinlock_t swap_lock; +extern int remove_vma_swap(struct vm_area_struct *vma, struct page *page); /* linux/mm/thrash.c */ extern struct mm_struct * swap_token_mm; diff --git a/mm/rmap.c b/mm/rmap.c index 13fad5fcdf79..f4b91d7aa5cf 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -206,6 +206,35 @@ out: return anon_vma; } +#ifdef CONFIG_MIGRATION +/* + * Remove an anonymous page from swap replacing the swap pte's + * through real pte's pointing to valid pages and then releasing + * the page from the swap cache. + * + * Must hold page lock on page. + */ +void remove_from_swap(struct page *page) +{ + struct anon_vma *anon_vma; + struct vm_area_struct *vma; + + if (!PageAnon(page) || !PageSwapCache(page)) + return; + + anon_vma = page_lock_anon_vma(page); + if (!anon_vma) + return; + + list_for_each_entry(vma, &anon_vma->head, anon_vma_node) + remove_vma_swap(vma, page); + + spin_unlock(&anon_vma->lock); + + delete_from_swap_cache(page); +} +#endif + /* * At what user virtual address is page expected in vma? */ diff --git a/mm/swapfile.c b/mm/swapfile.c index 9678182e0eef..1f9cf0d073b8 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -554,6 +554,15 @@ static int unuse_mm(struct mm_struct *mm, return 0; } +#ifdef CONFIG_MIGRATION +int remove_vma_swap(struct vm_area_struct *vma, struct page *page) +{ + swp_entry_t entry = { .val = page_private(page) }; + + return unuse_vma(vma, entry, page); +} +#endif + /* * Scan swap_map from current position to next entry still in use. * Recycle to start on reaching the end, returning 0 when empty. diff --git a/mm/vmscan.c b/mm/vmscan.c index 8f326ce2b690..5e98b86feb74 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -804,6 +804,15 @@ int migrate_page(struct page *newpage, struct page *page) migrate_page_copy(newpage, page); + /* + * Remove auxiliary swap entries and replace + * them with real ptes. + * + * Note that a real pte entry will allow processes that are not + * waiting on the page lock to use the new page via the page tables + * before the new page is unlocked. + */ + remove_from_swap(newpage); return 0; } From 7e2ab150d1b3b286a4c864c60a549b2601777b63 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:40 -0800 Subject: [PATCH 381/695] [PATCH] Direct Migration V9: upgrade MPOL_MF_MOVE and sys_migrate_pages() Modify policy layer to support direct page migration - Add migrate_pages_to() allowing the migration of a list of pages to a a specified node or to vma with a specific allocation policy in sets of MIGRATE_CHUNK_SIZE pages - Modify do_migrate_pages() to do a staged move of pages from the source nodes to the target nodes. Signed-off-by: Paul Jackson Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mempolicy.c | 167 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 146 insertions(+), 21 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 73790188b0eb..27da6d5c77ba 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -95,6 +95,9 @@ #define MPOL_MF_INVERT (MPOL_MF_INTERNAL << 1) /* Invert check for nodemask */ #define MPOL_MF_STATS (MPOL_MF_INTERNAL << 2) /* Gather statistics */ +/* The number of pages to migrate per call to migrate_pages() */ +#define MIGRATE_CHUNK_SIZE 256 + static kmem_cache_t *policy_cache; static kmem_cache_t *sn_cache; @@ -543,24 +546,91 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist, } } -static int swap_pages(struct list_head *pagelist) +/* + * Migrate the list 'pagelist' of pages to a certain destination. + * + * Specify destination with either non-NULL vma or dest_node >= 0 + * Return the number of pages not migrated or error code + */ +static int migrate_pages_to(struct list_head *pagelist, + struct vm_area_struct *vma, int dest) { + LIST_HEAD(newlist); LIST_HEAD(moved); LIST_HEAD(failed); - int n; + int err = 0; + int nr_pages; + struct page *page; + struct list_head *p; - n = migrate_pages(pagelist, NULL, &moved, &failed); - putback_lru_pages(&failed); - putback_lru_pages(&moved); +redo: + nr_pages = 0; + list_for_each(p, pagelist) { + if (vma) + page = alloc_page_vma(GFP_HIGHUSER, vma, vma->vm_start); + else + page = alloc_pages_node(dest, GFP_HIGHUSER, 0); - return n; + if (!page) { + err = -ENOMEM; + goto out; + } + list_add(&page->lru, &newlist); + nr_pages++; + if (nr_pages > MIGRATE_CHUNK_SIZE); + break; + } + err = migrate_pages(pagelist, &newlist, &moved, &failed); + + putback_lru_pages(&moved); /* Call release pages instead ?? */ + + if (err >= 0 && list_empty(&newlist) && !list_empty(pagelist)) + goto redo; +out: + /* Return leftover allocated pages */ + while (!list_empty(&newlist)) { + page = list_entry(newlist.next, struct page, lru); + list_del(&page->lru); + __free_page(page); + } + list_splice(&failed, pagelist); + if (err < 0) + return err; + + /* Calculate number of leftover pages */ + nr_pages = 0; + list_for_each(p, pagelist) + nr_pages++; + return nr_pages; } /* - * For now migrate_pages simply swaps out the pages from nodes that are in - * the source set but not in the target set. In the future, we would - * want a function that moves pages between the two nodesets in such - * a way as to preserve the physical layout as much as possible. + * Migrate pages from one node to a target node. + * Returns error or the number of pages not migrated. + */ +int migrate_to_node(struct mm_struct *mm, int source, int dest, int flags) +{ + nodemask_t nmask; + LIST_HEAD(pagelist); + int err = 0; + + nodes_clear(nmask); + node_set(source, nmask); + + check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nmask, + flags | MPOL_MF_DISCONTIG_OK, &pagelist); + + if (!list_empty(&pagelist)) { + err = migrate_pages_to(&pagelist, NULL, dest); + if (!list_empty(&pagelist)) + putback_lru_pages(&pagelist); + } + return err; +} + +/* + * Move pages between the two nodesets so as to preserve the physical + * layout as much as possible. * * Returns the number of page that could not be moved. */ @@ -568,22 +638,76 @@ int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags) { LIST_HEAD(pagelist); - int count = 0; - nodemask_t nodes; + int busy = 0; + int err = 0; + nodemask_t tmp; - nodes_andnot(nodes, *from_nodes, *to_nodes); + down_read(&mm->mmap_sem); - down_read(&mm->mmap_sem); - check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes, - flags | MPOL_MF_DISCONTIG_OK, &pagelist); +/* + * Find a 'source' bit set in 'tmp' whose corresponding 'dest' + * bit in 'to' is not also set in 'tmp'. Clear the found 'source' + * bit in 'tmp', and return that pair for migration. + * The pair of nodemasks 'to' and 'from' define the map. + * + * If no pair of bits is found that way, fallback to picking some + * pair of 'source' and 'dest' bits that are not the same. If the + * 'source' and 'dest' bits are the same, this represents a node + * that will be migrating to itself, so no pages need move. + * + * If no bits are left in 'tmp', or if all remaining bits left + * in 'tmp' correspond to the same bit in 'to', return false + * (nothing left to migrate). + * + * This lets us pick a pair of nodes to migrate between, such that + * if possible the dest node is not already occupied by some other + * source node, minimizing the risk of overloading the memory on a + * node that would happen if we migrated incoming memory to a node + * before migrating outgoing memory source that same node. + * + * A single scan of tmp is sufficient. As we go, we remember the + * most recent pair that moved (s != d). If we find a pair + * that not only moved, but what's better, moved to an empty slot + * (d is not set in tmp), then we break out then, with that pair. + * Otherwise when we finish scannng from_tmp, we at least have the + * most recent pair that moved. If we get all the way through + * the scan of tmp without finding any node that moved, much less + * moved to an empty node, then there is nothing left worth migrating. + */ - if (!list_empty(&pagelist)) { - count = swap_pages(&pagelist); - putback_lru_pages(&pagelist); + tmp = *from_nodes; + while (!nodes_empty(tmp)) { + int s,d; + int source = -1; + int dest = 0; + + for_each_node_mask(s, tmp) { + d = node_remap(s, *from_nodes, *to_nodes); + if (s == d) + continue; + + source = s; /* Node moved. Memorize */ + dest = d; + + /* dest not in remaining from nodes? */ + if (!node_isset(dest, tmp)) + break; + } + if (source == -1) + break; + + node_clear(source, tmp); + err = migrate_to_node(mm, source, dest, flags); + if (err > 0) + busy += err; + if (err < 0) + break; } up_read(&mm->mmap_sem); - return count; + if (err < 0) + return err; + return busy; } long do_mbind(unsigned long start, unsigned long len, @@ -643,8 +767,9 @@ long do_mbind(unsigned long start, unsigned long len, int nr_failed = 0; err = mbind_range(vma, start, end, new); + if (!list_empty(&pagelist)) - nr_failed = swap_pages(&pagelist); + nr_failed = migrate_pages_to(&pagelist, vma, -1); if (!err && nr_failed && (flags & MPOL_MF_STRICT)) err = -EIO; From e965f9630c651fa4249039fd4b80c9392d07a856 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:41 -0800 Subject: [PATCH 382/695] [PATCH] Direct Migration V9: Avoid writeback / page_migrate() method Migrate a page with buffers without requiring writeback This introduces a new address space operation migratepage() that may be used by a filesystem to implement its own version of page migration. A version is provided that migrates buffers attached to pages. Some filesystems (ext2, ext3, xfs) are modified to utilize this feature. The swapper address space operation are modified so that a regular migrate_page() will occur for anonymous pages without writeback (migrate_pages forces every anonymous page to have a swap entry). Signed-off-by: Mike Kravetz Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 60 +++++++++++++++++++++++++++++++++++++ fs/ext2/inode.c | 2 ++ fs/ext3/inode.c | 2 ++ fs/xfs/linux-2.6/xfs_aops.c | 1 + fs/xfs/linux-2.6/xfs_buf.c | 1 + include/linux/fs.h | 8 +++++ include/linux/swap.h | 5 ++++ mm/rmap.c | 1 + mm/swap_state.c | 1 + mm/vmscan.c | 20 ++++++++++++- 10 files changed, 100 insertions(+), 1 deletion(-) diff --git a/fs/buffer.c b/fs/buffer.c index 3dc712f29d2d..8bcbac87a28c 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3049,6 +3049,66 @@ asmlinkage long sys_bdflush(int func, long data) return 0; } +/* + * Migration function for pages with buffers. This function can only be used + * if the underlying filesystem guarantees that no other references to "page" + * exist. + */ +#ifdef CONFIG_MIGRATION +int buffer_migrate_page(struct page *newpage, struct page *page) +{ + struct address_space *mapping = page->mapping; + struct buffer_head *bh, *head; + + if (!mapping) + return -EAGAIN; + + if (!page_has_buffers(page)) + return migrate_page(newpage, page); + + head = page_buffers(page); + + if (migrate_page_remove_references(newpage, page, 3)) + return -EAGAIN; + + bh = head; + do { + get_bh(bh); + lock_buffer(bh); + bh = bh->b_this_page; + + } while (bh != head); + + ClearPagePrivate(page); + set_page_private(newpage, page_private(page)); + set_page_private(page, 0); + put_page(page); + get_page(newpage); + + bh = head; + do { + set_bh_page(bh, newpage, bh_offset(bh)); + bh = bh->b_this_page; + + } while (bh != head); + + SetPagePrivate(newpage); + + migrate_page_copy(newpage, page); + + bh = head; + do { + unlock_buffer(bh); + put_bh(bh); + bh = bh->b_this_page; + + } while (bh != head); + + return 0; +} +EXPORT_SYMBOL(buffer_migrate_page); +#endif + /* * Buffer-head allocation */ diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index e7d3f0522d01..a717837f272e 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -706,6 +706,7 @@ struct address_space_operations ext2_aops = { .bmap = ext2_bmap, .direct_IO = ext2_direct_IO, .writepages = ext2_writepages, + .migratepage = buffer_migrate_page, }; struct address_space_operations ext2_aops_xip = { @@ -723,6 +724,7 @@ struct address_space_operations ext2_nobh_aops = { .bmap = ext2_bmap, .direct_IO = ext2_direct_IO, .writepages = ext2_writepages, + .migratepage = buffer_migrate_page, }; /* diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 8824e84f8a56..3fc4238e9703 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -1559,6 +1559,7 @@ static struct address_space_operations ext3_ordered_aops = { .invalidatepage = ext3_invalidatepage, .releasepage = ext3_releasepage, .direct_IO = ext3_direct_IO, + .migratepage = buffer_migrate_page, }; static struct address_space_operations ext3_writeback_aops = { @@ -1572,6 +1573,7 @@ static struct address_space_operations ext3_writeback_aops = { .invalidatepage = ext3_invalidatepage, .releasepage = ext3_releasepage, .direct_IO = ext3_direct_IO, + .migratepage = buffer_migrate_page, }; static struct address_space_operations ext3_journalled_aops = { diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 120626789406..9892268e3005 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -1462,4 +1462,5 @@ struct address_space_operations linvfs_aops = { .commit_write = generic_commit_write, .bmap = linvfs_bmap, .direct_IO = linvfs_direct_IO, + .migratepage = buffer_migrate_page, }; diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index a36a8e3b703f..bfb4f2917bb6 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1521,6 +1521,7 @@ xfs_mapping_buftarg( struct address_space *mapping; static struct address_space_operations mapping_aops = { .sync_page = block_sync_page, + .migratepage = fail_migrate_page, }; inode = new_inode(bdev->bd_inode->i_sb); diff --git a/include/linux/fs.h b/include/linux/fs.h index 84bb449b9b01..e059da947007 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -363,6 +363,8 @@ struct address_space_operations { loff_t offset, unsigned long nr_segs); struct page* (*get_xip_page)(struct address_space *, sector_t, int); + /* migrate the contents of a page to the specified target */ + int (*migratepage) (struct page *, struct page *); }; struct backing_dev_info; @@ -1719,6 +1721,12 @@ extern void simple_release_fs(struct vfsmount **mount, int *count); extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const void *, size_t); +#ifdef CONFIG_MIGRATION +extern int buffer_migrate_page(struct page *, struct page *); +#else +#define buffer_migrate_page NULL +#endif + extern int inode_change_ok(struct inode *, struct iattr *); extern int __must_check inode_setattr(struct inode *, struct iattr *); diff --git a/include/linux/swap.h b/include/linux/swap.h index 229b6d04b4b6..f3e17d5963c3 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -193,13 +193,18 @@ extern int isolate_lru_page(struct page *p); extern int putback_lru_pages(struct list_head *l); extern int migrate_page(struct page *, struct page *); extern void migrate_page_copy(struct page *, struct page *); +extern int migrate_page_remove_references(struct page *, struct page *, int); extern int migrate_pages(struct list_head *l, struct list_head *t, struct list_head *moved, struct list_head *failed); +extern int fail_migrate_page(struct page *, struct page *); #else static inline int isolate_lru_page(struct page *p) { return -ENOSYS; } static inline int putback_lru_pages(struct list_head *l) { return 0; } static inline int migrate_pages(struct list_head *l, struct list_head *t, struct list_head *moved, struct list_head *failed) { return -ENOSYS; } +/* Possible settings for the migrate_page() method in address_operations */ +#define migrate_page NULL +#define fail_migrate_page NULL #endif #ifdef CONFIG_MMU diff --git a/mm/rmap.c b/mm/rmap.c index f4b91d7aa5cf..df2c41c2a9a2 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -233,6 +233,7 @@ void remove_from_swap(struct page *page) delete_from_swap_cache(page); } +EXPORT_SYMBOL(remove_from_swap); #endif /* diff --git a/mm/swap_state.c b/mm/swap_state.c index 7b09ac503fec..db8a3d3e1636 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -27,6 +27,7 @@ static struct address_space_operations swap_aops = { .writepage = swap_writepage, .sync_page = block_sync_page, .set_page_dirty = __set_page_dirty_nobuffers, + .migratepage = migrate_page, }; static struct backing_dev_info swap_backing_dev_info = { diff --git a/mm/vmscan.c b/mm/vmscan.c index 5e98b86feb74..5a610804cd06 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -614,6 +614,15 @@ int putback_lru_pages(struct list_head *l) return count; } +/* + * Non migratable page + */ +int fail_migrate_page(struct page *newpage, struct page *page) +{ + return -EIO; +} +EXPORT_SYMBOL(fail_migrate_page); + /* * swapout a single page * page is locked upon entry, unlocked on exit @@ -659,6 +668,7 @@ unlock_retry: retry: return -EAGAIN; } +EXPORT_SYMBOL(swap_page); /* * Page migration was first developed in the context of the memory hotplug @@ -674,7 +684,7 @@ retry: * Remove references for a page and establish the new page with the correct * basic settings to be able to stop accesses to the page. */ -static int migrate_page_remove_references(struct page *newpage, +int migrate_page_remove_references(struct page *newpage, struct page *page, int nr_refs) { struct address_space *mapping = page_mapping(page); @@ -749,6 +759,7 @@ static int migrate_page_remove_references(struct page *newpage, return 0; } +EXPORT_SYMBOL(migrate_page_remove_references); /* * Copy the page to its new location @@ -788,6 +799,7 @@ void migrate_page_copy(struct page *newpage, struct page *page) if (PageWriteback(newpage)) end_page_writeback(newpage); } +EXPORT_SYMBOL(migrate_page_copy); /* * Common logic to directly migrate a single page suitable for @@ -815,6 +827,7 @@ int migrate_page(struct page *newpage, struct page *page) remove_from_swap(newpage); return 0; } +EXPORT_SYMBOL(migrate_page); /* * migrate_pages @@ -914,6 +927,11 @@ redo: if (!mapping) goto unlock_both; + if (mapping->a_ops->migratepage) { + rc = mapping->a_ops->migratepage(newpage, page); + goto unlock_both; + } + /* * Trigger writeout if page is dirty */ From 3dafccf22751429e69b6266636cf3acf45b48075 Mon Sep 17 00:00:00 2001 From: Manfred Spraul Date: Wed, 1 Feb 2006 03:05:42 -0800 Subject: [PATCH 383/695] [PATCH] slab: distinguish between object and buffer size An object cache has two different object lengths: - the amount of memory available for the user (object size) - the amount of memory allocated internally (buffer size) This patch does some renames to make the code reflect that better. Signed-off-by: Manfred Spraul Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 154 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 80 insertions(+), 74 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 88082ae15736..1a014aaf4491 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -375,7 +375,7 @@ struct kmem_cache { unsigned int batchcount; unsigned int limit; unsigned int shared; - unsigned int objsize; + unsigned int buffer_size; /* 2) touched by every alloc & free from the backend */ struct kmem_list3 *nodelists[MAX_NUMNODES]; unsigned int flags; /* constant flags */ @@ -423,8 +423,14 @@ struct kmem_cache { atomic_t freemiss; #endif #if DEBUG - int dbghead; - int reallen; + /* + * If debugging is enabled, then the allocator can add additional + * fields and/or padding to every object. buffer_size contains the total + * object size including these internal fields, the following two + * variables contain the offset to the user object and its size. + */ + int obj_offset; + int obj_size; #endif }; @@ -495,50 +501,50 @@ struct kmem_cache { /* memory layout of objects: * 0 : objp - * 0 .. cachep->dbghead - BYTES_PER_WORD - 1: padding. This ensures that + * 0 .. cachep->obj_offset - BYTES_PER_WORD - 1: padding. This ensures that * the end of an object is aligned with the end of the real * allocation. Catches writes behind the end of the allocation. - * cachep->dbghead - BYTES_PER_WORD .. cachep->dbghead - 1: + * cachep->obj_offset - BYTES_PER_WORD .. cachep->obj_offset - 1: * redzone word. - * cachep->dbghead: The real object. - * cachep->objsize - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long] - * cachep->objsize - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long] + * cachep->obj_offset: The real object. + * cachep->buffer_size - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long] + * cachep->buffer_size - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long] */ -static int obj_dbghead(kmem_cache_t *cachep) +static int obj_offset(kmem_cache_t *cachep) { - return cachep->dbghead; + return cachep->obj_offset; } -static int obj_reallen(kmem_cache_t *cachep) +static int obj_size(kmem_cache_t *cachep) { - return cachep->reallen; + return cachep->obj_size; } static unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp) { BUG_ON(!(cachep->flags & SLAB_RED_ZONE)); - return (unsigned long*) (objp+obj_dbghead(cachep)-BYTES_PER_WORD); + return (unsigned long*) (objp+obj_offset(cachep)-BYTES_PER_WORD); } static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp) { BUG_ON(!(cachep->flags & SLAB_RED_ZONE)); if (cachep->flags & SLAB_STORE_USER) - return (unsigned long *)(objp + cachep->objsize - + return (unsigned long *)(objp + cachep->buffer_size - 2 * BYTES_PER_WORD); - return (unsigned long *)(objp + cachep->objsize - BYTES_PER_WORD); + return (unsigned long *)(objp + cachep->buffer_size - BYTES_PER_WORD); } static void **dbg_userword(kmem_cache_t *cachep, void *objp) { BUG_ON(!(cachep->flags & SLAB_STORE_USER)); - return (void **)(objp + cachep->objsize - BYTES_PER_WORD); + return (void **)(objp + cachep->buffer_size - BYTES_PER_WORD); } #else -#define obj_dbghead(x) 0 -#define obj_reallen(cachep) (cachep->objsize) +#define obj_offset(x) 0 +#define obj_size(cachep) (cachep->buffer_size) #define dbg_redzone1(cachep, objp) ({BUG(); (unsigned long *)NULL;}) #define dbg_redzone2(cachep, objp) ({BUG(); (unsigned long *)NULL;}) #define dbg_userword(cachep, objp) ({BUG(); (void **)NULL;}) @@ -623,12 +629,12 @@ static kmem_cache_t cache_cache = { .batchcount = 1, .limit = BOOT_CPUCACHE_ENTRIES, .shared = 1, - .objsize = sizeof(kmem_cache_t), + .buffer_size = sizeof(kmem_cache_t), .flags = SLAB_NO_REAP, .spinlock = SPIN_LOCK_UNLOCKED, .name = "kmem_cache", #if DEBUG - .reallen = sizeof(kmem_cache_t), + .obj_size = sizeof(kmem_cache_t), #endif }; @@ -1057,9 +1063,9 @@ void __init kmem_cache_init(void) cache_cache.array[smp_processor_id()] = &initarray_cache.cache; cache_cache.nodelists[numa_node_id()] = &initkmem_list3[CACHE_CACHE]; - cache_cache.objsize = ALIGN(cache_cache.objsize, cache_line_size()); + cache_cache.buffer_size = ALIGN(cache_cache.buffer_size, cache_line_size()); - cache_estimate(0, cache_cache.objsize, cache_line_size(), 0, + cache_estimate(0, cache_cache.buffer_size, cache_line_size(), 0, &left_over, &cache_cache.num); if (!cache_cache.num) BUG(); @@ -1274,9 +1280,9 @@ static void kmem_rcu_free(struct rcu_head *head) static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr, unsigned long caller) { - int size = obj_reallen(cachep); + int size = obj_size(cachep); - addr = (unsigned long *)&((char *)addr)[obj_dbghead(cachep)]; + addr = (unsigned long *)&((char *)addr)[obj_offset(cachep)]; if (size < 5 * sizeof(unsigned long)) return; @@ -1306,8 +1312,8 @@ static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr, static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val) { - int size = obj_reallen(cachep); - addr = &((char *)addr)[obj_dbghead(cachep)]; + int size = obj_size(cachep); + addr = &((char *)addr)[obj_offset(cachep)]; memset(addr, val, size); *(unsigned char *)(addr + size - 1) = POISON_END; @@ -1344,8 +1350,8 @@ static void print_objinfo(kmem_cache_t *cachep, void *objp, int lines) (unsigned long)*dbg_userword(cachep, objp)); printk("\n"); } - realobj = (char *)objp + obj_dbghead(cachep); - size = obj_reallen(cachep); + realobj = (char *)objp + obj_offset(cachep); + size = obj_size(cachep); for (i = 0; i < size && lines; i += 16, lines--) { int limit; limit = 16; @@ -1361,8 +1367,8 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp) int size, i; int lines = 0; - realobj = (char *)objp + obj_dbghead(cachep); - size = obj_reallen(cachep); + realobj = (char *)objp + obj_offset(cachep); + size = obj_size(cachep); for (i = 0; i < size; i++) { char exp = POISON_FREE; @@ -1398,17 +1404,17 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp) struct slab *slabp = page_get_slab(virt_to_page(objp)); int objnr; - objnr = (unsigned)(objp - slabp->s_mem) / cachep->objsize; + objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size; if (objnr) { - objp = slabp->s_mem + (objnr - 1) * cachep->objsize; - realobj = (char *)objp + obj_dbghead(cachep); + objp = slabp->s_mem + (objnr - 1) * cachep->buffer_size; + realobj = (char *)objp + obj_offset(cachep); printk(KERN_ERR "Prev obj: start=%p, len=%d\n", realobj, size); print_objinfo(cachep, objp, 2); } if (objnr + 1 < cachep->num) { - objp = slabp->s_mem + (objnr + 1) * cachep->objsize; - realobj = (char *)objp + obj_dbghead(cachep); + objp = slabp->s_mem + (objnr + 1) * cachep->buffer_size; + realobj = (char *)objp + obj_offset(cachep); printk(KERN_ERR "Next obj: start=%p, len=%d\n", realobj, size); print_objinfo(cachep, objp, 2); @@ -1428,14 +1434,14 @@ static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) #if DEBUG int i; for (i = 0; i < cachep->num; i++) { - void *objp = slabp->s_mem + cachep->objsize * i; + void *objp = slabp->s_mem + cachep->buffer_size * i; if (cachep->flags & SLAB_POISON) { #ifdef CONFIG_DEBUG_PAGEALLOC - if ((cachep->objsize % PAGE_SIZE) == 0 + if ((cachep->buffer_size % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) kernel_map_pages(virt_to_page(objp), - cachep->objsize / PAGE_SIZE, + cachep->buffer_size / PAGE_SIZE, 1); else check_poison_obj(cachep, objp); @@ -1452,13 +1458,13 @@ static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) "was overwritten"); } if (cachep->dtor && !(cachep->flags & SLAB_POISON)) - (cachep->dtor) (objp + obj_dbghead(cachep), cachep, 0); + (cachep->dtor) (objp + obj_offset(cachep), cachep, 0); } #else if (cachep->dtor) { int i; for (i = 0; i < cachep->num; i++) { - void *objp = slabp->s_mem + cachep->objsize * i; + void *objp = slabp->s_mem + cachep->buffer_size * i; (cachep->dtor) (objp, cachep, 0); } } @@ -1478,7 +1484,7 @@ static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) } } -/* For setting up all the kmem_list3s for cache whose objsize is same +/* For setting up all the kmem_list3s for cache whose buffer_size is same as size of kmem_list3. */ static inline void set_up_list3s(kmem_cache_t *cachep, int index) { @@ -1611,7 +1617,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, set_fs(old_fs); if (res) { printk("SLAB: cache with size %d has lost its name\n", - pc->objsize); + pc->buffer_size); continue; } @@ -1702,14 +1708,14 @@ kmem_cache_create (const char *name, size_t size, size_t align, memset(cachep, 0, sizeof(kmem_cache_t)); #if DEBUG - cachep->reallen = size; + cachep->obj_size = size; if (flags & SLAB_RED_ZONE) { /* redzoning only works with word aligned caches */ align = BYTES_PER_WORD; /* add space for red zone words */ - cachep->dbghead += BYTES_PER_WORD; + cachep->obj_offset += BYTES_PER_WORD; size += 2 * BYTES_PER_WORD; } if (flags & SLAB_STORE_USER) { @@ -1722,8 +1728,8 @@ kmem_cache_create (const char *name, size_t size, size_t align, } #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) if (size >= malloc_sizes[INDEX_L3 + 1].cs_size - && cachep->reallen > cache_line_size() && size < PAGE_SIZE) { - cachep->dbghead += PAGE_SIZE - size; + && cachep->obj_size > cache_line_size() && size < PAGE_SIZE) { + cachep->obj_offset += PAGE_SIZE - size; size = PAGE_SIZE; } #endif @@ -1786,7 +1792,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, if (flags & SLAB_CACHE_DMA) cachep->gfpflags |= GFP_DMA; spin_lock_init(&cachep->spinlock); - cachep->objsize = size; + cachep->buffer_size = size; if (flags & CFLGS_OFF_SLAB) cachep->slabp_cache = kmem_find_general_cachep(slab_size, 0u); @@ -2118,7 +2124,7 @@ static void cache_init_objs(kmem_cache_t *cachep, int i; for (i = 0; i < cachep->num; i++) { - void *objp = slabp->s_mem + cachep->objsize * i; + void *objp = slabp->s_mem + cachep->buffer_size * i; #if DEBUG /* need to poison the objs? */ if (cachep->flags & SLAB_POISON) @@ -2136,7 +2142,7 @@ static void cache_init_objs(kmem_cache_t *cachep, * Otherwise, deadlock. They must also be threaded. */ if (cachep->ctor && !(cachep->flags & SLAB_POISON)) - cachep->ctor(objp + obj_dbghead(cachep), cachep, + cachep->ctor(objp + obj_offset(cachep), cachep, ctor_flags); if (cachep->flags & SLAB_RED_ZONE) { @@ -2147,10 +2153,10 @@ static void cache_init_objs(kmem_cache_t *cachep, slab_error(cachep, "constructor overwrote the" " start of an object"); } - if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep) + if ((cachep->buffer_size % PAGE_SIZE) == 0 && OFF_SLAB(cachep) && cachep->flags & SLAB_POISON) kernel_map_pages(virt_to_page(objp), - cachep->objsize / PAGE_SIZE, 0); + cachep->buffer_size / PAGE_SIZE, 0); #else if (cachep->ctor) cachep->ctor(objp, cachep, ctor_flags); @@ -2309,7 +2315,7 @@ static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp, unsigned int objnr; struct slab *slabp; - objp -= obj_dbghead(cachep); + objp -= obj_offset(cachep); kfree_debugcheck(objp); page = virt_to_page(objp); @@ -2341,31 +2347,31 @@ static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp, if (cachep->flags & SLAB_STORE_USER) *dbg_userword(cachep, objp) = caller; - objnr = (unsigned)(objp - slabp->s_mem) / cachep->objsize; + objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size; BUG_ON(objnr >= cachep->num); - BUG_ON(objp != slabp->s_mem + objnr * cachep->objsize); + BUG_ON(objp != slabp->s_mem + objnr * cachep->buffer_size); if (cachep->flags & SLAB_DEBUG_INITIAL) { /* Need to call the slab's constructor so the * caller can perform a verify of its state (debugging). * Called without the cache-lock held. */ - cachep->ctor(objp + obj_dbghead(cachep), + cachep->ctor(objp + obj_offset(cachep), cachep, SLAB_CTOR_CONSTRUCTOR | SLAB_CTOR_VERIFY); } if (cachep->flags & SLAB_POISON && cachep->dtor) { /* we want to cache poison the object, * call the destruction callback */ - cachep->dtor(objp + obj_dbghead(cachep), cachep, 0); + cachep->dtor(objp + obj_offset(cachep), cachep, 0); } if (cachep->flags & SLAB_POISON) { #ifdef CONFIG_DEBUG_PAGEALLOC - if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) { + if ((cachep->buffer_size % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) { store_stackinfo(cachep, objp, (unsigned long)caller); kernel_map_pages(virt_to_page(objp), - cachep->objsize / PAGE_SIZE, 0); + cachep->buffer_size / PAGE_SIZE, 0); } else { poison_obj(cachep, objp, POISON_FREE); } @@ -2468,7 +2474,7 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags) /* get obj pointer */ ac->entry[ac->avail++] = slabp->s_mem + - slabp->free * cachep->objsize; + slabp->free * cachep->buffer_size; slabp->inuse++; next = slab_bufctl(slabp)[slabp->free]; @@ -2526,9 +2532,9 @@ static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags, return objp; if (cachep->flags & SLAB_POISON) { #ifdef CONFIG_DEBUG_PAGEALLOC - if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) + if ((cachep->buffer_size % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) kernel_map_pages(virt_to_page(objp), - cachep->objsize / PAGE_SIZE, 1); + cachep->buffer_size / PAGE_SIZE, 1); else check_poison_obj(cachep, objp); #else @@ -2553,7 +2559,7 @@ static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags, *dbg_redzone1(cachep, objp) = RED_ACTIVE; *dbg_redzone2(cachep, objp) = RED_ACTIVE; } - objp += obj_dbghead(cachep); + objp += obj_offset(cachep); if (cachep->ctor && cachep->flags & SLAB_POISON) { unsigned long ctor_flags = SLAB_CTOR_CONSTRUCTOR; @@ -2648,7 +2654,7 @@ static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid) BUG_ON(slabp->inuse == cachep->num); /* get obj pointer */ - obj = slabp->s_mem + slabp->free * cachep->objsize; + obj = slabp->s_mem + slabp->free * cachep->buffer_size; slabp->inuse++; next = slab_bufctl(slabp)[slabp->free]; #if DEBUG @@ -2699,7 +2705,7 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, slabp = page_get_slab(virt_to_page(objp)); l3 = cachep->nodelists[node]; list_del(&slabp->list); - objnr = (unsigned)(objp - slabp->s_mem) / cachep->objsize; + objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size; check_spinlock_acquired_node(cachep, node); check_slabp(cachep, slabp); @@ -2881,7 +2887,7 @@ int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr) unsigned long addr = (unsigned long)ptr; unsigned long min_addr = PAGE_OFFSET; unsigned long align_mask = BYTES_PER_WORD - 1; - unsigned long size = cachep->objsize; + unsigned long size = cachep->buffer_size; struct page *page; if (unlikely(addr < min_addr)) @@ -3083,7 +3089,7 @@ void kfree(const void *objp) local_irq_save(flags); kfree_debugcheck(objp); c = page_get_cache(virt_to_page(objp)); - mutex_debug_check_no_locks_freed(objp, obj_reallen(c)); + mutex_debug_check_no_locks_freed(objp, obj_size(c)); __cache_free(c, (void *)objp); local_irq_restore(flags); } @@ -3114,7 +3120,7 @@ EXPORT_SYMBOL(free_percpu); unsigned int kmem_cache_size(kmem_cache_t *cachep) { - return obj_reallen(cachep); + return obj_size(cachep); } EXPORT_SYMBOL(kmem_cache_size); @@ -3258,13 +3264,13 @@ static void enable_cpucache(kmem_cache_t *cachep) * The numbers are guessed, we should auto-tune as described by * Bonwick. */ - if (cachep->objsize > 131072) + if (cachep->buffer_size > 131072) limit = 1; - else if (cachep->objsize > PAGE_SIZE) + else if (cachep->buffer_size > PAGE_SIZE) limit = 8; - else if (cachep->objsize > 1024) + else if (cachep->buffer_size > 1024) limit = 24; - else if (cachep->objsize > 256) + else if (cachep->buffer_size > 256) limit = 54; else limit = 120; @@ -3279,7 +3285,7 @@ static void enable_cpucache(kmem_cache_t *cachep) */ shared = 0; #ifdef CONFIG_SMP - if (cachep->objsize <= PAGE_SIZE) + if (cachep->buffer_size <= PAGE_SIZE) shared = 8; #endif @@ -3528,7 +3534,7 @@ static int s_show(struct seq_file *m, void *p) printk(KERN_ERR "slab: cache %s error: %s\n", name, error); seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", - name, active_objs, num_objs, cachep->objsize, + name, active_objs, num_objs, cachep->buffer_size, cachep->num, (1 << cachep->gfporder)); seq_printf(m, " : tunables %4u %4u %4u", cachep->limit, cachep->batchcount, cachep->shared); @@ -3656,5 +3662,5 @@ unsigned int ksize(const void *objp) if (unlikely(objp == NULL)) return 0; - return obj_reallen(page_get_cache(virt_to_page(objp))); + return obj_size(page_get_cache(virt_to_page(objp))); } From 18f820f655ce93b1e4d9b48fc6fcafc64157c6bc Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Feb 2006 03:05:43 -0800 Subject: [PATCH 384/695] [PATCH] slab: minor cleanup to kmem_cache_alloc_node Clean up kmem_cache_alloc_node a bit. Signed-off-by: Christoph Lameter Acked-by: Manfred Spraul Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 1a014aaf4491..bb7a9837b949 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2928,27 +2928,18 @@ void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid) unsigned long save_flags; void *ptr; - if (nodeid == -1) - return __cache_alloc(cachep, flags); - - if (unlikely(!cachep->nodelists[nodeid])) { - /* Fall back to __cache_alloc if we run into trouble */ - printk(KERN_WARNING - "slab: not allocating in inactive node %d for cache %s\n", - nodeid, cachep->name); - return __cache_alloc(cachep, flags); - } - cache_alloc_debugcheck_before(cachep, flags); local_irq_save(save_flags); - if (nodeid == numa_node_id()) + + if (nodeid == -1 || nodeid == numa_node_id() || + !cachep->nodelists[nodeid]) ptr = ____cache_alloc(cachep, flags); else ptr = __cache_alloc_node(cachep, flags, nodeid); local_irq_restore(save_flags); - ptr = - cache_alloc_debugcheck_after(cachep, flags, ptr, - __builtin_return_address(0)); + + ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, + __builtin_return_address(0)); return ptr; } From 5ec8a847bb8ae2ba6395cfb7cb4bfdc78ada82ed Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 1 Feb 2006 03:05:44 -0800 Subject: [PATCH 385/695] [PATCH] slab: have index_of bug at compile time I noticed the code for index_of is a creative way of finding the cache index using the compiler to optimize to a single hard coded number. But I couldn't help noticing that it uses two methods to let you know that someone used it wrong. One is at compile time (the correct way), and the other is at run time (not good). Signed-off-by: Steven Rostedt Acked-by: Manfred Spraul Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index bb7a9837b949..613d385519fe 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -316,6 +316,8 @@ struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS]; */ static __always_inline int index_of(const size_t size) { + extern void __bad_size(void); + if (__builtin_constant_p(size)) { int i = 0; @@ -326,12 +328,9 @@ static __always_inline int index_of(const size_t size) i++; #include "linux/kmalloc_sizes.h" #undef CACHE - { - extern void __bad_size(void); - __bad_size(); - } + __bad_size(); } else - BUG(); + __bad_size(); return 0; } From fbaccacff1f17c65ae0972085368a7ec75be6062 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 1 Feb 2006 03:05:45 -0800 Subject: [PATCH 386/695] [PATCH] slab: cache_estimate cleanup Clean up cache_estimate() in mm/slab.c and improves the algorithm from O(n) to O(1). We first calculate the maximum number of objects a slab can hold after struct slab and kmem_bufctl_t for each object has been given enough space. After that, to respect alignment rules, we decrease the number of objects if necessary. As required padding is at most align-1 and memory of obj_size is at least align, it is always enough to decrease number of objects by one. The optimization was originally made by Balbir Singh with more improvements from Steven Rostedt. Manfred Spraul provider further modifications: no loop at all for the off-slab case and added comments to explain the background. Acked-by: Balbir Singh Signed-off-by: Manfred Spraul Signed-off-by: Steven Rostedt Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 83 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 23 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 613d385519fe..e869400ea731 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -702,32 +702,69 @@ kmem_cache_t *kmem_find_general_cachep(size_t size, gfp_t gfpflags) } EXPORT_SYMBOL(kmem_find_general_cachep); -/* Cal the num objs, wastage, and bytes left over for a given slab size. */ -static void cache_estimate(unsigned long gfporder, size_t size, size_t align, - int flags, size_t *left_over, unsigned int *num) +static size_t slab_mgmt_size(size_t nr_objs, size_t align) { - int i; - size_t wastage = PAGE_SIZE << gfporder; - size_t extra = 0; - size_t base = 0; + return ALIGN(sizeof(struct slab)+nr_objs*sizeof(kmem_bufctl_t), align); +} - if (!(flags & CFLGS_OFF_SLAB)) { - base = sizeof(struct slab); - extra = sizeof(kmem_bufctl_t); +/* Calculate the number of objects and left-over bytes for a given + buffer size. */ +static void cache_estimate(unsigned long gfporder, size_t buffer_size, + size_t align, int flags, size_t *left_over, + unsigned int *num) +{ + int nr_objs; + size_t mgmt_size; + size_t slab_size = PAGE_SIZE << gfporder; + + /* + * The slab management structure can be either off the slab or + * on it. For the latter case, the memory allocated for a + * slab is used for: + * + * - The struct slab + * - One kmem_bufctl_t for each object + * - Padding to respect alignment of @align + * - @buffer_size bytes for each object + * + * If the slab management structure is off the slab, then the + * alignment will already be calculated into the size. Because + * the slabs are all pages aligned, the objects will be at the + * correct alignment when allocated. + */ + if (flags & CFLGS_OFF_SLAB) { + mgmt_size = 0; + nr_objs = slab_size / buffer_size; + + if (nr_objs > SLAB_LIMIT) + nr_objs = SLAB_LIMIT; + } else { + /* + * Ignore padding for the initial guess. The padding + * is at most @align-1 bytes, and @buffer_size is at + * least @align. In the worst case, this result will + * be one greater than the number of objects that fit + * into the memory allocation when taking the padding + * into account. + */ + nr_objs = (slab_size - sizeof(struct slab)) / + (buffer_size + sizeof(kmem_bufctl_t)); + + /* + * This calculated number will be either the right + * amount, or one greater than what we want. + */ + if (slab_mgmt_size(nr_objs, align) + nr_objs*buffer_size + > slab_size) + nr_objs--; + + if (nr_objs > SLAB_LIMIT) + nr_objs = SLAB_LIMIT; + + mgmt_size = slab_mgmt_size(nr_objs, align); } - i = 0; - while (i * size + ALIGN(base + i * extra, align) <= wastage) - i++; - if (i > 0) - i--; - - if (i > SLAB_LIMIT) - i = SLAB_LIMIT; - - *num = i; - wastage -= i * size; - wastage -= ALIGN(base + i * extra, align); - *left_over = wastage; + *num = nr_objs; + *left_over = slab_size - nr_objs*buffer_size - mgmt_size; } #define slab_error(cachep, msg) __slab_error(__FUNCTION__, cachep, msg) From 12dd36faec5d3bd96da84fa8f76efecc632930ab Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Wed, 1 Feb 2006 03:05:46 -0800 Subject: [PATCH 387/695] [PATCH] slab: extract slab_destroy_objs() Create a helper function, slab_destroy_objs() which called from slab_destroy(). This makes slab_destroy() smaller and more readable, and moves ifdefs outside the function body. Signed-off-by: Matthew Dobson Acked-by: Manfred Spraul Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index e869400ea731..85adf0992011 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1459,15 +1459,13 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp) } #endif -/* Destroy all the objs in a slab, and release the mem back to the system. - * Before calling the slab must have been unlinked from the cache. - * The cache-lock is not held/needed. - */ -static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) -{ - void *addr = slabp->s_mem - slabp->colouroff; - #if DEBUG +/** + * slab_destroy_objs - call the registered destructor for each object in + * a slab that is to be destroyed. + */ +static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp) +{ int i; for (i = 0; i < cachep->num; i++) { void *objp = slabp->s_mem + cachep->buffer_size * i; @@ -1496,7 +1494,10 @@ static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) if (cachep->dtor && !(cachep->flags & SLAB_POISON)) (cachep->dtor) (objp + obj_offset(cachep), cachep, 0); } +} #else +static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp) +{ if (cachep->dtor) { int i; for (i = 0; i < cachep->num; i++) { @@ -1504,8 +1505,19 @@ static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) (cachep->dtor) (objp, cachep, 0); } } +} #endif +/** + * Destroy all the objs in a slab, and release the mem back to the system. + * Before calling the slab must have been unlinked from the cache. + * The cache-lock is not held/needed. + */ +static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) +{ + void *addr = slabp->s_mem - slabp->colouroff; + + slab_destroy_objs(cachep, slabp); if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) { struct slab_rcu *slab_rcu; From 78d382d77c84229d031431931bf6490d5da6ab86 Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Wed, 1 Feb 2006 03:05:47 -0800 Subject: [PATCH 388/695] [PATCH] slab: extract slab_{put|get}_obj Create two helper functions slab_get_obj() and slab_put_obj() to replace duplicated code in mm/slab.c Signed-off-by: Matthew Dobson Acked-by: Manfred Spraul Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 77 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 85adf0992011..594a9155c7d8 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2226,6 +2226,42 @@ static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags) } } +static void *slab_get_obj(kmem_cache_t *cachep, struct slab *slabp, int nodeid) +{ + void *objp = slabp->s_mem + (slabp->free * cachep->buffer_size); + kmem_bufctl_t next; + + slabp->inuse++; + next = slab_bufctl(slabp)[slabp->free]; +#if DEBUG + slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE; + WARN_ON(slabp->nodeid != nodeid); +#endif + slabp->free = next; + + return objp; +} + +static void slab_put_obj(kmem_cache_t *cachep, struct slab *slabp, void *objp, + int nodeid) +{ + unsigned int objnr = (unsigned)(objp-slabp->s_mem) / cachep->buffer_size; + +#if DEBUG + /* Verify that the slab belongs to the intended node */ + WARN_ON(slabp->nodeid != nodeid); + + if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) { + printk(KERN_ERR "slab: double free detected in cache " + "'%s', objp %p\n", cachep->name, objp); + BUG(); + } +#endif + slab_bufctl(slabp)[objnr] = slabp->free; + slabp->free = objnr; + slabp->inuse--; +} + static void set_slab_attr(kmem_cache_t *cachep, struct slab *slabp, void *objp) { int i; @@ -2515,22 +2551,12 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags) check_slabp(cachep, slabp); check_spinlock_acquired(cachep); while (slabp->inuse < cachep->num && batchcount--) { - kmem_bufctl_t next; STATS_INC_ALLOCED(cachep); STATS_INC_ACTIVE(cachep); STATS_SET_HIGH(cachep); - /* get obj pointer */ - ac->entry[ac->avail++] = slabp->s_mem + - slabp->free * cachep->buffer_size; - - slabp->inuse++; - next = slab_bufctl(slabp)[slabp->free]; -#if DEBUG - slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE; - WARN_ON(numa_node_id() != slabp->nodeid); -#endif - slabp->free = next; + ac->entry[ac->avail++] = slab_get_obj(cachep, slabp, + numa_node_id()); } check_slabp(cachep, slabp); @@ -2675,7 +2701,6 @@ static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid) struct slab *slabp; struct kmem_list3 *l3; void *obj; - kmem_bufctl_t next; int x; l3 = cachep->nodelists[nodeid]; @@ -2701,14 +2726,7 @@ static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid) BUG_ON(slabp->inuse == cachep->num); - /* get obj pointer */ - obj = slabp->s_mem + slabp->free * cachep->buffer_size; - slabp->inuse++; - next = slab_bufctl(slabp)[slabp->free]; -#if DEBUG - slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE; -#endif - slabp->free = next; + obj = slab_get_obj(cachep, slabp, nodeid); check_slabp(cachep, slabp); l3->free_objects--; /* move slabp to correct slabp list: */ @@ -2748,29 +2766,14 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, for (i = 0; i < nr_objects; i++) { void *objp = objpp[i]; struct slab *slabp; - unsigned int objnr; slabp = page_get_slab(virt_to_page(objp)); l3 = cachep->nodelists[node]; list_del(&slabp->list); - objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size; check_spinlock_acquired_node(cachep, node); check_slabp(cachep, slabp); - -#if DEBUG - /* Verify that the slab belongs to the intended node */ - WARN_ON(slabp->nodeid != node); - - if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) { - printk(KERN_ERR "slab: double free detected in cache " - "'%s', objp %p\n", cachep->name, objp); - BUG(); - } -#endif - slab_bufctl(slabp)[objnr] = slabp->free; - slabp->free = objnr; + slab_put_obj(cachep, slabp, objp, node); STATS_DEC_ACTIVE(cachep); - slabp->inuse--; l3->free_objects++; check_slabp(cachep, slabp); From 5295a74cc0bcf1291686eb734ccb06baa3d55c1a Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 1 Feb 2006 03:05:48 -0800 Subject: [PATCH 389/695] [PATCH] slab: reduce inlining From: Manfred Spraul Reduce the amount of inline functions in slab to the functions that are used in the hot path: - no inline for debug functions - no __always_inline, inline is already __always_inline - remove inline from a few numa support functions. Before: text data bss dec hex filename 13588 752 48 14388 3834 mm/slab.o (defconfig) 16671 2492 48 19211 4b0b mm/slab.o (numa) After: text data bss dec hex filename 13366 752 48 14166 3756 mm/slab.o (defconfig) 16230 2492 48 18770 4952 mm/slab.o (numa) Signed-off-by: Manfred Spraul Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 594a9155c7d8..ba288b3877d1 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -337,7 +337,7 @@ static __always_inline int index_of(const size_t size) #define INDEX_AC index_of(sizeof(struct arraycache_init)) #define INDEX_L3 index_of(sizeof(struct kmem_list3)) -static inline void kmem_list3_init(struct kmem_list3 *parent) +static void kmem_list3_init(struct kmem_list3 *parent) { INIT_LIST_HEAD(&parent->slabs_full); INIT_LIST_HEAD(&parent->slabs_partial); @@ -818,7 +818,7 @@ static struct array_cache *alloc_arraycache(int node, int entries, #ifdef CONFIG_NUMA static void *__cache_alloc_node(kmem_cache_t *, gfp_t, int); -static inline struct array_cache **alloc_alien_cache(int node, int limit) +static struct array_cache **alloc_alien_cache(int node, int limit) { struct array_cache **ac_ptr; int memsize = sizeof(void *) * MAX_NUMNODES; @@ -845,7 +845,7 @@ static inline struct array_cache **alloc_alien_cache(int node, int limit) return ac_ptr; } -static inline void free_alien_cache(struct array_cache **ac_ptr) +static void free_alien_cache(struct array_cache **ac_ptr) { int i; @@ -858,8 +858,8 @@ static inline void free_alien_cache(struct array_cache **ac_ptr) kfree(ac_ptr); } -static inline void __drain_alien_cache(kmem_cache_t *cachep, - struct array_cache *ac, int node) +static void __drain_alien_cache(kmem_cache_t *cachep, + struct array_cache *ac, int node) { struct kmem_list3 *rl3 = cachep->nodelists[node]; @@ -1534,7 +1534,7 @@ static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) /* For setting up all the kmem_list3s for cache whose buffer_size is same as size of kmem_list3. */ -static inline void set_up_list3s(kmem_cache_t *cachep, int index) +static void set_up_list3s(kmem_cache_t *cachep, int index) { int node; @@ -1937,7 +1937,7 @@ static void check_spinlock_acquired(kmem_cache_t *cachep) #endif } -static inline void check_spinlock_acquired_node(kmem_cache_t *cachep, int node) +static void check_spinlock_acquired_node(kmem_cache_t *cachep, int node) { #ifdef CONFIG_SMP check_irq_off(); From 6ed5eb2211204224799b2821656bbbfde26ef200 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 1 Feb 2006 03:05:49 -0800 Subject: [PATCH 390/695] [PATCH] slab: extract virt_to_{cache|slab} Introduce virt_to_cache() and virt_to_slab() functions to reduce duplicate code and introduce a proper abstraction should we want to support other kind of mapping for address to slab and cache (eg. for vmalloc() or I/O memory). Acked-by: Manfred Spraul Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index ba288b3877d1..c2f9e0a330ff 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -596,6 +596,18 @@ static inline struct slab *page_get_slab(struct page *page) return (struct slab *)page->lru.prev; } +static inline struct kmem_cache *virt_to_cache(const void *obj) +{ + struct page *page = virt_to_page(obj); + return page_get_cache(page); +} + +static inline struct slab *virt_to_slab(const void *obj) +{ + struct page *page = virt_to_page(obj); + return page_get_slab(page); +} + /* These are the default caches for kmalloc. Custom caches can have other sizes. */ struct cache_sizes malloc_sizes[] = { #define CACHE(x) { .cs_size = (x) }, @@ -1437,7 +1449,7 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp) /* Print some data about the neighboring objects, if they * exist: */ - struct slab *slabp = page_get_slab(virt_to_page(objp)); + struct slab *slabp = virt_to_slab(objp); int objnr; objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size; @@ -2767,7 +2779,7 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, void *objp = objpp[i]; struct slab *slabp; - slabp = page_get_slab(virt_to_page(objp)); + slabp = virt_to_slab(objp); l3 = cachep->nodelists[node]; list_del(&slabp->list); check_spinlock_acquired_node(cachep, node); @@ -2867,7 +2879,7 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp) #ifdef CONFIG_NUMA { struct slab *slabp; - slabp = page_get_slab(virt_to_page(objp)); + slabp = virt_to_slab(objp); if (unlikely(slabp->nodeid != numa_node_id())) { struct array_cache *alien = NULL; int nodeid = slabp->nodeid; @@ -3130,7 +3142,7 @@ void kfree(const void *objp) return; local_irq_save(flags); kfree_debugcheck(objp); - c = page_get_cache(virt_to_page(objp)); + c = virt_to_cache(objp); mutex_debug_check_no_locks_freed(objp, obj_size(c)); __cache_free(c, (void *)objp); local_irq_restore(flags); @@ -3704,5 +3716,5 @@ unsigned int ksize(const void *objp) if (unlikely(objp == NULL)) return 0; - return obj_size(page_get_cache(virt_to_page(objp))); + return obj_size(virt_to_cache(objp)); } From 9a2dba4b4912b493070cbc170629fdbf440b01d7 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 1 Feb 2006 03:05:49 -0800 Subject: [PATCH 391/695] [PATCH] slab: rename ac_data to cpu_cache_get Rename the ac_data() function to more descriptive cpu_cache_get(). Acked-by: Manfred Spraul Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index c2f9e0a330ff..b19093864998 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -679,7 +679,7 @@ static void enable_cpucache(kmem_cache_t *cachep); static void cache_reap(void *unused); static int __node_shrink(kmem_cache_t *cachep, int node); -static inline struct array_cache *ac_data(kmem_cache_t *cachep) +static inline struct array_cache *cpu_cache_get(kmem_cache_t *cachep) { return cachep->array[smp_processor_id()]; } @@ -1186,8 +1186,8 @@ void __init kmem_cache_init(void) ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL); local_irq_disable(); - BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache); - memcpy(ptr, ac_data(&cache_cache), + BUG_ON(cpu_cache_get(&cache_cache) != &initarray_cache.cache); + memcpy(ptr, cpu_cache_get(&cache_cache), sizeof(struct arraycache_init)); cache_cache.array[smp_processor_id()] = ptr; local_irq_enable(); @@ -1195,9 +1195,9 @@ void __init kmem_cache_init(void) ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL); local_irq_disable(); - BUG_ON(ac_data(malloc_sizes[INDEX_AC].cs_cachep) + BUG_ON(cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep) != &initarray_generic.cache); - memcpy(ptr, ac_data(malloc_sizes[INDEX_AC].cs_cachep), + memcpy(ptr, cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep), sizeof(struct arraycache_init)); malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] = ptr; @@ -1235,7 +1235,7 @@ void __init kmem_cache_init(void) g_cpucache_up = FULL; /* Register a cpu startup notifier callback - * that initializes ac_data for all new cpus + * that initializes cpu_cache_get for all new cpus */ register_cpu_notifier(&cpucache_notifier); @@ -1909,11 +1909,11 @@ kmem_cache_create (const char *name, size_t size, size_t align, jiffies + REAPTIMEOUT_LIST3 + ((unsigned long)cachep) % REAPTIMEOUT_LIST3; - BUG_ON(!ac_data(cachep)); - ac_data(cachep)->avail = 0; - ac_data(cachep)->limit = BOOT_CPUCACHE_ENTRIES; - ac_data(cachep)->batchcount = 1; - ac_data(cachep)->touched = 0; + BUG_ON(!cpu_cache_get(cachep)); + cpu_cache_get(cachep)->avail = 0; + cpu_cache_get(cachep)->limit = BOOT_CPUCACHE_ENTRIES; + cpu_cache_get(cachep)->batchcount = 1; + cpu_cache_get(cachep)->touched = 0; cachep->batchcount = 1; cachep->limit = BOOT_CPUCACHE_ENTRIES; } @@ -1992,7 +1992,7 @@ static void do_drain(void *arg) int node = numa_node_id(); check_irq_off(); - ac = ac_data(cachep); + ac = cpu_cache_get(cachep); spin_lock(&cachep->nodelists[node]->list_lock); free_block(cachep, ac->entry, ac->avail, node); spin_unlock(&cachep->nodelists[node]->list_lock); @@ -2518,7 +2518,7 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags) struct array_cache *ac; check_irq_off(); - ac = ac_data(cachep); + ac = cpu_cache_get(cachep); retry: batchcount = ac->batchcount; if (!ac->touched && batchcount > BATCHREFILL_LIMIT) { @@ -2590,7 +2590,7 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags) x = cache_grow(cachep, flags, numa_node_id()); // cache_grow can reenable interrupts, then ac could change. - ac = ac_data(cachep); + ac = cpu_cache_get(cachep); if (!x && ac->avail == 0) // no objects in sight? abort return NULL; @@ -2675,7 +2675,7 @@ static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags) #endif check_irq_off(); - ac = ac_data(cachep); + ac = cpu_cache_get(cachep); if (likely(ac->avail)) { STATS_INC_ALLOCHIT(cachep); ac->touched = 1; @@ -2868,7 +2868,7 @@ static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac) */ static inline void __cache_free(kmem_cache_t *cachep, void *objp) { - struct array_cache *ac = ac_data(cachep); + struct array_cache *ac = cpu_cache_get(cachep); check_irq_off(); objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); @@ -3253,7 +3253,7 @@ static void do_ccupdate_local(void *info) struct array_cache *old; check_irq_off(); - old = ac_data(new->cachep); + old = cpu_cache_get(new->cachep); new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()]; new->new[smp_processor_id()] = old; @@ -3419,7 +3419,7 @@ static void cache_reap(void *unused) drain_alien_cache(searchp, l3); spin_lock_irq(&l3->list_lock); - drain_array_locked(searchp, ac_data(searchp), 0, + drain_array_locked(searchp, cpu_cache_get(searchp), 0, numa_node_id()); if (time_after(l3->next_reap, jiffies)) From 343e0d7a93951e35065fdb5e3dd61aece0ec6b3c Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 1 Feb 2006 03:05:50 -0800 Subject: [PATCH 392/695] [PATCH] slab: replace kmem_cache_t with struct kmem_cache Replace uses of kmem_cache_t with proper struct kmem_cache in mm/slab.c. Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 195 +++++++++++++++++++++++++++--------------------------- 1 file changed, 98 insertions(+), 97 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index b19093864998..6fbd6a1cdeb4 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -55,7 +55,7 @@ * * SMP synchronization: * constructors and destructors are called without any locking. - * Several members in kmem_cache_t and struct slab never change, they + * Several members in struct kmem_cache and struct slab never change, they * are accessed without any locking. * The per-cpu arrays are never accessed from the wrong cpu, no locking, * and local interrupts are disabled so slab code is preempt-safe. @@ -244,7 +244,7 @@ struct slab { */ struct slab_rcu { struct rcu_head head; - kmem_cache_t *cachep; + struct kmem_cache *cachep; void *addr; }; @@ -363,7 +363,7 @@ static void kmem_list3_init(struct kmem_list3 *parent) } while (0) /* - * kmem_cache_t + * struct kmem_cache * * manages a cache. */ @@ -391,15 +391,15 @@ struct kmem_cache { size_t colour; /* cache colouring range */ unsigned int colour_off; /* colour offset */ unsigned int colour_next; /* cache colouring */ - kmem_cache_t *slabp_cache; + struct kmem_cache *slabp_cache; unsigned int slab_size; unsigned int dflags; /* dynamic flags */ /* constructor func */ - void (*ctor) (void *, kmem_cache_t *, unsigned long); + void (*ctor) (void *, struct kmem_cache *, unsigned long); /* de-constructor func */ - void (*dtor) (void *, kmem_cache_t *, unsigned long); + void (*dtor) (void *, struct kmem_cache *, unsigned long); /* 4) cache creation/removal */ const char *name; @@ -509,23 +509,23 @@ struct kmem_cache { * cachep->buffer_size - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long] * cachep->buffer_size - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long] */ -static int obj_offset(kmem_cache_t *cachep) +static int obj_offset(struct kmem_cache *cachep) { return cachep->obj_offset; } -static int obj_size(kmem_cache_t *cachep) +static int obj_size(struct kmem_cache *cachep) { return cachep->obj_size; } -static unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp) +static unsigned long *dbg_redzone1(struct kmem_cache *cachep, void *objp) { BUG_ON(!(cachep->flags & SLAB_RED_ZONE)); return (unsigned long*) (objp+obj_offset(cachep)-BYTES_PER_WORD); } -static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp) +static unsigned long *dbg_redzone2(struct kmem_cache *cachep, void *objp) { BUG_ON(!(cachep->flags & SLAB_RED_ZONE)); if (cachep->flags & SLAB_STORE_USER) @@ -534,7 +534,7 @@ static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp) return (unsigned long *)(objp + cachep->buffer_size - BYTES_PER_WORD); } -static void **dbg_userword(kmem_cache_t *cachep, void *objp) +static void **dbg_userword(struct kmem_cache *cachep, void *objp) { BUG_ON(!(cachep->flags & SLAB_STORE_USER)); return (void **)(objp + cachep->buffer_size - BYTES_PER_WORD); @@ -636,16 +636,16 @@ static struct arraycache_init initarray_generic = { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; /* internal cache of cache description objs */ -static kmem_cache_t cache_cache = { +static struct kmem_cache cache_cache = { .batchcount = 1, .limit = BOOT_CPUCACHE_ENTRIES, .shared = 1, - .buffer_size = sizeof(kmem_cache_t), + .buffer_size = sizeof(struct kmem_cache), .flags = SLAB_NO_REAP, .spinlock = SPIN_LOCK_UNLOCKED, .name = "kmem_cache", #if DEBUG - .obj_size = sizeof(kmem_cache_t), + .obj_size = sizeof(struct kmem_cache), #endif }; @@ -674,17 +674,17 @@ static enum { static DEFINE_PER_CPU(struct work_struct, reap_work); -static void free_block(kmem_cache_t *cachep, void **objpp, int len, int node); -static void enable_cpucache(kmem_cache_t *cachep); +static void free_block(struct kmem_cache *cachep, void **objpp, int len, int node); +static void enable_cpucache(struct kmem_cache *cachep); static void cache_reap(void *unused); -static int __node_shrink(kmem_cache_t *cachep, int node); +static int __node_shrink(struct kmem_cache *cachep, int node); -static inline struct array_cache *cpu_cache_get(kmem_cache_t *cachep) +static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep) { return cachep->array[smp_processor_id()]; } -static inline kmem_cache_t *__find_general_cachep(size_t size, gfp_t gfpflags) +static inline struct kmem_cache *__find_general_cachep(size_t size, gfp_t gfpflags) { struct cache_sizes *csizep = malloc_sizes; @@ -708,7 +708,7 @@ static inline kmem_cache_t *__find_general_cachep(size_t size, gfp_t gfpflags) return csizep->cs_cachep; } -kmem_cache_t *kmem_find_general_cachep(size_t size, gfp_t gfpflags) +struct kmem_cache *kmem_find_general_cachep(size_t size, gfp_t gfpflags) { return __find_general_cachep(size, gfpflags); } @@ -781,7 +781,7 @@ static void cache_estimate(unsigned long gfporder, size_t buffer_size, #define slab_error(cachep, msg) __slab_error(__FUNCTION__, cachep, msg) -static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg) +static void __slab_error(const char *function, struct kmem_cache *cachep, char *msg) { printk(KERN_ERR "slab error in %s(): cache `%s': %s\n", function, cachep->name, msg); @@ -828,7 +828,7 @@ static struct array_cache *alloc_arraycache(int node, int entries, } #ifdef CONFIG_NUMA -static void *__cache_alloc_node(kmem_cache_t *, gfp_t, int); +static void *__cache_alloc_node(struct kmem_cache *, gfp_t, int); static struct array_cache **alloc_alien_cache(int node, int limit) { @@ -870,7 +870,7 @@ static void free_alien_cache(struct array_cache **ac_ptr) kfree(ac_ptr); } -static void __drain_alien_cache(kmem_cache_t *cachep, +static void __drain_alien_cache(struct kmem_cache *cachep, struct array_cache *ac, int node) { struct kmem_list3 *rl3 = cachep->nodelists[node]; @@ -883,7 +883,7 @@ static void __drain_alien_cache(kmem_cache_t *cachep, } } -static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3) +static void drain_alien_cache(struct kmem_cache *cachep, struct kmem_list3 *l3) { int i = 0; struct array_cache *ac; @@ -908,7 +908,7 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { long cpu = (long)hcpu; - kmem_cache_t *cachep; + struct kmem_cache *cachep; struct kmem_list3 *l3 = NULL; int node = cpu_to_node(cpu); int memsize = sizeof(struct kmem_list3); @@ -1046,7 +1046,7 @@ static struct notifier_block cpucache_notifier = { &cpuup_callback, NULL, 0 }; /* * swap the static kmem_list3 with kmalloced memory */ -static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list, int nodeid) +static void init_list(struct kmem_cache *cachep, struct kmem_list3 *list, int nodeid) { struct kmem_list3 *ptr; @@ -1086,14 +1086,14 @@ void __init kmem_cache_init(void) /* Bootstrap is tricky, because several objects are allocated * from caches that do not exist yet: - * 1) initialize the cache_cache cache: it contains the kmem_cache_t + * 1) initialize the cache_cache cache: it contains the struct kmem_cache * structures of all caches, except cache_cache itself: cache_cache * is statically allocated. * Initially an __init data area is used for the head array and the * kmem_list3 structures, it's replaced with a kmalloc allocated * array at the end of the bootstrap. * 2) Create the first kmalloc cache. - * The kmem_cache_t for the new cache is allocated normally. + * The struct kmem_cache for the new cache is allocated normally. * An __init data area is used for the head array. * 3) Create the remaining kmalloc caches, with minimally sized * head arrays. @@ -1224,7 +1224,7 @@ void __init kmem_cache_init(void) /* 6) resize the head arrays to their final sizes */ { - kmem_cache_t *cachep; + struct kmem_cache *cachep; mutex_lock(&cache_chain_mutex); list_for_each_entry(cachep, &cache_chain, next) enable_cpucache(cachep); @@ -1267,7 +1267,7 @@ __initcall(cpucache_init); * did not request dmaable memory, we might get it, but that * would be relatively rare and ignorable. */ -static void *kmem_getpages(kmem_cache_t *cachep, gfp_t flags, int nodeid) +static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid) { struct page *page; void *addr; @@ -1293,7 +1293,7 @@ static void *kmem_getpages(kmem_cache_t *cachep, gfp_t flags, int nodeid) /* * Interface to system's page release. */ -static void kmem_freepages(kmem_cache_t *cachep, void *addr) +static void kmem_freepages(struct kmem_cache *cachep, void *addr) { unsigned long i = (1 << cachep->gfporder); struct page *page = virt_to_page(addr); @@ -1315,7 +1315,7 @@ static void kmem_freepages(kmem_cache_t *cachep, void *addr) static void kmem_rcu_free(struct rcu_head *head) { struct slab_rcu *slab_rcu = (struct slab_rcu *)head; - kmem_cache_t *cachep = slab_rcu->cachep; + struct kmem_cache *cachep = slab_rcu->cachep; kmem_freepages(cachep, slab_rcu->addr); if (OFF_SLAB(cachep)) @@ -1325,7 +1325,7 @@ static void kmem_rcu_free(struct rcu_head *head) #if DEBUG #ifdef CONFIG_DEBUG_PAGEALLOC -static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr, +static void store_stackinfo(struct kmem_cache *cachep, unsigned long *addr, unsigned long caller) { int size = obj_size(cachep); @@ -1358,7 +1358,7 @@ static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr, } #endif -static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val) +static void poison_obj(struct kmem_cache *cachep, void *addr, unsigned char val) { int size = obj_size(cachep); addr = &((char *)addr)[obj_offset(cachep)]; @@ -1380,7 +1380,7 @@ static void dump_line(char *data, int offset, int limit) #if DEBUG -static void print_objinfo(kmem_cache_t *cachep, void *objp, int lines) +static void print_objinfo(struct kmem_cache *cachep, void *objp, int lines) { int i, size; char *realobj; @@ -1409,7 +1409,7 @@ static void print_objinfo(kmem_cache_t *cachep, void *objp, int lines) } } -static void check_poison_obj(kmem_cache_t *cachep, void *objp) +static void check_poison_obj(struct kmem_cache *cachep, void *objp) { char *realobj; int size, i; @@ -1476,7 +1476,7 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp) * slab_destroy_objs - call the registered destructor for each object in * a slab that is to be destroyed. */ -static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp) +static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) { int i; for (i = 0; i < cachep->num; i++) { @@ -1508,7 +1508,7 @@ static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp) } } #else -static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp) +static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) { if (cachep->dtor) { int i; @@ -1525,7 +1525,7 @@ static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp) * Before calling the slab must have been unlinked from the cache. * The cache-lock is not held/needed. */ -static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) +static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp) { void *addr = slabp->s_mem - slabp->colouroff; @@ -1546,7 +1546,7 @@ static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp) /* For setting up all the kmem_list3s for cache whose buffer_size is same as size of kmem_list3. */ -static void set_up_list3s(kmem_cache_t *cachep, int index) +static void set_up_list3s(struct kmem_cache *cachep, int index) { int node; @@ -1566,7 +1566,7 @@ static void set_up_list3s(kmem_cache_t *cachep, int index) * high order pages for slabs. When the gfp() functions are more friendly * towards high-order requests, this should be changed. */ -static inline size_t calculate_slab_order(kmem_cache_t *cachep, size_t size, +static inline size_t calculate_slab_order(struct kmem_cache *cachep, size_t size, size_t align, gfp_t flags) { size_t left_over = 0; @@ -1638,13 +1638,13 @@ static inline size_t calculate_slab_order(kmem_cache_t *cachep, size_t size, * cacheline. This can be beneficial if you're counting cycles as closely * as davem. */ -kmem_cache_t * +struct kmem_cache * kmem_cache_create (const char *name, size_t size, size_t align, - unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long), - void (*dtor)(void*, kmem_cache_t *, unsigned long)) + unsigned long flags, void (*ctor)(void*, struct kmem_cache *, unsigned long), + void (*dtor)(void*, struct kmem_cache *, unsigned long)) { size_t left_over, slab_size, ralign; - kmem_cache_t *cachep = NULL; + struct kmem_cache *cachep = NULL; struct list_head *p; /* @@ -1662,7 +1662,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, mutex_lock(&cache_chain_mutex); list_for_each(p, &cache_chain) { - kmem_cache_t *pc = list_entry(p, kmem_cache_t, next); + struct kmem_cache *pc = list_entry(p, struct kmem_cache, next); mm_segment_t old_fs = get_fs(); char tmp; int res; @@ -1762,10 +1762,10 @@ kmem_cache_create (const char *name, size_t size, size_t align, align = ralign; /* Get cache's description obj. */ - cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL); + cachep = kmem_cache_alloc(&cache_cache, SLAB_KERNEL); if (!cachep) goto oops; - memset(cachep, 0, sizeof(kmem_cache_t)); + memset(cachep, 0, sizeof(struct kmem_cache)); #if DEBUG cachep->obj_size = size; @@ -1941,7 +1941,7 @@ static void check_irq_on(void) BUG_ON(irqs_disabled()); } -static void check_spinlock_acquired(kmem_cache_t *cachep) +static void check_spinlock_acquired(struct kmem_cache *cachep) { #ifdef CONFIG_SMP check_irq_off(); @@ -1949,7 +1949,7 @@ static void check_spinlock_acquired(kmem_cache_t *cachep) #endif } -static void check_spinlock_acquired_node(kmem_cache_t *cachep, int node) +static void check_spinlock_acquired_node(struct kmem_cache *cachep, int node) { #ifdef CONFIG_SMP check_irq_off(); @@ -1982,12 +1982,12 @@ static void smp_call_function_all_cpus(void (*func)(void *arg), void *arg) preempt_enable(); } -static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac, +static void drain_array_locked(struct kmem_cache *cachep, struct array_cache *ac, int force, int node); static void do_drain(void *arg) { - kmem_cache_t *cachep = (kmem_cache_t *) arg; + struct kmem_cache *cachep = (struct kmem_cache *) arg; struct array_cache *ac; int node = numa_node_id(); @@ -1999,7 +1999,7 @@ static void do_drain(void *arg) ac->avail = 0; } -static void drain_cpu_caches(kmem_cache_t *cachep) +static void drain_cpu_caches(struct kmem_cache *cachep) { struct kmem_list3 *l3; int node; @@ -2020,7 +2020,7 @@ static void drain_cpu_caches(kmem_cache_t *cachep) spin_unlock_irq(&cachep->spinlock); } -static int __node_shrink(kmem_cache_t *cachep, int node) +static int __node_shrink(struct kmem_cache *cachep, int node) { struct slab *slabp; struct kmem_list3 *l3 = cachep->nodelists[node]; @@ -2049,7 +2049,7 @@ static int __node_shrink(kmem_cache_t *cachep, int node) return ret; } -static int __cache_shrink(kmem_cache_t *cachep) +static int __cache_shrink(struct kmem_cache *cachep) { int ret = 0, i = 0; struct kmem_list3 *l3; @@ -2075,7 +2075,7 @@ static int __cache_shrink(kmem_cache_t *cachep) * Releases as many slabs as possible for a cache. * To help debugging, a zero exit status indicates all slabs were released. */ -int kmem_cache_shrink(kmem_cache_t *cachep) +int kmem_cache_shrink(struct kmem_cache *cachep) { if (!cachep || in_interrupt()) BUG(); @@ -2088,7 +2088,7 @@ EXPORT_SYMBOL(kmem_cache_shrink); * kmem_cache_destroy - delete a cache * @cachep: the cache to destroy * - * Remove a kmem_cache_t object from the slab cache. + * Remove a struct kmem_cache object from the slab cache. * Returns 0 on success. * * It is expected this function will be called by a module when it is @@ -2101,7 +2101,7 @@ EXPORT_SYMBOL(kmem_cache_shrink); * The caller must guarantee that noone will allocate memory from the cache * during the kmem_cache_destroy(). */ -int kmem_cache_destroy(kmem_cache_t *cachep) +int kmem_cache_destroy(struct kmem_cache *cachep) { int i; struct kmem_list3 *l3; @@ -2152,7 +2152,7 @@ int kmem_cache_destroy(kmem_cache_t *cachep) EXPORT_SYMBOL(kmem_cache_destroy); /* Get the memory for a slab management obj. */ -static struct slab *alloc_slabmgmt(kmem_cache_t *cachep, void *objp, +static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, int colour_off, gfp_t local_flags) { struct slab *slabp; @@ -2178,7 +2178,7 @@ static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp) return (kmem_bufctl_t *) (slabp + 1); } -static void cache_init_objs(kmem_cache_t *cachep, +static void cache_init_objs(struct kmem_cache *cachep, struct slab *slabp, unsigned long ctor_flags) { int i; @@ -2227,7 +2227,7 @@ static void cache_init_objs(kmem_cache_t *cachep, slabp->free = 0; } -static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags) +static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags) { if (flags & SLAB_DMA) { if (!(cachep->gfpflags & GFP_DMA)) @@ -2238,7 +2238,7 @@ static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags) } } -static void *slab_get_obj(kmem_cache_t *cachep, struct slab *slabp, int nodeid) +static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slabp, int nodeid) { void *objp = slabp->s_mem + (slabp->free * cachep->buffer_size); kmem_bufctl_t next; @@ -2254,7 +2254,7 @@ static void *slab_get_obj(kmem_cache_t *cachep, struct slab *slabp, int nodeid) return objp; } -static void slab_put_obj(kmem_cache_t *cachep, struct slab *slabp, void *objp, +static void slab_put_obj(struct kmem_cache *cachep, struct slab *slabp, void *objp, int nodeid) { unsigned int objnr = (unsigned)(objp-slabp->s_mem) / cachep->buffer_size; @@ -2274,7 +2274,7 @@ static void slab_put_obj(kmem_cache_t *cachep, struct slab *slabp, void *objp, slabp->inuse--; } -static void set_slab_attr(kmem_cache_t *cachep, struct slab *slabp, void *objp) +static void set_slab_attr(struct kmem_cache *cachep, struct slab *slabp, void *objp) { int i; struct page *page; @@ -2293,7 +2293,7 @@ static void set_slab_attr(kmem_cache_t *cachep, struct slab *slabp, void *objp) * Grow (by 1) the number of slabs within a cache. This is called by * kmem_cache_alloc() when there are no active objs left in a cache. */ -static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid) +static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid) { struct slab *slabp; void *objp; @@ -2404,7 +2404,7 @@ static void kfree_debugcheck(const void *objp) } } -static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp, +static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp, void *caller) { struct page *page; @@ -2478,7 +2478,7 @@ static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp, return objp; } -static void check_slabp(kmem_cache_t *cachep, struct slab *slabp) +static void check_slabp(struct kmem_cache *cachep, struct slab *slabp) { kmem_bufctl_t i; int entries = 0; @@ -2511,7 +2511,7 @@ static void check_slabp(kmem_cache_t *cachep, struct slab *slabp) #define check_slabp(x,y) do { } while(0) #endif -static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags) +static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) { int batchcount; struct kmem_list3 *l3; @@ -2602,7 +2602,7 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags) } static inline void -cache_alloc_debugcheck_before(kmem_cache_t *cachep, gfp_t flags) +cache_alloc_debugcheck_before(struct kmem_cache *cachep, gfp_t flags) { might_sleep_if(flags & __GFP_WAIT); #if DEBUG @@ -2611,7 +2611,7 @@ cache_alloc_debugcheck_before(kmem_cache_t *cachep, gfp_t flags) } #if DEBUG -static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags, +static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep, gfp_t flags, void *objp, void *caller) { if (!objp) @@ -2660,7 +2660,7 @@ static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags, #define cache_alloc_debugcheck_after(a,b,objp,d) (objp) #endif -static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags) +static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags) { void *objp; struct array_cache *ac; @@ -2687,7 +2687,7 @@ static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags) return objp; } -static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags) +static inline void *__cache_alloc(struct kmem_cache *cachep, gfp_t flags) { unsigned long save_flags; void *objp; @@ -2707,7 +2707,7 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags) /* * A interface to enable slab creation on nodeid */ -static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid) +static void *__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) { struct list_head *entry; struct slab *slabp; @@ -2769,7 +2769,7 @@ static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid) /* * Caller needs to acquire correct kmem_list's list_lock */ -static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, +static void free_block(struct kmem_cache *cachep, void **objpp, int nr_objects, int node) { int i; @@ -2807,7 +2807,7 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, } } -static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac) +static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac) { int batchcount; struct kmem_list3 *l3; @@ -2866,7 +2866,7 @@ static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac) * * Called with disabled ints. */ -static inline void __cache_free(kmem_cache_t *cachep, void *objp) +static inline void __cache_free(struct kmem_cache *cachep, void *objp) { struct array_cache *ac = cpu_cache_get(cachep); @@ -2925,7 +2925,7 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp) * Allocate an object from this cache. The flags are only relevant * if the cache has no available objects. */ -void *kmem_cache_alloc(kmem_cache_t *cachep, gfp_t flags) +void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) { return __cache_alloc(cachep, flags); } @@ -2945,7 +2945,7 @@ EXPORT_SYMBOL(kmem_cache_alloc); * * Currently only used for dentry validation. */ -int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr) +int fastcall kmem_ptr_validate(struct kmem_cache *cachep, void *ptr) { unsigned long addr = (unsigned long)ptr; unsigned long min_addr = PAGE_OFFSET; @@ -2986,7 +2986,7 @@ int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr) * New and improved: it will now make sure that the object gets * put on the correct node list so that there is no false sharing. */ -void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid) +void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) { unsigned long save_flags; void *ptr; @@ -3010,7 +3010,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_node); void *kmalloc_node(size_t size, gfp_t flags, int node) { - kmem_cache_t *cachep; + struct kmem_cache *cachep; cachep = kmem_find_general_cachep(size, flags); if (unlikely(cachep == NULL)) @@ -3043,7 +3043,7 @@ EXPORT_SYMBOL(kmalloc_node); */ void *__kmalloc(size_t size, gfp_t flags) { - kmem_cache_t *cachep; + struct kmem_cache *cachep; /* If you want to save a few bytes .text space: replace * __ with kmem_. @@ -3114,7 +3114,7 @@ EXPORT_SYMBOL(__alloc_percpu); * Free an object which was previously allocated from this * cache. */ -void kmem_cache_free(kmem_cache_t *cachep, void *objp) +void kmem_cache_free(struct kmem_cache *cachep, void *objp) { unsigned long flags; @@ -3135,7 +3135,7 @@ EXPORT_SYMBOL(kmem_cache_free); */ void kfree(const void *objp) { - kmem_cache_t *c; + struct kmem_cache *c; unsigned long flags; if (unlikely(!objp)) @@ -3172,13 +3172,13 @@ void free_percpu(const void *objp) EXPORT_SYMBOL(free_percpu); #endif -unsigned int kmem_cache_size(kmem_cache_t *cachep) +unsigned int kmem_cache_size(struct kmem_cache *cachep) { return obj_size(cachep); } EXPORT_SYMBOL(kmem_cache_size); -const char *kmem_cache_name(kmem_cache_t *cachep) +const char *kmem_cache_name(struct kmem_cache *cachep) { return cachep->name; } @@ -3187,7 +3187,7 @@ EXPORT_SYMBOL_GPL(kmem_cache_name); /* * This initializes kmem_list3 for all nodes. */ -static int alloc_kmemlist(kmem_cache_t *cachep) +static int alloc_kmemlist(struct kmem_cache *cachep) { int node; struct kmem_list3 *l3; @@ -3243,7 +3243,7 @@ static int alloc_kmemlist(kmem_cache_t *cachep) } struct ccupdate_struct { - kmem_cache_t *cachep; + struct kmem_cache *cachep; struct array_cache *new[NR_CPUS]; }; @@ -3259,7 +3259,7 @@ static void do_ccupdate_local(void *info) new->new[smp_processor_id()] = old; } -static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount, +static int do_tune_cpucache(struct kmem_cache *cachep, int limit, int batchcount, int shared) { struct ccupdate_struct new; @@ -3305,7 +3305,7 @@ static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount, return 0; } -static void enable_cpucache(kmem_cache_t *cachep) +static void enable_cpucache(struct kmem_cache *cachep) { int err; int limit, shared; @@ -3357,7 +3357,7 @@ static void enable_cpucache(kmem_cache_t *cachep) cachep->name, -err); } -static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac, +static void drain_array_locked(struct kmem_cache *cachep, struct array_cache *ac, int force, int node) { int tofree; @@ -3402,12 +3402,12 @@ static void cache_reap(void *unused) } list_for_each(walk, &cache_chain) { - kmem_cache_t *searchp; + struct kmem_cache *searchp; struct list_head *p; int tofree; struct slab *slabp; - searchp = list_entry(walk, kmem_cache_t, next); + searchp = list_entry(walk, struct kmem_cache, next); if (searchp->flags & SLAB_NO_REAP) goto next; @@ -3510,15 +3510,15 @@ static void *s_start(struct seq_file *m, loff_t *pos) if (p == &cache_chain) return NULL; } - return list_entry(p, kmem_cache_t, next); + return list_entry(p, struct kmem_cache, next); } static void *s_next(struct seq_file *m, void *p, loff_t *pos) { - kmem_cache_t *cachep = p; + struct kmem_cache *cachep = p; ++*pos; return cachep->next.next == &cache_chain ? NULL - : list_entry(cachep->next.next, kmem_cache_t, next); + : list_entry(cachep->next.next, struct kmem_cache, next); } static void s_stop(struct seq_file *m, void *p) @@ -3528,7 +3528,7 @@ static void s_stop(struct seq_file *m, void *p) static int s_show(struct seq_file *m, void *p) { - kmem_cache_t *cachep = p; + struct kmem_cache *cachep = p; struct list_head *q; struct slab *slabp; unsigned long active_objs; @@ -3678,7 +3678,8 @@ ssize_t slabinfo_write(struct file *file, const char __user * buffer, mutex_lock(&cache_chain_mutex); res = -EINVAL; list_for_each(p, &cache_chain) { - kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next); + struct kmem_cache *cachep = list_entry(p, struct kmem_cache, + next); if (!strcmp(cachep->name, kbuf)) { if (limit < 1 || From b958f7d9f35bfb61625f201cd92a3fc39504af7a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 1 Feb 2006 03:05:51 -0800 Subject: [PATCH 393/695] [PATCH] dump_stack() in oom handler Sometimes it's nice to know who's calling. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/oom_kill.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 14bd4ec79597..b05ab8f2a562 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -271,6 +271,7 @@ void out_of_memory(gfp_t gfp_mask, int order) if (printk_ratelimit()) { printk("oom-killer: gfp_mask=0x%x, order=%d\n", gfp_mask, order); + dump_stack(); show_mem(); } From 7fd6b1413082c303613fc137aca9a004740cacf0 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 1 Feb 2006 03:05:52 -0800 Subject: [PATCH 394/695] [PATCH] slab: fix kzalloc and kstrdup caller report for CONFIG_DEBUG_SLAB Fix kzalloc() and kstrdup() caller report for CONFIG_DEBUG_SLAB. We must pass the caller to __cache_alloc() instead of directly doing __builtin_return_address(0) there; otherwise kzalloc() and kstrdup() are reported as the allocation site instead of the real one. Thanks to Valdis Kletnieks for reporting the problem and Steven Rostedt for the original idea. Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab.h | 7 +++++++ mm/slab.c | 29 ++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/include/linux/slab.h b/include/linux/slab.h index 1fb77a9cc148..8cf52939d0ab 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -76,7 +76,14 @@ struct cache_sizes { kmem_cache_t *cs_dmacachep; }; extern struct cache_sizes malloc_sizes[]; + +#ifndef CONFIG_DEBUG_SLAB extern void *__kmalloc(size_t, gfp_t); +#else +extern void *__kmalloc_track_caller(size_t, gfp_t, void*); +#define __kmalloc(size, flags) \ + __kmalloc_track_caller(size, flags, __builtin_return_address(0)) +#endif static inline void *kmalloc(size_t size, gfp_t flags) { diff --git a/mm/slab.c b/mm/slab.c index 6fbd6a1cdeb4..67527268b01c 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2687,7 +2687,8 @@ static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags) return objp; } -static inline void *__cache_alloc(struct kmem_cache *cachep, gfp_t flags) +static __always_inline void * +__cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller) { unsigned long save_flags; void *objp; @@ -2698,7 +2699,7 @@ static inline void *__cache_alloc(struct kmem_cache *cachep, gfp_t flags) objp = ____cache_alloc(cachep, flags); local_irq_restore(save_flags); objp = cache_alloc_debugcheck_after(cachep, flags, objp, - __builtin_return_address(0)); + caller); prefetchw(objp); return objp; } @@ -2927,7 +2928,7 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp) */ void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) { - return __cache_alloc(cachep, flags); + return __cache_alloc(cachep, flags, __builtin_return_address(0)); } EXPORT_SYMBOL(kmem_cache_alloc); @@ -3041,7 +3042,8 @@ EXPORT_SYMBOL(kmalloc_node); * platforms. For example, on i386, it means that the memory must come * from the first 16MB. */ -void *__kmalloc(size_t size, gfp_t flags) +static __always_inline void *__do_kmalloc(size_t size, gfp_t flags, + void *caller) { struct kmem_cache *cachep; @@ -3053,10 +3055,27 @@ void *__kmalloc(size_t size, gfp_t flags) cachep = __find_general_cachep(size, flags); if (unlikely(cachep == NULL)) return NULL; - return __cache_alloc(cachep, flags); + return __cache_alloc(cachep, flags, caller); +} + +#ifndef CONFIG_DEBUG_SLAB + +void *__kmalloc(size_t size, gfp_t flags) +{ + return __do_kmalloc(size, flags, NULL); } EXPORT_SYMBOL(__kmalloc); +#else + +void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller) +{ + return __do_kmalloc(size, flags, caller); +} +EXPORT_SYMBOL(__kmalloc_track_caller); + +#endif + #ifdef CONFIG_SMP /** * __alloc_percpu - allocate one copy of the object for every present From a70773ddb96b74c7afe5a5bc859ba45e3d02899e Mon Sep 17 00:00:00 2001 From: "Randy.Dunlap" Date: Wed, 1 Feb 2006 03:05:52 -0800 Subject: [PATCH 395/695] [PATCH] mm/slab: add kernel-doc for one function Fix kernel-doc for calculate_slab_order(). Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 67527268b01c..afe9c5f8c57a 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1559,8 +1559,13 @@ static void set_up_list3s(struct kmem_cache *cachep, int index) } /** - * calculate_slab_order - calculate size (page order) of slabs and the number - * of objects per slab. + * calculate_slab_order - calculate size (page order) of slabs + * @cachep: pointer to the cache that is being created + * @size: size of objects to be created in this cache. + * @align: required alignment for the objects. + * @flags: slab allocation flags + * + * Also calculates the number of objects per slab. * * This could be made much more intelligent. For now, try to avoid using * high order pages for slabs. When the gfp() functions are more friendly From ee13d785eac1fbe7e79ecca77bf7e902734a0b30 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 1 Feb 2006 03:05:53 -0800 Subject: [PATCH 396/695] [PATCH] slab: fix sparse warning mm/slab.c:1522:13: error: incompatible types for operation (&) Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index afe9c5f8c57a..71370256a7eb 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1571,8 +1571,8 @@ static void set_up_list3s(struct kmem_cache *cachep, int index) * high order pages for slabs. When the gfp() functions are more friendly * towards high-order requests, this should be changed. */ -static inline size_t calculate_slab_order(struct kmem_cache *cachep, size_t size, - size_t align, gfp_t flags) +static inline size_t calculate_slab_order(struct kmem_cache *cachep, + size_t size, size_t align, unsigned long flags) { size_t left_over = 0; From db4c9641def55d36a6f9df79deb8a949292313ca Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Wed, 1 Feb 2006 03:05:54 -0800 Subject: [PATCH 397/695] [PATCH] selinux: fix and cleanup mprotect checks Fix the SELinux mprotect checks on executable mappings so that they are not re-applied when the mapping is already executable as well as cleaning up the code. This avoids a situation where e.g. an application is prevented from removing PROT_WRITE on an already executable mapping previously authorized via execmem permission due to an execmod denial. Signed-off-by: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 50 +++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b9f8d9731c3d..1bb5eea3b8c1 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2454,35 +2454,27 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, prot = reqprot; #ifndef CONFIG_PPC32 - if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) && - (vma->vm_start >= vma->vm_mm->start_brk && - vma->vm_end <= vma->vm_mm->brk)) { - /* - * We are making an executable mapping in the brk region. - * This has an additional execheap check. - */ - rc = task_has_perm(current, current, PROCESS__EXECHEAP); - if (rc) - return rc; - } - if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) { - /* - * We are making executable a file mapping that has - * had some COW done. Since pages might have been written, - * check ability to execute the possibly modified content. - * This typically should only occur for text relocations. - */ - int rc = file_has_perm(current, vma->vm_file, FILE__EXECMOD); - if (rc) - return rc; - } - if (!vma->vm_file && (prot & PROT_EXEC) && - vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack) { - /* Attempt to make the process stack executable. - * This has an additional execstack check. - */ - rc = task_has_perm(current, current, PROCESS__EXECSTACK); + if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { + rc = 0; + if (vma->vm_start >= vma->vm_mm->start_brk && + vma->vm_end <= vma->vm_mm->brk) { + rc = task_has_perm(current, current, + PROCESS__EXECHEAP); + } else if (!vma->vm_file && + vma->vm_start <= vma->vm_mm->start_stack && + vma->vm_end >= vma->vm_mm->start_stack) { + rc = task_has_perm(current, current, PROCESS__EXECSTACK); + } else if (vma->vm_file && vma->anon_vma) { + /* + * We are making executable a file mapping that has + * had some COW done. Since pages might have been + * written, check ability to execute the possibly + * modified content. This typically should only + * occur for text relocations. + */ + rc = file_has_perm(current, vma->vm_file, + FILE__EXECMOD); + } if (rc) return rc; } From 26d2a4be6a56eec575dac651f6606756a971f0fb Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Wed, 1 Feb 2006 03:05:55 -0800 Subject: [PATCH 398/695] [PATCH] selinux: change file_alloc_security to use GFP_KERNEL This patch changes the SELinux file_alloc_security function to use GFP_KERNEL rather than GFP_ATOMIC; the use of GFP_ATOMIC appears to be a remnant of when this function was being called with the files_lock spinlock held, and is no longer necessary. Please apply. Signed-off-by: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1bb5eea3b8c1..5e61635610bb 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -192,7 +192,7 @@ static int file_alloc_security(struct file *file) struct task_security_struct *tsec = current->security; struct file_security_struct *fsec; - fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC); + fsec = kzalloc(sizeof(struct file_security_struct), GFP_KERNEL); if (!fsec) return -ENOMEM; From 9ac49d22138348198f729f07371ffb11991368e6 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Wed, 1 Feb 2006 03:05:56 -0800 Subject: [PATCH 399/695] [PATCH] selinux: remove security struct magic number fields and tests Remove the SELinux security structure magic number fields and tests, along with some unnecessary tests for NULL security pointers. These fields and tests are leftovers from the early attempts to support SELinux as a loadable module during LSM development. Signed-off-by: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 49 ++++--------------------------- security/selinux/include/objsec.h | 8 ----- 2 files changed, 5 insertions(+), 52 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5e61635610bb..4ae834d89bce 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -127,7 +127,6 @@ static int task_alloc_security(struct task_struct *task) if (!tsec) return -ENOMEM; - tsec->magic = SELINUX_MAGIC; tsec->task = task; tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED; task->security = tsec; @@ -138,10 +137,6 @@ static int task_alloc_security(struct task_struct *task) static void task_free_security(struct task_struct *task) { struct task_security_struct *tsec = task->security; - - if (!tsec || tsec->magic != SELINUX_MAGIC) - return; - task->security = NULL; kfree(tsec); } @@ -157,14 +152,10 @@ static int inode_alloc_security(struct inode *inode) init_MUTEX(&isec->sem); INIT_LIST_HEAD(&isec->list); - isec->magic = SELINUX_MAGIC; isec->inode = inode; isec->sid = SECINITSID_UNLABELED; isec->sclass = SECCLASS_FILE; - if (tsec && tsec->magic == SELINUX_MAGIC) - isec->task_sid = tsec->sid; - else - isec->task_sid = SECINITSID_UNLABELED; + isec->task_sid = tsec->sid; inode->i_security = isec; return 0; @@ -175,9 +166,6 @@ static void inode_free_security(struct inode *inode) struct inode_security_struct *isec = inode->i_security; struct superblock_security_struct *sbsec = inode->i_sb->s_security; - if (!isec || isec->magic != SELINUX_MAGIC) - return; - spin_lock(&sbsec->isec_lock); if (!list_empty(&isec->list)) list_del_init(&isec->list); @@ -196,15 +184,9 @@ static int file_alloc_security(struct file *file) if (!fsec) return -ENOMEM; - fsec->magic = SELINUX_MAGIC; fsec->file = file; - if (tsec && tsec->magic == SELINUX_MAGIC) { - fsec->sid = tsec->sid; - fsec->fown_sid = tsec->sid; - } else { - fsec->sid = SECINITSID_UNLABELED; - fsec->fown_sid = SECINITSID_UNLABELED; - } + fsec->sid = tsec->sid; + fsec->fown_sid = tsec->sid; file->f_security = fsec; return 0; @@ -213,10 +195,6 @@ static int file_alloc_security(struct file *file) static void file_free_security(struct file *file) { struct file_security_struct *fsec = file->f_security; - - if (!fsec || fsec->magic != SELINUX_MAGIC) - return; - file->f_security = NULL; kfree(fsec); } @@ -233,7 +211,6 @@ static int superblock_alloc_security(struct super_block *sb) INIT_LIST_HEAD(&sbsec->list); INIT_LIST_HEAD(&sbsec->isec_head); spin_lock_init(&sbsec->isec_lock); - sbsec->magic = SELINUX_MAGIC; sbsec->sb = sb; sbsec->sid = SECINITSID_UNLABELED; sbsec->def_sid = SECINITSID_FILE; @@ -246,9 +223,6 @@ static void superblock_free_security(struct super_block *sb) { struct superblock_security_struct *sbsec = sb->s_security; - if (!sbsec || sbsec->magic != SELINUX_MAGIC) - return; - spin_lock(&sb_security_lock); if (!list_empty(&sbsec->list)) list_del_init(&sbsec->list); @@ -270,7 +244,6 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) if (!ssec) return -ENOMEM; - ssec->magic = SELINUX_MAGIC; ssec->sk = sk; ssec->peer_sid = SECINITSID_UNLABELED; sk->sk_security = ssec; @@ -282,7 +255,7 @@ static void sk_free_security(struct sock *sk) { struct sk_security_struct *ssec = sk->sk_security; - if (sk->sk_family != PF_UNIX || ssec->magic != SELINUX_MAGIC) + if (sk->sk_family != PF_UNIX) return; sk->sk_security = NULL; @@ -1483,7 +1456,6 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) if (!bsec) return -ENOMEM; - bsec->magic = SELINUX_MAGIC; bsec->bprm = bprm; bsec->sid = SECINITSID_UNLABELED; bsec->set = 0; @@ -3634,14 +3606,9 @@ static int ipc_alloc_security(struct task_struct *task, if (!isec) return -ENOMEM; - isec->magic = SELINUX_MAGIC; isec->sclass = sclass; isec->ipc_perm = perm; - if (tsec) { - isec->sid = tsec->sid; - } else { - isec->sid = SECINITSID_UNLABELED; - } + isec->sid = tsec->sid; perm->security = isec; return 0; @@ -3650,9 +3617,6 @@ static int ipc_alloc_security(struct task_struct *task, static void ipc_free_security(struct kern_ipc_perm *perm) { struct ipc_security_struct *isec = perm->security; - if (!isec || isec->magic != SELINUX_MAGIC) - return; - perm->security = NULL; kfree(isec); } @@ -3665,7 +3629,6 @@ static int msg_msg_alloc_security(struct msg_msg *msg) if (!msec) return -ENOMEM; - msec->magic = SELINUX_MAGIC; msec->msg = msg; msec->sid = SECINITSID_UNLABELED; msg->security = msec; @@ -3676,8 +3639,6 @@ static int msg_msg_alloc_security(struct msg_msg *msg) static void msg_msg_free_security(struct msg_msg *msg) { struct msg_security_struct *msec = msg->security; - if (!msec || msec->magic != SELINUX_MAGIC) - return; msg->security = NULL; kfree(msec); diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 887937c8134a..54c030778882 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -27,7 +27,6 @@ #include "avc.h" struct task_security_struct { - unsigned long magic; /* magic number for this module */ struct task_struct *task; /* back pointer to task object */ u32 osid; /* SID prior to last execve */ u32 sid; /* current SID */ @@ -37,7 +36,6 @@ struct task_security_struct { }; struct inode_security_struct { - unsigned long magic; /* magic number for this module */ struct inode *inode; /* back pointer to inode object */ struct list_head list; /* list of inode_security_struct */ u32 task_sid; /* SID of creating task */ @@ -49,14 +47,12 @@ struct inode_security_struct { }; struct file_security_struct { - unsigned long magic; /* magic number for this module */ struct file *file; /* back pointer to file object */ u32 sid; /* SID of open file description */ u32 fown_sid; /* SID of file owner (for SIGIO) */ }; struct superblock_security_struct { - unsigned long magic; /* magic number for this module */ struct super_block *sb; /* back pointer to sb object */ struct list_head list; /* list of superblock_security_struct */ u32 sid; /* SID of file system */ @@ -70,20 +66,17 @@ struct superblock_security_struct { }; struct msg_security_struct { - unsigned long magic; /* magic number for this module */ struct msg_msg *msg; /* back pointer */ u32 sid; /* SID of message */ }; struct ipc_security_struct { - unsigned long magic; /* magic number for this module */ struct kern_ipc_perm *ipc_perm; /* back pointer */ u16 sclass; /* security class of this object */ u32 sid; /* SID of IPC resource */ }; struct bprm_security_struct { - unsigned long magic; /* magic number for this module */ struct linux_binprm *bprm; /* back pointer to bprm object */ u32 sid; /* SID for transformed process */ unsigned char set; @@ -102,7 +95,6 @@ struct netif_security_struct { }; struct sk_security_struct { - unsigned long magic; /* magic number for this module */ struct sock *sk; /* back pointer to sk object */ u32 peer_sid; /* SID of peer */ }; From 39931e41becd6abeb2014747369d8b6392f5dbac Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Wed, 1 Feb 2006 03:05:57 -0800 Subject: [PATCH 400/695] [PATCH] powerpc: fix for kexec ppc32 - kexec.h is included from assembly code, thus C code must be properly protected. - (embedded) ppc32 systems use machine_kexec_simple whose declaration vanished during a recent powerpc merge change. Signed-off-by: Albert Herranz Cc: Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-powerpc/kexec.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h index 640a6459f2f4..bda2f217e6fe 100644 --- a/include/asm-powerpc/kexec.h +++ b/include/asm-powerpc/kexec.h @@ -33,6 +33,7 @@ #ifdef CONFIG_KEXEC +#ifndef __ASSEMBLY__ #ifdef __powerpc64__ /* * This function is responsible for capturing register states if coming @@ -104,7 +105,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs) { } #endif /* !__powerpc64 __ */ -#ifndef __ASSEMBLY__ #define MAX_NOTE_BYTES 1024 #ifdef __powerpc64__ @@ -121,6 +121,8 @@ extern void default_machine_kexec(struct kimage *image); extern int default_machine_kexec_prepare(struct kimage *image); extern void default_machine_crash_shutdown(struct pt_regs *regs); +extern void machine_kexec_simple(struct kimage *image); + #endif /* ! __ASSEMBLY__ */ #endif /* CONFIG_KEXEC */ #endif /* __KERNEL__ */ From e61997881e0402aedbfad8696e369568a0583f14 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Wed, 1 Feb 2006 03:05:58 -0800 Subject: [PATCH 401/695] [PATCH] MODALIAS= for macio Prodive a MODALIAS= enviroment variable for devices on the mac-io bus. Change the buffer length counter to not waste memory by advancing the pointer for the next string too far. Tested on an ibook1 with modular pmac_zilog. Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/macintosh/macio_asic.c | 72 ++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index ed6d3174d660..69596f6438e9 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -140,10 +140,9 @@ static int macio_uevent(struct device *dev, char **envp, int num_envp, { struct macio_dev * macio_dev; struct of_device * of; - char *scratch, *compat; + char *scratch, *compat, *compat2; int i = 0; - int length = 0; - int cplen, seen = 0; + int length, cplen, cplen2, seen = 0; if (!dev) return -ENODEV; @@ -153,23 +152,22 @@ static int macio_uevent(struct device *dev, char **envp, int num_envp, return -ENODEV; of = &macio_dev->ofdev; - scratch = buffer; /* stuff we want to pass to /sbin/hotplug */ - envp[i++] = scratch; - length += scnprintf (scratch, buffer_size - length, "OF_NAME=%s", - of->node->name); - if ((buffer_size - length <= 0) || (i >= num_envp)) - return -ENOMEM; + envp[i++] = scratch = buffer; + length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name); ++length; + buffer_size -= length; + if ((buffer_size <= 0) || (i >= num_envp)) + return -ENOMEM; scratch += length; envp[i++] = scratch; - length += scnprintf (scratch, buffer_size - length, "OF_TYPE=%s", - of->node->type); - if ((buffer_size - length <= 0) || (i >= num_envp)) - return -ENOMEM; + length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type); ++length; + buffer_size -= length; + if ((buffer_size <= 0) || (i >= num_envp)) + return -ENOMEM; scratch += length; /* Since the compatible field can contain pretty much anything @@ -177,29 +175,55 @@ static int macio_uevent(struct device *dev, char **envp, int num_envp, * up using a number of environment variables instead. */ compat = (char *) get_property(of->node, "compatible", &cplen); + compat2 = compat; + cplen2= cplen; while (compat && cplen > 0) { - int l; envp[i++] = scratch; - length += scnprintf (scratch, buffer_size - length, + length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_%d=%s", seen, compat); - if ((buffer_size - length <= 0) || (i >= num_envp)) + ++length; + buffer_size -= length; + if ((buffer_size <= 0) || (i >= num_envp)) return -ENOMEM; - length++; scratch += length; - l = strlen (compat) + 1; - compat += l; - cplen -= l; + length = strlen (compat) + 1; + compat += length; + cplen -= length; seen++; } envp[i++] = scratch; - length += scnprintf (scratch, buffer_size - length, - "OF_COMPATIBLE_N=%d", seen); - if ((buffer_size - length <= 0) || (i >= num_envp)) - return -ENOMEM; + length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen); ++length; + buffer_size -= length; + if ((buffer_size <= 0) || (i >= num_envp)) + return -ENOMEM; scratch += length; + envp[i++] = scratch; + length = scnprintf (scratch, buffer_size, "MODALIAS=of:N%sT%s", + of->node->name, of->node->type); + /* overwrite '\0' */ + buffer_size -= length; + if ((buffer_size <= 0) || (i >= num_envp)) + return -ENOMEM; + scratch += length; + + if (!compat2) { + compat2 = ""; + cplen2 = 1; + } + while (cplen2 > 0) { + length = snprintf (scratch, buffer_size, "C%s", compat2); + buffer_size -= length; + if (buffer_size <= 0) + return -ENOMEM; + scratch += length; + length = strlen (compat2) + 1; + compat2 += length; + cplen2 -= length; + } + envp[i] = NULL; return 0; From 4a41cdf9788f14bb120ad06d9ce17ca05fd72f03 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 1 Feb 2006 03:05:58 -0800 Subject: [PATCH 402/695] [PATCH] powerpc: Fix sigmask handling in sys_sigsuspend. Better save the sigmask instead of throwing it away so it can be restored. Signed-off-by: Heiko Carstens Acked-by: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/signal_32.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 3747ab0dac3f..c6d0595da6b5 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -254,11 +254,9 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs); */ long sys_sigsuspend(old_sigset_t mask) { - sigset_t saveset; - mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; + current->saved_sigmask = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); From 740172947b315fa97f8d29b0b9809b1ea1201642 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 1 Feb 2006 03:05:59 -0800 Subject: [PATCH 403/695] [PATCH] sh: SH4-202 microdev updates A few trivial updates for the microdev board support code: - Update for __IO_PREFIX changes. - Consolidate headers into a single microdev.h. - Update the microdev_defconfig. - Add init values for the S1D13806 used by s1d13xxxfb. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/boards/superh/microdev/io.c | 192 ++++---- arch/sh/boards/superh/microdev/irq.c | 2 +- arch/sh/boards/superh/microdev/setup.c | 166 ++++++- arch/sh/configs/microdev_defconfig | 414 +++++++++++------- include/asm-sh/{microdev/irq.h => microdev.h} | 60 +-- include/asm-sh/microdev/io.h | 53 --- 6 files changed, 538 insertions(+), 349 deletions(-) rename include/asm-sh/{microdev/irq.h => microdev.h} (65%) delete mode 100644 include/asm-sh/microdev/io.h diff --git a/arch/sh/boards/superh/microdev/io.c b/arch/sh/boards/superh/microdev/io.c index fe83b2c03076..1ed7f880b8c7 100644 --- a/arch/sh/boards/superh/microdev/io.c +++ b/arch/sh/boards/superh/microdev/io.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include /* * we need to have a 'safe' address to re-direct all I/O requests @@ -52,8 +52,90 @@ #define IO_ISP1161_PHYS 0xa7700000ul /* Physical address of Philips ISP1161x USB chip */ #define IO_SUPERIO_PHYS 0xa7800000ul /* Physical address of SMSC FDC37C93xAPM SuperIO chip */ -#define PORT2ADDR(x) (microdev_isa_port2addr(x)) +/* + * map I/O ports to memory-mapped addresses + */ +static unsigned long microdev_isa_port2addr(unsigned long offset) +{ + unsigned long result; + if ((offset >= IO_LAN91C111_BASE) && + (offset < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) { + /* + * SMSC LAN91C111 Ethernet chip + */ + result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE; + } else if ((offset >= IO_SUPERIO_BASE) && + (offset < IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * Configuration Registers + */ + result = IO_SUPERIO_PHYS + (offset << 1); +#if 0 + } else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG || + offset == KBD_STATUS_REG) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * PS/2 Keyboard + Mouse (ports 0x60 and 0x64). + */ + result = IO_SUPERIO_PHYS + (offset << 1); +#endif + } else if (((offset >= IO_IDE1_BASE) && + (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || + (offset == IO_IDE1_MISC)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * IDE #1 + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if (((offset >= IO_IDE2_BASE) && + (offset < IO_IDE2_BASE + IO_IDE_EXTENT)) || + (offset == IO_IDE2_MISC)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * IDE #2 + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if ((offset >= IO_SERIAL1_BASE) && + (offset < IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * Serial #1 + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if ((offset >= IO_SERIAL2_BASE) && + (offset < IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * Serial #2 + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if ((offset >= IO_ISP1161_BASE) && + (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) { + /* + * Philips USB ISP1161x chip + */ + result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE; + } else { + /* + * safe default. + */ + printk("Warning: unexpected port in %s( offset = 0x%lx )\n", + __FUNCTION__, offset); + result = PVR; + } + + return result; +} + +#define PORT2ADDR(x) (microdev_isa_port2addr(x)) static inline void delay(void) { @@ -94,6 +176,17 @@ unsigned int microdev_inl(unsigned long port) return *(volatile unsigned int*)PORT2ADDR(port); } +void microdev_outw(unsigned short b, unsigned long port) +{ +#ifdef CONFIG_PCI + if (port >= PCIBIOS_MIN_IO) { + microdev_pci_outw(b, port); + return; + } +#endif + *(volatile unsigned short*)PORT2ADDR(port) = b; +} + void microdev_outb(unsigned char b, unsigned long port) { #ifdef CONFIG_PCI @@ -158,17 +251,6 @@ void microdev_outb(unsigned char b, unsigned long port) } } -void microdev_outw(unsigned short b, unsigned long port) -{ -#ifdef CONFIG_PCI - if (port >= PCIBIOS_MIN_IO) { - microdev_pci_outw(b, port); - return; - } -#endif - *(volatile unsigned short*)PORT2ADDR(port) = b; -} - void microdev_outl(unsigned int b, unsigned long port) { #ifdef CONFIG_PCI @@ -284,87 +366,3 @@ void microdev_outsl(unsigned long port, const void *buffer, unsigned long count) while (count--) *port_addr = *buf++; } - -/* - * map I/O ports to memory-mapped addresses - */ -unsigned long microdev_isa_port2addr(unsigned long offset) -{ - unsigned long result; - - if ((offset >= IO_LAN91C111_BASE) && - (offset < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) { - /* - * SMSC LAN91C111 Ethernet chip - */ - result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE; - } else if ((offset >= IO_SUPERIO_BASE) && - (offset < IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) { - /* - * SMSC FDC37C93xAPM SuperIO chip - * - * Configuration Registers - */ - result = IO_SUPERIO_PHYS + (offset << 1); -#if 0 - } else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG || - offset == KBD_STATUS_REG) { - /* - * SMSC FDC37C93xAPM SuperIO chip - * - * PS/2 Keyboard + Mouse (ports 0x60 and 0x64). - */ - result = IO_SUPERIO_PHYS + (offset << 1); -#endif - } else if (((offset >= IO_IDE1_BASE) && - (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || - (offset == IO_IDE1_MISC)) { - /* - * SMSC FDC37C93xAPM SuperIO chip - * - * IDE #1 - */ - result = IO_SUPERIO_PHYS + (offset << 1); - } else if (((offset >= IO_IDE2_BASE) && - (offset < IO_IDE2_BASE + IO_IDE_EXTENT)) || - (offset == IO_IDE2_MISC)) { - /* - * SMSC FDC37C93xAPM SuperIO chip - * - * IDE #2 - */ - result = IO_SUPERIO_PHYS + (offset << 1); - } else if ((offset >= IO_SERIAL1_BASE) && - (offset < IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) { - /* - * SMSC FDC37C93xAPM SuperIO chip - * - * Serial #1 - */ - result = IO_SUPERIO_PHYS + (offset << 1); - } else if ((offset >= IO_SERIAL2_BASE) && - (offset < IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) { - /* - * SMSC FDC37C93xAPM SuperIO chip - * - * Serial #2 - */ - result = IO_SUPERIO_PHYS + (offset << 1); - } else if ((offset >= IO_ISP1161_BASE) && - (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) { - /* - * Philips USB ISP1161x chip - */ - result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE; - } else { - /* - * safe default. - */ - printk("Warning: unexpected port in %s( offset = 0x%lx )\n", - __FUNCTION__, offset); - result = PVR; - } - - return result; -} - diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c index 1395c1e65da4..efcbd86b7cd2 100644 --- a/arch/sh/boards/superh/microdev/irq.c +++ b/arch/sh/boards/superh/microdev/irq.c @@ -15,7 +15,7 @@ #include #include -#include +#include #define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */ diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c index 1c1d65fb12df..892b14d31405 100644 --- a/arch/sh/boards/superh/microdev/setup.c +++ b/arch/sh/boards/superh/microdev/setup.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com) * Copyright (C) 2003, 2004 SuperH, Inc. - * Copyright (C) 2004 Paul Mundt + * Copyright (C) 2004, 2005 Paul Mundt * * SuperH SH4-202 MicroDev board support. * @@ -15,11 +15,10 @@ #include #include #include +#include