#ifndef XPD_H #define XPD_H /* * Written by Oron Peled * Copyright (C) 2004-2006, 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 #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,10) /* * 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 /* From zaptel.h */ #define MAX_SPANDESC 40 /* From zaptel.h */ #define MAX_CHANNAME 40 /* From zaptel.h */ #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); }; /* * XBUS statistics counters */ 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) /* * An xbus is a transport layer for Xorcom Protocol commands */ 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]; int max_packet_size; /* Device-Model */ struct device the_bus; /* Simulator data */ xbus_type_t bus_type; 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 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; #ifdef __KERNEL__ /* * XPD statistics counters */ 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])) #define LED_BLINK_PERIOD (HZ/8) #define LED_ON 1 #define LED_OFF 0 #define LED_BLINK (-LED_BLINK_PERIOD) /* Values of SLIC register 0x40 */ enum fxs_state { FXS_LINE_DISABLED = 0x00, FXS_LINE_ENABLED = 0x01, FXS_LINE_CID = 0x02, FXS_LINE_TIPOPEN = 0x03, /* For GroundStart signalling */ FXS_LINE_RING = 0x04, FXS_LINE_REV_ACTIVE = 0x05 }; /* * An XPD is a single Xorcom Protocol Device */ struct xpd { char xpdname[XPD_NAMELEN]; struct zt_span span; struct zt_chan *chans; int channels; xpd_type_t type; byte revision; /* Card revision */ xpd_direction_t direction; /* TO_PHONE, TO_PSTN */ xpp_line_t enabled_chans; /* hardware activation: 0 - off, 1 - on */ xpp_line_t no_pcm; /* Temporary: disable PCM (for USB-1) */ xpp_line_t hookstate; /* Actual chip state: 0 - ONHOOK, 1 - OFHOOK */ 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 */ wait_queue_head_t txstateq[CHANNELS_PERXPD]; /* waiting on the tx state to change */ int delay_until_dialtone[CHANNELS_PERXPD]; enum fxs_state lasttxhook[CHANNELS_PERXPD]; int idletxhookstate[CHANNELS_PERXPD]; /* IDLE changing hook state */ int ohttimer[CHANNELS_PERXPD]; xbus_t *xbus; /* The XBUS we are connected to */ spinlock_t lock; atomic_t open_counter; /* Number of open channels */ int flags; #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 int counters[XPD_COUNTER_MAX]; const xproto_table_t *xproto; /* Card level protocol table */ const xops_t *xops; /* Card level operations */ void *priv; /* Card level private data */ bool 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]; }; #define for_each_line(xpd,i) \ for((i) = 0; (i) < (xpd)->channels; (i)++) #define for_each_enabled_line(xpd,i) \ for((i) = 0; (i) < (xpd)->channels; (i)++) \ if(IS_SET((xpd)->enabled_chans,(i))) #endif #endif /* XPD_H */