Part of the WritingPortableDrivers section

Accessing PCI Memory

To access the PCI memory of a device, you again must use some general functions and not try to access the memory directly. This is due to the different ways the PCI bus can be accessed, depending on the type of hardware you have. If you use the general functions, then your PCI driver will be able to work on any type of Linux system that has a PCI bus.

To read data from the PCI bus use the following functions:

   1 int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val);
   2 int pci_read_config_word(struct pci_dev *dev, int where, u16 *val);
   3 int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val);

and to write data, use these functions:

   1 int pci_write_config_byte(struct pci_dev *dev, int where, u8 val);
   2 int pci_write_config_word(struct pci_dev *dev, int where, u16 val);
   3 int pci_write_config_dword(struct pci_dev *dev, int where, u32 val);

These functions allow you to write 8, 16 or 32 bits to a specific location that is assigned to a specific PCI device. If you wish to access the memory location of a specific PCI device that has not been initialized by the Linux PCI core yet, you can use the following functions that are present in the pci_hotplug core code:

   1 int pci_read_config_byte_nodev(struct pci_ops *ops, u8 bus, u8 device,
   2                                u8 function, int where, u8 *val);
   3 int pci_read_config_word_nodev(struct pci_ops *ops, u8 bus, u8 device,
   4                                u8 function, int where, u16 *val);
   5 int pci_read_config_dword_nodev(struct pci_ops *ops, u8 bus, u8 device,
   6                                 u8 function, int where, u32 *val);
   8 int pci_write_config_byte_nodev(struct pci_ops *ops, u8 bus, u8 device,
   9                                 u8 function, int where, u8 val);
  10 int pci_write_config_word_nodev(struct pci_ops *ops, u8 bus, u8 device,
  11                                 u8 function, int where, u16 val);
  12 int pci_write_config_dword_nodev(struct pci_ops *ops, u8 bus, u8 device,
  13                                  u8 function, int where, u32 val);

An example of reading and writing to PCI memory by a driver can be seen in the USB OHCI driver at drivers/usb/host/usb-ohci.c:

   1 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
   2 if (latency) {
   3         pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
   4         if (limit && limit < latency) {
   5                 dbg("PCI latency reduced to max %d", limit);
   6                 pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
   7                 ohci->pci_latency = limit;
   8         } else {
   9                 /* it might already have been reduced */
  10                 ohci->pci_latency = latency;
  11         }
  12 }

KernelNewbies: AccessingPciMemory (last edited 2017-12-30 01:30:13 by localhost)