From a9ababa28c7ccedaf4be1501d009f99d9a7ba580 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 15 Feb 2006 02:26:14 +0000 Subject: Merged revisions 949 via svnmerge from https://origsvn.digium.com/svn/zaptel/branches/1.2 ........ r949 | kpfleming | 2006-02-14 20:24:18 -0600 (Tue, 14 Feb 2006) | 2 lines initial import of Xorcom Astribank driver (issue #6452, with minor mods) ........ git-svn-id: http://svn.digium.com/svn/zaptel/trunk@950 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/xpd.h | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 xpp/xpd.h (limited to 'xpp/xpd.h') diff --git a/xpp/xpd.h b/xpp/xpd.h new file mode 100644 index 0000000..f563ca3 --- /dev/null +++ b/xpp/xpd.h @@ -0,0 +1,290 @@ +#ifndef XPD_H +#define XPD_H + +/* + * Written by Oron Peled + * Copyright (C) 2004-2005, Xorcom + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "xdefs.h" +#include "xproto.h" + +#ifdef __KERNEL__ +#include +#include +#include +#include +#endif + +#include + +#ifdef __KERNEL__ +#define DEF_PARM(type,name,init,desc) \ + type name = init; \ + module_param(name, type, 0600); \ + MODULE_PARM_DESC(name, desc) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) +/* + * Old 2.6 kernels had module_param_array() macro that receive the counter + * by value. + */ +#define DEF_ARRAY(type,name,count,init,desc) \ + unsigned int name ## _num_values; \ + type name[count] = {[0 ... count-1] = init}; \ + module_param_array(name, type, name ## _num_values, 0600); \ + MODULE_PARM_DESC(name, desc " ( 1-" __MODULE_STRING(count) ")") +#else +#define DEF_ARRAY(type,name,count,init,desc) \ + unsigned int name ## _num_values; \ + type name[count] = {[0 ... count-1] = init}; \ + module_param_array(name, type, &name ## _num_values, 0600); \ + MODULE_PARM_DESC(name, desc " ( 1-" __MODULE_STRING(count) ")") +#endif +#endif // __KERNEL__ + + +#define MAX_SPANNAME 20 +#define MAX_SPANDESC 40 +#define MAX_CHANNAME 20 + +#define XPD_NAMELEN 10 /* must be <= from maximal workqueue name */ +#define XPD_DESCLEN 20 +#define XBUS_NAMELEN 20 /* must be <= from maximal workqueue name */ +#define XBUS_DESCLEN 40 + +/* Hardware does not check bank_num yet. So only 4 cards can be used */ +#define MAX_XPDS 4 // 1 FXS + 2 E1/T1 + 1 (Quad * E1/T1) + +#define VALID_XPD_NUM(x) ((x) < MAX_XPDS && (x) >= 0) + +typedef struct xbus_ops xbus_ops_t; + +typedef enum xbus_type { + FIRMWARE_LOOPBACK = 1, + FIRMWARE_XPP = 2, +} xbus_type_t; + +#ifdef __KERNEL__ + + +typedef struct packet_queue { + char qname[XPD_NAMELEN]; + struct list_head head; + unsigned int count; + unsigned int worst_count; + unsigned int overflows; + spinlock_t lock; +} packet_queue_t; + +struct xbus_ops { + int (*packet_send)(xbus_t *xbus, xpacket_t *packet); + xpacket_t *(*packet_new)(xbus_t *xbus, int flags); + void (*packet_free)(xbus_t *xbus, xpacket_t *p); +}; + +enum { + XBUS_N_DESC_REQ, + XBUS_N_DEV_DESC, + XBUS_N_PCM_WRITE, + XBUS_N_PCM_READ, + XBUS_N_TX_BYTES, + XBUS_N_RX_BYTES, + XBUS_N_SOFTSIM_PACKETS, + XBUS_N_SIM_PACKETS, +}; + +#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), + C_(PCM_WRITE), + C_(PCM_READ), + C_(TX_BYTES), + C_(RX_BYTES), + C_(SOFTSIM_PACKETS), + C_(SIM_PACKETS), +}; + +#undef C_ + +#define XBUS_COUNTER_MAX ARRAY_SIZE(xbus_counters) + +struct xpd_sim { + bool simulated; + bool softloop_xpd; + int loopto; + xpd_type_t xpd_type; + xpp_line_t hookstate; +}; + + +struct xbus { + char busname[XBUS_NAMELEN]; /* only xbus_new set this */ + char busdesc[XBUS_DESCLEN]; /* lowlevel drivers set this */ + int num; + xbus_ops_t *ops; + struct xpd *xpds[MAX_XPDS]; + + /* Simulator data */ + xbus_type_t bus_type; +#if SOFT_SIMULATOR + struct xpd_sim sim[MAX_XPDS]; + struct workqueue_struct *sim_workqueue; + struct work_struct sim_work; // workqueue job for running simulator + packet_queue_t sim_packet_queue; +#endif + + spinlock_t lock; + + bool hardware_exists; /* Hardware is functional */ + int open_counter; /* Number of open channels */ + atomic_t packet_counter; /* Allocated packets */ + wait_queue_head_t packet_cache_empty; + + struct timer_list poll_timer; + struct rw_semaphore in_use; + int num_xpds; + void *priv; /* Pointer to transport level data structures */ + +#ifdef XPP_PACKET_LOG + struct cyclic_buff *packet_log; +#endif + +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_xbus_dir; + struct proc_dir_entry *proc_xbus_summary; +#endif + + /* statistics */ + int counters[XBUS_COUNTER_MAX]; + +}; +#endif + +typedef enum xpd_direction { + TO_PHONE = 0, + TO_PSTN = 1, +} xpd_direction_t; + +#define LINE_BITS (sizeof(xpp_line_t)*8) + + +#ifdef __KERNEL__ +#define BIT_SET(x,i) ((x) |= (1 << (i))) +#define BIT_CLR(x,i) ((x) &= ~(1 << (i))) +#define IS_SET(x,i) (((x) & (1 << (i))) != 0) +#define BIT(i) (1 << (i)) + +enum { + XPD_N_PCM_READ, + XPD_N_PCM_WRITE, + XPD_N_RECV_ERRORS, +}; + +#define XPD_COUNTER(xpd, counter) ((xpd)->counters[XPD_N_ ## counter]) + +#define C_(x) [ XPD_N_ ## x ] = { #x } + +/* yucky, make an instance so we can size it... */ +static struct xpd_counters { + char *name; +} xpd_counters[] = { + C_(PCM_READ), + C_(PCM_WRITE), + C_(RECV_ERRORS), +}; + +#undef C_ + +#define XPD_COUNTER_MAX (sizeof(xpd_counters)/sizeof(xpd_counters[0])) + +enum leds { + LED_GREEN, + LED_RED, + LED_BLUE, +}; + +#define NUM_LEDS 3 + +struct xpd { + char xpdname[XPD_NAMELEN]; + struct zt_span span; + struct zt_chan *chans; + int channels; + xpd_type_t type; + xpd_direction_t direction; /* TO_PHONE, TO_PSTN */ + xpp_line_t enabled_chans; /* hardware activation: 0 - off, 1 - on */ + xpp_line_t hookstate; /* 0 - ONHOOK, 1 - OFHOOK */ + xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */ + xpp_line_t digital_outputs; /* 0 - no, 1 - yes */ + xpp_line_t digital_inputs; /* 0 - no, 1 - yes */ + + int ringing[CHANNELS_PERXPD]; + bool ringer_on[CHANNELS_PERXPD]; /* For ring toggling */ + bool led_on[CHANNELS_PERXPD]; /* For led toggling */ + int lasttxhook[CHANNELS_PERXPD]; + + struct work_struct xpd_post_init; + xbus_t *xbus; + + spinlock_t lock; + atomic_t open_counter; /* Number of open channels */ + + int flags; + + unsigned int board_flags; +#define XPD_BOARD_LOOPBACK 1 + +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_xpd_dir; + struct proc_dir_entry *proc_xpd_summary; + struct proc_dir_entry *proc_xpd_ztregister; +#endif + // Bit numbers of board_flags + + int counters[XPD_COUNTER_MAX]; + + const xops_t *xops; /* Card level operations */ + void *priv; /* Card level private data */ + atomic_t card_present; + + unsigned int recv_errors; + unsigned int seq_errors; + unsigned long last_response; /* in jiffies */ + unsigned id; + struct list_head xpd_list; + unsigned int timer_count; + volatile u_char *writechunk; /* Double-word aligned write memory */ + volatile u_char *readchunk; /* Double-word aligned read memory */ + /* Echo cancelation */ + u_char ec_chunk1[CHANNELS_PERXPD][ZT_CHUNKSIZE]; + u_char ec_chunk2[CHANNELS_PERXPD][ZT_CHUNKSIZE]; +}; + +#endif + +#endif /* XPD_H */ -- cgit v1.2.3