@ -328,6 +328,7 @@ static int rockusb_tx_write(const char *buffer, unsigned int buffer_size)
memcpy ( in_req - > buf , buffer , buffer_size ) ;
in_req - > length = buffer_size ;
debug ( " Transferring 0x%x bytes \n " , buffer_size ) ;
usb_ep_dequeue ( rockusb_func - > in_ep , in_req ) ;
ret = usb_ep_queue ( rockusb_func - > in_ep , in_req , 0 ) ;
if ( ret )
@ -421,6 +422,65 @@ static unsigned int rx_bytes_expected(struct usb_ep *ep)
return rx_remain ;
}
/* usb_request complete call back to handle upload image */
static void tx_handler_ul_image ( struct usb_ep * ep , struct usb_request * req )
{
ALLOC_CACHE_ALIGN_BUFFER ( char , rbuffer , RKBLOCK_BUF_SIZE ) ;
struct f_rockusb * f_rkusb = get_rkusb ( ) ;
struct usb_request * in_req = rockusb_func - > in_req ;
int ret ;
/* Print error status of previous transfer */
if ( req - > status )
debug ( " status: %d ep '%s' trans: %d len %d \n " , req - > status ,
ep - > name , req - > actual , req - > length ) ;
/* On transfer complete reset in_req and feedback host with CSW_GOOD */
if ( f_rkusb - > ul_bytes > = f_rkusb - > ul_size ) {
in_req - > length = 0 ;
in_req - > complete = rockusb_complete ;
rockusb_tx_write_csw ( f_rkusb - > tag , 0 , CSW_GOOD ,
USB_BULK_CS_WRAP_LEN ) ;
return ;
}
/* Proceed with current chunk */
unsigned int transfer_size = f_rkusb - > ul_size - f_rkusb - > ul_bytes ;
if ( transfer_size > RKBLOCK_BUF_SIZE )
transfer_size = RKBLOCK_BUF_SIZE ;
/* Read at least one block */
unsigned int blkcount = ( transfer_size + f_rkusb - > desc - > blksz - 1 ) /
f_rkusb - > desc - > blksz ;
debug ( " ul %x bytes, %x blks, read lba %x, ul_size:%x, ul_bytes:%x, " ,
transfer_size , blkcount , f_rkusb - > lba ,
f_rkusb - > ul_size , f_rkusb - > ul_bytes ) ;
int blks = blk_dread ( f_rkusb - > desc , f_rkusb - > lba , blkcount , rbuffer ) ;
if ( blks ! = blkcount ) {
printf ( " failed reading from device %s: %d \n " ,
f_rkusb - > dev_type , f_rkusb - > dev_index ) ;
rockusb_tx_write_csw ( f_rkusb - > tag , 0 , CSW_FAIL ,
USB_BULK_CS_WRAP_LEN ) ;
return ;
}
f_rkusb - > lba + = blkcount ;
f_rkusb - > ul_bytes + = transfer_size ;
/* Proceed with USB request */
memcpy ( in_req - > buf , rbuffer , transfer_size ) ;
in_req - > length = transfer_size ;
in_req - > complete = tx_handler_ul_image ;
printf ( " Uploading 0x%x bytes \n " , transfer_size ) ;
usb_ep_dequeue ( rockusb_func - > in_ep , in_req ) ;
ret = usb_ep_queue ( rockusb_func - > in_ep , in_req , 0 ) ;
if ( ret )
printf ( " Error %d on queue \n " , ret ) ;
}
/* usb_request complete call back to handle down load image */
static void rx_handler_dl_image ( struct usb_ep * ep , struct usb_request * req )
{
@ -565,6 +625,48 @@ static void cb_get_chip_version(struct usb_ep *ep, struct usb_request *req)
rockusb_tx_write ( ( char * ) chip_info , sizeof ( chip_info ) ) ;
}
static void cb_read_lba ( struct usb_ep * ep , struct usb_request * req )
{
ALLOC_CACHE_ALIGN_BUFFER ( struct fsg_bulk_cb_wrap , cbw ,
sizeof ( struct fsg_bulk_cb_wrap ) ) ;
struct f_rockusb * f_rkusb = get_rkusb ( ) ;
int sector_count ;
memcpy ( ( char * ) cbw , req - > buf , USB_BULK_CB_WRAP_LEN ) ;
sector_count = ( int ) get_unaligned_be16 ( & cbw - > CDB [ 7 ] ) ;
f_rkusb - > tag = cbw - > tag ;
if ( ! f_rkusb - > desc ) {
char * type = f_rkusb - > dev_type ;
int index = f_rkusb - > dev_index ;
f_rkusb - > desc = blk_get_dev ( type , index ) ;
if ( ! f_rkusb - > desc | |
f_rkusb - > desc - > type = = DEV_TYPE_UNKNOWN ) {
printf ( " invalid device \" %s \" , %d \n " , type , index ) ;
rockusb_tx_write_csw ( f_rkusb - > tag , 0 , CSW_FAIL ,
USB_BULK_CS_WRAP_LEN ) ;
return ;
}
}
f_rkusb - > lba = get_unaligned_be32 ( & cbw - > CDB [ 2 ] ) ;
f_rkusb - > ul_size = sector_count * f_rkusb - > desc - > blksz ;
f_rkusb - > ul_bytes = 0 ;
debug ( " require read %x bytes, %x sectors from lba %x \n " ,
f_rkusb - > ul_size , sector_count , f_rkusb - > lba ) ;
if ( f_rkusb - > ul_size = = 0 ) {
rockusb_tx_write_csw ( cbw - > tag , cbw - > data_transfer_length ,
CSW_FAIL , USB_BULK_CS_WRAP_LEN ) ;
return ;
}
/* Start right now sending first chunk */
tx_handler_ul_image ( ep , req ) ;
}
static void cb_write_lba ( struct usb_ep * ep , struct usb_request * req )
{
ALLOC_CACHE_ALIGN_BUFFER ( struct fsg_bulk_cb_wrap , cbw ,
@ -675,7 +777,7 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = {
} ,
{
. cmd = K_FW_LBA_READ_10 ,
. cb = cb_not_support ,
. cb = cb_read_lba ,
} ,
{
. cmd = K_FW_LBA_WRITE_10 ,