diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-12-18 14:31:07 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-12-18 14:31:07 +0000 |
commit | cfd61537b47387b0fb5c8228baad6cec16d8f6e6 (patch) | |
tree | 108deea65c09c7c273a9b981f8783efcd433eaea /xpp/xbus-core.h | |
parent | 4391b4a6ee42bdfd8e097c5ee5485e9eb13f19a0 (diff) |
xpp r5151:
* xpd_pri: Basically ready.
* PCM synchronization changes:
- Each Astribank unit ticks independently. Each with its own PLL.
- HOST synchronization is gone. Loading of xpp will no longer cause
useless 250 ticks per second if you have no Astribank.
- Synchronization from the zaptel sync master requires setting
ZAPTEL as sync source (xpp_sync ZAPTEL).
* rx_tasklet is now a parameter of the module xpp, rather than of xpp_usb.
* New FPGA firmware: 5128 (1151) / 5122 (1141, 1131):
- Fixes synchronization issues.
- PRI module: E1 should now work.
* perl module and utilities:
- Modules no longer magically scan system on initialization.
- Scanning is by calling explicit methods.
- "Serial" has been renamed "Label". It is basically unique, but
should be modifieble.
- Some basic documentation of zaptel perl modules.
* Default sort order of zt_registration is back to SORT_CONNCTOR.
* zt_registration proc file now shows the number of span registered to
if registered. Try: grep . /proc/xpp/XBUS-*/XPD-*/zt_registration
* genzaptelconf: Allow using a custom command instead of
/etc/init.d/asterisk to start/stop asterisk.
* Fixed the typo "Slagish".
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3506 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/xbus-core.h')
-rw-r--r-- | xpp/xbus-core.h | 202 |
1 files changed, 194 insertions, 8 deletions
diff --git a/xpp/xbus-core.h b/xpp/xbus-core.h index d1a3167..de6e859 100644 --- a/xpp/xbus-core.h +++ b/xpp/xbus-core.h @@ -22,20 +22,211 @@ #ifndef XBUS_CORE_H #define XBUS_CORE_H +#include <linux/wait.h> +#include <linux/interrupt.h> /* for tasklets */ #include "xpd.h" +#include "xframe_queue.h" +#include "xbus-pcm.h" #define MAX_BUSES 32 #define XFRAME_DATASIZE 512 +/* forward declarations */ +struct xbus_poller; +#ifdef XPP_DEBUGFS +struct debugfs_data; +#endif + +#ifdef __KERNEL__ + +struct xbus_ops { + int (*xframe_send_pcm)(xbus_t *xbus, xframe_t *xframe); + int (*xframe_send_cmd)(xbus_t *xbus, xframe_t *xframe); + xframe_t *(*alloc_xframe)(xbus_t *xbus, gfp_t gfp_flags); + void (*free_xframe)(xbus_t *xbus, xframe_t *xframe); +}; + +/* + * XBUS statistics counters + */ +enum { + XBUS_N_DESC_REQ, + XBUS_N_DEV_DESC_FULL, + XBUS_N_DEV_DESC_EMPTY, + XBUS_N_TX_XFRAME_PCM, + XBUS_N_RX_XFRAME_PCM, + XBUS_N_TX_PACK_PCM, + XBUS_N_RX_PACK_PCM, + XBUS_N_TX_BYTES, + XBUS_N_RX_BYTES, + XBUS_N_TX_PCM_FRAG, + XBUS_N_TX_CMD, +}; + +#define XBUS_COUNTER(xbus, counter) ((xbus)->counters[XBUS_N_ ## counter]) + +#define C_(x) [ XBUS_N_ ## x ] = { #x } + +/* yucky, make an instance so we can size it... */ +static struct xbus_counters { + char *name; +} xbus_counters[] = { + C_(DESC_REQ), + C_(DEV_DESC_FULL), + C_(DEV_DESC_EMPTY), + C_(TX_XFRAME_PCM), + C_(RX_XFRAME_PCM), + C_(TX_PACK_PCM), + C_(RX_PACK_PCM), + C_(TX_BYTES), + C_(RX_BYTES), + C_(TX_PCM_FRAG), + C_(TX_CMD), +}; + +#undef C_ + +#define XBUS_COUNTER_MAX ARRAY_SIZE(xbus_counters) + +struct xbus_transport { + struct xbus_ops *ops; + void *priv; + ushort max_send_size; + bool transport_running; /* Hardware is functional */ + atomic_t transport_refcount; + wait_queue_head_t transport_unused; + spinlock_t lock; +}; + +#define MAX_SEND_SIZE(xbus) ((xbus)->transport.max_send_size) +#define TRANSPORT_RUNNING(xbus) ((xbus)->transport.transport_running) +#define TRANSPORT_EXIST(xbus) ((xbus)->transport.ops != NULL) + +struct xbus_ops *transportops_get(xbus_t *xbus); +void transportops_put(xbus_t *xbus); + +/* + * Allocate/Free an xframe from pools of empty xframes. + * Calls to {get,put}_xframe are wrapped in + * the macros bellow, so we take/return it + * to the correct pool. + */ +xframe_t *get_xframe(struct xframe_queue *q); +void put_xframe(struct xframe_queue *q, xframe_t *xframe); + +#define ALLOC_SEND_XFRAME(xbus) get_xframe(&(xbus)->send_pool) +#define ALLOC_RECV_XFRAME(xbus) get_xframe(&(xbus)->receive_pool) +#define FREE_SEND_XFRAME(xbus, xframe) put_xframe(&(xbus)->send_pool, (xframe)) +#define FREE_RECV_XFRAME(xbus, xframe) put_xframe(&(xbus)->receive_pool, (xframe)) + +xbus_t *get_xbus(uint num); +void put_xbus(xbus_t *xbus); + +/* + * An xbus is a transport layer for Xorcom Protocol commands + */ +struct xbus { + char busname[XBUS_NAMELEN]; /* set by xbus_new() */ + + /* low-level bus drivers set these 2 fields */ + char busdesc[XBUS_DESCLEN]; + char label[LABEL_SIZE]; + struct xbus_transport transport; + + int num; + struct xpd *xpds[MAX_XPDS]; + + struct xframe_queue command_queue; + wait_queue_head_t command_queue_empty; + + struct xframe_queue send_pool; /* empty xframes for send */ + struct xframe_queue receive_pool; /* empty xframes for receive */ + + /* tasklet processing */ + struct xframe_queue receive_queue; + struct tasklet_struct receive_tasklet; + int cpu_rcv_intr[NR_CPUS]; + int cpu_rcv_tasklet[NR_CPUS]; + + bool self_ticking; + enum sync_mode sync_mode; + struct timer_list command_timer; + unsigned int xbus_frag_count; + struct xframe_queue pcm_tospan[2]; /* double buffer */ + struct xpp_timing timing; + atomic_t pcm_rx_counter; + unsigned int global_counter; + long sync_offset_usec; + + /* Device-Model */ + struct device astribank; +#define dev_to_xbus(dev) container_of(dev, struct xbus, astribank) + + spinlock_t lock; + atomic_t xbus_ref_count; /* How many need this struct? */ + + /* PCM metrics */ + struct timeval last_tx_sync; + struct timeval last_rx_sync; + unsigned long max_tx_sync; + unsigned long min_tx_sync; + unsigned long max_rx_sync; + unsigned long min_rx_sync; + unsigned long max_rx_process; /* packet processing time (usec) */ + + struct xbus_poller *poller; + + /* + * Sync adjustment + */ + int sync_adjustment; + int sync_adjustment_offset; + long pll_updated_at; + + struct rw_semaphore in_use; +#define XBUS_GET(xbus) down_read_trylock(&(xbus)->in_use) +#define XBUS_PUT(xbus) up_read(&(xbus)->in_use) + + int num_xpds; + +#ifdef XPP_DEBUGFS + struct dentry *debugfs_dir; + struct dentry *debugfs_file; + struct debugfs_data *debugfs_data; +#endif +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_xbus_dir; + struct proc_dir_entry *proc_xbus_summary; +#ifdef PROTOCOL_DEBUG + struct proc_dir_entry *proc_xbus_command; +#endif +#endif + + /* statistics */ + int counters[XBUS_COUNTER_MAX]; +}; +#endif + +#define XFRAME_MAGIC 123456L + struct xframe { + unsigned long xframe_magic; struct list_head frame_list; atomic_t frame_len; xbus_t *xbus; struct timeval tv_created; + struct timeval tv_queued; + struct timeval tv_submitted; struct timeval tv_received; + /* filled by transport layer */ + size_t frame_maxlen; byte *packets; /* max XFRAME_DATASIZE */ + byte *first_free; + void *priv; }; +void xframe_init(xbus_t *xbus, xframe_t *xframe, void *buf, size_t maxsize, void *priv); + #define XFRAME_LEN(frame) atomic_read(&(frame)->frame_len) int xbus_core_init(void); /* Initializer */ @@ -47,10 +238,7 @@ int xbus_log(xbus_t *xbus, xpd_t *xpd, int direction, const void *buf, unsigned #endif /* Frame handling */ -xframe_t *xbus_frame_new(xbus_t *xbus, gfp_t flags); -void xbus_frame_free(xbus_t *xbus, xframe_t *p); void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe); -int xframe_send(xbus_t *xbus, xframe_t *xframe); int send_cmd_frame(xbus_t *xbus, xframe_t *xframe); /* @@ -68,17 +256,15 @@ xpacket_t *xframe_next_packet(xframe_t *xframe, int len); #define XBUS_UNIT(idx) ((idx) / MAX_SUBUNIT) #define XBUS_SUBUNIT(idx) ((idx) % MAX_SUBUNIT) -xbus_t *xbus_of(int xbus_num); xpd_t *xpd_of(const xbus_t *xbus, int xpd_num); xpd_t *xpd_byaddr(const xbus_t *xbus, uint unit, uint subunit); -xbus_t *xbus_new(xbus_ops_t *ops, size_t xframe_size); +xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size, void *priv); void xbus_remove(xbus_t *xbus); -void xbus_activate(xbus_t *xbus); +int xbus_activate(xbus_t *xbus); void xbus_disconnect(xbus_t *xbus); +void xbus_receive_xframe(xbus_t *xbus, xframe_t *xframe); void xbus_poller_notify(xbus_t *xbus, struct card_desc_struct *card_desc); -void xbus_reset_counters(xbus_t *xbus); - int xbus_register_xpd(xbus_t *xbus, xpd_t *xpd); int xbus_unregister_xpd(xbus_t *xbus, xpd_t *xpd); |