Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: nsalloc - Namespace allocation and deletion utilities
  4.  *
  5.  ******************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
  12.  * All rights reserved.
  13.  *
  14.  * 2. License
  15.  *
  16.  * 2.1. This is your license from Intel Corp. under its intellectual property
  17.  * rights.  You may have additional license terms from the party that provided
  18.  * you this software, covering your right to use that party's intellectual
  19.  * property rights.
  20.  *
  21.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22.  * copy of the source code appearing in this file ("Covered Code") an
  23.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25.  * make derivatives, distribute, use and display any portion of the Covered
  26.  * Code in any form, with the right to sublicense such rights; and
  27.  *
  28.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29.  * license (with the right to sublicense), under only those claims of Intel
  30.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31.  * offer to sell, and import the Covered Code and derivative works thereof
  32.  * solely to the minimum extent necessary to exercise the above copyright
  33.  * license, and in no event shall the patent license extend to any additions
  34.  * to or modifications of the Original Intel Code.  No other license or right
  35.  * is granted directly or by implication, estoppel or otherwise;
  36.  *
  37.  * The above copyright and patent license is granted only if the following
  38.  * conditions are met:
  39.  *
  40.  * 3. Conditions
  41.  *
  42.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43.  * Redistribution of source code of any substantial portion of the Covered
  44.  * Code or modification with rights to further distribute source must include
  45.  * the above Copyright Notice, the above License, this list of Conditions,
  46.  * and the following Disclaimer and Export Compliance provision.  In addition,
  47.  * Licensee must cause all Covered Code to which Licensee contributes to
  48.  * contain a file documenting the changes Licensee made to create that Covered
  49.  * Code and the date of any change.  Licensee must include in that file the
  50.  * documentation of any changes made by any predecessor Licensee.  Licensee
  51.  * must include a prominent statement that the modification is derived,
  52.  * directly or indirectly, from Original Intel Code.
  53.  *
  54.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55.  * Redistribution of source code of any substantial portion of the Covered
  56.  * Code or modification without rights to further distribute source must
  57.  * include the following Disclaimer and Export Compliance provision in the
  58.  * documentation and/or other materials provided with distribution.  In
  59.  * addition, Licensee may not authorize further sublicense of source of any
  60.  * portion of the Covered Code, and must include terms to the effect that the
  61.  * license from Licensee to its licensee is limited to the intellectual
  62.  * property embodied in the software Licensee provides to its licensee, and
  63.  * not to intellectual property embodied in modifications its licensee may
  64.  * make.
  65.  *
  66.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67.  * substantial portion of the Covered Code or modification must reproduce the
  68.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69.  * provision in the documentation and/or other materials provided with the
  70.  * distribution.
  71.  *
  72.  * 3.4. Intel retains all right, title, and interest in and to the Original
  73.  * Intel Code.
  74.  *
  75.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77.  * other dealings in products derived from or relating to the Covered Code
  78.  * without prior written authorization from Intel.
  79.  *
  80.  * 4. Disclaimer and Export Compliance
  81.  *
  82.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  85.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  86.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  87.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88.  * PARTICULAR PURPOSE.
  89.  *
  90.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  96.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97.  * LIMITED REMEDY.
  98.  *
  99.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100.  * software or system incorporating such software without first obtaining any
  101.  * required license or other approval from the U. S. Department of Commerce or
  102.  * any other agency or department of the United States Government.  In the
  103.  * event Licensee exports any such software from the United States or
  104.  * re-exports any such software from a foreign destination, Licensee shall
  105.  * ensure that the distribution and export/re-export of the software is in
  106.  * compliance with all laws, regulations, orders, or other restrictions of the
  107.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108.  * any of its subsidiaries will export/re-export any technical data, process,
  109.  * software, or service, directly or indirectly, to any country for which the
  110.  * United States government or any agency thereof requires an export license,
  111.  * other governmental approval, or letter of assurance, without first obtaining
  112.  * such license, approval or letter.
  113.  *
  114.  *****************************************************************************/
  115.  
  116.  
  117. #define __NSALLOC_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "acnamesp.h"
  122.  
  123.  
  124. #define _COMPONENT          ACPI_NAMESPACE
  125.         ACPI_MODULE_NAME    ("nsalloc")
  126.  
  127.  
  128. /*******************************************************************************
  129.  *
  130.  * FUNCTION:    AcpiNsCreateNode
  131.  *
  132.  * PARAMETERS:  Name            - Name of the new node (4 char ACPI name)
  133.  *
  134.  * RETURN:      New namespace node (Null on failure)
  135.  *
  136.  * DESCRIPTION: Create a namespace node
  137.  *
  138.  ******************************************************************************/
  139.  
  140. ACPI_NAMESPACE_NODE *
  141. AcpiNsCreateNode (
  142.     UINT32                  Name)
  143. {
  144.     ACPI_NAMESPACE_NODE     *Node;
  145. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  146.     UINT32                  Temp;
  147. #endif
  148.  
  149.  
  150.     ACPI_FUNCTION_TRACE (NsCreateNode);
  151.  
  152.  
  153.     Node = AcpiOsAcquireObject (AcpiGbl_NamespaceCache);
  154.     if (!Node)
  155.     {
  156.         return_PTR (NULL);
  157.     }
  158.  
  159.     ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalAllocated++);
  160.  
  161. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  162.         Temp = AcpiGbl_NsNodeList->TotalAllocated -
  163.                 AcpiGbl_NsNodeList->TotalFreed;
  164.         if (Temp > AcpiGbl_NsNodeList->MaxOccupied)
  165.         {
  166.             AcpiGbl_NsNodeList->MaxOccupied = Temp;
  167.         }
  168. #endif
  169.  
  170.     Node->Name.Integer = Name;
  171.     ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED);
  172.     return_PTR (Node);
  173. }
  174.  
  175.  
  176. /*******************************************************************************
  177.  *
  178.  * FUNCTION:    AcpiNsDeleteNode
  179.  *
  180.  * PARAMETERS:  Node            - Node to be deleted
  181.  *
  182.  * RETURN:      None
  183.  *
  184.  * DESCRIPTION: Delete a namespace node. All node deletions must come through
  185.  *              here. Detaches any attached objects, including any attached
  186.  *              data. If a handler is associated with attached data, it is
  187.  *              invoked before the node is deleted.
  188.  *
  189.  ******************************************************************************/
  190.  
  191. void
  192. AcpiNsDeleteNode (
  193.     ACPI_NAMESPACE_NODE     *Node)
  194. {
  195.     ACPI_OPERAND_OBJECT     *ObjDesc;
  196.  
  197.  
  198.     ACPI_FUNCTION_NAME (NsDeleteNode);
  199.  
  200.  
  201.     /* Detach an object if there is one */
  202.  
  203.     AcpiNsDetachObject (Node);
  204.  
  205.     /*
  206.      * Delete an attached data object if present (an object that was created
  207.      * and attached via AcpiAttachData). Note: After any normal object is
  208.      * detached above, the only possible remaining object is a data object.
  209.      */
  210.     ObjDesc = Node->Object;
  211.     if (ObjDesc &&
  212.         (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA))
  213.     {
  214.         /* Invoke the attached data deletion handler if present */
  215.  
  216.         if (ObjDesc->Data.Handler)
  217.         {
  218.             ObjDesc->Data.Handler (Node, ObjDesc->Data.Pointer);
  219.         }
  220.  
  221.         AcpiUtRemoveReference (ObjDesc);
  222.     }
  223.  
  224.     /* Now we can delete the node */
  225.  
  226.     (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node);
  227.  
  228.     ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
  229.     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n",
  230.         Node, AcpiGbl_CurrentNodeCount));
  231. }
  232.  
  233.  
  234. /*******************************************************************************
  235.  *
  236.  * FUNCTION:    AcpiNsRemoveNode
  237.  *
  238.  * PARAMETERS:  Node            - Node to be removed/deleted
  239.  *
  240.  * RETURN:      None
  241.  *
  242.  * DESCRIPTION: Remove (unlink) and delete a namespace node
  243.  *
  244.  ******************************************************************************/
  245.  
  246. void
  247. AcpiNsRemoveNode (
  248.     ACPI_NAMESPACE_NODE     *Node)
  249. {
  250.     ACPI_NAMESPACE_NODE     *ParentNode;
  251.     ACPI_NAMESPACE_NODE     *PrevNode;
  252.     ACPI_NAMESPACE_NODE     *NextNode;
  253.  
  254.  
  255.     ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node);
  256.  
  257.  
  258.     ParentNode = Node->Parent;
  259.  
  260.     PrevNode = NULL;
  261.     NextNode = ParentNode->Child;
  262.  
  263.     /* Find the node that is the previous peer in the parent's child list */
  264.  
  265.     while (NextNode != Node)
  266.     {
  267.         PrevNode = NextNode;
  268.         NextNode = NextNode->Peer;
  269.     }
  270.  
  271.     if (PrevNode)
  272.     {
  273.         /* Node is not first child, unlink it */
  274.  
  275.         PrevNode->Peer = Node->Peer;
  276.     }
  277.     else
  278.     {
  279.         /*
  280.          * Node is first child (has no previous peer).
  281.          * Link peer list to parent
  282.          */
  283.         ParentNode->Child = Node->Peer;
  284.     }
  285.  
  286.     /* Delete the node and any attached objects */
  287.  
  288.     AcpiNsDeleteNode (Node);
  289.     return_VOID;
  290. }
  291.  
  292.  
  293. /*******************************************************************************
  294.  *
  295.  * FUNCTION:    AcpiNsInstallNode
  296.  *
  297.  * PARAMETERS:  WalkState       - Current state of the walk
  298.  *              ParentNode      - The parent of the new Node
  299.  *              Node            - The new Node to install
  300.  *              Type            - ACPI object type of the new Node
  301.  *
  302.  * RETURN:      None
  303.  *
  304.  * DESCRIPTION: Initialize a new namespace node and install it amongst
  305.  *              its peers.
  306.  *
  307.  *              Note: Current namespace lookup is linear search. This appears
  308.  *              to be sufficient as namespace searches consume only a small
  309.  *              fraction of the execution time of the ACPI subsystem.
  310.  *
  311.  ******************************************************************************/
  312.  
  313. void
  314. AcpiNsInstallNode (
  315.     ACPI_WALK_STATE         *WalkState,
  316.     ACPI_NAMESPACE_NODE     *ParentNode,    /* Parent */
  317.     ACPI_NAMESPACE_NODE     *Node,          /* New Child*/
  318.     ACPI_OBJECT_TYPE        Type)
  319. {
  320.     ACPI_OWNER_ID           OwnerId = 0;
  321.     ACPI_NAMESPACE_NODE     *ChildNode;
  322.  
  323.  
  324.     ACPI_FUNCTION_TRACE (NsInstallNode);
  325.  
  326.  
  327.     if (WalkState)
  328.     {
  329.         /*
  330.          * Get the owner ID from the Walk state. The owner ID is used to
  331.          * track table deletion and deletion of objects created by methods.
  332.          */
  333.         OwnerId = WalkState->OwnerId;
  334.  
  335.         if ((WalkState->MethodDesc) &&
  336.             (ParentNode != WalkState->MethodNode))
  337.         {
  338.             /*
  339.              * A method is creating a new node that is not a child of the
  340.              * method (it is non-local). Mark the executing method as having
  341.              * modified the namespace. This is used for cleanup when the
  342.              * method exits.
  343.              */
  344.             WalkState->MethodDesc->Method.Flags |= AOPOBJ_MODIFIED_NAMESPACE;
  345.         }
  346.     }
  347.  
  348.     /* Link the new entry into the parent and existing children */
  349.  
  350.     Node->Peer = NULL;
  351.     Node->Parent = ParentNode;
  352.     ChildNode = ParentNode->Child;
  353.  
  354.     if (!ChildNode)
  355.     {
  356.         ParentNode->Child = Node;
  357.     }
  358.     else
  359.     {
  360.         /* Add node to the end of the peer list */
  361.  
  362.         while (ChildNode->Peer)
  363.         {
  364.             ChildNode = ChildNode->Peer;
  365.         }
  366.  
  367.         ChildNode->Peer = Node;
  368.     }
  369.  
  370.     /* Init the new entry */
  371.  
  372.     Node->OwnerId = OwnerId;
  373.     Node->Type = (UINT8) Type;
  374.  
  375.     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  376.         "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
  377.         AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId,
  378.         AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type),
  379.         ParentNode));
  380.  
  381.     return_VOID;
  382. }
  383.  
  384.  
  385. /*******************************************************************************
  386.  *
  387.  * FUNCTION:    AcpiNsDeleteChildren
  388.  *
  389.  * PARAMETERS:  ParentNode      - Delete this objects children
  390.  *
  391.  * RETURN:      None.
  392.  *
  393.  * DESCRIPTION: Delete all children of the parent object. In other words,
  394.  *              deletes a "scope".
  395.  *
  396.  ******************************************************************************/
  397.  
  398. void
  399. AcpiNsDeleteChildren (
  400.     ACPI_NAMESPACE_NODE     *ParentNode)
  401. {
  402.     ACPI_NAMESPACE_NODE     *NextNode;
  403.     ACPI_NAMESPACE_NODE     *NodeToDelete;
  404.  
  405.  
  406.     ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode);
  407.  
  408.  
  409.     if (!ParentNode)
  410.     {
  411.         return_VOID;
  412.     }
  413.  
  414.     /* Deallocate all children at this level */
  415.  
  416.     NextNode = ParentNode->Child;
  417.     while (NextNode)
  418.     {
  419.         /* Grandchildren should have all been deleted already */
  420.  
  421.         if (NextNode->Child)
  422.         {
  423.             ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p",
  424.                 ParentNode, NextNode));
  425.         }
  426.  
  427.         /*
  428.          * Delete this child node and move on to the next child in the list.
  429.          * No need to unlink the node since we are deleting the entire branch.
  430.          */
  431.         NodeToDelete = NextNode;
  432.         NextNode = NextNode->Peer;
  433.         AcpiNsDeleteNode (NodeToDelete);
  434.     };
  435.  
  436.     /* Clear the parent's child pointer */
  437.  
  438.     ParentNode->Child = NULL;
  439.     return_VOID;
  440. }
  441.  
  442.  
  443. /*******************************************************************************
  444.  *
  445.  * FUNCTION:    AcpiNsDeleteNamespaceSubtree
  446.  *
  447.  * PARAMETERS:  ParentNode      - Root of the subtree to be deleted
  448.  *
  449.  * RETURN:      None.
  450.  *
  451.  * DESCRIPTION: Delete a subtree of the namespace.  This includes all objects
  452.  *              stored within the subtree.
  453.  *
  454.  ******************************************************************************/
  455.  
  456. void
  457. AcpiNsDeleteNamespaceSubtree (
  458.     ACPI_NAMESPACE_NODE     *ParentNode)
  459. {
  460.     ACPI_NAMESPACE_NODE     *ChildNode = NULL;
  461.     UINT32                  Level = 1;
  462.  
  463.  
  464.     ACPI_FUNCTION_TRACE (NsDeleteNamespaceSubtree);
  465.  
  466.  
  467.     if (!ParentNode)
  468.     {
  469.         return_VOID;
  470.     }
  471.  
  472.     /*
  473.      * Traverse the tree of objects until we bubble back up
  474.      * to where we started.
  475.      */
  476.     while (Level > 0)
  477.     {
  478.         /* Get the next node in this scope (NULL if none) */
  479.  
  480.         ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
  481.         if (ChildNode)
  482.         {
  483.             /* Found a child node - detach any attached object */
  484.  
  485.             AcpiNsDetachObject (ChildNode);
  486.  
  487.             /* Check if this node has any children */
  488.  
  489.             if (ChildNode->Child)
  490.             {
  491.                 /*
  492.                  * There is at least one child of this node,
  493.                  * visit the node
  494.                  */
  495.                 Level++;
  496.                 ParentNode = ChildNode;
  497.                 ChildNode  = NULL;
  498.             }
  499.         }
  500.         else
  501.         {
  502.             /*
  503.              * No more children of this parent node.
  504.              * Move up to the grandparent.
  505.              */
  506.             Level--;
  507.  
  508.             /*
  509.              * Now delete all of the children of this parent
  510.              * all at the same time.
  511.              */
  512.             AcpiNsDeleteChildren (ParentNode);
  513.  
  514.             /* New "last child" is this parent node */
  515.  
  516.             ChildNode = ParentNode;
  517.  
  518.             /* Move up the tree to the grandparent */
  519.  
  520.             ParentNode = ParentNode->Parent;
  521.         }
  522.     }
  523.  
  524.     return_VOID;
  525. }
  526.  
  527.  
  528. /*******************************************************************************
  529.  *
  530.  * FUNCTION:    AcpiNsDeleteNamespaceByOwner
  531.  *
  532.  * PARAMETERS:  OwnerId     - All nodes with this owner will be deleted
  533.  *
  534.  * RETURN:      Status
  535.  *
  536.  * DESCRIPTION: Delete entries within the namespace that are owned by a
  537.  *              specific ID.  Used to delete entire ACPI tables.  All
  538.  *              reference counts are updated.
  539.  *
  540.  * MUTEX:       Locks namespace during deletion walk.
  541.  *
  542.  ******************************************************************************/
  543.  
  544. void
  545. AcpiNsDeleteNamespaceByOwner (
  546.     ACPI_OWNER_ID            OwnerId)
  547. {
  548.     ACPI_NAMESPACE_NODE     *ChildNode;
  549.     ACPI_NAMESPACE_NODE     *DeletionNode;
  550.     ACPI_NAMESPACE_NODE     *ParentNode;
  551.     UINT32                  Level;
  552.     ACPI_STATUS             Status;
  553.  
  554.  
  555.     ACPI_FUNCTION_TRACE_U32 (NsDeleteNamespaceByOwner, OwnerId);
  556.  
  557.  
  558.     if (OwnerId == 0)
  559.     {
  560.         return_VOID;
  561.     }
  562.  
  563.     /* Lock namespace for possible update */
  564.  
  565.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  566.     if (ACPI_FAILURE (Status))
  567.     {
  568.         return_VOID;
  569.     }
  570.  
  571.     DeletionNode = NULL;
  572.     ParentNode = AcpiGbl_RootNode;
  573.     ChildNode = NULL;
  574.     Level = 1;
  575.  
  576.     /*
  577.      * Traverse the tree of nodes until we bubble back up
  578.      * to where we started.
  579.      */
  580.     while (Level > 0)
  581.     {
  582.         /*
  583.          * Get the next child of this parent node. When ChildNode is NULL,
  584.          * the first child of the parent is returned
  585.          */
  586.         ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
  587.  
  588.         if (DeletionNode)
  589.         {
  590.             AcpiNsDeleteChildren (DeletionNode);
  591.             AcpiNsRemoveNode (DeletionNode);
  592.             DeletionNode = NULL;
  593.         }
  594.  
  595.         if (ChildNode)
  596.         {
  597.             if (ChildNode->OwnerId == OwnerId)
  598.             {
  599.                 /* Found a matching child node - detach any attached object */
  600.  
  601.                 AcpiNsDetachObject (ChildNode);
  602.             }
  603.  
  604.             /* Check if this node has any children */
  605.  
  606.             if (ChildNode->Child)
  607.             {
  608.                 /*
  609.                  * There is at least one child of this node,
  610.                  * visit the node
  611.                  */
  612.                 Level++;
  613.                 ParentNode = ChildNode;
  614.                 ChildNode  = NULL;
  615.             }
  616.             else if (ChildNode->OwnerId == OwnerId)
  617.             {
  618.                 DeletionNode = ChildNode;
  619.             }
  620.         }
  621.         else
  622.         {
  623.             /*
  624.              * No more children of this parent node.
  625.              * Move up to the grandparent.
  626.              */
  627.             Level--;
  628.             if (Level != 0)
  629.             {
  630.                 if (ParentNode->OwnerId == OwnerId)
  631.                 {
  632.                     DeletionNode = ParentNode;
  633.                 }
  634.             }
  635.  
  636.             /* New "last child" is this parent node */
  637.  
  638.             ChildNode = ParentNode;
  639.  
  640.             /* Move up the tree to the grandparent */
  641.  
  642.             ParentNode = ParentNode->Parent;
  643.         }
  644.     }
  645.  
  646.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  647.     return_VOID;
  648. }
  649.  
  650.  
  651.