rsmisc.c revision 69450
1/******************************************************************************* 2 * 3 * Module Name: rsmisc - AcpiRsEndTagResource 4 * AcpiRsEndTagStream 5 * AcpiRsVendorResource 6 * AcpiRsVendorStream 7 * AcpiRsStartDependentFunctionsResource 8 * AcpiRsEndDependentFunctionsResource 9 * AcpiRsStartDependentFunctionsStream 10 * AcpiRsEndDependentFunctionsStream 11 * $Revision: 10 $ 12 * 13 ******************************************************************************/ 14 15/****************************************************************************** 16 * 17 * 1. Copyright Notice 18 * 19 * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 20 * reserved. 21 * 22 * 2. License 23 * 24 * 2.1. This is your license from Intel Corp. under its intellectual property 25 * rights. You may have additional license terms from the party that provided 26 * you this software, covering your right to use that party's intellectual 27 * property rights. 28 * 29 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 30 * copy of the source code appearing in this file ("Covered Code") an 31 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 32 * base code distributed originally by Intel ("Original Intel Code") to copy, 33 * make derivatives, distribute, use and display any portion of the Covered 34 * Code in any form, with the right to sublicense such rights; and 35 * 36 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 37 * license (with the right to sublicense), under only those claims of Intel 38 * patents that are infringed by the Original Intel Code, to make, use, sell, 39 * offer to sell, and import the Covered Code and derivative works thereof 40 * solely to the minimum extent necessary to exercise the above copyright 41 * license, and in no event shall the patent license extend to any additions 42 * to or modifications of the Original Intel Code. No other license or right 43 * is granted directly or by implication, estoppel or otherwise; 44 * 45 * The above copyright and patent license is granted only if the following 46 * conditions are met: 47 * 48 * 3. Conditions 49 * 50 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 51 * Redistribution of source code of any substantial portion of the Covered 52 * Code or modification with rights to further distribute source must include 53 * the above Copyright Notice, the above License, this list of Conditions, 54 * and the following Disclaimer and Export Compliance provision. In addition, 55 * Licensee must cause all Covered Code to which Licensee contributes to 56 * contain a file documenting the changes Licensee made to create that Covered 57 * Code and the date of any change. Licensee must include in that file the 58 * documentation of any changes made by any predecessor Licensee. Licensee 59 * must include a prominent statement that the modification is derived, 60 * directly or indirectly, from Original Intel Code. 61 * 62 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 63 * Redistribution of source code of any substantial portion of the Covered 64 * Code or modification without rights to further distribute source must 65 * include the following Disclaimer and Export Compliance provision in the 66 * documentation and/or other materials provided with distribution. In 67 * addition, Licensee may not authorize further sublicense of source of any 68 * portion of the Covered Code, and must include terms to the effect that the 69 * license from Licensee to its licensee is limited to the intellectual 70 * property embodied in the software Licensee provides to its licensee, and 71 * not to intellectual property embodied in modifications its licensee may 72 * make. 73 * 74 * 3.3. Redistribution of Executable. Redistribution in executable form of any 75 * substantial portion of the Covered Code or modification must reproduce the 76 * above Copyright Notice, and the following Disclaimer and Export Compliance 77 * provision in the documentation and/or other materials provided with the 78 * distribution. 79 * 80 * 3.4. Intel retains all right, title, and interest in and to the Original 81 * Intel Code. 82 * 83 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 84 * Intel shall be used in advertising or otherwise to promote the sale, use or 85 * other dealings in products derived from or relating to the Covered Code 86 * without prior written authorization from Intel. 87 * 88 * 4. Disclaimer and Export Compliance 89 * 90 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 91 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 92 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 93 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 94 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 95 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 96 * PARTICULAR PURPOSE. 97 * 98 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 99 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 100 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 101 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 102 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 103 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 104 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 105 * LIMITED REMEDY. 106 * 107 * 4.3. Licensee shall not export, either directly or indirectly, any of this 108 * software or system incorporating such software without first obtaining any 109 * required license or other approval from the U. S. Department of Commerce or 110 * any other agency or department of the United States Government. In the 111 * event Licensee exports any such software from the United States or 112 * re-exports any such software from a foreign destination, Licensee shall 113 * ensure that the distribution and export/re-export of the software is in 114 * compliance with all laws, regulations, orders, or other restrictions of the 115 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 116 * any of its subsidiaries will export/re-export any technical data, process, 117 * software, or service, directly or indirectly, to any country for which the 118 * United States government or any agency thereof requires an export license, 119 * other governmental approval, or letter of assurance, without first obtaining 120 * such license, approval or letter. 121 * 122 *****************************************************************************/ 123 124#define __RSMISC_C__ 125 126#include "acpi.h" 127#include "acresrc.h" 128 129#define _COMPONENT RESOURCE_MANAGER 130 MODULE_NAME ("rsmisc") 131 132 133/******************************************************************************* 134 * 135 * FUNCTION: AcpiRsEndTagResource 136 * 137 * PARAMETERS: ByteStreamBuffer - Pointer to the resource input byte 138 * stream 139 * BytesConsumed - UINT32 pointer that is filled with 140 * the number of bytes consumed from 141 * the ByteStreamBuffer 142 * OutputBuffer - Pointer to the user's return buffer 143 * StructureSize - UINT32 pointer that is filled with 144 * the number of bytes in the filled 145 * in structure 146 * 147 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 148 * 149 * DESCRIPTION: Take the resource byte stream and fill out the appropriate 150 * structure pointed to by the OutputBuffer. Return the 151 * number of bytes consumed from the byte stream. 152 * 153 ******************************************************************************/ 154 155ACPI_STATUS 156AcpiRsEndTagResource ( 157 UINT8 *ByteStreamBuffer, 158 UINT32 *BytesConsumed, 159 UINT8 **OutputBuffer, 160 UINT32 *StructureSize) 161{ 162 RESOURCE *OutputStruct = (RESOURCE *) * OutputBuffer; 163 UINT32 StructSize = RESOURCE_LENGTH; 164 165 166 FUNCTION_TRACE ("RsEndTagResource"); 167 168 /* 169 * The number of bytes consumed is static 170 */ 171 *BytesConsumed = 2; 172 173 /* 174 * Fill out the structure 175 */ 176 OutputStruct->Id = EndTag; 177 178 /* 179 * Set the Length parameter 180 */ 181 OutputStruct->Length = 0; 182 183 /* 184 * Return the final size of the structure 185 */ 186 *StructureSize = StructSize; 187 188 return_ACPI_STATUS (AE_OK); 189} 190 191 192/******************************************************************************* 193 * 194 * FUNCTION: AcpiRsEndTagStream 195 * 196 * PARAMETERS: LinkedList - Pointer to the resource linked list 197 * OutputBuffer - Pointer to the user's return buffer 198 * BytesConsumed - UINT32 pointer that is filled with 199 * the number of bytes of the 200 * OutputBuffer used 201 * 202 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 203 * 204 * DESCRIPTION: Take the linked list resource structure and fills in the 205 * the appropriate bytes in a byte stream 206 * 207 ******************************************************************************/ 208 209ACPI_STATUS 210AcpiRsEndTagStream ( 211 RESOURCE *LinkedList, 212 UINT8 **OutputBuffer, 213 UINT32 *BytesConsumed) 214{ 215 UINT8 *Buffer = *OutputBuffer; 216 UINT8 Temp8 = 0; 217 218 219 FUNCTION_TRACE ("RsEndTagStream"); 220 221 /* 222 * The descriptor field is static 223 */ 224 *Buffer = 0x79; 225 Buffer += 1; 226 227 /* 228 * Set the Checksum - zero means that the resource data is treated as if 229 * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8) 230 */ 231 Temp8 = 0; 232 233 *Buffer = Temp8; 234 Buffer += 1; 235 236 /* 237 * Return the number of bytes consumed in this operation 238 */ 239 *BytesConsumed = (UINT32) ((NATIVE_UINT) Buffer - 240 (NATIVE_UINT) *OutputBuffer); 241 242 return_ACPI_STATUS (AE_OK); 243} 244 245 246/******************************************************************************* 247 * 248 * FUNCTION: AcpiRsVendorResource 249 * 250 * PARAMETERS: ByteStreamBuffer - Pointer to the resource input byte 251 * stream 252 * BytesConsumed - UINT32 pointer that is filled with 253 * the number of bytes consumed from 254 * the ByteStreamBuffer 255 * OutputBuffer - Pointer to the user's return buffer 256 * StructureSize - UINT32 pointer that is filled with 257 * the number of bytes in the filled 258 * in structure 259 * 260 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 261 * 262 * DESCRIPTION: Take the resource byte stream and fill out the appropriate 263 * structure pointed to by the OutputBuffer. Return the 264 * number of bytes consumed from the byte stream. 265 * 266 ******************************************************************************/ 267 268ACPI_STATUS 269AcpiRsVendorResource ( 270 UINT8 *ByteStreamBuffer, 271 UINT32 *BytesConsumed, 272 UINT8 **OutputBuffer, 273 UINT32 *StructureSize) 274{ 275 UINT8 *Buffer = ByteStreamBuffer; 276 RESOURCE *OutputStruct = (RESOURCE *) * OutputBuffer; 277 UINT16 Temp16 = 0; 278 UINT8 Temp8 = 0; 279 UINT8 Index; 280 UINT32 StructSize = sizeof (VENDOR_RESOURCE) + 281 RESOURCE_LENGTH_NO_DATA; 282 283 284 FUNCTION_TRACE ("RsVendorResource"); 285 286 /* 287 * Dereference the Descriptor to find if this is a large or small item. 288 */ 289 Temp8 = *Buffer; 290 291 if (Temp8 & 0x80) 292 { 293 /* 294 * Large Item 295 */ 296 /* Point to the length field */ 297 298 Buffer += 1; 299 300 /* Dereference */ 301 302 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 303 304 /* Calculate bytes consumed */ 305 306 *BytesConsumed = Temp16 + 3; 307 308 /* Point to the first vendor byte */ 309 310 Buffer += 2; 311 } 312 313 else 314 { 315 /* 316 * Small Item 317 */ 318 319 /* Dereference the size */ 320 321 Temp16 = (UINT8)(*Buffer & 0x07); 322 323 /* Calculate bytes consumed */ 324 325 *BytesConsumed = Temp16 + 1; 326 327 /* Point to the first vendor byte */ 328 329 Buffer += 1; 330 } 331 332 OutputStruct->Id = VendorSpecific; 333 OutputStruct->Data.VendorSpecific.Length = Temp16; 334 335 for (Index = 0; Index < Temp16; Index++) 336 { 337 OutputStruct->Data.VendorSpecific.Reserved[Index] = *Buffer; 338 Buffer += 1; 339 } 340 341 /* 342 * In order for the StructSize to fall on a 32-bit boundry, 343 * calculate the length of the vendor string and expand the 344 * StructSize to the next 32-bit boundry. 345 */ 346 StructSize += ROUND_UP_TO_32BITS (Temp16); 347 348 /* 349 * Set the Length parameter 350 */ 351 OutputStruct->Length = StructSize; 352 353 /* 354 * Return the final size of the structure 355 */ 356 *StructureSize = StructSize; 357 358 return_ACPI_STATUS (AE_OK); 359} 360 361 362/******************************************************************************* 363 * 364 * FUNCTION: AcpiRsVendorStream 365 * 366 * PARAMETERS: LinkedList - Pointer to the resource linked list 367 * OutputBuffer - Pointer to the user's return buffer 368 * BytesConsumed - UINT32 pointer that is filled with 369 * the number of bytes of the 370 * OutputBuffer used 371 * 372 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 373 * 374 * DESCRIPTION: Take the linked list resource structure and fills in the 375 * the appropriate bytes in a byte stream 376 * 377 ******************************************************************************/ 378 379ACPI_STATUS 380AcpiRsVendorStream ( 381 RESOURCE *LinkedList, 382 UINT8 **OutputBuffer, 383 UINT32 *BytesConsumed) 384{ 385 UINT8 *Buffer = *OutputBuffer; 386 UINT16 Temp16 = 0; 387 UINT8 Temp8 = 0; 388 UINT8 Index; 389 390 391 FUNCTION_TRACE ("RsVendorStream"); 392 393 /* 394 * Dereference the length to find if this is a large or small item. 395 */ 396 397 if(LinkedList->Data.VendorSpecific.Length > 7) 398 { 399 /* 400 * Large Item 401 */ 402 /* 403 * Set the descriptor field and length bytes 404 */ 405 *Buffer = 0x84; 406 Buffer += 1; 407 408 Temp16 = (UINT16) LinkedList->Data.VendorSpecific.Length; 409 410 MOVE_UNALIGNED16_TO_16 (Buffer, &Temp16); 411 Buffer += 2; 412 } 413 414 else 415 { 416 /* 417 * Small Item 418 */ 419 420 /* 421 * Set the descriptor field 422 */ 423 Temp8 = 0x70; 424 Temp8 |= LinkedList->Data.VendorSpecific.Length; 425 426 *Buffer = Temp8; 427 Buffer += 1; 428 } 429 430 /* 431 * Loop through all of the Vendor Specific fields 432 */ 433 for (Index = 0; Index < LinkedList->Data.VendorSpecific.Length; Index++) 434 { 435 Temp8 = LinkedList->Data.VendorSpecific.Reserved[Index]; 436 437 *Buffer = Temp8; 438 Buffer += 1; 439 } 440 441 /* 442 * Return the number of bytes consumed in this operation 443 */ 444 *BytesConsumed = (UINT32) ((NATIVE_UINT) Buffer - 445 (NATIVE_UINT) *OutputBuffer); 446 447 return_ACPI_STATUS (AE_OK); 448} 449 450 451/******************************************************************************* 452 * 453 * FUNCTION: AcpiRsStartDependentFunctionsResource 454 * 455 * PARAMETERS: ByteStreamBuffer - Pointer to the resource input byte 456 * stream 457 * BytesConsumed - UINT32 pointer that is filled with 458 * the number of bytes consumed from 459 * the ByteStreamBuffer 460 * OutputBuffer - Pointer to the user's return buffer 461 * StructureSize - UINT32 pointer that is filled with 462 * the number of bytes in the filled 463 * in structure 464 * 465 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 466 * 467 * DESCRIPTION: Take the resource byte stream and fill out the appropriate 468 * structure pointed to by the OutputBuffer. Return the 469 * number of bytes consumed from the byte stream. 470 * 471 ******************************************************************************/ 472 473ACPI_STATUS 474AcpiRsStartDependentFunctionsResource ( 475 UINT8 *ByteStreamBuffer, 476 UINT32 *BytesConsumed, 477 UINT8 **OutputBuffer, 478 UINT32 *StructureSize) 479{ 480 UINT8 *Buffer = ByteStreamBuffer; 481 RESOURCE *OutputStruct = (RESOURCE *) * OutputBuffer; 482 UINT8 Temp8 = 0; 483 UINT32 StructSize = 484 sizeof(START_DEPENDENT_FUNCTIONS_RESOURCE) + 485 RESOURCE_LENGTH_NO_DATA; 486 487 488 FUNCTION_TRACE ("RsStartDependentFunctionsResource"); 489 490 /* 491 * The number of bytes consumed are contained in the descriptor (Bits:0-1) 492 */ 493 Temp8 = *Buffer; 494 495 *BytesConsumed = (Temp8 & 0x01) + 1; 496 497 OutputStruct->Id = StartDependentFunctions; 498 499 /* 500 * Point to Byte 1 if it is used 501 */ 502 if (2 == *BytesConsumed) 503 { 504 Buffer += 1; 505 Temp8 = *Buffer; 506 507 /* 508 * Check Compatibility priority 509 */ 510 OutputStruct->Data.StartDependentFunctions.CompatibilityPriority = 511 Temp8 & 0x03; 512 513 if (3 == OutputStruct->Data.StartDependentFunctions.CompatibilityPriority) 514 { 515 return_ACPI_STATUS (AE_AML_ERROR); 516 } 517 518 /* 519 * Check Performance/Robustness preference 520 */ 521 OutputStruct->Data.StartDependentFunctions.PerformanceRobustness = 522 (Temp8 >> 2) & 0x03; 523 524 if (3 == OutputStruct->Data.StartDependentFunctions.PerformanceRobustness) 525 { 526 return_ACPI_STATUS (AE_AML_ERROR); 527 } 528 } 529 530 else 531 { 532 OutputStruct->Data.StartDependentFunctions.CompatibilityPriority = 533 ACCEPTABLE_CONFIGURATION; 534 535 OutputStruct->Data.StartDependentFunctions.PerformanceRobustness = 536 ACCEPTABLE_CONFIGURATION; 537 } 538 539 /* 540 * Set the Length parameter 541 */ 542 OutputStruct->Length = StructSize; 543 544 /* 545 * Return the final size of the structure 546 */ 547 *StructureSize = StructSize; 548 549 return_ACPI_STATUS (AE_OK); 550} 551 552 553/******************************************************************************* 554 * 555 * FUNCTION: AcpiRsEndDependentFunctionsResource 556 * 557 * PARAMETERS: ByteStreamBuffer - Pointer to the resource input byte 558 * stream 559 * BytesConsumed - UINT32 pointer that is filled with 560 * the number of bytes consumed from 561 * the ByteStreamBuffer 562 * OutputBuffer - Pointer to the user's return buffer 563 * StructureSize - UINT32 pointer that is filled with 564 * the number of bytes in the filled 565 * in structure 566 * 567 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 568 * 569 * DESCRIPTION: Take the resource byte stream and fill out the appropriate 570 * structure pointed to by the OutputBuffer. Return the 571 * number of bytes consumed from the byte stream. 572 * 573 ******************************************************************************/ 574 575ACPI_STATUS 576AcpiRsEndDependentFunctionsResource ( 577 UINT8 *ByteStreamBuffer, 578 UINT32 *BytesConsumed, 579 UINT8 **OutputBuffer, 580 UINT32 *StructureSize) 581{ 582 RESOURCE *OutputStruct = (RESOURCE *) * OutputBuffer; 583 UINT32 StructSize = RESOURCE_LENGTH; 584 585 586 FUNCTION_TRACE ("RsEndDependentFunctionsResource"); 587 588 /* 589 * The number of bytes consumed is static 590 */ 591 *BytesConsumed = 1; 592 593 /* 594 * Fill out the structure 595 */ 596 OutputStruct->Id = EndDependentFunctions; 597 598 /* 599 * Set the Length parameter 600 */ 601 OutputStruct->Length = StructSize; 602 603 /* 604 * Return the final size of the structure 605 */ 606 *StructureSize = StructSize; 607 608 return_ACPI_STATUS (AE_OK); 609} 610 611 612/******************************************************************************* 613 * 614 * FUNCTION: AcpiRsStartDependentFunctionsStream 615 * 616 * PARAMETERS: LinkedList - Pointer to the resource linked list 617 * OutputBuffer - Pointer to the user's return buffer 618 * BytesConsumed - UINT32 pointer that is filled with 619 * the number of bytes of the 620 * OutputBuffer used 621 * 622 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 623 * 624 * DESCRIPTION: Take the linked list resource structure and fills in the 625 * the appropriate bytes in a byte stream 626 * 627 ******************************************************************************/ 628 629ACPI_STATUS 630AcpiRsStartDependentFunctionsStream ( 631 RESOURCE *LinkedList, 632 UINT8 **OutputBuffer, 633 UINT32 *BytesConsumed) 634{ 635 UINT8 *Buffer = *OutputBuffer; 636 UINT8 Temp8 = 0; 637 638 639 FUNCTION_TRACE ("RsStartDependentFunctionsStream"); 640 641 /* 642 * The descriptor field is set based upon whether a byte is needed 643 * to contain Priority data. 644 */ 645 if (ACCEPTABLE_CONFIGURATION == 646 LinkedList->Data.StartDependentFunctions.CompatibilityPriority && 647 ACCEPTABLE_CONFIGURATION == 648 LinkedList->Data.StartDependentFunctions.PerformanceRobustness) 649 { 650 *Buffer = 0x30; 651 } 652 else 653 { 654 *Buffer = 0x31; 655 Buffer += 1; 656 657 /* 658 * Set the Priority Byte Definition 659 */ 660 Temp8 = 0; 661 Temp8 = (UINT8) 662 ((LinkedList->Data.StartDependentFunctions.PerformanceRobustness & 663 0x03) << 2); 664 Temp8 |= 665 (LinkedList->Data.StartDependentFunctions.CompatibilityPriority & 666 0x03); 667 668 *Buffer = Temp8; 669 } 670 671 Buffer += 1; 672 673 /* 674 * Return the number of bytes consumed in this operation 675 */ 676 *BytesConsumed = (UINT32) ((NATIVE_UINT) Buffer - 677 (NATIVE_UINT) *OutputBuffer); 678 679 return_ACPI_STATUS (AE_OK); 680} 681 682 683/******************************************************************************* 684 * 685 * FUNCTION: AcpiRsEndDependentFunctionsStream 686 * 687 * PARAMETERS: LinkedList - Pointer to the resource linked list 688 * OutputBuffer - Pointer to the user's return buffer 689 * BytesConsumed - UINT32 pointer that is filled with 690 * the number of bytes of the 691 * OutputBuffer used 692 * 693 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 694 * 695 * DESCRIPTION: Take the linked list resource structure and fills in the 696 * the appropriate bytes in a byte stream 697 * 698 ******************************************************************************/ 699 700ACPI_STATUS 701AcpiRsEndDependentFunctionsStream ( 702 RESOURCE *LinkedList, 703 UINT8 **OutputBuffer, 704 UINT32 *BytesConsumed 705 ) 706{ 707 UINT8 *Buffer = *OutputBuffer; 708 709 710 FUNCTION_TRACE ("RsEndDependentFunctionsStream"); 711 712 /* 713 * The descriptor field is static 714 */ 715 *Buffer = 0x38; 716 Buffer += 1; 717 718 /* 719 * Return the number of bytes consumed in this operation 720 */ 721 *BytesConsumed = (UINT32) ((NATIVE_UINT) Buffer - 722 (NATIVE_UINT) *OutputBuffer); 723 724 return_ACPI_STATUS (AE_OK); 725} 726 727