Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * PCI Backend - Common data structures for overriding the configuration space
0004  *
0005  * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
0006  */
0007 
0008 #ifndef __XEN_PCIBACK_CONF_SPACE_H__
0009 #define __XEN_PCIBACK_CONF_SPACE_H__
0010 
0011 #include <linux/list.h>
0012 #include <linux/err.h>
0013 
0014 /* conf_field_init can return an errno in a ptr with ERR_PTR() */
0015 typedef void *(*conf_field_init) (struct pci_dev *dev, int offset);
0016 typedef void (*conf_field_reset) (struct pci_dev *dev, int offset, void *data);
0017 typedef void (*conf_field_free) (struct pci_dev *dev, int offset, void *data);
0018 
0019 typedef int (*conf_dword_write) (struct pci_dev *dev, int offset, u32 value,
0020                  void *data);
0021 typedef int (*conf_word_write) (struct pci_dev *dev, int offset, u16 value,
0022                 void *data);
0023 typedef int (*conf_byte_write) (struct pci_dev *dev, int offset, u8 value,
0024                 void *data);
0025 typedef int (*conf_dword_read) (struct pci_dev *dev, int offset, u32 *value,
0026                 void *data);
0027 typedef int (*conf_word_read) (struct pci_dev *dev, int offset, u16 *value,
0028                    void *data);
0029 typedef int (*conf_byte_read) (struct pci_dev *dev, int offset, u8 *value,
0030                    void *data);
0031 
0032 /* These are the fields within the configuration space which we
0033  * are interested in intercepting reads/writes to and changing their
0034  * values.
0035  */
0036 struct config_field {
0037     unsigned int offset;
0038     unsigned int size;
0039     unsigned int mask;
0040     conf_field_init init;
0041     conf_field_reset reset;
0042     conf_field_free release;
0043     void (*clean) (struct config_field *field);
0044     union {
0045         struct {
0046             conf_dword_write write;
0047             conf_dword_read read;
0048         } dw;
0049         struct {
0050             conf_word_write write;
0051             conf_word_read read;
0052         } w;
0053         struct {
0054             conf_byte_write write;
0055             conf_byte_read read;
0056         } b;
0057     } u;
0058     struct list_head list;
0059 };
0060 
0061 struct config_field_entry {
0062     struct list_head list;
0063     const struct config_field *field;
0064     unsigned int base_offset;
0065     void *data;
0066 };
0067 
0068 #define INTERRUPT_TYPE_NONE (0)
0069 #define INTERRUPT_TYPE_INTX (1<<0)
0070 #define INTERRUPT_TYPE_MSI  (1<<1)
0071 #define INTERRUPT_TYPE_MSIX (1<<2)
0072 
0073 extern bool xen_pcibk_permissive;
0074 
0075 #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
0076 
0077 /* Add fields to a device - the add_fields macro expects to get a pointer to
0078  * the first entry in an array (of which the ending is marked by size==0)
0079  */
0080 int xen_pcibk_config_add_field_offset(struct pci_dev *dev,
0081                     const struct config_field *field,
0082                     unsigned int offset);
0083 
0084 static inline int xen_pcibk_config_add_field(struct pci_dev *dev,
0085                        const struct config_field *field)
0086 {
0087     return xen_pcibk_config_add_field_offset(dev, field, 0);
0088 }
0089 
0090 static inline int xen_pcibk_config_add_fields(struct pci_dev *dev,
0091                         const struct config_field *field)
0092 {
0093     int i, err = 0;
0094     for (i = 0; field[i].size != 0; i++) {
0095         err = xen_pcibk_config_add_field(dev, &field[i]);
0096         if (err)
0097             break;
0098     }
0099     return err;
0100 }
0101 
0102 static inline int xen_pcibk_config_add_fields_offset(struct pci_dev *dev,
0103                     const struct config_field *field,
0104                     unsigned int offset)
0105 {
0106     int i, err = 0;
0107     for (i = 0; field[i].size != 0; i++) {
0108         err = xen_pcibk_config_add_field_offset(dev, &field[i], offset);
0109         if (err)
0110             break;
0111     }
0112     return err;
0113 }
0114 
0115 /* Read/Write the real configuration space */
0116 int xen_pcibk_read_config_byte(struct pci_dev *dev, int offset, u8 *value,
0117                    void *data);
0118 int xen_pcibk_read_config_word(struct pci_dev *dev, int offset, u16 *value,
0119                    void *data);
0120 int xen_pcibk_read_config_dword(struct pci_dev *dev, int offset, u32 *value,
0121                 void *data);
0122 int xen_pcibk_write_config_byte(struct pci_dev *dev, int offset, u8 value,
0123                  void *data);
0124 int xen_pcibk_write_config_word(struct pci_dev *dev, int offset, u16 value,
0125                 void *data);
0126 int xen_pcibk_write_config_dword(struct pci_dev *dev, int offset, u32 value,
0127                  void *data);
0128 
0129 int xen_pcibk_config_capability_init(void);
0130 
0131 int xen_pcibk_config_header_add_fields(struct pci_dev *dev);
0132 int xen_pcibk_config_capability_add_fields(struct pci_dev *dev);
0133 
0134 int xen_pcibk_get_interrupt_type(struct pci_dev *dev);
0135 
0136 #endif              /* __XEN_PCIBACK_CONF_SPACE_H__ */