]>
Commit | Line | Data |
---|---|---|
30edc14b KRW |
1 | /* |
2 | * PCI Backend Common Data Structures & Function Declarations | |
3 | * | |
4 | * Author: Ryan Wilson <[email protected]> | |
5 | */ | |
6 | #ifndef __XEN_PCIBACK_H__ | |
7 | #define __XEN_PCIBACK_H__ | |
8 | ||
9 | #include <linux/pci.h> | |
10 | #include <linux/interrupt.h> | |
11 | #include <xen/xenbus.h> | |
12 | #include <linux/list.h> | |
13 | #include <linux/spinlock.h> | |
14 | #include <linux/workqueue.h> | |
8bfd4e02 | 15 | #include <linux/atomic.h> |
30edc14b KRW |
16 | #include <xen/interface/io/pciif.h> |
17 | ||
402c5e15 JB |
18 | #define DRV_NAME "xen-pciback" |
19 | ||
30edc14b KRW |
20 | struct pci_dev_entry { |
21 | struct list_head list; | |
22 | struct pci_dev *dev; | |
23 | }; | |
24 | ||
8bfd4e02 KRW |
25 | #define _PDEVF_op_active (0) |
26 | #define PDEVF_op_active (1<<(_PDEVF_op_active)) | |
30edc14b KRW |
27 | #define _PCIB_op_pending (1) |
28 | #define PCIB_op_pending (1<<(_PCIB_op_pending)) | |
29 | ||
a92336a1 | 30 | struct xen_pcibk_device { |
30edc14b | 31 | void *pci_dev_data; |
b1766b62 | 32 | struct mutex dev_lock; |
30edc14b | 33 | struct xenbus_device *xdev; |
30edc14b KRW |
34 | struct xenbus_watch be_watch; |
35 | u8 be_watching; | |
30edc14b | 36 | int evtchn_irq; |
30edc14b | 37 | struct xen_pci_sharedinfo *sh_info; |
30edc14b | 38 | unsigned long flags; |
30edc14b | 39 | struct work_struct op_work; |
8135cf8b | 40 | struct xen_pci_op op; |
30edc14b KRW |
41 | }; |
42 | ||
a92336a1 | 43 | struct xen_pcibk_dev_data { |
30edc14b | 44 | struct list_head config_fields; |
cd9db80e | 45 | struct pci_saved_state *pci_saved_state; |
0513fe9e KRW |
46 | unsigned int permissive:1; |
47 | unsigned int warned_on_write:1; | |
48 | unsigned int enable_intx:1; | |
49 | unsigned int isr_on:1; /* Whether the IRQ handler is installed. */ | |
50 | unsigned int ack_intr:1; /* .. and ACK-ing */ | |
51 | unsigned long handled; | |
52 | unsigned int irq; /* Saved in case device transitions to MSI/MSI-X */ | |
a92336a1 | 53 | char irq_name[0]; /* xen-pcibk[000:04:00.0] */ |
30edc14b KRW |
54 | }; |
55 | ||
a92336a1 KRW |
56 | /* Used by XenBus and xen_pcibk_ops.c */ |
57 | extern wait_queue_head_t xen_pcibk_aer_wait_queue; | |
30edc14b | 58 | /* Used by pcistub.c and conf_space_quirks.c */ |
a92336a1 | 59 | extern struct list_head xen_pcibk_quirks; |
30edc14b KRW |
60 | |
61 | /* Get/Put PCI Devices that are hidden from the PCI Backend Domain */ | |
a92336a1 | 62 | struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev, |
30edc14b KRW |
63 | int domain, int bus, |
64 | int slot, int func); | |
a92336a1 | 65 | struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev, |
30edc14b KRW |
66 | struct pci_dev *dev); |
67 | void pcistub_put_pci_dev(struct pci_dev *dev); | |
68 | ||
69 | /* Ensure a device is turned off or reset */ | |
a92336a1 | 70 | void xen_pcibk_reset_device(struct pci_dev *pdev); |
30edc14b KRW |
71 | |
72 | /* Access a virtual configuration space for a PCI device */ | |
a92336a1 KRW |
73 | int xen_pcibk_config_init(void); |
74 | int xen_pcibk_config_init_dev(struct pci_dev *dev); | |
75 | void xen_pcibk_config_free_dyn_fields(struct pci_dev *dev); | |
76 | void xen_pcibk_config_reset_dev(struct pci_dev *dev); | |
77 | void xen_pcibk_config_free_dev(struct pci_dev *dev); | |
78 | int xen_pcibk_config_read(struct pci_dev *dev, int offset, int size, | |
79 | u32 *ret_val); | |
80 | int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, | |
81 | u32 value); | |
30edc14b KRW |
82 | |
83 | /* Handle requests for specific devices from the frontend */ | |
a92336a1 | 84 | typedef int (*publish_pci_dev_cb) (struct xen_pcibk_device *pdev, |
30edc14b KRW |
85 | unsigned int domain, unsigned int bus, |
86 | unsigned int devfn, unsigned int devid); | |
a92336a1 | 87 | typedef int (*publish_pci_root_cb) (struct xen_pcibk_device *pdev, |
30edc14b | 88 | unsigned int domain, unsigned int bus); |
30edc14b | 89 | |
2ebdc426 KRW |
90 | /* Backend registration for the two types of BDF representation: |
91 | * vpci - BDFs start at 00 | |
92 | * passthrough - BDFs are exactly like in the host. | |
93 | */ | |
94 | struct xen_pcibk_backend { | |
402c5e15 | 95 | const char *name; |
2ebdc426 KRW |
96 | int (*init)(struct xen_pcibk_device *pdev); |
97 | void (*free)(struct xen_pcibk_device *pdev); | |
98 | int (*find)(struct pci_dev *pcidev, struct xen_pcibk_device *pdev, | |
99 | unsigned int *domain, unsigned int *bus, | |
100 | unsigned int *devfn); | |
101 | int (*publish)(struct xen_pcibk_device *pdev, publish_pci_root_cb cb); | |
e8801a74 KRW |
102 | void (*release)(struct xen_pcibk_device *pdev, struct pci_dev *dev, |
103 | bool lock); | |
2ebdc426 KRW |
104 | int (*add)(struct xen_pcibk_device *pdev, struct pci_dev *dev, |
105 | int devid, publish_pci_dev_cb publish_cb); | |
106 | struct pci_dev *(*get)(struct xen_pcibk_device *pdev, | |
107 | unsigned int domain, unsigned int bus, | |
108 | unsigned int devfn); | |
109 | }; | |
110 | ||
402c5e15 JB |
111 | extern const struct xen_pcibk_backend xen_pcibk_vpci_backend; |
112 | extern const struct xen_pcibk_backend xen_pcibk_passthrough_backend; | |
113 | extern const struct xen_pcibk_backend *xen_pcibk_backend; | |
2ebdc426 KRW |
114 | |
115 | static inline int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, | |
116 | struct pci_dev *dev, | |
117 | int devid, | |
118 | publish_pci_dev_cb publish_cb) | |
119 | { | |
120 | if (xen_pcibk_backend && xen_pcibk_backend->add) | |
121 | return xen_pcibk_backend->add(pdev, dev, devid, publish_cb); | |
122 | return -1; | |
402c5e15 JB |
123 | } |
124 | ||
2ebdc426 | 125 | static inline void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev, |
e8801a74 | 126 | struct pci_dev *dev, bool lock) |
2ebdc426 | 127 | { |
6337a239 | 128 | if (xen_pcibk_backend && xen_pcibk_backend->release) |
e8801a74 | 129 | return xen_pcibk_backend->release(pdev, dev, lock); |
402c5e15 | 130 | } |
2ebdc426 KRW |
131 | |
132 | static inline struct pci_dev * | |
133 | xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, unsigned int domain, | |
134 | unsigned int bus, unsigned int devfn) | |
135 | { | |
136 | if (xen_pcibk_backend && xen_pcibk_backend->get) | |
137 | return xen_pcibk_backend->get(pdev, domain, bus, devfn); | |
138 | return NULL; | |
402c5e15 JB |
139 | } |
140 | ||
30edc14b | 141 | /** |
a92336a1 | 142 | * Add for domain0 PCIE-AER handling. Get guest domain/bus/devfn in xen_pcibk |
30edc14b | 143 | * before sending aer request to pcifront, so that guest could identify |
a92336a1 | 144 | * device, coopearte with xen_pcibk to finish aer recovery job if device driver |
30edc14b KRW |
145 | * has the capability |
146 | */ | |
2ebdc426 KRW |
147 | static inline int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev, |
148 | struct xen_pcibk_device *pdev, | |
149 | unsigned int *domain, | |
150 | unsigned int *bus, | |
151 | unsigned int *devfn) | |
152 | { | |
153 | if (xen_pcibk_backend && xen_pcibk_backend->find) | |
154 | return xen_pcibk_backend->find(pcidev, pdev, domain, bus, | |
155 | devfn); | |
156 | return -1; | |
402c5e15 JB |
157 | } |
158 | ||
2ebdc426 KRW |
159 | static inline int xen_pcibk_init_devices(struct xen_pcibk_device *pdev) |
160 | { | |
161 | if (xen_pcibk_backend && xen_pcibk_backend->init) | |
162 | return xen_pcibk_backend->init(pdev); | |
163 | return -1; | |
402c5e15 JB |
164 | } |
165 | ||
2ebdc426 KRW |
166 | static inline int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev, |
167 | publish_pci_root_cb cb) | |
168 | { | |
169 | if (xen_pcibk_backend && xen_pcibk_backend->publish) | |
170 | return xen_pcibk_backend->publish(pdev, cb); | |
171 | return -1; | |
402c5e15 JB |
172 | } |
173 | ||
2ebdc426 KRW |
174 | static inline void xen_pcibk_release_devices(struct xen_pcibk_device *pdev) |
175 | { | |
176 | if (xen_pcibk_backend && xen_pcibk_backend->free) | |
177 | return xen_pcibk_backend->free(pdev); | |
402c5e15 JB |
178 | } |
179 | ||
30edc14b | 180 | /* Handles events from front-end */ |
a92336a1 KRW |
181 | irqreturn_t xen_pcibk_handle_event(int irq, void *dev_id); |
182 | void xen_pcibk_do_op(struct work_struct *data); | |
30edc14b | 183 | |
a92336a1 KRW |
184 | int xen_pcibk_xenbus_register(void); |
185 | void xen_pcibk_xenbus_unregister(void); | |
30edc14b | 186 | |
30edc14b KRW |
187 | extern int verbose_request; |
188 | ||
a92336a1 | 189 | void xen_pcibk_test_and_schedule_op(struct xen_pcibk_device *pdev); |
30edc14b KRW |
190 | #endif |
191 | ||
0513fe9e | 192 | /* Handles shared IRQs that can to device domain and control domain. */ |
a92336a1 | 193 | void xen_pcibk_irq_handler(struct pci_dev *dev, int reset); |