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

📄 usbkeyboardlib.c

📁 T2.0 USB driver.rar T2.0 USB driver.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
    (    SIO_CHAN *pChan,	    /* channel */    int callbackType,	    /* type of callback */    STATUS (*callback) (),  /* callback */    void *callbackArg	    /* parameter to callback */    )    {    pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan;    switch (callbackType)	{	case SIO_CALLBACK_GET_TX_CHAR:	    pSioChan->getTxCharCallback = callback;	    pSioChan->getTxCharArg = callbackArg;	    return OK;	case SIO_CALLBACK_PUT_RCV_CHAR:	    pSioChan->putRxCharCallback = callback;	    pSioChan->putRxCharArg = callbackArg;	    return OK;	default:	    return ENOSYS;	}    }/***************************************************************************** usbKeyboardPollOutput - output a character in polled mode** The USB keyboard SIO driver does not support output to the keyboard.** RETURNS: EIO*/LOCAL int usbKeyboardPollOutput    (    SIO_CHAN *pChan,    char outChar    )    {    return EIO;    }/***************************************************************************** usbKeyboardPollInput - poll the device for input** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty, ENOSYS if the device is interrupt-only.*/LOCAL int usbKeyboardPollInput    (    SIO_CHAN *pChan,    char *thisChar    )    {    pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan;    int status = OK;    /* validate parameters */    if (thisChar == NULL)        return EIO;    OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK);    /* Check if the input queue is empty. */    if (pSioChan->inQueueCount == 0)        status = EAGAIN;    else	{	/* Return a character from the input queue. */	*thisChar = nextInChar (pSioChan);	}    OSS_MUTEX_RELEASE (kbdMutex);    return status;    }/***************************************************************************** initKbdIrp - Initialize IRP to listen for input on interrupt pipe** RETURNS: TRUE if able to submit IRP successfully, else FALSE*/LOCAL BOOL initKbdIrp    (    pUSB_KBD_SIO_CHAN pSioChan    )    {    pUSB_IRP pIrp = &pSioChan->irp;    /* Initialize IRP */    memset (pIrp, 0, sizeof (*pIrp));    pIrp->userPtr = pSioChan;    pIrp->irpLen = sizeof (*pIrp);    pIrp->userCallback = usbKeyboardIrpCallback;    pIrp->timeout = USB_TIMEOUT_NONE;    pIrp->transferLen = sizeof (HID_KBD_BOOT_REPORT);    pIrp->bfrCount = 1;    pIrp->bfrList [0].pid = USB_PID_IN;    pIrp->bfrList [0].pBfr = (pUINT8) pSioChan->pBootReport;    pIrp->bfrList [0].bfrLen = sizeof (HID_KBD_BOOT_REPORT);    /* Submit IRP */    if (usbdTransfer (usbdHandle, pSioChan->pipeHandle, pIrp) != OK)	return FALSE;    pSioChan->irpInUse = TRUE;    return TRUE;    }/***************************************************************************** usbKeyboardIrpCallback - Invoked upon IRP completion/cancellation** Examines the cause of the IRP completion.  If completion was successful,* interprets the USB keyboard's boot report and re-submits the IRP.** RETURNS: N/A*/LOCAL VOID usbKeyboardIrpCallback    (    pVOID p	    /* completed IRP */    )    {    pUSB_IRP pIrp = (pUSB_IRP) p;    pUSB_KBD_SIO_CHAN pSioChan = pIrp->userPtr;    OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK);    /* Was the IRP successful? */    if (pIrp->result == OK)	{	/* Interpret the keyboard report */	interpKbdReport (pSioChan);	}    /* Re-submit the IRP unless it was canceled - which would happen only     * during pipe shutdown (e.g., the disappearance of the device).     */    pSioChan->irpInUse = FALSE;    if (pIrp->result != S_usbHcdLib_IRP_CANCELED)	initKbdIrp (pSioChan);    OSS_MUTEX_RELEASE (kbdMutex);    }/***************************************************************************** typematicThread - Updates typematic state for each active channel** RETURNS: N/A*/LOCAL VOID typematicThread    (    pVOID param 	/* param not used by this thread */    )    {    pUSB_KBD_SIO_CHAN pSioChan;    while (!killTypematic)	{        OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK);        /* Walk the list of open channels and update the typematic         * state for each.         */        pSioChan = usbListFirst (&sioList);        while (pSioChan != NULL)	    {	    updateTypematic (pSioChan);	    pSioChan = usbListNext (&pSioChan->sioLink);	    }        OSS_MUTEX_RELEASE (kbdMutex);        OSS_THREAD_SLEEP (TYPEMATIC_PERIOD);	}    typematicExit = TRUE;    }/***************************************************************************** configureSioChan - configure USB keyboard for operation** Selects the configuration/interface specified in the <pSioChan>* structure.  These values come from the USBD dynamic attach callback,* which in turn retrieved them from the configuration/interface* descriptors which reported the device to be a keyboard.** RETURNS: TRUE if successful, else FALSE if failed to configure channel*/LOCAL BOOL configureSioChan    (    pUSB_KBD_SIO_CHAN pSioChan    )    {    pUSB_CONFIG_DESCR pCfgDescr;    pUSB_INTERFACE_DESCR pIfDescr;    pUSB_ENDPOINT_DESCR pEpDescr;    UINT8 bfr [USB_MAX_DESCR_LEN];    pUINT8 pBfr;    UINT16 actLen;    UINT16 ifNo;    UINT16 maxPacketSize;    /* Read the configuration descriptor to get the configuration selection     * value and to determine the device's power requirements.     */    if (usbdDescriptorGet (usbdHandle, 			   pSioChan->nodeId,			   USB_RT_STANDARD | USB_RT_DEVICE, 			   USB_DESCR_CONFIGURATION, 			   0, 			   0,			   sizeof (bfr), 			   bfr, 			   &actLen) 			 != OK)	return FALSE;    if ((pCfgDescr = usbDescrParse (bfr, 				    actLen, 				    USB_DESCR_CONFIGURATION)) 				== NULL)	return FALSE;    /* Look for the interface indicated in the pSioChan structure. */    ifNo = 0;    pBfr = bfr;    while ((pIfDescr = usbDescrParseSkip (&pBfr, 							  &actLen, 							  USB_DESCR_INTERFACE)) 				    != NULL)	{	if (ifNo == pSioChan->interface)	    break;	ifNo++;	}    if (pIfDescr == NULL)	return FALSE;    /* Retrieve the endpoint descriptor following the identified interface     * descriptor.     */    if ((pEpDescr = usbDescrParseSkip (&pBfr, &actLen, USB_DESCR_ENDPOINT))	== NULL)	return FALSE;    /* Select the configuration. */    if (usbdConfigurationSet (usbdHandle, 			      pSioChan->nodeId,			      pCfgDescr->configurationValue, 			      pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT) 			    != OK)	return FALSE;    /* Select interface      *      * NOTE: Some devices may reject this command, and this does not represent     * a fatal error.  Therefore, we ignore the return status.     */    usbdInterfaceSet (usbdHandle, 		      pSioChan->nodeId, 		      pSioChan->interface, 		      pIfDescr->alternateSetting);    /* Select the keyboard boot protocol. */    if (usbHidProtocolSet (usbdHandle, 			   pSioChan->nodeId,			   pSioChan->interface, 			   USB_HID_PROTOCOL_BOOT) 			 != OK)	return FALSE;    /* Set the keyboard idle time to infinite. */    if (usbHidIdleSet (usbdHandle, 		       pSioChan->nodeId,		       pSioChan->interface, 		       0 /* no report ID */, 		       0 /* infinite */) 		    != OK)	return FALSE;    /* Turn off LEDs. */    setLedReport (pSioChan, 0);    /* Create a pipe to monitor input reports from the keyboard. */    maxPacketSize = *((pUINT8) &pEpDescr->maxPacketSize) |		    (*(((pUINT8) &pEpDescr->maxPacketSize) + 1) << 8);    if (usbdPipeCreate (usbdHandle, 			pSioChan->nodeId,     			pEpDescr->endpointAddress, 			pCfgDescr->configurationValue,    			pSioChan->interface, 			USB_XFRTYPE_INTERRUPT, 			USB_DIR_IN,    			maxPacketSize, 			sizeof (HID_KBD_BOOT_REPORT), 			pEpDescr->interval, 			&pSioChan->pipeHandle) 		     != OK)	return FALSE;    /* Initiate IRP to listen for input on interrupt pipe */    if (!initKbdIrp (pSioChan))	return FALSE;    return TRUE;    }/***************************************************************************** destroyAttachRequest - disposes of an ATTACH_REQUEST structure** RETURNS: N/A*/LOCAL VOID destroyAttachRequest    (    pATTACH_REQUEST pRequest    )    {    /* Unlink request */    usbListUnlink (&pRequest->reqLink);    /* Dispose of structure */    OSS_FREE (pRequest);    }/***************************************************************************** destroySioChan - disposes of a USB_KBD_SIO_CHAN structure** Unlinks the indicated USB_KBD_SIO_CHAN structure and de-allocates* resources associated with the channel.** RETURNS: N/A*/LOCAL VOID destroySioChan    (    pUSB_KBD_SIO_CHAN pSioChan    )    {    /* Unlink the structure. */    usbListUnlink (&pSioChan->sioLink);    /* Release pipe if one has been allocated.	Wait for the IRP to be     * cancelled if necessary.     */    if (pSioChan->pipeHandle != NULL)	usbdPipeDestroy (usbdHandle, pSioChan->pipeHandle);    while (pSioChan->irpInUse)	OSS_THREAD_SLEEP (1);    /* Release structure. */    if (pSioChan->pBootReport != NULL)	OSS_FREE (pSioChan->pBootReport);    OSS_FREE (pSioChan);    }/***************************************************************************** createSioChan - creates a new USB_KBD_SIO_CHAN structure** Creates a new USB_KBD_SIO_CHAN structure for the indicated <nodeId>.* If successful, the new structure is linked into the sioList upon * return.** <configuration> and <interface> identify the configuration/interface* that first reported itself as a keyboard for this device.** RETURNS: pointer to newly created structure, or NULL if failure*/LOCAL pUSB_KBD_SIO_CHAN createSioChan    (    USBD_NODE_ID nodeId,    UINT16 configuration,    UINT16 interface    )    {    pUSB_KBD_SIO_CHAN pSioChan;    UINT16 i;    /* Try to allocate space for a new keyboard struct */    if ((pSioChan = OSS_CALLOC (sizeof (*pSioChan))) == NULL)    	return NULL;    if ((pSioChan->pBootReport = OSS_MALLOC_ALIGN (				 (sizeof (*pSioChan->pBootReport) 				 + CACHE_LINE_SIZE - 1) / CACHE_LINE_SIZE, 				 CACHE_LINE_SIZE, 			    	 TRUE)) 				      == NULL)	{	OSS_FREE (pSioChan);	return NULL;	}    pSioChan->sioChan.pDrvFuncs = &usbKeyboardSioDrvFuncs;    pSioChan->nodeId = nodeId;    pSioChan->connected = TRUE;    pSioChan->mode = SIO_MODE_POLL;    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. */    usbListLink (&sioList, pSioChan, &pSioChan->sioLink, LINK_TAIL);    return pSioChan;    }/***************************************************************************** findSioChan - Searches for a USB_KBD_SIO_CHAN for indicated node ID** RETURNS: pointer to matching USB_KBD_SIO_CHAN or NULL if not found*/LOCAL pUSB_KBD_SIO_CHAN findSioChan    (    USBD_NODE_ID nodeId    )    {

⌨️ 快捷键说明

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