1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 230edc14bSKonrad Rzeszutek Wilk /* 330edc14bSKonrad Rzeszutek Wilk * PCI Backend - Common data structures for overriding the configuration space 430edc14bSKonrad Rzeszutek Wilk * 530edc14bSKonrad Rzeszutek Wilk * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 630edc14bSKonrad Rzeszutek Wilk */ 730edc14bSKonrad Rzeszutek Wilk 830edc14bSKonrad Rzeszutek Wilk #ifndef __XEN_PCIBACK_CONF_SPACE_H__ 930edc14bSKonrad Rzeszutek Wilk #define __XEN_PCIBACK_CONF_SPACE_H__ 1030edc14bSKonrad Rzeszutek Wilk 1130edc14bSKonrad Rzeszutek Wilk #include <linux/list.h> 1230edc14bSKonrad Rzeszutek Wilk #include <linux/err.h> 1330edc14bSKonrad Rzeszutek Wilk 1430edc14bSKonrad Rzeszutek Wilk /* conf_field_init can return an errno in a ptr with ERR_PTR() */ 1530edc14bSKonrad Rzeszutek Wilk typedef void *(*conf_field_init) (struct pci_dev *dev, int offset); 1630edc14bSKonrad Rzeszutek Wilk typedef void (*conf_field_reset) (struct pci_dev *dev, int offset, void *data); 1730edc14bSKonrad Rzeszutek Wilk typedef void (*conf_field_free) (struct pci_dev *dev, int offset, void *data); 1830edc14bSKonrad Rzeszutek Wilk 1930edc14bSKonrad Rzeszutek Wilk typedef int (*conf_dword_write) (struct pci_dev *dev, int offset, u32 value, 2030edc14bSKonrad Rzeszutek Wilk void *data); 2130edc14bSKonrad Rzeszutek Wilk typedef int (*conf_word_write) (struct pci_dev *dev, int offset, u16 value, 2230edc14bSKonrad Rzeszutek Wilk void *data); 2330edc14bSKonrad Rzeszutek Wilk typedef int (*conf_byte_write) (struct pci_dev *dev, int offset, u8 value, 2430edc14bSKonrad Rzeszutek Wilk void *data); 2530edc14bSKonrad Rzeszutek Wilk typedef int (*conf_dword_read) (struct pci_dev *dev, int offset, u32 *value, 2630edc14bSKonrad Rzeszutek Wilk void *data); 2730edc14bSKonrad Rzeszutek Wilk typedef int (*conf_word_read) (struct pci_dev *dev, int offset, u16 *value, 2830edc14bSKonrad Rzeszutek Wilk void *data); 2930edc14bSKonrad Rzeszutek Wilk typedef int (*conf_byte_read) (struct pci_dev *dev, int offset, u8 *value, 3030edc14bSKonrad Rzeszutek Wilk void *data); 3130edc14bSKonrad Rzeszutek Wilk 3230edc14bSKonrad Rzeszutek Wilk /* These are the fields within the configuration space which we 3330edc14bSKonrad Rzeszutek Wilk * are interested in intercepting reads/writes to and changing their 3430edc14bSKonrad Rzeszutek Wilk * values. 3530edc14bSKonrad Rzeszutek Wilk */ 3630edc14bSKonrad Rzeszutek Wilk struct config_field { 3730edc14bSKonrad Rzeszutek Wilk unsigned int offset; 3830edc14bSKonrad Rzeszutek Wilk unsigned int size; 3930edc14bSKonrad Rzeszutek Wilk unsigned int mask; 4030edc14bSKonrad Rzeszutek Wilk conf_field_init init; 4130edc14bSKonrad Rzeszutek Wilk conf_field_reset reset; 4230edc14bSKonrad Rzeszutek Wilk conf_field_free release; 4330edc14bSKonrad Rzeszutek Wilk void (*clean) (struct config_field *field); 4430edc14bSKonrad Rzeszutek Wilk union { 4530edc14bSKonrad Rzeszutek Wilk struct { 4630edc14bSKonrad Rzeszutek Wilk conf_dword_write write; 4730edc14bSKonrad Rzeszutek Wilk conf_dword_read read; 4830edc14bSKonrad Rzeszutek Wilk } dw; 4930edc14bSKonrad Rzeszutek Wilk struct { 5030edc14bSKonrad Rzeszutek Wilk conf_word_write write; 5130edc14bSKonrad Rzeszutek Wilk conf_word_read read; 5230edc14bSKonrad Rzeszutek Wilk } w; 5330edc14bSKonrad Rzeszutek Wilk struct { 5430edc14bSKonrad Rzeszutek Wilk conf_byte_write write; 5530edc14bSKonrad Rzeszutek Wilk conf_byte_read read; 5630edc14bSKonrad Rzeszutek Wilk } b; 5730edc14bSKonrad Rzeszutek Wilk } u; 5830edc14bSKonrad Rzeszutek Wilk struct list_head list; 5930edc14bSKonrad Rzeszutek Wilk }; 6030edc14bSKonrad Rzeszutek Wilk 6130edc14bSKonrad Rzeszutek Wilk struct config_field_entry { 6230edc14bSKonrad Rzeszutek Wilk struct list_head list; 6330edc14bSKonrad Rzeszutek Wilk const struct config_field *field; 6430edc14bSKonrad Rzeszutek Wilk unsigned int base_offset; 6530edc14bSKonrad Rzeszutek Wilk void *data; 6630edc14bSKonrad Rzeszutek Wilk }; 6730edc14bSKonrad Rzeszutek Wilk 688014bcc8SBen Hutchings extern bool xen_pcibk_permissive; 69af6fc858SJan Beulich 7030edc14bSKonrad Rzeszutek Wilk #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset) 7130edc14bSKonrad Rzeszutek Wilk 7230edc14bSKonrad Rzeszutek Wilk /* Add fields to a device - the add_fields macro expects to get a pointer to 7330edc14bSKonrad Rzeszutek Wilk * the first entry in an array (of which the ending is marked by size==0) 7430edc14bSKonrad Rzeszutek Wilk */ 75a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_config_add_field_offset(struct pci_dev *dev, 7630edc14bSKonrad Rzeszutek Wilk const struct config_field *field, 7730edc14bSKonrad Rzeszutek Wilk unsigned int offset); 7830edc14bSKonrad Rzeszutek Wilk 79a92336a1SKonrad Rzeszutek Wilk static inline int xen_pcibk_config_add_field(struct pci_dev *dev, 8030edc14bSKonrad Rzeszutek Wilk const struct config_field *field) 8130edc14bSKonrad Rzeszutek Wilk { 82a92336a1SKonrad Rzeszutek Wilk return xen_pcibk_config_add_field_offset(dev, field, 0); 8330edc14bSKonrad Rzeszutek Wilk } 8430edc14bSKonrad Rzeszutek Wilk 85a92336a1SKonrad Rzeszutek Wilk static inline int xen_pcibk_config_add_fields(struct pci_dev *dev, 8630edc14bSKonrad Rzeszutek Wilk const struct config_field *field) 8730edc14bSKonrad Rzeszutek Wilk { 8830edc14bSKonrad Rzeszutek Wilk int i, err = 0; 8930edc14bSKonrad Rzeszutek Wilk for (i = 0; field[i].size != 0; i++) { 90a92336a1SKonrad Rzeszutek Wilk err = xen_pcibk_config_add_field(dev, &field[i]); 9130edc14bSKonrad Rzeszutek Wilk if (err) 9230edc14bSKonrad Rzeszutek Wilk break; 9330edc14bSKonrad Rzeszutek Wilk } 9430edc14bSKonrad Rzeszutek Wilk return err; 9530edc14bSKonrad Rzeszutek Wilk } 9630edc14bSKonrad Rzeszutek Wilk 97a92336a1SKonrad Rzeszutek Wilk static inline int xen_pcibk_config_add_fields_offset(struct pci_dev *dev, 9830edc14bSKonrad Rzeszutek Wilk const struct config_field *field, 9930edc14bSKonrad Rzeszutek Wilk unsigned int offset) 10030edc14bSKonrad Rzeszutek Wilk { 10130edc14bSKonrad Rzeszutek Wilk int i, err = 0; 10230edc14bSKonrad Rzeszutek Wilk for (i = 0; field[i].size != 0; i++) { 103a92336a1SKonrad Rzeszutek Wilk err = xen_pcibk_config_add_field_offset(dev, &field[i], offset); 10430edc14bSKonrad Rzeszutek Wilk if (err) 10530edc14bSKonrad Rzeszutek Wilk break; 10630edc14bSKonrad Rzeszutek Wilk } 10730edc14bSKonrad Rzeszutek Wilk return err; 10830edc14bSKonrad Rzeszutek Wilk } 10930edc14bSKonrad Rzeszutek Wilk 11030edc14bSKonrad Rzeszutek Wilk /* Read/Write the real configuration space */ 111a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_read_config_byte(struct pci_dev *dev, int offset, u8 *value, 11230edc14bSKonrad Rzeszutek Wilk void *data); 113a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_read_config_word(struct pci_dev *dev, int offset, u16 *value, 11430edc14bSKonrad Rzeszutek Wilk void *data); 115a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_read_config_dword(struct pci_dev *dev, int offset, u32 *value, 11630edc14bSKonrad Rzeszutek Wilk void *data); 117a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_write_config_byte(struct pci_dev *dev, int offset, u8 value, 11830edc14bSKonrad Rzeszutek Wilk void *data); 119a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_write_config_word(struct pci_dev *dev, int offset, u16 value, 12030edc14bSKonrad Rzeszutek Wilk void *data); 121a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_write_config_dword(struct pci_dev *dev, int offset, u32 value, 12230edc14bSKonrad Rzeszutek Wilk void *data); 12330edc14bSKonrad Rzeszutek Wilk 124a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_config_capability_init(void); 12530edc14bSKonrad Rzeszutek Wilk 126a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_config_header_add_fields(struct pci_dev *dev); 127a92336a1SKonrad Rzeszutek Wilk int xen_pcibk_config_capability_add_fields(struct pci_dev *dev); 12830edc14bSKonrad Rzeszutek Wilk 12930edc14bSKonrad Rzeszutek Wilk #endif /* __XEN_PCIBACK_CONF_SPACE_H__ */ 130