.. | .. |
---|
53 | 53 | phys_addr_t addr); |
---|
54 | 54 | int (*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts); |
---|
55 | 55 | int (*get_msi)(struct pci_epc *epc, u8 func_no); |
---|
56 | | - int (*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts); |
---|
| 56 | + int (*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts, |
---|
| 57 | + enum pci_barno, u32 offset); |
---|
57 | 58 | int (*get_msix)(struct pci_epc *epc, u8 func_no); |
---|
58 | 59 | int (*raise_irq)(struct pci_epc *epc, u8 func_no, |
---|
59 | 60 | enum pci_epc_irq_type type, u16 interrupt_num); |
---|
60 | 61 | int (*start)(struct pci_epc *epc); |
---|
61 | 62 | void (*stop)(struct pci_epc *epc); |
---|
| 63 | + const struct pci_epc_features* (*get_features)(struct pci_epc *epc, |
---|
| 64 | + u8 func_no); |
---|
62 | 65 | struct module *owner; |
---|
63 | 66 | }; |
---|
64 | 67 | |
---|
65 | 68 | /** |
---|
| 69 | + * struct pci_epc_mem_window - address window of the endpoint controller |
---|
| 70 | + * @phys_base: physical base address of the PCI address window |
---|
| 71 | + * @size: the size of the PCI address window |
---|
| 72 | + * @page_size: size of each page |
---|
| 73 | + */ |
---|
| 74 | +struct pci_epc_mem_window { |
---|
| 75 | + phys_addr_t phys_base; |
---|
| 76 | + size_t size; |
---|
| 77 | + size_t page_size; |
---|
| 78 | +}; |
---|
| 79 | + |
---|
| 80 | +/** |
---|
66 | 81 | * struct pci_epc_mem - address space of the endpoint controller |
---|
67 | | - * @phys_base: physical base address of the PCI address space |
---|
68 | | - * @size: the size of the PCI address space |
---|
| 82 | + * @window: address window of the endpoint controller |
---|
69 | 83 | * @bitmap: bitmap to manage the PCI address space |
---|
70 | 84 | * @pages: number of bits representing the address region |
---|
71 | | - * @page_size: size of each page |
---|
72 | 85 | * @lock: mutex to protect bitmap |
---|
73 | 86 | */ |
---|
74 | 87 | struct pci_epc_mem { |
---|
75 | | - phys_addr_t phys_base; |
---|
76 | | - size_t size; |
---|
| 88 | + struct pci_epc_mem_window window; |
---|
77 | 89 | unsigned long *bitmap; |
---|
78 | | - size_t page_size; |
---|
79 | 90 | int pages; |
---|
80 | 91 | /* mutex to protect against concurrent access for memory allocation*/ |
---|
81 | 92 | struct mutex lock; |
---|
.. | .. |
---|
86 | 97 | * @dev: PCI EPC device |
---|
87 | 98 | * @pci_epf: list of endpoint functions present in this EPC device |
---|
88 | 99 | * @ops: function pointers for performing endpoint operations |
---|
89 | | - * @mem: address space of the endpoint controller |
---|
| 100 | + * @windows: array of address space of the endpoint controller |
---|
| 101 | + * @mem: first window of the endpoint controller, which corresponds to |
---|
| 102 | + * default address space of the endpoint controller supporting |
---|
| 103 | + * single window. |
---|
| 104 | + * @num_windows: number of windows supported by device |
---|
90 | 105 | * @max_functions: max number of functions that can be configured in this EPC |
---|
91 | 106 | * @group: configfs group representing the PCI EPC device |
---|
92 | | - * @lock: spinlock to protect pci_epc ops |
---|
| 107 | + * @lock: mutex to protect pci_epc ops |
---|
| 108 | + * @function_num_map: bitmap to manage physical function number |
---|
| 109 | + * @notifier: used to notify EPF of any EPC events (like linkup) |
---|
93 | 110 | */ |
---|
94 | 111 | struct pci_epc { |
---|
95 | 112 | struct device dev; |
---|
96 | 113 | struct list_head pci_epf; |
---|
97 | 114 | const struct pci_epc_ops *ops; |
---|
| 115 | + struct pci_epc_mem **windows; |
---|
98 | 116 | struct pci_epc_mem *mem; |
---|
| 117 | + unsigned int num_windows; |
---|
99 | 118 | u8 max_functions; |
---|
100 | 119 | struct config_group *group; |
---|
101 | | - /* spinlock to protect against concurrent access of EP controller */ |
---|
102 | | - spinlock_t lock; |
---|
103 | | - unsigned int features; |
---|
| 120 | + /* mutex to protect against concurrent access of EP controller */ |
---|
| 121 | + struct mutex lock; |
---|
| 122 | + unsigned long function_num_map; |
---|
| 123 | + struct atomic_notifier_head notifier; |
---|
104 | 124 | }; |
---|
105 | 125 | |
---|
106 | | -#define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0) |
---|
107 | | -#define EPC_FEATURE_BAR_MASK (BIT(1) | BIT(2) | BIT(3)) |
---|
108 | | -#define EPC_FEATURE_MSIX_AVAILABLE BIT(4) |
---|
109 | | -#define EPC_FEATURE_SET_BAR(features, bar) \ |
---|
110 | | - (features |= (EPC_FEATURE_BAR_MASK & (bar << 1))) |
---|
111 | | -#define EPC_FEATURE_GET_BAR(features) \ |
---|
112 | | - ((features & EPC_FEATURE_BAR_MASK) >> 1) |
---|
| 126 | +/** |
---|
| 127 | + * struct pci_epc_features - features supported by a EPC device per function |
---|
| 128 | + * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up |
---|
| 129 | + * @msi_capable: indicate if the endpoint function has MSI capability |
---|
| 130 | + * @msix_capable: indicate if the endpoint function has MSI-X capability |
---|
| 131 | + * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver |
---|
| 132 | + * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs |
---|
| 133 | + * @bar_fixed_size: Array specifying the size supported by each BAR |
---|
| 134 | + * @align: alignment size required for BAR buffer allocation |
---|
| 135 | + */ |
---|
| 136 | +struct pci_epc_features { |
---|
| 137 | + unsigned int linkup_notifier : 1; |
---|
| 138 | + unsigned int core_init_notifier : 1; |
---|
| 139 | + unsigned int msi_capable : 1; |
---|
| 140 | + unsigned int msix_capable : 1; |
---|
| 141 | + u8 reserved_bar; |
---|
| 142 | + u8 bar_fixed_64bit; |
---|
| 143 | + u64 bar_fixed_size[PCI_STD_NUM_BARS]; |
---|
| 144 | + size_t align; |
---|
| 145 | +}; |
---|
113 | 146 | |
---|
114 | 147 | #define to_pci_epc(device) container_of((device), struct pci_epc, dev) |
---|
115 | 148 | |
---|
.. | .. |
---|
117 | 150 | __pci_epc_create((dev), (ops), THIS_MODULE) |
---|
118 | 151 | #define devm_pci_epc_create(dev, ops) \ |
---|
119 | 152 | __devm_pci_epc_create((dev), (ops), THIS_MODULE) |
---|
120 | | - |
---|
121 | | -#define pci_epc_mem_init(epc, phys_addr, size) \ |
---|
122 | | - __pci_epc_mem_init((epc), (phys_addr), (size), PAGE_SIZE) |
---|
123 | 153 | |
---|
124 | 154 | static inline void epc_set_drvdata(struct pci_epc *epc, void *data) |
---|
125 | 155 | { |
---|
.. | .. |
---|
129 | 159 | static inline void *epc_get_drvdata(struct pci_epc *epc) |
---|
130 | 160 | { |
---|
131 | 161 | return dev_get_drvdata(&epc->dev); |
---|
| 162 | +} |
---|
| 163 | + |
---|
| 164 | +static inline int |
---|
| 165 | +pci_epc_register_notifier(struct pci_epc *epc, struct notifier_block *nb) |
---|
| 166 | +{ |
---|
| 167 | + return atomic_notifier_chain_register(&epc->notifier, nb); |
---|
132 | 168 | } |
---|
133 | 169 | |
---|
134 | 170 | struct pci_epc * |
---|
.. | .. |
---|
141 | 177 | void pci_epc_destroy(struct pci_epc *epc); |
---|
142 | 178 | int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf); |
---|
143 | 179 | void pci_epc_linkup(struct pci_epc *epc); |
---|
| 180 | +void pci_epc_init_notify(struct pci_epc *epc); |
---|
144 | 181 | void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf); |
---|
145 | 182 | int pci_epc_write_header(struct pci_epc *epc, u8 func_no, |
---|
146 | 183 | struct pci_epf_header *hdr); |
---|
.. | .. |
---|
155 | 192 | phys_addr_t phys_addr); |
---|
156 | 193 | int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts); |
---|
157 | 194 | int pci_epc_get_msi(struct pci_epc *epc, u8 func_no); |
---|
158 | | -int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts); |
---|
| 195 | +int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts, |
---|
| 196 | + enum pci_barno, u32 offset); |
---|
159 | 197 | int pci_epc_get_msix(struct pci_epc *epc, u8 func_no); |
---|
160 | 198 | int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, |
---|
161 | 199 | enum pci_epc_irq_type type, u16 interrupt_num); |
---|
162 | 200 | int pci_epc_start(struct pci_epc *epc); |
---|
163 | 201 | void pci_epc_stop(struct pci_epc *epc); |
---|
| 202 | +const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, |
---|
| 203 | + u8 func_no); |
---|
| 204 | +enum pci_barno |
---|
| 205 | +pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features); |
---|
| 206 | +enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features |
---|
| 207 | + *epc_features, enum pci_barno bar); |
---|
164 | 208 | struct pci_epc *pci_epc_get(const char *epc_name); |
---|
165 | 209 | void pci_epc_put(struct pci_epc *epc); |
---|
166 | 210 | |
---|
167 | | -int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size, |
---|
168 | | - size_t page_size); |
---|
| 211 | +int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t base, |
---|
| 212 | + size_t size, size_t page_size); |
---|
| 213 | +int pci_epc_multi_mem_init(struct pci_epc *epc, |
---|
| 214 | + struct pci_epc_mem_window *window, |
---|
| 215 | + unsigned int num_windows); |
---|
169 | 216 | void pci_epc_mem_exit(struct pci_epc *epc); |
---|
170 | 217 | void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, |
---|
171 | 218 | phys_addr_t *phys_addr, size_t size); |
---|