static int rkusb_reinit_req( struct rkusb_dev *dev,struct usb_ep* ep_in,struct usb_ep* ep_out ) { __rkusb_free_ep_req( dev->ep_in, dev->req_in ); if( !ep_in ) return 0; dev->req_in = __rkusb_init_ep_req(dev, ep_in); dev->ep_in = ep_in; if( !dev->req_in ) return -ENOMEM; dev->req_in->complete = rkusb_complete_in; #if 0 buf = __rkusb_free_ep_req( dev->ep_out, dev->req_out); dev->req_out = __rkusb_init_ep_req(dev, ep_out , buf ); dev->ep_out = ep_out; if( !dev->req_out ) { if( buf ) kfree( buf ); buf = __rkusb_free_ep_req( dev->ep_in, dev->req_in ); if( buf ) kfree( buf ); return -ENOMEM; } dev->req_out->complete = rkusb_complete_out; DEV_LENGTH(dev) = RKUSB_BULK_CB_WRAP_LEN; rkusb_get_cb( dev , DEV_LENGTH(dev) ); #endif return 0; }
/* * 20091221,add file offset for large file. */ static int rkusb_xfer_file_task( struct rkusb_dev *dev ) { int nread; int mount; int total; int real_tranfs; FILE_INFO *fi = (FILE_INFO*)dev->private_tmp; char *buf_bak; loff_t pos = DEV_OFFSET(dev); real_tranfs = mount = __rkusb_rwbuffer_end(dev) -__rkusb_rwbuffer_start(dev); dev->buf_filled = 0; fi->error = 0; total = 0; if( FI_WRITE(fi) ) buf_bak = rkusb_reset_req_buf(dev->req_out,dev->buf); else buf_bak = rkusb_reset_req_buf(dev->req_in,dev->buf);; for(; ;) { if (signal_pending(current)) break; if( FI_WRITE(fi) ) { if( DEV_LENGTH( dev ) < mount ) { //mount = DEV_LENGTH( dev ) ; real_tranfs = DEV_LENGTH( dev ) ; //rk28printk("vfs r/w last pack , len =0x%x\n" , real_tranfs ); } //rk28printk("total write=0x%x,remain=0x%x,file size=0x%lx,mount=0x%x\n" , // total , DEV_LENGTH(dev) , fi->file_size , mount ); #if 1 rkusb_get_data_buffer( dev , mount , rkusb_rw_file_cb ); #else //__rkusb_set_dest_or_source( dev , rwb->buf ); rkusb_normal_data_xfer_max_size( dev , rkusb_rw_file_cb , mount); #endif while( !dev->buf_filled ) { rkusb_sleep_thread( dev ); } if( fi->error ) break; nread = vfs_write(fi->file, dev->buf , real_tranfs ,&pos); if( nread < 0 ) { rk28printk("vfs write failed , ret =%d\n" , nread ); fi->error = nread; } else { dev->buf_filled = 0; total += nread; } if( DEV_LENGTH( dev ) == 0 ) break; } else { //rk28printk("total read=0x%x,remain=0x%x,file size=0x%lx,mount=0x%x\n" , // total , DEV_LENGTH(dev) , fi->file_size , mount ); while( dev->buf_filled ) { rkusb_sleep_thread( dev ); } if( fi->error ) break; if( DEV_LENGTH( dev ) == 0 ) break; nread = vfs_read(fi->file, dev->buf , real_tranfs ,&pos); if( nread < 0 ) { rk28printk("vfs read failed , ret =%d\n" , nread ); fi->error = nread; } else { dev->buf_filled = 1; total += nread; if( nread < real_tranfs && total < fi->file_size ) { /* 20100115,HSL@RK,set 0 at pc tools */ //rwb->buf[nread] = 0; //if( real_tranfs - nread > 5 ) // strcpy(rwb->buf+nread+1,"@#$"); nread = real_tranfs; } } //rk28printk("read finish,nread=0x%x,start transfer,real transfer=0x%x\n" , // nread , real_tranfs ); #if 1 rkusb_send_data_buffer( dev , nread , rkusb_rw_file_cb ); #else __rkusb_set_dest_or_source( dev , rwb->buf ); rkusb_normal_data_xfer_max_size( dev , rkusb_rw_file_cb , mount); #endif } } rk28printk("file transfer finish,error=%d\n" , fi->error ); if( FI_WRITE(fi) ) { rkusb_reset_req_buf(dev->req_out , buf_bak); rkusb_get_cb( dev , RKUSB_BULK_CB_WRAP_LEN ); } else rkusb_reset_req_buf(dev->req_in , buf_bak); /* close file , free FILE_INFO */ if( !fi->error ) { fi->error = - FI_ERR_CLEAR; rkusb_send_csw( dev , RKUSB_STATUS_PASS ); } else { rkusb_send_csw( dev , RKUSB_STATUS_FAIL ); } return 0; }