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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
66bd8db52a
commit
4f723df45d
@@ -4,28 +4,6 @@
|
|||||||
API
|
API
|
||||||
===
|
===
|
||||||
|
|
||||||
DMA Resource Allocation incomplete
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
The current DMA resource Allocation provides no means of selecting the
|
|
||||||
suitability of a DMA controller based on it's supported modes of operation, as
|
|
||||||
opposed to the resource allocation mechanisms for master and slave windows:
|
|
||||||
|
|
||||||
struct vme_resource *vme_dma_request(struct device *dev);
|
|
||||||
|
|
||||||
As opposed to:
|
|
||||||
|
|
||||||
struct vme_resource * vme_master_request(struct device *dev,
|
|
||||||
vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
|
|
||||||
|
|
||||||
The TSI148 can perform, VME-to-PCI, PCI-to-VME, PATTERN-to-VME, PATTERN-to-PCI,
|
|
||||||
VME-to-VME and PCI-to-PCI transfers. The CA91C142 can only provide VME-to-PCI
|
|
||||||
and PCI-to-VME.
|
|
||||||
|
|
||||||
Add a mechanism to select a VME controller based on source/target type,
|
|
||||||
required aspace, cycle and width requirements.
|
|
||||||
|
|
||||||
|
|
||||||
Master window broadcast select mask
|
Master window broadcast select mask
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
@@ -1109,6 +1109,8 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
mutex_init(&(dma_ctrlr->mtx));
|
mutex_init(&(dma_ctrlr->mtx));
|
||||||
dma_ctrlr->locked = 0;
|
dma_ctrlr->locked = 0;
|
||||||
dma_ctrlr->number = i;
|
dma_ctrlr->number = i;
|
||||||
|
dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
|
||||||
|
VME_DMA_MEM_TO_VME;
|
||||||
INIT_LIST_HEAD(&(dma_ctrlr->pending));
|
INIT_LIST_HEAD(&(dma_ctrlr->pending));
|
||||||
INIT_LIST_HEAD(&(dma_ctrlr->running));
|
INIT_LIST_HEAD(&(dma_ctrlr->running));
|
||||||
list_add_tail(&(dma_ctrlr->list),
|
list_add_tail(&(dma_ctrlr->list),
|
||||||
|
@@ -2421,6 +2421,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
mutex_init(&(dma_ctrlr->mtx));
|
mutex_init(&(dma_ctrlr->mtx));
|
||||||
dma_ctrlr->locked = 0;
|
dma_ctrlr->locked = 0;
|
||||||
dma_ctrlr->number = i;
|
dma_ctrlr->number = i;
|
||||||
|
dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
|
||||||
|
VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME |
|
||||||
|
VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME |
|
||||||
|
VME_DMA_PATTERN_TO_MEM;
|
||||||
INIT_LIST_HEAD(&(dma_ctrlr->pending));
|
INIT_LIST_HEAD(&(dma_ctrlr->pending));
|
||||||
INIT_LIST_HEAD(&(dma_ctrlr->running));
|
INIT_LIST_HEAD(&(dma_ctrlr->running));
|
||||||
list_add_tail(&(dma_ctrlr->list),
|
list_add_tail(&(dma_ctrlr->list),
|
||||||
|
@@ -643,7 +643,7 @@ EXPORT_SYMBOL(vme_master_free);
|
|||||||
* Request a DMA controller with specific attributes, return some unique
|
* Request a DMA controller with specific attributes, return some unique
|
||||||
* identifier.
|
* identifier.
|
||||||
*/
|
*/
|
||||||
struct vme_resource *vme_dma_request(struct device *dev)
|
struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route)
|
||||||
{
|
{
|
||||||
struct vme_bridge *bridge;
|
struct vme_bridge *bridge;
|
||||||
struct list_head *dma_pos = NULL;
|
struct list_head *dma_pos = NULL;
|
||||||
@@ -670,9 +670,11 @@ struct vme_resource *vme_dma_request(struct device *dev)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find an unlocked controller */
|
/* Find an unlocked and compatible controller */
|
||||||
mutex_lock(&(dma_ctrlr->mtx));
|
mutex_lock(&(dma_ctrlr->mtx));
|
||||||
if (dma_ctrlr->locked == 0) {
|
if (((dma_ctrlr->route_attr & route) == route) &&
|
||||||
|
(dma_ctrlr->locked == 0)) {
|
||||||
|
|
||||||
dma_ctrlr->locked = 1;
|
dma_ctrlr->locked = 1;
|
||||||
mutex_unlock(&(dma_ctrlr->mtx));
|
mutex_unlock(&(dma_ctrlr->mtx));
|
||||||
allocated_ctrlr = dma_ctrlr;
|
allocated_ctrlr = dma_ctrlr;
|
||||||
|
@@ -68,6 +68,14 @@ typedef u32 vme_pattern_t;
|
|||||||
#define VME_DMA_PATTERN_WORD (1<<1)
|
#define VME_DMA_PATTERN_WORD (1<<1)
|
||||||
#define VME_DMA_PATTERN_INCREMENT (1<<2)
|
#define VME_DMA_PATTERN_INCREMENT (1<<2)
|
||||||
|
|
||||||
|
typedef u32 vme_dma_route_t;
|
||||||
|
#define VME_DMA_VME_TO_MEM (1<<0)
|
||||||
|
#define VME_DMA_MEM_TO_VME (1<<1)
|
||||||
|
#define VME_DMA_VME_TO_VME (1<<2)
|
||||||
|
#define VME_DMA_MEM_TO_MEM (1<<3)
|
||||||
|
#define VME_DMA_PATTERN_TO_VME (1<<4)
|
||||||
|
#define VME_DMA_PATTERN_TO_MEM (1<<5)
|
||||||
|
|
||||||
struct vme_dma_attr {
|
struct vme_dma_attr {
|
||||||
vme_dma_t type;
|
vme_dma_t type;
|
||||||
void *private;
|
void *private;
|
||||||
@@ -124,7 +132,7 @@ unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int,
|
|||||||
unsigned int, loff_t);
|
unsigned int, loff_t);
|
||||||
void vme_master_free(struct vme_resource *);
|
void vme_master_free(struct vme_resource *);
|
||||||
|
|
||||||
struct vme_resource *vme_dma_request(struct device *);
|
struct vme_resource *vme_dma_request(struct device *, vme_dma_route_t);
|
||||||
struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
|
struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
|
||||||
struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t);
|
struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t);
|
||||||
struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
|
struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
|
||||||
|
@@ -77,16 +77,21 @@ driver in question:
|
|||||||
struct vme_resource * vme_slave_request(struct device *dev,
|
struct vme_resource * vme_slave_request(struct device *dev,
|
||||||
vme_address_t aspace, vme_cycle_t cycle);
|
vme_address_t aspace, vme_cycle_t cycle);
|
||||||
|
|
||||||
struct vme_resource *vme_dma_request(struct device *dev);
|
struct vme_resource *vme_dma_request(struct device *dev,
|
||||||
|
vme_dma_route_t route);
|
||||||
|
|
||||||
For slave windows these attributes are split into those of type 'vme_address_t'
|
For slave windows these attributes are split into those of type 'vme_address_t'
|
||||||
and 'vme_cycle_t'. Master windows add a further set of attributes 'vme_cycle_t'.
|
and 'vme_cycle_t'. Master windows add a further set of attributes
|
||||||
These attributes are defined as bitmasks and as such any combination of the
|
'vme_cycle_t'. These attributes are defined as bitmasks and as such any
|
||||||
attributes can be requested for a single window, the core will assign a window
|
combination of the attributes can be requested for a single window, the core
|
||||||
that meets the requirements, returning a pointer of type vme_resource that
|
will assign a window that meets the requirements, returning a pointer of type
|
||||||
should be used to identify the allocated resource when it is used. If an
|
vme_resource that should be used to identify the allocated resource when it is
|
||||||
unallocated window fitting the requirements can not be found a NULL pointer will
|
used. For DMA controllers, the request function requires the potential
|
||||||
be returned.
|
direction of any transfers to be provided in the route attributes. This is
|
||||||
|
typically VME-to-MEM and/or MEM-to-VME, though some hardware can support
|
||||||
|
VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. If an
|
||||||
|
unallocated window fitting the requirements can not be found a NULL pointer
|
||||||
|
will be returned.
|
||||||
|
|
||||||
Functions are also provided to free window allocations once they are no longer
|
Functions are also provided to free window allocations once they are no longer
|
||||||
required. These functions should be passed the pointer to the resource provided
|
required. These functions should be passed the pointer to the resource provided
|
||||||
@@ -237,6 +242,12 @@ covered under "Transfer Attributes"):
|
|||||||
struct vme_dma_attr *src, struct vme_dma_attr *dest,
|
struct vme_dma_attr *src, struct vme_dma_attr *dest,
|
||||||
size_t count);
|
size_t count);
|
||||||
|
|
||||||
|
NOTE: The detailed attributes of the transfers source and destination
|
||||||
|
are not checked until an entry is added to a DMA list, the request
|
||||||
|
for a DMA channel purely checks the directions in which the
|
||||||
|
controller is expected to transfer data. As a result it is
|
||||||
|
possible for this call to return an error, for example if the
|
||||||
|
source or destination is in an unsupported VME address space.
|
||||||
|
|
||||||
Transfer Attributes
|
Transfer Attributes
|
||||||
-------------------
|
-------------------
|
||||||
|
@@ -64,6 +64,7 @@ struct vme_dma_resource {
|
|||||||
int number;
|
int number;
|
||||||
struct list_head pending;
|
struct list_head pending;
|
||||||
struct list_head running;
|
struct list_head running;
|
||||||
|
vme_dma_route_t route_attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vme_lm_resource {
|
struct vme_lm_resource {
|
||||||
|
Reference in New Issue
Block a user