diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-07-20 15:33:51 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-07-20 15:33:51 -0400 |
commit | 3a6d28b11a895d08b6b4fc6f16dd9ff995844b45 (patch) | |
tree | 6a37a1260a1f873d719e04383ede6e487a1f7e99 /drivers/xen/xen-pciback/pciback.h | |
parent | 136d9ebff300044865693a57d68fe5905635992a (diff) | |
parent | 2ebdc4263022e0015341016b123fe7f44f9cf396 (diff) |
Merge branch 'stable/xen-pciback-0.6.3' into stable/drivers
* stable/xen-pciback-0.6.3:
xen/pciback: Have 'passthrough' option instead of XEN_PCIDEV_BACKEND_PASS and XEN_PCIDEV_BACKEND_VPCI
xen/pciback: Remove the DEBUG option.
xen/pciback: Drop two backends, squash and cleanup some code.
xen/pciback: Print out the MSI/MSI-X (PIRQ) values
xen/pciback: Don't setup an fake IRQ handler for SR-IOV devices.
xen: rename pciback module to xen-pciback.
xen/pciback: Fine-grain the spinlocks and fix BUG: scheduling while atomic cases.
xen/pciback: Allocate IRQ handler for device that is shared with guest.
xen/pciback: Disable MSI/MSI-X when reseting a device
xen/pciback: guest SR-IOV support for PV guest
xen/pciback: Register the owner (domain) of the PCI device.
xen/pciback: Cleanup the driver based on checkpatch warnings and errors.
xen/pciback: xen pci backend driver.
Conflicts:
drivers/xen/Kconfig
Diffstat (limited to 'drivers/xen/xen-pciback/pciback.h')
-rw-r--r-- | drivers/xen/xen-pciback/pciback.h | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h new file mode 100644 index 000000000000..a0e131a81503 --- /dev/null +++ b/drivers/xen/xen-pciback/pciback.h | |||
@@ -0,0 +1,183 @@ | |||
1 | /* | ||
2 | * PCI Backend Common Data Structures & Function Declarations | ||
3 | * | ||
4 | * Author: Ryan Wilson <hap9@epoch.ncsc.mil> | ||
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> | ||
15 | #include <linux/atomic.h> | ||
16 | #include <xen/interface/io/pciif.h> | ||
17 | |||
18 | struct pci_dev_entry { | ||
19 | struct list_head list; | ||
20 | struct pci_dev *dev; | ||
21 | }; | ||
22 | |||
23 | #define _PDEVF_op_active (0) | ||
24 | #define PDEVF_op_active (1<<(_PDEVF_op_active)) | ||
25 | #define _PCIB_op_pending (1) | ||
26 | #define PCIB_op_pending (1<<(_PCIB_op_pending)) | ||
27 | |||
28 | struct xen_pcibk_device { | ||
29 | void *pci_dev_data; | ||
30 | spinlock_t dev_lock; | ||
31 | struct xenbus_device *xdev; | ||
32 | struct xenbus_watch be_watch; | ||
33 | u8 be_watching; | ||
34 | int evtchn_irq; | ||
35 | struct xen_pci_sharedinfo *sh_info; | ||
36 | unsigned long flags; | ||
37 | struct work_struct op_work; | ||
38 | }; | ||
39 | |||
40 | struct xen_pcibk_dev_data { | ||
41 | struct list_head config_fields; | ||
42 | unsigned int permissive:1; | ||
43 | unsigned int warned_on_write:1; | ||
44 | unsigned int enable_intx:1; | ||
45 | unsigned int isr_on:1; /* Whether the IRQ handler is installed. */ | ||
46 | unsigned int ack_intr:1; /* .. and ACK-ing */ | ||
47 | unsigned long handled; | ||
48 | unsigned int irq; /* Saved in case device transitions to MSI/MSI-X */ | ||
49 | char irq_name[0]; /* xen-pcibk[000:04:00.0] */ | ||
50 | }; | ||
51 | |||
52 | /* Used by XenBus and xen_pcibk_ops.c */ | ||
53 | extern wait_queue_head_t xen_pcibk_aer_wait_queue; | ||
54 | extern struct workqueue_struct *xen_pcibk_wq; | ||
55 | /* Used by pcistub.c and conf_space_quirks.c */ | ||
56 | extern struct list_head xen_pcibk_quirks; | ||
57 | |||
58 | /* Get/Put PCI Devices that are hidden from the PCI Backend Domain */ | ||
59 | struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev, | ||
60 | int domain, int bus, | ||
61 | int slot, int func); | ||
62 | struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev, | ||
63 | struct pci_dev *dev); | ||
64 | void pcistub_put_pci_dev(struct pci_dev *dev); | ||
65 | |||
66 | /* Ensure a device is turned off or reset */ | ||
67 | void xen_pcibk_reset_device(struct pci_dev *pdev); | ||
68 | |||
69 | /* Access a virtual configuration space for a PCI device */ | ||
70 | int xen_pcibk_config_init(void); | ||
71 | int xen_pcibk_config_init_dev(struct pci_dev *dev); | ||
72 | void xen_pcibk_config_free_dyn_fields(struct pci_dev *dev); | ||
73 | void xen_pcibk_config_reset_dev(struct pci_dev *dev); | ||
74 | void xen_pcibk_config_free_dev(struct pci_dev *dev); | ||
75 | int xen_pcibk_config_read(struct pci_dev *dev, int offset, int size, | ||
76 | u32 *ret_val); | ||
77 | int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, | ||
78 | u32 value); | ||
79 | |||
80 | /* Handle requests for specific devices from the frontend */ | ||
81 | typedef int (*publish_pci_dev_cb) (struct xen_pcibk_device *pdev, | ||
82 | unsigned int domain, unsigned int bus, | ||
83 | unsigned int devfn, unsigned int devid); | ||
84 | typedef int (*publish_pci_root_cb) (struct xen_pcibk_device *pdev, | ||
85 | unsigned int domain, unsigned int bus); | ||
86 | |||
87 | /* Backend registration for the two types of BDF representation: | ||
88 | * vpci - BDFs start at 00 | ||
89 | * passthrough - BDFs are exactly like in the host. | ||
90 | */ | ||
91 | struct xen_pcibk_backend { | ||
92 | char *name; | ||
93 | int (*init)(struct xen_pcibk_device *pdev); | ||
94 | void (*free)(struct xen_pcibk_device *pdev); | ||
95 | int (*find)(struct pci_dev *pcidev, struct xen_pcibk_device *pdev, | ||
96 | unsigned int *domain, unsigned int *bus, | ||
97 | unsigned int *devfn); | ||
98 | int (*publish)(struct xen_pcibk_device *pdev, publish_pci_root_cb cb); | ||
99 | void (*release)(struct xen_pcibk_device *pdev, struct pci_dev *dev); | ||
100 | int (*add)(struct xen_pcibk_device *pdev, struct pci_dev *dev, | ||
101 | int devid, publish_pci_dev_cb publish_cb); | ||
102 | struct pci_dev *(*get)(struct xen_pcibk_device *pdev, | ||
103 | unsigned int domain, unsigned int bus, | ||
104 | unsigned int devfn); | ||
105 | }; | ||
106 | |||
107 | extern struct xen_pcibk_backend xen_pcibk_vpci_backend; | ||
108 | extern struct xen_pcibk_backend xen_pcibk_passthrough_backend; | ||
109 | extern struct xen_pcibk_backend *xen_pcibk_backend; | ||
110 | |||
111 | static inline int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, | ||
112 | struct pci_dev *dev, | ||
113 | int devid, | ||
114 | publish_pci_dev_cb publish_cb) | ||
115 | { | ||
116 | if (xen_pcibk_backend && xen_pcibk_backend->add) | ||
117 | return xen_pcibk_backend->add(pdev, dev, devid, publish_cb); | ||
118 | return -1; | ||
119 | }; | ||
120 | static inline void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev, | ||
121 | struct pci_dev *dev) | ||
122 | { | ||
123 | if (xen_pcibk_backend && xen_pcibk_backend->free) | ||
124 | return xen_pcibk_backend->release(pdev, dev); | ||
125 | }; | ||
126 | |||
127 | static inline struct pci_dev * | ||
128 | xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, unsigned int domain, | ||
129 | unsigned int bus, unsigned int devfn) | ||
130 | { | ||
131 | if (xen_pcibk_backend && xen_pcibk_backend->get) | ||
132 | return xen_pcibk_backend->get(pdev, domain, bus, devfn); | ||
133 | return NULL; | ||
134 | }; | ||
135 | /** | ||
136 | * Add for domain0 PCIE-AER handling. Get guest domain/bus/devfn in xen_pcibk | ||
137 | * before sending aer request to pcifront, so that guest could identify | ||
138 | * device, coopearte with xen_pcibk to finish aer recovery job if device driver | ||
139 | * has the capability | ||
140 | */ | ||
141 | static inline int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev, | ||
142 | struct xen_pcibk_device *pdev, | ||
143 | unsigned int *domain, | ||
144 | unsigned int *bus, | ||
145 | unsigned int *devfn) | ||
146 | { | ||
147 | if (xen_pcibk_backend && xen_pcibk_backend->find) | ||
148 | return xen_pcibk_backend->find(pcidev, pdev, domain, bus, | ||
149 | devfn); | ||
150 | return -1; | ||
151 | }; | ||
152 | static inline int xen_pcibk_init_devices(struct xen_pcibk_device *pdev) | ||
153 | { | ||
154 | if (xen_pcibk_backend && xen_pcibk_backend->init) | ||
155 | return xen_pcibk_backend->init(pdev); | ||
156 | return -1; | ||
157 | }; | ||
158 | static inline int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev, | ||
159 | publish_pci_root_cb cb) | ||
160 | { | ||
161 | if (xen_pcibk_backend && xen_pcibk_backend->publish) | ||
162 | return xen_pcibk_backend->publish(pdev, cb); | ||
163 | return -1; | ||
164 | }; | ||
165 | static inline void xen_pcibk_release_devices(struct xen_pcibk_device *pdev) | ||
166 | { | ||
167 | if (xen_pcibk_backend && xen_pcibk_backend->free) | ||
168 | return xen_pcibk_backend->free(pdev); | ||
169 | }; | ||
170 | /* Handles events from front-end */ | ||
171 | irqreturn_t xen_pcibk_handle_event(int irq, void *dev_id); | ||
172 | void xen_pcibk_do_op(struct work_struct *data); | ||
173 | |||
174 | int xen_pcibk_xenbus_register(void); | ||
175 | void xen_pcibk_xenbus_unregister(void); | ||
176 | |||
177 | extern int verbose_request; | ||
178 | |||
179 | void xen_pcibk_test_and_schedule_op(struct xen_pcibk_device *pdev); | ||
180 | #endif | ||
181 | |||
182 | /* Handles shared IRQs that can to device domain and control domain. */ | ||
183 | void xen_pcibk_irq_handler(struct pci_dev *dev, int reset); | ||