ieee1394: move some comments from declaration to definition
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
This commit is contained in:
Родитель
ef8153348f
Коммит
afd6546d8d
|
@ -39,7 +39,7 @@ struct hpsb_config_rom_entry {
|
|||
unsigned int flag;
|
||||
};
|
||||
|
||||
|
||||
/* The default host entry. This must succeed. */
|
||||
int hpsb_default_host_entry(struct hpsb_host *host)
|
||||
{
|
||||
struct csr1212_keyval *root;
|
||||
|
@ -170,7 +170,7 @@ static struct hpsb_config_rom_entry *const config_rom_entries[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
|
||||
/* Initialize all config roms */
|
||||
int hpsb_init_config_roms(void)
|
||||
{
|
||||
int i, error = 0;
|
||||
|
@ -191,6 +191,7 @@ int hpsb_init_config_roms(void)
|
|||
return error;
|
||||
}
|
||||
|
||||
/* Cleanup all config roms */
|
||||
void hpsb_cleanup_config_roms(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -201,6 +202,7 @@ void hpsb_cleanup_config_roms(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Add extra config roms to specified host */
|
||||
int hpsb_add_extra_config_roms(struct hpsb_host *host)
|
||||
{
|
||||
int i, error = 0;
|
||||
|
@ -219,6 +221,7 @@ int hpsb_add_extra_config_roms(struct hpsb_host *host)
|
|||
return error;
|
||||
}
|
||||
|
||||
/* Remove extra config roms from specified host */
|
||||
void hpsb_remove_extra_config_roms(struct hpsb_host *host)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -4,22 +4,12 @@
|
|||
#include "ieee1394_types.h"
|
||||
#include "hosts.h"
|
||||
|
||||
/* The default host entry. This must succeed. */
|
||||
int hpsb_default_host_entry(struct hpsb_host *host);
|
||||
|
||||
/* Initialize all config roms */
|
||||
int hpsb_init_config_roms(void);
|
||||
|
||||
/* Cleanup all config roms */
|
||||
void hpsb_cleanup_config_roms(void);
|
||||
|
||||
/* Add extra config roms to specified host */
|
||||
int hpsb_add_extra_config_roms(struct hpsb_host *host);
|
||||
|
||||
/* Remove extra config roms from specified host */
|
||||
void hpsb_remove_extra_config_roms(struct hpsb_host *host);
|
||||
|
||||
|
||||
/* List of flags to check if a host contains a certain extra config rom
|
||||
* entry. Available in the host->config_roms member. */
|
||||
#define HPSB_CONFIG_ROM_ENTRY_IP1394 0x00000001
|
||||
|
|
|
@ -62,6 +62,9 @@ void dma_prog_region_free(struct dma_prog_region *prog)
|
|||
|
||||
/* dma_region */
|
||||
|
||||
/**
|
||||
* dma_region_init - clear out all fields but do not allocate anything
|
||||
*/
|
||||
void dma_region_init(struct dma_region *dma)
|
||||
{
|
||||
dma->kvirt = NULL;
|
||||
|
@ -71,6 +74,9 @@ void dma_region_init(struct dma_region *dma)
|
|||
dma->sglist = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_region_alloc - allocate the buffer and map it to the IOMMU
|
||||
*/
|
||||
int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
|
||||
struct pci_dev *dev, int direction)
|
||||
{
|
||||
|
@ -128,6 +134,9 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_region_free - unmap and free the buffer
|
||||
*/
|
||||
void dma_region_free(struct dma_region *dma)
|
||||
{
|
||||
if (dma->n_dma_pages) {
|
||||
|
@ -167,6 +176,12 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
|
|||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_region_offset_to_bus - get bus address of an offset within a DMA region
|
||||
*
|
||||
* Returns the DMA bus address of the byte with the given @offset relative to
|
||||
* the beginning of the @dma.
|
||||
*/
|
||||
dma_addr_t dma_region_offset_to_bus(struct dma_region * dma,
|
||||
unsigned long offset)
|
||||
{
|
||||
|
@ -177,6 +192,9 @@ dma_addr_t dma_region_offset_to_bus(struct dma_region * dma,
|
|||
return sg_dma_address(sg) + rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_region_sync_for_cpu - sync the CPU's view of the buffer
|
||||
*/
|
||||
void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
|
||||
unsigned long len)
|
||||
{
|
||||
|
@ -193,6 +211,9 @@ void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
|
|||
dma->direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_region_sync_for_device - sync the IO bus' view of the buffer
|
||||
*/
|
||||
void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
|
||||
unsigned long len)
|
||||
{
|
||||
|
@ -244,6 +265,9 @@ static struct vm_operations_struct dma_region_vm_ops = {
|
|||
.nopage = dma_region_pagefault,
|
||||
};
|
||||
|
||||
/**
|
||||
* dma_region_mmap - map the buffer into a user space process
|
||||
*/
|
||||
int dma_region_mmap(struct dma_region *dma, struct file *file,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
|
|
|
@ -66,35 +66,23 @@ struct dma_region {
|
|||
int direction;
|
||||
};
|
||||
|
||||
/* clear out all fields but do not allocate anything */
|
||||
void dma_region_init(struct dma_region *dma);
|
||||
|
||||
/* allocate the buffer and map it to the IOMMU */
|
||||
int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
|
||||
struct pci_dev *dev, int direction);
|
||||
|
||||
/* unmap and free the buffer */
|
||||
void dma_region_free(struct dma_region *dma);
|
||||
|
||||
/* sync the CPU's view of the buffer */
|
||||
void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
|
||||
unsigned long len);
|
||||
|
||||
/* sync the IO bus' view of the buffer */
|
||||
void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
|
||||
unsigned long len);
|
||||
|
||||
/* map the buffer into a user space process */
|
||||
int dma_region_mmap(struct dma_region *dma, struct file *file,
|
||||
struct vm_area_struct *vma);
|
||||
|
||||
/* macro to index into a DMA region (or dma_prog_region) */
|
||||
#define dma_region_i(_dma, _type, _index) \
|
||||
( ((_type*) ((_dma)->kvirt)) + (_index) )
|
||||
|
||||
/* return the DMA bus address of the byte with the given offset
|
||||
* relative to the beginning of the dma_region */
|
||||
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma,
|
||||
unsigned long offset);
|
||||
|
||||
/**
|
||||
* dma_region_i - macro to index into a DMA region (or dma_prog_region)
|
||||
*/
|
||||
#define dma_region_i(_dma, _type, _index) \
|
||||
( ((_type*) ((_dma)->kvirt)) + (_index) )
|
||||
|
||||
#endif /* IEEE1394_DMA_H */
|
||||
|
|
|
@ -70,8 +70,12 @@ static struct hl_host_info *hl_get_hostinfo(struct hpsb_highlevel *hl,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns a per host/driver data structure that was previously stored by
|
||||
* hpsb_create_hostinfo. */
|
||||
/**
|
||||
* hpsb_get_hostinfo - retrieve a hostinfo pointer bound to this driver/host
|
||||
*
|
||||
* Returns a per @host and @hl driver data structure that was previously stored
|
||||
* by hpsb_create_hostinfo.
|
||||
*/
|
||||
void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host)
|
||||
{
|
||||
struct hl_host_info *hi = hl_get_hostinfo(hl, host);
|
||||
|
@ -79,7 +83,13 @@ void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host)
|
|||
return hi ? hi->data : NULL;
|
||||
}
|
||||
|
||||
/* If size is zero, then the return here is only valid for error checking */
|
||||
/**
|
||||
* hpsb_create_hostinfo - allocate a hostinfo pointer bound to this driver/host
|
||||
*
|
||||
* Allocate a hostinfo pointer backed by memory with @data_size and bind it to
|
||||
* to this @hl driver and @host. If @data_size is zero, then the return here is
|
||||
* only valid for error checking.
|
||||
*/
|
||||
void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
size_t data_size)
|
||||
{
|
||||
|
@ -113,6 +123,11 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_set_hostinfo - set the hostinfo pointer to something useful
|
||||
*
|
||||
* Usually follows a call to hpsb_create_hostinfo, where the size is 0.
|
||||
*/
|
||||
int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
void *data)
|
||||
{
|
||||
|
@ -132,6 +147,11 @@ int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_destroy_hostinfo - free and remove a hostinfo pointer
|
||||
*
|
||||
* Free and remove the hostinfo pointer bound to this @hl driver and @host.
|
||||
*/
|
||||
void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host)
|
||||
{
|
||||
struct hl_host_info *hi;
|
||||
|
@ -147,6 +167,12 @@ void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host)
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_set_hostinfo_key - set an alternate lookup key for an hostinfo
|
||||
*
|
||||
* Sets an alternate lookup key for the hostinfo bound to this @hl driver and
|
||||
* @host.
|
||||
*/
|
||||
void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
unsigned long key)
|
||||
{
|
||||
|
@ -158,6 +184,9 @@ void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_get_hostinfo_bykey - retrieve a hostinfo pointer by its alternate key
|
||||
*/
|
||||
void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key)
|
||||
{
|
||||
struct hl_host_info *hi;
|
||||
|
@ -189,6 +218,12 @@ static int highlevel_for_each_host_reg(struct hpsb_host *host, void *__data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_register_highlevel - register highlevel driver
|
||||
*
|
||||
* The name pointer in @hl has to stay valid at all times because the string is
|
||||
* not copied.
|
||||
*/
|
||||
void hpsb_register_highlevel(struct hpsb_highlevel *hl)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -258,6 +293,9 @@ static int highlevel_for_each_host_unreg(struct hpsb_host *host, void *__data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_unregister_highlevel - unregister highlevel driver
|
||||
*/
|
||||
void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -273,6 +311,19 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
|
|||
nodemgr_for_each_host(hl, highlevel_for_each_host_unreg);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_allocate_and_register_addrspace - alloc' and reg' a host address space
|
||||
*
|
||||
* @start and @end are 48 bit pointers and have to be quadlet aligned.
|
||||
* @end points to the first address behind the handled addresses. This
|
||||
* function can be called multiple times for a single hpsb_highlevel @hl to
|
||||
* implement sparse register sets. The requested region must not overlap any
|
||||
* previously allocated region, otherwise registering will fail.
|
||||
*
|
||||
* It returns true for successful allocation. Address spaces can be
|
||||
* unregistered with hpsb_unregister_addrspace. All remaining address spaces
|
||||
* are automatically deallocated together with the hpsb_highlevel @hl.
|
||||
*/
|
||||
u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
|
||||
struct hpsb_host *host,
|
||||
struct hpsb_address_ops *ops,
|
||||
|
@ -348,6 +399,19 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_register_addrspace - register a host address space
|
||||
*
|
||||
* @start and @end are 48 bit pointers and have to be quadlet aligned.
|
||||
* @end points to the first address behind the handled addresses. This
|
||||
* function can be called multiple times for a single hpsb_highlevel @hl to
|
||||
* implement sparse register sets. The requested region must not overlap any
|
||||
* previously allocated region, otherwise registering will fail.
|
||||
*
|
||||
* It returns true for successful allocation. Address spaces can be
|
||||
* unregistered with hpsb_unregister_addrspace. All remaining address spaces
|
||||
* are automatically deallocated together with the hpsb_highlevel @hl.
|
||||
*/
|
||||
int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
struct hpsb_address_ops *ops, u64 start, u64 end)
|
||||
{
|
||||
|
@ -419,6 +483,11 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_listen_channel - enable receving a certain isochronous channel
|
||||
*
|
||||
* Reception is handled through the @hl's iso_receive op.
|
||||
*/
|
||||
int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
unsigned int channel)
|
||||
{
|
||||
|
@ -431,6 +500,9 @@ int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_unlisten_channel - disable receving a certain isochronous channel
|
||||
*/
|
||||
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
unsigned int channel)
|
||||
{
|
||||
|
@ -528,6 +600,17 @@ void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
|
|||
read_unlock_irqrestore(&hl_irqs_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* highlevel_read, highlevel_write, highlevel_lock, highlevel_lock64:
|
||||
*
|
||||
* These functions are called to handle transactions. They are called when a
|
||||
* packet arrives. The flags argument contains the second word of the first
|
||||
* header quadlet of the incoming packet (containing transaction label, retry
|
||||
* code, transaction code and priority). These functions either return a
|
||||
* response code or a negative number. In the first case a response will be
|
||||
* generated. In the latter case, no response will be sent and the driver which
|
||||
* handled the request will send the response itself.
|
||||
*/
|
||||
int highlevel_read(struct hpsb_host *host, int nodeid, void *data, u64 addr,
|
||||
unsigned int length, u16 flags)
|
||||
{
|
||||
|
|
|
@ -99,16 +99,6 @@ struct hpsb_address_ops {
|
|||
void highlevel_add_host(struct hpsb_host *host);
|
||||
void highlevel_remove_host(struct hpsb_host *host);
|
||||
void highlevel_host_reset(struct hpsb_host *host);
|
||||
|
||||
/*
|
||||
* These functions are called to handle transactions. They are called when a
|
||||
* packet arrives. The flags argument contains the second word of the first
|
||||
* header quadlet of the incoming packet (containing transaction label, retry
|
||||
* code, transaction code and priority). These functions either return a
|
||||
* response code or a negative number. In the first case a response will be
|
||||
* generated. In the latter case, no response will be sent and the driver which
|
||||
* handled the request will send the response itself.
|
||||
*/
|
||||
int highlevel_read(struct hpsb_host *host, int nodeid, void *data, u64 addr,
|
||||
unsigned int length, u16 flags);
|
||||
int highlevel_write(struct hpsb_host *host, int nodeid, int destid, void *data,
|
||||
|
@ -119,30 +109,13 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
|
|||
int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
|
||||
u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
|
||||
u16 flags);
|
||||
|
||||
void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length);
|
||||
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
|
||||
void *data, size_t length);
|
||||
|
||||
/*
|
||||
* Register highlevel driver. The name pointer has to stay valid at all times
|
||||
* because the string is not copied.
|
||||
*/
|
||||
void hpsb_register_highlevel(struct hpsb_highlevel *hl);
|
||||
void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
|
||||
|
||||
/*
|
||||
* Register handlers for host address spaces. Start and end are 48 bit pointers
|
||||
* and have to be quadlet aligned. Argument "end" points to the first address
|
||||
* behind the handled addresses. This function can be called multiple times for
|
||||
* a single hpsb_highlevel to implement sparse register sets. The requested
|
||||
* region must not overlap any previously allocated region, otherwise
|
||||
* registering will fail.
|
||||
*
|
||||
* It returns true for successful allocation. Address spaces can be
|
||||
* unregistered with hpsb_unregister_addrspace. All remaining address spaces
|
||||
* are automatically deallocated together with the hpsb_highlevel.
|
||||
*/
|
||||
u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
|
||||
struct hpsb_host *host,
|
||||
struct hpsb_address_ops *ops,
|
||||
|
@ -152,35 +125,18 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
|||
struct hpsb_address_ops *ops, u64 start, u64 end);
|
||||
int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
u64 start);
|
||||
|
||||
/*
|
||||
* Enable or disable receving a certain isochronous channel through the
|
||||
* iso_receive op.
|
||||
*/
|
||||
int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
unsigned int channel);
|
||||
unsigned int channel);
|
||||
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
unsigned int channel);
|
||||
|
||||
/* Retrieve a hostinfo pointer bound to this driver/host */
|
||||
void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
|
||||
|
||||
/* Allocate a hostinfo pointer of data_size bound to this driver/host */
|
||||
void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
size_t data_size);
|
||||
|
||||
/* Free and remove the hostinfo pointer bound to this driver/host */
|
||||
void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
|
||||
|
||||
/* Set an alternate lookup key for the hostinfo bound to this driver/host */
|
||||
void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
unsigned long key);
|
||||
|
||||
/* Retrieve a hostinfo pointer bound to this driver using its alternate key */
|
||||
void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key);
|
||||
|
||||
/* Set the hostinfo pointer to something useful. Usually follows a call to
|
||||
* hpsb_create_hostinfo, where the size is 0. */
|
||||
int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
|
||||
void *data);
|
||||
|
||||
|
|
|
@ -218,6 +218,14 @@ void hpsb_remove_host(struct hpsb_host *host)
|
|||
device_unregister(&host->device);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_update_config_rom_image - updates configuration ROM image of a host
|
||||
*
|
||||
* Updates the configuration ROM image of a host. rom_version must be the
|
||||
* current version, otherwise it will fail with return value -1. If this
|
||||
* host does not support config-rom-update, it will return -%EINVAL.
|
||||
* Return value 0 indicates success.
|
||||
*/
|
||||
int hpsb_update_config_rom_image(struct hpsb_host *host)
|
||||
{
|
||||
unsigned long reset_delay;
|
||||
|
|
|
@ -202,12 +202,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
|
|||
int hpsb_add_host(struct hpsb_host *host);
|
||||
void hpsb_resume_host(struct hpsb_host *host);
|
||||
void hpsb_remove_host(struct hpsb_host *host);
|
||||
|
||||
/* Updates the configuration rom image of a host. rom_version must be the
|
||||
* current version, otherwise it will fail with return value -1. If this
|
||||
* host does not support config-rom-update, it will return -EINVAL.
|
||||
* Return value 0 indicates success.
|
||||
*/
|
||||
int hpsb_update_config_rom_image(struct hpsb_host *host);
|
||||
|
||||
#endif /* _IEEE1394_HOSTS_H */
|
||||
|
|
|
@ -96,13 +96,13 @@ static void queue_packet_complete(struct hpsb_packet *packet);
|
|||
|
||||
|
||||
/**
|
||||
* hpsb_set_packet_complete_task - set the task that runs when a packet
|
||||
* completes. You cannot call this more than once on a single packet
|
||||
* before it is sent.
|
||||
*
|
||||
* hpsb_set_packet_complete_task - set task that runs when a packet completes
|
||||
* @packet: the packet whose completion we want the task added to
|
||||
* @routine: function to call
|
||||
* @data: data (if any) to pass to the above function
|
||||
*
|
||||
* Set the task that runs when a packet completes. You cannot call this more
|
||||
* than once on a single packet before it is sent.
|
||||
*/
|
||||
void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
|
||||
void (*routine)(void *), void *data)
|
||||
|
@ -179,6 +179,13 @@ void hpsb_free_packet(struct hpsb_packet *packet)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* hpsb_reset_bus - initiate bus reset on the given host
|
||||
* @host: host controller whose bus to reset
|
||||
* @type: one of enum reset_types
|
||||
*
|
||||
* Returns 1 if bus reset already in progress, 0 otherwise.
|
||||
*/
|
||||
int hpsb_reset_bus(struct hpsb_host *host, int type)
|
||||
{
|
||||
if (!host->in_bus_reset) {
|
||||
|
@ -229,6 +236,14 @@ int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_bus_reset - notify a bus reset to the core
|
||||
*
|
||||
* For host driver module usage. Safe to use in interrupt context, although
|
||||
* quite complex; so you may want to run it in the bottom rather than top half.
|
||||
*
|
||||
* Returns 1 if bus reset already in progress, 0 otherwise.
|
||||
*/
|
||||
int hpsb_bus_reset(struct hpsb_host *host)
|
||||
{
|
||||
if (host->in_bus_reset) {
|
||||
|
@ -405,6 +420,14 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* hpsb_selfid_received - hand over received selfid packet to the core
|
||||
*
|
||||
* For host driver module usage. Safe to use in interrupt context.
|
||||
*
|
||||
* The host driver should have done a successful complement check (second
|
||||
* quadlet is complement of first) beforehand.
|
||||
*/
|
||||
void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
|
||||
{
|
||||
if (host->in_bus_reset) {
|
||||
|
@ -416,6 +439,15 @@ void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_selfid_complete - notify completion of SelfID stage to the core
|
||||
*
|
||||
* For host driver module usage. Safe to use in interrupt context, although
|
||||
* quite complex; so you may want to run it in the bottom rather than top half.
|
||||
*
|
||||
* Notify completion of SelfID stage to the core and report new physical ID
|
||||
* and whether host is root now.
|
||||
*/
|
||||
void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
|
||||
{
|
||||
if (!host->in_bus_reset)
|
||||
|
@ -462,7 +494,16 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
|
|||
highlevel_host_reset(host);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hpsb_packet_sent - notify core of sending a packet
|
||||
*
|
||||
* For host driver module usage. Safe to call from within a transmit packet
|
||||
* routine.
|
||||
*
|
||||
* Notify core of sending a packet. Ackcode is the ack code returned for async
|
||||
* transmits or ACKX_SEND_ERROR if the transmission failed completely; ACKX_NONE
|
||||
* for other cases (internal errors that don't justify a panic).
|
||||
*/
|
||||
void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
|
||||
int ackcode)
|
||||
{
|
||||
|
@ -504,9 +545,10 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
|
|||
* @rootid: root whose force_root bit should get set (-1 = don't set force_root)
|
||||
* @gapcnt: gap count value to set (-1 = don't set gap count)
|
||||
*
|
||||
* This function sends a PHY config packet on the bus through the specified host.
|
||||
* This function sends a PHY config packet on the bus through the specified
|
||||
* host.
|
||||
*
|
||||
* Return value: 0 for success or error number otherwise.
|
||||
* Return value: 0 for success or negative error number otherwise.
|
||||
*/
|
||||
int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
|
||||
{
|
||||
|
@ -621,6 +663,12 @@ static void complete_packet(void *data)
|
|||
complete((struct completion *) data);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_send_packet_and_wait - enqueue packet, block until transaction completes
|
||||
* @packet: packet to send
|
||||
*
|
||||
* Return value: 0 on success, negative errno on failure.
|
||||
*/
|
||||
int hpsb_send_packet_and_wait(struct hpsb_packet *packet)
|
||||
{
|
||||
struct completion done;
|
||||
|
@ -935,7 +983,20 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
|
|||
}
|
||||
#undef PREP_REPLY_PACKET
|
||||
|
||||
|
||||
/**
|
||||
* hpsb_packet_received - hand over received packet to the core
|
||||
*
|
||||
* For host driver module usage.
|
||||
*
|
||||
* The contents of data are expected to be the full packet but with the CRCs
|
||||
* left out (data block follows header immediately), with the header (i.e. the
|
||||
* first four quadlets) in machine byte order and the data block in big endian.
|
||||
* *@data can be safely overwritten after this call.
|
||||
*
|
||||
* If the packet is a write request, @write_acked is to be set to true if it was
|
||||
* ack_complete'd already, false otherwise. This argument is ignored for any
|
||||
* other packet type.
|
||||
*/
|
||||
void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
|
||||
int write_acked)
|
||||
{
|
||||
|
|
|
@ -80,103 +80,42 @@ struct hpsb_packet {
|
|||
quadlet_t embedded_header[5];
|
||||
};
|
||||
|
||||
/* Set a task for when a packet completes */
|
||||
void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
|
||||
void (*routine)(void *), void *data);
|
||||
|
||||
static inline struct hpsb_packet *driver_packet(struct list_head *l)
|
||||
{
|
||||
return list_entry(l, struct hpsb_packet, driver_list);
|
||||
}
|
||||
|
||||
void abort_timedouts(unsigned long __opaque);
|
||||
|
||||
struct hpsb_packet *hpsb_alloc_packet(size_t data_size);
|
||||
void hpsb_free_packet(struct hpsb_packet *packet);
|
||||
|
||||
/*
|
||||
* Generation counter for the complete 1394 subsystem. Generation gets
|
||||
* incremented on every change in the subsystem (e.g. bus reset).
|
||||
/**
|
||||
* get_hpsb_generation - generation counter for the complete 1394 subsystem
|
||||
*
|
||||
* Use the functions, not the variable.
|
||||
* Generation gets incremented on every change in the subsystem (notably on bus
|
||||
* resets). Use the functions, not the variable.
|
||||
*/
|
||||
static inline unsigned int get_hpsb_generation(struct hpsb_host *host)
|
||||
{
|
||||
return atomic_read(&host->generation);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a PHY configuration packet, return 0 on success, negative
|
||||
* errno on failure.
|
||||
*/
|
||||
int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt);
|
||||
|
||||
/*
|
||||
* Queue packet for transmitting, return 0 on success, negative errno
|
||||
* on failure.
|
||||
*/
|
||||
int hpsb_send_packet(struct hpsb_packet *packet);
|
||||
|
||||
/*
|
||||
* Queue packet for transmitting, and block until the transaction
|
||||
* completes. Return 0 on success, negative errno on failure.
|
||||
*/
|
||||
int hpsb_send_packet_and_wait(struct hpsb_packet *packet);
|
||||
|
||||
/* Initiate bus reset on the given host. Returns 1 if bus reset already in
|
||||
* progress, 0 otherwise. */
|
||||
int hpsb_reset_bus(struct hpsb_host *host, int type);
|
||||
|
||||
int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
|
||||
u64 *local_time);
|
||||
|
||||
/*
|
||||
* The following functions are exported for host driver module usage. All of
|
||||
* them are safe to use in interrupt contexts, although some are quite
|
||||
* complicated so you may want to run them in bottom halves instead of calling
|
||||
* them directly.
|
||||
*/
|
||||
|
||||
/* Notify a bus reset to the core. Returns 1 if bus reset already in progress,
|
||||
* 0 otherwise. */
|
||||
int hpsb_bus_reset(struct hpsb_host *host);
|
||||
|
||||
/*
|
||||
* Hand over received selfid packet to the core. Complement check (second
|
||||
* quadlet is complement of first) is expected to be done and successful.
|
||||
*/
|
||||
void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid);
|
||||
|
||||
/*
|
||||
* Notify completion of SelfID stage to the core and report new physical ID
|
||||
* and whether host is root now.
|
||||
*/
|
||||
void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot);
|
||||
|
||||
/*
|
||||
* Notify core of sending a packet. Ackcode is the ack code returned for async
|
||||
* transmits or ACKX_SEND_ERROR if the transmission failed completely; ACKX_NONE
|
||||
* for other cases (internal errors that don't justify a panic). Safe to call
|
||||
* from within a transmit packet routine.
|
||||
*/
|
||||
void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
|
||||
int ackcode);
|
||||
|
||||
/*
|
||||
* Hand over received packet to the core. The contents of data are expected to
|
||||
* be the full packet but with the CRCs left out (data block follows header
|
||||
* immediately), with the header (i.e. the first four quadlets) in machine byte
|
||||
* order and the data block in big endian. *data can be safely overwritten
|
||||
* after this call.
|
||||
*
|
||||
* If the packet is a write request, write_acked is to be set to true if it was
|
||||
* ack_complete'd already, false otherwise. This arg is ignored for any other
|
||||
* packet type.
|
||||
*/
|
||||
void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
|
||||
int write_acked);
|
||||
|
||||
|
||||
/*
|
||||
* CHARACTER DEVICE DISPATCHING
|
||||
*
|
||||
|
@ -217,7 +156,9 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
|
|||
#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, \
|
||||
IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
|
||||
|
||||
/* return the index (within a minor number block) of a file */
|
||||
/**
|
||||
* ieee1394_file_to_instance - get the index within a minor number block
|
||||
*/
|
||||
static inline unsigned char ieee1394_file_to_instance(struct file *file)
|
||||
{
|
||||
return file->f_path.dentry->d_inode->i_cindex;
|
||||
|
|
|
@ -212,6 +212,15 @@ void hpsb_free_tlabel(struct hpsb_packet *packet)
|
|||
wake_up_interruptible(&tlabel_wq);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_packet_success - Make sense of the ack and reply codes
|
||||
*
|
||||
* Make sense of the ack and reply codes and return more convenient error codes:
|
||||
* 0 = success. -%EBUSY = node is busy, try again. -%EAGAIN = error which can
|
||||
* probably resolved by retry. -%EREMOTEIO = node suffers from an internal
|
||||
* error. -%EACCES = this transaction is not allowed on requested address.
|
||||
* -%EINVAL = invalid address at node.
|
||||
*/
|
||||
int hpsb_packet_success(struct hpsb_packet *packet)
|
||||
{
|
||||
switch (packet->ack_code) {
|
||||
|
@ -493,6 +502,16 @@ struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
|
|||
* avoid in kernel buffers for user space callers
|
||||
*/
|
||||
|
||||
/**
|
||||
* hpsb_read - generic read function
|
||||
*
|
||||
* Recognizes the local node ID and act accordingly. Automatically uses a
|
||||
* quadlet read request if @length == 4 and and a block read request otherwise.
|
||||
* It does not yet support lengths that are not a multiple of 4.
|
||||
*
|
||||
* You must explicitly specifiy the @generation for which the node ID is valid,
|
||||
* to avoid sending packets to the wrong nodes when we race with a bus reset.
|
||||
*/
|
||||
int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
|
||||
u64 addr, quadlet_t * buffer, size_t length)
|
||||
{
|
||||
|
@ -532,6 +551,16 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_write - generic write function
|
||||
*
|
||||
* Recognizes the local node ID and act accordingly. Automatically uses a
|
||||
* quadlet write request if @length == 4 and and a block write request
|
||||
* otherwise. It does not yet support lengths that are not a multiple of 4.
|
||||
*
|
||||
* You must explicitly specifiy the @generation for which the node ID is valid,
|
||||
* to avoid sending packets to the wrong nodes when we race with a bus reset.
|
||||
*/
|
||||
int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
|
||||
u64 addr, quadlet_t * buffer, size_t length)
|
||||
{
|
||||
|
|
|
@ -27,27 +27,7 @@ struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host,
|
|||
struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer,
|
||||
int length, int channel, int tag,
|
||||
int sync);
|
||||
|
||||
/*
|
||||
* hpsb_packet_success - Make sense of the ack and reply codes and
|
||||
* return more convenient error codes:
|
||||
* 0 success
|
||||
* -EBUSY node is busy, try again
|
||||
* -EAGAIN error which can probably resolved by retry
|
||||
* -EREMOTEIO node suffers from an internal error
|
||||
* -EACCES this transaction is not allowed on requested address
|
||||
* -EINVAL invalid address at node
|
||||
*/
|
||||
int hpsb_packet_success(struct hpsb_packet *packet);
|
||||
|
||||
/*
|
||||
* The generic read and write functions. All recognize the local node ID
|
||||
* and act accordingly. Read and write automatically use quadlet commands if
|
||||
* length == 4 and and block commands otherwise (however, they do not yet
|
||||
* support lengths that are not a multiple of 4). You must explicitly specifiy
|
||||
* the generation for which the node ID is valid, to avoid sending packets to
|
||||
* the wrong nodes when we race with a bus reset.
|
||||
*/
|
||||
int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
|
||||
u64 addr, quadlet_t *buffer, size_t length);
|
||||
int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#include "hosts.h"
|
||||
#include "iso.h"
|
||||
|
||||
/**
|
||||
* hpsb_iso_stop - stop DMA
|
||||
*/
|
||||
void hpsb_iso_stop(struct hpsb_iso *iso)
|
||||
{
|
||||
if (!(iso->flags & HPSB_ISO_DRIVER_STARTED))
|
||||
|
@ -25,6 +28,9 @@ void hpsb_iso_stop(struct hpsb_iso *iso)
|
|||
iso->flags &= ~HPSB_ISO_DRIVER_STARTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_shutdown - deallocate buffer and DMA context
|
||||
*/
|
||||
void hpsb_iso_shutdown(struct hpsb_iso *iso)
|
||||
{
|
||||
if (iso->flags & HPSB_ISO_DRIVER_INIT) {
|
||||
|
@ -130,6 +136,9 @@ static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_n_ready - returns number of packets ready to send or receive
|
||||
*/
|
||||
int hpsb_iso_n_ready(struct hpsb_iso *iso)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -142,6 +151,9 @@ int hpsb_iso_n_ready(struct hpsb_iso *iso)
|
|||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_xmit_init - allocate the buffer and DMA context
|
||||
*/
|
||||
struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host,
|
||||
unsigned int data_buf_size,
|
||||
unsigned int buf_packets,
|
||||
|
@ -172,6 +184,11 @@ struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_recv_init - allocate the buffer and DMA context
|
||||
*
|
||||
* Note, if channel = -1, multi-channel receive is enabled.
|
||||
*/
|
||||
struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host,
|
||||
unsigned int data_buf_size,
|
||||
unsigned int buf_packets,
|
||||
|
@ -199,6 +216,11 @@ struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_recv_listen_channel
|
||||
*
|
||||
* multi-channel only
|
||||
*/
|
||||
int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
|
||||
{
|
||||
if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
|
||||
|
@ -206,6 +228,11 @@ int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
|
|||
return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_recv_unlisten_channel
|
||||
*
|
||||
* multi-channel only
|
||||
*/
|
||||
int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
|
||||
{
|
||||
if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
|
||||
|
@ -213,6 +240,11 @@ int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
|
|||
return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_recv_set_channel_mask
|
||||
*
|
||||
* multi-channel only
|
||||
*/
|
||||
int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
|
||||
{
|
||||
if (iso->type != HPSB_ISO_RECV || iso->channel != -1)
|
||||
|
@ -221,6 +253,12 @@ int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
|
|||
(unsigned long)&mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_recv_flush - check for arrival of new packets
|
||||
*
|
||||
* check for arrival of new packets immediately (even if irq_interval
|
||||
* has not yet been reached)
|
||||
*/
|
||||
int hpsb_iso_recv_flush(struct hpsb_iso *iso)
|
||||
{
|
||||
if (iso->type != HPSB_ISO_RECV)
|
||||
|
@ -238,6 +276,9 @@ static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_xmit_start - start DMA
|
||||
*/
|
||||
int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
|
||||
{
|
||||
if (iso->type != HPSB_ISO_XMIT)
|
||||
|
@ -270,6 +311,9 @@ int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_recv_start - start DMA
|
||||
*/
|
||||
int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
|
||||
{
|
||||
int retval = 0;
|
||||
|
@ -306,8 +350,7 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
|
|||
}
|
||||
|
||||
/* check to make sure the user has not supplied bogus values of offset/len
|
||||
that would cause the kernel to access memory outside the buffer */
|
||||
|
||||
* that would cause the kernel to access memory outside the buffer */
|
||||
static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
|
||||
unsigned int offset, unsigned short len,
|
||||
unsigned int *out_offset,
|
||||
|
@ -331,6 +374,12 @@ static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_xmit_queue_packet - queue a packet for transmission.
|
||||
*
|
||||
* @offset is relative to the beginning of the DMA buffer, where the packet's
|
||||
* data payload should already have been placed.
|
||||
*/
|
||||
int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
|
||||
u8 tag, u8 sy)
|
||||
{
|
||||
|
@ -380,6 +429,9 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
|
|||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_xmit_sync - wait until all queued packets have been transmitted
|
||||
*/
|
||||
int hpsb_iso_xmit_sync(struct hpsb_iso *iso)
|
||||
{
|
||||
if (iso->type != HPSB_ISO_XMIT)
|
||||
|
@ -390,6 +442,15 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso)
|
|||
iso->buf_packets);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_packet_sent
|
||||
*
|
||||
* Available to low-level drivers.
|
||||
*
|
||||
* Call after a packet has been transmitted to the bus (interrupt context is
|
||||
* OK). @cycle is the _exact_ cycle the packet was sent on. @error should be
|
||||
* non-zero if some sort of error occurred when sending the packet.
|
||||
*/
|
||||
void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -413,6 +474,13 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
|
|||
spin_unlock_irqrestore(&iso->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_packet_received
|
||||
*
|
||||
* Available to low-level drivers.
|
||||
*
|
||||
* Call after a packet has been received (interrupt context is OK).
|
||||
*/
|
||||
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
|
||||
u16 total_len, u16 cycle, u8 channel, u8 tag,
|
||||
u8 sy)
|
||||
|
@ -442,6 +510,11 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
|
|||
spin_unlock_irqrestore(&iso->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_recv_release_packets - release packets, reuse buffer
|
||||
*
|
||||
* @n_packets have been read out of the buffer, re-use the buffer space
|
||||
*/
|
||||
int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -477,6 +550,13 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
|
|||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpsb_iso_wake
|
||||
*
|
||||
* Available to low-level drivers.
|
||||
*
|
||||
* Call to wake waiting processes after buffer space has opened up.
|
||||
*/
|
||||
void hpsb_iso_wake(struct hpsb_iso *iso)
|
||||
{
|
||||
wake_up_interruptible(&iso->waitq);
|
||||
|
|
|
@ -150,8 +150,6 @@ struct hpsb_iso {
|
|||
|
||||
/* functions available to high-level drivers (e.g. raw1394) */
|
||||
|
||||
/* allocate the buffer and DMA context */
|
||||
|
||||
struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
|
||||
unsigned int data_buf_size,
|
||||
unsigned int buf_packets,
|
||||
|
@ -159,8 +157,6 @@ struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
|
|||
int speed,
|
||||
int irq_interval,
|
||||
void (*callback)(struct hpsb_iso*));
|
||||
|
||||
/* note: if channel = -1, multi-channel receive is enabled */
|
||||
struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
|
||||
unsigned int data_buf_size,
|
||||
unsigned int buf_packets,
|
||||
|
@ -168,56 +164,29 @@ struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
|
|||
int dma_mode,
|
||||
int irq_interval,
|
||||
void (*callback)(struct hpsb_iso*));
|
||||
|
||||
/* multi-channel only */
|
||||
int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel);
|
||||
int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel);
|
||||
int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask);
|
||||
|
||||
/* start/stop DMA */
|
||||
int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle,
|
||||
int prebuffer);
|
||||
int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle,
|
||||
int tag_mask, int sync);
|
||||
void hpsb_iso_stop(struct hpsb_iso *iso);
|
||||
|
||||
/* deallocate buffer and DMA context */
|
||||
void hpsb_iso_shutdown(struct hpsb_iso *iso);
|
||||
|
||||
/* queue a packet for transmission.
|
||||
* 'offset' is relative to the beginning of the DMA buffer, where the packet's
|
||||
* data payload should already have been placed. */
|
||||
int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
|
||||
u8 tag, u8 sy);
|
||||
|
||||
/* wait until all queued packets have been transmitted to the bus */
|
||||
int hpsb_iso_xmit_sync(struct hpsb_iso *iso);
|
||||
|
||||
/* N packets have been read out of the buffer, re-use the buffer space */
|
||||
int hpsb_iso_recv_release_packets(struct hpsb_iso *recv,
|
||||
unsigned int n_packets);
|
||||
|
||||
/* check for arrival of new packets immediately (even if irq_interval
|
||||
* has not yet been reached) */
|
||||
int hpsb_iso_recv_release_packets(struct hpsb_iso *recv,
|
||||
unsigned int n_packets);
|
||||
int hpsb_iso_recv_flush(struct hpsb_iso *iso);
|
||||
|
||||
/* returns # of packets ready to send or receive */
|
||||
int hpsb_iso_n_ready(struct hpsb_iso *iso);
|
||||
|
||||
/* the following are callbacks available to low-level drivers */
|
||||
|
||||
/* call after a packet has been transmitted to the bus (interrupt context is OK)
|
||||
* 'cycle' is the _exact_ cycle the packet was sent on
|
||||
* 'error' should be non-zero if some sort of error occurred when sending the
|
||||
* packet */
|
||||
void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error);
|
||||
|
||||
/* call after a packet has been received (interrupt context OK) */
|
||||
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
|
||||
u16 total_len, u16 cycle, u8 channel, u8 tag,
|
||||
u8 sy);
|
||||
|
||||
/* call to wake waiting processes after buffer space has opened up. */
|
||||
void hpsb_iso_wake(struct hpsb_iso *iso);
|
||||
|
||||
#endif /* IEEE1394_ISO_H */
|
||||
|
|
|
@ -1738,7 +1738,19 @@ exit:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
|
||||
/**
|
||||
* nodemgr_for_each_host - call a function for each IEEE 1394 host
|
||||
* @data: an address to supply to the callback
|
||||
* @cb: function to call for each host
|
||||
*
|
||||
* Iterate the hosts, calling a given function with supplied data for each host.
|
||||
* If the callback fails on a host, i.e. if it returns a non-zero value, the
|
||||
* iteration is stopped.
|
||||
*
|
||||
* Return value: 0 on success, non-zero on failure (same as returned by last run
|
||||
* of the callback).
|
||||
*/
|
||||
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
|
||||
{
|
||||
struct class_device *cdev;
|
||||
struct hpsb_host *host;
|
||||
|
@ -1748,7 +1760,7 @@ int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
|
|||
list_for_each_entry(cdev, &hpsb_host_class.children, node) {
|
||||
host = container_of(cdev, struct hpsb_host, class_dev);
|
||||
|
||||
if ((error = cb(host, __data)))
|
||||
if ((error = cb(host, data)))
|
||||
break;
|
||||
}
|
||||
up(&hpsb_host_class.sem);
|
||||
|
@ -1771,12 +1783,20 @@ int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
|
|||
* ID's.
|
||||
*/
|
||||
|
||||
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
|
||||
/**
|
||||
* hpsb_node_fill_packet - fill some destination information into a packet
|
||||
* @ne: destination node
|
||||
* @packet: packet to fill in
|
||||
*
|
||||
* This will fill in the given, pre-initialised hpsb_packet with the current
|
||||
* information from the node entry (host, node ID, bus generation number).
|
||||
*/
|
||||
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet)
|
||||
{
|
||||
pkt->host = ne->host;
|
||||
pkt->generation = ne->generation;
|
||||
packet->host = ne->host;
|
||||
packet->generation = ne->generation;
|
||||
barrier();
|
||||
pkt->node_id = ne->nodeid;
|
||||
packet->node_id = ne->nodeid;
|
||||
}
|
||||
|
||||
int hpsb_node_write(struct node_entry *ne, u64 addr,
|
||||
|
|
|
@ -153,26 +153,10 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne)
|
|||
{
|
||||
return ne->generation == get_hpsb_generation(ne->host);
|
||||
}
|
||||
|
||||
/*
|
||||
* This will fill in the given, pre-initialised hpsb_packet with the current
|
||||
* information from the node entry (host, node ID, generation number). It will
|
||||
* return false if the node owning the GUID is not accessible (and not modify
|
||||
* the hpsb_packet) and return true otherwise.
|
||||
*
|
||||
* Note that packet sending may still fail in hpsb_send_packet if a bus reset
|
||||
* happens while you are trying to set up the packet (due to obsolete generation
|
||||
* number). It will at least reliably fail so that you don't accidentally and
|
||||
* unknowingly send your packet to the wrong node.
|
||||
*/
|
||||
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt);
|
||||
|
||||
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet);
|
||||
int hpsb_node_write(struct node_entry *ne, u64 addr,
|
||||
quadlet_t *buffer, size_t length);
|
||||
|
||||
/* Iterate the hosts, calling a given function with supplied data for each
|
||||
* host. */
|
||||
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *));
|
||||
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *));
|
||||
|
||||
int init_ieee1394_nodemgr(void);
|
||||
void cleanup_ieee1394_nodemgr(void);
|
||||
|
|
|
@ -3658,6 +3658,7 @@ static struct pci_driver ohci1394_pci_driver = {
|
|||
/* essentially the only purpose of this code is to allow another
|
||||
module to hook into ohci's interrupt handler */
|
||||
|
||||
/* returns zero if successful, one if DMA context is locked up */
|
||||
int ohci1394_stop_context(struct ti_ohci *ohci, int reg, char *msg)
|
||||
{
|
||||
int i=0;
|
||||
|
|
|
@ -461,9 +461,7 @@ int ohci1394_register_iso_tasklet(struct ti_ohci *ohci,
|
|||
struct ohci1394_iso_tasklet *tasklet);
|
||||
void ohci1394_unregister_iso_tasklet(struct ti_ohci *ohci,
|
||||
struct ohci1394_iso_tasklet *tasklet);
|
||||
|
||||
/* returns zero if successful, one if DMA context is locked up */
|
||||
int ohci1394_stop_context (struct ti_ohci *ohci, int reg, char *msg);
|
||||
int ohci1394_stop_context(struct ti_ohci *ohci, int reg, char *msg);
|
||||
struct ti_ohci *ohci1394_get_struct(int card_num);
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче