* New PCI Device Driver
@ 2002-10-07 17:24 Patrick Jennings
2002-10-07 19:58 ` Alan Cox
0 siblings, 1 reply; 3+ messages in thread
From: Patrick Jennings @ 2002-10-07 17:24 UTC (permalink / raw)
To: LKML
Hello All:
I have been tasked with writing a driver for my companies digital radio.
The card has 16K of PCI space at BAR0. I need to memory map this into user
space, and provide DMA and isr handling. First things first i want to get
the mapping working. When i run the code below after inserting the module
i seg. fault. I know this is what happens when engineers have to write
code, but can someone point me in the right direction?
Thanks!!!
/Patrick
+========================================================+
Patrick Jennings | jennings@red-river.com
Red River | Direct Phone (972) 671-9636
Radio Products Group | Main Phone (972) 671-9570
797 North Grove Road | Fax (972) 671-9572
Suite 101 | www.red-river.com
Richardson,TX 75081 |
[driver.c]
#define VEND_ID 0x1171
#define DEV_ID 0xA050
#define CARD_NAME "Model 300"
#define M300_MAJOR 240
int redriver_init_module(void)
{
int status;
struct pci_dev *pcidev=NULL;
unsigned long databuf;
printk("<1>Red River Module Init\n");
SET_MODULE_OWNER(&redriver_fops);
pcidev = pci_find_device(VEND_ID, DEV_ID, pcidev);
if(pcidev == NULL)
{
printk("<1>Couldn't find a red river device\n");
return ENODEV;
}
status = pci_enable_device(pcidev);
if(status)
{
printk("<1>Error enabling device\n");
return(status);
}
status = register_chrdev(M300_MAJOR, CARD_NAME, &redriver_fops);
if(status)
{
printk("<1>Couldn't register najor number for %s\n", CARD_NAME);
}
redriver_device_data.io_base_start = (unsigned long
*)pci_resource_start(pcidev, 0);
redriver_device_data.io_base_stop = (unsigned long
*)pci_resource_end(pcidev, 0);
printk("M300:IO_BASE: 0x%x\n", redriver_device_data.io_base_start);
databuf = *(redriver_device_data.io_base_start+(0x590));
printk("Firm rev register 0x%x\n",databuf);
return 0;
}
int redriver_remap_mmap(struct file * flip, struct vm_area_struct *vma)
{
vma->vm_flags |= (VM_RESERVED | VM_IO);
if(remap_page_range(vma->vm_start, redriver_device_data.io_base_start,
vma->vm_end-vma->vm_start,vma->vm_page_prot))
return -EAGAIN;
vma->vm_ops = &redriver_remap_vm_ops;
redriver_vma_open(vma);
return 0;
}
module_init(redriver_init_module);
module_exit(redriver_cleanup_module);
[testprog.c]
int main(void)
{
int fd;
unsigned long *vadr;
unsigned long read_data;
printf("%s\n",PROG_NAME);
printf("%s\n",__DATE__);
fd = open("/dev/model300_0", O_RDWR);
if(fd == -1)
{
printf("Error opening device\n");
return(-1);
}
else
{
printf("Device opend OK\n");
}
vadr = mmap(NULL, 0x, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(vadr)
{
printf("Error opening memory!\n");
exit(-1);
}
read_data = *(vadr+0x590/4) //Read 0x590 firm reg register
printf("Data is 0x%x\n",read_data);
close(fd);
return(0);
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: New PCI Device Driver
2002-10-07 17:24 New PCI Device Driver Patrick Jennings
@ 2002-10-07 19:58 ` Alan Cox
2002-10-07 20:01 ` Alan Cox
0 siblings, 1 reply; 3+ messages in thread
From: Alan Cox @ 2002-10-07 19:58 UTC (permalink / raw)
To: Patrick Jennings; +Cc: LKML
On Mon, 2002-10-07 at 18:24, Patrick Jennings wrote:
> I have been tasked with writing a driver for my companies digital radio.
> The card has 16K of PCI space at BAR0. I need to memory map this into user
> space, and provide DMA and isr handling. First things first i want to get
> the mapping working. When i run the code below after inserting the module
> i seg. fault. I know this is what happens when engineers have to write
> code, but can someone point me in the right direction?
First things I'd pick on are the obvious ones - we have headers defining
KERN_ERR etc as <1> so use them 8)
Second you probably want to use the pci_module_init api then multiple
cards will basically just work, cardbus will just work and even hotplug
should come for free.
Beyond that you get the pci resources correctly, you enable the device
first as you should. You then ruin it all by poking around directly into
I/O space you have not mapped.
The kernel isn't running in physical space, and on other platforms it
gets even more exciting as to what goes on. Its all abstracted do
addr = ioremap(io_base_start, len);
databuf = read(addr + 0x590);
Finally note that we have a radio interface layer as part of
video4linux. Other than some basic tuning ioctls it probably has little
in common with digital radio (assuming you mean something like
Eureka-147 (aka DAB) rather than digital tuner/mixer for analogue
radio.It would nice to make use of that API and extend it logically if
you want to get a driver into the base kernel eventually.
Alan
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: New PCI Device Driver
2002-10-07 19:58 ` Alan Cox
@ 2002-10-07 20:01 ` Alan Cox
0 siblings, 0 replies; 3+ messages in thread
From: Alan Cox @ 2002-10-07 20:01 UTC (permalink / raw)
To: Alan Cox; +Cc: Patrick Jennings, LKML
On Mon, 2002-10-07 at 20:58, Alan Cox wrote:
>
> addr = ioremap(io_base_start, len);
> databuf = read(addr + 0x590);
>
Should be readb (the functions are readb / readw / readl / writeb /
writew / writel)
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2002-10-07 19:46 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-07 17:24 New PCI Device Driver Patrick Jennings
2002-10-07 19:58 ` Alan Cox
2002-10-07 20:01 ` Alan Cox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®