I am having difficulties converting a user space program to a kernel character device. For some reason (possible poor programming on my part) ioremap is not pointing to the equivalent address as the user level program. I am running FC3 with kernel 2.6.9. Please help.
This is the working userspace. It returns the correct address after mmap'ing /dev/mem
******************************************************************************************
THIS WORKS!
******************************************************************************************
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 */
iopl (3)
/* 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;
/* 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]);
return (pci_mem_ptr);
}
**********************************************************************************************
Below, is my PCI device probe that results in an address that is not
equivalent to the userspace program above. The data at the address
returned by the working program is diffrent from the data returned
by my device driver.
This code does not work. Help me make the code above and below equivalent.
**********************************************************************************************
static char * probe(void)
{
struct pci_dev *pdev;
pdev = pci_get_device(VENDOR_ID,DEVICE_ID, NULL);
pci_enable_device(pdev);
unsigned long length = pci_resource_len(pdev,2);
pci_request_region(pdev,2,"SONET);
char * base;
return pci_iomap(pdev,2,length);
}
I'm still a kernelnewbie, but
I'm still a kernelnewbie, but I do notice that you don't check the
return values of function calls, in both of the functions above.
It's possible that one of the fucntions fail and the rest of the
program does not function as you intended it to as a result.