diff options
-rw-r--r-- | arch/x86/include/asm/intr_remapping.h | 26 | ||||
-rw-r--r-- | arch/x86/include/asm/irq_remapping.h | 23 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 119 | ||||
-rw-r--r-- | drivers/iommu/intel_intr_remapping.c | 97 | ||||
-rw-r--r-- | drivers/iommu/intr_remapping.c | 35 | ||||
-rw-r--r-- | drivers/iommu/intr_remapping.h | 16 |
6 files changed, 202 insertions, 114 deletions
diff --git a/arch/x86/include/asm/intr_remapping.h b/arch/x86/include/asm/intr_remapping.h index a195b7d6995c..a6afd6efa6c6 100644 --- a/arch/x86/include/asm/intr_remapping.h +++ b/arch/x86/include/asm/intr_remapping.h | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | struct IO_APIC_route_entry; | 27 | struct IO_APIC_route_entry; |
28 | struct io_apic_irq_attr; | 28 | struct io_apic_irq_attr; |
29 | struct pci_dev; | ||
29 | 30 | ||
30 | extern int intr_remapping_enabled; | 31 | extern int intr_remapping_enabled; |
31 | 32 | ||
@@ -44,6 +45,13 @@ extern int intr_set_affinity(struct irq_data *data, | |||
44 | const struct cpumask *mask, | 45 | const struct cpumask *mask, |
45 | bool force); | 46 | bool force); |
46 | extern void intr_free_irq(int irq); | 47 | extern void intr_free_irq(int irq); |
48 | extern void intr_compose_msi_msg(struct pci_dev *pdev, | ||
49 | unsigned int irq, unsigned int dest, | ||
50 | struct msi_msg *msg, u8 hpet_id); | ||
51 | extern int intr_msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec); | ||
52 | extern int intr_msi_setup_irq(struct pci_dev *pdev, unsigned int irq, | ||
53 | int index, int sub_handle); | ||
54 | extern int intr_setup_hpet_msi(unsigned int irq, unsigned int id); | ||
47 | 55 | ||
48 | #else /* CONFIG_IRQ_REMAP */ | 56 | #else /* CONFIG_IRQ_REMAP */ |
49 | 57 | ||
@@ -70,6 +78,24 @@ static inline int intr_set_affinity(struct irq_data *data, | |||
70 | return 0; | 78 | return 0; |
71 | } | 79 | } |
72 | static inline void intr_free_irq(int irq) { } | 80 | static inline void intr_free_irq(int irq) { } |
81 | static inline void intr_compose_msi_msg(struct pci_dev *pdev, | ||
82 | unsigned int irq, unsigned int dest, | ||
83 | struct msi_msg *msg, u8 hpet_id) | ||
84 | { | ||
85 | } | ||
86 | static inline int intr_msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec) | ||
87 | { | ||
88 | return -ENODEV; | ||
89 | } | ||
90 | static inline int intr_msi_setup_irq(struct pci_dev *pdev, unsigned int irq, | ||
91 | int index, int sub_handle) | ||
92 | { | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | static inline int intr_setup_hpet_msi(unsigned int irq, unsigned int id) | ||
96 | { | ||
97 | return -ENODEV; | ||
98 | } | ||
73 | #endif /* CONFIG_IRQ_REMAP */ | 99 | #endif /* CONFIG_IRQ_REMAP */ |
74 | 100 | ||
75 | #endif /* __X86_INTR_REMAPPING_H */ | 101 | #endif /* __X86_INTR_REMAPPING_H */ |
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h index 47d99934580f..0ddfc0b90adb 100644 --- a/arch/x86/include/asm/irq_remapping.h +++ b/arch/x86/include/asm/irq_remapping.h | |||
@@ -5,34 +5,11 @@ | |||
5 | 5 | ||
6 | #ifdef CONFIG_IRQ_REMAP | 6 | #ifdef CONFIG_IRQ_REMAP |
7 | static void irq_remap_modify_chip_defaults(struct irq_chip *chip); | 7 | static void irq_remap_modify_chip_defaults(struct irq_chip *chip); |
8 | static inline void prepare_irte(struct irte *irte, int vector, | ||
9 | unsigned int dest) | ||
10 | { | ||
11 | memset(irte, 0, sizeof(*irte)); | ||
12 | |||
13 | irte->present = 1; | ||
14 | irte->dst_mode = apic->irq_dest_mode; | ||
15 | /* | ||
16 | * Trigger mode in the IRTE will always be edge, and for IO-APIC, the | ||
17 | * actual level or edge trigger will be setup in the IO-APIC | ||
18 | * RTE. This will help simplify level triggered irq migration. | ||
19 | * For more details, see the comments (in io_apic.c) explainig IO-APIC | ||
20 | * irq migration in the presence of interrupt-remapping. | ||
21 | */ | ||
22 | irte->trigger_mode = 0; | ||
23 | irte->dlvry_mode = apic->irq_delivery_mode; | ||
24 | irte->vector = vector; | ||
25 | irte->dest_id = IRTE_DEST(dest); | ||
26 | irte->redir_hint = 1; | ||
27 | } | ||
28 | static inline bool irq_remapped(struct irq_cfg *cfg) | 8 | static inline bool irq_remapped(struct irq_cfg *cfg) |
29 | { | 9 | { |
30 | return cfg->irq_2_iommu.iommu != NULL; | 10 | return cfg->irq_2_iommu.iommu != NULL; |
31 | } | 11 | } |
32 | #else | 12 | #else |
33 | static void prepare_irte(struct irte *irte, int vector, unsigned int dest) | ||
34 | { | ||
35 | } | ||
36 | static inline bool irq_remapped(struct irq_cfg *cfg) | 13 | static inline bool irq_remapped(struct irq_cfg *cfg) |
37 | { | 14 | { |
38 | return false; | 15 | return false; |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 5690469555fb..3db693bda91d 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -3070,54 +3070,34 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, | |||
3070 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 3070 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); |
3071 | 3071 | ||
3072 | if (irq_remapped(cfg)) { | 3072 | if (irq_remapped(cfg)) { |
3073 | struct irte irte; | 3073 | intr_compose_msi_msg(pdev, irq, dest, msg, hpet_id); |
3074 | int ir_index; | 3074 | return err; |
3075 | u16 sub_handle; | 3075 | } |
3076 | |||
3077 | ir_index = map_irq_to_irte_handle(irq, &sub_handle); | ||
3078 | BUG_ON(ir_index == -1); | ||
3079 | |||
3080 | prepare_irte(&irte, cfg->vector, dest); | ||
3081 | |||
3082 | /* Set source-id of interrupt request */ | ||
3083 | if (pdev) | ||
3084 | set_msi_sid(&irte, pdev); | ||
3085 | else | ||
3086 | set_hpet_sid(&irte, hpet_id); | ||
3087 | |||
3088 | modify_irte(irq, &irte); | ||
3089 | 3076 | ||
3077 | if (x2apic_enabled()) | ||
3078 | msg->address_hi = MSI_ADDR_BASE_HI | | ||
3079 | MSI_ADDR_EXT_DEST_ID(dest); | ||
3080 | else | ||
3090 | msg->address_hi = MSI_ADDR_BASE_HI; | 3081 | msg->address_hi = MSI_ADDR_BASE_HI; |
3091 | msg->data = sub_handle; | ||
3092 | msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | | ||
3093 | MSI_ADDR_IR_SHV | | ||
3094 | MSI_ADDR_IR_INDEX1(ir_index) | | ||
3095 | MSI_ADDR_IR_INDEX2(ir_index); | ||
3096 | } else { | ||
3097 | if (x2apic_enabled()) | ||
3098 | msg->address_hi = MSI_ADDR_BASE_HI | | ||
3099 | MSI_ADDR_EXT_DEST_ID(dest); | ||
3100 | else | ||
3101 | msg->address_hi = MSI_ADDR_BASE_HI; | ||
3102 | 3082 | ||
3103 | msg->address_lo = | 3083 | msg->address_lo = |
3104 | MSI_ADDR_BASE_LO | | 3084 | MSI_ADDR_BASE_LO | |
3105 | ((apic->irq_dest_mode == 0) ? | 3085 | ((apic->irq_dest_mode == 0) ? |
3106 | MSI_ADDR_DEST_MODE_PHYSICAL: | 3086 | MSI_ADDR_DEST_MODE_PHYSICAL: |
3107 | MSI_ADDR_DEST_MODE_LOGICAL) | | 3087 | MSI_ADDR_DEST_MODE_LOGICAL) | |
3108 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | 3088 | ((apic->irq_delivery_mode != dest_LowestPrio) ? |
3109 | MSI_ADDR_REDIRECTION_CPU: | 3089 | MSI_ADDR_REDIRECTION_CPU: |
3110 | MSI_ADDR_REDIRECTION_LOWPRI) | | 3090 | MSI_ADDR_REDIRECTION_LOWPRI) | |
3111 | MSI_ADDR_DEST_ID(dest); | 3091 | MSI_ADDR_DEST_ID(dest); |
3092 | |||
3093 | msg->data = | ||
3094 | MSI_DATA_TRIGGER_EDGE | | ||
3095 | MSI_DATA_LEVEL_ASSERT | | ||
3096 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | ||
3097 | MSI_DATA_DELIVERY_FIXED: | ||
3098 | MSI_DATA_DELIVERY_LOWPRI) | | ||
3099 | MSI_DATA_VECTOR(cfg->vector); | ||
3112 | 3100 | ||
3113 | msg->data = | ||
3114 | MSI_DATA_TRIGGER_EDGE | | ||
3115 | MSI_DATA_LEVEL_ASSERT | | ||
3116 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | ||
3117 | MSI_DATA_DELIVERY_FIXED: | ||
3118 | MSI_DATA_DELIVERY_LOWPRI) | | ||
3119 | MSI_DATA_VECTOR(cfg->vector); | ||
3120 | } | ||
3121 | return err; | 3101 | return err; |
3122 | } | 3102 | } |
3123 | 3103 | ||
@@ -3160,33 +3140,6 @@ static struct irq_chip msi_chip = { | |||
3160 | .irq_retrigger = ioapic_retrigger_irq, | 3140 | .irq_retrigger = ioapic_retrigger_irq, |
3161 | }; | 3141 | }; |
3162 | 3142 | ||
3163 | /* | ||
3164 | * Map the PCI dev to the corresponding remapping hardware unit | ||
3165 | * and allocate 'nvec' consecutive interrupt-remapping table entries | ||
3166 | * in it. | ||
3167 | */ | ||
3168 | static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) | ||
3169 | { | ||
3170 | struct intel_iommu *iommu; | ||
3171 | int index; | ||
3172 | |||
3173 | iommu = map_dev_to_ir(dev); | ||
3174 | if (!iommu) { | ||
3175 | printk(KERN_ERR | ||
3176 | "Unable to map PCI %s to iommu\n", pci_name(dev)); | ||
3177 | return -ENOENT; | ||
3178 | } | ||
3179 | |||
3180 | index = alloc_irte(iommu, irq, nvec); | ||
3181 | if (index < 0) { | ||
3182 | printk(KERN_ERR | ||
3183 | "Unable to allocate %d IRTE for PCI %s\n", nvec, | ||
3184 | pci_name(dev)); | ||
3185 | return -ENOSPC; | ||
3186 | } | ||
3187 | return index; | ||
3188 | } | ||
3189 | |||
3190 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | 3143 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) |
3191 | { | 3144 | { |
3192 | struct irq_chip *chip = &msi_chip; | 3145 | struct irq_chip *chip = &msi_chip; |
@@ -3217,7 +3170,6 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3217 | int node, ret, sub_handle, index = 0; | 3170 | int node, ret, sub_handle, index = 0; |
3218 | unsigned int irq, irq_want; | 3171 | unsigned int irq, irq_want; |
3219 | struct msi_desc *msidesc; | 3172 | struct msi_desc *msidesc; |
3220 | struct intel_iommu *iommu = NULL; | ||
3221 | 3173 | ||
3222 | /* x86 doesn't support multiple MSI yet */ | 3174 | /* x86 doesn't support multiple MSI yet */ |
3223 | if (type == PCI_CAP_ID_MSI && nvec > 1) | 3175 | if (type == PCI_CAP_ID_MSI && nvec > 1) |
@@ -3239,23 +3191,15 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3239 | * allocate the consecutive block of IRTE's | 3191 | * allocate the consecutive block of IRTE's |
3240 | * for 'nvec' | 3192 | * for 'nvec' |
3241 | */ | 3193 | */ |
3242 | index = msi_alloc_irte(dev, irq, nvec); | 3194 | index = intr_msi_alloc_irq(dev, irq, nvec); |
3243 | if (index < 0) { | 3195 | if (index < 0) { |
3244 | ret = index; | 3196 | ret = index; |
3245 | goto error; | 3197 | goto error; |
3246 | } | 3198 | } |
3247 | } else { | 3199 | } else { |
3248 | iommu = map_dev_to_ir(dev); | 3200 | ret = intr_msi_setup_irq(dev, irq, index, sub_handle); |
3249 | if (!iommu) { | 3201 | if (ret < 0) |
3250 | ret = -ENOENT; | ||
3251 | goto error; | 3202 | goto error; |
3252 | } | ||
3253 | /* | ||
3254 | * setup the mapping between the irq and the IRTE | ||
3255 | * base index, the sub_handle pointing to the | ||
3256 | * appropriate interrupt remap table entry. | ||
3257 | */ | ||
3258 | set_irte_irq(irq, iommu, index, sub_handle); | ||
3259 | } | 3203 | } |
3260 | no_ir: | 3204 | no_ir: |
3261 | ret = setup_msi_irq(dev, msidesc, irq); | 3205 | ret = setup_msi_irq(dev, msidesc, irq); |
@@ -3374,14 +3318,7 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id) | |||
3374 | int ret; | 3318 | int ret; |
3375 | 3319 | ||
3376 | if (intr_remapping_enabled) { | 3320 | if (intr_remapping_enabled) { |
3377 | struct intel_iommu *iommu = map_hpet_to_ir(id); | 3321 | if (!intr_setup_hpet_msi(irq, id)) |
3378 | int index; | ||
3379 | |||
3380 | if (!iommu) | ||
3381 | return -1; | ||
3382 | |||
3383 | index = alloc_irte(iommu, irq, 1); | ||
3384 | if (index < 0) | ||
3385 | return -1; | 3322 | return -1; |
3386 | } | 3323 | } |
3387 | 3324 | ||
diff --git a/drivers/iommu/intel_intr_remapping.c b/drivers/iommu/intel_intr_remapping.c index 44a6e04a070b..a3bae67ec43c 100644 --- a/drivers/iommu/intel_intr_remapping.c +++ b/drivers/iommu/intel_intr_remapping.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <acpi/acpi.h> | 13 | #include <acpi/acpi.h> |
14 | #include <asm/intr_remapping.h> | 14 | #include <asm/intr_remapping.h> |
15 | #include <asm/pci-direct.h> | 15 | #include <asm/pci-direct.h> |
16 | #include <asm/msidef.h> | ||
16 | 17 | ||
17 | #include "intr_remapping.h" | 18 | #include "intr_remapping.h" |
18 | 19 | ||
@@ -955,6 +956,98 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
955 | return 0; | 956 | return 0; |
956 | } | 957 | } |
957 | 958 | ||
959 | static void intel_compose_msi_msg(struct pci_dev *pdev, | ||
960 | unsigned int irq, unsigned int dest, | ||
961 | struct msi_msg *msg, u8 hpet_id) | ||
962 | { | ||
963 | struct irq_cfg *cfg; | ||
964 | struct irte irte; | ||
965 | u16 sub_handle; | ||
966 | int ir_index; | ||
967 | |||
968 | cfg = irq_get_chip_data(irq); | ||
969 | |||
970 | ir_index = map_irq_to_irte_handle(irq, &sub_handle); | ||
971 | BUG_ON(ir_index == -1); | ||
972 | |||
973 | prepare_irte(&irte, cfg->vector, dest); | ||
974 | |||
975 | /* Set source-id of interrupt request */ | ||
976 | if (pdev) | ||
977 | set_msi_sid(&irte, pdev); | ||
978 | else | ||
979 | set_hpet_sid(&irte, hpet_id); | ||
980 | |||
981 | modify_irte(irq, &irte); | ||
982 | |||
983 | msg->address_hi = MSI_ADDR_BASE_HI; | ||
984 | msg->data = sub_handle; | ||
985 | msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | | ||
986 | MSI_ADDR_IR_SHV | | ||
987 | MSI_ADDR_IR_INDEX1(ir_index) | | ||
988 | MSI_ADDR_IR_INDEX2(ir_index); | ||
989 | } | ||
990 | |||
991 | /* | ||
992 | * Map the PCI dev to the corresponding remapping hardware unit | ||
993 | * and allocate 'nvec' consecutive interrupt-remapping table entries | ||
994 | * in it. | ||
995 | */ | ||
996 | static int intel_msi_alloc_irq(struct pci_dev *dev, int irq, int nvec) | ||
997 | { | ||
998 | struct intel_iommu *iommu; | ||
999 | int index; | ||
1000 | |||
1001 | iommu = map_dev_to_ir(dev); | ||
1002 | if (!iommu) { | ||
1003 | printk(KERN_ERR | ||
1004 | "Unable to map PCI %s to iommu\n", pci_name(dev)); | ||
1005 | return -ENOENT; | ||
1006 | } | ||
1007 | |||
1008 | index = alloc_irte(iommu, irq, nvec); | ||
1009 | if (index < 0) { | ||
1010 | printk(KERN_ERR | ||
1011 | "Unable to allocate %d IRTE for PCI %s\n", nvec, | ||
1012 | pci_name(dev)); | ||
1013 | return -ENOSPC; | ||
1014 | } | ||
1015 | return index; | ||
1016 | } | ||
1017 | |||
1018 | static int intel_msi_setup_irq(struct pci_dev *pdev, unsigned int irq, | ||
1019 | int index, int sub_handle) | ||
1020 | { | ||
1021 | struct intel_iommu *iommu; | ||
1022 | |||
1023 | iommu = map_dev_to_ir(pdev); | ||
1024 | if (!iommu) | ||
1025 | return -ENOENT; | ||
1026 | /* | ||
1027 | * setup the mapping between the irq and the IRTE | ||
1028 | * base index, the sub_handle pointing to the | ||
1029 | * appropriate interrupt remap table entry. | ||
1030 | */ | ||
1031 | set_irte_irq(irq, iommu, index, sub_handle); | ||
1032 | |||
1033 | return 0; | ||
1034 | } | ||
1035 | |||
1036 | static int intel_setup_hpet_msi(unsigned int irq, unsigned int id) | ||
1037 | { | ||
1038 | struct intel_iommu *iommu = map_hpet_to_ir(id); | ||
1039 | int index; | ||
1040 | |||
1041 | if (!iommu) | ||
1042 | return -1; | ||
1043 | |||
1044 | index = alloc_irte(iommu, irq, 1); | ||
1045 | if (index < 0) | ||
1046 | return -1; | ||
1047 | |||
1048 | return 0; | ||
1049 | } | ||
1050 | |||
958 | struct irq_remap_ops intel_irq_remap_ops = { | 1051 | struct irq_remap_ops intel_irq_remap_ops = { |
959 | .supported = intel_intr_remapping_supported, | 1052 | .supported = intel_intr_remapping_supported, |
960 | .hardware_init = dmar_table_init, | 1053 | .hardware_init = dmar_table_init, |
@@ -965,4 +1058,8 @@ struct irq_remap_ops intel_irq_remap_ops = { | |||
965 | .setup_ioapic_entry = intel_setup_ioapic_entry, | 1058 | .setup_ioapic_entry = intel_setup_ioapic_entry, |
966 | .set_affinity = intel_ioapic_set_affinity, | 1059 | .set_affinity = intel_ioapic_set_affinity, |
967 | .free_irq = free_irte, | 1060 | .free_irq = free_irte, |
1061 | .compose_msi_msg = intel_compose_msi_msg, | ||
1062 | .msi_alloc_irq = intel_msi_alloc_irq, | ||
1063 | .msi_setup_irq = intel_msi_setup_irq, | ||
1064 | .setup_hpet_msi = intel_setup_hpet_msi, | ||
968 | }; | 1065 | }; |
diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c index a68d304f9729..9dc179316ba1 100644 --- a/drivers/iommu/intr_remapping.c +++ b/drivers/iommu/intr_remapping.c | |||
@@ -127,3 +127,38 @@ void intr_free_irq(int irq) | |||
127 | 127 | ||
128 | remap_ops->free_irq(irq); | 128 | remap_ops->free_irq(irq); |
129 | } | 129 | } |
130 | |||
131 | void intr_compose_msi_msg(struct pci_dev *pdev, | ||
132 | unsigned int irq, unsigned int dest, | ||
133 | struct msi_msg *msg, u8 hpet_id) | ||
134 | { | ||
135 | if (!remap_ops || !remap_ops->compose_msi_msg) | ||
136 | return; | ||
137 | |||
138 | remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id); | ||
139 | } | ||
140 | |||
141 | int intr_msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec) | ||
142 | { | ||
143 | if (!remap_ops || !remap_ops->msi_alloc_irq) | ||
144 | return -ENODEV; | ||
145 | |||
146 | return remap_ops->msi_alloc_irq(pdev, irq, nvec); | ||
147 | } | ||
148 | |||
149 | int intr_msi_setup_irq(struct pci_dev *pdev, unsigned int irq, | ||
150 | int index, int sub_handle) | ||
151 | { | ||
152 | if (!remap_ops || !remap_ops->msi_setup_irq) | ||
153 | return -ENODEV; | ||
154 | |||
155 | return remap_ops->msi_setup_irq(pdev, irq, index, sub_handle); | ||
156 | } | ||
157 | |||
158 | int intr_setup_hpet_msi(unsigned int irq, unsigned int id) | ||
159 | { | ||
160 | if (!remap_ops || !remap_ops->setup_hpet_msi) | ||
161 | return -ENODEV; | ||
162 | |||
163 | return remap_ops->setup_hpet_msi(irq, id); | ||
164 | } | ||
diff --git a/drivers/iommu/intr_remapping.h b/drivers/iommu/intr_remapping.h index 57485539383d..6f4ea0a387b1 100644 --- a/drivers/iommu/intr_remapping.h +++ b/drivers/iommu/intr_remapping.h | |||
@@ -28,6 +28,8 @@ struct IO_APIC_route_entry; | |||
28 | struct io_apic_irq_attr; | 28 | struct io_apic_irq_attr; |
29 | struct irq_data; | 29 | struct irq_data; |
30 | struct cpumask; | 30 | struct cpumask; |
31 | struct pci_dev; | ||
32 | struct msi_msg; | ||
31 | 33 | ||
32 | extern int disable_intremap; | 34 | extern int disable_intremap; |
33 | extern int disable_sourceid_checking; | 35 | extern int disable_sourceid_checking; |
@@ -63,6 +65,20 @@ struct irq_remap_ops { | |||
63 | 65 | ||
64 | /* Free an IRQ */ | 66 | /* Free an IRQ */ |
65 | int (*free_irq)(int); | 67 | int (*free_irq)(int); |
68 | |||
69 | /* Create MSI msg to use for interrupt remapping */ | ||
70 | void (*compose_msi_msg)(struct pci_dev *, | ||
71 | unsigned int, unsigned int, | ||
72 | struct msi_msg *, u8); | ||
73 | |||
74 | /* Allocate remapping resources for MSI */ | ||
75 | int (*msi_alloc_irq)(struct pci_dev *, int, int); | ||
76 | |||
77 | /* Setup the remapped MSI irq */ | ||
78 | int (*msi_setup_irq)(struct pci_dev *, unsigned int, int, int); | ||
79 | |||
80 | /* Setup interrupt remapping for an HPET MSI */ | ||
81 | int (*setup_hpet_msi)(unsigned int, unsigned int); | ||
66 | }; | 82 | }; |
67 | 83 | ||
68 | extern struct irq_remap_ops intel_irq_remap_ops; | 84 | extern struct irq_remap_ops intel_irq_remap_ops; |