diff options
Diffstat (limited to 'drivers/acpi/resources')
| -rw-r--r-- | drivers/acpi/resources/Makefile | 2 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsaddr.c | 1164 | ||||
| -rw-r--r-- | drivers/acpi/resources/rscalc.c | 831 | ||||
| -rw-r--r-- | drivers/acpi/resources/rscreate.c | 231 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsdump.c | 1399 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsinfo.c | 204 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsio.c | 544 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsirq.c | 568 | ||||
| -rw-r--r-- | drivers/acpi/resources/rslist.c | 534 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsmemory.c | 517 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsmisc.c | 860 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsutils.c | 390 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsxface.c | 230 |
13 files changed, 2887 insertions, 4587 deletions
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 @@ | |||
| 2 | # Makefile for all Linux ACPI interpreter subdirectories | 2 | # Makefile for all Linux ACPI interpreter subdirectories |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := rsaddr.o rscreate.o rsio.o rslist.o rsmisc.o rsxface.o \ | 5 | obj-y := rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ |
| 6 | rscalc.o rsirq.o rsmemory.o rsutils.o | 6 | rscalc.o rsirq.o rsmemory.o rsutils.o |
| 7 | 7 | ||
| 8 | obj-$(ACPI_FUTURE_USAGE) += rsdump.o | 8 | obj-$(ACPI_FUTURE_USAGE) += rsdump.o |
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 23b54baa0cb2..8fa3213ce000 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -47,1072 +47,334 @@ | |||
| 47 | #define _COMPONENT ACPI_RESOURCES | 47 | #define _COMPONENT ACPI_RESOURCES |
| 48 | ACPI_MODULE_NAME("rsaddr") | 48 | ACPI_MODULE_NAME("rsaddr") |
| 49 | 49 | ||
| 50 | /* Local prototypes */ | ||
| 51 | static void | ||
| 52 | acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags); | ||
| 53 | |||
| 54 | static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource); | ||
| 55 | |||
| 56 | static void | ||
| 57 | acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags); | ||
| 58 | |||
| 59 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource); | ||
| 60 | |||
| 61 | /******************************************************************************* | 50 | /******************************************************************************* |
| 62 | * | 51 | * |
| 63 | * FUNCTION: acpi_rs_decode_general_flags | 52 | * acpi_rs_convert_address16 - All WORD (16-bit) address resources |
| 64 | * | ||
| 65 | * PARAMETERS: Resource - Address resource data struct | ||
| 66 | * Flags - Actual flag byte | ||
| 67 | * | ||
| 68 | * RETURN: Decoded flag bits in resource struct | ||
| 69 | * | ||
| 70 | * DESCRIPTION: Decode a general flag byte to an address resource struct | ||
| 71 | * | 53 | * |
| 72 | ******************************************************************************/ | 54 | ******************************************************************************/ |
| 55 | struct acpi_rsconvert_info acpi_rs_convert_address16[5] = { | ||
| 56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16, | ||
| 57 | ACPI_RS_SIZE(struct acpi_resource_address16), | ||
| 58 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)}, | ||
| 73 | 59 | ||
| 74 | static void | 60 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16, |
| 75 | acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags) | 61 | sizeof(struct aml_resource_address16), |
| 76 | { | 62 | 0}, |
| 77 | ACPI_FUNCTION_ENTRY(); | ||
| 78 | |||
| 79 | /* Producer / Consumer - flag bit[0] */ | ||
| 80 | |||
| 81 | resource->address.producer_consumer = (u32) (flags & 0x01); | ||
| 82 | 63 | ||
| 83 | /* Decode (_DEC) - flag bit[1] */ | 64 | /* Resource Type, General Flags, and Type-Specific Flags */ |
| 84 | 65 | ||
| 85 | resource->address.decode = (u32) ((flags >> 1) & 0x01); | 66 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
| 86 | 67 | ||
| 87 | /* Min Address Fixed (_MIF) - flag bit[2] */ | 68 | /* |
| 69 | * These fields are contiguous in both the source and destination: | ||
| 70 | * Address Granularity | ||
| 71 | * Address Range Minimum | ||
| 72 | * Address Range Maximum | ||
| 73 | * Address Translation Offset | ||
| 74 | * Address Length | ||
| 75 | */ | ||
| 76 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity), | ||
| 77 | AML_OFFSET(address16.granularity), | ||
| 78 | 5}, | ||
| 88 | 79 | ||
| 89 | resource->address.min_address_fixed = (u32) ((flags >> 2) & 0x01); | 80 | /* Optional resource_source (Index and String) */ |
| 90 | 81 | ||
| 91 | /* Max Address Fixed (_MAF) - flag bit[3] */ | 82 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source), |
| 92 | 83 | 0, | |
| 93 | resource->address.max_address_fixed = (u32) ((flags >> 3) & 0x01); | 84 | sizeof(struct aml_resource_address16)} |
| 94 | } | 85 | }; |
| 95 | 86 | ||
| 96 | /******************************************************************************* | 87 | /******************************************************************************* |
| 97 | * | 88 | * |
| 98 | * FUNCTION: acpi_rs_encode_general_flags | 89 | * acpi_rs_convert_address32 - All DWORD (32-bit) address resources |
| 99 | * | ||
| 100 | * PARAMETERS: Resource - Address resource data struct | ||
| 101 | * | ||
| 102 | * RETURN: Encoded general flag byte | ||
| 103 | * | ||
| 104 | * DESCRIPTION: Construct a general flag byte from an address resource struct | ||
| 105 | * | 90 | * |
| 106 | ******************************************************************************/ | 91 | ******************************************************************************/ |
| 107 | 92 | ||
| 108 | static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) | 93 | struct acpi_rsconvert_info acpi_rs_convert_address32[5] = { |
| 109 | { | 94 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32, |
| 110 | u8 flags; | 95 | ACPI_RS_SIZE(struct acpi_resource_address32), |
| 111 | 96 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)}, | |
| 112 | ACPI_FUNCTION_ENTRY(); | ||
| 113 | |||
| 114 | /* Producer / Consumer - flag bit[0] */ | ||
| 115 | |||
| 116 | flags = (u8) (resource->address.producer_consumer & 0x01); | ||
| 117 | |||
| 118 | /* Decode (_DEC) - flag bit[1] */ | ||
| 119 | |||
| 120 | flags |= (u8) ((resource->address.decode & 0x01) << 1); | ||
| 121 | |||
| 122 | /* Min Address Fixed (_MIF) - flag bit[2] */ | ||
| 123 | |||
| 124 | flags |= (u8) ((resource->address.min_address_fixed & 0x01) << 2); | ||
| 125 | 97 | ||
| 126 | /* Max Address Fixed (_MAF) - flag bit[3] */ | 98 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32, |
| 99 | sizeof(struct aml_resource_address32), | ||
| 100 | 0}, | ||
| 127 | 101 | ||
| 128 | flags |= (u8) ((resource->address.max_address_fixed & 0x01) << 3); | 102 | /* Resource Type, General Flags, and Type-Specific Flags */ |
| 129 | 103 | ||
| 130 | return (flags); | 104 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
| 131 | } | ||
| 132 | |||
| 133 | /******************************************************************************* | ||
| 134 | * | ||
| 135 | * FUNCTION: acpi_rs_decode_specific_flags | ||
| 136 | * | ||
| 137 | * PARAMETERS: Resource - Address resource data struct | ||
| 138 | * Flags - Actual flag byte | ||
| 139 | * | ||
| 140 | * RETURN: Decoded flag bits in attribute struct | ||
| 141 | * | ||
| 142 | * DESCRIPTION: Decode a type-specific flag byte to an attribute struct. | ||
| 143 | * Type-specific flags are only defined for the Memory and IO | ||
| 144 | * resource types. | ||
| 145 | * | ||
| 146 | ******************************************************************************/ | ||
| 147 | 105 | ||
| 148 | static void | 106 | /* |
| 149 | acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags) | 107 | * These fields are contiguous in both the source and destination: |
| 150 | { | 108 | * Address Granularity |
| 151 | ACPI_FUNCTION_ENTRY(); | 109 | * Address Range Minimum |
| 152 | 110 | * Address Range Maximum | |
| 153 | if (resource->address.resource_type == ACPI_MEMORY_RANGE) { | 111 | * Address Translation Offset |
| 154 | /* Write Status (_RW) - flag bit[0] */ | 112 | * Address Length |
| 155 | 113 | */ | |
| 156 | resource->address.attribute.memory.read_write_attribute = | 114 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity), |
| 157 | (u16) (flags & 0x01); | 115 | AML_OFFSET(address32.granularity), |
| 158 | 116 | 5}, | |
| 159 | /* Memory Attributes (_MEM) - flag bits[2:1] */ | ||
| 160 | |||
| 161 | resource->address.attribute.memory.cache_attribute = | ||
| 162 | (u16) ((flags >> 1) & 0x03); | ||
| 163 | } else if (resource->address.resource_type == ACPI_IO_RANGE) { | ||
| 164 | /* Ranges (_RNG) - flag bits[1:0] */ | ||
| 165 | |||
| 166 | resource->address.attribute.io.range_attribute = | ||
| 167 | (u16) (flags & 0x03); | ||
| 168 | 117 | ||
| 169 | /* Translations (_TTP and _TRS) - flag bits[5:4] */ | 118 | /* Optional resource_source (Index and String) */ |
| 170 | 119 | ||
| 171 | resource->address.attribute.io.translation_attribute = | 120 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source), |
| 172 | (u16) ((flags >> 4) & 0x03); | 121 | 0, |
| 173 | } | 122 | sizeof(struct aml_resource_address32)} |
| 174 | } | 123 | }; |
| 175 | 124 | ||
| 176 | /******************************************************************************* | 125 | /******************************************************************************* |
| 177 | * | 126 | * |
| 178 | * FUNCTION: acpi_rs_encode_specific_flags | 127 | * acpi_rs_convert_address64 - All QWORD (64-bit) address resources |
| 179 | * | ||
| 180 | * PARAMETERS: Resource - Address resource data struct | ||
| 181 | * | ||
| 182 | * RETURN: Encoded type-specific flag byte | ||
| 183 | * | ||
| 184 | * DESCRIPTION: Construct a type-specific flag byte from an attribute struct. | ||
| 185 | * Type-specific flags are only defined for the Memory and IO | ||
| 186 | * resource types. | ||
| 187 | * | 128 | * |
| 188 | ******************************************************************************/ | 129 | ******************************************************************************/ |
| 189 | 130 | ||
| 190 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) | 131 | struct acpi_rsconvert_info acpi_rs_convert_address64[5] = { |
| 191 | { | 132 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64, |
| 192 | u8 flags = 0; | 133 | ACPI_RS_SIZE(struct acpi_resource_address64), |
| 193 | 134 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)}, | |
| 194 | ACPI_FUNCTION_ENTRY(); | ||
| 195 | |||
| 196 | if (resource->address.resource_type == ACPI_MEMORY_RANGE) { | ||
| 197 | /* Write Status (_RW) - flag bit[0] */ | ||
| 198 | 135 | ||
| 199 | flags = (u8) | 136 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64, |
| 200 | (resource->address.attribute.memory. | 137 | sizeof(struct aml_resource_address64), |
| 201 | read_write_attribute & 0x01); | 138 | 0}, |
| 202 | 139 | ||
| 203 | /* Memory Attributes (_MEM) - flag bits[2:1] */ | 140 | /* Resource Type, General Flags, and Type-Specific Flags */ |
| 204 | 141 | ||
| 205 | flags |= (u8) | 142 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
| 206 | ((resource->address.attribute.memory. | ||
| 207 | cache_attribute & 0x03) << 1); | ||
| 208 | } else if (resource->address.resource_type == ACPI_IO_RANGE) { | ||
| 209 | /* Ranges (_RNG) - flag bits[1:0] */ | ||
| 210 | 143 | ||
| 211 | flags = (u8) | 144 | /* |
| 212 | (resource->address.attribute.io.range_attribute & 0x03); | 145 | * These fields are contiguous in both the source and destination: |
| 146 | * Address Granularity | ||
| 147 | * Address Range Minimum | ||
| 148 | * Address Range Maximum | ||
| 149 | * Address Translation Offset | ||
| 150 | * Address Length | ||
| 151 | */ | ||
| 152 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity), | ||
| 153 | AML_OFFSET(address64.granularity), | ||
| 154 | 5}, | ||
| 213 | 155 | ||
| 214 | /* Translations (_TTP and _TRS) - flag bits[5:4] */ | 156 | /* Optional resource_source (Index and String) */ |
| 215 | 157 | ||
| 216 | flags |= (u8) | 158 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source), |
| 217 | ((resource->address.attribute.io. | 159 | 0, |
| 218 | translation_attribute & 0x03) << 4); | 160 | sizeof(struct aml_resource_address64)} |
| 219 | } | 161 | }; |
| 220 | |||
| 221 | return (flags); | ||
| 222 | } | ||
| 223 | 162 | ||
| 224 | /******************************************************************************* | 163 | /******************************************************************************* |
| 225 | * | 164 | * |
| 226 | * FUNCTION: acpi_rs_address16_resource | 165 | * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources |
| 227 | * | ||
| 228 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 229 | * stream | ||
| 230 | * bytes_consumed - Pointer to where the number of bytes | ||
| 231 | * consumed the byte_stream_buffer is | ||
| 232 | * returned | ||
| 233 | * output_buffer - Pointer to the return data buffer | ||
| 234 | * structure_size - Pointer to where the number of bytes | ||
| 235 | * in the return data struct is returned | ||
| 236 | * | ||
| 237 | * RETURN: Status | ||
| 238 | * | ||
| 239 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 240 | * structure pointed to by the output_buffer. Return the | ||
| 241 | * number of bytes consumed from the byte stream. | ||
| 242 | * | 166 | * |
| 243 | ******************************************************************************/ | 167 | ******************************************************************************/ |
| 244 | 168 | ||
| 245 | acpi_status | 169 | struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = { |
| 246 | acpi_rs_address16_resource(u8 * byte_stream_buffer, | 170 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, |
| 247 | acpi_size * bytes_consumed, | 171 | ACPI_RS_SIZE(struct acpi_resource_extended_address64), |
| 248 | u8 ** output_buffer, acpi_size * structure_size) | 172 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)}, |
| 249 | { | ||
| 250 | u32 index; | ||
| 251 | u16 temp16; | ||
| 252 | u8 temp8; | ||
| 253 | u8 *temp_ptr; | ||
| 254 | u8 *buffer = byte_stream_buffer; | ||
| 255 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 256 | acpi_size struct_size = | ||
| 257 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16); | ||
| 258 | |||
| 259 | ACPI_FUNCTION_TRACE("rs_address16_resource"); | ||
| 260 | |||
| 261 | /* Get the Descriptor Length field */ | ||
| 262 | |||
| 263 | buffer += 1; | ||
| 264 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 265 | |||
| 266 | /* Validate minimum descriptor length */ | ||
| 267 | |||
| 268 | if (temp16 < 13) { | ||
| 269 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
| 270 | } | ||
| 271 | |||
| 272 | *bytes_consumed = temp16 + 3; | ||
| 273 | output_struct->id = ACPI_RSTYPE_ADDRESS16; | ||
| 274 | |||
| 275 | /* Get the Resource Type (Byte3) */ | ||
| 276 | 173 | ||
| 277 | buffer += 2; | 174 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, |
| 278 | temp8 = *buffer; | 175 | sizeof(struct aml_resource_extended_address64), |
| 176 | 0}, | ||
| 279 | 177 | ||
| 280 | /* Values 0-2 and 0xC0-0xFF are valid */ | 178 | /* Resource Type, General Flags, and Type-Specific Flags */ |
| 281 | 179 | ||
| 282 | if ((temp8 > 2) && (temp8 < 0xC0)) { | 180 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
| 283 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
| 284 | } | ||
| 285 | |||
| 286 | output_struct->data.address16.resource_type = temp8; | ||
| 287 | |||
| 288 | /* Get the General Flags (Byte4) */ | ||
| 289 | |||
| 290 | buffer += 1; | ||
| 291 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | ||
| 292 | |||
| 293 | /* Get the Type Specific Flags (Byte5) */ | ||
| 294 | |||
| 295 | buffer += 1; | ||
| 296 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | ||
| 297 | |||
| 298 | /* Get Granularity (Bytes 6-7) */ | ||
| 299 | |||
| 300 | buffer += 1; | ||
| 301 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer); | ||
| 302 | |||
| 303 | /* Get min_address_range (Bytes 8-9) */ | ||
| 304 | 181 | ||
| 305 | buffer += 2; | 182 | /* Revision ID */ |
| 306 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range, | ||
| 307 | buffer); | ||
| 308 | |||
| 309 | /* Get max_address_range (Bytes 10-11) */ | ||
| 310 | |||
| 311 | buffer += 2; | ||
| 312 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range, | ||
| 313 | buffer); | ||
| 314 | |||
| 315 | /* Get address_translation_offset (Bytes 12-13) */ | ||
| 316 | |||
| 317 | buffer += 2; | ||
| 318 | ACPI_MOVE_16_TO_32(&output_struct->data.address16. | ||
| 319 | address_translation_offset, buffer); | ||
| 320 | |||
| 321 | /* Get address_length (Bytes 14-15) */ | ||
| 322 | |||
| 323 | buffer += 2; | ||
| 324 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length, | ||
| 325 | buffer); | ||
| 326 | |||
| 327 | /* Resource Source Index (if present) */ | ||
| 328 | |||
| 329 | buffer += 2; | ||
| 330 | 183 | ||
| 184 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_iD), | ||
| 185 | AML_OFFSET(ext_address64.revision_iD), | ||
| 186 | 1}, | ||
| 331 | /* | 187 | /* |
| 332 | * This will leave us pointing to the Resource Source Index | 188 | * These fields are contiguous in both the source and destination: |
| 333 | * If it is present, then save it off and calculate the | 189 | * Address Granularity |
| 334 | * pointer to where the null terminated string goes: | 190 | * Address Range Minimum |
| 335 | * Each Interrupt takes 32-bits + the 5 bytes of the | 191 | * Address Range Maximum |
| 336 | * stream that are default. | 192 | * Address Translation Offset |
| 337 | * | 193 | * Address Length |
| 338 | * Note: Some resource descriptors will have an additional null, so | 194 | * Type-Specific Attribute |
| 339 | * we add 1 to the length. | ||
| 340 | */ | 195 | */ |
| 341 | if (*bytes_consumed > (16 + 1)) { | 196 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity), |
| 342 | /* Dereference the Index */ | 197 | AML_OFFSET(ext_address64.granularity), |
| 343 | 198 | 6} | |
| 344 | output_struct->data.address16.resource_source.index = | 199 | }; |
| 345 | (u32) * buffer; | ||
| 346 | |||
| 347 | /* Point to the String */ | ||
| 348 | |||
| 349 | buffer += 1; | ||
| 350 | |||
| 351 | /* Point the String pointer to the end of this structure */ | ||
| 352 | |||
| 353 | output_struct->data.address16.resource_source.string_ptr = | ||
| 354 | (char *)((u8 *) output_struct + struct_size); | ||
| 355 | |||
| 356 | temp_ptr = (u8 *) | ||
| 357 | output_struct->data.address16.resource_source.string_ptr; | ||
| 358 | |||
| 359 | /* Copy the resource_source string into the buffer */ | ||
| 360 | |||
| 361 | index = 0; | ||
| 362 | while (*buffer) { | ||
| 363 | *temp_ptr = *buffer; | ||
| 364 | |||
| 365 | temp_ptr++; | ||
| 366 | buffer++; | ||
| 367 | index++; | ||
| 368 | } | ||
| 369 | |||
| 370 | /* Add the terminating null and set the string length */ | ||
| 371 | |||
| 372 | *temp_ptr = 0; | ||
| 373 | output_struct->data.address16.resource_source.string_length = | ||
| 374 | index + 1; | ||
| 375 | |||
| 376 | /* | ||
| 377 | * In order for the struct_size to fall on a 32-bit boundary, | ||
| 378 | * calculate the length of the string and expand the | ||
| 379 | * struct_size to the next 32-bit boundary. | ||
| 380 | */ | ||
| 381 | temp8 = (u8) (index + 1); | ||
| 382 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
| 383 | } else { | ||
| 384 | output_struct->data.address16.resource_source.index = 0; | ||
| 385 | output_struct->data.address16.resource_source.string_length = 0; | ||
| 386 | output_struct->data.address16.resource_source.string_ptr = NULL; | ||
| 387 | } | ||
| 388 | |||
| 389 | /* Set the Length parameter */ | ||
| 390 | |||
| 391 | output_struct->length = (u32) struct_size; | ||
| 392 | |||
| 393 | /* Return the final size of the structure */ | ||
| 394 | |||
| 395 | *structure_size = struct_size; | ||
| 396 | return_ACPI_STATUS(AE_OK); | ||
| 397 | } | ||
| 398 | 200 | ||
| 399 | /******************************************************************************* | 201 | /******************************************************************************* |
| 400 | * | 202 | * |
| 401 | * FUNCTION: acpi_rs_address16_stream | 203 | * acpi_rs_convert_general_flags - Flags common to all address descriptors |
| 402 | * | ||
| 403 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 404 | * output_buffer - Pointer to the user's return buffer | ||
| 405 | * bytes_consumed - Pointer to where the number of bytes | ||
| 406 | * used in the output_buffer is returned | ||
| 407 | * | ||
| 408 | * RETURN: Status | ||
| 409 | * | ||
| 410 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 411 | * the appropriate bytes in a byte stream | ||
| 412 | * | 204 | * |
| 413 | ******************************************************************************/ | 205 | ******************************************************************************/ |
| 414 | 206 | ||
| 415 | acpi_status | 207 | static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = { |
| 416 | acpi_rs_address16_stream(struct acpi_resource *linked_list, | 208 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags), |
| 417 | u8 ** output_buffer, acpi_size * bytes_consumed) | 209 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)}, |
| 418 | { | ||
| 419 | u8 *buffer = *output_buffer; | ||
| 420 | u8 *length_field; | ||
| 421 | acpi_size actual_bytes; | ||
| 422 | |||
| 423 | ACPI_FUNCTION_TRACE("rs_address16_stream"); | ||
| 424 | |||
| 425 | /* Set the Descriptor Type field */ | ||
| 426 | |||
| 427 | *buffer = ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE; | ||
| 428 | buffer += 1; | ||
| 429 | |||
| 430 | /* Save a pointer to the Length field - to be filled in later */ | ||
| 431 | |||
| 432 | length_field = buffer; | ||
| 433 | buffer += 2; | ||
| 434 | |||
| 435 | /* Set the Resource Type (Memory, Io, bus_number) */ | ||
| 436 | |||
| 437 | *buffer = (u8) (linked_list->data.address16.resource_type & 0x03); | ||
| 438 | buffer += 1; | ||
| 439 | |||
| 440 | /* Set the general flags */ | ||
| 441 | |||
| 442 | *buffer = acpi_rs_encode_general_flags(&linked_list->data); | ||
| 443 | buffer += 1; | ||
| 444 | |||
| 445 | /* Set the type specific flags */ | ||
| 446 | |||
| 447 | *buffer = acpi_rs_encode_specific_flags(&linked_list->data); | ||
| 448 | buffer += 1; | ||
| 449 | |||
| 450 | /* Set the address space granularity */ | ||
| 451 | |||
| 452 | ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.granularity); | ||
| 453 | buffer += 2; | ||
| 454 | |||
| 455 | /* Set the address range minimum */ | ||
| 456 | 210 | ||
| 457 | ACPI_MOVE_32_TO_16(buffer, | 211 | /* Resource Type (Memory, Io, bus_number, etc.) */ |
| 458 | &linked_list->data.address16.min_address_range); | ||
| 459 | buffer += 2; | ||
| 460 | 212 | ||
| 461 | /* Set the address range maximum */ | 213 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type), |
| 214 | AML_OFFSET(address.resource_type), | ||
| 215 | 1}, | ||
| 462 | 216 | ||
| 463 | ACPI_MOVE_32_TO_16(buffer, | 217 | /* General Flags - Consume, Decode, min_fixed, max_fixed */ |
| 464 | &linked_list->data.address16.max_address_range); | ||
| 465 | buffer += 2; | ||
| 466 | 218 | ||
| 467 | /* Set the address translation offset */ | 219 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer), |
| 220 | AML_OFFSET(address.flags), | ||
| 221 | 0}, | ||
| 468 | 222 | ||
| 469 | ACPI_MOVE_32_TO_16(buffer, | 223 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode), |
| 470 | &linked_list->data.address16. | 224 | AML_OFFSET(address.flags), |
| 471 | address_translation_offset); | 225 | 1}, |
| 472 | buffer += 2; | ||
| 473 | 226 | ||
| 474 | /* Set the address length */ | 227 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed), |
| 228 | AML_OFFSET(address.flags), | ||
| 229 | 2}, | ||
| 475 | 230 | ||
| 476 | ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.address_length); | 231 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed), |
| 477 | buffer += 2; | 232 | AML_OFFSET(address.flags), |
| 478 | 233 | 3} | |
| 479 | /* Resource Source Index and Resource Source are optional */ | 234 | }; |
| 480 | |||
| 481 | if (linked_list->data.address16.resource_source.string_length) { | ||
| 482 | *buffer = | ||
| 483 | (u8) linked_list->data.address16.resource_source.index; | ||
| 484 | buffer += 1; | ||
| 485 | |||
| 486 | /* Copy the resource_source string */ | ||
| 487 | |||
| 488 | ACPI_STRCPY((char *)buffer, | ||
| 489 | linked_list->data.address16.resource_source. | ||
| 490 | string_ptr); | ||
| 491 | |||
| 492 | /* | ||
| 493 | * Buffer needs to be set to the length of the string + one for the | ||
| 494 | * terminating null | ||
| 495 | */ | ||
| 496 | buffer += | ||
| 497 | (acpi_size) (ACPI_STRLEN | ||
| 498 | (linked_list->data.address16.resource_source. | ||
| 499 | string_ptr) + 1); | ||
| 500 | } | ||
| 501 | |||
| 502 | /* Return the number of bytes consumed in this operation */ | ||
| 503 | |||
| 504 | actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 505 | *bytes_consumed = actual_bytes; | ||
| 506 | |||
| 507 | /* | ||
| 508 | * Set the length field to the number of bytes consumed | ||
| 509 | * minus the header size (3 bytes) | ||
| 510 | */ | ||
| 511 | actual_bytes -= 3; | ||
| 512 | ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes); | ||
| 513 | return_ACPI_STATUS(AE_OK); | ||
| 514 | } | ||
| 515 | 235 | ||
| 516 | /******************************************************************************* | 236 | /******************************************************************************* |
| 517 | * | 237 | * |
| 518 | * FUNCTION: acpi_rs_address32_resource | 238 | * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors |
| 519 | * | ||
| 520 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 521 | * stream | ||
| 522 | * bytes_consumed - Pointer to where the number of bytes | ||
| 523 | * consumed the byte_stream_buffer is | ||
| 524 | * returned | ||
| 525 | * output_buffer - Pointer to the return data buffer | ||
| 526 | * structure_size - Pointer to where the number of bytes | ||
| 527 | * in the return data struct is returned | ||
| 528 | * | ||
| 529 | * RETURN: Status | ||
| 530 | * | ||
| 531 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 532 | * structure pointed to by the output_buffer. Return the | ||
| 533 | * number of bytes consumed from the byte stream. | ||
| 534 | * | 239 | * |
| 535 | ******************************************************************************/ | 240 | ******************************************************************************/ |
| 536 | 241 | ||
| 537 | acpi_status | 242 | static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = { |
| 538 | acpi_rs_address32_resource(u8 * byte_stream_buffer, | 243 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), |
| 539 | acpi_size * bytes_consumed, | 244 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)}, |
| 540 | u8 ** output_buffer, acpi_size * structure_size) | ||
| 541 | { | ||
| 542 | u16 temp16; | ||
| 543 | u8 temp8; | ||
| 544 | u8 *temp_ptr; | ||
| 545 | u32 index; | ||
| 546 | u8 *buffer = byte_stream_buffer; | ||
| 547 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 548 | acpi_size struct_size = | ||
| 549 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32); | ||
| 550 | 245 | ||
| 551 | ACPI_FUNCTION_TRACE("rs_address32_resource"); | 246 | /* Memory-specific flags */ |
| 552 | 247 | ||
| 553 | /* Get the Descriptor Length field */ | 248 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect), |
| 249 | AML_OFFSET(address.specific_flags), | ||
| 250 | 0}, | ||
| 554 | 251 | ||
| 555 | buffer += 1; | 252 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching), |
| 556 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 253 | AML_OFFSET(address.specific_flags), |
| 254 | 1}, | ||
| 557 | 255 | ||
| 558 | /* Validate minimum descriptor length */ | 256 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type), |
| 257 | AML_OFFSET(address.specific_flags), | ||
| 258 | 3}, | ||
| 559 | 259 | ||
| 560 | if (temp16 < 23) { | 260 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation), |
| 561 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | 261 | AML_OFFSET(address.specific_flags), |
| 562 | } | 262 | 5} |
| 563 | 263 | }; | |
| 564 | *bytes_consumed = temp16 + 3; | ||
| 565 | output_struct->id = ACPI_RSTYPE_ADDRESS32; | ||
| 566 | |||
| 567 | /* Get the Resource Type (Byte3) */ | ||
| 568 | |||
| 569 | buffer += 2; | ||
| 570 | temp8 = *buffer; | ||
| 571 | |||
| 572 | /* Values 0-2 and 0xC0-0xFF are valid */ | ||
| 573 | |||
| 574 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
| 575 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
| 576 | } | ||
| 577 | |||
| 578 | output_struct->data.address32.resource_type = temp8; | ||
| 579 | |||
| 580 | /* Get the General Flags (Byte4) */ | ||
| 581 | |||
| 582 | buffer += 1; | ||
| 583 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | ||
| 584 | |||
| 585 | /* Get the Type Specific Flags (Byte5) */ | ||
| 586 | |||
| 587 | buffer += 1; | ||
| 588 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | ||
| 589 | |||
| 590 | /* Get Granularity (Bytes 6-9) */ | ||
| 591 | |||
| 592 | buffer += 1; | ||
| 593 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer); | ||
| 594 | |||
| 595 | /* Get min_address_range (Bytes 10-13) */ | ||
| 596 | |||
| 597 | buffer += 4; | ||
| 598 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range, | ||
| 599 | buffer); | ||
| 600 | |||
| 601 | /* Get max_address_range (Bytes 14-17) */ | ||
| 602 | |||
| 603 | buffer += 4; | ||
| 604 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range, | ||
| 605 | buffer); | ||
| 606 | |||
| 607 | /* Get address_translation_offset (Bytes 18-21) */ | ||
| 608 | |||
| 609 | buffer += 4; | ||
| 610 | ACPI_MOVE_32_TO_32(&output_struct->data.address32. | ||
| 611 | address_translation_offset, buffer); | ||
| 612 | |||
| 613 | /* Get address_length (Bytes 22-25) */ | ||
| 614 | |||
| 615 | buffer += 4; | ||
| 616 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length, | ||
| 617 | buffer); | ||
| 618 | |||
| 619 | /* Resource Source Index (if present) */ | ||
| 620 | |||
| 621 | buffer += 4; | ||
| 622 | |||
| 623 | /* | ||
| 624 | * This will leave us pointing to the Resource Source Index | ||
| 625 | * If it is present, then save it off and calculate the | ||
| 626 | * pointer to where the null terminated string goes: | ||
| 627 | * | ||
| 628 | * Note: Some resource descriptors will have an additional null, so | ||
| 629 | * we add 1 to the length. | ||
| 630 | */ | ||
| 631 | if (*bytes_consumed > (26 + 1)) { | ||
| 632 | /* Dereference the Index */ | ||
| 633 | |||
| 634 | output_struct->data.address32.resource_source.index = | ||
| 635 | (u32) * buffer; | ||
| 636 | |||
| 637 | /* Point to the String */ | ||
| 638 | |||
| 639 | buffer += 1; | ||
| 640 | |||
| 641 | /* Point the String pointer to the end of this structure */ | ||
| 642 | |||
| 643 | output_struct->data.address32.resource_source.string_ptr = | ||
| 644 | (char *)((u8 *) output_struct + struct_size); | ||
| 645 | |||
| 646 | temp_ptr = (u8 *) | ||
| 647 | output_struct->data.address32.resource_source.string_ptr; | ||
| 648 | |||
| 649 | /* Copy the resource_source string into the buffer */ | ||
| 650 | |||
| 651 | index = 0; | ||
| 652 | while (*buffer) { | ||
| 653 | *temp_ptr = *buffer; | ||
| 654 | |||
| 655 | temp_ptr++; | ||
| 656 | buffer++; | ||
| 657 | index++; | ||
| 658 | } | ||
| 659 | |||
| 660 | /* Add the terminating null and set the string length */ | ||
| 661 | |||
| 662 | *temp_ptr = 0; | ||
| 663 | output_struct->data.address32.resource_source.string_length = | ||
| 664 | index + 1; | ||
| 665 | |||
| 666 | /* | ||
| 667 | * In order for the struct_size to fall on a 32-bit boundary, | ||
| 668 | * calculate the length of the string and expand the | ||
| 669 | * struct_size to the next 32-bit boundary. | ||
| 670 | */ | ||
| 671 | temp8 = (u8) (index + 1); | ||
| 672 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
| 673 | } else { | ||
| 674 | output_struct->data.address32.resource_source.index = 0; | ||
| 675 | output_struct->data.address32.resource_source.string_length = 0; | ||
| 676 | output_struct->data.address32.resource_source.string_ptr = NULL; | ||
| 677 | } | ||
| 678 | |||
| 679 | /* Set the Length parameter */ | ||
| 680 | |||
| 681 | output_struct->length = (u32) struct_size; | ||
| 682 | |||
| 683 | /* Return the final size of the structure */ | ||
| 684 | |||
| 685 | *structure_size = struct_size; | ||
| 686 | return_ACPI_STATUS(AE_OK); | ||
| 687 | } | ||
| 688 | 264 | ||
| 689 | /******************************************************************************* | 265 | /******************************************************************************* |
| 690 | * | 266 | * |
| 691 | * FUNCTION: acpi_rs_address32_stream | 267 | * acpi_rs_convert_io_flags - Flags common to I/O address descriptors |
| 692 | * | ||
| 693 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 694 | * output_buffer - Pointer to the user's return buffer | ||
| 695 | * bytes_consumed - Pointer to where the number of bytes | ||
| 696 | * used in the output_buffer is returned | ||
| 697 | * | ||
| 698 | * RETURN: Status | ||
| 699 | * | ||
| 700 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 701 | * the appropriate bytes in a byte stream | ||
| 702 | * | 268 | * |
| 703 | ******************************************************************************/ | 269 | ******************************************************************************/ |
| 704 | 270 | ||
| 705 | acpi_status | 271 | static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = { |
| 706 | acpi_rs_address32_stream(struct acpi_resource *linked_list, | 272 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), |
| 707 | u8 ** output_buffer, acpi_size * bytes_consumed) | 273 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)}, |
| 708 | { | ||
| 709 | u8 *buffer; | ||
| 710 | u16 *length_field; | ||
| 711 | |||
| 712 | ACPI_FUNCTION_TRACE("rs_address32_stream"); | ||
| 713 | |||
| 714 | buffer = *output_buffer; | ||
| 715 | |||
| 716 | /* Set the Descriptor Type field */ | ||
| 717 | |||
| 718 | *buffer = ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE; | ||
| 719 | buffer += 1; | ||
| 720 | |||
| 721 | /* Save a pointer to the Length field - to be filled in later */ | ||
| 722 | |||
| 723 | length_field = ACPI_CAST_PTR(u16, buffer); | ||
| 724 | buffer += 2; | ||
| 725 | |||
| 726 | /* Set the Resource Type (Memory, Io, bus_number) */ | ||
| 727 | |||
| 728 | *buffer = (u8) (linked_list->data.address32.resource_type & 0x03); | ||
| 729 | buffer += 1; | ||
| 730 | |||
| 731 | /* Set the general flags */ | ||
| 732 | |||
| 733 | *buffer = acpi_rs_encode_general_flags(&linked_list->data); | ||
| 734 | buffer += 1; | ||
| 735 | |||
| 736 | /* Set the type specific flags */ | ||
| 737 | |||
| 738 | *buffer = acpi_rs_encode_specific_flags(&linked_list->data); | ||
| 739 | buffer += 1; | ||
| 740 | |||
| 741 | /* Set the address space granularity */ | ||
| 742 | |||
| 743 | ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.granularity); | ||
| 744 | buffer += 4; | ||
| 745 | |||
| 746 | /* Set the address range minimum */ | ||
| 747 | |||
| 748 | ACPI_MOVE_32_TO_32(buffer, | ||
| 749 | &linked_list->data.address32.min_address_range); | ||
| 750 | buffer += 4; | ||
| 751 | |||
| 752 | /* Set the address range maximum */ | ||
| 753 | |||
| 754 | ACPI_MOVE_32_TO_32(buffer, | ||
| 755 | &linked_list->data.address32.max_address_range); | ||
| 756 | buffer += 4; | ||
| 757 | |||
| 758 | /* Set the address translation offset */ | ||
| 759 | |||
| 760 | ACPI_MOVE_32_TO_32(buffer, | ||
| 761 | &linked_list->data.address32. | ||
| 762 | address_translation_offset); | ||
| 763 | buffer += 4; | ||
| 764 | |||
| 765 | /* Set the address length */ | ||
| 766 | |||
| 767 | ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.address_length); | ||
| 768 | buffer += 4; | ||
| 769 | 274 | ||
| 770 | /* Resource Source Index and Resource Source are optional */ | 275 | /* I/O-specific flags */ |
| 771 | 276 | ||
| 772 | if (linked_list->data.address32.resource_source.string_length) { | 277 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type), |
| 773 | *buffer = | 278 | AML_OFFSET(address.specific_flags), |
| 774 | (u8) linked_list->data.address32.resource_source.index; | 279 | 0}, |
| 775 | buffer += 1; | ||
| 776 | 280 | ||
| 777 | /* Copy the resource_source string */ | 281 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation), |
| 282 | AML_OFFSET(address.specific_flags), | ||
| 283 | 4}, | ||
| 778 | 284 | ||
| 779 | ACPI_STRCPY((char *)buffer, | 285 | {ACPI_RSC_1BITFLAG, |
| 780 | linked_list->data.address32.resource_source. | 286 | ACPI_RS_OFFSET(data.address.info.io.translation_type), |
| 781 | string_ptr); | 287 | AML_OFFSET(address.specific_flags), |
| 782 | 288 | 5} | |
| 783 | /* | 289 | }; |
| 784 | * Buffer needs to be set to the length of the string + one for the | ||
| 785 | * terminating null | ||
| 786 | */ | ||
| 787 | buffer += | ||
| 788 | (acpi_size) (ACPI_STRLEN | ||
| 789 | (linked_list->data.address32.resource_source. | ||
| 790 | string_ptr) + 1); | ||
| 791 | } | ||
| 792 | |||
| 793 | /* Return the number of bytes consumed in this operation */ | ||
| 794 | |||
| 795 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 796 | |||
| 797 | /* | ||
| 798 | * Set the length field to the number of bytes consumed | ||
| 799 | * minus the header size (3 bytes) | ||
| 800 | */ | ||
| 801 | *length_field = (u16) (*bytes_consumed - 3); | ||
| 802 | return_ACPI_STATUS(AE_OK); | ||
| 803 | } | ||
| 804 | 290 | ||
| 805 | /******************************************************************************* | 291 | /******************************************************************************* |
| 806 | * | 292 | * |
| 807 | * FUNCTION: acpi_rs_address64_resource | 293 | * FUNCTION: acpi_rs_get_address_common |
| 808 | * | 294 | * |
| 809 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | 295 | * PARAMETERS: Resource - Pointer to the internal resource struct |
| 810 | * stream | 296 | * Aml - Pointer to the AML resource descriptor |
| 811 | * bytes_consumed - Pointer to where the number of bytes | ||
| 812 | * consumed the byte_stream_buffer is | ||
| 813 | * returned | ||
| 814 | * output_buffer - Pointer to the return data buffer | ||
| 815 | * structure_size - Pointer to where the number of bytes | ||
| 816 | * in the return data struct is returned | ||
| 817 | * | 297 | * |
| 818 | * RETURN: Status | 298 | * RETURN: TRUE if the resource_type field is OK, FALSE otherwise |
| 819 | * | 299 | * |
| 820 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | 300 | * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor |
| 821 | * structure pointed to by the output_buffer. Return the | 301 | * to an internal resource descriptor |
| 822 | * number of bytes consumed from the byte stream. | ||
| 823 | * | 302 | * |
| 824 | ******************************************************************************/ | 303 | ******************************************************************************/ |
| 825 | 304 | ||
| 826 | acpi_status | 305 | u8 |
| 827 | acpi_rs_address64_resource(u8 * byte_stream_buffer, | 306 | acpi_rs_get_address_common(struct acpi_resource *resource, |
| 828 | acpi_size * bytes_consumed, | 307 | union aml_resource *aml) |
| 829 | u8 ** output_buffer, acpi_size * structure_size) | ||
| 830 | { | 308 | { |
| 831 | u16 temp16; | 309 | ACPI_FUNCTION_ENTRY(); |
| 832 | u8 temp8; | ||
| 833 | u8 resource_type; | ||
| 834 | u8 *temp_ptr; | ||
| 835 | u32 index; | ||
| 836 | u8 *buffer = byte_stream_buffer; | ||
| 837 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 838 | acpi_size struct_size = | ||
| 839 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64); | ||
| 840 | |||
| 841 | ACPI_FUNCTION_TRACE("rs_address64_resource"); | ||
| 842 | |||
| 843 | /* Get the Descriptor Type */ | ||
| 844 | |||
| 845 | resource_type = *buffer; | ||
| 846 | |||
| 847 | /* Get the Descriptor Length field */ | ||
| 848 | |||
| 849 | buffer += 1; | ||
| 850 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 851 | |||
| 852 | /* Validate minimum descriptor length */ | ||
| 853 | |||
| 854 | if (temp16 < 43) { | ||
| 855 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
| 856 | } | ||
| 857 | |||
| 858 | *bytes_consumed = temp16 + 3; | ||
| 859 | output_struct->id = ACPI_RSTYPE_ADDRESS64; | ||
| 860 | |||
| 861 | /* Get the Resource Type (Byte3) */ | ||
| 862 | |||
| 863 | buffer += 2; | ||
| 864 | temp8 = *buffer; | ||
| 865 | |||
| 866 | /* Values 0-2 and 0xC0-0xFF are valid */ | ||
| 867 | |||
| 868 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
| 869 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
| 870 | } | ||
| 871 | |||
| 872 | output_struct->data.address64.resource_type = temp8; | ||
| 873 | |||
| 874 | /* Get the General Flags (Byte4) */ | ||
| 875 | |||
| 876 | buffer += 1; | ||
| 877 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | ||
| 878 | |||
| 879 | /* Get the Type Specific Flags (Byte5) */ | ||
| 880 | |||
| 881 | buffer += 1; | ||
| 882 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | ||
| 883 | 310 | ||
| 884 | if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { | 311 | /* Validate the Resource Type */ |
| 885 | /* Move past revision_id and Reserved byte */ | ||
| 886 | 312 | ||
| 887 | buffer += 2; | 313 | if ((aml->address.resource_type > 2) |
| 314 | && (aml->address.resource_type < 0xC0)) { | ||
| 315 | return (FALSE); | ||
| 888 | } | 316 | } |
| 889 | 317 | ||
| 890 | /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */ | 318 | /* Get the Resource Type and General Flags */ |
| 891 | |||
| 892 | buffer += 1; | ||
| 893 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer); | ||
| 894 | |||
| 895 | /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */ | ||
| 896 | |||
| 897 | buffer += 8; | ||
| 898 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range, | ||
| 899 | buffer); | ||
| 900 | |||
| 901 | /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */ | ||
| 902 | |||
| 903 | buffer += 8; | ||
| 904 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range, | ||
| 905 | buffer); | ||
| 906 | |||
| 907 | /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */ | ||
| 908 | |||
| 909 | buffer += 8; | ||
| 910 | ACPI_MOVE_64_TO_64(&output_struct->data.address64. | ||
| 911 | address_translation_offset, buffer); | ||
| 912 | 319 | ||
| 913 | /* Get address_length (Bytes 38-45) or (Bytes 40-47) */ | 320 | (void)acpi_rs_convert_aml_to_resource(resource, aml, |
| 321 | acpi_rs_convert_general_flags); | ||
| 914 | 322 | ||
| 915 | buffer += 8; | 323 | /* Get the Type-Specific Flags (Memory and I/O descriptors only) */ |
| 916 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length, | ||
| 917 | buffer); | ||
| 918 | 324 | ||
| 919 | output_struct->data.address64.resource_source.index = 0; | 325 | if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { |
| 920 | output_struct->data.address64.resource_source.string_length = 0; | 326 | (void)acpi_rs_convert_aml_to_resource(resource, aml, |
| 921 | output_struct->data.address64.resource_source.string_ptr = NULL; | 327 | acpi_rs_convert_mem_flags); |
| 922 | 328 | } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { | |
| 923 | if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { | 329 | (void)acpi_rs_convert_aml_to_resource(resource, aml, |
| 924 | /* Get type_specific_attribute (Bytes 48-55) */ | 330 | acpi_rs_convert_io_flags); |
| 925 | |||
| 926 | buffer += 8; | ||
| 927 | ACPI_MOVE_64_TO_64(&output_struct->data.address64. | ||
| 928 | type_specific_attributes, buffer); | ||
| 929 | } else { | 331 | } else { |
| 930 | output_struct->data.address64.type_specific_attributes = 0; | 332 | /* Generic resource type, just grab the type_specific byte */ |
| 931 | |||
| 932 | /* Resource Source Index (if present) */ | ||
| 933 | |||
| 934 | buffer += 8; | ||
| 935 | |||
| 936 | /* | ||
| 937 | * This will leave us pointing to the Resource Source Index | ||
| 938 | * If it is present, then save it off and calculate the | ||
| 939 | * pointer to where the null terminated string goes: | ||
| 940 | * Each Interrupt takes 32-bits + the 5 bytes of the | ||
| 941 | * stream that are default. | ||
| 942 | * | ||
| 943 | * Note: Some resource descriptors will have an additional null, so | ||
| 944 | * we add 1 to the length. | ||
| 945 | */ | ||
| 946 | if (*bytes_consumed > (46 + 1)) { | ||
| 947 | /* Dereference the Index */ | ||
| 948 | |||
| 949 | output_struct->data.address64.resource_source.index = | ||
| 950 | (u32) * buffer; | ||
| 951 | |||
| 952 | /* Point to the String */ | ||
| 953 | |||
| 954 | buffer += 1; | ||
| 955 | |||
| 956 | /* Point the String pointer to the end of this structure */ | ||
| 957 | |||
| 958 | output_struct->data.address64.resource_source. | ||
| 959 | string_ptr = | ||
| 960 | (char *)((u8 *) output_struct + struct_size); | ||
| 961 | |||
| 962 | temp_ptr = (u8 *) | ||
| 963 | output_struct->data.address64.resource_source. | ||
| 964 | string_ptr; | ||
| 965 | |||
| 966 | /* Copy the resource_source string into the buffer */ | ||
| 967 | |||
| 968 | index = 0; | ||
| 969 | while (*buffer) { | ||
| 970 | *temp_ptr = *buffer; | ||
| 971 | |||
| 972 | temp_ptr++; | ||
| 973 | buffer++; | ||
| 974 | index++; | ||
| 975 | } | ||
| 976 | |||
| 977 | /* | ||
| 978 | * Add the terminating null and set the string length | ||
| 979 | */ | ||
| 980 | *temp_ptr = 0; | ||
| 981 | output_struct->data.address64.resource_source. | ||
| 982 | string_length = index + 1; | ||
| 983 | |||
| 984 | /* | ||
| 985 | * In order for the struct_size to fall on a 32-bit boundary, | ||
| 986 | * calculate the length of the string and expand the | ||
| 987 | * struct_size to the next 32-bit boundary. | ||
| 988 | */ | ||
| 989 | temp8 = (u8) (index + 1); | ||
| 990 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
| 991 | } | ||
| 992 | } | ||
| 993 | |||
| 994 | /* Set the Length parameter */ | ||
| 995 | |||
| 996 | output_struct->length = (u32) struct_size; | ||
| 997 | 333 | ||
| 998 | /* Return the final size of the structure */ | 334 | resource->data.address.info.type_specific = |
| 335 | aml->address.specific_flags; | ||
| 336 | } | ||
| 999 | 337 | ||
| 1000 | *structure_size = struct_size; | 338 | return (TRUE); |
| 1001 | return_ACPI_STATUS(AE_OK); | ||
| 1002 | } | 339 | } |
| 1003 | 340 | ||
| 1004 | /******************************************************************************* | 341 | /******************************************************************************* |
| 1005 | * | 342 | * |
| 1006 | * FUNCTION: acpi_rs_address64_stream | 343 | * FUNCTION: acpi_rs_set_address_common |
| 1007 | * | 344 | * |
| 1008 | * PARAMETERS: linked_list - Pointer to the resource linked list | 345 | * PARAMETERS: Aml - Pointer to the AML resource descriptor |
| 1009 | * output_buffer - Pointer to the user's return buffer | 346 | * Resource - Pointer to the internal resource struct |
| 1010 | * bytes_consumed - Pointer to where the number of bytes | ||
| 1011 | * used in the output_buffer is returned | ||
| 1012 | * | 347 | * |
| 1013 | * RETURN: Status | 348 | * RETURN: None |
| 1014 | * | 349 | * |
| 1015 | * DESCRIPTION: Take the linked list resource structure and fills in the | 350 | * DESCRIPTION: Convert common flag fields from a resource descriptor to an |
| 1016 | * the appropriate bytes in a byte stream | 351 | * AML descriptor |
| 1017 | * | 352 | * |
| 1018 | ******************************************************************************/ | 353 | ******************************************************************************/ |
| 1019 | 354 | ||
| 1020 | acpi_status | 355 | void |
| 1021 | acpi_rs_address64_stream(struct acpi_resource *linked_list, | 356 | acpi_rs_set_address_common(union aml_resource *aml, |
| 1022 | u8 ** output_buffer, acpi_size * bytes_consumed) | 357 | struct acpi_resource *resource) |
| 1023 | { | 358 | { |
| 1024 | u8 *buffer; | 359 | ACPI_FUNCTION_ENTRY(); |
| 1025 | u16 *length_field; | ||
| 1026 | |||
| 1027 | ACPI_FUNCTION_TRACE("rs_address64_stream"); | ||
| 1028 | |||
| 1029 | buffer = *output_buffer; | ||
| 1030 | |||
| 1031 | /* Set the Descriptor Type field */ | ||
| 1032 | |||
| 1033 | *buffer = ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE; | ||
| 1034 | buffer += 1; | ||
| 1035 | |||
| 1036 | /* Save a pointer to the Length field - to be filled in later */ | ||
| 1037 | |||
| 1038 | length_field = ACPI_CAST_PTR(u16, buffer); | ||
| 1039 | buffer += 2; | ||
| 1040 | |||
| 1041 | /* Set the Resource Type (Memory, Io, bus_number) */ | ||
| 1042 | |||
| 1043 | *buffer = (u8) (linked_list->data.address64.resource_type & 0x03); | ||
| 1044 | buffer += 1; | ||
| 1045 | |||
| 1046 | /* Set the general flags */ | ||
| 1047 | |||
| 1048 | *buffer = acpi_rs_encode_general_flags(&linked_list->data); | ||
| 1049 | buffer += 1; | ||
| 1050 | |||
| 1051 | /* Set the type specific flags */ | ||
| 1052 | |||
| 1053 | *buffer = acpi_rs_encode_specific_flags(&linked_list->data); | ||
| 1054 | buffer += 1; | ||
| 1055 | |||
| 1056 | /* Set the address space granularity */ | ||
| 1057 | |||
| 1058 | ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.granularity); | ||
| 1059 | buffer += 8; | ||
| 1060 | |||
| 1061 | /* Set the address range minimum */ | ||
| 1062 | |||
| 1063 | ACPI_MOVE_64_TO_64(buffer, | ||
| 1064 | &linked_list->data.address64.min_address_range); | ||
| 1065 | buffer += 8; | ||
| 1066 | |||
| 1067 | /* Set the address range maximum */ | ||
| 1068 | |||
| 1069 | ACPI_MOVE_64_TO_64(buffer, | ||
| 1070 | &linked_list->data.address64.max_address_range); | ||
| 1071 | buffer += 8; | ||
| 1072 | |||
| 1073 | /* Set the address translation offset */ | ||
| 1074 | |||
| 1075 | ACPI_MOVE_64_TO_64(buffer, | ||
| 1076 | &linked_list->data.address64. | ||
| 1077 | address_translation_offset); | ||
| 1078 | buffer += 8; | ||
| 1079 | |||
| 1080 | /* Set the address length */ | ||
| 1081 | |||
| 1082 | ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.address_length); | ||
| 1083 | buffer += 8; | ||
| 1084 | 360 | ||
| 1085 | /* Resource Source Index and Resource Source are optional */ | 361 | /* Set the Resource Type and General Flags */ |
| 1086 | 362 | ||
| 1087 | if (linked_list->data.address64.resource_source.string_length) { | 363 | (void)acpi_rs_convert_resource_to_aml(resource, aml, |
| 1088 | *buffer = | 364 | acpi_rs_convert_general_flags); |
| 1089 | (u8) linked_list->data.address64.resource_source.index; | ||
| 1090 | buffer += 1; | ||
| 1091 | 365 | ||
| 1092 | /* Copy the resource_source string */ | 366 | /* Set the Type-Specific Flags (Memory and I/O descriptors only) */ |
| 1093 | 367 | ||
| 1094 | ACPI_STRCPY((char *)buffer, | 368 | if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { |
| 1095 | linked_list->data.address64.resource_source. | 369 | (void)acpi_rs_convert_resource_to_aml(resource, aml, |
| 1096 | string_ptr); | 370 | acpi_rs_convert_mem_flags); |
| 371 | } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { | ||
| 372 | (void)acpi_rs_convert_resource_to_aml(resource, aml, | ||
| 373 | acpi_rs_convert_io_flags); | ||
| 374 | } else { | ||
| 375 | /* Generic resource type, just copy the type_specific byte */ | ||
| 1097 | 376 | ||
| 1098 | /* | 377 | aml->address.specific_flags = |
| 1099 | * Buffer needs to be set to the length of the string + one for the | 378 | resource->data.address.info.type_specific; |
| 1100 | * terminating null | ||
| 1101 | */ | ||
| 1102 | buffer += | ||
| 1103 | (acpi_size) (ACPI_STRLEN | ||
| 1104 | (linked_list->data.address64.resource_source. | ||
| 1105 | string_ptr) + 1); | ||
| 1106 | } | 379 | } |
| 1107 | |||
| 1108 | /* Return the number of bytes consumed in this operation */ | ||
| 1109 | |||
| 1110 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 1111 | |||
| 1112 | /* | ||
| 1113 | * Set the length field to the number of bytes consumed | ||
| 1114 | * minus the header size (3 bytes) | ||
| 1115 | */ | ||
| 1116 | *length_field = (u16) (*bytes_consumed - 3); | ||
| 1117 | return_ACPI_STATUS(AE_OK); | ||
| 1118 | } | 380 | } |
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 378f58390fc1..7d6481d9fbec 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -49,652 +49,433 @@ | |||
| 49 | #define _COMPONENT ACPI_RESOURCES | 49 | #define _COMPONENT ACPI_RESOURCES |
| 50 | ACPI_MODULE_NAME("rscalc") | 50 | ACPI_MODULE_NAME("rscalc") |
| 51 | 51 | ||
| 52 | /* Local prototypes */ | ||
| 53 | static u8 acpi_rs_count_set_bits(u16 bit_field); | ||
| 54 | |||
| 55 | static acpi_rs_length | ||
| 56 | acpi_rs_struct_option_length(struct acpi_resource_source *resource_source); | ||
| 57 | |||
| 58 | static u32 | ||
| 59 | acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length); | ||
| 60 | |||
| 52 | /******************************************************************************* | 61 | /******************************************************************************* |
| 53 | * | 62 | * |
| 54 | * FUNCTION: acpi_rs_get_byte_stream_length | 63 | * FUNCTION: acpi_rs_count_set_bits |
| 55 | * | 64 | * |
| 56 | * PARAMETERS: linked_list - Pointer to the resource linked list | 65 | * PARAMETERS: bit_field - Field in which to count bits |
| 57 | * size_needed - u32 pointer of the size buffer needed | ||
| 58 | * to properly return the parsed data | ||
| 59 | * | 66 | * |
| 60 | * RETURN: Status | 67 | * RETURN: Number of bits set within the field |
| 61 | * | 68 | * |
| 62 | * DESCRIPTION: Takes the resource byte stream and parses it once, calculating | 69 | * DESCRIPTION: Count the number of bits set in a resource field. Used for |
| 63 | * the size buffer needed to hold the linked list that conveys | 70 | * (Short descriptor) interrupt and DMA lists. |
| 64 | * the resource data. | ||
| 65 | * | 71 | * |
| 66 | ******************************************************************************/ | 72 | ******************************************************************************/ |
| 67 | acpi_status | ||
| 68 | acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list, | ||
| 69 | acpi_size * size_needed) | ||
| 70 | { | ||
| 71 | acpi_size byte_stream_size_needed = 0; | ||
| 72 | acpi_size segment_size; | ||
| 73 | u8 done = FALSE; | ||
| 74 | |||
| 75 | ACPI_FUNCTION_TRACE("rs_get_byte_stream_length"); | ||
| 76 | |||
| 77 | while (!done) { | ||
| 78 | /* Init the variable that will hold the size to add to the total. */ | ||
| 79 | |||
| 80 | segment_size = 0; | ||
| 81 | |||
| 82 | switch (linked_list->id) { | ||
| 83 | case ACPI_RSTYPE_IRQ: | ||
| 84 | /* | ||
| 85 | * IRQ Resource | ||
| 86 | * For an IRQ Resource, Byte 3, although optional, will always be | ||
| 87 | * created - it holds IRQ information. | ||
| 88 | */ | ||
| 89 | segment_size = 4; | ||
| 90 | break; | ||
| 91 | |||
| 92 | case ACPI_RSTYPE_DMA: | ||
| 93 | /* | ||
| 94 | * DMA Resource | ||
| 95 | * For this resource the size is static | ||
| 96 | */ | ||
| 97 | segment_size = 3; | ||
| 98 | break; | ||
| 99 | |||
| 100 | case ACPI_RSTYPE_START_DPF: | ||
| 101 | /* | ||
| 102 | * Start Dependent Functions Resource | ||
| 103 | * For a start_dependent_functions Resource, Byte 1, although | ||
| 104 | * optional, will always be created. | ||
| 105 | */ | ||
| 106 | segment_size = 2; | ||
| 107 | break; | ||
| 108 | |||
| 109 | case ACPI_RSTYPE_END_DPF: | ||
| 110 | /* | ||
| 111 | * End Dependent Functions Resource | ||
| 112 | * For this resource the size is static | ||
| 113 | */ | ||
| 114 | segment_size = 1; | ||
| 115 | break; | ||
| 116 | |||
| 117 | case ACPI_RSTYPE_IO: | ||
| 118 | /* | ||
| 119 | * IO Port Resource | ||
| 120 | * For this resource the size is static | ||
| 121 | */ | ||
| 122 | segment_size = 8; | ||
| 123 | break; | ||
| 124 | 73 | ||
| 125 | case ACPI_RSTYPE_FIXED_IO: | 74 | static u8 acpi_rs_count_set_bits(u16 bit_field) |
| 126 | /* | 75 | { |
| 127 | * Fixed IO Port Resource | 76 | u8 bits_set; |
| 128 | * For this resource the size is static | ||
| 129 | */ | ||
| 130 | segment_size = 4; | ||
| 131 | break; | ||
| 132 | |||
| 133 | case ACPI_RSTYPE_VENDOR: | ||
| 134 | /* | ||
| 135 | * Vendor Defined Resource | ||
| 136 | * For a Vendor Specific resource, if the Length is between 1 and 7 | ||
| 137 | * it will be created as a Small Resource data type, otherwise it | ||
| 138 | * is a Large Resource data type. | ||
| 139 | */ | ||
| 140 | if (linked_list->data.vendor_specific.length > 7) { | ||
| 141 | segment_size = 3; | ||
| 142 | } else { | ||
| 143 | segment_size = 1; | ||
| 144 | } | ||
| 145 | segment_size += | ||
| 146 | linked_list->data.vendor_specific.length; | ||
| 147 | break; | ||
| 148 | |||
| 149 | case ACPI_RSTYPE_END_TAG: | ||
| 150 | /* | ||
| 151 | * End Tag | ||
| 152 | * For this resource the size is static | ||
| 153 | */ | ||
| 154 | segment_size = 2; | ||
| 155 | done = TRUE; | ||
| 156 | break; | ||
| 157 | |||
| 158 | case ACPI_RSTYPE_MEM24: | ||
| 159 | /* | ||
| 160 | * 24-Bit Memory Resource | ||
| 161 | * For this resource the size is static | ||
| 162 | */ | ||
| 163 | segment_size = 12; | ||
| 164 | break; | ||
| 165 | 77 | ||
| 166 | case ACPI_RSTYPE_MEM32: | 78 | ACPI_FUNCTION_ENTRY(); |
| 167 | /* | ||
| 168 | * 32-Bit Memory Range Resource | ||
| 169 | * For this resource the size is static | ||
| 170 | */ | ||
| 171 | segment_size = 20; | ||
| 172 | break; | ||
| 173 | 79 | ||
| 174 | case ACPI_RSTYPE_FIXED_MEM32: | 80 | for (bits_set = 0; bit_field; bits_set++) { |
| 175 | /* | 81 | /* Zero the least significant bit that is set */ |
| 176 | * 32-Bit Fixed Memory Resource | ||
| 177 | * For this resource the size is static | ||
| 178 | */ | ||
| 179 | segment_size = 12; | ||
| 180 | break; | ||
| 181 | 82 | ||
| 182 | case ACPI_RSTYPE_ADDRESS16: | 83 | bit_field &= (bit_field - 1); |
| 183 | /* | 84 | } |
| 184 | * 16-Bit Address Resource | ||
| 185 | * The base size of this byte stream is 16. If a Resource Source | ||
| 186 | * string is not NULL, add 1 for the Index + the length of the null | ||
| 187 | * terminated string Resource Source + 1 for the null. | ||
| 188 | */ | ||
| 189 | segment_size = 16; | ||
| 190 | |||
| 191 | if (linked_list->data.address16.resource_source. | ||
| 192 | string_ptr) { | ||
| 193 | segment_size += | ||
| 194 | linked_list->data.address16.resource_source. | ||
| 195 | string_length; | ||
| 196 | segment_size++; | ||
| 197 | } | ||
| 198 | break; | ||
| 199 | 85 | ||
| 200 | case ACPI_RSTYPE_ADDRESS32: | 86 | return (bits_set); |
| 201 | /* | 87 | } |
| 202 | * 32-Bit Address Resource | ||
| 203 | * The base size of this byte stream is 26. If a Resource | ||
| 204 | * Source string is not NULL, add 1 for the Index + the | ||
| 205 | * length of the null terminated string Resource Source + | ||
| 206 | * 1 for the null. | ||
| 207 | */ | ||
| 208 | segment_size = 26; | ||
| 209 | |||
| 210 | if (linked_list->data.address32.resource_source. | ||
| 211 | string_ptr) { | ||
| 212 | segment_size += | ||
| 213 | linked_list->data.address32.resource_source. | ||
| 214 | string_length; | ||
| 215 | segment_size++; | ||
| 216 | } | ||
| 217 | break; | ||
| 218 | 88 | ||
| 219 | case ACPI_RSTYPE_ADDRESS64: | 89 | /******************************************************************************* |
| 220 | /* | 90 | * |
| 221 | * 64-Bit Address Resource | 91 | * FUNCTION: acpi_rs_struct_option_length |
| 222 | * The base size of this byte stream is 46. If a resource_source | 92 | * |
| 223 | * string is not NULL, add 1 for the Index + the length of the null | 93 | * PARAMETERS: resource_source - Pointer to optional descriptor field |
| 224 | * terminated string Resource Source + 1 for the null. | 94 | * |
| 225 | */ | 95 | * RETURN: Status |
| 226 | segment_size = 46; | 96 | * |
| 227 | 97 | * DESCRIPTION: Common code to handle optional resource_source_index and | |
| 228 | if (linked_list->data.address64.resource_source. | 98 | * resource_source fields in some Large descriptors. Used during |
| 229 | string_ptr) { | 99 | * list-to-stream conversion |
| 230 | segment_size += | 100 | * |
| 231 | linked_list->data.address64.resource_source. | 101 | ******************************************************************************/ |
| 232 | string_length; | ||
| 233 | segment_size++; | ||
| 234 | } | ||
| 235 | break; | ||
| 236 | 102 | ||
| 237 | case ACPI_RSTYPE_EXT_IRQ: | 103 | static acpi_rs_length |
| 238 | /* | 104 | acpi_rs_struct_option_length(struct acpi_resource_source *resource_source) |
| 239 | * Extended IRQ Resource | 105 | { |
| 240 | * The base size of this byte stream is 9. This is for an Interrupt | 106 | ACPI_FUNCTION_ENTRY(); |
| 241 | * table length of 1. For each additional interrupt, add 4. | ||
| 242 | * If a Resource Source string is not NULL, add 1 for the | ||
| 243 | * Index + the length of the null terminated string | ||
| 244 | * Resource Source + 1 for the null. | ||
| 245 | */ | ||
| 246 | segment_size = 9 + (((acpi_size) | ||
| 247 | linked_list->data.extended_irq. | ||
| 248 | number_of_interrupts - 1) * 4); | ||
| 249 | |||
| 250 | if (linked_list->data.extended_irq.resource_source. | ||
| 251 | string_ptr) { | ||
| 252 | segment_size += | ||
| 253 | linked_list->data.extended_irq. | ||
| 254 | resource_source.string_length; | ||
| 255 | segment_size++; | ||
| 256 | } | ||
| 257 | break; | ||
| 258 | 107 | ||
| 259 | default: | 108 | /* |
| 109 | * If the resource_source string is valid, return the size of the string | ||
| 110 | * (string_length includes the NULL terminator) plus the size of the | ||
| 111 | * resource_source_index (1). | ||
| 112 | */ | ||
| 113 | if (resource_source->string_ptr) { | ||
| 114 | return ((acpi_rs_length) (resource_source->string_length + 1)); | ||
| 115 | } | ||
| 260 | 116 | ||
| 261 | /* If we get here, everything is out of sync, exit with error */ | 117 | return (0); |
| 118 | } | ||
| 262 | 119 | ||
| 263 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | 120 | /******************************************************************************* |
| 121 | * | ||
| 122 | * FUNCTION: acpi_rs_stream_option_length | ||
| 123 | * | ||
| 124 | * PARAMETERS: resource_length - Length from the resource header | ||
| 125 | * minimum_total_length - Minimum length of this resource, before | ||
| 126 | * any optional fields. Includes header size | ||
| 127 | * | ||
| 128 | * RETURN: Length of optional string (0 if no string present) | ||
| 129 | * | ||
| 130 | * DESCRIPTION: Common code to handle optional resource_source_index and | ||
| 131 | * resource_source fields in some Large descriptors. Used during | ||
| 132 | * stream-to-list conversion | ||
| 133 | * | ||
| 134 | ******************************************************************************/ | ||
| 264 | 135 | ||
| 265 | } /* switch (linked_list->Id) */ | 136 | static u32 |
| 137 | acpi_rs_stream_option_length(u32 resource_length, | ||
| 138 | u32 minimum_aml_resource_length) | ||
| 139 | { | ||
| 140 | u32 string_length = 0; | ||
| 266 | 141 | ||
| 267 | /* Update the total */ | 142 | ACPI_FUNCTION_ENTRY(); |
| 268 | 143 | ||
| 269 | byte_stream_size_needed += segment_size; | 144 | /* |
| 145 | * The resource_source_index and resource_source are optional elements of some | ||
| 146 | * Large-type resource descriptors. | ||
| 147 | */ | ||
| 270 | 148 | ||
| 271 | /* Point to the next object */ | 149 | /* |
| 150 | * If the length of the actual resource descriptor is greater than the ACPI | ||
| 151 | * spec-defined minimum length, it means that a resource_source_index exists | ||
| 152 | * and is followed by a (required) null terminated string. The string length | ||
| 153 | * (including the null terminator) is the resource length minus the minimum | ||
| 154 | * length, minus one byte for the resource_source_index itself. | ||
| 155 | */ | ||
| 156 | if (resource_length > minimum_aml_resource_length) { | ||
| 157 | /* Compute the length of the optional string */ | ||
| 272 | 158 | ||
| 273 | linked_list = ACPI_PTR_ADD(struct acpi_resource, | 159 | string_length = |
| 274 | linked_list, linked_list->length); | 160 | resource_length - minimum_aml_resource_length - 1; |
| 275 | } | 161 | } |
| 276 | 162 | ||
| 277 | /* This is the data the caller needs */ | 163 | /* Round up length to 32 bits for internal structure alignment */ |
| 278 | 164 | ||
| 279 | *size_needed = byte_stream_size_needed; | 165 | return (ACPI_ROUND_UP_to_32_bITS(string_length)); |
| 280 | return_ACPI_STATUS(AE_OK); | ||
| 281 | } | 166 | } |
| 282 | 167 | ||
| 283 | /******************************************************************************* | 168 | /******************************************************************************* |
| 284 | * | 169 | * |
| 285 | * FUNCTION: acpi_rs_get_list_length | 170 | * FUNCTION: acpi_rs_get_aml_length |
| 286 | * | 171 | * |
| 287 | * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream | 172 | * PARAMETERS: Resource - Pointer to the resource linked list |
| 288 | * byte_stream_buffer_length - Size of byte_stream_buffer | 173 | * size_needed - Where the required size is returned |
| 289 | * size_needed - u32 pointer of the size buffer | ||
| 290 | * needed to properly return the | ||
| 291 | * parsed data | ||
| 292 | * | 174 | * |
| 293 | * RETURN: Status | 175 | * RETURN: Status |
| 294 | * | 176 | * |
| 295 | * DESCRIPTION: Takes the resource byte stream and parses it once, calculating | 177 | * DESCRIPTION: Takes a linked list of internal resource descriptors and |
| 296 | * the size buffer needed to hold the linked list that conveys | 178 | * calculates the size buffer needed to hold the corresponding |
| 297 | * the resource data. | 179 | * external resource byte stream. |
| 298 | * | 180 | * |
| 299 | ******************************************************************************/ | 181 | ******************************************************************************/ |
| 300 | 182 | ||
| 301 | acpi_status | 183 | acpi_status |
| 302 | acpi_rs_get_list_length(u8 * byte_stream_buffer, | 184 | acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) |
| 303 | u32 byte_stream_buffer_length, acpi_size * size_needed) | ||
| 304 | { | 185 | { |
| 305 | u32 buffer_size = 0; | 186 | acpi_size aml_size_needed = 0; |
| 306 | u32 bytes_parsed = 0; | 187 | acpi_rs_length total_size; |
| 307 | u8 number_of_interrupts = 0; | ||
| 308 | u8 number_of_channels = 0; | ||
| 309 | u8 resource_type; | ||
| 310 | u32 structure_size; | ||
| 311 | u32 bytes_consumed; | ||
| 312 | u8 *buffer; | ||
| 313 | u8 temp8; | ||
| 314 | u16 temp16; | ||
| 315 | u8 index; | ||
| 316 | u8 additional_bytes; | ||
| 317 | |||
| 318 | ACPI_FUNCTION_TRACE("rs_get_list_length"); | ||
| 319 | 188 | ||
| 320 | while (bytes_parsed < byte_stream_buffer_length) { | 189 | ACPI_FUNCTION_TRACE("rs_get_aml_length"); |
| 321 | /* The next byte in the stream is the resource type */ | ||
| 322 | 190 | ||
| 323 | resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); | 191 | /* Traverse entire list of internal resource descriptors */ |
| 324 | 192 | ||
| 325 | switch (resource_type) { | 193 | while (resource) { |
| 326 | case ACPI_RDESC_TYPE_MEMORY_24: | 194 | /* Validate the descriptor type */ |
| 327 | /* | ||
| 328 | * 24-Bit Memory Resource | ||
| 329 | */ | ||
| 330 | bytes_consumed = 12; | ||
| 331 | |||
| 332 | structure_size = | ||
| 333 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24); | ||
| 334 | break; | ||
| 335 | 195 | ||
| 336 | case ACPI_RDESC_TYPE_LARGE_VENDOR: | 196 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { |
| 337 | /* | 197 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); |
| 338 | * Vendor Defined Resource | 198 | } |
| 339 | */ | ||
| 340 | buffer = byte_stream_buffer; | ||
| 341 | ++buffer; | ||
| 342 | |||
| 343 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 344 | bytes_consumed = temp16 + 3; | ||
| 345 | |||
| 346 | /* Ensure a 32-bit boundary for the structure */ | ||
| 347 | 199 | ||
| 348 | temp16 = (u16) ACPI_ROUND_UP_to_32_bITS(temp16); | 200 | /* Get the base size of the (external stream) resource descriptor */ |
| 349 | 201 | ||
| 350 | structure_size = | 202 | total_size = acpi_gbl_aml_resource_sizes[resource->type]; |
| 351 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + | ||
| 352 | (temp16 * sizeof(u8)); | ||
| 353 | break; | ||
| 354 | 203 | ||
| 355 | case ACPI_RDESC_TYPE_MEMORY_32: | 204 | /* |
| 205 | * Augment the base size for descriptors with optional and/or | ||
| 206 | * variable-length fields | ||
| 207 | */ | ||
| 208 | switch (resource->type) { | ||
| 209 | case ACPI_RESOURCE_TYPE_VENDOR: | ||
| 356 | /* | 210 | /* |
| 357 | * 32-Bit Memory Range Resource | 211 | * Vendor Defined Resource: |
| 212 | * For a Vendor Specific resource, if the Length is between 1 and 7 | ||
| 213 | * it will be created as a Small Resource data type, otherwise it | ||
| 214 | * is a Large Resource data type. | ||
| 358 | */ | 215 | */ |
| 359 | bytes_consumed = 20; | 216 | if (resource->data.vendor.byte_length > 7) { |
| 217 | /* Base size of a Large resource descriptor */ | ||
| 360 | 218 | ||
| 361 | structure_size = | 219 | total_size = |
| 362 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32); | 220 | sizeof(struct aml_resource_large_header); |
| 363 | break; | 221 | } |
| 364 | 222 | ||
| 365 | case ACPI_RDESC_TYPE_FIXED_MEMORY_32: | 223 | /* Add the size of the vendor-specific data */ |
| 366 | /* | ||
| 367 | * 32-Bit Fixed Memory Resource | ||
| 368 | */ | ||
| 369 | bytes_consumed = 12; | ||
| 370 | 224 | ||
| 371 | structure_size = | 225 | total_size = (acpi_rs_length) |
| 372 | ACPI_SIZEOF_RESOURCE(struct | 226 | (total_size + resource->data.vendor.byte_length); |
| 373 | acpi_resource_fixed_mem32); | ||
| 374 | break; | 227 | break; |
| 375 | 228 | ||
| 376 | case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: | 229 | case ACPI_RESOURCE_TYPE_END_TAG: |
| 377 | /* | 230 | /* |
| 378 | * 64-Bit Address Resource | 231 | * End Tag: |
| 232 | * We are done -- return the accumulated total size. | ||
| 379 | */ | 233 | */ |
| 380 | buffer = byte_stream_buffer; | 234 | *size_needed = aml_size_needed + total_size; |
| 381 | 235 | ||
| 382 | ++buffer; | 236 | /* Normal exit */ |
| 383 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 384 | 237 | ||
| 385 | bytes_consumed = temp16 + 3; | 238 | return_ACPI_STATUS(AE_OK); |
| 386 | structure_size = | ||
| 387 | ACPI_SIZEOF_RESOURCE(struct | ||
| 388 | acpi_resource_address64); | ||
| 389 | break; | ||
| 390 | 239 | ||
| 391 | case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: | 240 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
| 392 | /* | 241 | /* |
| 393 | * 64-Bit Address Resource | 242 | * 16-Bit Address Resource: |
| 243 | * Add the size of the optional resource_source info | ||
| 394 | */ | 244 | */ |
| 395 | buffer = byte_stream_buffer; | 245 | total_size = (acpi_rs_length) |
| 396 | 246 | (total_size + | |
| 397 | ++buffer; | 247 | acpi_rs_struct_option_length(&resource->data. |
| 398 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 248 | address16. |
| 399 | 249 | resource_source)); | |
| 400 | bytes_consumed = temp16 + 3; | 250 | break; |
| 401 | 251 | ||
| 252 | case ACPI_RESOURCE_TYPE_ADDRESS32: | ||
| 402 | /* | 253 | /* |
| 403 | * Resource Source Index and Resource Source are optional elements. | 254 | * 32-Bit Address Resource: |
| 404 | * Check the length of the Bytestream. If it is greater than 43, | 255 | * Add the size of the optional resource_source info |
| 405 | * that means that an Index exists and is followed by a null | ||
| 406 | * terminated string. Therefore, set the temp variable to the | ||
| 407 | * length minus the minimum byte stream length plus the byte for | ||
| 408 | * the Index to determine the size of the NULL terminated string. | ||
| 409 | */ | 256 | */ |
| 410 | if (43 < temp16) { | 257 | total_size = (acpi_rs_length) |
| 411 | temp8 = (u8) (temp16 - 44); | 258 | (total_size + |
| 412 | } else { | 259 | acpi_rs_struct_option_length(&resource->data. |
| 413 | temp8 = 0; | 260 | address32. |
| 414 | } | 261 | resource_source)); |
| 415 | |||
| 416 | /* Ensure a 64-bit boundary for the structure */ | ||
| 417 | |||
| 418 | temp8 = (u8) ACPI_ROUND_UP_to_64_bITS(temp8); | ||
| 419 | |||
| 420 | structure_size = | ||
| 421 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64) | ||
| 422 | + (temp8 * sizeof(u8)); | ||
| 423 | break; | 262 | break; |
| 424 | 263 | ||
| 425 | case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: | 264 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
| 426 | /* | 265 | /* |
| 427 | * 32-Bit Address Resource | 266 | * 64-Bit Address Resource: |
| 267 | * Add the size of the optional resource_source info | ||
| 428 | */ | 268 | */ |
| 429 | buffer = byte_stream_buffer; | 269 | total_size = (acpi_rs_length) |
| 430 | 270 | (total_size + | |
| 431 | ++buffer; | 271 | acpi_rs_struct_option_length(&resource->data. |
| 432 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 272 | address64. |
| 433 | 273 | resource_source)); | |
| 434 | bytes_consumed = temp16 + 3; | 274 | break; |
| 435 | 275 | ||
| 276 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | ||
| 436 | /* | 277 | /* |
| 437 | * Resource Source Index and Resource Source are optional elements. | 278 | * Extended IRQ Resource: |
| 438 | * Check the length of the Bytestream. If it is greater than 23, | 279 | * Add the size of each additional optional interrupt beyond the |
| 439 | * that means that an Index exists and is followed by a null | 280 | * required 1 (4 bytes for each u32 interrupt number) |
| 440 | * terminated string. Therefore, set the temp variable to the | ||
| 441 | * length minus the minimum byte stream length plus the byte for | ||
| 442 | * the Index to determine the size of the NULL terminated string. | ||
| 443 | */ | 281 | */ |
| 444 | if (23 < temp16) { | 282 | total_size = (acpi_rs_length) |
| 445 | temp8 = (u8) (temp16 - 24); | 283 | (total_size + |
| 446 | } else { | 284 | ((resource->data.extended_irq.interrupt_count - |
| 447 | temp8 = 0; | 285 | 1) * 4) + |
| 448 | } | 286 | /* Add the size of the optional resource_source info */ |
| 449 | 287 | acpi_rs_struct_option_length(&resource->data. | |
| 450 | /* Ensure a 32-bit boundary for the structure */ | 288 | extended_irq. |
| 451 | 289 | resource_source)); | |
| 452 | temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); | 290 | break; |
| 453 | 291 | ||
| 454 | structure_size = | 292 | default: |
| 455 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32) | ||
| 456 | + (temp8 * sizeof(u8)); | ||
| 457 | break; | 293 | break; |
| 294 | } | ||
| 458 | 295 | ||
| 459 | case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: | 296 | /* Update the total */ |
| 460 | /* | ||
| 461 | * 16-Bit Address Resource | ||
| 462 | */ | ||
| 463 | buffer = byte_stream_buffer; | ||
| 464 | 297 | ||
| 465 | ++buffer; | 298 | aml_size_needed += total_size; |
| 466 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 467 | 299 | ||
| 468 | bytes_consumed = temp16 + 3; | 300 | /* Point to the next object */ |
| 469 | 301 | ||
| 470 | /* | 302 | resource = |
| 471 | * Resource Source Index and Resource Source are optional elements. | 303 | ACPI_ADD_PTR(struct acpi_resource, resource, |
| 472 | * Check the length of the Bytestream. If it is greater than 13, | 304 | resource->length); |
| 473 | * that means that an Index exists and is followed by a null | 305 | } |
| 474 | * terminated string. Therefore, set the temp variable to the | ||
| 475 | * length minus the minimum byte stream length plus the byte for | ||
| 476 | * the Index to determine the size of the NULL terminated string. | ||
| 477 | */ | ||
| 478 | if (13 < temp16) { | ||
| 479 | temp8 = (u8) (temp16 - 14); | ||
| 480 | } else { | ||
| 481 | temp8 = 0; | ||
| 482 | } | ||
| 483 | 306 | ||
| 484 | /* Ensure a 32-bit boundary for the structure */ | 307 | /* Did not find an end_tag resource descriptor */ |
| 485 | 308 | ||
| 486 | temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); | 309 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); |
| 310 | } | ||
| 487 | 311 | ||
| 488 | structure_size = | 312 | /******************************************************************************* |
| 489 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16) | 313 | * |
| 490 | + (temp8 * sizeof(u8)); | 314 | * FUNCTION: acpi_rs_get_list_length |
| 491 | break; | 315 | * |
| 316 | * PARAMETERS: aml_buffer - Pointer to the resource byte stream | ||
| 317 | * aml_buffer_length - Size of aml_buffer | ||
| 318 | * size_needed - Where the size needed is returned | ||
| 319 | * | ||
| 320 | * RETURN: Status | ||
| 321 | * | ||
| 322 | * DESCRIPTION: Takes an external resource byte stream and calculates the size | ||
| 323 | * buffer needed to hold the corresponding internal resource | ||
| 324 | * descriptor linked list. | ||
| 325 | * | ||
| 326 | ******************************************************************************/ | ||
| 492 | 327 | ||
| 493 | case ACPI_RDESC_TYPE_EXTENDED_XRUPT: | 328 | acpi_status |
| 494 | /* | 329 | acpi_rs_get_list_length(u8 * aml_buffer, |
| 495 | * Extended IRQ | 330 | u32 aml_buffer_length, acpi_size * size_needed) |
| 496 | */ | 331 | { |
| 497 | buffer = byte_stream_buffer; | 332 | acpi_status status; |
| 333 | u8 *end_aml; | ||
| 334 | u8 *buffer; | ||
| 335 | u32 buffer_size = 0; | ||
| 336 | u16 temp16; | ||
| 337 | u16 resource_length; | ||
| 338 | u32 extra_struct_bytes; | ||
| 339 | u8 resource_index; | ||
| 340 | u8 minimum_aml_resource_length; | ||
| 498 | 341 | ||
| 499 | ++buffer; | 342 | ACPI_FUNCTION_TRACE("rs_get_list_length"); |
| 500 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 501 | 343 | ||
| 502 | bytes_consumed = temp16 + 3; | 344 | end_aml = aml_buffer + aml_buffer_length; |
| 503 | 345 | ||
| 504 | /* | 346 | /* Walk the list of AML resource descriptors */ |
| 505 | * Point past the length field and the Interrupt vector flags to | ||
| 506 | * save off the Interrupt table length to the Temp8 variable. | ||
| 507 | */ | ||
| 508 | buffer += 3; | ||
| 509 | temp8 = *buffer; | ||
| 510 | 347 | ||
| 511 | /* | 348 | while (aml_buffer < end_aml) { |
| 512 | * To compensate for multiple interrupt numbers, add 4 bytes for | 349 | /* Validate the Resource Type and Resource Length */ |
| 513 | * each additional interrupts greater than 1 | ||
| 514 | */ | ||
| 515 | additional_bytes = (u8) ((temp8 - 1) * 4); | ||
| 516 | 350 | ||
| 517 | /* | 351 | status = acpi_ut_validate_resource(aml_buffer, &resource_index); |
| 518 | * Resource Source Index and Resource Source are optional elements. | 352 | if (ACPI_FAILURE(status)) { |
| 519 | * Check the length of the Bytestream. If it is greater than 9, | 353 | return_ACPI_STATUS(status); |
| 520 | * that means that an Index exists and is followed by a null | 354 | } |
| 521 | * terminated string. Therefore, set the temp variable to the | ||
| 522 | * length minus the minimum byte stream length plus the byte for | ||
| 523 | * the Index to determine the size of the NULL terminated string. | ||
| 524 | */ | ||
| 525 | if (9 + additional_bytes < temp16) { | ||
| 526 | temp8 = (u8) (temp16 - (9 + additional_bytes)); | ||
| 527 | } else { | ||
| 528 | temp8 = 0; | ||
| 529 | } | ||
| 530 | 355 | ||
| 531 | /* Ensure a 32-bit boundary for the structure */ | 356 | /* Get the resource length and base (minimum) AML size */ |
| 532 | 357 | ||
| 533 | temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); | 358 | resource_length = acpi_ut_get_resource_length(aml_buffer); |
| 359 | minimum_aml_resource_length = | ||
| 360 | acpi_gbl_resource_aml_sizes[resource_index]; | ||
| 534 | 361 | ||
| 535 | structure_size = | 362 | /* |
| 536 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq) + | 363 | * Augment the size for descriptors with optional |
| 537 | (additional_bytes * sizeof(u8)) + | 364 | * and/or variable length fields |
| 538 | (temp8 * sizeof(u8)); | 365 | */ |
| 539 | break; | 366 | extra_struct_bytes = 0; |
| 367 | buffer = | ||
| 368 | aml_buffer + acpi_ut_get_resource_header_length(aml_buffer); | ||
| 540 | 369 | ||
| 541 | case ACPI_RDESC_TYPE_IRQ_FORMAT: | 370 | switch (acpi_ut_get_resource_type(aml_buffer)) { |
| 371 | case ACPI_RESOURCE_NAME_IRQ: | ||
| 542 | /* | 372 | /* |
| 543 | * IRQ Resource. | 373 | * IRQ Resource: |
| 544 | * Determine if it there are two or three trailing bytes | 374 | * Get the number of bits set in the 16-bit IRQ mask |
| 545 | */ | 375 | */ |
| 546 | buffer = byte_stream_buffer; | ||
| 547 | temp8 = *buffer; | ||
| 548 | |||
| 549 | if (temp8 & 0x01) { | ||
| 550 | bytes_consumed = 4; | ||
| 551 | } else { | ||
| 552 | bytes_consumed = 3; | ||
| 553 | } | ||
| 554 | |||
| 555 | /* Point past the descriptor */ | ||
| 556 | |||
| 557 | ++buffer; | ||
| 558 | |||
| 559 | /* Look at the number of bits set */ | ||
| 560 | |||
| 561 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 376 | ACPI_MOVE_16_TO_16(&temp16, buffer); |
| 562 | 377 | extra_struct_bytes = acpi_rs_count_set_bits(temp16); | |
| 563 | for (index = 0; index < 16; index++) { | ||
| 564 | if (temp16 & 0x1) { | ||
| 565 | ++number_of_interrupts; | ||
| 566 | } | ||
| 567 | |||
| 568 | temp16 >>= 1; | ||
| 569 | } | ||
| 570 | |||
| 571 | structure_size = | ||
| 572 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_io) + | ||
| 573 | (number_of_interrupts * sizeof(u32)); | ||
| 574 | break; | 378 | break; |
| 575 | 379 | ||
| 576 | case ACPI_RDESC_TYPE_DMA_FORMAT: | 380 | case ACPI_RESOURCE_NAME_DMA: |
| 577 | /* | 381 | /* |
| 578 | * DMA Resource | 382 | * DMA Resource: |
| 383 | * Get the number of bits set in the 8-bit DMA mask | ||
| 579 | */ | 384 | */ |
| 580 | buffer = byte_stream_buffer; | 385 | extra_struct_bytes = acpi_rs_count_set_bits(*buffer); |
| 581 | bytes_consumed = 3; | ||
| 582 | |||
| 583 | /* Point past the descriptor */ | ||
| 584 | |||
| 585 | ++buffer; | ||
| 586 | |||
| 587 | /* Look at the number of bits set */ | ||
| 588 | |||
| 589 | temp8 = *buffer; | ||
| 590 | |||
| 591 | for (index = 0; index < 8; index++) { | ||
| 592 | if (temp8 & 0x1) { | ||
| 593 | ++number_of_channels; | ||
| 594 | } | ||
| 595 | |||
| 596 | temp8 >>= 1; | ||
| 597 | } | ||
| 598 | |||
| 599 | structure_size = | ||
| 600 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma) + | ||
| 601 | (number_of_channels * sizeof(u32)); | ||
| 602 | break; | 386 | break; |
| 603 | 387 | ||
| 604 | case ACPI_RDESC_TYPE_START_DEPENDENT: | 388 | case ACPI_RESOURCE_NAME_VENDOR_SMALL: |
| 605 | /* | 389 | /* |
| 606 | * Start Dependent Functions Resource | 390 | * Vendor Resource: |
| 607 | * Determine if it there are two or three trailing bytes | 391 | * Ensure a 32-bit boundary for the structure |
| 608 | */ | 392 | */ |
| 609 | buffer = byte_stream_buffer; | 393 | extra_struct_bytes = |
| 610 | temp8 = *buffer; | 394 | ACPI_ROUND_UP_to_32_bITS(resource_length) - |
| 611 | 395 | resource_length; | |
| 612 | if (temp8 & 0x01) { | ||
| 613 | bytes_consumed = 2; | ||
| 614 | } else { | ||
| 615 | bytes_consumed = 1; | ||
| 616 | } | ||
| 617 | |||
| 618 | structure_size = | ||
| 619 | ACPI_SIZEOF_RESOURCE(struct | ||
| 620 | acpi_resource_start_dpf); | ||
| 621 | break; | 396 | break; |
| 622 | 397 | ||
| 623 | case ACPI_RDESC_TYPE_END_DEPENDENT: | 398 | case ACPI_RESOURCE_NAME_END_TAG: |
| 624 | /* | 399 | /* |
| 625 | * End Dependent Functions Resource | 400 | * End Tag: This is the normal exit, add size of end_tag |
| 626 | */ | 401 | */ |
| 627 | bytes_consumed = 1; | 402 | *size_needed = buffer_size + ACPI_RS_SIZE_MIN; |
| 628 | structure_size = ACPI_RESOURCE_LENGTH; | 403 | return_ACPI_STATUS(AE_OK); |
| 629 | break; | ||
| 630 | 404 | ||
| 631 | case ACPI_RDESC_TYPE_IO_PORT: | 405 | case ACPI_RESOURCE_NAME_VENDOR_LARGE: |
| 632 | /* | 406 | /* |
| 633 | * IO Port Resource | 407 | * Vendor Resource: |
| 408 | * Add vendor data and ensure a 32-bit boundary for the structure | ||
| 634 | */ | 409 | */ |
| 635 | bytes_consumed = 8; | 410 | extra_struct_bytes = |
| 636 | structure_size = | 411 | ACPI_ROUND_UP_to_32_bITS(resource_length) - |
| 637 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); | 412 | resource_length; |
| 638 | break; | 413 | break; |
| 639 | 414 | ||
| 640 | case ACPI_RDESC_TYPE_FIXED_IO_PORT: | 415 | case ACPI_RESOURCE_NAME_ADDRESS32: |
| 416 | case ACPI_RESOURCE_NAME_ADDRESS16: | ||
| 641 | /* | 417 | /* |
| 642 | * Fixed IO Port Resource | 418 | * 32-Bit or 16-bit Address Resource: |
| 419 | * Add the size of any optional data (resource_source) | ||
| 643 | */ | 420 | */ |
| 644 | bytes_consumed = 4; | 421 | extra_struct_bytes = |
| 645 | structure_size = | 422 | acpi_rs_stream_option_length(resource_length, |
| 646 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); | 423 | minimum_aml_resource_length); |
| 647 | break; | 424 | break; |
| 648 | 425 | ||
| 649 | case ACPI_RDESC_TYPE_SMALL_VENDOR: | 426 | case ACPI_RESOURCE_NAME_EXTENDED_IRQ: |
| 650 | /* | 427 | /* |
| 651 | * Vendor Specific Resource | 428 | * Extended IRQ: |
| 429 | * Point past the interrupt_vector_flags to get the | ||
| 430 | * interrupt_table_length. | ||
| 652 | */ | 431 | */ |
| 653 | buffer = byte_stream_buffer; | 432 | buffer++; |
| 654 | 433 | ||
| 655 | temp8 = *buffer; | 434 | extra_struct_bytes = |
| 656 | temp8 = (u8) (temp8 & 0x7); | 435 | /* |
| 657 | bytes_consumed = temp8 + 1; | 436 | * Add 4 bytes for each additional interrupt. Note: at |
| 658 | 437 | * least one interrupt is required and is included in | |
| 659 | /* Ensure a 32-bit boundary for the structure */ | 438 | * the minimum descriptor size |
| 660 | 439 | */ | |
| 661 | temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8); | 440 | ((*buffer - 1) * sizeof(u32)) + |
| 662 | structure_size = | 441 | /* Add the size of any optional data (resource_source) */ |
| 663 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) + | 442 | acpi_rs_stream_option_length(resource_length - |
| 664 | (temp8 * sizeof(u8)); | 443 | extra_struct_bytes, |
| 444 | minimum_aml_resource_length); | ||
| 665 | break; | 445 | break; |
| 666 | 446 | ||
| 667 | case ACPI_RDESC_TYPE_END_TAG: | 447 | case ACPI_RESOURCE_NAME_ADDRESS64: |
| 668 | /* | 448 | /* |
| 669 | * End Tag | 449 | * 64-Bit Address Resource: |
| 450 | * Add the size of any optional data (resource_source) | ||
| 451 | * Ensure a 64-bit boundary for the structure | ||
| 670 | */ | 452 | */ |
| 671 | bytes_consumed = 2; | 453 | extra_struct_bytes = |
| 672 | structure_size = ACPI_RESOURCE_LENGTH; | 454 | ACPI_ROUND_UP_to_64_bITS |
| 673 | byte_stream_buffer_length = bytes_parsed; | 455 | (acpi_rs_stream_option_length |
| 456 | (resource_length, minimum_aml_resource_length)); | ||
| 674 | break; | 457 | break; |
| 675 | 458 | ||
| 676 | default: | 459 | default: |
| 677 | /* | 460 | break; |
| 678 | * If we get here, everything is out of sync, | ||
| 679 | * exit with an error | ||
| 680 | */ | ||
| 681 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
| 682 | } | 461 | } |
| 683 | 462 | ||
| 684 | /* Update the return value and counter */ | 463 | /* Update the required buffer size for the internal descriptor structs */ |
| 685 | |||
| 686 | buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(structure_size); | ||
| 687 | bytes_parsed += bytes_consumed; | ||
| 688 | 464 | ||
| 689 | /* Set the byte stream to point to the next resource */ | 465 | temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + |
| 466 | extra_struct_bytes); | ||
| 467 | buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16); | ||
| 690 | 468 | ||
| 691 | byte_stream_buffer += bytes_consumed; | 469 | /* |
| 470 | * Point to the next resource within the stream | ||
| 471 | * using the size of the header plus the length contained in the header | ||
| 472 | */ | ||
| 473 | aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); | ||
| 692 | } | 474 | } |
| 693 | 475 | ||
| 694 | /* This is the data the caller needs */ | 476 | /* Did not find an end_tag resource descriptor */ |
| 695 | 477 | ||
| 696 | *size_needed = buffer_size; | 478 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); |
| 697 | return_ACPI_STATUS(AE_OK); | ||
| 698 | } | 479 | } |
| 699 | 480 | ||
| 700 | /******************************************************************************* | 481 | /******************************************************************************* |
| @@ -760,13 +541,13 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
| 760 | 541 | ||
| 761 | for (table_index = 0; table_index < 4 && !name_found; | 542 | for (table_index = 0; table_index < 4 && !name_found; |
| 762 | table_index++) { | 543 | table_index++) { |
| 763 | if ((ACPI_TYPE_STRING == | 544 | if (*sub_object_list && /* Null object allowed */ |
| 764 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) | 545 | ((ACPI_TYPE_STRING == |
| 765 | || | 546 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) || |
| 766 | ((ACPI_TYPE_LOCAL_REFERENCE == | 547 | ((ACPI_TYPE_LOCAL_REFERENCE == |
| 767 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) | 548 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) && |
| 768 | && ((*sub_object_list)->reference.opcode == | 549 | ((*sub_object_list)->reference.opcode == |
| 769 | AML_INT_NAMEPATH_OP))) { | 550 | AML_INT_NAMEPATH_OP)))) { |
| 770 | name_found = TRUE; | 551 | name_found = TRUE; |
| 771 | } else { | 552 | } else { |
| 772 | /* Look at the next element */ | 553 | /* Look at the next element */ |
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 0911526b7ad8..8c128dea3252 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -53,10 +53,10 @@ ACPI_MODULE_NAME("rscreate") | |||
| 53 | * | 53 | * |
| 54 | * FUNCTION: acpi_rs_create_resource_list | 54 | * FUNCTION: acpi_rs_create_resource_list |
| 55 | * | 55 | * |
| 56 | * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream | 56 | * PARAMETERS: aml_buffer - Pointer to the resource byte stream |
| 57 | * output_buffer - Pointer to the user's buffer | 57 | * output_buffer - Pointer to the user's buffer |
| 58 | * | 58 | * |
| 59 | * RETURN: Status - AE_OK if okay, else a valid acpi_status code | 59 | * RETURN: Status: AE_OK if okay, else a valid acpi_status code |
| 60 | * If output_buffer is not large enough, output_buffer_length | 60 | * If output_buffer is not large enough, output_buffer_length |
| 61 | * indicates how large output_buffer should be, else it | 61 | * indicates how large output_buffer should be, else it |
| 62 | * indicates how may u8 elements of output_buffer are valid. | 62 | * indicates how may u8 elements of output_buffer are valid. |
| @@ -67,33 +67,30 @@ ACPI_MODULE_NAME("rscreate") | |||
| 67 | * | 67 | * |
| 68 | ******************************************************************************/ | 68 | ******************************************************************************/ |
| 69 | acpi_status | 69 | acpi_status |
| 70 | acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer, | 70 | acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, |
| 71 | struct acpi_buffer *output_buffer) | 71 | struct acpi_buffer *output_buffer) |
| 72 | { | 72 | { |
| 73 | 73 | ||
| 74 | acpi_status status; | 74 | acpi_status status; |
| 75 | u8 *byte_stream_start; | 75 | u8 *aml_start; |
| 76 | acpi_size list_size_needed = 0; | 76 | acpi_size list_size_needed = 0; |
| 77 | u32 byte_stream_buffer_length; | 77 | u32 aml_buffer_length; |
| 78 | 78 | ||
| 79 | ACPI_FUNCTION_TRACE("rs_create_resource_list"); | 79 | ACPI_FUNCTION_TRACE("rs_create_resource_list"); |
| 80 | 80 | ||
| 81 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_buffer = %p\n", | 81 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_buffer = %p\n", aml_buffer)); |
| 82 | byte_stream_buffer)); | ||
| 83 | 82 | ||
| 84 | /* Params already validated, so we don't re-validate here */ | 83 | /* Params already validated, so we don't re-validate here */ |
| 85 | 84 | ||
| 86 | byte_stream_buffer_length = byte_stream_buffer->buffer.length; | 85 | aml_buffer_length = aml_buffer->buffer.length; |
| 87 | byte_stream_start = byte_stream_buffer->buffer.pointer; | 86 | aml_start = aml_buffer->buffer.pointer; |
| 88 | 87 | ||
| 89 | /* | 88 | /* |
| 90 | * Pass the byte_stream_buffer into a module that can calculate | 89 | * Pass the aml_buffer into a module that can calculate |
| 91 | * the buffer size needed for the linked list | 90 | * the buffer size needed for the linked list |
| 92 | */ | 91 | */ |
| 93 | status = | 92 | status = acpi_rs_get_list_length(aml_start, aml_buffer_length, |
| 94 | acpi_rs_get_list_length(byte_stream_start, | 93 | &list_size_needed); |
| 95 | byte_stream_buffer_length, | ||
| 96 | &list_size_needed); | ||
| 97 | 94 | ||
| 98 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n", | 95 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n", |
| 99 | status, (u32) list_size_needed)); | 96 | status, (u32) list_size_needed)); |
| @@ -110,10 +107,8 @@ acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer, | |||
| 110 | 107 | ||
| 111 | /* Do the conversion */ | 108 | /* Do the conversion */ |
| 112 | 109 | ||
| 113 | status = | 110 | status = acpi_rs_convert_aml_to_resources(aml_start, aml_buffer_length, |
| 114 | acpi_rs_byte_stream_to_list(byte_stream_start, | 111 | output_buffer->pointer); |
| 115 | byte_stream_buffer_length, | ||
| 116 | output_buffer->pointer); | ||
| 117 | if (ACPI_FAILURE(status)) { | 112 | if (ACPI_FAILURE(status)) { |
| 118 | return_ACPI_STATUS(status); | 113 | return_ACPI_STATUS(status); |
| 119 | } | 114 | } |
| @@ -212,21 +207,20 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
| 212 | /* Each element of the top-level package must also be a package */ | 207 | /* Each element of the top-level package must also be a package */ |
| 213 | 208 | ||
| 214 | if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) { | 209 | if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) { |
| 215 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 210 | ACPI_ERROR((AE_INFO, |
| 216 | "(PRT[%X]) Need sub-package, found %s\n", | 211 | "(PRT[%X]) Need sub-package, found %s", |
| 217 | index, | 212 | index, |
| 218 | acpi_ut_get_object_type_name | 213 | acpi_ut_get_object_type_name |
| 219 | (*top_object_list))); | 214 | (*top_object_list))); |
| 220 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 215 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
| 221 | } | 216 | } |
| 222 | 217 | ||
| 223 | /* Each sub-package must be of length 4 */ | 218 | /* Each sub-package must be of length 4 */ |
| 224 | 219 | ||
| 225 | if ((*top_object_list)->package.count != 4) { | 220 | if ((*top_object_list)->package.count != 4) { |
| 226 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 221 | ACPI_ERROR((AE_INFO, |
| 227 | "(PRT[%X]) Need package of length 4, found length %d\n", | 222 | "(PRT[%X]) Need package of length 4, found length %d", |
| 228 | index, | 223 | index, (*top_object_list)->package.count)); |
| 229 | (*top_object_list)->package.count)); | ||
| 230 | return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT); | 224 | return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT); |
| 231 | } | 225 | } |
| 232 | 226 | ||
| @@ -243,11 +237,10 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
| 243 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 237 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { |
| 244 | user_prt->address = obj_desc->integer.value; | 238 | user_prt->address = obj_desc->integer.value; |
| 245 | } else { | 239 | } else { |
| 246 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 240 | ACPI_ERROR((AE_INFO, |
| 247 | "(PRT[%X].Address) Need Integer, found %s\n", | 241 | "(PRT[%X].Address) Need Integer, found %s", |
| 248 | index, | 242 | index, |
| 249 | acpi_ut_get_object_type_name | 243 | acpi_ut_get_object_type_name(obj_desc))); |
| 250 | (obj_desc))); | ||
| 251 | return_ACPI_STATUS(AE_BAD_DATA); | 244 | return_ACPI_STATUS(AE_BAD_DATA); |
| 252 | } | 245 | } |
| 253 | 246 | ||
| @@ -257,76 +250,83 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
| 257 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 250 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { |
| 258 | user_prt->pin = (u32) obj_desc->integer.value; | 251 | user_prt->pin = (u32) obj_desc->integer.value; |
| 259 | } else { | 252 | } else { |
| 260 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 253 | ACPI_ERROR((AE_INFO, |
| 261 | "(PRT[%X].Pin) Need Integer, found %s\n", | 254 | "(PRT[%X].Pin) Need Integer, found %s", |
| 262 | index, | 255 | index, |
| 263 | acpi_ut_get_object_type_name | 256 | acpi_ut_get_object_type_name(obj_desc))); |
| 264 | (obj_desc))); | ||
| 265 | return_ACPI_STATUS(AE_BAD_DATA); | 257 | return_ACPI_STATUS(AE_BAD_DATA); |
| 266 | } | 258 | } |
| 267 | 259 | ||
| 268 | /* 3) Third subobject: Dereference the PRT.source_name */ | 260 | /* |
| 269 | 261 | * 3) Third subobject: Dereference the PRT.source_name | |
| 262 | * The name may be unresolved (slack mode), so allow a null object | ||
| 263 | */ | ||
| 270 | obj_desc = sub_object_list[2]; | 264 | obj_desc = sub_object_list[2]; |
| 271 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 265 | if (obj_desc) { |
| 272 | case ACPI_TYPE_LOCAL_REFERENCE: | 266 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { |
| 273 | 267 | case ACPI_TYPE_LOCAL_REFERENCE: | |
| 274 | if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) { | 268 | |
| 275 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 269 | if (obj_desc->reference.opcode != |
| 276 | "(PRT[%X].Source) Need name, found reference op %X\n", | 270 | AML_INT_NAMEPATH_OP) { |
| 277 | index, | 271 | ACPI_ERROR((AE_INFO, |
| 278 | obj_desc->reference.opcode)); | 272 | "(PRT[%X].Source) Need name, found reference op %X", |
| 273 | index, | ||
| 274 | obj_desc->reference. | ||
| 275 | opcode)); | ||
| 276 | return_ACPI_STATUS(AE_BAD_DATA); | ||
| 277 | } | ||
| 278 | |||
| 279 | node = obj_desc->reference.node; | ||
| 280 | |||
| 281 | /* Use *remaining* length of the buffer as max for pathname */ | ||
| 282 | |||
| 283 | path_buffer.length = output_buffer->length - | ||
| 284 | (u32) ((u8 *) user_prt->source - | ||
| 285 | (u8 *) output_buffer->pointer); | ||
| 286 | path_buffer.pointer = user_prt->source; | ||
| 287 | |||
| 288 | status = | ||
| 289 | acpi_ns_handle_to_pathname((acpi_handle) | ||
| 290 | node, | ||
| 291 | &path_buffer); | ||
| 292 | |||
| 293 | /* +1 to include null terminator */ | ||
| 294 | |||
| 295 | user_prt->length += | ||
| 296 | (u32) ACPI_STRLEN(user_prt->source) + 1; | ||
| 297 | break; | ||
| 298 | |||
| 299 | case ACPI_TYPE_STRING: | ||
| 300 | |||
| 301 | ACPI_STRCPY(user_prt->source, | ||
| 302 | obj_desc->string.pointer); | ||
| 303 | |||
| 304 | /* | ||
| 305 | * Add to the Length field the length of the string | ||
| 306 | * (add 1 for terminator) | ||
| 307 | */ | ||
| 308 | user_prt->length += obj_desc->string.length + 1; | ||
| 309 | break; | ||
| 310 | |||
| 311 | case ACPI_TYPE_INTEGER: | ||
| 312 | /* | ||
| 313 | * If this is a number, then the Source Name is NULL, since the | ||
| 314 | * entire buffer was zeroed out, we can leave this alone. | ||
| 315 | * | ||
| 316 | * Add to the Length field the length of the u32 NULL | ||
| 317 | */ | ||
| 318 | user_prt->length += sizeof(u32); | ||
| 319 | break; | ||
| 320 | |||
| 321 | default: | ||
| 322 | |||
| 323 | ACPI_ERROR((AE_INFO, | ||
| 324 | "(PRT[%X].Source) Need Ref/String/Integer, found %s", | ||
| 325 | index, | ||
| 326 | acpi_ut_get_object_type_name | ||
| 327 | (obj_desc))); | ||
| 279 | return_ACPI_STATUS(AE_BAD_DATA); | 328 | return_ACPI_STATUS(AE_BAD_DATA); |
| 280 | } | 329 | } |
| 281 | |||
| 282 | node = obj_desc->reference.node; | ||
| 283 | |||
| 284 | /* Use *remaining* length of the buffer as max for pathname */ | ||
| 285 | |||
| 286 | path_buffer.length = output_buffer->length - | ||
| 287 | (u32) ((u8 *) user_prt->source - | ||
| 288 | (u8 *) output_buffer->pointer); | ||
| 289 | path_buffer.pointer = user_prt->source; | ||
| 290 | |||
| 291 | status = | ||
| 292 | acpi_ns_handle_to_pathname((acpi_handle) node, | ||
| 293 | &path_buffer); | ||
| 294 | |||
| 295 | /* +1 to include null terminator */ | ||
| 296 | |||
| 297 | user_prt->length += | ||
| 298 | (u32) ACPI_STRLEN(user_prt->source) + 1; | ||
| 299 | break; | ||
| 300 | |||
| 301 | case ACPI_TYPE_STRING: | ||
| 302 | |||
| 303 | ACPI_STRCPY(user_prt->source, obj_desc->string.pointer); | ||
| 304 | |||
| 305 | /* | ||
| 306 | * Add to the Length field the length of the string | ||
| 307 | * (add 1 for terminator) | ||
| 308 | */ | ||
| 309 | user_prt->length += obj_desc->string.length + 1; | ||
| 310 | break; | ||
| 311 | |||
| 312 | case ACPI_TYPE_INTEGER: | ||
| 313 | /* | ||
| 314 | * If this is a number, then the Source Name is NULL, since the | ||
| 315 | * entire buffer was zeroed out, we can leave this alone. | ||
| 316 | * | ||
| 317 | * Add to the Length field the length of the u32 NULL | ||
| 318 | */ | ||
| 319 | user_prt->length += sizeof(u32); | ||
| 320 | break; | ||
| 321 | |||
| 322 | default: | ||
| 323 | |||
| 324 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
| 325 | "(PRT[%X].Source) Need Ref/String/Integer, found %s\n", | ||
| 326 | index, | ||
| 327 | acpi_ut_get_object_type_name | ||
| 328 | (obj_desc))); | ||
| 329 | return_ACPI_STATUS(AE_BAD_DATA); | ||
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | /* Now align the current length */ | 332 | /* Now align the current length */ |
| @@ -340,11 +340,10 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
| 340 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 340 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { |
| 341 | user_prt->source_index = (u32) obj_desc->integer.value; | 341 | user_prt->source_index = (u32) obj_desc->integer.value; |
| 342 | } else { | 342 | } else { |
| 343 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 343 | ACPI_ERROR((AE_INFO, |
| 344 | "(PRT[%X].source_index) Need Integer, found %s\n", | 344 | "(PRT[%X].source_index) Need Integer, found %s", |
| 345 | index, | 345 | index, |
| 346 | acpi_ut_get_object_type_name | 346 | acpi_ut_get_object_type_name(obj_desc))); |
| 347 | (obj_desc))); | ||
| 348 | return_ACPI_STATUS(AE_BAD_DATA); | 347 | return_ACPI_STATUS(AE_BAD_DATA); |
| 349 | } | 348 | } |
| 350 | 349 | ||
| @@ -360,7 +359,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
| 360 | 359 | ||
| 361 | /******************************************************************************* | 360 | /******************************************************************************* |
| 362 | * | 361 | * |
| 363 | * FUNCTION: acpi_rs_create_byte_stream | 362 | * FUNCTION: acpi_rs_create_aml_resources |
| 364 | * | 363 | * |
| 365 | * PARAMETERS: linked_list_buffer - Pointer to the resource linked list | 364 | * PARAMETERS: linked_list_buffer - Pointer to the resource linked list |
| 366 | * output_buffer - Pointer to the user's buffer | 365 | * output_buffer - Pointer to the user's buffer |
| @@ -377,13 +376,13 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
| 377 | ******************************************************************************/ | 376 | ******************************************************************************/ |
| 378 | 377 | ||
| 379 | acpi_status | 378 | acpi_status |
| 380 | acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, | 379 | acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, |
| 381 | struct acpi_buffer *output_buffer) | 380 | struct acpi_buffer *output_buffer) |
| 382 | { | 381 | { |
| 383 | acpi_status status; | 382 | acpi_status status; |
| 384 | acpi_size byte_stream_size_needed = 0; | 383 | acpi_size aml_size_needed = 0; |
| 385 | 384 | ||
| 386 | ACPI_FUNCTION_TRACE("rs_create_byte_stream"); | 385 | ACPI_FUNCTION_TRACE("rs_create_aml_resources"); |
| 387 | 386 | ||
| 388 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "linked_list_buffer = %p\n", | 387 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "linked_list_buffer = %p\n", |
| 389 | linked_list_buffer)); | 388 | linked_list_buffer)); |
| @@ -394,11 +393,10 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, | |||
| 394 | * Pass the linked_list_buffer into a module that calculates | 393 | * Pass the linked_list_buffer into a module that calculates |
| 395 | * the buffer size needed for the byte stream. | 394 | * the buffer size needed for the byte stream. |
| 396 | */ | 395 | */ |
| 397 | status = acpi_rs_get_byte_stream_length(linked_list_buffer, | 396 | status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed); |
| 398 | &byte_stream_size_needed); | ||
| 399 | 397 | ||
| 400 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n", | 398 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_size_needed=%X, %s\n", |
| 401 | (u32) byte_stream_size_needed, | 399 | (u32) aml_size_needed, |
| 402 | acpi_format_exception(status))); | 400 | acpi_format_exception(status))); |
| 403 | if (ACPI_FAILURE(status)) { | 401 | if (ACPI_FAILURE(status)) { |
| 404 | return_ACPI_STATUS(status); | 402 | return_ACPI_STATUS(status); |
| @@ -406,8 +404,7 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, | |||
| 406 | 404 | ||
| 407 | /* Validate/Allocate/Clear caller buffer */ | 405 | /* Validate/Allocate/Clear caller buffer */ |
| 408 | 406 | ||
| 409 | status = | 407 | status = acpi_ut_initialize_buffer(output_buffer, aml_size_needed); |
| 410 | acpi_ut_initialize_buffer(output_buffer, byte_stream_size_needed); | ||
| 411 | if (ACPI_FAILURE(status)) { | 408 | if (ACPI_FAILURE(status)) { |
| 412 | return_ACPI_STATUS(status); | 409 | return_ACPI_STATUS(status); |
| 413 | } | 410 | } |
| @@ -415,9 +412,9 @@ acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer, | |||
| 415 | /* Do the conversion */ | 412 | /* Do the conversion */ |
| 416 | 413 | ||
| 417 | status = | 414 | status = |
| 418 | acpi_rs_list_to_byte_stream(linked_list_buffer, | 415 | acpi_rs_convert_resources_to_aml(linked_list_buffer, |
| 419 | byte_stream_size_needed, | 416 | aml_size_needed, |
| 420 | output_buffer->pointer); | 417 | output_buffer->pointer); |
| 421 | if (ACPI_FAILURE(status)) { | 418 | if (ACPI_FAILURE(status)) { |
| 422 | return_ACPI_STATUS(status); | 419 | return_ACPI_STATUS(status); |
| 423 | } | 420 | } |
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 75bd34d1783f..e7de061cf883 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -49,1063 +49,720 @@ ACPI_MODULE_NAME("rsdump") | |||
| 49 | 49 | ||
| 50 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | 50 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) |
| 51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
| 52 | static void acpi_rs_dump_irq(union acpi_resource_data *data); | 52 | static void acpi_rs_out_string(char *title, char *value); |
| 53 | 53 | ||
| 54 | static void acpi_rs_dump_address16(union acpi_resource_data *data); | 54 | static void acpi_rs_out_integer8(char *title, u8 value); |
| 55 | 55 | ||
| 56 | static void acpi_rs_dump_address32(union acpi_resource_data *data); | 56 | static void acpi_rs_out_integer16(char *title, u16 value); |
| 57 | 57 | ||
| 58 | static void acpi_rs_dump_address64(union acpi_resource_data *data); | 58 | static void acpi_rs_out_integer32(char *title, u32 value); |
| 59 | 59 | ||
| 60 | static void acpi_rs_dump_dma(union acpi_resource_data *data); | 60 | static void acpi_rs_out_integer64(char *title, u64 value); |
| 61 | 61 | ||
| 62 | static void acpi_rs_dump_io(union acpi_resource_data *data); | 62 | static void acpi_rs_out_title(char *title); |
| 63 | 63 | ||
| 64 | static void acpi_rs_dump_extended_irq(union acpi_resource_data *data); | 64 | static void acpi_rs_dump_byte_list(u16 length, u8 * data); |
| 65 | 65 | ||
| 66 | static void acpi_rs_dump_fixed_io(union acpi_resource_data *data); | 66 | static void acpi_rs_dump_dword_list(u8 length, u32 * data); |
| 67 | 67 | ||
| 68 | static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data); | 68 | static void acpi_rs_dump_short_byte_list(u8 length, u8 * data); |
| 69 | 69 | ||
| 70 | static void acpi_rs_dump_memory24(union acpi_resource_data *data); | 70 | static void |
| 71 | acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source); | ||
| 71 | 72 | ||
| 72 | static void acpi_rs_dump_memory32(union acpi_resource_data *data); | 73 | static void acpi_rs_dump_address_common(union acpi_resource_data *resource); |
| 73 | 74 | ||
| 74 | static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data); | 75 | static void |
| 76 | acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table); | ||
| 75 | 77 | ||
| 76 | static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data); | 78 | #define ACPI_RSD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_resource_data,f) |
| 79 | #define ACPI_PRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f) | ||
| 80 | #define ACPI_RSD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_rsdump_info)) | ||
| 77 | 81 | ||
| 78 | /******************************************************************************* | 82 | /******************************************************************************* |
| 79 | * | 83 | * |
| 80 | * FUNCTION: acpi_rs_dump_irq | 84 | * Resource Descriptor info tables |
| 81 | * | 85 | * |
| 82 | * PARAMETERS: Data - pointer to the resource structure to dump. | 86 | * Note: The first table entry must be a Title or Literal and must contain |
| 83 | * | 87 | * the table length (number of table entries) |
| 84 | * RETURN: None | ||
| 85 | * | ||
| 86 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
| 87 | * | 88 | * |
| 88 | ******************************************************************************/ | 89 | ******************************************************************************/ |
| 89 | 90 | ||
| 90 | static void acpi_rs_dump_irq(union acpi_resource_data *data) | 91 | struct acpi_rsdump_info acpi_rs_dump_irq[6] = { |
| 91 | { | 92 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, |
| 92 | struct acpi_resource_irq *irq_data = (struct acpi_resource_irq *)data; | 93 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", |
| 93 | u8 index = 0; | 94 | acpi_gbl_HEdecode}, |
| 94 | 95 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", | |
| 95 | ACPI_FUNCTION_ENTRY(); | 96 | acpi_gbl_LLdecode}, |
| 96 | 97 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing", | |
| 97 | acpi_os_printf("IRQ Resource\n"); | 98 | acpi_gbl_SHRdecode}, |
| 99 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count), | ||
| 100 | "Interrupt Count", NULL}, | ||
| 101 | {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]), | ||
| 102 | "Interrupt List", NULL} | ||
| 103 | }; | ||
| 104 | |||
| 105 | struct acpi_rsdump_info acpi_rs_dump_dma[6] = { | ||
| 106 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL}, | ||
| 107 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed", | ||
| 108 | acpi_gbl_TYPdecode}, | ||
| 109 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering", | ||
| 110 | acpi_gbl_BMdecode}, | ||
| 111 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type", | ||
| 112 | acpi_gbl_SIZdecode}, | ||
| 113 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count", | ||
| 114 | NULL}, | ||
| 115 | {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List", | ||
| 116 | NULL} | ||
| 117 | }; | ||
| 118 | |||
| 119 | struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = { | ||
| 120 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), | ||
| 121 | "Start-Dependent-Functions", NULL}, | ||
| 122 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), | ||
| 123 | "Compatibility Priority", acpi_gbl_config_decode}, | ||
| 124 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), | ||
| 125 | "Performance/Robustness", acpi_gbl_config_decode} | ||
| 126 | }; | ||
| 127 | |||
| 128 | struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = { | ||
| 129 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf), | ||
| 130 | "End-Dependent-Functions", NULL} | ||
| 131 | }; | ||
| 132 | |||
| 133 | struct acpi_rsdump_info acpi_rs_dump_io[6] = { | ||
| 134 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL}, | ||
| 135 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding", | ||
| 136 | acpi_gbl_io_decode}, | ||
| 137 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL}, | ||
| 138 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL}, | ||
| 139 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL}, | ||
| 140 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length", | ||
| 141 | NULL} | ||
| 142 | }; | ||
| 143 | |||
| 144 | struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = { | ||
| 145 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io), | ||
| 146 | "Fixed I/O", NULL}, | ||
| 147 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL}, | ||
| 148 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length), | ||
| 149 | "Address Length", NULL} | ||
| 150 | }; | ||
| 151 | |||
| 152 | struct acpi_rsdump_info acpi_rs_dump_vendor[3] = { | ||
| 153 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor), | ||
| 154 | "Vendor Specific", NULL}, | ||
| 155 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL}, | ||
| 156 | {ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data", | ||
| 157 | NULL} | ||
| 158 | }; | ||
| 159 | |||
| 160 | struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = { | ||
| 161 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "end_tag", | ||
| 162 | NULL} | ||
| 163 | }; | ||
| 164 | |||
| 165 | struct acpi_rsdump_info acpi_rs_dump_memory24[6] = { | ||
| 166 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24), | ||
| 167 | "24-Bit Memory Range", NULL}, | ||
| 168 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect), | ||
| 169 | "Write Protect", acpi_gbl_RWdecode}, | ||
| 170 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum", | ||
| 171 | NULL}, | ||
| 172 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum", | ||
| 173 | NULL}, | ||
| 174 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment", | ||
| 175 | NULL}, | ||
| 176 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length), | ||
| 177 | "Address Length", NULL} | ||
| 178 | }; | ||
| 179 | |||
| 180 | struct acpi_rsdump_info acpi_rs_dump_memory32[6] = { | ||
| 181 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32), | ||
| 182 | "32-Bit Memory Range", NULL}, | ||
| 183 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect), | ||
| 184 | "Write Protect", acpi_gbl_RWdecode}, | ||
| 185 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum", | ||
| 186 | NULL}, | ||
| 187 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum", | ||
| 188 | NULL}, | ||
| 189 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment", | ||
| 190 | NULL}, | ||
| 191 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length), | ||
| 192 | "Address Length", NULL} | ||
| 193 | }; | ||
| 194 | |||
| 195 | struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = { | ||
| 196 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32), | ||
| 197 | "32-Bit Fixed Memory Range", NULL}, | ||
| 198 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect), | ||
| 199 | "Write Protect", acpi_gbl_RWdecode}, | ||
| 200 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address", | ||
| 201 | NULL}, | ||
| 202 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length), | ||
| 203 | "Address Length", NULL} | ||
| 204 | }; | ||
| 205 | |||
| 206 | struct acpi_rsdump_info acpi_rs_dump_address16[8] = { | ||
| 207 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16), | ||
| 208 | "16-Bit WORD Address Space", NULL}, | ||
| 209 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, | ||
| 210 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity", | ||
| 211 | NULL}, | ||
| 212 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum", | ||
| 213 | NULL}, | ||
| 214 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum", | ||
| 215 | NULL}, | ||
| 216 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset), | ||
| 217 | "Translation Offset", NULL}, | ||
| 218 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length), | ||
| 219 | "Address Length", NULL}, | ||
| 220 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL} | ||
| 221 | }; | ||
| 222 | |||
| 223 | struct acpi_rsdump_info acpi_rs_dump_address32[8] = { | ||
| 224 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32), | ||
| 225 | "32-Bit DWORD Address Space", NULL}, | ||
| 226 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, | ||
| 227 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity", | ||
| 228 | NULL}, | ||
| 229 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum", | ||
| 230 | NULL}, | ||
| 231 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum", | ||
| 232 | NULL}, | ||
| 233 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset), | ||
| 234 | "Translation Offset", NULL}, | ||
| 235 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length), | ||
| 236 | "Address Length", NULL}, | ||
| 237 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL} | ||
| 238 | }; | ||
| 239 | |||
| 240 | struct acpi_rsdump_info acpi_rs_dump_address64[8] = { | ||
| 241 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64), | ||
| 242 | "64-Bit QWORD Address Space", NULL}, | ||
| 243 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, | ||
| 244 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity", | ||
| 245 | NULL}, | ||
| 246 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum", | ||
| 247 | NULL}, | ||
| 248 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum", | ||
| 249 | NULL}, | ||
| 250 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset), | ||
| 251 | "Translation Offset", NULL}, | ||
| 252 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length), | ||
| 253 | "Address Length", NULL}, | ||
| 254 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL} | ||
| 255 | }; | ||
| 256 | |||
| 257 | struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = { | ||
| 258 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64), | ||
| 259 | "64-Bit Extended Address Space", NULL}, | ||
| 260 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, | ||
| 261 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity), | ||
| 262 | "Granularity", NULL}, | ||
| 263 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum), | ||
| 264 | "Address Minimum", NULL}, | ||
| 265 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum), | ||
| 266 | "Address Maximum", NULL}, | ||
| 267 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset), | ||
| 268 | "Translation Offset", NULL}, | ||
| 269 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length), | ||
| 270 | "Address Length", NULL}, | ||
| 271 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific), | ||
| 272 | "Type-Specific Attribute", NULL} | ||
| 273 | }; | ||
| 274 | |||
| 275 | struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = { | ||
| 276 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq), | ||
| 277 | "Extended IRQ", NULL}, | ||
| 278 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer), | ||
| 279 | "Type", acpi_gbl_consume_decode}, | ||
| 280 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering), | ||
| 281 | "Triggering", acpi_gbl_HEdecode}, | ||
| 282 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity", | ||
| 283 | acpi_gbl_LLdecode}, | ||
| 284 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing", | ||
| 285 | acpi_gbl_SHRdecode}, | ||
| 286 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL, | ||
| 287 | NULL}, | ||
| 288 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count), | ||
| 289 | "Interrupt Count", NULL}, | ||
| 290 | {ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]), | ||
| 291 | "Interrupt List", NULL} | ||
| 292 | }; | ||
| 293 | |||
| 294 | struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = { | ||
| 295 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg), | ||
| 296 | "Generic Register", NULL}, | ||
| 297 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID", | ||
| 298 | NULL}, | ||
| 299 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width", | ||
| 300 | NULL}, | ||
| 301 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset", | ||
| 302 | NULL}, | ||
| 303 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size), | ||
| 304 | "Access Size", NULL}, | ||
| 305 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL} | ||
| 306 | }; | ||
| 98 | 307 | ||
| 99 | acpi_os_printf(" %s Triggered\n", | 308 | /* |
| 100 | ACPI_LEVEL_SENSITIVE == | 309 | * Tables used for common address descriptor flag fields |
| 101 | irq_data->edge_level ? "Level" : "Edge"); | 310 | */ |
| 102 | 311 | static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = { | |
| 103 | acpi_os_printf(" Active %s\n", | 312 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL, |
| 104 | ACPI_ACTIVE_LOW == | 313 | NULL}, |
| 105 | irq_data->active_high_low ? "Low" : "High"); | 314 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer), |
| 106 | 315 | "Consumer/Producer", acpi_gbl_consume_decode}, | |
| 107 | acpi_os_printf(" %s\n", | 316 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode", |
| 108 | ACPI_SHARED == | 317 | acpi_gbl_DECdecode}, |
| 109 | irq_data->shared_exclusive ? "Shared" : "Exclusive"); | 318 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed), |
| 110 | 319 | "Min Relocatability", acpi_gbl_min_decode}, | |
| 111 | acpi_os_printf(" %X Interrupts ( ", irq_data->number_of_interrupts); | 320 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed), |
| 112 | 321 | "Max Relocatability", acpi_gbl_max_decode} | |
| 113 | for (index = 0; index < irq_data->number_of_interrupts; index++) { | 322 | }; |
| 114 | acpi_os_printf("%X ", irq_data->interrupts[index]); | 323 | |
| 115 | } | 324 | static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = { |
| 325 | {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags), | ||
| 326 | "Resource Type", (void *)"Memory Range"}, | ||
| 327 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect), | ||
| 328 | "Write Protect", acpi_gbl_RWdecode}, | ||
| 329 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching), | ||
| 330 | "Caching", acpi_gbl_MEMdecode}, | ||
| 331 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type), | ||
| 332 | "Range Type", acpi_gbl_MTPdecode}, | ||
| 333 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation), | ||
| 334 | "Translation", acpi_gbl_TTPdecode} | ||
| 335 | }; | ||
| 336 | |||
| 337 | static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = { | ||
| 338 | {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags), | ||
| 339 | "Resource Type", (void *)"I/O Range"}, | ||
| 340 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type), | ||
| 341 | "Range Type", acpi_gbl_RNGdecode}, | ||
| 342 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation), | ||
| 343 | "Translation", acpi_gbl_TTPdecode}, | ||
| 344 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type), | ||
| 345 | "Translation Type", acpi_gbl_TRSdecode} | ||
| 346 | }; | ||
| 116 | 347 | ||
| 117 | acpi_os_printf(")\n"); | 348 | /* |
| 118 | return; | 349 | * Table used to dump _PRT contents |
| 119 | } | 350 | */ |
| 351 | static struct acpi_rsdump_info acpi_rs_dump_prt[5] = { | ||
| 352 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL}, | ||
| 353 | {ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL}, | ||
| 354 | {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL}, | ||
| 355 | {ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL}, | ||
| 356 | {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL} | ||
| 357 | }; | ||
| 120 | 358 | ||
| 121 | /******************************************************************************* | 359 | /******************************************************************************* |
| 122 | * | 360 | * |
| 123 | * FUNCTION: acpi_rs_dump_dma | 361 | * FUNCTION: acpi_rs_dump_descriptor |
| 124 | * | 362 | * |
| 125 | * PARAMETERS: Data - pointer to the resource structure to dump. | 363 | * PARAMETERS: Resource |
| 126 | * | 364 | * |
| 127 | * RETURN: None | 365 | * RETURN: None |
| 128 | * | 366 | * |
| 129 | * DESCRIPTION: Prints out the various members of the Data structure type. | 367 | * DESCRIPTION: |
| 130 | * | 368 | * |
| 131 | ******************************************************************************/ | 369 | ******************************************************************************/ |
| 132 | 370 | ||
| 133 | static void acpi_rs_dump_dma(union acpi_resource_data *data) | 371 | static void |
| 372 | acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) | ||
| 134 | { | 373 | { |
| 135 | struct acpi_resource_dma *dma_data = (struct acpi_resource_dma *)data; | 374 | u8 *target = NULL; |
| 136 | u8 index = 0; | 375 | u8 *previous_target; |
| 137 | 376 | char *name; | |
| 138 | ACPI_FUNCTION_ENTRY(); | 377 | u8 count; |
| 139 | 378 | ||
| 140 | acpi_os_printf("DMA Resource\n"); | 379 | /* First table entry must contain the table length (# of table entries) */ |
| 141 | 380 | ||
| 142 | switch (dma_data->type) { | 381 | count = table->offset; |
| 143 | case ACPI_COMPATIBILITY: | 382 | |
| 144 | acpi_os_printf(" Compatibility mode\n"); | 383 | while (count) { |
| 145 | break; | 384 | previous_target = target; |
| 146 | 385 | target = ACPI_ADD_PTR(u8, resource, table->offset); | |
| 147 | case ACPI_TYPE_A: | 386 | name = table->name; |
| 148 | acpi_os_printf(" Type A\n"); | 387 | |
| 149 | break; | 388 | switch (table->opcode) { |
| 150 | 389 | case ACPI_RSD_TITLE: | |
| 151 | case ACPI_TYPE_B: | 390 | /* |
| 152 | acpi_os_printf(" Type B\n"); | 391 | * Optional resource title |
| 153 | break; | 392 | */ |
| 154 | 393 | if (table->name) { | |
| 155 | case ACPI_TYPE_F: | 394 | acpi_os_printf("%s Resource\n", name); |
| 156 | acpi_os_printf(" Type F\n"); | 395 | } |
| 157 | break; | 396 | break; |
| 158 | |||
| 159 | default: | ||
| 160 | acpi_os_printf(" Invalid DMA type\n"); | ||
| 161 | break; | ||
| 162 | } | ||
| 163 | |||
| 164 | acpi_os_printf(" %sBus Master\n", | ||
| 165 | ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a "); | ||
| 166 | |||
| 167 | switch (dma_data->transfer) { | ||
| 168 | case ACPI_TRANSFER_8: | ||
| 169 | acpi_os_printf(" 8-bit only transfer\n"); | ||
| 170 | break; | ||
| 171 | 397 | ||
| 172 | case ACPI_TRANSFER_8_16: | 398 | /* Strings */ |
| 173 | acpi_os_printf(" 8 and 16-bit transfer\n"); | ||
| 174 | break; | ||
| 175 | 399 | ||
| 176 | case ACPI_TRANSFER_16: | 400 | case ACPI_RSD_LITERAL: |
| 177 | acpi_os_printf(" 16 bit only transfer\n"); | 401 | acpi_rs_out_string(name, |
| 178 | break; | 402 | ACPI_CAST_PTR(char, table->pointer)); |
| 403 | break; | ||
| 179 | 404 | ||
| 180 | default: | 405 | case ACPI_RSD_STRING: |
| 181 | acpi_os_printf(" Invalid transfer preference\n"); | 406 | acpi_rs_out_string(name, ACPI_CAST_PTR(char, target)); |
| 182 | break; | 407 | break; |
| 183 | } | ||
| 184 | 408 | ||
| 185 | acpi_os_printf(" Number of Channels: %X ( ", | 409 | /* Data items, 8/16/32/64 bit */ |
| 186 | dma_data->number_of_channels); | ||
| 187 | 410 | ||
| 188 | for (index = 0; index < dma_data->number_of_channels; index++) { | 411 | case ACPI_RSD_UINT8: |
| 189 | acpi_os_printf("%X ", dma_data->channels[index]); | 412 | acpi_rs_out_integer8(name, ACPI_GET8(target)); |
| 190 | } | 413 | break; |
| 191 | 414 | ||
| 192 | acpi_os_printf(")\n"); | 415 | case ACPI_RSD_UINT16: |
| 193 | return; | 416 | acpi_rs_out_integer16(name, ACPI_GET16(target)); |
| 194 | } | 417 | break; |
| 195 | 418 | ||
| 196 | /******************************************************************************* | 419 | case ACPI_RSD_UINT32: |
| 197 | * | 420 | acpi_rs_out_integer32(name, ACPI_GET32(target)); |
| 198 | * FUNCTION: acpi_rs_dump_start_depend_fns | 421 | break; |
| 199 | * | ||
| 200 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
| 201 | * | ||
| 202 | * RETURN: None | ||
| 203 | * | ||
| 204 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
| 205 | * | ||
| 206 | ******************************************************************************/ | ||
| 207 | 422 | ||
| 208 | static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data) | 423 | case ACPI_RSD_UINT64: |
| 209 | { | 424 | acpi_rs_out_integer64(name, ACPI_GET64(target)); |
| 210 | struct acpi_resource_start_dpf *sdf_data = | 425 | break; |
| 211 | (struct acpi_resource_start_dpf *)data; | ||
| 212 | 426 | ||
| 213 | ACPI_FUNCTION_ENTRY(); | 427 | /* Flags: 1-bit and 2-bit flags supported */ |
| 214 | 428 | ||
| 215 | acpi_os_printf("Start Dependent Functions Resource\n"); | 429 | case ACPI_RSD_1BITFLAG: |
| 430 | acpi_rs_out_string(name, ACPI_CAST_PTR(char, | ||
| 431 | table-> | ||
| 432 | pointer[*target & | ||
| 433 | 0x01])); | ||
| 434 | break; | ||
| 216 | 435 | ||
| 217 | switch (sdf_data->compatibility_priority) { | 436 | case ACPI_RSD_2BITFLAG: |
| 218 | case ACPI_GOOD_CONFIGURATION: | 437 | acpi_rs_out_string(name, ACPI_CAST_PTR(char, |
| 219 | acpi_os_printf(" Good configuration\n"); | 438 | table-> |
| 220 | break; | 439 | pointer[*target & |
| 440 | 0x03])); | ||
| 441 | break; | ||
| 221 | 442 | ||
| 222 | case ACPI_ACCEPTABLE_CONFIGURATION: | 443 | case ACPI_RSD_SHORTLIST: |
| 223 | acpi_os_printf(" Acceptable configuration\n"); | 444 | /* |
| 224 | break; | 445 | * Short byte list (single line output) for DMA and IRQ resources |
| 446 | * Note: The list length is obtained from the previous table entry | ||
| 447 | */ | ||
| 448 | if (previous_target) { | ||
| 449 | acpi_rs_out_title(name); | ||
| 450 | acpi_rs_dump_short_byte_list(*previous_target, | ||
| 451 | target); | ||
| 452 | } | ||
| 453 | break; | ||
| 225 | 454 | ||
| 226 | case ACPI_SUB_OPTIMAL_CONFIGURATION: | 455 | case ACPI_RSD_LONGLIST: |
| 227 | acpi_os_printf(" Sub-optimal configuration\n"); | 456 | /* |
| 228 | break; | 457 | * Long byte list for Vendor resource data |
| 458 | * Note: The list length is obtained from the previous table entry | ||
| 459 | */ | ||
| 460 | if (previous_target) { | ||
| 461 | acpi_rs_dump_byte_list(ACPI_GET16 | ||
| 462 | (previous_target), | ||
| 463 | target); | ||
| 464 | } | ||
| 465 | break; | ||
| 229 | 466 | ||
| 230 | default: | 467 | case ACPI_RSD_DWORDLIST: |
| 231 | acpi_os_printf(" Invalid compatibility priority\n"); | 468 | /* |
| 232 | break; | 469 | * Dword list for Extended Interrupt resources |
| 233 | } | 470 | * Note: The list length is obtained from the previous table entry |
| 471 | */ | ||
| 472 | if (previous_target) { | ||
| 473 | acpi_rs_dump_dword_list(*previous_target, | ||
| 474 | ACPI_CAST_PTR(u32, | ||
| 475 | target)); | ||
| 476 | } | ||
| 477 | break; | ||
| 234 | 478 | ||
| 235 | switch (sdf_data->performance_robustness) { | 479 | case ACPI_RSD_ADDRESS: |
| 236 | case ACPI_GOOD_CONFIGURATION: | 480 | /* |
| 237 | acpi_os_printf(" Good configuration\n"); | 481 | * Common flags for all Address resources |
| 238 | break; | 482 | */ |
| 483 | acpi_rs_dump_address_common(ACPI_CAST_PTR | ||
| 484 | (union acpi_resource_data, | ||
| 485 | target)); | ||
| 486 | break; | ||
| 239 | 487 | ||
| 240 | case ACPI_ACCEPTABLE_CONFIGURATION: | 488 | case ACPI_RSD_SOURCE: |
| 241 | acpi_os_printf(" Acceptable configuration\n"); | 489 | /* |
| 242 | break; | 490 | * Optional resource_source for Address resources |
| 491 | */ | ||
| 492 | acpi_rs_dump_resource_source(ACPI_CAST_PTR | ||
| 493 | (struct | ||
| 494 | acpi_resource_source, | ||
| 495 | target)); | ||
| 496 | break; | ||
| 243 | 497 | ||
| 244 | case ACPI_SUB_OPTIMAL_CONFIGURATION: | 498 | default: |
| 245 | acpi_os_printf(" Sub-optimal configuration\n"); | 499 | acpi_os_printf("**** Invalid table opcode [%X] ****\n", |
| 246 | break; | 500 | table->opcode); |
| 501 | return; | ||
| 502 | } | ||
| 247 | 503 | ||
| 248 | default: | 504 | table++; |
| 249 | acpi_os_printf(" Invalid performance robustness preference\n"); | 505 | count--; |
| 250 | break; | ||
| 251 | } | 506 | } |
| 252 | |||
| 253 | return; | ||
| 254 | } | ||
| 255 | |||
| 256 | /******************************************************************************* | ||
| 257 | * | ||
| 258 | * FUNCTION: acpi_rs_dump_io | ||
| 259 | * | ||
| 260 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
| 261 | * | ||
| 262 | * RETURN: None | ||
| 263 | * | ||
| 264 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
| 265 | * | ||
| 266 | ******************************************************************************/ | ||
| 267 | |||
| 268 | static void acpi_rs_dump_io(union acpi_resource_data *data) | ||
| 269 | { | ||
| 270 | struct acpi_resource_io *io_data = (struct acpi_resource_io *)data; | ||
| 271 | |||
| 272 | ACPI_FUNCTION_ENTRY(); | ||
| 273 | |||
| 274 | acpi_os_printf("Io Resource\n"); | ||
| 275 | |||
| 276 | acpi_os_printf(" %d bit decode\n", | ||
| 277 | ACPI_DECODE_16 == io_data->io_decode ? 16 : 10); | ||
| 278 | |||
| 279 | acpi_os_printf(" Range minimum base: %08X\n", | ||
| 280 | io_data->min_base_address); | ||
| 281 | |||
| 282 | acpi_os_printf(" Range maximum base: %08X\n", | ||
| 283 | io_data->max_base_address); | ||
| 284 | |||
| 285 | acpi_os_printf(" Alignment: %08X\n", io_data->alignment); | ||
| 286 | |||
| 287 | acpi_os_printf(" Range Length: %08X\n", io_data->range_length); | ||
| 288 | |||
| 289 | return; | ||
| 290 | } | ||
| 291 | |||
| 292 | /******************************************************************************* | ||
| 293 | * | ||
| 294 | * FUNCTION: acpi_rs_dump_fixed_io | ||
| 295 | * | ||
| 296 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
| 297 | * | ||
| 298 | * RETURN: None | ||
| 299 | * | ||
| 300 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
| 301 | * | ||
| 302 | ******************************************************************************/ | ||
| 303 | |||
| 304 | static void acpi_rs_dump_fixed_io(union acpi_resource_data *data) | ||
| 305 | { | ||
| 306 | struct acpi_resource_fixed_io *fixed_io_data = | ||
| 307 | (struct acpi_resource_fixed_io *)data; | ||
| 308 | |||
| 309 | ACPI_FUNCTION_ENTRY(); | ||
| 310 | |||
| 311 | acpi_os_printf("Fixed Io Resource\n"); | ||
| 312 | acpi_os_printf(" Range base address: %08X", | ||
| 313 | fixed_io_data->base_address); | ||
| 314 | |||
| 315 | acpi_os_printf(" Range length: %08X", fixed_io_data->range_length); | ||
| 316 | |||
| 317 | return; | ||
| 318 | } | 507 | } |
| 319 | 508 | ||
| 320 | /******************************************************************************* | 509 | /******************************************************************************* |
| 321 | * | 510 | * |
| 322 | * FUNCTION: acpi_rs_dump_vendor_specific | 511 | * FUNCTION: acpi_rs_dump_resource_source |
| 323 | * | 512 | * |
| 324 | * PARAMETERS: Data - pointer to the resource structure to dump. | 513 | * PARAMETERS: resource_source - Pointer to a Resource Source struct |
| 325 | * | 514 | * |
| 326 | * RETURN: None | 515 | * RETURN: None |
| 327 | * | 516 | * |
| 328 | * DESCRIPTION: Prints out the various members of the Data structure type. | 517 | * DESCRIPTION: Common routine for dumping the optional resource_source and the |
| 518 | * corresponding resource_source_index. | ||
| 329 | * | 519 | * |
| 330 | ******************************************************************************/ | 520 | ******************************************************************************/ |
| 331 | 521 | ||
| 332 | static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data) | 522 | static void |
| 523 | acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source) | ||
| 333 | { | 524 | { |
| 334 | struct acpi_resource_vendor *vendor_data = | ||
| 335 | (struct acpi_resource_vendor *)data; | ||
| 336 | u16 index = 0; | ||
| 337 | |||
| 338 | ACPI_FUNCTION_ENTRY(); | 525 | ACPI_FUNCTION_ENTRY(); |
| 339 | 526 | ||
| 340 | acpi_os_printf("Vendor Specific Resource\n"); | 527 | if (resource_source->index == 0xFF) { |
| 341 | 528 | return; | |
| 342 | acpi_os_printf(" Length: %08X\n", vendor_data->length); | ||
| 343 | |||
| 344 | for (index = 0; index < vendor_data->length; index++) { | ||
| 345 | acpi_os_printf(" Byte %X: %08X\n", | ||
| 346 | index, vendor_data->reserved[index]); | ||
| 347 | } | 529 | } |
| 348 | 530 | ||
| 349 | return; | 531 | acpi_rs_out_integer8("Resource Source Index", resource_source->index); |
| 350 | } | ||
| 351 | |||
| 352 | /******************************************************************************* | ||
| 353 | * | ||
| 354 | * FUNCTION: acpi_rs_dump_memory24 | ||
| 355 | * | ||
| 356 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
| 357 | * | ||
| 358 | * RETURN: None | ||
| 359 | * | ||
| 360 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
| 361 | * | ||
| 362 | ******************************************************************************/ | ||
| 363 | |||
| 364 | static void acpi_rs_dump_memory24(union acpi_resource_data *data) | ||
| 365 | { | ||
| 366 | struct acpi_resource_mem24 *memory24_data = | ||
| 367 | (struct acpi_resource_mem24 *)data; | ||
| 368 | |||
| 369 | ACPI_FUNCTION_ENTRY(); | ||
| 370 | |||
| 371 | acpi_os_printf("24-Bit Memory Range Resource\n"); | ||
| 372 | |||
| 373 | acpi_os_printf(" Read%s\n", | ||
| 374 | ACPI_READ_WRITE_MEMORY == | ||
| 375 | memory24_data->read_write_attribute ? | ||
| 376 | "/Write" : " only"); | ||
| 377 | |||
| 378 | acpi_os_printf(" Range minimum base: %08X\n", | ||
| 379 | memory24_data->min_base_address); | ||
| 380 | |||
| 381 | acpi_os_printf(" Range maximum base: %08X\n", | ||
| 382 | memory24_data->max_base_address); | ||
| 383 | |||
| 384 | acpi_os_printf(" Alignment: %08X\n", memory24_data->alignment); | ||
| 385 | |||
| 386 | acpi_os_printf(" Range length: %08X\n", memory24_data->range_length); | ||
| 387 | |||
| 388 | return; | ||
| 389 | } | ||
| 390 | |||
| 391 | /******************************************************************************* | ||
| 392 | * | ||
| 393 | * FUNCTION: acpi_rs_dump_memory32 | ||
| 394 | * | ||
| 395 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
| 396 | * | ||
| 397 | * RETURN: None | ||
| 398 | * | ||
| 399 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
| 400 | * | ||
| 401 | ******************************************************************************/ | ||
| 402 | |||
| 403 | static void acpi_rs_dump_memory32(union acpi_resource_data *data) | ||
| 404 | { | ||
| 405 | struct acpi_resource_mem32 *memory32_data = | ||
| 406 | (struct acpi_resource_mem32 *)data; | ||
| 407 | |||
| 408 | ACPI_FUNCTION_ENTRY(); | ||
| 409 | |||
| 410 | acpi_os_printf("32-Bit Memory Range Resource\n"); | ||
| 411 | |||
| 412 | acpi_os_printf(" Read%s\n", | ||
| 413 | ACPI_READ_WRITE_MEMORY == | ||
| 414 | memory32_data->read_write_attribute ? | ||
| 415 | "/Write" : " only"); | ||
| 416 | |||
| 417 | acpi_os_printf(" Range minimum base: %08X\n", | ||
| 418 | memory32_data->min_base_address); | ||
| 419 | |||
| 420 | acpi_os_printf(" Range maximum base: %08X\n", | ||
| 421 | memory32_data->max_base_address); | ||
| 422 | |||
| 423 | acpi_os_printf(" Alignment: %08X\n", memory32_data->alignment); | ||
| 424 | |||
| 425 | acpi_os_printf(" Range length: %08X\n", memory32_data->range_length); | ||
| 426 | 532 | ||
| 427 | return; | 533 | acpi_rs_out_string("Resource Source", |
| 534 | resource_source->string_ptr ? | ||
| 535 | resource_source->string_ptr : "[Not Specified]"); | ||
| 428 | } | 536 | } |
| 429 | 537 | ||
| 430 | /******************************************************************************* | 538 | /******************************************************************************* |
| 431 | * | 539 | * |
| 432 | * FUNCTION: acpi_rs_dump_fixed_memory32 | 540 | * FUNCTION: acpi_rs_dump_address_common |
| 433 | * | 541 | * |
| 434 | * PARAMETERS: Data - pointer to the resource structure to dump. | 542 | * PARAMETERS: Resource - Pointer to an internal resource descriptor |
| 435 | * | ||
| 436 | * RETURN: | ||
| 437 | * | ||
| 438 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
| 439 | * | ||
| 440 | ******************************************************************************/ | ||
| 441 | |||
| 442 | static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data) | ||
| 443 | { | ||
| 444 | struct acpi_resource_fixed_mem32 *fixed_memory32_data = | ||
| 445 | (struct acpi_resource_fixed_mem32 *)data; | ||
| 446 | |||
| 447 | ACPI_FUNCTION_ENTRY(); | ||
| 448 | |||
| 449 | acpi_os_printf("32-Bit Fixed Location Memory Range Resource\n"); | ||
| 450 | |||
| 451 | acpi_os_printf(" Read%s\n", | ||
| 452 | ACPI_READ_WRITE_MEMORY == | ||
| 453 | fixed_memory32_data-> | ||
| 454 | read_write_attribute ? "/Write" : " Only"); | ||
| 455 | |||
| 456 | acpi_os_printf(" Range base address: %08X\n", | ||
| 457 | fixed_memory32_data->range_base_address); | ||
| 458 | |||
| 459 | acpi_os_printf(" Range length: %08X\n", | ||
| 460 | fixed_memory32_data->range_length); | ||
| 461 | |||
| 462 | return; | ||
| 463 | } | ||
| 464 | |||
| 465 | /******************************************************************************* | ||
| 466 | * | ||
| 467 | * FUNCTION: acpi_rs_dump_address16 | ||
| 468 | * | ||
| 469 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
| 470 | * | 543 | * |
| 471 | * RETURN: None | 544 | * RETURN: None |
| 472 | * | 545 | * |
| 473 | * DESCRIPTION: Prints out the various members of the Data structure type. | 546 | * DESCRIPTION: Dump the fields that are common to all Address resource |
| 547 | * descriptors | ||
| 474 | * | 548 | * |
| 475 | ******************************************************************************/ | 549 | ******************************************************************************/ |
| 476 | 550 | ||
| 477 | static void acpi_rs_dump_address16(union acpi_resource_data *data) | 551 | static void acpi_rs_dump_address_common(union acpi_resource_data *resource) |
| 478 | { | 552 | { |
| 479 | struct acpi_resource_address16 *address16_data = | ||
| 480 | (struct acpi_resource_address16 *)data; | ||
| 481 | |||
| 482 | ACPI_FUNCTION_ENTRY(); | 553 | ACPI_FUNCTION_ENTRY(); |
| 483 | 554 | ||
| 484 | acpi_os_printf("16-Bit Address Space Resource\n"); | 555 | /* Decode the type-specific flags */ |
| 485 | acpi_os_printf(" Resource Type: "); | ||
| 486 | 556 | ||
| 487 | switch (address16_data->resource_type) { | 557 | switch (resource->address.resource_type) { |
| 488 | case ACPI_MEMORY_RANGE: | 558 | case ACPI_MEMORY_RANGE: |
| 489 | 559 | ||
| 490 | acpi_os_printf("Memory Range\n"); | 560 | acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags); |
| 491 | |||
| 492 | switch (address16_data->attribute.memory.cache_attribute) { | ||
| 493 | case ACPI_NON_CACHEABLE_MEMORY: | ||
| 494 | acpi_os_printf | ||
| 495 | (" Type Specific: Noncacheable memory\n"); | ||
| 496 | break; | ||
| 497 | |||
| 498 | case ACPI_CACHABLE_MEMORY: | ||
| 499 | acpi_os_printf(" Type Specific: Cacheable memory\n"); | ||
| 500 | break; | ||
| 501 | |||
| 502 | case ACPI_WRITE_COMBINING_MEMORY: | ||
| 503 | acpi_os_printf | ||
| 504 | (" Type Specific: Write-combining memory\n"); | ||
| 505 | break; | ||
| 506 | |||
| 507 | case ACPI_PREFETCHABLE_MEMORY: | ||
| 508 | acpi_os_printf | ||
| 509 | (" Type Specific: Prefetchable memory\n"); | ||
| 510 | break; | ||
| 511 | |||
| 512 | default: | ||
| 513 | acpi_os_printf | ||
| 514 | (" Type Specific: Invalid cache attribute\n"); | ||
| 515 | break; | ||
| 516 | } | ||
| 517 | |||
| 518 | acpi_os_printf(" Type Specific: Read%s\n", | ||
| 519 | ACPI_READ_WRITE_MEMORY == | ||
| 520 | address16_data->attribute.memory. | ||
| 521 | read_write_attribute ? "/Write" : " Only"); | ||
| 522 | break; | 561 | break; |
| 523 | 562 | ||
| 524 | case ACPI_IO_RANGE: | 563 | case ACPI_IO_RANGE: |
| 525 | 564 | ||
| 526 | acpi_os_printf("I/O Range\n"); | 565 | acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags); |
| 527 | |||
| 528 | switch (address16_data->attribute.io.range_attribute) { | ||
| 529 | case ACPI_NON_ISA_ONLY_RANGES: | ||
| 530 | acpi_os_printf | ||
| 531 | (" Type Specific: Non-ISA Io Addresses\n"); | ||
| 532 | break; | ||
| 533 | |||
| 534 | case ACPI_ISA_ONLY_RANGES: | ||
| 535 | acpi_os_printf(" Type Specific: ISA Io Addresses\n"); | ||
| 536 | break; | ||
| 537 | |||
| 538 | case ACPI_ENTIRE_RANGE: | ||
| 539 | acpi_os_printf | ||
| 540 | (" Type Specific: ISA and non-ISA Io Addresses\n"); | ||
| 541 | break; | ||
| 542 | |||
| 543 | default: | ||
| 544 | acpi_os_printf | ||
| 545 | (" Type Specific: Invalid range attribute\n"); | ||
| 546 | break; | ||
| 547 | } | ||
| 548 | |||
| 549 | acpi_os_printf(" Type Specific: %s Translation\n", | ||
| 550 | ACPI_SPARSE_TRANSLATION == | ||
| 551 | address16_data->attribute.io. | ||
| 552 | translation_attribute ? "Sparse" : "Dense"); | ||
| 553 | break; | 566 | break; |
| 554 | 567 | ||
| 555 | case ACPI_BUS_NUMBER_RANGE: | 568 | case ACPI_BUS_NUMBER_RANGE: |
| 556 | 569 | ||
| 557 | acpi_os_printf("Bus Number Range\n"); | 570 | acpi_rs_out_string("Resource Type", "Bus Number Range"); |
| 558 | break; | 571 | break; |
| 559 | 572 | ||
| 560 | default: | 573 | default: |
| 561 | 574 | ||
| 562 | acpi_os_printf("0x%2.2X\n", address16_data->resource_type); | 575 | acpi_rs_out_integer8("Resource Type", |
| 576 | (u8) resource->address.resource_type); | ||
| 563 | break; | 577 | break; |
| 564 | } | 578 | } |
| 565 | 579 | ||
| 566 | acpi_os_printf(" Resource %s\n", | 580 | /* Decode the general flags */ |
| 567 | ACPI_CONSUMER == address16_data->producer_consumer ? | ||
| 568 | "Consumer" : "Producer"); | ||
| 569 | |||
| 570 | acpi_os_printf(" %s decode\n", | ||
| 571 | ACPI_SUB_DECODE == address16_data->decode ? | ||
| 572 | "Subtractive" : "Positive"); | ||
| 573 | 581 | ||
| 574 | acpi_os_printf(" Min address is %s fixed\n", | 582 | acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags); |
| 575 | ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ? | ||
| 576 | "" : "not"); | ||
| 577 | |||
| 578 | acpi_os_printf(" Max address is %s fixed\n", | ||
| 579 | ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ? | ||
| 580 | "" : "not"); | ||
| 581 | |||
| 582 | acpi_os_printf(" Granularity: %08X\n", address16_data->granularity); | ||
| 583 | |||
| 584 | acpi_os_printf(" Address range min: %08X\n", | ||
| 585 | address16_data->min_address_range); | ||
| 586 | |||
| 587 | acpi_os_printf(" Address range max: %08X\n", | ||
| 588 | address16_data->max_address_range); | ||
| 589 | |||
| 590 | acpi_os_printf(" Address translation offset: %08X\n", | ||
| 591 | address16_data->address_translation_offset); | ||
| 592 | |||
| 593 | acpi_os_printf(" Address Length: %08X\n", | ||
| 594 | address16_data->address_length); | ||
| 595 | |||
| 596 | if (0xFF != address16_data->resource_source.index) { | ||
| 597 | acpi_os_printf(" Resource Source Index: %X\n", | ||
| 598 | address16_data->resource_source.index); | ||
| 599 | |||
| 600 | acpi_os_printf(" Resource Source: %s\n", | ||
| 601 | address16_data->resource_source.string_ptr); | ||
| 602 | } | ||
| 603 | |||
| 604 | return; | ||
| 605 | } | 583 | } |
| 606 | 584 | ||
| 607 | /******************************************************************************* | 585 | /******************************************************************************* |
| 608 | * | 586 | * |
| 609 | * FUNCTION: acpi_rs_dump_address32 | 587 | * FUNCTION: acpi_rs_dump_resource_list |
| 610 | * | 588 | * |
| 611 | * PARAMETERS: Data - pointer to the resource structure to dump. | 589 | * PARAMETERS: resource_list - Pointer to a resource descriptor list |
| 612 | * | 590 | * |
| 613 | * RETURN: None | 591 | * RETURN: None |
| 614 | * | 592 | * |
| 615 | * DESCRIPTION: Prints out the various members of the Data structure type. | 593 | * DESCRIPTION: Dispatches the structure to the correct dump routine. |
| 616 | * | 594 | * |
| 617 | ******************************************************************************/ | 595 | ******************************************************************************/ |
| 618 | 596 | ||
| 619 | static void acpi_rs_dump_address32(union acpi_resource_data *data) | 597 | void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) |
| 620 | { | 598 | { |
| 621 | struct acpi_resource_address32 *address32_data = | 599 | u32 count = 0; |
| 622 | (struct acpi_resource_address32 *)data; | 600 | u32 type; |
| 623 | 601 | ||
| 624 | ACPI_FUNCTION_ENTRY(); | 602 | ACPI_FUNCTION_ENTRY(); |
| 625 | 603 | ||
| 626 | acpi_os_printf("32-Bit Address Space Resource\n"); | 604 | if (!(acpi_dbg_level & ACPI_LV_RESOURCES) |
| 627 | 605 | || !(_COMPONENT & acpi_dbg_layer)) { | |
| 628 | switch (address32_data->resource_type) { | 606 | return; |
| 629 | case ACPI_MEMORY_RANGE: | 607 | } |
| 630 | |||
| 631 | acpi_os_printf(" Resource Type: Memory Range\n"); | ||
| 632 | |||
| 633 | switch (address32_data->attribute.memory.cache_attribute) { | ||
| 634 | case ACPI_NON_CACHEABLE_MEMORY: | ||
| 635 | acpi_os_printf | ||
| 636 | (" Type Specific: Noncacheable memory\n"); | ||
| 637 | break; | ||
| 638 | |||
| 639 | case ACPI_CACHABLE_MEMORY: | ||
| 640 | acpi_os_printf(" Type Specific: Cacheable memory\n"); | ||
| 641 | break; | ||
| 642 | |||
| 643 | case ACPI_WRITE_COMBINING_MEMORY: | ||
| 644 | acpi_os_printf | ||
| 645 | (" Type Specific: Write-combining memory\n"); | ||
| 646 | break; | ||
| 647 | |||
| 648 | case ACPI_PREFETCHABLE_MEMORY: | ||
| 649 | acpi_os_printf | ||
| 650 | (" Type Specific: Prefetchable memory\n"); | ||
| 651 | break; | ||
| 652 | |||
| 653 | default: | ||
| 654 | acpi_os_printf | ||
| 655 | (" Type Specific: Invalid cache attribute\n"); | ||
| 656 | break; | ||
| 657 | } | ||
| 658 | |||
| 659 | acpi_os_printf(" Type Specific: Read%s\n", | ||
| 660 | ACPI_READ_WRITE_MEMORY == | ||
| 661 | address32_data->attribute.memory. | ||
| 662 | read_write_attribute ? "/Write" : " Only"); | ||
| 663 | break; | ||
| 664 | |||
| 665 | case ACPI_IO_RANGE: | ||
| 666 | |||
| 667 | acpi_os_printf(" Resource Type: Io Range\n"); | ||
| 668 | 608 | ||
| 669 | switch (address32_data->attribute.io.range_attribute) { | 609 | /* Walk list and dump all resource descriptors (END_TAG terminates) */ |
| 670 | case ACPI_NON_ISA_ONLY_RANGES: | ||
| 671 | acpi_os_printf | ||
| 672 | (" Type Specific: Non-ISA Io Addresses\n"); | ||
| 673 | break; | ||
| 674 | 610 | ||
| 675 | case ACPI_ISA_ONLY_RANGES: | 611 | do { |
| 676 | acpi_os_printf(" Type Specific: ISA Io Addresses\n"); | 612 | acpi_os_printf("\n[%02X] ", count); |
| 677 | break; | 613 | count++; |
| 678 | 614 | ||
| 679 | case ACPI_ENTIRE_RANGE: | 615 | /* Validate Type before dispatch */ |
| 680 | acpi_os_printf | ||
| 681 | (" Type Specific: ISA and non-ISA Io Addresses\n"); | ||
| 682 | break; | ||
| 683 | 616 | ||
| 684 | default: | 617 | type = resource_list->type; |
| 618 | if (type > ACPI_RESOURCE_TYPE_MAX) { | ||
| 685 | acpi_os_printf | 619 | acpi_os_printf |
| 686 | (" Type Specific: Invalid Range attribute"); | 620 | ("Invalid descriptor type (%X) in resource list\n", |
| 687 | break; | 621 | resource_list->type); |
| 622 | return; | ||
| 688 | } | 623 | } |
| 689 | 624 | ||
| 690 | acpi_os_printf(" Type Specific: %s Translation\n", | 625 | /* Dump the resource descriptor */ |
| 691 | ACPI_SPARSE_TRANSLATION == | ||
| 692 | address32_data->attribute.io. | ||
| 693 | translation_attribute ? "Sparse" : "Dense"); | ||
| 694 | break; | ||
| 695 | |||
| 696 | case ACPI_BUS_NUMBER_RANGE: | ||
| 697 | |||
| 698 | acpi_os_printf(" Resource Type: Bus Number Range\n"); | ||
| 699 | break; | ||
| 700 | |||
| 701 | default: | ||
| 702 | |||
| 703 | acpi_os_printf(" Resource Type: 0x%2.2X\n", | ||
| 704 | address32_data->resource_type); | ||
| 705 | break; | ||
| 706 | } | ||
| 707 | |||
| 708 | acpi_os_printf(" Resource %s\n", | ||
| 709 | ACPI_CONSUMER == address32_data->producer_consumer ? | ||
| 710 | "Consumer" : "Producer"); | ||
| 711 | |||
| 712 | acpi_os_printf(" %s decode\n", | ||
| 713 | ACPI_SUB_DECODE == address32_data->decode ? | ||
| 714 | "Subtractive" : "Positive"); | ||
| 715 | |||
| 716 | acpi_os_printf(" Min address is %s fixed\n", | ||
| 717 | ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ? | ||
| 718 | "" : "not "); | ||
| 719 | |||
| 720 | acpi_os_printf(" Max address is %s fixed\n", | ||
| 721 | ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ? | ||
| 722 | "" : "not "); | ||
| 723 | 626 | ||
| 724 | acpi_os_printf(" Granularity: %08X\n", address32_data->granularity); | 627 | acpi_rs_dump_descriptor(&resource_list->data, |
| 628 | acpi_gbl_dump_resource_dispatch[type]); | ||
| 725 | 629 | ||
| 726 | acpi_os_printf(" Address range min: %08X\n", | 630 | /* Point to the next resource structure */ |
| 727 | address32_data->min_address_range); | ||
| 728 | 631 | ||
| 729 | acpi_os_printf(" Address range max: %08X\n", | 632 | resource_list = |
| 730 | address32_data->max_address_range); | 633 | ACPI_ADD_PTR(struct acpi_resource, resource_list, |
| 634 | resource_list->length); | ||
| 731 | 635 | ||
| 732 | acpi_os_printf(" Address translation offset: %08X\n", | 636 | /* Exit when END_TAG descriptor is reached */ |
| 733 | address32_data->address_translation_offset); | ||
| 734 | 637 | ||
| 735 | acpi_os_printf(" Address Length: %08X\n", | 638 | } while (type != ACPI_RESOURCE_TYPE_END_TAG); |
| 736 | address32_data->address_length); | ||
| 737 | |||
| 738 | if (0xFF != address32_data->resource_source.index) { | ||
| 739 | acpi_os_printf(" Resource Source Index: %X\n", | ||
| 740 | address32_data->resource_source.index); | ||
| 741 | |||
| 742 | acpi_os_printf(" Resource Source: %s\n", | ||
| 743 | address32_data->resource_source.string_ptr); | ||
| 744 | } | ||
| 745 | |||
| 746 | return; | ||
| 747 | } | 639 | } |
| 748 | 640 | ||
| 749 | /******************************************************************************* | 641 | /******************************************************************************* |
| 750 | * | 642 | * |
| 751 | * FUNCTION: acpi_rs_dump_address64 | 643 | * FUNCTION: acpi_rs_dump_irq_list |
| 752 | * | 644 | * |
| 753 | * PARAMETERS: Data - pointer to the resource structure to dump. | 645 | * PARAMETERS: route_table - Pointer to the routing table to dump. |
| 754 | * | 646 | * |
| 755 | * RETURN: None | 647 | * RETURN: None |
| 756 | * | 648 | * |
| 757 | * DESCRIPTION: Prints out the various members of the Data structure type. | 649 | * DESCRIPTION: Print IRQ routing table |
| 758 | * | 650 | * |
| 759 | ******************************************************************************/ | 651 | ******************************************************************************/ |
| 760 | 652 | ||
| 761 | static void acpi_rs_dump_address64(union acpi_resource_data *data) | 653 | void acpi_rs_dump_irq_list(u8 * route_table) |
| 762 | { | 654 | { |
| 763 | struct acpi_resource_address64 *address64_data = | 655 | struct acpi_pci_routing_table *prt_element; |
| 764 | (struct acpi_resource_address64 *)data; | 656 | u8 count; |
| 765 | 657 | ||
| 766 | ACPI_FUNCTION_ENTRY(); | 658 | ACPI_FUNCTION_ENTRY(); |
| 767 | 659 | ||
| 768 | acpi_os_printf("64-Bit Address Space Resource\n"); | 660 | if (!(acpi_dbg_level & ACPI_LV_RESOURCES) |
| 769 | 661 | || !(_COMPONENT & acpi_dbg_layer)) { | |
| 770 | switch (address64_data->resource_type) { | 662 | return; |
| 771 | case ACPI_MEMORY_RANGE: | ||
| 772 | |||
| 773 | acpi_os_printf(" Resource Type: Memory Range\n"); | ||
| 774 | |||
| 775 | switch (address64_data->attribute.memory.cache_attribute) { | ||
| 776 | case ACPI_NON_CACHEABLE_MEMORY: | ||
| 777 | acpi_os_printf | ||
| 778 | (" Type Specific: Noncacheable memory\n"); | ||
| 779 | break; | ||
| 780 | |||
| 781 | case ACPI_CACHABLE_MEMORY: | ||
| 782 | acpi_os_printf(" Type Specific: Cacheable memory\n"); | ||
| 783 | break; | ||
| 784 | |||
| 785 | case ACPI_WRITE_COMBINING_MEMORY: | ||
| 786 | acpi_os_printf | ||
| 787 | (" Type Specific: Write-combining memory\n"); | ||
| 788 | break; | ||
| 789 | |||
| 790 | case ACPI_PREFETCHABLE_MEMORY: | ||
| 791 | acpi_os_printf | ||
| 792 | (" Type Specific: Prefetchable memory\n"); | ||
| 793 | break; | ||
| 794 | |||
| 795 | default: | ||
| 796 | acpi_os_printf | ||
| 797 | (" Type Specific: Invalid cache attribute\n"); | ||
| 798 | break; | ||
| 799 | } | ||
| 800 | |||
| 801 | acpi_os_printf(" Type Specific: Read%s\n", | ||
| 802 | ACPI_READ_WRITE_MEMORY == | ||
| 803 | address64_data->attribute.memory. | ||
| 804 | read_write_attribute ? "/Write" : " Only"); | ||
| 805 | break; | ||
| 806 | |||
| 807 | case ACPI_IO_RANGE: | ||
| 808 | |||
| 809 | acpi_os_printf(" Resource Type: Io Range\n"); | ||
| 810 | |||
| 811 | switch (address64_data->attribute.io.range_attribute) { | ||
| 812 | case ACPI_NON_ISA_ONLY_RANGES: | ||
| 813 | acpi_os_printf | ||
| 814 | (" Type Specific: Non-ISA Io Addresses\n"); | ||
| 815 | break; | ||
| 816 | |||
| 817 | case ACPI_ISA_ONLY_RANGES: | ||
| 818 | acpi_os_printf(" Type Specific: ISA Io Addresses\n"); | ||
| 819 | break; | ||
| 820 | |||
| 821 | case ACPI_ENTIRE_RANGE: | ||
| 822 | acpi_os_printf | ||
| 823 | (" Type Specific: ISA and non-ISA Io Addresses\n"); | ||
| 824 | break; | ||
| 825 | |||
| 826 | default: | ||
| 827 | acpi_os_printf | ||
| 828 | (" Type Specific: Invalid Range attribute"); | ||
| 829 | break; | ||
| 830 | } | ||
| 831 | |||
| 832 | acpi_os_printf(" Type Specific: %s Translation\n", | ||
| 833 | ACPI_SPARSE_TRANSLATION == | ||
| 834 | address64_data->attribute.io. | ||
| 835 | translation_attribute ? "Sparse" : "Dense"); | ||
| 836 | break; | ||
| 837 | |||
| 838 | case ACPI_BUS_NUMBER_RANGE: | ||
| 839 | |||
| 840 | acpi_os_printf(" Resource Type: Bus Number Range\n"); | ||
| 841 | break; | ||
| 842 | |||
| 843 | default: | ||
| 844 | |||
| 845 | acpi_os_printf(" Resource Type: 0x%2.2X\n", | ||
| 846 | address64_data->resource_type); | ||
| 847 | break; | ||
| 848 | } | 663 | } |
| 849 | 664 | ||
| 850 | acpi_os_printf(" Resource %s\n", | 665 | prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table); |
| 851 | ACPI_CONSUMER == address64_data->producer_consumer ? | ||
| 852 | "Consumer" : "Producer"); | ||
| 853 | |||
| 854 | acpi_os_printf(" %s decode\n", | ||
| 855 | ACPI_SUB_DECODE == address64_data->decode ? | ||
| 856 | "Subtractive" : "Positive"); | ||
| 857 | |||
| 858 | acpi_os_printf(" Min address is %s fixed\n", | ||
| 859 | ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ? | ||
| 860 | "" : "not "); | ||
| 861 | |||
| 862 | acpi_os_printf(" Max address is %s fixed\n", | ||
| 863 | ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ? | ||
| 864 | "" : "not "); | ||
| 865 | 666 | ||
| 866 | acpi_os_printf(" Granularity: %8.8X%8.8X\n", | 667 | /* Dump all table elements, Exit on zero length element */ |
| 867 | ACPI_FORMAT_UINT64(address64_data->granularity)); | ||
| 868 | 668 | ||
| 869 | acpi_os_printf(" Address range min: %8.8X%8.8X\n", | 669 | for (count = 0; prt_element->length; count++) { |
| 870 | ACPI_FORMAT_UINT64(address64_data->min_address_range)); | 670 | acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n", |
| 671 | count); | ||
| 672 | acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt); | ||
| 871 | 673 | ||
| 872 | acpi_os_printf(" Address range max: %8.8X%8.8X\n", | 674 | prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table, |
| 873 | ACPI_FORMAT_UINT64(address64_data->max_address_range)); | 675 | prt_element, prt_element->length); |
| 874 | |||
| 875 | acpi_os_printf(" Address translation offset: %8.8X%8.8X\n", | ||
| 876 | ACPI_FORMAT_UINT64(address64_data-> | ||
| 877 | address_translation_offset)); | ||
| 878 | |||
| 879 | acpi_os_printf(" Address Length: %8.8X%8.8X\n", | ||
| 880 | ACPI_FORMAT_UINT64(address64_data->address_length)); | ||
| 881 | |||
| 882 | acpi_os_printf(" Type Specific Attributes: %8.8X%8.8X\n", | ||
| 883 | ACPI_FORMAT_UINT64(address64_data-> | ||
| 884 | type_specific_attributes)); | ||
| 885 | |||
| 886 | if (0xFF != address64_data->resource_source.index) { | ||
| 887 | acpi_os_printf(" Resource Source Index: %X\n", | ||
| 888 | address64_data->resource_source.index); | ||
| 889 | |||
| 890 | acpi_os_printf(" Resource Source: %s\n", | ||
| 891 | address64_data->resource_source.string_ptr); | ||
| 892 | } | 676 | } |
| 893 | |||
| 894 | return; | ||
| 895 | } | 677 | } |
| 896 | 678 | ||
| 897 | /******************************************************************************* | 679 | /******************************************************************************* |
| 898 | * | 680 | * |
| 899 | * FUNCTION: acpi_rs_dump_extended_irq | 681 | * FUNCTION: acpi_rs_out* |
| 900 | * | 682 | * |
| 901 | * PARAMETERS: Data - pointer to the resource structure to dump. | 683 | * PARAMETERS: Title - Name of the resource field |
| 684 | * Value - Value of the resource field | ||
| 902 | * | 685 | * |
| 903 | * RETURN: None | 686 | * RETURN: None |
| 904 | * | 687 | * |
| 905 | * DESCRIPTION: Prints out the various members of the Data structure type. | 688 | * DESCRIPTION: Miscellaneous helper functions to consistently format the |
| 689 | * output of the resource dump routines | ||
| 906 | * | 690 | * |
| 907 | ******************************************************************************/ | 691 | ******************************************************************************/ |
| 908 | 692 | ||
| 909 | static void acpi_rs_dump_extended_irq(union acpi_resource_data *data) | 693 | static void acpi_rs_out_string(char *title, char *value) |
| 910 | { | 694 | { |
| 911 | struct acpi_resource_ext_irq *ext_irq_data = | 695 | acpi_os_printf("%27s : %s", title, value); |
| 912 | (struct acpi_resource_ext_irq *)data; | 696 | if (!*value) { |
| 913 | u8 index = 0; | 697 | acpi_os_printf("[NULL NAMESTRING]"); |
| 914 | |||
| 915 | ACPI_FUNCTION_ENTRY(); | ||
| 916 | |||
| 917 | acpi_os_printf("Extended IRQ Resource\n"); | ||
| 918 | |||
| 919 | acpi_os_printf(" Resource %s\n", | ||
| 920 | ACPI_CONSUMER == ext_irq_data->producer_consumer ? | ||
| 921 | "Consumer" : "Producer"); | ||
| 922 | |||
| 923 | acpi_os_printf(" %s\n", | ||
| 924 | ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ? | ||
| 925 | "Level" : "Edge"); | ||
| 926 | |||
| 927 | acpi_os_printf(" Active %s\n", | ||
| 928 | ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ? | ||
| 929 | "low" : "high"); | ||
| 930 | |||
| 931 | acpi_os_printf(" %s\n", | ||
| 932 | ACPI_SHARED == ext_irq_data->shared_exclusive ? | ||
| 933 | "Shared" : "Exclusive"); | ||
| 934 | |||
| 935 | acpi_os_printf(" Interrupts : %X ( ", | ||
| 936 | ext_irq_data->number_of_interrupts); | ||
| 937 | |||
| 938 | for (index = 0; index < ext_irq_data->number_of_interrupts; index++) { | ||
| 939 | acpi_os_printf("%X ", ext_irq_data->interrupts[index]); | ||
| 940 | } | ||
| 941 | |||
| 942 | acpi_os_printf(")\n"); | ||
| 943 | |||
| 944 | if (0xFF != ext_irq_data->resource_source.index) { | ||
| 945 | acpi_os_printf(" Resource Source Index: %X", | ||
| 946 | ext_irq_data->resource_source.index); | ||
| 947 | |||
| 948 | acpi_os_printf(" Resource Source: %s", | ||
| 949 | ext_irq_data->resource_source.string_ptr); | ||
| 950 | } | 698 | } |
| 951 | 699 | acpi_os_printf("\n"); | |
| 952 | return; | ||
| 953 | } | 700 | } |
| 954 | 701 | ||
| 955 | /******************************************************************************* | 702 | static void acpi_rs_out_integer8(char *title, u8 value) |
| 956 | * | ||
| 957 | * FUNCTION: acpi_rs_dump_resource_list | ||
| 958 | * | ||
| 959 | * PARAMETERS: Resource - pointer to the resource structure to dump. | ||
| 960 | * | ||
| 961 | * RETURN: None | ||
| 962 | * | ||
| 963 | * DESCRIPTION: Dispatches the structure to the correct dump routine. | ||
| 964 | * | ||
| 965 | ******************************************************************************/ | ||
| 966 | |||
| 967 | void acpi_rs_dump_resource_list(struct acpi_resource *resource) | ||
| 968 | { | 703 | { |
| 969 | u8 count = 0; | 704 | acpi_os_printf("%27s : %2.2X\n", title, value); |
| 970 | u8 done = FALSE; | 705 | } |
| 971 | |||
| 972 | ACPI_FUNCTION_ENTRY(); | ||
| 973 | |||
| 974 | if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { | ||
| 975 | while (!done) { | ||
| 976 | acpi_os_printf("Resource structure %X.\n", count++); | ||
| 977 | |||
| 978 | switch (resource->id) { | ||
| 979 | case ACPI_RSTYPE_IRQ: | ||
| 980 | acpi_rs_dump_irq(&resource->data); | ||
| 981 | break; | ||
| 982 | |||
| 983 | case ACPI_RSTYPE_DMA: | ||
| 984 | acpi_rs_dump_dma(&resource->data); | ||
| 985 | break; | ||
| 986 | |||
| 987 | case ACPI_RSTYPE_START_DPF: | ||
| 988 | acpi_rs_dump_start_depend_fns(&resource->data); | ||
| 989 | break; | ||
| 990 | |||
| 991 | case ACPI_RSTYPE_END_DPF: | ||
| 992 | acpi_os_printf | ||
| 993 | ("end_dependent_functions Resource\n"); | ||
| 994 | /* acpi_rs_dump_end_dependent_functions (Resource->Data); */ | ||
| 995 | break; | ||
| 996 | |||
| 997 | case ACPI_RSTYPE_IO: | ||
| 998 | acpi_rs_dump_io(&resource->data); | ||
| 999 | break; | ||
| 1000 | |||
| 1001 | case ACPI_RSTYPE_FIXED_IO: | ||
| 1002 | acpi_rs_dump_fixed_io(&resource->data); | ||
| 1003 | break; | ||
| 1004 | |||
| 1005 | case ACPI_RSTYPE_VENDOR: | ||
| 1006 | acpi_rs_dump_vendor_specific(&resource->data); | ||
| 1007 | break; | ||
| 1008 | |||
| 1009 | case ACPI_RSTYPE_END_TAG: | ||
| 1010 | /*rs_dump_end_tag (Resource->Data); */ | ||
| 1011 | acpi_os_printf("end_tag Resource\n"); | ||
| 1012 | done = TRUE; | ||
| 1013 | break; | ||
| 1014 | |||
| 1015 | case ACPI_RSTYPE_MEM24: | ||
| 1016 | acpi_rs_dump_memory24(&resource->data); | ||
| 1017 | break; | ||
| 1018 | |||
| 1019 | case ACPI_RSTYPE_MEM32: | ||
| 1020 | acpi_rs_dump_memory32(&resource->data); | ||
| 1021 | break; | ||
| 1022 | |||
| 1023 | case ACPI_RSTYPE_FIXED_MEM32: | ||
| 1024 | acpi_rs_dump_fixed_memory32(&resource->data); | ||
| 1025 | break; | ||
| 1026 | |||
| 1027 | case ACPI_RSTYPE_ADDRESS16: | ||
| 1028 | acpi_rs_dump_address16(&resource->data); | ||
| 1029 | break; | ||
| 1030 | |||
| 1031 | case ACPI_RSTYPE_ADDRESS32: | ||
| 1032 | acpi_rs_dump_address32(&resource->data); | ||
| 1033 | break; | ||
| 1034 | |||
| 1035 | case ACPI_RSTYPE_ADDRESS64: | ||
| 1036 | acpi_rs_dump_address64(&resource->data); | ||
| 1037 | break; | ||
| 1038 | |||
| 1039 | case ACPI_RSTYPE_EXT_IRQ: | ||
| 1040 | acpi_rs_dump_extended_irq(&resource->data); | ||
| 1041 | break; | ||
| 1042 | 706 | ||
| 1043 | default: | 707 | static void acpi_rs_out_integer16(char *title, u16 value) |
| 1044 | acpi_os_printf("Invalid resource type\n"); | 708 | { |
| 1045 | break; | 709 | acpi_os_printf("%27s : %4.4X\n", title, value); |
| 710 | } | ||
| 1046 | 711 | ||
| 1047 | } | 712 | static void acpi_rs_out_integer32(char *title, u32 value) |
| 713 | { | ||
| 714 | acpi_os_printf("%27s : %8.8X\n", title, value); | ||
| 715 | } | ||
| 1048 | 716 | ||
| 1049 | resource = | 717 | static void acpi_rs_out_integer64(char *title, u64 value) |
| 1050 | ACPI_PTR_ADD(struct acpi_resource, resource, | 718 | { |
| 1051 | resource->length); | 719 | acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value)); |
| 1052 | } | 720 | } |
| 1053 | } | ||
| 1054 | 721 | ||
| 1055 | return; | 722 | static void acpi_rs_out_title(char *title) |
| 723 | { | ||
| 724 | acpi_os_printf("%27s : ", title); | ||
| 1056 | } | 725 | } |
| 1057 | 726 | ||
| 1058 | /******************************************************************************* | 727 | /******************************************************************************* |
| 1059 | * | 728 | * |
| 1060 | * FUNCTION: acpi_rs_dump_irq_list | 729 | * FUNCTION: acpi_rs_dump*List |
| 1061 | * | 730 | * |
| 1062 | * PARAMETERS: route_table - pointer to the routing table to dump. | 731 | * PARAMETERS: Length - Number of elements in the list |
| 732 | * Data - Start of the list | ||
| 1063 | * | 733 | * |
| 1064 | * RETURN: None | 734 | * RETURN: None |
| 1065 | * | 735 | * |
| 1066 | * DESCRIPTION: Dispatches the structures to the correct dump routine. | 736 | * DESCRIPTION: Miscellaneous functions to dump lists of raw data |
| 1067 | * | 737 | * |
| 1068 | ******************************************************************************/ | 738 | ******************************************************************************/ |
| 1069 | 739 | ||
| 1070 | void acpi_rs_dump_irq_list(u8 * route_table) | 740 | static void acpi_rs_dump_byte_list(u16 length, u8 * data) |
| 1071 | { | 741 | { |
| 1072 | u8 *buffer = route_table; | 742 | u8 i; |
| 1073 | u8 count = 0; | ||
| 1074 | u8 done = FALSE; | ||
| 1075 | struct acpi_pci_routing_table *prt_element; | ||
| 1076 | 743 | ||
| 1077 | ACPI_FUNCTION_ENTRY(); | 744 | for (i = 0; i < length; i++) { |
| 1078 | 745 | acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]); | |
| 1079 | if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { | 746 | } |
| 1080 | prt_element = | 747 | } |
| 1081 | ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); | ||
| 1082 | |||
| 1083 | while (!done) { | ||
| 1084 | acpi_os_printf("PCI IRQ Routing Table structure %X.\n", | ||
| 1085 | count++); | ||
| 1086 | |||
| 1087 | acpi_os_printf(" Address: %8.8X%8.8X\n", | ||
| 1088 | ACPI_FORMAT_UINT64(prt_element-> | ||
| 1089 | address)); | ||
| 1090 | 748 | ||
| 1091 | acpi_os_printf(" Pin: %X\n", prt_element->pin); | 749 | static void acpi_rs_dump_short_byte_list(u8 length, u8 * data) |
| 750 | { | ||
| 751 | u8 i; | ||
| 1092 | 752 | ||
| 1093 | acpi_os_printf(" Source: %s\n", prt_element->source); | 753 | for (i = 0; i < length; i++) { |
| 754 | acpi_os_printf("%X ", data[i]); | ||
| 755 | } | ||
| 756 | acpi_os_printf("\n"); | ||
| 757 | } | ||
| 1094 | 758 | ||
| 1095 | acpi_os_printf(" source_index: %X\n", | 759 | static void acpi_rs_dump_dword_list(u8 length, u32 * data) |
| 1096 | prt_element->source_index); | 760 | { |
| 761 | u8 i; | ||
| 1097 | 762 | ||
| 1098 | buffer += prt_element->length; | 763 | for (i = 0; i < length; i++) { |
| 1099 | prt_element = | 764 | acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]); |
| 1100 | ACPI_CAST_PTR(struct acpi_pci_routing_table, | ||
| 1101 | buffer); | ||
| 1102 | if (0 == prt_element->length) { | ||
| 1103 | done = TRUE; | ||
| 1104 | } | ||
| 1105 | } | ||
| 1106 | } | 765 | } |
| 1107 | |||
| 1108 | return; | ||
| 1109 | } | 766 | } |
| 1110 | 767 | ||
| 1111 | #endif | 768 | #endif |
diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c new file mode 100644 index 000000000000..d9ae64b77bd9 --- /dev/null +++ b/drivers/acpi/resources/rsinfo.c | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * | ||
| 3 | * Module Name: rsinfo - Dispatch and Info tables | ||
| 4 | * | ||
| 5 | ******************************************************************************/ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
| 9 | * All rights reserved. | ||
| 10 | * | ||
| 11 | * Redistribution and use in source and binary forms, with or without | ||
| 12 | * modification, are permitted provided that the following conditions | ||
| 13 | * are met: | ||
| 14 | * 1. Redistributions of source code must retain the above copyright | ||
| 15 | * notice, this list of conditions, and the following disclaimer, | ||
| 16 | * without modification. | ||
| 17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| 18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
| 19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
| 20 | * including a substantially similar Disclaimer requirement for further | ||
| 21 | * binary redistribution. | ||
| 22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
| 23 | * of any contributors may be used to endorse or promote products derived | ||
| 24 | * from this software without specific prior written permission. | ||
| 25 | * | ||
| 26 | * Alternatively, this software may be distributed under the terms of the | ||
| 27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
| 28 | * Software Foundation. | ||
| 29 | * | ||
| 30 | * NO WARRANTY | ||
| 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
| 34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| 40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 41 | * POSSIBILITY OF SUCH DAMAGES. | ||
| 42 | */ | ||
| 43 | |||
| 44 | #include <acpi/acpi.h> | ||
| 45 | #include <acpi/acresrc.h> | ||
| 46 | |||
| 47 | #define _COMPONENT ACPI_RESOURCES | ||
| 48 | ACPI_MODULE_NAME("rsinfo") | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Resource dispatch and information tables. Any new resource types (either | ||
| 52 | * Large or Small) must be reflected in each of these tables, so they are here | ||
| 53 | * in one place. | ||
| 54 | * | ||
| 55 | * The tables for Large descriptors are indexed by bits 6:0 of the AML | ||
| 56 | * descriptor type byte. The tables for Small descriptors are indexed by | ||
| 57 | * bits 6:3 of the descriptor byte. The tables for internal resource | ||
| 58 | * descriptors are indexed by the acpi_resource_type field. | ||
| 59 | */ | ||
| 60 | /* Dispatch table for resource-to-AML (Set Resource) conversion functions */ | ||
| 61 | struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[] = { | ||
| 62 | acpi_rs_set_irq, /* 0x00, ACPI_RESOURCE_TYPE_IRQ */ | ||
| 63 | acpi_rs_convert_dma, /* 0x01, ACPI_RESOURCE_TYPE_DMA */ | ||
| 64 | acpi_rs_set_start_dpf, /* 0x02, ACPI_RESOURCE_TYPE_START_DEPENDENT */ | ||
| 65 | acpi_rs_convert_end_dpf, /* 0x03, ACPI_RESOURCE_TYPE_END_DEPENDENT */ | ||
| 66 | acpi_rs_convert_io, /* 0x04, ACPI_RESOURCE_TYPE_IO */ | ||
| 67 | acpi_rs_convert_fixed_io, /* 0x05, ACPI_RESOURCE_TYPE_FIXED_IO */ | ||
| 68 | acpi_rs_set_vendor, /* 0x06, ACPI_RESOURCE_TYPE_VENDOR */ | ||
| 69 | acpi_rs_convert_end_tag, /* 0x07, ACPI_RESOURCE_TYPE_END_TAG */ | ||
| 70 | acpi_rs_convert_memory24, /* 0x08, ACPI_RESOURCE_TYPE_MEMORY24 */ | ||
| 71 | acpi_rs_convert_memory32, /* 0x09, ACPI_RESOURCE_TYPE_MEMORY32 */ | ||
| 72 | acpi_rs_convert_fixed_memory32, /* 0x0A, ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */ | ||
| 73 | acpi_rs_convert_address16, /* 0x0B, ACPI_RESOURCE_TYPE_ADDRESS16 */ | ||
| 74 | acpi_rs_convert_address32, /* 0x0C, ACPI_RESOURCE_TYPE_ADDRESS32 */ | ||
| 75 | acpi_rs_convert_address64, /* 0x0D, ACPI_RESOURCE_TYPE_ADDRESS64 */ | ||
| 76 | acpi_rs_convert_ext_address64, /* 0x0E, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ | ||
| 77 | acpi_rs_convert_ext_irq, /* 0x0F, ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ | ||
| 78 | acpi_rs_convert_generic_reg /* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ | ||
| 79 | }; | ||
| 80 | |||
| 81 | /* Dispatch tables for AML-to-resource (Get Resource) conversion functions */ | ||
| 82 | |||
| 83 | struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[] = { | ||
| 84 | /* Small descriptors */ | ||
| 85 | |||
| 86 | NULL, /* 0x00, Reserved */ | ||
| 87 | NULL, /* 0x01, Reserved */ | ||
| 88 | NULL, /* 0x02, Reserved */ | ||
| 89 | NULL, /* 0x03, Reserved */ | ||
| 90 | acpi_rs_get_irq, /* 0x04, ACPI_RESOURCE_NAME_IRQ */ | ||
| 91 | acpi_rs_convert_dma, /* 0x05, ACPI_RESOURCE_NAME_DMA */ | ||
| 92 | acpi_rs_get_start_dpf, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */ | ||
| 93 | acpi_rs_convert_end_dpf, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */ | ||
| 94 | acpi_rs_convert_io, /* 0x08, ACPI_RESOURCE_NAME_IO */ | ||
| 95 | acpi_rs_convert_fixed_io, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO */ | ||
| 96 | NULL, /* 0x0A, Reserved */ | ||
| 97 | NULL, /* 0x0B, Reserved */ | ||
| 98 | NULL, /* 0x0C, Reserved */ | ||
| 99 | NULL, /* 0x0D, Reserved */ | ||
| 100 | acpi_rs_get_vendor_small, /* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */ | ||
| 101 | acpi_rs_convert_end_tag, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */ | ||
| 102 | |||
| 103 | /* Large descriptors */ | ||
| 104 | |||
| 105 | NULL, /* 0x00, Reserved */ | ||
| 106 | acpi_rs_convert_memory24, /* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */ | ||
| 107 | acpi_rs_convert_generic_reg, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */ | ||
| 108 | NULL, /* 0x03, Reserved */ | ||
| 109 | acpi_rs_get_vendor_large, /* 0x04, ACPI_RESOURCE_NAME_VENDOR_LARGE */ | ||
| 110 | acpi_rs_convert_memory32, /* 0x05, ACPI_RESOURCE_NAME_MEMORY32 */ | ||
| 111 | acpi_rs_convert_fixed_memory32, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY32 */ | ||
| 112 | acpi_rs_convert_address32, /* 0x07, ACPI_RESOURCE_NAME_ADDRESS32 */ | ||
| 113 | acpi_rs_convert_address16, /* 0x08, ACPI_RESOURCE_NAME_ADDRESS16 */ | ||
| 114 | acpi_rs_convert_ext_irq, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_IRQ */ | ||
| 115 | acpi_rs_convert_address64, /* 0x0A, ACPI_RESOURCE_NAME_ADDRESS64 */ | ||
| 116 | acpi_rs_convert_ext_address64 /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */ | ||
| 117 | }; | ||
| 118 | |||
| 119 | #ifdef ACPI_FUTURE_USAGE | ||
| 120 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
| 121 | |||
| 122 | /* Dispatch table for resource dump functions */ | ||
| 123 | |||
| 124 | struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = { | ||
| 125 | acpi_rs_dump_irq, /* ACPI_RESOURCE_TYPE_IRQ */ | ||
| 126 | acpi_rs_dump_dma, /* ACPI_RESOURCE_TYPE_DMA */ | ||
| 127 | acpi_rs_dump_start_dpf, /* ACPI_RESOURCE_TYPE_START_DEPENDENT */ | ||
| 128 | acpi_rs_dump_end_dpf, /* ACPI_RESOURCE_TYPE_END_DEPENDENT */ | ||
| 129 | acpi_rs_dump_io, /* ACPI_RESOURCE_TYPE_IO */ | ||
| 130 | acpi_rs_dump_fixed_io, /* ACPI_RESOURCE_TYPE_FIXED_IO */ | ||
| 131 | acpi_rs_dump_vendor, /* ACPI_RESOURCE_TYPE_VENDOR */ | ||
| 132 | acpi_rs_dump_end_tag, /* ACPI_RESOURCE_TYPE_END_TAG */ | ||
| 133 | acpi_rs_dump_memory24, /* ACPI_RESOURCE_TYPE_MEMORY24 */ | ||
| 134 | acpi_rs_dump_memory32, /* ACPI_RESOURCE_TYPE_MEMORY32 */ | ||
| 135 | acpi_rs_dump_fixed_memory32, /* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */ | ||
| 136 | acpi_rs_dump_address16, /* ACPI_RESOURCE_TYPE_ADDRESS16 */ | ||
| 137 | acpi_rs_dump_address32, /* ACPI_RESOURCE_TYPE_ADDRESS32 */ | ||
| 138 | acpi_rs_dump_address64, /* ACPI_RESOURCE_TYPE_ADDRESS64 */ | ||
| 139 | acpi_rs_dump_ext_address64, /* ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ | ||
| 140 | acpi_rs_dump_ext_irq, /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ | ||
| 141 | acpi_rs_dump_generic_reg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ | ||
| 142 | }; | ||
| 143 | #endif | ||
| 144 | #endif /* ACPI_FUTURE_USAGE */ | ||
| 145 | /* | ||
| 146 | * Base sizes for external AML resource descriptors, indexed by internal type. | ||
| 147 | * Includes size of the descriptor header (1 byte for small descriptors, | ||
| 148 | * 3 bytes for large descriptors) | ||
| 149 | */ | ||
| 150 | const u8 acpi_gbl_aml_resource_sizes[] = { | ||
| 151 | sizeof(struct aml_resource_irq), /* ACPI_RESOURCE_TYPE_IRQ (optional Byte 3 always created) */ | ||
| 152 | sizeof(struct aml_resource_dma), /* ACPI_RESOURCE_TYPE_DMA */ | ||
| 153 | sizeof(struct aml_resource_start_dependent), /* ACPI_RESOURCE_TYPE_START_DEPENDENT (optional Byte 1 always created) */ | ||
| 154 | sizeof(struct aml_resource_end_dependent), /* ACPI_RESOURCE_TYPE_END_DEPENDENT */ | ||
| 155 | sizeof(struct aml_resource_io), /* ACPI_RESOURCE_TYPE_IO */ | ||
| 156 | sizeof(struct aml_resource_fixed_io), /* ACPI_RESOURCE_TYPE_FIXED_IO */ | ||
| 157 | sizeof(struct aml_resource_vendor_small), /* ACPI_RESOURCE_TYPE_VENDOR */ | ||
| 158 | sizeof(struct aml_resource_end_tag), /* ACPI_RESOURCE_TYPE_END_TAG */ | ||
| 159 | sizeof(struct aml_resource_memory24), /* ACPI_RESOURCE_TYPE_MEMORY24 */ | ||
| 160 | sizeof(struct aml_resource_memory32), /* ACPI_RESOURCE_TYPE_MEMORY32 */ | ||
| 161 | sizeof(struct aml_resource_fixed_memory32), /* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */ | ||
| 162 | sizeof(struct aml_resource_address16), /* ACPI_RESOURCE_TYPE_ADDRESS16 */ | ||
| 163 | sizeof(struct aml_resource_address32), /* ACPI_RESOURCE_TYPE_ADDRESS32 */ | ||
| 164 | sizeof(struct aml_resource_address64), /* ACPI_RESOURCE_TYPE_ADDRESS64 */ | ||
| 165 | sizeof(struct aml_resource_extended_address64), /*ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ | ||
| 166 | sizeof(struct aml_resource_extended_irq), /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ | ||
| 167 | sizeof(struct aml_resource_generic_register) /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ | ||
| 168 | }; | ||
| 169 | |||
| 170 | const u8 acpi_gbl_resource_struct_sizes[] = { | ||
| 171 | /* Small descriptors */ | ||
| 172 | |||
| 173 | 0, | ||
| 174 | 0, | ||
| 175 | 0, | ||
| 176 | 0, | ||
| 177 | ACPI_RS_SIZE(struct acpi_resource_irq), | ||
| 178 | ACPI_RS_SIZE(struct acpi_resource_dma), | ||
| 179 | ACPI_RS_SIZE(struct acpi_resource_start_dependent), | ||
| 180 | ACPI_RS_SIZE_MIN, | ||
| 181 | ACPI_RS_SIZE(struct acpi_resource_io), | ||
| 182 | ACPI_RS_SIZE(struct acpi_resource_fixed_io), | ||
| 183 | 0, | ||
| 184 | 0, | ||
| 185 | 0, | ||
| 186 | 0, | ||
| 187 | ACPI_RS_SIZE(struct acpi_resource_vendor), | ||
| 188 | ACPI_RS_SIZE_MIN, | ||
| 189 | |||
| 190 | /* Large descriptors */ | ||
| 191 | |||
| 192 | 0, | ||
| 193 | ACPI_RS_SIZE(struct acpi_resource_memory24), | ||
| 194 | ACPI_RS_SIZE(struct acpi_resource_generic_register), | ||
| 195 | 0, | ||
| 196 | ACPI_RS_SIZE(struct acpi_resource_vendor), | ||
| 197 | ACPI_RS_SIZE(struct acpi_resource_memory32), | ||
| 198 | ACPI_RS_SIZE(struct acpi_resource_fixed_memory32), | ||
| 199 | ACPI_RS_SIZE(struct acpi_resource_address32), | ||
| 200 | ACPI_RS_SIZE(struct acpi_resource_address16), | ||
| 201 | ACPI_RS_SIZE(struct acpi_resource_extended_irq), | ||
| 202 | ACPI_RS_SIZE(struct acpi_resource_address64), | ||
| 203 | ACPI_RS_SIZE(struct acpi_resource_extended_address64) | ||
| 204 | }; | ||
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index d53bbe89e851..ea567167c4f2 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -49,428 +49,206 @@ ACPI_MODULE_NAME("rsio") | |||
| 49 | 49 | ||
| 50 | /******************************************************************************* | 50 | /******************************************************************************* |
| 51 | * | 51 | * |
| 52 | * FUNCTION: acpi_rs_io_resource | 52 | * acpi_rs_convert_io |
| 53 | * | 53 | * |
| 54 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | 54 | ******************************************************************************/ |
| 55 | * stream | 55 | struct acpi_rsconvert_info acpi_rs_convert_io[5] = { |
| 56 | * bytes_consumed - Pointer to where the number of bytes | 56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IO, |
| 57 | * consumed the byte_stream_buffer is | 57 | ACPI_RS_SIZE(struct acpi_resource_io), |
| 58 | * returned | 58 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io)}, |
| 59 | * output_buffer - Pointer to the return data buffer | 59 | |
| 60 | * structure_size - Pointer to where the number of bytes | 60 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IO, |
| 61 | * in the return data struct is returned | 61 | sizeof(struct aml_resource_io), |
| 62 | * | 62 | 0}, |
| 63 | * RETURN: Status | 63 | |
| 64 | /* Decode flag */ | ||
| 65 | |||
| 66 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.io.io_decode), | ||
| 67 | AML_OFFSET(io.flags), | ||
| 68 | 0}, | ||
| 69 | /* | ||
| 70 | * These fields are contiguous in both the source and destination: | ||
| 71 | * Address Alignment | ||
| 72 | * Length | ||
| 73 | * Minimum Base Address | ||
| 74 | * Maximum Base Address | ||
| 75 | */ | ||
| 76 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.io.alignment), | ||
| 77 | AML_OFFSET(io.alignment), | ||
| 78 | 2}, | ||
| 79 | |||
| 80 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.io.minimum), | ||
| 81 | AML_OFFSET(io.minimum), | ||
| 82 | 2} | ||
| 83 | }; | ||
| 84 | |||
| 85 | /******************************************************************************* | ||
| 64 | * | 86 | * |
| 65 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | 87 | * acpi_rs_convert_fixed_io |
| 66 | * structure pointed to by the output_buffer. Return the | ||
| 67 | * number of bytes consumed from the byte stream. | ||
| 68 | * | 88 | * |
| 69 | ******************************************************************************/ | 89 | ******************************************************************************/ |
| 70 | acpi_status | ||
| 71 | acpi_rs_io_resource(u8 * byte_stream_buffer, | ||
| 72 | acpi_size * bytes_consumed, | ||
| 73 | u8 ** output_buffer, acpi_size * structure_size) | ||
| 74 | { | ||
| 75 | u8 *buffer = byte_stream_buffer; | ||
| 76 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 77 | u16 temp16 = 0; | ||
| 78 | u8 temp8 = 0; | ||
| 79 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); | ||
| 80 | |||
| 81 | ACPI_FUNCTION_TRACE("rs_io_resource"); | ||
| 82 | |||
| 83 | /* The number of bytes consumed are Constant */ | ||
| 84 | |||
| 85 | *bytes_consumed = 8; | ||
| 86 | |||
| 87 | output_struct->id = ACPI_RSTYPE_IO; | ||
| 88 | |||
| 89 | /* Check Decode */ | ||
| 90 | |||
| 91 | buffer += 1; | ||
| 92 | temp8 = *buffer; | ||
| 93 | |||
| 94 | output_struct->data.io.io_decode = temp8 & 0x01; | ||
| 95 | |||
| 96 | /* Check min_base Address */ | ||
| 97 | |||
| 98 | buffer += 1; | ||
| 99 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 100 | |||
| 101 | output_struct->data.io.min_base_address = temp16; | ||
| 102 | |||
| 103 | /* Check max_base Address */ | ||
| 104 | 90 | ||
| 105 | buffer += 2; | 91 | struct acpi_rsconvert_info acpi_rs_convert_fixed_io[4] = { |
| 106 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 92 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_IO, |
| 107 | 93 | ACPI_RS_SIZE(struct acpi_resource_fixed_io), | |
| 108 | output_struct->data.io.max_base_address = temp16; | 94 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_io)}, |
| 109 | 95 | ||
| 110 | /* Check Base alignment */ | 96 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_IO, |
| 111 | 97 | sizeof(struct aml_resource_fixed_io), | |
| 112 | buffer += 2; | 98 | 0}, |
| 113 | temp8 = *buffer; | 99 | /* |
| 114 | 100 | * These fields are contiguous in both the source and destination: | |
| 115 | output_struct->data.io.alignment = temp8; | 101 | * Base Address |
| 116 | 102 | * Length | |
| 117 | /* Check range_length */ | 103 | */ |
| 118 | 104 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_io.address_length), | |
| 119 | buffer += 1; | 105 | AML_OFFSET(fixed_io.address_length), |
| 120 | temp8 = *buffer; | 106 | 1}, |
| 121 | 107 | ||
| 122 | output_struct->data.io.range_length = temp8; | 108 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_io.address), |
| 123 | 109 | AML_OFFSET(fixed_io.address), | |
| 124 | /* Set the Length parameter */ | 110 | 1} |
| 125 | 111 | }; | |
| 126 | output_struct->length = (u32) struct_size; | ||
| 127 | |||
| 128 | /* Return the final size of the structure */ | ||
| 129 | |||
| 130 | *structure_size = struct_size; | ||
| 131 | return_ACPI_STATUS(AE_OK); | ||
| 132 | } | ||
| 133 | 112 | ||
| 134 | /******************************************************************************* | 113 | /******************************************************************************* |
| 135 | * | 114 | * |
| 136 | * FUNCTION: acpi_rs_fixed_io_resource | 115 | * acpi_rs_convert_generic_reg |
| 137 | * | ||
| 138 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 139 | * stream | ||
| 140 | * bytes_consumed - Pointer to where the number of bytes | ||
| 141 | * consumed the byte_stream_buffer is | ||
| 142 | * returned | ||
| 143 | * output_buffer - Pointer to the return data buffer | ||
| 144 | * structure_size - Pointer to where the number of bytes | ||
| 145 | * in the return data struct is returned | ||
| 146 | * | ||
| 147 | * RETURN: Status | ||
| 148 | * | ||
| 149 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 150 | * structure pointed to by the output_buffer. Return the | ||
| 151 | * number of bytes consumed from the byte stream. | ||
| 152 | * | 116 | * |
| 153 | ******************************************************************************/ | 117 | ******************************************************************************/ |
| 154 | 118 | ||
| 155 | acpi_status | 119 | struct acpi_rsconvert_info acpi_rs_convert_generic_reg[4] = { |
| 156 | acpi_rs_fixed_io_resource(u8 * byte_stream_buffer, | 120 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GENERIC_REGISTER, |
| 157 | acpi_size * bytes_consumed, | 121 | ACPI_RS_SIZE(struct acpi_resource_generic_register), |
| 158 | u8 ** output_buffer, acpi_size * structure_size) | 122 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_generic_reg)}, |
| 159 | { | 123 | |
| 160 | u8 *buffer = byte_stream_buffer; | 124 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GENERIC_REGISTER, |
| 161 | struct acpi_resource *output_struct = (void *)*output_buffer; | 125 | sizeof(struct aml_resource_generic_register), |
| 162 | u16 temp16 = 0; | 126 | 0}, |
| 163 | u8 temp8 = 0; | 127 | /* |
| 164 | acpi_size struct_size = | 128 | * These fields are contiguous in both the source and destination: |
| 165 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); | 129 | * Address Space ID |
| 166 | 130 | * Register Bit Width | |
| 167 | ACPI_FUNCTION_TRACE("rs_fixed_io_resource"); | 131 | * Register Bit Offset |
| 168 | 132 | * Access Size | |
| 169 | /* The number of bytes consumed are Constant */ | 133 | */ |
| 170 | 134 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.generic_reg.space_id), | |
| 171 | *bytes_consumed = 4; | 135 | AML_OFFSET(generic_reg.address_space_id), |
| 172 | 136 | 4}, | |
| 173 | output_struct->id = ACPI_RSTYPE_FIXED_IO; | 137 | |
| 174 | 138 | /* Get the Register Address */ | |
| 175 | /* Check Range Base Address */ | 139 | |
| 176 | 140 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.generic_reg.address), | |
| 177 | buffer += 1; | 141 | AML_OFFSET(generic_reg.address), |
| 178 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 142 | 1} |
| 179 | 143 | }; | |
| 180 | output_struct->data.fixed_io.base_address = temp16; | ||
| 181 | |||
| 182 | /* Check range_length */ | ||
| 183 | |||
| 184 | buffer += 2; | ||
| 185 | temp8 = *buffer; | ||
| 186 | |||
| 187 | output_struct->data.fixed_io.range_length = temp8; | ||
| 188 | |||
| 189 | /* Set the Length parameter */ | ||
| 190 | |||
| 191 | output_struct->length = (u32) struct_size; | ||
| 192 | |||
| 193 | /* Return the final size of the structure */ | ||
| 194 | |||
| 195 | *structure_size = struct_size; | ||
| 196 | return_ACPI_STATUS(AE_OK); | ||
| 197 | } | ||
| 198 | 144 | ||
| 199 | /******************************************************************************* | 145 | /******************************************************************************* |
| 200 | * | 146 | * |
| 201 | * FUNCTION: acpi_rs_io_stream | 147 | * acpi_rs_convert_end_dpf |
| 202 | * | ||
| 203 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 204 | * output_buffer - Pointer to the user's return buffer | ||
| 205 | * bytes_consumed - Pointer to where the number of bytes | ||
| 206 | * used in the output_buffer is returned | ||
| 207 | * | ||
| 208 | * RETURN: Status | ||
| 209 | * | ||
| 210 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 211 | * the appropriate bytes in a byte stream | ||
| 212 | * | 148 | * |
| 213 | ******************************************************************************/ | 149 | ******************************************************************************/ |
| 214 | 150 | ||
| 215 | acpi_status | 151 | struct acpi_rsconvert_info acpi_rs_convert_end_dpf[2] = { |
| 216 | acpi_rs_io_stream(struct acpi_resource *linked_list, | 152 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_DEPENDENT, |
| 217 | u8 ** output_buffer, acpi_size * bytes_consumed) | 153 | ACPI_RS_SIZE_MIN, |
| 218 | { | 154 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_dpf)}, |
| 219 | u8 *buffer = *output_buffer; | ||
| 220 | u16 temp16 = 0; | ||
| 221 | u8 temp8 = 0; | ||
| 222 | |||
| 223 | ACPI_FUNCTION_TRACE("rs_io_stream"); | ||
| 224 | |||
| 225 | /* The descriptor field is static */ | ||
| 226 | |||
| 227 | *buffer = 0x47; | ||
| 228 | buffer += 1; | ||
| 229 | |||
| 230 | /* Io Information Byte */ | ||
| 231 | |||
| 232 | temp8 = (u8) (linked_list->data.io.io_decode & 0x01); | ||
| 233 | |||
| 234 | *buffer = temp8; | ||
| 235 | buffer += 1; | ||
| 236 | |||
| 237 | /* Set the Range minimum base address */ | ||
| 238 | |||
| 239 | temp16 = (u16) linked_list->data.io.min_base_address; | ||
| 240 | |||
| 241 | ACPI_MOVE_16_TO_16(buffer, &temp16); | ||
| 242 | buffer += 2; | ||
| 243 | |||
| 244 | /* Set the Range maximum base address */ | ||
| 245 | |||
| 246 | temp16 = (u16) linked_list->data.io.max_base_address; | ||
| 247 | 155 | ||
| 248 | ACPI_MOVE_16_TO_16(buffer, &temp16); | 156 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_DEPENDENT, |
| 249 | buffer += 2; | 157 | sizeof(struct aml_resource_end_dependent), |
| 250 | 158 | 0} | |
| 251 | /* Set the base alignment */ | 159 | }; |
| 252 | |||
| 253 | temp8 = (u8) linked_list->data.io.alignment; | ||
| 254 | |||
| 255 | *buffer = temp8; | ||
| 256 | buffer += 1; | ||
| 257 | |||
| 258 | /* Set the range length */ | ||
| 259 | |||
| 260 | temp8 = (u8) linked_list->data.io.range_length; | ||
| 261 | |||
| 262 | *buffer = temp8; | ||
| 263 | buffer += 1; | ||
| 264 | |||
| 265 | /* Return the number of bytes consumed in this operation */ | ||
| 266 | |||
| 267 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 268 | return_ACPI_STATUS(AE_OK); | ||
| 269 | } | ||
| 270 | 160 | ||
| 271 | /******************************************************************************* | 161 | /******************************************************************************* |
| 272 | * | 162 | * |
| 273 | * FUNCTION: acpi_rs_fixed_io_stream | 163 | * acpi_rs_convert_end_tag |
| 274 | * | ||
| 275 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 276 | * output_buffer - Pointer to the user's return buffer | ||
| 277 | * bytes_consumed - Pointer to where the number of bytes | ||
| 278 | * used in the output_buffer is returned | ||
| 279 | * | ||
| 280 | * RETURN: Status | ||
| 281 | * | ||
| 282 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 283 | * the appropriate bytes in a byte stream | ||
| 284 | * | 164 | * |
| 285 | ******************************************************************************/ | 165 | ******************************************************************************/ |
| 286 | 166 | ||
| 287 | acpi_status | 167 | struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = { |
| 288 | acpi_rs_fixed_io_stream(struct acpi_resource *linked_list, | 168 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_TAG, |
| 289 | u8 ** output_buffer, acpi_size * bytes_consumed) | 169 | ACPI_RS_SIZE_MIN, |
| 290 | { | 170 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_tag)}, |
| 291 | u8 *buffer = *output_buffer; | 171 | |
| 292 | u16 temp16 = 0; | 172 | /* |
| 293 | u8 temp8 = 0; | 173 | * Note: The checksum field is set to zero, meaning that the resource |
| 294 | 174 | * data is treated as if the checksum operation succeeded. | |
| 295 | ACPI_FUNCTION_TRACE("rs_fixed_io_stream"); | 175 | * (ACPI Spec 1.0b Section 6.4.2.8) |
| 296 | 176 | */ | |
| 297 | /* The descriptor field is static */ | 177 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_TAG, |
| 298 | 178 | sizeof(struct aml_resource_end_tag), | |
| 299 | *buffer = 0x4B; | 179 | 0} |
| 300 | 180 | }; | |
| 301 | buffer += 1; | ||
| 302 | |||
| 303 | /* Set the Range base address */ | ||
| 304 | |||
| 305 | temp16 = (u16) linked_list->data.fixed_io.base_address; | ||
| 306 | |||
| 307 | ACPI_MOVE_16_TO_16(buffer, &temp16); | ||
| 308 | buffer += 2; | ||
| 309 | |||
| 310 | /* Set the range length */ | ||
| 311 | |||
| 312 | temp8 = (u8) linked_list->data.fixed_io.range_length; | ||
| 313 | |||
| 314 | *buffer = temp8; | ||
| 315 | buffer += 1; | ||
| 316 | |||
| 317 | /* Return the number of bytes consumed in this operation */ | ||
| 318 | |||
| 319 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 320 | return_ACPI_STATUS(AE_OK); | ||
| 321 | } | ||
| 322 | 181 | ||
| 323 | /******************************************************************************* | 182 | /******************************************************************************* |
| 324 | * | 183 | * |
| 325 | * FUNCTION: acpi_rs_dma_resource | 184 | * acpi_rs_get_start_dpf |
| 326 | * | ||
| 327 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 328 | * stream | ||
| 329 | * bytes_consumed - Pointer to where the number of bytes | ||
| 330 | * consumed the byte_stream_buffer is | ||
| 331 | * returned | ||
| 332 | * output_buffer - Pointer to the return data buffer | ||
| 333 | * structure_size - Pointer to where the number of bytes | ||
| 334 | * in the return data struct is returned | ||
| 335 | * | ||
| 336 | * RETURN: Status | ||
| 337 | * | ||
| 338 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 339 | * structure pointed to by the output_buffer. Return the | ||
| 340 | * number of bytes consumed from the byte stream. | ||
| 341 | * | 185 | * |
| 342 | ******************************************************************************/ | 186 | ******************************************************************************/ |
| 343 | 187 | ||
| 344 | acpi_status | 188 | struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { |
| 345 | acpi_rs_dma_resource(u8 * byte_stream_buffer, | 189 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, |
| 346 | acpi_size * bytes_consumed, | 190 | ACPI_RS_SIZE(struct acpi_resource_start_dependent), |
| 347 | u8 ** output_buffer, acpi_size * structure_size) | 191 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, |
| 348 | { | ||
| 349 | u8 *buffer = byte_stream_buffer; | ||
| 350 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 351 | u8 temp8 = 0; | ||
| 352 | u8 index; | ||
| 353 | u8 i; | ||
| 354 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma); | ||
| 355 | |||
| 356 | ACPI_FUNCTION_TRACE("rs_dma_resource"); | ||
| 357 | |||
| 358 | /* The number of bytes consumed are Constant */ | ||
| 359 | 192 | ||
| 360 | *bytes_consumed = 3; | 193 | /* Defaults for Compatibility and Performance priorities */ |
| 361 | output_struct->id = ACPI_RSTYPE_DMA; | ||
| 362 | 194 | ||
| 363 | /* Point to the 8-bits of Byte 1 */ | 195 | {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), |
| 196 | ACPI_ACCEPTABLE_CONFIGURATION, | ||
| 197 | 2}, | ||
| 364 | 198 | ||
| 365 | buffer += 1; | 199 | /* All done if there is no flag byte present in the descriptor */ |
| 366 | temp8 = *buffer; | ||
| 367 | 200 | ||
| 368 | /* Decode the DMA channel bits */ | 201 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, |
| 369 | 202 | ||
| 370 | for (i = 0, index = 0; index < 8; index++) { | 203 | /* Flag byte is present, get the flags */ |
| 371 | if ((temp8 >> index) & 0x01) { | ||
| 372 | output_struct->data.dma.channels[i] = index; | ||
| 373 | i++; | ||
| 374 | } | ||
| 375 | } | ||
| 376 | 204 | ||
| 377 | /* Zero DMA channels is valid */ | 205 | {ACPI_RSC_2BITFLAG, |
| 206 | ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), | ||
| 207 | AML_OFFSET(start_dpf.flags), | ||
| 208 | 0}, | ||
| 378 | 209 | ||
| 379 | output_struct->data.dma.number_of_channels = i; | 210 | {ACPI_RSC_2BITFLAG, |
| 380 | if (i > 0) { | 211 | ACPI_RS_OFFSET(data.start_dpf.performance_robustness), |
| 381 | /* Calculate the structure size based upon the number of interrupts */ | 212 | AML_OFFSET(start_dpf.flags), |
| 382 | 213 | 2} | |
| 383 | struct_size += ((acpi_size) i - 1) * 4; | 214 | }; |
| 384 | } | ||
| 385 | |||
| 386 | /* Point to Byte 2 */ | ||
| 387 | |||
| 388 | buffer += 1; | ||
| 389 | temp8 = *buffer; | ||
| 390 | |||
| 391 | /* Check for transfer preference (Bits[1:0]) */ | ||
| 392 | |||
| 393 | output_struct->data.dma.transfer = temp8 & 0x03; | ||
| 394 | |||
| 395 | if (0x03 == output_struct->data.dma.transfer) { | ||
| 396 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
| 397 | "Invalid DMA.Transfer preference (3)\n")); | ||
| 398 | return_ACPI_STATUS(AE_BAD_DATA); | ||
| 399 | } | ||
| 400 | |||
| 401 | /* Get bus master preference (Bit[2]) */ | ||
| 402 | |||
| 403 | output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01; | ||
| 404 | |||
| 405 | /* Get channel speed support (Bits[6:5]) */ | ||
| 406 | |||
| 407 | output_struct->data.dma.type = (temp8 >> 5) & 0x03; | ||
| 408 | |||
| 409 | /* Set the Length parameter */ | ||
| 410 | |||
| 411 | output_struct->length = (u32) struct_size; | ||
| 412 | |||
| 413 | /* Return the final size of the structure */ | ||
| 414 | |||
| 415 | *structure_size = struct_size; | ||
| 416 | return_ACPI_STATUS(AE_OK); | ||
| 417 | } | ||
| 418 | 215 | ||
| 419 | /******************************************************************************* | 216 | /******************************************************************************* |
| 420 | * | 217 | * |
| 421 | * FUNCTION: acpi_rs_dma_stream | 218 | * acpi_rs_set_start_dpf |
| 422 | * | ||
| 423 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 424 | * output_buffer - Pointer to the user's return buffer | ||
| 425 | * bytes_consumed - Pointer to where the number of bytes | ||
| 426 | * used in the output_buffer is returned | ||
| 427 | * | ||
| 428 | * RETURN: Status | ||
| 429 | * | ||
| 430 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 431 | * the appropriate bytes in a byte stream | ||
| 432 | * | 219 | * |
| 433 | ******************************************************************************/ | 220 | ******************************************************************************/ |
| 434 | 221 | ||
| 435 | acpi_status | 222 | struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { |
| 436 | acpi_rs_dma_stream(struct acpi_resource *linked_list, | 223 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, |
| 437 | u8 ** output_buffer, acpi_size * bytes_consumed) | 224 | sizeof(struct aml_resource_start_dependent), |
| 438 | { | 225 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, |
| 439 | u8 *buffer = *output_buffer; | 226 | |
| 440 | u16 temp16 = 0; | 227 | /* Set the default flag values */ |
| 441 | u8 temp8 = 0; | 228 | |
| 442 | u8 index; | 229 | {ACPI_RSC_2BITFLAG, |
| 443 | 230 | ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), | |
| 444 | ACPI_FUNCTION_TRACE("rs_dma_stream"); | 231 | AML_OFFSET(start_dpf.flags), |
| 445 | 232 | 0}, | |
| 446 | /* The descriptor field is static */ | 233 | |
| 447 | 234 | {ACPI_RSC_2BITFLAG, | |
| 448 | *buffer = 0x2A; | 235 | ACPI_RS_OFFSET(data.start_dpf.performance_robustness), |
| 449 | buffer += 1; | 236 | AML_OFFSET(start_dpf.flags), |
| 450 | temp8 = 0; | 237 | 2}, |
| 451 | 238 | /* | |
| 452 | /* Loop through all of the Channels and set the mask bits */ | 239 | * All done if flags byte is necessary -- if either priority value |
| 453 | 240 | * is not ACPI_ACCEPTABLE_CONFIGURATION | |
| 454 | for (index = 0; | 241 | */ |
| 455 | index < linked_list->data.dma.number_of_channels; index++) { | 242 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, |
| 456 | temp16 = (u16) linked_list->data.dma.channels[index]; | 243 | ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), |
| 457 | temp8 |= 0x1 << temp16; | 244 | ACPI_ACCEPTABLE_CONFIGURATION}, |
| 458 | } | 245 | |
| 459 | 246 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, | |
| 460 | *buffer = temp8; | 247 | ACPI_RS_OFFSET(data.start_dpf.performance_robustness), |
| 461 | buffer += 1; | 248 | ACPI_ACCEPTABLE_CONFIGURATION}, |
| 462 | 249 | ||
| 463 | /* Set the DMA Info */ | 250 | /* Flag byte is not necessary */ |
| 464 | 251 | ||
| 465 | temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5); | 252 | {ACPI_RSC_LENGTH, 0, 0, |
| 466 | temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2); | 253 | sizeof(struct aml_resource_start_dependent_noprio)} |
| 467 | temp8 |= (linked_list->data.dma.transfer & 0x03); | 254 | }; |
| 468 | |||
| 469 | *buffer = temp8; | ||
| 470 | buffer += 1; | ||
| 471 | |||
| 472 | /* Return the number of bytes consumed in this operation */ | ||
| 473 | |||
| 474 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 475 | return_ACPI_STATUS(AE_OK); | ||
| 476 | } | ||
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 56043fee96cb..1fa63bc2e36f 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -49,504 +49,182 @@ ACPI_MODULE_NAME("rsirq") | |||
| 49 | 49 | ||
| 50 | /******************************************************************************* | 50 | /******************************************************************************* |
| 51 | * | 51 | * |
| 52 | * FUNCTION: acpi_rs_irq_resource | 52 | * acpi_rs_get_irq |
| 53 | * | ||
| 54 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 55 | * stream | ||
| 56 | * bytes_consumed - Pointer to where the number of bytes | ||
| 57 | * consumed the byte_stream_buffer is | ||
| 58 | * returned | ||
| 59 | * output_buffer - Pointer to the return data buffer | ||
| 60 | * structure_size - Pointer to where the number of bytes | ||
| 61 | * in the return data struct is returned | ||
| 62 | * | ||
| 63 | * RETURN: Status | ||
| 64 | * | ||
| 65 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 66 | * structure pointed to by the output_buffer. Return the | ||
| 67 | * number of bytes consumed from the byte stream. | ||
| 68 | * | 53 | * |
| 69 | ******************************************************************************/ | 54 | ******************************************************************************/ |
| 70 | acpi_status | 55 | struct acpi_rsconvert_info acpi_rs_get_irq[7] = { |
| 71 | acpi_rs_irq_resource(u8 * byte_stream_buffer, | 56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, |
| 72 | acpi_size * bytes_consumed, | 57 | ACPI_RS_SIZE(struct acpi_resource_irq), |
| 73 | u8 ** output_buffer, acpi_size * structure_size) | 58 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, |
| 74 | { | ||
| 75 | u8 *buffer = byte_stream_buffer; | ||
| 76 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 77 | u16 temp16 = 0; | ||
| 78 | u8 temp8 = 0; | ||
| 79 | u8 index; | ||
| 80 | u8 i; | ||
| 81 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq); | ||
| 82 | |||
| 83 | ACPI_FUNCTION_TRACE("rs_irq_resource"); | ||
| 84 | |||
| 85 | /* | ||
| 86 | * The number of bytes consumed are contained in the descriptor | ||
| 87 | * (Bits:0-1) | ||
| 88 | */ | ||
| 89 | temp8 = *buffer; | ||
| 90 | *bytes_consumed = (temp8 & 0x03) + 1; | ||
| 91 | output_struct->id = ACPI_RSTYPE_IRQ; | ||
| 92 | |||
| 93 | /* Point to the 16-bits of Bytes 1 and 2 */ | ||
| 94 | |||
| 95 | buffer += 1; | ||
| 96 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 97 | |||
| 98 | output_struct->data.irq.number_of_interrupts = 0; | ||
| 99 | |||
| 100 | /* Decode the IRQ bits */ | ||
| 101 | |||
| 102 | for (i = 0, index = 0; index < 16; index++) { | ||
| 103 | if ((temp16 >> index) & 0x01) { | ||
| 104 | output_struct->data.irq.interrupts[i] = index; | ||
| 105 | i++; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | 59 | ||
| 109 | /* Zero interrupts is valid */ | 60 | /* Get the IRQ mask (bytes 1:2) */ |
| 110 | 61 | ||
| 111 | output_struct->data.irq.number_of_interrupts = i; | 62 | {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]), |
| 112 | if (i > 0) { | 63 | AML_OFFSET(irq.irq_mask), |
| 113 | /* Calculate the structure size based upon the number of interrupts */ | 64 | ACPI_RS_OFFSET(data.irq.interrupt_count)}, |
| 114 | 65 | ||
| 115 | struct_size += ((acpi_size) i - 1) * 4; | 66 | /* Set default flags (others are zero) */ |
| 116 | } | ||
| 117 | 67 | ||
| 118 | /* Point to Byte 3 if it is used */ | 68 | {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.irq.triggering), |
| 69 | ACPI_EDGE_SENSITIVE, | ||
| 70 | 1}, | ||
| 119 | 71 | ||
| 120 | if (4 == *bytes_consumed) { | 72 | /* All done if no flag byte present in descriptor */ |
| 121 | buffer += 2; | ||
| 122 | temp8 = *buffer; | ||
| 123 | 73 | ||
| 124 | /* Check for HE, LL interrupts */ | 74 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, |
| 125 | 75 | ||
| 126 | switch (temp8 & 0x09) { | 76 | /* Get flags: Triggering[0], Polarity[3], Sharing[4] */ |
| 127 | case 0x01: /* HE */ | ||
| 128 | output_struct->data.irq.edge_level = | ||
| 129 | ACPI_EDGE_SENSITIVE; | ||
| 130 | output_struct->data.irq.active_high_low = | ||
| 131 | ACPI_ACTIVE_HIGH; | ||
| 132 | break; | ||
| 133 | 77 | ||
| 134 | case 0x08: /* LL */ | 78 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), |
| 135 | output_struct->data.irq.edge_level = | 79 | AML_OFFSET(irq.flags), |
| 136 | ACPI_LEVEL_SENSITIVE; | 80 | 0}, |
| 137 | output_struct->data.irq.active_high_low = | ||
| 138 | ACPI_ACTIVE_LOW; | ||
| 139 | break; | ||
| 140 | 81 | ||
| 141 | default: | 82 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity), |
| 142 | /* | 83 | AML_OFFSET(irq.flags), |
| 143 | * Only _LL and _HE polarity/trigger interrupts | 84 | 3}, |
| 144 | * are allowed (ACPI spec, section "IRQ Format") | ||
| 145 | * so 0x00 and 0x09 are illegal. | ||
| 146 | */ | ||
| 147 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
| 148 | "Invalid interrupt polarity/trigger in resource list, %X\n", | ||
| 149 | temp8)); | ||
| 150 | return_ACPI_STATUS(AE_BAD_DATA); | ||
| 151 | } | ||
| 152 | 85 | ||
| 153 | /* Check for sharable */ | 86 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), |
| 154 | 87 | AML_OFFSET(irq.flags), | |
| 155 | output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01; | 88 | 4} |
| 156 | } else { | 89 | }; |
| 157 | /* | ||
| 158 | * Assume Edge Sensitive, Active High, Non-Sharable | ||
| 159 | * per ACPI Specification | ||
| 160 | */ | ||
| 161 | output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; | ||
| 162 | output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; | ||
| 163 | output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE; | ||
| 164 | } | ||
| 165 | |||
| 166 | /* Set the Length parameter */ | ||
| 167 | |||
| 168 | output_struct->length = (u32) struct_size; | ||
| 169 | |||
| 170 | /* Return the final size of the structure */ | ||
| 171 | |||
| 172 | *structure_size = struct_size; | ||
| 173 | return_ACPI_STATUS(AE_OK); | ||
| 174 | } | ||
| 175 | 90 | ||
| 176 | /******************************************************************************* | 91 | /******************************************************************************* |
| 177 | * | 92 | * |
| 178 | * FUNCTION: acpi_rs_irq_stream | 93 | * acpi_rs_set_irq |
| 179 | * | ||
| 180 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 181 | * output_buffer - Pointer to the user's return buffer | ||
| 182 | * bytes_consumed - Pointer to where the number of bytes | ||
| 183 | * used in the output_buffer is returned | ||
| 184 | * | ||
| 185 | * RETURN: Status | ||
| 186 | * | ||
| 187 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 188 | * the appropriate bytes in a byte stream | ||
| 189 | * | 94 | * |
| 190 | ******************************************************************************/ | 95 | ******************************************************************************/ |
| 191 | 96 | ||
| 192 | acpi_status | 97 | struct acpi_rsconvert_info acpi_rs_set_irq[9] = { |
| 193 | acpi_rs_irq_stream(struct acpi_resource *linked_list, | 98 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, |
| 194 | u8 ** output_buffer, acpi_size * bytes_consumed) | 99 | sizeof(struct aml_resource_irq), |
| 195 | { | 100 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, |
| 196 | u8 *buffer = *output_buffer; | ||
| 197 | u16 temp16 = 0; | ||
| 198 | u8 temp8 = 0; | ||
| 199 | u8 index; | ||
| 200 | u8 IRqinfo_byte_needed; | ||
| 201 | |||
| 202 | ACPI_FUNCTION_TRACE("rs_irq_stream"); | ||
| 203 | |||
| 204 | /* | ||
| 205 | * The descriptor field is set based upon whether a third byte is | ||
| 206 | * needed to contain the IRQ Information. | ||
| 207 | */ | ||
| 208 | if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level && | ||
| 209 | ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low && | ||
| 210 | ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) { | ||
| 211 | *buffer = 0x22; | ||
| 212 | IRqinfo_byte_needed = FALSE; | ||
| 213 | } else { | ||
| 214 | *buffer = 0x23; | ||
| 215 | IRqinfo_byte_needed = TRUE; | ||
| 216 | } | ||
| 217 | |||
| 218 | buffer += 1; | ||
| 219 | temp16 = 0; | ||
| 220 | |||
| 221 | /* Loop through all of the interrupts and set the mask bits */ | ||
| 222 | |||
| 223 | for (index = 0; | ||
| 224 | index < linked_list->data.irq.number_of_interrupts; index++) { | ||
| 225 | temp8 = (u8) linked_list->data.irq.interrupts[index]; | ||
| 226 | temp16 |= 0x1 << temp8; | ||
| 227 | } | ||
| 228 | |||
| 229 | ACPI_MOVE_16_TO_16(buffer, &temp16); | ||
| 230 | buffer += 2; | ||
| 231 | |||
| 232 | /* Set the IRQ Info byte if needed. */ | ||
| 233 | |||
| 234 | if (IRqinfo_byte_needed) { | ||
| 235 | temp8 = 0; | ||
| 236 | temp8 = (u8) ((linked_list->data.irq.shared_exclusive & | ||
| 237 | 0x01) << 4); | ||
| 238 | |||
| 239 | if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level && | ||
| 240 | ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) { | ||
| 241 | temp8 |= 0x08; | ||
| 242 | } else { | ||
| 243 | temp8 |= 0x01; | ||
| 244 | } | ||
| 245 | |||
| 246 | *buffer = temp8; | ||
| 247 | buffer += 1; | ||
| 248 | } | ||
| 249 | |||
| 250 | /* Return the number of bytes consumed in this operation */ | ||
| 251 | |||
| 252 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 253 | return_ACPI_STATUS(AE_OK); | ||
| 254 | } | ||
| 255 | |||
| 256 | /******************************************************************************* | ||
| 257 | * | ||
| 258 | * FUNCTION: acpi_rs_extended_irq_resource | ||
| 259 | * | ||
| 260 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 261 | * stream | ||
| 262 | * bytes_consumed - Pointer to where the number of bytes | ||
| 263 | * consumed the byte_stream_buffer is | ||
| 264 | * returned | ||
| 265 | * output_buffer - Pointer to the return data buffer | ||
| 266 | * structure_size - Pointer to where the number of bytes | ||
| 267 | * in the return data struct is returned | ||
| 268 | * | ||
| 269 | * RETURN: Status | ||
| 270 | * | ||
| 271 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 272 | * structure pointed to by the output_buffer. Return the | ||
| 273 | * number of bytes consumed from the byte stream. | ||
| 274 | * | ||
| 275 | ******************************************************************************/ | ||
| 276 | |||
| 277 | acpi_status | ||
| 278 | acpi_rs_extended_irq_resource(u8 * byte_stream_buffer, | ||
| 279 | acpi_size * bytes_consumed, | ||
| 280 | u8 ** output_buffer, acpi_size * structure_size) | ||
| 281 | { | ||
| 282 | u8 *buffer = byte_stream_buffer; | ||
| 283 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 284 | u16 temp16 = 0; | ||
| 285 | u8 temp8 = 0; | ||
| 286 | u8 *temp_ptr; | ||
| 287 | u8 index; | ||
| 288 | acpi_size struct_size = | ||
| 289 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq); | ||
| 290 | |||
| 291 | ACPI_FUNCTION_TRACE("rs_extended_irq_resource"); | ||
| 292 | |||
| 293 | /* Get the Descriptor Length field */ | ||
| 294 | |||
| 295 | buffer += 1; | ||
| 296 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 297 | |||
| 298 | /* Validate minimum descriptor length */ | ||
| 299 | |||
| 300 | if (temp16 < 6) { | ||
| 301 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
| 302 | } | ||
| 303 | |||
| 304 | *bytes_consumed = temp16 + 3; | ||
| 305 | output_struct->id = ACPI_RSTYPE_EXT_IRQ; | ||
| 306 | |||
| 307 | /* Point to the Byte3 */ | ||
| 308 | |||
| 309 | buffer += 2; | ||
| 310 | temp8 = *buffer; | ||
| 311 | |||
| 312 | output_struct->data.extended_irq.producer_consumer = temp8 & 0x01; | ||
| 313 | 101 | ||
| 314 | /* | 102 | /* Convert interrupt list to 16-bit IRQ bitmask */ |
| 315 | * Check for Interrupt Mode | ||
| 316 | * | ||
| 317 | * The definition of an Extended IRQ changed between ACPI spec v1.0b | ||
| 318 | * and ACPI spec 2.0 (section 6.4.3.6 in both). | ||
| 319 | * | ||
| 320 | * - Edge/Level are defined opposite in the table vs the headers | ||
| 321 | */ | ||
| 322 | output_struct->data.extended_irq.edge_level = | ||
| 323 | (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; | ||
| 324 | |||
| 325 | /* Check Interrupt Polarity */ | ||
| 326 | |||
| 327 | output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1; | ||
| 328 | |||
| 329 | /* Check for sharable */ | ||
| 330 | |||
| 331 | output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01; | ||
| 332 | 103 | ||
| 333 | /* Point to Byte4 (IRQ Table length) */ | 104 | {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]), |
| 105 | AML_OFFSET(irq.irq_mask), | ||
| 106 | ACPI_RS_OFFSET(data.irq.interrupt_count)}, | ||
| 334 | 107 | ||
| 335 | buffer += 1; | 108 | /* Set the flags byte by default */ |
| 336 | temp8 = *buffer; | ||
| 337 | 109 | ||
| 338 | /* Must have at least one IRQ */ | 110 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), |
| 111 | AML_OFFSET(irq.flags), | ||
| 112 | 0}, | ||
| 339 | 113 | ||
| 340 | if (temp8 < 1) { | 114 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity), |
| 341 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | 115 | AML_OFFSET(irq.flags), |
| 342 | } | 116 | 3}, |
| 343 | |||
| 344 | output_struct->data.extended_irq.number_of_interrupts = temp8; | ||
| 345 | 117 | ||
| 118 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), | ||
| 119 | AML_OFFSET(irq.flags), | ||
| 120 | 4}, | ||
| 346 | /* | 121 | /* |
| 347 | * Add any additional structure size to properly calculate | 122 | * Check if the flags byte is necessary. Not needed if the flags are: |
| 348 | * the next pointer at the end of this function | 123 | * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE |
| 349 | */ | 124 | */ |
| 350 | struct_size += (temp8 - 1) * 4; | 125 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, |
| 351 | 126 | ACPI_RS_OFFSET(data.irq.triggering), | |
| 352 | /* Point to Byte5 (First IRQ Number) */ | 127 | ACPI_EDGE_SENSITIVE}, |
| 353 | |||
| 354 | buffer += 1; | ||
| 355 | |||
| 356 | /* Cycle through every IRQ in the table */ | ||
| 357 | |||
| 358 | for (index = 0; index < temp8; index++) { | ||
| 359 | ACPI_MOVE_32_TO_32(&output_struct->data.extended_irq. | ||
| 360 | interrupts[index], buffer); | ||
| 361 | |||
| 362 | /* Point to the next IRQ */ | ||
| 363 | |||
| 364 | buffer += 4; | ||
| 365 | } | ||
| 366 | |||
| 367 | /* | ||
| 368 | * This will leave us pointing to the Resource Source Index | ||
| 369 | * If it is present, then save it off and calculate the | ||
| 370 | * pointer to where the null terminated string goes: | ||
| 371 | * Each Interrupt takes 32-bits + the 5 bytes of the | ||
| 372 | * stream that are default. | ||
| 373 | * | ||
| 374 | * Note: Some resource descriptors will have an additional null, so | ||
| 375 | * we add 1 to the length. | ||
| 376 | */ | ||
| 377 | if (*bytes_consumed > | ||
| 378 | ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * | ||
| 379 | 4) + (5 + 1)) { | ||
| 380 | /* Dereference the Index */ | ||
| 381 | |||
| 382 | temp8 = *buffer; | ||
| 383 | output_struct->data.extended_irq.resource_source.index = | ||
| 384 | (u32) temp8; | ||
| 385 | |||
| 386 | /* Point to the String */ | ||
| 387 | |||
| 388 | buffer += 1; | ||
| 389 | |||
| 390 | /* Point the String pointer to the end of this structure. */ | ||
| 391 | |||
| 392 | output_struct->data.extended_irq.resource_source.string_ptr = | ||
| 393 | (char *)((char *)output_struct + struct_size); | ||
| 394 | 128 | ||
| 395 | temp_ptr = (u8 *) | 129 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, |
| 396 | output_struct->data.extended_irq.resource_source.string_ptr; | 130 | ACPI_RS_OFFSET(data.irq.polarity), |
| 131 | ACPI_ACTIVE_HIGH}, | ||
| 397 | 132 | ||
| 398 | /* Copy the string into the buffer */ | 133 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, |
| 134 | ACPI_RS_OFFSET(data.irq.sharable), | ||
| 135 | ACPI_EXCLUSIVE}, | ||
| 399 | 136 | ||
| 400 | index = 0; | 137 | /* irq_no_flags() descriptor can be used */ |
| 401 | while (*buffer) { | ||
| 402 | *temp_ptr = *buffer; | ||
| 403 | 138 | ||
| 404 | temp_ptr += 1; | 139 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} |
| 405 | buffer += 1; | 140 | }; |
| 406 | index += 1; | ||
| 407 | } | ||
| 408 | |||
| 409 | /* Add the terminating null */ | ||
| 410 | |||
| 411 | *temp_ptr = 0; | ||
| 412 | output_struct->data.extended_irq.resource_source.string_length = | ||
| 413 | index + 1; | ||
| 414 | |||
| 415 | /* | ||
| 416 | * In order for the struct_size to fall on a 32-bit boundary, | ||
| 417 | * calculate the length of the string and expand the | ||
| 418 | * struct_size to the next 32-bit boundary. | ||
| 419 | */ | ||
| 420 | temp8 = (u8) (index + 1); | ||
| 421 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
| 422 | } else { | ||
| 423 | output_struct->data.extended_irq.resource_source.index = 0; | ||
| 424 | output_struct->data.extended_irq.resource_source.string_length = | ||
| 425 | 0; | ||
| 426 | output_struct->data.extended_irq.resource_source.string_ptr = | ||
| 427 | NULL; | ||
| 428 | } | ||
| 429 | |||
| 430 | /* Set the Length parameter */ | ||
| 431 | |||
| 432 | output_struct->length = (u32) struct_size; | ||
| 433 | |||
| 434 | /* Return the final size of the structure */ | ||
| 435 | |||
| 436 | *structure_size = struct_size; | ||
| 437 | return_ACPI_STATUS(AE_OK); | ||
| 438 | } | ||
| 439 | 141 | ||
| 440 | /******************************************************************************* | 142 | /******************************************************************************* |
| 441 | * | 143 | * |
| 442 | * FUNCTION: acpi_rs_extended_irq_stream | 144 | * acpi_rs_convert_ext_irq |
| 443 | * | ||
| 444 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 445 | * output_buffer - Pointer to the user's return buffer | ||
| 446 | * bytes_consumed - Pointer to where the number of bytes | ||
| 447 | * used in the output_buffer is returned | ||
| 448 | * | ||
| 449 | * RETURN: Status | ||
| 450 | * | ||
| 451 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 452 | * the appropriate bytes in a byte stream | ||
| 453 | * | 145 | * |
| 454 | ******************************************************************************/ | 146 | ******************************************************************************/ |
| 455 | 147 | ||
| 456 | acpi_status | 148 | struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = { |
| 457 | acpi_rs_extended_irq_stream(struct acpi_resource *linked_list, | 149 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ, |
| 458 | u8 ** output_buffer, acpi_size * bytes_consumed) | 150 | ACPI_RS_SIZE(struct acpi_resource_extended_irq), |
| 459 | { | 151 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)}, |
| 460 | u8 *buffer = *output_buffer; | ||
| 461 | u16 *length_field; | ||
| 462 | u8 temp8 = 0; | ||
| 463 | u8 index; | ||
| 464 | 152 | ||
| 465 | ACPI_FUNCTION_TRACE("rs_extended_irq_stream"); | 153 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ, |
| 154 | sizeof(struct aml_resource_extended_irq), | ||
| 155 | 0}, | ||
| 466 | 156 | ||
| 467 | /* Set the Descriptor Type field */ | 157 | /* Flag bits */ |
| 468 | 158 | ||
| 469 | *buffer = ACPI_RDESC_TYPE_EXTENDED_XRUPT; | 159 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer), |
| 470 | buffer += 1; | 160 | AML_OFFSET(extended_irq.flags), |
| 161 | 0}, | ||
| 471 | 162 | ||
| 472 | /* Save a pointer to the Length field - to be filled in later */ | 163 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.triggering), |
| 164 | AML_OFFSET(extended_irq.flags), | ||
| 165 | 1}, | ||
| 473 | 166 | ||
| 474 | length_field = ACPI_CAST_PTR(u16, buffer); | 167 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.polarity), |
| 475 | buffer += 2; | 168 | AML_OFFSET(extended_irq.flags), |
| 169 | 2}, | ||
| 476 | 170 | ||
| 477 | /* Set the Interrupt vector flags */ | 171 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.sharable), |
| 172 | AML_OFFSET(extended_irq.flags), | ||
| 173 | 3}, | ||
| 478 | 174 | ||
| 479 | temp8 = (u8) (linked_list->data.extended_irq.producer_consumer & 0x01); | 175 | /* IRQ Table length (Byte4) */ |
| 480 | temp8 |= | ||
| 481 | ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3); | ||
| 482 | 176 | ||
| 483 | /* | 177 | {ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count), |
| 484 | * Set the Interrupt Mode | 178 | AML_OFFSET(extended_irq.interrupt_count), |
| 485 | * | 179 | sizeof(u32)} |
| 486 | * The definition of an Extended IRQ changed between ACPI spec v1.0b | 180 | , |
| 487 | * and ACPI spec 2.0 (section 6.4.3.6 in both). This code does not | ||
| 488 | * implement the more restrictive definition of 1.0b | ||
| 489 | * | ||
| 490 | * - Edge/Level are defined opposite in the table vs the headers | ||
| 491 | */ | ||
| 492 | if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) { | ||
| 493 | temp8 |= 0x2; | ||
| 494 | } | ||
| 495 | |||
| 496 | /* Set the Interrupt Polarity */ | ||
| 497 | 181 | ||
| 498 | temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2); | 182 | /* Copy every IRQ in the table, each is 32 bits */ |
| 499 | 183 | ||
| 500 | *buffer = temp8; | 184 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]), |
| 501 | buffer += 1; | 185 | AML_OFFSET(extended_irq.interrupts[0]), |
| 186 | 0} | ||
| 187 | , | ||
| 502 | 188 | ||
| 503 | /* Set the Interrupt table length */ | 189 | /* Optional resource_source (Index and String) */ |
| 504 | 190 | ||
| 505 | temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts; | 191 | {ACPI_RSC_SOURCEX, ACPI_RS_OFFSET(data.extended_irq.resource_source), |
| 192 | ACPI_RS_OFFSET(data.extended_irq.interrupts[0]), | ||
| 193 | sizeof(struct aml_resource_extended_irq)} | ||
| 194 | }; | ||
| 506 | 195 | ||
| 507 | *buffer = temp8; | 196 | /******************************************************************************* |
| 508 | buffer += 1; | 197 | * |
| 509 | 198 | * acpi_rs_convert_dma | |
| 510 | for (index = 0; | 199 | * |
| 511 | index < linked_list->data.extended_irq.number_of_interrupts; | 200 | ******************************************************************************/ |
| 512 | index++) { | ||
| 513 | ACPI_MOVE_32_TO_32(buffer, | ||
| 514 | &linked_list->data.extended_irq. | ||
| 515 | interrupts[index]); | ||
| 516 | buffer += 4; | ||
| 517 | } | ||
| 518 | 201 | ||
| 519 | /* Resource Source Index and Resource Source are optional */ | 202 | struct acpi_rsconvert_info acpi_rs_convert_dma[6] = { |
| 203 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA, | ||
| 204 | ACPI_RS_SIZE(struct acpi_resource_dma), | ||
| 205 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_dma)}, | ||
| 520 | 206 | ||
| 521 | if (0 != linked_list->data.extended_irq.resource_source.string_length) { | 207 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA, |
| 522 | *buffer = | 208 | sizeof(struct aml_resource_dma), |
| 523 | (u8) linked_list->data.extended_irq.resource_source.index; | 209 | 0}, |
| 524 | buffer += 1; | ||
| 525 | 210 | ||
| 526 | /* Copy the string */ | 211 | /* Flags: transfer preference, bus mastering, channel speed */ |
| 527 | 212 | ||
| 528 | ACPI_STRCPY((char *)buffer, | 213 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.transfer), |
| 529 | linked_list->data.extended_irq.resource_source. | 214 | AML_OFFSET(dma.flags), |
| 530 | string_ptr); | 215 | 0}, |
| 531 | 216 | ||
| 532 | /* | 217 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.dma.bus_master), |
| 533 | * Buffer needs to be set to the length of the string + one for the | 218 | AML_OFFSET(dma.flags), |
| 534 | * terminating null | 219 | 2}, |
| 535 | */ | ||
| 536 | buffer += | ||
| 537 | (acpi_size) (ACPI_STRLEN | ||
| 538 | (linked_list->data.extended_irq. | ||
| 539 | resource_source.string_ptr) + 1); | ||
| 540 | } | ||
| 541 | 220 | ||
| 542 | /* Return the number of bytes consumed in this operation */ | 221 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.type), |
| 222 | AML_OFFSET(dma.flags), | ||
| 223 | 5}, | ||
| 543 | 224 | ||
| 544 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | 225 | /* DMA channel mask bits */ |
| 545 | 226 | ||
| 546 | /* | 227 | {ACPI_RSC_BITMASK, ACPI_RS_OFFSET(data.dma.channels[0]), |
| 547 | * Set the length field to the number of bytes consumed | 228 | AML_OFFSET(dma.dma_channel_mask), |
| 548 | * minus the header size (3 bytes) | 229 | ACPI_RS_OFFSET(data.dma.channel_count)} |
| 549 | */ | 230 | }; |
| 550 | *length_field = (u16) (*bytes_consumed - 3); | ||
| 551 | return_ACPI_STATUS(AE_OK); | ||
| 552 | } | ||
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 103eb31c284e..1434e786477e 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -49,52 +49,12 @@ ACPI_MODULE_NAME("rslist") | |||
| 49 | 49 | ||
| 50 | /******************************************************************************* | 50 | /******************************************************************************* |
| 51 | * | 51 | * |
| 52 | * FUNCTION: acpi_rs_get_resource_type | 52 | * FUNCTION: acpi_rs_convert_aml_to_resources |
| 53 | * | 53 | * |
| 54 | * PARAMETERS: resource_start_byte - Byte 0 of a resource descriptor | 54 | * PARAMETERS: Aml - Pointer to the resource byte stream |
| 55 | * | 55 | * aml_length - Length of Aml |
| 56 | * RETURN: The Resource Type with no extraneous bits | 56 | * output_buffer - Pointer to the buffer that will |
| 57 | * | 57 | * contain the output structures |
| 58 | * DESCRIPTION: Extract the Resource Type/Name from the first byte of | ||
| 59 | * a resource descriptor. | ||
| 60 | * | ||
| 61 | ******************************************************************************/ | ||
| 62 | u8 acpi_rs_get_resource_type(u8 resource_start_byte) | ||
| 63 | { | ||
| 64 | |||
| 65 | ACPI_FUNCTION_ENTRY(); | ||
| 66 | |||
| 67 | /* Determine if this is a small or large resource */ | ||
| 68 | |||
| 69 | switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) { | ||
| 70 | case ACPI_RDESC_TYPE_SMALL: | ||
| 71 | |||
| 72 | /* Small Resource Type -- Only bits 6:3 are valid */ | ||
| 73 | |||
| 74 | return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK)); | ||
| 75 | |||
| 76 | case ACPI_RDESC_TYPE_LARGE: | ||
| 77 | |||
| 78 | /* Large Resource Type -- All bits are valid */ | ||
| 79 | |||
| 80 | return (resource_start_byte); | ||
| 81 | |||
| 82 | default: | ||
| 83 | /* Invalid type */ | ||
| 84 | break; | ||
| 85 | } | ||
| 86 | |||
| 87 | return (0xFF); | ||
| 88 | } | ||
| 89 | |||
| 90 | /******************************************************************************* | ||
| 91 | * | ||
| 92 | * FUNCTION: acpi_rs_byte_stream_to_list | ||
| 93 | * | ||
| 94 | * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream | ||
| 95 | * byte_stream_buffer_length - Length of byte_stream_buffer | ||
| 96 | * output_buffer - Pointer to the buffer that will | ||
| 97 | * contain the output structures | ||
| 98 | * | 58 | * |
| 99 | * RETURN: Status | 59 | * RETURN: Status |
| 100 | * | 60 | * |
| @@ -102,241 +62,78 @@ u8 acpi_rs_get_resource_type(u8 resource_start_byte) | |||
| 102 | * linked list of resources in the caller's output buffer | 62 | * linked list of resources in the caller's output buffer |
| 103 | * | 63 | * |
| 104 | ******************************************************************************/ | 64 | ******************************************************************************/ |
| 105 | |||
| 106 | acpi_status | 65 | acpi_status |
| 107 | acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, | 66 | acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) |
| 108 | u32 byte_stream_buffer_length, u8 * output_buffer) | ||
| 109 | { | 67 | { |
| 68 | struct acpi_resource *resource = (void *)output_buffer; | ||
| 110 | acpi_status status; | 69 | acpi_status status; |
| 111 | acpi_size bytes_parsed = 0; | 70 | u8 resource_index; |
| 112 | u8 resource_type = 0; | 71 | u8 *end_aml; |
| 113 | acpi_size bytes_consumed = 0; | 72 | |
| 114 | u8 *buffer = output_buffer; | 73 | ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); |
| 115 | acpi_size structure_size = 0; | ||
| 116 | u8 end_tag_processed = FALSE; | ||
| 117 | struct acpi_resource *resource; | ||
| 118 | |||
| 119 | ACPI_FUNCTION_TRACE("rs_byte_stream_to_list"); | ||
| 120 | |||
| 121 | while (bytes_parsed < byte_stream_buffer_length && !end_tag_processed) { | ||
| 122 | /* The next byte in the stream is the resource type */ | ||
| 123 | |||
| 124 | resource_type = acpi_rs_get_resource_type(*byte_stream_buffer); | ||
| 125 | |||
| 126 | switch (resource_type) { | ||
| 127 | case ACPI_RDESC_TYPE_MEMORY_24: | ||
| 128 | /* | ||
| 129 | * 24-Bit Memory Resource | ||
| 130 | */ | ||
| 131 | status = acpi_rs_memory24_resource(byte_stream_buffer, | ||
| 132 | &bytes_consumed, | ||
| 133 | &buffer, | ||
| 134 | &structure_size); | ||
| 135 | break; | ||
| 136 | |||
| 137 | case ACPI_RDESC_TYPE_LARGE_VENDOR: | ||
| 138 | /* | ||
| 139 | * Vendor Defined Resource | ||
| 140 | */ | ||
| 141 | status = acpi_rs_vendor_resource(byte_stream_buffer, | ||
| 142 | &bytes_consumed, | ||
| 143 | &buffer, | ||
| 144 | &structure_size); | ||
| 145 | break; | ||
| 146 | |||
| 147 | case ACPI_RDESC_TYPE_MEMORY_32: | ||
| 148 | /* | ||
| 149 | * 32-Bit Memory Range Resource | ||
| 150 | */ | ||
| 151 | status = | ||
| 152 | acpi_rs_memory32_range_resource(byte_stream_buffer, | ||
| 153 | &bytes_consumed, | ||
| 154 | &buffer, | ||
| 155 | &structure_size); | ||
| 156 | break; | ||
| 157 | |||
| 158 | case ACPI_RDESC_TYPE_FIXED_MEMORY_32: | ||
| 159 | /* | ||
| 160 | * 32-Bit Fixed Memory Resource | ||
| 161 | */ | ||
| 162 | status = | ||
| 163 | acpi_rs_fixed_memory32_resource(byte_stream_buffer, | ||
| 164 | &bytes_consumed, | ||
| 165 | &buffer, | ||
| 166 | &structure_size); | ||
| 167 | break; | ||
| 168 | |||
| 169 | case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: | ||
| 170 | case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: | ||
| 171 | /* | ||
| 172 | * 64-Bit Address Resource | ||
| 173 | */ | ||
| 174 | status = acpi_rs_address64_resource(byte_stream_buffer, | ||
| 175 | &bytes_consumed, | ||
| 176 | &buffer, | ||
| 177 | &structure_size); | ||
| 178 | break; | ||
| 179 | |||
| 180 | case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: | ||
| 181 | /* | ||
| 182 | * 32-Bit Address Resource | ||
| 183 | */ | ||
| 184 | status = acpi_rs_address32_resource(byte_stream_buffer, | ||
| 185 | &bytes_consumed, | ||
| 186 | &buffer, | ||
| 187 | &structure_size); | ||
| 188 | break; | ||
| 189 | |||
| 190 | case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: | ||
| 191 | /* | ||
| 192 | * 16-Bit Address Resource | ||
| 193 | */ | ||
| 194 | status = acpi_rs_address16_resource(byte_stream_buffer, | ||
| 195 | &bytes_consumed, | ||
| 196 | &buffer, | ||
| 197 | &structure_size); | ||
| 198 | break; | ||
| 199 | |||
| 200 | case ACPI_RDESC_TYPE_EXTENDED_XRUPT: | ||
| 201 | /* | ||
| 202 | * Extended IRQ | ||
| 203 | */ | ||
| 204 | status = | ||
| 205 | acpi_rs_extended_irq_resource(byte_stream_buffer, | ||
| 206 | &bytes_consumed, | ||
| 207 | &buffer, | ||
| 208 | &structure_size); | ||
| 209 | break; | ||
| 210 | |||
| 211 | case ACPI_RDESC_TYPE_IRQ_FORMAT: | ||
| 212 | /* | ||
| 213 | * IRQ Resource | ||
| 214 | */ | ||
| 215 | status = acpi_rs_irq_resource(byte_stream_buffer, | ||
| 216 | &bytes_consumed, &buffer, | ||
| 217 | &structure_size); | ||
| 218 | break; | ||
| 219 | |||
| 220 | case ACPI_RDESC_TYPE_DMA_FORMAT: | ||
| 221 | /* | ||
| 222 | * DMA Resource | ||
| 223 | */ | ||
| 224 | status = acpi_rs_dma_resource(byte_stream_buffer, | ||
| 225 | &bytes_consumed, &buffer, | ||
| 226 | &structure_size); | ||
| 227 | break; | ||
| 228 | |||
| 229 | case ACPI_RDESC_TYPE_START_DEPENDENT: | ||
| 230 | /* | ||
| 231 | * Start Dependent Functions Resource | ||
| 232 | */ | ||
| 233 | status = | ||
| 234 | acpi_rs_start_depend_fns_resource | ||
| 235 | (byte_stream_buffer, &bytes_consumed, &buffer, | ||
| 236 | &structure_size); | ||
| 237 | break; | ||
| 238 | |||
| 239 | case ACPI_RDESC_TYPE_END_DEPENDENT: | ||
| 240 | /* | ||
| 241 | * End Dependent Functions Resource | ||
| 242 | */ | ||
| 243 | status = | ||
| 244 | acpi_rs_end_depend_fns_resource(byte_stream_buffer, | ||
| 245 | &bytes_consumed, | ||
| 246 | &buffer, | ||
| 247 | &structure_size); | ||
| 248 | break; | ||
| 249 | |||
| 250 | case ACPI_RDESC_TYPE_IO_PORT: | ||
| 251 | /* | ||
| 252 | * IO Port Resource | ||
| 253 | */ | ||
| 254 | status = acpi_rs_io_resource(byte_stream_buffer, | ||
| 255 | &bytes_consumed, &buffer, | ||
| 256 | &structure_size); | ||
| 257 | break; | ||
| 258 | |||
| 259 | case ACPI_RDESC_TYPE_FIXED_IO_PORT: | ||
| 260 | /* | ||
| 261 | * Fixed IO Port Resource | ||
| 262 | */ | ||
| 263 | status = acpi_rs_fixed_io_resource(byte_stream_buffer, | ||
| 264 | &bytes_consumed, | ||
| 265 | &buffer, | ||
| 266 | &structure_size); | ||
| 267 | break; | ||
| 268 | |||
| 269 | case ACPI_RDESC_TYPE_SMALL_VENDOR: | ||
| 270 | /* | ||
| 271 | * Vendor Specific Resource | ||
| 272 | */ | ||
| 273 | status = acpi_rs_vendor_resource(byte_stream_buffer, | ||
| 274 | &bytes_consumed, | ||
| 275 | &buffer, | ||
| 276 | &structure_size); | ||
| 277 | break; | ||
| 278 | |||
| 279 | case ACPI_RDESC_TYPE_END_TAG: | ||
| 280 | /* | ||
| 281 | * End Tag | ||
| 282 | */ | ||
| 283 | end_tag_processed = TRUE; | ||
| 284 | status = acpi_rs_end_tag_resource(byte_stream_buffer, | ||
| 285 | &bytes_consumed, | ||
| 286 | &buffer, | ||
| 287 | &structure_size); | ||
| 288 | break; | ||
| 289 | |||
| 290 | default: | ||
| 291 | /* | ||
| 292 | * Invalid/Unknown resource type | ||
| 293 | */ | ||
| 294 | status = AE_AML_INVALID_RESOURCE_TYPE; | ||
| 295 | break; | ||
| 296 | } | ||
| 297 | 74 | ||
| 75 | end_aml = aml + aml_length; | ||
| 76 | |||
| 77 | /* Loop until end-of-buffer or an end_tag is found */ | ||
| 78 | |||
| 79 | while (aml < end_aml) { | ||
| 80 | /* Validate the Resource Type and Resource Length */ | ||
| 81 | |||
| 82 | status = acpi_ut_validate_resource(aml, &resource_index); | ||
| 298 | if (ACPI_FAILURE(status)) { | 83 | if (ACPI_FAILURE(status)) { |
| 299 | return_ACPI_STATUS(status); | 84 | return_ACPI_STATUS(status); |
| 300 | } | 85 | } |
| 301 | 86 | ||
| 302 | /* Update the return value and counter */ | 87 | /* Convert the AML byte stream resource to a local resource struct */ |
| 303 | 88 | ||
| 304 | bytes_parsed += bytes_consumed; | 89 | status = |
| 90 | acpi_rs_convert_aml_to_resource(resource, | ||
| 91 | ACPI_CAST_PTR(union | ||
| 92 | aml_resource, | ||
| 93 | aml), | ||
| 94 | acpi_gbl_get_resource_dispatch | ||
| 95 | [resource_index]); | ||
| 96 | if (ACPI_FAILURE(status)) { | ||
| 97 | ACPI_EXCEPTION((AE_INFO, status, | ||
| 98 | "Could not convert AML resource (Type %X)", | ||
| 99 | *aml)); | ||
| 100 | return_ACPI_STATUS(status); | ||
| 101 | } | ||
| 305 | 102 | ||
| 306 | /* Set the byte stream to point to the next resource */ | 103 | /* Normal exit on completion of an end_tag resource descriptor */ |
| 307 | 104 | ||
| 308 | byte_stream_buffer += bytes_consumed; | 105 | if (acpi_ut_get_resource_type(aml) == |
| 106 | ACPI_RESOURCE_NAME_END_TAG) { | ||
| 107 | return_ACPI_STATUS(AE_OK); | ||
| 108 | } | ||
| 309 | 109 | ||
| 310 | /* Set the Buffer to the next structure */ | 110 | /* Point to the next input AML resource */ |
| 311 | 111 | ||
| 312 | resource = ACPI_CAST_PTR(struct acpi_resource, buffer); | 112 | aml += acpi_ut_get_descriptor_length(aml); |
| 313 | resource->length = | ||
| 314 | (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); | ||
| 315 | buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); | ||
| 316 | } | ||
| 317 | 113 | ||
| 318 | /* Check the reason for exiting the while loop */ | 114 | /* Point to the next structure in the output buffer */ |
| 319 | 115 | ||
| 320 | if (!end_tag_processed) { | 116 | resource = |
| 321 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); | 117 | ACPI_ADD_PTR(struct acpi_resource, resource, |
| 118 | resource->length); | ||
| 322 | } | 119 | } |
| 323 | 120 | ||
| 324 | return_ACPI_STATUS(AE_OK); | 121 | /* Did not find an end_tag resource descriptor */ |
| 122 | |||
| 123 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); | ||
| 325 | } | 124 | } |
| 326 | 125 | ||
| 327 | /******************************************************************************* | 126 | /******************************************************************************* |
| 328 | * | 127 | * |
| 329 | * FUNCTION: acpi_rs_list_to_byte_stream | 128 | * FUNCTION: acpi_rs_convert_resources_to_aml |
| 330 | * | 129 | * |
| 331 | * PARAMETERS: linked_list - Pointer to the resource linked list | 130 | * PARAMETERS: Resource - Pointer to the resource linked list |
| 332 | * byte_steam_size_needed - Calculated size of the byte stream | 131 | * aml_size_needed - Calculated size of the byte stream |
| 333 | * needed from calling | 132 | * needed from calling acpi_rs_get_aml_length() |
| 334 | * acpi_rs_get_byte_stream_length() | 133 | * The size of the output_buffer is |
| 335 | * The size of the output_buffer is | 134 | * guaranteed to be >= aml_size_needed |
| 336 | * guaranteed to be >= | 135 | * output_buffer - Pointer to the buffer that will |
| 337 | * byte_stream_size_needed | 136 | * contain the byte stream |
| 338 | * output_buffer - Pointer to the buffer that will | ||
| 339 | * contain the byte stream | ||
| 340 | * | 137 | * |
| 341 | * RETURN: Status | 138 | * RETURN: Status |
| 342 | * | 139 | * |
| @@ -346,180 +143,73 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, | |||
| 346 | ******************************************************************************/ | 143 | ******************************************************************************/ |
| 347 | 144 | ||
| 348 | acpi_status | 145 | acpi_status |
| 349 | acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list, | 146 | acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, |
| 350 | acpi_size byte_stream_size_needed, | 147 | acpi_size aml_size_needed, u8 * output_buffer) |
| 351 | u8 * output_buffer) | ||
| 352 | { | 148 | { |
| 149 | u8 *aml = output_buffer; | ||
| 150 | u8 *end_aml = output_buffer + aml_size_needed; | ||
| 353 | acpi_status status; | 151 | acpi_status status; |
| 354 | u8 *buffer = output_buffer; | 152 | |
| 355 | acpi_size bytes_consumed = 0; | 153 | ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); |
| 356 | u8 done = FALSE; | 154 | |
| 357 | 155 | /* Walk the resource descriptor list, convert each descriptor */ | |
| 358 | ACPI_FUNCTION_TRACE("rs_list_to_byte_stream"); | 156 | |
| 359 | 157 | while (aml < end_aml) { | |
| 360 | while (!done) { | 158 | /* Validate the (internal) Resource Type */ |
| 361 | switch (linked_list->id) { | 159 | |
| 362 | case ACPI_RSTYPE_IRQ: | 160 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { |
| 363 | /* | 161 | ACPI_ERROR((AE_INFO, |
| 364 | * IRQ Resource | 162 | "Invalid descriptor type (%X) in resource list", |
| 365 | */ | 163 | resource->type)); |
| 366 | status = | 164 | return_ACPI_STATUS(AE_BAD_DATA); |
| 367 | acpi_rs_irq_stream(linked_list, &buffer, | ||
| 368 | &bytes_consumed); | ||
| 369 | break; | ||
| 370 | |||
| 371 | case ACPI_RSTYPE_DMA: | ||
| 372 | /* | ||
| 373 | * DMA Resource | ||
| 374 | */ | ||
| 375 | status = | ||
| 376 | acpi_rs_dma_stream(linked_list, &buffer, | ||
| 377 | &bytes_consumed); | ||
| 378 | break; | ||
| 379 | |||
| 380 | case ACPI_RSTYPE_START_DPF: | ||
| 381 | /* | ||
| 382 | * Start Dependent Functions Resource | ||
| 383 | */ | ||
| 384 | status = acpi_rs_start_depend_fns_stream(linked_list, | ||
| 385 | &buffer, | ||
| 386 | &bytes_consumed); | ||
| 387 | break; | ||
| 388 | |||
| 389 | case ACPI_RSTYPE_END_DPF: | ||
| 390 | /* | ||
| 391 | * End Dependent Functions Resource | ||
| 392 | */ | ||
| 393 | status = acpi_rs_end_depend_fns_stream(linked_list, | ||
| 394 | &buffer, | ||
| 395 | &bytes_consumed); | ||
| 396 | break; | ||
| 397 | |||
| 398 | case ACPI_RSTYPE_IO: | ||
| 399 | /* | ||
| 400 | * IO Port Resource | ||
| 401 | */ | ||
| 402 | status = | ||
| 403 | acpi_rs_io_stream(linked_list, &buffer, | ||
| 404 | &bytes_consumed); | ||
| 405 | break; | ||
| 406 | |||
| 407 | case ACPI_RSTYPE_FIXED_IO: | ||
| 408 | /* | ||
| 409 | * Fixed IO Port Resource | ||
| 410 | */ | ||
| 411 | status = | ||
| 412 | acpi_rs_fixed_io_stream(linked_list, &buffer, | ||
| 413 | &bytes_consumed); | ||
| 414 | break; | ||
| 415 | |||
| 416 | case ACPI_RSTYPE_VENDOR: | ||
| 417 | /* | ||
| 418 | * Vendor Defined Resource | ||
| 419 | */ | ||
| 420 | status = | ||
| 421 | acpi_rs_vendor_stream(linked_list, &buffer, | ||
| 422 | &bytes_consumed); | ||
| 423 | break; | ||
| 424 | |||
| 425 | case ACPI_RSTYPE_END_TAG: | ||
| 426 | /* | ||
| 427 | * End Tag | ||
| 428 | */ | ||
| 429 | status = | ||
| 430 | acpi_rs_end_tag_stream(linked_list, &buffer, | ||
| 431 | &bytes_consumed); | ||
| 432 | |||
| 433 | /* An End Tag indicates the end of the Resource Template */ | ||
| 434 | |||
| 435 | done = TRUE; | ||
| 436 | break; | ||
| 437 | |||
| 438 | case ACPI_RSTYPE_MEM24: | ||
| 439 | /* | ||
| 440 | * 24-Bit Memory Resource | ||
| 441 | */ | ||
| 442 | status = | ||
| 443 | acpi_rs_memory24_stream(linked_list, &buffer, | ||
| 444 | &bytes_consumed); | ||
| 445 | break; | ||
| 446 | |||
| 447 | case ACPI_RSTYPE_MEM32: | ||
| 448 | /* | ||
| 449 | * 32-Bit Memory Range Resource | ||
| 450 | */ | ||
| 451 | status = | ||
| 452 | acpi_rs_memory32_range_stream(linked_list, &buffer, | ||
| 453 | &bytes_consumed); | ||
| 454 | break; | ||
| 455 | |||
| 456 | case ACPI_RSTYPE_FIXED_MEM32: | ||
| 457 | /* | ||
| 458 | * 32-Bit Fixed Memory Resource | ||
| 459 | */ | ||
| 460 | status = | ||
| 461 | acpi_rs_fixed_memory32_stream(linked_list, &buffer, | ||
| 462 | &bytes_consumed); | ||
| 463 | break; | ||
| 464 | |||
| 465 | case ACPI_RSTYPE_ADDRESS16: | ||
| 466 | /* | ||
| 467 | * 16-Bit Address Descriptor Resource | ||
| 468 | */ | ||
| 469 | status = acpi_rs_address16_stream(linked_list, &buffer, | ||
| 470 | &bytes_consumed); | ||
| 471 | break; | ||
| 472 | |||
| 473 | case ACPI_RSTYPE_ADDRESS32: | ||
| 474 | /* | ||
| 475 | * 32-Bit Address Descriptor Resource | ||
| 476 | */ | ||
| 477 | status = acpi_rs_address32_stream(linked_list, &buffer, | ||
| 478 | &bytes_consumed); | ||
| 479 | break; | ||
| 480 | |||
| 481 | case ACPI_RSTYPE_ADDRESS64: | ||
| 482 | /* | ||
| 483 | * 64-Bit Address Descriptor Resource | ||
| 484 | */ | ||
| 485 | status = acpi_rs_address64_stream(linked_list, &buffer, | ||
| 486 | &bytes_consumed); | ||
| 487 | break; | ||
| 488 | |||
| 489 | case ACPI_RSTYPE_EXT_IRQ: | ||
| 490 | /* | ||
| 491 | * Extended IRQ Resource | ||
| 492 | */ | ||
| 493 | status = | ||
| 494 | acpi_rs_extended_irq_stream(linked_list, &buffer, | ||
| 495 | &bytes_consumed); | ||
| 496 | break; | ||
| 497 | |||
| 498 | default: | ||
| 499 | /* | ||
| 500 | * If we get here, everything is out of sync, | ||
| 501 | * so exit with an error | ||
| 502 | */ | ||
| 503 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
| 504 | "Invalid descriptor type (%X) in resource list\n", | ||
| 505 | linked_list->id)); | ||
| 506 | status = AE_BAD_DATA; | ||
| 507 | break; | ||
| 508 | } | 165 | } |
| 509 | 166 | ||
| 167 | /* Perform the conversion */ | ||
| 168 | |||
| 169 | status = acpi_rs_convert_resource_to_aml(resource, | ||
| 170 | ACPI_CAST_PTR(union | ||
| 171 | aml_resource, | ||
| 172 | aml), | ||
| 173 | acpi_gbl_set_resource_dispatch | ||
| 174 | [resource->type]); | ||
| 510 | if (ACPI_FAILURE(status)) { | 175 | if (ACPI_FAILURE(status)) { |
| 176 | ACPI_EXCEPTION((AE_INFO, status, | ||
| 177 | "Could not convert resource (type %X) to AML", | ||
| 178 | resource->type)); | ||
| 511 | return_ACPI_STATUS(status); | 179 | return_ACPI_STATUS(status); |
| 512 | } | 180 | } |
| 513 | 181 | ||
| 514 | /* Set the Buffer to point to the open byte */ | 182 | /* Perform final sanity check on the new AML resource descriptor */ |
| 183 | |||
| 184 | status = | ||
| 185 | acpi_ut_validate_resource(ACPI_CAST_PTR | ||
| 186 | (union aml_resource, aml), NULL); | ||
| 187 | if (ACPI_FAILURE(status)) { | ||
| 188 | return_ACPI_STATUS(status); | ||
| 189 | } | ||
| 515 | 190 | ||
| 516 | buffer += bytes_consumed; | 191 | /* Check for end-of-list, normal exit */ |
| 517 | 192 | ||
| 518 | /* Point to the next object */ | 193 | if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { |
| 194 | /* An End Tag indicates the end of the input Resource Template */ | ||
| 519 | 195 | ||
| 520 | linked_list = ACPI_PTR_ADD(struct acpi_resource, | 196 | return_ACPI_STATUS(AE_OK); |
| 521 | linked_list, linked_list->length); | 197 | } |
| 198 | |||
| 199 | /* | ||
| 200 | * Extract the total length of the new descriptor and set the | ||
| 201 | * Aml to point to the next (output) resource descriptor | ||
| 202 | */ | ||
| 203 | aml += acpi_ut_get_descriptor_length(aml); | ||
| 204 | |||
| 205 | /* Point to the next input resource descriptor */ | ||
| 206 | |||
| 207 | resource = | ||
| 208 | ACPI_ADD_PTR(struct acpi_resource, resource, | ||
| 209 | resource->length); | ||
| 522 | } | 210 | } |
| 523 | 211 | ||
| 524 | return_ACPI_STATUS(AE_OK); | 212 | /* Completed buffer, but did not find an end_tag resource descriptor */ |
| 213 | |||
| 214 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); | ||
| 525 | } | 215 | } |
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index daba1a1ed46d..a5131936d690 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -49,454 +49,187 @@ ACPI_MODULE_NAME("rsmemory") | |||
| 49 | 49 | ||
| 50 | /******************************************************************************* | 50 | /******************************************************************************* |
| 51 | * | 51 | * |
| 52 | * FUNCTION: acpi_rs_memory24_resource | 52 | * acpi_rs_convert_memory24 |
| 53 | * | ||
| 54 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 55 | * stream | ||
| 56 | * bytes_consumed - Pointer to where the number of bytes | ||
| 57 | * consumed the byte_stream_buffer is | ||
| 58 | * returned | ||
| 59 | * output_buffer - Pointer to the return data buffer | ||
| 60 | * structure_size - Pointer to where the number of bytes | ||
| 61 | * in the return data struct is returned | ||
| 62 | * | ||
| 63 | * RETURN: Status | ||
| 64 | * | ||
| 65 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 66 | * structure pointed to by the output_buffer. Return the | ||
| 67 | * number of bytes consumed from the byte stream. | ||
| 68 | * | 53 | * |
| 69 | ******************************************************************************/ | 54 | ******************************************************************************/ |
| 70 | acpi_status | 55 | struct acpi_rsconvert_info acpi_rs_convert_memory24[4] = { |
| 71 | acpi_rs_memory24_resource(u8 * byte_stream_buffer, | 56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY24, |
| 72 | acpi_size * bytes_consumed, | 57 | ACPI_RS_SIZE(struct acpi_resource_memory24), |
| 73 | u8 ** output_buffer, acpi_size * structure_size) | 58 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory24)}, |
| 74 | { | ||
| 75 | u8 *buffer = byte_stream_buffer; | ||
| 76 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 77 | u16 temp16 = 0; | ||
| 78 | u8 temp8 = 0; | ||
| 79 | acpi_size struct_size = | ||
| 80 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24); | ||
| 81 | |||
| 82 | ACPI_FUNCTION_TRACE("rs_memory24_resource"); | ||
| 83 | |||
| 84 | /* Point past the Descriptor to get the number of bytes consumed */ | ||
| 85 | |||
| 86 | buffer += 1; | ||
| 87 | |||
| 88 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 89 | buffer += 2; | ||
| 90 | *bytes_consumed = (acpi_size) temp16 + 3; | ||
| 91 | output_struct->id = ACPI_RSTYPE_MEM24; | ||
| 92 | |||
| 93 | /* Check Byte 3 the Read/Write bit */ | ||
| 94 | |||
| 95 | temp8 = *buffer; | ||
| 96 | buffer += 1; | ||
| 97 | output_struct->data.memory24.read_write_attribute = temp8 & 0x01; | ||
| 98 | |||
| 99 | /* Get min_base_address (Bytes 4-5) */ | ||
| 100 | |||
| 101 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 102 | buffer += 2; | ||
| 103 | output_struct->data.memory24.min_base_address = temp16; | ||
| 104 | |||
| 105 | /* Get max_base_address (Bytes 6-7) */ | ||
| 106 | |||
| 107 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
| 108 | buffer += 2; | ||
| 109 | output_struct->data.memory24.max_base_address = temp16; | ||
| 110 | 59 | ||
| 111 | /* Get Alignment (Bytes 8-9) */ | 60 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY24, |
| 61 | sizeof(struct aml_resource_memory24), | ||
| 62 | 0}, | ||
| 112 | 63 | ||
| 113 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 64 | /* Read/Write bit */ |
| 114 | buffer += 2; | ||
| 115 | output_struct->data.memory24.alignment = temp16; | ||
| 116 | 65 | ||
| 117 | /* Get range_length (Bytes 10-11) */ | 66 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory24.write_protect), |
| 118 | 67 | AML_OFFSET(memory24.flags), | |
| 119 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 68 | 0}, |
| 120 | output_struct->data.memory24.range_length = temp16; | 69 | /* |
| 121 | 70 | * These fields are contiguous in both the source and destination: | |
| 122 | /* Set the Length parameter */ | 71 | * Minimum Base Address |
| 123 | 72 | * Maximum Base Address | |
| 124 | output_struct->length = (u32) struct_size; | 73 | * Address Base Alignment |
| 125 | 74 | * Range Length | |
| 126 | /* Return the final size of the structure */ | 75 | */ |
| 127 | 76 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.memory24.minimum), | |
| 128 | *structure_size = struct_size; | 77 | AML_OFFSET(memory24.minimum), |
| 129 | return_ACPI_STATUS(AE_OK); | 78 | 4} |
| 130 | } | 79 | }; |
| 131 | 80 | ||
| 132 | /******************************************************************************* | 81 | /******************************************************************************* |
| 133 | * | 82 | * |
| 134 | * FUNCTION: acpi_rs_memory24_stream | 83 | * acpi_rs_convert_memory32 |
| 135 | * | ||
| 136 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 137 | * output_buffer - Pointer to the user's return buffer | ||
| 138 | * bytes_consumed - Pointer to where the number of bytes | ||
| 139 | * used in the output_buffer is returned | ||
| 140 | * | ||
| 141 | * RETURN: Status | ||
| 142 | * | ||
| 143 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 144 | * the appropriate bytes in a byte stream | ||
| 145 | * | 84 | * |
| 146 | ******************************************************************************/ | 85 | ******************************************************************************/ |
| 147 | 86 | ||
| 148 | acpi_status | 87 | struct acpi_rsconvert_info acpi_rs_convert_memory32[4] = { |
| 149 | acpi_rs_memory24_stream(struct acpi_resource *linked_list, | 88 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY32, |
| 150 | u8 ** output_buffer, acpi_size * bytes_consumed) | 89 | ACPI_RS_SIZE(struct acpi_resource_memory32), |
| 151 | { | 90 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory32)}, |
| 152 | u8 *buffer = *output_buffer; | ||
| 153 | u16 temp16 = 0; | ||
| 154 | u8 temp8 = 0; | ||
| 155 | |||
| 156 | ACPI_FUNCTION_TRACE("rs_memory24_stream"); | ||
| 157 | |||
| 158 | /* The descriptor field is static */ | ||
| 159 | |||
| 160 | *buffer = 0x81; | ||
| 161 | buffer += 1; | ||
| 162 | 91 | ||
| 163 | /* The length field is static */ | 92 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY32, |
| 93 | sizeof(struct aml_resource_memory32), | ||
| 94 | 0}, | ||
| 164 | 95 | ||
| 165 | temp16 = 0x09; | 96 | /* Read/Write bit */ |
| 166 | ACPI_MOVE_16_TO_16(buffer, &temp16); | ||
| 167 | buffer += 2; | ||
| 168 | 97 | ||
| 169 | /* Set the Information Byte */ | 98 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory32.write_protect), |
| 170 | 99 | AML_OFFSET(memory32.flags), | |
| 171 | temp8 = (u8) (linked_list->data.memory24.read_write_attribute & 0x01); | 100 | 0}, |
| 172 | *buffer = temp8; | 101 | /* |
| 173 | buffer += 1; | 102 | * These fields are contiguous in both the source and destination: |
| 174 | 103 | * Minimum Base Address | |
| 175 | /* Set the Range minimum base address */ | 104 | * Maximum Base Address |
| 176 | 105 | * Address Base Alignment | |
| 177 | ACPI_MOVE_32_TO_16(buffer, | 106 | * Range Length |
| 178 | &linked_list->data.memory24.min_base_address); | 107 | */ |
| 179 | buffer += 2; | 108 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.memory32.minimum), |
| 180 | 109 | AML_OFFSET(memory32.minimum), | |
| 181 | /* Set the Range maximum base address */ | 110 | 4} |
| 182 | 111 | }; | |
| 183 | ACPI_MOVE_32_TO_16(buffer, | ||
| 184 | &linked_list->data.memory24.max_base_address); | ||
| 185 | buffer += 2; | ||
| 186 | |||
| 187 | /* Set the base alignment */ | ||
| 188 | |||
| 189 | ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.alignment); | ||
| 190 | buffer += 2; | ||
| 191 | |||
| 192 | /* Set the range length */ | ||
| 193 | |||
| 194 | ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.range_length); | ||
| 195 | buffer += 2; | ||
| 196 | |||
| 197 | /* Return the number of bytes consumed in this operation */ | ||
| 198 | |||
| 199 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 200 | return_ACPI_STATUS(AE_OK); | ||
| 201 | } | ||
| 202 | 112 | ||
| 203 | /******************************************************************************* | 113 | /******************************************************************************* |
| 204 | * | 114 | * |
| 205 | * FUNCTION: acpi_rs_memory32_range_resource | 115 | * acpi_rs_convert_fixed_memory32 |
| 206 | * | ||
| 207 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 208 | * stream | ||
| 209 | * bytes_consumed - Pointer to where the number of bytes | ||
| 210 | * consumed the byte_stream_buffer is | ||
| 211 | * returned | ||
| 212 | * output_buffer - Pointer to the return data buffer | ||
| 213 | * structure_size - Pointer to where the number of bytes | ||
| 214 | * in the return data struct is returned | ||
| 215 | * | ||
| 216 | * RETURN: Status | ||
| 217 | * | ||
| 218 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 219 | * structure pointed to by the output_buffer. Return the | ||
| 220 | * number of bytes consumed from the byte stream. | ||
| 221 | * | 116 | * |
| 222 | ******************************************************************************/ | 117 | ******************************************************************************/ |
| 223 | 118 | ||
| 224 | acpi_status | 119 | struct acpi_rsconvert_info acpi_rs_convert_fixed_memory32[4] = { |
| 225 | acpi_rs_memory32_range_resource(u8 * byte_stream_buffer, | 120 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_MEMORY32, |
| 226 | acpi_size * bytes_consumed, | 121 | ACPI_RS_SIZE(struct acpi_resource_fixed_memory32), |
| 227 | u8 ** output_buffer, acpi_size * structure_size) | 122 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_memory32)}, |
| 228 | { | ||
| 229 | u8 *buffer = byte_stream_buffer; | ||
| 230 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 231 | u16 temp16 = 0; | ||
| 232 | u8 temp8 = 0; | ||
| 233 | acpi_size struct_size = | ||
| 234 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32); | ||
| 235 | |||
| 236 | ACPI_FUNCTION_TRACE("rs_memory32_range_resource"); | ||
| 237 | |||
| 238 | /* Point past the Descriptor to get the number of bytes consumed */ | ||
| 239 | |||
| 240 | buffer += 1; | ||
| 241 | 123 | ||
| 242 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 124 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_MEMORY32, |
| 243 | buffer += 2; | 125 | sizeof(struct aml_resource_fixed_memory32), |
| 244 | *bytes_consumed = (acpi_size) temp16 + 3; | 126 | 0}, |
| 245 | 127 | ||
| 246 | output_struct->id = ACPI_RSTYPE_MEM32; | 128 | /* Read/Write bit */ |
| 247 | 129 | ||
| 130 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.fixed_memory32.write_protect), | ||
| 131 | AML_OFFSET(fixed_memory32.flags), | ||
| 132 | 0}, | ||
| 248 | /* | 133 | /* |
| 249 | * Point to the place in the output buffer where the data portion will | 134 | * These fields are contiguous in both the source and destination: |
| 250 | * begin. | 135 | * Base Address |
| 251 | * 1. Set the RESOURCE_DATA * Data to point to its own address, then | 136 | * Range Length |
| 252 | * 2. Set the pointer to the next address. | ||
| 253 | * | ||
| 254 | * NOTE: output_struct->Data is cast to u8, otherwise, this addition adds | ||
| 255 | * 4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8) | ||
| 256 | */ | 137 | */ |
| 257 | 138 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.fixed_memory32.address), | |
| 258 | /* Check Byte 3 the Read/Write bit */ | 139 | AML_OFFSET(fixed_memory32.address), |
| 259 | 140 | 2} | |
| 260 | temp8 = *buffer; | 141 | }; |
| 261 | buffer += 1; | ||
| 262 | |||
| 263 | output_struct->data.memory32.read_write_attribute = temp8 & 0x01; | ||
| 264 | |||
| 265 | /* Get min_base_address (Bytes 4-7) */ | ||
| 266 | |||
| 267 | ACPI_MOVE_32_TO_32(&output_struct->data.memory32.min_base_address, | ||
| 268 | buffer); | ||
| 269 | buffer += 4; | ||
| 270 | |||
| 271 | /* Get max_base_address (Bytes 8-11) */ | ||
| 272 | |||
| 273 | ACPI_MOVE_32_TO_32(&output_struct->data.memory32.max_base_address, | ||
| 274 | buffer); | ||
| 275 | buffer += 4; | ||
| 276 | |||
| 277 | /* Get Alignment (Bytes 12-15) */ | ||
| 278 | |||
| 279 | ACPI_MOVE_32_TO_32(&output_struct->data.memory32.alignment, buffer); | ||
| 280 | buffer += 4; | ||
| 281 | |||
| 282 | /* Get range_length (Bytes 16-19) */ | ||
| 283 | |||
| 284 | ACPI_MOVE_32_TO_32(&output_struct->data.memory32.range_length, buffer); | ||
| 285 | |||
| 286 | /* Set the Length parameter */ | ||
| 287 | |||
| 288 | output_struct->length = (u32) struct_size; | ||
| 289 | |||
| 290 | /* Return the final size of the structure */ | ||
| 291 | |||
| 292 | *structure_size = struct_size; | ||
| 293 | return_ACPI_STATUS(AE_OK); | ||
| 294 | } | ||
| 295 | 142 | ||
| 296 | /******************************************************************************* | 143 | /******************************************************************************* |
| 297 | * | 144 | * |
| 298 | * FUNCTION: acpi_rs_fixed_memory32_resource | 145 | * acpi_rs_get_vendor_small |
| 299 | * | ||
| 300 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 301 | * stream | ||
| 302 | * bytes_consumed - Pointer to where the number of bytes | ||
| 303 | * consumed the byte_stream_buffer is | ||
| 304 | * returned | ||
| 305 | * output_buffer - Pointer to the return data buffer | ||
| 306 | * structure_size - Pointer to where the number of bytes | ||
| 307 | * in the return data struct is returned | ||
| 308 | * | ||
| 309 | * RETURN: Status | ||
| 310 | * | ||
| 311 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 312 | * structure pointed to by the output_buffer. Return the | ||
| 313 | * number of bytes consumed from the byte stream. | ||
| 314 | * | 146 | * |
| 315 | ******************************************************************************/ | 147 | ******************************************************************************/ |
| 316 | 148 | ||
| 317 | acpi_status | 149 | struct acpi_rsconvert_info acpi_rs_get_vendor_small[3] = { |
| 318 | acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer, | 150 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR, |
| 319 | acpi_size * bytes_consumed, | 151 | ACPI_RS_SIZE(struct acpi_resource_vendor), |
| 320 | u8 ** output_buffer, acpi_size * structure_size) | 152 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_small)}, |
| 321 | { | ||
| 322 | u8 *buffer = byte_stream_buffer; | ||
| 323 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 324 | u16 temp16 = 0; | ||
| 325 | u8 temp8 = 0; | ||
| 326 | acpi_size struct_size = | ||
| 327 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32); | ||
| 328 | |||
| 329 | ACPI_FUNCTION_TRACE("rs_fixed_memory32_resource"); | ||
| 330 | 153 | ||
| 331 | /* Point past the Descriptor to get the number of bytes consumed */ | 154 | /* Length of the vendor data (byte count) */ |
| 332 | 155 | ||
| 333 | buffer += 1; | 156 | {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), |
| 334 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 157 | 0, |
| 158 | sizeof(u8)} | ||
| 159 | , | ||
| 335 | 160 | ||
| 336 | buffer += 2; | 161 | /* Vendor data */ |
| 337 | *bytes_consumed = (acpi_size) temp16 + 3; | ||
| 338 | 162 | ||
| 339 | output_struct->id = ACPI_RSTYPE_FIXED_MEM32; | 163 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), |
| 340 | 164 | sizeof(struct aml_resource_small_header), | |
| 341 | /* Check Byte 3 the Read/Write bit */ | 165 | 0} |
| 342 | 166 | }; | |
| 343 | temp8 = *buffer; | ||
| 344 | buffer += 1; | ||
| 345 | output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01; | ||
| 346 | |||
| 347 | /* Get range_base_address (Bytes 4-7) */ | ||
| 348 | |||
| 349 | ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32. | ||
| 350 | range_base_address, buffer); | ||
| 351 | buffer += 4; | ||
| 352 | |||
| 353 | /* Get range_length (Bytes 8-11) */ | ||
| 354 | |||
| 355 | ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32.range_length, | ||
| 356 | buffer); | ||
| 357 | |||
| 358 | /* Set the Length parameter */ | ||
| 359 | |||
| 360 | output_struct->length = (u32) struct_size; | ||
| 361 | |||
| 362 | /* Return the final size of the structure */ | ||
| 363 | |||
| 364 | *structure_size = struct_size; | ||
| 365 | return_ACPI_STATUS(AE_OK); | ||
| 366 | } | ||
| 367 | 167 | ||
| 368 | /******************************************************************************* | 168 | /******************************************************************************* |
| 369 | * | 169 | * |
| 370 | * FUNCTION: acpi_rs_memory32_range_stream | 170 | * acpi_rs_get_vendor_large |
| 371 | * | ||
| 372 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 373 | * output_buffer - Pointer to the user's return buffer | ||
| 374 | * bytes_consumed - Pointer to where the number of bytes | ||
| 375 | * used in the output_buffer is returned | ||
| 376 | * | ||
| 377 | * RETURN: Status | ||
| 378 | * | ||
| 379 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 380 | * the appropriate bytes in a byte stream | ||
| 381 | * | 171 | * |
| 382 | ******************************************************************************/ | 172 | ******************************************************************************/ |
| 383 | 173 | ||
| 384 | acpi_status | 174 | struct acpi_rsconvert_info acpi_rs_get_vendor_large[3] = { |
| 385 | acpi_rs_memory32_range_stream(struct acpi_resource *linked_list, | 175 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR, |
| 386 | u8 ** output_buffer, acpi_size * bytes_consumed) | 176 | ACPI_RS_SIZE(struct acpi_resource_vendor), |
| 387 | { | 177 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_large)}, |
| 388 | u8 *buffer = *output_buffer; | ||
| 389 | u16 temp16 = 0; | ||
| 390 | u8 temp8 = 0; | ||
| 391 | |||
| 392 | ACPI_FUNCTION_TRACE("rs_memory32_range_stream"); | ||
| 393 | |||
| 394 | /* The descriptor field is static */ | ||
| 395 | |||
| 396 | *buffer = 0x85; | ||
| 397 | buffer += 1; | ||
| 398 | |||
| 399 | /* The length field is static */ | ||
| 400 | |||
| 401 | temp16 = 0x11; | ||
| 402 | |||
| 403 | ACPI_MOVE_16_TO_16(buffer, &temp16); | ||
| 404 | buffer += 2; | ||
| 405 | |||
| 406 | /* Set the Information Byte */ | ||
| 407 | |||
| 408 | temp8 = (u8) (linked_list->data.memory32.read_write_attribute & 0x01); | ||
| 409 | *buffer = temp8; | ||
| 410 | buffer += 1; | ||
| 411 | |||
| 412 | /* Set the Range minimum base address */ | ||
| 413 | |||
| 414 | ACPI_MOVE_32_TO_32(buffer, | ||
| 415 | &linked_list->data.memory32.min_base_address); | ||
| 416 | buffer += 4; | ||
| 417 | |||
| 418 | /* Set the Range maximum base address */ | ||
| 419 | |||
| 420 | ACPI_MOVE_32_TO_32(buffer, | ||
| 421 | &linked_list->data.memory32.max_base_address); | ||
| 422 | buffer += 4; | ||
| 423 | 178 | ||
| 424 | /* Set the base alignment */ | 179 | /* Length of the vendor data (byte count) */ |
| 425 | 180 | ||
| 426 | ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.alignment); | 181 | {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), |
| 427 | buffer += 4; | 182 | 0, |
| 183 | sizeof(u8)} | ||
| 184 | , | ||
| 428 | 185 | ||
| 429 | /* Set the range length */ | 186 | /* Vendor data */ |
| 430 | 187 | ||
| 431 | ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.range_length); | 188 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), |
| 432 | buffer += 4; | 189 | sizeof(struct aml_resource_large_header), |
| 433 | 190 | 0} | |
| 434 | /* Return the number of bytes consumed in this operation */ | 191 | }; |
| 435 | |||
| 436 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 437 | return_ACPI_STATUS(AE_OK); | ||
| 438 | } | ||
| 439 | 192 | ||
| 440 | /******************************************************************************* | 193 | /******************************************************************************* |
| 441 | * | 194 | * |
| 442 | * FUNCTION: acpi_rs_fixed_memory32_stream | 195 | * acpi_rs_set_vendor |
| 443 | * | ||
| 444 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 445 | * output_buffer - Pointer to the user's return buffer | ||
| 446 | * bytes_consumed - Pointer to where the number of bytes | ||
| 447 | * used in the output_buffer is returned | ||
| 448 | * | ||
| 449 | * RETURN: Status | ||
| 450 | * | ||
| 451 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 452 | * the appropriate bytes in a byte stream | ||
| 453 | * | 196 | * |
| 454 | ******************************************************************************/ | 197 | ******************************************************************************/ |
| 455 | 198 | ||
| 456 | acpi_status | 199 | struct acpi_rsconvert_info acpi_rs_set_vendor[7] = { |
| 457 | acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list, | 200 | /* Default is a small vendor descriptor */ |
| 458 | u8 ** output_buffer, acpi_size * bytes_consumed) | ||
| 459 | { | ||
| 460 | u8 *buffer = *output_buffer; | ||
| 461 | u16 temp16 = 0; | ||
| 462 | u8 temp8 = 0; | ||
| 463 | |||
| 464 | ACPI_FUNCTION_TRACE("rs_fixed_memory32_stream"); | ||
| 465 | 201 | ||
| 466 | /* The descriptor field is static */ | 202 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_SMALL, |
| 203 | sizeof(struct aml_resource_small_header), | ||
| 204 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_vendor)}, | ||
| 467 | 205 | ||
| 468 | *buffer = 0x86; | 206 | /* Get the length and copy the data */ |
| 469 | buffer += 1; | ||
| 470 | 207 | ||
| 471 | /* The length field is static */ | 208 | {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), |
| 209 | 0, | ||
| 210 | 0}, | ||
| 472 | 211 | ||
| 473 | temp16 = 0x09; | 212 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), |
| 213 | sizeof(struct aml_resource_small_header), | ||
| 214 | 0}, | ||
| 474 | 215 | ||
| 475 | ACPI_MOVE_16_TO_16(buffer, &temp16); | 216 | /* |
| 476 | buffer += 2; | 217 | * All done if the Vendor byte length is 7 or less, meaning that it will |
| 477 | 218 | * fit within a small descriptor | |
| 478 | /* Set the Information Byte */ | 219 | */ |
| 479 | 220 | {ACPI_RSC_EXIT_LE, 0, 0, 7}, | |
| 480 | temp8 = | ||
| 481 | (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01); | ||
| 482 | *buffer = temp8; | ||
| 483 | buffer += 1; | ||
| 484 | |||
| 485 | /* Set the Range base address */ | ||
| 486 | |||
| 487 | ACPI_MOVE_32_TO_32(buffer, | ||
| 488 | &linked_list->data.fixed_memory32. | ||
| 489 | range_base_address); | ||
| 490 | buffer += 4; | ||
| 491 | 221 | ||
| 492 | /* Set the range length */ | 222 | /* Must create a large vendor descriptor */ |
| 493 | 223 | ||
| 494 | ACPI_MOVE_32_TO_32(buffer, | 224 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_LARGE, |
| 495 | &linked_list->data.fixed_memory32.range_length); | 225 | sizeof(struct aml_resource_large_header), |
| 496 | buffer += 4; | 226 | 0}, |
| 497 | 227 | ||
| 498 | /* Return the number of bytes consumed in this operation */ | 228 | {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length), |
| 229 | 0, | ||
| 230 | 0}, | ||
| 499 | 231 | ||
| 500 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | 232 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]), |
| 501 | return_ACPI_STATUS(AE_OK); | 233 | sizeof(struct aml_resource_large_header), |
| 502 | } | 234 | 0} |
| 235 | }; | ||
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 7a8a34e757f5..ed866cf1c6d2 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -47,481 +47,501 @@ | |||
| 47 | #define _COMPONENT ACPI_RESOURCES | 47 | #define _COMPONENT ACPI_RESOURCES |
| 48 | ACPI_MODULE_NAME("rsmisc") | 48 | ACPI_MODULE_NAME("rsmisc") |
| 49 | 49 | ||
| 50 | #define INIT_RESOURCE_TYPE(i) i->resource_offset | ||
| 51 | #define INIT_RESOURCE_LENGTH(i) i->aml_offset | ||
| 52 | #define INIT_TABLE_LENGTH(i) i->value | ||
| 53 | #define COMPARE_OPCODE(i) i->resource_offset | ||
| 54 | #define COMPARE_TARGET(i) i->aml_offset | ||
| 55 | #define COMPARE_VALUE(i) i->value | ||
| 50 | /******************************************************************************* | 56 | /******************************************************************************* |
| 51 | * | 57 | * |
| 52 | * FUNCTION: acpi_rs_end_tag_resource | 58 | * FUNCTION: acpi_rs_convert_aml_to_resource |
| 53 | * | 59 | * |
| 54 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | 60 | * PARAMETERS: Resource - Pointer to the resource descriptor |
| 55 | * stream | 61 | * Aml - Where the AML descriptor is returned |
| 56 | * bytes_consumed - Pointer to where the number of bytes | 62 | * Info - Pointer to appropriate conversion table |
| 57 | * consumed the byte_stream_buffer is | ||
| 58 | * returned | ||
| 59 | * output_buffer - Pointer to the return data buffer | ||
| 60 | * structure_size - Pointer to where the number of bytes | ||
| 61 | * in the return data struct is returned | ||
| 62 | * | 63 | * |
| 63 | * RETURN: Status | 64 | * RETURN: Status |
| 64 | * | 65 | * |
| 65 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | 66 | * DESCRIPTION: Convert an external AML resource descriptor to the corresponding |
| 66 | * structure pointed to by the output_buffer. Return the | 67 | * internal resource descriptor |
| 67 | * number of bytes consumed from the byte stream. | ||
| 68 | * | 68 | * |
| 69 | ******************************************************************************/ | 69 | ******************************************************************************/ |
| 70 | acpi_status | 70 | acpi_status |
| 71 | acpi_rs_end_tag_resource(u8 * byte_stream_buffer, | 71 | acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, |
| 72 | acpi_size * bytes_consumed, | 72 | union aml_resource *aml, |
| 73 | u8 ** output_buffer, acpi_size * structure_size) | 73 | struct acpi_rsconvert_info *info) |
| 74 | { | 74 | { |
| 75 | struct acpi_resource *output_struct = (void *)*output_buffer; | 75 | acpi_rs_length aml_resource_length; |
| 76 | acpi_size struct_size = ACPI_RESOURCE_LENGTH; | 76 | void *source; |
| 77 | 77 | void *destination; | |
| 78 | ACPI_FUNCTION_TRACE("rs_end_tag_resource"); | 78 | char *target; |
| 79 | 79 | u8 count; | |
| 80 | /* The number of bytes consumed is static */ | 80 | u8 flags_mode = FALSE; |
| 81 | 81 | u16 item_count = 0; | |
| 82 | *bytes_consumed = 2; | ||
| 83 | |||
| 84 | /* Fill out the structure */ | ||
| 85 | |||
| 86 | output_struct->id = ACPI_RSTYPE_END_TAG; | ||
| 87 | |||
| 88 | /* Set the Length parameter */ | ||
| 89 | |||
| 90 | output_struct->length = 0; | ||
| 91 | |||
| 92 | /* Return the final size of the structure */ | ||
| 93 | |||
| 94 | *structure_size = struct_size; | ||
| 95 | return_ACPI_STATUS(AE_OK); | ||
| 96 | } | ||
| 97 | |||
| 98 | /******************************************************************************* | ||
| 99 | * | ||
| 100 | * FUNCTION: acpi_rs_end_tag_stream | ||
| 101 | * | ||
| 102 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 103 | * output_buffer - Pointer to the user's return buffer | ||
| 104 | * bytes_consumed - Pointer to where the number of bytes | ||
| 105 | * used in the output_buffer is returned | ||
| 106 | * | ||
| 107 | * RETURN: Status | ||
| 108 | * | ||
| 109 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 110 | * the appropriate bytes in a byte stream | ||
| 111 | * | ||
| 112 | ******************************************************************************/ | ||
| 113 | |||
| 114 | acpi_status | ||
| 115 | acpi_rs_end_tag_stream(struct acpi_resource *linked_list, | ||
| 116 | u8 ** output_buffer, acpi_size * bytes_consumed) | ||
| 117 | { | ||
| 118 | u8 *buffer = *output_buffer; | ||
| 119 | u8 temp8 = 0; | ||
| 120 | |||
| 121 | ACPI_FUNCTION_TRACE("rs_end_tag_stream"); | ||
| 122 | |||
| 123 | /* The descriptor field is static */ | ||
| 124 | |||
| 125 | *buffer = 0x79; | ||
| 126 | buffer += 1; | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Set the Checksum - zero means that the resource data is treated as if | ||
| 130 | * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8) | ||
| 131 | */ | ||
| 132 | temp8 = 0; | ||
| 133 | |||
| 134 | *buffer = temp8; | ||
| 135 | buffer += 1; | ||
| 136 | |||
| 137 | /* Return the number of bytes consumed in this operation */ | ||
| 138 | |||
| 139 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 140 | return_ACPI_STATUS(AE_OK); | ||
| 141 | } | ||
| 142 | |||
| 143 | /******************************************************************************* | ||
| 144 | * | ||
| 145 | * FUNCTION: acpi_rs_vendor_resource | ||
| 146 | * | ||
| 147 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 148 | * stream | ||
| 149 | * bytes_consumed - Pointer to where the number of bytes | ||
| 150 | * consumed the byte_stream_buffer is | ||
| 151 | * returned | ||
| 152 | * output_buffer - Pointer to the return data buffer | ||
| 153 | * structure_size - Pointer to where the number of bytes | ||
| 154 | * in the return data struct is returned | ||
| 155 | * | ||
| 156 | * RETURN: Status | ||
| 157 | * | ||
| 158 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 159 | * structure pointed to by the output_buffer. Return the | ||
| 160 | * number of bytes consumed from the byte stream. | ||
| 161 | * | ||
| 162 | ******************************************************************************/ | ||
| 163 | |||
| 164 | acpi_status | ||
| 165 | acpi_rs_vendor_resource(u8 * byte_stream_buffer, | ||
| 166 | acpi_size * bytes_consumed, | ||
| 167 | u8 ** output_buffer, acpi_size * structure_size) | ||
| 168 | { | ||
| 169 | u8 *buffer = byte_stream_buffer; | ||
| 170 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 171 | u16 temp16 = 0; | 82 | u16 temp16 = 0; |
| 172 | u8 temp8 = 0; | ||
| 173 | u8 index; | ||
| 174 | acpi_size struct_size = | ||
| 175 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor); | ||
| 176 | |||
| 177 | ACPI_FUNCTION_TRACE("rs_vendor_resource"); | ||
| 178 | |||
| 179 | /* Dereference the Descriptor to find if this is a large or small item. */ | ||
| 180 | |||
| 181 | temp8 = *buffer; | ||
| 182 | |||
| 183 | if (temp8 & 0x80) { | ||
| 184 | /* Large Item, point to the length field */ | ||
| 185 | |||
| 186 | buffer += 1; | ||
| 187 | 83 | ||
| 188 | /* Dereference */ | 84 | ACPI_FUNCTION_TRACE("rs_get_resource"); |
| 189 | 85 | ||
| 190 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 86 | if (((acpi_native_uint) resource) & 0x3) { |
| 87 | /* Each internal resource struct is expected to be 32-bit aligned */ | ||
| 191 | 88 | ||
| 192 | /* Calculate bytes consumed */ | 89 | ACPI_WARNING((AE_INFO, |
| 193 | 90 | "Misaligned resource pointer (get): %p Type %2.2X Len %X", | |
| 194 | *bytes_consumed = (acpi_size) temp16 + 3; | 91 | resource, resource->type, resource->length)); |
| 195 | |||
| 196 | /* Point to the first vendor byte */ | ||
| 197 | |||
| 198 | buffer += 2; | ||
| 199 | } else { | ||
| 200 | /* Small Item, dereference the size */ | ||
| 201 | |||
| 202 | temp16 = (u8) (*buffer & 0x07); | ||
| 203 | |||
| 204 | /* Calculate bytes consumed */ | ||
| 205 | |||
| 206 | *bytes_consumed = (acpi_size) temp16 + 1; | ||
| 207 | |||
| 208 | /* Point to the first vendor byte */ | ||
| 209 | |||
| 210 | buffer += 1; | ||
| 211 | } | 92 | } |
| 212 | 93 | ||
| 213 | output_struct->id = ACPI_RSTYPE_VENDOR; | 94 | /* Extract the resource Length field (does not include header length) */ |
| 214 | output_struct->data.vendor_specific.length = temp16; | ||
| 215 | 95 | ||
| 216 | for (index = 0; index < temp16; index++) { | 96 | aml_resource_length = acpi_ut_get_resource_length(aml); |
| 217 | output_struct->data.vendor_specific.reserved[index] = *buffer; | ||
| 218 | buffer += 1; | ||
| 219 | } | ||
| 220 | 97 | ||
| 221 | /* | 98 | /* |
| 222 | * In order for the struct_size to fall on a 32-bit boundary, | 99 | * First table entry must be ACPI_RSC_INITxxx and must contain the |
| 223 | * calculate the length of the vendor string and expand the | 100 | * table length (# of table entries) |
| 224 | * struct_size to the next 32-bit boundary. | ||
| 225 | */ | 101 | */ |
| 226 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp16); | 102 | count = INIT_TABLE_LENGTH(info); |
| 227 | 103 | ||
| 228 | /* Set the Length parameter */ | 104 | while (count) { |
| 229 | 105 | /* | |
| 230 | output_struct->length = (u32) struct_size; | 106 | * Source is the external AML byte stream buffer, |
| 231 | 107 | * destination is the internal resource descriptor | |
| 232 | /* Return the final size of the structure */ | 108 | */ |
| 233 | 109 | source = ACPI_ADD_PTR(void, aml, info->aml_offset); | |
| 234 | *structure_size = struct_size; | 110 | destination = |
| 235 | return_ACPI_STATUS(AE_OK); | 111 | ACPI_ADD_PTR(void, resource, info->resource_offset); |
| 236 | } | 112 | |
| 237 | 113 | switch (info->opcode) { | |
| 238 | /******************************************************************************* | 114 | case ACPI_RSC_INITGET: |
| 239 | * | 115 | /* |
| 240 | * FUNCTION: acpi_rs_vendor_stream | 116 | * Get the resource type and the initial (minimum) length |
| 241 | * | 117 | */ |
| 242 | * PARAMETERS: linked_list - Pointer to the resource linked list | 118 | ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info)); |
| 243 | * output_buffer - Pointer to the user's return buffer | 119 | resource->type = INIT_RESOURCE_TYPE(info); |
| 244 | * bytes_consumed - Pointer to where the number of bytes | 120 | resource->length = INIT_RESOURCE_LENGTH(info); |
| 245 | * used in the output_buffer is returned | 121 | break; |
| 246 | * | 122 | |
| 247 | * RETURN: Status | 123 | case ACPI_RSC_INITSET: |
| 248 | * | 124 | break; |
| 249 | * DESCRIPTION: Take the linked list resource structure and fills in the | 125 | |
| 250 | * the appropriate bytes in a byte stream | 126 | case ACPI_RSC_FLAGINIT: |
| 251 | * | 127 | |
| 252 | ******************************************************************************/ | 128 | flags_mode = TRUE; |
| 253 | 129 | break; | |
| 254 | acpi_status | 130 | |
| 255 | acpi_rs_vendor_stream(struct acpi_resource *linked_list, | 131 | case ACPI_RSC_1BITFLAG: |
| 256 | u8 ** output_buffer, acpi_size * bytes_consumed) | 132 | /* |
| 257 | { | 133 | * Mask and shift the flag bit |
| 258 | u8 *buffer = *output_buffer; | 134 | */ |
| 259 | u16 temp16 = 0; | 135 | ACPI_SET8(destination) = (u8) |
| 260 | u8 temp8 = 0; | 136 | ((ACPI_GET8(source) >> info->value) & 0x01); |
| 261 | u8 index; | 137 | break; |
| 262 | 138 | ||
| 263 | ACPI_FUNCTION_TRACE("rs_vendor_stream"); | 139 | case ACPI_RSC_2BITFLAG: |
| 264 | 140 | /* | |
| 265 | /* Dereference the length to find if this is a large or small item. */ | 141 | * Mask and shift the flag bits |
| 266 | 142 | */ | |
| 267 | if (linked_list->data.vendor_specific.length > 7) { | 143 | ACPI_SET8(destination) = (u8) |
| 268 | /* Large Item, Set the descriptor field and length bytes */ | 144 | ((ACPI_GET8(source) >> info->value) & 0x03); |
| 269 | 145 | break; | |
| 270 | *buffer = 0x84; | 146 | |
| 271 | buffer += 1; | 147 | case ACPI_RSC_COUNT: |
| 272 | 148 | ||
| 273 | temp16 = (u16) linked_list->data.vendor_specific.length; | 149 | item_count = ACPI_GET8(source); |
| 274 | 150 | ACPI_SET8(destination) = (u8) item_count; | |
| 275 | ACPI_MOVE_16_TO_16(buffer, &temp16); | 151 | |
| 276 | buffer += 2; | 152 | resource->length = resource->length + |
| 277 | } else { | 153 | (info->value * (item_count - 1)); |
| 278 | /* Small Item, Set the descriptor field */ | 154 | break; |
| 279 | 155 | ||
| 280 | temp8 = 0x70; | 156 | case ACPI_RSC_COUNT16: |
| 281 | temp8 |= (u8) linked_list->data.vendor_specific.length; | 157 | |
| 158 | item_count = aml_resource_length; | ||
| 159 | ACPI_SET16(destination) = item_count; | ||
| 160 | |||
| 161 | resource->length = resource->length + | ||
| 162 | (info->value * (item_count - 1)); | ||
| 163 | break; | ||
| 164 | |||
| 165 | case ACPI_RSC_LENGTH: | ||
| 166 | |||
| 167 | resource->length = resource->length + info->value; | ||
| 168 | break; | ||
| 169 | |||
| 170 | case ACPI_RSC_MOVE8: | ||
| 171 | case ACPI_RSC_MOVE16: | ||
| 172 | case ACPI_RSC_MOVE32: | ||
| 173 | case ACPI_RSC_MOVE64: | ||
| 174 | /* | ||
| 175 | * Raw data move. Use the Info value field unless item_count has | ||
| 176 | * been previously initialized via a COUNT opcode | ||
| 177 | */ | ||
| 178 | if (info->value) { | ||
| 179 | item_count = info->value; | ||
| 180 | } | ||
| 181 | acpi_rs_move_data(destination, source, item_count, | ||
| 182 | info->opcode); | ||
| 183 | break; | ||
| 184 | |||
| 185 | case ACPI_RSC_SET8: | ||
| 186 | |||
| 187 | ACPI_MEMSET(destination, info->aml_offset, info->value); | ||
| 188 | break; | ||
| 189 | |||
| 190 | case ACPI_RSC_DATA8: | ||
| 191 | |||
| 192 | target = ACPI_ADD_PTR(char, resource, info->value); | ||
| 193 | ACPI_MEMCPY(destination, source, ACPI_GET16(target)); | ||
| 194 | break; | ||
| 195 | |||
| 196 | case ACPI_RSC_ADDRESS: | ||
| 197 | /* | ||
| 198 | * Common handler for address descriptor flags | ||
| 199 | */ | ||
| 200 | if (!acpi_rs_get_address_common(resource, aml)) { | ||
| 201 | return_ACPI_STATUS | ||
| 202 | (AE_AML_INVALID_RESOURCE_TYPE); | ||
| 203 | } | ||
| 204 | break; | ||
| 205 | |||
| 206 | case ACPI_RSC_SOURCE: | ||
| 207 | /* | ||
| 208 | * Optional resource_source (Index and String) | ||
| 209 | */ | ||
| 210 | resource->length += | ||
| 211 | acpi_rs_get_resource_source(aml_resource_length, | ||
| 212 | info->value, | ||
| 213 | destination, aml, NULL); | ||
| 214 | break; | ||
| 215 | |||
| 216 | case ACPI_RSC_SOURCEX: | ||
| 217 | /* | ||
| 218 | * Optional resource_source (Index and String). This is the more | ||
| 219 | * complicated case used by the Interrupt() macro | ||
| 220 | */ | ||
| 221 | target = | ||
| 222 | ACPI_ADD_PTR(char, resource, | ||
| 223 | info->aml_offset + (item_count * 4)); | ||
| 224 | |||
| 225 | resource->length += | ||
| 226 | acpi_rs_get_resource_source(aml_resource_length, | ||
| 227 | (acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target); | ||
| 228 | break; | ||
| 229 | |||
| 230 | case ACPI_RSC_BITMASK: | ||
| 231 | /* | ||
| 232 | * 8-bit encoded bitmask (DMA macro) | ||
| 233 | */ | ||
| 234 | item_count = | ||
| 235 | acpi_rs_decode_bitmask(ACPI_GET8(source), | ||
| 236 | destination); | ||
| 237 | if (item_count) { | ||
| 238 | resource->length += (item_count - 1); | ||
| 239 | } | ||
| 240 | |||
| 241 | target = ACPI_ADD_PTR(char, resource, info->value); | ||
| 242 | ACPI_SET8(target) = (u8) item_count; | ||
| 243 | break; | ||
| 244 | |||
| 245 | case ACPI_RSC_BITMASK16: | ||
| 246 | /* | ||
| 247 | * 16-bit encoded bitmask (IRQ macro) | ||
| 248 | */ | ||
| 249 | ACPI_MOVE_16_TO_16(&temp16, source); | ||
| 250 | |||
| 251 | item_count = | ||
| 252 | acpi_rs_decode_bitmask(temp16, destination); | ||
| 253 | if (item_count) { | ||
| 254 | resource->length += (item_count - 1); | ||
| 255 | } | ||
| 256 | |||
| 257 | target = ACPI_ADD_PTR(char, resource, info->value); | ||
| 258 | ACPI_SET8(target) = (u8) item_count; | ||
| 259 | break; | ||
| 260 | |||
| 261 | case ACPI_RSC_EXIT_NE: | ||
| 262 | /* | ||
| 263 | * Control - Exit conversion if not equal | ||
| 264 | */ | ||
| 265 | switch (info->resource_offset) { | ||
| 266 | case ACPI_RSC_COMPARE_AML_LENGTH: | ||
| 267 | if (aml_resource_length != info->value) { | ||
| 268 | goto exit; | ||
| 269 | } | ||
| 270 | break; | ||
| 271 | |||
| 272 | case ACPI_RSC_COMPARE_VALUE: | ||
| 273 | if (ACPI_GET8(source) != info->value) { | ||
| 274 | goto exit; | ||
| 275 | } | ||
| 276 | break; | ||
| 277 | |||
| 278 | default: | ||
| 279 | |||
| 280 | ACPI_ERROR((AE_INFO, | ||
| 281 | "Invalid conversion sub-opcode")); | ||
| 282 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 283 | } | ||
| 284 | break; | ||
| 285 | |||
| 286 | default: | ||
| 287 | |||
| 288 | ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); | ||
| 289 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 290 | } | ||
| 282 | 291 | ||
| 283 | *buffer = temp8; | 292 | count--; |
| 284 | buffer += 1; | 293 | info++; |
| 285 | } | 294 | } |
| 286 | 295 | ||
| 287 | /* Loop through all of the Vendor Specific fields */ | 296 | exit: |
| 297 | if (!flags_mode) { | ||
| 298 | /* Round the resource struct length up to the next 32-bit boundary */ | ||
| 288 | 299 | ||
| 289 | for (index = 0; index < linked_list->data.vendor_specific.length; | 300 | resource->length = ACPI_ROUND_UP_to_32_bITS(resource->length); |
| 290 | index++) { | ||
| 291 | temp8 = linked_list->data.vendor_specific.reserved[index]; | ||
| 292 | |||
| 293 | *buffer = temp8; | ||
| 294 | buffer += 1; | ||
| 295 | } | 301 | } |
| 296 | |||
| 297 | /* Return the number of bytes consumed in this operation */ | ||
| 298 | |||
| 299 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 300 | return_ACPI_STATUS(AE_OK); | 302 | return_ACPI_STATUS(AE_OK); |
| 301 | } | 303 | } |
| 302 | 304 | ||
| 303 | /******************************************************************************* | 305 | /******************************************************************************* |
| 304 | * | 306 | * |
| 305 | * FUNCTION: acpi_rs_start_depend_fns_resource | 307 | * FUNCTION: acpi_rs_convert_resource_to_aml |
| 306 | * | 308 | * |
| 307 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | 309 | * PARAMETERS: Resource - Pointer to the resource descriptor |
| 308 | * stream | 310 | * Aml - Where the AML descriptor is returned |
| 309 | * bytes_consumed - Pointer to where the number of bytes | 311 | * Info - Pointer to appropriate conversion table |
| 310 | * consumed the byte_stream_buffer is | ||
| 311 | * returned | ||
| 312 | * output_buffer - Pointer to the return data buffer | ||
| 313 | * structure_size - Pointer to where the number of bytes | ||
| 314 | * in the return data struct is returned | ||
| 315 | * | 312 | * |
| 316 | * RETURN: Status | 313 | * RETURN: Status |
| 317 | * | 314 | * |
| 318 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | 315 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding |
| 319 | * structure pointed to by the output_buffer. Return the | 316 | * external AML resource descriptor. |
| 320 | * number of bytes consumed from the byte stream. | ||
| 321 | * | 317 | * |
| 322 | ******************************************************************************/ | 318 | ******************************************************************************/ |
| 323 | 319 | ||
| 324 | acpi_status | 320 | acpi_status |
| 325 | acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer, | 321 | acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, |
| 326 | acpi_size * bytes_consumed, | 322 | union aml_resource *aml, |
| 327 | u8 ** output_buffer, | 323 | struct acpi_rsconvert_info *info) |
| 328 | acpi_size * structure_size) | ||
| 329 | { | 324 | { |
| 330 | u8 *buffer = byte_stream_buffer; | 325 | void *source = NULL; |
| 331 | struct acpi_resource *output_struct = (void *)*output_buffer; | 326 | void *destination; |
| 332 | u8 temp8 = 0; | 327 | acpi_rsdesc_size aml_length = 0; |
| 333 | acpi_size struct_size = | 328 | u8 count; |
| 334 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf); | 329 | u16 temp16 = 0; |
| 335 | 330 | u16 item_count = 0; | |
| 336 | ACPI_FUNCTION_TRACE("rs_start_depend_fns_resource"); | ||
| 337 | |||
| 338 | /* The number of bytes consumed are found in the descriptor (Bits:0-1) */ | ||
| 339 | |||
| 340 | temp8 = *buffer; | ||
| 341 | |||
| 342 | *bytes_consumed = (temp8 & 0x01) + 1; | ||
| 343 | |||
| 344 | output_struct->id = ACPI_RSTYPE_START_DPF; | ||
| 345 | |||
| 346 | /* Point to Byte 1 if it is used */ | ||
| 347 | |||
| 348 | if (2 == *bytes_consumed) { | ||
| 349 | buffer += 1; | ||
| 350 | temp8 = *buffer; | ||
| 351 | |||
| 352 | /* Check Compatibility priority */ | ||
| 353 | |||
| 354 | output_struct->data.start_dpf.compatibility_priority = | ||
| 355 | temp8 & 0x03; | ||
| 356 | |||
| 357 | if (3 == output_struct->data.start_dpf.compatibility_priority) { | ||
| 358 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); | ||
| 359 | } | ||
| 360 | |||
| 361 | /* Check Performance/Robustness preference */ | ||
| 362 | 331 | ||
| 363 | output_struct->data.start_dpf.performance_robustness = | 332 | ACPI_FUNCTION_TRACE("rs_convert_resource_to_aml"); |
| 364 | (temp8 >> 2) & 0x03; | ||
| 365 | 333 | ||
| 366 | if (3 == output_struct->data.start_dpf.performance_robustness) { | 334 | /* |
| 367 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); | 335 | * First table entry must be ACPI_RSC_INITxxx and must contain the |
| 336 | * table length (# of table entries) | ||
| 337 | */ | ||
| 338 | count = INIT_TABLE_LENGTH(info); | ||
| 339 | |||
| 340 | while (count) { | ||
| 341 | /* | ||
| 342 | * Source is the internal resource descriptor, | ||
| 343 | * destination is the external AML byte stream buffer | ||
| 344 | */ | ||
| 345 | source = ACPI_ADD_PTR(void, resource, info->resource_offset); | ||
| 346 | destination = ACPI_ADD_PTR(void, aml, info->aml_offset); | ||
| 347 | |||
| 348 | switch (info->opcode) { | ||
| 349 | case ACPI_RSC_INITSET: | ||
| 350 | |||
| 351 | ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info)); | ||
| 352 | aml_length = INIT_RESOURCE_LENGTH(info); | ||
| 353 | acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info), | ||
| 354 | aml_length, aml); | ||
| 355 | break; | ||
| 356 | |||
| 357 | case ACPI_RSC_INITGET: | ||
| 358 | break; | ||
| 359 | |||
| 360 | case ACPI_RSC_FLAGINIT: | ||
| 361 | /* | ||
| 362 | * Clear the flag byte | ||
| 363 | */ | ||
| 364 | ACPI_SET8(destination) = 0; | ||
| 365 | break; | ||
| 366 | |||
| 367 | case ACPI_RSC_1BITFLAG: | ||
| 368 | /* | ||
| 369 | * Mask and shift the flag bit | ||
| 370 | */ | ||
| 371 | ACPI_SET8(destination) |= (u8) | ||
| 372 | ((ACPI_GET8(source) & 0x01) << info->value); | ||
| 373 | break; | ||
| 374 | |||
| 375 | case ACPI_RSC_2BITFLAG: | ||
| 376 | /* | ||
| 377 | * Mask and shift the flag bits | ||
| 378 | */ | ||
| 379 | ACPI_SET8(destination) |= (u8) | ||
| 380 | ((ACPI_GET8(source) & 0x03) << info->value); | ||
| 381 | break; | ||
| 382 | |||
| 383 | case ACPI_RSC_COUNT: | ||
| 384 | |||
| 385 | item_count = ACPI_GET8(source); | ||
| 386 | ACPI_SET8(destination) = (u8) item_count; | ||
| 387 | |||
| 388 | aml_length = | ||
| 389 | (u16) (aml_length + | ||
| 390 | (info->value * (item_count - 1))); | ||
| 391 | break; | ||
| 392 | |||
| 393 | case ACPI_RSC_COUNT16: | ||
| 394 | |||
| 395 | item_count = ACPI_GET16(source); | ||
| 396 | aml_length = (u16) (aml_length + item_count); | ||
| 397 | acpi_rs_set_resource_length(aml_length, aml); | ||
| 398 | break; | ||
| 399 | |||
| 400 | case ACPI_RSC_LENGTH: | ||
| 401 | |||
| 402 | acpi_rs_set_resource_length(info->value, aml); | ||
| 403 | break; | ||
| 404 | |||
| 405 | case ACPI_RSC_MOVE8: | ||
| 406 | case ACPI_RSC_MOVE16: | ||
| 407 | case ACPI_RSC_MOVE32: | ||
| 408 | case ACPI_RSC_MOVE64: | ||
| 409 | |||
| 410 | if (info->value) { | ||
| 411 | item_count = info->value; | ||
| 412 | } | ||
| 413 | acpi_rs_move_data(destination, source, item_count, | ||
| 414 | info->opcode); | ||
| 415 | break; | ||
| 416 | |||
| 417 | case ACPI_RSC_ADDRESS: | ||
| 418 | |||
| 419 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ | ||
| 420 | |||
| 421 | acpi_rs_set_address_common(aml, resource); | ||
| 422 | break; | ||
| 423 | |||
| 424 | case ACPI_RSC_SOURCEX: | ||
| 425 | /* | ||
| 426 | * Optional resource_source (Index and String) | ||
| 427 | */ | ||
| 428 | aml_length = | ||
| 429 | acpi_rs_set_resource_source(aml, | ||
| 430 | (acpi_rs_length) | ||
| 431 | aml_length, source); | ||
| 432 | acpi_rs_set_resource_length(aml_length, aml); | ||
| 433 | break; | ||
| 434 | |||
| 435 | case ACPI_RSC_SOURCE: | ||
| 436 | /* | ||
| 437 | * Optional resource_source (Index and String). This is the more | ||
| 438 | * complicated case used by the Interrupt() macro | ||
| 439 | */ | ||
| 440 | aml_length = | ||
| 441 | acpi_rs_set_resource_source(aml, info->value, | ||
| 442 | source); | ||
| 443 | acpi_rs_set_resource_length(aml_length, aml); | ||
| 444 | break; | ||
| 445 | |||
| 446 | case ACPI_RSC_BITMASK: | ||
| 447 | /* | ||
| 448 | * 8-bit encoded bitmask (DMA macro) | ||
| 449 | */ | ||
| 450 | ACPI_SET8(destination) = (u8) | ||
| 451 | acpi_rs_encode_bitmask(source, | ||
| 452 | *ACPI_ADD_PTR(u8, resource, | ||
| 453 | info->value)); | ||
| 454 | break; | ||
| 455 | |||
| 456 | case ACPI_RSC_BITMASK16: | ||
| 457 | /* | ||
| 458 | * 16-bit encoded bitmask (IRQ macro) | ||
| 459 | */ | ||
| 460 | temp16 = acpi_rs_encode_bitmask(source, | ||
| 461 | *ACPI_ADD_PTR(u8, | ||
| 462 | resource, | ||
| 463 | info-> | ||
| 464 | value)); | ||
| 465 | ACPI_MOVE_16_TO_16(destination, &temp16); | ||
| 466 | break; | ||
| 467 | |||
| 468 | case ACPI_RSC_EXIT_LE: | ||
| 469 | /* | ||
| 470 | * Control - Exit conversion if less than or equal | ||
| 471 | */ | ||
| 472 | if (item_count <= info->value) { | ||
| 473 | goto exit; | ||
| 474 | } | ||
| 475 | break; | ||
| 476 | |||
| 477 | case ACPI_RSC_EXIT_NE: | ||
| 478 | /* | ||
| 479 | * Control - Exit conversion if not equal | ||
| 480 | */ | ||
| 481 | switch (COMPARE_OPCODE(info)) { | ||
| 482 | case ACPI_RSC_COMPARE_VALUE: | ||
| 483 | |||
| 484 | if (*ACPI_ADD_PTR(u8, resource, | ||
| 485 | COMPARE_TARGET(info)) != | ||
| 486 | COMPARE_VALUE(info)) { | ||
| 487 | goto exit; | ||
| 488 | } | ||
| 489 | break; | ||
| 490 | |||
| 491 | default: | ||
| 492 | |||
| 493 | ACPI_ERROR((AE_INFO, | ||
| 494 | "Invalid conversion sub-opcode")); | ||
| 495 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 496 | } | ||
| 497 | break; | ||
| 498 | |||
| 499 | default: | ||
| 500 | |||
| 501 | ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); | ||
| 502 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 368 | } | 503 | } |
| 369 | } else { | ||
| 370 | output_struct->data.start_dpf.compatibility_priority = | ||
| 371 | ACPI_ACCEPTABLE_CONFIGURATION; | ||
| 372 | 504 | ||
| 373 | output_struct->data.start_dpf.performance_robustness = | 505 | count--; |
| 374 | ACPI_ACCEPTABLE_CONFIGURATION; | 506 | info++; |
| 375 | } | 507 | } |
| 376 | 508 | ||
| 377 | /* Set the Length parameter */ | 509 | exit: |
| 378 | |||
| 379 | output_struct->length = (u32) struct_size; | ||
| 380 | |||
| 381 | /* Return the final size of the structure */ | ||
| 382 | |||
| 383 | *structure_size = struct_size; | ||
| 384 | return_ACPI_STATUS(AE_OK); | 510 | return_ACPI_STATUS(AE_OK); |
| 385 | } | 511 | } |
| 386 | 512 | ||
| 387 | /******************************************************************************* | 513 | #if 0 |
| 388 | * | 514 | /* Previous resource validations */ |
| 389 | * FUNCTION: acpi_rs_end_depend_fns_resource | ||
| 390 | * | ||
| 391 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
| 392 | * stream | ||
| 393 | * bytes_consumed - Pointer to where the number of bytes | ||
| 394 | * consumed the byte_stream_buffer is | ||
| 395 | * returned | ||
| 396 | * output_buffer - Pointer to the return data buffer | ||
| 397 | * structure_size - Pointer to where the number of bytes | ||
| 398 | * in the return data struct is returned | ||
| 399 | * | ||
| 400 | * RETURN: Status | ||
| 401 | * | ||
| 402 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
| 403 | * structure pointed to by the output_buffer. Return the | ||
| 404 | * number of bytes consumed from the byte stream. | ||
| 405 | * | ||
| 406 | ******************************************************************************/ | ||
| 407 | |||
| 408 | acpi_status | ||
| 409 | acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer, | ||
| 410 | acpi_size * bytes_consumed, | ||
| 411 | u8 ** output_buffer, acpi_size * structure_size) | ||
| 412 | { | ||
| 413 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
| 414 | acpi_size struct_size = ACPI_RESOURCE_LENGTH; | ||
| 415 | |||
| 416 | ACPI_FUNCTION_TRACE("rs_end_depend_fns_resource"); | ||
| 417 | |||
| 418 | /* The number of bytes consumed is static */ | ||
| 419 | |||
| 420 | *bytes_consumed = 1; | ||
| 421 | 515 | ||
| 422 | /* Fill out the structure */ | 516 | if (aml->ext_address64.revision_iD != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) { |
| 423 | 517 | return_ACPI_STATUS(AE_SUPPORT); | |
| 424 | output_struct->id = ACPI_RSTYPE_END_DPF; | ||
| 425 | |||
| 426 | /* Set the Length parameter */ | ||
| 427 | |||
| 428 | output_struct->length = (u32) struct_size; | ||
| 429 | |||
| 430 | /* Return the final size of the structure */ | ||
| 431 | |||
| 432 | *structure_size = struct_size; | ||
| 433 | return_ACPI_STATUS(AE_OK); | ||
| 434 | } | 518 | } |
| 435 | 519 | ||
| 436 | /******************************************************************************* | 520 | if (resource->data.start_dpf.performance_robustness >= 3) { |
| 437 | * | 521 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); |
| 438 | * FUNCTION: acpi_rs_start_depend_fns_stream | 522 | } |
| 439 | * | ||
| 440 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 441 | * output_buffer - Pointer to the user's return buffer | ||
| 442 | * bytes_consumed - u32 pointer that is filled with | ||
| 443 | * the number of bytes of the | ||
| 444 | * output_buffer used | ||
| 445 | * | ||
| 446 | * RETURN: Status | ||
| 447 | * | ||
| 448 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 449 | * the appropriate bytes in a byte stream | ||
| 450 | * | ||
| 451 | ******************************************************************************/ | ||
| 452 | |||
| 453 | acpi_status | ||
| 454 | acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list, | ||
| 455 | u8 ** output_buffer, acpi_size * bytes_consumed) | ||
| 456 | { | ||
| 457 | u8 *buffer = *output_buffer; | ||
| 458 | u8 temp8 = 0; | ||
| 459 | |||
| 460 | ACPI_FUNCTION_TRACE("rs_start_depend_fns_stream"); | ||
| 461 | 523 | ||
| 524 | if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) { | ||
| 462 | /* | 525 | /* |
| 463 | * The descriptor field is set based upon whether a byte is needed | 526 | * Only [active_high, edge_sensitive] or [active_low, level_sensitive] |
| 464 | * to contain Priority data. | 527 | * polarity/trigger interrupts are allowed (ACPI spec, section |
| 528 | * "IRQ Format"), so 0x00 and 0x09 are illegal. | ||
| 465 | */ | 529 | */ |
| 466 | if (ACPI_ACCEPTABLE_CONFIGURATION == | 530 | ACPI_ERROR((AE_INFO, |
| 467 | linked_list->data.start_dpf.compatibility_priority && | 531 | "Invalid interrupt polarity/trigger in resource list, %X", |
| 468 | ACPI_ACCEPTABLE_CONFIGURATION == | 532 | aml->irq.flags)); |
| 469 | linked_list->data.start_dpf.performance_robustness) { | 533 | return_ACPI_STATUS(AE_BAD_DATA); |
| 470 | *buffer = 0x30; | ||
| 471 | } else { | ||
| 472 | *buffer = 0x31; | ||
| 473 | buffer += 1; | ||
| 474 | |||
| 475 | /* Set the Priority Byte Definition */ | ||
| 476 | |||
| 477 | temp8 = 0; | ||
| 478 | temp8 = | ||
| 479 | (u8) ((linked_list->data.start_dpf. | ||
| 480 | performance_robustness & 0x03) << 2); | ||
| 481 | temp8 |= | ||
| 482 | (linked_list->data.start_dpf.compatibility_priority & 0x03); | ||
| 483 | *buffer = temp8; | ||
| 484 | } | ||
| 485 | |||
| 486 | buffer += 1; | ||
| 487 | |||
| 488 | /* Return the number of bytes consumed in this operation */ | ||
| 489 | |||
| 490 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
| 491 | return_ACPI_STATUS(AE_OK); | ||
| 492 | } | 534 | } |
| 493 | 535 | ||
| 494 | /******************************************************************************* | 536 | resource->data.extended_irq.interrupt_count = temp8; |
| 495 | * | 537 | if (temp8 < 1) { |
| 496 | * FUNCTION: acpi_rs_end_depend_fns_stream | 538 | /* Must have at least one IRQ */ |
| 497 | * | ||
| 498 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
| 499 | * output_buffer - Pointer to the user's return buffer | ||
| 500 | * bytes_consumed - Pointer to where the number of bytes | ||
| 501 | * used in the output_buffer is returned | ||
| 502 | * | ||
| 503 | * RETURN: Status | ||
| 504 | * | ||
| 505 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
| 506 | * the appropriate bytes in a byte stream | ||
| 507 | * | ||
| 508 | ******************************************************************************/ | ||
| 509 | |||
| 510 | acpi_status | ||
| 511 | acpi_rs_end_depend_fns_stream(struct acpi_resource *linked_list, | ||
| 512 | u8 ** output_buffer, acpi_size * bytes_consumed) | ||
| 513 | { | ||
| 514 | u8 *buffer = *output_buffer; | ||
| 515 | |||
| 516 | ACPI_FUNCTION_TRACE("rs_end_depend_fns_stream"); | ||
| 517 | |||
| 518 | /* The descriptor field is static */ | ||
| 519 | |||
| 520 | *buffer = 0x38; | ||
| 521 | buffer += 1; | ||
| 522 | 539 | ||
| 523 | /* Return the number of bytes consumed in this operation */ | 540 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); |
| 541 | } | ||
| 524 | 542 | ||
| 525 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | 543 | if (resource->data.dma.transfer == 0x03) { |
| 526 | return_ACPI_STATUS(AE_OK); | 544 | ACPI_ERROR((AE_INFO, "Invalid DMA.Transfer preference (3)")); |
| 545 | return_ACPI_STATUS(AE_BAD_DATA); | ||
| 527 | } | 546 | } |
| 547 | #endif | ||
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 4446778eaf79..25b5aedd6612 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -50,6 +50,389 @@ ACPI_MODULE_NAME("rsutils") | |||
| 50 | 50 | ||
| 51 | /******************************************************************************* | 51 | /******************************************************************************* |
| 52 | * | 52 | * |
| 53 | * FUNCTION: acpi_rs_decode_bitmask | ||
| 54 | * | ||
| 55 | * PARAMETERS: Mask - Bitmask to decode | ||
| 56 | * List - Where the converted list is returned | ||
| 57 | * | ||
| 58 | * RETURN: Count of bits set (length of list) | ||
| 59 | * | ||
| 60 | * DESCRIPTION: Convert a bit mask into a list of values | ||
| 61 | * | ||
| 62 | ******************************************************************************/ | ||
| 63 | u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) | ||
| 64 | { | ||
| 65 | acpi_native_uint i; | ||
| 66 | u8 bit_count; | ||
| 67 | |||
| 68 | ACPI_FUNCTION_ENTRY(); | ||
| 69 | |||
| 70 | /* Decode the mask bits */ | ||
| 71 | |||
| 72 | for (i = 0, bit_count = 0; mask; i++) { | ||
| 73 | if (mask & 0x0001) { | ||
| 74 | list[bit_count] = (u8) i; | ||
| 75 | bit_count++; | ||
| 76 | } | ||
| 77 | |||
| 78 | mask >>= 1; | ||
| 79 | } | ||
| 80 | |||
| 81 | return (bit_count); | ||
| 82 | } | ||
| 83 | |||
| 84 | /******************************************************************************* | ||
| 85 | * | ||
| 86 | * FUNCTION: acpi_rs_encode_bitmask | ||
| 87 | * | ||
| 88 | * PARAMETERS: List - List of values to encode | ||
| 89 | * Count - Length of list | ||
| 90 | * | ||
| 91 | * RETURN: Encoded bitmask | ||
| 92 | * | ||
| 93 | * DESCRIPTION: Convert a list of values to an encoded bitmask | ||
| 94 | * | ||
| 95 | ******************************************************************************/ | ||
| 96 | |||
| 97 | u16 acpi_rs_encode_bitmask(u8 * list, u8 count) | ||
| 98 | { | ||
| 99 | acpi_native_uint i; | ||
| 100 | u16 mask; | ||
| 101 | |||
| 102 | ACPI_FUNCTION_ENTRY(); | ||
| 103 | |||
| 104 | /* Encode the list into a single bitmask */ | ||
| 105 | |||
| 106 | for (i = 0, mask = 0; i < count; i++) { | ||
| 107 | mask |= (0x0001 << list[i]); | ||
| 108 | } | ||
| 109 | |||
| 110 | return (mask); | ||
| 111 | } | ||
| 112 | |||
| 113 | /******************************************************************************* | ||
| 114 | * | ||
| 115 | * FUNCTION: acpi_rs_move_data | ||
| 116 | * | ||
| 117 | * PARAMETERS: Destination - Pointer to the destination descriptor | ||
| 118 | * Source - Pointer to the source descriptor | ||
| 119 | * item_count - How many items to move | ||
| 120 | * move_type - Byte width | ||
| 121 | * | ||
| 122 | * RETURN: None | ||
| 123 | * | ||
| 124 | * DESCRIPTION: Move multiple data items from one descriptor to another. Handles | ||
| 125 | * alignment issues and endian issues if necessary, as configured | ||
| 126 | * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) | ||
| 127 | * | ||
| 128 | ******************************************************************************/ | ||
| 129 | |||
| 130 | void | ||
| 131 | acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) | ||
| 132 | { | ||
| 133 | acpi_native_uint i; | ||
| 134 | |||
| 135 | ACPI_FUNCTION_ENTRY(); | ||
| 136 | |||
| 137 | /* One move per item */ | ||
| 138 | |||
| 139 | for (i = 0; i < item_count; i++) { | ||
| 140 | switch (move_type) { | ||
| 141 | /* | ||
| 142 | * For the 8-bit case, we can perform the move all at once | ||
| 143 | * since there are no alignment or endian issues | ||
| 144 | */ | ||
| 145 | case ACPI_RSC_MOVE8: | ||
| 146 | ACPI_MEMCPY(destination, source, item_count); | ||
| 147 | return; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * 16-, 32-, and 64-bit cases must use the move macros that perform | ||
| 151 | * endian conversion and/or accomodate hardware that cannot perform | ||
| 152 | * misaligned memory transfers | ||
| 153 | */ | ||
| 154 | case ACPI_RSC_MOVE16: | ||
| 155 | ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i], | ||
| 156 | &ACPI_CAST_PTR(u16, source)[i]); | ||
| 157 | break; | ||
| 158 | |||
| 159 | case ACPI_RSC_MOVE32: | ||
| 160 | ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i], | ||
| 161 | &ACPI_CAST_PTR(u32, source)[i]); | ||
| 162 | break; | ||
| 163 | |||
| 164 | case ACPI_RSC_MOVE64: | ||
| 165 | ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i], | ||
| 166 | &ACPI_CAST_PTR(u64, source)[i]); | ||
| 167 | break; | ||
| 168 | |||
| 169 | default: | ||
| 170 | return; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | /******************************************************************************* | ||
| 176 | * | ||
| 177 | * FUNCTION: acpi_rs_set_resource_length | ||
| 178 | * | ||
| 179 | * PARAMETERS: total_length - Length of the AML descriptor, including | ||
| 180 | * the header and length fields. | ||
| 181 | * Aml - Pointer to the raw AML descriptor | ||
| 182 | * | ||
| 183 | * RETURN: None | ||
| 184 | * | ||
| 185 | * DESCRIPTION: Set the resource_length field of an AML | ||
| 186 | * resource descriptor, both Large and Small descriptors are | ||
| 187 | * supported automatically. Note: Descriptor Type field must | ||
| 188 | * be valid. | ||
| 189 | * | ||
| 190 | ******************************************************************************/ | ||
| 191 | |||
| 192 | void | ||
| 193 | acpi_rs_set_resource_length(acpi_rsdesc_size total_length, | ||
| 194 | union aml_resource *aml) | ||
| 195 | { | ||
| 196 | acpi_rs_length resource_length; | ||
| 197 | |||
| 198 | ACPI_FUNCTION_ENTRY(); | ||
| 199 | |||
| 200 | /* Length is the total descriptor length minus the header length */ | ||
| 201 | |||
| 202 | resource_length = (acpi_rs_length) | ||
| 203 | (total_length - acpi_ut_get_resource_header_length(aml)); | ||
| 204 | |||
| 205 | /* Length is stored differently for large and small descriptors */ | ||
| 206 | |||
| 207 | if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { | ||
| 208 | /* Large descriptor -- bytes 1-2 contain the 16-bit length */ | ||
| 209 | |||
| 210 | ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, | ||
| 211 | &resource_length); | ||
| 212 | } else { | ||
| 213 | /* Small descriptor -- bits 2:0 of byte 0 contain the length */ | ||
| 214 | |||
| 215 | aml->small_header.descriptor_type = (u8) | ||
| 216 | |||
| 217 | /* Clear any existing length, preserving descriptor type bits */ | ||
| 218 | ((aml->small_header. | ||
| 219 | descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK) | ||
| 220 | |||
| 221 | | resource_length); | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | /******************************************************************************* | ||
| 226 | * | ||
| 227 | * FUNCTION: acpi_rs_set_resource_header | ||
| 228 | * | ||
| 229 | * PARAMETERS: descriptor_type - Byte to be inserted as the type | ||
| 230 | * total_length - Length of the AML descriptor, including | ||
| 231 | * the header and length fields. | ||
| 232 | * Aml - Pointer to the raw AML descriptor | ||
| 233 | * | ||
| 234 | * RETURN: None | ||
| 235 | * | ||
| 236 | * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML | ||
| 237 | * resource descriptor, both Large and Small descriptors are | ||
| 238 | * supported automatically | ||
| 239 | * | ||
| 240 | ******************************************************************************/ | ||
| 241 | |||
| 242 | void | ||
| 243 | acpi_rs_set_resource_header(u8 descriptor_type, | ||
| 244 | acpi_rsdesc_size total_length, | ||
| 245 | union aml_resource *aml) | ||
| 246 | { | ||
| 247 | ACPI_FUNCTION_ENTRY(); | ||
| 248 | |||
| 249 | /* Set the Resource Type */ | ||
| 250 | |||
| 251 | aml->small_header.descriptor_type = descriptor_type; | ||
| 252 | |||
| 253 | /* Set the Resource Length */ | ||
| 254 | |||
| 255 | acpi_rs_set_resource_length(total_length, aml); | ||
| 256 | } | ||
| 257 | |||
| 258 | /******************************************************************************* | ||
| 259 | * | ||
| 260 | * FUNCTION: acpi_rs_strcpy | ||
| 261 | * | ||
| 262 | * PARAMETERS: Destination - Pointer to the destination string | ||
| 263 | * Source - Pointer to the source string | ||
| 264 | * | ||
| 265 | * RETURN: String length, including NULL terminator | ||
| 266 | * | ||
| 267 | * DESCRIPTION: Local string copy that returns the string length, saving a | ||
| 268 | * strcpy followed by a strlen. | ||
| 269 | * | ||
| 270 | ******************************************************************************/ | ||
| 271 | |||
| 272 | static u16 acpi_rs_strcpy(char *destination, char *source) | ||
| 273 | { | ||
| 274 | u16 i; | ||
| 275 | |||
| 276 | ACPI_FUNCTION_ENTRY(); | ||
| 277 | |||
| 278 | for (i = 0; source[i]; i++) { | ||
| 279 | destination[i] = source[i]; | ||
| 280 | } | ||
| 281 | |||
| 282 | destination[i] = 0; | ||
| 283 | |||
| 284 | /* Return string length including the NULL terminator */ | ||
| 285 | |||
| 286 | return ((u16) (i + 1)); | ||
| 287 | } | ||
| 288 | |||
| 289 | /******************************************************************************* | ||
| 290 | * | ||
| 291 | * FUNCTION: acpi_rs_get_resource_source | ||
| 292 | * | ||
| 293 | * PARAMETERS: resource_length - Length field of the descriptor | ||
| 294 | * minimum_length - Minimum length of the descriptor (minus | ||
| 295 | * any optional fields) | ||
| 296 | * resource_source - Where the resource_source is returned | ||
| 297 | * Aml - Pointer to the raw AML descriptor | ||
| 298 | * string_ptr - (optional) where to store the actual | ||
| 299 | * resource_source string | ||
| 300 | * | ||
| 301 | * RETURN: Length of the string plus NULL terminator, rounded up to 32 bit | ||
| 302 | * | ||
| 303 | * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor | ||
| 304 | * to an internal resource descriptor | ||
| 305 | * | ||
| 306 | ******************************************************************************/ | ||
| 307 | |||
| 308 | acpi_rs_length | ||
| 309 | acpi_rs_get_resource_source(acpi_rs_length resource_length, | ||
| 310 | acpi_rs_length minimum_length, | ||
| 311 | struct acpi_resource_source * resource_source, | ||
| 312 | union aml_resource * aml, char *string_ptr) | ||
| 313 | { | ||
| 314 | acpi_rsdesc_size total_length; | ||
| 315 | u8 *aml_resource_source; | ||
| 316 | |||
| 317 | ACPI_FUNCTION_ENTRY(); | ||
| 318 | |||
| 319 | total_length = | ||
| 320 | resource_length + sizeof(struct aml_resource_large_header); | ||
| 321 | aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); | ||
| 322 | |||
| 323 | /* | ||
| 324 | * resource_source is present if the length of the descriptor is longer than | ||
| 325 | * the minimum length. | ||
| 326 | * | ||
| 327 | * Note: Some resource descriptors will have an additional null, so | ||
| 328 | * we add 1 to the minimum length. | ||
| 329 | */ | ||
| 330 | if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) { | ||
| 331 | /* Get the resource_source_index */ | ||
| 332 | |||
| 333 | resource_source->index = aml_resource_source[0]; | ||
| 334 | |||
| 335 | resource_source->string_ptr = string_ptr; | ||
| 336 | if (!string_ptr) { | ||
| 337 | /* | ||
| 338 | * String destination pointer is not specified; Set the String | ||
| 339 | * pointer to the end of the current resource_source structure. | ||
| 340 | */ | ||
| 341 | resource_source->string_ptr = | ||
| 342 | ACPI_ADD_PTR(char, resource_source, | ||
| 343 | sizeof(struct acpi_resource_source)); | ||
| 344 | } | ||
| 345 | |||
| 346 | /* | ||
| 347 | * In order for the struct_size to fall on a 32-bit boundary, calculate | ||
| 348 | * the length of the string (+1 for the NULL terminator) and expand the | ||
| 349 | * struct_size to the next 32-bit boundary. | ||
| 350 | * | ||
| 351 | * Zero the entire area of the buffer. | ||
| 352 | */ | ||
| 353 | total_length = | ||
| 354 | ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN | ||
| 355 | ((char *)&aml_resource_source[1]) + | ||
| 356 | 1); | ||
| 357 | ACPI_MEMSET(resource_source->string_ptr, 0, total_length); | ||
| 358 | |||
| 359 | /* Copy the resource_source string to the destination */ | ||
| 360 | |||
| 361 | resource_source->string_length = | ||
| 362 | acpi_rs_strcpy(resource_source->string_ptr, | ||
| 363 | (char *)&aml_resource_source[1]); | ||
| 364 | |||
| 365 | return ((acpi_rs_length) total_length); | ||
| 366 | } | ||
| 367 | |||
| 368 | /* resource_source is not present */ | ||
| 369 | |||
| 370 | resource_source->index = 0; | ||
| 371 | resource_source->string_length = 0; | ||
| 372 | resource_source->string_ptr = NULL; | ||
| 373 | return (0); | ||
| 374 | } | ||
| 375 | |||
| 376 | /******************************************************************************* | ||
| 377 | * | ||
| 378 | * FUNCTION: acpi_rs_set_resource_source | ||
| 379 | * | ||
| 380 | * PARAMETERS: Aml - Pointer to the raw AML descriptor | ||
| 381 | * minimum_length - Minimum length of the descriptor (minus | ||
| 382 | * any optional fields) | ||
| 383 | * resource_source - Internal resource_source | ||
| 384 | |||
| 385 | * | ||
| 386 | * RETURN: Total length of the AML descriptor | ||
| 387 | * | ||
| 388 | * DESCRIPTION: Convert an optional resource_source from internal format to a | ||
| 389 | * raw AML resource descriptor | ||
| 390 | * | ||
| 391 | ******************************************************************************/ | ||
| 392 | |||
| 393 | acpi_rsdesc_size | ||
| 394 | acpi_rs_set_resource_source(union aml_resource * aml, | ||
| 395 | acpi_rs_length minimum_length, | ||
| 396 | struct acpi_resource_source * resource_source) | ||
| 397 | { | ||
| 398 | u8 *aml_resource_source; | ||
| 399 | acpi_rsdesc_size descriptor_length; | ||
| 400 | |||
| 401 | ACPI_FUNCTION_ENTRY(); | ||
| 402 | |||
| 403 | descriptor_length = minimum_length; | ||
| 404 | |||
| 405 | /* Non-zero string length indicates presence of a resource_source */ | ||
| 406 | |||
| 407 | if (resource_source->string_length) { | ||
| 408 | /* Point to the end of the AML descriptor */ | ||
| 409 | |||
| 410 | aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); | ||
| 411 | |||
| 412 | /* Copy the resource_source_index */ | ||
| 413 | |||
| 414 | aml_resource_source[0] = (u8) resource_source->index; | ||
| 415 | |||
| 416 | /* Copy the resource_source string */ | ||
| 417 | |||
| 418 | ACPI_STRCPY((char *)&aml_resource_source[1], | ||
| 419 | resource_source->string_ptr); | ||
| 420 | |||
| 421 | /* | ||
| 422 | * Add the length of the string (+ 1 for null terminator) to the | ||
| 423 | * final descriptor length | ||
| 424 | */ | ||
| 425 | descriptor_length += | ||
| 426 | ((acpi_rsdesc_size) resource_source->string_length + 1); | ||
| 427 | } | ||
| 428 | |||
| 429 | /* Return the new total length of the AML descriptor */ | ||
| 430 | |||
| 431 | return (descriptor_length); | ||
| 432 | } | ||
| 433 | |||
| 434 | /******************************************************************************* | ||
| 435 | * | ||
| 53 | * FUNCTION: acpi_rs_get_prt_method_data | 436 | * FUNCTION: acpi_rs_get_prt_method_data |
| 54 | * | 437 | * |
| 55 | * PARAMETERS: Handle - a handle to the containing object | 438 | * PARAMETERS: Handle - a handle to the containing object |
| @@ -65,8 +448,9 @@ ACPI_MODULE_NAME("rsutils") | |||
| 65 | * and the contents of the callers buffer is undefined. | 448 | * and the contents of the callers buffer is undefined. |
| 66 | * | 449 | * |
| 67 | ******************************************************************************/ | 450 | ******************************************************************************/ |
| 451 | |||
| 68 | acpi_status | 452 | acpi_status |
| 69 | acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) | 453 | acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) |
| 70 | { | 454 | { |
| 71 | union acpi_operand_object *obj_desc; | 455 | union acpi_operand_object *obj_desc; |
| 72 | acpi_status status; | 456 | acpi_status status; |
| @@ -284,7 +668,7 @@ acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer) | |||
| 284 | * Convert the linked list into a byte stream | 668 | * Convert the linked list into a byte stream |
| 285 | */ | 669 | */ |
| 286 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 670 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; |
| 287 | status = acpi_rs_create_byte_stream(in_buffer->pointer, &buffer); | 671 | status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); |
| 288 | if (ACPI_FAILURE(status)) { | 672 | if (ACPI_FAILURE(status)) { |
| 289 | return_ACPI_STATUS(status); | 673 | return_ACPI_STATUS(status); |
| 290 | } | 674 | } |
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index ee5a5c509199..88b67077aeeb 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -57,13 +57,17 @@ ACPI_MODULE_NAME("rsxface") | |||
| 57 | ACPI_COPY_FIELD(out, in, decode); \ | 57 | ACPI_COPY_FIELD(out, in, decode); \ |
| 58 | ACPI_COPY_FIELD(out, in, min_address_fixed); \ | 58 | ACPI_COPY_FIELD(out, in, min_address_fixed); \ |
| 59 | ACPI_COPY_FIELD(out, in, max_address_fixed); \ | 59 | ACPI_COPY_FIELD(out, in, max_address_fixed); \ |
| 60 | ACPI_COPY_FIELD(out, in, attribute); \ | 60 | ACPI_COPY_FIELD(out, in, info); \ |
| 61 | ACPI_COPY_FIELD(out, in, granularity); \ | 61 | ACPI_COPY_FIELD(out, in, granularity); \ |
| 62 | ACPI_COPY_FIELD(out, in, min_address_range); \ | 62 | ACPI_COPY_FIELD(out, in, minimum); \ |
| 63 | ACPI_COPY_FIELD(out, in, max_address_range); \ | 63 | ACPI_COPY_FIELD(out, in, maximum); \ |
| 64 | ACPI_COPY_FIELD(out, in, address_translation_offset); \ | 64 | ACPI_COPY_FIELD(out, in, translation_offset); \ |
| 65 | ACPI_COPY_FIELD(out, in, address_length); \ | 65 | ACPI_COPY_FIELD(out, in, address_length); \ |
| 66 | ACPI_COPY_FIELD(out, in, resource_source); | 66 | ACPI_COPY_FIELD(out, in, resource_source); |
| 67 | /* Local prototypes */ | ||
| 68 | static acpi_status | ||
| 69 | acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context); | ||
| 70 | |||
| 67 | /******************************************************************************* | 71 | /******************************************************************************* |
| 68 | * | 72 | * |
| 69 | * FUNCTION: acpi_get_irq_routing_table | 73 | * FUNCTION: acpi_get_irq_routing_table |
| @@ -86,6 +90,7 @@ ACPI_MODULE_NAME("rsxface") | |||
| 86 | * the object indicated by the passed device_handle. | 90 | * the object indicated by the passed device_handle. |
| 87 | * | 91 | * |
| 88 | ******************************************************************************/ | 92 | ******************************************************************************/ |
| 93 | |||
| 89 | acpi_status | 94 | acpi_status |
| 90 | acpi_get_irq_routing_table(acpi_handle device_handle, | 95 | acpi_get_irq_routing_table(acpi_handle device_handle, |
| 91 | struct acpi_buffer *ret_buffer) | 96 | struct acpi_buffer *ret_buffer) |
| @@ -222,12 +227,12 @@ EXPORT_SYMBOL(acpi_get_possible_resources); | |||
| 222 | * | 227 | * |
| 223 | * FUNCTION: acpi_walk_resources | 228 | * FUNCTION: acpi_walk_resources |
| 224 | * | 229 | * |
| 225 | * PARAMETERS: device_handle - a handle to the device object for the | 230 | * PARAMETERS: device_handle - Handle to the device object for the |
| 226 | * device we are querying | 231 | * device we are querying |
| 227 | * Path - method name of the resources we want | 232 | * Name - Method name of the resources we want |
| 228 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) | 233 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) |
| 229 | * user_function - called for each resource | 234 | * user_function - Called for each resource |
| 230 | * Context - passed to user_function | 235 | * Context - Passed to user_function |
| 231 | * | 236 | * |
| 232 | * RETURN: Status | 237 | * RETURN: Status |
| 233 | * | 238 | * |
| @@ -239,79 +244,74 @@ EXPORT_SYMBOL(acpi_get_possible_resources); | |||
| 239 | 244 | ||
| 240 | acpi_status | 245 | acpi_status |
| 241 | acpi_walk_resources(acpi_handle device_handle, | 246 | acpi_walk_resources(acpi_handle device_handle, |
| 242 | char *path, | 247 | char *name, |
| 243 | ACPI_WALK_RESOURCE_CALLBACK user_function, void *context) | 248 | ACPI_WALK_RESOURCE_CALLBACK user_function, void *context) |
| 244 | { | 249 | { |
| 245 | acpi_status status; | 250 | acpi_status status; |
| 246 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 251 | struct acpi_buffer buffer; |
| 247 | struct acpi_resource *resource; | 252 | struct acpi_resource *resource; |
| 248 | struct acpi_resource *buffer_end; | 253 | struct acpi_resource *resource_end; |
| 249 | 254 | ||
| 250 | ACPI_FUNCTION_TRACE("acpi_walk_resources"); | 255 | ACPI_FUNCTION_TRACE("acpi_walk_resources"); |
| 251 | 256 | ||
| 252 | if (!device_handle || | 257 | /* Parameter validation */ |
| 253 | (ACPI_STRNCMP(path, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) && | 258 | |
| 254 | ACPI_STRNCMP(path, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) { | 259 | if (!device_handle || !user_function || !name || |
| 260 | (ACPI_STRNCMP(name, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) && | ||
| 261 | ACPI_STRNCMP(name, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) { | ||
| 255 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 262 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
| 256 | } | 263 | } |
| 257 | 264 | ||
| 258 | status = acpi_rs_get_method_data(device_handle, path, &buffer); | 265 | /* Get the _CRS or _PRS resource list */ |
| 266 | |||
| 267 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
| 268 | status = acpi_rs_get_method_data(device_handle, name, &buffer); | ||
| 259 | if (ACPI_FAILURE(status)) { | 269 | if (ACPI_FAILURE(status)) { |
| 260 | return_ACPI_STATUS(status); | 270 | return_ACPI_STATUS(status); |
| 261 | } | 271 | } |
| 262 | 272 | ||
| 263 | /* Setup pointers */ | 273 | /* Buffer now contains the resource list */ |
| 264 | 274 | ||
| 265 | resource = (struct acpi_resource *)buffer.pointer; | 275 | resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); |
| 266 | buffer_end = ACPI_CAST_PTR(struct acpi_resource, | 276 | resource_end = |
| 267 | ((u8 *) buffer.pointer + buffer.length)); | 277 | ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); |
| 268 | 278 | ||
| 269 | /* Walk the resource list */ | 279 | /* Walk the resource list until the end_tag is found (or buffer end) */ |
| 270 | 280 | ||
| 271 | for (;;) { | 281 | while (resource < resource_end) { |
| 272 | if (!resource || resource->id == ACPI_RSTYPE_END_TAG) { | 282 | /* Sanity check the resource */ |
| 283 | |||
| 284 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { | ||
| 285 | status = AE_AML_INVALID_RESOURCE_TYPE; | ||
| 273 | break; | 286 | break; |
| 274 | } | 287 | } |
| 275 | 288 | ||
| 276 | status = user_function(resource, context); | 289 | /* Invoke the user function, abort on any error returned */ |
| 277 | |||
| 278 | switch (status) { | ||
| 279 | case AE_OK: | ||
| 280 | case AE_CTRL_DEPTH: | ||
| 281 | 290 | ||
| 282 | /* Just keep going */ | 291 | status = user_function(resource, context); |
| 292 | if (ACPI_FAILURE(status)) { | ||
| 293 | if (status == AE_CTRL_TERMINATE) { | ||
| 294 | /* This is an OK termination by the user function */ | ||
| 283 | 295 | ||
| 284 | status = AE_OK; | 296 | status = AE_OK; |
| 297 | } | ||
| 285 | break; | 298 | break; |
| 299 | } | ||
| 286 | 300 | ||
| 287 | case AE_CTRL_TERMINATE: | 301 | /* end_tag indicates end-of-list */ |
| 288 | |||
| 289 | /* Exit now, with OK stats */ | ||
| 290 | |||
| 291 | status = AE_OK; | ||
| 292 | goto cleanup; | ||
| 293 | |||
| 294 | default: | ||
| 295 | |||
| 296 | /* All others are valid exceptions */ | ||
| 297 | 302 | ||
| 298 | goto cleanup; | 303 | if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { |
| 304 | break; | ||
| 299 | } | 305 | } |
| 300 | 306 | ||
| 301 | /* Get the next resource descriptor */ | 307 | /* Get the next resource descriptor */ |
| 302 | 308 | ||
| 303 | resource = ACPI_NEXT_RESOURCE(resource); | 309 | resource = |
| 304 | 310 | ACPI_ADD_PTR(struct acpi_resource, resource, | |
| 305 | /* Check for end-of-buffer */ | 311 | resource->length); |
| 306 | |||
| 307 | if (resource >= buffer_end) { | ||
| 308 | goto cleanup; | ||
| 309 | } | ||
| 310 | } | 312 | } |
| 311 | 313 | ||
| 312 | cleanup: | 314 | ACPI_MEM_FREE(buffer.pointer); |
| 313 | |||
| 314 | acpi_os_free(buffer.pointer); | ||
| 315 | return_ACPI_STATUS(status); | 315 | return_ACPI_STATUS(status); |
| 316 | } | 316 | } |
| 317 | 317 | ||
| @@ -360,8 +360,8 @@ EXPORT_SYMBOL(acpi_set_current_resources); | |||
| 360 | * | 360 | * |
| 361 | * FUNCTION: acpi_resource_to_address64 | 361 | * FUNCTION: acpi_resource_to_address64 |
| 362 | * | 362 | * |
| 363 | * PARAMETERS: resource - Pointer to a resource | 363 | * PARAMETERS: Resource - Pointer to a resource |
| 364 | * out - Pointer to the users's return | 364 | * Out - Pointer to the users's return |
| 365 | * buffer (a struct | 365 | * buffer (a struct |
| 366 | * struct acpi_resource_address64) | 366 | * struct acpi_resource_address64) |
| 367 | * | 367 | * |
| @@ -381,20 +381,26 @@ acpi_resource_to_address64(struct acpi_resource *resource, | |||
| 381 | struct acpi_resource_address16 *address16; | 381 | struct acpi_resource_address16 *address16; |
| 382 | struct acpi_resource_address32 *address32; | 382 | struct acpi_resource_address32 *address32; |
| 383 | 383 | ||
| 384 | switch (resource->id) { | 384 | if (!resource || !out) { |
| 385 | case ACPI_RSTYPE_ADDRESS16: | 385 | return (AE_BAD_PARAMETER); |
| 386 | } | ||
| 387 | |||
| 388 | /* Convert 16 or 32 address descriptor to 64 */ | ||
| 389 | |||
| 390 | switch (resource->type) { | ||
| 391 | case ACPI_RESOURCE_TYPE_ADDRESS16: | ||
| 386 | 392 | ||
| 387 | address16 = (struct acpi_resource_address16 *)&resource->data; | 393 | address16 = (struct acpi_resource_address16 *)&resource->data; |
| 388 | ACPI_COPY_ADDRESS(out, address16); | 394 | ACPI_COPY_ADDRESS(out, address16); |
| 389 | break; | 395 | break; |
| 390 | 396 | ||
| 391 | case ACPI_RSTYPE_ADDRESS32: | 397 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
| 392 | 398 | ||
| 393 | address32 = (struct acpi_resource_address32 *)&resource->data; | 399 | address32 = (struct acpi_resource_address32 *)&resource->data; |
| 394 | ACPI_COPY_ADDRESS(out, address32); | 400 | ACPI_COPY_ADDRESS(out, address32); |
| 395 | break; | 401 | break; |
| 396 | 402 | ||
| 397 | case ACPI_RSTYPE_ADDRESS64: | 403 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
| 398 | 404 | ||
| 399 | /* Simple copy for 64 bit source */ | 405 | /* Simple copy for 64 bit source */ |
| 400 | 406 | ||
| @@ -410,3 +416,113 @@ acpi_resource_to_address64(struct acpi_resource *resource, | |||
| 410 | } | 416 | } |
| 411 | 417 | ||
| 412 | EXPORT_SYMBOL(acpi_resource_to_address64); | 418 | EXPORT_SYMBOL(acpi_resource_to_address64); |
| 419 | |||
| 420 | /******************************************************************************* | ||
| 421 | * | ||
| 422 | * FUNCTION: acpi_get_vendor_resource | ||
| 423 | * | ||
| 424 | * PARAMETERS: device_handle - Handle for the parent device object | ||
| 425 | * Name - Method name for the parent resource | ||
| 426 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) | ||
| 427 | * Uuid - Pointer to the UUID to be matched. | ||
| 428 | * includes both subtype and 16-byte UUID | ||
| 429 | * ret_buffer - Where the vendor resource is returned | ||
| 430 | * | ||
| 431 | * RETURN: Status | ||
| 432 | * | ||
| 433 | * DESCRIPTION: Walk a resource template for the specified evice to find a | ||
| 434 | * vendor-defined resource that matches the supplied UUID and | ||
| 435 | * UUID subtype. Returns a struct acpi_resource of type Vendor. | ||
| 436 | * | ||
| 437 | ******************************************************************************/ | ||
| 438 | |||
| 439 | acpi_status | ||
| 440 | acpi_get_vendor_resource(acpi_handle device_handle, | ||
| 441 | char *name, | ||
| 442 | struct acpi_vendor_uuid * uuid, | ||
| 443 | struct acpi_buffer * ret_buffer) | ||
| 444 | { | ||
| 445 | struct acpi_vendor_walk_info info; | ||
| 446 | acpi_status status; | ||
| 447 | |||
| 448 | /* Other parameters are validated by acpi_walk_resources */ | ||
| 449 | |||
| 450 | if (!uuid || !ret_buffer) { | ||
| 451 | return (AE_BAD_PARAMETER); | ||
| 452 | } | ||
| 453 | |||
| 454 | info.uuid = uuid; | ||
| 455 | info.buffer = ret_buffer; | ||
| 456 | info.status = AE_NOT_EXIST; | ||
| 457 | |||
| 458 | /* Walk the _CRS or _PRS resource list for this device */ | ||
| 459 | |||
| 460 | status = | ||
| 461 | acpi_walk_resources(device_handle, name, | ||
| 462 | acpi_rs_match_vendor_resource, &info); | ||
| 463 | if (ACPI_FAILURE(status)) { | ||
| 464 | return (status); | ||
| 465 | } | ||
| 466 | |||
| 467 | return (info.status); | ||
| 468 | } | ||
| 469 | |||
| 470 | /******************************************************************************* | ||
| 471 | * | ||
| 472 | * FUNCTION: acpi_rs_match_vendor_resource | ||
| 473 | * | ||
| 474 | * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK | ||
| 475 | * | ||
| 476 | * RETURN: Status | ||
| 477 | * | ||
| 478 | * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID | ||
| 479 | * | ||
| 480 | ******************************************************************************/ | ||
| 481 | |||
| 482 | static acpi_status | ||
| 483 | acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) | ||
| 484 | { | ||
| 485 | struct acpi_vendor_walk_info *info = context; | ||
| 486 | struct acpi_resource_vendor_typed *vendor; | ||
| 487 | struct acpi_buffer *buffer; | ||
| 488 | acpi_status status; | ||
| 489 | |||
| 490 | /* Ignore all descriptors except Vendor */ | ||
| 491 | |||
| 492 | if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) { | ||
| 493 | return (AE_OK); | ||
| 494 | } | ||
| 495 | |||
| 496 | vendor = &resource->data.vendor_typed; | ||
| 497 | |||
| 498 | /* | ||
| 499 | * For a valid match, these conditions must hold: | ||
| 500 | * | ||
| 501 | * 1) Length of descriptor data must be at least as long as a UUID struct | ||
| 502 | * 2) The UUID subtypes must match | ||
| 503 | * 3) The UUID data must match | ||
| 504 | */ | ||
| 505 | if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) || | ||
| 506 | (vendor->uuid_subtype != info->uuid->subtype) || | ||
| 507 | (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) { | ||
| 508 | return (AE_OK); | ||
| 509 | } | ||
| 510 | |||
| 511 | /* Validate/Allocate/Clear caller buffer */ | ||
| 512 | |||
| 513 | buffer = info->buffer; | ||
| 514 | status = acpi_ut_initialize_buffer(buffer, resource->length); | ||
| 515 | if (ACPI_FAILURE(status)) { | ||
| 516 | return (status); | ||
| 517 | } | ||
| 518 | |||
| 519 | /* Found the correct resource, copy and return it */ | ||
| 520 | |||
| 521 | ACPI_MEMCPY(buffer->pointer, resource, resource->length); | ||
| 522 | buffer->length = resource->length; | ||
| 523 | |||
| 524 | /* Found the desired descriptor, terminate resource walk */ | ||
| 525 | |||
| 526 | info->status = AE_OK; | ||
| 527 | return (AE_CTRL_TERMINATE); | ||
| 528 | } | ||
