problem in registering the device while inserting the kernel module

patel rajendra rdpatel55 at yahoo.co.in
Thu May 21 16:20:42 EST 2009


Hi Members of linuxppc,

 

I'm working on XUPV2P board with Virtex II Pro FPGA device.

 

I written a kernel module for LED device. I got that module run
successfuly on ML403 board having Virtex 4 FPGA.I have not make any
change in my source code for XUP board, because I don't feel any change is required.

 

On XUP board when I run "insmod xilinx_led.ko" command on my target board, I got following message.

 

# insmod xilinx_led.ko 

Oops: kernel access of bad area, sig: 11 [#1] 

PREEMPT 

NIP: d1006190 LR: d1006188 CTR: 00000000 

REGS: c0705db0 TRAP: 0300   Not tainted  (2.6.23xlnx) 

MSR: 00029030 <EE,ME,IR,DR>  CR: 24000024  XER: 00000000 

DEAR: 0000004c, ESR: 00000000 

TASK = c04c63d0[186] 'insmod' THREAD: c0704000 

GPR00: d1006188 c0705e60 c04c63d0 00000000 000000d0 00000001 00000000 c0220ae0 

GPR08: c006c60c 00000000 00000001 c04553f0 026f4bac 100b4260 d1003288 d1007668 

GPR16: d1003288 d1003238 0000fff1 0000fff2 0000004c 00000000 d100762c c003e94c 

GPR24: d1002e02 00000018 d1002000 00000019 d1000000 d1007598 d10077c8 00000000 

NIP [d1006190] xilinx_ml403_led_setup+0x174/0x1dc [xilinx_led] 

LR [d1006188] xilinx_ml403_led_setup+0x16c/0x1dc [xilinx_led] 

Call Trace: 

[c0705e60] [d1006188] xilinx_ml403_led_setup+0x16c/0x1dc [xilinx_led] (unreliable) 

[c0705e90] [c0040be0] sys_init_module+0x120c/0x12f8 

[c0705f40] [c0002c10] ret_from_syscall+0x0/0x3c 

Instruction dump: 

48000819 3d20d100 39297620 913f003c 93bf0040 3c800fc0 60840001 7fe3fb78 

38a00001 48000805 813e0014 7c7f1b78 <80e9004c> 3c60d100 3c80d100 80bc77c8 

   

Note: After above output when I execute "lsmod" command. I observed that led device is tainted. 

   

~ # lsmod 

Module                  Size  Used by    Tainted: G 

xilinx_led              6172  1 

~ # 


 

What I understood from above message is that there is a problem in registering the device in function xilinx_ml403_led_setup( ). 

 

Anyone can help me out to solve this problem?

The source code is given below. 

Rajendra


---------------------------------------Xilinx_led.c---------------------------------------------------------------

#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/slab.h>

#include <linux/fs.h>

#include <linux/errno.h>

#include <linux/types.h>

#include <linux/mm.h>

#include <linux/cdev.h>

#include <linux/proc_fs.h>

#include <linux/fcntl.h>

#include <linux/ioport.h>

#include <linux/interrupt.h>

#include <linux/xilinx_devices.h>

#include <asm/system.h>

#include <asm/io.h>

#include <asm/uaccess.h>



#include "xparameters.h"

#include "xio.h"

#include "xgpio.h"

#include "xgpio_l.h"

#include "xstatus.h"



#include "xbasic_types.h"

/* LED constant */



#define DRIVER_NAME "led"

#define DRIVER_DESCRIPTION "GPIO based 4 bit led peripheral driver"

#define LED_PHY_BASEADDR XPAR_LEDS_4BIT_BASEADDR

#define LED_PHY_HIGHADDR XPAR_LEDS_4BIT_HIGHADDR

#define LED_DEVICE_ID XPAR_LEDS_4BIT_DEVICE_ID

#define LED_MAJOR 252

#define LED_MINOR 1

#define LEDChan 1



XGpio gp_out;



/* Device Structure */



struct led_instance

{

    Xuint32 phy_baseaddr;

    Xuint32 phy_highaddr;

    Xuint32 remap_size;

    Xuint32 virtual_baseaddr;

    u32    device_id;

    struct  cdev *cdev;



    XGpio    gpio;

};



struct led_instance xilinx_ml403_led;



/*Open and Release method */



int led_open(struct inode *inode, struct file *filp)

{

    struct led_instance *dev;



    dev = container_of(inode -> i_cdev, struct led_instance, cdev);

    filp -> private_data = dev;

    return 0;

}



int led_release(struct inode *inode, struct file *filp)

{

    return 0;

}



/* Read Method */



ssize_t led_read(struct file *flip, char __user *buf, size_t count, loff_t *f_pos)

{

    size_t  retval = 0;

    u32    data;



    printk(KERN_INFO "%s: Entering\n\r", __FUNCTION__);



    if(*f_pos >= sizeof(data))

    {

        goto out01;

    }



    if(*f_pos + count >= sizeof(data))

    {

        count = sizeof(data) - *f_pos;

    }



    data = XGpio_DiscreteRead(&gp_out, LEDChan);

    printk(KERN_INFO "data = 0x%08X!\n\r", data);



    if(copy_to_user(buf, &data, count))

    {

        retval = -EFAULT;

        goto out01;

    }

    *f_pos += count;

    retval = count;



out01:    return retval;



}



/* Write Method */

ssize_t led_write(struct file *flip, const char __user *buf, size_t count, loff_t *f_pos)

{

    size_t  retval = 0;

    Xuint32    data;



    printk(KERN_INFO "%s: Entering\n\r", __FUNCTION__);



    if(count < sizeof(data))

    {

        printk("argument to small!\n\r");

        retval = -EINVAL;

        goto out01;

    }

    

    if(*f_pos + count >= sizeof(data))

    {

        count = sizeof(data) - *f_pos;

    }

    if(copy_from_user(&data,buf, count))

    {

        retval = -EFAULT;

        goto out01;

    }

    XGpio_DiscreteWrite(&gp_out,LEDChan,data);

    *f_pos += count;

    retval = count;



out01:    return retval;

}



/* File Operations Structure */



struct file_operations led_fops = {

    

    owner:    THIS_MODULE,

    open:    led_open,

    read:    led_read,

    write:    led_write,

    release:led_release

};



/* Device Registration */

int xilinx_ml403_led_setup(void)

{

    XGpio_Config xgpio_config;

    struct cdev *cdev=0;

    int retval = 0;

    dev_t devno;



    memset(&xilinx_ml403_led, 0, sizeof(struct led_instance));

    

    /* Map the control registers in */

    /* get baseaddress and highaddress */

    xilinx_ml403_led.phy_baseaddr    = LED_PHY_BASEADDR;

    xilinx_ml403_led.remap_size    = LED_PHY_HIGHADDR - LED_PHY_BASEADDR + 1;

    xilinx_ml403_led.device_id    = LED_DEVICE_ID;



    if(!xilinx_ml403_led.phy_baseaddr ||
(xilinx_ml403_led.remap_size - xilinx_ml403_led.phy_baseaddr + 1 <
8))

    {



        printk(KERN_ERR "%s: Couldn't get registers resource\n\r","led");

        retval = -EFAULT;

        goto failed1;

    }    



    if(!request_mem_region(xilinx_ml403_led.phy_baseaddr, xilinx_ml403_led.remap_size, DRIVER_NAME))

    {

        

        printk(KERN_ERR "Couldn't lock
memory region at 0x%08lX\n\r",(unsigned long)
xilinx_ml403_led.phy_baseaddr);

        retval = -EBUSY;

        goto failed2; 



    }



    xilinx_ml403_led.virtual_baseaddr = ioremap(xilinx_ml403_led.phy_baseaddr, xilinx_ml403_led.remap_size);



    

    if(!xilinx_ml403_led.virtual_baseaddr)

    {

        

        printk(KERN_ERR "Couldn't ioremap
memory at 0x%08lX\n\r", (unsigned long) xilinx_ml403_led.phy_baseaddr);

        retval = -EFAULT;

        goto failed3;



    }



    if(XGpio_CfgInitialize(&gp_out, &xgpio_config,xilinx_ml403_led.virtual_baseaddr) != XST_SUCCESS)

    {

        printk(KERN_ERR "%s: Couldn't initialize instance.\n\r","xilinx_led");

        retval = -ENODEV;

        goto failed3;

    }

    XGpio_SetDataDirection(&gp_out, LEDChan , 0x00000000);



    cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL);

    if(!cdev)

    {

        printk(KERN_ERR "%s: Couldn't allocate device private record\n\r","led");

    return -ENOMEM;

    }



    memset(cdev,0,sizeof(struct cdev));



    cdev_init(cdev,&led_fops);

    cdev->owner = THIS_MODULE;

    cdev->ops = &led_fops;

    devno = MKDEV(LED_MAJOR,LED_MINOR);

    retval = cdev_add(cdev,devno,1);



    xilinx_ml403_led.cdev;



    printk(KERN_ERR "%s at 0x%081X mapped to 0x%08X
device:%u,%u\n\r","xilinx_led",xilinx_ml403_led.phy_baseaddr,(unsigned
int) xilinx_ml403_led.virtual_baseaddr,(unsigned
int)MAJOR(xilinx_ml403_led.cdev->dev),(unsigned
int)MINOR(xilinx_ml403_led.cdev->dev));



    failed3:

        iounmap((void *) (xilinx_ml403_led.phy_baseaddr));

        

    failed2:

        release_mem_region(xilinx_ml403_led.phy_baseaddr,xilinx_ml403_led.remap_size);



    failed1:

        return retval;

}



int __init led_init(void)

{

    int retval;

    retval=xilinx_ml403_led_setup();

    if(retval)

        return retval;

    return 0;

}



void __exit led_exit(void)

{

    cdev_del(xilinx_ml403_led.cdev);



    iounmap((void *)(xilinx_ml403_led.virtual_baseaddr));

    release_mem_region(xilinx_ml403_led.phy_baseaddr,xilinx_ml403_led..remap_size);

}



module_init(led_init);

module_exit(led_exit);



MODULE_AUTHOR("SANDEEPANI - SCHOOL OF EMBEDDDED DESIGN");

MODULE_DESCRIPTION(DRIVER_DESCRIPTION);

MODULE_LICENSE("Dual BSD/GPL");








      Explore your hobbies and interests. Go to http://in.promos.yahoo.com/groups/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20090521/fd2871e6/attachment.htm>


More information about the Linuxppc-dev mailing list