diff options
author | Martyn Welch <martyn.welch@gefanuc.com> | 2010-02-18 10:12:58 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-03 19:43:00 -0500 |
commit | 4f723df45d3952c485ee0125fb6797ad615901c3 (patch) | |
tree | 3db9d8a00c01c0ffa4d3d66630abf4e72e4771ed | |
parent | 66bd8db52ab48e7189e02d4bf1f23109cc1ede70 (diff) |
Staging: vme: Attribute Testing For Dma Request
Check the directions in which the DMA controller is expected to operate
before giving control of a resource.
Signed-off-by: Martyn Welch <martyn.welch@gefanuc.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/vme/TODO | 22 | ||||
-rw-r--r-- | drivers/staging/vme/bridges/vme_ca91cx42.c | 2 | ||||
-rw-r--r-- | drivers/staging/vme/bridges/vme_tsi148.c | 4 | ||||
-rw-r--r-- | drivers/staging/vme/vme.c | 8 | ||||
-rw-r--r-- | drivers/staging/vme/vme.h | 10 | ||||
-rw-r--r-- | drivers/staging/vme/vme_api.txt | 27 | ||||
-rw-r--r-- | drivers/staging/vme/vme_bridge.h | 1 |
7 files changed, 40 insertions, 34 deletions
diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO index 2201ff6f74d1..bdc5f6248bcc 100644 --- a/drivers/staging/vme/TODO +++ b/drivers/staging/vme/TODO | |||
@@ -4,28 +4,6 @@ | |||
4 | API | 4 | API |
5 | === | 5 | === |
6 | 6 | ||
7 | DMA Resource Allocation incomplete | ||
8 | ---------------------------------- | ||
9 | |||
10 | The current DMA resource Allocation provides no means of selecting the | ||
11 | suitability of a DMA controller based on it's supported modes of operation, as | ||
12 | opposed to the resource allocation mechanisms for master and slave windows: | ||
13 | |||
14 | struct vme_resource *vme_dma_request(struct device *dev); | ||
15 | |||
16 | As opposed to: | ||
17 | |||
18 | struct vme_resource * vme_master_request(struct device *dev, | ||
19 | vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); | ||
20 | |||
21 | The TSI148 can perform, VME-to-PCI, PCI-to-VME, PATTERN-to-VME, PATTERN-to-PCI, | ||
22 | VME-to-VME and PCI-to-PCI transfers. The CA91C142 can only provide VME-to-PCI | ||
23 | and PCI-to-VME. | ||
24 | |||
25 | Add a mechanism to select a VME controller based on source/target type, | ||
26 | required aspace, cycle and width requirements. | ||
27 | |||
28 | |||
29 | Master window broadcast select mask | 7 | Master window broadcast select mask |
30 | ----------------------------------- | 8 | ----------------------------------- |
31 | 9 | ||
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 272cc26ba5ac..7eaba3511ea8 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c | |||
@@ -1109,6 +1109,8 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1109 | mutex_init(&(dma_ctrlr->mtx)); | 1109 | mutex_init(&(dma_ctrlr->mtx)); |
1110 | dma_ctrlr->locked = 0; | 1110 | dma_ctrlr->locked = 0; |
1111 | dma_ctrlr->number = i; | 1111 | dma_ctrlr->number = i; |
1112 | dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | | ||
1113 | VME_DMA_MEM_TO_VME; | ||
1112 | INIT_LIST_HEAD(&(dma_ctrlr->pending)); | 1114 | INIT_LIST_HEAD(&(dma_ctrlr->pending)); |
1113 | INIT_LIST_HEAD(&(dma_ctrlr->running)); | 1115 | INIT_LIST_HEAD(&(dma_ctrlr->running)); |
1114 | list_add_tail(&(dma_ctrlr->list), | 1116 | list_add_tail(&(dma_ctrlr->list), |
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 2ca5126627cd..e74c4a953b2d 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c | |||
@@ -2421,6 +2421,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2421 | mutex_init(&(dma_ctrlr->mtx)); | 2421 | mutex_init(&(dma_ctrlr->mtx)); |
2422 | dma_ctrlr->locked = 0; | 2422 | dma_ctrlr->locked = 0; |
2423 | dma_ctrlr->number = i; | 2423 | dma_ctrlr->number = i; |
2424 | dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | | ||
2425 | VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME | | ||
2426 | VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME | | ||
2427 | VME_DMA_PATTERN_TO_MEM; | ||
2424 | INIT_LIST_HEAD(&(dma_ctrlr->pending)); | 2428 | INIT_LIST_HEAD(&(dma_ctrlr->pending)); |
2425 | INIT_LIST_HEAD(&(dma_ctrlr->running)); | 2429 | INIT_LIST_HEAD(&(dma_ctrlr->running)); |
2426 | list_add_tail(&(dma_ctrlr->list), | 2430 | list_add_tail(&(dma_ctrlr->list), |
diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 8d8f9cb2974d..79c501dac5f9 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c | |||
@@ -643,7 +643,7 @@ EXPORT_SYMBOL(vme_master_free); | |||
643 | * Request a DMA controller with specific attributes, return some unique | 643 | * Request a DMA controller with specific attributes, return some unique |
644 | * identifier. | 644 | * identifier. |
645 | */ | 645 | */ |
646 | struct vme_resource *vme_dma_request(struct device *dev) | 646 | struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route) |
647 | { | 647 | { |
648 | struct vme_bridge *bridge; | 648 | struct vme_bridge *bridge; |
649 | struct list_head *dma_pos = NULL; | 649 | struct list_head *dma_pos = NULL; |
@@ -670,9 +670,11 @@ struct vme_resource *vme_dma_request(struct device *dev) | |||
670 | continue; | 670 | continue; |
671 | } | 671 | } |
672 | 672 | ||
673 | /* Find an unlocked controller */ | 673 | /* Find an unlocked and compatible controller */ |
674 | mutex_lock(&(dma_ctrlr->mtx)); | 674 | mutex_lock(&(dma_ctrlr->mtx)); |
675 | if (dma_ctrlr->locked == 0) { | 675 | if (((dma_ctrlr->route_attr & route) == route) && |
676 | (dma_ctrlr->locked == 0)) { | ||
677 | |||
676 | dma_ctrlr->locked = 1; | 678 | dma_ctrlr->locked = 1; |
677 | mutex_unlock(&(dma_ctrlr->mtx)); | 679 | mutex_unlock(&(dma_ctrlr->mtx)); |
678 | allocated_ctrlr = dma_ctrlr; | 680 | allocated_ctrlr = dma_ctrlr; |
diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h index 5a4d163fae10..48768ca97e16 100644 --- a/drivers/staging/vme/vme.h +++ b/drivers/staging/vme/vme.h | |||
@@ -68,6 +68,14 @@ typedef u32 vme_pattern_t; | |||
68 | #define VME_DMA_PATTERN_WORD (1<<1) | 68 | #define VME_DMA_PATTERN_WORD (1<<1) |
69 | #define VME_DMA_PATTERN_INCREMENT (1<<2) | 69 | #define VME_DMA_PATTERN_INCREMENT (1<<2) |
70 | 70 | ||
71 | typedef u32 vme_dma_route_t; | ||
72 | #define VME_DMA_VME_TO_MEM (1<<0) | ||
73 | #define VME_DMA_MEM_TO_VME (1<<1) | ||
74 | #define VME_DMA_VME_TO_VME (1<<2) | ||
75 | #define VME_DMA_MEM_TO_MEM (1<<3) | ||
76 | #define VME_DMA_PATTERN_TO_VME (1<<4) | ||
77 | #define VME_DMA_PATTERN_TO_MEM (1<<5) | ||
78 | |||
71 | struct vme_dma_attr { | 79 | struct vme_dma_attr { |
72 | vme_dma_t type; | 80 | vme_dma_t type; |
73 | void *private; | 81 | void *private; |
@@ -124,7 +132,7 @@ unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int, | |||
124 | unsigned int, loff_t); | 132 | unsigned int, loff_t); |
125 | void vme_master_free(struct vme_resource *); | 133 | void vme_master_free(struct vme_resource *); |
126 | 134 | ||
127 | struct vme_resource *vme_dma_request(struct device *); | 135 | struct vme_resource *vme_dma_request(struct device *, vme_dma_route_t); |
128 | struct vme_dma_list *vme_new_dma_list(struct vme_resource *); | 136 | struct vme_dma_list *vme_new_dma_list(struct vme_resource *); |
129 | struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t); | 137 | struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t); |
130 | struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t); | 138 | struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t); |
diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt index a5c1b1cd5fcc..a910a0c4388b 100644 --- a/drivers/staging/vme/vme_api.txt +++ b/drivers/staging/vme/vme_api.txt | |||
@@ -77,16 +77,21 @@ driver in question: | |||
77 | struct vme_resource * vme_slave_request(struct device *dev, | 77 | struct vme_resource * vme_slave_request(struct device *dev, |
78 | vme_address_t aspace, vme_cycle_t cycle); | 78 | vme_address_t aspace, vme_cycle_t cycle); |
79 | 79 | ||
80 | struct vme_resource *vme_dma_request(struct device *dev); | 80 | struct vme_resource *vme_dma_request(struct device *dev, |
81 | vme_dma_route_t route); | ||
81 | 82 | ||
82 | For slave windows these attributes are split into those of type 'vme_address_t' | 83 | For slave windows these attributes are split into those of type 'vme_address_t' |
83 | and 'vme_cycle_t'. Master windows add a further set of attributes 'vme_cycle_t'. | 84 | and 'vme_cycle_t'. Master windows add a further set of attributes |
84 | These attributes are defined as bitmasks and as such any combination of the | 85 | 'vme_cycle_t'. These attributes are defined as bitmasks and as such any |
85 | attributes can be requested for a single window, the core will assign a window | 86 | combination of the attributes can be requested for a single window, the core |
86 | that meets the requirements, returning a pointer of type vme_resource that | 87 | will assign a window that meets the requirements, returning a pointer of type |
87 | should be used to identify the allocated resource when it is used. If an | 88 | vme_resource that should be used to identify the allocated resource when it is |
88 | unallocated window fitting the requirements can not be found a NULL pointer will | 89 | used. For DMA controllers, the request function requires the potential |
89 | be returned. | 90 | direction of any transfers to be provided in the route attributes. This is |
91 | typically VME-to-MEM and/or MEM-to-VME, though some hardware can support | ||
92 | VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. If an | ||
93 | unallocated window fitting the requirements can not be found a NULL pointer | ||
94 | will be returned. | ||
90 | 95 | ||
91 | Functions are also provided to free window allocations once they are no longer | 96 | Functions are also provided to free window allocations once they are no longer |
92 | required. These functions should be passed the pointer to the resource provided | 97 | required. These functions should be passed the pointer to the resource provided |
@@ -237,6 +242,12 @@ covered under "Transfer Attributes"): | |||
237 | struct vme_dma_attr *src, struct vme_dma_attr *dest, | 242 | struct vme_dma_attr *src, struct vme_dma_attr *dest, |
238 | size_t count); | 243 | size_t count); |
239 | 244 | ||
245 | NOTE: The detailed attributes of the transfers source and destination | ||
246 | are not checked until an entry is added to a DMA list, the request | ||
247 | for a DMA channel purely checks the directions in which the | ||
248 | controller is expected to transfer data. As a result it is | ||
249 | possible for this call to return an error, for example if the | ||
250 | source or destination is in an unsupported VME address space. | ||
240 | 251 | ||
241 | Transfer Attributes | 252 | Transfer Attributes |
242 | ------------------- | 253 | ------------------- |
diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h index 92e5614ab910..f8ead21c94fb 100644 --- a/drivers/staging/vme/vme_bridge.h +++ b/drivers/staging/vme/vme_bridge.h | |||
@@ -64,6 +64,7 @@ struct vme_dma_resource { | |||
64 | int number; | 64 | int number; |
65 | struct list_head pending; | 65 | struct list_head pending; |
66 | struct list_head running; | 66 | struct list_head running; |
67 | vme_dma_route_t route_attr; | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | struct vme_lm_resource { | 70 | struct vme_lm_resource { |