aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorJon Burgess <jburgess777@googlemail.com>2007-05-03 11:23:44 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-05-09 09:12:42 -0400
commit87c3019d7b1acb7704a257d78c482112e9b0c227 (patch)
tree312478a0bed426b3ca89bf4fae1880fed9986bd2 /drivers/media/common
parent32a1db42480dc972e8e92be68d9e604f6aff5381 (diff)
V4L/DVB (5592): DMA: Correctly free resources on error, sync PCI streamed data
I added saa7146_vmalloc_destroy_pgtable() which frees the resources allocated by saa7146_vmalloc_build_pgtable() and updated the callers in budget-core.c and av7110.c. I have also been through the updated functions and updated the error paths to ensure they free all allocated resources on error. I also realised that there are other callers to saa7146_pgtable_free() which did not have any sg DMA mapped so it seems wrong to add the pci_unmap_sg() into that function. Instead I created saa7146_vmalloc_destroy_pgtable() to do this. Also included in this patch are the previous fixes for pci_unmap_sg() and syncing the PCI streamed data to work with a SWIOTLB and match the requirements documented in DMA-API.txt. Signed-off-by: Jon Burgess <jburgess777@googlemail.com> Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/saa7146_core.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 86cbdbcf9d7d..ef3e54cd9407 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -136,28 +136,45 @@ char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa
136 char *mem = vmalloc_32(length); 136 char *mem = vmalloc_32(length);
137 int slen = 0; 137 int slen = 0;
138 138
139 if (NULL == mem) { 139 if (NULL == mem)
140 return NULL; 140 goto err_null;
141 }
142 141
143 if (!(pt->slist = vmalloc_to_sg(mem, pages))) { 142 if (!(pt->slist = vmalloc_to_sg(mem, pages)))
144 vfree(mem); 143 goto err_free_mem;
145 return NULL;
146 }
147 144
148 if (saa7146_pgtable_alloc(pci, pt)) { 145 if (saa7146_pgtable_alloc(pci, pt))
149 kfree(pt->slist); 146 goto err_free_slist;
150 pt->slist = NULL;
151 vfree(mem);
152 return NULL;
153 }
154 147
155 slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE); 148 pt->nents = pages;
156 if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) { 149 slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
157 return NULL; 150 if (0 == slen)
158 } 151 goto err_free_pgtable;
152
153 if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
154 goto err_unmap_sg;
159 155
160 return mem; 156 return mem;
157
158err_unmap_sg:
159 pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
160err_free_pgtable:
161 saa7146_pgtable_free(pci, pt);
162err_free_slist:
163 kfree(pt->slist);
164 pt->slist = NULL;
165err_free_mem:
166 vfree(mem);
167err_null:
168 return NULL;
169}
170
171void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt)
172{
173 pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
174 saa7146_pgtable_free(pci, pt);
175 kfree(pt->slist);
176 pt->slist = NULL;
177 vfree(mem);
161} 178}
162 179
163void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt) 180void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -166,8 +183,6 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
166 return; 183 return;
167 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma); 184 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
168 pt->cpu = NULL; 185 pt->cpu = NULL;
169 kfree(pt->slist);
170 pt->slist = NULL;
171} 186}
172 187
173int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) 188int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -528,6 +543,7 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
528EXPORT_SYMBOL_GPL(saa7146_pgtable_free); 543EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
529EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single); 544EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
530EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable); 545EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
546EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
531EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done); 547EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
532 548
533EXPORT_SYMBOL_GPL(saa7146_setgpio); 549EXPORT_SYMBOL_GPL(saa7146_setgpio);