}
dev_dbg(dev,
- "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
- __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr),
- buf->safe, (void *) buf->safe_dma_addr);
+ "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
if ((dir == DMA_TO_DEVICE) ||
(dir == DMA_BIDIRECTIONAL)) {
BUG_ON(buf->size != size);
dev_dbg(dev,
- "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
- __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr),
- buf->safe, (void *) buf->safe_dma_addr);
+ "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
DO_STATS ( device_info->bounce_count++ );
}
}
-static inline void
-sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction dir)
+static int sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction dir)
{
struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
struct safe_buffer *buf = NULL;
*/
dev_dbg(dev,
- "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
- __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr),
- buf->safe, (void *) buf->safe_dma_addr);
+ "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
DO_STATS ( device_info->bounce_count++ );
* No need to sync the safe buffer - it was allocated
* via the coherent allocators.
*/
+ return 0;
} else {
- dma_cache_maint(dma_to_virt(dev, dma_addr), size, dir);
+ return 1;
}
}
return dma_addr;
}
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir)
+{
+ dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
+ __func__, page, offset, size, dir);
+
+ BUG_ON(dir == DMA_NONE);
+
+ return map_single(dev, page_address(page) + offset, size, dir);
+}
+EXPORT_SYMBOL(dma_map_page);
+
/*
* see if a mapped address was really a "safe" buffer and if so, copy
* the data from the safe buffer back to the unsafe buffer and free up
unmap_single(dev, dma_addr, size, dir);
}
-int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir)
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_addr,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir)
{
- int i;
-
- dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
- __func__, sg, nents, dir);
-
- BUG_ON(dir == DMA_NONE);
+ dev_dbg(dev, "%s(dma=%#x,off=%#lx,size=%zx,dir=%x)\n",
+ __func__, dma_addr, offset, size, dir);
- for (i = 0; i < nents; i++, sg++) {
- struct page *page = sg_page(sg);
- unsigned int offset = sg->offset;
- unsigned int length = sg->length;
- void *ptr = page_address(page) + offset;
-
- sg->dma_address =
- map_single(dev, ptr, length, dir);
- }
-
- return nents;
+ if (sync_single(dev, dma_addr, offset + size, dir))
+ dma_cache_maint(dma_to_virt(dev, dma_addr) + offset, size, dir);
}
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir)
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_addr,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir)
{
- int i;
-
- dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
- __func__, sg, nents, dir);
-
- BUG_ON(dir == DMA_NONE);
-
- for (i = 0; i < nents; i++, sg++) {
- dma_addr_t dma_addr = sg->dma_address;
- unsigned int length = sg->length;
-
- unmap_single(dev, dma_addr, length, dir);
- }
-}
-
-void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction dir)
-{
- dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
- __func__, (void *) dma_addr, size, dir);
-
- sync_single(dev, dma_addr, size, dir);
-}
-
-void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction dir)
-{
- dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
- __func__, (void *) dma_addr, size, dir);
+ dev_dbg(dev, "%s(dma=%#x,off=%#lx,size=%zx,dir=%x)\n",
+ __func__, dma_addr, offset, size, dir);
- sync_single(dev, dma_addr, size, dir);
+ if (sync_single(dev, dma_addr, offset + size, dir))
+ dma_cache_maint(dma_to_virt(dev, dma_addr) + offset, size, dir);
}
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
void
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
+ struct scatterlist *s;
int i;
dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
BUG_ON(dir == DMA_NONE);
- for (i = 0; i < nents; i++, sg++) {
- dma_addr_t dma_addr = sg->dma_address;
- unsigned int length = sg->length;
+ for_each_sg(sg, s, nents, i) {
+ dma_addr_t dma_addr = s->dma_address;
+ unsigned int length = s->length;
sync_single(dev, dma_addr, length, dir);
}
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
+ struct scatterlist *s;
int i;
dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
BUG_ON(dir == DMA_NONE);
- for (i = 0; i < nents; i++, sg++) {
- dma_addr_t dma_addr = sg->dma_address;
- unsigned int length = sg->length;
+ for_each_sg(sg, s, nents, i) {
+ dma_addr_t dma_addr = s->dma_address;
+ unsigned int length = s->length;
sync_single(dev, dma_addr, length, dir);
}
EXPORT_SYMBOL(dma_map_single);
EXPORT_SYMBOL(dma_unmap_single);
-EXPORT_SYMBOL(dma_map_sg);
-EXPORT_SYMBOL(dma_unmap_sg);
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-EXPORT_SYMBOL(dma_sync_single_for_device);
EXPORT_SYMBOL(dma_sync_sg_for_cpu);
EXPORT_SYMBOL(dma_sync_sg_for_device);
EXPORT_SYMBOL(dmabounce_register_dev);