Hello all,

I modified a kernel module ( in a ARM board from Digi - www.digi.com ) to use procfs, when I pass data to this device using proc file using shell commands works fine ( cat filebuff > /proc/ns9360_fb/screen_1 filebuff about 600KB size ), but when I use an write() call from user-space program this doesn't works (after open() OK), when debugging I found that the function copy_from_user() cannot transfer 0 byte to buffer returning the same size of passed to it.

Why this occurs ?
Theres some way to write in procfs files using write() call ?

Thanks for any help

Flavio Alberto Lopes Soares

PS: Follow the procfs write function in driver

int ns9xxxfb_write_func_procfs(struct file* file, const char* buffer, unsigned long count, void* data)
{
        struct  proc_fb_data *ptr_proc_fb_data;
        struct auxiliar_fb *ptr_aux_fb;
        int res;
        unsigned char n;
        ptr_proc_fb_data = (struct proc_fb_data *)data;
        ptr_aux_fb = (struct auxiliar_fb *)ptr_proc_fb_data->data;

        printk("%d BYTES\n", count);
        switch(ptr_proc_fb_data->id){
                case PROC_MAIN_DIR:
                        res = count;            
                break;
                case PROC_SCR_1:
                        printk(KERN_WARNING DRIVER_NAME "NA TELA 1\n");
                        if(count <= info.fb.fix.smem_len){
                                //res = count;
                                n = 0;
                        }
                        else{
                                printk("ERRO TELA 1\n");
                                res = -ENOMEM;
                        }
                break;
                case PROC_SCR_2:
                        printk(KERN_WARNING DRIVER_NAME "NA TELA 2\n");
                        if(count <= info.fb.fix.smem_len){
                                //res = count;
                                n = 1;
                        }
                        else{
                                printk("ERRO TELA 2\n");
                                res = -ENOMEM;  
                        }               
                break;
                case PROC_CTRL:
                {
                        struct fb_fix_screeninfo *fixptr;
                        copy_from_user((void *)&proc_cmd, (const void *)buffer, 
1);
                        res = 1;
                        switch(proc_cmd){
                                case PROC_CMD_SWITCH_SCR_ORIG:
                                        /*Switch one framebuffer with other*/
                                        fixptr = &fix_orig;
                                        info.fb.screen_base = screen_base_orig;
                                        ns9xxxfb_switch_fb(*fixptr);            
        
                                break;
                                case PROC_CMD_SWITCH_SCR_1:
                                        /*Switch one framebuffer with other*/
                                        fixptr = 
&info_fb_dbbuff[0].info_fb.fb.fix; 
                                        info.fb.screen_base = 
info_fb_dbbuff[0].info_fb.fb.screen_base;
                                        ns9xxxfb_switch_fb(*fixptr);
                                break;
                                case PROC_CMD_SWITCH_SCR_2:
                                        /*Switch one framebuffer with other*/
                                        fixptr = 
&info_fb_dbbuff[1].info_fb.fb.fix;
                                        info.fb.screen_base = 
info_fb_dbbuff[1].info_fb.fb.screen_base;
                                        ns9xxxfb_switch_fb(*fixptr);
                                break;
                                case PROC_CMD_SWITCH_LCD_ON:
                                        LCD_CONTROL = (lcd_active->control |= 
LCD_CONTROL_EN );
                                break;
                                case PROC_CMD_SWITCH_LCD_OFF:
                                        LCD_CONTROL = (lcd_active->control &= 
~LCD_CONTROL_EN);                          
                                break;
                                default:
printk(KERN_WARNING DRIVER_NAME ": Unknown control command : %c\n", proc_cmd);
                                        res = -ENOSYS;
                        }
                }       
                break;
        }

        if(ptr_proc_fb_data->id != PROC_CTRL && res != -ENOMEM){
                unsigned long remain = 0;
                long pos = 0;

                pos = ptr_aux_fb->datasize - ptr_aux_fb->datacopyremain;
                pos = (pos < 0) ? 0 : pos;
remain = copy_from_user((void *)ptr_aux_fb->info_fb.fb.screen_base + pos, (const void *)buffer, count);

                printk("SOBROU : %ld\n", remain);
                res = count;
                ptr_aux_fb->datacopyremain -= (count + remain);

                if(ptr_aux_fb->datacopyremain <= 0){
                        ptr_aux_fb->datacopyremain = ptr_aux_fb->datasize;      
  
                
                }                                       
                //printk(DRIVER_NAME ": Copiando %d bytes\n", count);
                //printk(DRIVER_NAME ": Faltaram %d bytes\n", remain);
        }
        
        return res;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-newbie" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.linux-learn.org/faqs

Reply via email to