/**************************************************************************
*
*               Copyright 2004 Mentor Graphics Corporation
*                         All Rights Reserved.
*
* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS THE
* PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS SUBJECT
* TO LICENSE TERMS.
*
***************************************************************************

***************************************************************************
* FILE NAME
*
*       nu_usbh_kbd_ext.c
*
*
* COMPONENT
*
*       Nucleus USB Host Keyboard Driver.
*
* DESCRIPTION
*
*       This file contains the implementation of external interfaces
*       exported by Nucleus USB Host Keyboard driver.
*
*
* DATA STRUCTURES
*
*       None
*
* FUNCTIONS
*       NU_USBH_KBD_Create                  Creates an instance of Keyboard
*                                           driver.
*       _NU_USBH_KBD_Notify_Report          Handles Report generated by
*                                           Keyboard.
*       _NU_USBH_KBD_Get_Usages             Reports the usages supported by
*                                           the keyboard driver.
*       NU_USBH_KBD_Reg_Event_Handler       Notes down the handler for the
*                                           key up/down events.
*       NU_USBH_KBD_Reg_State_Handlers      Registers callback functions
*                                           for application notification.
*       _NU_USBH_KBD_Connect                Handles a newly connected
*                                           keyboard event.
*       _NU_USBH_KBD_Disconnect             Handles keyboard disconnection
*                                           event.
*       _NU_USBH_KBD_Delete                 This function deletes the
*                                           instance of the keyboard
*                                           driver.
*       NU_USBH_KBD_Init_GetHandle          This function is used to get
*                                           the address of the keyboard
*                                           user driver.
*
* DEPENDENCIES
*
*       nu_usb.h                            All USB definitions.
*
**************************************************************************/

#include    "connectivity/nu_usb.h"
#include    "services/runlevel_init.h"

/*************************************************************************
*   FUNCTION
*
*       nu_os_conn_usb_host_hid_keyboard_init
*
*   DESCRIPTION
*
*       This function initializes the HID KBD driver component.
*
*   INPUTS
*
*       path                                Registry path of component.
*       compctrl                            Flag to find if component is
*                                           being enabled or disabled.
*
*   OUTPUTS
*
*       status             Success or failure of the creation of the
*                          underlying initialization routines.
*
*************************************************************************/
STATUS nu_os_conn_usb_host_hid_keyboard_init(CHAR *path, INT compctrl)
{
    STATUS  status = NU_SUCCESS,internal_sts = NU_SUCCESS;
    VOID *usbh_hid_handle;
    UINT8 rollback = 0;

    if(compctrl == RUNLEVEL_START)
    {
        /* Allocate memory for KBD user driver control block. */
        status = USB_Allocate_Object(sizeof(NU_USBH_KBD),
                                     (VOID **)&NU_USBH_KBD_Cb_Pt);

        /* Create the device subsystem. */
        if (status == NU_SUCCESS)
        {
            /* Zero out allocated block. */
            memset(NU_USBH_KBD_Cb_Pt, 0, sizeof(NU_USBH_KBD));

            status = NU_USBH_KBD_Create (NU_USBH_KBD_Cb_Pt,
                                         "USBH_KBD",
                                         NU_NULL);

            /*  Get the host HID class driver handle. */
            if (status == NU_SUCCESS)
            {
                status = NU_USBH_HID_Init_GetHandle(&usbh_hid_handle);

                /* Register the user driver to the class driver. */
                if (status == NU_SUCCESS)
                {
                    status = NU_USB_DRVR_Register_User ( (NU_USB_DRVR *) usbh_hid_handle,
                                                (NU_USB_USER *)
                                                 NU_USBH_KBD_Cb_Pt);
                    if ( status != NU_SUCCESS )
                    {
                        rollback = 3;
                    }
                }
                else
                {
                    rollback = 3;
                }
            }
            else
            {
                rollback = 2;
            }
        }

        else
        {
        	rollback=1;
        }
    }
    else if(compctrl== RUNLEVEL_STOP)
    {
        rollback = 2;
        internal_sts |= NU_USBH_HID_Init_GetHandle(&usbh_hid_handle);
        internal_sts |= NU_USB_DRVR_Deregister_User( (NU_USB_DRVR *) usbh_hid_handle,
                                                     (NU_USB_USER *)NU_USBH_KBD_Cb_Pt);
    }



    switch( rollback )
    {
        case 3:
            internal_sts |=_NU_USBH_KBD_Delete((void*)NU_USBH_KBD_Cb_Pt);

        case 2:
            internal_sts |= USB_Deallocate_Memory(NU_USBH_KBD_Cb_Pt);
            NU_USBH_KBD_Cb_Pt = NU_NULL;

        case 1:
        
        default:
           NU_UNUSED_PARAM(internal_sts);
           

    }

    return (status);
}

/*************************************************************************
* FUNCTION
*
*       NU_USBH_KBD_Create
*
* DESCRIPTION
*
*       This function initializes the data structures required by
*       NU_USBH_HID_USER. This is used by extenders of user layer
*       to initialize base resources.
*
* INPUTS
*
*       cb                  Pointer to keyboard driver control block.
*       name                Name for this USB object.
*       pool                Pointer to memory pool for use by keyboard
*                           driver.
*
* OUTPUTS
*
*       NU_SUCCESS              Indicates successful completion.
*       NU_INVALID_SEMAPHORE    Indicates control block is invalid.
*
*************************************************************************/
STATUS NU_USBH_KBD_Create ( NU_USBH_KBD     *cb,
                            CHAR            *name,
                            NU_MEMORY_POOL  *pool)
{
    STATUS status = NU_INVALID_SEMAPHORE;

    /* Switch to supervisor mode. */
    NU_SUPERV_USER_VARIABLES
    NU_SUPERVISOR_MODE();

    if(cb != NU_NULL)
    {
        cb->usages[0].usage_page = 0x07;        /* Keyboard. */
        cb->usages[0].usage_id = 0xFFFF;
        cb->usages[1].usage_page = 0x08;        /* LED page. */
        cb->usages[1].usage_id = 0xFFFF;
        cb->keyboard_list_head = NU_NULL;

        /* Create base. */
        status = _NU_USBH_HID_USER_Create ((NU_USBH_HID_USER *) cb,
                                            name,
                                            pool,
                                            2,
                                            &Usbh_Kbd_Dispatch);
    }
    /* Return to user mode. */
    NU_USER_MODE();
    return (status);
}

/**************************************************************************
* FUNCTION
*
*       _NU_USBH_KBD_Notify_Report
*
* DESCRIPTION
*
*       This function handles the report sent by a keyboard.
*
* INPUTS
*
*       cb          pointer to USER control block.
*       drvr        class driver control block.
*       handle      handle/cookie for the concerned device.
*       report_data Report sent by the device.
*       report_len  Length of the report.
*
* OUTPUTS
*
*       NU_SUCCESS          Indicates successful completion.
*       NU_NOT_PRESENT      Indicates Device doesn't exist.
*
*
*************************************************************************/
STATUS _NU_USBH_KBD_Notify_Report (NU_USBH_HID_USER *cb,
                                   NU_USBH_HID      *driver,
                                   VOID             *handle,
                                   UINT8            *report_data,
                                   UINT16            report_len)
{
    NU_USBH_KBD *kbdcb = (NU_USBH_KBD *) cb;
    NU_USBH_KBD_DEVICE *keyboard;
    NU_USBH_KBD_EVENT event;
    UINT8 i;
    UINT8 j;
    UINT8 reported = 0;
    UINT8 led_keys;
    UINT8 temp_data[USBH_KBD_MAX_KEY_DOWNS];
    UINT32 key_data_offset = 0;
    UINT32 key_report_count = 0;
    UINT32 modifier_offset = 0;
    USBH_HID_DEVICE  *dev;
    UINT8            num_items;
    STATUS status = NU_SUCCESS;

    keyboard = USBH_KBD_Find_Device (kbdcb, handle);
    if (keyboard == NU_NULL)
        return (NU_NOT_PRESENT);

    /* Get the HID device handle. */
    dev = (USBH_HID_DEVICE  *)handle;
    /* Get the number of items from HID device. */
    num_items = dev->num_items;
    led_keys = keyboard->led_keys;

    status = NU_USBH_HID_Get_Country_Code(driver,cb, handle,
                                 &event.country_code);

    if ( status == NU_SUCCESS )
    {
        for(i=0; i<num_items; i++)
        {
            if(keyboard->kbd_items[i].report_type != USBH_HID_IN_REPORT)
                continue;

            if(keyboard->kbd_items[i].report_count == 8 &&
                keyboard->kbd_items[i].report_size == 1)
                modifier_offset = (keyboard->kbd_items[i].report_offset)/8;
            else
            {
                key_data_offset = (keyboard->kbd_items[i].report_offset)/8;
                key_report_count = keyboard->kbd_items[i].report_count;
            }
        }


        /* Modifier Key Report Item. */
        event.modifier_keys = *(report_data + modifier_offset);

        for (i = 0; i < key_report_count; i++)
        {
            /* report size is one byte. */
            temp_data[i] = *(report_data + i +key_data_offset);

            if (temp_data[i])
            {
                /* Check for LED Keys. */
                switch (temp_data[i])
                {
                    case 0x39:
                        led_keys ^= USBH_KEY_CAPS_LOCK;
                        break;
                    case 0x47:
                        led_keys ^= USBH_KEY_SCROLL_LOCK;
                        break;
                    case 0x53:
                        led_keys ^= USBH_KEY_NUM_LOCK;
                        break;
                    default:
                        break;
                }
            }
        }

        if(keyboard->led_keys != led_keys)
        {
            for(i=0; i<num_items; i++)
            {
                if(keyboard->kbd_items[i].report_type == USBH_HID_OUT_REPORT)
                {
                    status = NU_USBH_HID_Set_Report(driver,cb, handle,
                                keyboard->kbd_items[i].report_id,
                                2, 1, &led_keys );
                    keyboard->led_keys = led_keys;
                    break;
                }
            }
        }
    }

    if ( status == NU_SUCCESS )
    {
        for (i = 0; i < key_report_count; i++)
        {
            if (keyboard->keys_down[i])
            {
                for(j=0;j<key_report_count;j++)
                    if (keyboard->keys_down[i] == temp_data[j])
                        break;
                if (j == key_report_count)
                {
                    /* Key UP event. */
                    event.type = USBH_KEY_UP;
                    event.scan_code = keyboard->keys_down[i];
                    keyboard->keys_down[i] = 0;

                    /* Call Event Handler for each key. */
                    if(kbdcb->ev_handler)
                        status |= kbdcb->ev_handler (kbdcb, keyboard, &event);
                    reported = 1;
                }
                else
                {
                    /* An already reported key, ignore it. */
                    temp_data[j] = 0;
                }
            }
        }
    }

    if ( status == NU_SUCCESS )
    {
        /* Process remaining new key down events. */
        for (i = 0; i < key_report_count; i++)
        {
            if (temp_data[i])
            {
                /* Key DOWN  or error event. */
                event.type = USBH_KEY_DOWN;
                event.scan_code = temp_data[i];
                /* Call Event Handler for each key. */
                if(kbdcb->ev_handler)
                    status |= kbdcb->ev_handler (kbdcb, keyboard, &event);
                reported = 1;

                /* error cases need not be stored. */
                if (temp_data[i] < 4)
                    continue;

                /* Save to report UP event. */
                for(j=0;j<key_report_count;j++)
                if ( keyboard->keys_down[j] == 0)
                {
                    keyboard->keys_down[j] = temp_data[i];
                    break;
                }
            }
        }
    }

    if ( status == NU_SUCCESS )
    {
        if ((!reported) && (keyboard->modifier_keys != event.modifier_keys))
        {
            /* At least report Modifier keys. */
            event.type = USBH_KEY_MODIFIER;

            /* Call Event Handler.  */
            if(kbdcb->ev_handler)
                status = kbdcb->ev_handler (kbdcb, keyboard, &event);
        }
        if ( status == NU_SUCCESS )
        {
            keyboard->modifier_keys = event.modifier_keys;
        }
    }

    return ( status );
}

/*************************************************************************
* FUNCTION
*
*       _NU_USBH_KBD_Get_Usages
*
* DESCRIPTION
*
*       Reports the usage pages supported by the keyboard driver.
*
* INPUTS
*
*       cb          Pointer to Keyboard driver control block.
*       drvr        Pointer to HID class driver control block
*       handle      Handle/cookie for the concerned device.
*       usage_out   Pointer to memory location where the supported usages
*                   must be filled.
*       num_usages  Max number of usages that may be filled at
*                   'usage_out'.
*
* OUTPUTS
*
*       NU_SUCCESS  Indicates successful completion.
*
*
*************************************************************************/
STATUS _NU_USBH_KBD_Get_Usages (NU_USBH_HID_USER    *cb,
                                NU_USBH_HID         *drvr,
                                NU_USBH_HID_USAGE   *usage_out,
                                UINT8                num_usages)
{
    UINT8 num;
    UINT8 i;

    if (cb->num_usages > num_usages)
        num = num_usages;
    else
        num = cb->num_usages;

    for (i = 0; i < num; i++)
        usage_out[i] = ((NU_USBH_KBD *) cb)->usages[i];

  return (NU_SUCCESS);
}

/*************************************************************************
* FUNCTION
*
*       NU_USBH_KBD_Reg_Event_Handler
*
* DESCRIPTION
*
*       Registers the function pointer that has to be invoked upon
*       detecting a keyboard event.
*
* INPUTS
*
*       cb          Pointer to Keyboard driver control block.
*       func        Pointer to the event handler.
*
* OUTPUTS
*
*       NU_SUCCESS  Indicates successful completion.
*
*************************************************************************/
STATUS NU_USBH_KBD_Reg_Event_Handler ( NU_USBH_KBD              *cb,
                                       NU_USBH_KBD_Event_Handler func)
{

    /* Switch to supervisor mode. */
    NU_SUPERV_USER_VARIABLES
    NU_SUPERVISOR_MODE();

    cb->ev_handler = func;

    /* Return to user mode */
    NU_USER_MODE();
    return (NU_SUCCESS);
}

/**************************************************************************
* FUNCTION
*
*   NU_USBH_KBD_Reg_State_Handlers
*
* DESCRIPTION
*   Registers the function pointers for the connection and disconnection
*   callback routines implemented in application.
*
* INPUTS
*
*   drvr_cb     Pointer to Keyboard driver control block.
*   context     Pointer which will be passed as context in the callback.
*   call_back   Pointer to structure containing the pointers to callback
*               routines.
*
* OUTPUTS
*
*   NU_SUCCESS            Indicates successful completion.
*   NU_INVALID_POINTER    Any of passed parameter is invalid.
*
**************************************************************************/
STATUS NU_USBH_KBD_Reg_State_Handlers (NU_USBH_KBD*           drvr_cb,
                                       VOID*                  context,
                                       NU_USBH_KBD_CALLBACK*  call_back)
{
    STATUS status;

    /* Switch to supervisor mode. */
    NU_SUPERV_USER_VARIABLES
    NU_SUPERVISOR_MODE();


    if((!drvr_cb)||(!call_back))
    {
        status = NU_INVALID_POINTER;
    }
    else
    {
        drvr_cb->call_back = call_back;
        drvr_cb->context   = context;
        status = NU_SUCCESS;
    }

    /* Return to user mode */
    NU_USER_MODE();
    return (status);
}
/**************************************************************************
*
* FUNCTION
*
*       _NU_USBH_KBD_Connect
*
* DESCRIPTION
*
*       This function creates an instance of an internal data structure to
*       manage the newly connected keyboard and does some initial settings
*       (LEDs, Idle rate) of the keyboard.
*
* INPUTS
*
*       cb              Pointer to the keyboard driver control block.
*       class_driver    Pointer to  HID class driver's control block.
*       handle          Handle for the device connected.
*
* OUTPUTS
*
*       NU_SUCCESS          Indicates successful completion.
*       NU_USB_MAX_EXCEEDED Indicates user is already serving maximum
*                           devices it can support.
*       NU_INVALID_GROUP    Indicates invalid control block.
*
*
*************************************************************************/
STATUS _NU_USBH_KBD_Connect (NU_USB_USER    *cb,
                             NU_USB_DRVR    *class_driver,
                             VOID           *handle)
{
    STATUS status;
    NU_USBH_KBD   *kbdcb = (NU_USBH_KBD *)cb;
    NU_USBH_KBD_DEVICE *keyboard = NU_NULL;
    UINT8 i, items_count, rollback = 0;
    USBH_HID_DEVICE  *dev;
    UINT8 num_items;

    NU_USBH_HID_ASSERT(cb);
    NU_USBH_HID_ASSERT(class_driver);
    NU_USBH_HID_ASSERT(handle);

    /* Get the HID device handle. */
    dev = (USBH_HID_DEVICE  *)handle;

    /* Get the number of items from HID device. */
    num_items = dev->num_items;

    do
    {
        /* Allocate and initialize a new instance of NU_USBH_KBD_DEVICE. */
        status = USB_Allocate_Object (sizeof (NU_USBH_KBD_DEVICE),
                                      (VOID **)&keyboard);
        if (status != NU_SUCCESS)
        {
            break;
        }

        memset(keyboard, 0, sizeof (NU_USBH_KBD_DEVICE));

        /* store the handle. */
        keyboard->handle =  handle;

        /* Get keyboard items. */
        status = NU_USBH_HID_Get_Items((NU_USBH_HID *)class_driver,
                           (NU_USBH_HID_USER*)cb, handle,
                           keyboard->kbd_items, num_items, &items_count);
        if (status != NU_SUCCESS)
        {
            rollback = 1;
            break;
        }

        /* Place Device Structure on the list. */
        NU_Place_On_List ((CS_NODE **) & kbdcb->keyboard_list_head,
                           (CS_NODE *) keyboard);

        /* Set idle to "0". */
        status = NU_USBH_HID_Set_Idle((NU_USBH_HID *)class_driver,
                            (NU_USBH_HID_USER*)cb, handle, 0, 0);
        if ( status != NU_SUCCESS )
        {
            rollback = 2;
            break;
        }

        /* Clear the LEDs. */
        for(i=0; i<num_items; i++)
        {
            if(keyboard->kbd_items[i].report_type == USBH_HID_OUT_REPORT)
            {
                status = NU_USBH_HID_Set_Report((NU_USBH_HID*)class_driver,
                                        (NU_USBH_HID_USER*)cb, handle,
                                        keyboard->kbd_items[i].report_id,
                                        2, 1, &keyboard->led_keys );
                break;
            }
        }

        if ( status != NU_SUCCESS )
        {
            rollback = 2;
            break;
        }

        /* calling the base behavior. */
        status = _NU_USBH_USER_Connect (cb, class_driver, handle);
        if (status != NU_SUCCESS)
        {
            rollback = 2;
            break;
        }

        /* Reporting new connection to application through callback
         * routine.
         */
        if(kbdcb->call_back != NU_NULL)
        {
            status = kbdcb->call_back->Connection(kbdcb->context,
                                              keyboard);
            if ( status != NU_SUCCESS )
            {
                rollback = 3;
            }
        }
        else
        {

           status =  NU_USB_SYS_Register_Device((void *)keyboard,
                                        NU_USBCOMPH_KBD);
           if ( status != NU_SUCCESS )
           {
               rollback = 3;
           }
        }
    }while(0);

    switch(rollback)
    {
        case 3: _NU_USBH_USER_Disconnect (cb, class_driver, handle);
        case 2: NU_Remove_From_List((CS_NODE**)&kbdcb->keyboard_list_head,
                                    (CS_NODE *) keyboard);
        case 1: USB_Deallocate_Memory(keyboard);
        default: break;
    }

    return (status);
}

/**************************************************************************
*
* FUNCTION
*
*   _NU_USBH_KBD_Disconnect
*
* DESCRIPTION
*   This function deletes the instance that corresponds to the keyboard
*   thats disconnected and releases all the associated resources.
*
* INPUTS
*   cb              Pointer to the keyboard driver control block
*   class_driver    Pointer to HID class driver's control block.
*   handle          Handle for the device disconnected.
*
* OUTPUTS
*   NU_SUCCESS      Indicates successful completion.
*   NU_NOT_PRESENT  Indicates that the handle cannot be located.
*
*
**************************************************************************/
STATUS _NU_USBH_KBD_Disconnect (NU_USB_USER *cb,
                                NU_USB_DRVR *class_driver,
                                VOID        *handle)
{
    STATUS status = NU_SUCCESS;
    NU_USBH_KBD   *kbdcb = (NU_USBH_KBD *)cb;
    NU_USBH_KBD_DEVICE *kbd;
    /* Call the base behavior. */
    status = _NU_USBH_USER_Disconnect (cb, class_driver, handle);

    kbd = USBH_KBD_Find_Device((NU_USBH_KBD *)cb, handle);
    if(kbd == NU_NULL)
    {
        status = NU_NOT_PRESENT;
    }
    else
    {
        if(kbdcb->call_back != NU_NULL)
        {
            /* Notify application of keyboard disconnection. */
            status |= kbdcb->call_back->Disconnection(kbdcb->context,
                                                     kbd);
        }
        else
        {
            status |= NU_USB_SYS_DeRegister_Device( kbd, NU_USBCOMPH_KBD );
        }

        /* Remove Device Structure on the list. */
        NU_Remove_From_List (  (CS_NODE **) & kbdcb->keyboard_list_head,
                                    (CS_NODE *) kbd);

        status |= USB_Deallocate_Memory(kbd);
    }

    return (status);
}

/*************************************************************************
*
* FUNCTION
*
*       _NU_USBH_KBD_Delete
*
* DESCRIPTION
*
*       This function deletes the instance of the keyboard driver and
*       releases all the resources associated with the keyboard devices
*       managed by this driver.
*
* INPUTS
*
*       cb              Pointer to the keyboard driver control block.
*
* OUTPUTS
*
*       NU_SUCCESS      Indicates successful completion.
*
*
*************************************************************************/
STATUS _NU_USBH_KBD_Delete (VOID    *cb)
{
    NU_USBH_KBD   *kbdcb = (NU_USBH_KBD *)cb;
    NU_USBH_KBD_DEVICE  *next;
    NU_USBH_KBD_DEVICE  *kbd = kbdcb->keyboard_list_head;

    while (kbd)
    {
        next = (NU_USBH_KBD_DEVICE *) kbd->node.cs_next;

        /* Remove Device Structure on the list. */
        NU_Remove_From_List (  (CS_NODE **) & kbdcb->keyboard_list_head,
                                (CS_NODE *) kbd);

        USB_Deallocate_Memory(kbd);

        if ((next == kbdcb->keyboard_list_head) || (next == NU_NULL))
            kbd = NU_NULL;
        else
            kbd = next;
    }
    return (_NU_USBH_USER_Delete(cb));
}

/*************************************************************************
*   FUNCTION
*
*       NU_USBH_KBD_Init_GetHandle
*
*   DESCRIPTION
*
*       This function is called to retrieve the host keyboard
*       user driver's address.
*
*   INPUTS
*
*       handle              Double pointer used to retrieve the user
*                           driver's address.
*
*   OUTPUTS
*
*       NU_SUCCESS          Indicates there exists a host keyboard
*                           user driver.
*       NU_NOT_PRESENT      Indicates there exists no user driver.
*
*************************************************************************/
STATUS NU_USBH_KBD_Init_GetHandle(VOID  **handle)
{
    STATUS status;

    /* Switch to supervisor mode. */
    NU_SUPERV_USER_VARIABLES
    NU_SUPERVISOR_MODE();

    status = NU_SUCCESS;
    *handle = NU_USBH_KBD_Cb_Pt;

    if (NU_USBH_KBD_Cb_Pt == NU_NULL)
    {
        status = NU_NOT_PRESENT;
    }

    /* Switch back to user mode. */
    NU_USER_MODE();

    return status;
}

/*************************************************************************
*
* FUNCTION
*
*       NU_USBH_KBD_DM_Open
*
* DESCRIPTION
*
*       This function is called by the application when it opens a device
*       for read/write/ioctl operations.
*
* INPUTS
*
*       dev_handle         Pointer to the mouse driver passed as context.
*
* OUTPUTS
*
*       NU_SUCCESS         Indicates successful completion.
*
**************************************************************************/
 STATUS  NU_USBH_KBD_DM_Open (VOID* dev_handle)
{
    return (NU_SUCCESS);
}

 /*************************************************************************
 *
 * FUNCTION
 *
 *       NU_USBH_KBD_DM_Close
 *
 * DESCRIPTION
 *
 *       This function is called by the application when it wants to close a device
 *       which it has opend already for read/write/ioctl operations.
 *
 * INPUTS
 *
 *       dev_handle         Pointer to the mouse driver passed as context.
 *
 * OUTPUTS
 *
 *       NU_SUCCESS         Indicates successful completion.
 *
 **************************************************************************/
STATUS  NU_USBH_KBD_DM_Close (VOID* dev_handle)
{
    return ( NU_SUCCESS );
}
/*************************************************************************
*
* FUNCTION
*
*       NU_USBH_KBD_DM_IOCTL
*
* DESCRIPTION
*
*       This function is called by the application when it wants to perform
*       a control operation on the device.
*
* INPUTS
*
*       dev_handle         Pointer to the mouse driver passed as context.
*       cmd                IOCTL number.
*       data               IOCTL data pointer of variable type.
*       length             IOCTL data length in bytes.
*
* OUTPUTS
*
*       NU_SUCCESS         Indicates successful completion.
*
**************************************************************************/
STATUS  NU_USBH_KBD_DM_IOCTL (VOID *session_handle,
                              INT cmd,
                              VOID *data,
                              INT length)
{
    STATUS status = NU_SUCCESS;

    /* Get the control block for IOCTL data. */
    HID_KBD_IOCTL_DATA *ioctl_data = (HID_KBD_IOCTL_DATA* )data;

    switch(cmd)
    {
        /******************************** *
         * USB Host Mouse User IOCTLS *
         ******************************** */
        case (USB_KBD_IOCTL_BASE + USBH_KBD_Get_USAGES):

            status = _NU_USBH_KBD_Get_Usages ((NU_USBH_HID_USER *)NU_USBH_KBD_Cb_Pt,
                                               NU_NULL,
                                              (NU_USBH_HID_USAGE*)ioctl_data->data_buffer,
                                              ioctl_data->usages);
        break;

        case (USB_KBD_IOCTL_BASE + USBH_KBD_REG_EVENT_HANDLER):

            status = NU_USBH_KBD_Reg_Event_Handler(NU_USBH_KBD_Cb_Pt,
                                                  (NU_USBH_KBD_Event_Handler)ioctl_data->call_back);
        break;

        case (USB_KBD_IOCTL_BASE + USBH_KBD_REG_STATE_HANDLER):

            status = NU_USBH_KBD_Reg_State_Handlers(NU_USBH_KBD_Cb_Pt,
                                                   ioctl_data->context,
                                                   (NU_USBH_KBD_CALLBACK*)ioctl_data->call_back);
        break;

        case (USB_KBD_IOCTL_BASE + USBH_KBD_DELETE):

            status = _NU_USBH_KBD_Delete(NU_USBH_KBD_Cb_Pt);

        break;

        case (USB_KBD_IOCTL_BASE + USBH_KBD_GET_HANLDE):

            status = NU_USBH_KBD_Init_GetHandle(&ioctl_data->data_buffer);

        break;

        default:
            status = DV_IOCTL_INVALID_CMD;
        break;
    }

    return (status);
}
/*************************************************************************
*
* FUNCTION
*
*       NU_USBH_KBD_DM_Read
*
* DESCRIPTION
*
*       This function is called by the application when it wants to read
*       data from the device.
*
* INPUTS
*
*       dev_handle         Pointer to the mouse driver passed as context.
*       buffer             Pointer to memory location where to put the read data.
*       numbyte            Number of bytes to be read.
*       byte_offset        In case read data is to be placed at certain offset in the buffer.
*       bytes_read_ptr     OUTPUT: Number of bytes actually read.
*
* OUTPUTS
*
*       NU_SUCCESS         Indicates successful completion.
*
**************************************************************************/
STATUS  NU_USBH_KBD_DM_Read (VOID *session_handle,
                             VOID *buffer,
                             UINT32 numbyte,
                             OFFSET_T byte_offset,
                             UINT32 *bytes_read_ptr)
{
    return ( NU_SUCCESS );
}
/*************************************************************************
*
* FUNCTION
*
*       NU_USBH_KBD_DM_Write
*
* DESCRIPTION
*
*       This function is called by the application when it wants to write
*       data from the device.
*
* INPUTS
*
*       dev_handle         Pointer to the mouse driver passed as context.
*       buffer             Pointer to memory location where data to be written is available.
*       numbyte            Number of bytes to be written.
*       byte_offset        In case data is to be read at certain offset in the buffer.
*       bytes_written_ptr  OUTPUT: Number of bytes actually written.
*
* OUTPUTS
*
*       NU_SUCCESS         Indicates successful completion.
*
**************************************************************************/
STATUS  NU_USBH_KBD_DM_Write (VOID *session_handle,
                              const VOID *buffer,
                              UINT32 numbyte,
                              OFFSET_T byte_offset,
                              UINT32 *bytes_written_ptr)
{
    return ( NU_SUCCESS );
}
/*************************** end of file ********************************/

