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