xref: /linux/drivers/xen/xen-pciback/conf_space.h (revision 8014bcc86ef112eab9ee1db312dba4e6b608cf89)
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