Help with converting a userspace PCI program to a Device Driver
I am trying to convert a userspace program to a device driver.
My device driver returns an address to the PCI address space, but it is not working.
I need the variable (void *) base to be the pointer to the start of the PCI device's memory(bar [2]).
Any advice will be much appreciated.
Thank you in advance
/*****************************
WORKING USER SPACE PROGRAM
*****************************/
u16 * pciOpen (int bus_num, int dev_num, int func_num)
{
u16 * pci_mem_ptr = NULL;
int bar[6];
struct pci_access *pci_acc; /* pointer to all PCI devices */
struct pci_dev *config_space = NULL; /* pointer to the PCI device that will be configered */
/* Check IO permissions to be able to open /dev/mem */
if (iopl (3))
{
printf ("Cannot get I/O permissions (being root helps)\n");
return ((u16 *)0);
}
/* pci_acc holds info on all the PCI devices */
pci_acc = pci_alloc (); /* Allocate mem for pci_acc */
pci_init (pci_acc);
pci_scan_bus (pci_acc);
/* Pointer to *our* device */
config_space = pci_get_dev (pci_acc, 0, bus_num, dev_num, func_num);
/* Grab all of the info on our device from the pci_acc structure */
pci_fill_info(config_space, PCI_FILL_IDENT|PCI_FILL_IRQ|PCI_FILL_BASES|
PCI_FILL_ROM_BASE|PCI_FILL_SIZES|PCI_FILL_RESCAN );
/* Get the relevant address pointer */
bar[2] = (unsigned)config_space->base_addr[2] & PCI_BASE_ADDRESS_MEM_MASK;
printf("Base address 2 is 0x%x\n",bar[2]);
/* Open the raw memory */
fd = open ("/dev/mem", O_RDWR);
/* MMAP the PCI memory we want */
pci_mem_ptr = (u16 *)mmap (NULL, _PCI_MMAP_SIZE, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, (off_t)bar[2]);
if ((int)pci_mem_ptr == -1)
{
printf("Unable to mmap: Error %d=\"%s\"\n", errno, strerror(errno));
return ((u16 *)0);
}
printf("The base address is 0x%lx\n",pci_mem_ptr);
return (pci_mem_ptr);
}
/******************************
MY NOT WORKING DEVICE DRIVER
******************************/
static int init(void)
{
major=register_chrdev(0, DEVICE_NAME, &fops);
if (major<0){
printk(KERN_ALERT "Registration failed\n");
}else{
printk(KERN_ALERT "Registered with major number %d\n",major);
}
pdev = pci_get_device(VENDOR_ID,DEVICE_ID, NULL);
pci_enable_device(pdev);
unsigned long start = pci_resource_start(pdev,2);
unsigned long length = pci_resource_len(pdev,2);
printk(KERN_ALERT "Requesting Region\n");
if(pci_request_region(pdev,2,"SONNET")){
printk(KERN_ALERT "Could not request region\n");
}
base = pci_iomap(pdev,2,length);
if(!base)
printk(KERN_ALERT "Unable to pci_iomap\n");
printk(KERN_ALERT "Base is 0x%llx\n",base);
if(pdev){
printk(KERN_ALERT "FOUND SONET CARD\n");
printk(KERN_ALERT "IRQ IN USE %d\n",(unsigned int) pdev->irq);
printk(KERN_ALERT "Base Address 2 starts at 0x%lx\n",start);
printk(KERN_ALERT "Base Address 2 ends at 0x%lx\n",start+length);
printk(KERN_ALERT "Base Address 2 length is 0x%lx\n",length);
}else{
printk(KERN_ALERT "NO CARD FOUND\n");
}
return 0;
}
Last edited by cstrask; 10-31-2005 at 09:11 PM.
|