📄 usbtcdisp1582endpoint.c
字号:
pTRB_COPY_DATA_TO_EPBUF pTrb /* TRB to be executed */ ) { pTRB_HEADER pHeader = (pTRB_HEADER) pTrb; /* TRB_HEADER */ pUSB_TCD_ISP1582_ENDPOINT pEndpointInfo = NULL;/*USB_TCD_ISP1582_ENDPOINT*/ pUSB_TCD_ISP1582_TARGET pTarget = NULL; /* USB_TCD_ISP1582_TARGET */ UINT8 endpointIndex = 0; /* endpoint index */ UINT8 transferType = 0; /* transfer type */#ifdef DMA_SUPPORTED UINT16 data16 = 0;#endif UINT32 sizeToCopy = 0; /* size of data to copy */ STATUS status = ERROR; unsigned char * pBuf = pTrb->pBuffer; /* pointer to buffer */ UINT16 data = 0 ; /* WindView Instrumentation */ USB_TCD_LOG_EVENT(USB_TCD_ISP1582_ENDPOINT, "usbTcdIsp1582FncCopyDataToEpBuf entered...", USB_TCD_ISP582_WV_FILTER); USBISP1582_DEBUG ("usbTcdIsp1582FncCopyDataToEpBuf : Entered...\n", 0,0,0,0,0,0); /* Validate parameters */ if ((pHeader == NULL) || (pHeader->trbLength < sizeof (TRB_HEADER)) || (pHeader->handle == NULL) || (pTrb->pipeHandle == 0)) { /* WindView Instrumentation */ USB_TCD_LOG_EVENT(USB_TCD_ISP1582_ENDPOINT, "usbTcdIsp1582FncCopyDataToEpBuf exiting: Bad Parameter Received...", USB_TCD_ISP582_WV_FILTER); USBISP1582_ERROR ("usbTcdIsp1582FncCopyDataToEpBuf : Bad Parameters \ ...\n",0,0,0,0,0,0); return ossStatus(S_usbTcdLib_BAD_PARAM); } pEndpointInfo = (pUSB_TCD_ISP1582_ENDPOINT)pTrb->pipeHandle; pTarget = (pUSB_TCD_ISP1582_TARGET)pHeader->handle; endpointIndex = pEndpointInfo->endpointIndex; transferType = pEndpointInfo->transferType; #ifdef DMA_SUPPORTED /* * Check if the endpoint supports DMA, i.e. the transfer types are * bulk or isochronous. */ if ((transferType == USB_ATTR_ISOCH || transferType == USB_ATTR_BULK)) { /* * Check whether DMA Channel is in use and whether DMA transfer has * completed succesfully. */ if ((pTarget->dmaEndpointId == endpointIndex) && (pTarget->dmaInUse) && (pTarget->dmaEot)) { USBISP1582_DEBUG ("usbTcdIsp1582FncCopyDataToEpBuf : DMA EOT has \ happened...\n",0,0,0,0,0,0); data16 = isp1582Read16 (pTarget,ISP1582_DMA_INT_RESN_REG) & isp1582Read16 (pTarget , ISP1582_DMA_INT_ENBL_REG); if (( data16 & ISP1582_DMA_INT_RESN_REG_DMA_XFER_OK) != 0) { /* DMA Transfer is completed succesfully */ /* Determine the size to copy */ if (pTrb->uActLength < sysFdBufSize) pTarget->dmaXferLen = pTrb->uActLength; else pTarget->dmaXferLen = sysFdBufSize; /* Copy data from pBuffer to the DMA Buffer */ memcpy ((char *)sysFdBuf , pTrb->pBuffer , pTarget->dmaXferLen ); /* Flush the DMA Buffer */ USB_PCI_MEM_FLUSH ((pVOID)sysFdBuf ,pTarget->dmaXferLen ); /* Update uActLength */ pTrb->uActLength = pTarget->dmaXferLen; /* Clear the Dma Interrupt Register */ isp1582Write16 ( pTarget , ISP1582_DMA_INT_RESN_REG , ISP1582_DMA_INT_RESN_MASK); /* Initialize the DMA Controller for another operation */ /* * Initailize the Dma Transfer Counter Register with the * length of data */ isp1582Write32 (pTarget , ISP1582_DMA_TRANS_CNT_REG , pTrb->uActLength); /* Intialize the DMA Command Regsiter */ isp1582Write8 (pTarget , ISP1582_DMA_COMMAND_REG , ISP1582_DMA_COMMAND_REG_GDMA_READ); status = OK; } else { /* DMA Transfer didn't complete normally */ /* Clear the Dma Interrupt Register */ isp1582Write16 ( pTarget , ISP1582_DMA_INT_RESN_REG , ISP1582_DMA_INT_RESN_MASK); USBISP1582_DEBUG ("usbTcdIsp1582FncCopyDataToEpBuf : \ Disabling the DMA...\n",0,0,0,0,0,0); /* Disable DMA */ disableDma (pTarget , endpointIndex); status = ERROR; } USBISP1582_DEBUG ("usbTcdIsp1582FncCopyDataToEpBuf : Exiting...\n", 0,0,0,0,0,0); return status; } else if ((pTarget->dmaEndpointId == endpointIndex) && (pTarget->dmaInUse) && (pTarget->dmaEot != TRUE)) return ERROR; else if (pTarget->dmaInUse == FALSE) { /* * If the dma channel is unused. initialize the DMA Controller * to carry out the DMA operation. */ /* Determine the size to copy */ if (pTrb->uActLength < sysFdBufSize) pTarget->dmaXferLen = pTrb->uActLength; else pTarget->dmaXferLen = sysFdBufSize; /* Copy data from pBuffer to the DMA Buffer */ memcpy ((char *)sysFdBuf , pTrb->pBuffer , pTarget->dmaXferLen ); /* Flush the DMA Buffer */ USB_PCI_MEM_FLUSH ((pVOID)sysFdBuf ,pTarget->dmaXferLen ); pTarget->dmaEot = FALSE; USBISP1582_DEBUG ("usbTcdIsp1582FncCopyDataToEpBuf :Initializing \ the DMA for the next operation...\n",0,0,0,0,0,0); /* Initialize the DMA */ initializeDma (pTarget , endpointIndex , ISP1582_DMA_COMMAND_REG_GDMA_READ); /* Update uActLength */ pTrb->uActLength = pTarget->dmaXferLen; USBISP1582_DEBUG ("usbTcdIsp1582FncCopyDataToEpBuf : Exiting...\n", 0,0,0,0,0,0); return OK; } } /* Endpoint does not support DMA or the dma channel is already in use */#endif USBISP1582_DEBUG ("usbTcdIsp1582FncCopyDataToEpBuf : Working in PIO Mode \ ...\n",0,0,0,0,0,0); /* Initialize the endpoint index register */ isp1582Write8 (pTarget , ISP1582_ENDPT_INDEX_REG , endpointIndex); if ( pTrb->uActLength < pEndpointInfo->maxPacketSize) sizeToCopy = pTrb->uActLength; else sizeToCopy = pEndpointInfo->maxPacketSize; /* * Write to the buffer length register, the size of data which is to be * sent to the host */ if (sizeToCopy < pEndpointInfo->maxPacketSize) isp1582Write16 (pTarget , ISP1582_BUF_LEN_REG ,sizeToCopy); else isp1582Write16 (pTarget , ISP1582_BUF_LEN_REG ,pEndpointInfo->maxPacketSize); /* * If this function is called for the endpoint 0 IN endpoint, * initiate a status stage after copying the data */ if ((endpointIndex == ISP1582_ENDPT_0_TX) && (pTrb->uActLength == sizeToCopy) && (pTrb->zeroLengthPacket == FALSE)) pTarget->controlOUTStatusPending = TRUE; /* Update uActLength */ pTrb->uActLength = sizeToCopy; /* * Write Data Port Regsiter. It is a 16 bit access, hence sizeToCopy * should be decremented by 2 and pBuf should be incremented by 2 */ while (sizeToCopy > 0) { data = *pBuf; sizeToCopy--; if (sizeToCopy > 0) { pBuf += 1; sizeToCopy--; data |= (*pBuf << 8); if (sizeToCopy > 0) pBuf += 1; } isp1582Write16( pTarget , ISP1582_DATA_PORT_REG , data); } status = OK; /* WindView Instrumentation */ USB_TCD_LOG_EVENT(USB_TCD_ISP1582_ENDPOINT, "usbTcdIsp1582FncCopyDataToEpBuf exited...", USB_TCD_ISP582_WV_FILTER); USBISP1582_DEBUG ("usbTcdIsp1582FncCopyDataToEpBuf : Exiting...\n", 0,0,0,0,0,0); return status; }#ifdef DMA_SUPPORTED/********************************************************************************* disableDma - Disable the DMA** This is a utility function to disable the DMA.** RETURNS: N/A.** ERRNO:* none.** \NOMANUAL*/LOCAL VOID disableDma ( pUSB_TCD_ISP1582_TARGET pTarget, /* USB_TCD_ISP1582_TARGET */ UINT8 endpointIndex /* endpoint Index */ ) { UINT32 data32 = 0; /* Reset the DMA Interrupt Enable Regsiter */ isp1582Write16 (pTarget , ISP1582_DMA_INT_ENBL_REG , 0); /* Enable the endpoint by writing into Interrupt Enable register.*/ data32 = isp1582Read32 (pTarget , ISP_1582_INT_ENABLE_REG); /* * Enable that endpoint by writing into endpoint enable * register. Also reset the but IE_DMA */ data32 &= ~ISP1582_INT_ENABLE_REG_IEDMA; data32 |= ISP1582_INT_ENABLE_REG_ENDPT_SET(endpointIndex); isp1582Write32 (pTarget , ISP_1582_INT_ENABLE_REG , data32); /* Initialize the DMA Endpoint Register to endpoint not used. */ isp1582Write8 (pTarget , ISP1582_DMA_ENDPT_REG ,pTarget->dmaEndptNotInUse); /* * Set dmaInUse and dmaEot member of structure USB_TCD_ISP1582_TARGET * to False. */ pTarget->dmaInUse = FALSE; pTarget->dmaEot = FALSE; /* Reset the dmaEndpointId and dmaXferLen */ pTarget->dmaEndpointId = 0; pTarget->dmaXferLen = 0; return; }/********************************************************************************* initializeDma - initializes the DMA** This is a utility function which is used to initilize the DMA for DMA* operations.** RETURNS: N/A** ERRNO:* none** \NOMANUAL*/LOCAL VOID initializeDma ( pUSB_TCD_ISP1582_TARGET pTarget, /* USB_TCD_ISP1582_TARGET */ UINT8 endpointIndex, /* endpoint index */ UINT8 command /* DMA command */ ) { UINT32 data32 = 0; UINT8 data8 = 0; /* Give Reset DMA Command */ isp1582Write8 (pTarget , ISP1582_DMA_COMMAND_REG , ISP1582_DMA_COMMAND_REG_DMA_RESET); /* Initialize the DMA Configuration Register */ isp1582Write16 (pTarget , ISP1582_DMA_CONFIG_REG , ISP1582_DMA_CONFIG_REG_MODE_SET(ISP1582_DMA_CONFIG_REG_MODE_00) | ISP1582_DMA_CONFIG_REG_WIDTH_8); /* Initialize the DMA Hardware Register */ data8 = ISP1582_DMA_HARDWARE_REG_DREQ_POL|ISP1582_DMA_HARDWARE_REG_EOT_POL; isp1582Write8 (pTarget, ISP1582_DMA_HARDWARE_REG , data8 ); /* * In default Burstmode is set to 0. The Burstmode are set to * define the number of DIOR/DIOW strobes to be detected before * de-asserting DREQ. As an example, Burstmode '000' will mean that * the DREQ will stay asserted until the end of transfer OR maximum * packet size is reached. */ /* Set the DMA Burst Counter Regsiter to default value */ isp1582Write16 ( pTarget , ISP1582_DMA_BURST_COUNT_REG , 0); /* Initailize the Dma Transfer Counter Register with the length of data */ isp1582Write32 (pTarget , ISP1582_DMA_TRANS_CNT_REG , pTarget->dmaXferLen); /* * Initialize Dma Interrupt Enable Register to generate interrupt only * when the DMA transfer counter reaches 0 i.e set bit IE_DMA_XFER_OK. */ isp1582Write16 (pTarget , ISP1582_DMA_INT_ENBL_REG , ISP1582_DMA_INT_ENBL_REG_IE_DMA_XFER_OK); /* * Disable the interrupt for endpoint in Interrupt Enalbe Register * and enable the bit IE_DMA. */ data32 = isp1582Read32 (pTarget , ISP_1582_INT_ENABLE_REG); /* Disable the interrupt for endpoint */ data32 &= ~(ISP1582_INT_ENABLE_REG_ENDPT_SET(endpointIndex)); /* Enable the bit for the DMA interupt */ data32 |= ISP1582_INT_ENABLE_REG_IEDMA; /* Write into interrupt enable regsiter */ isp1582Write32 (pTarget , ISP_1582_INT_ENABLE_REG , data32); /* Initialize the DMA endpoint register */ isp1582Write8 (pTarget , ISP1582_DMA_ENDPT_REG , endpointIndex); /* Set member dmaInUse and reset member dmaEot */ pTarget->dmaInUse = TRUE; pTarget->dmaEot = FALSE; /* Update dmaEndpointId to endpointIndex */ pTarget->dmaEndpointId = endpointIndex; /* Give the DMA Command by writing into the DMA Regsiter */ isp1582Write8 (pTarget , ISP1582_DMA_COMMAND_REG , command); return; }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -