XenevaOS
Loading...
Searching...
No Matches
pci.h
Go to the documentation of this file.
1/*
2 * DCL pci.h -- the PCI surface the drm set names, and now a bus behind it.
3 *
4 * This header was compile-only for its first act: there was no PCI on the
5 * boards this kernel targets, drm_file.c:987 and drm_ioctl.c:152 asked
6 * dev_is_pci(dev->dev) before every bus-id setup, the answer was always
7 * false, and the struct below was a three-member sketch sized for the BDF
8 * string those reads print. The scanout stage changed what it has to carry:
9 * QEMU's bochs-display is a real PCI device, and the vendored driver that
10 * owns it (Vendored/drivers/gpu/drm/tiny/bochs.c) compiles and links whole
11 * against this surface -- probe/remove/shutdown records, the id_table match
12 * quadruple, BAR resources with start/length/flags, and the
13 * pci_set/get_drvdata pair.
14 *
15 * The bus behind the surface is DCL/pci_shim.c: it walks the ECAM window the
16 * native pcie code already maps, fills one struct pci_dev per function, and
17 * runs id_table matching plus probe when a vendored driver registers. This
18 * header stays a pure data contract except for one participant:
19 * dev_is_pci() now has to answer for real devices (drm_file.c prints the BDF
20 * string when it is true), and the only honest registry of "which devices
21 * this bus made" lives in the fabric, so the inline forwards there. That
22 * query is also what keeps the vendored drm core's own PCI paths (drm_edid's
23 * switcheroo wrappers) answering correctly for a device that is now actually
24 * behind a PCI bus, and keeps answering false for every device that is not.
25 *
26 * struct device lives in the pinned <linux/fs.h> (fs.h:184), which is why
27 * this header includes fs.h rather than declaring the member opaque: an
28 * incomplete struct device cannot be a member. The pinned struct is 800
29 * bytes whether it describes a PCI device or not -- the fabric embeds it
30 * inside its own pci_dev and never grows it, per the note in device.h about
31 * writes at offset 800 being a heap overrun.
32 */
33#ifndef _LINUX_PCI_H
34#define _LINUX_PCI_H
35
36#include <linux/types.h>
37#include <linux/fs.h> /* struct device, at fs.h:184 */
38
39/*
40 * <linux/capability.h> for capable(), which the drm sources that name this
41 * header also name without including it -- drm_file.c:149 and drm_ioctl.c:152
42 * both write `capable(CAP_SYS_ADMIN)`. In mainline the chain runs through
43 * this header's own <linux/device.h> (mainline pci.h:38); DCL's device layer
44 * is struct device in the pinned <linux/fs.h> with nothing but a struct body
45 * behind it, so the chain stops here and this header names the source
46 * directly.
47 *
48 * Carried here rather than in <linux/file.h>, which is DCL's other carrier
49 * of mainline fs.h's vocabulary, because drm_ioctl.c needs capable() and
50 * does not include file.h -- and this header is the one the consumers all
51 * name. Leaf, like every header on this path: capability.h includes only
52 * <stdbool.h>.
53 */
54#include <linux/capability.h>
55
56/*
57 * The id structures, from upstream's 7.2 homes: PCI_ANY_ID and
58 * struct pci_device_id live in <linux/device-id/pci.h>, and
59 * struct device_driver -- the tag pci_driver.driver is -- in
60 * <linux/device/driver.h>. Both are split out of mainline's pci.h set
61 * because a second bus (virtio) shares the driver tag.
62 */
63#include <linux/device-id/pci.h>
64#include <linux/device/driver.h>
65#include <linux/ioport.h> /* struct resource, IORESOURCE_MEM/IO */
66#include <linux/pm.h> /* struct dev_pm_ops, for pci_driver.driver.pm */
67#include <linux/pci_ids.h> /* the subvendor/subdevice pair id_tables match */
68
69/*
70 * struct pci_bus -- just the bus number. drm_file.c:991 prints
71 * `pdev->bus->number` as the middle field of %02x in a BDF string, and
72 * pci_domain_nr() below takes the bus, not the device. The fabric owns the
73 * one instance per slot, next to the device it belongs to.
74 */
75struct pci_bus {
76 unsigned char number;
77};
78
79/*
80 * struct pci_dev -- identity plus BARs, which is the whole of what a driver
81 * ported into this tree reads.
82 *
83 * mainline's pci_dev is a kernel object: device lists, PM state, MSI
84 * vectors, config-space accessors, the driver bound to it. None of that has
85 * code here -- the fabric matches once at initcall time and nothing ever
86 * unbinds -- so this carries the DCL delta on purpose, after the pinned
87 * struct device:
88 *
89 * - vendor/device/subsystem_vendor/subsystem_device and class, so
90 * pci_match_one_device()'s quadruple test and class filter can run.
91 * class is class<<8 | subclass, mainline's spelling.
92 * - revision, because bochs_hw_init() selects its register window from
93 * `pdev->revision >= 2` (the qext block exists from revision 2 on).
94 * - resource[6], filled for a matched device only (the fabric probes sizes
95 * by writing ~0 to a BAR -- a write effect no unmatched device should
96 * see) with mainline's start/end/flags fields.
97 * - driver_data, which is where pci_set_drvdata()/pci_get_drvdata()
98 * keep the drm_device pointer. A field here rather than mainline's
99 * dev->driver_data because struct device is the pinned 800-byte blob
100 * and device.h's note explains why nothing may grow it.
101 */
102struct pci_dev {
103 struct pci_bus* bus;
104 unsigned int devfn;
105 struct device dev;
106
107 unsigned short vendor;
108 unsigned short device;
109 unsigned short subsystem_vendor;
110 unsigned short subsystem_device;
111 unsigned int class; /* class<<8 | subclass */
112 unsigned char revision;
113 struct resource resource[6]; /* BARs 0..5, mainline's indices */
115};
116
117/*
118 * PCI_SLOT / PCI_FUNC -- the two bitfields packed into devfn. mainline spells
119 * them the same way: slot is bits 7:3, function is bits 2:0. drm_file.c:992
120 * prints both, and the fabric packs devices the same way.
121 */
122#define PCI_SLOT(devfn) (((devfn) >> 3) & 0xff)
123#define PCI_FUNC(devfn) ((devfn) & 0x07)
124
125/*
126 * to_pci_dev() -- mainline's spelling, container_of back from the embedded
127 * struct device. drm_file.c:988 and drm_edid.c:2909/:2938 call it before
128 * their dev_is_pci() test, so for a non-PCI device it still produces a
129 * pointer into whatever object embeds the struct device -- which is why the
130 * test, not this, is the gate.
131 */
132#define to_pci_dev(n) container_of(n, struct pci_dev, dev)
133
134/*
135 * dev_is_pci() -- forwards to the fabric's registry. mainline compares
136 * `dev->bus` against &pci_bus_type; there is no bus_type in DCL, and the
137 * truthful answer for "did this bus create that device" is membership in the
138 * fabric's slot table, which DCL/pci_shim.c owns.
139 *
140 * Still a function taking the argument (and still NULL-safe): drm_file.c:410
141 * and :987 pass dev->dev, which can be NULL, and mainline survives that only
142 * because its callers never do -- this one does not have to be as hopeful.
143 */
144extern int dcl_pci_device_is_pci(const struct device* dev);
145
146static inline int dev_is_pci(const struct device* dev)
147{
148 if (!dev)
149 return 0;
151}
152
153/*
154 * pci_domain_nr() -- 0, which is the correct answer for a single-segment
155 * system: the fabric scans segment 0 only (AuPCIEGetDevice(0, ...)), so
156 * every bus it hands out is domain 0. The argument is a struct pci_bus *
157 * (drm_file.c:991 passes pdev->bus).
158 */
159static inline unsigned int pci_domain_nr(const struct pci_bus* bus)
160{
161 (void)bus;
162 return 0;
163}
164
165/* ── driver binding ─────────────────────────────────────────────────────── */
166
167/*
168 * struct pci_driver -- the registration record, reduced to what the fabric
169 * runs and what a driver initialises. mainline's err_handler, dynids,
170 * driver_managed_dma and friends have no code here to call them.
171 *
172 * The nested struct device_driver is the shared tag from
173 * <linux/device/driver.h> (also used by virtio_driver); only its `name` and
174 * `pm` members exist, and bochs.c writes `.driver.pm` through this nesting.
175 * `name` at the pci_driver level is separate and is what probes pass to
176 * aperture_remove_conflicting_pci_devices().
177 */
179 const char* name;
180 const struct pci_device_id* id_table;
181 int (*probe)(struct pci_dev* dev, const struct pci_device_id* id);
182 void (*remove)(struct pci_dev* dev);
183 void (*shutdown)(struct pci_dev* dev);
185};
186
187/*
188 * Registration is match-and-probe, run immediately: the fabric scans once,
189 * then for every device whose id_table entry matches and which no earlier
190 * driver took, calls ->probe. There is no deferred bus callback to simulate
191 * because there is no other time for a device to appear.
192 *
193 * The return value is 0 even when probes fail -- mainline's
194 * pci_register_driver() reports whether the *driver* registered, not whether
195 * its probes succeeded, and a vendored driver keeps its initcall result
196 * unread either way. A driver whose probe failed on every device is visible
197 * in the boot log, not as an error code.
198 */
201
202/*
203 * pcim_enable_device() -- set the command register's I/O and memory decode
204 * bits. mainline's version also allocates MSI state and does power-state
205 * bookkeeping; none of that exists here, and bochs's use of it is exactly
206 * this decode gate before its BARs may be touched. Firmware has usually
207 * enabled decode already, but the write is idempotent and is what the
208 * driver is entitled to assume afterward.
209 */
210int pcim_enable_device(struct pci_dev* pdev);
211
212/* ── BAR accessors ──────────────────────────────────────────────────────── */
213
214#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
215#define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end)
216#define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags)
217
218static inline resource_size_t pci_resource_len(const struct pci_dev* dev, int bar)
219{
220 return dev->resource[bar].end - dev->resource[bar].start + 1;
221}
222
223/*
224 * pci_set_drvdata() / pci_get_drvdata() -- mainline stores the pointer in
225 * dev->driver_data; see the note on struct pci_dev above for why this tree
226 * keeps it on the pci_dev instead.
227 */
228static inline void pci_set_drvdata(struct pci_dev* pdev, void* data)
229{
230 pdev->driver_data = data;
231}
232
233static inline void* pci_get_drvdata(const struct pci_dev* pdev)
234{
235 return pdev->driver_data;
236}
237
238/* ── device lookup ──────────────────────────────────────────────────────── */
239
240/*
241 * pci_get_device() / pci_dev_put(), as virtio-gpu's init names them: mainline
242 * walks the device list and returns a match with a reference held, the caller
243 * dropping it with pci_dev_put() when done. The DCL fabric's slot table is
244 * the list (DCL/pci_shim.c walks ECAM into it; nothing is ever removed), and
245 * the from-argument keeps mainline's iteration contract -- resuming *after*
246 * the device handed to the previous call -- because the one caller passes
247 * NULL and a second caller, if it ever comes, will expect the same walk.
248 *
249 * The reference itself is the no-op of a bus whose devices outlive every
250 * driver: there is no removal path to fence against, so get is "the pointer
251 * is still valid" and put has nothing to drop. Both bodies are in
252 * DCL/pci_shim.c beside the scan.
253 */
254struct pci_dev* pci_get_device(unsigned int vendor, unsigned int device,
255 struct pci_dev* from);
256void pci_dev_put(struct pci_dev* pdev);
257
258/*
259 * pci_is_vga() -- mainline's legacy-VGA class test, body verbatim
260 * (include/linux/pci.h:784 in linux-7.2.6): the device either announces the
261 * display-VGA class or the old not-defined-VGA one. Only the class matters
262 * here; mainline's ioport/parity extras are x86 machinery this port has no
263 * registers for.
264 *
265 * What reads it: virtio_gpu_driver_init()'s VGA-quirk branch. The device
266 * this port runs against (virtio-gpu-pci) reports 0x0380, so the answer is
267 * false and the branch -- vga_get_interruptible()/vga_put() -- is skipped;
268 * virtio_gpu_probe()'s aperture_remove_conflicting_pci_devices() is skipped
269 * for the same reason.
270 */
271static inline bool pci_is_vga(struct pci_dev* pdev)
272{
273 if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
274 return true;
275
276 if ((pdev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA)
277 return true;
278
279 return false;
280}
281
282#endif /* _LINUX_PCI_H */
uint16_t vendor
Definition devhw.c:88
const struct device * dev
Definition drm_print.h:519
void * data
Definition kthread.h:30
uintptr_t resource_size_t
Definition kernel.h:41
int dcl_pci_device_is_pci(const struct device *dev)
void pci_unregister_driver(struct pci_driver *drv)
struct pci_dev * pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
int pcim_enable_device(struct pci_dev *pdev)
void pci_dev_put(struct pci_dev *pdev)
int pci_register_driver(struct pci_driver *drv)
#define PCI_CLASS_NOT_DEFINED_VGA
Definition pci_ids.h:33
#define PCI_CLASS_DISPLAY_VGA
Definition pci_ids.h:34
Definition driver.h:39
Definition fs.h:255
Definition pci.h:75
unsigned char number
Definition pci.h:76
Definition pci.h:102
unsigned int devfn
Definition pci.h:104
unsigned short subsystem_device
Definition pci.h:110
unsigned char revision
Definition pci.h:112
struct device dev
Definition pci.h:105
void * driver_data
Definition pci.h:114
unsigned short vendor
Definition pci.h:107
unsigned int class
Definition pci.h:111
unsigned short device
Definition pci.h:108
unsigned short subsystem_vendor
Definition pci.h:109
struct pci_bus * bus
Definition pci.h:103
Definition pci.h:28
Definition pci.h:178
const char * name
Definition pci.h:179
const struct pci_device_id * id_table
Definition pci.h:180
void(* remove)(struct pci_dev *dev)
Definition pci.h:182
struct device_driver driver
Definition pci.h:184
void(* shutdown)(struct pci_dev *dev)
Definition pci.h:183
int(* probe)(struct pci_dev *dev, const struct pci_device_id *id)
Definition pci.h:181
Definition ioport.h:44