[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