forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-02-20 e636c8d336489bf3eed5878299e6cc045bbad077
kernel/drivers/xen/xen-pciback/conf_space_capability.c
....@@ -189,6 +189,88 @@
189189 {}
190190 };
191191
192
+static struct msi_msix_field_config {
193
+ u16 enable_bit; /* bit for enabling MSI/MSI-X */
194
+ u16 allowed_bits; /* bits allowed to be changed */
195
+ unsigned int int_type; /* interrupt type for exclusiveness check */
196
+} msi_field_config = {
197
+ .enable_bit = PCI_MSI_FLAGS_ENABLE,
198
+ .allowed_bits = PCI_MSI_FLAGS_ENABLE,
199
+ .int_type = INTERRUPT_TYPE_MSI,
200
+}, msix_field_config = {
201
+ .enable_bit = PCI_MSIX_FLAGS_ENABLE,
202
+ .allowed_bits = PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL,
203
+ .int_type = INTERRUPT_TYPE_MSIX,
204
+};
205
+
206
+static void *msi_field_init(struct pci_dev *dev, int offset)
207
+{
208
+ return &msi_field_config;
209
+}
210
+
211
+static void *msix_field_init(struct pci_dev *dev, int offset)
212
+{
213
+ return &msix_field_config;
214
+}
215
+
216
+static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
217
+ void *data)
218
+{
219
+ int err;
220
+ u16 old_value;
221
+ const struct msi_msix_field_config *field_config = data;
222
+ const struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
223
+
224
+ if (xen_pcibk_permissive || dev_data->permissive)
225
+ goto write;
226
+
227
+ err = pci_read_config_word(dev, offset, &old_value);
228
+ if (err)
229
+ return err;
230
+
231
+ if (new_value == old_value)
232
+ return 0;
233
+
234
+ if (!dev_data->allow_interrupt_control ||
235
+ (new_value ^ old_value) & ~field_config->allowed_bits)
236
+ return PCIBIOS_SET_FAILED;
237
+
238
+ if (new_value & field_config->enable_bit) {
239
+ /* don't allow enabling together with other interrupt types */
240
+ int int_type = xen_pcibk_get_interrupt_type(dev);
241
+
242
+ if (int_type == INTERRUPT_TYPE_NONE ||
243
+ int_type == field_config->int_type)
244
+ goto write;
245
+ return PCIBIOS_SET_FAILED;
246
+ }
247
+
248
+write:
249
+ return pci_write_config_word(dev, offset, new_value);
250
+}
251
+
252
+static const struct config_field caplist_msix[] = {
253
+ {
254
+ .offset = PCI_MSIX_FLAGS,
255
+ .size = 2,
256
+ .init = msix_field_init,
257
+ .u.w.read = xen_pcibk_read_config_word,
258
+ .u.w.write = msi_msix_flags_write,
259
+ },
260
+ {}
261
+};
262
+
263
+static const struct config_field caplist_msi[] = {
264
+ {
265
+ .offset = PCI_MSI_FLAGS,
266
+ .size = 2,
267
+ .init = msi_field_init,
268
+ .u.w.read = xen_pcibk_read_config_word,
269
+ .u.w.write = msi_msix_flags_write,
270
+ },
271
+ {}
272
+};
273
+
192274 static struct xen_pcibk_config_capability xen_pcibk_config_capability_pm = {
193275 .capability = PCI_CAP_ID_PM,
194276 .fields = caplist_pm,
....@@ -197,11 +279,21 @@
197279 .capability = PCI_CAP_ID_VPD,
198280 .fields = caplist_vpd,
199281 };
282
+static struct xen_pcibk_config_capability xen_pcibk_config_capability_msi = {
283
+ .capability = PCI_CAP_ID_MSI,
284
+ .fields = caplist_msi,
285
+};
286
+static struct xen_pcibk_config_capability xen_pcibk_config_capability_msix = {
287
+ .capability = PCI_CAP_ID_MSIX,
288
+ .fields = caplist_msix,
289
+};
200290
201291 int xen_pcibk_config_capability_init(void)
202292 {
203293 register_capability(&xen_pcibk_config_capability_vpd);
204294 register_capability(&xen_pcibk_config_capability_pm);
295
+ register_capability(&xen_pcibk_config_capability_msi);
296
+ register_capability(&xen_pcibk_config_capability_msix);
205297
206298 return 0;
207299 }