aslrestype1.c revision 281075
1/****************************************************************************** 2 * 3 * Module Name: aslrestype1 - Miscellaneous small resource descriptors 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2015, Intel Corp. 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 <contrib/dev/acpica/compiler/aslcompiler.h> 45#include "aslcompiler.y.h" 46 47#define _COMPONENT ACPI_COMPILER 48 ACPI_MODULE_NAME ("aslrestype1") 49 50/* 51 * This module contains miscellaneous small resource descriptors: 52 * 53 * EndTag 54 * EndDependentFn 55 * Memory24 56 * Memory32 57 * Memory32Fixed 58 * StartDependentFn 59 * StartDependentFnNoPri 60 * VendorShort 61 */ 62 63/******************************************************************************* 64 * 65 * FUNCTION: RsDoEndTagDescriptor 66 * 67 * PARAMETERS: Info - Parse Op and resource template offset 68 * 69 * RETURN: Completed resource node 70 * 71 * DESCRIPTION: Construct a short "EndDependentFn" descriptor 72 * 73 ******************************************************************************/ 74 75ASL_RESOURCE_NODE * 76RsDoEndTagDescriptor ( 77 ASL_RESOURCE_INFO *Info) 78{ 79 AML_RESOURCE *Descriptor; 80 ASL_RESOURCE_NODE *Rnode; 81 82 83 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_END_TAG)); 84 85 Descriptor = Rnode->Buffer; 86 Descriptor->EndTag.DescriptorType = ACPI_RESOURCE_NAME_END_TAG | 87 ASL_RDESC_END_TAG_SIZE; 88 Descriptor->EndTag.Checksum = 0; 89 90 return (Rnode); 91} 92 93 94/******************************************************************************* 95 * 96 * FUNCTION: RsDoEndDependentDescriptor 97 * 98 * PARAMETERS: Info - Parse Op and resource template offset 99 * 100 * RETURN: Completed resource node 101 * 102 * DESCRIPTION: Construct a short "EndDependentFn" descriptor 103 * 104 ******************************************************************************/ 105 106ASL_RESOURCE_NODE * 107RsDoEndDependentDescriptor ( 108 ASL_RESOURCE_INFO *Info) 109{ 110 AML_RESOURCE *Descriptor; 111 ASL_RESOURCE_NODE *Rnode; 112 113 114 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_END_DEPENDENT)); 115 116 Descriptor = Rnode->Buffer; 117 Descriptor->EndDpf.DescriptorType = ACPI_RESOURCE_NAME_END_DEPENDENT | 118 ASL_RDESC_END_DEPEND_SIZE; 119 return (Rnode); 120} 121 122 123/******************************************************************************* 124 * 125 * FUNCTION: RsDoMemory24Descriptor 126 * 127 * PARAMETERS: Info - Parse Op and resource template offset 128 * 129 * RETURN: Completed resource node 130 * 131 * DESCRIPTION: Construct a short "Memory24" descriptor 132 * 133 ******************************************************************************/ 134 135ASL_RESOURCE_NODE * 136RsDoMemory24Descriptor ( 137 ASL_RESOURCE_INFO *Info) 138{ 139 AML_RESOURCE *Descriptor; 140 ACPI_PARSE_OBJECT *InitializerOp; 141 ACPI_PARSE_OBJECT *MinOp = NULL; 142 ACPI_PARSE_OBJECT *MaxOp = NULL; 143 ACPI_PARSE_OBJECT *LengthOp = NULL; 144 ASL_RESOURCE_NODE *Rnode; 145 UINT32 CurrentByteOffset; 146 UINT32 i; 147 148 149 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 150 CurrentByteOffset = Info->CurrentByteOffset; 151 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_MEMORY24)); 152 153 Descriptor = Rnode->Buffer; 154 Descriptor->Memory24.DescriptorType = ACPI_RESOURCE_NAME_MEMORY24; 155 Descriptor->Memory24.ResourceLength = 9; 156 157 /* Process all child initialization nodes */ 158 159 for (i = 0; InitializerOp; i++) 160 { 161 switch (i) 162 { 163 case 0: /* Read/Write type */ 164 165 RsSetFlagBits (&Descriptor->Memory24.Flags, InitializerOp, 0, 1); 166 RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE, 167 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.Flags), 0); 168 break; 169 170 case 1: /* Min Address */ 171 172 Descriptor->Memory24.Minimum = (UINT16) InitializerOp->Asl.Value.Integer; 173 RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR, 174 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.Minimum)); 175 MinOp = InitializerOp; 176 break; 177 178 case 2: /* Max Address */ 179 180 Descriptor->Memory24.Maximum = (UINT16) InitializerOp->Asl.Value.Integer; 181 RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR, 182 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.Maximum)); 183 MaxOp = InitializerOp; 184 break; 185 186 case 3: /* Alignment */ 187 188 Descriptor->Memory24.Alignment = (UINT16) InitializerOp->Asl.Value.Integer; 189 RsCreateWordField (InitializerOp, ACPI_RESTAG_ALIGNMENT, 190 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.Alignment)); 191 break; 192 193 case 4: /* Length */ 194 195 Descriptor->Memory24.AddressLength = (UINT16) InitializerOp->Asl.Value.Integer; 196 RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH, 197 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory24.AddressLength)); 198 LengthOp = InitializerOp; 199 break; 200 201 case 5: /* Name */ 202 203 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 204 break; 205 206 default: 207 208 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 209 break; 210 } 211 212 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 213 } 214 215 /* Validate the Min/Max/Len/Align values (Alignment==0 means 64K) */ 216 217 RsSmallAddressCheck (ACPI_RESOURCE_NAME_MEMORY24, 218 Descriptor->Memory24.Minimum, 219 Descriptor->Memory24.Maximum, 220 Descriptor->Memory24.AddressLength, 221 Descriptor->Memory24.Alignment, 222 MinOp, MaxOp, LengthOp, NULL, Info->DescriptorTypeOp); 223 224 return (Rnode); 225} 226 227 228/******************************************************************************* 229 * 230 * FUNCTION: RsDoMemory32Descriptor 231 * 232 * PARAMETERS: Info - Parse Op and resource template offset 233 * 234 * RETURN: Completed resource node 235 * 236 * DESCRIPTION: Construct a short "Memory32" descriptor 237 * 238 ******************************************************************************/ 239 240ASL_RESOURCE_NODE * 241RsDoMemory32Descriptor ( 242 ASL_RESOURCE_INFO *Info) 243{ 244 AML_RESOURCE *Descriptor; 245 ACPI_PARSE_OBJECT *InitializerOp; 246 ACPI_PARSE_OBJECT *MinOp = NULL; 247 ACPI_PARSE_OBJECT *MaxOp = NULL; 248 ACPI_PARSE_OBJECT *LengthOp = NULL; 249 ACPI_PARSE_OBJECT *AlignOp = NULL; 250 ASL_RESOURCE_NODE *Rnode; 251 UINT32 CurrentByteOffset; 252 UINT32 i; 253 254 255 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 256 CurrentByteOffset = Info->CurrentByteOffset; 257 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_MEMORY32)); 258 259 Descriptor = Rnode->Buffer; 260 Descriptor->Memory32.DescriptorType = ACPI_RESOURCE_NAME_MEMORY32; 261 Descriptor->Memory32.ResourceLength = 17; 262 263 /* Process all child initialization nodes */ 264 265 for (i = 0; InitializerOp; i++) 266 { 267 switch (i) 268 { 269 case 0: /* Read/Write type */ 270 271 RsSetFlagBits (&Descriptor->Memory32.Flags, InitializerOp, 0, 1); 272 RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE, 273 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Flags), 0); 274 break; 275 276 case 1: /* Min Address */ 277 278 Descriptor->Memory32.Minimum = (UINT32) InitializerOp->Asl.Value.Integer; 279 RsCreateDwordField (InitializerOp, ACPI_RESTAG_MINADDR, 280 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Minimum)); 281 MinOp = InitializerOp; 282 break; 283 284 case 2: /* Max Address */ 285 286 Descriptor->Memory32.Maximum = (UINT32) InitializerOp->Asl.Value.Integer; 287 RsCreateDwordField (InitializerOp, ACPI_RESTAG_MAXADDR, 288 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Maximum)); 289 MaxOp = InitializerOp; 290 break; 291 292 case 3: /* Alignment */ 293 294 Descriptor->Memory32.Alignment = (UINT32) InitializerOp->Asl.Value.Integer; 295 RsCreateDwordField (InitializerOp, ACPI_RESTAG_ALIGNMENT, 296 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Alignment)); 297 AlignOp = InitializerOp; 298 break; 299 300 case 4: /* Length */ 301 302 Descriptor->Memory32.AddressLength = (UINT32) InitializerOp->Asl.Value.Integer; 303 RsCreateDwordField (InitializerOp, ACPI_RESTAG_LENGTH, 304 CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.AddressLength)); 305 LengthOp = InitializerOp; 306 break; 307 308 case 5: /* Name */ 309 310 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 311 break; 312 313 default: 314 315 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 316 break; 317 } 318 319 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 320 } 321 322 /* Validate the Min/Max/Len/Align values */ 323 324 RsSmallAddressCheck (ACPI_RESOURCE_NAME_MEMORY32, 325 Descriptor->Memory32.Minimum, 326 Descriptor->Memory32.Maximum, 327 Descriptor->Memory32.AddressLength, 328 Descriptor->Memory32.Alignment, 329 MinOp, MaxOp, LengthOp, AlignOp, Info->DescriptorTypeOp); 330 331 return (Rnode); 332} 333 334 335/******************************************************************************* 336 * 337 * FUNCTION: RsDoMemory32FixedDescriptor 338 * 339 * PARAMETERS: Info - Parse Op and resource template offset 340 * 341 * RETURN: Completed resource node 342 * 343 * DESCRIPTION: Construct a short "Memory32Fixed" descriptor 344 * 345 ******************************************************************************/ 346 347ASL_RESOURCE_NODE * 348RsDoMemory32FixedDescriptor ( 349 ASL_RESOURCE_INFO *Info) 350{ 351 AML_RESOURCE *Descriptor; 352 ACPI_PARSE_OBJECT *InitializerOp; 353 ASL_RESOURCE_NODE *Rnode; 354 UINT32 CurrentByteOffset; 355 UINT32 i; 356 357 358 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 359 CurrentByteOffset = Info->CurrentByteOffset; 360 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_MEMORY32)); 361 362 Descriptor = Rnode->Buffer; 363 Descriptor->FixedMemory32.DescriptorType = ACPI_RESOURCE_NAME_FIXED_MEMORY32; 364 Descriptor->FixedMemory32.ResourceLength = 9; 365 366 /* Process all child initialization nodes */ 367 368 for (i = 0; InitializerOp; i++) 369 { 370 switch (i) 371 { 372 case 0: /* Read/Write type */ 373 374 RsSetFlagBits (&Descriptor->FixedMemory32.Flags, InitializerOp, 0, 1); 375 RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE, 376 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.Flags), 0); 377 break; 378 379 case 1: /* Address */ 380 381 Descriptor->FixedMemory32.Address = (UINT32) InitializerOp->Asl.Value.Integer; 382 RsCreateDwordField (InitializerOp, ACPI_RESTAG_BASEADDRESS, 383 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.Address)); 384 break; 385 386 case 2: /* Length */ 387 388 Descriptor->FixedMemory32.AddressLength = (UINT32) InitializerOp->Asl.Value.Integer; 389 RsCreateDwordField (InitializerOp, ACPI_RESTAG_LENGTH, 390 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.AddressLength)); 391 break; 392 393 case 3: /* Name */ 394 395 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 396 break; 397 398 default: 399 400 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 401 break; 402 } 403 404 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 405 } 406 407 return (Rnode); 408} 409 410 411/******************************************************************************* 412 * 413 * FUNCTION: RsDoStartDependentDescriptor 414 * 415 * PARAMETERS: Info - Parse Op and resource template offset 416 * 417 * RETURN: Completed resource node 418 * 419 * DESCRIPTION: Construct a short "StartDependentFn" descriptor 420 * 421 ******************************************************************************/ 422 423ASL_RESOURCE_NODE * 424RsDoStartDependentDescriptor ( 425 ASL_RESOURCE_INFO *Info) 426{ 427 AML_RESOURCE *Descriptor; 428 ACPI_PARSE_OBJECT *InitializerOp; 429 ASL_RESOURCE_NODE *Rnode; 430 ASL_RESOURCE_NODE *PreviousRnode; 431 ASL_RESOURCE_NODE *NextRnode; 432 ASL_RESOURCE_INFO NextInfo; 433 UINT32 CurrentByteOffset; 434 UINT32 i; 435 UINT8 State; 436 437 438 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 439 CurrentByteOffset = Info->CurrentByteOffset; 440 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_START_DEPENDENT)); 441 442 PreviousRnode = Rnode; 443 Descriptor = Rnode->Buffer; 444 445 /* Increment offset past StartDependent descriptor */ 446 447 CurrentByteOffset += sizeof (AML_RESOURCE_START_DEPENDENT); 448 449 /* Descriptor has priority byte */ 450 451 Descriptor->StartDpf.DescriptorType = ACPI_RESOURCE_NAME_START_DEPENDENT | 452 (ASL_RDESC_ST_DEPEND_SIZE + 0x01); 453 454 /* Process all child initialization nodes */ 455 456 State = ACPI_RSTATE_START_DEPENDENT; 457 for (i = 0; InitializerOp; i++) 458 { 459 switch (i) 460 { 461 case 0: /* Compatibility Priority */ 462 463 if ((UINT8) InitializerOp->Asl.Value.Integer > 2) 464 { 465 AslError (ASL_ERROR, ASL_MSG_INVALID_PRIORITY, 466 InitializerOp, NULL); 467 } 468 469 RsSetFlagBits (&Descriptor->StartDpf.Flags, InitializerOp, 0, 0); 470 break; 471 472 case 1: /* Performance/Robustness Priority */ 473 474 if ((UINT8) InitializerOp->Asl.Value.Integer > 2) 475 { 476 AslError (ASL_ERROR, ASL_MSG_INVALID_PERFORMANCE, 477 InitializerOp, NULL); 478 } 479 480 RsSetFlagBits (&Descriptor->StartDpf.Flags, InitializerOp, 2, 0); 481 break; 482 483 default: 484 485 NextInfo.CurrentByteOffset = CurrentByteOffset; 486 NextInfo.DescriptorTypeOp = InitializerOp; 487 488 NextRnode = RsDoOneResourceDescriptor (&NextInfo, &State); 489 490 /* 491 * Update current byte offset to indicate the number of bytes from the 492 * start of the buffer. Buffer can include multiple descriptors, we 493 * must keep track of the offset of not only each descriptor, but each 494 * element (field) within each descriptor as well. 495 */ 496 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, 497 NextRnode); 498 break; 499 } 500 501 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 502 } 503 504 return (Rnode); 505} 506 507 508/******************************************************************************* 509 * 510 * FUNCTION: RsDoStartDependentNoPriDescriptor 511 * 512 * PARAMETERS: Info - Parse Op and resource template offset 513 * 514 * RETURN: Completed resource node 515 * 516 * DESCRIPTION: Construct a short "StartDependentNoPri" descriptor 517 * 518 ******************************************************************************/ 519 520ASL_RESOURCE_NODE * 521RsDoStartDependentNoPriDescriptor ( 522 ASL_RESOURCE_INFO *Info) 523{ 524 AML_RESOURCE *Descriptor; 525 ACPI_PARSE_OBJECT *InitializerOp; 526 ASL_RESOURCE_NODE *Rnode; 527 ASL_RESOURCE_NODE *PreviousRnode; 528 ASL_RESOURCE_NODE *NextRnode; 529 ASL_RESOURCE_INFO NextInfo; 530 UINT32 CurrentByteOffset; 531 UINT8 State; 532 533 534 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 535 CurrentByteOffset = Info->CurrentByteOffset; 536 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_START_DEPENDENT_NOPRIO)); 537 538 Descriptor = Rnode->Buffer; 539 Descriptor->StartDpf.DescriptorType = ACPI_RESOURCE_NAME_START_DEPENDENT | 540 ASL_RDESC_ST_DEPEND_SIZE; 541 PreviousRnode = Rnode; 542 543 /* Increment offset past StartDependentNoPri descriptor */ 544 545 CurrentByteOffset += sizeof (AML_RESOURCE_START_DEPENDENT_NOPRIO); 546 547 /* Process all child initialization nodes */ 548 549 State = ACPI_RSTATE_START_DEPENDENT; 550 while (InitializerOp) 551 { 552 NextInfo.CurrentByteOffset = CurrentByteOffset; 553 NextInfo.DescriptorTypeOp = InitializerOp; 554 555 NextRnode = RsDoOneResourceDescriptor (&NextInfo, &State); 556 557 /* 558 * Update current byte offset to indicate the number of bytes from the 559 * start of the buffer. Buffer can include multiple descriptors, we 560 * must keep track of the offset of not only each descriptor, but each 561 * element (field) within each descriptor as well. 562 */ 563 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, NextRnode); 564 565 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 566 } 567 568 return (Rnode); 569} 570 571 572/******************************************************************************* 573 * 574 * FUNCTION: RsDoVendorSmallDescriptor 575 * 576 * PARAMETERS: Info - Parse Op and resource template offset 577 * 578 * RETURN: Completed resource node 579 * 580 * DESCRIPTION: Construct a short "VendorShort" descriptor 581 * 582 ******************************************************************************/ 583 584ASL_RESOURCE_NODE * 585RsDoVendorSmallDescriptor ( 586 ASL_RESOURCE_INFO *Info) 587{ 588 AML_RESOURCE *Descriptor; 589 ACPI_PARSE_OBJECT *InitializerOp; 590 ASL_RESOURCE_NODE *Rnode; 591 UINT8 *VendorData; 592 UINT32 i; 593 594 595 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 596 597 /* Allocate worst case - 7 vendor bytes */ 598 599 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_SMALL) + 7); 600 601 Descriptor = Rnode->Buffer; 602 Descriptor->VendorSmall.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_SMALL; 603 VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_SMALL_HEADER); 604 605 /* Process all child initialization nodes */ 606 607 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 608 for (i = 0; InitializerOp; i++) 609 { 610 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 611 { 612 break; 613 } 614 615 /* Maximum 7 vendor data bytes allowed (0-6) */ 616 617 if (i >= 7) 618 { 619 AslError (ASL_ERROR, ASL_MSG_VENDOR_LIST, InitializerOp, NULL); 620 621 /* Eat the excess initializers */ 622 623 while (InitializerOp) 624 { 625 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 626 } 627 break; 628 } 629 630 VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer; 631 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 632 } 633 634 /* Adjust the Rnode buffer size, so correct number of bytes are emitted */ 635 636 Rnode->BufferLength -= (7 - i); 637 638 /* Set the length in the Type Tag */ 639 640 Descriptor->VendorSmall.DescriptorType |= (UINT8) i; 641 return (Rnode); 642} 643