diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-02-24 15:17:07 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-02-24 15:17:07 -0500 |
commit | e11d57ca0b6dada29007ce3ad3db6c84034a768f (patch) | |
tree | 39ad0c208e2cb3da79f958bd0e9d0d12b8e5f8fe /drivers/gpu/drm/nouveau/nouveau_sgdma.c | |
parent | 317495b25ec1f0beb0dbac8ee0dfec59a1addf03 (diff) | |
parent | a2c06ee2fe5b48a71e697bae00c6e7195fc016b6 (diff) |
Merge remote-tracking branch 'airlied/drm-core-next' into drm-nouveau-next
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_sgdma.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_sgdma.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 9a250eb53098..07b115184b87 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -12,6 +12,7 @@ struct nouveau_sgdma_be { | |||
12 | struct drm_device *dev; | 12 | struct drm_device *dev; |
13 | 13 | ||
14 | dma_addr_t *pages; | 14 | dma_addr_t *pages; |
15 | bool *ttm_alloced; | ||
15 | unsigned nr_pages; | 16 | unsigned nr_pages; |
16 | 17 | ||
17 | u64 offset; | 18 | u64 offset; |
@@ -20,7 +21,8 @@ struct nouveau_sgdma_be { | |||
20 | 21 | ||
21 | static int | 22 | static int |
22 | nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, | 23 | nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, |
23 | struct page **pages, struct page *dummy_read_page) | 24 | struct page **pages, struct page *dummy_read_page, |
25 | dma_addr_t *dma_addrs) | ||
24 | { | 26 | { |
25 | struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; | 27 | struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; |
26 | struct drm_device *dev = nvbe->dev; | 28 | struct drm_device *dev = nvbe->dev; |
@@ -34,15 +36,25 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, | |||
34 | if (!nvbe->pages) | 36 | if (!nvbe->pages) |
35 | return -ENOMEM; | 37 | return -ENOMEM; |
36 | 38 | ||
39 | nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL); | ||
40 | if (!nvbe->ttm_alloced) | ||
41 | return -ENOMEM; | ||
42 | |||
37 | nvbe->nr_pages = 0; | 43 | nvbe->nr_pages = 0; |
38 | while (num_pages--) { | 44 | while (num_pages--) { |
39 | nvbe->pages[nvbe->nr_pages] = | 45 | if (dma_addrs[nvbe->nr_pages] != DMA_ERROR_CODE) { |
40 | pci_map_page(dev->pdev, pages[nvbe->nr_pages], 0, | 46 | nvbe->pages[nvbe->nr_pages] = |
47 | dma_addrs[nvbe->nr_pages]; | ||
48 | nvbe->ttm_alloced[nvbe->nr_pages] = true; | ||
49 | } else { | ||
50 | nvbe->pages[nvbe->nr_pages] = | ||
51 | pci_map_page(dev->pdev, pages[nvbe->nr_pages], 0, | ||
41 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 52 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
42 | if (pci_dma_mapping_error(dev->pdev, | 53 | if (pci_dma_mapping_error(dev->pdev, |
43 | nvbe->pages[nvbe->nr_pages])) { | 54 | nvbe->pages[nvbe->nr_pages])) { |
44 | be->func->clear(be); | 55 | be->func->clear(be); |
45 | return -EFAULT; | 56 | return -EFAULT; |
57 | } | ||
46 | } | 58 | } |
47 | 59 | ||
48 | nvbe->nr_pages++; | 60 | nvbe->nr_pages++; |
@@ -65,11 +77,14 @@ nouveau_sgdma_clear(struct ttm_backend *be) | |||
65 | be->func->unbind(be); | 77 | be->func->unbind(be); |
66 | 78 | ||
67 | while (nvbe->nr_pages--) { | 79 | while (nvbe->nr_pages--) { |
68 | pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages], | 80 | if (!nvbe->ttm_alloced[nvbe->nr_pages]) |
81 | pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages], | ||
69 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 82 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
70 | } | 83 | } |
71 | kfree(nvbe->pages); | 84 | kfree(nvbe->pages); |
85 | kfree(nvbe->ttm_alloced); | ||
72 | nvbe->pages = NULL; | 86 | nvbe->pages = NULL; |
87 | nvbe->ttm_alloced = NULL; | ||
73 | nvbe->nr_pages = 0; | 88 | nvbe->nr_pages = 0; |
74 | } | 89 | } |
75 | } | 90 | } |