⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbkeyboardlib.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Try to allocate space for a new keyboard struct */

    if ((pSioChan = OSS_CALLOC (sizeof (*pSioChan))) == NULL)
    	return NULL;

    if ((pSioChan->pBootReport = OSS_CALLOC (sizeof (*pSioChan->pBootReport)))
				      == NULL)
	{
	OSS_FREE (pSioChan);
	return NULL;
	}

    pSioChan->sioChan.pDrvFuncs = &usbKeyboardSioDrvFuncs;
    pSioChan->nodeId = nodeId;
    pSioChan->connected = TRUE;
    pSioChan->mode = SIO_MODE_POLL;
    pSioChan->scanMode = SIO_KYBD_MODE_ASCII;

    pSioChan->configuration = configuration;
    pSioChan->interface = interface;

    for (i = 0; i < BOOT_RPT_KEYCOUNT; i++)
	pSioChan->activeScanCodes [i] = NOTKEY;


    /* Try to configure the keyboard. */

    if (!configureSioChan (pSioChan))
	{
	destroySioChan (pSioChan);
	return NULL;
	}


    /* Link the newly created structure. */

    usbListLinkProt (&sioList, pSioChan, &pSioChan->sioLink, LINK_TAIL,kbdMutex);

    return pSioChan;
    }


/***************************************************************************
*
* findSioChan - Searches for a USB_KBD_SIO_CHAN for indicated node ID
*
* Searches for a USB_KBD_SIO_CHAN for indicated <nodeId>.
*
* RETURNS: pointer to matching USB_KBD_SIO_CHAN or NULL if not found
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL pUSB_KBD_SIO_CHAN findSioChan
    (
    USBD_NODE_ID nodeId
    )

    {
    pUSB_KBD_SIO_CHAN pSioChan = usbListFirst (&sioList);

    while (pSioChan != NULL)
	{
	if (pSioChan->nodeId == nodeId)
	    break;

	pSioChan = usbListNext (&pSioChan->sioLink);
	}

    return pSioChan;
    }


/***************************************************************************
*
* notifyAttach - Notifies registered callers of attachment/removal
*
* This function notifies of the device attachment or removal to the 
* registered clients
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID notifyAttach
    (
    pUSB_KBD_SIO_CHAN pSioChan,
    UINT16 attachCode
    )

    {
    pATTACH_REQUEST pRequest = usbListFirst (&reqList);

    while (pRequest != NULL)
	{
	(*pRequest->callback) (pRequest->callbackArg, 
			       (SIO_CHAN *) pSioChan, 
			       attachCode);

	pRequest = usbListNext (&pRequest->reqLink);
	}
    }


/***************************************************************************
*
* usbKeyboardAttachCallback - called by USBD when keyboard attached/removed
*
* The USBD will invoke this callback when a USB keyboard is attached to or
* removed from the system.  <nodeId> is the USBD_NODE_ID of the node being
* attached or removed.	<attachAction> is USBD_DYNA_ATTACH or USBD_DYNA_REMOVE.
* Keyboards generally report their class information at the interface level,
* so <configuration> and <interface> will indicate the configuration/interface
* that reports itself as a keyboard.  Finally, <deviceClass>, <deviceSubClass>,
* and <deviceProtocol> will identify a HID/BOOT/KEYBOARD device.
*
* NOTE: The USBD will invoke this function once for each configuration/
* interface which reports itself as a keyboard.  So, it is possible that
* a single device insertion/removal may trigger multiple callbacks.  We
* ignore all callbacks except the first for a given device.
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID usbKeyboardAttachCallback
    (
    USBD_NODE_ID nodeId, 
    UINT16 attachAction, 
    UINT16 configuration,
    UINT16 interface,
    UINT16 deviceClass, 
    UINT16 deviceSubClass, 
    UINT16 deviceProtocol
    )

    {
    pUSB_KBD_SIO_CHAN pSioChan;


    OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK);

    /* Depending on the attach code, add a new keyboard or disabled one
     * that's already been created.
     */

    switch (attachAction)
	{
	case USBD_DYNA_ATTACH:

	    /* A new device is being attached.  Check if we already 
	     * have a structure for this device.
	     */

	    if (findSioChan (nodeId) != NULL)
		break;

	    /* Create a new structure to manage this device.  If there's
	     * an error, there's nothing we can do about it, so skip the
	     * device and return immediately. 
	     */

	    if ((pSioChan = createSioChan (nodeId, configuration, interface)) == NULL)
		break;

	    /* Notify registered callers that a new keyboard has been
	     * added and a new channel created.
	     */

	    notifyAttach (pSioChan, USB_KBD_ATTACH);

	    break;


	case USBD_DYNA_REMOVE:

	    /* A device is being detached.	Check if we have any
	     * structures to manage this device.
	     */

	    if ((pSioChan = findSioChan (nodeId)) == NULL)
		break;

	    /* The device has been disconnected. */

	    pSioChan->connected = FALSE;

	    /* Notify registered callers that the keyboard has been
	     * removed and the channel disabled. 
	     *
	     * NOTE: We temporarily increment the channel's lock count
	     * to prevent usbKeyboardSioChanUnlock() from destroying the
	     * structure while we're still using it.
	     */

	    pSioChan->lockCount++;

	    notifyAttach (pSioChan, USB_KBD_REMOVE);

	    pSioChan->lockCount--;

	    /* If no callers have the channel structure locked, destroy
	     * it now.  If it is locked, it will be destroyed later during
	     * a call to usbKeyboardUnlock().
	     */

	    if (pSioChan->lockCount == 0)
		destroySioChan (pSioChan);

	    break;
	}

    OSS_MUTEX_RELEASE (kbdMutex);
    }


/***************************************************************************
*
* doShutdown - shuts down USB keyboard SIO driver
*
* <errCode> should be OK or S_usbKeyboardLib_xxxx.  This value will be
* passed to ossStatus() and the return value from ossStatus() is the
* return value of this function.
*
* RETURNS: OK, or ERROR per value of <errCode> passed by caller
*
* ERRNO: appropiate error code
*
*\NOMANUAL
*/

LOCAL STATUS doShutdown
    (
    int errCode
    )

    {
    pATTACH_REQUEST pRequest;
    pUSB_KBD_SIO_CHAN pSioChan;


    /* Kill typematic thread */

    if (typematicThread != NULL)
	{
	killTypematic = TRUE;

	while (!typematicExit)
	    OSS_THREAD_SLEEP (1);

	OSS_THREAD_DESTROY (typematicHandle);
	}


    /* Dispose of any outstanding notification requests */

    while ((pRequest = usbListFirst (&reqList)) != NULL)
	destroyAttachRequest (pRequest);


    /* Dispose of any open keyboard connections. */

    while ((pSioChan = usbListFirst (&sioList)) != NULL)
	destroySioChan (pSioChan);
    

    /* Release our connection to the USBD.  The USBD automatically 
     * releases any outstanding dynamic attach requests when a client
     * unregisters.
     */

    if (usbdHandle != NULL)
	{
	usbdClientUnregister (usbdHandle);
	usbdHandle = NULL;
	}


    /* Release resources. */

    if (kbdMutex != NULL)
	{
	OSS_MUTEX_DESTROY (kbdMutex);
	kbdMutex = NULL;
	}


    return ossStatus (errCode);
    }


/***************************************************************************
*
* usbKeyboardDevInit - initialize USB keyboard SIO driver
*
* Initializes the USB keyboard SIO driver. The USB keyboard SIO driver
* maintains an initialization count, so calls to this function may be
* nested.
*
* RETURNS: OK, or ERROR if unable to initialize.
*
* ERRNO:
* \is
* \i S_usbKeyboardLib_OUT_OF_RESOURCES
* Sufficient resources are not available to create mutex
*
* \i S_usbKeyboardLib_USBD_FAULT
* Fault in the USBD Layer
* \ie
*/

STATUS usbKeyboardDevInit (void)
    {
    /* If not already initialized, then initialize internal structures
     * and connection to USBD.
     */

    if (initCount == 0)
	{
	/* Initialize lists, structures, resources. */

	memset (&sioList, 0, sizeof (sioList));
	memset (&reqList, 0, sizeof (reqList));
	kbdMutex = NULL;
	usbdHandle = NULL;
	typematicHandle = NULL;
	killTypematic = FALSE;
	typematicExit = FALSE;


	if (OSS_MUTEX_CREATE (&kbdMutex) != OK)
	    return doShutdown (S_usbKeyboardLib_OUT_OF_RESOURCES);


	/* Initialize typematic repeat thread */

	if (OSS_THREAD_CREATE (typematicThread, 
			       NULL, 
			       OSS_PRIORITY_LOW,
			       TYPEMATIC_NAME, 
			       &typematicHandle) 
			     != OK)
	    return doShutdown (S_usbKeyboardLib_OUT_OF_RESOURCES);
	

	/* Establish connection to USBD
	 * The usbdDynamicAttachRegister requires a flag as the fourth parameter
         * to indicate whether the device registered with this driver will be a
         * vendor specific device (flag = TRUE) or class specific device (flag =
         * FALSE
         */

	if (usbdClientRegister (KBD_CLIENT_NAME, &usbdHandle) != OK ||
	    usbdDynamicAttachRegister (usbdHandle, 
				       USB_CLASS_HID,
				       USB_SUBCLASS_HID_BOOT, 
				       USB_PROTOCOL_HID_BOOT_KEYBOARD,FALSE,
				       usbKeyboardAttachCallback) 
				     != OK)
		{
		return doShutdown (S_usbKeyboardLib_USBD_FAULT);
		}
	}

    initCount++;

    return OK;
    }


/***************************************************************************
*
* usbKeyboardDevShutdown - shuts down keyboard SIO driver
*
* This function shuts down the keyboard driver. The driver is shutdown only 
* if <initCount> after decrementing. If it is more the 0, it is decremented.
*
* RETURNS: OK, or ERROR if unable to shutdown.
*
* ERRNO:
* \is
* \i S_usbKeyboardLib_NOT_INITIALIZED
* Keyboard Driver not initialized
* \ie
*/

STATUS usbKeyboardDevShutdown (void)
    {
    /* Shut down the USB keyboard SIO driver if the initCount goes to 0. */

    if (initCount == 0)
	return ossStatus (S_usbKeyboardLib_NOT_INITIALIZED);

    if (--initCount == 0)
	return doShutdown (OK);

    return OK;
    }


/***************************************************************************
*
* usbKeyboardDynamicAttachRegister - Register keyboard attach callback
*
* <callback> is a caller-supplied function of the form:
*
* \cs
* typedef (*USB_KBD_ATTACH_CALLBACK)
*     (
*     pVOID arg,
*     SIO_CHAN *pSioChan,
*     UINT16 attachCode
*     );
* \ce
*
* usbKeyboardLib will invoke <callback> each time a USB keyboard
* is attached to or removed from the system.  <arg> is a caller-defined
* parameter which will be passed to the <callback> each time it is
* invoked.  The <callback> will also be passed a pointer to the 
* SIO_CHAN structure for the channel being created/destroyed and
* an attach code of USB_KBD_ATTACH or USB_KBD_REMOVE.
*
* RETURNS: OK, or ERROR if unable to register callback
*
* ERRNO:
* \is
* \i S_usbKeyboardLib_BAD_PARAM
* Bad Parameter are passed
*
* \i S_usbKeyboardLib_OUT_OF_MEMORY
* Not sufficient memory is available
* \ie
*/

STATUS usbKeyboardDynamicAttachRegister
    (
    USB_KBD_ATTACH_CALLBACK callback,	/* new callback to be registered */
    pVOID arg		    /* user-defined arg to callback */
    )

    {
    pATTACH_REQUEST pRequest;
    pUSB_KBD_SIO_CHAN pSioChan;
    int status = OK;


    /* Validate parameters */

    if (callback == NULL)
	return ossStatus (S_usbKeyboardLib_BAD_PARAM);


    OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK);


    /* Create a new 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -