diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2012-10-09 00:49:35 -0400 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2012-10-24 11:29:33 -0400 |
commit | eb9c95271eafb62f7024547016ad00636c1425c1 (patch) | |
tree | 115fd4401f71da4b6be52d2467a6dcb9596c6102 /drivers/iommu/amd_iommu.c | |
parent | 6f0c0580b70c89094b3422ba81118c7b959c7556 (diff) |
iommu/amd: Split IOMMU group initialization
This needs to be broken apart, start with pulling all the IOMMU
group init code into a new function.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 55074cba20eb..b65b377815ac 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -276,39 +276,32 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) | |||
276 | 276 | ||
277 | #define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF) | 277 | #define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF) |
278 | 278 | ||
279 | static int iommu_init_device(struct device *dev) | 279 | static int init_iommu_group(struct device *dev) |
280 | { | 280 | { |
281 | struct pci_dev *dma_pdev = NULL, *pdev = to_pci_dev(dev); | ||
282 | struct iommu_dev_data *dev_data; | 281 | struct iommu_dev_data *dev_data; |
283 | struct iommu_group *group; | 282 | struct iommu_group *group; |
284 | u16 alias; | 283 | struct pci_dev *dma_pdev = NULL; |
285 | int ret; | 284 | int ret; |
286 | 285 | ||
287 | if (dev->archdata.iommu) | 286 | group = iommu_group_get(dev); |
287 | if (group) { | ||
288 | iommu_group_put(group); | ||
288 | return 0; | 289 | return 0; |
290 | } | ||
289 | 291 | ||
290 | dev_data = find_dev_data(get_device_id(dev)); | 292 | dev_data = find_dev_data(get_device_id(dev)); |
291 | if (!dev_data) | 293 | if (!dev_data) |
292 | return -ENOMEM; | 294 | return -ENOMEM; |
293 | 295 | ||
294 | alias = amd_iommu_alias_table[dev_data->devid]; | 296 | if (dev_data->alias_data) { |
295 | if (alias != dev_data->devid) { | 297 | u16 alias; |
296 | struct iommu_dev_data *alias_data; | ||
297 | |||
298 | alias_data = find_dev_data(alias); | ||
299 | if (alias_data == NULL) { | ||
300 | pr_err("AMD-Vi: Warning: Unhandled device %s\n", | ||
301 | dev_name(dev)); | ||
302 | free_dev_data(dev_data); | ||
303 | return -ENOTSUPP; | ||
304 | } | ||
305 | dev_data->alias_data = alias_data; | ||
306 | 298 | ||
299 | alias = amd_iommu_alias_table[dev_data->devid]; | ||
307 | dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff); | 300 | dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff); |
308 | } | 301 | } |
309 | 302 | ||
310 | if (dma_pdev == NULL) | 303 | if (!dma_pdev) |
311 | dma_pdev = pci_dev_get(pdev); | 304 | dma_pdev = pci_dev_get(to_pci_dev(dev)); |
312 | 305 | ||
313 | /* Account for quirked devices */ | 306 | /* Account for quirked devices */ |
314 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | 307 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); |
@@ -358,6 +351,38 @@ root_bus: | |||
358 | 351 | ||
359 | iommu_group_put(group); | 352 | iommu_group_put(group); |
360 | 353 | ||
354 | return ret; | ||
355 | } | ||
356 | |||
357 | static int iommu_init_device(struct device *dev) | ||
358 | { | ||
359 | struct pci_dev *pdev = to_pci_dev(dev); | ||
360 | struct iommu_dev_data *dev_data; | ||
361 | u16 alias; | ||
362 | int ret; | ||
363 | |||
364 | if (dev->archdata.iommu) | ||
365 | return 0; | ||
366 | |||
367 | dev_data = find_dev_data(get_device_id(dev)); | ||
368 | if (!dev_data) | ||
369 | return -ENOMEM; | ||
370 | |||
371 | alias = amd_iommu_alias_table[dev_data->devid]; | ||
372 | if (alias != dev_data->devid) { | ||
373 | struct iommu_dev_data *alias_data; | ||
374 | |||
375 | alias_data = find_dev_data(alias); | ||
376 | if (alias_data == NULL) { | ||
377 | pr_err("AMD-Vi: Warning: Unhandled device %s\n", | ||
378 | dev_name(dev)); | ||
379 | free_dev_data(dev_data); | ||
380 | return -ENOTSUPP; | ||
381 | } | ||
382 | dev_data->alias_data = alias_data; | ||
383 | } | ||
384 | |||
385 | ret = init_iommu_group(dev); | ||
361 | if (ret) | 386 | if (ret) |
362 | return ret; | 387 | return ret; |
363 | 388 | ||