[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Help needed for Linux driver
>>>>> "Andreas" == Andreas Heiner <andreas.heiner@de.bosch.com> writes:
Andreas> Hello, I need some help for my current project. Maybe there is
Andreas> someone who have had the same problem and can give me some hot
Andreas> links or sample codes. The problem is the following:
Andreas> We have a self designed PCI board running under WinNT. The
Andreas> driver was really hard work. Now we are moving to Linux and we
Andreas> hope that we now get a really good operating system. I thing we
Andreas> have the same problems which each driver developer has:
Andreas> 1. What is the right way to found my PCI card inside the system
Andreas> and to read out the BAR's ?
Generally, the best way is to take a look at existing code. That's the
advantage of source released OSs. But, I'll summerize for you:
You should have a "probe" routine that gets called by your module init,
or by something like drivers/net/Space.c. (This is from a driver that
was originally drivers/net/lance32.c)
You should do:
if (pci_present()) {
unsigned char pci_bus, pci_device_fn;
int pci_index;
for(pci_index=0; pci_index < 0xff; pci_index++) {
u16 vendor, device, pci_command;
u16 svendor,sdevice;
int chip_idx;
if(pcibios_find_class(PCI_CLASS_NETWORK_ETHERNET << 8,
pci_index,
&pci_bus,
&pci_device_fn) != PCIBIOS_SUCCESSFUL)
break;
pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, &vendor);
pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, &device);
pcibios_read_config_word(pci_bus, pci_device_fn, PCI_SUBSYSTEM_VENDOR_ID, &svendor);
pcibios_read_config_word(pci_bus, pci_device_fn, PCI_SUBSYSTEM_ID, &sdevice);
Make some decision about whether it is your device.
If so, then you can do:
pdev = pci_find_slot(pci_bus, pci_device_fn);
and you will find, e.g:
ioaddr = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
You should check this space with, e.g:
/* Avoid already found cards from previous pcnet32_probe() calls */
if ((pcnet32_tbl[chip_idx].flags & PCI_USES_IO) &&
check_region(ioaddr, pcnet32_tbl[chip_idx].io_size))
continue;
and later reserve it:
request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname);
(for I/O regions).
Andreas> 2. How do I map my memory on the card to the Linux memory map ?
hah. That's a pain. There are conflicting documents on how this is
supposed to occur. This is what I've used:
lp->sc_pattmem_phys = fpgadev->base_address[1]&PCI_BASE_ADDRESS_MEM_MASK;
/* now determine the size of the spaces by writing ones! */
pci_read_config_dword(lp->fpgadev, PCI_BASE_ADDRESS_1, &save_base);
pci_write_config_dword(lp->fpgadev, PCI_BASE_ADDRESS_1, 0xffffffff);
pci_read_config_dword(lp->fpgadev, PCI_BASE_ADDRESS_1, &size);
pci_write_config_dword(lp->fpgadev, PCI_BASE_ADDRESS_1, save_base);
/* this formula from NetBSD's sys/dev/pci/pcireg.h */
lp->sc_pattmem_size = (((size) & PCI_BASE_ADDRESS_MEM_MASK) &
-((size) & PCI_BASE_ADDRESS_MEM_MASK));
/* translate physical addresses to kernel's idea of virtual addresses */
lp->sc_pattmem = (u_int64_t *)ioremap(lp->sc_pattmem_phys, lp->sc_pattmem_size);
[the (u_int64_t *) is because sc_pattmem is of that type]
Andreas> 3. How do I create a complete scatter-gather list with the
Andreas> physical adresses for my DMA controller on the board ?
Usually you use "virt_to_bus".
Something like:
lp->tx_ring[entry].base = (u32)le32_to_cpu(virt_to_bus(skb->data));
*BSD has a much saner and better documented device driver API.
Andreas> Btw, we are using the Xilinx PCI controller inside a Virtex
Andreas> device, working with Linux SuSe 6.3 (but I thing the function
Andreas> calls are the same by all Linux distributions) und working with
Andreas> the gnu compiler.
Andreas> Can everybody help me ?
Andreas> Best regards and many thanks in advance,
Andreas> Andreas Heiner
:!mcr!: | Solidum Systems Corporation, http://www.solidum.com
Michael Richardson |For a better connected world,where data flows faster<tm>
Personal: http://www.sandelman.ottawa.on.ca/People/Michael_Richardson/Bio.html
mailto:mcr@sandelman.ottawa.on.ca mailto:mcr@solidum.com