rsmisc.c 20.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7
/*******************************************************************************
 *
 * Module Name: rsmisc - Miscellaneous resource descriptors
 *
 ******************************************************************************/

/*
8
 * Copyright (C) 2000 - 2012, Intel Corp.
L
Linus Torvalds 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include <acpi/acpi.h>
L
Len Brown 已提交
45 46
#include "accommon.h"
#include "acresrc.h"
L
Linus Torvalds 已提交
47 48

#define _COMPONENT          ACPI_RESOURCES
L
Len Brown 已提交
49
ACPI_MODULE_NAME("rsmisc")
B
Bob Moore 已提交
50 51 52 53 54 55
#define INIT_RESOURCE_TYPE(i)       i->resource_offset
#define INIT_RESOURCE_LENGTH(i)     i->aml_offset
#define INIT_TABLE_LENGTH(i)        i->value
#define COMPARE_OPCODE(i)           i->resource_offset
#define COMPARE_TARGET(i)           i->aml_offset
#define COMPARE_VALUE(i)            i->value
R
Robert Moore 已提交
56 57
/*******************************************************************************
 *
B
Bob Moore 已提交
58
 * FUNCTION:    acpi_rs_convert_aml_to_resource
R
Robert Moore 已提交
59
 *
60 61 62
 * PARAMETERS:  resource            - Pointer to the resource descriptor
 *              aml                 - Where the AML descriptor is returned
 *              info                - Pointer to appropriate conversion table
R
Robert Moore 已提交
63 64 65
 *
 * RETURN:      Status
 *
B
Bob Moore 已提交
66 67
 * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
 *              internal resource descriptor
L
Linus Torvalds 已提交
68 69 70
 *
 ******************************************************************************/
acpi_status
B
Bob Moore 已提交
71 72 73
acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
				union aml_resource *aml,
				struct acpi_rsconvert_info *info)
L
Linus Torvalds 已提交
74
{
B
Bob Moore 已提交
75 76 77 78 79 80 81 82 83
	acpi_rs_length aml_resource_length;
	void *source;
	void *destination;
	char *target;
	u8 count;
	u8 flags_mode = FALSE;
	u16 item_count = 0;
	u16 temp16 = 0;

B
Bob Moore 已提交
84
	ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource);
B
Bob Moore 已提交
85

86 87 88 89
	if (!info) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

90
	if (((acpi_size) resource) & 0x3) {
B
Bob Moore 已提交
91

B
Bob Moore 已提交
92 93 94
		/* Each internal resource struct is expected to be 32-bit aligned */

		ACPI_WARNING((AE_INFO,
95
			      "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u",
B
Bob Moore 已提交
96
			      resource, resource->type, resource->length));
B
Bob Moore 已提交
97
	}
R
Robert Moore 已提交
98

B
Bob Moore 已提交
99
	/* Extract the resource Length field (does not include header length) */
L
Linus Torvalds 已提交
100

B
Bob Moore 已提交
101
	aml_resource_length = acpi_ut_get_resource_length(aml);
R
Robert Moore 已提交
102

B
Bob Moore 已提交
103 104 105 106 107 108 109 110 111 112
	/*
	 * First table entry must be ACPI_RSC_INITxxx and must contain the
	 * table length (# of table entries)
	 */
	count = INIT_TABLE_LENGTH(info);
	while (count) {
		/*
		 * Source is the external AML byte stream buffer,
		 * destination is the internal resource descriptor
		 */
B
Bob Moore 已提交
113 114 115
		source = ACPI_ADD_PTR(void, aml, info->aml_offset);
		destination =
		    ACPI_ADD_PTR(void, resource, info->resource_offset);
B
Bob Moore 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138

		switch (info->opcode) {
		case ACPI_RSC_INITGET:
			/*
			 * Get the resource type and the initial (minimum) length
			 */
			ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info));
			resource->type = INIT_RESOURCE_TYPE(info);
			resource->length = INIT_RESOURCE_LENGTH(info);
			break;

		case ACPI_RSC_INITSET:
			break;

		case ACPI_RSC_FLAGINIT:

			flags_mode = TRUE;
			break;

		case ACPI_RSC_1BITFLAG:
			/*
			 * Mask and shift the flag bit
			 */
139 140
			ACPI_SET8(destination,
				  ((ACPI_GET8(source) >> info->value) & 0x01));
B
Bob Moore 已提交
141 142 143 144 145 146
			break;

		case ACPI_RSC_2BITFLAG:
			/*
			 * Mask and shift the flag bits
			 */
147 148
			ACPI_SET8(destination,
				  ((ACPI_GET8(source) >> info->value) & 0x03));
B
Bob Moore 已提交
149 150
			break;

151 152 153 154
		case ACPI_RSC_3BITFLAG:
			/*
			 * Mask and shift the flag bits
			 */
155 156
			ACPI_SET8(destination,
				  ((ACPI_GET8(source) >> info->value) & 0x07));
157 158
			break;

B
Bob Moore 已提交
159 160
		case ACPI_RSC_COUNT:

B
Bob Moore 已提交
161
			item_count = ACPI_GET8(source);
162
			ACPI_SET8(destination, item_count);
B
Bob Moore 已提交
163 164 165 166 167 168 169 170

			resource->length = resource->length +
			    (info->value * (item_count - 1));
			break;

		case ACPI_RSC_COUNT16:

			item_count = aml_resource_length;
171
			ACPI_SET16(destination, item_count);
B
Bob Moore 已提交
172 173 174 175 176

			resource->length = resource->length +
			    (info->value * (item_count - 1));
			break;

177 178 179 180 181 182 183
		case ACPI_RSC_COUNT_GPIO_PIN:

			target = ACPI_ADD_PTR(void, aml, info->value);
			item_count = ACPI_GET16(target) - ACPI_GET16(source);

			resource->length = resource->length + item_count;
			item_count = item_count / 2;
184
			ACPI_SET16(destination, item_count);
185 186 187 188 189
			break;

		case ACPI_RSC_COUNT_GPIO_VEN:

			item_count = ACPI_GET8(source);
190
			ACPI_SET8(destination, item_count);
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218

			resource->length = resource->length +
			    (info->value * item_count);
			break;

		case ACPI_RSC_COUNT_GPIO_RES:

			/*
			 * Vendor data is optional (length/offset may both be zero)
			 * Examine vendor data length field first
			 */
			target = ACPI_ADD_PTR(void, aml, (info->value + 2));
			if (ACPI_GET16(target)) {

				/* Use vendor offset to get resource source length */

				target = ACPI_ADD_PTR(void, aml, info->value);
				item_count =
				    ACPI_GET16(target) - ACPI_GET16(source);
			} else {
				/* No vendor data to worry about */

				item_count = aml->large_header.resource_length +
				    sizeof(struct aml_resource_large_header) -
				    ACPI_GET16(source);
			}

			resource->length = resource->length + item_count;
219
			ACPI_SET16(destination, item_count);
220 221 222 223 224 225 226
			break;

		case ACPI_RSC_COUNT_SERIAL_VEN:

			item_count = ACPI_GET16(source) - info->value;

			resource->length = resource->length + item_count;
227
			ACPI_SET16(destination, item_count);
228 229 230 231 232 233 234 235 236
			break;

		case ACPI_RSC_COUNT_SERIAL_RES:

			item_count = (aml_resource_length +
				      sizeof(struct aml_resource_large_header))
			    - ACPI_GET16(source) - info->value;

			resource->length = resource->length + item_count;
237
			ACPI_SET16(destination, item_count);
238 239
			break;

B
Bob Moore 已提交
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
		case ACPI_RSC_LENGTH:

			resource->length = resource->length + info->value;
			break;

		case ACPI_RSC_MOVE8:
		case ACPI_RSC_MOVE16:
		case ACPI_RSC_MOVE32:
		case ACPI_RSC_MOVE64:
			/*
			 * Raw data move. Use the Info value field unless item_count has
			 * been previously initialized via a COUNT opcode
			 */
			if (info->value) {
				item_count = info->value;
			}
			acpi_rs_move_data(destination, source, item_count,
					  info->opcode);
			break;

260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
		case ACPI_RSC_MOVE_GPIO_PIN:

			/* Generate and set the PIN data pointer */

			target = (char *)ACPI_ADD_PTR(void, resource,
						      (resource->length -
						       item_count * 2));
			*(u16 **)destination = ACPI_CAST_PTR(u16, target);

			/* Copy the PIN data */

			source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source));
			acpi_rs_move_data(target, source, item_count,
					  info->opcode);
			break;

		case ACPI_RSC_MOVE_GPIO_RES:

			/* Generate and set the resource_source string pointer */

			target = (char *)ACPI_ADD_PTR(void, resource,
						      (resource->length -
						       item_count));
			*(u8 **)destination = ACPI_CAST_PTR(u8, target);

			/* Copy the resource_source string */

			source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source));
			acpi_rs_move_data(target, source, item_count,
					  info->opcode);
			break;

		case ACPI_RSC_MOVE_SERIAL_VEN:

			/* Generate and set the Vendor Data pointer */

			target = (char *)ACPI_ADD_PTR(void, resource,
						      (resource->length -
						       item_count));
			*(u8 **)destination = ACPI_CAST_PTR(u8, target);

			/* Copy the Vendor Data */

			source = ACPI_ADD_PTR(void, aml, info->value);
			acpi_rs_move_data(target, source, item_count,
					  info->opcode);
			break;

		case ACPI_RSC_MOVE_SERIAL_RES:

			/* Generate and set the resource_source string pointer */

			target = (char *)ACPI_ADD_PTR(void, resource,
						      (resource->length -
						       item_count));
			*(u8 **)destination = ACPI_CAST_PTR(u8, target);

			/* Copy the resource_source string */

			source =
			    ACPI_ADD_PTR(void, aml,
					 (ACPI_GET16(source) + info->value));
			acpi_rs_move_data(target, source, item_count,
					  info->opcode);
			break;

B
Bob Moore 已提交
326 327 328 329 330 331 332
		case ACPI_RSC_SET8:

			ACPI_MEMSET(destination, info->aml_offset, info->value);
			break;

		case ACPI_RSC_DATA8:

B
Bob Moore 已提交
333 334
			target = ACPI_ADD_PTR(char, resource, info->value);
			ACPI_MEMCPY(destination, source, ACPI_GET16(target));
B
Bob Moore 已提交
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
			break;

		case ACPI_RSC_ADDRESS:
			/*
			 * Common handler for address descriptor flags
			 */
			if (!acpi_rs_get_address_common(resource, aml)) {
				return_ACPI_STATUS
				    (AE_AML_INVALID_RESOURCE_TYPE);
			}
			break;

		case ACPI_RSC_SOURCE:
			/*
			 * Optional resource_source (Index and String)
			 */
			resource->length +=
			    acpi_rs_get_resource_source(aml_resource_length,
							info->value,
							destination, aml, NULL);
			break;

		case ACPI_RSC_SOURCEX:
			/*
			 * Optional resource_source (Index and String). This is the more
			 * complicated case used by the Interrupt() macro
			 */
362 363 364
			target = ACPI_ADD_PTR(char, resource,
					      info->aml_offset +
					      (item_count * 4));
B
Bob Moore 已提交
365 366 367

			resource->length +=
			    acpi_rs_get_resource_source(aml_resource_length,
368 369 370 371 372 373
							(acpi_rs_length)
							(((item_count -
							   1) * sizeof(u32)) +
							 info->value),
							destination, aml,
							target);
B
Bob Moore 已提交
374 375 376 377 378 379 380
			break;

		case ACPI_RSC_BITMASK:
			/*
			 * 8-bit encoded bitmask (DMA macro)
			 */
			item_count =
B
Bob Moore 已提交
381
			    acpi_rs_decode_bitmask(ACPI_GET8(source),
B
Bob Moore 已提交
382 383
						   destination);
			if (item_count) {
B
Bob Moore 已提交
384
				resource->length += (item_count - 1);
B
Bob Moore 已提交
385 386
			}

B
Bob Moore 已提交
387
			target = ACPI_ADD_PTR(char, resource, info->value);
388
			ACPI_SET8(target, item_count);
B
Bob Moore 已提交
389 390 391 392 393 394 395 396 397 398 399
			break;

		case ACPI_RSC_BITMASK16:
			/*
			 * 16-bit encoded bitmask (IRQ macro)
			 */
			ACPI_MOVE_16_TO_16(&temp16, source);

			item_count =
			    acpi_rs_decode_bitmask(temp16, destination);
			if (item_count) {
B
Bob Moore 已提交
400
				resource->length += (item_count - 1);
B
Bob Moore 已提交
401 402
			}

B
Bob Moore 已提交
403
			target = ACPI_ADD_PTR(char, resource, info->value);
404
			ACPI_SET8(target, item_count);
B
Bob Moore 已提交
405 406 407 408
			break;

		case ACPI_RSC_EXIT_NE:
			/*
409
			 * control - Exit conversion if not equal
B
Bob Moore 已提交
410 411 412 413 414 415 416 417 418
			 */
			switch (info->resource_offset) {
			case ACPI_RSC_COMPARE_AML_LENGTH:
				if (aml_resource_length != info->value) {
					goto exit;
				}
				break;

			case ACPI_RSC_COMPARE_VALUE:
B
Bob Moore 已提交
419
				if (ACPI_GET8(source) != info->value) {
B
Bob Moore 已提交
420 421 422 423 424
					goto exit;
				}
				break;

			default:
B
Bob Moore 已提交
425 426 427

				ACPI_ERROR((AE_INFO,
					    "Invalid conversion sub-opcode"));
B
Bob Moore 已提交
428 429 430 431 432 433
				return_ACPI_STATUS(AE_BAD_PARAMETER);
			}
			break;

		default:

B
Bob Moore 已提交
434
			ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
B
Bob Moore 已提交
435 436
			return_ACPI_STATUS(AE_BAD_PARAMETER);
		}
L
Linus Torvalds 已提交
437

B
Bob Moore 已提交
438 439
		count--;
		info++;
B
Bob Moore 已提交
440
	}
R
Robert Moore 已提交
441

B
Bob Moore 已提交
442 443
      exit:
	if (!flags_mode) {
B
Bob Moore 已提交
444

B
Bob Moore 已提交
445
		/* Round the resource struct length up to the next boundary (32 or 64) */
R
Robert Moore 已提交
446

B
Bob Moore 已提交
447
		resource->length =
B
Bob Moore 已提交
448
		    (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(resource->length);
B
Bob Moore 已提交
449
	}
L
Len Brown 已提交
450
	return_ACPI_STATUS(AE_OK);
L
Linus Torvalds 已提交
451 452 453 454
}

/*******************************************************************************
 *
B
Bob Moore 已提交
455
 * FUNCTION:    acpi_rs_convert_resource_to_aml
L
Linus Torvalds 已提交
456
 *
457 458 459
 * PARAMETERS:  resource            - Pointer to the resource descriptor
 *              aml                 - Where the AML descriptor is returned
 *              info                - Pointer to appropriate conversion table
L
Linus Torvalds 已提交
460 461 462
 *
 * RETURN:      Status
 *
B
Bob Moore 已提交
463 464
 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
 *              external AML resource descriptor.
L
Linus Torvalds 已提交
465 466 467 468
 *
 ******************************************************************************/

acpi_status
B
Bob Moore 已提交
469 470 471
acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
				union aml_resource *aml,
				struct acpi_rsconvert_info *info)
L
Linus Torvalds 已提交
472
{
B
Bob Moore 已提交
473 474
	void *source = NULL;
	void *destination;
475
	char *target;
B
Bob Moore 已提交
476 477 478 479
	acpi_rsdesc_size aml_length = 0;
	u8 count;
	u16 temp16 = 0;
	u16 item_count = 0;
L
Linus Torvalds 已提交
480

B
Bob Moore 已提交
481
	ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml);
B
Bob Moore 已提交
482

483 484 485 486
	if (!info) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

B
Bob Moore 已提交
487 488 489 490 491 492 493 494 495 496 497
	/*
	 * First table entry must be ACPI_RSC_INITxxx and must contain the
	 * table length (# of table entries)
	 */
	count = INIT_TABLE_LENGTH(info);

	while (count) {
		/*
		 * Source is the internal resource descriptor,
		 * destination is the external AML byte stream buffer
		 */
B
Bob Moore 已提交
498 499
		source = ACPI_ADD_PTR(void, resource, info->resource_offset);
		destination = ACPI_ADD_PTR(void, aml, info->aml_offset);
B
Bob Moore 已提交
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516

		switch (info->opcode) {
		case ACPI_RSC_INITSET:

			ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info));
			aml_length = INIT_RESOURCE_LENGTH(info);
			acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info),
						    aml_length, aml);
			break;

		case ACPI_RSC_INITGET:
			break;

		case ACPI_RSC_FLAGINIT:
			/*
			 * Clear the flag byte
			 */
517
			ACPI_SET8(destination, 0);
B
Bob Moore 已提交
518 519 520 521 522 523
			break;

		case ACPI_RSC_1BITFLAG:
			/*
			 * Mask and shift the flag bit
			 */
524 525 526
			ACPI_SET_BIT(*ACPI_CAST8(destination), (u8)
				     ((ACPI_GET8(source) & 0x01) << info->
				      value));
B
Bob Moore 已提交
527 528 529 530 531 532
			break;

		case ACPI_RSC_2BITFLAG:
			/*
			 * Mask and shift the flag bits
			 */
533 534 535
			ACPI_SET_BIT(*ACPI_CAST8(destination), (u8)
				     ((ACPI_GET8(source) & 0x03) << info->
				      value));
B
Bob Moore 已提交
536 537
			break;

538 539 540 541
		case ACPI_RSC_3BITFLAG:
			/*
			 * Mask and shift the flag bits
			 */
542 543 544
			ACPI_SET_BIT(*ACPI_CAST8(destination), (u8)
				     ((ACPI_GET8(source) & 0x07) << info->
				      value));
545 546
			break;

B
Bob Moore 已提交
547 548
		case ACPI_RSC_COUNT:

B
Bob Moore 已提交
549
			item_count = ACPI_GET8(source);
550
			ACPI_SET8(destination, item_count);
B
Bob Moore 已提交
551

B
Bob Moore 已提交
552 553 554
			aml_length =
			    (u16) (aml_length +
				   (info->value * (item_count - 1)));
B
Bob Moore 已提交
555 556 557 558
			break;

		case ACPI_RSC_COUNT16:

B
Bob Moore 已提交
559
			item_count = ACPI_GET16(source);
B
Bob Moore 已提交
560 561 562 563
			aml_length = (u16) (aml_length + item_count);
			acpi_rs_set_resource_length(aml_length, aml);
			break;

564 565 566
		case ACPI_RSC_COUNT_GPIO_PIN:

			item_count = ACPI_GET16(source);
567
			ACPI_SET16(destination, aml_length);
568 569 570

			aml_length = (u16)(aml_length + item_count * 2);
			target = ACPI_ADD_PTR(void, aml, info->value);
571
			ACPI_SET16(target, aml_length);
572 573 574 575 576 577
			acpi_rs_set_resource_length(aml_length, aml);
			break;

		case ACPI_RSC_COUNT_GPIO_VEN:

			item_count = ACPI_GET16(source);
578
			ACPI_SET16(destination, item_count);
579 580 581 582 583 584 585 586 587 588 589

			aml_length =
			    (u16)(aml_length + (info->value * item_count));
			acpi_rs_set_resource_length(aml_length, aml);
			break;

		case ACPI_RSC_COUNT_GPIO_RES:

			/* Set resource source string length */

			item_count = ACPI_GET16(source);
590
			ACPI_SET16(destination, aml_length);
591 592 593 594 595 596 597 598 599

			/* Compute offset for the Vendor Data */

			aml_length = (u16)(aml_length + item_count);
			target = ACPI_ADD_PTR(void, aml, info->value);

			/* Set vendor offset only if there is vendor data */

			if (resource->data.gpio.vendor_length) {
600
				ACPI_SET16(target, aml_length);
601 602 603 604 605 606 607 608
			}

			acpi_rs_set_resource_length(aml_length, aml);
			break;

		case ACPI_RSC_COUNT_SERIAL_VEN:

			item_count = ACPI_GET16(source);
609
			ACPI_SET16(destination, item_count + info->value);
610 611 612 613 614 615 616 617 618 619 620
			aml_length = (u16)(aml_length + item_count);
			acpi_rs_set_resource_length(aml_length, aml);
			break;

		case ACPI_RSC_COUNT_SERIAL_RES:

			item_count = ACPI_GET16(source);
			aml_length = (u16)(aml_length + item_count);
			acpi_rs_set_resource_length(aml_length, aml);
			break;

B
Bob Moore 已提交
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
		case ACPI_RSC_LENGTH:

			acpi_rs_set_resource_length(info->value, aml);
			break;

		case ACPI_RSC_MOVE8:
		case ACPI_RSC_MOVE16:
		case ACPI_RSC_MOVE32:
		case ACPI_RSC_MOVE64:

			if (info->value) {
				item_count = info->value;
			}
			acpi_rs_move_data(destination, source, item_count,
					  info->opcode);
			break;

638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
		case ACPI_RSC_MOVE_GPIO_PIN:

			destination = (char *)ACPI_ADD_PTR(void, aml,
							   ACPI_GET16
							   (destination));
			source = *(u16 **)source;
			acpi_rs_move_data(destination, source, item_count,
					  info->opcode);
			break;

		case ACPI_RSC_MOVE_GPIO_RES:

			/* Used for both resource_source string and vendor_data */

			destination = (char *)ACPI_ADD_PTR(void, aml,
							   ACPI_GET16
							   (destination));
			source = *(u8 **)source;
			acpi_rs_move_data(destination, source, item_count,
					  info->opcode);
			break;

		case ACPI_RSC_MOVE_SERIAL_VEN:

			destination = (char *)ACPI_ADD_PTR(void, aml,
							   (aml_length -
							    item_count));
			source = *(u8 **)source;
			acpi_rs_move_data(destination, source, item_count,
					  info->opcode);
			break;

		case ACPI_RSC_MOVE_SERIAL_RES:

			destination = (char *)ACPI_ADD_PTR(void, aml,
							   (aml_length -
							    item_count));
			source = *(u8 **)source;
			acpi_rs_move_data(destination, source, item_count,
					  info->opcode);
			break;

B
Bob Moore 已提交
680 681 682 683 684 685 686 687 688 689 690 691
		case ACPI_RSC_ADDRESS:

			/* Set the Resource Type, General Flags, and Type-Specific Flags */

			acpi_rs_set_address_common(aml, resource);
			break;

		case ACPI_RSC_SOURCEX:
			/*
			 * Optional resource_source (Index and String)
			 */
			aml_length =
692 693
			    acpi_rs_set_resource_source(aml,
							(acpi_rs_length)
B
Bob Moore 已提交
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
							aml_length, source);
			acpi_rs_set_resource_length(aml_length, aml);
			break;

		case ACPI_RSC_SOURCE:
			/*
			 * Optional resource_source (Index and String). This is the more
			 * complicated case used by the Interrupt() macro
			 */
			aml_length =
			    acpi_rs_set_resource_source(aml, info->value,
							source);
			acpi_rs_set_resource_length(aml_length, aml);
			break;

		case ACPI_RSC_BITMASK:
			/*
			 * 8-bit encoded bitmask (DMA macro)
			 */
713 714 715 716 717 718
			ACPI_SET8(destination,
				  acpi_rs_encode_bitmask(source,
							 *ACPI_ADD_PTR(u8,
								       resource,
								       info->
								       value)));
B
Bob Moore 已提交
719 720 721 722 723 724
			break;

		case ACPI_RSC_BITMASK16:
			/*
			 * 16-bit encoded bitmask (IRQ macro)
			 */
B
Bob Moore 已提交
725 726 727 728 729
			temp16 = acpi_rs_encode_bitmask(source,
							*ACPI_ADD_PTR(u8,
								      resource,
								      info->
								      value));
B
Bob Moore 已提交
730 731 732 733 734
			ACPI_MOVE_16_TO_16(destination, &temp16);
			break;

		case ACPI_RSC_EXIT_LE:
			/*
735
			 * control - Exit conversion if less than or equal
B
Bob Moore 已提交
736 737 738 739 740 741 742 743
			 */
			if (item_count <= info->value) {
				goto exit;
			}
			break;

		case ACPI_RSC_EXIT_NE:
			/*
744
			 * control - Exit conversion if not equal
B
Bob Moore 已提交
745 746 747
			 */
			switch (COMPARE_OPCODE(info)) {
			case ACPI_RSC_COMPARE_VALUE:
B
Bob Moore 已提交
748 749 750

				if (*ACPI_ADD_PTR(u8, resource,
						  COMPARE_TARGET(info)) !=
B
Bob Moore 已提交
751 752 753 754 755 756
				    COMPARE_VALUE(info)) {
					goto exit;
				}
				break;

			default:
B
Bob Moore 已提交
757 758 759

				ACPI_ERROR((AE_INFO,
					    "Invalid conversion sub-opcode"));
B
Bob Moore 已提交
760 761 762 763
				return_ACPI_STATUS(AE_BAD_PARAMETER);
			}
			break;

764 765
		case ACPI_RSC_EXIT_EQ:
			/*
766
			 * control - Exit conversion if equal
767 768 769 770 771 772 773 774
			 */
			if (*ACPI_ADD_PTR(u8, resource,
					  COMPARE_TARGET(info)) ==
			    COMPARE_VALUE(info)) {
				goto exit;
			}
			break;

B
Bob Moore 已提交
775 776
		default:

B
Bob Moore 已提交
777
			ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
B
Bob Moore 已提交
778
			return_ACPI_STATUS(AE_BAD_PARAMETER);
B
Bob Moore 已提交
779
		}
L
Linus Torvalds 已提交
780

B
Bob Moore 已提交
781 782
		count--;
		info++;
L
Linus Torvalds 已提交
783 784
	}

B
Bob Moore 已提交
785
      exit:
L
Len Brown 已提交
786
	return_ACPI_STATUS(AE_OK);
L
Linus Torvalds 已提交
787 788
}

B
Bob Moore 已提交
789 790
#if 0
/* Previous resource validations */
R
Robert Moore 已提交
791

792
if (aml->ext_address64.revision_ID != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) {
B
Bob Moore 已提交
793
	return_ACPI_STATUS(AE_SUPPORT);
L
Linus Torvalds 已提交
794 795
}

B
Bob Moore 已提交
796 797
if (resource->data.start_dpf.performance_robustness >= 3) {
	return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
L
Linus Torvalds 已提交
798 799
}

B
Bob Moore 已提交
800 801 802 803 804 805
if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) {
	/*
	 * Only [active_high, edge_sensitive] or [active_low, level_sensitive]
	 * polarity/trigger interrupts are allowed (ACPI spec, section
	 * "IRQ Format"), so 0x00 and 0x09 are illegal.
	 */
B
Bob Moore 已提交
806
	ACPI_ERROR((AE_INFO,
807
		    "Invalid interrupt polarity/trigger in resource list, 0x%X",
B
Bob Moore 已提交
808
		    aml->irq.flags));
B
Bob Moore 已提交
809
	return_ACPI_STATUS(AE_BAD_DATA);
L
Linus Torvalds 已提交
810 811
}

B
Bob Moore 已提交
812 813
resource->data.extended_irq.interrupt_count = temp8;
if (temp8 < 1) {
B
Bob Moore 已提交
814

B
Bob Moore 已提交
815
	/* Must have at least one IRQ */
R
Robert Moore 已提交
816

B
Bob Moore 已提交
817
	return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
L
Linus Torvalds 已提交
818 819
}

B
Bob Moore 已提交
820
if (resource->data.dma.transfer == 0x03) {
B
Bob Moore 已提交
821
	ACPI_ERROR((AE_INFO, "Invalid DMA.Transfer preference (3)"));
B
Bob Moore 已提交
822
	return_ACPI_STATUS(AE_BAD_DATA);
L
Linus Torvalds 已提交
823
}
B
Bob Moore 已提交
824
#endif