diff options
author | FUJITA Tomonori <tomof@acm.org> | 2008-02-05 01:27:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-05 12:44:10 -0500 |
commit | 6b7b651055221127304a4e373ee9b762398d54d7 (patch) | |
tree | 06a8383d5d20011a5ffe04b4e78234a8fcc98f51 | |
parent | 7bbdc3d51cf793dd81c38f794f4cb73df58d1527 (diff) |
iommu sg merging: add device_dma_parameters structure
IOMMUs merges scatter/gather segments without considering a low level
driver's restrictions. The problem is that IOMMUs can't access to the
limitations because they are in request_queue.
This patchset introduces a new structure, device_dma_parameters,
including dma information. A pointer to device_dma_parameters is added
to struct device. The bus specific structures (like pci_dev) includes
device_dma_parameters. Low level drivers can use dma_set_max_seg_size
to tell IOMMUs about the restrictions.
We can move more dma stuff in struct device (like dma_mask) to struct
device_dma_parameters later (needs some cleanups before that).
This includes patches for all the IOMMUs that could merge sg (x86_64,
ppc, IA64, alpha, sparc64, and parisc) though only the ppc patch was
tested. The patches for other IOMMUs are only compile tested.
This patch:
Add a new structure, device_dma_parameters, including dma information. A
pointer to device_dma_parameters is added to struct device.
- there are only max_segment_size and segment_boundary_mask there but we'll
move more dma stuff in struct device (like dma_mask) to struct
device_dma_parameters later. segment_boundary_mask is not supported yet.
- new accessors for the dma parameters are added. So we can easily change
where to place struct device_dma_parameters in the future.
- dma_get_max_seg_size returns 64K if dma_parms in struct device isn't set
up properly. 64K is the default max_segment_size in the block layer.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Jeff Garzik <jeff@garzik.org>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/device.h | 11 | ||||
-rw-r--r-- | include/linux/dma-mapping.h | 15 |
2 files changed, 26 insertions, 0 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 479c0b31593c..2258d89bf523 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -410,6 +410,15 @@ extern int devres_release_group(struct device *dev, void *id); | |||
410 | extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp); | 410 | extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp); |
411 | extern void devm_kfree(struct device *dev, void *p); | 411 | extern void devm_kfree(struct device *dev, void *p); |
412 | 412 | ||
413 | struct device_dma_parameters { | ||
414 | /* | ||
415 | * a low level driver may set these to teach IOMMU code about | ||
416 | * sg limitations. | ||
417 | */ | ||
418 | unsigned int max_segment_size; | ||
419 | unsigned long segment_boundary_mask; | ||
420 | }; | ||
421 | |||
413 | struct device { | 422 | struct device { |
414 | struct klist klist_children; | 423 | struct klist klist_children; |
415 | struct klist_node knode_parent; /* node in sibling list */ | 424 | struct klist_node knode_parent; /* node in sibling list */ |
@@ -445,6 +454,8 @@ struct device { | |||
445 | 64 bit addresses for consistent | 454 | 64 bit addresses for consistent |
446 | allocations such descriptors. */ | 455 | allocations such descriptors. */ |
447 | 456 | ||
457 | struct device_dma_parameters *dma_parms; | ||
458 | |||
448 | struct list_head dma_pools; /* dma pools (if dma'ble) */ | 459 | struct list_head dma_pools; /* dma pools (if dma'ble) */ |
449 | 460 | ||
450 | struct dma_coherent_mem *dma_mem; /* internal for coherent mem | 461 | struct dma_coherent_mem *dma_mem; /* internal for coherent mem |
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 4470950892be..df3a3610caf0 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
@@ -60,6 +60,21 @@ static inline int is_device_dma_capable(struct device *dev) | |||
60 | 60 | ||
61 | extern u64 dma_get_required_mask(struct device *dev); | 61 | extern u64 dma_get_required_mask(struct device *dev); |
62 | 62 | ||
63 | static inline unsigned int dma_get_max_seg_size(struct device *dev) | ||
64 | { | ||
65 | return dev->dma_parms ? dev->dma_parms->max_segment_size : 65536; | ||
66 | } | ||
67 | |||
68 | static inline unsigned int dma_set_max_seg_size(struct device *dev, | ||
69 | unsigned int size) | ||
70 | { | ||
71 | if (dev->dma_parms) { | ||
72 | dev->dma_parms->max_segment_size = size; | ||
73 | return 0; | ||
74 | } else | ||
75 | return -EIO; | ||
76 | } | ||
77 | |||
63 | /* flags for the coherent memory api */ | 78 | /* flags for the coherent memory api */ |
64 | #define DMA_MEMORY_MAP 0x01 | 79 | #define DMA_MEMORY_MAP 0x01 |
65 | #define DMA_MEMORY_IO 0x02 | 80 | #define DMA_MEMORY_IO 0x02 |