From martyn.welch@gefanuc.com Fri Aug 28 08:27:25 2009 From: Martyn Welch Date: Fri, 28 Aug 2009 11:28:56 +0100 Subject: Staging: vme: Separate the list of TODOs from the API documentation To: gregkh@suse.de Cc: devel@linuxdriverproject.org Message-ID: <20090828102855.29110.48917.stgit@ES-J7S4D2J.amer.consind.ge.com> This patch moves the API documentation to it's own file and provides a proper list of TODOs. Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/TODO | 410 +++++----------------------------------- drivers/staging/vme/vme_api.txt | 372 ++++++++++++++++++++++++++++++++++++ 2 files changed, 432 insertions(+), 350 deletions(-) --- a/drivers/staging/vme/TODO +++ b/drivers/staging/vme/TODO @@ -1,388 +1,98 @@ - VME Device Driver API - ===================== + TODO + ==== -Driver registration -=================== +API +=== -As with other subsystems within the Linux kernel, VME device drivers register -with the VME subsystem, typically called from the devices init routine. This is -achieved via a call to the follwoing function: +DMA Resource Allocation incomplete +---------------------------------- - int vme_register_driver (struct vme_driver *driver); - -If driver registration is successful this function returns zero, if an error -occurred a negative error code will be returned. - -A pointer to a structure of type ???vme_driver??? must be provided to the -registration function. The structure is as follows: - - struct vme_driver { - struct list_head node; - char *name; - const struct vme_device_id *bind_table; - int (*probe) (struct device *, int, int); - int (*remove) (struct device *, int, int); - void (*shutdown) (void); - struct device_driver driver; - }; - -At the minimum, the ???.name???, ???.probe??? and ???.bind_table??? elements of this -structure should be correctly set. The ???.name??? element is a pointer to a string -holding the device driver???s name. The ???.probe??? element should contain a pointer -to the probe routine. - -The arguments of the probe routine are as follows: - - probe(struct device *dev, int bus, int slot); - -The ???.bind_table??? is a pointer to an array of type ???vme_device_id???: - - struct vme_device_id { - int bus; - int slot; - }; - -Each structure in this array should provide a bus and slot number where the core -should probe, using the driver???s probe routine, for a device on the specified -VME bus. - -The VME subsystem supports a single VME driver per ???slot???. There are considered -to be 32 slots per bus, one for each slot-ID as defined in the ANSI/VITA 1-1994 -specification and are analogious to the physical slots on the VME backplane. - -A function is also provided to unregister the driver from the VME core and is -usually called from the device driver???s exit routine: - - void vme_unregister_driver (struct vme_driver *driver); - - -Resource management -=================== - -Once a driver has registered with the VME core the provided probe routine will -be called for each of the bus/slot combination that becomes valid as VME buses -are themselves registered. The probe routine is passed a pointer to the devices -device structure. This pointer should be saved, it will be required for -requesting VME resources. - -The driver can request ownership of one or more master windows, slave windows -and/or dma channels. Rather than allowing the device driver to request a -specific window or DMA channel (which may be used by a different driver) this -driver allows a resource to be assigned based on the required attributes of the -driver in question: - - struct vme_resource * vme_master_request(struct device *dev, - vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); - - struct vme_resource * vme_slave_request(struct device *dev, - vme_address_t aspace, vme_cycle_t cycle); - -TODO: DMA Resource Allocation incomplete. No attribute based selection. +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_request_dma(struct device *dev); -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???. -These attributes are defined as bitmasks and as such any combination of the -attributes can be requested for a single window, the core will assign a window -that meets the requirements, returning a pointer of type vme_resource that -should be used to identify the allocated resource when it is used. 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 -required. These functions should be passed the pointer to the resource provided -during resource allocation: - - void vme_master_free(struct vme_resource *res); - - void vme_slave_free(struct vme_resource *res); - - void vme_dma_free(struct vme_resource *res); - - -Master windows -============== - -Master windows provide access from the local processor[s] out onto the VME bus. -The number of windows available and the available access modes is dependant on -the underlying chipset. A window must be configured before it can be used. - +As opposed to: -Master window configuration ---------------------------- - -Once a master window has been assigned the following functions can be used to -configure it and retrieve the current settings: - - int vme_master_set (struct vme_resource *res, int enabled, - unsigned long long base, unsigned long long size, + struct vme_resource * vme_master_request(struct device *dev, vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); - int vme_master_get (struct vme_resource *res, int *enabled, - unsigned long long *base, unsigned long long *size, - vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *width); - -The address spaces, transfer widths and cycle types are the same as described -under resource management, however some of the options are mutually exclusive. -For example, only one address space may be specified. +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. -These functions return 0 on success or an error code should the call fail. +Add a mechanism to select a VME controller based on source/target type, +required aspace, cycle and width requirements. Master window broadcast select mask ----------------------------------- -TODO: Add functions to set and get Broadcast Select mask: +API currently provides no method to set or get Broadcast Select mask. Suggest +somthing like: int vme_master_bmsk_set (struct vme_resource *res, int mask); int vme_master_bmsk_get (struct vme_resource *res, int *mask); -Master window access --------------------- - -The following functions can be used to read from and write to configured master -windows. These functions return the number of bytes copied: - - ssize_t vme_master_read(struct vme_resource *res, void *buf, - size_t count, loff_t offset); - - ssize_t vme_master_write(struct vme_resource *res, void *buf, - size_t count, loff_t offset); - -In addition to simple reads and writes, a function is provided to do a -read-modify-write transaction. This function returns the original value of the -VME bus location : - - unsigned int vme_master_rmw (struct vme_resource *res, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset); - -This functions by reading the offset, applying the mask. If the bits selected in -the mask match with the values of the corresponding bits in the compare field, -the value of swap is written the specified offset. - - -Slave windows -============= - -Slave windows provide devices on the VME bus access into mapped portions of the -local memory. The number of windows available and the access modes that can be -used is dependant on the underlying chipset. A window must be configured before -it can be used. - - -Slave window configuration --------------------------- - -Once a slave window has been assigned the following functions can be used to -configure it and retrieve the current settings: - - int vme_slave_set (struct vme_resource *res, int enabled, - unsigned long long base, unsigned long long size, - dma_addr_t mem, vme_address_t aspace, vme_cycle_t cycle); - - int vme_slave_get (struct vme_resource *res, int *enabled, - unsigned long long *base, unsigned long long *size, - dma_addr_t *mem, vme_address_t *aspace, vme_cycle_t *cycle); - -The address spaces, transfer widths and cycle types are the same as described -under resource management, however some of the options are mutually exclusive. -For example, only one address space may be specified. - -These functions return 0 on success or an error code should the call fail. - - -Slave window buffer allocation ------------------------------- - -Functions are provided to allow the user to allocate and free a contiguous -buffers which will be accessible by the VME bridge. These functions do not have -to be used, other methods can be used to allocate a buffer, though care must be -taken to ensure that they are contiguous and accessible by the VME bridge: - - void * vme_alloc_consistent(struct vme_resource *res, size_t size, - dma_addr_t *mem); - - void vme_free_consistent(struct vme_resource *res, size_t size, - void *virt, dma_addr_t mem); - - -Slave window access -------------------- - -Slave windows map local memory onto the VME bus, the standard methods for -accessing memory should be used. - - -DMA channels -============ - -The VME DMA transfer provides the ability to run link-list DMA transfers. The -API introduces the concept of DMA lists. Each DMA list is a link-list which can -be passed to a DMA controller. Multiple lists can be created, extended, -executed, reused and destroyed. - - -List Management ---------------- - -The following functions are provided to create and destroy DMA lists. Execution -of a list will not automatically destroy the list, thus enabling a list to be -reused for repetitive tasks: - - struct vme_dma_list *vme_new_dma_list(struct vme_resource *res); - - int vme_dma_list_free(struct vme_dma_list *list); - - -List Population ---------------- - -An item can be added to a list using the following function ( the source and -destination attributes need to be created before calling this function, this is -covered under "Transfer Attributes"): - - int vme_dma_list_add(struct vme_dma_list *list, - struct vme_dma_attr *src, struct vme_dma_attr *dest, - size_t count); - - -Transfer Attributes -------------------- - -The attributes for the source and destination are handled separately from adding -an item to a list. This is due to the diverse attributes required for each type -of source and destination. There are functions to create attributes for PCI, VME -and pattern sources and destinations (where appropriate): - -Pattern source: - - struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, - vme_pattern_t type); - -PCI source or destination: - - struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem); - -VME source or destination: - - struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base, - vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); - -The following function should be used to free an attribute: - - void vme_dma_free_attribute(struct vme_dma_attr *attr); - - -List Execution --------------- - -The following function queues a list for execution. The function will return -once the list has been executed: - - int vme_dma_list_exec(struct vme_dma_list *list); - - -Interrupts -========== - -The VME API provides functions to attach and detach callbacks to specific VME -level and status ID combinations and for the generation of VME interrupts with -specific VME level and status IDs. - - -Attaching Interrupt Handlers ----------------------------- - -The following functions can be used to attach and free a specific VME level and -status ID combination. Any given combination can only be assigned a single -callback function. A void pointer parameter is provided, the value of which is -passed to the callback function, the use of this pointer is user undefined: - - int vme_request_irq(struct device *dev, int level, int statid, - void (*callback)(int, int, void *), void *priv); - - void vme_free_irq(struct device *dev, int level, int statid); - -The callback parameters are as follows. Care must be taken in writing a callback -function, callback functions run in interrupt context: - - void callback(int level, int statid, void *priv); - - Interrupt Generation -------------------- -The following function can be used to generate a VME interrupt at a given VME -level and VME status ID: - - int vme_generate_irq(struct device *dev, int level, int statid); - - -Location monitors -================= - -The VME API provides the following functionality to configure the location -monitor. +Add optional timeout when waiting for an IACK. -Location Monitor Management ---------------------------- +CR/CSR Buffer +------------- -The following functions are provided to request the use of a block of location -monitors and to free them after they are no longer required: +The VME API provides no functions to access the buffer mapped into the CR/CSR +space. - struct vme_resource * vme_lm_request(struct device *dev); - void vme_lm_free(struct vme_resource * res); +Mailboxes +--------- -Each block may provide a number of location monitors, monitoring adjacent -locations. The following function can be used to determine how many locations -are provided: +Whilst not part of the VME specification, they are provided by a number of +chips. They are currently not supported at all by the API. - int vme_lm_count(struct vme_resource * res); +Core +==== -Location Monitor Configuration ------------------------------- - -Once a bank of location monitors has been allocated, the following functions -are provided to configure the location and mode of the location monitor: - - int vme_lm_set(struct vme_resource *res, unsigned long long base, - vme_address_t aspace, vme_cycle_t cycle); - - int vme_lm_get(struct vme_resource *res, unsigned long long *base, - vme_address_t *aspace, vme_cycle_t *cycle); - - -Location Monitor Use --------------------- - -The following functions allow a callback to be attached and detached from each -location monitor location. Each location monitor can monitor a number of -adjacent locations: - - int vme_lm_attach(struct vme_resource *res, int num, - void (*callback)(int)); - - int vme_lm_detach(struct vme_resource *res, int num); - -The callback function is declared as follows. - - void callback(int num); +- Rename vme_master_resource's "pci_resource" to be bus agnostic. +- Improve generic sanity checks (Such as does an offset and size fit within a + window and parameter checking). +Bridge Support +============== -CR/CSR -====== +Tempe (tsi148) +-------------- -TODO: The VME API needs functions to access the CR/CSR buffer. +- Driver can currently only support a single bridge. +- 2eSST Broadcast mode. +- Mailboxes unsupported. +- Improve error detection. +- Control of prefetch size, threshold. +- Arbiter control +- Requestor control + +Universe II (ca91c142) +---------------------- + +- Driver can currently only support a single bridge. +- DMA unsupported. +- RMW transactions unsupported. +- Location Monitors unsupported. +- Mailboxes unsupported. +- Error Detection. +- Control of prefetch size, threshold. +- Arbiter control +- Requestor control +- Slot detection -Slot Detection -============== +Universe I (ca91x042) +--------------------- -This function returns the slot ID of the provided bridge. +Currently completely unsupported. - int vme_slot_get(struct device *dev); --- /dev/null +++ b/drivers/staging/vme/vme_api.txt @@ -0,0 +1,372 @@ + VME Device Driver API + ===================== + +Driver registration +=================== + +As with other subsystems within the Linux kernel, VME device drivers register +with the VME subsystem, typically called from the devices init routine. This is +achieved via a call to the follwoing function: + + int vme_register_driver (struct vme_driver *driver); + +If driver registration is successful this function returns zero, if an error +occurred a negative error code will be returned. + +A pointer to a structure of type 'vme_driver' must be provided to the +registration function. The structure is as follows: + + struct vme_driver { + struct list_head node; + char *name; + const struct vme_device_id *bind_table; + int (*probe) (struct device *, int, int); + int (*remove) (struct device *, int, int); + void (*shutdown) (void); + struct device_driver driver; + }; + +At the minimum, the '.name', '.probe' and '.bind_table' elements of this +structure should be correctly set. The '.name' element is a pointer to a string +holding the device driver's name. The '.probe' element should contain a pointer +to the probe routine. + +The arguments of the probe routine are as follows: + + probe(struct device *dev, int bus, int slot); + +The '.bind_table' is a pointer to an array of type 'vme_device_id': + + struct vme_device_id { + int bus; + int slot; + }; + +Each structure in this array should provide a bus and slot number where the core +should probe, using the driver's probe routine, for a device on the specified +VME bus. + +The VME subsystem supports a single VME driver per 'slot'. There are considered +to be 32 slots per bus, one for each slot-ID as defined in the ANSI/VITA 1-1994 +specification and are analogious to the physical slots on the VME backplane. + +A function is also provided to unregister the driver from the VME core and is +usually called from the device driver's exit routine: + + void vme_unregister_driver (struct vme_driver *driver); + + +Resource management +=================== + +Once a driver has registered with the VME core the provided probe routine will +be called for each of the bus/slot combination that becomes valid as VME buses +are themselves registered. The probe routine is passed a pointer to the devices +device structure. This pointer should be saved, it will be required for +requesting VME resources. + +The driver can request ownership of one or more master windows, slave windows +and/or dma channels. Rather than allowing the device driver to request a +specific window or DMA channel (which may be used by a different driver) this +driver allows a resource to be assigned based on the required attributes of the +driver in question: + + struct vme_resource * vme_master_request(struct device *dev, + vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); + + struct vme_resource * vme_slave_request(struct device *dev, + vme_address_t aspace, vme_cycle_t cycle); + + struct vme_resource *vme_request_dma(struct device *dev); + +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'. +These attributes are defined as bitmasks and as such any combination of the +attributes can be requested for a single window, the core will assign a window +that meets the requirements, returning a pointer of type vme_resource that +should be used to identify the allocated resource when it is used. 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 +required. These functions should be passed the pointer to the resource provided +during resource allocation: + + void vme_master_free(struct vme_resource *res); + + void vme_slave_free(struct vme_resource *res); + + void vme_dma_free(struct vme_resource *res); + + +Master windows +============== + +Master windows provide access from the local processor[s] out onto the VME bus. +The number of windows available and the available access modes is dependant on +the underlying chipset. A window must be configured before it can be used. + + +Master window configuration +--------------------------- + +Once a master window has been assigned the following functions can be used to +configure it and retrieve the current settings: + + int vme_master_set (struct vme_resource *res, int enabled, + unsigned long long base, unsigned long long size, + vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); + + int vme_master_get (struct vme_resource *res, int *enabled, + unsigned long long *base, unsigned long long *size, + vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *width); + +The address spaces, transfer widths and cycle types are the same as described +under resource management, however some of the options are mutually exclusive. +For example, only one address space may be specified. + +These functions return 0 on success or an error code should the call fail. + + +Master window access +-------------------- + +The following functions can be used to read from and write to configured master +windows. These functions return the number of bytes copied: + + ssize_t vme_master_read(struct vme_resource *res, void *buf, + size_t count, loff_t offset); + + ssize_t vme_master_write(struct vme_resource *res, void *buf, + size_t count, loff_t offset); + +In addition to simple reads and writes, a function is provided to do a +read-modify-write transaction. This function returns the original value of the +VME bus location : + + unsigned int vme_master_rmw (struct vme_resource *res, + unsigned int mask, unsigned int compare, unsigned int swap, + loff_t offset); + +This functions by reading the offset, applying the mask. If the bits selected in +the mask match with the values of the corresponding bits in the compare field, +the value of swap is written the specified offset. + + +Slave windows +============= + +Slave windows provide devices on the VME bus access into mapped portions of the +local memory. The number of windows available and the access modes that can be +used is dependant on the underlying chipset. A window must be configured before +it can be used. + + +Slave window configuration +-------------------------- + +Once a slave window has been assigned the following functions can be used to +configure it and retrieve the current settings: + + int vme_slave_set (struct vme_resource *res, int enabled, + unsigned long long base, unsigned long long size, + dma_addr_t mem, vme_address_t aspace, vme_cycle_t cycle); + + int vme_slave_get (struct vme_resource *res, int *enabled, + unsigned long long *base, unsigned long long *size, + dma_addr_t *mem, vme_address_t *aspace, vme_cycle_t *cycle); + +The address spaces, transfer widths and cycle types are the same as described +under resource management, however some of the options are mutually exclusive. +For example, only one address space may be specified. + +These functions return 0 on success or an error code should the call fail. + + +Slave window buffer allocation +------------------------------ + +Functions are provided to allow the user to allocate and free a contiguous +buffers which will be accessible by the VME bridge. These functions do not have +to be used, other methods can be used to allocate a buffer, though care must be +taken to ensure that they are contiguous and accessible by the VME bridge: + + void * vme_alloc_consistent(struct vme_resource *res, size_t size, + dma_addr_t *mem); + + void vme_free_consistent(struct vme_resource *res, size_t size, + void *virt, dma_addr_t mem); + + +Slave window access +------------------- + +Slave windows map local memory onto the VME bus, the standard methods for +accessing memory should be used. + + +DMA channels +============ + +The VME DMA transfer provides the ability to run link-list DMA transfers. The +API introduces the concept of DMA lists. Each DMA list is a link-list which can +be passed to a DMA controller. Multiple lists can be created, extended, +executed, reused and destroyed. + + +List Management +--------------- + +The following functions are provided to create and destroy DMA lists. Execution +of a list will not automatically destroy the list, thus enabling a list to be +reused for repetitive tasks: + + struct vme_dma_list *vme_new_dma_list(struct vme_resource *res); + + int vme_dma_list_free(struct vme_dma_list *list); + + +List Population +--------------- + +An item can be added to a list using the following function ( the source and +destination attributes need to be created before calling this function, this is +covered under "Transfer Attributes"): + + int vme_dma_list_add(struct vme_dma_list *list, + struct vme_dma_attr *src, struct vme_dma_attr *dest, + size_t count); + + +Transfer Attributes +------------------- + +The attributes for the source and destination are handled separately from adding +an item to a list. This is due to the diverse attributes required for each type +of source and destination. There are functions to create attributes for PCI, VME +and pattern sources and destinations (where appropriate): + +Pattern source: + + struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, + vme_pattern_t type); + +PCI source or destination: + + struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem); + +VME source or destination: + + struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base, + vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); + +The following function should be used to free an attribute: + + void vme_dma_free_attribute(struct vme_dma_attr *attr); + + +List Execution +-------------- + +The following function queues a list for execution. The function will return +once the list has been executed: + + int vme_dma_list_exec(struct vme_dma_list *list); + + +Interrupts +========== + +The VME API provides functions to attach and detach callbacks to specific VME +level and status ID combinations and for the generation of VME interrupts with +specific VME level and status IDs. + + +Attaching Interrupt Handlers +---------------------------- + +The following functions can be used to attach and free a specific VME level and +status ID combination. Any given combination can only be assigned a single +callback function. A void pointer parameter is provided, the value of which is +passed to the callback function, the use of this pointer is user undefined: + + int vme_request_irq(struct device *dev, int level, int statid, + void (*callback)(int, int, void *), void *priv); + + void vme_free_irq(struct device *dev, int level, int statid); + +The callback parameters are as follows. Care must be taken in writing a callback +function, callback functions run in interrupt context: + + void callback(int level, int statid, void *priv); + + +Interrupt Generation +-------------------- + +The following function can be used to generate a VME interrupt at a given VME +level and VME status ID: + + int vme_generate_irq(struct device *dev, int level, int statid); + + +Location monitors +================= + +The VME API provides the following functionality to configure the location +monitor. + + +Location Monitor Management +--------------------------- + +The following functions are provided to request the use of a block of location +monitors and to free them after they are no longer required: + + struct vme_resource * vme_lm_request(struct device *dev); + + void vme_lm_free(struct vme_resource * res); + +Each block may provide a number of location monitors, monitoring adjacent +locations. The following function can be used to determine how many locations +are provided: + + int vme_lm_count(struct vme_resource * res); + + +Location Monitor Configuration +------------------------------ + +Once a bank of location monitors has been allocated, the following functions +are provided to configure the location and mode of the location monitor: + + int vme_lm_set(struct vme_resource *res, unsigned long long base, + vme_address_t aspace, vme_cycle_t cycle); + + int vme_lm_get(struct vme_resource *res, unsigned long long *base, + vme_address_t *aspace, vme_cycle_t *cycle); + + +Location Monitor Use +-------------------- + +The following functions allow a callback to be attached and detached from each +location monitor location. Each location monitor can monitor a number of +adjacent locations: + + int vme_lm_attach(struct vme_resource *res, int num, + void (*callback)(int)); + + int vme_lm_detach(struct vme_resource *res, int num); + +The callback function is declared as follows. + + void callback(int num); + + +Slot Detection +============== + +This function returns the slot ID of the provided bridge. + + int vme_slot_get(struct device *dev);