fseek - llseek not behaving in kernel driver -


i have been writing lcd kernel driver lcd module. going well, can write display, create /dev/lcd node can write , display results on screen. thought using llseek fops callback position cursor on lcd good, way use rewind fseek etc. not working expected, below summary of seeing:

the relevant lines of code driver side are:

loff_t lcd_llseek(struct file *filp, loff_t off, int whence) {     switch (whence) {         case 0: // seek_set             if (off > 4*line_length || off < 0) {                 printk(kern_err "unsupported seek_set offset %llx\n", off);                 return -einval;             }             lcd_gotoxy(&lcd, off, 0, whence_abs);             break;         case 1: // seek_cur              if (off > 4*line_length || off < -4*line_length) {                 printk(kern_err "unsupported seek_cur offset %llx\n", off);                 return -einval;             }             lcd_gotoxy(&lcd, off, 0, whence_rel);             break;         case 2: // seek_end (not supported, hence fall though)         default:             // how did here !             printk(kern_err "unsupported seek operation\n");             return -einval;     }     filp->f_pos = lcd.pos;     printk(kern_info "lcd_llseek complete\n");     return lcd.pos; }  int lcd_open(struct inode *inode, struct file *filp) {     if (!atomic_dec_and_test(&lcd_available)) {         atomic_inc(&lcd_available);         return -ebusy; // open     }      return 0; }  static struct file_operations fops = {     .owner = this_module,     .write = lcd_write,     .llseek = lcd_llseek,     .open = lcd_open,     .release = lcd_release, };  int lcd_init(void) {     ...      // allocate new dev number (this can dynamic or     // static if passed in module param)     if (major) {         devno = mkdev(major, 0);         ret = register_chrdev_region(devno, 1, module_name);     } else {         ret = alloc_chrdev_region(&devno, 0, 1, module_name);         major = major(devno);     }     if (ret < 0) {         printk(kern_err "alloc_chrdev_region failed\n");         goto fail;     }      // create dummy class lcd     cl = class_create(this_module, "lcd");     if (is_err(cl)) {         printk(kern_err "class_simple_create class lcd failed\n");         goto fail1;     }      // create cdev interface     cdev_init(&cdev, &fops);     cdev.owner = this_module;     ret = cdev_add(&cdev, devno, 1);     if (ret) {         printk(kern_err "cdev_add failed\n");         goto fail2;     }      // create /sys/lcd/fplcd/dev udev add our device /dev/fplcd     device = device_create(cl, null, devno, null, "lcd");     if (is_err(device)) {         printk(kern_err "device_create fplcd failed\n");         goto fail3;     }     ... } 

to test lseek call have following unit test:

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #define log(msg, ...) fprintf(stdout, __file__ ":%s():[%d]:" msg, __func__, __line__, __va_args__)  int lcd;  void test(void) {     int k;      // lot of hello's     log("hello world test\n",1);     if (lseek(lcd, 0, seek_cur) == -1) {         log("failed seek\n", 1);     } }  int main(int argc, char **argv) {     lcd = open("/dev/lcd", o_wronly);     if (lcd == -1) {         perror("unable open lcd");         exit(exit_failure);     }      test();      close(lcd);     return 0; } 

the files cross compiled so:

~/workspace/ts4x00/lcd-module$ cat makefile  obj-m += fls_lcd.o  all:     make -c $(kpath) m=$(pwd) modules     $(cross_compile)gcc -g -fpic $(cflags) lcd_unit_test.c -o lcd_unit_test  clean:     make -c $(kpath) m=$(pwd) clean     rm -rf lcd_unit_test ~/workspace/ts4x00/lcd-module$ make cflags+="-march=armv4 -ffunction-sections -fdata-sections" make -c ~/workspace/ts4x00/linux-2.6.29 m=~/workspace/ts4x00/lcd-module modules make[1]: entering directory `~/workspace/ts4x00/linux-2.6.29'   cc [m]  ~/workspace/ts4x00/lcd-module/fls_lcd.o ~/workspace/ts4x00/lcd-module/fls_lcd.c:443: warning: 'lcd_entry_mode' defined not used   building modules, stage 2.   modpost 1 modules   cc      ~/workspace/ts4x00/lcd-module/fls_lcd.mod.o   ld [m]  ~/workspace/ts4x00/lcd-module/fls_lcd.ko make[1]: leaving directory `~/workspace/ts4x00/linux-2.6.29' ~/workspace/ts4x00/arm-2008q3/bin/arm-none-linux-gnueabi-gcc -g -fpic -march=armv4 -ffunction-sections -fdata-sections lcd_unit_test.c -o lcd_unit_test 

this output of running driver unit test is:

root@ts4700:~/devel# insmod ./fls_lcd.ko  root@ts4700:~/devel# ./lcd_unit_test  lcd_unit_test.c:test():[61]:hello world test lcd_unit_test.c:test():[63]:failed seek root@ts4700:~/devel# dmesg fls lcd driver started unsupported seek_set offset bf0a573c 

i cannot figure out why parameters being mucked badly on kernel side, tried seek_cur position 0 , in driver seek_set (no matter put in unit test) , crazy big number off?

does know going on please ?

btw compiling kernel 2.6.29 on arm dev kit

ok sorry guys after trying debug last night comes down compiling against wrong kernel (i had kpath left different config of kernel on sdcard)

sorry wasting everyones time, if seeing looks crazy stack in kernel driver might set them straight.

oh , :)


Comments

Popular posts from this blog

image - ClassNotFoundException when add a prebuilt apk into system.img in android -

I need to import mysql 5.1 to 5.5? -

Java, Hibernate, MySQL - store UTC date-time -