Share your knowledge at the LQ Wiki.
Go Back > Forums > Linux Forums > Linux - Software
User Name
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.


  Search this Thread
Old 10-20-2004, 08:51 AM   #1
LQ Newbie
Registered: May 2004
Location: istanbul
Posts: 2

Rep: Reputation: 0
PCI Device Driver

hi all;
I ma writing a device driver for a PCI card. I finished the outline of my module. I can initialize the module, open the card. and reach the driver via ioctl calls. So far so good.
The PCI card has a RAM and some registers on this RAM starting from Base Address-0 . All I need to do is to read and write to these registers.
My code to read and write from/to RAM is as follows:

Static int _ioctl(struct inode *inode,
struct file *filp,
unsigned int ioctl_num,
unsigned long ioctl_param){

unsigned int minor = MINOR(inode->i_rdev);
Device *dv;
if(minor >= device_count){
PDEBUG("Invalid minor number\n");
return -ENODEV;
dv = &devtbl[minor];

unsigned int page_base = 0;
unsigned int offset = 0;
unsigned int region_size = 0;
volatile void *pci_memory_p = NULL;
unsigned int virtual_address = 0;
unsigned int value32=0;


//read from RAM

page_base = dv->BaseAddress & PAGE_MASK;
offset = dv->BaseAddress +CONFIG_REGISTER_OFFSET - page_base;
region_size = offset + 4;

pci_memory_p = ioremap((unsigned int)page_base, region_size);
virtual_address = ((unsigned int) pci_memory_p) + offset;

if (pci_memory_p != NULL) {
value32 = *((volatile unsigned int *)virtual_address);

iounmap((void *)pci_memory_p);

}//end of if-else

copy_to_user((unsigned int *)ioctl_param,&value32, sizeof(value32));


//writeto RAM

page_base = dv->BaseAddress & PAGE_MASK;
offset = dv->BaseAddress + CONFIG_REGISTER_OFFSET - page_base;
region_size = offset + 4;

pci_memory_p = ioremap((unsigned int)page_base, region_size);
virtual_address = ((unsigned int) pci_memory_p) + offset;

if (pci_memory_p != NULL) { // map OK?
copy_from_user(&value32,(unsigned int *)ioctl_param,sizeof(value32));

*((volatile unsigned int *)virtual_address) =value32;

iounmap((void *)pci_memory_p);



}//end of switch

}//end of ioctl


in my test program I send 0x123456787 to ioctl method to write to RAM . Inside ioctl method after writing to virtual address, I tried to read from the same virtual address but the value that I read is 0xFFFC5678.
Somehow Upper 13 bits of 32 bits data is always set to 1. the remaining 19 bit are the data that I wrote to RAM.
when I write 0x00005678 to RAM, I read 0xFFF85678
when I write 0x000E5678 to RAM, I read 0xFFFE5678

What could be the reason for this. Is there any other way to read and write to memory space of PCI card.
One more little question: what is the difference between readl, readw, readb?




Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Help with converting a userspace PCI program to a Device Driver cstrask Linux - Hardware 0 10-31-2005 09:07 PM
From PCI device ID to ifconfg: how does it work? cconvey Linux - Networking 1 10-26-2003 12:20 PM
device to simulate physical memory with PCI device kevinsung Linux - Software 1 12-14-2002 10:11 AM
iPAQ 10/100 fast Ethernet PCI card device driver philipsyyy Linux - Hardware 4 10-07-2002 05:32 PM
pci: bios reporting unknown device thegman54 Linux - Networking 0 08-05-2001 02:04 PM > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 08:06 AM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration