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