diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2012-10-09 00:49:41 -0400 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2012-10-24 11:29:46 -0400 |
commit | 2851db21b88ff3e80e1b3ab5e23b1a49d6f734bf (patch) | |
tree | c9528636112b73201f6822e6341b5ebb508013bc /drivers/iommu/amd_iommu.c | |
parent | eb9c95271eafb62f7024547016ad00636c1425c1 (diff) |
iommu/amd: Split IOMMU Group topology walk
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 | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index b65b377815ac..6edbd0edcae7 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -276,32 +276,9 @@ 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 init_iommu_group(struct device *dev) | 279 | static struct pci_dev *get_isolation_root(struct pci_dev *pdev) |
280 | { | 280 | { |
281 | struct iommu_dev_data *dev_data; | 281 | struct pci_dev *dma_pdev = pdev; |
282 | struct iommu_group *group; | ||
283 | struct pci_dev *dma_pdev = NULL; | ||
284 | int ret; | ||
285 | |||
286 | group = iommu_group_get(dev); | ||
287 | if (group) { | ||
288 | iommu_group_put(group); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | dev_data = find_dev_data(get_device_id(dev)); | ||
293 | if (!dev_data) | ||
294 | return -ENOMEM; | ||
295 | |||
296 | if (dev_data->alias_data) { | ||
297 | u16 alias; | ||
298 | |||
299 | alias = amd_iommu_alias_table[dev_data->devid]; | ||
300 | dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff); | ||
301 | } | ||
302 | |||
303 | if (!dma_pdev) | ||
304 | dma_pdev = pci_dev_get(to_pci_dev(dev)); | ||
305 | 282 | ||
306 | /* Account for quirked devices */ | 283 | /* Account for quirked devices */ |
307 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | 284 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); |
@@ -339,6 +316,37 @@ static int init_iommu_group(struct device *dev) | |||
339 | } | 316 | } |
340 | 317 | ||
341 | root_bus: | 318 | root_bus: |
319 | return dma_pdev; | ||
320 | } | ||
321 | |||
322 | static int init_iommu_group(struct device *dev) | ||
323 | { | ||
324 | struct iommu_dev_data *dev_data; | ||
325 | struct iommu_group *group; | ||
326 | struct pci_dev *dma_pdev = NULL; | ||
327 | int ret; | ||
328 | |||
329 | group = iommu_group_get(dev); | ||
330 | if (group) { | ||
331 | iommu_group_put(group); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | dev_data = find_dev_data(get_device_id(dev)); | ||
336 | if (!dev_data) | ||
337 | return -ENOMEM; | ||
338 | |||
339 | if (dev_data->alias_data) { | ||
340 | u16 alias; | ||
341 | |||
342 | alias = amd_iommu_alias_table[dev_data->devid]; | ||
343 | dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff); | ||
344 | } | ||
345 | |||
346 | if (!dma_pdev) | ||
347 | dma_pdev = pci_dev_get(to_pci_dev(dev)); | ||
348 | |||
349 | dma_pdev = get_isolation_root(dma_pdev); | ||
342 | group = iommu_group_get(&dma_pdev->dev); | 350 | group = iommu_group_get(&dma_pdev->dev); |
343 | pci_dev_put(dma_pdev); | 351 | pci_dev_put(dma_pdev); |
344 | if (!group) { | 352 | if (!group) { |