aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_sgdma.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-02-24 15:17:07 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-02-24 15:17:07 -0500
commite11d57ca0b6dada29007ce3ad3db6c84034a768f (patch)
tree39ad0c208e2cb3da79f958bd0e9d0d12b8e5f8fe /drivers/gpu/drm/nouveau/nouveau_sgdma.c
parent317495b25ec1f0beb0dbac8ee0dfec59a1addf03 (diff)
parenta2c06ee2fe5b48a71e697bae00c6e7195fc016b6 (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.c31
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
21static int 22static int
22nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, 23nouveau_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}