📄 usbuhcdschedulequeue.c
字号:
qh->dWord1Qh = USB_UHCD_SWAP_DATA(uBusIndex, qh->dWord1Qh); usbUhcdLinkQheadBetween(uBusIndex, qh, presentQh); }/* End of else (currentPipe->endPointType == PIPE_INTERRUPT) */ else if ((currentPipe->endPointType == PIPE_ISOCHRONOUS)) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Isochronous pipe\n",0,0,0,0); /* Update the bandwidth required by the pipe */ currentPipe->bw = bwReqd; /* Updating the usbUhcdTable Stucture with the allocated bandwidth */ for (i= 0; i<1024; i++) { pHCDData->usbUhcdTable[i].bandWidth += bwReqd; } } *puPipeHandle = (UINT32)currentPipe; /* Leave the critical section */ usbUhcdLeaveCritical(pHCDData); OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdCreatePipe\n",0,0,0,0); /* Return success from the function */ return USBHST_SUCCESS; }/* End of usbUhcdCreatePipe() *//***************************************************************************** usbUhcdSubmitUrb - submits a transfer request to the HCD..** This function is used to submit an URB to the HCD.** RETURNS: FALSE if request is not submitted successfully** ERRNO:* None.** \NOMANUAL*/USBHST_STATUS usbUhcdSubmitUrb ( UINT8 uBusIndex, UINT32 uPipeHandle, USBHST_URB *pUrb ) { /* Pointer to the Host Controller Data stucture */ PUHCD_DATA pHCDData = g_pUHCDData[uBusIndex]; /* Pointer to the HCD maintained pipe */ USB_UHCD_HCD_PIPE *targetPipe =NULL; /* Pointer to the non isochronous request queue structure */ USB_UHCD_NON_ISO_REQUEST_QUEUE *nIreqQ = NULL; /* Pointer to the isochronous request queue structure */ USB_UHCD_ISO_REQUEST_QUEUE *iReqQ = NULL; /* Pointer to the TD which forms the head of the request queue */ USB_UHCD_TD *dataHead = NULL; /* Pointer to the TD which forms the tail of the request queue */ USB_UHCD_TD *dataTail = NULL; USB_UHCD_TD *temptd = NULL; /* Pointer to the temporary TD structure */ USB_UHCD_TD *td = NULL; /* To hold the data toggle information */ UINT8 toggle = 0; /* To hold the bandwidth required */ INT32 bwReqd = 0; /* To hold the maximum number of isochronous TDs */ UINT16 maxNumOfItd = 0; /* To hold the starting index of the list */ INT32 startIndex = 0, currentReqStartFrame = 0, currentReqEndFrame = 0; /* current frameNumber */ UINT16 frameNum = 0; UINT8 direction = 0; UINT32 dword0 = 0; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_UHCI_WV_TRANSFER, "usbUhcdSubmitUrb() starts", USB_UHCD_WV_FILTER); OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering UHCD_submitURB()\n",0,0,0,0); targetPipe = (USB_UHCD_HCD_PIPE *)uPipeHandle; /* If pipe is not found, return error */ if (targetPipe == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe not found\n",0,0,0,0); return USBHST_INVALID_REQUEST; } if (((pHCDData->rootHub.uDeviceAddress == 0) && (targetPipe == pHCDData->hcDefaultPipe)) || (targetPipe->deviceNum == pHCDData->rootHub.uDeviceAddress )) { if (usbUhcdQueueRhRequest( pHCDData, pUrb , uPipeHandle) == TRUE) return USBHST_SUCCESS; else return USBHST_FAILURE; } /* Check if the request is for a non-isochronous transfer */ if (targetPipe->endPointType != PIPE_ISOCHRONOUS) { /* If non Isochronous the pUrb->pTransferSpecificData contains * the setup packet */ pUSBHST_SETUP_PACKET pSetupPacket = (pUSBHST_SETUP_PACKET )pUrb->pTransferSpecificData; OS_LOG_MESSAGE_MEDIUM(UHCD,"Non-Isochronous request\n",0,0,0,0); /* * Check if this is the only request in the * non-isochronous request queue */ /* Create the non-isochronous request block */ nIreqQ = (USB_UHCD_NON_ISO_REQUEST_QUEUE *) OS_MALLOC(\ sizeof(USB_UHCD_NON_ISO_REQUEST_QUEUE)); /* Check if memory allocation is successful */ if (NULL == nIreqQ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Memory allocation unsuccessful\n",0,0,0,0); return USBHST_INSUFFICIENT_MEMORY; } /* Fill the request block with 0s */ OS_MEMSET(nIreqQ, 0, sizeof(USB_UHCD_NON_ISO_REQUEST_QUEUE)); nIreqQ->next = NULL; /* Update the URB pointer in the request queue element */ nIreqQ->pUrb = pUrb; /* Update the request element's QH to be that of the HCD pipe's QH */ nIreqQ->qh = targetPipe->qh; /* update the pipe pointer */ nIreqQ->pipe = targetPipe; if (targetPipe->endPointType == PIPE_CONTROL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe type Control\n",0,0,0,0); /* Swap the buffer contents */ USB_UHCD_SWAP_BUFDATA( uBusIndex, pSetupPacket, sizeof(USBHST_SETUP_PACKET)); USER_FLUSH(pSetupPacket,sizeof(USBHST_SETUP_PACKET)); /* Create TD for SETUP TRANSACTION - Start */ /* Form an empty TD and make it as the head */ nIreqQ->head = usbUhcdFormEmptyTd (uPipeHandle); /* Check if the TD is created successfully */ if (nIreqQ->head == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"TD creation unsuccessful\n",0,0,0,0); return(USBHST_FAILURE); } /* update buffer and Length fields of the TD */ /* Update the buffer pointer to the DevRequest pointer */ nIreqQ->head->dWord3Td = USB_UHCD_CONVERT_TO_BUS_MEM( uBusIndex, (PVOID) pSetupPacket); /* * Update the maximum length of the buffer to be 7 * ie 8 bytes of setup packet is there in the buffer */ nIreqQ->head->dWord2Td &= ~(USBUHCD_TDTOK_MAXLEN_MASK); nIreqQ->head->dWord2Td |=USBUHCD_TDTOK_MAXLEN_FMT(7); /* Data toggle is 0 for setup */ nIreqQ->head->toggle = 0; nIreqQ->head->dWord2Td &= ~(USBUHCD_TDTOK_DATA_TOGGLE); /* Indicate that it is a SETUP PID */ nIreqQ->head->dWord2Td &= ~(USBUHCD_TDTOK_PID_MASK); nIreqQ->head->dWord2Td |=USBUHCD_TDTOK_PID_FMT(0x2D); /* Update the previous TD pointer to be NULL */ nIreqQ->head->hPrevTd = NULL; /* Create TD for SETUP TRANSACTION - End */ /* Create TD for STATUS TRANSACTION - Start */ /* * The Status TD forms the tail of the control request. So * make the TD to be created as the request queue's tail. */ /* Call the function to form an empty TD for the status phase */ nIreqQ->tail = usbUhcdFormEmptyTd (uPipeHandle); /* Check if the TD is created successfully */ if (nIreqQ->tail == NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"TD creation unsuccessful\n",0,0,0,0); return(USBHST_FAILURE); } /* * Update the maximum length of data to be 0. This is done as * writing a zero would mean a maximum length of 1 */ nIreqQ->tail->dWord2Td &= ~(USBUHCD_TDTOK_MAXLEN_MASK); nIreqQ->tail->dWord2Td |= USBUHCD_TDTOK_MAXLEN_FMT(0x7FF); /* Update the toggle field to be 1 */ nIreqQ->tail->toggle = 1; nIreqQ->tail->dWord2Td |= USBUHCD_TDTOK_DATA_TOGGLE; /* * Indicate that an interrupt is * to be generated on transfer completion */ nIreqQ->tail->dWord1Td |= USBUHCD_TDCS_COMPLETE; /* Update the next pointer to be NULL */ nIreqQ->tail->hNextTd = NULL; /* * The direction of the status phase would be the opposite of the * Data phase. * Check if the direction is IN, indicate the * direction of the TD to be OUT and vice-versa */ direction = pSetupPacket->bmRequestType & 0x80 ; /* Update the PID field from the setup packet */ nIreqQ->tail->dWord2Td &= ~(USBUHCD_TDTOK_PID_MASK); if(0 != (pSetupPacket->bmRequestType & 0x80)) nIreqQ->tail->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0xE1); else nIreqQ->tail->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0x69); /* Create TDs for DATA TRANSACTION - Start */ /* Check if the length of data to be transferred is non-zero */ if (pUrb->uTransferLength != 0) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Length of data is not 0\n",0,0,0,0); /* The toggle bit is 1 */ toggle = 1; /* Call the function to create TD chain for the data stage */ USER_FLUSH(pUrb->pTransferBuffer, pUrb->uTransferLength); /* Swap the buffer data */ if ( pUrb->pTransferBuffer != NULL) USB_UHCD_SWAP_BUFDATA( uBusIndex, pUrb->pTransferBuffer, pUrb->uTransferLength); if (usbUhcdMakeTds( uBusIndex, &dataHead, &dataTail, pUrb, &toggle,targetPipe) == FALSE) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Make TD failed\n",0,0,0,0); return(USBHST_FAILURE); } /* * Update the Previous link pointer of the head of data TDs * to be the TD created for the SETUP stage. */ dataHead->hPrevTd = nIreqQ->head; /* * Update the next link pointer of the SETUP TD * to be the head of the data TDs created */ nIreqQ->head->hNextTd = dataHead; /* Update the HC TD's link pointer */ nIreqQ->head->dWord0Td &= ~(USBUHCD_LINK_PTR_MASK); nIreqQ->head->dWord0Td |= USBUHCD_LINK_PTR_FMT( ((unsigned) dataHead) >> 4); /* Indicate that this is not the last element in the queue */ nIreqQ->head->dWord0Td &= ~(USBUHCD_LINK_TERMINATE); nIreqQ->head->dWord0Td = USB_UHCD_CONVERT_TO_BUS_MEM( uBusIndex, (PVOID)nIreqQ->head->dWord0Td); /* * The data stage is followed by the Status Stage. * So the tail TD of the data stage forms the TD * previous to the Status Stage. */ nIreqQ->tail->hPrevTd = dataTail; /* * Update the next pointer of the tail of the data request * to point to the Status TD */ dataTail->hNextTd = nIreqQ->tail; /* Update the HC TD's link pointer */ dataTail->dWord0Td &=~(USBUHCD_LINK_PTR_MASK); dataTail->dWord0Td |= USBUHCD_LINK_PTR_FMT( ((unsigned) (nIreqQ->tail)) >> 4); /* Indicate that this is not the last element in the queue */ dataTail->dWord0Td &= ~(USBUHCD_LINK_TERMINATE); dataTail->dWord0Td = USB_UHCD_CONVERT_TO_BUS_MEM( uBusIndex, (PVOID)dataTail->dWord0Td); } /* The control transfer has no data satage */ else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Control has no data\n",0,0,0,0); /* * Update the next pointer of the head * to be pointing to the tail */ nIreqQ->head->hNextTd = nIreqQ->tail; /* Update the HC TD's link pointer */ nIreqQ->head->dWord0Td &=~(USBUHCD_LINK_PTR_MASK); nIreqQ->head->dWord0Td |=USBUHCD_LINK_PTR_FMT( ((unsigned) (nIreqQ->tail)) >> 4); /* * Indicate that the head pointer is not * the last element in the queue. */ nIreqQ->head->dWord0Td &= ~(USBUHCD_LINK_TERMINATE); nIreqQ->head->dWord0Td = USB_UHCD_CONVERT_TO_BUS_MEM( uBusIndex, (PVOID)nIreqQ->head->dWord0Td); /* * Update the element previous to the tail of the request to * be the head of the request as there is no data stage */ nIreqQ->tail->hPrevTd = nIreqQ->head; } /* Create TDs for DATA TRANSACTION - End */ } /* Check if it is a bulk transfer request */ else if (targetPipe->endPointType == PIPE_BULK) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe type Bulk\n",0,0,0,0); USER_FLUSH(pUrb->pTransferBuffer, pUrb->uTransferLength); /* Swap the buffer data */ if ( pUrb->pTransferBuffer != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -