static int rkusb_do_get_task_cmd( struct rkusb_dev *dev ) { struct task_struct *p = dev->slave_task; int len = rkusb_get_task_cmdline( p , __rkusb_rwbuffer_start(dev) , DEV_RWBUF_LENGTH( dev ) ); __rkusb_set_dest_or_source( dev , __rkusb_rwbuffer_start(dev) ); rkusb_normal_data_xfer( dev , rkusb_do_get_taskcmd_cb ); dev->buf[0].filled = len; //rkusb_normal_data_xfer_onetime( dev , __rkusb_rwbuffer_start(dev) ); return RKUSB_CB_OK_NONE; }
static int rkusb_get_symbol( struct rkusb_dev *dev ) { switch ( DEV_FUNC(dev) ) { case FUNC_GSYM_KERNEL: return rkusb_get_kernel_symbols( dev ); case FUNC_GSYM_GETTASKS: return rksub_get_sym_tasks( dev ); case FUNC_GSYM_GETTASKVM: return rkusb_get_task_mm( dev ); case FUNC_GSYM_PROFILE: { char * buf = __rkusb_rwbuffer_start(dev); PROFILE_INFO pe; pe.size = sizeof( pe ); pe.npc = profile_check( buf ); pe.buf = (unsigned long)buf; pe.now = ktime_to_ns( ktime_get() ); rk28printk("%s::profile n=%ld\n" , __func__ , pe.npc ); rkusb_normal_data_xfer_onetime( dev , &pe ); return 0; } default: break; } return RKUSB_CB_FAILD; }
static int rkusb_write_sdram( struct rkusb_dev *dev ) { int pid; if( __rkusb_write_enable() ) { int max_len; if( DEV_OFFSET(dev) >= 0xc0000000 ) { rkusb_normal_data_xfer( dev , NULL ); return RKUSB_CB_OK_NONE; } max_len = DEV_RWBUF_LENGTH( dev ); if( max_len < DEV_LENGTH(dev) ) { return RKUSB_CB_FAILD; } pid = DEV_PID( dev ); if( pid ) { dev->slave_task = find_task_by_pid( pid ); if(!dev->slave_task ) return RKUSB_CB_FAILD; //rk28printk("%s::pid=%d,task=%s\n" , __func__ , pid , dev->slave_task->comm ); } else { dev->slave_task = current ; } /* bakeup real offset and length */ dev->private_tmp = (void*)DEV_OFFSET(dev); dev->buf_nfill = DEV_LENGTH(dev); __rkusb_set_dest_or_source( dev , __rkusb_rwbuffer_start( dev ) ); rkusb_normal_data_xfer( dev , rkusb_write_sdram_cb); return RKUSB_CB_OK_NONE; } return RKUSB_CB_FAILD; }
static int rkusb_read_sdram( struct rkusb_dev *dev ) { int pid; if( __rkusb_read_enable() ) { if( DEV_OFFSET(dev) >= 0xc0000000 ) { rkusb_normal_data_xfer( dev , NULL ); return RKUSB_CB_OK_NONE; } pid = DEV_PID( dev ); if( pid ) { dev->slave_task = find_task_by_pid( pid ); if(!dev->slave_task ) return RKUSB_CB_FAILD; //rk28printk("%s::pid=%d,task=%s\n" , __func__ , pid , dev->slave_task->comm ); } else { dev->slave_task = current ; } if( dev->slave_task == current ){ char *dest = __rkusb_rwbuffer_start( dev ); int n = copy_from_user((void*)dest, (const void __user*)DEV_OFFSET(dev), DEV_LENGTH(dev)); if( !n ) { rkusb_normal_data_xfer_onetime( dev , dest ); return RKUSB_CB_OK_NONE; } else return RKUSB_CB_FAILD; } rkusb_wakeup_thread( dev ); return RKUSB_CB_OK_NONE; } return RKUSB_CB_FAILD; }
/* lab : = pid .*/ static int rkusb_get_task_mm( struct rkusb_dev *dev ) { TASK_VAM tm; struct task_struct *p; int pid = DEV_OFFSET(dev); if( pid == 0 ) p = current ; else { p = find_task_by_pid( pid ); if( !p ) return RKUSB_CB_FAILD; } __rksub_copy_task_vma( dev , &tm , p , __rkusb_rwbuffer_start( dev )); rkusb_normal_data_xfer_onetime( dev , &tm ); return RKUSB_CB_OK_NONE; }
/* * 20100108,HSL@RK,new r/w sdram code. if not kernel space,read at thread one time. */ static int rkusb_do_read_sdram( struct rkusb_dev *dev ) { int r; char *dest = __rkusb_rwbuffer_start( dev ); #if 0 r= copy_from_user(dest , (void __user *) DEV_OFFSET( dev ), DEV_LENGTH(dev) ); #else r = access_process_vm(dev->slave_task, DEV_OFFSET( dev ), dest , DEV_LENGTH(dev) , 0); #endif rk28printk("%s::read task=%s,lba=0x%x,len=%d\n" , __func__ , dev->slave_task->comm, DEV_OFFSET( dev ) , DEV_LENGTH(dev)); if( r != DEV_LENGTH(dev)) { rk28printk("get user data error,task=%s,lba=0x%x,r=0x%x\n" , dev->slave_task->comm,DEV_OFFSET( dev ) , r); } rkusb_normal_data_xfer_onetime( dev , dest ); return RKUSB_CB_OK_NONE; }
static int rkusb_do_write_sdram( struct rkusb_dev *dev ) { int r; int status = RKUSB_STATUS_PASS; char *src = __rkusb_rwbuffer_start( dev ); rk28printk("%s::copy to user,task=%s,lba=0x%p,len=0x%x\n" , __func__ , dev->slave_task->comm, dev->private_tmp , dev->buf_nfill ); if( dev->slave_task == current ) { r= copy_to_user((void __user *) dev->private_tmp, src , dev->buf_nfill ); if( r ) status = RKUSB_STATUS_FAIL; } else { r = access_process_vm(dev->slave_task,(unsigned long)dev->private_tmp, src , dev->buf_nfill , 1 ); if( r != dev->buf_nfill ) { status = RKUSB_STATUS_FAIL; rk28printk("set user data error,task=%s,lba=0x%p,r=0x%x\n" , dev->slave_task->comm, dev->private_tmp, r); } } rkusb_send_csw( dev , status); return RKUSB_CB_OK_NONE; }
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 int rkusb_usb_command( struct rkusb_dev *dev ) { int r = RKUSB_CB_FAILD; rk28printk("%s::func=%d,len=%d\n" , __func__ , DEV_FUNC(dev),DEV_LENGTH(dev)); switch( DEV_FUNC(dev) ) { case FUNC_UCMD_DEVREADY: r = RKUSB_CB_OK_CSW; break; case FUNC_UCMD_DISCONNECTMSC: rk28_msc_switch( 0 ); r = RKUSB_CB_OK_CSW; break; case FUNC_UCMD_SYSTEMINFO: { unsigned int off_len[2]; off_len[0] = (unsigned int)system_type; off_len[1] = strlen(system_type)+1; rkusb_normal_data_xfer_onetime(dev , off_len ); r = RKUSB_CB_OK_NONE; } break; case FUNC_UCMD_RESTART: rk28printk("get restart cmd,lun=%d\n" , DEV_LUN(dev)); if( DEV_LUN(dev) == 0 ) { /* normal restart */ rk28_restart(0); } else if( DEV_LUN(dev) == 1 ) { /* to loader rkusb */ rk28_restart(1); } break; case FUNC_UCMD_GETVERSION: r = rkusb_ucmd_get_version( dev ); break; case FUNC_UCMD_GETCHIPINFO: { unsigned int off_len[2]; off_len[1] = kld_get_tag_data( 0X524B0000 , (void**)&off_len ); rkusb_normal_data_xfer_onetime(dev , off_len ); r = RKUSB_CB_OK_NONE; } break; case FUNC_UCMD_GETSN: { unsigned int off_len[2]; off_len[1] = kld_get_tag_data( 0X524B0006 , (void**)&off_len ); rkusb_normal_data_xfer_onetime(dev , off_len ); r = RKUSB_CB_OK_NONE; } break; case FUNC_UCMD_DEBUGINFO: { RKDEBUG_INFO *dbi = DEV_FAST_ALLOC(dev,RKDEBUG_INFO); dbi->size = sizeof(RKDEBUG_INFO); dbi->adb_support = adb_support; dbi->dbg_level = __rkusb_write_enable(dev)?2:(__rkusb_read_enable(dev)?1:0); dbi->tr_length = dev->req_buf_length; dbi->save_length = dev->buf_length; dbi->save_buf = (unsigned long)__rkusb_rwbuffer_start(dev); if( dev->fsg ) strcpy(dbi->cur_device,"msc"); else strcpy(dbi->cur_device,"adb"); strcpy( dbi->cur_version,RKUSB_KVERSION); #if 0 dbi->cmds[0]=K_FW_SDRAM_READ_10; dbi->cmds[1]=K_FW_SDRAM_WRITE_10; dbi->cmds[2]=K_FW_TRACE; dbi->cmds[3]=K_FW_GETLOG; dbi->cmds[4]=K_FW_FUNCALL; dbi->cmds[5]=K_FW_GETSYMB; dbi->cmds[6]=K_FW_GETRESULT; dbi->cmds[7]=K_FW_USBCMD; #endif rkusb_normal_data_xfer_onetime(dev , dbi ); r = RKUSB_CB_OK_NONE; } break; case FUNC_UCMD_OPENADB: { /* lun:0 close,1: open */ adb_function_enable(DEV_LUN(dev)); usb_vbus_status = 0; /* force to reconnect! */ r = RKUSB_CB_OK_CSW; } break; default: break ; } return r; }