Results 1 to 1 of 1
I have a wireless network card over PCMCIA....i need to just access
the registers of this card and pass this register details to the user
application.Since i will not connect ...
- 06-24-2007 #1Just Joined!
- Join Date
- Jun 2007
- Posts
- 1
character driver over PCI
I have a wireless network card over PCMCIA....i need to just access
the registers of this card and pass this register details to the user
application.Since i will not connect to the network at this stage i
preferred bypassing the network stack.Hence instead of a network
driver i went ahead writing a character driver.
Once the device opened i made a readl call to read the mapped
memory..This fails..It gives me a segmentation fault.....If i call
readl in the probe function it works fine and reads the memory at that
location..However this call fails in open..What can be the reason...
Have i proceeded the right way....Are there any additional things to
be set..Am working on linux 2.6 kernel
Attached below is my prog
#define _KERNEL_
//#include <linux/mod_devicetable.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
/*-----------------------------------------------------------------------------* FUNCTION DECLARATION FOR CHARACTER DRIVER
------------------------------------------------------------------------------*/
int ath_open
(struct inode *inode ,struct file *filp);
int ath_release
(struct inode *inode , struct file *filp);
/*Structure that defines the common file access functions*/
static struct file_operations ath_fops={
open:ath_open,
release:ath_release,
ioctl:ath_ioctl
};
/*Driver Global variables*/
/*Major number*/
int ath_major = 75;
unsigned long mem;
/*PCI device ID table*/
static struct pci_device_id test_pci_id_table[] __devinitdata = {
{ 0x168c, 0x0007, PCI_ANY_ID, PCI_ANY_ID },
{ 0x168c, 0x0012, PCI_ANY_ID, PCI_ANY_ID },
{ 0x168c, 0x0013, PCI_ANY_ID, PCI_ANY_ID },
{ 0xa727, 0x0013, PCI_ANY_ID, PCI_ANY_ID }, /* 3com */
{ 0x10b7, 0x0013, PCI_ANY_ID, PCI_ANY_ID }, /* 3com 3CRDAG675 */
{ 0x168c, 0x1014, PCI_ANY_ID, PCI_ANY_ID }, /* IBM minipci 5212 */
{ 0x168c, 0x0015, PCI_ANY_ID, PCI_ANY_ID },
{ 0x168c, 0x0016, PCI_ANY_ID, PCI_ANY_ID },
{ 0x168c, 0x0017, PCI_ANY_ID, PCI_ANY_ID },
{ 0x168c, 0x0018, PCI_ANY_ID, PCI_ANY_ID },
{ 0x168c, 0x0019, PCI_ANY_ID, PCI_ANY_ID },
{ 0x168c, 0x001a, PCI_ANY_ID, PCI_ANY_ID },
{ 0 }
};
static int
test_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
u_int8_t csz;
u_int32_t val;
unsigned long phymem;
int i=0,result;
if (pci_enable_device(pdev))
printk("device not enabled\n:");
//return (-EIO);
pci_set_master(pdev);
phymem = pci_resource_start(pdev, 0);
if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "test_pci")) {
printk(KERN_ERR "test_pci: cannot reserve PCI memory region\n");
goto bad;
}
mem = (unsigned long) ioremap(phymem, pci_resource_len(pdev, 0));
if (!mem) {
printk(KERN_ERR "test_pci: cannot remap PCI memory region\n") ;
goto bad1;
}
/*Registering the character driver*/
result=register_chrdev(ath_major,"atherosdev",&ath _fops);
if (result<0)
{
printk("character dev cannot obtain major number\n");
}
else
printk("%d\n",result);
bad2:
iounmap((void *) mem);
bad1:
release_mem_region(phymem, pci_resource_len(pdev, 0));
bad:
pci_disable_device(pdev);
return (-ENODEV);
return 0;
}
int ath_open(struct inode *inode,struct file *filp)
{
printk("success\n");
readl(mem);
return 0;
}
int ath_release(struct inode *inode, struct file *filp)
{
return 0;
}
static void
test_pci_remove(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
iounmap((void *) dev->mem_start);
release_mem_region(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
pci_disable_device(pdev);
free_netdev(dev);
}
MODULE_DEVICE_TABLE(pci, test_pci_id_table);
static struct pci_driver test_pci_drv_id = {
.name = "test_pci",
.id_table = test_pci_id_table,
.probe = test_pci_probe,
.remove = test_pci_remove,
/* Linux 2.4.6 has save_state and enable_wake that are not used here */
};
/*
* Module glue.
*/
static char *version = "1.0";
static char *dev_info = "test_pci";
MODULE_AUTHOR("TCS, tubelight");
MODULE_DESCRIPTION("Support for PCI device");
#ifdef MODULE_VERSION
MODULE_VERSION("1.0");
#endif
MODULE_SUPPORTED_DEVICE("PCI cards");
#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL");
#endif
static int __init
init_test_pci(void)
{
printk("<1> %s: %s\n", dev_info, version);
if (pci_register_driver(&test_pci_drv_id) < 0) {
printk("test_pci: No devices found, driver not installed.\n");
return (-ENODEV);
}
return (0);
}
module_init(init_test_pci);
static void __exit
exit_test_pci(void)
{
unregister_chrdev(ath_major,"atherosdev");
printk("character driver unloaded");
pci_unregister_driver(&test_pci_drv_id);
printk("<1> %s: driver unloaded\n", dev_info);
}
module_exit(exit_test_pci);
the user space program is
#include <stdio.h>
#include <unistd.h>
#include <asm/ioctl.h>
#include <sys/ioctl.h>
int main()
{
int ATHEROSDEV;
int ret;
/*Opening the device port*/
ATHEROSDEV=open("/dev/atherosdev","wr");
if(ATHEROSDEV!=0)
//printf("The device is open");
printf("%d\n",ATHEROSDEV);
close(ATHEROSDEV);
printf("device closed");
}


Reply With Quote