Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
conf_space.h
Go to the documentation of this file.
1 /*
2  * PCI Backend - Common data structures for overriding the configuration space
3  *
4  * Author: Ryan Wilson <[email protected]>
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() */
14 typedef void *(*conf_field_init) (struct pci_dev *dev, int offset);
15 typedef void (*conf_field_reset) (struct pci_dev *dev, int offset, void *data);
16 typedef void (*conf_field_free) (struct pci_dev *dev, int offset, void *data);
17 
18 typedef int (*conf_dword_write) (struct pci_dev *dev, int offset, u32 value,
19  void *data);
20 typedef int (*conf_word_write) (struct pci_dev *dev, int offset, u16 value,
21  void *data);
22 typedef int (*conf_byte_write) (struct pci_dev *dev, int offset, u8 value,
23  void *data);
24 typedef int (*conf_dword_read) (struct pci_dev *dev, int offset, u32 *value,
25  void *data);
26 typedef int (*conf_word_read) (struct pci_dev *dev, int offset, u16 *value,
27  void *data);
28 typedef 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  */
35 struct config_field {
36  unsigned int offset;
37  unsigned int size;
38  unsigned int mask;
42  void (*clean) (struct config_field *field);
43  union {
44  struct {
47  } dw;
48  struct {
51  } w;
52  struct {
55  } b;
56  } u;
57  struct list_head list;
58 };
59 
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  */
73  const struct config_field *field,
74  unsigned int offset);
75 
76 static 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 
82 static 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 
94 static 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 */
108 int xen_pcibk_read_config_byte(struct pci_dev *dev, int offset, u8 *value,
109  void *data);
110 int xen_pcibk_read_config_word(struct pci_dev *dev, int offset, u16 *value,
111  void *data);
112 int xen_pcibk_read_config_dword(struct pci_dev *dev, int offset, u32 *value,
113  void *data);
114 int xen_pcibk_write_config_byte(struct pci_dev *dev, int offset, u8 value,
115  void *data);
116 int xen_pcibk_write_config_word(struct pci_dev *dev, int offset, u16 value,
117  void *data);
118 int xen_pcibk_write_config_dword(struct pci_dev *dev, int offset, u32 value,
119  void *data);
120 
122 
125 
126 #endif /* __XEN_PCIBACK_CONF_SPACE_H__ */