aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources/rslist.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2005-09-30 19:03:00 -0400
committerLen Brown <len.brown@intel.com>2005-12-10 00:20:25 -0500
commit50eca3eb89d73d9f0aa070b126c7ee6a616016ab (patch)
treeb2d06d21b34b9bd17eea4c53cff1f3866fa1b21d /drivers/acpi/resources/rslist.c
parent3d5271f9883cba7b54762bc4fe027d4172f06db7 (diff)
[ACPI] ACPICA 20050930
Completed a major overhaul of the Resource Manager code - specifically, optimizations in the area of the AML/internal resource conversion code. The code has been optimized to simplify and eliminate duplicated code, CPU stack use has been decreased by optimizing function parameters and local variables, and naming conventions across the manager have been standardized for clarity and ease of maintenance (this includes function, parameter, variable, and struct/typedef names.) All Resource Manager dispatch and information tables have been moved to a single location for clarity and ease of maintenance. One new file was created, named "rsinfo.c". The ACPI return macros (return_ACPI_STATUS, etc.) have been modified to guarantee that the argument is not evaluated twice, making them less prone to macro side-effects. However, since there exists the possibility of additional stack use if a particular compiler cannot optimize them (such as in the debug generation case), the original macros are optionally available. Note that some invocations of the return_VALUE macro may now cause size mismatch warnings; the return_UINT8 and return_UINT32 macros are provided to eliminate these. (From Randy Dunlap) Implemented a new mechanism to enable debug tracing for individual control methods. A new external interface, acpi_debug_trace(), is provided to enable this mechanism. The intent is to allow the host OS to easily enable and disable tracing for problematic control methods. This interface can be easily exposed to a user or debugger interface if desired. See the file psxface.c for details. acpi_ut_callocate() will now return a valid pointer if a length of zero is specified - a length of one is used and a warning is issued. This matches the behavior of acpi_ut_allocate(). Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/resources/rslist.c')
-rw-r--r--drivers/acpi/resources/rslist.c290
1 files changed, 146 insertions, 144 deletions
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index 87e75349dd0a..f72d42e0927b 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -47,106 +47,70 @@
47#define _COMPONENT ACPI_RESOURCES 47#define _COMPONENT ACPI_RESOURCES
48ACPI_MODULE_NAME("rslist") 48ACPI_MODULE_NAME("rslist")
49 49
50/* Dispatch table for convert-to-stream functions */
51typedef
52acpi_status(*ACPI_STREAM_HANDLER) (struct acpi_resource * resource,
53 u8 ** output_buffer,
54 acpi_size * bytes_consumed);
55
56static ACPI_STREAM_HANDLER acpi_gbl_stream_dispatch[] = {
57 acpi_rs_irq_stream, /* ACPI_RSTYPE_IRQ */
58 acpi_rs_dma_stream, /* ACPI_RSTYPE_DMA */
59 acpi_rs_start_depend_fns_stream, /* ACPI_RSTYPE_START_DPF */
60 acpi_rs_end_depend_fns_stream, /* ACPI_RSTYPE_END_DPF */
61 acpi_rs_io_stream, /* ACPI_RSTYPE_IO */
62 acpi_rs_fixed_io_stream, /* ACPI_RSTYPE_FIXED_IO */
63 acpi_rs_vendor_stream, /* ACPI_RSTYPE_VENDOR */
64 acpi_rs_end_tag_stream, /* ACPI_RSTYPE_END_TAG */
65 acpi_rs_memory24_stream, /* ACPI_RSTYPE_MEM24 */
66 acpi_rs_memory32_range_stream, /* ACPI_RSTYPE_MEM32 */
67 acpi_rs_fixed_memory32_stream, /* ACPI_RSTYPE_FIXED_MEM32 */
68 acpi_rs_address16_stream, /* ACPI_RSTYPE_ADDRESS16 */
69 acpi_rs_address32_stream, /* ACPI_RSTYPE_ADDRESS32 */
70 acpi_rs_address64_stream, /* ACPI_RSTYPE_ADDRESS64 */
71 acpi_rs_extended_irq_stream, /* ACPI_RSTYPE_EXT_IRQ */
72 acpi_rs_generic_register_stream /* ACPI_RSTYPE_GENERIC_REG */
73};
74
75/* Dispatch tables for convert-to-resource functions */
76
77typedef
78acpi_status(*ACPI_RESOURCE_HANDLER) (u8 * byte_stream_buffer,
79 acpi_size * bytes_consumed,
80 u8 ** output_buffer,
81 acpi_size * structure_size);
82
83static ACPI_RESOURCE_HANDLER acpi_gbl_sm_resource_dispatch[] = {
84 NULL, /* 0x00, Reserved */
85 NULL, /* 0x01, Reserved */
86 NULL, /* 0x02, Reserved */
87 NULL, /* 0x03, Reserved */
88 acpi_rs_irq_resource, /* ACPI_RDESC_TYPE_IRQ_FORMAT */
89 acpi_rs_dma_resource, /* ACPI_RDESC_TYPE_DMA_FORMAT */
90 acpi_rs_start_depend_fns_resource, /* ACPI_RDESC_TYPE_START_DEPENDENT */
91 acpi_rs_end_depend_fns_resource, /* ACPI_RDESC_TYPE_END_DEPENDENT */
92 acpi_rs_io_resource, /* ACPI_RDESC_TYPE_IO_PORT */
93 acpi_rs_fixed_io_resource, /* ACPI_RDESC_TYPE_FIXED_IO_PORT */
94 NULL, /* 0x0A, Reserved */
95 NULL, /* 0x0B, Reserved */
96 NULL, /* 0x0C, Reserved */
97 NULL, /* 0x0D, Reserved */
98 acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_SMALL_VENDOR */
99 acpi_rs_end_tag_resource /* ACPI_RDESC_TYPE_END_TAG */
100};
101
102static ACPI_RESOURCE_HANDLER acpi_gbl_lg_resource_dispatch[] = {
103 NULL, /* 0x00, Reserved */
104 acpi_rs_memory24_resource, /* ACPI_RDESC_TYPE_MEMORY_24 */
105 acpi_rs_generic_register_resource, /* ACPI_RDESC_TYPE_GENERIC_REGISTER */
106 NULL, /* 0x03, Reserved */
107 acpi_rs_vendor_resource, /* ACPI_RDESC_TYPE_LARGE_VENDOR */
108 acpi_rs_memory32_range_resource, /* ACPI_RDESC_TYPE_MEMORY_32 */
109 acpi_rs_fixed_memory32_resource, /* ACPI_RDESC_TYPE_FIXED_MEMORY_32 */
110 acpi_rs_address32_resource, /* ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE */
111 acpi_rs_address16_resource, /* ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE */
112 acpi_rs_extended_irq_resource, /* ACPI_RDESC_TYPE_EXTENDED_XRUPT */
113 acpi_rs_address64_resource, /* ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE */
114 acpi_rs_address64_resource /* ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE */
115};
116
117/* Local prototypes */ 50/* Local prototypes */
51static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type);
118 52
119static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type); 53static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml);
120 54
121/******************************************************************************* 55/*******************************************************************************
122 * 56 *
123 * FUNCTION: acpi_rs_get_resource_type 57 * FUNCTION: acpi_rs_validate_resource_length
124 * 58 *
125 * PARAMETERS: resource_type - Byte 0 of a resource descriptor 59 * PARAMETERS: Aml - Pointer to the AML resource descriptor
126 * 60 *
127 * RETURN: The Resource Type with no extraneous bits (except the large/ 61 * RETURN: Status - AE_OK if the resource length appears valid
128 * small bit -- left alone)
129 * 62 *
130 * DESCRIPTION: Extract the Resource Type/Name from the first byte of 63 * DESCRIPTION: Validate the resource_length. Fixed-length descriptors must
131 * a resource descriptor. 64 * have the exact length; variable-length descriptors must be
65 * at least as long as the minimum. Certain Small descriptors
66 * can vary in size by at most one byte.
132 * 67 *
133 ******************************************************************************/ 68 ******************************************************************************/
134 69
135u8 acpi_rs_get_resource_type(u8 resource_type) 70static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml)
136{ 71{
72 struct acpi_resource_info *resource_info;
73 u16 minimum_aml_resource_length;
74 u16 resource_length;
75
137 ACPI_FUNCTION_ENTRY(); 76 ACPI_FUNCTION_ENTRY();
138 77
139 /* Determine if this is a small or large resource */ 78 /* Get the size and type info about this resource descriptor */
140 79
141 if (resource_type & ACPI_RDESC_TYPE_LARGE) { 80 resource_info =
142 /* Large Resource Type -- bits 6:0 contain the name */ 81 acpi_rs_get_resource_info(aml->small_header.descriptor_type);
82 if (!resource_info) {
83 return (AE_AML_INVALID_RESOURCE_TYPE);
84 }
85
86 resource_length = acpi_rs_get_resource_length(aml);
87 minimum_aml_resource_length =
88 resource_info->minimum_aml_resource_length;
89
90 /* Validate based upon the type of resource, fixed length or variable */
91
92 if (resource_info->length_type == ACPI_FIXED_LENGTH) {
93 /* Fixed length resource, length must match exactly */
143 94
144 return (resource_type); 95 if (resource_length != minimum_aml_resource_length) {
96 return (AE_AML_BAD_RESOURCE_LENGTH);
97 }
98 } else if (resource_info->length_type == ACPI_VARIABLE_LENGTH) {
99 /* Variable length resource, must be at least the minimum */
100
101 if (resource_length < minimum_aml_resource_length) {
102 return (AE_AML_BAD_RESOURCE_LENGTH);
103 }
145 } else { 104 } else {
146 /* Small Resource Type -- bits 6:3 contain the name */ 105 /* Small variable length resource, allowed to be (Min) or (Min-1) */
147 106
148 return ((u8) (resource_type & ACPI_RDESC_SMALL_MASK)); 107 if ((resource_length > minimum_aml_resource_length) ||
108 (resource_length < (minimum_aml_resource_length - 1))) {
109 return (AE_AML_BAD_RESOURCE_LENGTH);
110 }
149 } 111 }
112
113 return (AE_OK);
150} 114}
151 115
152/******************************************************************************* 116/*******************************************************************************
@@ -162,38 +126,38 @@ u8 acpi_rs_get_resource_type(u8 resource_type)
162 * 126 *
163 ******************************************************************************/ 127 ******************************************************************************/
164 128
165static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type) 129static ACPI_GET_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type)
166{ 130{
167 ACPI_FUNCTION_ENTRY(); 131 ACPI_FUNCTION_ENTRY();
168 132
169 /* Determine if this is a small or large resource */ 133 /* Determine if this is a small or large resource */
170 134
171 if (resource_type & ACPI_RDESC_TYPE_LARGE) { 135 if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
172 /* Large Resource Type -- bits 6:0 contain the name */ 136 /* Large Resource Type -- bits 6:0 contain the name */
173 137
174 if (resource_type > ACPI_RDESC_LARGE_MAX) { 138 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
175 return (NULL); 139 return (NULL);
176 } 140 }
177 141
178 return (acpi_gbl_lg_resource_dispatch[(resource_type & 142 return (acpi_gbl_lg_get_resource_dispatch[(resource_type &
179 ACPI_RDESC_LARGE_MASK)]); 143 ACPI_RESOURCE_NAME_LARGE_MASK)]);
180 } else { 144 } else {
181 /* Small Resource Type -- bits 6:3 contain the name */ 145 /* Small Resource Type -- bits 6:3 contain the name */
182 146
183 return (acpi_gbl_sm_resource_dispatch[((resource_type & 147 return (acpi_gbl_sm_get_resource_dispatch[((resource_type &
184 ACPI_RDESC_SMALL_MASK) 148 ACPI_RESOURCE_NAME_SMALL_MASK)
185 >> 3)]); 149 >> 3)]);
186 } 150 }
187} 151}
188 152
189/******************************************************************************* 153/*******************************************************************************
190 * 154 *
191 * FUNCTION: acpi_rs_byte_stream_to_list 155 * FUNCTION: acpi_rs_convert_aml_to_resources
192 * 156 *
193 * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream 157 * PARAMETERS: aml_buffer - Pointer to the resource byte stream
194 * byte_stream_buffer_length - Length of byte_stream_buffer 158 * aml_buffer_length - Length of aml_buffer
195 * output_buffer - Pointer to the buffer that will 159 * output_buffer - Pointer to the buffer that will
196 * contain the output structures 160 * contain the output structures
197 * 161 *
198 * RETURN: Status 162 * RETURN: Status
199 * 163 *
@@ -203,37 +167,60 @@ static ACPI_RESOURCE_HANDLER acpi_rs_get_resource_handler(u8 resource_type)
203 ******************************************************************************/ 167 ******************************************************************************/
204 168
205acpi_status 169acpi_status
206acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer, 170acpi_rs_convert_aml_to_resources(u8 * aml_buffer,
207 u32 byte_stream_buffer_length, u8 * output_buffer) 171 u32 aml_buffer_length, u8 * output_buffer)
208{ 172{
209 u8 *buffer = output_buffer; 173 u8 *buffer = output_buffer;
210 acpi_status status; 174 acpi_status status;
211 acpi_size bytes_parsed = 0; 175 acpi_size bytes_parsed = 0;
212 acpi_size bytes_consumed = 0;
213 acpi_size structure_size = 0;
214 struct acpi_resource *resource; 176 struct acpi_resource *resource;
215 ACPI_RESOURCE_HANDLER handler; 177 u16 resource_length;
178 u32 descriptor_length;
179 ACPI_GET_RESOURCE_HANDLER handler;
216 180
217 ACPI_FUNCTION_TRACE("rs_byte_stream_to_list"); 181 ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources");
218 182
219 /* Loop until end-of-buffer or an end_tag is found */ 183 /* Loop until end-of-buffer or an end_tag is found */
220 184
221 while (bytes_parsed < byte_stream_buffer_length) { 185 while (bytes_parsed < aml_buffer_length) {
222 /* Get the handler associated with this Descriptor Type */ 186 /* Get the handler associated with this Descriptor Type */
223 187
224 handler = acpi_rs_get_resource_handler(*byte_stream_buffer); 188 handler = acpi_rs_get_resource_handler(*aml_buffer);
225 if (handler) { 189 if (!handler) {
226 /* Convert a byte stream resource to local resource struct */ 190 /* No handler indicates invalid resource type */
227 191
228 status = handler(byte_stream_buffer, &bytes_consumed, 192 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
229 &buffer, &structure_size); 193 }
230 } else {
231 /* Invalid resource type */
232 194
233 status = AE_AML_INVALID_RESOURCE_TYPE; 195 resource_length =
196 acpi_rs_get_resource_length(ACPI_CAST_PTR
197 (union aml_resource,
198 aml_buffer));
199
200 descriptor_length =
201 acpi_rs_get_descriptor_length(ACPI_CAST_PTR
202 (union aml_resource,
203 aml_buffer));
204
205 /*
206 * Perform limited validation of the resource length, based upon
207 * what we know about the resource type
208 */
209 status =
210 acpi_rs_validate_resource_length(ACPI_CAST_PTR
211 (union aml_resource,
212 aml_buffer));
213 if (ACPI_FAILURE(status)) {
214 return_ACPI_STATUS(status);
234 } 215 }
235 216
217 /* Convert a byte stream resource to local resource struct */
218
219 status = handler(ACPI_CAST_PTR(union aml_resource, aml_buffer),
220 resource_length,
221 ACPI_CAST_PTR(struct acpi_resource, buffer));
236 if (ACPI_FAILURE(status)) { 222 if (ACPI_FAILURE(status)) {
223 ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status)));
237 return_ACPI_STATUS(status); 224 return_ACPI_STATUS(status);
238 } 225 }
239 226
@@ -245,19 +232,19 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer,
245 232
246 /* Normal exit on completion of an end_tag resource descriptor */ 233 /* Normal exit on completion of an end_tag resource descriptor */
247 234
248 if (acpi_rs_get_resource_type(*byte_stream_buffer) == 235 if (acpi_rs_get_resource_type(*aml_buffer) ==
249 ACPI_RDESC_TYPE_END_TAG) { 236 ACPI_RESOURCE_NAME_END_TAG) {
250 return_ACPI_STATUS(AE_OK); 237 return_ACPI_STATUS(AE_OK);
251 } 238 }
252 239
253 /* Update counter and point to the next input resource */ 240 /* Update counter and point to the next input resource */
254 241
255 bytes_parsed += bytes_consumed; 242 bytes_parsed += descriptor_length;
256 byte_stream_buffer += bytes_consumed; 243 aml_buffer += descriptor_length;
257 244
258 /* Point to the next structure in the output buffer */ 245 /* Point to the next structure in the output buffer */
259 246
260 buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); 247 buffer += resource->length;
261 } 248 }
262 249
263 /* Completed buffer, but did not find an end_tag resource descriptor */ 250 /* Completed buffer, but did not find an end_tag resource descriptor */
@@ -267,17 +254,15 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer,
267 254
268/******************************************************************************* 255/*******************************************************************************
269 * 256 *
270 * FUNCTION: acpi_rs_list_to_byte_stream 257 * FUNCTION: acpi_rs_convert_resources_to_aml
271 * 258 *
272 * PARAMETERS: Resource - Pointer to the resource linked list 259 * PARAMETERS: Resource - Pointer to the resource linked list
273 * byte_steam_size_needed - Calculated size of the byte stream 260 * aml_size_needed - Calculated size of the byte stream
274 * needed from calling 261 * needed from calling acpi_rs_get_aml_length()
275 * acpi_rs_get_byte_stream_length() 262 * The size of the output_buffer is
276 * The size of the output_buffer is 263 * guaranteed to be >= aml_size_needed
277 * guaranteed to be >= 264 * output_buffer - Pointer to the buffer that will
278 * byte_stream_size_needed 265 * contain the byte stream
279 * output_buffer - Pointer to the buffer that will
280 * contain the byte stream
281 * 266 *
282 * RETURN: Status 267 * RETURN: Status
283 * 268 *
@@ -287,52 +272,69 @@ acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer,
287 ******************************************************************************/ 272 ******************************************************************************/
288 273
289acpi_status 274acpi_status
290acpi_rs_list_to_byte_stream(struct acpi_resource *resource, 275acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
291 acpi_size byte_stream_size_needed, 276 acpi_size aml_size_needed, u8 * output_buffer)
292 u8 * output_buffer)
293{ 277{
294 u8 *buffer = output_buffer; 278 u8 *aml_buffer = output_buffer;
295 acpi_size bytes_consumed = 0;
296 acpi_status status; 279 acpi_status status;
297 280
298 ACPI_FUNCTION_TRACE("rs_list_to_byte_stream"); 281 ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml");
299 282
300 /* Convert each resource descriptor in the list */ 283 /* Convert each resource descriptor in the list */
301 284
302 while (1) { 285 while (1) {
303 /* Validate Type before dispatch */ 286 /* Validate Resource Descriptor Type before dispatch */
304 287
305 if (resource->type > ACPI_RSTYPE_MAX) { 288 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
306 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 289 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
307 "Invalid descriptor type (%X) in resource list\n", 290 "Invalid descriptor type (%X) in resource list\n",
308 resource->type)); 291 resource->type));
309 return_ACPI_STATUS(AE_BAD_DATA); 292 return_ACPI_STATUS(AE_BAD_DATA);
310 } 293 }
311 294
312 /* Perform the conversion, per resource type */ 295 /* Perform the conversion per resource type */
296
297 status =
298 acpi_gbl_set_resource_dispatch[resource->type] (resource,
299 ACPI_CAST_PTR
300 (union
301 aml_resource,
302 aml_buffer));
303 if (ACPI_FAILURE(status)) {
304 ACPI_REPORT_ERROR(("Could not convert resource (type %X) to AML, %s\n", resource->type, acpi_format_exception(status)));
305 return_ACPI_STATUS(status);
306 }
307
308 /* Perform final sanity check on the new AML resource descriptor */
313 309
314 status = acpi_gbl_stream_dispatch[resource->type] (resource, 310 status =
315 &buffer, 311 acpi_rs_validate_resource_length(ACPI_CAST_PTR
316 &bytes_consumed); 312 (union aml_resource,
313 aml_buffer));
317 if (ACPI_FAILURE(status)) { 314 if (ACPI_FAILURE(status)) {
318 return_ACPI_STATUS(status); 315 return_ACPI_STATUS(status);
319 } 316 }
320 317
321 /* Check for end-of-list */ 318 /* Check for end-of-list, normal exit */
322 319
323 if (resource->type == ACPI_RSTYPE_END_TAG) { 320 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
324 /* An End Tag indicates the end of the Resource Template */ 321 /* An End Tag indicates the end of the input Resource Template */
325 322
326 return_ACPI_STATUS(AE_OK); 323 return_ACPI_STATUS(AE_OK);
327 } 324 }
328 325
329 /* Set the Buffer to point to the next (output) resource descriptor */ 326 /* Extract the total length of the new descriptor */
327 /* Set the aml_buffer to point to the next (output) resource descriptor */
330 328
331 buffer += bytes_consumed; 329 aml_buffer +=
330 acpi_rs_get_descriptor_length(ACPI_CAST_PTR
331 (union aml_resource,
332 aml_buffer));
332 333
333 /* Point to the next input resource object */ 334 /* Point to the next input resource descriptor */
334 335
335 resource = ACPI_PTR_ADD(struct acpi_resource, 336 resource =
336 resource, resource->length); 337 ACPI_PTR_ADD(struct acpi_resource, resource,
338 resource->length);
337 } 339 }
338} 340}