static int rksub_get_sym_tasks( struct rkusb_dev *dev ) { ALL_TASK at; TASK_INFO *ti; struct task_struct *g, *p; int buf_full = 0; int tn , tntoal; ti = (TASK_INFO*)__rkusb_rwbuffer_start( dev ); at.size = sizeof( at ); at.start_ts = ti; at.ti_size = sizeof(*ti); tntoal = 0; tn = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if( !buf_full ) { if( ti+1 > (TASK_INFO*)__rkusb_rwbuffer_end( dev ) ) { buf_full = 1; tn = tntoal; } else { __rksub_copy_task_info( ti , p ); ti++; } } tntoal ++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if( !tn ) tn = tntoal; at.task_num = tn; at.task_total_num = tntoal; at.now = ktime_to_ns(ktime_get() ); rkusb_normal_data_xfer_onetime( dev , &at ); return RKUSB_CB_OK_NONE; }
/* * 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; }
static void __rksub_copy_task_vma(struct rkusb_dev *dev , TASK_VAM *tm , struct task_struct * p , char *dest ) { TASK_VMA_INFO *tv; struct mm_struct *mm; struct vm_area_struct * mmap; int buf_full = 0; int n,ntotal; tv = (TASK_VMA_INFO*)dest; mm = p->mm; tm->size = sizeof(*tm); tm->flag = (1<<0); tm->pid = p->pid; if( !mm ) { mm = p->active_mm; tm->flag &= ~(1<<0); } tm->start_code = mm->start_code; tm->end_code= mm->start_code; tm->start_code = mm->end_code; tm->start_data= mm->start_data; tm->end_data = mm->end_data; tm->start_brk = mm->start_brk; tm->brk = mm->brk; tm->start_stack = mm->start_stack; tm->arg_start = mm->arg_start; tm->arg_end = mm->arg_end; tm->env_start = mm->env_start; tm->env_end = mm->env_end; tm->vi = tv; tm->vi_size = sizeof(TASK_VMA_INFO); mmap = mm->mmap; n = ntotal = 0; while( mmap ) { if( buf_full ) goto loop_none; tv->size = sizeof(TASK_VMA_INFO); tv->start = mmap->vm_start; tv->end = mmap->vm_end; tv->flags = mmap->vm_flags; tv->pgoff = mmap->vm_pgoff; /* 20100226,HSL@RK,add offset in file*/ tv->file = mmap->vm_file; memset( tv->mape_filename , 0 , sizeof(tv->mape_filename) ); if( tv->file ) { if( strlen( FILENAME(mmap->vm_file) ) >= sizeof(tv->mape_filename) ) strncpy(tv->mape_filename,FILENAME(mmap->vm_file)+ strlen( FILENAME(mmap->vm_file) )-sizeof(tv->mape_filename)+1, sizeof(tv->mape_filename)-1 ); else strcpy(tv->mape_filename,FILENAME(mmap->vm_file) ); } tv++; if( tv >= (TASK_VMA_INFO*)__rkusb_rwbuffer_end( dev ) ) { buf_full = 1; n = ntotal+1; } loop_none: ntotal++; mmap = mmap->vm_next; } if( !n ) n = ntotal; tm->vi_xfer = n; tm->vi_tolnum = ntotal; rk28printk("%s::task=%s,pid=%d,total vma=%d\n", __func__ , p->comm , p->pid , ntotal ); }