/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_host_send_setup * Returned Value : None * Comments : * Sends a Setup packet. Internally, following the SendSetup call * this takes care of the whole transaction (including receiving or sending * any data to or from the device. * *END*-----------------------------------------------------------------*/ USB_STATUS _usb_host_send_setup ( /* [IN] the USB Host state structure */ _usb_host_handle handle, /* [IN] the pipe handle */ _usb_pipe_handle pipe_handle, /* [IN] transfer parameters */ TR_INIT_PARAM_STRUCT_PTR tr_params_ptr ) { /* Body */ TR_STRUCT_PTR tr_ptr; PIPE_STRUCT_PTR pipe_ptr; USB_HOST_STATE_STRUCT_PTR usb_host_ptr; uint_32 return_code; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_send_setup"); #endif USB_lock(); /* Initialize a TR and link it into the pipe's TR list */ return_code = _usb_host_set_up_tr(pipe_handle, tr_params_ptr, &tr_ptr); if (return_code != USB_STATUS_TRANSFER_QUEUED) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_send_setup error status"); #endif return return_code; } /* Endif */ usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; pipe_ptr = (PIPE_STRUCT_PTR)pipe_handle; pipe_ptr->NEXTDATA01 = 0; /* reset DATA0/1 */ /* We have obtained the current TR on the Pipe's TR list ** from _usb_host_set_up_tr */ /* true if this setup packet will have a send data phase */ tr_ptr->SEND_PHASE = (boolean)!(tr_ptr->setup_packet.BMREQUESTTYPE & USB_SETUP_DATA_XFER_DIRECTION); /*************************************************************** For data caching it is important that we update the memory with the intended contents. ***************************************************************/ #if PSP_HAS_DATA_CACHE // TODO check - maybe uncached allocation used/can be used USB_dcache_flush_mlines((void *)&tr_ptr->setup_packet, 1); if(pipe_ptr->DIRECTION == USB_SEND) { if(tr_ptr->TX_LENGTH > 0) { USB_dcache_flush_mlines((void *)tr_ptr->TX_BUFFER, tr_ptr->TX_LENGTH); } } else { if(tr_ptr->RX_LENGTH > 0) { USB_dcache_invalidate_mlines((void *)tr_ptr->RX_BUFFER, tr_ptr->RX_LENGTH); } } #endif // PSP_HAS_DATA_CACHE /* Call the low-level routine to send a setup packet */ return_code = _usb_host_send_setup_call_interface (handle, pipe_ptr, tr_ptr); USB_unlock(); if(return_code == USB_OK) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_send_setup SUCCESSFUL"); #endif return USB_STATUS_TRANSFER_QUEUED; } else { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_send_setup FAILED"); #endif return USB_log_error(__FILE__,__LINE__,return_code); } } /* Endbody */
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_host_recv_data * Returned Value : error or status of the transfer * Comments : * The Receive Data routine is non-blocking routine that causes a buffer * to be made available for data recieved from the * USB host. It takes the buffer and passes it down to lower level hardware driver. *END*-----------------------------------------------------------------*/ USB_STATUS _usb_host_recv_data ( /* [IN] the USB Host state structure */ _usb_host_handle handle, /* [IN] the pipe handle */ _usb_pipe_handle pipe_handle, /* [IN] transfer parameters */ TR_INIT_PARAM_STRUCT_PTR tr_params_ptr ) { /* Body */ PIPE_DESCRIPTOR_STRUCT_PTR pipe_descr_ptr; USB_HOST_STATE_STRUCT_PTR usb_host_ptr; USB_STATUS status; /***************************************************************** CODE FOR ARC FULL SPEED CORE *****************************************************************/ PIPE_TR_STRUCT_PTR pipe_tr_ptr; USB_STATUS return_code; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_recv_data"); #endif USB_lock(); return_code = _usb_host_set_up_TR(pipe_handle, tr_params_ptr, &pipe_tr_ptr); if (return_code != USB_STATUS_TRANSFER_QUEUED) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_recv_data transfer queue failed"); #endif return USB_log_error(__FILE__,__LINE__,return_code); } /* Endif */ usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; pipe_descr_ptr = (PIPE_DESCRIPTOR_STRUCT_PTR)pipe_handle; /*Must Flush and Invalidate the buffer before sending /receiving the data in it */ USB_dcache_invalidate_mlines((void *)pipe_tr_ptr->RX_BUFFER, pipe_tr_ptr->RX_LENGTH); /* We have obtained the current TR on the Pipe's TR list ** from _usb_host_set_up_TR */ /* Call the low-level routine to receive data */ status = _usb_host_recv_data_call_interface (handle, pipe_descr_ptr, pipe_tr_ptr); USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_recv_data SUCCESSFUL"); #endif if(status == USB_OK) { return USB_STATUS_TRANSFER_QUEUED; } else { return USB_log_error(__FILE__,__LINE__,status); } } /* 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 */ 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*-----------------------------------------------------------------*/ 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 */