Exemple #1
0
static int rkusb_do_task_cmd( struct rkusb_dev *dev )
{
        switch( DEV_FUNC(dev )) {
        case FUNC_TASKF_PING:
                rkusb_send_csw( dev , RKUSB_STATUS_PASS );
                break;
        default:
                return RKUSB_CB_FAILD;
        }
        return RKUSB_CB_OK_NONE;
}
Exemple #2
0
/*
 * call at main thread.
 */
static int rkusb_file_path( struct rkusb_dev *dev )
{
        FILE_INFO               *fi = (FILE_INFO*)dev->private_tmp;
        struct file                *fp;
        struct inode	        *inode = NULL;
        int                             flags ;
        if( FI_WRITE(fi) ) { /* write */
                flags = O_TRUNC|O_CREAT|O_WRONLY;
        } else {
                flags = O_RDONLY;
        }
        fp = filp_open(fi->file_path , flags , (fi->mod&0777) );
        rk28printk("%s::open file %s ,rw=0x%x,mod=0%o\n" , __func__ , fi->file_path , fi->rw , fi->mod );
        if (IS_ERR(fp)) {
                fi->error = (int)fp;
        	printk("%s::unable to open file: %s,ret=%d\n",__func__ , fi->file_path , fi->error );
        	goto failed;
        }
        if( !FI_WRITE(fi) )  {  /* file read ,get file size */
                inode = fp->f_path.dentry->d_inode;
                if( !inode || !S_ISREG( inode->i_mode ) ) {
                        fi->error = -EINVAL;
                        fput( fp );
                        goto failed;
                }
                fi->mod = inode->i_mode;
                fi->file_size = (unsigned long)i_size_read(inode);
                /* 20100115,HSL@RK,for sysfs,procfs ,the size will be zero or not right */
                if( !fi->file_size && (!strncmp(fi->file_path,"/proc/" , 6)||!strncmp(fi->file_path,"/sys/" , 5))) {
                        //fi->mod |= FILE_MOD_TREAT;
                        fi->file_size = PAGE_SIZE; 
                }
        }
        fi->file = fp;
        rkusb_send_csw( dev , RKUSB_STATUS_PASS );
        return 0;
failed: 
        rkusb_send_csw( dev , RKUSB_STATUS_FAIL );
        return -1;
}
Exemple #3
0
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;
}
Exemple #4
0
static int rkusb_do_thread_cmd( struct rkusb_dev *dev )
{
        rk28printk("rkusb thread cmd = 0x%x,func=0x%x,len=%d\n" , 
            DEV_CMD(dev),DEV_FUNC(dev) , DEV_LENGTH(dev));
        switch( DEV_CMD(dev)) {
        #if RKUSB_XFILE
        case K_FW_XFERFILE:
                {
                        FILE_INFO               *fi = rkusb_xfer_cmd_valid( dev );
                        if( !fi ) {
                                rk28printk("invalid FILE_INFO for K_FW_XFERFILE[0x%x]\n" , K_FW_XFERFILE );
                                break;
                        }
                        switch( DEV_FUNC(dev )) {
                        case FUNC_XFER_FILE_PATH:
                                rkusb_file_path( dev );
                                break;
                        case FUNC_RFILE_DATA:
                        case FUNC_WFILE_DATA:
                                rkusb_xfer_file_task( dev );
                                break;
                        default:
                                break;
                        }
                        if( fi->error )
                                rkusb_xfer_free_fi( dev );
                }
                break;
        #endif /* RKUSB_XFILE */
        case K_FW_TASKFUN:
                rkusb_do_task_cmd( dev );
                break;
        case K_FW_SDRAM_READ_10:
                rkusb_do_read_sdram( dev );
                break;
        case K_FW_SDRAM_WRITE_10:
                rkusb_do_write_sdram( dev );
                break;
        case K_FW_FUNCALL:
                rkusb_do_func_call( dev );
                break;
         case K_FW_USBCMD : 
                if(FUNC_UCMD_RKUSBVER== DEV_FUNC(dev ) && 
                    (DEV_OFFSET(dev) == ECC_SWITCH_MSC || DEV_OFFSET(dev) == ECC_RESET) ) {
                        char cmd[32];
                        char *p=(char *)DEV_INREQ_BUF(dev);
                        strncpy( cmd , p , sizeof(cmd) );
                        rkusb_send_csw( dev , RKUSB_STATUS_PASS );
        		  mdelay(10);
                        sys_sync();
        		  kernel_restart( cmd );
		  } else {
		         rkusb_send_csw( dev , RKUSB_STATUS_FAIL );
		  }
		  break;
        default:
                return -ENOTSUPP;
                break;
        }
        return 0;
}
Exemple #5
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;
}
Exemple #6
0
static int rkusb_command( struct rkusb_dev *dev )
{
        int r= RKUSB_CB_FAILD;
        //dev->cb.DataTransferLength = __be32_to_cpu( dev->cb.DataTransferLength );
        //dev->cb.Lba = __be32_to_cpu( dev->cb.Lba );
        //dev->cb.pid = __be16_to_cpu( dev->cb.pid );

        rkusb_print_cb( dev );
        if( DEV_LENGTH(dev) > dev->req_buf_length ){
                rk28printk("data length[0x%x] > limit[0x%x]\n" , DEV_LENGTH(dev),dev->req_buf_length);
                DEV_LENGTH(dev) = dev->req_buf_length;
        }
        //dev->thread_task->mm = NULL;
        dev->slave_task = NULL;
        switch ( DEV_CMD(dev) )
        {
        case K_FW_GETRESULT:
                r = rkusb_get_lastcmd_result( dev );
                break;
        case K_FW_GETLOG:				
                r = rkusb_get_log( dev );
                break;
        case K_FW_SETLOG:				
                r = rkusb_set_log( dev );
                break;
        case K_FW_TRACE:
               r = rkusb_do_trace( dev );
               break;
        case K_FW_USBCMD:
               r = rkusb_usb_command( dev );
               break;
        case K_FW_XFERFILE:
                r = rkusb_do_xfer_file( dev );
                break;
        case K_FW_FUNCALL:
                r = rkusb_function_call( dev );
                break;
        case K_FW_SDRAM_READ_10:
                r = rkusb_read_sdram( dev );
                break;
        case K_FW_SDRAM_WRITE_10:
                r = rkusb_write_sdram( dev );
                break;
        case K_FW_GETSYMB:
                r = rkusb_get_symbol( dev );
                break;
        case K_FW_TASKFUN:
                r = rkusb_task_cmd( dev );
                break;
        default:
                return RKUSB_NOT_HANDLED;
        } 
        if( RKUSB_CB_FAILD == r ) {
                /* 20100330,HSL@RK,for failed cmd,must handle it */
                DEV_OFFSET(dev) = 0;
                rkusb_normal_data_xfer( dev , rkusb_failed_cb ); 
                return 0 ; /* RKUSB_NOT_HANDLED;*/
        } else if( RKUSB_CB_OK_CSW == r )
                rkusb_send_csw( dev , RKUSB_STATUS_PASS );
        else if( RKUSB_CB_FAILD_CSW == r )
                rkusb_send_csw( dev , RKUSB_STATUS_FAIL);
        return 0;
}