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
  67#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
  68
  69/* Add fields to a device - the add_fields macro expects to get a pointer to
  70 * the first entry in an array (of which the ending is marked by size==0)
  71 */
  72int xen_pcibk_config_add_field_offset(struct pci_dev *dev,
  73                                    const struct config_field *field,
  74                                    unsigned int offset);
  75
  76static inline int xen_pcibk_config_add_field(struct pci_dev *dev,
  77                                           const struct config_field *field)
  78{
  79        return xen_pcibk_config_add_field_offset(dev, field, 0);
  80}
  81
  82static inline int xen_pcibk_config_add_fields(struct pci_dev *dev,
  83                                            const struct config_field *field)
  84{
  85        int i, err = 0;
  86        for (i = 0; field[i].size != 0; i++) {
  87                err = xen_pcibk_config_add_field(dev, &field[i]);
  88                if (err)
  89                        break;
  90        }
  91        return err;
  92}
  93
  94static inline int xen_pcibk_config_add_fields_offset(struct pci_dev *dev,
  95                                        const struct config_field *field,
  96                                        unsigned int offset)
  97{
  98        int i, err = 0;
  99        for (i = 0; field[i].size != 0; i++) {
 100                err = xen_pcibk_config_add_field_offset(dev, &field[i], offset);
 101                if (err)
 102                        break;
 103        }
 104        return err;
 105}
 106
 107/* Read/Write the real configuration space */
 108int xen_pcibk_read_config_byte(struct pci_dev *dev, int offset, u8 *value,
 109                               void *data);
 110int xen_pcibk_read_config_word(struct pci_dev *dev, int offset, u16 *value,
 111                               void *data);
 112int xen_pcibk_read_config_dword(struct pci_dev *dev, int offset, u32 *value,
 113                                void *data);
 114int xen_pcibk_write_config_byte(struct pci_dev *dev, int offset, u8 value,
 115                                 void *data);
 116int xen_pcibk_write_config_word(struct pci_dev *dev, int offset, u16 value,
 117                                void *data);
 118int xen_pcibk_write_config_dword(struct pci_dev *dev, int offset, u32 value,
 119                                 void *data);
 120
 121int xen_pcibk_config_capability_init(void);
 122
 123int xen_pcibk_config_header_add_fields(struct pci_dev *dev);
 124int xen_pcibk_config_capability_add_fields(struct pci_dev *dev);
 125
 126#endif                          /* __XEN_PCIBACK_CONF_SPACE_H__ */
 127