18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci============================================
48c2ecf20Sopenharmony_ciAccessing PCI device resources through sysfs
58c2ecf20Sopenharmony_ci============================================
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_cisysfs, usually mounted at /sys, provides access to PCI resources on platforms
88c2ecf20Sopenharmony_cithat support it.  For example, a given bus might look like this::
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci     /sys/devices/pci0000:17
118c2ecf20Sopenharmony_ci     |-- 0000:17:00.0
128c2ecf20Sopenharmony_ci     |   |-- class
138c2ecf20Sopenharmony_ci     |   |-- config
148c2ecf20Sopenharmony_ci     |   |-- device
158c2ecf20Sopenharmony_ci     |   |-- enable
168c2ecf20Sopenharmony_ci     |   |-- irq
178c2ecf20Sopenharmony_ci     |   |-- local_cpus
188c2ecf20Sopenharmony_ci     |   |-- remove
198c2ecf20Sopenharmony_ci     |   |-- resource
208c2ecf20Sopenharmony_ci     |   |-- resource0
218c2ecf20Sopenharmony_ci     |   |-- resource1
228c2ecf20Sopenharmony_ci     |   |-- resource2
238c2ecf20Sopenharmony_ci     |   |-- revision
248c2ecf20Sopenharmony_ci     |   |-- rom
258c2ecf20Sopenharmony_ci     |   |-- subsystem_device
268c2ecf20Sopenharmony_ci     |   |-- subsystem_vendor
278c2ecf20Sopenharmony_ci     |   `-- vendor
288c2ecf20Sopenharmony_ci     `-- ...
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ciThe topmost element describes the PCI domain and bus number.  In this case,
318c2ecf20Sopenharmony_cithe domain number is 0000 and the bus number is 17 (both values are in hex).
328c2ecf20Sopenharmony_ciThis bus contains a single function device in slot 0.  The domain and bus
338c2ecf20Sopenharmony_cinumbers are reproduced for convenience.  Under the device directory are several
348c2ecf20Sopenharmony_cifiles, each with their own function.
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci       =================== =====================================================
378c2ecf20Sopenharmony_ci       file		   function
388c2ecf20Sopenharmony_ci       =================== =====================================================
398c2ecf20Sopenharmony_ci       class		   PCI class (ascii, ro)
408c2ecf20Sopenharmony_ci       config		   PCI config space (binary, rw)
418c2ecf20Sopenharmony_ci       device		   PCI device (ascii, ro)
428c2ecf20Sopenharmony_ci       enable	           Whether the device is enabled (ascii, rw)
438c2ecf20Sopenharmony_ci       irq		   IRQ number (ascii, ro)
448c2ecf20Sopenharmony_ci       local_cpus	   nearby CPU mask (cpumask, ro)
458c2ecf20Sopenharmony_ci       remove		   remove device from kernel's list (ascii, wo)
468c2ecf20Sopenharmony_ci       resource		   PCI resource host addresses (ascii, ro)
478c2ecf20Sopenharmony_ci       resource0..N	   PCI resource N, if present (binary, mmap, rw\ [1]_)
488c2ecf20Sopenharmony_ci       resource0_wc..N_wc  PCI WC map resource N, if prefetchable (binary, mmap)
498c2ecf20Sopenharmony_ci       revision		   PCI revision (ascii, ro)
508c2ecf20Sopenharmony_ci       rom		   PCI ROM resource, if present (binary, ro)
518c2ecf20Sopenharmony_ci       subsystem_device	   PCI subsystem device (ascii, ro)
528c2ecf20Sopenharmony_ci       subsystem_vendor	   PCI subsystem vendor (ascii, ro)
538c2ecf20Sopenharmony_ci       vendor		   PCI vendor (ascii, ro)
548c2ecf20Sopenharmony_ci       =================== =====================================================
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci::
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci  ro - read only file
598c2ecf20Sopenharmony_ci  rw - file is readable and writable
608c2ecf20Sopenharmony_ci  wo - write only file
618c2ecf20Sopenharmony_ci  mmap - file is mmapable
628c2ecf20Sopenharmony_ci  ascii - file contains ascii text
638c2ecf20Sopenharmony_ci  binary - file contains binary data
648c2ecf20Sopenharmony_ci  cpumask - file contains a cpumask type
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci.. [1] rw for IORESOURCE_IO (I/O port) regions only
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ciThe read only files are informational, writes to them will be ignored, with
698c2ecf20Sopenharmony_cithe exception of the 'rom' file.  Writable files can be used to perform
708c2ecf20Sopenharmony_ciactions on the device (e.g. changing config space, detaching a device).
718c2ecf20Sopenharmony_cimmapable files are available via an mmap of the file at offset 0 and can be
728c2ecf20Sopenharmony_ciused to do actual device programming from userspace.  Note that some platforms
738c2ecf20Sopenharmony_cidon't support mmapping of certain resources, so be sure to check the return
748c2ecf20Sopenharmony_civalue from any attempted mmap.  The most notable of these are I/O port
758c2ecf20Sopenharmony_ciresources, which also provide read/write access.
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ciThe 'enable' file provides a counter that indicates how many times the device
788c2ecf20Sopenharmony_cihas been enabled.  If the 'enable' file currently returns '4', and a '1' is
798c2ecf20Sopenharmony_ciechoed into it, it will then return '5'.  Echoing a '0' into it will decrease
808c2ecf20Sopenharmony_cithe count.  Even when it returns to 0, though, some of the initialisation
818c2ecf20Sopenharmony_cimay not be reversed.
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ciThe 'rom' file is special in that it provides read-only access to the device's
848c2ecf20Sopenharmony_ciROM file, if available.  It's disabled by default, however, so applications
858c2ecf20Sopenharmony_cishould write the string "1" to the file to enable it before attempting a read
868c2ecf20Sopenharmony_cicall, and disable it following the access by writing "0" to the file.  Note
878c2ecf20Sopenharmony_cithat the device must be enabled for a rom read to return data successfully.
888c2ecf20Sopenharmony_ciIn the event a driver is not bound to the device, it can be enabled using the
898c2ecf20Sopenharmony_ci'enable' file, documented above.
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ciThe 'remove' file is used to remove the PCI device, by writing a non-zero
928c2ecf20Sopenharmony_ciinteger to the file.  This does not involve any kind of hot-plug functionality,
938c2ecf20Sopenharmony_cie.g. powering off the device.  The device is removed from the kernel's list of
948c2ecf20Sopenharmony_ciPCI devices, the sysfs directory for it is removed, and the device will be
958c2ecf20Sopenharmony_ciremoved from any drivers attached to it. Removal of PCI root buses is
968c2ecf20Sopenharmony_cidisallowed.
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ciAccessing legacy resources through sysfs
998c2ecf20Sopenharmony_ci----------------------------------------
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ciLegacy I/O port and ISA memory resources are also provided in sysfs if the
1028c2ecf20Sopenharmony_ciunderlying platform supports them.  They're located in the PCI class hierarchy,
1038c2ecf20Sopenharmony_cie.g.::
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	/sys/class/pci_bus/0000:17/
1068c2ecf20Sopenharmony_ci	|-- bridge -> ../../../devices/pci0000:17
1078c2ecf20Sopenharmony_ci	|-- cpuaffinity
1088c2ecf20Sopenharmony_ci	|-- legacy_io
1098c2ecf20Sopenharmony_ci	`-- legacy_mem
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ciThe legacy_io file is a read/write file that can be used by applications to
1128c2ecf20Sopenharmony_cido legacy port I/O.  The application should open the file, seek to the desired
1138c2ecf20Sopenharmony_ciport (e.g. 0x3e8) and do a read or a write of 1, 2 or 4 bytes.  The legacy_mem
1148c2ecf20Sopenharmony_cifile should be mmapped with an offset corresponding to the memory offset
1158c2ecf20Sopenharmony_cidesired, e.g. 0xa0000 for the VGA frame buffer.  The application can then
1168c2ecf20Sopenharmony_cisimply dereference the returned pointer (after checking for errors of course)
1178c2ecf20Sopenharmony_cito access legacy memory space.
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ciSupporting PCI access on new platforms
1208c2ecf20Sopenharmony_ci--------------------------------------
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ciIn order to support PCI resource mapping as described above, Linux platform
1238c2ecf20Sopenharmony_cicode should ideally define ARCH_GENERIC_PCI_MMAP_RESOURCE and use the generic
1248c2ecf20Sopenharmony_ciimplementation of that functionality. To support the historical interface of
1258c2ecf20Sopenharmony_cimmap() through files in /proc/bus/pci, platforms may also set HAVE_PCI_MMAP.
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ciAlternatively, platforms which set HAVE_PCI_MMAP may provide their own
1288c2ecf20Sopenharmony_ciimplementation of pci_mmap_page_range() instead of defining
1298c2ecf20Sopenharmony_ciARCH_GENERIC_PCI_MMAP_RESOURCE.
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ciPlatforms which support write-combining maps of PCI resources must define
1328c2ecf20Sopenharmony_ciarch_can_pci_mmap_wc() which shall evaluate to non-zero at runtime when
1338c2ecf20Sopenharmony_ciwrite-combining is permitted. Platforms which support maps of I/O resources
1348c2ecf20Sopenharmony_cidefine arch_can_pci_mmap_io() similarly.
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ciLegacy resources are protected by the HAVE_PCI_LEGACY define.  Platforms
1378c2ecf20Sopenharmony_ciwishing to support legacy functionality should define it and provide
1388c2ecf20Sopenharmony_cipci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
139