linux/drivers/xen/xen-pciback/conf_space.h
<<
>>
Prefs
   1/*
   2 * PCI Backend - Common data structures for overriding the configuration space
   3 *
   4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
   5 */
   6
   7#ifndef __XEN_PCIBACK_CONF_SPACE_H__
   8#define __XEN_PCIBACK_CONF_SPACE_H__
   9
  10#include <linux/list.h>
  11#include <linux/err.h>
  12
  13/* conf_field_init can return an errno in a ptr with ERR_PTR() */
  14typedef void *(*conf_field_init) (struct pci_dev *dev, int offset);
  15typedef void (*conf_field_reset) (struct pci_dev *dev, int offset, void *data);
  16typedef void (*conf_field_free) (struct pci_dev *dev, int offset, void *data);
  17
  18typedef int (*conf_dword_write) (struct pci_dev *dev, int offset, u32 value,
  19                                 void *data);
  20typedef int (*conf_word_write) (struct pci_dev *dev, int offset, u16 value,
  21                                void *data);
  22typedef int (*conf_byte_write) (struct pci_dev *dev, int offset, u8 value,
  23                                void *data);
  24typedef int (*conf_dword_read) (struct pci_dev *dev, int offset, u32 *value,
  25                                void *data);
  26typedef int (*conf_word_read) (struct pci_dev *dev, int offset, u16 *value,
  27                               void *data);
  28typedef int (*conf_byte_read) (struct pci_dev *dev, int offset, u8 *value,
  29                               void *data);
  30
  31/* These are the fields within the configuration space which we
  32 * are interested in intercepting reads/writes to and changing their
  33 * values.
  34 */
  35struct config_field {
  36        unsigned int offset;
  37        unsigned int size;
  38        unsigned int mask;
  39        conf_field_init init;
  40        conf_field_reset reset;
  41        conf_field_free release;
  42        void (*clean) (struct config_field *field);
  43        union {
  44                struct {
  45                        conf_dword_write write;
  46                        conf_dword_read read;
  47                } dw;
  48                struct {
  49                        conf_word_write write;
  50                        conf_word_read read;
  51                } w;
  52                struct {
  53                        conf_byte_write write;
  54                        conf_byte_read read;
  55                } b;
  56        } u;
  57        struct list_head list;
  58};
  59
  60struct config_field_entry {
  61        struct list_head list;
  62        const struct config_field *field;
  63        unsigned int base_offset;
  64        void *data;
  65};
  66
  67extern bool xen_pcibk_permissive;
  68
  69#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
  70
  71/* Add fields to a device - the add_fields macro expects to get a pointer to
  72 * the first entry in an array (of which the ending is marked by size==0)
  73 */
  74int xen_pcibk_config_add_field_offset(struct pci_dev *dev,
  75                                    const struct config_field *field,
  76                                    unsigned int offset);
  77
  78static inline int xen_pcibk_config_add_field(struct pci_dev *dev,
  79                                           const struct config_field *field)
  80{
  81        return xen_pcibk_config_add_field_offset(dev, field, 0);
  82}
  83
  84static inline int xen_pcibk_config_add_fields(struct pci_dev *dev,
  85                                            const struct config_field *field)
  86{
  87        int i, err = 0;
  88        for (i = 0; field[i].size != 0; i++) {
  89                err = xen_pcibk_config_add_field(dev, &field[i]);
  90                if (err)
  91                        break;
  92        }
  93        return err;
  94}
  95
  96static inline int xen_pcibk_config_add_fields_offset(struct pci_dev *dev,
  97                                        const struct config_field *field,
  98                                        unsigned int offset)
  99{
 100        int i, err = 0;
 101        for (i = 0; field[i].size != 0; i++) {
 102                err = xen_pcibk_config_add_field_offset(dev, &field[i], offset);
 103                if (err)
 104                        break;
 105        }
 106        return err;
 107}
 108
 109/* Read/Write the real configuration space */
 110int xen_pcibk_read_config_byte(struct pci_dev *dev, int offset, u8 *value,
 111                               void *data);
 112int xen_pcibk_read_config_word(struct pci_dev *dev, int offset, u16 *value,
 113                               void *data);
 114int xen_pcibk_read_config_dword(struct pci_dev *dev, int offset, u32 *value,
 115                                void *data);
 116int xen_pcibk_write_config_byte(struct pci_dev *dev, int offset, u8 value,
 117                                 void *data);
 118int xen_pcibk_write_config_word(struct pci_dev *dev, int offset, u16 value,
 119                                void *data);
 120int xen_pcibk_write_config_dword(struct pci_dev *dev, int offset, u32 value,
 121                                 void *data);
 122
 123int xen_pcibk_config_capability_init(void);
 124
 125int xen_pcibk_config_header_add_fields(struct pci_dev *dev);
 126int xen_pcibk_config_capability_add_fields(struct pci_dev *dev);
 127
 128#endif                          /* __XEN_PCIBACK_CONF_SPACE_H__ */
 129