/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_device_recv_data * Returned Value : USB_OK or error code * Comments : * Receives data on a specified endpoint. * *END*-----------------------------------------------------------------*/ uint_8 _usb_device_recv_data ( /* [IN] the USB_USB_dev_initialize state structure */ _usb_device_handle handle, /* [IN] the Endpoint number */ uint_8 ep_num, /* [IN] buffer to receive data */ uint_8_ptr buff_ptr, /* [IN] length of the transfer */ uint_32 size ) { /* Body */ uint_8 error = USB_OK; XD_STRUCT_PTR xd_ptr; USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; if (handle == NULL) { return USBERR_ERROR; } usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; #if PSP_HAS_DATA_CACHE /******************************************************** If system has a data cache, it is assumed that buffer passed to this routine will be aligned on a cache line boundry. The following code will invalidate the buffer before passing it to hardware driver. ********************************************************/ USB_dcache_invalidate_mlines((pointer)buff_ptr,size); #endif USB_lock(); if (!usb_dev_ptr->XD_ENTRIES) { USB_unlock(); return USB_STATUS_TRANSFER_IN_PROGRESS; } /* Endif */ /* Get a transfer descriptor for the specified endpoint ** and direction */ USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr); usb_dev_ptr->XD_ENTRIES--; /* Initialize the new transfer descriptor */ xd_ptr->EP_NUM = ep_num; xd_ptr->BDIRECTION = USB_RECV; xd_ptr->WTOTALLENGTH = size; xd_ptr->WSTARTADDRESS = buff_ptr; xd_ptr->WSOFAR = 0; xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED; if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\ usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_RECV != NULL) { error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\ usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_RECV(handle, xd_ptr); } else { #if _DEBUG printf("_usb_device_recv_data: DEV_RECV is NULL\n"); #endif return USBERR_ERROR; } USB_unlock(); if (error) { return USBERR_RX_FAILED; } /* Endif */ return error; } /* EndBody */
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_device_recv_data * Returned Value : USB_OK or error code * Comments : * Receives data on a specified endpoint. * *END*-----------------------------------------------------------------*/ uint_8 _usb_device_recv_data ( /* [IN] the USB_USB_dev_initialize state structure */ _usb_device_handle handle, /* [IN] the Endpoint number */ uint_8 ep_num, /* [IN] buffer to receive data */ uchar_ptr buff_ptr, /* [IN] length of the transfer */ uint_32 size ) { /* Body */ #ifdef _DEVICE_DEBUG_ DEBUG_LOG_TRACE("_usb_device_recv_data"); #endif uint_8 error = USB_OK; XD_STRUCT_PTR xd_ptr; USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; USB_lock(); if (!usb_dev_ptr->XD_ENTRIES) { USB_unlock(); #ifdef _DEVICE_DEBUG_ DEBUG_LOG_TRACE("_usb_device_recv_data, transfer in progress"); #endif return USB_STATUS_TRANSFER_IN_PROGRESS; } /* Endif */ /* Get a transfer descriptor for the specified endpoint ** and direction */ USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr); usb_dev_ptr->XD_ENTRIES--; /* Initialize the new transfer descriptor */ xd_ptr->EP_NUM = ep_num; xd_ptr->BDIRECTION = USB_RECV; xd_ptr->WTOTALLENGTH = size; xd_ptr->WSOFAR = 0; xd_ptr->WSTARTADDRESS = buff_ptr; xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED; error = _usb_dci_vusb20_recv_data(handle, xd_ptr); USB_unlock(); if (error) { #ifdef _DEVICE_DEBUG_ DEBUG_LOG_TRACE("_usb_device_recv_data, receive failed"); #endif return USBERR_RX_FAILED; } /* Endif */ return error; } /* EndBody */
uint_8 _usb_prepare_to_send(void* handle) { XD_STRUCT_PTR xd_ptr; USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; uint_8* buff_ptr; uint_8* tmp_buff; uint_32 size; int num_dma, tail_dma, i; uint_8 error = 0; usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; tail_dma = usbSendQueue.tail_dma; num_dma = usbSendQueue.num_dma; buff_ptr = usbSendQueue.buff_ptr[tail_dma]; size = usbSendQueue.size[tail_dma]; if(num_dma == 0) return 0; /* USB_printf("_usb_prepare_to_send: num=%d, tail=%d, sentSize=%d, size=%d, buff=%p\n", num_dma, tail_dma, usbSentSize, size, buff_ptr); */ for(i=0; i<global_wa_sram_parts; i++) { if(sram_parts[dma_index] != S_FREE) break; if(usbDmaSize >= usbSendQueue.size[tail_dma]) { /* Remove from the usbSendQueues */ num_dma--; tail_dma++; if(tail_dma == MAX_XDS_FOR_TR_CALLS) tail_dma = 0; usbSendQueue.tail_dma = tail_dma; usbSendQueue.num_dma = num_dma; usbDmaSize = 0; if(num_dma == 0) break; } buff_ptr = usbSendQueue.buff_ptr[tail_dma] + usbDmaSize; size = MIN(usbSramPartSize, (usbSendQueue.size[tail_dma] - usbDmaSize) ); usbDmaSize += size; if(size > global_wa_threshold) { tmp_buff = buff_ptr; buff_ptr = (uint_8*)((int)usbSramBase + (dma_index * usbSramPartSize)); USB_idma_copy(buff_ptr, tmp_buff, size); sram_parts[dma_index] = S_BUSY; dma_index++; if(dma_index == global_wa_sram_parts) dma_index = 0; } /* Get a transfer descriptor */ USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr); usb_dev_ptr->XD_ENTRIES--; USB_dcache_flush((pointer)buff_ptr, size); /* Initialize the new transfer descriptor */ xd_ptr->EP_NUM = usbSendQueue.ep_num[tail_dma]; xd_ptr->BDIRECTION = ARC_USB_SEND; xd_ptr->WTOTALLENGTH = size; xd_ptr->WSOFAR = 0; xd_ptr->WSTARTADDRESS = buff_ptr; xd_ptr->BSTATUS = ARC_USB_STATUS_TRANSFER_ACCEPTED; error = _usb_dci_vusb20_add_dTD(handle, xd_ptr); if(error) break; } return error; }
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_device_send_data * Returned Value : USB_OK or error code * Comments : * Sends data on a specified endpoint. * *END*-----------------------------------------------------------------*/ uint_8 _usb_device_send_data ( /* [IN] the USB_USB_dev_initialize state structure */ _usb_device_handle handle, /* [IN] the Endpoint number */ uint_8 ep_num, /* [IN] buffer to send */ uint_8_ptr buff_ptr, /* [IN] length of the transfer */ uint_32 size ) { /* Body */ int lockKey; uint_8 error = 0; XD_STRUCT_PTR xd_ptr; USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; boolean toSend = TRUE; usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_TX, "send_data: handle=%p, ep=%d, pBuf=0x%x, size=%d, EP_QH=%p\n", handle, ep_num, (unsigned)buff_ptr, (int)size, usb_dev_ptr->EP_QUEUE_HEAD_PTR); ARC_DEBUG_CODE(ARC_DEBUG_FLAG_STATS, (usb_dev_ptr->STATS.usb_send_count++)); lockKey = USB_lock(); if (!usb_dev_ptr->XD_ENTRIES) { USB_unlock(lockKey); USB_printf("_usb_device_send_data, transfer in progress\n"); return ARC_USB_STATUS_TRANSFER_IN_PROGRESS; } /* Endif */ #if defined(USB_UNDERRUN_WA) { int head; VUSB20_EP_QUEUE_HEAD_STRUCT* ep_queue_head_ptr; ep_queue_head_ptr = (VUSB20_EP_QUEUE_HEAD_STRUCT_PTR)usb_dev_ptr->EP_QUEUE_HEAD_PTR + 2*ep_num + ARC_USB_SEND; if( ((ep_queue_head_ptr->MAX_PKT_LENGTH >> 16) & 0x7FF) > global_wa_threshold) { /* Only Endpoints with maxPktSize more than 128 bytes need special processing */ if( (size > global_wa_threshold) || (usbSendQueue.num != 0) ) { /* USB_printf("_usb_device_send_data: ep_num=%d, maxPktSize=%d, size=%d\n", ep_num, (ep_queue_head_ptr->MAX_PKT_LENGTH >> 16) & 0x7FF, size); */ /* Check if usbSendQueue is not Full */ if(usbSendQueue.num == MAX_XDS_FOR_TR_CALLS) { USB_printf("ep=%d: usbSendQueue is FULL\n", ep_num); USB_unlock(lockKey); return USBERR_TX_FAILED; } /* Add to usbSendQueu */ head = usbSendQueue.head; usbSendQueue.num++; usbSendQueue.num_dma++; usbSendQueue.size[head] = size; usbSendQueue.buff_ptr[head] = buff_ptr; usbSendQueue.ep_num[head] = ep_num; head++; if(head == MAX_XDS_FOR_TR_CALLS) head = 0; usbSendQueue.head = head; /* Process first usbSendQueue element if possible */ if(usbSendQueue.num == 1) { error = _usb_prepare_to_send(handle); } toSend = FALSE; } } } #endif /* USB_UNDERRUN_WA */ if(toSend == TRUE) { /* Get a transfer descriptor */ USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr); usb_dev_ptr->XD_ENTRIES--; if(buff_ptr != NULL) USB_dcache_flush((pointer)buff_ptr, size); /* Initialize the new transfer descriptor */ xd_ptr->EP_NUM = ep_num; xd_ptr->BDIRECTION = ARC_USB_SEND; xd_ptr->WTOTALLENGTH = size; xd_ptr->WSOFAR = 0; xd_ptr->WSTARTADDRESS = buff_ptr; xd_ptr->BSTATUS = ARC_USB_STATUS_TRANSFER_ACCEPTED; error = _usb_dci_vusb20_add_dTD(handle, xd_ptr); } USB_unlock(lockKey); if (error) { USB_printf("_usb_device_send_data, transfer failed\n"); return USBERR_TX_FAILED; } /* Endif */ return error; } /* EndBody */
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_device_recv_data * Returned Value : USB_OK or error code * Comments : * Receives data on a specified endpoint. * *END*-----------------------------------------------------------------*/ uint_8 _usb_device_recv_data ( /* [IN] the USB_USB_dev_initialize state structure */ _usb_device_handle handle, /* [IN] the Endpoint number */ uint_8 ep_num, /* [IN] buffer to receive data */ uint_8_ptr buff_ptr, /* [IN] length of the transfer */ uint_32 size ) { /* Body */ int lockKey; uint_8 error = USB_OK; XD_STRUCT_PTR xd_ptr; USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_RX, "recv_data: ep=%d, buf_ptr=0x%x, size=%d\n", ep_num, (unsigned)buff_ptr, (int)size); ARC_DEBUG_CODE(ARC_DEBUG_FLAG_STATS, (usb_dev_ptr->STATS.usb_recv_count++)); if(buff_ptr != NULL) USB_dcache_inv((pointer)buff_ptr,size); lockKey = USB_lock(); if (!usb_dev_ptr->XD_ENTRIES) { USB_unlock(lockKey); USB_printf("_usb_device_recv_data, transfer in progress\n"); return ARC_USB_STATUS_TRANSFER_IN_PROGRESS; } /* Endif */ /* Get a transfer descriptor for the specified endpoint ** and direction */ USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr); usb_dev_ptr->XD_ENTRIES--; /* Initialize the new transfer descriptor */ xd_ptr->EP_NUM = ep_num; xd_ptr->BDIRECTION = ARC_USB_RECV; xd_ptr->WTOTALLENGTH = size; xd_ptr->WSOFAR = 0; xd_ptr->WSTARTADDRESS = buff_ptr; xd_ptr->BSTATUS = ARC_USB_STATUS_TRANSFER_ACCEPTED; error = _usb_dci_vusb20_add_dTD(handle, xd_ptr); USB_unlock(lockKey); if (error) { USB_printf("_usb_device_recv_data, receive failed\n"); return USBERR_RX_FAILED; } /* Endif */ return error; } /* EndBody */
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_device_recv_data * Returned Value : USB_OK or error code * Comments : * Receives data on a specified endpoint. * *END*-----------------------------------------------------------------*/ uint8_t _usb_device_recv_data( /* [IN] the USB_USB_dev_initialize state structure */ _usb_device_handle handle, /* [IN] the Endpoint number */ uint8_t ep_num, /* [IN] buffer to receive data */ uint8_t * buff_ptr, /* [IN] length of the transfer */ uint32_t size) { /* Body */ uint8_t error = USB_OK; XD_STRUCT_PTR xd_ptr; USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; TOMBSTONE_USB_DEVICE_DEBUG(0x40210000); #ifdef _DEVICE_DEBUG_ DEBUG_LOG_TRACE("_usb_device_recv_data"); #endif usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR) handle; #ifdef ENABLE_DCACHE /******************************************************** If system has a data cache, it is assumed that buffer passed to this routine will be aligned on a cache line boundry. The following code will invalidate the buffer before passing it to hardware driver. ********************************************************/ USB_dcache_invalidate_mlines((void *)buff_ptr, size); #endif USB_device_lock(); if (!usb_dev_ptr->XD_ENTRIES) { TOMBSTONE_USB_DEVICE_DEBUG(0x40210001); USB_device_unlock(); #ifdef _DEVICE_DEBUG_ DEBUG_LOG_TRACE("_usb_device_recv_data, transfer in progress"); #endif TOMBSTONE_USB_DEVICE_DEBUG(0x40210002); return USB_STATUS_TRANSFER_IN_PROGRESS; } /* Endif */ /* Get a transfer descriptor for the specified endpoint ** and direction */ USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr); usb_dev_ptr->XD_ENTRIES--; /* Initialize the new transfer descriptor */ xd_ptr->EP_NUM = ep_num; xd_ptr->BDIRECTION = USB_RECV; xd_ptr->WTOTALLENGTH = size; xd_ptr->WSOFAR = 0; xd_ptr->WSTARTADDRESS = buff_ptr; xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED; TOMBSTONE_USB_DEVICE_DEBUG(0x40210003); error = _usb_dci_vusb20_recv_data(handle, xd_ptr); TOMBSTONE_USB_DEVICE_DEBUG(0x40210004); USB_device_unlock(); if (error) { TOMBSTONE_USB_DEVICE_DEBUG(0x40210005); #ifdef _DEVICE_DEBUG_ DEBUG_LOG_TRACE("_usb_device_recv_data, receive failed"); #endif return USBERR_RX_FAILED; } /* Endif */ TOMBSTONE_USB_DEVICE_DEBUG(0x40210099); return error; } /* EndBody */