From: James Bottomley <James.Bottomley@steeleye.com>
To: David Brownell <david-b@pacbell.net>
Cc: James Bottomley <James.Bottomley@SteelEye.com>,
linux-kernel@vger.kernel.org
Subject: Re: [RFT][PATCH] generic device DMA implementation
Date: Sat, 28 Dec 2002 10:13:28 -0600 [thread overview]
Message-ID: <200212281613.gBSGDTn02392@localhost.localdomain> (raw)
In-Reply-To: Message from David Brownell <david-b@pacbell.net> of "Fri, 27 Dec 2002 17:56:43 PST." <3E0D04DB.1000500@pacbell.net>
[-- Attachment #1: Type: text/plain, Size: 757 bytes --]
OK, the attached is a sketch of an implementation of bus_type operations.
It renames all the platform dma_ operations to platform_dma_ and will call
only the bus specific operation if it exists. Thus it will be the
responsibility of the bus to call the platform_dma_ functions correctly (this
one is a large loaded gun).
The answer to error handling in the general case is still no (because I don't
want to impact the main line code for a specific problem, and the main line is
x86 which effectively has infinite mapping resources), but I don't see why the
platforms can't export a set of values they guarantee not to return as
dma_addr_t's that you can use for errors in the bus implementations.
Would this solve most of your problems?
James
[-- Attachment #2: tmp.diff --]
[-- Type: text/plain , Size: 5094 bytes --]
===== include/linux/device.h 1.70 vs edited =====
--- 1.70/include/linux/device.h Mon Dec 16 10:01:41 2002
+++ edited/include/linux/device.h Sat Dec 28 09:57:51 2002
@@ -61,6 +61,7 @@
struct device;
struct device_driver;
struct device_class;
+struct bus_dma_ops;
struct bus_type {
char * name;
@@ -75,6 +76,7 @@
struct device * (*add) (struct device * parent, char * bus_id);
int (*hotplug) (struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
+ struct bus_dma_ops * dma_ops;
};
===== include/linux/dma-mapping.h 1.1 vs edited =====
--- 1.1/include/linux/dma-mapping.h Sat Dec 21 22:37:05 2002
+++ edited/include/linux/dma-mapping.h Sat Dec 28 10:02:37 2002
@@ -10,7 +10,144 @@
DMA_NONE = 3,
};
+struct bus_dma_ops {
+ int (*supported)(struct device *dev, u64 mask);
+ int (*set_mask)(struct device *dev, u64 mask);
+ void *(*alloc_coherent)(struct device *dev, size_t size,
+ dma_addr_t *dma_handle);
+ void (*free_coherent)(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t dma_handle);
+ dma_addr_t (*map_single)(struct device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction direction);
+ void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction);
+ int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction);
+ void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction direction);
+ void (*sync_single)(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction);
+ void (*sync_sg)(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction);
+};
+
#include <asm/dma-mapping.h>
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->supported)
+ return bus->dma_ops->supported(dev, mask);
+
+ return platform_dma_supported(dev, mask);
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->set_mask)
+ return bus->dma_ops->set_mask(dev, mask);
+
+ return platform_dma_set_mask(dev, dma_mask);
+}
+
+static inline void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->alloc_coherent)
+ return bus->dma_ops->alloc_coherent(dev, size, dma_handle);
+
+ return platform_dma_alloc_coherent(dev, size, dma_handle);
+}
+
+static inline void
+dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t dma_handle)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->free_coherent)
+ bus->dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+ else
+ platform_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->map_single)
+ return bus->dma_ops->map_single(dev, cpu_addr, size, direction);
+ return platform_dma_map_single(dev, cpu_addr, size, direction);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->unmap_single)
+ bus->dma_ops->unmap_single(dev, dma_addr, size, direction);
+ else
+ platform_dma_unmap_single(dev, dma_addr, size, direction);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->map_sg)
+ return bus->dma_ops->map_sg(dev, sg, nents, direction);
+
+ return platform_dma_map_sg(dev, sg, nents, direction);
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+ enum dma_data_direction direction)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->unmap_sg)
+ bus->dma_ops->unmap_sg(dev, sg, nhwentries, direction);
+ else
+ platform_dma_unmap_sg(dev, sg, nhwentries, direction);
+}
+
+static inline void
+dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->sync_single)
+ bus->dma_ops->sync_single(dev, dma_handle, size, direction);
+ else
+ platform_dma_sync_single(dev, dma_handle, size, direction);
+}
+
+static inline void
+dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ struct bus_type *bus = dev->bus;
+
+ if(bus->dma_ops && bus->dma_ops->sync_sg)
+ bus->dma_ops->sync_sg(dev, sg, nelems, direction);
+ else
+ platform_dma_sync_sg(dev, sg, nelems, direction);
+}
#endif
next prev parent reply other threads:[~2002-12-28 16:05 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-12-27 20:21 [RFT][PATCH] generic device DMA implementation David Brownell
2002-12-27 21:40 ` James Bottomley
2002-12-28 1:29 ` David Brownell
2002-12-28 16:18 ` James Bottomley
2002-12-28 18:16 ` David Brownell
2002-12-28 1:56 ` David Brownell
2002-12-28 16:13 ` James Bottomley [this message]
2002-12-28 17:41 ` David Brownell
2002-12-30 23:11 ` [PATCH] generic device DMA (dma_pool update) David Brownell
2002-12-31 15:00 ` James Bottomley
2002-12-31 17:04 ` David Brownell
2002-12-31 17:23 ` James Bottomley
2002-12-31 18:11 ` David Brownell
2002-12-31 18:44 ` James Bottomley
2002-12-31 19:29 ` David Brownell
2002-12-31 19:50 ` James Bottomley
2002-12-31 21:17 ` David Brownell
2002-12-31 16:36 ` James Bottomley
2002-12-31 17:32 ` David Brownell
2002-12-27 21:47 ` [RFT][PATCH] generic device DMA implementation James Bottomley
2002-12-28 2:28 ` David Brownell
-- strict thread matches above, loose matches on Subject: below --
2002-12-28 22:19 Adam J. Richter
2002-12-30 23:23 ` David Brownell
2002-12-28 20:11 Adam J. Richter
2002-12-28 15:41 Adam J. Richter
2002-12-28 16:59 ` David Brownell
2002-12-28 3:39 Adam J. Richter
2002-12-30 0:45 ` Alan Cox
2002-12-28 2:48 Adam J. Richter
2002-12-28 15:05 ` David Brownell
2002-12-27 22:57 Manfred Spraul
2002-12-27 23:55 ` James Bottomley
2002-12-28 0:20 ` Manfred Spraul
2002-12-28 16:26 ` James Bottomley
2002-12-28 17:54 ` Manfred Spraul
2002-12-28 18:13 ` James Bottomley
2002-12-28 18:25 ` Manfred Spraul
2002-12-28 18:40 ` James Bottomley
2002-12-28 20:05 ` Manfred Spraul
2002-12-18 3:01 James Bottomley
2002-12-18 3:13 ` David Mosberger
2002-12-28 18:14 ` Russell King
2002-12-28 18:19 ` James Bottomley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200212281613.gBSGDTn02392@localhost.localdomain \
--to=james.bottomley@steeleye.com \
--cc=david-b@pacbell.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox