?? usbkeyboardlib.c
字號:
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 */ if (usbdClientRegister (KBD_CLIENT_NAME, &usbdHandle) != OK || usbdDynamicAttachRegister (usbdHandle, USB_CLASS_HID, USB_SUBCLASS_HID_BOOT, USB_PROTOCOL_HID_BOOT_KEYBOARD, 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 request structure to track this callback request. */ if ((pRequest = OSS_CALLOC (sizeof (*pRequest))) == NULL) status = S_usbKeyboardLib_OUT_OF_MEMORY; else { pRequest->callback = callback; pRequest->callbackArg = arg; usbListLinkProt (&reqList, pRequest, &pRequest->reqLink, LINK_TAIL,kbdMutex); /* Perform an initial notification of all currrently attached * keyboard devices. */ pSioChan = usbListFirst (&sioList); while (pSioChan != NULL) { if (pSioChan->connected) (*callback) (arg, (SIO_CHAN *) pSioChan, USB_KBD_ATTACH); pSioChan = usbListNext (&pSioChan->sioLink); } } OSS_MUTEX_RELEASE (kbdMutex); return ossStatus (status); }/***************************************************************************** usbKeyboardDynamicAttachUnregister - Unregisters keyboard attach callback** This function cancels a previous request to be dynamically notified for* keyboard attachment and removal. The <callback> and <arg> paramters must* exactly match those passed in a previous call to * usbKeyboardDynamicAttachRegister().** RETURNS: OK, or ERROR if unable to unregister callback** ERRNO:* \is* \i S_usbKeyboardLib_NOT_REGISTERED* Could not register the callback* \ie*/STATUS usbKeyboardDynamicAttachUnRegister ( USB_KBD_ATTACH_CALLBACK callback, /* callback to be unregistered */ pVOID arg /* user-defined arg to callback */ ) { pATTACH_REQUEST pRequest; pUSB_KBD_SIO_CHAN pSioChan = NULL; int status = S_usbKeyboardLib_NOT_REGISTERED; OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK); pRequest = usbListFirst (&reqList); while (pRequest != NULL) { if (callback == pRequest->callback && arg == pRequest->callbackArg) { /* Perform a notification of all currrently attached * keyboard devices. */ pSioChan = usbListFirst (&sioList); while (pSioChan != NULL) { if (pSioChan->connected) (*callback) (arg, (SIO_CHAN *) pSioChan, USB_KBD_REMOVE); pSioChan = usbListNext (&pSioChan->sioLink); } /* We found a matching notification request. */ destroyAttachRequest (pRequest); status = OK; break; } pRequest = usbListNext (&pRequest->reqLink); } OSS_MUTEX_RELEASE (kbdMutex); return ossStatus (status); }/***************************************************************************** usbKeyboardSioChanLock - Marks SIO_CHAN structure as in use** A caller uses usbKeyboardSioChanLock() to notify usbKeyboardLib that* it is using the indicated SIO_CHAN structure. usbKeyboardLib maintains* a count of callers using a particular SIO_CHAN structure so that it * knows when it is safe to dispose of a structure when the underlying* USB keyboard is removed from the system. So long as the "lock count"* is greater than zero, usbKeyboardLib will not dispose of an SIO_CHAN* structure.** RETURNS: OK** ERRNO: none.*/STATUS usbKeyboardSioChanLock ( SIO_CHAN *pChan /* SIO_CHAN to be marked as in use */ ) { pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan; pSioChan->lockCount++; return OK; }/***************************************************************************** usbKeyboardSioChanUnlock - Marks SIO_CHAN structure as unused** This function releases a lock placed on an SIO_CHAN structure. When a* caller no longer needs an SIO_CHAN structure for which it has previously* called usbKeyboardSioChanLock(), then it should call this function to* release the lock.** NOTE: If the underlying USB keyboard device has already been removed* from the system, then this function will automatically dispose of the* SIO_CHAN structure if this call removes the last lock on the structure.* Therefore, a caller must not reference the SIO_CHAN again structure after* making this call.** RETURNS: OK, or ERROR if unable to mark SIO_CHAN structure unused** ERRNO:* \is* \i S_usbKeyboardLib_NOT_LOCKED* No lock to unlock* \ie*/STATUS usbKeyboardSioChanUnlock ( SIO_CHAN *pChan /* SIO_CHAN to be marked as unused */ ) { pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan; int status = OK; OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK); if (pSioChan->lockCount == 0) status = S_usbKeyboardLib_NOT_LOCKED; else { /* If this is the last lock and the underlying USB keyboard is * no longer connected, then dispose of the keyboard. */ if (--pSioChan->lockCount == 0 && !pSioChan->connected) destroySioChan (pSioChan); } OSS_MUTEX_RELEASE (kbdMutex); return ossStatus (status); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -