/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_host_send_data * Returned Value : error or status of the transfer * Comments : * The Send Data routine is non-blocking routine that causes a block of data * to be made available for transmission to the USB host. * *END*-----------------------------------------------------------------*/ uint_32 _usb_host_send_data ( /* [IN] the USB Host state structure */ _usb_host_handle hci_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; uint_32 return_code; PIPE_TR_STRUCT_PTR pipe_tr_ptr; 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(); return return_code; } /* Endif */ usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)hci_handle; UNUSED(usb_host_ptr); pipe_descr_ptr = (PIPE_DESCRIPTOR_STRUCT_PTR)pipe_handle; /*Must Flush and Invalidate the buffer before sending /receiving the data in it */ USB_dcache_flush_mlines((void *)pipe_tr_ptr->TX_BUFFER, pipe_tr_ptr->TX_LENGTH); /* We have obtained the current TR on the Pipe's TR list ** from _usb_host_set_up_TR */ /* Call the low-level send routine */ return_code = _usb_host_send_call_interface (hci_handle, pipe_descr_ptr, pipe_tr_ptr); USB_unlock(); if(return_code == USB_OK) { return USB_STATUS_TRANSFER_QUEUED; } else { return return_code; } } /* Endbody */
/*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_device_send_data * Returned Value : USB_OK or error code * Comments : * Sends data on a specified endpoint. * *END*-----------------------------------------------------------------*/ USB_STATUS _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 */ USB_STATUS error; XD_STRUCT_PTR xd_ptr; volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; if (handle == NULL) { #if _DEBUG printf("_usb_device_send_data: handle is NULL\n"); #endif 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 flush the buffer before passing it to hardware driver. ********************************************************/ USB_dcache_flush_mlines((pointer)buff_ptr,size); #endif USB_lock(); if (!usb_dev_ptr->XD_ENTRIES) { USB_unlock(); return USB_STATUS_TRANSFER_IN_PROGRESS; } /* Get a transfer descriptor */ 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_SEND; 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_SEND != NULL) { error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\ usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SEND(handle, xd_ptr); } else { #if _DEBUG printf("_usb_device_send_data: DEV_SEND is NULL\n"); #endif return USBERR_ERROR; } USB_unlock(); if (error) { #if _DEBUG printf("_usb_device_send_data, transfer failed\n"); #endif return USBERR_TX_FAILED; } return error; }