diff options
-rw-r--r-- | drivers/dma/ioat/dma.c | 8 | ||||
-rw-r--r-- | drivers/dma/ioat/dma.h | 10 | ||||
-rw-r--r-- | drivers/dma/ioat/dma_v3.c | 236 |
3 files changed, 171 insertions, 83 deletions
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 1879a5942bfc..17a2393b3e25 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
@@ -892,7 +892,7 @@ MODULE_PARM_DESC(ioat_interrupt_style, | |||
892 | * ioat_dma_setup_interrupts - setup interrupt handler | 892 | * ioat_dma_setup_interrupts - setup interrupt handler |
893 | * @device: ioat device | 893 | * @device: ioat device |
894 | */ | 894 | */ |
895 | static int ioat_dma_setup_interrupts(struct ioatdma_device *device) | 895 | int ioat_dma_setup_interrupts(struct ioatdma_device *device) |
896 | { | 896 | { |
897 | struct ioat_chan_common *chan; | 897 | struct ioat_chan_common *chan; |
898 | struct pci_dev *pdev = device->pdev; | 898 | struct pci_dev *pdev = device->pdev; |
@@ -941,6 +941,7 @@ msix: | |||
941 | } | 941 | } |
942 | } | 942 | } |
943 | intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL; | 943 | intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL; |
944 | device->irq_mode = IOAT_MSIX; | ||
944 | goto done; | 945 | goto done; |
945 | 946 | ||
946 | msix_single_vector: | 947 | msix_single_vector: |
@@ -956,6 +957,7 @@ msix_single_vector: | |||
956 | pci_disable_msix(pdev); | 957 | pci_disable_msix(pdev); |
957 | goto msi; | 958 | goto msi; |
958 | } | 959 | } |
960 | device->irq_mode = IOAT_MSIX_SINGLE; | ||
959 | goto done; | 961 | goto done; |
960 | 962 | ||
961 | msi: | 963 | msi: |
@@ -969,6 +971,7 @@ msi: | |||
969 | pci_disable_msi(pdev); | 971 | pci_disable_msi(pdev); |
970 | goto intx; | 972 | goto intx; |
971 | } | 973 | } |
974 | device->irq_mode = IOAT_MSIX; | ||
972 | goto done; | 975 | goto done; |
973 | 976 | ||
974 | intx: | 977 | intx: |
@@ -977,6 +980,7 @@ intx: | |||
977 | if (err) | 980 | if (err) |
978 | goto err_no_irq; | 981 | goto err_no_irq; |
979 | 982 | ||
983 | device->irq_mode = IOAT_INTX; | ||
980 | done: | 984 | done: |
981 | if (device->intr_quirk) | 985 | if (device->intr_quirk) |
982 | device->intr_quirk(device); | 986 | device->intr_quirk(device); |
@@ -987,9 +991,11 @@ done: | |||
987 | err_no_irq: | 991 | err_no_irq: |
988 | /* Disable all interrupt generation */ | 992 | /* Disable all interrupt generation */ |
989 | writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET); | 993 | writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET); |
994 | device->irq_mode = IOAT_NOIRQ; | ||
990 | dev_err(dev, "no usable interrupts\n"); | 995 | dev_err(dev, "no usable interrupts\n"); |
991 | return err; | 996 | return err; |
992 | } | 997 | } |
998 | EXPORT_SYMBOL(ioat_dma_setup_interrupts); | ||
993 | 999 | ||
994 | static void ioat_disable_interrupts(struct ioatdma_device *device) | 1000 | static void ioat_disable_interrupts(struct ioatdma_device *device) |
995 | { | 1001 | { |
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 9285caadf825..b16902cd2684 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -48,6 +48,14 @@ | |||
48 | */ | 48 | */ |
49 | #define NULL_DESC_BUFFER_SIZE 1 | 49 | #define NULL_DESC_BUFFER_SIZE 1 |
50 | 50 | ||
51 | enum ioat_irq_mode { | ||
52 | IOAT_NOIRQ = 0, | ||
53 | IOAT_MSIX, | ||
54 | IOAT_MSIX_SINGLE, | ||
55 | IOAT_MSI, | ||
56 | IOAT_INTX | ||
57 | }; | ||
58 | |||
51 | /** | 59 | /** |
52 | * struct ioatdma_device - internal representation of a IOAT device | 60 | * struct ioatdma_device - internal representation of a IOAT device |
53 | * @pdev: PCI-Express device | 61 | * @pdev: PCI-Express device |
@@ -77,6 +85,7 @@ struct ioatdma_device { | |||
77 | struct msix_entry msix_entries[4]; | 85 | struct msix_entry msix_entries[4]; |
78 | struct ioat_chan_common *idx[4]; | 86 | struct ioat_chan_common *idx[4]; |
79 | struct dca_provider *dca; | 87 | struct dca_provider *dca; |
88 | enum ioat_irq_mode irq_mode; | ||
80 | void (*intr_quirk)(struct ioatdma_device *device); | 89 | void (*intr_quirk)(struct ioatdma_device *device); |
81 | int (*enumerate_channels)(struct ioatdma_device *device); | 90 | int (*enumerate_channels)(struct ioatdma_device *device); |
82 | int (*reset_hw)(struct ioat_chan_common *chan); | 91 | int (*reset_hw)(struct ioat_chan_common *chan); |
@@ -341,6 +350,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, | |||
341 | dma_addr_t *phys_complete); | 350 | dma_addr_t *phys_complete); |
342 | void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); | 351 | void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); |
343 | void ioat_kobject_del(struct ioatdma_device *device); | 352 | void ioat_kobject_del(struct ioatdma_device *device); |
353 | int ioat_dma_setup_interrupts(struct ioatdma_device *device); | ||
344 | extern const struct sysfs_ops ioat_sysfs_ops; | 354 | extern const struct sysfs_ops ioat_sysfs_ops; |
345 | extern struct ioat_sysfs_entry ioat_version_attr; | 355 | extern struct ioat_sysfs_entry ioat_version_attr; |
346 | extern struct ioat_sysfs_entry ioat_cap_attr; | 356 | extern struct ioat_sysfs_entry ioat_cap_attr; |
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index ab5655eb0602..65b912aa1012 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -111,6 +111,103 @@ static void pq_set_src(struct ioat_raw_descriptor *descs[2], | |||
111 | pq->coef[idx] = coef; | 111 | pq->coef[idx] = coef; |
112 | } | 112 | } |
113 | 113 | ||
114 | static bool is_jf_ioat(struct pci_dev *pdev) | ||
115 | { | ||
116 | switch (pdev->device) { | ||
117 | case PCI_DEVICE_ID_INTEL_IOAT_JSF0: | ||
118 | case PCI_DEVICE_ID_INTEL_IOAT_JSF1: | ||
119 | case PCI_DEVICE_ID_INTEL_IOAT_JSF2: | ||
120 | case PCI_DEVICE_ID_INTEL_IOAT_JSF3: | ||
121 | case PCI_DEVICE_ID_INTEL_IOAT_JSF4: | ||
122 | case PCI_DEVICE_ID_INTEL_IOAT_JSF5: | ||
123 | case PCI_DEVICE_ID_INTEL_IOAT_JSF6: | ||
124 | case PCI_DEVICE_ID_INTEL_IOAT_JSF7: | ||
125 | case PCI_DEVICE_ID_INTEL_IOAT_JSF8: | ||
126 | case PCI_DEVICE_ID_INTEL_IOAT_JSF9: | ||
127 | return true; | ||
128 | default: | ||
129 | return false; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static bool is_snb_ioat(struct pci_dev *pdev) | ||
134 | { | ||
135 | switch (pdev->device) { | ||
136 | case PCI_DEVICE_ID_INTEL_IOAT_SNB0: | ||
137 | case PCI_DEVICE_ID_INTEL_IOAT_SNB1: | ||
138 | case PCI_DEVICE_ID_INTEL_IOAT_SNB2: | ||
139 | case PCI_DEVICE_ID_INTEL_IOAT_SNB3: | ||
140 | case PCI_DEVICE_ID_INTEL_IOAT_SNB4: | ||
141 | case PCI_DEVICE_ID_INTEL_IOAT_SNB5: | ||
142 | case PCI_DEVICE_ID_INTEL_IOAT_SNB6: | ||
143 | case PCI_DEVICE_ID_INTEL_IOAT_SNB7: | ||
144 | case PCI_DEVICE_ID_INTEL_IOAT_SNB8: | ||
145 | case PCI_DEVICE_ID_INTEL_IOAT_SNB9: | ||
146 | return true; | ||
147 | default: | ||
148 | return false; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | static bool is_ivb_ioat(struct pci_dev *pdev) | ||
153 | { | ||
154 | switch (pdev->device) { | ||
155 | case PCI_DEVICE_ID_INTEL_IOAT_IVB0: | ||
156 | case PCI_DEVICE_ID_INTEL_IOAT_IVB1: | ||
157 | case PCI_DEVICE_ID_INTEL_IOAT_IVB2: | ||
158 | case PCI_DEVICE_ID_INTEL_IOAT_IVB3: | ||
159 | case PCI_DEVICE_ID_INTEL_IOAT_IVB4: | ||
160 | case PCI_DEVICE_ID_INTEL_IOAT_IVB5: | ||
161 | case PCI_DEVICE_ID_INTEL_IOAT_IVB6: | ||
162 | case PCI_DEVICE_ID_INTEL_IOAT_IVB7: | ||
163 | case PCI_DEVICE_ID_INTEL_IOAT_IVB8: | ||
164 | case PCI_DEVICE_ID_INTEL_IOAT_IVB9: | ||
165 | return true; | ||
166 | default: | ||
167 | return false; | ||
168 | } | ||
169 | |||
170 | } | ||
171 | |||
172 | static bool is_hsw_ioat(struct pci_dev *pdev) | ||
173 | { | ||
174 | switch (pdev->device) { | ||
175 | case PCI_DEVICE_ID_INTEL_IOAT_HSW0: | ||
176 | case PCI_DEVICE_ID_INTEL_IOAT_HSW1: | ||
177 | case PCI_DEVICE_ID_INTEL_IOAT_HSW2: | ||
178 | case PCI_DEVICE_ID_INTEL_IOAT_HSW3: | ||
179 | case PCI_DEVICE_ID_INTEL_IOAT_HSW4: | ||
180 | case PCI_DEVICE_ID_INTEL_IOAT_HSW5: | ||
181 | case PCI_DEVICE_ID_INTEL_IOAT_HSW6: | ||
182 | case PCI_DEVICE_ID_INTEL_IOAT_HSW7: | ||
183 | case PCI_DEVICE_ID_INTEL_IOAT_HSW8: | ||
184 | case PCI_DEVICE_ID_INTEL_IOAT_HSW9: | ||
185 | return true; | ||
186 | default: | ||
187 | return false; | ||
188 | } | ||
189 | |||
190 | } | ||
191 | |||
192 | static bool is_xeon_cb32(struct pci_dev *pdev) | ||
193 | { | ||
194 | return is_jf_ioat(pdev) || is_snb_ioat(pdev) || is_ivb_ioat(pdev) || | ||
195 | is_hsw_ioat(pdev); | ||
196 | } | ||
197 | |||
198 | static bool is_bwd_ioat(struct pci_dev *pdev) | ||
199 | { | ||
200 | switch (pdev->device) { | ||
201 | case PCI_DEVICE_ID_INTEL_IOAT_BWD0: | ||
202 | case PCI_DEVICE_ID_INTEL_IOAT_BWD1: | ||
203 | case PCI_DEVICE_ID_INTEL_IOAT_BWD2: | ||
204 | case PCI_DEVICE_ID_INTEL_IOAT_BWD3: | ||
205 | return true; | ||
206 | default: | ||
207 | return false; | ||
208 | } | ||
209 | } | ||
210 | |||
114 | static void ioat3_dma_unmap(struct ioat2_dma_chan *ioat, | 211 | static void ioat3_dma_unmap(struct ioat2_dma_chan *ioat, |
115 | struct ioat_ring_ent *desc, int idx) | 212 | struct ioat_ring_ent *desc, int idx) |
116 | { | 213 | { |
@@ -1168,6 +1265,56 @@ static int ioat3_dma_self_test(struct ioatdma_device *device) | |||
1168 | return 0; | 1265 | return 0; |
1169 | } | 1266 | } |
1170 | 1267 | ||
1268 | static int ioat3_irq_reinit(struct ioatdma_device *device) | ||
1269 | { | ||
1270 | int msixcnt = device->common.chancnt; | ||
1271 | struct pci_dev *pdev = device->pdev; | ||
1272 | int i; | ||
1273 | struct msix_entry *msix; | ||
1274 | struct ioat_chan_common *chan; | ||
1275 | int err = 0; | ||
1276 | |||
1277 | switch (device->irq_mode) { | ||
1278 | case IOAT_MSIX: | ||
1279 | |||
1280 | for (i = 0; i < msixcnt; i++) { | ||
1281 | msix = &device->msix_entries[i]; | ||
1282 | chan = ioat_chan_by_index(device, i); | ||
1283 | devm_free_irq(&pdev->dev, msix->vector, chan); | ||
1284 | } | ||
1285 | |||
1286 | pci_disable_msix(pdev); | ||
1287 | break; | ||
1288 | |||
1289 | case IOAT_MSIX_SINGLE: | ||
1290 | msix = &device->msix_entries[0]; | ||
1291 | chan = ioat_chan_by_index(device, 0); | ||
1292 | devm_free_irq(&pdev->dev, msix->vector, chan); | ||
1293 | pci_disable_msix(pdev); | ||
1294 | break; | ||
1295 | |||
1296 | case IOAT_MSI: | ||
1297 | chan = ioat_chan_by_index(device, 0); | ||
1298 | devm_free_irq(&pdev->dev, pdev->irq, chan); | ||
1299 | pci_disable_msi(pdev); | ||
1300 | break; | ||
1301 | |||
1302 | case IOAT_INTX: | ||
1303 | chan = ioat_chan_by_index(device, 0); | ||
1304 | devm_free_irq(&pdev->dev, pdev->irq, chan); | ||
1305 | break; | ||
1306 | |||
1307 | default: | ||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | device->irq_mode = IOAT_NOIRQ; | ||
1312 | |||
1313 | err = ioat_dma_setup_interrupts(device); | ||
1314 | |||
1315 | return err; | ||
1316 | } | ||
1317 | |||
1171 | static int ioat3_reset_hw(struct ioat_chan_common *chan) | 1318 | static int ioat3_reset_hw(struct ioat_chan_common *chan) |
1172 | { | 1319 | { |
1173 | /* throw away whatever the channel was doing and get it | 1320 | /* throw away whatever the channel was doing and get it |
@@ -1199,91 +1346,16 @@ static int ioat3_reset_hw(struct ioat_chan_common *chan) | |||
1199 | if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0) | 1346 | if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0) |
1200 | pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10); | 1347 | pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10); |
1201 | 1348 | ||
1202 | return ioat2_reset_sync(chan, msecs_to_jiffies(200)); | 1349 | err = ioat2_reset_sync(chan, msecs_to_jiffies(200)); |
1203 | } | 1350 | if (err) { |
1204 | 1351 | dev_err(&pdev->dev, "Failed to reset!\n"); | |
1205 | static bool is_jf_ioat(struct pci_dev *pdev) | 1352 | return err; |
1206 | { | ||
1207 | switch (pdev->device) { | ||
1208 | case PCI_DEVICE_ID_INTEL_IOAT_JSF0: | ||
1209 | case PCI_DEVICE_ID_INTEL_IOAT_JSF1: | ||
1210 | case PCI_DEVICE_ID_INTEL_IOAT_JSF2: | ||
1211 | case PCI_DEVICE_ID_INTEL_IOAT_JSF3: | ||
1212 | case PCI_DEVICE_ID_INTEL_IOAT_JSF4: | ||
1213 | case PCI_DEVICE_ID_INTEL_IOAT_JSF5: | ||
1214 | case PCI_DEVICE_ID_INTEL_IOAT_JSF6: | ||
1215 | case PCI_DEVICE_ID_INTEL_IOAT_JSF7: | ||
1216 | case PCI_DEVICE_ID_INTEL_IOAT_JSF8: | ||
1217 | case PCI_DEVICE_ID_INTEL_IOAT_JSF9: | ||
1218 | return true; | ||
1219 | default: | ||
1220 | return false; | ||
1221 | } | ||
1222 | } | ||
1223 | |||
1224 | static bool is_snb_ioat(struct pci_dev *pdev) | ||
1225 | { | ||
1226 | switch (pdev->device) { | ||
1227 | case PCI_DEVICE_ID_INTEL_IOAT_SNB0: | ||
1228 | case PCI_DEVICE_ID_INTEL_IOAT_SNB1: | ||
1229 | case PCI_DEVICE_ID_INTEL_IOAT_SNB2: | ||
1230 | case PCI_DEVICE_ID_INTEL_IOAT_SNB3: | ||
1231 | case PCI_DEVICE_ID_INTEL_IOAT_SNB4: | ||
1232 | case PCI_DEVICE_ID_INTEL_IOAT_SNB5: | ||
1233 | case PCI_DEVICE_ID_INTEL_IOAT_SNB6: | ||
1234 | case PCI_DEVICE_ID_INTEL_IOAT_SNB7: | ||
1235 | case PCI_DEVICE_ID_INTEL_IOAT_SNB8: | ||
1236 | case PCI_DEVICE_ID_INTEL_IOAT_SNB9: | ||
1237 | return true; | ||
1238 | default: | ||
1239 | return false; | ||
1240 | } | ||
1241 | } | ||
1242 | |||
1243 | static bool is_ivb_ioat(struct pci_dev *pdev) | ||
1244 | { | ||
1245 | switch (pdev->device) { | ||
1246 | case PCI_DEVICE_ID_INTEL_IOAT_IVB0: | ||
1247 | case PCI_DEVICE_ID_INTEL_IOAT_IVB1: | ||
1248 | case PCI_DEVICE_ID_INTEL_IOAT_IVB2: | ||
1249 | case PCI_DEVICE_ID_INTEL_IOAT_IVB3: | ||
1250 | case PCI_DEVICE_ID_INTEL_IOAT_IVB4: | ||
1251 | case PCI_DEVICE_ID_INTEL_IOAT_IVB5: | ||
1252 | case PCI_DEVICE_ID_INTEL_IOAT_IVB6: | ||
1253 | case PCI_DEVICE_ID_INTEL_IOAT_IVB7: | ||
1254 | case PCI_DEVICE_ID_INTEL_IOAT_IVB8: | ||
1255 | case PCI_DEVICE_ID_INTEL_IOAT_IVB9: | ||
1256 | return true; | ||
1257 | default: | ||
1258 | return false; | ||
1259 | } | ||
1260 | |||
1261 | } | ||
1262 | |||
1263 | static bool is_hsw_ioat(struct pci_dev *pdev) | ||
1264 | { | ||
1265 | switch (pdev->device) { | ||
1266 | case PCI_DEVICE_ID_INTEL_IOAT_HSW0: | ||
1267 | case PCI_DEVICE_ID_INTEL_IOAT_HSW1: | ||
1268 | case PCI_DEVICE_ID_INTEL_IOAT_HSW2: | ||
1269 | case PCI_DEVICE_ID_INTEL_IOAT_HSW3: | ||
1270 | case PCI_DEVICE_ID_INTEL_IOAT_HSW4: | ||
1271 | case PCI_DEVICE_ID_INTEL_IOAT_HSW5: | ||
1272 | case PCI_DEVICE_ID_INTEL_IOAT_HSW6: | ||
1273 | case PCI_DEVICE_ID_INTEL_IOAT_HSW7: | ||
1274 | case PCI_DEVICE_ID_INTEL_IOAT_HSW8: | ||
1275 | case PCI_DEVICE_ID_INTEL_IOAT_HSW9: | ||
1276 | return true; | ||
1277 | default: | ||
1278 | return false; | ||
1279 | } | 1353 | } |
1280 | 1354 | ||
1281 | } | 1355 | if (device->irq_mode != IOAT_NOIRQ && is_bwd_ioat(pdev)) |
1356 | err = ioat3_irq_reinit(device); | ||
1282 | 1357 | ||
1283 | static bool is_xeon_cb32(struct pci_dev *pdev) | 1358 | return err; |
1284 | { | ||
1285 | return is_jf_ioat(pdev) || is_snb_ioat(pdev) || is_ivb_ioat(pdev) || | ||
1286 | is_hsw_ioat(pdev); | ||
1287 | } | 1359 | } |
1288 | 1360 | ||
1289 | int ioat3_dma_probe(struct ioatdma_device *device, int dca) | 1361 | int ioat3_dma_probe(struct ioatdma_device *device, int dca) |