aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/pci')
-rw-r--r--arch/x86/pci/xen.c68
1 files changed, 26 insertions, 42 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 0d5087eeced8..93e42152d8d0 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -86,7 +86,7 @@ static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
86 86
87static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 87static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
88{ 88{
89 int irq, pirq, ret = 0; 89 int irq, pirq;
90 struct msi_desc *msidesc; 90 struct msi_desc *msidesc;
91 struct msi_msg msg; 91 struct msi_msg msg;
92 92
@@ -94,39 +94,32 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
94 __read_msi_msg(msidesc, &msg); 94 __read_msi_msg(msidesc, &msg);
95 pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | 95 pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
96 ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); 96 ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
97 if (xen_irq_from_pirq(pirq) >= 0 && msg.data == XEN_PIRQ_MSI_DATA) { 97 if (msg.data != XEN_PIRQ_MSI_DATA ||
98 irq = xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? 98 xen_irq_from_pirq(pirq) < 0) {
99 "msi-x" : "msi", &pirq, 0); 99 pirq = xen_allocate_pirq_msi(dev, msidesc);
100 if (irq < 0) 100 if (pirq < 0)
101 goto error; 101 goto error;
102 ret = set_irq_msi(irq, msidesc); 102 xen_msi_compose_msg(dev, pirq, &msg);
103 if (ret < 0) 103 __write_msi_msg(msidesc, &msg);
104 goto error_while; 104 dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
105 printk(KERN_DEBUG "xen: msi already setup: msi --> irq=%d" 105 } else {
106 " pirq=%d\n", irq, pirq); 106 dev_dbg(&dev->dev,
107 return 0; 107 "xen: msi already bound to pirq=%d\n", pirq);
108 } 108 }
109 irq = xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? 109 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
110 "msi-x" : "msi", &pirq, 1); 110 (type == PCI_CAP_ID_MSIX) ?
111 if (irq < 0 || pirq < 0) 111 "msi-x" : "msi");
112 if (irq < 0)
112 goto error; 113 goto error;
113 printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq); 114 dev_dbg(&dev->dev,
114 xen_msi_compose_msg(dev, pirq, &msg); 115 "xen: msi --> pirq=%d --> irq=%d\n", pirq, irq);
115 ret = set_irq_msi(irq, msidesc);
116 if (ret < 0)
117 goto error_while;
118 write_msi_msg(irq, &msg);
119 } 116 }
120 return 0; 117 return 0;
121 118
122error_while:
123 unbind_from_irqhandler(irq, NULL);
124error: 119error:
125 if (ret == -ENODEV) 120 dev_err(&dev->dev,
126 dev_err(&dev->dev, "Xen PCI frontend has not registered" \ 121 "Xen PCI frontend has not registered MSI/MSI-X support!\n");
127 " MSI/MSI-X support!\n"); 122 return -ENODEV;
128
129 return ret;
130} 123}
131 124
132/* 125/*
@@ -152,28 +145,19 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
152 goto error; 145 goto error;
153 i = 0; 146 i = 0;
154 list_for_each_entry(msidesc, &dev->msi_list, list) { 147 list_for_each_entry(msidesc, &dev->msi_list, list) {
155 irq = xen_allocate_pirq_msi( 148 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
156 (type == PCI_CAP_ID_MSIX) ? 149 (type == PCI_CAP_ID_MSIX) ?
157 "pcifront-msi-x" : "pcifront-msi", 150 "pcifront-msi-x" :
158 &v[i], 0); 151 "pcifront-msi");
159 if (irq < 0) { 152 if (irq < 0)
160 ret = -1;
161 goto free; 153 goto free;
162 }
163 ret = set_irq_msi(irq, msidesc);
164 if (ret)
165 goto error_while;
166 i++; 154 i++;
167 } 155 }
168 kfree(v); 156 kfree(v);
169 return 0; 157 return 0;
170 158
171error_while:
172 unbind_from_irqhandler(irq, NULL);
173error: 159error:
174 if (ret == -ENODEV) 160 dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n");
175 dev_err(&dev->dev, "Xen PCI frontend has not registered" \
176 " MSI/MSI-X support!\n");
177free: 161free:
178 kfree(v); 162 kfree(v);
179 return ret; 163 return ret;