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