130edc14bSKonrad Rzeszutek Wilk /* 230edc14bSKonrad Rzeszutek Wilk * PCI Backend - Common data structures for overriding the configuration space 330edc14bSKonrad Rzeszutek Wilk * 430edc14bSKonrad Rzeszutek Wilk * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 530edc14bSKonrad Rzeszutek Wilk */ 630edc14bSKonrad Rzeszutek Wilk 730edc14bSKonrad Rzeszutek Wilk #ifndef __XEN_PCIBACK_CONF_SPACE_H__ 830edc14bSKonrad Rzeszutek Wilk #define __XEN_PCIBACK_CONF_SPACE_H__ 930edc14bSKonrad Rzeszutek Wilk 1030edc14bSKonrad Rzeszutek Wilk #include <linux/list.h> 1130edc14bSKonrad Rzeszutek Wilk #include <linux/err.h> 1230edc14bSKonrad Rzeszutek Wilk 1330edc14bSKonrad Rzeszutek Wilk /* conf_field_init can return an errno in a ptr with ERR_PTR() */ 1430edc14bSKonrad Rzeszutek Wilk typedef void *(*conf_field_init) (struct pci_dev *dev, int offset); 1530edc14bSKonrad Rzeszutek Wilk typedef void (*conf_field_reset) (struct pci_dev *dev, int offset, void *data); 1630edc14bSKonrad Rzeszutek Wilk typedef void (*conf_field_free) (struct pci_dev *dev, int offset, void *data); 1730edc14bSKonrad Rzeszutek Wilk 1830edc14bSKonrad Rzeszutek Wilk typedef int (*conf_dword_write) (struct pci_dev *dev, int offset, u32 value, 1930edc14bSKonrad Rzeszutek Wilk void *data); 2030edc14bSKonrad Rzeszutek Wilk typedef int (*conf_word_write) (struct pci_dev *dev, int offset, u16 value, 2130edc14bSKonrad Rzeszutek Wilk void *data); 2230edc14bSKonrad Rzeszutek Wilk typedef int (*conf_byte_write) (struct pci_dev *dev, int offset, u8 value, 2330edc14bSKonrad Rzeszutek Wilk void *data); 2430edc14bSKonrad Rzeszutek Wilk typedef int (*conf_dword_read) (struct pci_dev *dev, int offset, u32 *value, 2530edc14bSKonrad Rzeszutek Wilk void *data); 2630edc14bSKonrad Rzeszutek Wilk typedef int (*conf_word_read) (struct pci_dev *dev, int offset, u16 *value, 2730edc14bSKonrad Rzeszutek Wilk void *data); 2830edc14bSKonrad Rzeszutek Wilk typedef int (*conf_byte_read) (struct pci_dev *dev, int offset, u8 *value, 2930edc14bSKonrad Rzeszutek Wilk void *data); 3030edc14bSKonrad Rzeszutek Wilk 3130edc14bSKonrad Rzeszutek Wilk /* These are the fields within the configuration space which we 3230edc14bSKonrad Rzeszutek Wilk * are interested in intercepting reads/writes to and changing their 3330edc14bSKonrad Rzeszutek Wilk * values. 3430edc14bSKonrad Rzeszutek Wilk */ 3530edc14bSKonrad Rzeszutek Wilk struct config_field { 3630edc14bSKonrad Rzeszutek Wilk unsigned int offset; 3730edc14bSKonrad Rzeszutek Wilk unsigned int size; 3830edc14bSKonrad Rzeszutek Wilk unsigned int mask; 3930edc14bSKonrad Rzeszutek Wilk conf_field_init init; 4030edc14bSKonrad Rzeszutek Wilk conf_field_reset reset; 4130edc14bSKonrad Rzeszutek Wilk conf_field_free release; 4230edc14bSKonrad Rzeszutek Wilk void (*clean) (struct config_field *field); 4330edc14bSKonrad Rzeszutek Wilk union { 4430edc14bSKonrad Rzeszutek Wilk struct { 4530edc14bSKonrad Rzeszutek Wilk conf_dword_write write; 4630edc14bSKonrad Rzeszutek Wilk conf_dword_read read; 4730edc14bSKonrad Rzeszutek Wilk } dw; 4830edc14bSKonrad Rzeszutek Wilk struct { 4930edc14bSKonrad Rzeszutek Wilk conf_word_write write; 5030edc14bSKonrad Rzeszutek Wilk conf_word_read read; 5130edc14bSKonrad Rzeszutek Wilk } w; 5230edc14bSKonrad Rzeszutek Wilk struct { 5330edc14bSKonrad Rzeszutek Wilk conf_byte_write write; 5430edc14bSKonrad Rzeszutek Wilk conf_byte_read read; 5530edc14bSKonrad Rzeszutek Wilk } b; 5630edc14bSKonrad Rzeszutek Wilk } u; 5730edc14bSKonrad Rzeszutek Wilk struct list_head list; 5830edc14bSKonrad Rzeszutek Wilk }; 5930edc14bSKonrad Rzeszutek Wilk 6030edc14bSKonrad Rzeszutek Wilk struct config_field_entry { 6130edc14bSKonrad Rzeszutek Wilk struct list_head list; 6230edc14bSKonrad Rzeszutek Wilk const struct config_field *field; 6330edc14bSKonrad Rzeszutek Wilk unsigned int base_offset; 6430edc14bSKonrad Rzeszutek Wilk void *data; 6530edc14bSKonrad Rzeszutek Wilk }; 6630edc14bSKonrad Rzeszutek Wilk 67*8014bcc8SBen Hutchings extern bool xen_pcibk_permissive; 68af6fc858SJan Beulich 6930edc14bSKonrad Rzeszutek Wilk #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset) 7030edc14bSKonrad Rzeszutek Wilk 7130edc14bSKonrad Rzeszutek Wilk /* Add fields to a device - the add_fields macro expects to get a pointer to 7230edc14bSKonrad Rzeszutek Wilk * the first entry in an array (of which the ending is marked by size==0) 7330edc14bSKonrad Rzeszutek Wilk */ 74a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_config_add_field_offset(struct pci_dev *dev, 7530edc14bSKonrad Rzeszutek Wilk const struct config_field *field, 7630edc14bSKonrad Rzeszutek Wilk unsigned int offset); 7730edc14bSKonrad Rzeszutek Wilk 78a92336a1SKonrad Rzeszutek Wilk static inline int xen_pcibk_config_add_field(struct pci_dev *dev, 7930edc14bSKonrad Rzeszutek Wilk const struct config_field *field) 8030edc14bSKonrad Rzeszutek Wilk { 81a92336a1SKonrad Rzeszutek Wilk return xen_pcibk_config_add_field_offset(dev, field, 0); 8230edc14bSKonrad Rzeszutek Wilk } 8330edc14bSKonrad Rzeszutek Wilk 84a92336a1SKonrad Rzeszutek Wilk static inline int xen_pcibk_config_add_fields(struct pci_dev *dev, 8530edc14bSKonrad Rzeszutek Wilk const struct config_field *field) 8630edc14bSKonrad Rzeszutek Wilk { 8730edc14bSKonrad Rzeszutek Wilk int i, err = 0; 8830edc14bSKonrad Rzeszutek Wilk for (i = 0; field[i].size != 0; i++) { 89a92336a1SKonrad Rzeszutek Wilk err = xen_pcibk_config_add_field(dev, &field[i]); 9030edc14bSKonrad Rzeszutek Wilk if (err) 9130edc14bSKonrad Rzeszutek Wilk break; 9230edc14bSKonrad Rzeszutek Wilk } 9330edc14bSKonrad Rzeszutek Wilk return err; 9430edc14bSKonrad Rzeszutek Wilk } 9530edc14bSKonrad Rzeszutek Wilk 96a92336a1SKonrad Rzeszutek Wilk static inline int xen_pcibk_config_add_fields_offset(struct pci_dev *dev, 9730edc14bSKonrad Rzeszutek Wilk const struct config_field *field, 9830edc14bSKonrad Rzeszutek Wilk unsigned int offset) 9930edc14bSKonrad Rzeszutek Wilk { 10030edc14bSKonrad Rzeszutek Wilk int i, err = 0; 10130edc14bSKonrad Rzeszutek Wilk for (i = 0; field[i].size != 0; i++) { 102a92336a1SKonrad Rzeszutek Wilk err = xen_pcibk_config_add_field_offset(dev, &field[i], offset); 10330edc14bSKonrad Rzeszutek Wilk if (err) 10430edc14bSKonrad Rzeszutek Wilk break; 10530edc14bSKonrad Rzeszutek Wilk } 10630edc14bSKonrad Rzeszutek Wilk return err; 10730edc14bSKonrad Rzeszutek Wilk } 10830edc14bSKonrad Rzeszutek Wilk 10930edc14bSKonrad Rzeszutek Wilk /* Read/Write the real configuration space */ 110a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_read_config_byte(struct pci_dev *dev, int offset, u8 *value, 11130edc14bSKonrad Rzeszutek Wilk void *data); 112a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_read_config_word(struct pci_dev *dev, int offset, u16 *value, 11330edc14bSKonrad Rzeszutek Wilk void *data); 114a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_read_config_dword(struct pci_dev *dev, int offset, u32 *value, 11530edc14bSKonrad Rzeszutek Wilk void *data); 116a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_write_config_byte(struct pci_dev *dev, int offset, u8 value, 11730edc14bSKonrad Rzeszutek Wilk void *data); 118a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_write_config_word(struct pci_dev *dev, int offset, u16 value, 11930edc14bSKonrad Rzeszutek Wilk void *data); 120a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_write_config_dword(struct pci_dev *dev, int offset, u32 value, 12130edc14bSKonrad Rzeszutek Wilk void *data); 12230edc14bSKonrad Rzeszutek Wilk 123a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_config_capability_init(void); 12430edc14bSKonrad Rzeszutek Wilk 125a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_config_header_add_fields(struct pci_dev *dev); 126a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_config_capability_add_fields(struct pci_dev *dev); 12730edc14bSKonrad Rzeszutek Wilk 12830edc14bSKonrad Rzeszutek Wilk #endif /* __XEN_PCIBACK_CONF_SPACE_H__ */ 129