2 * PCI Backend - Handle special overlays for broken devices.
4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
5 * Author: Chris Bookholt <hap10@epoch.ncsc.mil>
8 #include <linux/kernel.h>
11 #include "conf_space.h"
12 #include "conf_space_quirks.h"
14 LIST_HEAD(xen_pcibk_quirks
);
15 static inline const struct pci_device_id
*
16 match_one_device(const struct pci_device_id
*id
, const struct pci_dev
*dev
)
18 if ((id
->vendor
== PCI_ANY_ID
|| id
->vendor
== dev
->vendor
) &&
19 (id
->device
== PCI_ANY_ID
|| id
->device
== dev
->device
) &&
20 (id
->subvendor
== PCI_ANY_ID
||
21 id
->subvendor
== dev
->subsystem_vendor
) &&
22 (id
->subdevice
== PCI_ANY_ID
||
23 id
->subdevice
== dev
->subsystem_device
) &&
24 !((id
->class ^ dev
->class) & id
->class_mask
))
29 static struct xen_pcibk_config_quirk
*xen_pcibk_find_quirk(struct pci_dev
*dev
)
31 struct xen_pcibk_config_quirk
*tmp_quirk
;
33 list_for_each_entry(tmp_quirk
, &xen_pcibk_quirks
, quirks_list
)
34 if (match_one_device(&tmp_quirk
->devid
, dev
) != NULL
)
37 printk(KERN_DEBUG DRV_NAME
38 ": quirk didn't match any device known\n");
43 static inline void register_quirk(struct xen_pcibk_config_quirk
*quirk
)
45 list_add_tail(&quirk
->quirks_list
, &xen_pcibk_quirks
);
48 int xen_pcibk_field_is_dup(struct pci_dev
*dev
, unsigned int reg
)
51 struct xen_pcibk_dev_data
*dev_data
= pci_get_drvdata(dev
);
52 struct config_field_entry
*cfg_entry
;
54 list_for_each_entry(cfg_entry
, &dev_data
->config_fields
, list
) {
55 if (OFFSET(cfg_entry
) == reg
) {
63 int xen_pcibk_config_quirks_add_field(struct pci_dev
*dev
, struct config_field
68 switch (field
->size
) {
70 field
->u
.b
.read
= xen_pcibk_read_config_byte
;
71 field
->u
.b
.write
= xen_pcibk_write_config_byte
;
74 field
->u
.w
.read
= xen_pcibk_read_config_word
;
75 field
->u
.w
.write
= xen_pcibk_write_config_word
;
78 field
->u
.dw
.read
= xen_pcibk_read_config_dword
;
79 field
->u
.dw
.write
= xen_pcibk_write_config_dword
;
86 xen_pcibk_config_add_field(dev
, field
);
92 int xen_pcibk_config_quirks_init(struct pci_dev
*dev
)
94 struct xen_pcibk_config_quirk
*quirk
;
97 quirk
= kzalloc(sizeof(*quirk
), GFP_ATOMIC
);
103 quirk
->devid
.vendor
= dev
->vendor
;
104 quirk
->devid
.device
= dev
->device
;
105 quirk
->devid
.subvendor
= dev
->subsystem_vendor
;
106 quirk
->devid
.subdevice
= dev
->subsystem_device
;
107 quirk
->devid
.class = 0;
108 quirk
->devid
.class_mask
= 0;
109 quirk
->devid
.driver_data
= 0UL;
113 register_quirk(quirk
);
118 void xen_pcibk_config_field_free(struct config_field
*field
)
123 int xen_pcibk_config_quirk_release(struct pci_dev
*dev
)
125 struct xen_pcibk_config_quirk
*quirk
;
128 quirk
= xen_pcibk_find_quirk(dev
);
134 list_del(&quirk
->quirks_list
);