1 #ifndef __PCIDEVICE_H
2 #define __PCIDEVICE_H
3 
4 #include "types.h" // u32
5 #include "list.h" // hlist_node
6 
7 struct pci_device {
8     u16 bdf;
9     u8 rootbus;
10     struct hlist_node node;
11     struct pci_device *parent;
12 
13     // Configuration space device information
14     u16 vendor, device;
15     u16 class;
16     u8 prog_if, revision;
17     u8 header_type;
18     u8 secondary_bus;
19 
20     // Local information on device.
21     int have_driver;
22 };
23 extern struct hlist_head PCIDevices;
24 extern int MaxPCIBus;
25 
pci_classprog(struct pci_device * pci)26 static inline u32 pci_classprog(struct pci_device *pci) {
27     return (pci->class << 8) | pci->prog_if;
28 }
29 
30 #define foreachpci(PCI)                                 \
31     hlist_for_each_entry(PCI, &PCIDevices, node)
32 
33 #define PCI_ANY_ID      (~0)
34 struct pci_device_id {
35     u32 vendid;
36     u32 devid;
37     u32 class;
38     u32 class_mask;
39     void (*func)(struct pci_device *pci, void *arg);
40 };
41 
42 #define PCI_DEVICE(vendor_id, device_id, init_func)     \
43     {                                                   \
44         .vendid = (vendor_id),                          \
45         .devid = (device_id),                           \
46         .class = PCI_ANY_ID,                            \
47         .class_mask = 0,                                \
48         .func = (init_func)                             \
49     }
50 
51 #define PCI_DEVICE_CLASS(vendor_id, device_id, class_code, init_func)   \
52     {                                                                   \
53         .vendid = (vendor_id),                                          \
54         .devid = (device_id),                                           \
55         .class = (class_code),                                          \
56         .class_mask = ~0,                                               \
57         .func = (init_func)                                             \
58     }
59 
60 #define PCI_DEVICE_END                          \
61     {                                           \
62         .vendid = 0,                            \
63     }
64 
65 void pci_probe_devices(void);
66 struct pci_device *pci_find_device(u16 vendid, u16 devid);
67 struct pci_device *pci_find_class(u16 classid);
68 int pci_init_device(const struct pci_device_id *ids
69                     , struct pci_device *pci, void *arg);
70 struct pci_device *pci_find_init_device(const struct pci_device_id *ids
71                                         , void *arg);
72 void pci_enable_busmaster(struct pci_device *pci);
73 u16 pci_enable_iobar(struct pci_device *pci, u32 addr);
74 void *pci_enable_membar(struct pci_device *pci, u32 addr);
75 
76 #endif // pcidevice.h
77