📄 usbuhcdrhemulate.c
字号:
UINT8 status=0; /* To hold the callback handler's name */ char cbName[20]; /* * To hold the number of callback function tasks created. * This is used to give a unique name to the callback task */ static UINT rcbNum=0; /* To hold the offset of the register */ UINT32 offset = 0; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering ProcessRH_InterruptTransfer\n",0,0,0,0); /* free the pHCDDataURB stucture */ OS_FREE(pHCDDataURB); /* Check if the URB pointer is valid */ if (NULL == pUrb) { OS_LOG_MESSAGE_MEDIUM(UHCD,"URB pointer is not validn \n",0,0,0,0); return; } /* * This is an infinite loop which * 1. Waits on the semaphore to be signalled from the uhc_manage_port * task. * 2. Checks for any change in the Root hub ports * 3. If there are any changes, signals the task handling the * Root hub emulation module's interrupt transfer request. * 4. All the above steps are repeated */ while (1) {#ifdef DEBUG OS_LOG_MESSAGE_MEDIUM(UHCD,"*** Interrupt tr : waiting for sem ...\n",0,0,0,0);#endif /* Wait for a semaphore to be released by the uhc_manage_port task */ if (OS_WAIT_FOR_EVENT (pHCDData->usbUhcdSemPortInterruptTransfer, WAIT_FOREVER) == USB_UHCD_REQUEST_FAILURE) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Unable to take semaphore",0,0,0,0); return; } /* * Check whether the semaphore has been released from the manage port function, * or from the cancel urb for the root hub. */ if(pHCDData->flagRhIntDel == TRUE) { break; } /* * The status bitmap is as follows * Bit 0 - Change in the hub itself * Bit 1 - Change in hub port 1 * Bit 2 - Change in hub port 2 * etc */ /* Form the status change bitmap for both the ports */ for (i = 0; i < 2; ++i) { /* Base Address offset. First Port1 then port2. */ offset = USB_UHCD_PORT1 + i * 2; OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking Status\n",0,0,0,0); /* Check ff there is a status change in the ports */ if (usbUhcdIsBitSet (pHCDData, offset, 6) || usbUhcdIsBitSet (pHCDData, offset, 3) || usbUhcdIsBitSet (pHCDData, offset, 1) || /* To check whether a reset change has happened */ (pHCDData->usbUhcdResetChange[i] == 1)) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Status changed\n",0,0,0,0); /* Record it in the status bit map */ status = status | (1 << (i + 1)); } }/* End of for() */ /* If there is any status change, break */ if (status != 0) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Status Changed\n",0,0,0,0); break; } }/* End of while () */ if(pHCDData->flagRhIntDel == FALSE) { /* Fill URB's status */ pUrb->nStatus = 0; /* Update the buffer with the status bitmap */ if (pUrb->pTransferBuffer != NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Updating the buffer with status bitmap\n",0,0,0,0); /* Copy the status to URB's buffer */ usbUhcdCopy (pUrb->pTransferBuffer, (UCHAR *) &status, &(pUrb->uTransferLength), 1); } /* Form a unique name for the task */ sprintf (cbName, "uriCB%d", rcbNum++); /* * Spawn the callback function if * the callback function pointer is not NULL */ if (pUrb->pfCallback != NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Spawned call back function\n",0,0,0,0); OS_CREATE_THREAD(cbName, 95,pUrb->pfCallback, pUrb); } } /* end if pHCDDataURB->flagRhIntDel is FALSE */ else { /* Make the flag as false, so to trace the next cancel request */ pHCDData->flagRhIntDel = FALSE; } OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting ProcessRH_InterruptTransfer()\n",0,0,0,0); return; }/* End of usbUhcdProcessRhInterruptTransfer() *//***************************************************************************** usbUhcdQueueRhRequest - handles request queued** This function handles the request queued to the Root hub, called by * SubmitHCDRequest** RETURNS: FALSE if the request for the Root hub is not queued.** ERRNO:* None.** \NOMANUAL*/BOOLEAN usbUhcdQueueRhRequest ( PUHCD_DATA pHCDData, USBHST_URB *pUrb , UINT32 uPipeHandle ) { /* To hold the request number */ static UINT reqNum = 0; /* To hold the task name */ char spName[20]; /* Pointer to the Structure which contains pointer to Host controller stucture and the pointer to the URB . Pointer send as argument to the OS_CREATE_TASK */ PHCD_DATA_URB pHCDDataURB = NULL; USB_UHCD_HCD_PIPE * targetPipe ; targetPipe = (USB_UHCD_HCD_PIPE *)uPipeHandle; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering QueRHRequest()\n",0,0,0,0); pHCDDataURB = (PHCD_DATA_URB)OS_MALLOC(sizeof(HCD_DATA_URB)); /* Populating the pHCDData field */ pHCDDataURB->pHCDData = pHCDData; /* Populating the purb field */ pHCDDataURB->purb = pUrb; /* If a control transfer is requested */ if ( targetPipe->endPointType == PIPE_CONTROL ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Request is Control Transfer\n",0,0,0,0); /* call the control transfer for a root hub*/ usbUhcdProcessRhControlTransfer(pHCDDataURB); } /* If a interrupt transfer is requested */ else if ( targetPipe->endPointType == PIPE_INTERRUPT ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Request is Interrupt Transfer\n",0,0,0,0); /* Create a unique name for the task */ sprintf(spName, "uRHI%d", reqNum++ ); /* Spawn the handler for the interrupt transfer */ OS_CREATE_THREAD(spName, 90, usbUhcdProcessRhInterruptTransfer, pHCDDataURB); pHCDData->flagRhIntDel = FALSE; } /* No other types of transfer is supported by the Root Hub */ else { OS_LOG_MESSAGE_MEDIUM(UHCD, "*** UHC : Invalid request to the Root Hub\n",0,0,0,0 ); return FALSE; } OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting QueueRHRequest\n",0,0,0,0); return TRUE; }/* End of usbUhcdQueueRhRequest() *//***************************************************************************** usbUhcdRhCreatePipe - creates a pipe specific to an endpoint.** This function is used to create a pipe specific to an endpoint. The * inforamtion about the endpoint is obtained from the endpoint descriptor* <pEndpointDescriptor>.** RETURNS: USBHST_SUCCESS if the pipe was created successfully** ERRNO:* None.** \NOMANUAL*/USBHST_STATUS usbUhcdRhCreatePipe ( PUHCD_DATA pHCDData, UINT8 uDeviceAddress, UINT8 uDeviceSpeed, PUCHAR pEndpointDescriptor, PUINT32 puPipeHandle ) { /* To hold the status of the function call */ USBHST_STATUS status = USBHST_FAILURE; /* Pointer to the Endpoint Descriptor */ pUSBHST_ENDPOINT_DESCRIPTOR pEndpointDesc = NULL; OS_LOG_MESSAGE_MEDIUM(UHCD,"usbUhcdRhCreatePipe - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if ((NULL == pEndpointDescriptor) ||(NULL == puPipeHandle)) { OS_LOG_MESSAGE_MEDIUM(UHCD,"usbUhcdRhCreatePipe - parameters are not valid",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Extract the endpoint descriptor */ pEndpointDesc = (pUSBHST_ENDPOINT_DESCRIPTOR)pEndpointDescriptor; OS_LOG_MESSAGE_MEDIUM(UHCD,"Switch based on endpoint type\n",0,0,0,0); /* Switch based on the endpoint type */ switch (pEndpointDesc->bmAttributes & USB_UHCD_ATTR_EPTYPE_MASK) { case USBHST_CONTROL_TRANSFER:/* Control endpoint */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : control endpoint\n",0,0,0,0); /* If the endpoint number is not 0, it is an error */ if ( 0 != (pEndpointDesc->bEndpointAddress & 0x0F)) { OS_LOG_MESSAGE_MEDIUM(UHCD,"endpoint is not 0\n",0,0,0,0); return USBHST_INVALID_REQUEST; } else { OS_LOG_MESSAGE_MEDIUM(UHCD,"end point is zero\n",0,0,0,0); /* Allocate memory for the control endpoint */ pHCDData->rootHub.pControlPipe = usbUhcdFormEmptyPipe(); /* Check if pipe is created successfully */ if (NULL == pHCDData->rootHub.pControlPipe) { OS_LOG_MESSAGE_MEDIUM(UHCD,"usbUhcdRhCreatePipe - Memory not\ allocated for control pipe\n",0,0,0,0); return USBHST_INSUFFICIENT_MEMORY; } /* Populate the fields of the control pipe - Start */ pHCDData->rootHub.pControlPipe->deviceNum = uDeviceAddress; pHCDData->rootHub.pControlPipe->endPointNum = 0; pHCDData->rootHub.pControlPipe->uDeviceSpeed = uDeviceSpeed; pHCDData->rootHub.pControlPipe->uMaximumPacketSize = pEndpointDesc->wMaxPacketSize; /* Copy the pipe direction */ pHCDData->rootHub.pControlPipe->endPointDirection = pEndpointDesc->bEndpointAddress >>7; /* Copy the pipe type */ pHCDData->rootHub.pControlPipe->endPointType = USBHST_CONTROL_TRANSFER; /* Populate the fields of the control pipe - End */ /* Update the pipe handle information */ *(puPipeHandle) = (UINT32)(pHCDData->rootHub.pControlPipe); status = USBHST_SUCCESS; } break; } case USBHST_INTERRUPT_TRANSFER:/* Interrupt endpoint */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : Interrupt endpoint\n",0,0,0,0); /* Allocate memory for the control endpoint */ pHCDData->rootHub.pInterruptPipe = usbUhcdFormEmptyPipe(); /* Check if pipe is created successfully */ if (NULL == pHCDData->rootHub.pInterruptPipe) { OS_LOG_MESSAGE_MEDIUM(UHCD,"usbUhcdRhCreatePipe - Memory not\ allocated for control pipe\n",0,0,0,0); return USBHST_INSUFFICIENT_MEMORY; } /* Populate the fields of the control pipe - Start */ pHCDData->rootHub.pInterruptPipe->deviceNum = uDeviceAddress; pHCDData->rootHub.pInterruptPipe->endPointNum = 0; pHCDData->rootHub.pInterruptPipe->uDeviceSpeed =uDeviceSpeed; pHCDData->rootHub.pInterruptPipe->uMaximumPacketSize = pEndpointDesc->wMaxPacketSize; /* Copy the pipe direction */ pHCDData->rootHub.pInterruptPipe->endPointDirection = pEndpointDesc->bEndpointAddress >>7;; /* Copy the pipe type */ pHCDData->rootHub.pInterruptPipe->endPointType = USBHST_INTERRUPT_TRANSFER; /* Populate the fields of the control pipe - End */ /* Update the pipe handle information */ *(puPipeHandle) = (UINT32)(pHCDData->rootHub.pInterruptPipe); status = USBHST_SUCCESS; break; } default: { OS_LOG_MESSAGE_MEDIUM(UHCD,"default : invalid request\n",0,0,0,0); status = USBHST_INVALID_REQUEST; } }/* End of switch */ OS_LOG_MESSAGE_MEDIUM(UHCD,"usbUhcdRhCreatePipe - Exit\n",0,0,0,0); return status; }/* End of function usbUhcdRhCreatePipe() *//***************************************************************************** usbUhcdRhDeletePipe - deletes a pipe specific to an endpoint** This function is used to delete a pipe specific to an endpoint. The pipe* to be deleted is specified by <uPipeHandle>.** Delete pipe for specified endpoint** RETURNS: USBHST_SUCCESS if the pipe was deleted successfully** ERRNO:* None.** \NOMANUAL*/USBHST_STATUS usbUhcdRhDeletePipe ( PUHCD_DATA pHCDData, UINT32 uPipeHandle ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"usbUhcdRhDeletePipe - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if (0 == uPipeHandle) { OS_LOG_MESSAGE_MEDIUM(UHCD,"usbUhcdRhDeletePipe - Parameters not valid\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Check if it is a control pipe delete request */ if (uPipeHandle == (UINT32)(pHCDData->rootHub.pControlPipe)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -