Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 275635 | Differences between
and this patch

Collapse All | Expand All

(-)dahdi-linux-2.2.0/.version (-1 lines)
Line 1 Link Here
1
2.2.0
(-)dahdi-linux-2.2.0/Makefile (-1 / +1 lines)
Lines 197-203 Link Here
197
		rm -rf /lib/modules/$(KVERS)/dahdi; \
197
		rm -rf /lib/modules/$(KVERS)/dahdi; \
198
		echo "done."; \
198
		echo "done."; \
199
	fi
199
	fi
200
#	[ `id -u` = 0 ] && /sbin/depmod -a $(KVERS) || :
200
	[ `id -u` = 0 ] && /sbin/depmod -a $(KVERS) || :
201
endif
201
endif
202
202
203
update:
203
update:
(-)dahdi-linux-2.2.0/drivers/dahdi/Kbuild (+2 lines)
Lines 16-21 Link Here
16
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT1XXP)		+= wct1xxp.o
16
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT1XXP)		+= wct1xxp.o
17
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE11XP)		+= wcte11xp.o
17
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE11XP)		+= wcte11xp.o
18
18
19
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ZAPHFC)		+= zaphfc/
20
19
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCFXO)		+= wcfxo.o
21
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCFXO)		+= wcfxo.o
20
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TOR2)		+= tor2.o
22
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TOR2)		+= tor2.o
21
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_PCIRADIO)		+= pciradio.o
23
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_PCIRADIO)		+= pciradio.o
(-)dahdi-linux-2.2.0/drivers/dahdi/dahdi-base.c (+67 lines)
Lines 6026-6036 Link Here
6026
					*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
6026
					*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
6027
				}
6027
				}
6028
				bytes -= left;
6028
				bytes -= left;
6029
#ifdef CONFIG_DAHDI_BRI_DCHANS
6030
			} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
6031
			    /*
6032
			     * Let's get this right, we want to transmit complete frames only.
6033
			     * The card driver will do the dirty HDLC work for us.
6034
			     * txb (transmit buffer) is supposed to be big enough to store one frame
6035
			     * we will make this as big as the D fifo (1KB or 2KB)
6036
			     */
6037
6038
			    /* there are 'left' bytes in the user buffer left to transmit */
6039
			    left = ms->writen[ms->outwritebuf] - ms->writeidx[ms->outwritebuf] - 2;
6040
			    if (left > ms->maxbytes2transmit) {
6041
				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], ms->maxbytes2transmit);
6042
				ms->writeidx[ms->outwritebuf] += ms->maxbytes2transmit;
6043
				txb += ms->maxbytes2transmit;
6044
				ms->bytes2transmit = ms->maxbytes2transmit;
6045
				ms->eoftx = 0;
6046
			    } else {
6047
				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
6048
				ms->writeidx[ms->outwritebuf] += left + 2;
6049
				txb += left + 2;
6050
				ms->bytes2transmit = left;
6051
				ms->eoftx = 1;
6052
			    }
6053
			    bytes = 0;
6054
#endif
6029
			} else {
6055
			} else {
6030
				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
6056
				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
6031
				ms->writeidx[ms->outwritebuf]+=left;
6057
				ms->writeidx[ms->outwritebuf]+=left;
6032
				txb += left;
6058
				txb += left;
6033
				bytes -= left;
6059
				bytes -= left;
6060
#if defined(CONFIG_DAHDI_BRI_DCHANS)
6061
				ms->bytes2transmit=DAHDI_CHUNKSIZE;
6062
#endif
6034
			}
6063
			}
6035
			/* Check buffer status */
6064
			/* Check buffer status */
6036
			if (ms->writeidx[ms->outwritebuf] >= ms->writen[ms->outwritebuf]) {
6065
			if (ms->writeidx[ms->outwritebuf] >= ms->writen[ms->outwritebuf]) {
Lines 6089-6094 Link Here
6089
				/* Transmit a flag if this is an HDLC channel */
6118
				/* Transmit a flag if this is an HDLC channel */
6090
				if (ms->flags & DAHDI_FLAG_HDLC)
6119
				if (ms->flags & DAHDI_FLAG_HDLC)
6091
					fasthdlc_tx_frame_nocheck(&ms->txhdlc);
6120
					fasthdlc_tx_frame_nocheck(&ms->txhdlc);
6121
#if defined(CONFIG_DAHDI_BRI_DCHANS)
6122
				if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
6123
			//	    if (ms->bytes2transmit > 0) {
6124
					// txb += 2;
6125
					// ms->bytes2transmit -= 2;
6126
					bytes=0;
6127
					ms->eoftx = 1;
6128
//					printk(KERN_CRIT "zaptel EOF(%d) bytes2transmit %d\n",ms->eoftx,ms->bytes2transmit);
6129
			//	    }
6130
				}
6131
#endif
6092
#ifdef CONFIG_DAHDI_NET
6132
#ifdef CONFIG_DAHDI_NET
6093
				if (ms->flags & DAHDI_FLAG_NETDEV)
6133
				if (ms->flags & DAHDI_FLAG_NETDEV)
6094
					netif_wake_queue(ztchan_to_dev(ms));
6134
					netif_wake_queue(ztchan_to_dev(ms));
Lines 6149-6154 Link Here
6149
				memset(txb, 0xFF, bytes);
6189
				memset(txb, 0xFF, bytes);
6150
			}
6190
			}
6151
			bytes = 0;
6191
			bytes = 0;
6192
#if defined(CONFIG_DAHDI_BRI_DCHANS)
6193
		} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
6194
		    ms->bytes2transmit = 0;
6195
		    ms->eoftx = 0;
6196
		    bytes = 0;
6197
#endif
6152
		} else {
6198
		} else {
6153
			memset(txb, DAHDI_LIN2X(0, ms), bytes);	/* Lastly we use silence on telephony channels */
6199
			memset(txb, DAHDI_LIN2X(0, ms), bytes);	/* Lastly we use silence on telephony channels */
6154
			bytes = 0;
6200
			bytes = 0;
Lines 7005-7010 Link Here
7005
	int res;
7051
	int res;
7006
	int left, x;
7052
	int left, x;
7007
7053
7054
#if defined(CONFIG_DAHDI_BRI_DCHANS)
7055
	if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
7056
	    bytes = ms->bytes2receive;
7057
	    if (bytes < 1) return;
7058
//	    printk(KERN_CRIT "bytes2receive %d\n",ms->bytes2receive);
7059
	}
7060
#endif
7061
7008
	while(bytes) {
7062
	while(bytes) {
7009
#if defined(CONFIG_DAHDI_NET)  || defined(CONFIG_DAHDI_PPP)
7063
#if defined(CONFIG_DAHDI_NET)  || defined(CONFIG_DAHDI_PPP)
7010
		skb = NULL;
7064
		skb = NULL;
Lines 7062-7067 Link Here
7062
						}
7116
						}
7063
					}
7117
					}
7064
				}
7118
				}
7119
#ifdef CONFIG_DAHDI_BRI_DCHANS
7120
			} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
7121
			    memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
7122
			    rxb += left;
7123
			    ms->readidx[ms->inreadbuf] += left;
7124
			    bytes -= left;
7125
			    if (ms->eofrx == 1) {
7126
				eof=1;
7127
			    }
7128
//			    printk(KERN_CRIT "receiving %d bytes\n",ms->bytes2receive);
7129
			    ms->bytes2receive = 0;
7130
			    ms->eofrx = 0;
7131
#endif
7065
			} else {
7132
			} else {
7066
				/* Not HDLC */
7133
				/* Not HDLC */
7067
				memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
7134
				memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
(-)dahdi-linux-2.2.0/drivers/dahdi/dahdi-base.c.orig (+8074 lines)
Line 0 Link Here
1
/*
2
 * DAHDI Telephony Interface Driver
3
 *
4
 * Written by Mark Spencer <markster@digium.com>
5
 * Based on previous works, designs, and architectures conceived and
6
 * written by Jim Dixon <jim@lambdatel.com>.
7
 *
8
 * Special thanks to Steve Underwood <steve@coppice.org>
9
 * for substantial contributions to signal processing functions
10
 * in DAHDI and the Zapata library.
11
 *
12
 * Yury Bokhoncovich <byg@cf1.ru>
13
 * Adaptation for 2.4.20+ kernels (HDLC API was changed)
14
 * The work has been performed as a part of our move
15
 * from Cisco 3620 to IBM x305 here in F1 Group
16
 *
17
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
18
 * Copyright (C) 2001 - 2008 Digium, Inc.
19
 *
20
 * All rights reserved.
21
 *
22
 */
23
24
/*
25
 * See http://www.asterisk.org for more information about
26
 * the Asterisk project. Please do not directly contact
27
 * any of the maintainers of this project for assistance;
28
 * the project provides a web site, mailing lists and IRC
29
 * channels for your use.
30
 *
31
 * This program is free software, distributed under the terms of
32
 * the GNU General Public License Version 2 as published by the
33
 * Free Software Foundation. See the LICENSE file included with
34
 * this program for more details.
35
 */
36
37
38
#include <linux/kernel.h>
39
#include <linux/errno.h>
40
#include <linux/module.h>
41
#include <linux/proc_fs.h>
42
#include <linux/pci.h>
43
#include <linux/init.h>
44
#include <linux/version.h>
45
#include <linux/ctype.h>
46
#include <linux/kmod.h>
47
#include <linux/moduleparam.h>
48
#include <linux/list.h>
49
50
#include <linux/ppp_defs.h>
51
52
#include <asm/atomic.h>
53
54
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
55
56
/* #define BUF_MUNGE */
57
58
#include <dahdi/version.h>
59
/* Grab fasthdlc with tables */
60
#define FAST_HDLC_NEED_TABLES
61
#include <dahdi/kernel.h>
62
#include "ecdis.h"
63
64
#ifndef CONFIG_OLD_HDLC_API
65
#define NEW_HDLC_INTERFACE
66
#endif
67
68
#ifdef CONFIG_DAHDI_PPP
69
#include <linux/netdevice.h>
70
#include <linux/if.h>
71
#include <linux/if_ppp.h>
72
#endif
73
74
#ifdef CONFIG_DAHDI_NET
75
#include <linux/netdevice.h>
76
#endif
77
78
#include "hpec/hpec_user.h"
79
80
/* Get helper arithmetic */
81
#include "arith.h"
82
#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
83
#include <asm/i387.h>
84
#endif
85
86
#define hdlc_to_ztchan(h) (((struct dahdi_hdlc *)(h))->chan)
87
#define dev_to_ztchan(h) (((struct dahdi_hdlc *)(dev_to_hdlc(h)->priv))->chan)
88
#define ztchan_to_dev(h) ((h)->hdlcnetdev->netdev)
89
90
/* macro-oni for determining a unit (channel) number */
91
#define	UNIT(file) MINOR(file->f_dentry->d_inode->i_rdev)
92
93
/* names of tx level settings */
94
static char *dahdi_txlevelnames[] = {
95
"0 db (CSU)/0-133 feet (DSX-1)",
96
"133-266 feet (DSX-1)",
97
"266-399 feet (DSX-1)",
98
"399-533 feet (DSX-1)",
99
"533-655 feet (DSX-1)",
100
"-7.5db (CSU)",
101
"-15db (CSU)",
102
"-22.5db (CSU)"
103
} ;
104
105
EXPORT_SYMBOL(dahdi_transcode_fops);
106
EXPORT_SYMBOL(dahdi_init_tone_state);
107
EXPORT_SYMBOL(dahdi_mf_tone);
108
EXPORT_SYMBOL(dahdi_register);
109
EXPORT_SYMBOL(dahdi_unregister);
110
EXPORT_SYMBOL(__dahdi_mulaw);
111
EXPORT_SYMBOL(__dahdi_alaw);
112
#ifdef CONFIG_CALC_XLAW
113
EXPORT_SYMBOL(__dahdi_lineartoulaw);
114
EXPORT_SYMBOL(__dahdi_lineartoalaw);
115
#else
116
EXPORT_SYMBOL(__dahdi_lin2mu);
117
EXPORT_SYMBOL(__dahdi_lin2a);
118
#endif
119
EXPORT_SYMBOL(dahdi_lboname);
120
EXPORT_SYMBOL(dahdi_transmit);
121
EXPORT_SYMBOL(dahdi_receive);
122
EXPORT_SYMBOL(dahdi_rbsbits);
123
EXPORT_SYMBOL(dahdi_qevent_nolock);
124
EXPORT_SYMBOL(dahdi_qevent_lock);
125
EXPORT_SYMBOL(dahdi_hooksig);
126
EXPORT_SYMBOL(dahdi_alarm_notify);
127
EXPORT_SYMBOL(dahdi_set_dynamic_ioctl);
128
EXPORT_SYMBOL(dahdi_ec_chunk);
129
EXPORT_SYMBOL(dahdi_ec_span);
130
EXPORT_SYMBOL(dahdi_hdlc_abort);
131
EXPORT_SYMBOL(dahdi_hdlc_finish);
132
EXPORT_SYMBOL(dahdi_hdlc_getbuf);
133
EXPORT_SYMBOL(dahdi_hdlc_putbuf);
134
EXPORT_SYMBOL(dahdi_alarm_channel);
135
EXPORT_SYMBOL(dahdi_register_chardev);
136
EXPORT_SYMBOL(dahdi_unregister_chardev);
137
138
EXPORT_SYMBOL(dahdi_register_echocan_factory);
139
EXPORT_SYMBOL(dahdi_unregister_echocan_factory);
140
141
EXPORT_SYMBOL(dahdi_set_hpec_ioctl);
142
143
#ifdef CONFIG_PROC_FS
144
static struct proc_dir_entry *proc_entries[DAHDI_MAX_SPANS];
145
#endif
146
147
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
148
#define CLASS_DEV_CREATE(class, devt, device, name) \
149
	device_create(class, device, devt, NULL, "%s", name)
150
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
151
#define CLASS_DEV_CREATE(class, devt, device, name) \
152
	device_create(class, device, devt, name)
153
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
154
#define CLASS_DEV_CREATE(class, devt, device, name) \
155
        class_device_create(class, NULL, devt, device, name)
156
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
157
#define CLASS_DEV_CREATE(class, devt, device, name) \
158
        class_device_create(class, devt, device, name)
159
#else
160
#define CLASS_DEV_CREATE(class, devt, device, name) \
161
        class_simple_device_add(class, devt, device, name)
162
#endif
163
164
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
165
#define CLASS_DEV_DESTROY(class, devt) \
166
	device_destroy(class, devt)
167
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
168
#define CLASS_DEV_DESTROY(class, devt) \
169
	class_device_destroy(class, devt)
170
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
171
#define CLASS_DEV_DESTROY(class, devt) \
172
	class_simple_device_remove(devt)
173
#else
174
#define CLASS_DEV_DESTROY(class, devt) \
175
	class_simple_device_remove(class, devt)
176
#endif
177
178
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
179
static struct class *dahdi_class = NULL;
180
#else
181
static struct class_simple *dahdi_class = NULL;
182
#define class_create class_simple_create
183
#define class_destroy class_simple_destroy
184
#endif
185
186
/*
187
 * See issue http://bugs.digium.com/view.php?id=13504 for more information. 
188
 * on why reference counting on the echo canceller modules is disabled
189
 * currently.
190
 */
191
#undef USE_ECHOCAN_REFCOUNT 
192
193
static int deftaps = 64;
194
195
static int debug;
196
197
/*!
198
 * \brief states for transmit signalling
199
 */
200
enum dahdi_txstate {
201
	DAHDI_TXSTATE_ONHOOK,
202
	DAHDI_TXSTATE_OFFHOOK,
203
	DAHDI_TXSTATE_START,
204
	DAHDI_TXSTATE_PREWINK,
205
	DAHDI_TXSTATE_WINK,
206
	DAHDI_TXSTATE_PREFLASH,
207
	DAHDI_TXSTATE_FLASH,
208
	DAHDI_TXSTATE_DEBOUNCE,
209
	DAHDI_TXSTATE_AFTERSTART,
210
	DAHDI_TXSTATE_RINGON,
211
	DAHDI_TXSTATE_RINGOFF,
212
	DAHDI_TXSTATE_KEWL,
213
	DAHDI_TXSTATE_AFTERKEWL,
214
	DAHDI_TXSTATE_PULSEBREAK,
215
	DAHDI_TXSTATE_PULSEMAKE,
216
	DAHDI_TXSTATE_PULSEAFTER,
217
};
218
219
typedef short sumtype[DAHDI_MAX_CHUNKSIZE];
220
221
static sumtype sums[(DAHDI_MAX_CONF + 1) * 3];
222
223
/* Translate conference aliases into actual conferences
224
   and vice-versa */
225
static short confalias[DAHDI_MAX_CONF + 1];
226
static short confrev[DAHDI_MAX_CONF + 1];
227
228
static sumtype *conf_sums_next;
229
static sumtype *conf_sums;
230
static sumtype *conf_sums_prev;
231
232
static struct dahdi_span *master;
233
static struct file_operations dahdi_fops;
234
struct file_operations *dahdi_transcode_fops = NULL;
235
236
static struct {
237
	int	src;	/* source conf number */
238
	int	dst;	/* dst conf number */
239
} conf_links[DAHDI_MAX_CONF + 1];
240
241
242
/* There are three sets of conference sum accumulators. One for the current
243
sample chunk (conf_sums), one for the next sample chunk (conf_sums_next), and
244
one for the previous sample chunk (conf_sums_prev). The following routine
245
(rotate_sums) "rotates" the pointers to these accululator arrays as part
246
of the events of sample chink processing as follows:
247
248
The following sequence is designed to be looked at from the reference point
249
of the receive routine of the master span.
250
251
1. All (real span) receive chunks are processed (with putbuf). The last one
252
to be processed is the master span. The data received is loaded into the
253
accumulators for the next chunk (conf_sums_next), to be in alignment with
254
current data after rotate_sums() is called (which immediately follows).
255
Keep in mind that putbuf is *also* a transmit routine for the pseudo parts
256
of channels that are in the REALANDPSEUDO conference mode. These channels
257
are processed from data in the current sample chunk (conf_sums), being
258
that this is a "transmit" function (for the pseudo part).
259
260
2. rotate_sums() is called.
261
262
3. All pseudo channel receive chunks are processed. This data is loaded into
263
the current sample chunk accumulators (conf_sums).
264
265
4. All conference links are processed (being that all receive data for this
266
chunk has already been processed by now).
267
268
5. All pseudo channel transmit chunks are processed. This data is loaded from
269
the current sample chunk accumulators (conf_sums).
270
271
6. All (real span) transmit chunks are processed (with getbuf).  This data is
272
loaded from the current sample chunk accumulators (conf_sums). Keep in mind
273
that getbuf is *also* a receive routine for the pseudo part of channels that
274
are in the REALANDPSEUDO conference mode. These samples are loaded into
275
the next sample chunk accumulators (conf_sums_next) to be processed as part
276
of the next sample chunk's data (next time around the world).
277
278
*/
279
280
enum dahdi_digit_mode {
281
	DIGIT_MODE_DTMF,
282
	DIGIT_MODE_MFR1,
283
	DIGIT_MODE_PULSE,
284
	DIGIT_MODE_MFR2_FWD,
285
	DIGIT_MODE_MFR2_REV,
286
};
287
288
#include "digits.h"
289
290
static struct dahdi_dialparams global_dialparams = {
291
	.dtmf_tonelen = DEFAULT_DTMF_LENGTH,
292
	.mfv1_tonelen = DEFAULT_MFR1_LENGTH,
293
	.mfr2_tonelen = DEFAULT_MFR2_LENGTH,
294
};
295
296
static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit);
297
298
#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
299
#define dahdi_kernel_fpu_begin kernel_fpu_begin
300
#endif
301
302
struct dahdi_timer {
303
	int ms;			/* Countdown */
304
	int pos;		/* Position */
305
	int ping;		/* Whether we've been ping'd */
306
	int tripped;	/* Whether we're tripped */
307
	struct list_head list;
308
	wait_queue_head_t sel;
309
};
310
311
static LIST_HEAD(zaptimers);
312
313
#ifdef DEFINE_SPINLOCK
314
static DEFINE_SPINLOCK(zaptimerlock);
315
static DEFINE_SPINLOCK(bigzaplock);
316
#else
317
static spinlock_t zaptimerlock = SPIN_LOCK_UNLOCKED;
318
static spinlock_t bigzaplock = SPIN_LOCK_UNLOCKED;
319
#endif
320
321
struct dahdi_zone {
322
	atomic_t refcount;
323
	char name[40];	/* Informational, only */
324
	int ringcadence[DAHDI_MAX_CADENCE];
325
	struct dahdi_tone *tones[DAHDI_TONE_MAX];
326
	/* Each of these is a circular list
327
	   of dahdi_tones to generate what we
328
	   want.  Use NULL if the tone is
329
	   unavailable */
330
	struct dahdi_tone dtmf[16];		/* DTMF tones for this zone, with desired length */
331
	struct dahdi_tone dtmf_continuous[16];	/* DTMF tones for this zone, continuous play */
332
	struct dahdi_tone mfr1[15];		/* MFR1 tones for this zone, with desired length */
333
	struct dahdi_tone mfr2_fwd[15];		/* MFR2 FWD tones for this zone, with desired length */
334
	struct dahdi_tone mfr2_rev[15];		/* MFR2 REV tones for this zone, with desired length */
335
	struct dahdi_tone mfr2_fwd_continuous[16];	/* MFR2 FWD tones for this zone, continuous play */
336
	struct dahdi_tone mfr2_rev_continuous[16];	/* MFR2 REV tones for this zone, continuous play */
337
};
338
339
static struct dahdi_span *spans[DAHDI_MAX_SPANS];
340
static struct dahdi_chan *chans[DAHDI_MAX_CHANNELS];
341
342
static int maxspans = 0;
343
static int maxchans = 0;
344
static int maxconfs = 0;
345
static int maxlinks = 0;
346
347
static int default_zone = -1;
348
349
short __dahdi_mulaw[256];
350
short __dahdi_alaw[256];
351
352
#ifndef CONFIG_CALC_XLAW
353
u_char __dahdi_lin2mu[16384];
354
355
u_char __dahdi_lin2a[16384];
356
#endif
357
358
static u_char defgain[256];
359
360
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
361
#define __RW_LOCK_UNLOCKED() RW_LOCK_UNLOCKED
362
#endif
363
364
#ifdef DEFINE_RWLOCK
365
static DEFINE_RWLOCK(zone_lock);
366
static DEFINE_RWLOCK(chan_lock);
367
#else
368
static rwlock_t zone_lock = RW_LOCK_UNLOCKED;
369
static rwlock_t chan_lock = RW_LOCK_UNLOCKED;
370
#endif
371
372
static struct dahdi_zone *tone_zones[DAHDI_TONE_ZONE_MAX];
373
374
#define NUM_SIGS	10
375
376
#ifdef DEFINE_RWLOCK
377
static DEFINE_RWLOCK(ecfactory_list_lock);
378
#else
379
static rwlock_t ecfactory_list_lock = __RW_LOCK_UNLOCKED();
380
#endif
381
382
static LIST_HEAD(ecfactory_list);
383
384
struct ecfactory {
385
	const struct dahdi_echocan_factory *ec;
386
	struct module *owner;
387
	struct list_head list;
388
};
389
390
int dahdi_register_echocan_factory(const struct dahdi_echocan_factory *ec)
391
{
392
	struct ecfactory *cur;
393
394
	write_lock(&ecfactory_list_lock);
395
396
	/* make sure it isn't already registered */
397
	list_for_each_entry(cur, &ecfactory_list, list) {
398
		if (cur->ec == ec) {
399
			write_unlock(&ecfactory_list_lock);
400
			return -EPERM;
401
		}
402
	}
403
404
	if (!(cur = kzalloc(sizeof(*cur), GFP_KERNEL))) {
405
		write_unlock(&ecfactory_list_lock);
406
		return -ENOMEM;
407
	}
408
409
	cur->ec = ec;
410
	INIT_LIST_HEAD(&cur->list);
411
412
	list_add_tail(&cur->list, &ecfactory_list);
413
414
	write_unlock(&ecfactory_list_lock);
415
416
	return 0;
417
}
418
419
void dahdi_unregister_echocan_factory(const struct dahdi_echocan_factory *ec)
420
{
421
	struct ecfactory *cur, *next;
422
423
	write_lock(&ecfactory_list_lock);
424
425
	list_for_each_entry_safe(cur, next, &ecfactory_list, list) {
426
		if (cur->ec == ec) {
427
			list_del(&cur->list);
428
			break;
429
		}
430
	}
431
432
	write_unlock(&ecfactory_list_lock);
433
}
434
435
static inline void rotate_sums(void)
436
{
437
	/* Rotate where we sum and so forth */
438
	static int pos = 0;
439
	conf_sums_prev = sums + (DAHDI_MAX_CONF + 1) * pos;
440
	conf_sums = sums + (DAHDI_MAX_CONF + 1) * ((pos + 1) % 3);
441
	conf_sums_next = sums + (DAHDI_MAX_CONF + 1) * ((pos + 2) % 3);
442
	pos = (pos + 1) % 3;
443
	memset(conf_sums_next, 0, maxconfs * sizeof(sumtype));
444
}
445
446
/*!
447
 * \return quiescent (idle) signalling states, for the various signalling types
448
 */
449
static int dahdi_q_sig(struct dahdi_chan *chan)
450
{
451
	int	x;
452
	static const unsigned int in_sig[NUM_SIGS][2] = {
453
		{ DAHDI_SIG_NONE,  0 },
454
		{ DAHDI_SIG_EM,    (DAHDI_ABIT << 8) },
455
		{ DAHDI_SIG_FXSLS, DAHDI_BBIT | (DAHDI_BBIT << 8) },
456
		{ DAHDI_SIG_FXSGS, DAHDI_ABIT | DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8) },
457
		{ DAHDI_SIG_FXSKS, DAHDI_BBIT | DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8) },
458
		{ DAHDI_SIG_FXOLS, (DAHDI_ABIT << 8) },
459
		{ DAHDI_SIG_FXOGS, DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8) },
460
		{ DAHDI_SIG_FXOKS, (DAHDI_ABIT << 8) },
461
		{ DAHDI_SIG_SF,    0 },
462
		{ DAHDI_SIG_EM_E1, DAHDI_DBIT | ((DAHDI_ABIT | DAHDI_DBIT) << 8) },
463
	};
464
465
	/* must have span to begin with */
466
	if (!chan->span)
467
		return -1;
468
469
	/* if RBS does not apply, return error */
470
	if (!(chan->span->flags & DAHDI_FLAG_RBS) || !chan->span->rbsbits)
471
		return -1;
472
473
	if (chan->sig == DAHDI_SIG_CAS)
474
		return chan->idlebits;
475
476
	for (x = 0; x < NUM_SIGS; x++) {
477
		if (in_sig[x][0] == chan->sig)
478
			return in_sig[x][1];
479
	}
480
481
	return -1; /* not found -- error */
482
}
483
484
#ifdef CONFIG_PROC_FS
485
static const char *sigstr(int sig)
486
{
487
	switch (sig) {
488
	case DAHDI_SIG_FXSLS:
489
		return "FXSLS";
490
	case DAHDI_SIG_FXSKS:
491
		return "FXSKS";
492
	case DAHDI_SIG_FXSGS:
493
		return "FXSGS";
494
	case DAHDI_SIG_FXOLS:
495
		return "FXOLS";
496
	case DAHDI_SIG_FXOKS:
497
		return "FXOKS";
498
	case DAHDI_SIG_FXOGS:
499
		return "FXOGS";
500
	case DAHDI_SIG_EM:
501
		return "E&M";
502
	case DAHDI_SIG_EM_E1:
503
		return "E&M-E1";
504
	case DAHDI_SIG_CLEAR:
505
		return "Clear";
506
	case DAHDI_SIG_HDLCRAW:
507
		return "HDLCRAW";
508
	case DAHDI_SIG_HDLCFCS:
509
		return "HDLCFCS";
510
	case DAHDI_SIG_HDLCNET:
511
		return "HDLCNET";
512
	case DAHDI_SIG_HARDHDLC:
513
		return "Hardware-assisted HDLC";
514
	case DAHDI_SIG_MTP2:
515
		return "MTP2";
516
	case DAHDI_SIG_SLAVE:
517
		return "Slave";
518
	case DAHDI_SIG_CAS:
519
		return "CAS";
520
	case DAHDI_SIG_DACS:
521
		return "DACS";
522
	case DAHDI_SIG_DACS_RBS:
523
		return "DACS+RBS";
524
	case DAHDI_SIG_SF:
525
		return "SF (ToneOnly)";
526
	case DAHDI_SIG_NONE:
527
	default:
528
		return "Unconfigured";
529
	}
530
}
531
532
static int fill_alarm_string(char *buf, int count, int alarms)
533
{
534
	int len;
535
536
	if (alarms <= 0)
537
		return 0;
538
539
	len = snprintf(buf, count, "%s%s%s%s%s%s",
540
			(alarms & DAHDI_ALARM_BLUE) ? "BLUE " : "",
541
			(alarms & DAHDI_ALARM_YELLOW) ? "YELLOW " : "",
542
			(alarms & DAHDI_ALARM_RED) ? "RED " : "",
543
			(alarms & DAHDI_ALARM_LOOPBACK) ? "LOOP " : "",
544
			(alarms & DAHDI_ALARM_RECOVER) ? "RECOVERING " : "",
545
			(alarms & DAHDI_ALARM_NOTOPEN) ? "NOTOPEN " : "");
546
547
	if (len > 0)
548
		buf[--len] = '\0';	/* strip last space */
549
550
	return len;
551
}
552
553
static int dahdi_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
554
{
555
	int x, len = 0, real_count;
556
	long span;
557
558
	/* In Linux 2.6, page is always PROC_BLOCK_SIZE=(PAGE_SIZE-1024) bytes.
559
	 * 0<count<=PROC_BLOCK_SIZE . count=1 will produce an error in
560
	 * vsnprintf ('head -c 1 /proc/dahdi/1', 'dd bs=1').
561
	 * An ugly hack. Good way: seq_printf (seq_file.c). */
562
        real_count = count;
563
	count = PAGE_SIZE-1024;
564
	span = (long)data;
565
	if (!span)
566
		return 0;
567
568
	if (spans[span]->name)
569
		len += snprintf(page + len, count - len, "Span %ld: %s ",
570
				span, spans[span]->name);
571
	if (spans[span]->desc)
572
		len += snprintf(page + len, count - len, "\"%s\"",
573
				spans[span]->desc);
574
	else
575
		len += snprintf(page + len, count - len, "\"\"");
576
577
	if (spans[span] == master)
578
		len += snprintf(page + len, count - len, " (MASTER)");
579
580
	if (spans[span]->lineconfig) {
581
		/* framing first */
582
		if (spans[span]->lineconfig & DAHDI_CONFIG_B8ZS)
583
			len += snprintf(page + len, count - len, " B8ZS/");
584
		else if (spans[span]->lineconfig & DAHDI_CONFIG_AMI)
585
			len += snprintf(page + len, count - len, " AMI/");
586
		else if (spans[span]->lineconfig & DAHDI_CONFIG_HDB3)
587
			len += snprintf(page + len, count - len, " HDB3/");
588
		/* then coding */
589
		if (spans[span]->lineconfig & DAHDI_CONFIG_ESF)
590
			len += snprintf(page + len, count - len, "ESF");
591
		else if (spans[span]->lineconfig & DAHDI_CONFIG_D4)
592
			len += snprintf(page + len, count - len, "D4");
593
		else if (spans[span]->lineconfig & DAHDI_CONFIG_CCS)
594
			len += snprintf(page + len, count - len, "CCS");
595
		/* E1's can enable CRC checking */
596
		if (spans[span]->lineconfig & DAHDI_CONFIG_CRC4)
597
			len += snprintf(page + len, count - len, "/CRC4");
598
	}
599
600
	len += snprintf(page + len, count - len, " ");
601
602
	/* list alarms */
603
	len += fill_alarm_string(page + len, count - len, spans[span]->alarms);
604
	if (spans[span]->syncsrc &&
605
		(spans[span]->syncsrc == spans[span]->spanno))
606
		len += snprintf(page + len, count - len, "ClockSource ");
607
	len += snprintf(page + len, count - len, "\n");
608
	if (spans[span]->bpvcount)
609
		len += snprintf(page + len, count - len, "\tBPV count: %d\n",
610
				spans[span]->bpvcount);
611
	if (spans[span]->crc4count)
612
		len += snprintf(page + len, count - len,
613
				"\tCRC4 error count: %d\n",
614
				spans[span]->crc4count);
615
	if (spans[span]->ebitcount)
616
		len += snprintf(page + len, count - len,
617
				"\tE-bit error count: %d\n",
618
				spans[span]->ebitcount);
619
	if (spans[span]->fascount)
620
		len += snprintf(page + len, count - len,
621
				"\tFAS error count: %d\n",
622
				spans[span]->fascount);
623
	if (spans[span]->irqmisses)
624
		len += snprintf(page + len, count - len,
625
				"\tIRQ misses: %d\n",
626
				spans[span]->irqmisses);
627
	if (spans[span]->timingslips)
628
		len += snprintf(page + len, count - len,
629
				"\tTiming slips: %d\n",
630
				spans[span]->timingslips);
631
	len += snprintf(page + len, count - len, "\n");
632
633
	for (x = 0; x < spans[span]->channels; x++) {
634
		struct dahdi_chan *chan = spans[span]->chans[x];
635
636
		if (chan->name)
637
			len += snprintf(page + len, count - len,
638
					"\t%4d %s ", chan->channo, chan->name);
639
640
		if (chan->sig) {
641
			if (chan->sig == DAHDI_SIG_SLAVE)
642
				len += snprintf(page+len, count-len, "%s ",
643
						sigstr(chan->master->sig));
644
			else {
645
				len += snprintf(page+len, count-len, "%s ",
646
						sigstr(chan->sig));
647
				if (chan->nextslave &&
648
					(chan->master->channo == chan->channo))
649
					len += snprintf(page+len, count-len,
650
							"Master ");
651
			}
652
		}
653
654
		if (test_bit(DAHDI_FLAGBIT_OPEN, &chan->flags))
655
			len += snprintf(page + len, count - len, "(In use) ");
656
657
#ifdef	OPTIMIZE_CHANMUTE
658
		if (chan->chanmute)
659
			len += snprintf(page+len, count-len, "(no pcm) ");
660
#endif
661
662
		len += fill_alarm_string(page+len, count-len,
663
				chan->chan_alarms);
664
665
		if (chan->ec_factory)
666
			len += snprintf(page+len, count-len, "(SWEC: %s) ",
667
					chan->ec_factory->name);
668
669
		if (chan->ec_state)
670
			len += snprintf(page+len, count-len, "(EC: %s) ",
671
					chan->ec_state->ops->name);
672
673
		len += snprintf(page+len, count-len, "\n");
674
675
		/* If everything printed so far is before beginning 
676
		 * of request */
677
		if (len <= off) {
678
			off -= len;
679
			len = 0;
680
		}
681
682
		/* stop if we've already generated enough */
683
		if (len > off + count)
684
			break;
685
		/* stop if we're NEAR danger limit. let it be -128 bytes. */
686
		if (len > count-128)
687
			break;
688
	}
689
	count = real_count;
690
	/* If everything printed so far is before beginning of request */
691
	if (len <= off) {
692
		off = 0;
693
		len = 0;
694
	}
695
	*start = page + off;
696
	len -= off;		/* un-count any remaining offset */
697
	*eof = 1;
698
	if (len > count)
699
		len = count;	/* don't return bytes not asked for */
700
	return len;
701
}
702
#endif
703
704
static int dahdi_first_empty_alias(void)
705
{
706
	/* Find the first conference which has no alias pointing to it */
707
	int x;
708
	for (x=1;x<DAHDI_MAX_CONF;x++) {
709
		if (!confrev[x])
710
			return x;
711
	}
712
	return -1;
713
}
714
715
static void recalc_maxconfs(void)
716
{
717
	int x;
718
719
	for (x = DAHDI_MAX_CONF - 1; x > 0; x--) {
720
		if (confrev[x]) {
721
			maxconfs = x + 1;
722
			return;
723
		}
724
	}
725
726
	maxconfs = 0;
727
}
728
729
static void recalc_maxlinks(void)
730
{
731
	int x;
732
733
	for (x = DAHDI_MAX_CONF - 1; x > 0; x--) {
734
		if (conf_links[x].src || conf_links[x].dst) {
735
			maxlinks = x + 1;
736
			return;
737
		}
738
	}
739
740
	maxlinks = 0;
741
}
742
743
static int dahdi_first_empty_conference(void)
744
{
745
	/* Find the first conference which has no alias */
746
	int x;
747
748
	for (x = DAHDI_MAX_CONF - 1; x > 0; x--) {
749
		if (!confalias[x])
750
			return x;
751
	}
752
753
	return -1;
754
}
755
756
static int dahdi_get_conf_alias(int x)
757
{
758
	int a;
759
760
	if (confalias[x])
761
		return confalias[x];
762
763
	/* Allocate an alias */
764
	a = dahdi_first_empty_alias();
765
	confalias[x] = a;
766
	confrev[a] = x;
767
768
	/* Highest conference may have changed */
769
	recalc_maxconfs();
770
771
	return a;
772
}
773
774
static void dahdi_check_conf(int x)
775
{
776
	int y;
777
778
	/* return if no valid conf number */
779
	if (x <= 0)
780
		return;
781
782
	/* Return if there is no alias */
783
	if (!confalias[x])
784
		return;
785
786
	for (y = 0; y < maxchans; y++) {
787
		if (chans[y] && (chans[y]->confna == x) &&
788
				((chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONF ||
789
				(chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFANN ||
790
				(chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFMON ||
791
				(chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFANNMON ||
792
				(chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_REALANDPSEUDO)) {
793
			return;
794
		}
795
	}
796
797
	/* If we get here, nobody is in the conference anymore.  Clear it out
798
	   both forward and reverse */
799
	confrev[confalias[x]] = 0;
800
	confalias[x] = 0;
801
802
	/* Highest conference may have changed */
803
	recalc_maxconfs();
804
}
805
806
/* enqueue an event on a channel */
807
static void __qevent(struct dahdi_chan *chan, int event)
808
{
809
	/* if full, ignore */
810
	if ((chan->eventoutidx == 0) && (chan->eventinidx == (DAHDI_MAX_EVENTSIZE - 1)))
811
		return;
812
813
	/* if full, ignore */
814
	if (chan->eventinidx == (chan->eventoutidx - 1))
815
		return;
816
817
	/* save the event */
818
	chan->eventbuf[chan->eventinidx++] = event;
819
820
	/* wrap the index, if necessary */
821
	if (chan->eventinidx >= DAHDI_MAX_EVENTSIZE)
822
		chan->eventinidx = 0;
823
824
	/* wake em all up */
825
	if (chan->iomask & DAHDI_IOMUX_SIGEVENT)
826
		wake_up_interruptible(&chan->eventbufq);
827
828
	wake_up_interruptible(&chan->readbufq);
829
	wake_up_interruptible(&chan->writebufq);
830
	wake_up_interruptible(&chan->sel);
831
832
	return;
833
}
834
835
void dahdi_qevent_nolock(struct dahdi_chan *chan, int event)
836
{
837
	__qevent(chan, event);
838
}
839
840
void dahdi_qevent_lock(struct dahdi_chan *chan, int event)
841
{
842
	unsigned long flags;
843
	spin_lock_irqsave(&chan->lock, flags);
844
	__qevent(chan, event);
845
	spin_unlock_irqrestore(&chan->lock, flags);
846
}
847
848
/* sleep in user space until woken up. Equivilant of tsleep() in BSD */
849
static int schluffen(wait_queue_head_t *q)
850
{
851
	DECLARE_WAITQUEUE(wait, current);
852
853
	add_wait_queue(q, &wait);
854
	current->state = TASK_INTERRUPTIBLE;
855
856
	if (!signal_pending(current))
857
		schedule();
858
859
	current->state = TASK_RUNNING;
860
	remove_wait_queue(q, &wait);
861
862
	if (signal_pending(current))
863
		return -ERESTARTSYS;
864
865
	return 0;
866
}
867
868
static inline void calc_fcs(struct dahdi_chan *ss, int inwritebuf)
869
{
870
	int x;
871
	unsigned int fcs = PPP_INITFCS;
872
	unsigned char *data = ss->writebuf[inwritebuf];
873
	int len = ss->writen[inwritebuf];
874
875
	/* Not enough space to do FCS calculation */
876
	if (len < 2)
877
		return;
878
879
	for (x = 0; x < len - 2; x++)
880
		fcs = PPP_FCS(fcs, data[x]);
881
882
	fcs ^= 0xffff;
883
	/* Send out the FCS */
884
	data[len - 2] = (fcs & 0xff);
885
	data[len - 1] = (fcs >> 8) & 0xff;
886
}
887
888
static int dahdi_reallocbufs(struct dahdi_chan *ss, int j, int numbufs)
889
{
890
	unsigned char *newbuf, *oldbuf;
891
	unsigned long flags;
892
	int x;
893
894
	/* Check numbufs */
895
	if (numbufs < 2)
896
		numbufs = 2;
897
898
	if (numbufs > DAHDI_MAX_NUM_BUFS)
899
		numbufs = DAHDI_MAX_NUM_BUFS;
900
901
	/* We need to allocate our buffers now */
902
	if (j) {
903
		if (!(newbuf = kcalloc(j * 2, numbufs, GFP_KERNEL)))
904
			return -ENOMEM;
905
	} else
906
		newbuf = NULL;
907
908
	/* Now that we've allocated our new buffer, we can safely
909
 	   move things around... */
910
911
	spin_lock_irqsave(&ss->lock, flags);
912
913
	ss->blocksize = j; /* set the blocksize */
914
	oldbuf = ss->readbuf[0]; /* Keep track of the old buffer */
915
	ss->readbuf[0] = NULL;
916
917
	if (newbuf) {
918
		for (x = 0; x < numbufs; x++) {
919
			ss->readbuf[x] = newbuf + x * j;
920
			ss->writebuf[x] = newbuf + (numbufs + x) * j;
921
		}
922
	} else {
923
		for (x = 0; x < numbufs; x++) {
924
			ss->readbuf[x] = NULL;
925
			ss->writebuf[x] = NULL;
926
		}
927
	}
928
929
	/* Mark all buffers as empty */
930
	for (x = 0; x < numbufs; x++) {
931
		ss->writen[x] =
932
		ss->writeidx[x]=
933
		ss->readn[x]=
934
		ss->readidx[x] = 0;
935
	}
936
937
	/* Keep track of where our data goes (if it goes
938
	   anywhere at all) */
939
	if (newbuf) {
940
		ss->inreadbuf = 0;
941
		ss->inwritebuf = 0;
942
	} else {
943
		ss->inreadbuf = -1;
944
		ss->inwritebuf = -1;
945
	}
946
947
	ss->outreadbuf = -1;
948
	ss->outwritebuf = -1;
949
	ss->numbufs = numbufs;
950
951
	if ((ss->txbufpolicy == DAHDI_POLICY_WHEN_FULL) || (ss->txbufpolicy == DAHDI_POLICY_HALF_FULL))
952
		ss->txdisable = 1;
953
	else
954
		ss->txdisable = 0;
955
956
	if (ss->rxbufpolicy == DAHDI_POLICY_WHEN_FULL)
957
		ss->rxdisable = 1;
958
	else
959
		ss->rxdisable = 0;
960
961
	spin_unlock_irqrestore(&ss->lock, flags);
962
963
	if (oldbuf)
964
		kfree(oldbuf);
965
966
	return 0;
967
}
968
969
static int dahdi_hangup(struct dahdi_chan *chan);
970
static void dahdi_set_law(struct dahdi_chan *chan, int law);
971
972
/* Pull a DAHDI_CHUNKSIZE piece off the queue.  Returns
973
   0 on success or -1 on failure.  If failed, provides
974
   silence */
975
static int __buf_pull(struct confq *q, u_char *data, struct dahdi_chan *c, char *label)
976
{
977
	int oldoutbuf = q->outbuf;
978
	/* Ain't nuffin to read */
979
	if (q->outbuf < 0) {
980
		if (data)
981
			memset(data, DAHDI_LIN2X(0,c), DAHDI_CHUNKSIZE);
982
		return -1;
983
	}
984
	if (data)
985
		memcpy(data, q->buf[q->outbuf], DAHDI_CHUNKSIZE);
986
	q->outbuf = (q->outbuf + 1) % DAHDI_CB_SIZE;
987
988
	/* Won't be nuffin next time */
989
	if (q->outbuf == q->inbuf) {
990
		q->outbuf = -1;
991
	}
992
993
	/* If they thought there was no space then
994
	   there is now where we just read */
995
	if (q->inbuf < 0)
996
		q->inbuf = oldoutbuf;
997
	return 0;
998
}
999
1000
/* Returns a place to put stuff, or NULL if there is
1001
   no room */
1002
1003
static u_char *__buf_pushpeek(struct confq *q)
1004
{
1005
	if (q->inbuf < 0)
1006
		return NULL;
1007
	return q->buf[q->inbuf];
1008
}
1009
1010
static u_char *__buf_peek(struct confq *q)
1011
{
1012
	if (q->outbuf < 0)
1013
		return NULL;
1014
	return q->buf[q->outbuf];
1015
}
1016
1017
#ifdef BUF_MUNGE
1018
static u_char *__buf_cpush(struct confq *q)
1019
{
1020
	int pos;
1021
	/* If we have no space, return where the
1022
	   last space that we *did* have was */
1023
	if (q->inbuf > -1)
1024
		return NULL;
1025
	pos = q->outbuf - 1;
1026
	if (pos < 0)
1027
		pos += DAHDI_CB_SIZE;
1028
	return q->buf[pos];
1029
}
1030
1031
static void __buf_munge(struct dahdi_chan *chan, u_char *old, u_char *new)
1032
{
1033
	/* Run a weighted average of the old and new, in order to
1034
	   mask a missing sample */
1035
	int x;
1036
	int val;
1037
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
1038
		val = x * DAHDI_XLAW(new[x], chan) + (DAHDI_CHUNKSIZE - x - 1) * DAHDI_XLAW(old[x], chan);
1039
		val = val / (DAHDI_CHUNKSIZE - 1);
1040
		old[x] = DAHDI_LIN2X(val, chan);
1041
	}
1042
}
1043
#endif
1044
/* Push something onto the queue, or assume what
1045
   is there is valid if data is NULL */
1046
static int __buf_push(struct confq *q, u_char *data, char *label)
1047
{
1048
	int oldinbuf = q->inbuf;
1049
	if (q->inbuf < 0) {
1050
		return -1;
1051
	}
1052
	if (data)
1053
		/* Copy in the data */
1054
		memcpy(q->buf[q->inbuf], data, DAHDI_CHUNKSIZE);
1055
1056
	/* Advance the inbuf pointer */
1057
	q->inbuf = (q->inbuf + 1) % DAHDI_CB_SIZE;
1058
1059
	if (q->inbuf == q->outbuf) {
1060
		/* No space anymore... */
1061
		q->inbuf = -1;
1062
	}
1063
	/* If they don't think data is ready, let
1064
	   them know it is now */
1065
	if (q->outbuf < 0) {
1066
		q->outbuf = oldinbuf;
1067
	}
1068
	return 0;
1069
}
1070
1071
static void reset_conf(struct dahdi_chan *chan)
1072
{
1073
	int x;
1074
1075
	/* Empty out buffers and reset to initialization */
1076
1077
	for (x = 0; x < DAHDI_CB_SIZE; x++)
1078
		chan->confin.buf[x] = chan->confin.buffer + DAHDI_CHUNKSIZE * x;
1079
1080
	chan->confin.inbuf = 0;
1081
	chan->confin.outbuf = -1;
1082
1083
	for (x = 0; x < DAHDI_CB_SIZE; x++)
1084
		chan->confout.buf[x] = chan->confout.buffer + DAHDI_CHUNKSIZE * x;
1085
1086
	chan->confout.inbuf = 0;
1087
	chan->confout.outbuf = -1;
1088
}
1089
1090
1091
static const struct dahdi_echocan_factory *find_echocan(const char *name)
1092
{
1093
	struct ecfactory *cur;
1094
	char name_upper[strlen(name) + 1];
1095
	char *c;
1096
	const char *d;
1097
	char modname_buf[128] = "dahdi_echocan_";
1098
	unsigned int tried_once = 0;
1099
1100
	for (c = name_upper, d = name; *d; c++, d++) {
1101
		*c = toupper(*d);
1102
	}
1103
1104
	*c = '\0';
1105
1106
retry:
1107
	read_lock(&ecfactory_list_lock);
1108
1109
	list_for_each_entry(cur, &ecfactory_list, list) {
1110
		if (!strcmp(name_upper, cur->ec->name)) {
1111
#ifdef USE_ECHOCAN_REFCOUNT
1112
			if (try_module_get(cur->owner)) {
1113
				read_unlock(&ecfactory_list_lock);
1114
				return cur->ec;
1115
			} else {
1116
				read_unlock(&ecfactory_list_lock);
1117
				return NULL;
1118
			}
1119
#else
1120
			read_unlock(&ecfactory_list_lock);
1121
			return cur->ec;
1122
#endif
1123
		}
1124
	}
1125
1126
	read_unlock(&ecfactory_list_lock);
1127
1128
	if (tried_once) {
1129
		return NULL;
1130
	}
1131
1132
	/* couldn't find it, let's try to load it */
1133
1134
	for (c = &modname_buf[strlen(modname_buf)], d = name; *d; c++, d++) {
1135
		*c = tolower(*d);
1136
	}
1137
1138
	request_module("%s", modname_buf);
1139
1140
	tried_once = 1;
1141
1142
	/* and try one more time */
1143
	goto retry;
1144
}
1145
1146
static void release_echocan(const struct dahdi_echocan_factory *ec)
1147
{
1148
#ifdef USE_ECHOCAN_REFCOUNT
1149
	if (ec)
1150
		module_put(ec->owner);
1151
#endif
1152
}
1153
1154
/** 
1155
 * close_channel - close the channel, resetting any channel variables
1156
 * @chan: the dahdi_chan to close
1157
 *
1158
 * This function might be called before the channel is placed on the global
1159
 * array of channels, (chans), and therefore, neither this function nor it's
1160
 * children should depend on the dahdi_chan.channo member which is not set yet.
1161
 */
1162
static void close_channel(struct dahdi_chan *chan)
1163
{
1164
	unsigned long flags;
1165
	void *rxgain = NULL;
1166
	struct dahdi_echocan_state *ec_state;
1167
	const struct dahdi_echocan_factory *ec_current;
1168
	int oldconf;
1169
	short *readchunkpreec;
1170
#ifdef CONFIG_DAHDI_PPP
1171
	struct ppp_channel *ppp;
1172
#endif
1173
1174
	might_sleep();
1175
1176
	/* XXX Buffers should be send out before reallocation!!! XXX */
1177
	if (!(chan->flags & DAHDI_FLAG_NOSTDTXRX))
1178
		dahdi_reallocbufs(chan, 0, 0);
1179
	spin_lock_irqsave(&chan->lock, flags);
1180
#ifdef CONFIG_DAHDI_PPP
1181
	ppp = chan->ppp;
1182
	chan->ppp = NULL;
1183
#endif
1184
	ec_state = chan->ec_state;
1185
	chan->ec_state = NULL;
1186
	ec_current = chan->ec_current;
1187
	chan->ec_current = NULL;
1188
	readchunkpreec = chan->readchunkpreec;
1189
	chan->readchunkpreec = NULL;
1190
	chan->curtone = NULL;
1191
	if (chan->curzone)
1192
		atomic_dec(&chan->curzone->refcount);
1193
	chan->curzone = NULL;
1194
	chan->cadencepos = 0;
1195
	chan->pdialcount = 0;
1196
	dahdi_hangup(chan);
1197
	chan->itimerset = chan->itimer = 0;
1198
	chan->pulsecount = 0;
1199
	chan->pulsetimer = 0;
1200
	chan->ringdebtimer = 0;
1201
	init_waitqueue_head(&chan->sel);
1202
	init_waitqueue_head(&chan->readbufq);
1203
	init_waitqueue_head(&chan->writebufq);
1204
	init_waitqueue_head(&chan->eventbufq);
1205
	init_waitqueue_head(&chan->txstateq);
1206
	chan->txdialbuf[0] = '\0';
1207
	chan->digitmode = DIGIT_MODE_DTMF;
1208
	chan->dialing = 0;
1209
	chan->afterdialingtimer = 0;
1210
	  /* initialize IO MUX mask */
1211
	chan->iomask = 0;
1212
	/* save old conf number, if any */
1213
	oldconf = chan->confna;
1214
	  /* initialize conference variables */
1215
	chan->_confn = 0;
1216
	if ((chan->sig & __DAHDI_SIG_DACS) != __DAHDI_SIG_DACS) {
1217
		chan->confna = 0;
1218
		chan->confmode = 0;
1219
	}
1220
	chan->confmute = 0;
1221
	/* release conference resource, if any to release */
1222
	if (oldconf) dahdi_check_conf(oldconf);
1223
	chan->gotgs = 0;
1224
	reset_conf(chan);
1225
1226
	if (chan->gainalloc && chan->rxgain)
1227
		rxgain = chan->rxgain;
1228
1229
	chan->rxgain = defgain;
1230
	chan->txgain = defgain;
1231
	chan->gainalloc = 0;
1232
	chan->eventinidx = chan->eventoutidx = 0;
1233
	chan->flags &= ~(DAHDI_FLAG_LOOPED | DAHDI_FLAG_LINEAR | DAHDI_FLAG_PPP | DAHDI_FLAG_SIGFREEZE);
1234
1235
	dahdi_set_law(chan,0);
1236
1237
	memset(chan->conflast, 0, sizeof(chan->conflast));
1238
	memset(chan->conflast1, 0, sizeof(chan->conflast1));
1239
	memset(chan->conflast2, 0, sizeof(chan->conflast2));
1240
1241
	if (chan->span && chan->span->dacs && oldconf)
1242
		chan->span->dacs(chan, NULL);
1243
1244
	if (ec_state) {
1245
		ec_state->ops->echocan_free(chan, ec_state);
1246
		release_echocan(ec_current);
1247
	}
1248
1249
	spin_unlock_irqrestore(&chan->lock, flags);
1250
1251
	if (rxgain)
1252
		kfree(rxgain);
1253
	if (readchunkpreec)
1254
		kfree(readchunkpreec);
1255
1256
#ifdef CONFIG_DAHDI_PPP
1257
	if (ppp) {
1258
		tasklet_kill(&chan->ppp_calls);
1259
		skb_queue_purge(&chan->ppp_rq);
1260
		ppp_unregister_channel(ppp);
1261
		kfree(ppp);
1262
	}
1263
#endif
1264
1265
}
1266
1267
static int free_tone_zone(int num)
1268
{
1269
	struct dahdi_zone *z = NULL;
1270
	int res = 0;
1271
1272
	if ((num >= DAHDI_TONE_ZONE_MAX) || (num < 0))
1273
		return -EINVAL;
1274
1275
	write_lock(&zone_lock);
1276
	if (tone_zones[num]) {
1277
		if (!atomic_read(&tone_zones[num]->refcount)) {
1278
			z = tone_zones[num];
1279
			tone_zones[num] = NULL;
1280
		} else {
1281
			res = -EBUSY;
1282
		}
1283
	}
1284
	write_unlock(&zone_lock);
1285
1286
	if (z)
1287
		kfree(z);
1288
1289
	return res;
1290
}
1291
1292
static int dahdi_register_tone_zone(int num, struct dahdi_zone *zone)
1293
{
1294
	int res = 0;
1295
1296
	if ((num >= DAHDI_TONE_ZONE_MAX) || (num < 0))
1297
		return -EINVAL;
1298
1299
	write_lock(&zone_lock);
1300
	if (tone_zones[num]) {
1301
		res = -EINVAL;
1302
	} else {
1303
		res = 0;
1304
		tone_zones[num] = zone;
1305
	}
1306
	write_unlock(&zone_lock);
1307
1308
	if (!res)
1309
		module_printk(KERN_INFO, "Registered tone zone %d (%s)\n", num, zone->name);
1310
1311
	return res;
1312
}
1313
1314
static int start_tone_digit(struct dahdi_chan *chan, int tone)
1315
{
1316
	struct dahdi_tone *playtone = NULL;
1317
	int base, max;
1318
1319
	if (!chan->curzone)
1320
		return -ENODATA;
1321
1322
	switch (chan->digitmode) {
1323
	case DIGIT_MODE_DTMF:
1324
		/* Set dialing so that a dial operation doesn't interrupt this tone */
1325
		chan->dialing = 1;
1326
		base = DAHDI_TONE_DTMF_BASE;
1327
		max = DAHDI_TONE_DTMF_MAX;
1328
		break;
1329
	case DIGIT_MODE_MFR2_FWD:
1330
		base = DAHDI_TONE_MFR2_FWD_BASE;
1331
		max = DAHDI_TONE_MFR2_FWD_MAX;
1332
		break;
1333
	case DIGIT_MODE_MFR2_REV:
1334
		base = DAHDI_TONE_MFR2_REV_BASE;
1335
		max = DAHDI_TONE_MFR2_REV_MAX;
1336
		break;
1337
	default:
1338
		return -EINVAL;
1339
	}
1340
1341
	if ((tone < base) || (tone > max))
1342
		return -EINVAL;
1343
1344
	switch (chan->digitmode) {
1345
	case DIGIT_MODE_DTMF:
1346
		playtone = &chan->curzone->dtmf_continuous[tone - base];
1347
		break;
1348
	case DIGIT_MODE_MFR2_FWD:
1349
		playtone = &chan->curzone->mfr2_fwd_continuous[tone - base];
1350
		break;
1351
	case DIGIT_MODE_MFR2_REV:
1352
		playtone = &chan->curzone->mfr2_rev_continuous[tone - base];
1353
		break;
1354
	}
1355
1356
	if (!playtone || !playtone->tonesamples)
1357
		return -ENOSYS;
1358
1359
	chan->curtone = playtone;
1360
1361
	return 0;
1362
}
1363
1364
static int start_tone(struct dahdi_chan *chan, int tone)
1365
{
1366
	int res = -EINVAL;
1367
1368
	/* Stop the current tone, no matter what */
1369
	chan->tonep = 0;
1370
	chan->curtone = NULL;
1371
	chan->pdialcount = 0;
1372
	chan->txdialbuf[0] = '\0';
1373
	chan->dialing = 0;
1374
1375
	if (tone == -1) {
1376
		/* Just stop the current tone */
1377
		res = 0;
1378
	} else if (!chan->curzone) {
1379
		static int __warnonce = 1;
1380
		if (__warnonce) {
1381
			__warnonce = 0;
1382
			/* The tonezones are loaded by dahdi_cfg based on /etc/dahdi/system.conf. */
1383
			module_printk(KERN_WARNING, "DAHDI: Cannot start tones until tone zone is loaded.\n");
1384
		}
1385
		/* Note that no tone zone exists at the moment */
1386
		res = -ENODATA;
1387
	} else if ((tone >= 0 && tone <= DAHDI_TONE_MAX)) {
1388
		/* Have a tone zone */
1389
		if (chan->curzone->tones[tone]) {
1390
			chan->curtone = chan->curzone->tones[tone];
1391
			res = 0;
1392
		} else { /* Indicate that zone is loaded but no such tone exists */
1393
			res = -ENOSYS;
1394
		}
1395
	} else if (chan->digitmode == DIGIT_MODE_DTMF ||
1396
			chan->digitmode == DIGIT_MODE_MFR2_FWD ||
1397
			chan->digitmode == DIGIT_MODE_MFR2_REV) {
1398
		res = start_tone_digit(chan, tone);
1399
	} else {
1400
		chan->dialing = 0;
1401
		res = -EINVAL;
1402
	}
1403
1404
	if (chan->curtone)
1405
		dahdi_init_tone_state(&chan->ts, chan->curtone);
1406
1407
	return res;
1408
}
1409
1410
static int set_tone_zone(struct dahdi_chan *chan, int zone)
1411
{
1412
	int res = 0;
1413
	struct dahdi_zone *z;
1414
1415
	/* Do not call with the channel locked. */
1416
1417
	if (zone == -1)
1418
		zone = default_zone;
1419
1420
	if ((zone >= DAHDI_TONE_ZONE_MAX) || (zone < 0))
1421
		return -EINVAL;
1422
1423
	read_lock(&zone_lock);
1424
1425
	if ((z = tone_zones[zone])) {
1426
		unsigned long flags;
1427
1428
		spin_lock_irqsave(&chan->lock, flags);
1429
1430
		if (chan->curzone)
1431
			atomic_dec(&chan->curzone->refcount);
1432
1433
		atomic_inc(&z->refcount);
1434
		chan->curzone = z;
1435
		chan->tonezone = zone;
1436
		memcpy(chan->ringcadence, z->ringcadence, sizeof(chan->ringcadence));
1437
1438
		spin_unlock_irqrestore(&chan->lock, flags);
1439
	} else {
1440
		res = -ENODATA;
1441
	}
1442
1443
	read_unlock(&zone_lock);
1444
1445
	return res;
1446
}
1447
1448
static void dahdi_set_law(struct dahdi_chan *chan, int law)
1449
{
1450
	if (!law) {
1451
		if (chan->deflaw)
1452
			law = chan->deflaw;
1453
		else
1454
			if (chan->span) law = chan->span->deflaw;
1455
			else law = DAHDI_LAW_MULAW;
1456
	}
1457
	if (law == DAHDI_LAW_ALAW) {
1458
		chan->xlaw = __dahdi_alaw;
1459
#ifdef CONFIG_CALC_XLAW
1460
		chan->lineartoxlaw = __dahdi_lineartoalaw;
1461
#else
1462
		chan->lin2x = __dahdi_lin2a;
1463
#endif
1464
	} else {
1465
		chan->xlaw = __dahdi_mulaw;
1466
#ifdef CONFIG_CALC_XLAW
1467
		chan->lineartoxlaw = __dahdi_lineartoulaw;
1468
#else
1469
		chan->lin2x = __dahdi_lin2mu;
1470
#endif
1471
	}
1472
}
1473
1474
static int dahdi_chan_reg(struct dahdi_chan *chan)
1475
{
1476
	int x;
1477
	unsigned long flags;
1478
1479
	might_sleep();
1480
1481
	spin_lock_init(&chan->lock);
1482
	if (!chan->master)
1483
		chan->master = chan;
1484
	if (!chan->readchunk)
1485
		chan->readchunk = chan->sreadchunk;
1486
	if (!chan->writechunk)
1487
		chan->writechunk = chan->swritechunk;
1488
	dahdi_set_law(chan, 0);
1489
	close_channel(chan);
1490
1491
	write_lock_irqsave(&chan_lock, flags);
1492
	for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
1493
		if (chans[x])
1494
			continue;
1495
1496
		chans[x] = chan;
1497
		if (maxchans < x + 1)
1498
			maxchans = x + 1;
1499
		chan->channo = x;
1500
		write_unlock_irqrestore(&chan_lock, flags);
1501
		/* set this AFTER running close_channel() so that
1502
		   HDLC channels wont cause hangage */
1503
		set_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags);
1504
		break;
1505
	}
1506
1507
	if (DAHDI_MAX_CHANNELS == x) {
1508
		write_unlock_irqrestore(&chan_lock, flags);
1509
		module_printk(KERN_ERR, "No more channels available\n");
1510
		return -ENOMEM;
1511
	}
1512
1513
	return 0;
1514
}
1515
1516
char *dahdi_lboname(int x)
1517
{
1518
	if ((x < 0) || (x > 7))
1519
		return "Unknown";
1520
	return dahdi_txlevelnames[x];
1521
}
1522
1523
#if defined(CONFIG_DAHDI_NET) || defined(CONFIG_DAHDI_PPP)
1524
static inline void print_debug_writebuf(struct dahdi_chan* ss, struct sk_buff *skb, int oldbuf)
1525
{
1526
#ifdef CONFIG_DAHDI_DEBUG
1527
	int x;
1528
1529
	module_printk(KERN_NOTICE, "Buffered %d bytes to go out in buffer %d\n", ss->writen[oldbuf], oldbuf);
1530
	module_printk(KERN_DEBUG "");
1531
	for (x=0;x<ss->writen[oldbuf];x++)
1532
		printk("%02x ", ss->writebuf[oldbuf][x]);
1533
	printk("\n");
1534
#endif
1535
}
1536
#endif
1537
1538
#ifdef CONFIG_DAHDI_NET
1539
#ifdef NEW_HDLC_INTERFACE
1540
static int dahdi_net_open(struct net_device *dev)
1541
{
1542
	int res = hdlc_open(dev);
1543
	struct dahdi_chan *ms = dev_to_ztchan(dev);
1544
1545
/*	if (!dev->hard_start_xmit) return res; is this really necessary? --byg */
1546
	if (res) /* this is necessary to avoid kernel panic when UNSPEC link encap, proven --byg */
1547
		return res;
1548
#else
1549
static int dahdi_net_open(hdlc_device *hdlc)
1550
{
1551
	struct dahdi_chan *ms = hdlc_to_ztchan(hdlc);
1552
	int res;
1553
#endif
1554
	if (!ms) {
1555
		module_printk(KERN_NOTICE, "dahdi_net_open: nothing??\n");
1556
		return -EINVAL;
1557
	}
1558
	if (test_bit(DAHDI_FLAGBIT_OPEN, &ms->flags)) {
1559
		module_printk(KERN_NOTICE, "%s is already open!\n", ms->name);
1560
		return -EBUSY;
1561
	}
1562
	if (!(ms->flags & DAHDI_FLAG_NETDEV)) {
1563
		module_printk(KERN_NOTICE, "%s is not a net device!\n", ms->name);
1564
		return -EINVAL;
1565
	}
1566
	ms->txbufpolicy = DAHDI_POLICY_IMMEDIATE;
1567
	ms->rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
1568
1569
	res = dahdi_reallocbufs(ms, DAHDI_DEFAULT_MTU_MRU, DAHDI_DEFAULT_NUM_BUFS);
1570
	if (res)
1571
		return res;
1572
1573
	fasthdlc_init(&ms->rxhdlc, (ms->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
1574
	fasthdlc_init(&ms->txhdlc, (ms->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
1575
	ms->infcs = PPP_INITFCS;
1576
1577
	netif_start_queue(ztchan_to_dev(ms));
1578
1579
#ifdef CONFIG_DAHDI_DEBUG
1580
	module_printk(KERN_NOTICE, "DAHDINET: Opened channel %d name %s\n", ms->channo, ms->name);
1581
#endif
1582
	return 0;
1583
}
1584
1585
static int dahdi_register_hdlc_device(struct net_device *dev, const char *dev_name)
1586
{
1587
	int result;
1588
1589
	if (dev_name && *dev_name) {
1590
		if ((result = dev_alloc_name(dev, dev_name)) < 0)
1591
			return result;
1592
	}
1593
	result = register_netdev(dev);
1594
	if (result != 0)
1595
		return -EIO;
1596
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,14)
1597
	if (netif_carrier_ok(dev))
1598
		netif_carrier_off(dev); /* no carrier until DCD goes up */
1599
#endif
1600
	return 0;
1601
}
1602
1603
#ifdef NEW_HDLC_INTERFACE
1604
static int dahdi_net_stop(struct net_device *dev)
1605
{
1606
    hdlc_device *h = dev_to_hdlc(dev);
1607
    struct dahdi_hdlc *hdlc = h->priv;
1608
1609
#else
1610
static void dahdi_net_close(hdlc_device *hdlc)
1611
{
1612
#endif
1613
	struct dahdi_chan *ms = hdlc_to_ztchan(hdlc);
1614
	if (!ms) {
1615
#ifdef NEW_HDLC_INTERFACE
1616
		module_printk(KERN_NOTICE, "dahdi_net_stop: nothing??\n");
1617
		return 0;
1618
#else
1619
		module_printk(KERN_NOTICE, "dahdi_net_close: nothing??\n");
1620
		return;
1621
#endif
1622
	}
1623
	if (!(ms->flags & DAHDI_FLAG_NETDEV)) {
1624
#ifdef NEW_HDLC_INTERFACE
1625
		module_printk(KERN_NOTICE, "dahdi_net_stop: %s is not a net device!\n", ms->name);
1626
		return 0;
1627
#else
1628
		module_printk(KERN_NOTICE, "dahdi_net_close: %s is not a net device!\n", ms->name);
1629
		return;
1630
#endif
1631
	}
1632
	/* Not much to do here.  Just deallocate the buffers */
1633
        netif_stop_queue(ztchan_to_dev(ms));
1634
	dahdi_reallocbufs(ms, 0, 0);
1635
	hdlc_close(dev);
1636
#ifdef NEW_HDLC_INTERFACE
1637
	return 0;
1638
#else
1639
	return;
1640
#endif
1641
}
1642
1643
#ifdef NEW_HDLC_INTERFACE
1644
/* kernel 2.4.20+ has introduced attach function, dunno what to do,
1645
 just copy sources from dscc4 to be sure and ready for further mastering,
1646
 NOOP right now (i.e. really a stub)  --byg */
1647
static int dahdi_net_attach(struct net_device *dev, unsigned short encoding,
1648
        unsigned short parity)
1649
{
1650
/*        struct net_device *dev = hdlc_to_dev(hdlc);
1651
        struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
1652
1653
        if (encoding != ENCODING_NRZ &&
1654
            encoding != ENCODING_NRZI &&
1655
            encoding != ENCODING_FM_MARK &&
1656
            encoding != ENCODING_FM_SPACE &&
1657
            encoding != ENCODING_MANCHESTER)
1658
                return -EINVAL;
1659
1660
        if (parity != PARITY_NONE &&
1661
            parity != PARITY_CRC16_PR0_CCITT &&
1662
            parity != PARITY_CRC16_PR1_CCITT &&
1663
            parity != PARITY_CRC32_PR0_CCITT &&
1664
            parity != PARITY_CRC32_PR1_CCITT)
1665
                return -EINVAL;
1666
1667
        dpriv->encoding = encoding;
1668
        dpriv->parity = parity;*/
1669
        return 0;
1670
}
1671
#endif
1672
1673
static struct dahdi_hdlc *dahdi_hdlc_alloc(void)
1674
{
1675
	return kzalloc(sizeof(struct dahdi_hdlc), GFP_KERNEL);
1676
}
1677
1678
#ifdef NEW_HDLC_INTERFACE
1679
static int dahdi_xmit(struct sk_buff *skb, struct net_device *dev)
1680
{
1681
	/* FIXME: this construction seems to be not very optimal for me but I could find nothing better at the moment (Friday, 10PM :( )  --byg */
1682
/*	struct dahdi_chan *ss = hdlc_to_ztchan(list_entry(dev, struct dahdi_hdlc, netdev.netdev));*/
1683
	struct dahdi_chan *ss = dev_to_ztchan(dev);
1684
	struct net_device_stats *stats = hdlc_stats(dev);
1685
1686
#else
1687
static int dahdi_xmit(hdlc_device *hdlc, struct sk_buff *skb)
1688
{
1689
	struct dahdi_chan *ss = hdlc_to_ztchan(hdlc);
1690
	struct net_device *dev = &ss->hdlcnetdev->netdev.netdev;
1691
	struct net_device_stats *stats = &ss->hdlcnetdev->netdev.stats;
1692
#endif
1693
	int retval = 1;
1694
	int x,oldbuf;
1695
	unsigned int fcs;
1696
	unsigned char *data;
1697
	unsigned long flags;
1698
	/* See if we have any buffers */
1699
	spin_lock_irqsave(&ss->lock, flags);
1700
	if (skb->len > ss->blocksize - 2) {
1701
		module_printk(KERN_ERR, "dahdi_xmit(%s): skb is too large (%d > %d)\n", dev->name, skb->len, ss->blocksize -2);
1702
		stats->tx_dropped++;
1703
		retval = 0;
1704
	} else if (ss->inwritebuf >= 0) {
1705
		/* We have a place to put this packet */
1706
		/* XXX We should keep the SKB and avoid the memcpy XXX */
1707
		data = ss->writebuf[ss->inwritebuf];
1708
		memcpy(data, skb->data, skb->len);
1709
		ss->writen[ss->inwritebuf] = skb->len;
1710
		ss->writeidx[ss->inwritebuf] = 0;
1711
		/* Calculate the FCS */
1712
		fcs = PPP_INITFCS;
1713
		for (x=0;x<skb->len;x++)
1714
			fcs = PPP_FCS(fcs, data[x]);
1715
		/* Invert it */
1716
		fcs ^= 0xffff;
1717
		/* Send it out LSB first */
1718
		data[ss->writen[ss->inwritebuf]++] = (fcs & 0xff);
1719
		data[ss->writen[ss->inwritebuf]++] = (fcs >> 8) & 0xff;
1720
		/* Advance to next window */
1721
		oldbuf = ss->inwritebuf;
1722
		ss->inwritebuf = (ss->inwritebuf + 1) % ss->numbufs;
1723
1724
		if (ss->inwritebuf == ss->outwritebuf) {
1725
			/* Whoops, no more space.  */
1726
		    ss->inwritebuf = -1;
1727
1728
		    netif_stop_queue(ztchan_to_dev(ss));
1729
		}
1730
		if (ss->outwritebuf < 0) {
1731
			/* Let the interrupt handler know there's
1732
			   some space for us */
1733
			ss->outwritebuf = oldbuf;
1734
		}
1735
		dev->trans_start = jiffies;
1736
		stats->tx_packets++;
1737
		stats->tx_bytes += ss->writen[oldbuf];
1738
		print_debug_writebuf(ss, skb, oldbuf);
1739
		retval = 0;
1740
		/* Free the SKB */
1741
		dev_kfree_skb_any(skb);
1742
	}
1743
	spin_unlock_irqrestore(&ss->lock, flags);
1744
	return retval;
1745
}
1746
1747
#ifdef NEW_HDLC_INTERFACE
1748
static int dahdi_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1749
{
1750
	return hdlc_ioctl(dev, ifr, cmd);
1751
}
1752
#else
1753
static int dahdi_net_ioctl(hdlc_device *hdlc, struct ifreq *ifr, int cmd)
1754
{
1755
	return -EIO;
1756
}
1757
#endif
1758
1759
#endif
1760
1761
#ifdef CONFIG_DAHDI_PPP
1762
1763
static int dahdi_ppp_xmit(struct ppp_channel *ppp, struct sk_buff *skb)
1764
{
1765
1766
	/*
1767
	 * If we can't handle the packet right now, return 0.  If we
1768
	 * we handle or drop it, return 1.  Always free if we return
1769
	 * 1 and never if we return 0
1770
         */
1771
	struct dahdi_chan *ss = ppp->private;
1772
	int x,oldbuf;
1773
	unsigned int fcs;
1774
	unsigned char *data;
1775
	unsigned long flags;
1776
	int retval = 0;
1777
1778
	/* See if we have any buffers */
1779
	spin_lock_irqsave(&ss->lock, flags);
1780
	if (!(test_bit(DAHDI_FLAGBIT_OPEN, &ss->flags))) {
1781
		module_printk(KERN_ERR, "Can't transmit on closed channel\n");
1782
		retval = 1;
1783
	} else if (skb->len > ss->blocksize - 4) {
1784
		module_printk(KERN_ERR, "dahdi_ppp_xmit(%s): skb is too large (%d > %d)\n", ss->name, skb->len, ss->blocksize -2);
1785
		retval = 1;
1786
	} else if (ss->inwritebuf >= 0) {
1787
		/* We have a place to put this packet */
1788
		/* XXX We should keep the SKB and avoid the memcpy XXX */
1789
		data = ss->writebuf[ss->inwritebuf];
1790
		/* Start with header of two bytes */
1791
		/* Add "ALL STATIONS" and "UNNUMBERED" */
1792
		data[0] = 0xff;
1793
		data[1] = 0x03;
1794
		ss->writen[ss->inwritebuf] = 2;
1795
1796
		/* Copy real data and increment amount written */
1797
		memcpy(data + 2, skb->data, skb->len);
1798
1799
		ss->writen[ss->inwritebuf] += skb->len;
1800
1801
		/* Re-set index back to zero */
1802
		ss->writeidx[ss->inwritebuf] = 0;
1803
1804
		/* Calculate the FCS */
1805
		fcs = PPP_INITFCS;
1806
		for (x=0;x<skb->len + 2;x++)
1807
			fcs = PPP_FCS(fcs, data[x]);
1808
		/* Invert it */
1809
		fcs ^= 0xffff;
1810
1811
		/* Point past the real data now */
1812
		data += (skb->len + 2);
1813
1814
		/* Send FCS out LSB first */
1815
		data[0] = (fcs & 0xff);
1816
		data[1] = (fcs >> 8) & 0xff;
1817
1818
		/* Account for FCS length */
1819
		ss->writen[ss->inwritebuf]+=2;
1820
1821
		/* Advance to next window */
1822
		oldbuf = ss->inwritebuf;
1823
		ss->inwritebuf = (ss->inwritebuf + 1) % ss->numbufs;
1824
1825
		if (ss->inwritebuf == ss->outwritebuf) {
1826
			/* Whoops, no more space.  */
1827
			ss->inwritebuf = -1;
1828
		}
1829
		if (ss->outwritebuf < 0) {
1830
			/* Let the interrupt handler know there's
1831
			   some space for us */
1832
			ss->outwritebuf = oldbuf;
1833
		}
1834
		print_debug_writebuf(ss, skb, oldbuf);
1835
		retval = 1;
1836
	}
1837
	spin_unlock_irqrestore(&ss->lock, flags);
1838
	if (retval) {
1839
		/* Get rid of the SKB if we're returning non-zero */
1840
		/* N.B. this is called in process or BH context so
1841
		   dev_kfree_skb is OK. */
1842
		dev_kfree_skb(skb);
1843
	}
1844
	return retval;
1845
}
1846
1847
static int dahdi_ppp_ioctl(struct ppp_channel *ppp, unsigned int cmd, unsigned long flags)
1848
{
1849
	return -EIO;
1850
}
1851
1852
static struct ppp_channel_ops ztppp_ops =
1853
{
1854
	.start_xmit = dahdi_ppp_xmit,
1855
	.ioctl      = dahdi_ppp_ioctl,
1856
};
1857
1858
#endif
1859
1860
static void dahdi_chan_unreg(struct dahdi_chan *chan)
1861
{
1862
	int x;
1863
	unsigned long flags;
1864
1865
	might_sleep();
1866
1867
#ifdef CONFIG_DAHDI_NET
1868
	if (chan->flags & DAHDI_FLAG_NETDEV) {
1869
		unregister_hdlc_device(chan->hdlcnetdev->netdev);
1870
		free_netdev(chan->hdlcnetdev->netdev);
1871
		kfree(chan->hdlcnetdev);
1872
		chan->hdlcnetdev = NULL;
1873
	}
1874
#endif
1875
	write_lock_irqsave(&chan_lock, flags);
1876
	if (test_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags)) {
1877
		chans[chan->channo] = NULL;
1878
		clear_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags);
1879
	}
1880
#ifdef CONFIG_DAHDI_PPP
1881
	if (chan->ppp) {
1882
		module_printk(KERN_NOTICE, "HUH???  PPP still attached??\n");
1883
	}
1884
#endif
1885
	maxchans = 0;
1886
	for (x=1;x<DAHDI_MAX_CHANNELS;x++)
1887
		if (chans[x]) {
1888
			maxchans = x + 1;
1889
			/* Remove anyone pointing to us as master
1890
			   and make them their own thing */
1891
			if (chans[x]->master == chan) {
1892
				chans[x]->master = chans[x];
1893
			}
1894
			if ((chans[x]->confna == chan->channo) &&
1895
				((chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR ||
1896
				(chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORTX ||
1897
				(chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH ||
1898
				(chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_RX_PREECHO ||
1899
				(chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_TX_PREECHO ||
1900
				(chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH_PREECHO ||
1901
				(chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_DIGITALMON)) {
1902
				/* Take them out of conference with us */
1903
				/* release conference resource if any */
1904
				if (chans[x]->confna) {
1905
					dahdi_check_conf(chans[x]->confna);
1906
					if (chans[x]->span && chans[x]->span->dacs)
1907
						chans[x]->span->dacs(chans[x], NULL);
1908
				}
1909
				chans[x]->confna = 0;
1910
				chans[x]->_confn = 0;
1911
				chans[x]->confmode = 0;
1912
			}
1913
		}
1914
	chan->channo = -1;
1915
	write_unlock_irqrestore(&chan_lock, flags);
1916
}
1917
1918
static ssize_t dahdi_chan_read(struct file *file, char *usrbuf, size_t count, int unit)
1919
{
1920
	struct dahdi_chan *chan = chans[unit];
1921
	int amnt;
1922
	int res, rv;
1923
	int oldbuf,x;
1924
	unsigned long flags;
1925
1926
	/* Make sure count never exceeds 65k, and make sure it's unsigned */
1927
	count &= 0xffff;
1928
1929
	if (!chan)
1930
		return -EINVAL;
1931
1932
	if (count < 1)
1933
		return -EINVAL;
1934
1935
	for (;;) {
1936
		spin_lock_irqsave(&chan->lock, flags);
1937
		if (chan->eventinidx != chan->eventoutidx) {
1938
			spin_unlock_irqrestore(&chan->lock, flags);
1939
			return -ELAST /* - chan->eventbuf[chan->eventoutidx]*/;
1940
		}
1941
		res = chan->outreadbuf;
1942
		if (chan->rxdisable)
1943
			res = -1;
1944
		spin_unlock_irqrestore(&chan->lock, flags);
1945
		if (res >= 0)
1946
			break;
1947
		if (file->f_flags & O_NONBLOCK)
1948
			return -EAGAIN;
1949
		rv = schluffen(&chan->readbufq);
1950
		if (rv)
1951
			return rv;
1952
	}
1953
	amnt = count;
1954
/* added */
1955
#if 0
1956
	if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) {
1957
		int myamnt = amnt;
1958
		int x;
1959
		if (amnt > chan->readn[res])
1960
			myamnt = chan->readn[res];
1961
		module_printk(KERN_NOTICE, "dahdi_chan_read(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n",
1962
			      unit, chan->inwritebuf, chan->outwritebuf, myamnt);
1963
1964
		module_printk(KERN_DEBUG, "\t("); 
1965
		for (x = 0; x < myamnt; x++) 
1966
			printk((x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]);
1967
		printk(")\n");
1968
	}
1969
#endif
1970
/* end addition */
1971
	if (chan->flags & DAHDI_FLAG_LINEAR) {
1972
		if (amnt > (chan->readn[res] << 1))
1973
			amnt = chan->readn[res] << 1;
1974
		if (amnt) {
1975
			/* There seems to be a max stack size, so we have
1976
			   to do this in smaller pieces */
1977
			short lindata[128];
1978
			int left = amnt >> 1; /* amnt is in bytes */
1979
			int pos = 0;
1980
			int pass;
1981
			while (left) {
1982
				pass = left;
1983
				if (pass > 128)
1984
					pass = 128;
1985
				for (x = 0; x < pass; x++)
1986
					lindata[x] = DAHDI_XLAW(chan->readbuf[res][x + pos], chan);
1987
				if (copy_to_user(usrbuf + (pos << 1), lindata, pass << 1))
1988
					return -EFAULT;
1989
				left -= pass;
1990
				pos += pass;
1991
			}
1992
		}
1993
	} else {
1994
		if (amnt > chan->readn[res])
1995
			amnt = chan->readn[res];
1996
		if (amnt) {
1997
			if (copy_to_user(usrbuf, chan->readbuf[res], amnt))
1998
				return -EFAULT;
1999
		}
2000
	}
2001
	spin_lock_irqsave(&chan->lock, flags);
2002
	chan->readidx[res] = 0;
2003
	chan->readn[res] = 0;
2004
	oldbuf = res;
2005
	chan->outreadbuf = (res + 1) % chan->numbufs;
2006
	if (chan->outreadbuf == chan->inreadbuf) {
2007
		/* Out of stuff */
2008
		chan->outreadbuf = -1;
2009
		if (chan->rxbufpolicy == DAHDI_POLICY_WHEN_FULL)
2010
			chan->rxdisable = 1;
2011
	}
2012
	if (chan->inreadbuf < 0) {
2013
		/* Notify interrupt handler that we have some space now */
2014
		chan->inreadbuf = oldbuf;
2015
	}
2016
	spin_unlock_irqrestore(&chan->lock, flags);
2017
2018
	return amnt;
2019
}
2020
2021
static int num_filled_bufs(struct dahdi_chan *chan)
2022
{
2023
	int range1, range2;
2024
2025
	if (chan->inwritebuf < 0) {
2026
		return chan->numbufs;
2027
	}
2028
2029
	if (chan->outwritebuf < 0) {
2030
		return 0;
2031
	}
2032
2033
	if (chan->outwritebuf <= chan->inwritebuf) {
2034
		return chan->inwritebuf - chan->outwritebuf;
2035
	}
2036
2037
	/* This means (in > out) and we have wrap around */
2038
	range1 = chan->numbufs - chan->outwritebuf;
2039
	range2 = chan->inwritebuf;
2040
2041
	return range1 + range2;
2042
}
2043
2044
static ssize_t dahdi_chan_write(struct file *file, const char *usrbuf, size_t count, int unit)
2045
{
2046
	unsigned long flags;
2047
	struct dahdi_chan *chan = chans[unit];
2048
	int res, amnt, oldbuf, rv, x;
2049
2050
	/* Make sure count never exceeds 65k, and make sure it's unsigned */
2051
	count &= 0xffff;
2052
2053
	if (!chan)
2054
		return -EINVAL;
2055
2056
	if (count < 1) {
2057
		return -EINVAL;
2058
	}
2059
2060
	for (;;) {
2061
		spin_lock_irqsave(&chan->lock, flags);
2062
		if ((chan->curtone || chan->pdialcount) && !(chan->flags & DAHDI_FLAG_PSEUDO)) {
2063
			chan->curtone = NULL;
2064
			chan->tonep = 0;
2065
			chan->dialing = 0;
2066
			chan->txdialbuf[0] = '\0';
2067
			chan->pdialcount = 0;
2068
		}
2069
		if (chan->eventinidx != chan->eventoutidx) {
2070
			spin_unlock_irqrestore(&chan->lock, flags);
2071
			return -ELAST;
2072
		}
2073
		res = chan->inwritebuf;
2074
		spin_unlock_irqrestore(&chan->lock, flags);
2075
		if (res >= 0)
2076
			break;
2077
		if (file->f_flags & O_NONBLOCK) {
2078
#ifdef BUFFER_DEBUG
2079
			printk("Error: Nonblock\n");
2080
#endif
2081
			return -EAGAIN;
2082
		}
2083
		/* Wait for something to be available */
2084
		rv = schluffen(&chan->writebufq);
2085
		if (rv) {
2086
			return rv;
2087
		}
2088
	}
2089
2090
	amnt = count;
2091
	if (chan->flags & DAHDI_FLAG_LINEAR) {
2092
		if (amnt > (chan->blocksize << 1))
2093
			amnt = chan->blocksize << 1;
2094
	} else {
2095
		if (amnt > chan->blocksize)
2096
			amnt = chan->blocksize;
2097
	}
2098
2099
#ifdef CONFIG_DAHDI_DEBUG
2100
	module_printk(KERN_NOTICE, "dahdi_chan_write(unit: %d, res: %d, outwritebuf: %d amnt: %d\n",
2101
		      unit, res, chan->outwritebuf, amnt);
2102
#endif
2103
#if 0
2104
 	if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) {
2105
 		int x;
2106
 		module_printk(KERN_NOTICE, "dahdi_chan_write/in(unit: %d, res: %d, outwritebuf: %d amnt: %d, txdisable: %d)\n",
2107
			      unit, res, chan->outwritebuf, amnt, chan->txdisable);
2108
 		module_printk(KERN_DEBUG, "\t("); for (x = 0; x < amnt; x++) module_printk(KERN_DEBUG, (x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]);
2109
 		module_printk(KERN_DEBUG, ")\n");
2110
 	}
2111
#endif
2112
2113
	if (amnt) {
2114
		if (chan->flags & DAHDI_FLAG_LINEAR) {
2115
			/* There seems to be a max stack size, so we have
2116
			   to do this in smaller pieces */
2117
			short lindata[128];
2118
			int left = amnt >> 1; /* amnt is in bytes */
2119
			int pos = 0;
2120
			int pass;
2121
			while (left) {
2122
				pass = left;
2123
				if (pass > 128)
2124
					pass = 128;
2125
				if (copy_from_user(lindata, usrbuf + (pos << 1), pass << 1)) {
2126
					return -EFAULT;
2127
				}
2128
				left -= pass;
2129
				for (x = 0; x < pass; x++)
2130
					chan->writebuf[res][x + pos] = DAHDI_LIN2X(lindata[x], chan);
2131
				pos += pass;
2132
			}
2133
			chan->writen[res] = amnt >> 1;
2134
		} else {
2135
			if (copy_from_user(chan->writebuf[res], usrbuf, amnt)) {
2136
				return -EFAULT;
2137
			}
2138
			chan->writen[res] = amnt;
2139
		}
2140
		chan->writeidx[res] = 0;
2141
		if (chan->flags & DAHDI_FLAG_FCS)
2142
			calc_fcs(chan, res);
2143
		oldbuf = res;
2144
		spin_lock_irqsave(&chan->lock, flags);
2145
		chan->inwritebuf = (res + 1) % chan->numbufs;
2146
2147
		if (chan->inwritebuf == chan->outwritebuf) {
2148
			/* Don't stomp on the transmitter, just wait for them to
2149
			   wake us up */
2150
			chan->inwritebuf = -1;
2151
			/* Make sure the transmitter is transmitting in case of POLICY_WHEN_FULL */
2152
			chan->txdisable = 0;
2153
		}
2154
2155
		if (chan->outwritebuf < 0) {
2156
			/* Okay, the interrupt handler has been waiting for us.  Give them a buffer */
2157
			chan->outwritebuf = oldbuf;
2158
		}
2159
2160
		if ((chan->txbufpolicy == DAHDI_POLICY_HALF_FULL) && (chan->txdisable)) {
2161
			if (num_filled_bufs(chan) >= (chan->numbufs >> 1)) {
2162
#ifdef BUFFER_DEBUG
2163
				printk("Reached buffer fill mark of %d\n", num_filled_bufs(chan));
2164
#endif
2165
				chan->txdisable = 0;
2166
			}
2167
		}
2168
2169
#ifdef BUFFER_DEBUG
2170
		if ((chan->statcount <= 0) || (amnt != 128) || (num_filled_bufs(chan) != chan->lastnumbufs)) {
2171
			printk("amnt: %d Number of filled buffers: %d\n", amnt, num_filled_bufs(chan));
2172
			chan->statcount = 32000;
2173
			chan->lastnumbufs = num_filled_bufs(chan);
2174
		}
2175
#endif
2176
2177
		spin_unlock_irqrestore(&chan->lock, flags);
2178
2179
		if (chan->flags & DAHDI_FLAG_NOSTDTXRX && chan->span->hdlc_hard_xmit)
2180
			chan->span->hdlc_hard_xmit(chan);
2181
	}
2182
	return amnt;
2183
}
2184
2185
static int dahdi_ctl_open(struct inode *inode, struct file *file)
2186
{
2187
	/* Nothing to do, really */
2188
	return 0;
2189
}
2190
2191
static int dahdi_chan_open(struct inode *inode, struct file *file)
2192
{
2193
	/* Nothing to do here for now either */
2194
	return 0;
2195
}
2196
2197
static int dahdi_ctl_release(struct inode *inode, struct file *file)
2198
{
2199
	/* Nothing to do */
2200
	return 0;
2201
}
2202
2203
static int dahdi_chan_release(struct inode *inode, struct file *file)
2204
{
2205
	/* Nothing to do for now */
2206
	return 0;
2207
}
2208
2209
static void set_txtone(struct dahdi_chan *ss, int fac, int init_v2, int init_v3)
2210
{
2211
	if (fac == 0) {
2212
		ss->v2_1 = 0;
2213
		ss->v3_1 = 0;
2214
		return;
2215
	}
2216
	ss->txtone = fac;
2217
	ss->v1_1 = 0;
2218
	ss->v2_1 = init_v2;
2219
	ss->v3_1 = init_v3;
2220
	return;
2221
}
2222
2223
static void dahdi_rbs_sethook(struct dahdi_chan *chan, int txsig, int txstate,
2224
		int timeout)
2225
{
2226
	static const struct {
2227
		unsigned int sig_type;
2228
		/* Index is dahdi_txsig enum */
2229
		unsigned int bits[DAHDI_TXSIG_TOTAL];
2230
	} outs[NUM_SIGS] = {
2231
		{
2232
			/*
2233
			 * We set the idle case of the DAHDI_SIG_NONE to this pattern to make idle E1 CAS
2234
			 * channels happy. Should not matter with T1, since on an un-configured channel,
2235
			 * who cares what the sig bits are as long as they are stable
2236
			 */
2237
			.sig_type = DAHDI_SIG_NONE,
2238
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_BITS_ACD,
2239
		}, {
2240
			.sig_type = DAHDI_SIG_EM,
2241
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD,
2242
			.bits[DAHDI_TXSIG_START]   = DAHDI_BITS_ABCD,
2243
		}, {
2244
			.sig_type = DAHDI_SIG_FXSLS,
2245
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_BITS_BD,
2246
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD,
2247
			.bits[DAHDI_TXSIG_START]   = DAHDI_BITS_ABCD,
2248
		}, {
2249
			.sig_type = DAHDI_SIG_FXSGS,
2250
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_BITS_BD,
2251
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD,
2252
#ifndef CONFIG_CAC_GROUNDSTART
2253
			.bits[DAHDI_TXSIG_START]   = DAHDI_BITS_AC,
2254
#endif
2255
		}, {
2256
			.sig_type = DAHDI_SIG_FXSKS,
2257
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_BITS_BD,
2258
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD,
2259
			.bits[DAHDI_TXSIG_START]   = DAHDI_BITS_ABCD,
2260
		}, {
2261
			.sig_type = DAHDI_SIG_FXOLS,
2262
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_BITS_BD,
2263
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_BD,
2264
		}, {
2265
			.sig_type = DAHDI_SIG_FXOGS,
2266
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_BITS_ABCD,
2267
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_BD,
2268
		}, {
2269
			.sig_type = DAHDI_SIG_FXOKS,
2270
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_BITS_BD,
2271
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_BD,
2272
			.bits[DAHDI_TXSIG_KEWL]    = DAHDI_BITS_ABCD,
2273
		}, {
2274
			.sig_type = DAHDI_SIG_SF,
2275
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_BITS_BCD,
2276
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD,
2277
			.bits[DAHDI_TXSIG_START]   = DAHDI_BITS_ABCD,
2278
			.bits[DAHDI_TXSIG_KEWL]    = DAHDI_BITS_BCD,
2279
		}, {
2280
			.sig_type = DAHDI_SIG_EM_E1,
2281
			.bits[DAHDI_TXSIG_ONHOOK]  = DAHDI_DBIT,
2282
			.bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABD,
2283
			.bits[DAHDI_TXSIG_START]   = DAHDI_BITS_ABD,
2284
			.bits[DAHDI_TXSIG_KEWL]    = DAHDI_DBIT,
2285
		}
2286
	};
2287
	int x;
2288
2289
	/* if no span, return doing nothing */
2290
	if (!chan->span)
2291
		return;
2292
2293
	if (!chan->span->flags & DAHDI_FLAG_RBS) {
2294
		module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state on non-RBS channel %s\n", chan->name);
2295
		return;
2296
	}
2297
	if ((txsig > 3) || (txsig < 0)) {
2298
		module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state %d (> 3) on  channel %s\n", txsig, chan->name);
2299
		return;
2300
	}
2301
	if (!chan->span->rbsbits && !chan->span->hooksig) {
2302
		module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state %d on channel %s while span %s lacks rbsbits or hooksig function\n",
2303
			txsig, chan->name, chan->span->name);
2304
		return;
2305
	}
2306
	/* Don't do anything for RBS */
2307
	if (chan->sig == DAHDI_SIG_DACS_RBS)
2308
		return;
2309
	chan->txstate = txstate;
2310
2311
	/* if tone signalling */
2312
	if (chan->sig == DAHDI_SIG_SF) {
2313
		chan->txhooksig = txsig;
2314
		if (chan->txtone) { /* if set to make tone for tx */
2315
			if ((txsig && !(chan->toneflags & DAHDI_REVERSE_TXTONE)) ||
2316
			 ((!txsig) && (chan->toneflags & DAHDI_REVERSE_TXTONE))) {
2317
				set_txtone(chan,chan->txtone,chan->tx_v2,chan->tx_v3);
2318
			} else {
2319
				set_txtone(chan,0,0,0);
2320
			}
2321
		}
2322
		chan->otimer = timeout * DAHDI_CHUNKSIZE;			/* Otimer is timer in samples */
2323
		return;
2324
	}
2325
	if (chan->span->hooksig) {
2326
		if (chan->txhooksig != txsig) {
2327
			chan->txhooksig = txsig;
2328
			chan->span->hooksig(chan, txsig);
2329
		}
2330
		chan->otimer = timeout * DAHDI_CHUNKSIZE;			/* Otimer is timer in samples */
2331
		return;
2332
	} else {
2333
		for (x = 0; x < NUM_SIGS; x++) {
2334
			if (outs[x].sig_type == chan->sig) {
2335
#ifdef CONFIG_DAHDI_DEBUG
2336
				module_printk(KERN_NOTICE, "Setting bits to %d for channel %s state %d in %d signalling\n", outs[x].bits[txsig], chan->name, txsig, chan->sig);
2337
#endif
2338
				chan->txhooksig = txsig;
2339
				chan->txsig = outs[x].bits[txsig];
2340
				chan->span->rbsbits(chan, chan->txsig);
2341
				chan->otimer = timeout * DAHDI_CHUNKSIZE;	/* Otimer is timer in samples */
2342
				return;
2343
			}
2344
		}
2345
	}
2346
	module_printk(KERN_NOTICE, "dahdi_rbs: Don't know RBS signalling type %d on channel %s\n", chan->sig, chan->name);
2347
}
2348
2349
static int dahdi_cas_setbits(struct dahdi_chan *chan, int bits)
2350
{
2351
	/* if no span, return as error */
2352
	if (!chan->span)
2353
		return -1;
2354
	if (chan->span->rbsbits) {
2355
		chan->txsig = bits;
2356
		chan->span->rbsbits(chan, bits);
2357
	} else {
2358
		module_printk(KERN_NOTICE, "Huh?  CAS setbits, but no RBS bits function\n");
2359
	}
2360
2361
	return 0;
2362
}
2363
2364
static int dahdi_hangup(struct dahdi_chan *chan)
2365
{
2366
	int x, res = 0;
2367
2368
	/* Can't hangup pseudo channels */
2369
	if (!chan->span)
2370
		return 0;
2371
2372
	/* Can't hang up a clear channel */
2373
	if (chan->flags & (DAHDI_FLAG_CLEAR | DAHDI_FLAG_NOSTDTXRX))
2374
		return -EINVAL;
2375
2376
	chan->kewlonhook = 0;
2377
2378
	if ((chan->sig == DAHDI_SIG_FXSLS) || (chan->sig == DAHDI_SIG_FXSKS) ||
2379
			(chan->sig == DAHDI_SIG_FXSGS)) {
2380
		chan->ringdebtimer = RING_DEBOUNCE_TIME;
2381
	}
2382
2383
	if (chan->span->flags & DAHDI_FLAG_RBS) {
2384
		if (chan->sig == DAHDI_SIG_CAS) {
2385
			dahdi_cas_setbits(chan, chan->idlebits);
2386
		} else if ((chan->sig == DAHDI_SIG_FXOKS) && (chan->txstate != DAHDI_TXSTATE_ONHOOK)
2387
			/* if other party is already on-hook we shouldn't do any battery drop */
2388
			&& !((chan->rxhooksig == DAHDI_RXSIG_ONHOOK) && (chan->itimer <= 0))) {
2389
			/* Do RBS signalling on the channel's behalf */
2390
			dahdi_rbs_sethook(chan, DAHDI_TXSIG_KEWL, DAHDI_TXSTATE_KEWL, DAHDI_KEWLTIME);
2391
		} else
2392
			dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_ONHOOK, 0);
2393
	} else {
2394
		/* Let the driver hang up the line if it wants to  */
2395
		if (chan->span->sethook) {
2396
			if (chan->txhooksig != DAHDI_ONHOOK) {
2397
				chan->txhooksig = DAHDI_ONHOOK;
2398
				res = chan->span->sethook(chan, DAHDI_ONHOOK);
2399
			} else
2400
				res = 0;
2401
		}
2402
	}
2403
2404
	/* if not registered yet, just return here */
2405
	if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags))
2406
		return res;
2407
2408
	/* Mark all buffers as empty */
2409
	for (x = 0; x < chan->numbufs; x++) {
2410
		chan->writen[x] =
2411
		chan->writeidx[x]=
2412
		chan->readn[x]=
2413
		chan->readidx[x] = 0;
2414
	}
2415
2416
	if (chan->readbuf[0]) {
2417
		chan->inreadbuf = 0;
2418
		chan->inwritebuf = 0;
2419
	} else {
2420
		chan->inreadbuf = -1;
2421
		chan->inwritebuf = -1;
2422
	}
2423
	chan->outreadbuf = -1;
2424
	chan->outwritebuf = -1;
2425
	chan->dialing = 0;
2426
	chan->afterdialingtimer = 0;
2427
	chan->curtone = NULL;
2428
	chan->pdialcount = 0;
2429
	chan->cadencepos = 0;
2430
	chan->txdialbuf[0] = 0;
2431
2432
	return res;
2433
}
2434
2435
static int initialize_channel(struct dahdi_chan *chan)
2436
{
2437
	int res;
2438
	unsigned long flags;
2439
	void *rxgain=NULL;
2440
	struct dahdi_echocan_state *ec_state;
2441
	const struct dahdi_echocan_factory *ec_current;
2442
2443
	if ((res = dahdi_reallocbufs(chan, DAHDI_DEFAULT_BLOCKSIZE, DAHDI_DEFAULT_NUM_BUFS)))
2444
		return res;
2445
2446
	spin_lock_irqsave(&chan->lock, flags);
2447
2448
	chan->rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
2449
	chan->txbufpolicy = DAHDI_POLICY_IMMEDIATE;
2450
2451
	ec_state = chan->ec_state;
2452
	chan->ec_state = NULL;
2453
	ec_current = chan->ec_current;
2454
	chan->ec_current = NULL;
2455
2456
	chan->txdisable = 0;
2457
	chan->rxdisable = 0;
2458
2459
	chan->digitmode = DIGIT_MODE_DTMF;
2460
	chan->dialing = 0;
2461
	chan->afterdialingtimer = 0;
2462
2463
	chan->cadencepos = 0;
2464
	chan->firstcadencepos = 0; /* By default loop back to first cadence position */
2465
2466
	/* HDLC & FCS stuff */
2467
	fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
2468
	fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
2469
	chan->infcs = PPP_INITFCS;
2470
2471
	/* Timings for RBS */
2472
	chan->prewinktime = DAHDI_DEFAULT_PREWINKTIME;
2473
	chan->preflashtime = DAHDI_DEFAULT_PREFLASHTIME;
2474
	chan->winktime = DAHDI_DEFAULT_WINKTIME;
2475
	chan->flashtime = DAHDI_DEFAULT_FLASHTIME;
2476
2477
	if (chan->sig & __DAHDI_SIG_FXO)
2478
		chan->starttime = DAHDI_DEFAULT_RINGTIME;
2479
	else
2480
		chan->starttime = DAHDI_DEFAULT_STARTTIME;
2481
	chan->rxwinktime = DAHDI_DEFAULT_RXWINKTIME;
2482
	chan->rxflashtime = DAHDI_DEFAULT_RXFLASHTIME;
2483
	chan->debouncetime = DAHDI_DEFAULT_DEBOUNCETIME;
2484
	chan->pulsemaketime = DAHDI_DEFAULT_PULSEMAKETIME;
2485
	chan->pulsebreaktime = DAHDI_DEFAULT_PULSEBREAKTIME;
2486
	chan->pulseaftertime = DAHDI_DEFAULT_PULSEAFTERTIME;
2487
2488
	/* Initialize RBS timers */
2489
	chan->itimerset = chan->itimer = chan->otimer = 0;
2490
	chan->ringdebtimer = 0;
2491
2492
	init_waitqueue_head(&chan->sel);
2493
	init_waitqueue_head(&chan->readbufq);
2494
	init_waitqueue_head(&chan->writebufq);
2495
	init_waitqueue_head(&chan->eventbufq);
2496
	init_waitqueue_head(&chan->txstateq);
2497
2498
	/* Reset conferences */
2499
	reset_conf(chan);
2500
2501
	/* I/O Mask, etc */
2502
	chan->iomask = 0;
2503
	/* release conference resource if any */
2504
	if (chan->confna)
2505
		dahdi_check_conf(chan->confna);
2506
	if ((chan->sig & __DAHDI_SIG_DACS) != __DAHDI_SIG_DACS) {
2507
		chan->confna = 0;
2508
		chan->confmode = 0;
2509
		if (chan->span && chan->span->dacs)
2510
			chan->span->dacs(chan, NULL);
2511
	}
2512
	chan->_confn = 0;
2513
	memset(chan->conflast, 0, sizeof(chan->conflast));
2514
	memset(chan->conflast1, 0, sizeof(chan->conflast1));
2515
	memset(chan->conflast2, 0, sizeof(chan->conflast2));
2516
	chan->confmute = 0;
2517
	chan->gotgs = 0;
2518
	chan->curtone = NULL;
2519
	chan->tonep = 0;
2520
	chan->pdialcount = 0;
2521
	if (chan->gainalloc && chan->rxgain)
2522
		rxgain = chan->rxgain;
2523
	chan->rxgain = defgain;
2524
	chan->txgain = defgain;
2525
	chan->gainalloc = 0;
2526
	chan->eventinidx = chan->eventoutidx = 0;
2527
	dahdi_set_law(chan,0);
2528
	dahdi_hangup(chan);
2529
2530
	/* Make sure that the audio flag is cleared on a clear channel */
2531
	if ((chan->sig & DAHDI_SIG_CLEAR) || (chan->sig & DAHDI_SIG_HARDHDLC))
2532
		chan->flags &= ~DAHDI_FLAG_AUDIO;
2533
2534
	if ((chan->sig == DAHDI_SIG_CLEAR) || (chan->sig == DAHDI_SIG_HARDHDLC))
2535
		chan->flags &= ~(DAHDI_FLAG_PPP | DAHDI_FLAG_FCS | DAHDI_FLAG_HDLC);
2536
2537
	chan->flags &= ~DAHDI_FLAG_LINEAR;
2538
	if (chan->curzone) {
2539
		/* Take cadence from tone zone */
2540
		memcpy(chan->ringcadence, chan->curzone->ringcadence, sizeof(chan->ringcadence));
2541
	} else {
2542
		/* Do a default */
2543
		memset(chan->ringcadence, 0, sizeof(chan->ringcadence));
2544
		chan->ringcadence[0] = chan->starttime;
2545
		chan->ringcadence[1] = DAHDI_RINGOFFTIME;
2546
	}
2547
2548
	if (ec_state) {
2549
		ec_state->ops->echocan_free(chan, ec_state);
2550
		release_echocan(ec_current);
2551
	}
2552
2553
	spin_unlock_irqrestore(&chan->lock, flags);
2554
2555
	set_tone_zone(chan, -1);
2556
2557
	if (rxgain)
2558
		kfree(rxgain);
2559
2560
	return 0;
2561
}
2562
2563
static int dahdi_timing_open(struct inode *inode, struct file *file)
2564
{
2565
	struct dahdi_timer *t;
2566
	unsigned long flags;
2567
2568
	if (!(t = kzalloc(sizeof(*t), GFP_KERNEL)))
2569
		return -ENOMEM;
2570
2571
	init_waitqueue_head(&t->sel);
2572
	INIT_LIST_HEAD(&t->list);
2573
	file->private_data = t;
2574
2575
	spin_lock_irqsave(&zaptimerlock, flags);
2576
	list_add(&t->list, &zaptimers);
2577
	spin_unlock_irqrestore(&zaptimerlock, flags);
2578
2579
	return 0;
2580
}
2581
2582
static int dahdi_timer_release(struct inode *inode, struct file *file)
2583
{
2584
	struct dahdi_timer *t, *cur, *next;
2585
	unsigned long flags;
2586
2587
	if (!(t = file->private_data))
2588
		return 0;
2589
2590
	spin_lock_irqsave(&zaptimerlock, flags);
2591
2592
	list_for_each_entry_safe(cur, next, &zaptimers, list) {
2593
		if (t == cur) {
2594
			list_del(&cur->list);
2595
			break;
2596
		}
2597
	}
2598
2599
	spin_unlock_irqrestore(&zaptimerlock, flags);
2600
2601
	if (!cur) {
2602
		module_printk(KERN_NOTICE, "Timer: Not on list??\n");
2603
		return 0;
2604
	}
2605
2606
	kfree(cur);
2607
2608
	return 0;
2609
}
2610
2611
static int dahdi_specchan_open(struct inode *inode, struct file *file, int unit)
2612
{
2613
	int res = 0;
2614
2615
	if (chans[unit] && chans[unit]->sig) {
2616
		/* Make sure we're not already open, a net device, or a slave device */
2617
		if (chans[unit]->flags & DAHDI_FLAG_NETDEV)
2618
			res = -EBUSY;
2619
		else if (chans[unit]->master != chans[unit])
2620
			res = -EBUSY;
2621
		else if ((chans[unit]->sig & __DAHDI_SIG_DACS) == __DAHDI_SIG_DACS)
2622
			res = -EBUSY;
2623
		else if (!test_and_set_bit(DAHDI_FLAGBIT_OPEN, &chans[unit]->flags)) {
2624
			unsigned long flags;
2625
			res = initialize_channel(chans[unit]);
2626
			if (res) {
2627
				/* Reallocbufs must have failed */
2628
				clear_bit(DAHDI_FLAGBIT_OPEN, &chans[unit]->flags);
2629
				return res;
2630
			}
2631
			spin_lock_irqsave(&chans[unit]->lock, flags);
2632
			if (chans[unit]->flags & DAHDI_FLAG_PSEUDO)
2633
				chans[unit]->flags |= DAHDI_FLAG_AUDIO;
2634
			if (chans[unit]->span && chans[unit]->span->open) {
2635
				res = chans[unit]->span->open(chans[unit]);
2636
			}
2637
			if (!res) {
2638
				chans[unit]->file = file;
2639
				spin_unlock_irqrestore(&chans[unit]->lock, flags);
2640
			} else {
2641
				spin_unlock_irqrestore(&chans[unit]->lock, flags);
2642
				close_channel(chans[unit]);
2643
				clear_bit(DAHDI_FLAGBIT_OPEN, &chans[unit]->flags);
2644
			}
2645
		} else
2646
			res = -EBUSY;
2647
	} else
2648
		res = -ENXIO;
2649
	return res;
2650
}
2651
2652
static int dahdi_specchan_release(struct inode *node, struct file *file, int unit)
2653
{
2654
	int res=0;
2655
	unsigned long flags;
2656
2657
	if (chans[unit]) {
2658
		/* Chan lock protects contents against potentially non atomic accesses.
2659
		 * So if the pointer setting is not atomic, we should protect */
2660
		spin_lock_irqsave(&chans[unit]->lock, flags);
2661
		chans[unit]->file = NULL;
2662
		spin_unlock_irqrestore(&chans[unit]->lock, flags);
2663
		close_channel(chans[unit]);
2664
		if (chans[unit]->span && chans[unit]->span->close)
2665
			res = chans[unit]->span->close(chans[unit]);
2666
		/* The channel might be destroyed by low-level driver span->close() */
2667
		if(chans[unit])
2668
			clear_bit(DAHDI_FLAGBIT_OPEN, &chans[unit]->flags);
2669
	} else
2670
		res = -ENXIO;
2671
	return res;
2672
}
2673
2674
static struct dahdi_chan *dahdi_alloc_pseudo(void)
2675
{
2676
	struct dahdi_chan *pseudo;
2677
2678
	/* Don't allow /dev/dahdi/pseudo to open if there are no spans */
2679
	if (maxspans < 1)
2680
		return NULL;
2681
2682
	if (!(pseudo = kzalloc(sizeof(*pseudo), GFP_KERNEL)))
2683
		return NULL;
2684
2685
	pseudo->sig = DAHDI_SIG_CLEAR;
2686
	pseudo->sigcap = DAHDI_SIG_CLEAR;
2687
	pseudo->flags = DAHDI_FLAG_PSEUDO | DAHDI_FLAG_AUDIO;
2688
2689
	if (dahdi_chan_reg(pseudo)) {
2690
		kfree(pseudo);
2691
		pseudo = NULL;
2692
	} else {
2693
		snprintf(pseudo->name, sizeof(pseudo->name)-1,"Pseudo/%d", pseudo->channo); 
2694
	}
2695
2696
	return pseudo;
2697
}
2698
2699
static void dahdi_free_pseudo(struct dahdi_chan *pseudo)
2700
{
2701
	if (pseudo) {
2702
		dahdi_chan_unreg(pseudo);
2703
		kfree(pseudo);
2704
	}
2705
}
2706
2707
static int dahdi_open(struct inode *inode, struct file *file)
2708
{
2709
	int unit = UNIT(file);
2710
	struct dahdi_chan *chan;
2711
	/* Minor 0: Special "control" descriptor */
2712
	if (!unit)
2713
		return dahdi_ctl_open(inode, file);
2714
	if (unit == 250) {
2715
		if (!dahdi_transcode_fops) {
2716
			if (request_module("dahdi_transcode")) {
2717
				return -ENXIO;
2718
			}
2719
		}
2720
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2721
		__MOD_INC_USE_COUNT (dahdi_transcode_fops->owner);
2722
#else
2723
		if (!try_module_get(dahdi_transcode_fops->owner)) {
2724
			return -ENXIO;
2725
		}
2726
#endif
2727
		if (dahdi_transcode_fops && dahdi_transcode_fops->open) {
2728
			return dahdi_transcode_fops->open(inode, file);
2729
		} else {
2730
			/* dahdi_transcode module should have exported a
2731
			 * file_operations table. */
2732
			 WARN_ON(1);
2733
		}
2734
		return -ENXIO;
2735
	}
2736
	if (unit == 253) {
2737
		if (maxspans) {
2738
			return dahdi_timing_open(inode, file);
2739
		} else {
2740
			return -ENXIO;
2741
		}
2742
	}
2743
	if (unit == 254)
2744
		return dahdi_chan_open(inode, file);
2745
	if (unit == 255) {
2746
		if (maxspans) {
2747
			chan = dahdi_alloc_pseudo();
2748
			if (chan) {
2749
				file->private_data = chan;
2750
				return dahdi_specchan_open(inode, file, chan->channo);
2751
			} else {
2752
				return -ENXIO;
2753
			}
2754
		} else
2755
			return -ENXIO;
2756
	}
2757
	return dahdi_specchan_open(inode, file, unit);
2758
}
2759
2760
#if 0
2761
static int dahdi_open(struct inode *inode, struct file *file)
2762
{
2763
	int res;
2764
	unsigned long flags;
2765
	spin_lock_irqsave(&bigzaplock, flags);
2766
	res = __dahdi_open(inode, file);
2767
	spin_unlock_irqrestore(&bigzaplock, flags);
2768
	return res;
2769
}
2770
#endif
2771
2772
static ssize_t dahdi_read(struct file *file, char *usrbuf, size_t count, loff_t *ppos)
2773
{
2774
	int unit = UNIT(file);
2775
	struct dahdi_chan *chan;
2776
2777
	/* Can't read from control */
2778
	if (!unit) {
2779
		return -EINVAL;
2780
	}
2781
2782
	if (unit == 253)
2783
		return -EINVAL;
2784
2785
	if (unit == 254) {
2786
		chan = file->private_data;
2787
		if (!chan)
2788
			return -EINVAL;
2789
		return dahdi_chan_read(file, usrbuf, count, chan->channo);
2790
	}
2791
2792
	if (unit == 255) {
2793
		chan = file->private_data;
2794
		if (!chan) {
2795
			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
2796
			return -EINVAL;
2797
		}
2798
		return dahdi_chan_read(file, usrbuf, count, chan->channo);
2799
	}
2800
	if (count < 0)
2801
		return -EINVAL;
2802
2803
	return dahdi_chan_read(file, usrbuf, count, unit);
2804
}
2805
2806
static ssize_t dahdi_write(struct file *file, const char *usrbuf, size_t count, loff_t *ppos)
2807
{
2808
	int unit = UNIT(file);
2809
	struct dahdi_chan *chan;
2810
	/* Can't read from control */
2811
	if (!unit)
2812
		return -EINVAL;
2813
	if (count < 0)
2814
		return -EINVAL;
2815
	if (unit == 253)
2816
		return -EINVAL;
2817
	if (unit == 254) {
2818
		chan = file->private_data;
2819
		if (!chan)
2820
			return -EINVAL;
2821
		return dahdi_chan_write(file, usrbuf, count, chan->channo);
2822
	}
2823
	if (unit == 255) {
2824
		chan = file->private_data;
2825
		if (!chan) {
2826
			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
2827
			return -EINVAL;
2828
		}
2829
		return dahdi_chan_write(file, usrbuf, count, chan->channo);
2830
	}
2831
	return dahdi_chan_write(file, usrbuf, count, unit);
2832
2833
}
2834
2835
static int dahdi_set_default_zone(int defzone)
2836
{
2837
	if ((defzone < 0) || (defzone >= DAHDI_TONE_ZONE_MAX))
2838
		return -EINVAL;
2839
	write_lock(&zone_lock);
2840
	if (!tone_zones[defzone]) {
2841
		write_unlock(&zone_lock);
2842
		return -EINVAL;
2843
	}
2844
	if ((default_zone != -1) && tone_zones[default_zone])
2845
		atomic_dec(&tone_zones[default_zone]->refcount);
2846
	atomic_inc(&tone_zones[defzone]->refcount);
2847
	default_zone = defzone;
2848
	write_unlock(&zone_lock);
2849
	return 0;
2850
}
2851
2852
/* No bigger than 32k for everything per tone zone */
2853
#define MAX_SIZE 32768
2854
/* No more than 128 subtones */
2855
#define MAX_TONES 128
2856
2857
/* The tones to be loaded can (will) be a mix of regular tones,
2858
   DTMF tones and MF tones. We need to load DTMF and MF tones
2859
   a bit differently than regular tones because their storage
2860
   format is much simpler (an array structure field of the zone
2861
   structure, rather an array of pointers).
2862
*/
2863
static int ioctl_load_zone(unsigned long data)
2864
{
2865
	struct dahdi_tone *samples[MAX_TONES] = { NULL, };
2866
	short next[MAX_TONES] = { 0, };
2867
	struct dahdi_tone_def_header th;
2868
	struct dahdi_tone_def td;
2869
	struct dahdi_zone *z;
2870
	struct dahdi_tone *t;
2871
	void *slab, *ptr;
2872
	int x;
2873
	size_t space;
2874
	size_t size;
2875
	int res;
2876
2877
	if (copy_from_user(&th, (struct dahdi_tone_def_header *) data, sizeof(th)))
2878
		return -EFAULT;
2879
2880
	data += sizeof(th);
2881
2882
	if ((th.count < 0) || (th.count > MAX_TONES)) {
2883
		module_printk(KERN_NOTICE, "Too many tones included\n");
2884
		return -EINVAL;
2885
	}
2886
2887
	space = size = sizeof(*z) + th.count * sizeof(*t);
2888
2889
	if (size > MAX_SIZE)
2890
		return -E2BIG;
2891
2892
	if (!(z = ptr = slab = kzalloc(size, GFP_KERNEL)))
2893
		return -ENOMEM;
2894
2895
	ptr += sizeof(*z);
2896
	space -= sizeof(*z);
2897
2898
	dahdi_copy_string(z->name, th.name, sizeof(z->name));
2899
2900
	for (x = 0; x < DAHDI_MAX_CADENCE; x++)
2901
		z->ringcadence[x] = th.ringcadence[x];
2902
2903
	atomic_set(&z->refcount, 0);
2904
2905
	for (x = 0; x < th.count; x++) {
2906
		enum {
2907
			REGULAR_TONE,
2908
			DTMF_TONE,
2909
			MFR1_TONE,
2910
			MFR2_FWD_TONE,
2911
			MFR2_REV_TONE,
2912
		} tone_type;
2913
2914
		if (space < sizeof(*t)) {
2915
			kfree(slab);
2916
			module_printk(KERN_NOTICE, "Insufficient tone zone space\n");
2917
			return -EINVAL;
2918
		}
2919
2920
		if (copy_from_user(&td, (struct dahdi_tone_def *) data, sizeof(td))) {
2921
			kfree(slab);
2922
			return -EFAULT;
2923
		}
2924
2925
		data += sizeof(td);
2926
2927
		if ((td.tone >= 0) && (td.tone < DAHDI_TONE_MAX)) {
2928
			tone_type = REGULAR_TONE;
2929
2930
			t = samples[x] = ptr;
2931
2932
			space -= sizeof(*t);
2933
			ptr += sizeof(*t);
2934
2935
			/* Remember which sample is next */
2936
			next[x] = td.next;
2937
2938
			/* Make sure the "next" one is sane */
2939
			if ((next[x] >= th.count) || (next[x] < 0)) {
2940
				module_printk(KERN_NOTICE, "Invalid 'next' pointer: %d\n", next[x]);
2941
				kfree(slab);
2942
				return -EINVAL;
2943
			}
2944
		} else if ((td.tone >= DAHDI_TONE_DTMF_BASE) &&
2945
			   (td.tone <= DAHDI_TONE_DTMF_MAX)) {
2946
			tone_type = DTMF_TONE;
2947
			td.tone -= DAHDI_TONE_DTMF_BASE;
2948
			t = &z->dtmf[td.tone];
2949
		} else if ((td.tone >= DAHDI_TONE_MFR1_BASE) &&
2950
			   (td.tone <= DAHDI_TONE_MFR1_MAX)) {
2951
			tone_type = MFR1_TONE;
2952
			td.tone -= DAHDI_TONE_MFR1_BASE;
2953
			t = &z->mfr1[td.tone];
2954
		} else if ((td.tone >= DAHDI_TONE_MFR2_FWD_BASE) &&
2955
			   (td.tone <= DAHDI_TONE_MFR2_FWD_MAX)) {
2956
			tone_type = MFR2_FWD_TONE;
2957
			td.tone -= DAHDI_TONE_MFR2_FWD_BASE;
2958
			t = &z->mfr2_fwd[td.tone];
2959
		} else if ((td.tone >= DAHDI_TONE_MFR2_REV_BASE) &&
2960
			   (td.tone <= DAHDI_TONE_MFR2_REV_MAX)) {
2961
			tone_type = MFR2_REV_TONE;
2962
			td.tone -= DAHDI_TONE_MFR2_REV_BASE;
2963
			t = &z->mfr2_rev[td.tone];
2964
		} else {
2965
			module_printk(KERN_NOTICE, "Invalid tone (%d) defined\n", td.tone);
2966
			kfree(slab);
2967
			return -EINVAL;
2968
		}
2969
2970
		t->fac1 = td.fac1;
2971
		t->init_v2_1 = td.init_v2_1;
2972
		t->init_v3_1 = td.init_v3_1;
2973
		t->fac2 = td.fac2;
2974
		t->init_v2_2 = td.init_v2_2;
2975
		t->init_v3_2 = td.init_v3_2;
2976
		t->modulate = td.modulate;
2977
2978
		switch (tone_type) {
2979
		case REGULAR_TONE:
2980
			t->tonesamples = td.samples;
2981
			if (!z->tones[td.tone])
2982
				z->tones[td.tone] = t;
2983
			break;
2984
		case DTMF_TONE:
2985
			t->tonesamples = global_dialparams.dtmf_tonelen;
2986
			t->next = &dtmf_silence;
2987
			z->dtmf_continuous[td.tone] = *t;
2988
			z->dtmf_continuous[td.tone].next = &z->dtmf_continuous[td.tone];
2989
			break;
2990
		case MFR1_TONE:
2991
			switch (td.tone + DAHDI_TONE_MFR1_BASE) {
2992
			case DAHDI_TONE_MFR1_KP:
2993
			case DAHDI_TONE_MFR1_ST:
2994
			case DAHDI_TONE_MFR1_STP:
2995
			case DAHDI_TONE_MFR1_ST2P:
2996
			case DAHDI_TONE_MFR1_ST3P:
2997
				/* signaling control tones are always 100ms */
2998
				t->tonesamples = 100 * DAHDI_CHUNKSIZE;
2999
				break;
3000
			default:
3001
				t->tonesamples = global_dialparams.mfv1_tonelen;
3002
				break;
3003
			}
3004
			t->next = &mfr1_silence;
3005
			break;
3006
		case MFR2_FWD_TONE:
3007
			t->tonesamples = global_dialparams.mfr2_tonelen;
3008
			t->next = &dtmf_silence;
3009
			z->mfr2_fwd_continuous[td.tone] = *t;
3010
			z->mfr2_fwd_continuous[td.tone].next = &z->mfr2_fwd_continuous[td.tone];
3011
			break;
3012
		case MFR2_REV_TONE:
3013
			t->tonesamples = global_dialparams.mfr2_tonelen;
3014
			t->next = &dtmf_silence;
3015
			z->mfr2_rev_continuous[td.tone] = *t;
3016
			z->mfr2_rev_continuous[td.tone].next = &z->mfr2_rev_continuous[td.tone];
3017
			break;
3018
		}
3019
	}
3020
3021
	for (x = 0; x < th.count; x++) {
3022
		if (samples[x])
3023
			samples[x]->next = samples[next[x]];
3024
	}
3025
3026
	if ((res = dahdi_register_tone_zone(th.zone, z))) {
3027
		kfree(slab);
3028
	} else {
3029
		if ( -1 == default_zone ) {
3030
			dahdi_set_default_zone(th.zone);
3031
		}
3032
	}
3033
3034
	return res;
3035
}
3036
3037
void dahdi_init_tone_state(struct dahdi_tone_state *ts, struct dahdi_tone *zt)
3038
{
3039
	ts->v1_1 = 0;
3040
	ts->v2_1 = zt->init_v2_1;
3041
	ts->v3_1 = zt->init_v3_1;
3042
	ts->v1_2 = 0;
3043
	ts->v2_2 = zt->init_v2_2;
3044
	ts->v3_2 = zt->init_v3_2;
3045
	ts->modulate = zt->modulate;
3046
}
3047
3048
struct dahdi_tone *dahdi_mf_tone(const struct dahdi_chan *chan, char digit, int digitmode)
3049
{
3050
	unsigned int tone_index;
3051
3052
	if (!chan->curzone) {
3053
		static int __warnonce = 1;
3054
		if (__warnonce) {
3055
			__warnonce = 0;
3056
			/* The tonezones are loaded by dahdi_cfg based on /etc/dahdi/system.conf. */
3057
			module_printk(KERN_WARNING, "Cannot get dtmf tone until tone zone is loaded.\n");
3058
		}
3059
		return NULL;
3060
	}
3061
3062
	switch (digitmode) {
3063
	case DIGIT_MODE_PULSE:
3064
		/* We should only get here with a pulse digit if we need
3065
		 * to "dial" 'W' (wait 0.5 second) 
3066
		 */
3067
		if (digit == 'W')
3068
			return &tone_pause;
3069
3070
		return NULL;
3071
		/* You should not get here */
3072
	case DIGIT_MODE_DTMF:
3073
		switch (digit) {
3074
		case '0':
3075
		case '1':
3076
		case '2':
3077
		case '3':
3078
		case '4':
3079
		case '5':
3080
		case '6':
3081
		case '7':
3082
		case '8':
3083
		case '9':
3084
			tone_index = DAHDI_TONE_DTMF_0 + (digit - '0');
3085
			break;
3086
		case '*':
3087
			tone_index = DAHDI_TONE_DTMF_s;
3088
			break;
3089
		case '#':
3090
			tone_index = DAHDI_TONE_DTMF_p;
3091
			break;
3092
		case 'A':
3093
		case 'B':
3094
		case 'C':
3095
		case 'D':
3096
			tone_index = DAHDI_TONE_DTMF_A + (digit - 'A');
3097
		case 'W':
3098
			return &tone_pause;
3099
		default:
3100
			return NULL;
3101
		}
3102
		return &chan->curzone->dtmf[tone_index - DAHDI_TONE_DTMF_BASE];
3103
	case DIGIT_MODE_MFR1:
3104
		switch (digit) {
3105
		case '0':
3106
		case '1':
3107
		case '2':
3108
		case '3':
3109
		case '4':
3110
		case '5':
3111
		case '6':
3112
		case '7':
3113
		case '8':
3114
		case '9':
3115
			tone_index = DAHDI_TONE_MFR1_0 + (digit - '0');
3116
			break;
3117
		case '*':
3118
			tone_index = DAHDI_TONE_MFR1_KP;
3119
			break;
3120
		case '#':
3121
			tone_index = DAHDI_TONE_MFR1_ST;
3122
			break;
3123
		case 'A':
3124
			tone_index = DAHDI_TONE_MFR1_STP;
3125
			break;
3126
		case 'B':
3127
			tone_index = DAHDI_TONE_MFR1_ST2P;
3128
			break;
3129
		case 'C':
3130
			tone_index = DAHDI_TONE_MFR1_ST3P;
3131
			break;
3132
		case 'W':
3133
			return &tone_pause;
3134
		default:
3135
			return NULL;
3136
		}
3137
		return &chan->curzone->mfr1[tone_index - DAHDI_TONE_MFR1_BASE];
3138
	case DIGIT_MODE_MFR2_FWD:
3139
		switch (digit) {
3140
		case '1':
3141
		case '2':
3142
		case '3':
3143
		case '4':
3144
		case '5':
3145
		case '6':
3146
		case '7':
3147
		case '8':
3148
		case '9':
3149
			tone_index = DAHDI_TONE_MFR2_FWD_1 + (digit - '1');
3150
			break;
3151
		case 'A':
3152
		case 'B':
3153
		case 'C':
3154
		case 'D':
3155
		case 'E':
3156
		case 'F':
3157
			tone_index = DAHDI_TONE_MFR2_FWD_10 + (digit - 'A');
3158
			break;
3159
		case 'W':
3160
			return &tone_pause;
3161
		default:
3162
			return NULL;
3163
		}
3164
		return &chan->curzone->mfr2_fwd[tone_index - DAHDI_TONE_MFR2_FWD_BASE];
3165
	case DIGIT_MODE_MFR2_REV:
3166
		switch (digit) {
3167
		case '1':
3168
		case '2':
3169
		case '3':
3170
		case '4':
3171
		case '5':
3172
		case '6':
3173
		case '7':
3174
		case '8':
3175
		case '9':
3176
			tone_index = DAHDI_TONE_MFR2_REV_1 + (digit - '1');
3177
			break;
3178
		case 'A':
3179
		case 'B':
3180
		case 'C':
3181
		case 'D':
3182
		case 'E':
3183
		case 'F':
3184
			tone_index = DAHDI_TONE_MFR2_REV_10 + (digit - 'A');
3185
			break;
3186
		case 'W':
3187
			return &tone_pause;
3188
		default:
3189
			return NULL;
3190
		}
3191
		return &chan->curzone->mfr2_rev[tone_index - DAHDI_TONE_MFR2_REV_BASE];
3192
	default:
3193
		return NULL;
3194
	}
3195
}
3196
3197
static void __do_dtmf(struct dahdi_chan *chan)
3198
{
3199
	char c;
3200
3201
	/* Called with chan->lock held */
3202
	while ((c = chan->txdialbuf[0])) {
3203
		memmove(chan->txdialbuf, chan->txdialbuf + 1, sizeof(chan->txdialbuf) - 1);
3204
		switch (c) {
3205
		case 'T':
3206
			chan->digitmode = DIGIT_MODE_DTMF;
3207
			chan->tonep = 0;
3208
			break;
3209
		case 'M':
3210
			chan->digitmode = DIGIT_MODE_MFR1;
3211
			chan->tonep = 0;
3212
			break;
3213
		case 'O':
3214
			chan->digitmode = DIGIT_MODE_MFR2_FWD;
3215
			chan->tonep = 0;
3216
			break;
3217
		case 'R':
3218
			chan->digitmode = DIGIT_MODE_MFR2_REV;
3219
			chan->tonep = 0;
3220
			break;
3221
		case 'P':
3222
			chan->digitmode = DIGIT_MODE_PULSE;
3223
			chan->tonep = 0;
3224
			break;
3225
		default:
3226
			if ((c != 'W') && (chan->digitmode == DIGIT_MODE_PULSE)) {
3227
				if ((c >= '0') && (c <= '9') && (chan->txhooksig == DAHDI_TXSIG_OFFHOOK)) {
3228
					chan->pdialcount = (c == '0') ? 10 : c - '0';
3229
					dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_PULSEBREAK,
3230
						       chan->pulsebreaktime);
3231
					return;
3232
				}
3233
			} else {
3234
				chan->curtone = dahdi_mf_tone(chan, c, chan->digitmode);
3235
				chan->tonep = 0;
3236
				if (chan->curtone) {
3237
					dahdi_init_tone_state(&chan->ts, chan->curtone);
3238
					return;
3239
				}
3240
			}
3241
		}
3242
	}
3243
3244
	/* Notify userspace process if there is nothing left */
3245
	chan->dialing = 0;
3246
	__qevent(chan, DAHDI_EVENT_DIALCOMPLETE);
3247
}
3248
3249
static int dahdi_release(struct inode *inode, struct file *file)
3250
{
3251
	int unit = UNIT(file);
3252
	int res;
3253
	struct dahdi_chan *chan;
3254
3255
	if (!unit)
3256
		return dahdi_ctl_release(inode, file);
3257
	if (unit == 253) {
3258
		return dahdi_timer_release(inode, file);
3259
	}
3260
	if (unit == 250) {
3261
		/* We should not be here because the dahdi_transcode.ko module
3262
		 * should have updated the file_operations for this file
3263
		 * handle when the file was opened. */
3264
		WARN_ON(1);
3265
		return -EFAULT;
3266
	}
3267
	if (unit == 254) {
3268
		chan = file->private_data;
3269
		if (!chan)
3270
			return dahdi_chan_release(inode, file);
3271
		else
3272
			return dahdi_specchan_release(inode, file, chan->channo);
3273
	}
3274
	if (unit == 255) {
3275
		chan = file->private_data;
3276
		if (chan) {
3277
			res = dahdi_specchan_release(inode, file, chan->channo);
3278
			dahdi_free_pseudo(chan);
3279
		} else {
3280
			module_printk(KERN_NOTICE, "Pseudo release and no private data??\n");
3281
			res = 0;
3282
		}
3283
		return res;
3284
	}
3285
	return dahdi_specchan_release(inode, file, unit);
3286
}
3287
3288
#if 0
3289
static int dahdi_release(struct inode *inode, struct file *file)
3290
{
3291
	/* Lock the big zap lock when handling a release */
3292
	unsigned long flags;
3293
	int res;
3294
	spin_lock_irqsave(&bigzaplock, flags);
3295
	res = __dahdi_release(inode, file);
3296
	spin_unlock_irqrestore(&bigzaplock, flags);
3297
	return res;
3298
}
3299
#endif
3300
3301
3302
void dahdi_alarm_channel(struct dahdi_chan *chan, int alarms)
3303
{
3304
	unsigned long flags;
3305
3306
	spin_lock_irqsave(&chan->lock, flags);
3307
	if (chan->chan_alarms != alarms) {
3308
		chan->chan_alarms = alarms;
3309
		dahdi_qevent_nolock(chan, alarms ? DAHDI_EVENT_ALARM : DAHDI_EVENT_NOALARM);
3310
	}
3311
	spin_unlock_irqrestore(&chan->lock, flags);
3312
}
3313
3314
void dahdi_alarm_notify(struct dahdi_span *span)
3315
{
3316
	int x;
3317
3318
	span->alarms &= ~DAHDI_ALARM_LOOPBACK;
3319
	/* Determine maint status */
3320
	if (span->maintstat || span->mainttimer)
3321
		span->alarms |= DAHDI_ALARM_LOOPBACK;
3322
	/* DON'T CHANGE THIS AGAIN. THIS WAS DONE FOR A REASON.
3323
 	   The expression (a != b) does *NOT* do the same thing
3324
	   as ((!a) != (!b)) */
3325
	/* if change in general state */
3326
	if ((!span->alarms) != (!span->lastalarms)) {
3327
		span->lastalarms = span->alarms;
3328
		for (x = 0; x < span->channels; x++)
3329
			dahdi_alarm_channel(span->chans[x], span->alarms);
3330
		/* Switch to other master if current master in alarm */
3331
		for (x=1; x<maxspans; x++) {
3332
			if (spans[x] && !spans[x]->alarms && (spans[x]->flags & DAHDI_FLAG_RUNNING)) {
3333
				if(master != spans[x])
3334
					module_printk(KERN_NOTICE, "Master changed to %s\n", spans[x]->name);
3335
				master = spans[x];
3336
				break;
3337
			}
3338
		}
3339
	}
3340
}
3341
3342
#define VALID_SPAN(j) do { \
3343
	if ((j >= DAHDI_MAX_SPANS) || (j < 1)) \
3344
		return -EINVAL; \
3345
	if (!spans[j]) \
3346
		return -ENXIO; \
3347
} while(0)
3348
3349
#define CHECK_VALID_SPAN(j) do { \
3350
	/* Start a given span */ \
3351
	if (get_user(j, (int *)data)) \
3352
		return -EFAULT; \
3353
	VALID_SPAN(j); \
3354
} while(0)
3355
3356
#define VALID_CHANNEL(j) do { \
3357
	if ((j >= DAHDI_MAX_CHANNELS) || (j < 1)) \
3358
		return -EINVAL; \
3359
	if (!chans[j]) \
3360
		return -ENXIO; \
3361
} while(0)
3362
3363
static int dahdi_timer_ioctl(struct inode *node, struct file *file, unsigned int cmd, unsigned long data, struct dahdi_timer *timer)
3364
{
3365
	int j;
3366
	unsigned long flags;
3367
	switch(cmd) {
3368
	case DAHDI_TIMERCONFIG:
3369
		get_user(j, (int *)data);
3370
		if (j < 0)
3371
			j = 0;
3372
		spin_lock_irqsave(&zaptimerlock, flags);
3373
		timer->ms = timer->pos = j;
3374
		spin_unlock_irqrestore(&zaptimerlock, flags);
3375
		break;
3376
	case DAHDI_TIMERACK:
3377
		get_user(j, (int *)data);
3378
		spin_lock_irqsave(&zaptimerlock, flags);
3379
		if ((j < 1) || (j > timer->tripped))
3380
			j = timer->tripped;
3381
		timer->tripped -= j;
3382
		spin_unlock_irqrestore(&zaptimerlock, flags);
3383
		break;
3384
	case DAHDI_GETEVENT:  /* Get event on queue */
3385
		j = DAHDI_EVENT_NONE;
3386
		spin_lock_irqsave(&zaptimerlock, flags);
3387
		  /* set up for no event */
3388
		if (timer->tripped)
3389
			j = DAHDI_EVENT_TIMER_EXPIRED;
3390
		if (timer->ping)
3391
			j = DAHDI_EVENT_TIMER_PING;
3392
		spin_unlock_irqrestore(&zaptimerlock, flags);
3393
		put_user(j,(int *)data);
3394
		break;
3395
	case DAHDI_TIMERPING:
3396
		spin_lock_irqsave(&zaptimerlock, flags);
3397
		timer->ping = 1;
3398
		wake_up_interruptible(&timer->sel);
3399
		spin_unlock_irqrestore(&zaptimerlock, flags);
3400
		break;
3401
	case DAHDI_TIMERPONG:
3402
		spin_lock_irqsave(&zaptimerlock, flags);
3403
		timer->ping = 0;
3404
		spin_unlock_irqrestore(&zaptimerlock, flags);
3405
		break;
3406
	default:
3407
		return -ENOTTY;
3408
	}
3409
	return 0;
3410
}
3411
3412
static int dahdi_common_ioctl(struct inode *node, struct file *file, unsigned int cmd, unsigned long data, int unit)
3413
{
3414
	union {
3415
		struct dahdi_gains gain;
3416
		struct dahdi_spaninfo spaninfo;
3417
		struct dahdi_params param;
3418
	} stack;
3419
	struct dahdi_chan *chan;
3420
	unsigned long flags;
3421
	unsigned char *txgain, *rxgain;
3422
	int i,j;
3423
	int return_master = 0;
3424
	size_t size_to_copy;
3425
3426
	switch(cmd) {
3427
		/* get channel parameters */
3428
	case DAHDI_GET_PARAMS_V1: /* Intentional drop through. */
3429
	case DAHDI_GET_PARAMS:
3430
		size_to_copy = sizeof(struct dahdi_params);
3431
		if (copy_from_user(&stack.param, (struct dahdi_params *) data, size_to_copy))
3432
			return -EFAULT;
3433
3434
		/* check to see if the caller wants to receive our master channel number */
3435
		if (stack.param.channo & DAHDI_GET_PARAMS_RETURN_MASTER) {
3436
			return_master = 1;
3437
			stack.param.channo &= ~DAHDI_GET_PARAMS_RETURN_MASTER;
3438
		}
3439
3440
		/* Pick the right channo's */
3441
		if (!stack.param.channo || unit) {
3442
			stack.param.channo = unit;
3443
		}
3444
		/* Check validity of channel */
3445
		VALID_CHANNEL(stack.param.channo);
3446
		chan = chans[stack.param.channo];
3447
3448
		/* point to relevant structure */
3449
		stack.param.sigtype = chan->sig;  /* get signalling type */
3450
		/* return non-zero if rx not in idle state */
3451
		if (chan->span) {
3452
			j = dahdi_q_sig(chan);
3453
			if (j >= 0) { /* if returned with success */
3454
				stack.param.rxisoffhook = ((chan->rxsig & (j >> 8)) != (j & 0xff));
3455
			} else {
3456
				stack.param.rxisoffhook = ((chan->rxhooksig != DAHDI_RXSIG_ONHOOK) &&
3457
					(chan->rxhooksig != DAHDI_RXSIG_INITIAL));
3458
			}
3459
		} else if ((chan->txstate == DAHDI_TXSTATE_KEWL) || (chan->txstate == DAHDI_TXSTATE_AFTERKEWL))
3460
			stack.param.rxisoffhook = 1;
3461
		else
3462
			stack.param.rxisoffhook = 0;
3463
		if (chan->span && chan->span->rbsbits && !(chan->sig & DAHDI_SIG_CLEAR)) {
3464
			stack.param.rxbits = chan->rxsig;
3465
			stack.param.txbits = chan->txsig;
3466
			stack.param.idlebits = chan->idlebits;
3467
		} else {
3468
			stack.param.rxbits = -1;
3469
			stack.param.txbits = -1;
3470
			stack.param.idlebits = 0;
3471
		}
3472
		if (chan->span && (chan->span->rbsbits || chan->span->hooksig) &&
3473
			!(chan->sig & DAHDI_SIG_CLEAR)) {
3474
			stack.param.rxhooksig = chan->rxhooksig;
3475
			stack.param.txhooksig = chan->txhooksig;
3476
		} else {
3477
			stack.param.rxhooksig = -1;
3478
			stack.param.txhooksig = -1;
3479
		}
3480
		stack.param.prewinktime = chan->prewinktime;
3481
		stack.param.preflashtime = chan->preflashtime;
3482
		stack.param.winktime = chan->winktime;
3483
		stack.param.flashtime = chan->flashtime;
3484
		stack.param.starttime = chan->starttime;
3485
		stack.param.rxwinktime = chan->rxwinktime;
3486
		stack.param.rxflashtime = chan->rxflashtime;
3487
		stack.param.debouncetime = chan->debouncetime;
3488
		stack.param.channo = chan->channo;
3489
		stack.param.chan_alarms = chan->chan_alarms;
3490
3491
		/* if requested, put the master channel number in the top 16 bits of the result */
3492
		if (return_master)
3493
			stack.param.channo |= chan->master->channo << 16;
3494
3495
		stack.param.pulsemaketime = chan->pulsemaketime;
3496
		stack.param.pulsebreaktime = chan->pulsebreaktime;
3497
		stack.param.pulseaftertime = chan->pulseaftertime;
3498
		if (chan->span) stack.param.spanno = chan->span->spanno;
3499
			else stack.param.spanno = 0;
3500
		dahdi_copy_string(stack.param.name, chan->name, sizeof(stack.param.name));
3501
		stack.param.chanpos = chan->chanpos;
3502
		stack.param.sigcap = chan->sigcap;
3503
		/* Return current law */
3504
		if (chan->xlaw == __dahdi_alaw)
3505
			stack.param.curlaw = DAHDI_LAW_ALAW;
3506
		else
3507
			stack.param.curlaw = DAHDI_LAW_MULAW;
3508
3509
		if (copy_to_user((struct dahdi_params *) data, &stack.param, size_to_copy))
3510
			return -EFAULT;
3511
3512
		break;
3513
		/* set channel parameters */
3514
	case DAHDI_SET_PARAMS:
3515
		if (copy_from_user(&stack.param, (struct dahdi_params *) data, sizeof(struct dahdi_params)))
3516
			return -EFAULT;
3517
3518
		stack.param.chan_alarms = 0; /* be explicit about the above */
3519
3520
		/* Pick the right channo's */
3521
		if (!stack.param.channo || unit) {
3522
			stack.param.channo = unit;
3523
		}
3524
		/* Check validity of channel */
3525
		VALID_CHANNEL(stack.param.channo);
3526
		chan = chans[stack.param.channo];
3527
		  /* point to relevant structure */
3528
		/* NOTE: sigtype is *not* included in this */
3529
		  /* get timing stack.paramters */
3530
		chan->prewinktime = stack.param.prewinktime;
3531
		chan->preflashtime = stack.param.preflashtime;
3532
		chan->winktime = stack.param.winktime;
3533
		chan->flashtime = stack.param.flashtime;
3534
		chan->starttime = stack.param.starttime;
3535
		/* Update ringtime if not using a tone zone */
3536
		if (!chan->curzone)
3537
			chan->ringcadence[0] = chan->starttime;
3538
		chan->rxwinktime = stack.param.rxwinktime;
3539
		chan->rxflashtime = stack.param.rxflashtime;
3540
		chan->debouncetime = stack.param.debouncetime;
3541
		chan->pulsemaketime = stack.param.pulsemaketime;
3542
		chan->pulsebreaktime = stack.param.pulsebreaktime;
3543
		chan->pulseaftertime = stack.param.pulseaftertime;
3544
		break;
3545
	case DAHDI_GETGAINS_V1: /* Intentional drop through. */
3546
	case DAHDI_GETGAINS:  /* get gain stuff */
3547
		if (copy_from_user(&stack.gain,(struct dahdi_gains *) data,sizeof(stack.gain)))
3548
			return -EFAULT;
3549
		i = stack.gain.chan;  /* get channel no */
3550
		   /* if zero, use current channel no */
3551
		if (!i) i = unit;
3552
		  /* make sure channel number makes sense */
3553
		if ((i < 0) || (i > DAHDI_MAX_CHANNELS) || !chans[i]) return(-EINVAL);
3554
3555
		if (!(chans[i]->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
3556
		stack.gain.chan = i; /* put the span # in here */
3557
		for (j=0;j<256;j++)  {
3558
			stack.gain.txgain[j] = chans[i]->txgain[j];
3559
			stack.gain.rxgain[j] = chans[i]->rxgain[j];
3560
		}
3561
		if (copy_to_user((struct dahdi_gains *) data,&stack.gain,sizeof(stack.gain)))
3562
			return -EFAULT;
3563
		break;
3564
	case DAHDI_SETGAINS:  /* set gain stuff */
3565
		if (copy_from_user(&stack.gain,(struct dahdi_gains *) data,sizeof(stack.gain)))
3566
			return -EFAULT;
3567
		i = stack.gain.chan;  /* get channel no */
3568
		   /* if zero, use current channel no */
3569
		if (!i) i = unit;
3570
		  /* make sure channel number makes sense */
3571
		if ((i < 0) || (i > DAHDI_MAX_CHANNELS) || !chans[i]) return(-EINVAL);
3572
		if (!(chans[i]->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
3573
3574
		if (!(rxgain = kmalloc(512, GFP_KERNEL)))
3575
			return -ENOMEM;
3576
3577
		stack.gain.chan = i; /* put the span # in here */
3578
		txgain = rxgain + 256;
3579
3580
		for (j=0;j<256;j++) {
3581
			rxgain[j] = stack.gain.rxgain[j];
3582
			txgain[j] = stack.gain.txgain[j];
3583
		}
3584
3585
		if (!memcmp(rxgain, defgain, 256) &&
3586
		    !memcmp(txgain, defgain, 256)) {
3587
			if (rxgain)
3588
				kfree(rxgain);
3589
			spin_lock_irqsave(&chans[i]->lock, flags);
3590
			if (chans[i]->gainalloc)
3591
				kfree(chans[i]->rxgain);
3592
			chans[i]->gainalloc = 0;
3593
			chans[i]->rxgain = defgain;
3594
			chans[i]->txgain = defgain;
3595
			spin_unlock_irqrestore(&chans[i]->lock, flags);
3596
		} else {
3597
			/* This is a custom gain setting */
3598
			spin_lock_irqsave(&chans[i]->lock, flags);
3599
			if (chans[i]->gainalloc)
3600
				kfree(chans[i]->rxgain);
3601
			chans[i]->gainalloc = 1;
3602
			chans[i]->rxgain = rxgain;
3603
			chans[i]->txgain = txgain;
3604
			spin_unlock_irqrestore(&chans[i]->lock, flags);
3605
		}
3606
		if (copy_to_user((struct dahdi_gains *) data,&stack.gain,sizeof(stack.gain)))
3607
			return -EFAULT;
3608
		break;
3609
	case DAHDI_SPANSTAT:
3610
		size_to_copy = sizeof(struct dahdi_spaninfo);
3611
		if (copy_from_user(&stack.spaninfo, (struct dahdi_spaninfo *) data, size_to_copy))
3612
			return -EFAULT;
3613
		i = stack.spaninfo.spanno; /* get specified span number */
3614
		if ((i < 0) || (i >= maxspans)) return(-EINVAL);  /* if bad span no */
3615
		if (i == 0) {
3616
			/* if to figure it out for this chan */
3617
			if (!chans[unit])
3618
				return -EINVAL;
3619
			i = chans[unit]->span->spanno;
3620
		}
3621
		if (!spans[i])
3622
			return -EINVAL;
3623
		stack.spaninfo.spanno = i; /* put the span # in here */
3624
		stack.spaninfo.totalspans = 0;
3625
		if (maxspans) stack.spaninfo.totalspans = maxspans - 1; /* put total number of spans here */
3626
		dahdi_copy_string(stack.spaninfo.desc, spans[i]->desc, sizeof(stack.spaninfo.desc));
3627
		dahdi_copy_string(stack.spaninfo.name, spans[i]->name, sizeof(stack.spaninfo.name));
3628
		stack.spaninfo.alarms = spans[i]->alarms;		/* get alarm status */
3629
		stack.spaninfo.bpvcount = spans[i]->bpvcount;	/* get BPV count */
3630
		stack.spaninfo.rxlevel = spans[i]->rxlevel;	/* get rx level */
3631
		stack.spaninfo.txlevel = spans[i]->txlevel;	/* get tx level */
3632
		stack.spaninfo.crc4count = spans[i]->crc4count;	/* get CRC4 error count */
3633
		stack.spaninfo.ebitcount = spans[i]->ebitcount;	/* get E-bit error count */
3634
		stack.spaninfo.fascount = spans[i]->fascount;	/* get FAS error count */
3635
		stack.spaninfo.irqmisses = spans[i]->irqmisses;	/* get IRQ miss count */
3636
		stack.spaninfo.syncsrc = spans[i]->syncsrc;	/* get active sync source */
3637
		stack.spaninfo.totalchans = spans[i]->channels;
3638
		stack.spaninfo.numchans = 0;
3639
		for (j = 0; j < spans[i]->channels; j++) {
3640
			if (spans[i]->chans[j]->sig)
3641
				stack.spaninfo.numchans++;
3642
		}
3643
		stack.spaninfo.lbo = spans[i]->lbo;
3644
		stack.spaninfo.lineconfig = spans[i]->lineconfig;
3645
		stack.spaninfo.irq = spans[i]->irq;
3646
		stack.spaninfo.linecompat = spans[i]->linecompat;
3647
		dahdi_copy_string(stack.spaninfo.lboname, dahdi_lboname(spans[i]->lbo), sizeof(stack.spaninfo.lboname));
3648
		if (spans[i]->manufacturer)
3649
			dahdi_copy_string(stack.spaninfo.manufacturer, spans[i]->manufacturer,
3650
				sizeof(stack.spaninfo.manufacturer));
3651
		if (spans[i]->devicetype)
3652
			dahdi_copy_string(stack.spaninfo.devicetype, spans[i]->devicetype, sizeof(stack.spaninfo.devicetype));
3653
		dahdi_copy_string(stack.spaninfo.location, spans[i]->location, sizeof(stack.spaninfo.location));
3654
		if (spans[i]->spantype)
3655
			dahdi_copy_string(stack.spaninfo.spantype, spans[i]->spantype, sizeof(stack.spaninfo.spantype));
3656
3657
		if (copy_to_user((struct dahdi_spaninfo *) data, &stack.spaninfo, size_to_copy))
3658
			return -EFAULT;
3659
		break;
3660
	case DAHDI_CHANDIAG_V1: /* Intentional drop through. */
3661
	case DAHDI_CHANDIAG:
3662
	{
3663
		/* there really is no need to initialize this structure because when it is used it has
3664
		 * already been completely overwritten, but apparently the compiler cannot figure that
3665
		 * out and warns about uninitialized usage... so initialize it.
3666
		 */
3667
		struct dahdi_echocan_state ec_state = { .ops = NULL, };
3668
3669
		get_user(j, (int *) data); /* get channel number from user */
3670
		/* make sure its a valid channel number */
3671
		if ((j < 1) || (j >= maxchans))
3672
			return -EINVAL;
3673
		/* if channel not mapped, not there */
3674
		if (!chans[j])
3675
			return -EINVAL;
3676
3677
		chan = kmalloc(sizeof(*chan), GFP_KERNEL);
3678
		if (!chan)
3679
			return -ENOMEM;
3680
3681
		/* lock channel */
3682
		spin_lock_irqsave(&chans[j]->lock, flags);
3683
		/* make static copy of channel */
3684
		*chan = *chans[j];
3685
		if (chan->ec_state) {
3686
			ec_state = *chan->ec_state;
3687
		}
3688
		/* release it. */
3689
		spin_unlock_irqrestore(&chans[j]->lock, flags);
3690
3691
		module_printk(KERN_INFO, "Dump of DAHDI Channel %d (%s,%d,%d):\n\n",j,
3692
			      chan->name, chan->channo, chan->chanpos);
3693
		module_printk(KERN_INFO, "flags: %x hex, writechunk: %p, readchunk: %p\n",
3694
			      (unsigned int) chan->flags, chan->writechunk, chan->readchunk);
3695
		module_printk(KERN_INFO, "rxgain: %p, txgain: %p, gainalloc: %d\n",
3696
			      chan->rxgain, chan->txgain, chan->gainalloc);
3697
		module_printk(KERN_INFO, "span: %p, sig: %x hex, sigcap: %x hex\n",
3698
			      chan->span, chan->sig, chan->sigcap);
3699
		module_printk(KERN_INFO, "inreadbuf: %d, outreadbuf: %d, inwritebuf: %d, outwritebuf: %d\n",
3700
			      chan->inreadbuf, chan->outreadbuf, chan->inwritebuf, chan->outwritebuf);
3701
		module_printk(KERN_INFO, "blocksize: %d, numbufs: %d, txbufpolicy: %d, txbufpolicy: %d\n",
3702
			      chan->blocksize, chan->numbufs, chan->txbufpolicy, chan->rxbufpolicy);
3703
		module_printk(KERN_INFO, "txdisable: %d, rxdisable: %d, iomask: %d\n",
3704
			      chan->txdisable, chan->rxdisable, chan->iomask);
3705
		module_printk(KERN_INFO, "curzone: %p, tonezone: %d, curtone: %p, tonep: %d\n",
3706
			      chan->curzone, chan->tonezone, chan->curtone, chan->tonep);
3707
		module_printk(KERN_INFO, "digitmode: %d, txdialbuf: %s, dialing: %d, aftdialtimer: %d, cadpos. %d\n",
3708
			      chan->digitmode, chan->txdialbuf, chan->dialing,
3709
			      chan->afterdialingtimer, chan->cadencepos);
3710
		module_printk(KERN_INFO, "confna: %d, confn: %d, confmode: %d, confmute: %d\n",
3711
			      chan->confna, chan->_confn, chan->confmode, chan->confmute);
3712
		module_printk(KERN_INFO, "ec: %p, deflaw: %d, xlaw: %p\n",
3713
			      chan->ec_state, chan->deflaw, chan->xlaw);
3714
		if (chan->ec_state) {
3715
			module_printk(KERN_INFO, "echostate: %02x, echotimer: %d, echolastupdate: %d\n",
3716
				      ec_state.status.mode, ec_state.status.pretrain_timer, ec_state.status.last_train_tap);
3717
		}
3718
		module_printk(KERN_INFO, "itimer: %d, otimer: %d, ringdebtimer: %d\n\n",
3719
			      chan->itimer, chan->otimer, chan->ringdebtimer);
3720
		kfree(chan);
3721
		break;
3722
	}
3723
	default:
3724
		return -ENOTTY;
3725
	}
3726
	return 0;
3727
}
3728
3729
static int (*dahdi_dynamic_ioctl)(unsigned int cmd, unsigned long data);
3730
3731
void dahdi_set_dynamic_ioctl(int (*func)(unsigned int cmd, unsigned long data))
3732
{
3733
	dahdi_dynamic_ioctl = func;
3734
}
3735
3736
static int (*dahdi_hpec_ioctl)(unsigned int cmd, unsigned long data);
3737
3738
void dahdi_set_hpec_ioctl(int (*func)(unsigned int cmd, unsigned long data))
3739
{
3740
	dahdi_hpec_ioctl = func;
3741
}
3742
3743
static void recalc_slaves(struct dahdi_chan *chan)
3744
{
3745
	int x;
3746
	struct dahdi_chan *last = chan;
3747
3748
	/* Makes no sense if you don't have a span */
3749
	if (!chan->span)
3750
		return;
3751
3752
#ifdef CONFIG_DAHDI_DEBUG
3753
	module_printk(KERN_NOTICE, "Recalculating slaves on %s\n", chan->name);
3754
#endif
3755
3756
	/* Link all slaves appropriately */
3757
	for (x=chan->chanpos;x<chan->span->channels;x++)
3758
		if (chan->span->chans[x]->master == chan) {
3759
#ifdef CONFIG_DAHDI_DEBUG
3760
			module_printk(KERN_NOTICE, "Channel %s, slave to %s, last is %s, its next will be %d\n",
3761
				      chan->span->chans[x]->name, chan->name, last->name, x);
3762
#endif
3763
			last->nextslave = x;
3764
			last = chan->span->chans[x];
3765
		}
3766
	/* Terminate list */
3767
	last->nextslave = 0;
3768
#ifdef CONFIG_DAHDI_DEBUG
3769
	module_printk(KERN_NOTICE, "Done Recalculating slaves on %s (last is %s)\n", chan->name, last->name);
3770
#endif
3771
}
3772
3773
static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data)
3774
{
3775
	/* I/O CTL's for control interface */
3776
	int i,j;
3777
	int sigcap;
3778
	int res = 0;
3779
	int x,y;
3780
	struct dahdi_chan *newmaster;
3781
	unsigned long flags;
3782
	int rv;
3783
	switch(cmd) {
3784
	case DAHDI_INDIRECT:
3785
	{
3786
		struct dahdi_indirect_data ind;
3787
3788
		if (copy_from_user(&ind, (struct dahdi_indirect_data *)data, sizeof(ind)))
3789
			return -EFAULT;
3790
		VALID_CHANNEL(ind.chan);
3791
		return dahdi_chan_ioctl(inode, file, ind.op, (unsigned long) ind.data, ind.chan);
3792
	}
3793
	case DAHDI_SPANCONFIG:
3794
	{
3795
		struct dahdi_lineconfig lc;
3796
3797
		if (copy_from_user(&lc, (struct dahdi_lineconfig *)data, sizeof(lc)))
3798
			return -EFAULT;
3799
		VALID_SPAN(lc.span);
3800
		if ((lc.lineconfig & 0x07f0 & spans[lc.span]->linecompat) != (lc.lineconfig & 0x07f0))
3801
			return -EINVAL;
3802
		if (spans[lc.span]->spanconfig) {
3803
			spans[lc.span]->lineconfig = lc.lineconfig;
3804
			spans[lc.span]->lbo = lc.lbo;
3805
			spans[lc.span]->txlevel = lc.lbo;
3806
			spans[lc.span]->rxlevel = 0;
3807
3808
			return spans[lc.span]->spanconfig(spans[lc.span], &lc);
3809
		}
3810
		return 0;
3811
	}
3812
	case DAHDI_STARTUP:
3813
		CHECK_VALID_SPAN(j);
3814
		if (spans[j]->flags & DAHDI_FLAG_RUNNING)
3815
			return 0;
3816
		if (spans[j]->startup)
3817
			res = spans[j]->startup(spans[j]);
3818
		if (!res) {
3819
			/* Mark as running and hangup any channels */
3820
			spans[j]->flags |= DAHDI_FLAG_RUNNING;
3821
			for (x=0;x<spans[j]->channels;x++) {
3822
				y = dahdi_q_sig(spans[j]->chans[x]) & 0xff;
3823
				if (y >= 0) spans[j]->chans[x]->rxsig = (unsigned char)y;
3824
				spin_lock_irqsave(&spans[j]->chans[x]->lock, flags);
3825
				dahdi_hangup(spans[j]->chans[x]);
3826
				spin_unlock_irqrestore(&spans[j]->chans[x]->lock, flags);
3827
				spans[j]->chans[x]->rxhooksig = DAHDI_RXSIG_INITIAL;
3828
			}
3829
		}
3830
		return 0;
3831
	case DAHDI_SHUTDOWN:
3832
		CHECK_VALID_SPAN(j);
3833
		if (spans[j]->shutdown)
3834
			res =  spans[j]->shutdown(spans[j]);
3835
		spans[j]->flags &= ~DAHDI_FLAG_RUNNING;
3836
		return 0;
3837
	case DAHDI_ATTACH_ECHOCAN:
3838
	{
3839
		struct dahdi_attach_echocan ae;
3840
		const struct dahdi_echocan_factory *new = NULL, *old;
3841
3842
		if (copy_from_user(&ae, (struct dahdi_attach_echocan *) data, sizeof(ae))) {
3843
			return -EFAULT;
3844
		}
3845
3846
		VALID_CHANNEL(ae.chan);
3847
3848
		ae.echocan[sizeof(ae.echocan) - 1] = 0;
3849
		if (ae.echocan[0]) {
3850
			if (!(new = find_echocan(ae.echocan))) {
3851
				return -EINVAL;
3852
			}
3853
		}
3854
3855
		spin_lock_irqsave(&chans[ae.chan]->lock, flags);
3856
		old = chans[ae.chan]->ec_factory;
3857
		chans[ae.chan]->ec_factory = new;
3858
		spin_unlock_irqrestore(&chans[ae.chan]->lock, flags);
3859
3860
		if (old) {
3861
			release_echocan(old);
3862
		}
3863
3864
		break;
3865
	}
3866
	case DAHDI_CHANCONFIG:
3867
	{
3868
		struct dahdi_chanconfig ch;
3869
3870
		if (copy_from_user(&ch, (struct dahdi_chanconfig *)data, sizeof(ch)))
3871
			return -EFAULT;
3872
		VALID_CHANNEL(ch.chan);
3873
		if (ch.sigtype == DAHDI_SIG_SLAVE) {
3874
			/* We have to use the master's sigtype */
3875
			if ((ch.master < 1) || (ch.master >= DAHDI_MAX_CHANNELS))
3876
				return -EINVAL;
3877
			if (!chans[ch.master])
3878
				return -EINVAL;
3879
			ch.sigtype = chans[ch.master]->sig;
3880
			newmaster = chans[ch.master];
3881
		} else if ((ch.sigtype & __DAHDI_SIG_DACS) == __DAHDI_SIG_DACS) {
3882
			newmaster = chans[ch.chan];
3883
			if ((ch.idlebits < 1) || (ch.idlebits >= DAHDI_MAX_CHANNELS))
3884
				return -EINVAL;
3885
			if (!chans[ch.idlebits])
3886
				return -EINVAL;
3887
		} else {
3888
			newmaster = chans[ch.chan];
3889
		}
3890
		spin_lock_irqsave(&chans[ch.chan]->lock, flags);
3891
#ifdef CONFIG_DAHDI_NET
3892
		if (chans[ch.chan]->flags & DAHDI_FLAG_NETDEV) {
3893
			if (ztchan_to_dev(chans[ch.chan])->flags & IFF_UP) {
3894
				spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
3895
				module_printk(KERN_WARNING, "Can't switch HDLC net mode on channel %s, since current interface is up\n", chans[ch.chan]->name);
3896
				return -EBUSY;
3897
			}
3898
			spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
3899
			unregister_hdlc_device(chans[ch.chan]->hdlcnetdev->netdev);
3900
			spin_lock_irqsave(&chans[ch.chan]->lock, flags);
3901
			free_netdev(chans[ch.chan]->hdlcnetdev->netdev);
3902
			kfree(chans[ch.chan]->hdlcnetdev);
3903
			chans[ch.chan]->hdlcnetdev = NULL;
3904
			chans[ch.chan]->flags &= ~DAHDI_FLAG_NETDEV;
3905
		}
3906
#else
3907
		if (ch.sigtype == DAHDI_SIG_HDLCNET) {
3908
			spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
3909
			module_printk(KERN_WARNING, "DAHDI networking not supported by this build.\n");
3910
			return -ENOSYS;
3911
		}
3912
#endif
3913
		sigcap = chans[ch.chan]->sigcap;
3914
		/* If they support clear channel, then they support the HDLC and such through
3915
		   us.  */
3916
		if (sigcap & DAHDI_SIG_CLEAR)
3917
			sigcap |= (DAHDI_SIG_HDLCRAW | DAHDI_SIG_HDLCFCS | DAHDI_SIG_HDLCNET | DAHDI_SIG_DACS);
3918
3919
		if ((sigcap & ch.sigtype) != ch.sigtype)
3920
			res = -EINVAL;
3921
3922
		if (!res && chans[ch.chan]->span->chanconfig)
3923
			res = chans[ch.chan]->span->chanconfig(chans[ch.chan], ch.sigtype);
3924
3925
		if (chans[ch.chan]->master != chans[ch.chan]) {
3926
			struct dahdi_chan *oldmaster = chans[ch.chan]->master;
3927
3928
			/* Clear the master channel */
3929
			chans[ch.chan]->master = chans[ch.chan];
3930
			chans[ch.chan]->nextslave = 0;
3931
			/* Unlink this channel from the master's channel list */
3932
			recalc_slaves(oldmaster);
3933
		}
3934
3935
		if (!res) {
3936
			chans[ch.chan]->sig = ch.sigtype;
3937
			if (chans[ch.chan]->sig == DAHDI_SIG_CAS)
3938
				chans[ch.chan]->idlebits = ch.idlebits;
3939
			else
3940
				chans[ch.chan]->idlebits = 0;
3941
			if ((ch.sigtype & DAHDI_SIG_CLEAR) == DAHDI_SIG_CLEAR) {
3942
				/* Set clear channel flag if appropriate */
3943
				chans[ch.chan]->flags &= ~DAHDI_FLAG_AUDIO;
3944
				chans[ch.chan]->flags |= DAHDI_FLAG_CLEAR;
3945
			} else {
3946
				/* Set audio flag and not clear channel otherwise */
3947
				chans[ch.chan]->flags |= DAHDI_FLAG_AUDIO;
3948
				chans[ch.chan]->flags &= ~DAHDI_FLAG_CLEAR;
3949
			}
3950
			if ((ch.sigtype & DAHDI_SIG_HDLCRAW) == DAHDI_SIG_HDLCRAW) {
3951
				/* Set the HDLC flag */
3952
				chans[ch.chan]->flags |= DAHDI_FLAG_HDLC;
3953
			} else {
3954
				/* Clear the HDLC flag */
3955
				chans[ch.chan]->flags &= ~DAHDI_FLAG_HDLC;
3956
			}
3957
			if ((ch.sigtype & DAHDI_SIG_HDLCFCS) == DAHDI_SIG_HDLCFCS) {
3958
				/* Set FCS to be calculated if appropriate */
3959
				chans[ch.chan]->flags |= DAHDI_FLAG_FCS;
3960
			} else {
3961
				/* Clear FCS flag */
3962
				chans[ch.chan]->flags &= ~DAHDI_FLAG_FCS;
3963
			}
3964
			if ((ch.sigtype & __DAHDI_SIG_DACS) == __DAHDI_SIG_DACS) {
3965
				/* Setup conference properly */
3966
				chans[ch.chan]->confmode = DAHDI_CONF_DIGITALMON;
3967
				chans[ch.chan]->confna = ch.idlebits;
3968
				if (chans[ch.chan]->span &&
3969
				    chans[ch.chan]->span->dacs &&
3970
				    chans[ch.idlebits] &&
3971
				    chans[ch.chan]->span &&
3972
				    (chans[ch.chan]->span->dacs == chans[ch.idlebits]->span->dacs))
3973
					chans[ch.chan]->span->dacs(chans[ch.chan], chans[ch.idlebits]);
3974
			} else if (chans[ch.chan]->span && chans[ch.chan]->span->dacs) {
3975
				chans[ch.chan]->span->dacs(chans[ch.chan], NULL);
3976
			}
3977
			chans[ch.chan]->master = newmaster;
3978
			/* Note new slave if we are not our own master */
3979
			if (newmaster != chans[ch.chan]) {
3980
				recalc_slaves(chans[ch.chan]->master);
3981
			}
3982
			if ((ch.sigtype & DAHDI_SIG_HARDHDLC) == DAHDI_SIG_HARDHDLC) {
3983
				chans[ch.chan]->flags &= ~DAHDI_FLAG_FCS;
3984
				chans[ch.chan]->flags &= ~DAHDI_FLAG_HDLC;
3985
				chans[ch.chan]->flags |= DAHDI_FLAG_NOSTDTXRX;
3986
			} else {
3987
				chans[ch.chan]->flags &= ~DAHDI_FLAG_NOSTDTXRX;
3988
			}
3989
3990
			if ((ch.sigtype & DAHDI_SIG_MTP2) == DAHDI_SIG_MTP2)
3991
				chans[ch.chan]->flags |= DAHDI_FLAG_MTP2;
3992
			else
3993
				chans[ch.chan]->flags &= ~DAHDI_FLAG_MTP2;
3994
		}
3995
#ifdef CONFIG_DAHDI_NET
3996
		if (!res &&
3997
		    (newmaster == chans[ch.chan]) &&
3998
		    (chans[ch.chan]->sig == DAHDI_SIG_HDLCNET)) {
3999
			chans[ch.chan]->hdlcnetdev = dahdi_hdlc_alloc();
4000
			if (chans[ch.chan]->hdlcnetdev) {
4001
/*				struct hdlc_device *hdlc = chans[ch.chan]->hdlcnetdev;
4002
				struct net_device *d = hdlc_to_dev(hdlc); mmm...get it right later --byg */
4003
4004
				chans[ch.chan]->hdlcnetdev->netdev = alloc_hdlcdev(chans[ch.chan]->hdlcnetdev);
4005
				if (chans[ch.chan]->hdlcnetdev->netdev) {
4006
					chans[ch.chan]->hdlcnetdev->chan = chans[ch.chan];
4007
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
4008
					SET_MODULE_OWNER(chans[ch.chan]->hdlcnetdev->netdev);
4009
#endif
4010
					chans[ch.chan]->hdlcnetdev->netdev->irq = chans[ch.chan]->span->irq;
4011
					chans[ch.chan]->hdlcnetdev->netdev->tx_queue_len = 50;
4012
					chans[ch.chan]->hdlcnetdev->netdev->do_ioctl = dahdi_net_ioctl;
4013
					chans[ch.chan]->hdlcnetdev->netdev->open = dahdi_net_open;
4014
					chans[ch.chan]->hdlcnetdev->netdev->stop = dahdi_net_stop;
4015
					dev_to_hdlc(chans[ch.chan]->hdlcnetdev->netdev)->attach = dahdi_net_attach;
4016
					dev_to_hdlc(chans[ch.chan]->hdlcnetdev->netdev)->xmit = dahdi_xmit;
4017
					spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
4018
					/* Briefly restore interrupts while we register the device */
4019
					res = dahdi_register_hdlc_device(chans[ch.chan]->hdlcnetdev->netdev, ch.netdev_name);
4020
					spin_lock_irqsave(&chans[ch.chan]->lock, flags);
4021
				} else {
4022
					module_printk(KERN_NOTICE, "Unable to allocate hdlc: *shrug*\n");
4023
					res = -1;
4024
				}
4025
				if (!res)
4026
					chans[ch.chan]->flags |= DAHDI_FLAG_NETDEV;
4027
			} else {
4028
				module_printk(KERN_NOTICE, "Unable to allocate netdev: out of memory\n");
4029
				res = -1;
4030
			}
4031
		}
4032
#endif
4033
		if ((chans[ch.chan]->sig == DAHDI_SIG_HDLCNET) &&
4034
		    (chans[ch.chan] == newmaster) &&
4035
		    !(chans[ch.chan]->flags & DAHDI_FLAG_NETDEV))
4036
			module_printk(KERN_NOTICE, "Unable to register HDLC device for channel %s\n", chans[ch.chan]->name);
4037
		if (!res) {
4038
			/* Setup default law */
4039
			chans[ch.chan]->deflaw = ch.deflaw;
4040
			/* Copy back any modified settings */
4041
			spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
4042
			if (copy_to_user((struct dahdi_chanconfig *)data, &ch, sizeof(ch)))
4043
				return -EFAULT;
4044
			spin_lock_irqsave(&chans[ch.chan]->lock, flags);
4045
			/* And hangup */
4046
			dahdi_hangup(chans[ch.chan]);
4047
			y = dahdi_q_sig(chans[ch.chan]) & 0xff;
4048
			if (y >= 0)
4049
				chans[ch.chan]->rxsig = (unsigned char) y;
4050
			chans[ch.chan]->rxhooksig = DAHDI_RXSIG_INITIAL;
4051
		}
4052
#ifdef CONFIG_DAHDI_DEBUG
4053
		module_printk(KERN_NOTICE, "Configured channel %s, flags %04lx, sig %04x\n", chans[ch.chan]->name, chans[ch.chan]->flags, chans[ch.chan]->sig);
4054
#endif
4055
		spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
4056
4057
		return res;
4058
	}
4059
	case DAHDI_SFCONFIG:
4060
	{
4061
		struct dahdi_sfconfig sf;
4062
4063
		if (copy_from_user(&sf, (struct dahdi_chanconfig *)data, sizeof(sf)))
4064
			return -EFAULT;
4065
		VALID_CHANNEL(sf.chan);
4066
		if (chans[sf.chan]->sig != DAHDI_SIG_SF) return -EINVAL;
4067
		spin_lock_irqsave(&chans[sf.chan]->lock, flags);
4068
		chans[sf.chan]->rxp1 = sf.rxp1;
4069
		chans[sf.chan]->rxp2 = sf.rxp2;
4070
		chans[sf.chan]->rxp3 = sf.rxp3;
4071
		chans[sf.chan]->txtone = sf.txtone;
4072
		chans[sf.chan]->tx_v2 = sf.tx_v2;
4073
		chans[sf.chan]->tx_v3 = sf.tx_v3;
4074
		chans[sf.chan]->toneflags = sf.toneflag;
4075
		if (sf.txtone) /* if set to make tone for tx */
4076
		{
4077
			if ((chans[sf.chan]->txhooksig && !(sf.toneflag & DAHDI_REVERSE_TXTONE)) ||
4078
			 ((!chans[sf.chan]->txhooksig) && (sf.toneflag & DAHDI_REVERSE_TXTONE)))
4079
			{
4080
				set_txtone(chans[sf.chan],sf.txtone,sf.tx_v2,sf.tx_v3);
4081
			}
4082
			else
4083
			{
4084
				set_txtone(chans[sf.chan],0,0,0);
4085
			}
4086
		}
4087
		spin_unlock_irqrestore(&chans[sf.chan]->lock, flags);
4088
		return res;
4089
	}
4090
	case DAHDI_DEFAULTZONE:
4091
		if (get_user(j,(int *)data))
4092
			return -EFAULT;
4093
		return dahdi_set_default_zone(j);
4094
	case DAHDI_LOADZONE:
4095
		return ioctl_load_zone(data);
4096
	case DAHDI_FREEZONE:
4097
		get_user(j, (int *) data);
4098
		return free_tone_zone(j);
4099
	case DAHDI_SET_DIALPARAMS:
4100
	{
4101
		struct dahdi_dialparams tdp;
4102
4103
		if (copy_from_user(&tdp, (struct dahdi_dialparams *) data, sizeof(tdp)))
4104
			return -EFAULT;
4105
4106
		if ((tdp.dtmf_tonelen >= 10) && (tdp.dtmf_tonelen <= 4000)) {
4107
			global_dialparams.dtmf_tonelen = tdp.dtmf_tonelen;
4108
		}
4109
		if ((tdp.mfv1_tonelen >= 10) && (tdp.mfv1_tonelen <= 4000)) {
4110
			global_dialparams.mfv1_tonelen = tdp.mfv1_tonelen;
4111
		}
4112
		if ((tdp.mfr2_tonelen >= 10) && (tdp.mfr2_tonelen <= 4000)) {
4113
			global_dialparams.mfr2_tonelen = tdp.mfr2_tonelen;
4114
		}
4115
4116
		/* update the lengths in all currently loaded zones */
4117
		write_lock(&zone_lock);
4118
		for (j = 0; j < ARRAY_SIZE(tone_zones); j++) {
4119
			struct dahdi_zone *z = tone_zones[j];
4120
4121
			if (!z)
4122
				continue;
4123
4124
			for (i = 0; i < ARRAY_SIZE(z->dtmf); i++) {
4125
				z->dtmf[i].tonesamples = global_dialparams.dtmf_tonelen * DAHDI_CHUNKSIZE;
4126
			}
4127
4128
			/* for MFR1, we only adjust the length of the digits */
4129
			for (i = DAHDI_TONE_MFR1_0; i <= DAHDI_TONE_MFR1_9; i++) {
4130
				z->mfr1[i - DAHDI_TONE_MFR1_BASE].tonesamples = global_dialparams.mfv1_tonelen * DAHDI_CHUNKSIZE;
4131
			}
4132
4133
			for (i = 0; i < ARRAY_SIZE(z->mfr2_fwd); i++) {
4134
				z->mfr2_fwd[i].tonesamples = global_dialparams.mfr2_tonelen * DAHDI_CHUNKSIZE;
4135
			}
4136
4137
			for (i = 0; i < ARRAY_SIZE(z->mfr2_rev); i++) {
4138
				z->mfr2_rev[i].tonesamples = global_dialparams.mfr2_tonelen * DAHDI_CHUNKSIZE;
4139
			}
4140
		}
4141
		write_unlock(&zone_lock);
4142
4143
		dtmf_silence.tonesamples = global_dialparams.dtmf_tonelen * DAHDI_CHUNKSIZE;
4144
		mfr1_silence.tonesamples = global_dialparams.mfv1_tonelen * DAHDI_CHUNKSIZE;
4145
		mfr2_silence.tonesamples = global_dialparams.mfr2_tonelen * DAHDI_CHUNKSIZE;
4146
4147
		break;
4148
	}
4149
	case DAHDI_GET_DIALPARAMS:
4150
	{
4151
		struct dahdi_dialparams tdp;
4152
4153
		tdp = global_dialparams;
4154
		if (copy_to_user((struct dahdi_dialparams *) data, &tdp, sizeof(tdp)))
4155
			return -EFAULT;
4156
		break;
4157
	}
4158
	case DAHDI_GETVERSION:
4159
	{
4160
		struct dahdi_versioninfo vi;
4161
		struct ecfactory *cur;
4162
		size_t space = sizeof(vi.echo_canceller) - 1;
4163
4164
		memset(&vi, 0, sizeof(vi));
4165
		dahdi_copy_string(vi.version, DAHDI_VERSION, sizeof(vi.version));
4166
		read_lock(&ecfactory_list_lock);
4167
		list_for_each_entry(cur, &ecfactory_list, list) {
4168
			strncat(vi.echo_canceller + strlen(vi.echo_canceller), cur->ec->name, space);
4169
			space -= strlen(cur->ec->name);
4170
			if (space < 1) {
4171
				break;
4172
			}
4173
			if (cur->list.next && (cur->list.next != &ecfactory_list)) {
4174
				strncat(vi.echo_canceller + strlen(vi.echo_canceller), ", ", space);
4175
				space -= 2;
4176
				if (space < 1) {
4177
					break;
4178
				}
4179
			}
4180
		}
4181
		read_unlock(&ecfactory_list_lock);
4182
		if (copy_to_user((struct dahdi_versioninfo *) data, &vi, sizeof(vi)))
4183
			return -EFAULT;
4184
		break;
4185
	}
4186
	case DAHDI_MAINT:  /* do maintenance stuff */
4187
	{
4188
		struct dahdi_maintinfo maint;
4189
		  /* get struct from user */
4190
		if (copy_from_user(&maint,(struct dahdi_maintinfo *) data, sizeof(maint)))
4191
			return -EFAULT;
4192
		/* must be valid span number */
4193
		if ((maint.spanno < 1) || (maint.spanno > DAHDI_MAX_SPANS) || (!spans[maint.spanno]))
4194
			return -EINVAL;
4195
		if (!spans[maint.spanno]->maint)
4196
			return -ENOSYS;
4197
		spin_lock_irqsave(&spans[maint.spanno]->lock, flags);
4198
		  /* save current maint state */
4199
		i = spans[maint.spanno]->maintstat;
4200
		  /* set maint mode */
4201
		spans[maint.spanno]->maintstat = maint.command;
4202
		switch(maint.command) {
4203
		case DAHDI_MAINT_NONE:
4204
		case DAHDI_MAINT_LOCALLOOP:
4205
		case DAHDI_MAINT_REMOTELOOP:
4206
			/* if same, ignore it */
4207
			if (i == maint.command)
4208
				break;
4209
			rv = spans[maint.spanno]->maint(spans[maint.spanno], maint.command);
4210
			spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags);
4211
			if (rv)
4212
				return rv;
4213
			spin_lock_irqsave(&spans[maint.spanno]->lock, flags);
4214
			break;
4215
		case DAHDI_MAINT_LOOPUP:
4216
		case DAHDI_MAINT_LOOPDOWN:
4217
			spans[maint.spanno]->mainttimer = DAHDI_LOOPCODE_TIME * DAHDI_CHUNKSIZE;
4218
			rv = spans[maint.spanno]->maint(spans[maint.spanno], maint.command);
4219
			spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags);
4220
			if (rv)
4221
				return rv;
4222
			rv = schluffen(&spans[maint.spanno]->maintq);
4223
			if (rv)
4224
				return rv;
4225
			spin_lock_irqsave(&spans[maint.spanno]->lock, flags);
4226
			break;
4227
		default:
4228
			module_printk(KERN_NOTICE, "Unknown maintenance event: %d\n", maint.command);
4229
		}
4230
		dahdi_alarm_notify(spans[maint.spanno]);  /* process alarm-related events */
4231
		spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags);
4232
		break;
4233
	}
4234
	case DAHDI_DYNAMIC_CREATE:
4235
	case DAHDI_DYNAMIC_DESTROY:
4236
		if (dahdi_dynamic_ioctl) {
4237
			return dahdi_dynamic_ioctl(cmd, data);
4238
		} else {
4239
			request_module("dahdi_dynamic");
4240
			if (dahdi_dynamic_ioctl)
4241
				return dahdi_dynamic_ioctl(cmd, data);
4242
		}
4243
		return -ENOSYS;
4244
	case DAHDI_EC_LICENSE_CHALLENGE:
4245
	case DAHDI_EC_LICENSE_RESPONSE:
4246
		if (dahdi_hpec_ioctl) {
4247
			return dahdi_hpec_ioctl(cmd, data);
4248
		} else {
4249
			request_module("dahdi_echocan_hpec");
4250
			if (dahdi_hpec_ioctl)
4251
				return dahdi_hpec_ioctl(cmd, data);
4252
		}
4253
		return -ENOSYS;
4254
	default:
4255
		return dahdi_common_ioctl(inode, file, cmd, data, 0);
4256
	}
4257
	return 0;
4258
}
4259
4260
static int ioctl_dahdi_dial(struct dahdi_chan *chan, unsigned long data)
4261
{
4262
	struct dahdi_dialoperation *tdo;
4263
	unsigned long flags;
4264
	char *s;
4265
	int rv;
4266
4267
	tdo = kmalloc(sizeof(*tdo), GFP_KERNEL);
4268
4269
	if (!tdo)
4270
		return -ENOMEM;
4271
4272
	if (copy_from_user(tdo, (struct dahdi_dialoperation *)data, sizeof(*tdo)))
4273
		return -EFAULT;
4274
	rv = 0;
4275
	/* Force proper NULL termination and uppercase entry */
4276
	tdo->dialstr[DAHDI_MAX_DTMF_BUF - 1] = '\0';
4277
	for (s = tdo->dialstr; *s; s++)
4278
		*s = toupper(*s);
4279
	spin_lock_irqsave(&chan->lock, flags);
4280
	if (!chan->curzone) {
4281
		spin_unlock_irqrestore(&chan->lock, flags);
4282
		/* The tone zones are loaded by dahdi_cfg from /etc/dahdi/system.conf */
4283
		module_printk(KERN_WARNING, "Cannot dial until a tone zone is loaded.\n");
4284
		return -ENODATA;
4285
	}
4286
	switch (tdo->op) {
4287
	case DAHDI_DIAL_OP_CANCEL:
4288
		chan->curtone = NULL;
4289
		chan->dialing = 0;
4290
		chan->txdialbuf[0] = '\0';
4291
		chan->tonep = 0;
4292
		chan->pdialcount = 0;
4293
		break;
4294
	case DAHDI_DIAL_OP_REPLACE:
4295
		strcpy(chan->txdialbuf, tdo->dialstr);
4296
		chan->dialing = 1;
4297
		__do_dtmf(chan);
4298
		break;
4299
	case DAHDI_DIAL_OP_APPEND:
4300
		if (strlen(tdo->dialstr) + strlen(chan->txdialbuf) >= (DAHDI_MAX_DTMF_BUF - 1)) {
4301
			rv = -EBUSY;
4302
			break;
4303
		}
4304
		dahdi_copy_string(chan->txdialbuf + strlen(chan->txdialbuf), tdo->dialstr, DAHDI_MAX_DTMF_BUF - strlen(chan->txdialbuf));
4305
		if (!chan->dialing) {
4306
			chan->dialing = 1;
4307
			__do_dtmf(chan);
4308
		}
4309
		break;
4310
	default:
4311
		rv = -EINVAL;
4312
	}
4313
	spin_unlock_irqrestore(&chan->lock, flags);
4314
	return rv;
4315
}
4316
4317
static int dahdi_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
4318
{
4319
	struct dahdi_chan *chan = chans[unit];
4320
	union {
4321
		struct dahdi_bufferinfo bi;
4322
		struct dahdi_confinfo conf;
4323
		struct dahdi_ring_cadence cad;
4324
	} stack;
4325
	unsigned long flags;
4326
	int i, j, k, rv;
4327
	int ret, c;
4328
4329
	if (!chan)
4330
		return -EINVAL;
4331
	switch(cmd) {
4332
	case DAHDI_DIALING:
4333
		spin_lock_irqsave(&chan->lock, flags);
4334
		j = chan->dialing;
4335
		spin_unlock_irqrestore(&chan->lock, flags);
4336
		if (copy_to_user((int *)data,&j,sizeof(int)))
4337
			return -EFAULT;
4338
		return 0;
4339
	case DAHDI_DIAL:
4340
		return ioctl_dahdi_dial(chan, data);
4341
	case DAHDI_GET_BUFINFO:
4342
		memset(&stack.bi, 0, sizeof(stack.bi));
4343
		stack.bi.rxbufpolicy = chan->rxbufpolicy;
4344
		stack.bi.txbufpolicy = chan->txbufpolicy;
4345
		stack.bi.numbufs = chan->numbufs;
4346
		stack.bi.bufsize = chan->blocksize;
4347
		/* XXX FIXME! XXX */
4348
		stack.bi.readbufs = -1;
4349
		stack.bi.writebufs = -1;
4350
		if (copy_to_user((struct dahdi_bufferinfo *)data, &stack.bi, sizeof(stack.bi)))
4351
			return -EFAULT;
4352
		break;
4353
	case DAHDI_SET_BUFINFO:
4354
		if (copy_from_user(&stack.bi, (struct dahdi_bufferinfo *)data, sizeof(stack.bi)))
4355
			return -EFAULT;
4356
		if (stack.bi.bufsize > DAHDI_MAX_BLOCKSIZE)
4357
			return -EINVAL;
4358
		if (stack.bi.bufsize < 16)
4359
			return -EINVAL;
4360
		if (stack.bi.bufsize * stack.bi.numbufs > DAHDI_MAX_BUF_SPACE)
4361
			return -EINVAL;
4362
		/* It does not make sense to allow user mode to change the
4363
		 * receive buffering policy.  DAHDI always provides received
4364
		 * buffers to upper layers immediately.  Transmission is
4365
		 * different since we might want to allow the kernel to build
4366
		 * up a buffer in order to prevent underruns from the
4367
		 * interrupt context. */
4368
		chan->txbufpolicy = stack.bi.txbufpolicy & 0x3;
4369
		if ((rv = dahdi_reallocbufs(chan,  stack.bi.bufsize, stack.bi.numbufs)))
4370
			return (rv);
4371
		break;
4372
	case DAHDI_GET_BLOCKSIZE:  /* get blocksize */
4373
		put_user(chan->blocksize,(int *)data); /* return block size */
4374
		break;
4375
	case DAHDI_SET_BLOCKSIZE:  /* set blocksize */
4376
		get_user(j,(int *)data);
4377
		  /* cannot be larger than max amount */
4378
		if (j > DAHDI_MAX_BLOCKSIZE) return(-EINVAL);
4379
		  /* cannot be less then 16 */
4380
		if (j < 16) return(-EINVAL);
4381
		  /* allocate a single kernel buffer which we then
4382
		     sub divide into four pieces */
4383
		if ((rv = dahdi_reallocbufs(chan, j, chan->numbufs)))
4384
			return (rv);
4385
		break;
4386
	case DAHDI_FLUSH:  /* flush input buffer, output buffer, and/or event queue */
4387
		get_user(i,(int *)data);  /* get param */
4388
		spin_lock_irqsave(&chan->lock, flags);
4389
		if (i & DAHDI_FLUSH_READ)  /* if for read (input) */
4390
		   {
4391
			  /* initialize read buffers and pointers */
4392
			chan->inreadbuf = 0;
4393
			chan->outreadbuf = -1;
4394
			for (j=0;j<chan->numbufs;j++) {
4395
				/* Do we need this? */
4396
				chan->readn[j] = 0;
4397
				chan->readidx[j] = 0;
4398
			}
4399
			wake_up_interruptible(&chan->readbufq);  /* wake_up_interruptible waiting on read */
4400
			wake_up_interruptible(&chan->sel); /* wake_up_interruptible waiting on select */
4401
		   }
4402
		if (i & DAHDI_FLUSH_WRITE) /* if for write (output) */
4403
		   {
4404
			  /* initialize write buffers and pointers */
4405
			chan->outwritebuf = -1;
4406
			chan->inwritebuf = 0;
4407
			for (j=0;j<chan->numbufs;j++) {
4408
				/* Do we need this? */
4409
				chan->writen[j] = 0;
4410
				chan->writeidx[j] = 0;
4411
			}
4412
			wake_up_interruptible(&chan->writebufq); /* wake_up_interruptible waiting on write */
4413
			wake_up_interruptible(&chan->sel);  /* wake_up_interruptible waiting on select */
4414
			   /* if IO MUX wait on write empty, well, this
4415
				certainly *did* empty the write */
4416
			if (chan->iomask & DAHDI_IOMUX_WRITEEMPTY)
4417
				wake_up_interruptible(&chan->eventbufq); /* wake_up_interruptible waiting on IOMUX */
4418
		   }
4419
		if (i & DAHDI_FLUSH_EVENT) /* if for events */
4420
		   {
4421
			   /* initialize the event pointers */
4422
			chan->eventinidx = chan->eventoutidx = 0;
4423
		   }
4424
		spin_unlock_irqrestore(&chan->lock, flags);
4425
		break;
4426
	case DAHDI_SYNC:  /* wait for no tx */
4427
		for(;;)  /* loop forever */
4428
		   {
4429
			spin_lock_irqsave(&chan->lock, flags);
4430
			  /* Know if there is a write pending */
4431
			i = (chan->outwritebuf > -1);
4432
			spin_unlock_irqrestore(&chan->lock, flags);
4433
			if (!i) break; /* skip if none */
4434
			rv = schluffen(&chan->writebufq);
4435
			if (rv) return(rv);
4436
		   }
4437
		break;
4438
	case DAHDI_IOMUX: /* wait for something to happen */
4439
		get_user(chan->iomask,(int*)data);  /* save mask */
4440
		if (!chan->iomask) return(-EINVAL);  /* cant wait for nothing */
4441
		for(;;)  /* loop forever */
4442
		   {
4443
			  /* has to have SOME mask */
4444
			ret = 0;  /* start with empty return value */
4445
			spin_lock_irqsave(&chan->lock, flags);
4446
			  /* if looking for read */
4447
			if (chan->iomask & DAHDI_IOMUX_READ)
4448
			   {
4449
				/* if read available */
4450
				if ((chan->outreadbuf > -1)  && !chan->rxdisable)
4451
					ret |= DAHDI_IOMUX_READ;
4452
			   }
4453
			  /* if looking for write avail */
4454
			if (chan->iomask & DAHDI_IOMUX_WRITE)
4455
			   {
4456
				if (chan->inwritebuf > -1)
4457
					ret |= DAHDI_IOMUX_WRITE;
4458
			   }
4459
			  /* if looking for write empty */
4460
			if (chan->iomask & DAHDI_IOMUX_WRITEEMPTY)
4461
			   {
4462
				  /* if everything empty -- be sure the transmitter is enabled */
4463
				chan->txdisable = 0;
4464
				if (chan->outwritebuf < 0)
4465
					ret |= DAHDI_IOMUX_WRITEEMPTY;
4466
			   }
4467
			  /* if looking for signalling event */
4468
			if (chan->iomask & DAHDI_IOMUX_SIGEVENT)
4469
			   {
4470
				  /* if event */
4471
				if (chan->eventinidx != chan->eventoutidx)
4472
					ret |= DAHDI_IOMUX_SIGEVENT;
4473
			   }
4474
			spin_unlock_irqrestore(&chan->lock, flags);
4475
			  /* if something to return, or not to wait */
4476
			if (ret || (chan->iomask & DAHDI_IOMUX_NOWAIT))
4477
			   {
4478
				  /* set return value */
4479
				put_user(ret,(int *)data);
4480
				break; /* get out of loop */
4481
			   }
4482
			rv = schluffen(&chan->eventbufq);
4483
			if (rv) return(rv);
4484
		   }
4485
		  /* clear IO MUX mask */
4486
		chan->iomask = 0;
4487
		break;
4488
	case DAHDI_GETEVENT:  /* Get event on queue */
4489
		  /* set up for no event */
4490
		j = DAHDI_EVENT_NONE;
4491
		spin_lock_irqsave(&chan->lock, flags);
4492
		  /* if some event in queue */
4493
		if (chan->eventinidx != chan->eventoutidx)
4494
		   {
4495
			j = chan->eventbuf[chan->eventoutidx++];
4496
			  /* get the data, bump index */
4497
			  /* if index overflow, set to beginning */
4498
			if (chan->eventoutidx >= DAHDI_MAX_EVENTSIZE)
4499
				chan->eventoutidx = 0;
4500
		   }
4501
		spin_unlock_irqrestore(&chan->lock, flags);
4502
		put_user(j,(int *)data);
4503
		break;
4504
	case DAHDI_CONFMUTE:  /* set confmute flag */
4505
		get_user(j,(int *)data);  /* get conf # */
4506
		if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
4507
		spin_lock_irqsave(&bigzaplock, flags);
4508
		chan->confmute = j;
4509
		spin_unlock_irqrestore(&bigzaplock, flags);
4510
		break;
4511
	case DAHDI_GETCONFMUTE:  /* get confmute flag */
4512
		if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
4513
		j = chan->confmute;
4514
		put_user(j,(int *)data);  /* get conf # */
4515
		rv = 0;
4516
		break;
4517
	case DAHDI_SETTONEZONE:
4518
		get_user(j, (int *) data);
4519
		rv = set_tone_zone(chan, j);
4520
		return rv;
4521
	case DAHDI_GETTONEZONE:
4522
		spin_lock_irqsave(&chan->lock, flags);
4523
		if (chan->curzone)
4524
			j = chan->tonezone;
4525
		spin_unlock_irqrestore(&chan->lock, flags);
4526
		put_user(j, (int *) data);
4527
		break;
4528
	case DAHDI_SENDTONE:
4529
		get_user(j,(int *)data);
4530
		spin_lock_irqsave(&chan->lock, flags);
4531
		rv = start_tone(chan, j);
4532
		spin_unlock_irqrestore(&chan->lock, flags);
4533
		return rv;
4534
	case DAHDI_GETCONF_V1: /* intentional drop through */
4535
	case DAHDI_GETCONF:  /* get conf stuff */
4536
		if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf)))
4537
			return -EFAULT;
4538
		i = stack.conf.chan;  /* get channel no */
4539
		   /* if zero, use current channel no */
4540
		if (!i) i = chan->channo;
4541
		  /* make sure channel number makes sense */
4542
		if ((i < 0) || (i > DAHDI_MAX_CONF) || (!chans[i])) return(-EINVAL);
4543
		if (!(chans[i]->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
4544
		stack.conf.chan = i;  /* get channel number */
4545
		stack.conf.confno = chans[i]->confna;  /* get conference number */
4546
		stack.conf.confmode = chans[i]->confmode; /* get conference mode */
4547
		if (copy_to_user((struct dahdi_confinfo *) data,&stack.conf,sizeof(stack.conf)))
4548
			return -EFAULT;
4549
		break;
4550
	case DAHDI_SETCONF_V1: /* Intentional fall through. */
4551
	case DAHDI_SETCONF:  /* set conf stuff */
4552
		if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf)))
4553
			return -EFAULT;
4554
		i = stack.conf.chan;  /* get channel no */
4555
		   /* if zero, use current channel no */
4556
		if (!i) i = chan->channo;
4557
		  /* make sure channel number makes sense */
4558
		if ((i < 1) || (i > DAHDI_MAX_CHANNELS) || (!chans[i])) return(-EINVAL);
4559
		if (!(chans[i]->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
4560
		if ((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR ||
4561
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORTX ||
4562
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH ||
4563
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_RX_PREECHO ||
4564
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_TX_PREECHO ||
4565
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH_PREECHO) {
4566
			/* Monitor mode -- it's a channel */
4567
			if ((stack.conf.confno < 0) || (stack.conf.confno >= DAHDI_MAX_CHANNELS) || !chans[stack.conf.confno]) return(-EINVAL);
4568
		} else {
4569
			  /* make sure conf number makes sense, too */
4570
			if ((stack.conf.confno < -1) || (stack.conf.confno > DAHDI_MAX_CONF)) return(-EINVAL);
4571
		}
4572
4573
		  /* if taking off of any conf, must have 0 mode */
4574
		if ((!stack.conf.confno) && stack.conf.confmode) return(-EINVAL);
4575
		  /* likewise if 0 mode must have no conf */
4576
		if ((!stack.conf.confmode) && stack.conf.confno) return (-EINVAL);
4577
		stack.conf.chan = i;  /* return with real channel # */
4578
		spin_lock_irqsave(&bigzaplock, flags);
4579
		spin_lock(&chan->lock);
4580
		if (stack.conf.confno == -1)
4581
			stack.conf.confno = dahdi_first_empty_conference();
4582
		if ((stack.conf.confno < 1) && (stack.conf.confmode)) {
4583
			/* No more empty conferences */
4584
			spin_unlock(&chan->lock);
4585
			spin_unlock_irqrestore(&bigzaplock, flags);
4586
			return -EBUSY;
4587
		}
4588
		  /* if changing confs, clear last added info */
4589
		if (stack.conf.confno != chans[i]->confna) {
4590
			memset(chans[i]->conflast, 0, DAHDI_MAX_CHUNKSIZE);
4591
			memset(chans[i]->conflast1, 0, DAHDI_MAX_CHUNKSIZE);
4592
			memset(chans[i]->conflast2, 0, DAHDI_MAX_CHUNKSIZE);
4593
		}
4594
		j = chans[i]->confna;  /* save old conference number */
4595
		chans[i]->confna = stack.conf.confno;   /* set conference number */
4596
		chans[i]->confmode = stack.conf.confmode;  /* set conference mode */
4597
		chans[i]->_confn = 0;		     /* Clear confn */
4598
		dahdi_check_conf(j);
4599
		dahdi_check_conf(stack.conf.confno);
4600
		if (chans[i]->span && chans[i]->span->dacs) {
4601
			if (((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_DIGITALMON) &&
4602
			    chans[stack.conf.confno]->span &&
4603
			    chans[stack.conf.confno]->span->dacs == chans[i]->span->dacs &&
4604
			    chans[i]->txgain == defgain &&
4605
			    chans[i]->rxgain == defgain &&
4606
			    chans[stack.conf.confno]->txgain == defgain &&
4607
			    chans[stack.conf.confno]->rxgain == defgain) {
4608
				chans[i]->span->dacs(chans[i], chans[stack.conf.confno]);
4609
			} else {
4610
				chans[i]->span->dacs(chans[i], NULL);
4611
			}
4612
		}
4613
		/* if we are going onto a conf */
4614
		if (stack.conf.confno &&
4615
			((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONF ||
4616
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFANN ||
4617
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFMON ||
4618
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFANNMON ||
4619
			(stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_REALANDPSEUDO)) {
4620
			/* Get alias */
4621
			chans[i]->_confn = dahdi_get_conf_alias(stack.conf.confno);
4622
		}
4623
4624
		if (chans[stack.conf.confno]) {
4625
			if ((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_RX_PREECHO ||
4626
			    (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_TX_PREECHO ||
4627
			    (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH_PREECHO)
4628
				chans[stack.conf.confno]->readchunkpreec = kmalloc(sizeof(*chans[stack.conf.confno]->readchunkpreec) * DAHDI_CHUNKSIZE, GFP_ATOMIC);
4629
			else {
4630
				if (chans[stack.conf.confno]->readchunkpreec) {
4631
					kfree(chans[stack.conf.confno]->readchunkpreec);
4632
					chans[stack.conf.confno]->readchunkpreec = NULL;
4633
				}
4634
			}
4635
		}
4636
4637
		spin_unlock(&chan->lock);
4638
		spin_unlock_irqrestore(&bigzaplock, flags);
4639
		if (copy_to_user((struct dahdi_confinfo *) data,&stack.conf,sizeof(stack.conf)))
4640
			return -EFAULT;
4641
		break;
4642
	case DAHDI_CONFLINK:  /* do conf link stuff */
4643
		if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
4644
		if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf)))
4645
			return -EFAULT;
4646
		  /* check sanity of arguments */
4647
		if ((stack.conf.chan < 0) || (stack.conf.chan > DAHDI_MAX_CONF)) return(-EINVAL);
4648
		if ((stack.conf.confno < 0) || (stack.conf.confno > DAHDI_MAX_CONF)) return(-EINVAL);
4649
		  /* cant listen to self!! */
4650
		if (stack.conf.chan && (stack.conf.chan == stack.conf.confno)) return(-EINVAL);
4651
		spin_lock_irqsave(&bigzaplock, flags);
4652
		spin_lock(&chan->lock);
4653
		  /* if to clear all links */
4654
		if ((!stack.conf.chan) && (!stack.conf.confno))
4655
		   {
4656
			   /* clear all the links */
4657
			memset(conf_links,0,sizeof(conf_links));
4658
			recalc_maxlinks();
4659
			spin_unlock(&chan->lock);
4660
			spin_unlock_irqrestore(&bigzaplock, flags);
4661
			break;
4662
		   }
4663
		rv = 0;  /* clear return value */
4664
		/* look for already existant specified combination */
4665
		for(i = 1; i <= DAHDI_MAX_CONF; i++)
4666
		   {
4667
			  /* if found, exit */
4668
			if ((conf_links[i].src == stack.conf.chan) &&
4669
				(conf_links[i].dst == stack.conf.confno)) break;
4670
		   }
4671
		if (i <= DAHDI_MAX_CONF) /* if found */
4672
		   {
4673
			if (!stack.conf.confmode) /* if to remove link */
4674
			   {
4675
				conf_links[i].src = conf_links[i].dst = 0;
4676
			   }
4677
			else /* if to add and already there, error */
4678
			   {
4679
				rv = -EEXIST;
4680
			   }
4681
		   }
4682
		else  /* if not found */
4683
		   {
4684
			if (stack.conf.confmode) /* if to add link */
4685
			   {
4686
				/* look for empty location */
4687
				for(i = 1; i <= DAHDI_MAX_CONF; i++)
4688
				   {
4689
					  /* if empty, exit loop */
4690
					if ((!conf_links[i].src) &&
4691
						 (!conf_links[i].dst)) break;
4692
				   }
4693
				   /* if empty spot found */
4694
				if (i <= DAHDI_MAX_CONF)
4695
				   {
4696
					conf_links[i].src = stack.conf.chan;
4697
					conf_links[i].dst = stack.conf.confno;
4698
				   }
4699
				else /* if no empties -- error */
4700
				   {
4701
					rv = -ENOSPC;
4702
				   }
4703
			   }
4704
			else /* if to remove, and not found -- error */
4705
			   {
4706
				rv = -ENOENT;
4707
			   }
4708
		   }
4709
		recalc_maxlinks();
4710
		spin_unlock(&chan->lock);
4711
		spin_unlock_irqrestore(&bigzaplock, flags);
4712
		return(rv);
4713
	case DAHDI_CONFDIAG_V1: /* Intention fall-through */
4714
	case DAHDI_CONFDIAG:  /* output diagnostic info to console */
4715
		if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
4716
		get_user(j,(int *)data);  /* get conf # */
4717
 		  /* loop thru the interesting ones */
4718
		for(i = ((j) ? j : 1); i <= ((j) ? j : DAHDI_MAX_CONF); i++)
4719
		   {
4720
			c = 0;
4721
			for(k = 1; k < DAHDI_MAX_CHANNELS; k++)
4722
			   {
4723
				  /* skip if no pointer */
4724
				if (!chans[k]) continue;
4725
				  /* skip if not in this conf */
4726
				if (chans[k]->confna != i) continue;
4727
				if (!c) module_printk(KERN_NOTICE, "Conf #%d:\n",i);
4728
				c = 1;
4729
				module_printk(KERN_NOTICE, "chan %d, mode %x\n", k,chans[k]->confmode);
4730
			   }
4731
			rv = 0;
4732
			for(k = 1; k <= DAHDI_MAX_CONF; k++)
4733
			   {
4734
				if (conf_links[k].dst == i)
4735
				   {
4736
					if (!c) module_printk(KERN_NOTICE, "Conf #%d:\n",i);
4737
					c = 1;
4738
					if (!rv) module_printk(KERN_NOTICE, "Snooping on:\n");
4739
					rv = 1;
4740
					module_printk(KERN_NOTICE, "conf %d\n",conf_links[k].src);
4741
				   }
4742
			   }
4743
			if (c) module_printk(KERN_NOTICE, "\n");
4744
		   }
4745
		break;
4746
	case DAHDI_CHANNO:  /* get channel number of stream */
4747
		put_user(unit,(int *)data); /* return unit/channel number */
4748
		break;
4749
	case DAHDI_SETLAW:
4750
		get_user(j, (int *)data);
4751
		if ((j < 0) || (j > DAHDI_LAW_ALAW))
4752
			return -EINVAL;
4753
		dahdi_set_law(chan, j);
4754
		break;
4755
	case DAHDI_SETLINEAR:
4756
		get_user(j, (int *)data);
4757
		/* Makes no sense on non-audio channels */
4758
		if (!(chan->flags & DAHDI_FLAG_AUDIO))
4759
			return -EINVAL;
4760
4761
		if (j)
4762
			chan->flags |= DAHDI_FLAG_LINEAR;
4763
		else
4764
			chan->flags &= ~DAHDI_FLAG_LINEAR;
4765
		break;
4766
	case DAHDI_SETCADENCE:
4767
		if (data) {
4768
			/* Use specific ring cadence */
4769
			if (copy_from_user(&stack.cad, (struct dahdi_ring_cadence *)data, sizeof(stack.cad)))
4770
				return -EFAULT;
4771
			memcpy(chan->ringcadence, &stack.cad, sizeof(chan->ringcadence));
4772
			chan->firstcadencepos = 0;
4773
			/* Looking for negative ringing time indicating where to loop back into ringcadence */
4774
			for (i=0; i<DAHDI_MAX_CADENCE; i+=2 ) {
4775
				if (chan->ringcadence[i]<0) {
4776
					chan->ringcadence[i] *= -1;
4777
					chan->firstcadencepos = i;
4778
					break;
4779
				}
4780
			}
4781
		} else {
4782
			/* Reset to default */
4783
			chan->firstcadencepos = 0;
4784
			if (chan->curzone) {
4785
				memcpy(chan->ringcadence, chan->curzone->ringcadence, sizeof(chan->ringcadence));
4786
				/* Looking for negative ringing time indicating where to loop back into ringcadence */
4787
				for (i=0; i<DAHDI_MAX_CADENCE; i+=2 ) {
4788
					if (chan->ringcadence[i]<0) {
4789
						chan->ringcadence[i] *= -1;
4790
						chan->firstcadencepos = i;
4791
						break;
4792
					}
4793
				}
4794
			} else {
4795
				memset(chan->ringcadence, 0, sizeof(chan->ringcadence));
4796
				chan->ringcadence[0] = chan->starttime;
4797
				chan->ringcadence[1] = DAHDI_RINGOFFTIME;
4798
			}
4799
		}
4800
		break;
4801
	default:
4802
		/* Check for common ioctl's and private ones */
4803
		rv = dahdi_common_ioctl(inode, file, cmd, data, unit);
4804
		/* if no span, just return with value */
4805
		if (!chan->span) return rv;
4806
		if ((rv == -ENOTTY) && chan->span->ioctl)
4807
			rv = chan->span->ioctl(chan, cmd, data);
4808
		return rv;
4809
4810
	}
4811
	return 0;
4812
}
4813
4814
#ifdef CONFIG_DAHDI_PPP
4815
/*
4816
 * This is called at softirq (BH) level when there are calls
4817
 * we need to make to the ppp_generic layer.  We do it this
4818
 * way because the ppp_generic layer functions may not be called
4819
 * at interrupt level.
4820
 */
4821
static void do_ppp_calls(unsigned long data)
4822
{
4823
	struct dahdi_chan *chan = (struct dahdi_chan *) data;
4824
	struct sk_buff *skb;
4825
4826
	if (!chan->ppp)
4827
		return;
4828
	if (chan->do_ppp_wakeup) {
4829
		chan->do_ppp_wakeup = 0;
4830
		ppp_output_wakeup(chan->ppp);
4831
	}
4832
	while ((skb = skb_dequeue(&chan->ppp_rq)) != NULL)
4833
		ppp_input(chan->ppp, skb);
4834
	if (chan->do_ppp_error) {
4835
		chan->do_ppp_error = 0;
4836
		ppp_input_error(chan->ppp, 0);
4837
	}
4838
}
4839
#endif
4840
4841
static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, void *data)
4842
{
4843
	struct dahdi_echocan_state *ec = NULL, *ec_state;
4844
	const struct dahdi_echocan_factory *ec_current;
4845
	struct dahdi_echocanparam *params;
4846
	int ret;
4847
	unsigned long flags;
4848
4849
	if (ecp->param_count > DAHDI_MAX_ECHOCANPARAMS)
4850
		return -E2BIG;
4851
4852
	if (ecp->tap_length == 0) {
4853
		/* disable mode, don't need to inspect params */
4854
		spin_lock_irqsave(&chan->lock, flags);
4855
		ec_state = chan->ec_state;
4856
		chan->ec_state = NULL;
4857
		ec_current = chan->ec_current;
4858
		chan->ec_current = NULL;
4859
		spin_unlock_irqrestore(&chan->lock, flags);
4860
		if (ec_state) {
4861
			ec_state->ops->echocan_free(chan, ec_state);
4862
			release_echocan(ec_current);
4863
		}
4864
4865
		return 0;
4866
	}
4867
4868
	params = kmalloc(sizeof(params[0]) * DAHDI_MAX_ECHOCANPARAMS, GFP_KERNEL);
4869
4870
	if (!params)
4871
		return -ENOMEM;
4872
4873
	/* enable mode, need the params */
4874
4875
	if (copy_from_user(params, (struct dahdi_echocanparam *) data, sizeof(params[0]) * ecp->param_count)) {
4876
		ret = -EFAULT;
4877
		goto exit_with_free;
4878
	}
4879
4880
	/* free any echocan that may be on the channel already */
4881
	spin_lock_irqsave(&chan->lock, flags);
4882
	ec_state = chan->ec_state;
4883
	chan->ec_state = NULL;
4884
	ec_current = chan->ec_current;
4885
	chan->ec_current = NULL;
4886
	spin_unlock_irqrestore(&chan->lock, flags);
4887
	if (ec_state) {
4888
		ec_state->ops->echocan_free(chan, ec_state);
4889
		release_echocan(ec_current);
4890
	}
4891
4892
	switch (ecp->tap_length) {
4893
	case 32:
4894
	case 64:
4895
	case 128:
4896
	case 256:
4897
	case 512:
4898
	case 1024:
4899
		break;
4900
	default:
4901
		ecp->tap_length = deftaps;
4902
	}
4903
4904
	ret = -ENODEV;
4905
	ec_current = NULL;
4906
4907
	/* attempt to use the span's echo canceler; fall back to built-in
4908
	   if it fails (but not if an error occurs) */
4909
	if (chan->span && chan->span->echocan_create)
4910
		ret = chan->span->echocan_create(chan, ecp, params, &ec);
4911
4912
	if ((ret == -ENODEV) && chan->ec_factory) {
4913
#ifdef USE_ECHOCAN_REFCOUNT
4914
		/* try to get another reference to the module providing
4915
		   this channel's echo canceler */
4916
		if (!try_module_get(chan->ec_factory->owner)) {
4917
			module_printk(KERN_ERR, "Cannot get a reference to the '%s' echo canceler\n", chan->ec_factory->name);
4918
			goto exit_with_free;
4919
		}
4920
#endif
4921
4922
		/* got the reference, copy the pointer and use it for making
4923
		   an echo canceler instance if possible */
4924
		ec_current = chan->ec_factory;
4925
4926
		ret = ec_current->echocan_create(chan, ecp, params, &ec);
4927
		if (ret) {
4928
			release_echocan(ec_current);
4929
4930
			goto exit_with_free;
4931
		}
4932
		if (!ec) {
4933
			module_printk(KERN_ERR, "%s failed to allocate an " \
4934
				      "dahdi_echocan_state instance.\n",
4935
				      ec_current->name);
4936
			ret = -EFAULT;
4937
			goto exit_with_free;
4938
		}
4939
	}
4940
4941
	if (ec) {
4942
		spin_lock_irqsave(&chan->lock, flags);
4943
		chan->ec_current = ec_current;
4944
		chan->ec_state = ec;
4945
		ec->status.mode = ECHO_MODE_ACTIVE;
4946
		if (!ec->features.CED_tx_detect) {
4947
			echo_can_disable_detector_init(&chan->ec_state->txecdis);
4948
		}
4949
		if (!ec->features.CED_rx_detect) {
4950
			echo_can_disable_detector_init(&chan->ec_state->rxecdis);
4951
		}
4952
		spin_unlock_irqrestore(&chan->lock, flags);
4953
	}
4954
4955
exit_with_free:
4956
	kfree(params);
4957
4958
	return ret;
4959
}
4960
4961
static void set_echocan_fax_mode(struct dahdi_chan *chan, unsigned int channo, const char *reason, unsigned int enable)
4962
{
4963
	if (enable) {
4964
		if (!chan->ec_state)
4965
			module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for channel %d with no echo canceller\n", reason, channo);
4966
		else if (chan->ec_state->status.mode == ECHO_MODE_FAX)
4967
			module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for echo canceller already in FAX mode on channel %d\n", reason, channo);
4968
		else if (chan->ec_state->status.mode != ECHO_MODE_ACTIVE)
4969
			module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for echo canceller not in active mode on channel %d\n", reason, channo);
4970
		else if (chan->ec_state->features.NLP_automatic) {
4971
			/* for echocans that automatically do the right thing, just
4972
			 * mark it as being in FAX mode without making any
4973
			 * changes, as none are necessary.
4974
			*/
4975
			chan->ec_state->status.mode = ECHO_MODE_FAX;
4976
		} else if (chan->ec_state->features.NLP_toggle) {
4977
			module_printk(KERN_NOTICE, "Disabled echo canceller NLP because of %s on channel %d\n", reason, channo);
4978
			dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_DISABLED);
4979
			chan->ec_state->ops->echocan_NLP_toggle(chan->ec_state, 0);
4980
			chan->ec_state->status.mode = ECHO_MODE_FAX;
4981
		} else {
4982
			module_printk(KERN_NOTICE, "Idled echo canceller because of %s on channel %d\n", reason, channo);
4983
			chan->ec_state->status.mode = ECHO_MODE_IDLE;
4984
		}
4985
	} else {
4986
		if (!chan->ec_state)
4987
			module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for channel %d with no echo canceller\n", reason, channo);
4988
		else if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE)
4989
			module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for echo canceller already in voice mode on channel %d\n", reason, channo);
4990
		else if ((chan->ec_state->status.mode != ECHO_MODE_FAX) &&
4991
			 (chan->ec_state->status.mode != ECHO_MODE_IDLE))
4992
			module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for echo canceller not in FAX or idle mode on channel %d\n", reason, channo);
4993
		else if (chan->ec_state->features.NLP_automatic) {
4994
			/* for echocans that automatically do the right thing, just
4995
			 * mark it as being in active mode without making any
4996
			 * changes, as none are necessary.
4997
			*/
4998
			chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
4999
		} else if (chan->ec_state->features.NLP_toggle) {
5000
			module_printk(KERN_NOTICE, "Enabled echo canceller NLP because of %s on channel %d\n", reason, channo);
5001
			dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_ENABLED);
5002
			chan->ec_state->ops->echocan_NLP_toggle(chan->ec_state, 1);
5003
			chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
5004
		} else {
5005
			module_printk(KERN_NOTICE, "Activated echo canceller because of %s on channel %d\n", reason, channo);
5006
			chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
5007
		}
5008
	}
5009
}
5010
5011
static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
5012
{
5013
	struct dahdi_chan *chan = chans[unit];
5014
	unsigned long flags;
5015
	int j, rv;
5016
	int ret;
5017
	int oldconf;
5018
	void *rxgain=NULL;
5019
5020
	WARN_ON(!chan->master);
5021
	if (!chan)
5022
		return -ENOSYS;
5023
5024
	switch(cmd) {
5025
	case DAHDI_SETSIGFREEZE:
5026
		get_user(j, (int *)data);
5027
		spin_lock_irqsave(&chan->lock, flags);
5028
		if (j) {
5029
			chan->flags |= DAHDI_FLAG_SIGFREEZE;
5030
		} else {
5031
			chan->flags &= ~DAHDI_FLAG_SIGFREEZE;
5032
		}
5033
		spin_unlock_irqrestore(&chan->lock, flags);
5034
		break;
5035
	case DAHDI_GETSIGFREEZE:
5036
		spin_lock_irqsave(&chan->lock, flags);
5037
		if (chan->flags & DAHDI_FLAG_SIGFREEZE)
5038
			j = 1;
5039
		else
5040
			j = 0;
5041
		spin_unlock_irqrestore(&chan->lock, flags);
5042
		put_user(j, (int *)data);
5043
		break;
5044
	case DAHDI_AUDIOMODE:
5045
		/* Only literal clear channels can be put in  */
5046
		if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL);
5047
		get_user(j, (int *)data);
5048
		if (j) {
5049
			spin_lock_irqsave(&chan->lock, flags);
5050
			chan->flags |= DAHDI_FLAG_AUDIO;
5051
			chan->flags &= ~(DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
5052
			spin_unlock_irqrestore(&chan->lock, flags);
5053
		} else {
5054
			/* Coming out of audio mode, also clear all
5055
			   conferencing and gain related info as well
5056
			   as echo canceller */
5057
			struct dahdi_echocan_state *ec_state;
5058
			const struct dahdi_echocan_factory *ec_current;
5059
5060
			spin_lock_irqsave(&chan->lock, flags);
5061
			chan->flags &= ~DAHDI_FLAG_AUDIO;
5062
			/* save old conf number, if any */
5063
			oldconf = chan->confna;
5064
			  /* initialize conference variables */
5065
			chan->_confn = 0;
5066
			chan->confna = 0;
5067
			if (chan->span && chan->span->dacs)
5068
				chan->span->dacs(chan, NULL);
5069
			chan->confmode = 0;
5070
			chan->confmute = 0;
5071
			memset(chan->conflast, 0, sizeof(chan->conflast));
5072
			memset(chan->conflast1, 0, sizeof(chan->conflast1));
5073
			memset(chan->conflast2, 0, sizeof(chan->conflast2));
5074
			ec_state = chan->ec_state;
5075
			chan->ec_state = NULL;
5076
			ec_current = chan->ec_current;
5077
			chan->ec_current = NULL;
5078
			/* release conference resource, if any to release */
5079
			reset_conf(chan);
5080
			if (chan->gainalloc && chan->rxgain)
5081
				rxgain = chan->rxgain;
5082
			else
5083
				rxgain = NULL;
5084
5085
			chan->rxgain = defgain;
5086
			chan->txgain = defgain;
5087
			chan->gainalloc = 0;
5088
			spin_unlock_irqrestore(&chan->lock, flags);
5089
5090
			if (ec_state) {
5091
				ec_state->ops->echocan_free(chan, ec_state);
5092
				release_echocan(ec_current);
5093
			}
5094
5095
			if (rxgain)
5096
				kfree(rxgain);
5097
			if (oldconf) dahdi_check_conf(oldconf);
5098
		}
5099
		break;
5100
	case DAHDI_HDLCPPP:
5101
#ifdef CONFIG_DAHDI_PPP
5102
		if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL);
5103
		get_user(j, (int *)data);
5104
		if (j) {
5105
			if (!chan->ppp) {
5106
				chan->ppp = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL);
5107
				if (chan->ppp) {
5108
					struct dahdi_echocan_state *tec;
5109
					const struct dahdi_echocan_factory *ec_current;
5110
5111
					chan->ppp->private = chan;
5112
					chan->ppp->ops = &ztppp_ops;
5113
					chan->ppp->mtu = DAHDI_DEFAULT_MTU_MRU;
5114
					chan->ppp->hdrlen = 0;
5115
					skb_queue_head_init(&chan->ppp_rq);
5116
					chan->do_ppp_wakeup = 0;
5117
					tasklet_init(&chan->ppp_calls, do_ppp_calls,
5118
						     (unsigned long)chan);
5119
					if ((ret = dahdi_reallocbufs(chan, DAHDI_DEFAULT_MTU_MRU, DAHDI_DEFAULT_NUM_BUFS))) {
5120
						kfree(chan->ppp);
5121
						chan->ppp = NULL;
5122
						return ret;
5123
					}
5124
5125
					if ((ret = ppp_register_channel(chan->ppp))) {
5126
						kfree(chan->ppp);
5127
						chan->ppp = NULL;
5128
						return ret;
5129
					}
5130
					tec = chan->ec_state;
5131
					chan->ec_state = NULL;
5132
					ec_current = chan->ec_current;
5133
					chan->ec_current = NULL;
5134
					/* Make sure there's no gain */
5135
					if (chan->gainalloc)
5136
						kfree(chan->rxgain);
5137
					chan->rxgain = defgain;
5138
					chan->txgain = defgain;
5139
					chan->gainalloc = 0;
5140
					chan->flags &= ~DAHDI_FLAG_AUDIO;
5141
					chan->flags |= (DAHDI_FLAG_PPP | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
5142
5143
					if (tec) {
5144
						tec->ops->echocan_free(chan, tec);
5145
						release_echocan(ec_current);
5146
					}
5147
				} else
5148
					return -ENOMEM;
5149
			}
5150
		} else {
5151
			chan->flags &= ~(DAHDI_FLAG_PPP | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
5152
			if (chan->ppp) {
5153
				struct ppp_channel *ppp = chan->ppp;
5154
				chan->ppp = NULL;
5155
				tasklet_kill(&chan->ppp_calls);
5156
				skb_queue_purge(&chan->ppp_rq);
5157
				ppp_unregister_channel(ppp);
5158
				kfree(ppp);
5159
			}
5160
		}
5161
#else
5162
		module_printk(KERN_NOTICE, "PPP support not compiled in\n");
5163
		return -ENOSYS;
5164
#endif
5165
		break;
5166
	case DAHDI_HDLCRAWMODE:
5167
		if (chan->sig != DAHDI_SIG_CLEAR)	return (-EINVAL);
5168
		get_user(j, (int *)data);
5169
		chan->flags &= ~(DAHDI_FLAG_AUDIO | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
5170
		if (j) {
5171
			chan->flags |= DAHDI_FLAG_HDLC;
5172
			fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
5173
			fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
5174
		}
5175
		break;
5176
	case DAHDI_HDLCFCSMODE:
5177
		if (chan->sig != DAHDI_SIG_CLEAR)	return (-EINVAL);
5178
		get_user(j, (int *)data);
5179
		chan->flags &= ~(DAHDI_FLAG_AUDIO | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
5180
		if (j) {
5181
			chan->flags |= DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS;
5182
			fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
5183
			fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
5184
		}
5185
		break;
5186
	case DAHDI_HDLC_RATE:
5187
		get_user(j, (int *) data);
5188
		if (j == 56) {
5189
			chan->flags |= DAHDI_FLAG_HDLC56;
5190
		} else {
5191
			chan->flags &= ~DAHDI_FLAG_HDLC56;
5192
		}
5193
5194
		fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
5195
		fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64);
5196
		break;
5197
	case DAHDI_ECHOCANCEL_PARAMS:
5198
	{
5199
		struct dahdi_echocanparams ecp;
5200
5201
		if (!(chan->flags & DAHDI_FLAG_AUDIO))
5202
			return -EINVAL;
5203
		if (copy_from_user(&ecp, (struct dahdi_echocanparams *) data, sizeof(ecp)))
5204
			return -EFAULT;
5205
		data += sizeof(ecp);
5206
		if ((ret = ioctl_echocancel(chan, &ecp, (void *) data)))
5207
			return ret;
5208
		break;
5209
	}
5210
	case DAHDI_ECHOCANCEL:
5211
	{
5212
		struct dahdi_echocanparams ecp;
5213
5214
		if (!(chan->flags & DAHDI_FLAG_AUDIO))
5215
			return -EINVAL;
5216
		get_user(j, (int *) data);
5217
		ecp.tap_length = j;
5218
		ecp.param_count = 0;
5219
		if ((ret = ioctl_echocancel(chan, &ecp, NULL)))
5220
			return ret;
5221
		break;
5222
	}
5223
	case DAHDI_ECHOTRAIN:
5224
		get_user(j, (int *)data); /* get pre-training time from user */
5225
		if ((j < 0) || (j >= DAHDI_MAX_PRETRAINING))
5226
			return -EINVAL;
5227
		j <<= 3;
5228
		if (chan->ec_state) {
5229
			/* Start pretraining stage */
5230
			spin_lock_irqsave(&chan->lock, flags);
5231
			chan->ec_state->status.mode = ECHO_MODE_PRETRAINING;
5232
			chan->ec_state->status.pretrain_timer = j;
5233
			spin_unlock_irqrestore(&chan->lock, flags);
5234
		} else
5235
			return -EINVAL;
5236
		break;
5237
	case DAHDI_ECHOCANCEL_FAX_MODE:
5238
		if (!chan->ec_state) {
5239
			return -EINVAL;
5240
		} else {
5241
			get_user(j, (int *) data);
5242
			spin_lock_irqsave(&chan->lock, flags);
5243
			set_echocan_fax_mode(chan, chan->channo, "ioctl", j ? 1 : 0);
5244
			spin_unlock_irqrestore(&chan->lock, flags);
5245
		}
5246
		break;
5247
	case DAHDI_SETTXBITS:
5248
		if (chan->sig != DAHDI_SIG_CAS)
5249
			return -EINVAL;
5250
		get_user(j,(int *)data);
5251
		dahdi_cas_setbits(chan, j);
5252
		break;
5253
	case DAHDI_GETRXBITS:
5254
		put_user(chan->rxsig, (int *)data);
5255
		break;
5256
	case DAHDI_LOOPBACK:
5257
		get_user(j, (int *)data);
5258
		spin_lock_irqsave(&chan->lock, flags);
5259
		if (j)
5260
			chan->flags |= DAHDI_FLAG_LOOPED;
5261
		else
5262
			chan->flags &= ~DAHDI_FLAG_LOOPED;
5263
		spin_unlock_irqrestore(&chan->lock, flags);
5264
		break;
5265
	case DAHDI_HOOK:
5266
		get_user(j,(int *)data);
5267
		if (chan->flags & DAHDI_FLAG_CLEAR)
5268
			return -EINVAL;
5269
		if (chan->sig == DAHDI_SIG_CAS)
5270
			return -EINVAL;
5271
		/* if no span, just do nothing */
5272
		if (!chan->span) return(0);
5273
		spin_lock_irqsave(&chan->lock, flags);
5274
		/* if dialing, stop it */
5275
		chan->curtone = NULL;
5276
		chan->dialing = 0;
5277
		chan->txdialbuf[0] = '\0';
5278
		chan->tonep = 0;
5279
		chan->pdialcount = 0;
5280
		spin_unlock_irqrestore(&chan->lock, flags);
5281
		if (chan->span->flags & DAHDI_FLAG_RBS) {
5282
			switch (j) {
5283
			case DAHDI_ONHOOK:
5284
				spin_lock_irqsave(&chan->lock, flags);
5285
				dahdi_hangup(chan);
5286
				spin_unlock_irqrestore(&chan->lock, flags);
5287
				break;
5288
			case DAHDI_OFFHOOK:
5289
				spin_lock_irqsave(&chan->lock, flags);
5290
				if ((chan->txstate == DAHDI_TXSTATE_KEWL) ||
5291
				  (chan->txstate == DAHDI_TXSTATE_AFTERKEWL)) {
5292
					spin_unlock_irqrestore(&chan->lock, flags);
5293
					return -EBUSY;
5294
				}
5295
				dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_DEBOUNCE, chan->debouncetime);
5296
				spin_unlock_irqrestore(&chan->lock, flags);
5297
				break;
5298
			case DAHDI_RING:
5299
			case DAHDI_START:
5300
				spin_lock_irqsave(&chan->lock, flags);
5301
				if (!chan->curzone) {
5302
					spin_unlock_irqrestore(&chan->lock, flags);
5303
					module_printk(KERN_WARNING, "Cannot start tone until a tone zone is loaded.\n");
5304
					return -ENODATA;
5305
				}
5306
				if (chan->txstate != DAHDI_TXSTATE_ONHOOK) {
5307
					spin_unlock_irqrestore(&chan->lock, flags);
5308
					return -EBUSY;
5309
				}
5310
				if (chan->sig & __DAHDI_SIG_FXO) {
5311
					ret = 0;
5312
					chan->cadencepos = 0;
5313
					ret = chan->ringcadence[0];
5314
					dahdi_rbs_sethook(chan, DAHDI_TXSIG_START, DAHDI_TXSTATE_RINGON, ret);
5315
				} else
5316
					dahdi_rbs_sethook(chan, DAHDI_TXSIG_START, DAHDI_TXSTATE_START, chan->starttime);
5317
				spin_unlock_irqrestore(&chan->lock, flags);
5318
				if (file->f_flags & O_NONBLOCK)
5319
					return -EINPROGRESS;
5320
#if 0
5321
				rv = schluffen(&chan->txstateq);
5322
				if (rv) return rv;
5323
#endif
5324
				break;
5325
			case DAHDI_WINK:
5326
				spin_lock_irqsave(&chan->lock, flags);
5327
				if (chan->txstate != DAHDI_TXSTATE_ONHOOK) {
5328
					spin_unlock_irqrestore(&chan->lock, flags);
5329
					return -EBUSY;
5330
				}
5331
				dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_PREWINK, chan->prewinktime);
5332
				spin_unlock_irqrestore(&chan->lock, flags);
5333
				if (file->f_flags & O_NONBLOCK)
5334
					return -EINPROGRESS;
5335
				rv = schluffen(&chan->txstateq);
5336
				if (rv) return rv;
5337
				break;
5338
			case DAHDI_FLASH:
5339
				spin_lock_irqsave(&chan->lock, flags);
5340
				if (chan->txstate != DAHDI_TXSTATE_OFFHOOK) {
5341
					spin_unlock_irqrestore(&chan->lock, flags);
5342
					return -EBUSY;
5343
				}
5344
				dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_PREFLASH, chan->preflashtime);
5345
				spin_unlock_irqrestore(&chan->lock, flags);
5346
				if (file->f_flags & O_NONBLOCK)
5347
					return -EINPROGRESS;
5348
				rv = schluffen(&chan->txstateq);
5349
				if (rv) return rv;
5350
				break;
5351
			case DAHDI_RINGOFF:
5352
				spin_lock_irqsave(&chan->lock, flags);
5353
				dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_ONHOOK, 0);
5354
				spin_unlock_irqrestore(&chan->lock, flags);
5355
				break;
5356
			default:
5357
				return -EINVAL;
5358
			}
5359
		} else if (chan->span->sethook) {
5360
			if (chan->txhooksig != j) {
5361
				chan->txhooksig = j;
5362
				chan->span->sethook(chan, j);
5363
			}
5364
		} else
5365
			return -ENOSYS;
5366
		break;
5367
#ifdef CONFIG_DAHDI_PPP
5368
	case PPPIOCGCHAN:
5369
		if (chan->flags & DAHDI_FLAG_PPP)
5370
			return put_user(ppp_channel_index(chan->ppp), (int *)data) ? -EFAULT : 0;
5371
		else
5372
			return -EINVAL;
5373
		break;
5374
	case PPPIOCGUNIT:
5375
		if (chan->flags & DAHDI_FLAG_PPP)
5376
			return put_user(ppp_unit_number(chan->ppp), (int *)data) ? -EFAULT : 0;
5377
		else
5378
			return -EINVAL;
5379
		break;
5380
#endif
5381
	default:
5382
		return dahdi_chanandpseudo_ioctl(inode, file, cmd, data, unit);
5383
	}
5384
	return 0;
5385
}
5386
5387
static int dahdi_prechan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
5388
{
5389
	struct dahdi_chan *chan = file->private_data;
5390
	int channo;
5391
	int res;
5392
5393
	if (chan) {
5394
		module_printk(KERN_NOTICE, "Huh?  Prechan already has private data??\n");
5395
	}
5396
	switch(cmd) {
5397
	case DAHDI_SPECIFY:
5398
		get_user(channo,(int *)data);
5399
		if (channo < 1)
5400
			return -EINVAL;
5401
		if (channo > DAHDI_MAX_CHANNELS)
5402
			return -EINVAL;
5403
		res = dahdi_specchan_open(inode, file, channo);
5404
		if (!res) {
5405
			/* Setup the pointer for future stuff */
5406
			chan = chans[channo];
5407
			file->private_data = chan;
5408
			/* Return success */
5409
			return 0;
5410
		}
5411
		return res;
5412
	default:
5413
		return -ENOSYS;
5414
	}
5415
	return 0;
5416
}
5417
5418
static int dahdi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data)
5419
{
5420
	int unit = UNIT(file);
5421
	struct dahdi_chan *chan;
5422
	struct dahdi_timer *timer;
5423
5424
	if (!unit)
5425
		return dahdi_ctl_ioctl(inode, file, cmd, data);
5426
5427
	if (unit == 250) {
5428
		/* dahdi_transcode should have updated the file_operations on
5429
		 * this file object on open, so we shouldn't be here. */
5430
		WARN_ON(1);
5431
		return -EFAULT;
5432
	}
5433
5434
	if (unit == 253) {
5435
		timer = file->private_data;
5436
		if (timer)
5437
			return dahdi_timer_ioctl(inode, file, cmd, data, timer);
5438
		else
5439
			return -EINVAL;
5440
	}
5441
	if (unit == 254) {
5442
		chan = file->private_data;
5443
		if (chan)
5444
			return dahdi_chan_ioctl(inode, file, cmd, data, chan->channo);
5445
		else
5446
			return dahdi_prechan_ioctl(inode, file, cmd, data, unit);
5447
	}
5448
	if (unit == 255) {
5449
		chan = file->private_data;
5450
		if (!chan) {
5451
			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
5452
			return -EINVAL;
5453
		}
5454
		return dahdi_chanandpseudo_ioctl(inode, file, cmd, data, chan->channo);
5455
	}
5456
	return dahdi_chan_ioctl(inode, file, cmd, data, unit);
5457
}
5458
5459
int dahdi_register(struct dahdi_span *span, int prefmaster)
5460
{
5461
	int x;
5462
5463
	if (!span)
5464
		return -EINVAL;
5465
5466
	if (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
5467
		module_printk(KERN_ERR, "Span %s already appears to be registered\n", span->name);
5468
		return -EBUSY;
5469
	}
5470
5471
	for (x = 1; x < maxspans; x++) {
5472
		if (spans[x] == span) {
5473
			module_printk(KERN_ERR, "Span %s already in list\n", span->name);
5474
			return -EBUSY;
5475
		}
5476
	}
5477
5478
	for (x = 1; x < DAHDI_MAX_SPANS; x++) {
5479
		if (!spans[x])
5480
			break;
5481
	}
5482
5483
	if (x < DAHDI_MAX_SPANS) {
5484
		spans[x] = span;
5485
		if (maxspans < x + 1)
5486
			maxspans = x + 1;
5487
	} else {
5488
		module_printk(KERN_ERR, "Too many DAHDI spans registered\n");
5489
		return -EBUSY;
5490
	}
5491
5492
	set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
5493
	span->spanno = x;
5494
5495
	spin_lock_init(&span->lock);
5496
5497
	if (!span->deflaw) {
5498
		module_printk(KERN_NOTICE, "Span %s didn't specify default law.  "
5499
				"Assuming mulaw, please fix driver!\n", span->name);
5500
		span->deflaw = DAHDI_LAW_MULAW;
5501
	}
5502
5503
	for (x = 0; x < span->channels; x++) {
5504
		span->chans[x]->span = span;
5505
		dahdi_chan_reg(span->chans[x]);
5506
	}
5507
5508
#ifdef CONFIG_PROC_FS
5509
	{
5510
		char tempfile[17];
5511
		snprintf(tempfile, sizeof(tempfile), "dahdi/%d", span->spanno);
5512
		proc_entries[span->spanno] = create_proc_read_entry(tempfile, 0444,
5513
				NULL, dahdi_proc_read, (int *) (long) span->spanno);
5514
	}
5515
#endif
5516
5517
	for (x = 0; x < span->channels; x++) {
5518
		if (span->chans[x]->channo < 250) {
5519
			char chan_name[32];
5520
			snprintf(chan_name, sizeof(chan_name), "dahdi!%d", 
5521
					span->chans[x]->channo);
5522
			CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 
5523
					span->chans[x]->channo), NULL, chan_name);
5524
		}
5525
	}
5526
5527
	if (debug) {
5528
		module_printk(KERN_NOTICE, "Registered Span %d ('%s') with "
5529
				"%d channels\n", span->spanno, span->name, span->channels);
5530
	}
5531
5532
	if (!master || prefmaster) {
5533
		master = span;
5534
		if (debug) {
5535
			module_printk(KERN_NOTICE, "Span ('%s') is new master\n", 
5536
					span->name);
5537
		}
5538
	}
5539
5540
	return 0;
5541
}
5542
5543
int dahdi_unregister(struct dahdi_span *span)
5544
{
5545
	int x;
5546
	int new_maxspans;
5547
	static struct dahdi_span *new_master;
5548
5549
#ifdef CONFIG_PROC_FS
5550
	char tempfile[17];
5551
#endif /* CONFIG_PROC_FS */
5552
5553
	if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
5554
		module_printk(KERN_ERR, "Span %s does not appear to be registered\n", span->name);
5555
		return -1;
5556
	}
5557
	/* Shutdown the span if it's running */
5558
	if (span->flags & DAHDI_FLAG_RUNNING)
5559
		if (span->shutdown)
5560
			span->shutdown(span);
5561
5562
	if (spans[span->spanno] != span) {
5563
		module_printk(KERN_ERR, "Span %s has spanno %d which is something else\n", span->name, span->spanno);
5564
		return -1;
5565
	}
5566
	if (debug)
5567
		module_printk(KERN_NOTICE, "Unregistering Span '%s' with %d channels\n", span->name, span->channels);
5568
#ifdef CONFIG_PROC_FS
5569
	snprintf(tempfile, sizeof(tempfile)-1, "dahdi/%d", span->spanno);
5570
        remove_proc_entry(tempfile, NULL);
5571
#endif /* CONFIG_PROC_FS */
5572
5573
	for (x = 0; x < span->channels; x++) {
5574
		if (span->chans[x]->channo < 250)
5575
			CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x]->channo));
5576
	}
5577
5578
	spans[span->spanno] = NULL;
5579
	span->spanno = 0;
5580
	clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
5581
	for (x=0;x<span->channels;x++)
5582
		dahdi_chan_unreg(span->chans[x]);
5583
	new_maxspans = 0;
5584
	new_master = master; /* FIXME: locking */
5585
	if (master == span)
5586
		new_master = NULL;
5587
	for (x=1;x<DAHDI_MAX_SPANS;x++) {
5588
		if (spans[x]) {
5589
			new_maxspans = x+1;
5590
			if (!new_master)
5591
				new_master = spans[x];
5592
		}
5593
	}
5594
	maxspans = new_maxspans;
5595
	if (master != new_master)
5596
		if (debug)
5597
			module_printk(KERN_NOTICE, "%s: Span ('%s') is new master\n", __FUNCTION__,
5598
				      (new_master)? new_master->name: "no master");
5599
	master = new_master;
5600
5601
	return 0;
5602
}
5603
5604
/*
5605
** This routine converts from linear to ulaw
5606
**
5607
** Craig Reese: IDA/Supercomputing Research Center
5608
** Joe Campbell: Department of Defense
5609
** 29 September 1989
5610
**
5611
** References:
5612
** 1) CCITT Recommendation G.711  (very difficult to follow)
5613
** 2) "A New Digital Technique for Implementation of Any
5614
**     Continuous PCM Companding Law," Villeret, Michel,
5615
**     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
5616
**     1973, pg. 11.12-11.17
5617
** 3) MIL-STD-188-113,"Interoperability and Performance Standards
5618
**     for Analog-to_Digital Conversion Techniques,"
5619
**     17 February 1987
5620
**
5621
** Input: Signed 16 bit linear sample
5622
** Output: 8 bit ulaw sample
5623
*/
5624
5625
#define ZEROTRAP    /* turn on the trap as per the MIL-STD */
5626
#define BIAS 0x84   /* define the add-in bias for 16 bit samples */
5627
#define CLIP 32635
5628
5629
#ifdef CONFIG_CALC_XLAW
5630
unsigned char
5631
#else
5632
static unsigned char  __init
5633
#endif
5634
__dahdi_lineartoulaw(short sample)
5635
{
5636
  static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
5637
                             4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5638
                             5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5639
                             5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5640
                             6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
5641
                             6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
5642
                             6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
5643
                             6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
5644
                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5645
                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5646
                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5647
                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5648
                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5649
                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5650
                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5651
                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
5652
  int sign, exponent, mantissa;
5653
  unsigned char ulawbyte;
5654
5655
  /* Get the sample into sign-magnitude. */
5656
  sign = (sample >> 8) & 0x80;          /* set aside the sign */
5657
  if (sign != 0) sample = -sample;              /* get magnitude */
5658
  if (sample > CLIP) sample = CLIP;             /* clip the magnitude */
5659
5660
  /* Convert from 16 bit linear to ulaw. */
5661
  sample = sample + BIAS;
5662
  exponent = exp_lut[(sample >> 7) & 0xFF];
5663
  mantissa = (sample >> (exponent + 3)) & 0x0F;
5664
  ulawbyte = ~(sign | (exponent << 4) | mantissa);
5665
#ifdef ZEROTRAP
5666
  if (ulawbyte == 0) ulawbyte = 0x02;   /* optional CCITT trap */
5667
#endif
5668
  if (ulawbyte == 0xff) ulawbyte = 0x7f;   /* never return 0xff */
5669
  return(ulawbyte);
5670
}
5671
5672
#define AMI_MASK 0x55
5673
5674
#ifdef CONFIG_CALC_XLAW
5675
unsigned char
5676
#else
5677
static inline unsigned char __init
5678
#endif
5679
__dahdi_lineartoalaw (short linear)
5680
{
5681
    int mask;
5682
    int seg;
5683
    int pcm_val;
5684
    static int seg_end[8] =
5685
    {
5686
         0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
5687
    };
5688
5689
    pcm_val = linear;
5690
    if (pcm_val >= 0)
5691
    {
5692
        /* Sign (7th) bit = 1 */
5693
        mask = AMI_MASK | 0x80;
5694
    }
5695
    else
5696
    {
5697
        /* Sign bit = 0 */
5698
        mask = AMI_MASK;
5699
        pcm_val = -pcm_val;
5700
    }
5701
5702
    /* Convert the scaled magnitude to segment number. */
5703
    for (seg = 0;  seg < 8;  seg++)
5704
    {
5705
        if (pcm_val <= seg_end[seg])
5706
	    break;
5707
    }
5708
    /* Combine the sign, segment, and quantization bits. */
5709
    return  ((seg << 4) | ((pcm_val >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask;
5710
}
5711
/*- End of function --------------------------------------------------------*/
5712
5713
static inline short int __init alaw2linear (uint8_t alaw)
5714
{
5715
    int i;
5716
    int seg;
5717
5718
    alaw ^= AMI_MASK;
5719
    i = ((alaw & 0x0F) << 4);
5720
    seg = (((int) alaw & 0x70) >> 4);
5721
    if (seg)
5722
        i = (i + 0x100) << (seg - 1);
5723
    return (short int) ((alaw & 0x80)  ?  i  :  -i);
5724
}
5725
/*- End of function --------------------------------------------------------*/
5726
static void  __init dahdi_conv_init(void)
5727
{
5728
	int i;
5729
5730
	/*
5731
	 *  Set up mu-law conversion table
5732
	 */
5733
	for(i = 0;i < 256;i++)
5734
	   {
5735
		short mu,e,f,y;
5736
		static short etab[]={0,132,396,924,1980,4092,8316,16764};
5737
5738
		mu = 255-i;
5739
		e = (mu & 0x70)/16;
5740
		f = mu & 0x0f;
5741
		y = f * (1 << (e + 3));
5742
		y += etab[e];
5743
		if (mu & 0x80) y = -y;
5744
	        __dahdi_mulaw[i] = y;
5745
		__dahdi_alaw[i] = alaw2linear(i);
5746
		/* Default (0.0 db) gain table */
5747
		defgain[i] = i;
5748
	   }
5749
#ifndef CONFIG_CALC_XLAW
5750
	  /* set up the reverse (mu-law) conversion table */
5751
	for(i = -32768; i < 32768; i += 4)
5752
	   {
5753
		__dahdi_lin2mu[((unsigned short)(short)i) >> 2] = __dahdi_lineartoulaw(i);
5754
		__dahdi_lin2a[((unsigned short)(short)i) >> 2] = __dahdi_lineartoalaw(i);
5755
	   }
5756
#endif
5757
}
5758
5759
static inline void __dahdi_process_getaudio_chunk(struct dahdi_chan *ss, unsigned char *txb)
5760
{
5761
	/* We transmit data from our master channel */
5762
	/* Called with ss->lock held */
5763
	struct dahdi_chan *ms = ss->master;
5764
	/* Linear representation */
5765
	short getlin[DAHDI_CHUNKSIZE], k[DAHDI_CHUNKSIZE];
5766
	int x;
5767
5768
	/* Okay, now we've got something to transmit */
5769
	for (x=0;x<DAHDI_CHUNKSIZE;x++)
5770
		getlin[x] = DAHDI_XLAW(txb[x], ms);
5771
5772
	if (ms->ec_state && (ms->ec_state->status.mode == ECHO_MODE_ACTIVE) && !ms->ec_state->features.CED_tx_detect) {
5773
		for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
5774
			if (echo_can_disable_detector_update(&ms->ec_state->txecdis, getlin[x])) {
5775
				set_echocan_fax_mode(ms, ss->channo, "CED tx detected", 1);
5776
				dahdi_qevent_nolock(ms, DAHDI_EVENT_TX_CED_DETECTED);
5777
				break;
5778
			}
5779
		}
5780
	}
5781
5782
	if ((!ms->confmute && !ms->dialing) || (ms->flags & DAHDI_FLAG_PSEUDO)) {
5783
		/* Handle conferencing on non-clear channel and non-HDLC channels */
5784
		switch(ms->confmode & DAHDI_CONF_MODE_MASK) {
5785
		case DAHDI_CONF_NORMAL:
5786
			/* Do nuffin */
5787
			break;
5788
		case DAHDI_CONF_MONITOR:	/* Monitor a channel's rx mode */
5789
			  /* if a pseudo-channel, ignore */
5790
			if (ms->flags & DAHDI_FLAG_PSEUDO) break;
5791
			/* Add monitored channel */
5792
			if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) {
5793
				ACSS(getlin, chans[ms->confna]->getlin);
5794
			} else {
5795
				ACSS(getlin, chans[ms->confna]->putlin);
5796
			}
5797
			for (x=0;x<DAHDI_CHUNKSIZE;x++)
5798
				txb[x] = DAHDI_LIN2X(getlin[x], ms);
5799
			break;
5800
		case DAHDI_CONF_MONITORTX: /* Monitor a channel's tx mode */
5801
			  /* if a pseudo-channel, ignore */
5802
			if (ms->flags & DAHDI_FLAG_PSEUDO) break;
5803
			/* Add monitored channel */
5804
			if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) {
5805
				ACSS(getlin, chans[ms->confna]->putlin);
5806
			} else {
5807
				ACSS(getlin, chans[ms->confna]->getlin);
5808
			}
5809
5810
			for (x=0;x<DAHDI_CHUNKSIZE;x++)
5811
				txb[x] = DAHDI_LIN2X(getlin[x], ms);
5812
			break;
5813
		case DAHDI_CONF_MONITORBOTH: /* monitor a channel's rx and tx mode */
5814
			  /* if a pseudo-channel, ignore */
5815
			if (ms->flags & DAHDI_FLAG_PSEUDO) break;
5816
			ACSS(getlin, chans[ms->confna]->putlin);
5817
			ACSS(getlin, chans[ms->confna]->getlin);
5818
			for (x=0;x<DAHDI_CHUNKSIZE;x++)
5819
				txb[x] = DAHDI_LIN2X(getlin[x], ms);
5820
			break;
5821
		case DAHDI_CONF_MONITOR_RX_PREECHO:	/* Monitor a channel's rx mode */
5822
			  /* if a pseudo-channel, ignore */
5823
			if (ms->flags & DAHDI_FLAG_PSEUDO)
5824
				break;
5825
5826
			if (!chans[ms->confna]->readchunkpreec)
5827
				break;
5828
5829
			/* Add monitored channel */
5830
			ACSS(getlin, chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO ?
5831
			     chans[ms->confna]->readchunkpreec : chans[ms->confna]->putlin);
5832
			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
5833
				txb[x] = DAHDI_LIN2X(getlin[x], ms);
5834
5835
			break;
5836
		case DAHDI_CONF_MONITOR_TX_PREECHO: /* Monitor a channel's tx mode */
5837
			  /* if a pseudo-channel, ignore */
5838
			if (ms->flags & DAHDI_FLAG_PSEUDO)
5839
				break;
5840
5841
			if (!chans[ms->confna]->readchunkpreec)
5842
				break;
5843
5844
			/* Add monitored channel */
5845
			ACSS(getlin, chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO ?
5846
			     chans[ms->confna]->putlin : chans[ms->confna]->readchunkpreec);
5847
			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
5848
				txb[x] = DAHDI_LIN2X(getlin[x], ms);
5849
5850
			break;
5851
		case DAHDI_CONF_MONITORBOTH_PREECHO: /* monitor a channel's rx and tx mode */
5852
			  /* if a pseudo-channel, ignore */
5853
			if (ms->flags & DAHDI_FLAG_PSEUDO)
5854
				break;
5855
5856
			if (!chans[ms->confna]->readchunkpreec)
5857
				break;
5858
5859
			ACSS(getlin, chans[ms->confna]->putlin);
5860
			ACSS(getlin, chans[ms->confna]->readchunkpreec);
5861
5862
			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
5863
				txb[x] = DAHDI_LIN2X(getlin[x], ms);
5864
5865
			break;
5866
		case DAHDI_CONF_REALANDPSEUDO:
5867
			/* This strange mode takes the transmit buffer and
5868
				puts it on the conference, minus its last sample,
5869
				then outputs from the conference minus the
5870
				real channel's last sample. */
5871
			  /* if to talk on conf */
5872
			if (ms->confmode & DAHDI_CONF_PSEUDO_TALKER) {
5873
				/* Store temp value */
5874
				memcpy(k, getlin, DAHDI_CHUNKSIZE * sizeof(short));
5875
				/* Add conf value */
5876
				ACSS(k, conf_sums_next[ms->_confn]);
5877
				/* save last one */
5878
				memcpy(ms->conflast2, ms->conflast1, DAHDI_CHUNKSIZE * sizeof(short));
5879
				memcpy(ms->conflast1, k, DAHDI_CHUNKSIZE * sizeof(short));
5880
				/*  get amount actually added */
5881
				SCSS(ms->conflast1, conf_sums_next[ms->_confn]);
5882
				/* Really add in new value */
5883
				ACSS(conf_sums_next[ms->_confn], ms->conflast1);
5884
			} else {
5885
				memset(ms->conflast1, 0, DAHDI_CHUNKSIZE * sizeof(short));
5886
				memset(ms->conflast2, 0, DAHDI_CHUNKSIZE * sizeof(short));
5887
			}
5888
			memset(getlin, 0, DAHDI_CHUNKSIZE * sizeof(short));
5889
			txb[0] = DAHDI_LIN2X(0, ms);
5890
			memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1);
5891
			/* fall through to normal conf mode */
5892
		case DAHDI_CONF_CONF:	/* Normal conference mode */
5893
			if (ms->flags & DAHDI_FLAG_PSEUDO) /* if pseudo-channel */
5894
			   {
5895
				  /* if to talk on conf */
5896
				if (ms->confmode & DAHDI_CONF_TALKER) {
5897
					/* Store temp value */
5898
					memcpy(k, getlin, DAHDI_CHUNKSIZE * sizeof(short));
5899
					/* Add conf value */
5900
					ACSS(k, conf_sums[ms->_confn]);
5901
					/*  get amount actually added */
5902
					memcpy(ms->conflast, k, DAHDI_CHUNKSIZE * sizeof(short));
5903
					SCSS(ms->conflast, conf_sums[ms->_confn]);
5904
					/* Really add in new value */
5905
					ACSS(conf_sums[ms->_confn], ms->conflast);
5906
					memcpy(ms->getlin, getlin, DAHDI_CHUNKSIZE * sizeof(short));
5907
				} else {
5908
					memset(ms->conflast, 0, DAHDI_CHUNKSIZE * sizeof(short));
5909
					memcpy(getlin, ms->getlin, DAHDI_CHUNKSIZE * sizeof(short));
5910
				}
5911
				txb[0] = DAHDI_LIN2X(0, ms);
5912
				memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1);
5913
				break;
5914
		 	   }
5915
			/* fall through */
5916
		case DAHDI_CONF_CONFMON:	/* Conference monitor mode */
5917
			if (ms->confmode & DAHDI_CONF_LISTENER) {
5918
				/* Subtract out last sample written to conf */
5919
				SCSS(getlin, ms->conflast);
5920
				/* Add in conference */
5921
				ACSS(getlin, conf_sums[ms->_confn]);
5922
			}
5923
			for (x=0;x<DAHDI_CHUNKSIZE;x++)
5924
				txb[x] = DAHDI_LIN2X(getlin[x], ms);
5925
			break;
5926
		case DAHDI_CONF_CONFANN:
5927
		case DAHDI_CONF_CONFANNMON:
5928
			/* First, add tx buffer to conf */
5929
			ACSS(conf_sums_next[ms->_confn], getlin);
5930
			/* Start with silence */
5931
			memset(getlin, 0, DAHDI_CHUNKSIZE * sizeof(short));
5932
			/* If a listener on the conf... */
5933
			if (ms->confmode & DAHDI_CONF_LISTENER) {
5934
				/* Subtract last value written */
5935
				SCSS(getlin, ms->conflast);
5936
				/* Add in conf */
5937
				ACSS(getlin, conf_sums[ms->_confn]);
5938
			}
5939
			for (x=0;x<DAHDI_CHUNKSIZE;x++)
5940
				txb[x] = DAHDI_LIN2X(getlin[x], ms);
5941
			break;
5942
		case DAHDI_CONF_DIGITALMON:
5943
			/* Real digital monitoring, but still echo cancel if desired */
5944
			if (!chans[ms->confna])
5945
				break;
5946
			if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) {
5947
				if (ms->ec_state) {
5948
					for (x=0;x<DAHDI_CHUNKSIZE;x++)
5949
						txb[x] = DAHDI_LIN2X(chans[ms->confna]->getlin[x], ms);
5950
				} else {
5951
					memcpy(txb, chans[ms->confna]->getraw, DAHDI_CHUNKSIZE);
5952
				}
5953
			} else {
5954
				if (ms->ec_state) {
5955
					for (x=0;x<DAHDI_CHUNKSIZE;x++)
5956
						txb[x] = DAHDI_LIN2X(chans[ms->confna]->putlin[x], ms);
5957
				} else {
5958
					memcpy(txb, chans[ms->confna]->putraw, DAHDI_CHUNKSIZE);
5959
				}
5960
			}
5961
			for (x=0;x<DAHDI_CHUNKSIZE;x++)
5962
				getlin[x] = DAHDI_XLAW(txb[x], ms);
5963
			break;
5964
		}
5965
	}
5966
	if (ms->confmute || (ms->ec_state && (ms->ec_state->status.mode) & __ECHO_MODE_MUTE)) {
5967
		txb[0] = DAHDI_LIN2X(0, ms);
5968
		memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1);
5969
		if (ms->ec_state && (ms->ec_state->status.mode == ECHO_MODE_STARTTRAINING)) {
5970
			/* Transmit impulse now */
5971
			txb[0] = DAHDI_LIN2X(16384, ms);
5972
			ms->ec_state->status.mode = ECHO_MODE_AWAITINGECHO;
5973
		}
5974
	}
5975
	/* save value from last chunk */
5976
	memcpy(ms->getlin_lastchunk, ms->getlin, DAHDI_CHUNKSIZE * sizeof(short));
5977
	/* save value from current */
5978
	memcpy(ms->getlin, getlin, DAHDI_CHUNKSIZE * sizeof(short));
5979
	/* save value from current */
5980
	memcpy(ms->getraw, txb, DAHDI_CHUNKSIZE);
5981
	/* if to make tx tone */
5982
	if (ms->v1_1 || ms->v2_1 || ms->v3_1)
5983
	{
5984
		for (x=0;x<DAHDI_CHUNKSIZE;x++)
5985
		{
5986
			getlin[x] += dahdi_txtone_nextsample(ms);
5987
			txb[x] = DAHDI_LIN2X(getlin[x], ms);
5988
		}
5989
	}
5990
	/* This is what to send (after having applied gain) */
5991
	for (x=0;x<DAHDI_CHUNKSIZE;x++)
5992
		txb[x] = ms->txgain[txb[x]];
5993
}
5994
5995
static inline void __dahdi_getbuf_chunk(struct dahdi_chan *ss, unsigned char *txb)
5996
{
5997
	/* Called with ss->lock held */
5998
	/* We transmit data from our master channel */
5999
	struct dahdi_chan *ms = ss->master;
6000
	/* Buffer we're using */
6001
	unsigned char *buf;
6002
	/* Old buffer number */
6003
	int oldbuf;
6004
	/* Linear representation */
6005
	int getlin;
6006
	/* How many bytes we need to process */
6007
	int bytes = DAHDI_CHUNKSIZE, left;
6008
	int x;
6009
6010
	/* Let's pick something to transmit.  First source to
6011
	   try is our write-out buffer.  Always check it first because
6012
	   its our 'fast path' for whatever that's worth. */
6013
	while(bytes) {
6014
		if ((ms->outwritebuf > -1) && !ms->txdisable) {
6015
			buf= ms->writebuf[ms->outwritebuf];
6016
			left = ms->writen[ms->outwritebuf] - ms->writeidx[ms->outwritebuf];
6017
			if (left > bytes)
6018
				left = bytes;
6019
			if (ms->flags & DAHDI_FLAG_HDLC) {
6020
				/* If this is an HDLC channel we only send a byte of
6021
				   HDLC. */
6022
				for(x=0;x<left;x++) {
6023
					if (fasthdlc_tx_need_data(&ms->txhdlc))
6024
						/* Load a byte of data only if needed */
6025
						fasthdlc_tx_load_nocheck(&ms->txhdlc, buf[ms->writeidx[ms->outwritebuf]++]);
6026
					*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
6027
				}
6028
				bytes -= left;
6029
			} else {
6030
				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
6031
				ms->writeidx[ms->outwritebuf]+=left;
6032
				txb += left;
6033
				bytes -= left;
6034
			}
6035
			/* Check buffer status */
6036
			if (ms->writeidx[ms->outwritebuf] >= ms->writen[ms->outwritebuf]) {
6037
				/* We've reached the end of our buffer.  Go to the next. */
6038
				oldbuf = ms->outwritebuf;
6039
				/* Clear out write index and such */
6040
				ms->writeidx[oldbuf] = 0;
6041
				ms->outwritebuf = (ms->outwritebuf + 1) % ms->numbufs;
6042
6043
				if (!(ms->flags & DAHDI_FLAG_MTP2)) {
6044
					ms->writen[oldbuf] = 0;
6045
					if (ms->outwritebuf == ms->inwritebuf) {
6046
						/* Whoopsies, we're run out of buffers.  Mark ours
6047
						as -1 and wait for the filler to notify us that
6048
						there is something to write */
6049
						ms->outwritebuf = -1;
6050
						if (ms->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY))
6051
							wake_up_interruptible(&ms->eventbufq);
6052
						/* If we're only supposed to start when full, disable the transmitter */
6053
						if ((ms->txbufpolicy == DAHDI_POLICY_WHEN_FULL) ||
6054
							(ms->txbufpolicy == DAHDI_POLICY_HALF_FULL))
6055
							ms->txdisable = 1;
6056
					}
6057
				} else {
6058
					if (ms->outwritebuf == ms->inwritebuf) {
6059
						ms->outwritebuf = oldbuf;
6060
						if (ms->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY))
6061
							wake_up_interruptible(&ms->eventbufq);
6062
						/* If we're only supposed to start when full, disable the transmitter */
6063
						if ((ms->txbufpolicy == DAHDI_POLICY_WHEN_FULL) ||
6064
							(ms->txbufpolicy == DAHDI_POLICY_HALF_FULL))
6065
							ms->txdisable = 1;
6066
					}
6067
				}
6068
				if (ms->inwritebuf < 0) {
6069
					/* The filler doesn't have a place to put data.  Now
6070
					that we're done with this buffer, notify them. */
6071
					ms->inwritebuf = oldbuf;
6072
				}
6073
/* In the very orignal driver, it was quite well known to me (Jim) that there
6074
was a possibility that a channel sleeping on a write block needed to
6075
be potentially woken up EVERY time a buffer was emptied, not just on the first
6076
one, because if only done on the first one there is a slight timing potential
6077
of missing the wakeup (between where it senses the (lack of) active condition
6078
(with interrupts disabled) and where it does the sleep (interrupts enabled)
6079
in the read or iomux call, etc). That is why the write and iomux calls start
6080
with an infinite loop that gets broken out of upon an active condition,
6081
otherwise keeps sleeping and looking. The part in this code got "optimized"
6082
out in the later versions, and is put back now. */
6083
				if (!(ms->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP))) {
6084
					wake_up_interruptible(&ms->writebufq);
6085
					wake_up_interruptible(&ms->sel);
6086
					if (ms->iomask & DAHDI_IOMUX_WRITE)
6087
						wake_up_interruptible(&ms->eventbufq);
6088
				}
6089
				/* Transmit a flag if this is an HDLC channel */
6090
				if (ms->flags & DAHDI_FLAG_HDLC)
6091
					fasthdlc_tx_frame_nocheck(&ms->txhdlc);
6092
#ifdef CONFIG_DAHDI_NET
6093
				if (ms->flags & DAHDI_FLAG_NETDEV)
6094
					netif_wake_queue(ztchan_to_dev(ms));
6095
#endif
6096
#ifdef CONFIG_DAHDI_PPP
6097
				if (ms->flags & DAHDI_FLAG_PPP) {
6098
					ms->do_ppp_wakeup = 1;
6099
					tasklet_schedule(&ms->ppp_calls);
6100
				}
6101
#endif
6102
			}
6103
		} else if (ms->curtone && !(ms->flags & DAHDI_FLAG_PSEUDO)) {
6104
			left = ms->curtone->tonesamples - ms->tonep;
6105
			if (left > bytes)
6106
				left = bytes;
6107
			for (x=0;x<left;x++) {
6108
				/* Pick our default value from the next sample of the current tone */
6109
				getlin = dahdi_tone_nextsample(&ms->ts, ms->curtone);
6110
				*(txb++) = DAHDI_LIN2X(getlin, ms);
6111
			}
6112
			ms->tonep+=left;
6113
			bytes -= left;
6114
			if (ms->tonep >= ms->curtone->tonesamples) {
6115
				struct dahdi_tone *last;
6116
				/* Go to the next sample of the tone */
6117
				ms->tonep = 0;
6118
				last = ms->curtone;
6119
				ms->curtone = ms->curtone->next;
6120
				if (!ms->curtone) {
6121
					/* No more tones...  Is this dtmf or mf?  If so, go to the next digit */
6122
					if (ms->dialing)
6123
						__do_dtmf(ms);
6124
				} else {
6125
					if (last != ms->curtone)
6126
						dahdi_init_tone_state(&ms->ts, ms->curtone);
6127
				}
6128
			}
6129
		} else if (ms->flags & DAHDI_FLAG_LOOPED) {
6130
			for (x = 0; x < bytes; x++)
6131
				txb[x] = ms->readchunk[x];
6132
			bytes = 0;
6133
		} else if (ms->flags & DAHDI_FLAG_HDLC) {
6134
			for (x=0;x<bytes;x++) {
6135
				/* Okay, if we're HDLC, then transmit a flag by default */
6136
				if (fasthdlc_tx_need_data(&ms->txhdlc))
6137
					fasthdlc_tx_frame_nocheck(&ms->txhdlc);
6138
				*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
6139
			}
6140
			bytes = 0;
6141
		} else if (ms->flags & DAHDI_FLAG_CLEAR) {
6142
			/* Clear channels that are idle in audio mode need
6143
			   to send silence; in non-audio mode, always send 0xff
6144
			   so stupid switches won't consider the channel active
6145
			*/
6146
			if (ms->flags & DAHDI_FLAG_AUDIO) {
6147
				memset(txb, DAHDI_LIN2X(0, ms), bytes);
6148
			} else {
6149
				memset(txb, 0xFF, bytes);
6150
			}
6151
			bytes = 0;
6152
		} else {
6153
			memset(txb, DAHDI_LIN2X(0, ms), bytes);	/* Lastly we use silence on telephony channels */
6154
			bytes = 0;
6155
		}
6156
	}
6157
}
6158
6159
static inline void rbs_itimer_expire(struct dahdi_chan *chan)
6160
{
6161
	/* the only way this could have gotten here, is if a channel
6162
	    went onf hook longer then the wink or flash detect timeout */
6163
	/* Called with chan->lock held */
6164
	switch(chan->sig)
6165
	{
6166
	    case DAHDI_SIG_FXOLS:  /* if FXO, its definitely on hook */
6167
	    case DAHDI_SIG_FXOGS:
6168
	    case DAHDI_SIG_FXOKS:
6169
		__qevent(chan,DAHDI_EVENT_ONHOOK);
6170
		chan->gotgs = 0;
6171
		break;
6172
#if defined(EMFLASH) || defined(EMPULSE)
6173
	    case DAHDI_SIG_EM:
6174
	    case DAHDI_SIG_EM_E1:
6175
		if (chan->rxhooksig == DAHDI_RXSIG_ONHOOK) {
6176
			__qevent(chan,DAHDI_EVENT_ONHOOK);
6177
			break;
6178
		}
6179
		__qevent(chan,DAHDI_EVENT_RINGOFFHOOK);
6180
		break;
6181
#endif
6182
#ifdef	FXSFLASH
6183
	    case DAHDI_SIG_FXSKS:
6184
		if (chan->rxhooksig == DAHDI_RXSIG_ONHOOK) {
6185
			__qevent(chan, DAHDI_EVENT_ONHOOK);
6186
			break;
6187
		}
6188
#endif
6189
		/* fall thru intentionally */
6190
	    default:  /* otherwise, its definitely off hook */
6191
		__qevent(chan,DAHDI_EVENT_RINGOFFHOOK);
6192
		break;
6193
	}
6194
}
6195
6196
static inline void __rbs_otimer_expire(struct dahdi_chan *chan)
6197
{
6198
	int len = 0;
6199
	/* Called with chan->lock held */
6200
6201
	chan->otimer = 0;
6202
	/* Move to the next timer state */
6203
	switch(chan->txstate) {
6204
	case DAHDI_TXSTATE_RINGOFF:
6205
		/* Turn on the ringer now that the silent time has passed */
6206
		++chan->cadencepos;
6207
		if (chan->cadencepos >= DAHDI_MAX_CADENCE)
6208
			chan->cadencepos = chan->firstcadencepos;
6209
		len = chan->ringcadence[chan->cadencepos];
6210
6211
		if (!len) {
6212
			chan->cadencepos = chan->firstcadencepos;
6213
			len = chan->ringcadence[chan->cadencepos];
6214
		}
6215
6216
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_START, DAHDI_TXSTATE_RINGON, len);
6217
		__qevent(chan, DAHDI_EVENT_RINGERON);
6218
		break;
6219
6220
	case DAHDI_TXSTATE_RINGON:
6221
		/* Turn off the ringer now that the loud time has passed */
6222
		++chan->cadencepos;
6223
		if (chan->cadencepos >= DAHDI_MAX_CADENCE)
6224
			chan->cadencepos = 0;
6225
		len = chan->ringcadence[chan->cadencepos];
6226
6227
		if (!len) {
6228
			chan->cadencepos = 0;
6229
			len = chan->curzone->ringcadence[chan->cadencepos];
6230
		}
6231
6232
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_RINGOFF, len);
6233
		__qevent(chan, DAHDI_EVENT_RINGEROFF);
6234
		break;
6235
6236
	case DAHDI_TXSTATE_START:
6237
		/* If we were starting, go off hook now ready to debounce */
6238
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_AFTERSTART, DAHDI_AFTERSTART_TIME);
6239
		wake_up_interruptible(&chan->txstateq);
6240
		break;
6241
6242
	case DAHDI_TXSTATE_PREWINK:
6243
		/* Actually wink */
6244
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_WINK, chan->winktime);
6245
		break;
6246
6247
	case DAHDI_TXSTATE_WINK:
6248
		/* Wink complete, go on hook and stabalize */
6249
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_ONHOOK, 0);
6250
		if (chan->file && (chan->file->f_flags & O_NONBLOCK))
6251
			__qevent(chan, DAHDI_EVENT_HOOKCOMPLETE);
6252
		wake_up_interruptible(&chan->txstateq);
6253
		break;
6254
6255
	case DAHDI_TXSTATE_PREFLASH:
6256
		/* Actually flash */
6257
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_FLASH, chan->flashtime);
6258
		break;
6259
6260
	case DAHDI_TXSTATE_FLASH:
6261
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_OFFHOOK, 0);
6262
		if (chan->file && (chan->file->f_flags & O_NONBLOCK))
6263
			__qevent(chan, DAHDI_EVENT_HOOKCOMPLETE);
6264
		wake_up_interruptible(&chan->txstateq);
6265
		break;
6266
6267
	case DAHDI_TXSTATE_DEBOUNCE:
6268
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_OFFHOOK, 0);
6269
		/* See if we've gone back on hook */
6270
		if ((chan->rxhooksig == DAHDI_RXSIG_ONHOOK) && (chan->rxflashtime > 2))
6271
			chan->itimerset = chan->itimer = chan->rxflashtime * DAHDI_CHUNKSIZE;
6272
		wake_up_interruptible(&chan->txstateq);
6273
		break;
6274
6275
	case DAHDI_TXSTATE_AFTERSTART:
6276
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_OFFHOOK, 0);
6277
		if (chan->file && (chan->file->f_flags & O_NONBLOCK))
6278
			__qevent(chan, DAHDI_EVENT_HOOKCOMPLETE);
6279
		wake_up_interruptible(&chan->txstateq);
6280
		break;
6281
6282
	case DAHDI_TXSTATE_KEWL:
6283
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_AFTERKEWL, DAHDI_AFTERKEWLTIME);
6284
		if (chan->file && (chan->file->f_flags & O_NONBLOCK))
6285
			__qevent(chan, DAHDI_EVENT_HOOKCOMPLETE);
6286
		wake_up_interruptible(&chan->txstateq);
6287
		break;
6288
6289
	case DAHDI_TXSTATE_AFTERKEWL:
6290
		if (chan->kewlonhook)  {
6291
			__qevent(chan,DAHDI_EVENT_ONHOOK);
6292
		}
6293
		chan->txstate = DAHDI_TXSTATE_ONHOOK;
6294
		chan->gotgs = 0;
6295
		break;
6296
6297
	case DAHDI_TXSTATE_PULSEBREAK:
6298
		dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_PULSEMAKE,
6299
			chan->pulsemaketime);
6300
		wake_up_interruptible(&chan->txstateq);
6301
		break;
6302
6303
	case DAHDI_TXSTATE_PULSEMAKE:
6304
		if (chan->pdialcount)
6305
			chan->pdialcount--;
6306
		if (chan->pdialcount)
6307
		{
6308
			dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK,
6309
				DAHDI_TXSTATE_PULSEBREAK, chan->pulsebreaktime);
6310
			break;
6311
		}
6312
		chan->txstate = DAHDI_TXSTATE_PULSEAFTER;
6313
		chan->otimer = chan->pulseaftertime * DAHDI_CHUNKSIZE;
6314
		wake_up_interruptible(&chan->txstateq);
6315
		break;
6316
6317
	case DAHDI_TXSTATE_PULSEAFTER:
6318
		chan->txstate = DAHDI_TXSTATE_OFFHOOK;
6319
		__do_dtmf(chan);
6320
		wake_up_interruptible(&chan->txstateq);
6321
		break;
6322
6323
	default:
6324
		break;
6325
	}
6326
}
6327
6328
static void __dahdi_hooksig_pvt(struct dahdi_chan *chan, enum dahdi_rxsig rxsig)
6329
{
6330
6331
	/* State machines for receive hookstate transitions
6332
		called with chan->lock held */
6333
6334
	if ((chan->rxhooksig) == rxsig) return;
6335
6336
	if ((chan->flags & DAHDI_FLAG_SIGFREEZE)) return;
6337
6338
	chan->rxhooksig = rxsig;
6339
#ifdef	RINGBEGIN
6340
	if ((chan->sig & __DAHDI_SIG_FXS) && (rxsig == DAHDI_RXSIG_RING) &&
6341
	    (!chan->ringdebtimer))
6342
		__qevent(chan,DAHDI_EVENT_RINGBEGIN);
6343
#endif
6344
	switch(chan->sig) {
6345
	    case DAHDI_SIG_EM:  /* E and M */
6346
	    case DAHDI_SIG_EM_E1:
6347
		switch(rxsig) {
6348
		    case DAHDI_RXSIG_OFFHOOK: /* went off hook */
6349
			/* The interface is going off hook */
6350
#ifdef	EMFLASH
6351
			if (chan->itimer)
6352
			{
6353
				__qevent(chan,DAHDI_EVENT_WINKFLASH);
6354
				chan->itimerset = chan->itimer = 0;
6355
				break;
6356
			}
6357
#endif
6358
#ifdef EMPULSE
6359
			if (chan->itimer) /* if timer still running */
6360
			{
6361
			    int plen = chan->itimerset - chan->itimer;
6362
			    if (plen <= DAHDI_MAXPULSETIME)
6363
			    {
6364
					if (plen >= DAHDI_MINPULSETIME)
6365
					{
6366
						chan->pulsecount++;
6367
6368
						chan->pulsetimer = DAHDI_PULSETIMEOUT;
6369
                                                chan->itimerset = chan->itimer = 0;
6370
						if (chan->pulsecount == 1)
6371
							__qevent(chan,DAHDI_EVENT_PULSE_START);
6372
					}
6373
			    }
6374
			    break;
6375
			}
6376
#endif
6377
			/* set wink timer */
6378
			chan->itimerset = chan->itimer = chan->rxwinktime * DAHDI_CHUNKSIZE;
6379
			break;
6380
		    case DAHDI_RXSIG_ONHOOK: /* went on hook */
6381
			/* This interface is now going on hook.
6382
			   Check for WINK, etc */
6383
			if (chan->itimer)
6384
				__qevent(chan,DAHDI_EVENT_WINKFLASH);
6385
#if defined(EMFLASH) || defined(EMPULSE)
6386
			else {
6387
#ifdef EMFLASH
6388
				chan->itimerset = chan->itimer = chan->rxflashtime * DAHDI_CHUNKSIZE;
6389
6390
#else /* EMFLASH */
6391
				chan->itimerset = chan->itimer = chan->rxwinktime * DAHDI_CHUNKSIZE;
6392
6393
#endif /* EMFLASH */
6394
				chan->gotgs = 0;
6395
				break;
6396
			}
6397
#else /* EMFLASH || EMPULSE */
6398
			else {
6399
				__qevent(chan,DAHDI_EVENT_ONHOOK);
6400
				chan->gotgs = 0;
6401
			}
6402
#endif
6403
			chan->itimerset = chan->itimer = 0;
6404
			break;
6405
		    default:
6406
			break;
6407
		}
6408
		break;
6409
	   case DAHDI_SIG_FXSKS:  /* FXS Kewlstart */
6410
		  /* ignore a bit error if loop not closed and stable */
6411
		if (chan->txstate != DAHDI_TXSTATE_OFFHOOK) break;
6412
#ifdef	FXSFLASH
6413
		if (rxsig == DAHDI_RXSIG_ONHOOK) {
6414
			chan->itimer = DAHDI_FXSFLASHMAXTIME * DAHDI_CHUNKSIZE;
6415
			break;
6416
		} else 	if (rxsig == DAHDI_RXSIG_OFFHOOK) {
6417
			if (chan->itimer) {
6418
				/* did the offhook occur in the window? if not, ignore both events */
6419
				if (chan->itimer <= ((DAHDI_FXSFLASHMAXTIME - DAHDI_FXSFLASHMINTIME) * DAHDI_CHUNKSIZE))
6420
					__qevent(chan, DAHDI_EVENT_WINKFLASH);
6421
			}
6422
			chan->itimer = 0;
6423
			break;
6424
		}
6425
#endif
6426
		/* fall through intentionally */
6427
	   case DAHDI_SIG_FXSGS:  /* FXS Groundstart */
6428
		if (rxsig == DAHDI_RXSIG_ONHOOK) {
6429
			chan->ringdebtimer = RING_DEBOUNCE_TIME;
6430
			chan->ringtrailer = 0;
6431
			if (chan->txstate != DAHDI_TXSTATE_DEBOUNCE) {
6432
				chan->gotgs = 0;
6433
				__qevent(chan,DAHDI_EVENT_ONHOOK);
6434
			}
6435
		}
6436
		break;
6437
	   case DAHDI_SIG_FXOGS: /* FXO Groundstart */
6438
		if (rxsig == DAHDI_RXSIG_START) {
6439
			  /* if havent got gs, report it */
6440
			if (!chan->gotgs) {
6441
				__qevent(chan,DAHDI_EVENT_RINGOFFHOOK);
6442
				chan->gotgs = 1;
6443
			}
6444
		}
6445
		/* fall through intentionally */
6446
	   case DAHDI_SIG_FXOLS: /* FXO Loopstart */
6447
	   case DAHDI_SIG_FXOKS: /* FXO Kewlstart */
6448
		switch(rxsig) {
6449
		    case DAHDI_RXSIG_OFFHOOK: /* went off hook */
6450
			  /* if asserti ng ring, stop it */
6451
			if (chan->txstate == DAHDI_TXSTATE_START) {
6452
				dahdi_rbs_sethook(chan,DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_AFTERSTART, DAHDI_AFTERSTART_TIME);
6453
			}
6454
			chan->kewlonhook = 0;
6455
#ifdef CONFIG_DAHDI_DEBUG
6456
			module_printk(KERN_NOTICE, "Off hook on channel %d, itimer = %d, gotgs = %d\n", chan->channo, chan->itimer, chan->gotgs);
6457
#endif
6458
			if (chan->itimer) /* if timer still running */
6459
			{
6460
			    int plen = chan->itimerset - chan->itimer;
6461
			    if (plen <= DAHDI_MAXPULSETIME)
6462
			    {
6463
					if (plen >= DAHDI_MINPULSETIME)
6464
					{
6465
						chan->pulsecount++;
6466
						chan->pulsetimer = DAHDI_PULSETIMEOUT;
6467
						chan->itimer = chan->itimerset;
6468
						if (chan->pulsecount == 1)
6469
							__qevent(chan,DAHDI_EVENT_PULSE_START);
6470
					}
6471
			    } else
6472
					__qevent(chan,DAHDI_EVENT_WINKFLASH);
6473
			} else {
6474
				  /* if havent got GS detect */
6475
				if (!chan->gotgs) {
6476
					__qevent(chan,DAHDI_EVENT_RINGOFFHOOK);
6477
					chan->gotgs = 1;
6478
					chan->itimerset = chan->itimer = 0;
6479
				}
6480
			}
6481
			chan->itimerset = chan->itimer = 0;
6482
			break;
6483
		    case DAHDI_RXSIG_ONHOOK: /* went on hook */
6484
			  /* if not during offhook debounce time */
6485
			if ((chan->txstate != DAHDI_TXSTATE_DEBOUNCE) &&
6486
			    (chan->txstate != DAHDI_TXSTATE_KEWL) &&
6487
			    (chan->txstate != DAHDI_TXSTATE_AFTERKEWL)) {
6488
				chan->itimerset = chan->itimer = chan->rxflashtime * DAHDI_CHUNKSIZE;
6489
			}
6490
			if (chan->txstate == DAHDI_TXSTATE_KEWL)
6491
				chan->kewlonhook = 1;
6492
			break;
6493
		    default:
6494
			break;
6495
		}
6496
	    default:
6497
		break;
6498
	}
6499
}
6500
6501
void dahdi_hooksig(struct dahdi_chan *chan, enum dahdi_rxsig rxsig)
6502
{
6503
	  /* skip if no change */
6504
	unsigned long flags;
6505
	spin_lock_irqsave(&chan->lock, flags);
6506
	__dahdi_hooksig_pvt(chan,rxsig);
6507
	spin_unlock_irqrestore(&chan->lock, flags);
6508
}
6509
6510
void dahdi_rbsbits(struct dahdi_chan *chan, int cursig)
6511
{
6512
	unsigned long flags;
6513
	if (cursig == chan->rxsig)
6514
		return;
6515
6516
	if ((chan->flags & DAHDI_FLAG_SIGFREEZE)) return;
6517
6518
	spin_lock_irqsave(&chan->lock, flags);
6519
	switch(chan->sig) {
6520
	    case DAHDI_SIG_FXOGS: /* FXO Groundstart */
6521
		/* B-bit only matters for FXO GS */
6522
		if (!(cursig & DAHDI_BBIT)) {
6523
			__dahdi_hooksig_pvt(chan, DAHDI_RXSIG_START);
6524
			break;
6525
		}
6526
		/* Fall through */
6527
	    case DAHDI_SIG_EM:  /* E and M */
6528
	    case DAHDI_SIG_EM_E1:
6529
	    case DAHDI_SIG_FXOLS: /* FXO Loopstart */
6530
	    case DAHDI_SIG_FXOKS: /* FXO Kewlstart */
6531
		if (cursig & DAHDI_ABIT)  /* off hook */
6532
			__dahdi_hooksig_pvt(chan,DAHDI_RXSIG_OFFHOOK);
6533
		else /* on hook */
6534
			__dahdi_hooksig_pvt(chan,DAHDI_RXSIG_ONHOOK);
6535
		break;
6536
6537
	   case DAHDI_SIG_FXSKS:  /* FXS Kewlstart */
6538
	   case DAHDI_SIG_FXSGS:  /* FXS Groundstart */
6539
		/* Fall through */
6540
	   case DAHDI_SIG_FXSLS:
6541
		if (!(cursig & DAHDI_BBIT)) {
6542
			/* Check for ringing first */
6543
			__dahdi_hooksig_pvt(chan, DAHDI_RXSIG_RING);
6544
			break;
6545
		}
6546
		if ((chan->sig != DAHDI_SIG_FXSLS) && (cursig & DAHDI_ABIT)) {
6547
			    /* if went on hook */
6548
			__dahdi_hooksig_pvt(chan, DAHDI_RXSIG_ONHOOK);
6549
		} else {
6550
			__dahdi_hooksig_pvt(chan, DAHDI_RXSIG_OFFHOOK);
6551
		}
6552
		break;
6553
	   case DAHDI_SIG_CAS:
6554
		/* send event that something changed */
6555
		__qevent(chan, DAHDI_EVENT_BITSCHANGED);
6556
		break;
6557
6558
	   default:
6559
		break;
6560
	}
6561
	/* Keep track of signalling for next time */
6562
	chan->rxsig = cursig;
6563
	spin_unlock_irqrestore(&chan->lock, flags);
6564
}
6565
6566
static void process_echocan_events(struct dahdi_chan *chan)
6567
{
6568
	union dahdi_echocan_events events = chan->ec_state->events;
6569
6570
	if (events.CED_tx_detected) {
6571
		dahdi_qevent_nolock(chan, DAHDI_EVENT_TX_CED_DETECTED);
6572
		if (chan->ec_state) {
6573
			if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE)
6574
				set_echocan_fax_mode(chan, chan->channo, "CED tx detected", 1);
6575
			else
6576
				module_printk(KERN_NOTICE, "Detected CED tone (tx) on channel %d\n", chan->channo);
6577
		}
6578
	}
6579
6580
	if (events.CED_rx_detected) {
6581
		dahdi_qevent_nolock(chan, DAHDI_EVENT_RX_CED_DETECTED);
6582
		if (chan->ec_state) {
6583
			if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE)
6584
				set_echocan_fax_mode(chan, chan->channo, "CED rx detected", 1);
6585
			else
6586
				module_printk(KERN_NOTICE, "Detected CED tone (rx) on channel %d\n", chan->channo);
6587
		}
6588
	}
6589
6590
	if (events.CNG_tx_detected)
6591
		dahdi_qevent_nolock(chan, DAHDI_EVENT_TX_CNG_DETECTED);
6592
6593
	if (events.CNG_rx_detected)
6594
		dahdi_qevent_nolock(chan, DAHDI_EVENT_RX_CNG_DETECTED);
6595
6596
	if (events.NLP_auto_disabled) {
6597
		dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_DISABLED);
6598
		chan->ec_state->status.mode = ECHO_MODE_FAX;
6599
	}
6600
6601
	if (events.NLP_auto_enabled) {
6602
		dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_ENABLED);
6603
		chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
6604
	}
6605
}
6606
6607
static inline void __dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk)
6608
{
6609
	short rxlin, txlin;
6610
	int x;
6611
	unsigned long flags;
6612
6613
	spin_lock_irqsave(&ss->lock, flags);
6614
6615
	if (ss->readchunkpreec) {
6616
		/* Save a copy of the audio before the echo can has its way with it */
6617
		for (x = 0; x < DAHDI_CHUNKSIZE; x++)
6618
			/* We only ever really need to deal with signed linear - let's just convert it now */
6619
			ss->readchunkpreec[x] = DAHDI_XLAW(rxchunk[x], ss);
6620
	}
6621
6622
	/* Perform echo cancellation on a chunk if necessary */
6623
	if (ss->ec_state) {
6624
#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
6625
		dahdi_kernel_fpu_begin();
6626
#endif
6627
		if (ss->ec_state->status.mode & __ECHO_MODE_MUTE) {
6628
			/* Special stuff for training the echo can */
6629
			for (x=0;x<DAHDI_CHUNKSIZE;x++) {
6630
				rxlin = DAHDI_XLAW(rxchunk[x], ss);
6631
				txlin = DAHDI_XLAW(txchunk[x], ss);
6632
				if (ss->ec_state->status.mode == ECHO_MODE_PRETRAINING) {
6633
					if (--ss->ec_state->status.pretrain_timer <= 0) {
6634
						ss->ec_state->status.pretrain_timer = 0;
6635
						ss->ec_state->status.mode = ECHO_MODE_STARTTRAINING;
6636
					}
6637
				}
6638
				if ((ss->ec_state->status.mode == ECHO_MODE_AWAITINGECHO) && (txlin > 8000)) {
6639
					ss->ec_state->status.last_train_tap = 0;
6640
					ss->ec_state->status.mode = ECHO_MODE_TRAINING;
6641
				}
6642
				if (ss->ec_state->status.mode == ECHO_MODE_TRAINING) {
6643
					if (ss->ec_state->ops->echocan_traintap(ss->ec_state, ss->ec_state->status.last_train_tap++, rxlin)) {
6644
#if 0
6645
						module_printk(KERN_NOTICE, "Finished training (%d taps trained)!\n", ss->ec_state->status.last_train_tap);
6646
#endif
6647
						ss->ec_state->status.mode = ECHO_MODE_ACTIVE;
6648
					}
6649
				}
6650
				rxlin = 0;
6651
				rxchunk[x] = DAHDI_LIN2X((int)rxlin, ss);
6652
			}
6653
		} else if (ss->ec_state->status.mode != ECHO_MODE_IDLE) {
6654
			ss->ec_state->events.all = 0;
6655
6656
			if (ss->ec_state->ops->echocan_process) {
6657
				short rxlins[DAHDI_CHUNKSIZE], txlins[DAHDI_CHUNKSIZE];
6658
6659
				for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
6660
					rxlins[x] = DAHDI_XLAW(rxchunk[x], ss);
6661
					txlins[x] = DAHDI_XLAW(txchunk[x], ss);
6662
				}
6663
				ss->ec_state->ops->echocan_process(ss->ec_state, rxlins, txlins, DAHDI_CHUNKSIZE);
6664
6665
				for (x = 0; x < DAHDI_CHUNKSIZE; x++)
6666
					rxchunk[x] = DAHDI_LIN2X((int) rxlins[x], ss);
6667
			} else if (ss->ec_state->ops->echocan_events)
6668
				ss->ec_state->ops->echocan_events(ss->ec_state);
6669
6670
			if (ss->ec_state->events.all)
6671
				process_echocan_events(ss);
6672
6673
		}
6674
#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
6675
		kernel_fpu_end();
6676
#endif
6677
	}
6678
	spin_unlock_irqrestore(&ss->lock, flags);
6679
}
6680
6681
void dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk)
6682
{
6683
	__dahdi_ec_chunk(ss, rxchunk, txchunk);
6684
}
6685
6686
void dahdi_ec_span(struct dahdi_span *span)
6687
{
6688
	int x;
6689
	for (x = 0; x < span->channels; x++) {
6690
		if (span->chans[x]->ec_current)
6691
			__dahdi_ec_chunk(span->chans[x], span->chans[x]->readchunk, span->chans[x]->writechunk);
6692
	}
6693
}
6694
6695
/* return 0 if nothing detected, 1 if lack of tone, 2 if presence of tone */
6696
/* modifies buffer pointed to by 'amp' with notched-out values */
6697
static inline int sf_detect(struct sf_detect_state *s,
6698
                 short *amp,
6699
                 int samples,long p1, long p2, long p3)
6700
{
6701
int     i,rv = 0;
6702
long x,y;
6703
6704
#define	SF_DETECT_SAMPLES (DAHDI_CHUNKSIZE * 5)
6705
#define	SF_DETECT_MIN_ENERGY 500
6706
#define	NB 14  /* number of bits to shift left */
6707
6708
        /* determine energy level before filtering */
6709
        for(i = 0; i < samples; i++)
6710
        {
6711
                if (amp[i] < 0) s->e1 -= amp[i];
6712
                else s->e1 += amp[i];
6713
        }
6714
	/* do 2nd order IIR notch filter at given freq. and calculate
6715
	    energy */
6716
        for(i = 0; i < samples; i++)
6717
        {
6718
                x = amp[i] << NB;
6719
                y = s->x2 + (p1 * (s->x1 >> NB)) + x;
6720
                y += (p2 * (s->y2 >> NB)) +
6721
			(p3 * (s->y1 >> NB));
6722
                s->x2 = s->x1;
6723
                s->x1 = x;
6724
                s->y2 = s->y1;
6725
                s->y1 = y;
6726
                amp[i] = y >> NB;
6727
                if (amp[i] < 0) s->e2 -= amp[i];
6728
                else s->e2 += amp[i];
6729
        }
6730
	s->samps += i;
6731
	/* if time to do determination */
6732
	if ((s->samps) >= SF_DETECT_SAMPLES)
6733
	{
6734
		rv = 1; /* default to no tone */
6735
		/* if enough energy, it is determined to be a tone */
6736
		if (((s->e1 - s->e2) / s->samps) > SF_DETECT_MIN_ENERGY) rv = 2;
6737
		/* reset energy processing variables */
6738
		s->samps = 0;
6739
		s->e1 = s->e2 = 0;
6740
	}
6741
	return(rv);
6742
}
6743
6744
static inline void __dahdi_process_putaudio_chunk(struct dahdi_chan *ss, unsigned char *rxb)
6745
{
6746
	/* We transmit data from our master channel */
6747
	/* Called with ss->lock held */
6748
	struct dahdi_chan *ms = ss->master;
6749
	/* Linear version of received data */
6750
	short putlin[DAHDI_CHUNKSIZE],k[DAHDI_CHUNKSIZE];
6751
	int x,r;
6752
6753
	if (ms->dialing) ms->afterdialingtimer = 50;
6754
	else if (ms->afterdialingtimer) ms->afterdialingtimer--;
6755
	if (ms->afterdialingtimer && (!(ms->flags & DAHDI_FLAG_PSEUDO))) {
6756
		/* Be careful since memset is likely a macro */
6757
		rxb[0] = DAHDI_LIN2X(0, ms);
6758
		memset(&rxb[1], rxb[0], DAHDI_CHUNKSIZE - 1);  /* receive as silence if dialing */
6759
	}
6760
	for (x=0;x<DAHDI_CHUNKSIZE;x++) {
6761
		rxb[x] = ms->rxgain[rxb[x]];
6762
		putlin[x] = DAHDI_XLAW(rxb[x], ms);
6763
	}
6764
6765
	if (ms->ec_state && (ms->ec_state->status.mode == ECHO_MODE_ACTIVE) && !ms->ec_state->features.CED_rx_detect) {
6766
		for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
6767
			if (echo_can_disable_detector_update(&ms->ec_state->rxecdis, putlin[x])) {
6768
				set_echocan_fax_mode(ms, ss->channo, "CED rx detected", 1);
6769
				dahdi_qevent_nolock(ms, DAHDI_EVENT_RX_CED_DETECTED);
6770
				break;
6771
			}
6772
		}
6773
	}
6774
6775
	/* if doing rx tone decoding */
6776
	if (ms->rxp1 && ms->rxp2 && ms->rxp3)
6777
	{
6778
		r = sf_detect(&ms->rd,putlin,DAHDI_CHUNKSIZE,ms->rxp1,
6779
			ms->rxp2,ms->rxp3);
6780
		/* Convert back */
6781
		for(x=0;x<DAHDI_CHUNKSIZE;x++)
6782
			rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6783
		if (r) /* if something happened */
6784
		{
6785
			if (r != ms->rd.lastdetect)
6786
			{
6787
				if (((r == 2) && !(ms->toneflags & DAHDI_REVERSE_RXTONE)) ||
6788
				    ((r == 1) && (ms->toneflags & DAHDI_REVERSE_RXTONE)))
6789
				{
6790
					__qevent(ms,DAHDI_EVENT_RINGOFFHOOK);
6791
				}
6792
				else
6793
				{
6794
					__qevent(ms,DAHDI_EVENT_ONHOOK);
6795
				}
6796
				ms->rd.lastdetect = r;
6797
			}
6798
		}
6799
	}
6800
6801
	if (!(ms->flags &  DAHDI_FLAG_PSEUDO)) {
6802
		memcpy(ms->putlin, putlin, DAHDI_CHUNKSIZE * sizeof(short));
6803
		memcpy(ms->putraw, rxb, DAHDI_CHUNKSIZE);
6804
	}
6805
6806
	/* Take the rxc, twiddle it for conferencing if appropriate and put it
6807
	   back */
6808
	if ((!ms->confmute && !ms->afterdialingtimer) ||
6809
	    (ms->flags & DAHDI_FLAG_PSEUDO)) {
6810
		switch(ms->confmode & DAHDI_CONF_MODE_MASK) {
6811
		case DAHDI_CONF_NORMAL:		/* Normal mode */
6812
			/* Do nothing.  rx goes output */
6813
			break;
6814
		case DAHDI_CONF_MONITOR:		/* Monitor a channel's rx mode */
6815
			  /* if not a pseudo-channel, ignore */
6816
			if (!(ms->flags & DAHDI_FLAG_PSEUDO)) break;
6817
			/* Add monitored channel */
6818
			if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) {
6819
				ACSS(putlin, chans[ms->confna]->getlin);
6820
			} else {
6821
				ACSS(putlin, chans[ms->confna]->putlin);
6822
			}
6823
			/* Convert back */
6824
			for(x=0;x<DAHDI_CHUNKSIZE;x++)
6825
				rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6826
			break;
6827
		case DAHDI_CONF_MONITORTX:	/* Monitor a channel's tx mode */
6828
			  /* if not a pseudo-channel, ignore */
6829
			if (!(ms->flags & DAHDI_FLAG_PSEUDO)) break;
6830
			/* Add monitored channel */
6831
			if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) {
6832
				ACSS(putlin, chans[ms->confna]->putlin);
6833
			} else {
6834
				ACSS(putlin, chans[ms->confna]->getlin);
6835
			}
6836
			/* Convert back */
6837
			for(x=0;x<DAHDI_CHUNKSIZE;x++)
6838
				rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6839
			break;
6840
		case DAHDI_CONF_MONITORBOTH:	/* Monitor a channel's tx and rx mode */
6841
			  /* if not a pseudo-channel, ignore */
6842
			if (!(ms->flags & DAHDI_FLAG_PSEUDO)) break;
6843
			/* Note: Technically, saturation should be done at
6844
			   the end of the whole addition, but for performance
6845
			   reasons, we don't do that.  Besides, it only matters
6846
			   when you're so loud you're clipping anyway */
6847
			ACSS(putlin, chans[ms->confna]->getlin);
6848
			ACSS(putlin, chans[ms->confna]->putlin);
6849
			/* Convert back */
6850
			for(x=0;x<DAHDI_CHUNKSIZE;x++)
6851
				rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6852
			break;
6853
		case DAHDI_CONF_MONITOR_RX_PREECHO:		/* Monitor a channel's rx mode */
6854
			  /* if not a pseudo-channel, ignore */
6855
			if (!(ms->flags & DAHDI_FLAG_PSEUDO))
6856
				break;
6857
6858
			if (!chans[ms->confna]->readchunkpreec)
6859
				break;
6860
6861
			/* Add monitored channel */
6862
			ACSS(putlin, chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO ?
6863
			     chans[ms->confna]->getlin : chans[ms->confna]->readchunkpreec);
6864
			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
6865
				rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6866
6867
			break;
6868
		case DAHDI_CONF_MONITOR_TX_PREECHO:	/* Monitor a channel's tx mode */
6869
			  /* if not a pseudo-channel, ignore */
6870
			if (!(ms->flags & DAHDI_FLAG_PSEUDO))
6871
				break;
6872
6873
			if (!chans[ms->confna]->readchunkpreec)
6874
				break;
6875
6876
			/* Add monitored channel */
6877
			ACSS(putlin, chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO ?
6878
			     chans[ms->confna]->readchunkpreec : chans[ms->confna]->getlin);
6879
			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
6880
				rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6881
6882
			break;
6883
		case DAHDI_CONF_MONITORBOTH_PREECHO:	/* Monitor a channel's tx and rx mode */
6884
			  /* if not a pseudo-channel, ignore */
6885
			if (!(ms->flags & DAHDI_FLAG_PSEUDO))
6886
				break;
6887
6888
			if (!chans[ms->confna]->readchunkpreec)
6889
				break;
6890
6891
			/* Note: Technically, saturation should be done at
6892
			   the end of the whole addition, but for performance
6893
			   reasons, we don't do that.  Besides, it only matters
6894
			   when you're so loud you're clipping anyway */
6895
			ACSS(putlin, chans[ms->confna]->getlin);
6896
			ACSS(putlin, chans[ms->confna]->readchunkpreec);
6897
			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
6898
				rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6899
6900
			break;
6901
		case DAHDI_CONF_REALANDPSEUDO:
6902
			  /* do normal conf mode processing */
6903
			if (ms->confmode & DAHDI_CONF_TALKER) {
6904
				/* Store temp value */
6905
				memcpy(k, putlin, DAHDI_CHUNKSIZE * sizeof(short));
6906
				/* Add conf value */
6907
				ACSS(k, conf_sums_next[ms->_confn]);
6908
				/*  get amount actually added */
6909
				memcpy(ms->conflast, k, DAHDI_CHUNKSIZE * sizeof(short));
6910
				SCSS(ms->conflast, conf_sums_next[ms->_confn]);
6911
				/* Really add in new value */
6912
				ACSS(conf_sums_next[ms->_confn], ms->conflast);
6913
			} else memset(ms->conflast, 0, DAHDI_CHUNKSIZE * sizeof(short));
6914
			  /* do the pseudo-channel part processing */
6915
			memset(putlin, 0, DAHDI_CHUNKSIZE * sizeof(short));
6916
			if (ms->confmode & DAHDI_CONF_PSEUDO_LISTENER) {
6917
				/* Subtract out previous last sample written to conf */
6918
				SCSS(putlin, ms->conflast2);
6919
				/* Add in conference */
6920
				ACSS(putlin, conf_sums[ms->_confn]);
6921
			}
6922
			/* Convert back */
6923
			for(x=0;x<DAHDI_CHUNKSIZE;x++)
6924
				rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6925
			break;
6926
		case DAHDI_CONF_CONF:	/* Normal conference mode */
6927
			if (ms->flags & DAHDI_FLAG_PSEUDO) /* if a pseudo-channel */
6928
			   {
6929
				if (ms->confmode & DAHDI_CONF_LISTENER) {
6930
					/* Subtract out last sample written to conf */
6931
					SCSS(putlin, ms->conflast);
6932
					/* Add in conference */
6933
					ACSS(putlin, conf_sums[ms->_confn]);
6934
				}
6935
				/* Convert back */
6936
				for(x=0;x<DAHDI_CHUNKSIZE;x++)
6937
					rxb[x] = DAHDI_LIN2X(putlin[x], ms);
6938
				memcpy(ss->putlin, putlin, DAHDI_CHUNKSIZE * sizeof(short));
6939
				break;
6940
			   }
6941
			/* fall through */
6942
		case DAHDI_CONF_CONFANN:  /* Conference with announce */
6943
			if (ms->confmode & DAHDI_CONF_TALKER) {
6944
				/* Store temp value */
6945
				memcpy(k, putlin, DAHDI_CHUNKSIZE * sizeof(short));
6946
				/* Add conf value */
6947
				ACSS(k, conf_sums_next[ms->_confn]);
6948
				/*  get amount actually added */
6949
				memcpy(ms->conflast, k, DAHDI_CHUNKSIZE * sizeof(short));
6950
				SCSS(ms->conflast, conf_sums_next[ms->_confn]);
6951
				/* Really add in new value */
6952
				ACSS(conf_sums_next[ms->_confn], ms->conflast);
6953
			} else
6954
				memset(ms->conflast, 0, DAHDI_CHUNKSIZE * sizeof(short));
6955
			  /* rxc unmodified */
6956
			break;
6957
		case DAHDI_CONF_CONFMON:
6958
		case DAHDI_CONF_CONFANNMON:
6959
			if (ms->confmode & DAHDI_CONF_TALKER) {
6960
				/* Store temp value */
6961
				memcpy(k, putlin, DAHDI_CHUNKSIZE * sizeof(short));
6962
				/* Subtract last value */
6963
				SCSS(conf_sums[ms->_confn], ms->conflast);
6964
				/* Add conf value */
6965
				ACSS(k, conf_sums[ms->_confn]);
6966
				/*  get amount actually added */
6967
				memcpy(ms->conflast, k, DAHDI_CHUNKSIZE * sizeof(short));
6968
				SCSS(ms->conflast, conf_sums[ms->_confn]);
6969
				/* Really add in new value */
6970
				ACSS(conf_sums[ms->_confn], ms->conflast);
6971
			} else
6972
				memset(ms->conflast, 0, DAHDI_CHUNKSIZE * sizeof(short));
6973
			for (x=0;x<DAHDI_CHUNKSIZE;x++)
6974
				rxb[x] = DAHDI_LIN2X((int)conf_sums_prev[ms->_confn][x], ms);
6975
			break;
6976
		case DAHDI_CONF_DIGITALMON:
6977
			  /* if not a pseudo-channel, ignore */
6978
			if (!(ms->flags & DAHDI_FLAG_PSEUDO)) break;
6979
			/* Add monitored channel */
6980
			if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) {
6981
				memcpy(rxb, chans[ms->confna]->getraw, DAHDI_CHUNKSIZE);
6982
			} else {
6983
				memcpy(rxb, chans[ms->confna]->putraw, DAHDI_CHUNKSIZE);
6984
			}
6985
			break;
6986
		}
6987
	}
6988
}
6989
6990
/* HDLC (or other) receiver buffer functions for read side */
6991
static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int bytes)
6992
{
6993
	/* We transmit data from our master channel */
6994
	/* Called with ss->lock held */
6995
	struct dahdi_chan *ms = ss->master;
6996
	/* Our receive buffer */
6997
	unsigned char *buf;
6998
#if defined(CONFIG_DAHDI_NET)  || defined(CONFIG_DAHDI_PPP)
6999
	/* SKB for receiving network stuff */
7000
	struct sk_buff *skb=NULL;
7001
#endif
7002
	int oldbuf;
7003
	int eof=0;
7004
	int abort=0;
7005
	int res;
7006
	int left, x;
7007
7008
	while(bytes) {
7009
#if defined(CONFIG_DAHDI_NET)  || defined(CONFIG_DAHDI_PPP)
7010
		skb = NULL;
7011
#endif
7012
		abort = 0;
7013
		eof = 0;
7014
		/* Next, figure out if we've got a buffer to receive into */
7015
		if (ms->inreadbuf > -1) {
7016
			/* Read into the current buffer */
7017
			buf = ms->readbuf[ms->inreadbuf];
7018
			left = ms->blocksize - ms->readidx[ms->inreadbuf];
7019
			if (left > bytes)
7020
				left = bytes;
7021
			if (ms->flags & DAHDI_FLAG_HDLC) {
7022
				for (x=0;x<left;x++) {
7023
					/* Handle HDLC deframing */
7024
					fasthdlc_rx_load_nocheck(&ms->rxhdlc, *(rxb++));
7025
					bytes--;
7026
					res = fasthdlc_rx_run(&ms->rxhdlc);
7027
					/* If there is nothing there, continue */
7028
					if (res & RETURN_EMPTY_FLAG)
7029
						continue;
7030
					else if (res & RETURN_COMPLETE_FLAG) {
7031
						/* Only count this if it's a non-empty frame */
7032
						if (ms->readidx[ms->inreadbuf]) {
7033
							if ((ms->flags & DAHDI_FLAG_FCS) && (ms->infcs != PPP_GOODFCS)) {
7034
								abort = DAHDI_EVENT_BADFCS;
7035
							} else
7036
								eof=1;
7037
							break;
7038
						}
7039
						continue;
7040
					} else if (res & RETURN_DISCARD_FLAG) {
7041
						/* This could be someone idling with
7042
						  "idle" instead of "flag" */
7043
						if (!ms->readidx[ms->inreadbuf])
7044
							continue;
7045
						abort = DAHDI_EVENT_ABORT;
7046
						break;
7047
					} else {
7048
						unsigned char rxc;
7049
						rxc = res;
7050
						ms->infcs = PPP_FCS(ms->infcs, rxc);
7051
						buf[ms->readidx[ms->inreadbuf]++] = rxc;
7052
						/* Pay attention to the possibility of an overrun */
7053
						if (ms->readidx[ms->inreadbuf] >= ms->blocksize) {
7054
							if (!ss->span->alarms)
7055
								module_printk(KERN_WARNING, "HDLC Receiver overrun on channel %s (master=%s)\n", ss->name, ss->master->name);
7056
							abort=DAHDI_EVENT_OVERRUN;
7057
							/* Force the HDLC state back to frame-search mode */
7058
							ms->rxhdlc.state = 0;
7059
							ms->rxhdlc.bits = 0;
7060
							ms->readidx[ms->inreadbuf]=0;
7061
							break;
7062
						}
7063
					}
7064
				}
7065
			} else {
7066
				/* Not HDLC */
7067
				memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
7068
				rxb += left;
7069
				ms->readidx[ms->inreadbuf] += left;
7070
				bytes -= left;
7071
				/* End of frame is decided by block size of 'N' */
7072
				eof = (ms->readidx[ms->inreadbuf] >= ms->blocksize);
7073
				if (eof && (ss->flags & DAHDI_FLAG_NOSTDTXRX)) {
7074
					eof = 0;
7075
					abort = DAHDI_EVENT_OVERRUN;
7076
				}
7077
			}
7078
			if (eof)  {
7079
				/* Finished with this buffer, try another. */
7080
				oldbuf = ms->inreadbuf;
7081
				ms->infcs = PPP_INITFCS;
7082
				ms->readn[ms->inreadbuf] = ms->readidx[ms->inreadbuf];
7083
#ifdef CONFIG_DAHDI_DEBUG
7084
				module_printk(KERN_NOTICE, "EOF, len is %d\n", ms->readn[ms->inreadbuf]);
7085
#endif
7086
#if defined(CONFIG_DAHDI_NET) || defined(CONFIG_DAHDI_PPP)
7087
				if (ms->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP)) {
7088
#ifdef CONFIG_DAHDI_NET
7089
#endif /* CONFIG_DAHDI_NET */
7090
					/* Our network receiver logic is MUCH
7091
					  different.  We actually only use a single
7092
					  buffer */
7093
					if (ms->readn[ms->inreadbuf] > 1) {
7094
						/* Drop the FCS */
7095
						ms->readn[ms->inreadbuf] -= 2;
7096
						/* Allocate an SKB */
7097
#ifdef CONFIG_DAHDI_PPP
7098
						if (!ms->do_ppp_error)
7099
#endif
7100
							skb = dev_alloc_skb(ms->readn[ms->inreadbuf]);
7101
						if (skb) {
7102
							/* XXX Get rid of this memcpy XXX */
7103
							memcpy(skb->data, ms->readbuf[ms->inreadbuf], ms->readn[ms->inreadbuf]);
7104
							skb_put(skb, ms->readn[ms->inreadbuf]);
7105
#ifdef CONFIG_DAHDI_NET
7106
							if (ms->flags & DAHDI_FLAG_NETDEV) {
7107
								struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev);
7108
								stats->rx_packets++;
7109
								stats->rx_bytes += ms->readn[ms->inreadbuf];
7110
							}
7111
#endif
7112
7113
						} else {
7114
#ifdef CONFIG_DAHDI_NET
7115
							if (ms->flags & DAHDI_FLAG_NETDEV) {
7116
								struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev);
7117
								stats->rx_dropped++;
7118
							}
7119
#endif
7120
#ifdef CONFIG_DAHDI_PPP
7121
							if (ms->flags & DAHDI_FLAG_PPP) {
7122
								abort = DAHDI_EVENT_OVERRUN;
7123
							}
7124
#endif
7125
#if 1
7126
#ifdef CONFIG_DAHDI_PPP
7127
							if (!ms->do_ppp_error)
7128
#endif
7129
								module_printk(KERN_NOTICE, "Memory squeeze, dropped one\n");
7130
#endif
7131
						}
7132
					}
7133
					/* We don't cycle through buffers, just
7134
					reuse the same one */
7135
					ms->readn[ms->inreadbuf] = 0;
7136
					ms->readidx[ms->inreadbuf] = 0;
7137
				} else
7138
#endif
7139
				{
7140
					/* This logic might confuse and astound.  Basically we need to find
7141
					 * the previous buffer index.  It should be safe because, regardless
7142
					 * of whether or not it has been copied to user space, nothing should
7143
					 * have messed around with it since then */
7144
7145
					int comparemessage;
7146
					/* Shut compiler up */
7147
					int myres = 0;
7148
7149
					if (ms->flags & DAHDI_FLAG_MTP2) {
7150
						comparemessage = (ms->inreadbuf - 1) & (ms->numbufs - 1);
7151
7152
						myres = memcmp(ms->readbuf[comparemessage], ms->readbuf[ms->inreadbuf], ms->readn[ms->inreadbuf]);
7153
					}
7154
7155
					if ((ms->flags & DAHDI_FLAG_MTP2) && !myres) {
7156
						/* Our messages are the same, so discard -
7157
						 * 	Don't advance buffers, reset indexes and buffer sizes. */
7158
						ms->readn[ms->inreadbuf] = 0;
7159
						ms->readidx[ms->inreadbuf] = 0;
7160
					} else {
7161
						ms->inreadbuf = (ms->inreadbuf + 1) % ms->numbufs;
7162
						if (ms->inreadbuf == ms->outreadbuf) {
7163
							/* Whoops, we're full, and have no where else
7164
							   to store into at the moment.  We'll drop it
7165
							   until there's a buffer available */
7166
#ifdef BUFFER_DEBUG
7167
							module_printk(KERN_NOTICE, "Out of storage space\n");
7168
#endif
7169
							ms->inreadbuf = -1;
7170
							/* Enable the receiver in case they've got POLICY_WHEN_FULL */
7171
							ms->rxdisable = 0;
7172
						}
7173
						if (ms->outreadbuf < 0) { /* start out buffer if not already */
7174
							ms->outreadbuf = oldbuf;
7175
							/* if there are processes waiting in poll() on this channel,
7176
							   wake them up */
7177
							if (!ms->rxdisable) {
7178
								wake_up_interruptible(&ms->sel);
7179
							}
7180
						}
7181
/* In the very orignal driver, it was quite well known to me (Jim) that there
7182
was a possibility that a channel sleeping on a receive block needed to
7183
be potentially woken up EVERY time a buffer was filled, not just on the first
7184
one, because if only done on the first one there is a slight timing potential
7185
of missing the wakeup (between where it senses the (lack of) active condition
7186
(with interrupts disabled) and where it does the sleep (interrupts enabled)
7187
in the read or iomux call, etc). That is why the read and iomux calls start
7188
with an infinite loop that gets broken out of upon an active condition,
7189
otherwise keeps sleeping and looking. The part in this code got "optimized"
7190
out in the later versions, and is put back now. Note that this is *NOT*
7191
needed for poll() waiters, because the poll_wait() function that is used there
7192
is atomic enough for this purpose; it will not go to sleep before ensuring
7193
that the waitqueue is empty. */
7194
						if (!ms->rxdisable) { /* if receiver enabled */
7195
							/* Notify a blocked reader that there is data available
7196
							to be read, unless we're waiting for it to be full */
7197
#ifdef CONFIG_DAHDI_DEBUG
7198
							module_printk(KERN_NOTICE, "Notifying reader data in block %d\n", oldbuf);
7199
#endif
7200
							wake_up_interruptible(&ms->readbufq);
7201
							if (ms->iomask & DAHDI_IOMUX_READ)
7202
								wake_up_interruptible(&ms->eventbufq);
7203
						}
7204
					}
7205
				}
7206
			}
7207
			if (abort) {
7208
				/* Start over reading frame */
7209
				ms->readidx[ms->inreadbuf] = 0;
7210
				ms->infcs = PPP_INITFCS;
7211
7212
#ifdef CONFIG_DAHDI_NET
7213
				if (ms->flags & DAHDI_FLAG_NETDEV) {
7214
					struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev);
7215
					stats->rx_errors++;
7216
					if (abort == DAHDI_EVENT_OVERRUN)
7217
						stats->rx_over_errors++;
7218
					if (abort == DAHDI_EVENT_BADFCS)
7219
						stats->rx_crc_errors++;
7220
					if (abort == DAHDI_EVENT_ABORT)
7221
						stats->rx_frame_errors++;
7222
				} else
7223
#endif
7224
#ifdef CONFIG_DAHDI_PPP
7225
				if (ms->flags & DAHDI_FLAG_PPP) {
7226
					ms->do_ppp_error = 1;
7227
					tasklet_schedule(&ms->ppp_calls);
7228
				} else
7229
#endif
7230
					if (test_bit(DAHDI_FLAGBIT_OPEN, &ms->flags) && !ss->span->alarms) {
7231
						/* Notify the receiver... */
7232
						__qevent(ss->master, abort);
7233
					}
7234
#if 0
7235
				module_printk(KERN_NOTICE, "torintr_receive: Aborted %d bytes of frame on %d\n", amt, ss->master);
7236
#endif
7237
7238
			}
7239
		} else /* No place to receive -- drop on the floor */
7240
			break;
7241
#ifdef CONFIG_DAHDI_NET
7242
		if (skb && (ms->flags & DAHDI_FLAG_NETDEV))
7243
#ifdef NEW_HDLC_INTERFACE
7244
		{
7245
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
7246
			skb->mac.raw = skb->data;
7247
#else
7248
			skb_reset_mac_header(skb);
7249
#endif
7250
			skb->dev = ztchan_to_dev(ms);
7251
#ifdef DAHDI_HDLC_TYPE_TRANS
7252
			skb->protocol = hdlc_type_trans(skb, ztchan_to_dev(ms));
7253
#else
7254
			skb->protocol = htons (ETH_P_HDLC);
7255
#endif
7256
			netif_rx(skb);
7257
		}
7258
#else
7259
			hdlc_netif_rx(&ms->hdlcnetdev->netdev, skb);
7260
#endif
7261
#endif
7262
#ifdef CONFIG_DAHDI_PPP
7263
		if (skb && (ms->flags & DAHDI_FLAG_PPP)) {
7264
			unsigned char *tmp;
7265
			tmp = skb->data;
7266
			skb_pull(skb, 2);
7267
			/* Make sure that it's addressed to ALL STATIONS and UNNUMBERED */
7268
			if (!tmp || (tmp[0] != 0xff) || (tmp[1] != 0x03)) {
7269
				/* Invalid SKB -- drop */
7270
				if (tmp)
7271
					module_printk(KERN_NOTICE, "Received invalid SKB (%02x, %02x)\n", tmp[0], tmp[1]);
7272
				dev_kfree_skb_irq(skb);
7273
			} else {
7274
				skb_queue_tail(&ms->ppp_rq, skb);
7275
				tasklet_schedule(&ms->ppp_calls);
7276
			}
7277
		}
7278
#endif
7279
	}
7280
}
7281
7282
static inline void __dahdi_putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb)
7283
{
7284
	__putbuf_chunk(ss, rxb, DAHDI_CHUNKSIZE);
7285
}
7286
7287
static void __dahdi_hdlc_abort(struct dahdi_chan *ss, int event)
7288
{
7289
	if (ss->inreadbuf >= 0)
7290
		ss->readidx[ss->inreadbuf] = 0;
7291
	if (test_bit(DAHDI_FLAGBIT_OPEN, &ss->flags) && !ss->span->alarms)
7292
		__qevent(ss->master, event);
7293
}
7294
7295
void dahdi_hdlc_abort(struct dahdi_chan *ss, int event)
7296
{
7297
	unsigned long flags;
7298
	spin_lock_irqsave(&ss->lock, flags);
7299
	__dahdi_hdlc_abort(ss, event);
7300
	spin_unlock_irqrestore(&ss->lock, flags);
7301
}
7302
7303
void dahdi_hdlc_putbuf(struct dahdi_chan *ss, unsigned char *rxb, int bytes)
7304
{
7305
	unsigned long flags;
7306
	int res;
7307
	int left;
7308
7309
	spin_lock_irqsave(&ss->lock, flags);
7310
	if (ss->inreadbuf < 0) {
7311
#ifdef CONFIG_DAHDI_DEBUG
7312
		module_printk(KERN_NOTICE, "No place to receive HDLC frame\n");
7313
#endif
7314
		spin_unlock_irqrestore(&ss->lock, flags);
7315
		return;
7316
	}
7317
	/* Read into the current buffer */
7318
	left = ss->blocksize - ss->readidx[ss->inreadbuf];
7319
	if (left > bytes)
7320
		left = bytes;
7321
	if (left > 0) {
7322
		memcpy(ss->readbuf[ss->inreadbuf] + ss->readidx[ss->inreadbuf], rxb, left);
7323
		rxb += left;
7324
		ss->readidx[ss->inreadbuf] += left;
7325
		bytes -= left;
7326
	}
7327
	/* Something isn't fit into buffer */
7328
	if (bytes) {
7329
#ifdef CONFIG_DAHDI_DEBUG
7330
		module_printk(KERN_NOTICE, "HDLC frame isn't fit into buffer space\n");
7331
#endif
7332
		__dahdi_hdlc_abort(ss, DAHDI_EVENT_OVERRUN);
7333
	}
7334
	res = left;
7335
	spin_unlock_irqrestore(&ss->lock, flags);
7336
}
7337
7338
void dahdi_hdlc_finish(struct dahdi_chan *ss)
7339
{
7340
	int oldreadbuf;
7341
	unsigned long flags;
7342
7343
	spin_lock_irqsave(&ss->lock, flags);
7344
7345
	if ((oldreadbuf = ss->inreadbuf) < 0) {
7346
#ifdef CONFIG_DAHDI_DEBUG
7347
		module_printk(KERN_NOTICE, "No buffers to finish\n");
7348
#endif
7349
		spin_unlock_irqrestore(&ss->lock, flags);
7350
		return;
7351
	}
7352
7353
	if (!ss->readidx[ss->inreadbuf]) {
7354
#ifdef CONFIG_DAHDI_DEBUG
7355
		module_printk(KERN_NOTICE, "Empty HDLC frame received\n");
7356
#endif
7357
		spin_unlock_irqrestore(&ss->lock, flags);
7358
		return;
7359
	}
7360
7361
	ss->readn[ss->inreadbuf] = ss->readidx[ss->inreadbuf];
7362
	ss->inreadbuf = (ss->inreadbuf + 1) % ss->numbufs;
7363
	if (ss->inreadbuf == ss->outreadbuf) {
7364
		ss->inreadbuf = -1;
7365
#ifdef CONFIG_DAHDI_DEBUG
7366
		module_printk(KERN_NOTICE, "Notifying reader data in block %d\n", oldreadbuf);
7367
#endif
7368
		ss->rxdisable = 0;
7369
	}
7370
	if (ss->outreadbuf < 0) {
7371
		ss->outreadbuf = oldreadbuf;
7372
	}
7373
7374
	if (!ss->rxdisable) {
7375
		wake_up_interruptible(&ss->readbufq);
7376
		wake_up_interruptible(&ss->sel);
7377
		if (ss->iomask & DAHDI_IOMUX_READ)
7378
			wake_up_interruptible(&ss->eventbufq);
7379
	}
7380
	spin_unlock_irqrestore(&ss->lock, flags);
7381
}
7382
7383
/* Returns 1 if EOF, 0 if data is still in frame, -1 if EOF and no buffers left */
7384
int dahdi_hdlc_getbuf(struct dahdi_chan *ss, unsigned char *bufptr, unsigned int *size)
7385
{
7386
	unsigned char *buf;
7387
	unsigned long flags;
7388
	int left = 0;
7389
	int res;
7390
	int oldbuf;
7391
7392
	spin_lock_irqsave(&ss->lock, flags);
7393
	if (ss->outwritebuf > -1) {
7394
		buf = ss->writebuf[ss->outwritebuf];
7395
		left = ss->writen[ss->outwritebuf] - ss->writeidx[ss->outwritebuf];
7396
		/* Strip off the empty HDLC CRC end */
7397
		left -= 2;
7398
		if (left <= *size) {
7399
			*size = left;
7400
			res = 1;
7401
		} else
7402
			res = 0;
7403
7404
		memcpy(bufptr, &buf[ss->writeidx[ss->outwritebuf]], *size);
7405
		ss->writeidx[ss->outwritebuf] += *size;
7406
7407
		if (res) {
7408
			/* Rotate buffers */
7409
			oldbuf = ss->outwritebuf;
7410
			ss->writeidx[oldbuf] = 0;
7411
			ss->writen[oldbuf] = 0;
7412
			ss->outwritebuf = (ss->outwritebuf + 1) % ss->numbufs;
7413
			if (ss->outwritebuf == ss->inwritebuf) {
7414
				ss->outwritebuf = -1;
7415
				if (ss->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY))
7416
					wake_up_interruptible(&ss->eventbufq);
7417
				/* If we're only supposed to start when full, disable the transmitter */
7418
				if ((ss->txbufpolicy == DAHDI_POLICY_WHEN_FULL) || (ss->txbufpolicy == DAHDI_POLICY_HALF_FULL))
7419
					ss->txdisable = 1;
7420
				res = -1;
7421
			}
7422
7423
			if (ss->inwritebuf < 0)
7424
				ss->inwritebuf = oldbuf;
7425
7426
			if (!(ss->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP))) {
7427
				wake_up_interruptible(&ss->writebufq);
7428
				wake_up_interruptible(&ss->sel);
7429
				if ((ss->iomask & DAHDI_IOMUX_WRITE) && (res >= 0))
7430
					wake_up_interruptible(&ss->eventbufq);
7431
			}
7432
		}
7433
	} else {
7434
		res = -1;
7435
		*size = 0;
7436
	}
7437
	spin_unlock_irqrestore(&ss->lock, flags);
7438
7439
	return res;
7440
}
7441
7442
7443
static void process_timers(void)
7444
{
7445
	unsigned long flags;
7446
	struct dahdi_timer *cur;
7447
7448
	spin_lock_irqsave(&zaptimerlock, flags);
7449
7450
	list_for_each_entry(cur, &zaptimers, list) {
7451
		if (cur->ms) {
7452
			cur->pos -= DAHDI_CHUNKSIZE;
7453
			if (cur->pos <= 0) {
7454
				cur->tripped++;
7455
				cur->pos = cur->ms;
7456
				wake_up_interruptible(&cur->sel);
7457
			}
7458
		}
7459
	}
7460
7461
	spin_unlock_irqrestore(&zaptimerlock, flags);
7462
}
7463
7464
static unsigned int dahdi_timer_poll(struct file *file, struct poll_table_struct *wait_table)
7465
{
7466
	struct dahdi_timer *timer = file->private_data;
7467
	unsigned long flags;
7468
	int ret = 0;
7469
	if (timer) {
7470
		poll_wait(file, &timer->sel, wait_table);
7471
		spin_lock_irqsave(&zaptimerlock, flags);
7472
		if (timer->tripped || timer->ping)
7473
			ret |= POLLPRI;
7474
		spin_unlock_irqrestore(&zaptimerlock, flags);
7475
	} else
7476
		ret = -EINVAL;
7477
	return ret;
7478
}
7479
7480
/* device poll routine */
7481
static unsigned int
7482
dahdi_chan_poll(struct file *file, struct poll_table_struct *wait_table, int unit)
7483
{
7484
7485
	struct dahdi_chan *chan = chans[unit];
7486
	int	ret;
7487
	unsigned long flags;
7488
7489
	  /* do the poll wait */
7490
	if (chan) {
7491
		poll_wait(file, &chan->sel, wait_table);
7492
		ret = 0; /* start with nothing to return */
7493
		spin_lock_irqsave(&chan->lock, flags);
7494
		   /* if at least 1 write buffer avail */
7495
		if (chan->inwritebuf > -1) {
7496
			ret |= POLLOUT | POLLWRNORM;
7497
		}
7498
		if ((chan->outreadbuf > -1) && !chan->rxdisable) {
7499
			ret |= POLLIN | POLLRDNORM;
7500
		}
7501
		if (chan->eventoutidx != chan->eventinidx)
7502
		   {
7503
			/* Indicate an exception */
7504
			ret |= POLLPRI;
7505
		   }
7506
		spin_unlock_irqrestore(&chan->lock, flags);
7507
	} else
7508
		ret = -EINVAL;
7509
	return(ret);  /* return what we found */
7510
}
7511
7512
static int dahdi_mmap(struct file *file, struct vm_area_struct *vm)
7513
{
7514
	int unit = UNIT(file);
7515
	if (unit == 250)
7516
		return dahdi_transcode_fops->mmap(file, vm);
7517
	return -ENOSYS;
7518
}
7519
7520
static unsigned int dahdi_poll(struct file *file, struct poll_table_struct *wait_table)
7521
{
7522
	int unit = UNIT(file);
7523
	struct dahdi_chan *chan;
7524
7525
	if (!unit)
7526
		return -EINVAL;
7527
7528
	if (unit == 250)
7529
		return dahdi_transcode_fops->poll(file, wait_table);
7530
7531
	if (unit == 253)
7532
		return dahdi_timer_poll(file, wait_table);
7533
7534
	if (unit == 254) {
7535
		chan = file->private_data;
7536
		if (!chan)
7537
			return -EINVAL;
7538
		return dahdi_chan_poll(file, wait_table,chan->channo);
7539
	}
7540
	if (unit == 255) {
7541
		chan = file->private_data;
7542
		if (!chan) {
7543
			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
7544
			return -EINVAL;
7545
		}
7546
		return dahdi_chan_poll(file, wait_table, chan->channo);
7547
	}
7548
	return dahdi_chan_poll(file, wait_table, unit);
7549
}
7550
7551
static void __dahdi_transmit_chunk(struct dahdi_chan *chan, unsigned char *buf)
7552
{
7553
	unsigned char silly[DAHDI_CHUNKSIZE];
7554
	/* Called with chan->lock locked */
7555
#ifdef	OPTIMIZE_CHANMUTE
7556
	if(likely(chan->chanmute))
7557
		return;
7558
#endif
7559
	if (!buf)
7560
		buf = silly;
7561
	__dahdi_getbuf_chunk(chan, buf);
7562
7563
	if ((chan->flags & DAHDI_FLAG_AUDIO) || (chan->confmode)) {
7564
#ifdef CONFIG_DAHDI_MMX
7565
		dahdi_kernel_fpu_begin();
7566
#endif
7567
		__dahdi_process_getaudio_chunk(chan, buf);
7568
#ifdef CONFIG_DAHDI_MMX
7569
		kernel_fpu_end();
7570
#endif
7571
	}
7572
}
7573
7574
static inline void __dahdi_real_transmit(struct dahdi_chan *chan)
7575
{
7576
	/* Called with chan->lock held */
7577
#ifdef	OPTIMIZE_CHANMUTE
7578
	if(likely(chan->chanmute))
7579
		return;
7580
#endif
7581
	if (chan->confmode) {
7582
		/* Pull queued data off the conference */
7583
		__buf_pull(&chan->confout, chan->writechunk, chan, "dahdi_real_transmit");
7584
	} else {
7585
		__dahdi_transmit_chunk(chan, chan->writechunk);
7586
	}
7587
}
7588
7589
static void __dahdi_getempty(struct dahdi_chan *ms, unsigned char *buf)
7590
{
7591
	int bytes = DAHDI_CHUNKSIZE;
7592
	int left;
7593
	unsigned char *txb = buf;
7594
	int x;
7595
	short getlin;
7596
	/* Called with ms->lock held */
7597
7598
	while(bytes) {
7599
		/* Receive silence, or tone */
7600
		if (ms->curtone) {
7601
			left = ms->curtone->tonesamples - ms->tonep;
7602
			if (left > bytes)
7603
				left = bytes;
7604
			for (x=0;x<left;x++) {
7605
				/* Pick our default value from the next sample of the current tone */
7606
				getlin = dahdi_tone_nextsample(&ms->ts, ms->curtone);
7607
				*(txb++) = DAHDI_LIN2X(getlin, ms);
7608
			}
7609
			ms->tonep+=left;
7610
			bytes -= left;
7611
			if (ms->tonep >= ms->curtone->tonesamples) {
7612
				struct dahdi_tone *last;
7613
				/* Go to the next sample of the tone */
7614
				ms->tonep = 0;
7615
				last = ms->curtone;
7616
				ms->curtone = ms->curtone->next;
7617
				if (!ms->curtone) {
7618
					/* No more tones...  Is this dtmf or mf?  If so, go to the next digit */
7619
					if (ms->dialing)
7620
						__do_dtmf(ms);
7621
				} else {
7622
					if (last != ms->curtone)
7623
						dahdi_init_tone_state(&ms->ts, ms->curtone);
7624
				}
7625
			}
7626
		} else {
7627
			/* Use silence */
7628
			memset(txb, DAHDI_LIN2X(0, ms), bytes);
7629
			bytes = 0;
7630
		}
7631
	}
7632
7633
}
7634
7635
static void __dahdi_receive_chunk(struct dahdi_chan *chan, unsigned char *buf)
7636
{
7637
	/* Receive chunk of audio -- called with chan->lock held */
7638
	unsigned char waste[DAHDI_CHUNKSIZE];
7639
7640
#ifdef	OPTIMIZE_CHANMUTE
7641
	if(likely(chan->chanmute))
7642
		return;
7643
#endif
7644
	if (!buf) {
7645
		memset(waste, DAHDI_LIN2X(0, chan), sizeof(waste));
7646
		buf = waste;
7647
	}
7648
	if ((chan->flags & DAHDI_FLAG_AUDIO) || (chan->confmode)) {
7649
#ifdef CONFIG_DAHDI_MMX
7650
		dahdi_kernel_fpu_begin();
7651
#endif
7652
		__dahdi_process_putaudio_chunk(chan, buf);
7653
#ifdef CONFIG_DAHDI_MMX
7654
		kernel_fpu_end();
7655
#endif
7656
	}
7657
	__dahdi_putbuf_chunk(chan, buf);
7658
}
7659
7660
static inline void __dahdi_real_receive(struct dahdi_chan *chan)
7661
{
7662
	/* Called with chan->lock held */
7663
#ifdef	OPTIMIZE_CHANMUTE
7664
	if(likely(chan->chanmute))
7665
		return;
7666
#endif
7667
	if (chan->confmode) {
7668
		/* Load into queue if we have space */
7669
		__buf_push(&chan->confin, chan->readchunk, "dahdi_real_receive");
7670
	} else {
7671
		__dahdi_receive_chunk(chan, chan->readchunk);
7672
	}
7673
}
7674
7675
int dahdi_transmit(struct dahdi_span *span)
7676
{
7677
	int x,y,z;
7678
	unsigned long flags;
7679
7680
#if 1
7681
	for (x=0;x<span->channels;x++) {
7682
		spin_lock_irqsave(&span->chans[x]->lock, flags);
7683
		if (span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX) {
7684
			spin_unlock_irqrestore(&span->chans[x]->lock, flags);
7685
			continue;
7686
		}
7687
		if (span->chans[x] == span->chans[x]->master) {
7688
			if (span->chans[x]->otimer) {
7689
				span->chans[x]->otimer -= DAHDI_CHUNKSIZE;
7690
				if (span->chans[x]->otimer <= 0) {
7691
					__rbs_otimer_expire(span->chans[x]);
7692
				}
7693
			}
7694
			if (span->chans[x]->flags & DAHDI_FLAG_AUDIO) {
7695
				__dahdi_real_transmit(span->chans[x]);
7696
			} else {
7697
				if (span->chans[x]->nextslave) {
7698
					u_char data[DAHDI_CHUNKSIZE];
7699
					int pos=DAHDI_CHUNKSIZE;
7700
					/* Process master/slaves one way */
7701
					for (y=0;y<DAHDI_CHUNKSIZE;y++) {
7702
						/* Process slaves for this byte too */
7703
						z = x;
7704
						do {
7705
							if (pos==DAHDI_CHUNKSIZE) {
7706
								/* Get next chunk */
7707
								__dahdi_transmit_chunk(span->chans[x], data);
7708
								pos = 0;
7709
							}
7710
							span->chans[z]->writechunk[y] = data[pos++];
7711
							z = span->chans[z]->nextslave;
7712
						} while(z);
7713
					}
7714
				} else {
7715
					/* Process independents elsewise */
7716
					__dahdi_real_transmit(span->chans[x]);
7717
				}
7718
			}
7719
			if (span->chans[x]->sig == DAHDI_SIG_DACS_RBS) {
7720
				if (chans[span->chans[x]->confna]) {
7721
				    	/* Just set bits for our destination */
7722
					if (span->chans[x]->txsig != chans[span->chans[x]->confna]->rxsig) {
7723
						span->chans[x]->txsig = chans[span->chans[x]->confna]->rxsig;
7724
						span->rbsbits(span->chans[x], chans[span->chans[x]->confna]->rxsig);
7725
					}
7726
				}
7727
			}
7728
7729
		}
7730
		spin_unlock_irqrestore(&span->chans[x]->lock, flags);
7731
	}
7732
	if (span->mainttimer) {
7733
		span->mainttimer -= DAHDI_CHUNKSIZE;
7734
		if (span->mainttimer <= 0) {
7735
			span->mainttimer = 0;
7736
			if (span->maint)
7737
				span->maint(span, DAHDI_MAINT_LOOPSTOP);
7738
			span->maintstat = 0;
7739
			wake_up_interruptible(&span->maintq);
7740
		}
7741
	}
7742
#endif
7743
	return 0;
7744
}
7745
7746
int dahdi_receive(struct dahdi_span *span)
7747
{
7748
	int x,y,z;
7749
	unsigned long flags;
7750
7751
#if 1
7752
#ifdef CONFIG_DAHDI_WATCHDOG
7753
	span->watchcounter--;
7754
#endif
7755
	for (x=0;x<span->channels;x++) {
7756
		if (span->chans[x]->master == span->chans[x]) {
7757
			spin_lock_irqsave(&span->chans[x]->lock, flags);
7758
			if (span->chans[x]->nextslave) {
7759
				/* Must process each slave at the same time */
7760
				u_char data[DAHDI_CHUNKSIZE];
7761
				int pos = 0;
7762
				for (y=0;y<DAHDI_CHUNKSIZE;y++) {
7763
					/* Put all its slaves, too */
7764
					z = x;
7765
					do {
7766
						data[pos++] = span->chans[z]->readchunk[y];
7767
						if (pos == DAHDI_CHUNKSIZE) {
7768
							if(!(span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX))
7769
								__dahdi_receive_chunk(span->chans[x], data);
7770
							pos = 0;
7771
						}
7772
						z=span->chans[z]->nextslave;
7773
					} while(z);
7774
				}
7775
			} else {
7776
				/* Process a normal channel */
7777
				if (!(span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX))
7778
					__dahdi_real_receive(span->chans[x]);
7779
			}
7780
			if (span->chans[x]->itimer) {
7781
				span->chans[x]->itimer -= DAHDI_CHUNKSIZE;
7782
				if (span->chans[x]->itimer <= 0) {
7783
					rbs_itimer_expire(span->chans[x]);
7784
				}
7785
			}
7786
			if (span->chans[x]->ringdebtimer)
7787
				span->chans[x]->ringdebtimer--;
7788
			if (span->chans[x]->sig & __DAHDI_SIG_FXS) {
7789
				if (span->chans[x]->rxhooksig == DAHDI_RXSIG_RING)
7790
					span->chans[x]->ringtrailer = DAHDI_RINGTRAILER;
7791
				else if (span->chans[x]->ringtrailer) {
7792
					span->chans[x]->ringtrailer-= DAHDI_CHUNKSIZE;
7793
					/* See if RING trailer is expired */
7794
					if (!span->chans[x]->ringtrailer && !span->chans[x]->ringdebtimer)
7795
						__qevent(span->chans[x],DAHDI_EVENT_RINGOFFHOOK);
7796
				}
7797
			}
7798
			if (span->chans[x]->pulsetimer)
7799
			{
7800
				span->chans[x]->pulsetimer--;
7801
				if (span->chans[x]->pulsetimer <= 0)
7802
				{
7803
					if (span->chans[x]->pulsecount)
7804
					{
7805
						if (span->chans[x]->pulsecount > 12) {
7806
7807
							module_printk(KERN_NOTICE, "Got pulse digit %d on %s???\n",
7808
						    span->chans[x]->pulsecount,
7809
							span->chans[x]->name);
7810
						} else if (span->chans[x]->pulsecount > 11) {
7811
							__qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '#');
7812
						} else if (span->chans[x]->pulsecount > 10) {
7813
							__qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '*');
7814
						} else if (span->chans[x]->pulsecount > 9) {
7815
							__qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '0');
7816
						} else {
7817
							__qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | ('0' +
7818
								span->chans[x]->pulsecount));
7819
						}
7820
						span->chans[x]->pulsecount = 0;
7821
					}
7822
				}
7823
			}
7824
#ifdef BUFFER_DEBUG
7825
			span->chans[x]->statcount -= DAHDI_CHUNKSIZE;
7826
#endif
7827
			spin_unlock_irqrestore(&span->chans[x]->lock, flags);
7828
		}
7829
	}
7830
7831
	if (span == master) {
7832
		/* Hold the big zap lock for the duration of major
7833
		   activities which touch all sorts of channels */
7834
		spin_lock_irqsave(&bigzaplock, flags);
7835
		read_lock(&chan_lock);
7836
		/* Process any timers */
7837
		process_timers();
7838
		/* If we have dynamic stuff, call the ioctl with 0,0 parameters to
7839
		   make it run */
7840
		if (dahdi_dynamic_ioctl)
7841
			dahdi_dynamic_ioctl(0,0);
7842
		for (x=1;x<maxchans;x++) {
7843
			if (chans[x] && chans[x]->confmode && !(chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
7844
				u_char *data;
7845
				spin_lock(&chans[x]->lock);
7846
				data = __buf_peek(&chans[x]->confin);
7847
				__dahdi_receive_chunk(chans[x], data);
7848
				if (data)
7849
					__buf_pull(&chans[x]->confin, NULL,chans[x], "confreceive");
7850
				spin_unlock(&chans[x]->lock);
7851
			}
7852
		}
7853
		/* This is the master channel, so make things switch over */
7854
		rotate_sums();
7855
		/* do all the pseudo and/or conferenced channel receives (getbuf's) */
7856
		for (x=1;x<maxchans;x++) {
7857
			if (chans[x] && (chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
7858
				spin_lock(&chans[x]->lock);
7859
				__dahdi_transmit_chunk(chans[x], NULL);
7860
				spin_unlock(&chans[x]->lock);
7861
			}
7862
		}
7863
		if (maxlinks) {
7864
#ifdef CONFIG_DAHDI_MMX
7865
			dahdi_kernel_fpu_begin();
7866
#endif
7867
			  /* process all the conf links */
7868
			for(x = 1; x <= maxlinks; x++) {
7869
				  /* if we have a destination conf */
7870
				if (((z = confalias[conf_links[x].dst]) > 0) &&
7871
				    ((y = confalias[conf_links[x].src]) > 0)) {
7872
					ACSS(conf_sums[z], conf_sums[y]);
7873
				}
7874
			}
7875
#ifdef CONFIG_DAHDI_MMX
7876
			kernel_fpu_end();
7877
#endif
7878
		}
7879
		/* do all the pseudo/conferenced channel transmits (putbuf's) */
7880
		for (x=1;x<maxchans;x++) {
7881
			if (chans[x] && (chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
7882
				unsigned char tmp[DAHDI_CHUNKSIZE];
7883
				spin_lock(&chans[x]->lock);
7884
				__dahdi_getempty(chans[x], tmp);
7885
				__dahdi_receive_chunk(chans[x], tmp);
7886
				spin_unlock(&chans[x]->lock);
7887
			}
7888
		}
7889
		for (x=1;x<maxchans;x++) {
7890
			if (chans[x] && chans[x]->confmode && !(chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
7891
				u_char *data;
7892
				spin_lock(&chans[x]->lock);
7893
				data = __buf_pushpeek(&chans[x]->confout);
7894
				__dahdi_transmit_chunk(chans[x], data);
7895
				if (data)
7896
					__buf_push(&chans[x]->confout, NULL, "conftransmit");
7897
				spin_unlock(&chans[x]->lock);
7898
			}
7899
		}
7900
#ifdef	DAHDI_SYNC_TICK
7901
		for (x=0;x<maxspans;x++) {
7902
			struct dahdi_span	*s = spans[x];
7903
7904
			if (s && s->sync_tick)
7905
				s->sync_tick(s, s == master);
7906
		}
7907
#endif
7908
		read_unlock(&chan_lock);
7909
		spin_unlock_irqrestore(&bigzaplock, flags);
7910
	}
7911
#endif
7912
	return 0;
7913
}
7914
7915
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
7916
MODULE_DESCRIPTION("DAHDI Telephony Interface");
7917
MODULE_LICENSE("GPL v2");
7918
MODULE_VERSION(DAHDI_VERSION);
7919
7920
module_param(debug, int, 0644);
7921
module_param(deftaps, int, 0644);
7922
7923
static struct file_operations dahdi_fops = {
7924
	.owner   = THIS_MODULE,
7925
	.llseek  = NULL,
7926
	.open    = dahdi_open,
7927
	.release = dahdi_release,
7928
	.ioctl   = dahdi_ioctl,
7929
	.read    = dahdi_read,
7930
	.write   = dahdi_write,
7931
	.poll    = dahdi_poll,
7932
	.mmap    = dahdi_mmap,
7933
	.flush   = NULL,
7934
	.fsync   = NULL,
7935
	.fasync  = NULL,
7936
};
7937
7938
#ifdef CONFIG_DAHDI_WATCHDOG
7939
static struct timer_list watchdogtimer;
7940
7941
static void watchdog_check(unsigned long ignored)
7942
{
7943
	int x;
7944
	unsigned long flags;
7945
	static int wdcheck=0;
7946
7947
	local_irq_save(flags);
7948
	for (x=0;x<maxspans;x++) {
7949
		if (spans[x] && (spans[x]->flags & DAHDI_FLAG_RUNNING)) {
7950
			if (spans[x]->watchcounter == DAHDI_WATCHDOG_INIT) {
7951
				/* Whoops, dead card */
7952
				if ((spans[x]->watchstate == DAHDI_WATCHSTATE_OK) ||
7953
					(spans[x]->watchstate == DAHDI_WATCHSTATE_UNKNOWN)) {
7954
					spans[x]->watchstate = DAHDI_WATCHSTATE_RECOVERING;
7955
					if (spans[x]->watchdog) {
7956
						module_printk(KERN_NOTICE, "Kicking span %s\n", spans[x]->name);
7957
						spans[x]->watchdog(spans[x], DAHDI_WATCHDOG_NOINTS);
7958
					} else {
7959
						module_printk(KERN_NOTICE, "Span %s is dead with no revival\n", spans[x]->name);
7960
						spans[x]->watchstate = DAHDI_WATCHSTATE_FAILED;
7961
					}
7962
				}
7963
			} else {
7964
				if ((spans[x]->watchstate != DAHDI_WATCHSTATE_OK) &&
7965
					(spans[x]->watchstate != DAHDI_WATCHSTATE_UNKNOWN))
7966
						module_printk(KERN_NOTICE, "Span %s is alive!\n", spans[x]->name);
7967
				spans[x]->watchstate = DAHDI_WATCHSTATE_OK;
7968
			}
7969
			spans[x]->watchcounter = DAHDI_WATCHDOG_INIT;
7970
		}
7971
	}
7972
	local_irq_restore(flags);
7973
	if (!wdcheck) {
7974
		module_printk(KERN_NOTICE, "watchdog on duty!\n");
7975
		wdcheck=1;
7976
	}
7977
	mod_timer(&watchdogtimer, jiffies + 2);
7978
}
7979
7980
static int __init watchdog_init(void)
7981
{
7982
	init_timer(&watchdogtimer);
7983
	watchdogtimer.expires = 0;
7984
	watchdogtimer.data =0;
7985
	watchdogtimer.function = watchdog_check;
7986
	/* Run every couple of jiffy or so */
7987
	mod_timer(&watchdogtimer, jiffies + 2);
7988
	return 0;
7989
}
7990
7991
static void __exit watchdog_cleanup(void)
7992
{
7993
	del_timer(&watchdogtimer);
7994
}
7995
7996
#endif
7997
7998
int dahdi_register_chardev(struct dahdi_chardev *dev)
7999
{
8000
	char udevname[strlen(dev->name) + sizeof("dahdi!")];
8001
8002
	strcpy(udevname, "dahdi!");
8003
	strcat(udevname, dev->name);
8004
	CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname);
8005
8006
	return 0;
8007
}
8008
8009
int dahdi_unregister_chardev(struct dahdi_chardev *dev)
8010
{
8011
	CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor));
8012
8013
	return 0;
8014
}
8015
8016
static int __init dahdi_init(void)
8017
{
8018
	int res = 0;
8019
8020
#ifdef CONFIG_PROC_FS
8021
	proc_entries[0] = proc_mkdir("dahdi", NULL);
8022
#endif
8023
8024
	if ((res = register_chrdev(DAHDI_MAJOR, "dahdi", &dahdi_fops))) {
8025
		module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR);
8026
		return res;
8027
	}
8028
8029
	dahdi_class = class_create(THIS_MODULE, "dahdi");
8030
	CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 253), NULL, "dahdi!timer");
8031
	CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 254), NULL, "dahdi!channel");
8032
	CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 255), NULL, "dahdi!pseudo");
8033
	CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 0), NULL, "dahdi!ctl");
8034
8035
	module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n", DAHDI_MAJOR);
8036
	module_printk(KERN_INFO, "Version: %s\n", DAHDI_VERSION);
8037
	dahdi_conv_init();
8038
	fasthdlc_precalc();
8039
	rotate_sums();
8040
#ifdef CONFIG_DAHDI_WATCHDOG
8041
	watchdog_init();
8042
#endif
8043
	return res;
8044
}
8045
8046
static void __exit dahdi_cleanup(void)
8047
{
8048
	int x;
8049
8050
	CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 253)); /* timer */
8051
	CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 254)); /* channel */
8052
	CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 255)); /* pseudo */
8053
	CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 0)); /* ctl */
8054
	class_destroy(dahdi_class);
8055
8056
	unregister_chrdev(DAHDI_MAJOR, "dahdi");
8057
8058
#ifdef CONFIG_PROC_FS
8059
	remove_proc_entry("dahdi", NULL);
8060
#endif
8061
8062
	module_printk(KERN_INFO, "Telephony Interface Unloaded\n");
8063
	for (x = 0; x < DAHDI_TONE_ZONE_MAX; x++) {
8064
		if (tone_zones[x])
8065
			kfree(tone_zones[x]);
8066
	}
8067
8068
#ifdef CONFIG_DAHDI_WATCHDOG
8069
	watchdog_cleanup();
8070
#endif
8071
}
8072
8073
module_init(dahdi_init);
8074
module_exit(dahdi_cleanup);
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/Makefile (+128 lines)
Line 0 Link Here
1
ifeq ($(MAKELEVEL),0)
2
PWD:=$(shell pwd)
3
endif
4
5
ifndef MACHINE
6
  MACHINE	:=$(shell uname -m)
7
endif
8
# FIXME: this variable sets ARCH in the kernel Makefile.
9
ARCH		:=$(shell echo $(MACHINE) | sed -e s/i.86/i386/)
10
BRISTUFFBASE = $(shell dirname `pwd`)
11
ZAP = $(shell [ -f $(BRISTUFFBASE)/dahdi/kernel.h ] && echo "-I$(BRISTUFFBASE)/dahdi")
12
EXTRA_CFLAGS+=$(ZAP)
13
14
# If you want to build for a kernel other than the current kernel, set KVERS
15
ifndef KVERS
16
KVERS:=$(shell uname -r)
17
endif
18
ifndef KSRC
19
  ifneq (,$(wildcard /lib/modules/$(KVERS)/build))
20
    KSRC:=/lib/modules/$(KVERS)/build
21
  else
22
    KSRC_SEARCH_PATH:=/usr/src/linux-2.4 /usr/src/linux
23
    KSRC:=$(shell for dir in $(KSRC_SEARCH_PATH); do if [ -d $$dir ]; then echo $$dir; break; fi; done)
24
  endif
25
endif
26
KINCLUDES:=$(KSRC)/include
27
28
ifeq (2.6,$(shell echo $(KVERS) | cut -d. -f1-2))
29
  BUILDVER:=linux26
30
else
31
  BUILDVER:=linux24
32
endif
33
34
MODULES:=zaphfc
35
36
MODULESO:=$(MODULES:%=%.o)
37
MODULESKO:=$(MODULES:%=%.ko)
38
39
ifeq ($(BUILDVER),linux26)
40
MODULESO+=$(SUBDIRS_EXTRA:%=%/)
41
endif
42
43
#NOTE NOTE NOTE
44
#
45
# all variables set before the include of Makefile.kernel26 are needed by the 2.6 kernel module build process
46
47
ifneq ($(KBUILD_EXTMOD),)
48
49
include $(src)/Makefile.kernel26
50
51
else
52
53
HOSTCC=gcc
54
55
INSTALL_PREFIX	:= /usr
56
57
CFLAGS+=-I. -O4 -g -fPIC -Wall
58
ifneq (,$(findstring ppc,$(MACHINE)))
59
  CFLAGS	+= -fsigned-char
60
  KFLAGS	+= -msoft-float -fsigned-char
61
endif
62
ifneq (,$(findstring x86_64,$(MACHINE)))
63
  CFLAGS	+= -m64
64
  KFLAGS	+= -mcmodel=kernel
65
endif
66
KFLAGS:=-I$(KINCLUDES) -O6 
67
KFLAGS+=-DMODULE -D__KERNEL__ -DEXPORT_SYMTAB\
68
	-Wall -I. -Wstrict-prototypes -fomit-frame-pointer 
69
ifneq (,$(wildcard $(KINCLUDES)/linux/modversions.h))
70
  KFLAGS+=-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h
71
endif
72
73
#
74
# Features are now configured in zconfig.h
75
#
76
77
KMAKE:= $(MAKE) -C $(KSRC) SUBDIRS=$(PWD)
78
KMAKE_INST:= $(KMAKE) INSTALL_MOD_PATH=$(DESTDIR) INSTALL_MOD_DIR=misc modules_install
79
80
# sample makefile "trace print"
81
#tracedummy=$(shell echo ====== GOT HERE ===== >&2; echo >&2)
82
83
SELINUX_ENABLED	:= $(shell  [ -x /usr/sbin/sestatus ] && (/usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"))
84
85
all: modules
86
87
88
ifeq ($(BUILDVER),linux24)
89
modules: $(MODULESO)
90
else
91
modules: 
92
ifeq (,$(wildcard $(KSRC)/.config))
93
	@echo "You do not appear to have the sources for the $(KVERS) kernel installed (under $(KSRC))."; exit 1
94
endif
95
	$(MAKE) -C $(KSRC) SUBDIRS=$(PWD) HOTPLUG_FIRMWARE=$(HOTPLUG_FIRMWARE) EXTRA_CFLAGS=$(EXTRA_CFLAGS) modules
96
endif
97
98
99
install: all install-modules
100
	@echo "###################################################"
101
	@echo "###"
102
	@echo "### zaphfc installed successfully."
103
	@echo "###"
104
	@echo "###################################################"
105
106
107
# Specific to a kernel version:
108
install-modules: modules
109
ifeq ($(BUILDVER),linux26)
110
	for x in $(MODULESKO); do \
111
		rm -f $(DESTDIR)/lib/modules/$(KVERS)/extra/$$x ; \
112
	done
113
	$(KMAKE_INST)
114
else
115
	install -d $(DESTDIR)$(MODS_DIR)
116
endif
117
	[ `id -u` = 0 ] && /sbin/depmod -a $(KVERS) || :
118
119
clean:
120
	$(MAKE) -C $(KSRC) SUBDIRS=$(PWD) clean
121
	rm -f Module.symvers
122
123
.EXPORT_ALL_VARIABLES:
124
125
FORCE:
126
127
endif
128
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/Makefile.kernel26 (+8 lines)
Line 0 Link Here
1
obj-m := $(MODULESO)
2
3
# fix typo present in CentOS and RHEL 2.6.9 kernels
4
BAD_KERNELS_VERS := 22 34 34.0.1 34.0.2
5
BAD_KERNELS := $(foreach ver,$(BAD_KERNELS_VERS),2.6.9-$(ver).EL 2.6.9-$(ver).ELsmp)
6
ifneq (,$(filter $(KVERS),$(BAD_KERNELS)))
7
EXTRA_CFLAGS+=-Drw_lock_t=rwlock_t
8
endif
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/Makefile.new (+118 lines)
Line 0 Link Here
1
KINCLUDES = /usr/src/linux/include
2
BRISTUFFBASE = $(shell dirname `pwd`)
3
4
ZAP = $(shell [ -f $(BRISTUFFBASE)/dahdi/kernel.h ] && echo "-I$(BRISTUFFBASE)/dahdi")
5
RTAI = $(shell [ -f /usr/realtime/include/rtai.h ] && echo "-DRTAITIMING -I/usr/realtime/include")
6
7
EXTRA_CFLAGS+=$(ZAP)
8
9
CFLAGS+=-I. $(ZAP) $(RTAI) -O2 -g -Wall -DBUILDING_TONEZONE 
10
CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
11
12
KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) $(RTAI) -Wall
13
KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h")
14
KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi)
15
16
17
BUILDVER=$(shell if uname -r | grep -q ^2.6; then echo "linux26"; else echo "linux24"; fi)
18
19
MODCONF=$(shell if [ -d $(INSTALL_PREFIX)/etc/modprobe.d ]; then echo "$(INSTALL_PREFIX)/etc/modprobe.d/dahdi"; elif [ -d $(INSTALL_PREFIX)/etc/modutils ]; then echo "$(INSTALL_PREFIX)/etc/modutils/dahdi"; elif [ -f $(INSTALL_PREFIX)/etc/modprobe.conf ]; then echo "$(INSTALL_PREFIX)/modprobe.conf"; elif [ -f $(INSTALL_PREFIX)/etc/modules.conf ]; then echo "$(INSTALL_PREFIX)/etc/modules.conf"; else echo $(INSTALL_PREFIX)/etc/conf.modules ; fi)
20
21
OBJS=zaphfc.o
22
23
MODULES=zaphfc
24
25
MODULESO=$(shell for x in $(MODULES); do echo "$$x.o "; done )
26
MODULESKO=$(shell for x in $(MODULES); do echo "$$x.ko "; done )
27
28
PWD=$(shell pwd)
29
30
obj-m := $(MODULESO)
31
32
all: $(BUILDVER)
33
34
linux24: $(OBJS)
35
	sync
36
37
38
zaphfc.o: zaphfc.c zaphfc.h
39
	$(CC) -c zaphfc.c $(KFLAGS)
40
41
clean:	
42
	rm -f $(OBJS) *.ko *.mod.c *.mod.o .*o.cmd *~
43
	rm -rf .tmp_versions
44
45
test: all
46
	modprobe zaptel
47
	insmod ./zaphfc.o
48
	cat /proc/interrupts
49
	sleep 1
50
	cat /proc/interrupts
51
	rmmod zaphfc
52
	rmmod zaptel
53
54
load:	load$(BUILDVER)
55
56
loadNT:	load$(BUILDVER)NT
57
58
load-debug:	load$(BUILDVER)-debug
59
60
loadNT-debug:	load$(BUILDVER)NT-debug
61
62
loadlinux24: all
63
	modprobe zaptel
64
	insmod ./zaphfc.o
65
	ztcfg -v
66
67
loadlinux24-debug: all
68
	modprobe zaptel
69
	insmod ./zaphfc.o debug=1
70
	ztcfg -v
71
72
loadlinux26: linux26
73
	modprobe zaptel
74
	insmod ./zaphfc.ko
75
	ztcfg -v
76
77
loadlinux26-debug: linux26
78
	modprobe zaptel
79
	insmod ./zaphfc.ko debug=1
80
	ztcfg -v
81
82
loadlinux24NT: all
83
	modprobe zaptel
84
	insmod ./zaphfc.o modes=1
85
	ztcfg -v
86
87
loadlinux24NT-debug: all
88
	modprobe zaptel
89
	insmod ./zaphfc.o modes=1 debug=1
90
	ztcfg -v
91
92
loadlinux26NT: linux26
93
	modprobe zaptel
94
	insmod ./zaphfc.ko modes=1
95
	ztcfg -v
96
97
loadlinux26NT-debug: linux26
98
	modprobe zaptel
99
	insmod ./zaphfc.ko modes=1 debug=1
100
	ztcfg -v
101
102
unload: 
103
	-rmmod zaphfc zaptel
104
105
zaphfc.ko: zaphfc.c zaphfc.h
106
107
linux26: 
108
	@if ! [ -d /usr/src/linux-2.6 ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi
109
	make -C /usr/src/linux-2.6 SUBDIRS=$(PWD) ZAP=$(ZAP) modules
110
111
install:	install$(BUILDVER)
112
113
installlinux26:
114
	install -D -m 644 zaphfc.ko $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/zaphfc.ko
115
116
installlinux24:
117
	install -D -m 644 zaphfc.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/zaphfc.o
118
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/Module.markers (+7 lines)
Line 0 Link Here
1
core_marker_format	vmlinux	name %s format %s
2
ext4_discard_blocks	vmlinux	dev %s blk %llu count %u
3
ext4_sync_file	vmlinux	dev %s datasync %d ino %ld parent %ld
4
ext4_sync_fs	vmlinux	dev %s wait %d
5
jbd2_checkpoint	vmlinux	dev %s need_checkpoint %d
6
jbd2_end_commit	vmlinux	dev %s transaction %d head %d
7
jbd2_start_commit	vmlinux	dev %s transaction %d
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/dahdi_config.h (+176 lines)
Line 0 Link Here
1
/*
2
 * DAHDI configuration options 
3
 *
4
 */
5
6
/*
7
 * See http://www.asterisk.org for more information about
8
 * the Asterisk project. Please do not directly contact
9
 * any of the maintainers of this project for assistance;
10
 * the project provides a web site, mailing lists and IRC
11
 * channels for your use.
12
 *
13
 * This program is free software, distributed under the terms of
14
 * the GNU General Public License Version 2 as published by the
15
 * Free Software Foundation. See the LICENSE file included with
16
 * this program for more details.
17
 */
18
19
#ifndef _DAHDI_CONFIG_H
20
#define _DAHDI_CONFIG_H
21
22
#ifdef __KERNEL__
23
#include <linux/version.h>
24
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
25
#include <linux/config.h>
26
#else
27
#include <linux/autoconf.h>
28
#endif
29
#endif
30
31
/* DAHDI compile time options */
32
33
/*
34
 * Uncomment if you have a European phone, or any other phone with a 
35
 *  short flash time.
36
 * This will stop the flash being mis-detected as a pulse dial "1" on
37
 *  phones with short flashes
38
 */
39
/* #define SHORT_FLASH_TIME */
40
41
/*
42
 * Uncomment to disable calibration and/or DC/DC converter tests
43
 * (not generally recommended)
44
 */
45
/* #define NO_CALIBRATION */
46
/* #define NO_DCDC */
47
48
/*
49
 * Boost ring voltage (Higher ring voltage, takes more power)
50
 * Note: this only affects the wcfxsusb and wcusb drivers; all other
51
 *       drivers have a 'boostringer' module parameter.
52
 */
53
/* #define BOOST_RINGER */
54
55
/*
56
 * Define CONFIG_CALC_XLAW if you have a small number of channels and/or
57
 * a small level 2 cache, to optimize for few channels
58
 *
59
 */
60
/* #define CONFIG_CALC_XLAW */
61
62
/*
63
 * Define if you want MMX optimizations in DAHDI
64
 *
65
 * Note: CONFIG_DAHDI_MMX is generally incompatible with AMD 
66
 * processors and can cause system instability!
67
 * 
68
 */
69
/* #define CONFIG_DAHDI_MMX */
70
71
/* We now use the linux kernel config to detect which options to use */
72
/* You can still override them below */
73
#if defined(CONFIG_HDLC) || defined(CONFIG_HDLC_MODULE)
74
#define DAHDI_HDLC_TYPE_TRANS
75
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3)
76
#define HDLC_MAINTAINERS_ARE_MORE_STUPID_THAN_I_THOUGHT
77
#endif
78
#endif
79
80
#ifdef CONFIG_PPP
81
#define CONFIG_DAHDI_PPP
82
#endif
83
84
/*
85
 * Uncomment CONFIG_DAHDI_NET to enable SyncPPP, CiscoHDLC, and Frame Relay
86
 * support.
87
 */
88
/* #define CONFIG_DAHDI_NET */
89
90
/*
91
 * Uncomment CONFIG_OLD_HDLC_API if your are compiling with CONFIG_DAHDI_NET
92
 * defined and you are using the old kernel HDLC interface (or if you get
93
 * an error about ETH_P_HDLC while compiling).
94
 */
95
/* #define CONFIG_OLD_HDLC_API */
96
97
/*
98
 * Uncomment for Generic PPP support (i.e. ZapRAS)
99
 */
100
/* #define CONFIG_DAHDI_PPP */
101
/*
102
 * Uncomment to enable "watchdog" to monitor if interfaces
103
 * stop taking interrupts or otherwise misbehave
104
 */
105
/* #define CONFIG_DAHDI_WATCHDOG */
106
107
/*
108
 * Uncomment the following to include extra debugging output.
109
 */
110
/* #define CONFIG_DAHDI_DEBUG */
111
112
/*
113
 * Uncomment for Non-standard FXS groundstart start state (A=Low, B=Low)
114
 * particularly for CAC channel bank groundstart FXO ports.
115
 */
116
/* #define CONFIG_CAC_GROUNDSTART */
117
118
/* 
119
 * Uncomment if you happen have an early TDM400P Rev H which 
120
 * sometimes forgets its PCI ID to have wcfxs match essentially all
121
 * subvendor ID's
122
 */
123
/* #define TDM_REVH_MATCHALL */
124
125
/* 
126
 * Uncomment the following if you want to support E&M trunks being
127
 * able to "flash" after going off-hook (dont ask why, just nod :-) ).
128
 *
129
 * NOTE: *DO NOT* Enable "EMFLASH" and "EMPULSE" at the same time!!
130
 *
131
 */
132
/* #define EMFLASH */
133
134
/* 
135
 * Uncomment the following if you want to support E&M trunks being
136
 * able to recognize Dial Pulse digits. This can validly be enabled
137
 * so that either Dial Pulse or DTMF/MF tones will be recognized, but
138
 * the drawback is that the ONHOOK will take an extra {rxwinktime}
139
 * to be recognized.
140
 *
141
 * NOTE: *DO NOT* Enable "EMFLASH" and "EMPULSE" at the same time!!
142
 *
143
 */
144
/* #define EMPULSE */
145
146
/* 
147
 * Comment out the following if you dont want events to indicate the
148
 * beginning of an incoming ring. Most non-Asterisk applications will
149
 * want this commented out.
150
 */
151
#define RINGBEGIN
152
153
/* 
154
 * Uncomment the following if you need to support FXS Flash events.
155
 * Most applications will want this commented out.
156
 */
157
/* #define FXSFLASH */
158
159
/*
160
 * Enable sync_tick() calls. Allows low-level drivers to synchronize
161
 * their internal clocks to the DAHDI master clock.
162
 */
163
#define DAHDI_SYNC_TICK
164
165
/*
166
 * Skip processing PCM if low-level driver won't use it anyway
167
 */
168
/* #define	OPTIMIZE_CHANMUTE */
169
170
/*
171
 * Uncomment the following for BRI D channels
172
 *
173
 */
174
#define CONFIG_DAHDI_BRI_DCHANS
175
176
#endif
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/fasthdlc.h (+507 lines)
Line 0 Link Here
1
/*
2
 * Mark's Mythical Table-based raw HDLC implementation
3
 *
4
 * This is designed to be a very fast, but memory efficient
5
 * implementation of standard HDLC protocol.
6
 *
7
 * This table based HDLC technology is PATENT PENDING, but will always be
8
 * remain freely distributable under the terms of the GPL version 2. 
9
 *
10
 * For non-GPL licensing, please contact Mark Spencer at 
11
 * the below e-mail address.
12
 *
13
 * Copyright (C) 2001-2008, Digium, Inc.
14
 *
15
 * Written by Mark Spencer <markster@digium.com>
16
 * 
17
 */
18
19
/*
20
 * See http://www.asterisk.org for more information about
21
 * the Asterisk project. Please do not directly contact
22
 * any of the maintainers of this project for assistance;
23
 * the project provides a web site, mailing lists and IRC
24
 * channels for your use.
25
 *
26
 * This program is free software, distributed under the terms of
27
 * the GNU General Public License Version 2 as published by the
28
 * Free Software Foundation. See the LICENSE file included with
29
 * this program for more details.
30
 */
31
32
#ifndef _FASTHDLC_H
33
#define _FASTHDLC_H
34
35
enum fasthdlc_mode {
36
	FASTHDLC_MODE_64 = 0,
37
	FASTHDLC_MODE_56,
38
};
39
40
struct fasthdlc_state {
41
	int state;		/* What state we are in */
42
	unsigned int data;	/* Our current data queue */
43
	int bits;		/* Number of bits in our data queue */
44
	int ones;		/* Number of ones */
45
	enum fasthdlc_mode mode;
46
};
47
48
#ifdef FAST_HDLC_NEED_TABLES
49
#define RETURN_COMPLETE_FLAG	(0x1000)
50
#define RETURN_DISCARD_FLAG	(0x2000)
51
#define RETURN_EMPTY_FLAG	(0x4000)
52
53
/* Unlike most HDLC implementations, we define only two states,
54
   when we are in a valid frame, and when we are searching for
55
   a frame header */
56
57
#define FRAME_SEARCH	0
58
#define PROCESS_FRAME	1
59
60
/* 
61
62
   HDLC Search State table -- Look for a frame header.  The return value
63
   of this table is as follows:
64
65
  |---8---|---7---|---6---|---5---|---4---|---3---|---2---|---1---| 
66
  |      Z E R O E S      |  Next |         Bits Consumed         |
67
  |-------|-------|-------|-------|-------|-------|-------|-------|
68
69
   The indexes for this table are the state (0 or 1) and the next 8
70
   bits of the stream.
71
72
   Note that this table is only used for state 0 and 1.
73
74
   The user should discard the top "bits consumed" bits of data before
75
   the next call.  "Next state" represents the actual next state for
76
   decoding.
77
78
*/
79
static unsigned char hdlc_search[256];
80
81
/*
82
  HDLC Data Table
83
84
  The indexes to this table are the number of one's we've seen so far (0-5) and
85
  the next 10 bits of input (which is enough to guarantee us that we
86
  will retrieve at least one byte of data (or frame or whatever).
87
88
  The format for the return value is:
89
90
  Bits 15: Status (1=Valid Data, 0=Control Frame (see bits 7-0 for type))
91
  Bits 14-12: Number of ones in a row, so far
92
  Bits 11-8:  The number of bits consumed (0-10)
93
  Bits 7-0:   The return data (if appropriate)
94
  
95
  The next state is simply bit #15
96
97
*/
98
99
#define CONTROL_COMPLETE	1
100
#define CONTROL_ABORT		2
101
102
#define STATUS_MASK	(1 << 15)
103
#define STATUS_VALID	(1 << 15)
104
#define STATUS_CONTROL	(0 << 15)
105
#define STATE_MASK	(1 << 15)
106
#define ONES_MASK	(7 << 12)
107
#define	DATA_MASK	(0xff)
108
109
static unsigned short hdlc_frame[6][1024];
110
111
static unsigned int minbits[2] = { 8, 10 };
112
113
/*
114
   Last, but not least, we have the encoder table.  It takes
115
   as its indices the number of ones so far and a byte of data
116
   and returns an int composed of the following fields:
117
118
   Bots 31-22: Actual Data
119
   Bits 21-16: Unused
120
   Bits 15-8:  Number of ones
121
   Bits 3-0:   Number of bits of output (13-4) to use
122
123
   Of course we could optimize by reducing to two tables, but I don't
124
   really think it's worth the trouble at this point.
125
  */
126
127
static unsigned int hdlc_encode[6][256];
128
129
static inline char hdlc_search_precalc(unsigned char c)
130
{
131
	int x, p=0;
132
	/* Look for a flag.  If this isn't a flag,
133
	   line us up for the next possible shot at
134
	   a flag */
135
136
	/* If it's a flag, we go to state 1, and have
137
	   consumed 8 bits */
138
	if (c == 0x7e) 
139
		return 0x10 | 8;
140
141
	/* If it's an abort, we stay in the same state
142
	   and have consumed 8 bits */
143
	if (c == 0x7f)
144
		return 0x00 | 8;
145
146
	/* If it's all 1's, we state in the same state and
147
	   have consumed 8 bits */
148
	if (c == 0xff)
149
		return 0x00 | 8;
150
151
	/* If we get here, we must have at least one zero in us
152
	   but we're not the flag.  So, start at the end (LSB) and
153
	   work our way to the top (MSB) looking for a zero.  The 
154
	   position of that 0 is most optimistic start of a real
155
	   frame header */
156
	x=1;
157
	p=7;
158
	while(p && (c & x)) {
159
		x <<= 1;
160
		p--;
161
	}
162
	return p;
163
}
164
165
#ifdef DEBUG_PRECALC
166
static inline void hdlc_search_print(char c, char r)
167
{
168
	int x=0x80;
169
	while(x) {
170
		printf("%s", c & x ? "1" : "0");
171
		x >>= 1;
172
	}
173
	printf(" => State %d, Consume %d\n", (r & 0x10) >> 4, r & 0xf);
174
}
175
#endif
176
177
#define HFP(status, ones, bits, data) \
178
	((status) | ((ones) << 12) | ((bits) << 8) | (data))
179
180
static inline unsigned int hdlc_frame_precalc(unsigned char x, unsigned short c)
181
{
182
	/* Assume we have seen 'x' one's so far, and have read the
183
	   bottom 10 bytes of c (MSB first).  Now, we HAVE to have
184
	   a byte of data or a frame or something.  We are assumed
185
	   to be at the beginning of a byte of data or something */
186
	unsigned char ones = x;
187
	unsigned char data=0;
188
	int bits=0;
189
	int consumed=0;
190
	while(bits < 8) {
191
		data >>=1;
192
		consumed++;
193
		if (ones == 5) {
194
			/* We've seen five ones */
195
			if (c & 0x0200) {
196
				/* Another one -- Some sort of signal frame */
197
				if ((!(c & 0x0100)) && (bits == 6)) {
198
					/* This is a frame terminator (10) */
199
					return HFP(0, 
200
						   0, 8, CONTROL_COMPLETE);
201
				} else {
202
					/* Yuck!  It's something else...
203
					   Abort this entire frame, and
204
					   start looking for a good frame */
205
					return HFP(0, 
206
						   0, consumed+1, CONTROL_ABORT);
207
				}
208
			} else {
209
				/* It's an inserted zero, just skip it */
210
				ones = 0;
211
				data <<= 1;
212
			}
213
		} else {
214
			/* Add it to our bit list, LSB to
215
			   MSB */
216
			if (c & 0x0200) {
217
				data |= 0x80;
218
				ones++;
219
			} else 
220
				ones=0;
221
			bits++;	
222
		}
223
		c <<= 1;
224
	}
225
	/* Consume the extra 0 now rather than later. */
226
	if (ones == 5) {
227
		ones = 0;
228
		consumed++;
229
	}
230
	return HFP(STATUS_VALID, ones, consumed, data);
231
}
232
233
#ifdef DEBUG_PRECALC
234
235
static inline void hdlc_frame_print(unsigned char x, unsigned short c, unsigned int res)
236
{
237
	int z=0x0200;
238
	char *status[] = {
239
		"Control",
240
		"Valid",
241
	};
242
	printf("%d one's then ", x);
243
	while(z) {
244
		printf("%s", c & z ? "1" : "0");
245
		z >>= 1;
246
	}
247
	printf(" => Status %s, ", res & STATUS_MASK ? "1" : "0");
248
	printf("Consumed: %d, ", (res & 0x0f00) >> 8);
249
	printf("Status: %s, ", status[(res & STATUS_MASK) >> 15]);
250
	printf("Ones: %d, ", (res & ONES_MASK) >> 12);
251
	printf("Data: %02x\n", res & 0xff);
252
	
253
}
254
255
#endif
256
257
static inline unsigned int hdlc_encode_precalc(int x, unsigned char y)
258
{
259
	int bits=0;
260
	int ones=x;
261
	unsigned short data=0;
262
	int z;
263
	for (z=0;z<8;z++) {
264
		/* Zero-stuff if needed */
265
		if (ones == 5) {
266
			/* Stuff a zero */
267
			data <<= 1;
268
			ones=0;
269
			bits++;
270
		}
271
		if (y & 0x01) {
272
			/* There's a one */
273
			data <<= 1;
274
			data |= 0x1;
275
			ones++;
276
			bits++;
277
		} else {
278
			data <<= 1;
279
			ones = 0;
280
			bits++;
281
		}
282
		y >>= 1;
283
	}
284
	/* Special case -- Stuff the zero at the end if appropriate */
285
	if (ones == 5) {
286
		/* Stuff a zero */
287
		data <<= 1;
288
		ones=0;
289
		bits++;
290
	}
291
	data <<= (10-bits);
292
	return (data << 22) | (ones << 8) | (bits);
293
}
294
295
#ifdef DEBUG_PRECALC
296
static inline void hdlc_encode_print(int x, unsigned char y, unsigned int val)
297
{
298
	unsigned int z;
299
	unsigned short c;
300
	printf("%d ones, %02x (", x, y);
301
	z = 0x80;
302
	while(z) {
303
		printf("%s", y & z ? "1" : "0");
304
		z >>= 1;
305
	}
306
	printf(") encoded as ");
307
	z = 1 << 31;
308
	for (x=0;x<(val & 0xf);x++) {
309
		printf("%s", val & z ? "1" : "0");
310
		z >>= 1;
311
	}
312
	printf(" with %d ones now, %d bits in len\n", (val & 0xf00) >> 8, val & 0xf);
313
314
		
315
}
316
#endif
317
318
static inline void fasthdlc_precalc(void)
319
{
320
	int x;
321
	int y;
322
	/* First the easy part -- the searching */
323
	for (x=0;x<256;x++) {
324
		hdlc_search[x] = hdlc_search_precalc(x);
325
#ifdef DEBUG_PRECALC
326
		hdlc_search_print(x, hdlc_search[x]);
327
#endif
328
	}
329
	/* Now the hard part -- the frame tables */
330
	for (x=0;x<6;x++) {
331
		/* Given the # of preceeding ones, process the next
332
		   byte of input (up to 10 actual bits) */
333
		for (y=0;y<1024;y++) {
334
			hdlc_frame[x][y] = hdlc_frame_precalc(x, y);
335
#ifdef DEBUG_PRECALC
336
			hdlc_frame_print(x, y, hdlc_frame[x][y]);
337
#endif
338
		}
339
	}
340
	/* Now another not-so-hard part, the encoding table */
341
	for (x=0;x<6;x++) {
342
		for (y=0;y<256;y++) {
343
			hdlc_encode[x][y] = hdlc_encode_precalc(x,y);
344
#ifdef DEBUG_PRECALC
345
			hdlc_encode_print(x,y,hdlc_encode[x][y]);
346
#endif
347
		}
348
	}
349
}
350
351
352
static inline void fasthdlc_init(struct fasthdlc_state *h, enum fasthdlc_mode mode)
353
{
354
	/* Initializes all states appropriately */
355
	h->mode = mode;
356
	h->state = 0;
357
	h->bits = 0;
358
	h->data = 0;
359
	h->ones = 0;
360
361
}
362
363
static inline int fasthdlc_tx_load_nocheck(struct fasthdlc_state *h, unsigned char c)
364
{
365
	unsigned int res;
366
	res = hdlc_encode[h->ones][c];
367
	h->ones = (res & 0xf00) >> 8;
368
	h->data |= (res & 0xffc00000) >> h->bits;
369
	h->bits += (res & 0xf);
370
	return 0;
371
}
372
373
static inline int fasthdlc_tx_load(struct fasthdlc_state *h, unsigned char c)
374
{
375
	/* Gotta have at least 10 bits left */
376
	if (h->bits > 22) 
377
		return -1;
378
	return fasthdlc_tx_load_nocheck(h, c);
379
}
380
381
static inline int fasthdlc_tx_frame_nocheck(struct fasthdlc_state *h)
382
{
383
	h->ones = 0;
384
	h->data |= ( 0x7e000000 >> h->bits);
385
	h->bits += 8;
386
	return 0;
387
}
388
389
static inline int fasthdlc_tx_frame(struct fasthdlc_state *h)
390
{
391
	if (h->bits > 24)
392
		return -1;
393
	return fasthdlc_tx_frame_nocheck(h);
394
}
395
396
static inline int fasthdlc_tx_need_data(struct fasthdlc_state *h)
397
{
398
	if (h->mode == FASTHDLC_MODE_56) {
399
		if (h->bits < 7)
400
			return 1;
401
	} else {
402
		if (h->bits < 8)
403
			return 1;
404
	}
405
406
	return 0;
407
}
408
409
static inline int fasthdlc_tx_run_nocheck(struct fasthdlc_state *h)
410
{
411
	unsigned char b;
412
	if (h->mode == FASTHDLC_MODE_56) {
413
		b = h->data >> 25;
414
		h->bits -= 7;
415
		h->data <<= 7;
416
417
		return ((b & 0x7f) << 1) | 1;
418
	} else {
419
		b = h->data >> 24;
420
		h->bits -= 8;
421
		h->data <<= 8;
422
423
		return b;
424
	}
425
426
}
427
428
static inline int fasthdlc_tx_run(struct fasthdlc_state *h)
429
{
430
	if (h->bits < 8)
431
		return -1;
432
	return fasthdlc_tx_run_nocheck(h);
433
}
434
435
static inline int fasthdlc_rx_load_nocheck(struct fasthdlc_state *h, unsigned char b)
436
{
437
	if (h->mode == FASTHDLC_MODE_56) {
438
		h->data |= (b >> 1) << (25-h->bits);
439
		h->bits += 7;
440
	} else {
441
		/* Put the new byte in the data stream */
442
		h->data |= b << (24-h->bits);
443
		h->bits += 8;
444
	}
445
	return 0;
446
}
447
448
static inline int fasthdlc_rx_load(struct fasthdlc_state *h, unsigned char b)
449
{
450
	/* Make sure we have enough space */
451
	if (h->bits > 24)
452
		return -1;
453
	return fasthdlc_rx_load_nocheck(h, b);
454
}
455
456
/*
457
   Returns a data character if available, logical OR'd with 
458
   zero or more of RETURN_COMPLETE_FLAG, RETURN_DISCARD_FLAG,
459
   and RETURN_EMPTY_FLAG, signifying a complete frame, a
460
   discarded frame, or there is nothing to return.
461
   */
462
463
static inline int fasthdlc_rx_run(struct fasthdlc_state *h)
464
{
465
	unsigned short next;
466
	int retval=RETURN_EMPTY_FLAG;
467
	while ((h->bits >= minbits[h->state]) && (retval == RETURN_EMPTY_FLAG)) {
468
		/* Run until we can no longer be assured that we will
469
		   have enough bits to continue */
470
		switch(h->state) {
471
		case FRAME_SEARCH:
472
			/* Look for an HDLC frame, keying from
473
			   the top byte.  */
474
			next = hdlc_search[h->data >> 24];
475
			h->bits -= next & 0x0f;
476
			h->data <<= next & 0x0f;
477
			h->state = next >> 4;
478
			h->ones = 0;
479
			break;
480
		case PROCESS_FRAME:
481
			/* Process as much as the next ten bits */
482
			next = hdlc_frame[h->ones][h->data >> 22];
483
			h->bits  -= ((next & 0x0f00) >> 8);
484
			h->data <<= ((next & 0x0f00) >> 8);
485
			h->state = (next & STATE_MASK) >> 15;
486
			h->ones = (next & ONES_MASK) >> 12;
487
			switch(next & STATUS_MASK) {
488
			case STATUS_CONTROL:
489
				if (next & CONTROL_COMPLETE) {
490
					/* A complete, valid frame received */
491
					retval = (RETURN_COMPLETE_FLAG);
492
					/* Stay in this state */
493
					h->state = 1;
494
				} else {
495
				/* An abort (either out of sync of explicit) */
496
					retval = (RETURN_DISCARD_FLAG);
497
				}
498
				break;
499
			case STATUS_VALID:
500
				retval = (next & DATA_MASK);
501
			}
502
		}
503
	}
504
	return retval;
505
}
506
#endif /* FAST_HDLC_NEED_TABLES */
507
#endif
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/kernel.h (+1180 lines)
Line 0 Link Here
1
/*
2
 * DAHDI Telephony Interface
3
 *
4
 * Written by Mark Spencer <markster@digium.com>
5
 * Based on previous works, designs, and architectures conceived and
6
 * written by Jim Dixon <jim@lambdatel.com>.
7
 *
8
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
9
 * Copyright (C) 2001 - 2008 Digium, Inc.
10
 *
11
 * All rights reserved.
12
 *
13
 */
14
15
/*
16
 * See http://www.asterisk.org for more information about
17
 * the Asterisk project. Please do not directly contact
18
 * any of the maintainers of this project for assistance;
19
 * the project provides a web site, mailing lists and IRC
20
 * channels for your use.
21
 *
22
 * This program is free software, distributed under the terms of
23
 * the GNU General Public License Version 2 as published by the
24
 * Free Software Foundation. See the LICENSE file included with
25
 * this program for more details.
26
 */
27
28
/*!
29
 * \file
30
 * \brief DAHDI kernel interface definitions
31
 */
32
33
#ifndef _DAHDI_KERNEL_H
34
#define _DAHDI_KERNEL_H
35
36
#include "user.h"
37
#include "fasthdlc.h"
38
39
#include "dahdi_config.h"
40
#include <linux/version.h>
41
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
42
#include <linux/config.h>
43
#endif
44
#include <linux/fs.h>
45
#include <linux/ioctl.h>
46
47
#ifdef CONFIG_DAHDI_NET	
48
#include <linux/hdlc.h>
49
#endif
50
51
#ifdef CONFIG_DAHDI_PPP
52
#include <linux/ppp_channel.h>
53
#include <linux/skbuff.h>
54
#include <linux/interrupt.h>
55
#endif
56
57
#include <linux/poll.h>
58
59
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
60
#define dahdi_pci_module pci_register_driver
61
#else
62
#define dahdi_pci_module pci_module_init
63
#endif
64
65
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
66
#define DAHDI_IRQ_HANDLER(a) static irqreturn_t a(int irq, void *dev_id)
67
#else
68
#define DAHDI_IRQ_HANDLER(a) static irqreturn_t a(int irq, void *dev_id, struct pt_regs *regs)
69
#endif
70
71
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
72
#define DAHDI_IRQ_SHARED IRQF_SHARED
73
#define DAHDI_IRQ_DISABLED IRQF_DISABLED
74
#define DAHDI_IRQ_SHARED_DISABLED IRQF_SHARED | IRQF_DISABLED
75
#else
76
#define DAHDI_IRQ_SHARED SA_SHIRQ
77
#define DAHDI_IRQ_DISABLED SA_INTERRUPT
78
#define DAHDI_IRQ_SHARED_DISABLED SA_SHIRQ | SA_INTERRUPT
79
#endif
80
81
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)
82
#ifndef dev_notice
83
#define dev_notice(dev, format, arg...)         \
84
        dev_printk(KERN_NOTICE , dev , format , ## arg)
85
#endif
86
#endif
87
88
/*! Default chunk size for conferences and such -- static right now, might make
89
   variable sometime.  8 samples = 1 ms = most frequent service interval possible
90
   for a USB device */
91
#define DAHDI_CHUNKSIZE		 8
92
#define DAHDI_MIN_CHUNKSIZE	 DAHDI_CHUNKSIZE
93
#define DAHDI_DEFAULT_CHUNKSIZE	 DAHDI_CHUNKSIZE
94
#define DAHDI_MAX_CHUNKSIZE 	 DAHDI_CHUNKSIZE
95
#define DAHDI_CB_SIZE		 2
96
97
#define RING_DEBOUNCE_TIME	2000	/*!< 2000 ms ring debounce time */
98
99
typedef struct
100
{
101
    int32_t gain;
102
    int32_t a1;
103
    int32_t a2;
104
    int32_t b1;
105
    int32_t b2;
106
107
    int32_t z1;
108
    int32_t z2;
109
} biquad2_state_t;
110
111
typedef struct
112
{
113
    biquad2_state_t notch;
114
    int notch_level;
115
    int channel_level;
116
    int tone_present;
117
    int tone_cycle_duration;
118
    int good_cycles;
119
    int hit;
120
} echo_can_disable_detector_state_t;
121
122
struct sf_detect_state {
123
	long	x1;
124
	long	x2;
125
	long	y1;
126
	long	y2;
127
	long	e1;
128
	long	e2;
129
	int	samps;
130
	int	lastdetect;
131
};
132
133
struct dahdi_tone_state {
134
	int v1_1;
135
	int v2_1;
136
	int v3_1;
137
	int v1_2;
138
	int v2_2;
139
	int v3_2;
140
	int modulate;
141
};
142
143
/*! \brief Conference queue structure */
144
struct confq {
145
	u_char buffer[DAHDI_CHUNKSIZE * DAHDI_CB_SIZE];
146
	u_char *buf[DAHDI_CB_SIZE];
147
	int inbuf;
148
	int outbuf;
149
};
150
151
struct dahdi_chan;
152
struct dahdi_echocan_state;
153
154
/*! Features a DAHDI echo canceler (software or hardware) can provide to the DAHDI core. */
155
struct dahdi_echocan_features {
156
157
	/*! Able to detect CED tone (2100 Hz with phase reversals) in the transmit direction.
158
	 * If the echocan can detect this tone, it may report it it as an event (see
159
	 * the events.CED_tx_detected field of dahdi_echocan_state), and if it will automatically
160
	 * disable itself or its non-linear processor, then the NLP_automatic feature flag should also
161
	 * be set so that the DAHDI core doesn't bother trying to do so.
162
	*/
163
	u32 CED_tx_detect:1;
164
165
	/*! Able to detect CED tone (2100 Hz with phase reversals) in the receive direction.
166
	 * If the echocan can detect this tone, it may report it it as an event (see
167
	 * the events.CED_rx_detected field of dahdi_echocan_state), and if it will automatically
168
	 * disable itself or its non-linear processor, then the NLP_automatic flag feature should also
169
	 * be set so that the DAHDI core doesn't bother trying to do so.
170
	*/
171
	u32 CED_rx_detect:1;
172
173
	/*! Able to detect CNG tone (1100 Hz) in the transmit direction. */
174
	u32 CNG_tx_detect:1;
175
176
	/*! Able to detect CNG tone (1100 Hz) in the receive direction. */
177
	u32 CNG_rx_detect:1;
178
179
	/*! If the echocan's NLP can be enabled and disabled without requiring destruction
180
	 * and recreation of the state structure, this feature flag should be set and the
181
	 * echocan_NLP_toggle field of the dahdi_echocan_ops structure should be filled with a
182
	 * pointer to the function to perform that operation.
183
	 */
184
	u32 NLP_toggle:1;
185
186
	/*! If the echocan will automatically disable itself (or even just its NLP) based on
187
	 * detection of a CED tone in either direction, this feature flag should be set (along
188
	 * with the tone detection feature flags).
189
	 */
190
	u32 NLP_automatic:1;
191
};
192
193
/*! Operations (methods) that can be performed on a DAHDI echo canceler instance (state
194
 * structure) after it has been created, by either a software or hardware echo canceller.
195
 * The echo canceler must populate the owner field of the dahdi_echocan_state structure
196
 * with a pointer to the relevant operations structure for that instance.
197
 */
198
struct dahdi_echocan_ops {
199
200
	/*! The name of the echocan that created this structure. */
201
	const char *name;
202
203
	/*! \brief Free an echocan state structure.
204
	 * \param[in,out] ec Pointer to the state structure to free.
205
	 *
206
	 * \return Nothing.
207
	 */
208
	void (*echocan_free)(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
209
210
	/*! \brief Process an array of audio samples through the echocan.
211
	 * \param[in,out] ec Pointer to the state structure.
212
	 * \param[in,out] isig The receive direction data (will be modified).
213
	 * \param[in] iref The transmit direction data.
214
	 * \param[in] size The number of elements in the isig and iref arrays.
215
	 *
216
	 * Note: This function can also return events in the events field of the
217
	 * dahdi_echocan_state structure. If it can do so, then the echocan does
218
	 * not need to provide the echocan_events function.
219
	 *
220
	 * \return Nothing.
221
	 */
222
	void (*echocan_process)(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
223
224
	/*! \brief Retrieve events from the echocan.
225
	 * \param[in,out] ec Pointer to the state structure.
226
	 *
227
	 *
228
	 * If any events have occurred, the events field of the dahdi_echocan_state
229
	 * structure should be updated to include them.
230
	 *
231
	 * \return Nothing.
232
	 */
233
	void (*echocan_events)(struct dahdi_echocan_state *ec);
234
235
	/*! \brief Feed a sample (and its position) for echocan training.
236
	 * \param[in,out] ec Pointer to the state structure.
237
	 * \param[in] pos The tap position to be 'trained'.
238
	 * \param[in] val The receive direction sample for the specified tap position.
239
	 *
240
	 * \retval Zero if training should continue.
241
	 * \retval Non-zero if training is complete.
242
	 */
243
	int (*echocan_traintap)(struct dahdi_echocan_state *ec, int pos, short val);
244
245
	/*! \brief Enable or disable non-linear processing (NLP) in the echocan.
246
	 * \param[in,out] ec Pointer to the state structure.
247
	 * \param[in] enable Zero to disable, non-zero to enable.
248
	 *
249
	 * \return Nothing.
250
	 */
251
	void (*echocan_NLP_toggle)(struct dahdi_echocan_state *ec, unsigned int enable);
252
};
253
254
/*! A factory for creating instances of software echo cancelers to be used on DAHDI channels. */
255
struct dahdi_echocan_factory {
256
257
	/*! The name of the factory. */
258
	const char *name;
259
260
	/*! Pointer to the module that owns this factory; the module's reference count will be
261
	 * incremented/decremented by the DAHDI core as needed.
262
	 */
263
	struct module *owner;
264
265
	/*! \brief Function to create an instance of the echocan.
266
	 * \param[in] ecp Structure defining parameters to be used for the instance creation.
267
	 * \param[in] p Pointer to the beginning of an (optional) array of user-defined parameters.
268
	 * \param[out] ec Pointer to the state structure that is created, if any.
269
	 *
270
	 * \retval Zero on success.
271
	 * \retval Non-zero on failure (return value will be returned to userspace so it should be a
272
	 * standard error number).
273
	 */
274
	int (*echocan_create)(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
275
			      struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
276
};
277
278
/*! \brief Register an echo canceler factory with the DAHDI core.
279
 * \param[in] ec Pointer to the dahdi_echocan_factory structure to be registered.
280
 *
281
 * \retval Zero on success.
282
 * \retval Non-zero on failure (return value will be a standard error number).
283
 */
284
int dahdi_register_echocan_factory(const struct dahdi_echocan_factory *ec);
285
286
/*! \brief Unregister a previously-registered echo canceler factory from the DAHDI core.
287
 * \param[in] ec Pointer to the dahdi_echocan_factory structure to be unregistered.
288
 *
289
 * \return Nothing.
290
 */
291
void dahdi_unregister_echocan_factory(const struct dahdi_echocan_factory *ec);
292
293
enum dahdi_echocan_mode {
294
	__ECHO_MODE_MUTE = 1 << 8,
295
	ECHO_MODE_IDLE = 0,
296
	ECHO_MODE_PRETRAINING = 1 | __ECHO_MODE_MUTE,
297
	ECHO_MODE_STARTTRAINING = 2 | __ECHO_MODE_MUTE,
298
	ECHO_MODE_AWAITINGECHO = 3 | __ECHO_MODE_MUTE,
299
	ECHO_MODE_TRAINING = 4 | __ECHO_MODE_MUTE,
300
	ECHO_MODE_ACTIVE = 5,
301
	ECHO_MODE_FAX = 6,
302
};
303
304
/*! An instance of a DAHDI echo canceler (software or hardware). */
305
struct dahdi_echocan_state {
306
307
	/*! Pointer to a dahdi_echocan_ops structure of operations that can be
308
	 * performed on this instance.
309
	 */
310
	const struct dahdi_echocan_ops *ops;
311
312
	/*! State data used by the DAHDI core's CED detector for the transmit
313
	 * direction, if needed.
314
	 */
315
	echo_can_disable_detector_state_t txecdis;
316
317
	/*! State data used by the DAHDI core's CED detector for the receive
318
	 * direction, if needed.
319
	 */
320
	echo_can_disable_detector_state_t rxecdis;
321
322
	/*! Features offered by the echo canceler that provided this instance. */
323
	struct dahdi_echocan_features features;
324
325
	struct {
326
		/*! The mode the echocan is currently in. */
327
		enum dahdi_echocan_mode mode;
328
329
		/*! The last tap position that was fed to the echocan's training function. */
330
		u32 last_train_tap;
331
332
		/*! How many samples to wait before beginning the training operation. */
333
		u32 pretrain_timer;
334
	} status;
335
336
	/*! This structure contains event flags, allowing the echocan to report
337
	 * events that occurred as it processed the transmit and receive streams
338
	 * of samples. Each call to the echocan_process operation for this
339
	 * instance may report events, so the structure should be cleared before
340
	 * calling that operation.
341
	 */
342
	union dahdi_echocan_events {
343
		u32 all;
344
		struct {
345
			/*! CED tone was detected in the transmit direction. If the
346
			 * echocan automatically disables its NLP when this occurs,
347
			 * it must also signal the NLP_auto_disabled event during the *same*
348
			 * call to echocan_process that reports the CED detection.
349
			 */
350
			u32 CED_tx_detected:1;
351
352
			/*! CED tone was detected in the receive direction. If the
353
			 * echocan automatically disables its NLP when this occurs,
354
			 * it must also signal the NLP_auto_disabled event during the *same*
355
			 * call to echocan_process that reports the CED detection.
356
			 */
357
			u32 CED_rx_detected:1;
358
359
			/*! CNG tone was detected in the transmit direction. */
360
			u32 CNG_tx_detected:1;
361
362
			/*! CNG tone was detected in the receive direction. */
363
			u32 CNG_rx_detected:1;
364
365
			/*! The echocan disabled its NLP automatically.
366
			 */
367
			u32 NLP_auto_disabled:1;
368
369
			/*! The echocan enabled its NLP automatically.
370
			 */
371
			u32 NLP_auto_enabled:1;
372
		};
373
	} events;
374
};
375
376
struct dahdi_chan {
377
#ifdef CONFIG_DAHDI_NET
378
	/*! \note Must be first */
379
	struct dahdi_hdlc *hdlcnetdev;
380
#endif
381
#ifdef CONFIG_DAHDI_PPP
382
	struct ppp_channel *ppp;
383
	struct tasklet_struct ppp_calls;
384
	int do_ppp_wakeup;
385
	int do_ppp_error;
386
	struct sk_buff_head ppp_rq;
387
#endif
388
#ifdef BUFFER_DEBUG
389
	int statcount;
390
	int lastnumbufs;
391
#endif
392
#ifdef CONFIG_DAHDI_BRI_DCHANS
393
	int bytes2receive;
394
	int maxbytes2transmit; /* size of the tx buffer in the card driver */
395
	int bytes2transmit;
396
	int eofrx;
397
	int eoftx;
398
#endif
399
	spinlock_t lock;
400
	char name[40];
401
	/* Specified by DAHDI */
402
	/*! \brief DAHDI channel number */
403
	int channo;
404
	int chanpos;
405
	unsigned long flags;
406
	long rxp1;
407
	long rxp2;
408
	long rxp3;
409
	int txtone;
410
	int tx_v2;
411
	int tx_v3;
412
	int v1_1;
413
	int v2_1;
414
	int v3_1;
415
	int toneflags;
416
	struct sf_detect_state rd;
417
418
	struct dahdi_chan *master;	/*!< Our Master channel (could be us) */
419
	/*! \brief Next slave (if appropriate) */
420
	int nextslave;
421
422
	u_char *writechunk;						/*!< Actual place to write to */
423
	u_char swritechunk[DAHDI_MAX_CHUNKSIZE];	/*!< Buffer to be written */
424
	u_char *readchunk;						/*!< Actual place to read from */
425
	u_char sreadchunk[DAHDI_MAX_CHUNKSIZE];	/*!< Preallocated static area */
426
	short *readchunkpreec;
427
428
	/*! Pointer to tx and rx gain tables */
429
	u_char *rxgain;
430
	u_char *txgain;
431
	
432
	/*! Whether or not we have allocated gains or are using the default */
433
	int gainalloc;
434
435
	/* Specified by driver, readable by DAHDI */
436
	void *pvt;			/*!< Private channel data */
437
	struct file *file;	/*!< File structure */
438
	
439
	
440
	struct dahdi_span	*span;			/*!< Span we're a member of */
441
	int		sig;			/*!< Signalling */
442
	int		sigcap;			/*!< Capability for signalling */
443
	__u32		chan_alarms;		/*!< alarms status */
444
445
	/* Used only by DAHDI -- NO DRIVER SERVICEABLE PARTS BELOW */
446
	/* Buffer declarations */
447
	u_char		*readbuf[DAHDI_MAX_NUM_BUFS];	/*!< read buffer */
448
	int		inreadbuf;
449
	int		outreadbuf;
450
	wait_queue_head_t readbufq; /*!< read wait queue */
451
452
	u_char		*writebuf[DAHDI_MAX_NUM_BUFS]; /*!< write buffers */
453
	int		inwritebuf;
454
	int		outwritebuf;
455
	wait_queue_head_t writebufq; /*!< write wait queue */
456
	
457
	int		blocksize;	/*!< Block size */
458
459
	int		eventinidx;  /*!< out index in event buf (circular) */
460
	int		eventoutidx;  /*!< in index in event buf (circular) */
461
	unsigned int	eventbuf[DAHDI_MAX_EVENTSIZE];  /*!< event circ. buffer */
462
	wait_queue_head_t eventbufq; /*!< event wait queue */
463
	
464
	wait_queue_head_t txstateq;	/*!< waiting on the tx state to change */
465
	
466
	int		readn[DAHDI_MAX_NUM_BUFS];  /*!< # of bytes ready in read buf */
467
	int		readidx[DAHDI_MAX_NUM_BUFS];  /*!< current read pointer */
468
	int		writen[DAHDI_MAX_NUM_BUFS];  /*!< # of bytes ready in write buf */
469
	int		writeidx[DAHDI_MAX_NUM_BUFS];  /*!< current write pointer */
470
	
471
	int		numbufs;			/*!< How many buffers in channel */
472
	int		txbufpolicy;			/*!< Buffer policy */
473
	int		rxbufpolicy;			/*!< Buffer policy */
474
	int		txdisable;				/*!< Disable transmitter */
475
	int 	rxdisable;				/*!< Disable receiver */
476
	
477
	
478
	/* Tone zone stuff */
479
	struct dahdi_zone *curzone;		/*!< Zone for selecting tones */
480
	int 	tonezone;				/*!< Tone zone for this channel */
481
	struct dahdi_tone *curtone;		/*!< Current tone we're playing (if any) */
482
	int		tonep;					/*!< Current position in tone */
483
	struct dahdi_tone_state ts;		/*!< Tone state */
484
485
	/* Pulse dial stuff */
486
	int	pdialcount;			/*!< pulse dial count */
487
488
	/*! Ring cadence */
489
	int ringcadence[DAHDI_MAX_CADENCE];
490
	int firstcadencepos;				/*!< Where to restart ring cadence */
491
492
	/* Digit string dialing stuff */
493
	int		digitmode;			/*!< What kind of tones are we sending? */
494
	char	txdialbuf[DAHDI_MAX_DTMF_BUF];
495
	int 	dialing;
496
	int	afterdialingtimer;
497
	int		cadencepos;				/*!< Where in the cadence we are */
498
499
	/* I/O Mask */	
500
	int		iomask;  /*! I/O Mux signal mask */
501
	wait_queue_head_t sel;	/*! thingy for select stuff */
502
	
503
	/* HDLC state machines */
504
	struct fasthdlc_state txhdlc;
505
	struct fasthdlc_state rxhdlc;
506
	int infcs;
507
508
	/* Conferencing stuff */
509
	int		confna;	/*! conference number (alias) */
510
	int		_confn;	/*! Actual conference number */
511
	int		confmode;  /*! conference mode */
512
	int		confmute; /*! conference mute mode */
513
514
	/* Incoming and outgoing conference chunk queues for
515
	   communicating between DAHDI master time and
516
	   other boards */
517
	struct confq confin;
518
	struct confq confout;
519
520
	short	getlin[DAHDI_MAX_CHUNKSIZE];			/*!< Last transmitted samples */
521
	unsigned char getraw[DAHDI_MAX_CHUNKSIZE];		/*!< Last received raw data */
522
	short	getlin_lastchunk[DAHDI_MAX_CHUNKSIZE];	/*!< Last transmitted samples from last chunk */
523
	short	putlin[DAHDI_MAX_CHUNKSIZE];			/*!< Last received samples */
524
	unsigned char putraw[DAHDI_MAX_CHUNKSIZE];		/*!< Last received raw data */
525
	short	conflast[DAHDI_MAX_CHUNKSIZE];			/*!< Last conference sample -- base part of channel */
526
	short	conflast1[DAHDI_MAX_CHUNKSIZE];		/*!< Last conference sample  -- pseudo part of channel */
527
	short	conflast2[DAHDI_MAX_CHUNKSIZE];		/*!< Previous last conference sample -- pseudo part of channel */
528
	
529
530
	/*! The echo canceler module that should be used to create an
531
	   instance when this channel needs one */
532
	const struct dahdi_echocan_factory *ec_factory;
533
	/*! The echo canceler module that owns the instance currently
534
	   on this channel, if one is present */
535
	const struct dahdi_echocan_factory *ec_current;
536
	/*! The state data of the echo canceler instance in use */
537
	struct dahdi_echocan_state *ec_state;
538
539
	/* RBS timings  */
540
	int		prewinktime;  /*!< pre-wink time (ms) */
541
	int		preflashtime;	/*!< pre-flash time (ms) */
542
	int		winktime;  /*!< wink time (ms) */
543
	int		flashtime;  /*!< flash time (ms) */
544
	int		starttime;  /*!< start time (ms) */
545
	int		rxwinktime;  /*!< rx wink time (ms) */
546
	int		rxflashtime; /*!< rx flash time (ms) */
547
	int		debouncetime;  /*!< FXS GS sig debounce time (ms) */
548
	int		pulsebreaktime; /*!< pulse line open time (ms) */
549
	int		pulsemaketime;  /*!< pulse line closed time (ms) */
550
	int		pulseaftertime; /*!< pulse time between digits (ms) */
551
552
	/*! RING debounce timer */
553
	int	ringdebtimer;
554
	
555
	/*! RING trailing detector to make sure a RING is really over */
556
	int ringtrailer;
557
558
	/* PULSE digit receiver stuff */
559
	int	pulsecount;
560
	int	pulsetimer;
561
562
	/* RBS timers */
563
	int 	itimerset;		/*!< what the itimer was set to last */
564
	int 	itimer;
565
	int 	otimer;
566
	
567
	/* RBS state */
568
	int gotgs;
569
	int txstate;
570
	int rxsig;
571
	int txsig;
572
	int rxsigstate;
573
574
	/* non-RBS rx state */
575
	int rxhooksig;
576
	int txhooksig;
577
	int kewlonhook;
578
579
	/*! Idle signalling if CAS signalling */
580
	int idlebits;
581
582
	int deflaw;		/*! 1 = mulaw, 2=alaw, 0=undefined */
583
	short *xlaw;
584
#ifdef	OPTIMIZE_CHANMUTE
585
	int chanmute;		/*!< no need for PCM data */
586
#endif
587
#ifdef CONFIG_CALC_XLAW
588
	unsigned char (*lineartoxlaw)(short a);
589
#else
590
	unsigned char *lin2x;
591
#endif
592
};
593
594
#ifdef CONFIG_DAHDI_NET
595
struct dahdi_hdlc {
596
	struct net_device *netdev;
597
	struct dahdi_chan *chan;
598
};
599
#endif
600
601
/*! Define the maximum block size */
602
#define DAHDI_MAX_BLOCKSIZE	8192
603
604
605
#define DAHDI_DEFAULT_WINKTIME	150	/*!< 150 ms default wink time */
606
#define DAHDI_DEFAULT_FLASHTIME	750	/*!< 750 ms default flash time */
607
608
#define DAHDI_DEFAULT_PREWINKTIME	50	/*!< 50 ms before wink */
609
#define DAHDI_DEFAULT_PREFLASHTIME 50	/*!< 50 ms before flash */
610
#define DAHDI_DEFAULT_STARTTIME 1500	/*!< 1500 ms of start */
611
#define DAHDI_DEFAULT_RINGTIME 2000	/*!< 2000 ms of ring on (start, FXO) */
612
#if 0
613
#define DAHDI_DEFAULT_RXWINKTIME 250	/*!< 250ms longest rx wink */
614
#endif
615
#define DAHDI_DEFAULT_RXWINKTIME 300	/*!< 300ms longest rx wink (to work with the Atlas) */
616
#define DAHDI_DEFAULT_RXFLASHTIME 1250	/*!< 1250ms longest rx flash */
617
#define DAHDI_DEFAULT_DEBOUNCETIME 600	/*!< 600ms of FXS GS signalling debounce */
618
#define DAHDI_DEFAULT_PULSEMAKETIME 50	/*!< 50 ms of line closed when dial pulsing */
619
#define DAHDI_DEFAULT_PULSEBREAKTIME 50	/*!< 50 ms of line open when dial pulsing */
620
#define DAHDI_DEFAULT_PULSEAFTERTIME 750	/*!< 750ms between dial pulse digits */
621
622
#define DAHDI_MINPULSETIME (15 * 8)	/*!< 15 ms minimum */
623
624
#ifdef SHORT_FLASH_TIME
625
#define DAHDI_MAXPULSETIME (80 * 8)	/*!< we need 80 ms, not 200ms, as we have a short flash */
626
#else
627
#define DAHDI_MAXPULSETIME (200 * 8)	/*!< 200 ms maximum */
628
#endif
629
630
#define DAHDI_PULSETIMEOUT ((DAHDI_MAXPULSETIME / 8) + 50)
631
632
#define DAHDI_RINGTRAILER (50 * 8)	/*!< Don't consider a ring "over" until it's been gone at least this
633
									   much time */
634
635
#define DAHDI_LOOPCODE_TIME 10000		/*!< send loop codes for 10 secs */
636
#define DAHDI_ALARMSETTLE_TIME	5000	/*!< allow alarms to settle for 5 secs */
637
#define DAHDI_AFTERSTART_TIME 500		/*!< 500ms after start */
638
639
#define DAHDI_RINGOFFTIME 4000		/*!< Turn off ringer for 4000 ms */
640
#define DAHDI_KEWLTIME 500		/*!< 500ms for kewl pulse */
641
#define DAHDI_AFTERKEWLTIME 300    /*!< 300ms after kewl pulse */
642
643
#define DAHDI_MAX_PRETRAINING   1000	/*!< 1000ms max pretraining time */
644
645
#ifdef	FXSFLASH
646
#define DAHDI_FXSFLASHMINTIME	450	/*!< min 450ms */
647
#define DAHDI_FXSFLASHMAXTIME	550	/*!< max 550ms */
648
#endif
649
650
651
struct dahdi_chardev {
652
	const char *name;
653
	__u8 minor;
654
};
655
656
int dahdi_register_chardev(struct dahdi_chardev *dev);
657
int dahdi_unregister_chardev(struct dahdi_chardev *dev);
658
659
/*! \brief defines for transmit signalling */
660
enum dahdi_txsig {
661
	DAHDI_TXSIG_ONHOOK,  /*!< On hook */
662
	DAHDI_TXSIG_OFFHOOK, /*!< Off hook */
663
	DAHDI_TXSIG_START,   /*!< Start / Ring */
664
	DAHDI_TXSIG_KEWL,     /*!< Drop battery if possible */
665
	/*! Leave this as the last entry */
666
	DAHDI_TXSIG_TOTAL,
667
};
668
669
enum dahdi_rxsig {
670
	DAHDI_RXSIG_ONHOOK,
671
	DAHDI_RXSIG_OFFHOOK,
672
	DAHDI_RXSIG_START,
673
	DAHDI_RXSIG_RING,
674
	DAHDI_RXSIG_INITIAL
675
};
676
	
677
enum {
678
	/* Span flags */
679
	DAHDI_FLAGBIT_REGISTERED= 0,
680
	DAHDI_FLAGBIT_RUNNING	= 1,
681
	DAHDI_FLAGBIT_RBS	= 12,	/*!< Span uses RBS signalling */
682
683
	/* Channel flags */
684
	DAHDI_FLAGBIT_DTMFDECODE= 2,	/*!< Channel supports native DTMF decode */
685
	DAHDI_FLAGBIT_MFDECODE	= 3,	/*!< Channel supports native MFr2 decode */
686
	DAHDI_FLAGBIT_ECHOCANCEL= 4,	/*!< Channel supports native echo cancellation */
687
	DAHDI_FLAGBIT_HDLC	= 5,	/*!< Perform HDLC */
688
	DAHDI_FLAGBIT_NETDEV	= 6,	/*!< Send to network */
689
	DAHDI_FLAGBIT_PSEUDO	= 7,	/*!< Pseudo channel */
690
	DAHDI_FLAGBIT_CLEAR	= 8,	/*!< Clear channel */
691
	DAHDI_FLAGBIT_AUDIO	= 9,	/*!< Audio mode channel */
692
	DAHDI_FLAGBIT_OPEN	= 10,	/*!< Channel is open */
693
	DAHDI_FLAGBIT_FCS	= 11,	/*!< Calculate FCS */
694
	/* Reserve 12 for uniqueness with span flags */
695
	DAHDI_FLAGBIT_LINEAR	= 13,	/*!< Talk to user space in linear */
696
	DAHDI_FLAGBIT_PPP	= 14,	/*!< PPP is available */
697
	DAHDI_FLAGBIT_T1PPP	= 15,
698
	DAHDI_FLAGBIT_SIGFREEZE	= 16,	/*!< Freeze signalling */
699
	DAHDI_FLAGBIT_NOSTDTXRX	= 17,	/*!< Do NOT do standard transmit and receive on every interrupt */
700
	DAHDI_FLAGBIT_LOOPED	= 18,	/*!< Loopback the receive data from the channel to the transmit */
701
	DAHDI_FLAGBIT_MTP2	= 19,	/*!< Repeats last message in buffer and also discards repeating messages sent to us */
702
	DAHDI_FLAGBIT_HDLC56	= 20,	/*!< Sets the given channel (if in HDLC mode) to use 56K HDLC instead of 64K  */
703
#if defined(CONFIG_DAHDI_BRI_DCHANS)
704
	DAHDI_FLAGBIT_BRIDCHAN   = 21,	/*!< hardhdlc-like handling of the D channel */
705
#endif
706
};
707
708
/* map flagbits to flag masks */
709
#define	DAHDI_FLAG(x)	(1 << (DAHDI_FLAGBIT_ ## x))
710
711
/*! This is a redefinition of the flags from above to allow use of the 
712
 * legacy drivers that do not use the kernel atomic bit testing and 
713
 * changing routines.
714
 * 
715
 * See the above descriptions for DAHDI_FLAGBIT_....  for documentation 
716
 * about function. */
717
/* Span flags */
718
#define DAHDI_FLAG_REGISTERED	DAHDI_FLAG(REGISTERED)
719
#define DAHDI_FLAG_RUNNING	DAHDI_FLAG(RUNNING)
720
#define DAHDI_FLAG_RBS		DAHDI_FLAG(RBS)
721
722
/* Channel flags */
723
#define DAHDI_FLAG_DTMFDECODE	DAHDI_FLAG(DTMFDECODE)
724
#define DAHDI_FLAG_MFDECODE	DAHDI_FLAG(MFDECODE)
725
#define DAHDI_FLAG_ECHOCANCEL	DAHDI_FLAG(ECHOCANCEL)
726
727
#define DAHDI_FLAG_HDLC		DAHDI_FLAG(HDLC)
728
#define DAHDI_FLAG_NETDEV	DAHDI_FLAG(NETDEV)
729
#define DAHDI_FLAG_PSEUDO	DAHDI_FLAG(PSEUDO)
730
#define DAHDI_FLAG_CLEAR	DAHDI_FLAG(CLEAR)
731
#define DAHDI_FLAG_AUDIO	DAHDI_FLAG(AUDIO)
732
733
#define DAHDI_FLAG_OPEN		DAHDI_FLAG(OPEN)
734
#define DAHDI_FLAG_FCS		DAHDI_FLAG(FCS)
735
/* Reserve 12 for uniqueness with span flags */
736
#define DAHDI_FLAG_LINEAR	DAHDI_FLAG(LINEAR)
737
#define DAHDI_FLAG_PPP		DAHDI_FLAG(PPP)
738
#define DAHDI_FLAG_T1PPP	DAHDI_FLAG(T1PPP)
739
#define DAHDI_FLAG_SIGFREEZE	DAHDI_FLAG(SIGFREEZE)
740
#define DAHDI_FLAG_NOSTDTXRX	DAHDI_FLAG(NOSTDTXRX)
741
#define DAHDI_FLAG_LOOPED	DAHDI_FLAG(LOOPED)
742
#define DAHDI_FLAG_MTP2		DAHDI_FLAG(MTP2)
743
#define DAHDI_FLAG_HDLC56	DAHDI_FLAG(HDLC56)
744
#define DAHDI_FLAG_BRIDCHAN	DAHDI_FLAG(BRIDCHAN)
745
746
struct dahdi_span {
747
	spinlock_t lock;
748
	void *pvt;			/*!< Private stuff */
749
	char name[40];			/*!< Span name */
750
	char desc[80];			/*!< Span description */
751
	const char *spantype;		/*!< span type in text form */
752
	const char *manufacturer;	/*!< span's device manufacturer */
753
	char devicetype[80];		/*!< span's device type */
754
	char location[40];		/*!< span device's location in system */
755
	int deflaw;			/*!< Default law (DAHDI_MULAW or DAHDI_ALAW) */
756
	int alarms;			/*!< Pending alarms on span */
757
	unsigned long flags;
758
	int irq;			/*!< IRQ for this span's hardware */
759
	int lbo;			/*!< Span Line-Buildout */
760
	int lineconfig;			/*!< Span line configuration */
761
	int linecompat;			/*!< Span line compatibility */
762
	int channels;			/*!< Number of channels in span */
763
	int txlevel;			/*!< Tx level */
764
	int rxlevel;			/*!< Rx level */
765
	int syncsrc;			/*!< current sync src (gets copied here) */
766
	unsigned int bpvcount;		/*!< BPV counter */
767
	unsigned int crc4count;	        /*!< CRC4 error counter */
768
	unsigned int ebitcount;		/*!< current E-bit error count */
769
	unsigned int fascount;		/*!< current FAS error count */
770
771
	int maintstat;			/*!< Maintenance state */
772
	wait_queue_head_t maintq;	/*!< Maintenance queue */
773
	int mainttimer;			/*!< Maintenance timer */
774
	
775
	int irqmisses;			/*!< Interrupt misses */
776
777
	int timingslips;			/*!< Clock slips */
778
779
	struct dahdi_chan **chans;		/*!< Member channel structures */
780
781
	/*   ==== Span Callback Operations ====   */
782
	/*! Req: Set the requested chunk size.  This is the unit in which you must
783
	   report results for conferencing, etc */
784
	int (*setchunksize)(struct dahdi_span *span, int chunksize);
785
786
	/*! Opt: Configure the span (if appropriate) */
787
	int (*spanconfig)(struct dahdi_span *span, struct dahdi_lineconfig *lc);
788
	
789
	/*! Opt: Start the span */
790
	int (*startup)(struct dahdi_span *span);
791
	
792
	/*! Opt: Shutdown the span */
793
	int (*shutdown)(struct dahdi_span *span);
794
	
795
	/*! Opt: Enable maintenance modes */
796
	int (*maint)(struct dahdi_span *span, int mode);
797
798
#ifdef	DAHDI_SYNC_TICK
799
	/*! Opt: send sync to spans */
800
	int (*sync_tick)(struct dahdi_span *span, int is_master);
801
#endif
802
803
	/* ====  Channel Callback Operations ==== */
804
	/*! Opt: Set signalling type (if appropriate) */
805
	int (*chanconfig)(struct dahdi_chan *chan, int sigtype);
806
807
	/*! Opt: Prepare a channel for I/O */
808
	int (*open)(struct dahdi_chan *chan);
809
810
	/*! Opt: Close channel for I/O */
811
	int (*close)(struct dahdi_chan *chan);
812
	
813
	/*! Opt: IOCTL */
814
	int (*ioctl)(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
815
	
816
	/*! Opt: Provide echo cancellation on a channel */
817
	int (*echocan_create)(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
818
			      struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
819
820
	/* Okay, now we get to the signalling.  You have several options: */
821
822
	/* Option 1: If you're a T1 like interface, you can just provide a
823
	   rbsbits function and we'll assert robbed bits for you.  Be sure to 
824
	   set the DAHDI_FLAG_RBS in this case.  */
825
826
	/*! Opt: If the span uses A/B bits, set them here */
827
	int (*rbsbits)(struct dahdi_chan *chan, int bits);
828
	
829
	/*! Option 2: If you don't know about sig bits, but do have their
830
	   equivalents (i.e. you can disconnect battery, detect off hook,
831
	   generate ring, etc directly) then you can just specify a
832
	   sethook function, and we'll call you with appropriate hook states
833
	   to set.  Still set the DAHDI_FLAG_RBS in this case as well */
834
	int (*hooksig)(struct dahdi_chan *chan, enum dahdi_txsig hookstate);
835
	
836
	/*! Option 3: If you can't use sig bits, you can write a function
837
	   which handles the individual hook states  */
838
	int (*sethook)(struct dahdi_chan *chan, int hookstate);
839
	
840
	/*! Opt: Dacs the contents of chan2 into chan1 if possible */
841
	int (*dacs)(struct dahdi_chan *chan1, struct dahdi_chan *chan2);
842
843
	/*! Opt: Used to tell an onboard HDLC controller that there is data ready to transmit */
844
	void (*hdlc_hard_xmit)(struct dahdi_chan *chan);
845
846
	/* Used by DAHDI only -- no user servicable parts inside */
847
	int spanno;			/*!< Span number for DAHDI */
848
	int offset;			/*!< Offset within a given card */
849
	int lastalarms;		/*!< Previous alarms */
850
	/*! If the watchdog detects no received data, it will call the
851
	   watchdog routine */
852
	int (*watchdog)(struct dahdi_span *span, int cause);
853
#ifdef CONFIG_DAHDI_WATCHDOG
854
	int watchcounter;
855
	int watchstate;
856
#endif	
857
};
858
859
struct dahdi_transcoder_channel {
860
	void *pvt;
861
	struct dahdi_transcoder *parent;
862
	wait_queue_head_t ready;
863
	__u32 built_fmts;
864
#define DAHDI_TC_FLAG_BUSY		1
865
#define DAHDI_TC_FLAG_CHAN_BUILT	2
866
#define DAHDI_TC_FLAG_NONBLOCK		3
867
#define DAHDI_TC_FLAG_DATA_WAITING	4
868
	unsigned long flags;
869
	u32 dstfmt;
870
	u32 srcfmt;
871
};
872
873
static inline int 
874
dahdi_tc_is_built(struct dahdi_transcoder_channel *dtc) {
875
	return test_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
876
}
877
static inline void
878
dahdi_tc_set_built(struct dahdi_transcoder_channel *dtc) {
879
	set_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
880
}
881
static inline void 
882
dahdi_tc_clear_built(struct dahdi_transcoder_channel *dtc) {
883
	clear_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
884
}
885
static inline int 
886
dahdi_tc_is_nonblock(struct dahdi_transcoder_channel *dtc) {
887
	return test_bit(DAHDI_TC_FLAG_NONBLOCK, &dtc->flags);
888
}
889
static inline void 
890
dahdi_tc_set_nonblock(struct dahdi_transcoder_channel *dtc) {
891
	set_bit(DAHDI_TC_FLAG_NONBLOCK, &dtc->flags);
892
}
893
static inline void 
894
dahdi_tc_clear_nonblock(struct dahdi_transcoder_channel *dtc) {
895
	clear_bit(DAHDI_TC_FLAG_NONBLOCK, &dtc->flags);
896
}
897
static inline int 
898
dahdi_tc_is_data_waiting(struct dahdi_transcoder_channel *dtc) {
899
	return test_bit(DAHDI_TC_FLAG_DATA_WAITING, &dtc->flags);
900
}
901
static inline int 
902
dahdi_tc_is_busy(struct dahdi_transcoder_channel *dtc) {
903
	return test_bit(DAHDI_TC_FLAG_BUSY, &dtc->flags);
904
}
905
static inline void 
906
dahdi_tc_set_busy(struct dahdi_transcoder_channel *dtc) {
907
	set_bit(DAHDI_TC_FLAG_BUSY, &dtc->flags);
908
}
909
static inline void 
910
dahdi_tc_clear_busy(struct dahdi_transcoder_channel *dtc) {
911
	clear_bit(DAHDI_TC_FLAG_BUSY, &dtc->flags);
912
}
913
static inline void 
914
dahdi_tc_set_data_waiting(struct dahdi_transcoder_channel *dtc) {
915
	set_bit(DAHDI_TC_FLAG_DATA_WAITING, &dtc->flags);
916
}
917
static inline void 
918
dahdi_tc_clear_data_waiting(struct dahdi_transcoder_channel *dtc) {
919
	clear_bit(DAHDI_TC_FLAG_DATA_WAITING, &dtc->flags);
920
}
921
922
struct dahdi_transcoder {
923
	struct list_head active_list_node;
924
	struct list_head registration_list_node;
925
	char name[80];
926
	int numchannels;
927
	unsigned int srcfmts;
928
	unsigned int dstfmts;
929
	struct file_operations fops;
930
	int (*allocate)(struct dahdi_transcoder_channel *channel);
931
	int (*release)(struct dahdi_transcoder_channel *channel);
932
	/* Transcoder channels */
933
	struct dahdi_transcoder_channel channels[0];
934
};
935
936
#define DAHDI_WATCHDOG_NOINTS		(1 << 0)
937
938
#define DAHDI_WATCHDOG_INIT			1000
939
940
#define DAHDI_WATCHSTATE_UNKNOWN		0
941
#define DAHDI_WATCHSTATE_OK			1
942
#define DAHDI_WATCHSTATE_RECOVERING	2
943
#define DAHDI_WATCHSTATE_FAILED		3
944
945
946
struct dahdi_dynamic_driver {
947
	/*! Driver name (e.g. Eth) */
948
	char name[20];
949
950
	/*! Driver description */
951
	char desc[80];
952
953
	/*! Create a new transmission pipe */
954
	void *(*create)(struct dahdi_span *span, char *address);
955
956
	/*! Destroy a created transmission pipe */
957
	void (*destroy)(void *tpipe);
958
959
	/*! Transmit a given message */
960
	int (*transmit)(void *tpipe, unsigned char *msg, int msglen);
961
962
	/*! Flush any pending messages */
963
	int (*flush)(void);
964
965
	struct dahdi_dynamic_driver *next;
966
};
967
968
/*! \brief Receive a dynamic span message */
969
void dahdi_dynamic_receive(struct dahdi_span *span, unsigned char *msg, int msglen);
970
971
/*! \brief Register a dynamic driver */
972
int dahdi_dynamic_register(struct dahdi_dynamic_driver *driver);
973
974
/*! \brief Unregister a dynamic driver */
975
void dahdi_dynamic_unregister(struct dahdi_dynamic_driver *driver);
976
977
/*! Receive on a span.  The DAHDI interface will handle all the calculations for
978
   all member channels of the span, pulling the data from the readchunk buffer */
979
int dahdi_receive(struct dahdi_span *span);
980
981
/*! Prepare writechunk buffers on all channels for this span */
982
int dahdi_transmit(struct dahdi_span *span);
983
984
/*! Abort the buffer currently being receive with event "event" */
985
void dahdi_hdlc_abort(struct dahdi_chan *ss, int event);
986
987
/*! Indicate to DAHDI that the end of frame was received and rotate buffers */
988
void dahdi_hdlc_finish(struct dahdi_chan *ss);
989
990
/*! Put a chunk of data into the current receive buffer */
991
void dahdi_hdlc_putbuf(struct dahdi_chan *ss, unsigned char *rxb, int bytes);
992
993
/*! Get a chunk of data from the current transmit buffer.  Returns -1 if no data
994
 * is left to send, 0 if there is data remaining in the current message to be sent
995
 * and 1 if the currently transmitted message is now done */
996
int dahdi_hdlc_getbuf(struct dahdi_chan *ss, unsigned char *bufptr, unsigned int *size);
997
998
999
/*! Register a span.  Returns 0 on success, -1 on failure.  Pref-master is non-zero if
1000
   we should have preference in being the master device */
1001
int dahdi_register(struct dahdi_span *span, int prefmaster);
1002
1003
/*! Allocate / free memory for a transcoder */
1004
struct dahdi_transcoder *dahdi_transcoder_alloc(int numchans);
1005
void dahdi_transcoder_free(struct dahdi_transcoder *ztc);
1006
1007
/*! \brief Register a transcoder */
1008
int dahdi_transcoder_register(struct dahdi_transcoder *tc);
1009
1010
/*! \brief Unregister a transcoder */
1011
int dahdi_transcoder_unregister(struct dahdi_transcoder *tc);
1012
1013
/*! \brief Alert a transcoder */
1014
int dahdi_transcoder_alert(struct dahdi_transcoder_channel *ztc);
1015
1016
/*! \brief Unregister a span */
1017
int dahdi_unregister(struct dahdi_span *span);
1018
1019
/*! \brief Gives a name to an LBO */
1020
char *dahdi_lboname(int lbo);
1021
1022
/*! \brief Tell DAHDI about changes in received rbs bits */
1023
void dahdi_rbsbits(struct dahdi_chan *chan, int bits);
1024
1025
/*! \brief Tell DAHDI abou changes in received signalling */
1026
void dahdi_hooksig(struct dahdi_chan *chan, enum dahdi_rxsig rxsig);
1027
1028
/*! \brief Queue an event on a channel */
1029
void dahdi_qevent_nolock(struct dahdi_chan *chan, int event);
1030
1031
/*! \brief Queue an event on a channel, locking it first */
1032
void dahdi_qevent_lock(struct dahdi_chan *chan, int event);
1033
1034
/*! \brief Notify a change possible change in alarm status on a channel */
1035
void dahdi_alarm_channel(struct dahdi_chan *chan, int alarms);
1036
1037
/*! \brief Notify a change possible change in alarm status on a span */
1038
void dahdi_alarm_notify(struct dahdi_span *span);
1039
1040
/*! \brief Initialize a tone state */
1041
void dahdi_init_tone_state(struct dahdi_tone_state *ts, struct dahdi_tone *zt);
1042
1043
/*! \brief Get a given MF tone struct, suitable for dahdi_tone_nextsample. */
1044
struct dahdi_tone *dahdi_mf_tone(const struct dahdi_chan *chan, char digit, int digitmode);
1045
1046
/* Echo cancel a receive and transmit chunk for a given channel.  This
1047
   should be called by the low-level driver as close to the interface
1048
   as possible.  ECHO CANCELLATION IS NO LONGER AUTOMATICALLY DONE
1049
   AT THE DAHDI LEVEL.  dahdi_ec_chunk will not echo cancel if it should
1050
   not be doing so.  rxchunk is modified in-place */
1051
1052
void dahdi_ec_chunk(struct dahdi_chan *chan, unsigned char *rxchunk, const unsigned char *txchunk);
1053
void dahdi_ec_span(struct dahdi_span *span);
1054
1055
extern struct file_operations *dahdi_transcode_fops;
1056
1057
/* Don't use these directly -- they're not guaranteed to
1058
   be there. */
1059
extern short __dahdi_mulaw[256];
1060
extern short __dahdi_alaw[256];
1061
#ifdef CONFIG_CALC_XLAW
1062
u_char __dahdi_lineartoulaw(short a);
1063
u_char __dahdi_lineartoalaw(short a);
1064
#else
1065
extern u_char __dahdi_lin2mu[16384];
1066
extern u_char __dahdi_lin2a[16384];
1067
#endif
1068
1069
/*! \brief Used by dynamic DAHDI -- don't use directly */
1070
void dahdi_set_dynamic_ioctl(int (*func)(unsigned int cmd, unsigned long data));
1071
1072
/*! \brief Used by DAHDI HPEC module -- don't use directly */
1073
void dahdi_set_hpec_ioctl(int (*func)(unsigned int cmd, unsigned long data));
1074
1075
/*! \brief Used privately by DAHDI.  Avoid touching directly */
1076
struct dahdi_tone {
1077
	int fac1;
1078
	int init_v2_1;
1079
	int init_v3_1;
1080
1081
	int fac2;
1082
	int init_v2_2;
1083
	int init_v3_2;
1084
1085
	int tonesamples;		/*!< How long to play this tone before 
1086
					   going to the next (in samples) */
1087
	struct dahdi_tone *next;		/* Next tone in this sequence */
1088
1089
	int modulate;
1090
};
1091
1092
static inline short dahdi_tone_nextsample(struct dahdi_tone_state *ts, struct dahdi_tone *zt)
1093
{
1094
	/* follow the curves, return the sum */
1095
1096
	int p;
1097
1098
	ts->v1_1 = ts->v2_1;
1099
	ts->v2_1 = ts->v3_1;
1100
	ts->v3_1 = (zt->fac1 * ts->v2_1 >> 15) - ts->v1_1;
1101
1102
	ts->v1_2 = ts->v2_2;
1103
	ts->v2_2 = ts->v3_2;
1104
	ts->v3_2 = (zt->fac2 * ts->v2_2 >> 15) - ts->v1_2;
1105
1106
	/* Return top 16 bits */
1107
	if (!ts->modulate) return ts->v3_1 + ts->v3_2;
1108
	/* we are modulating */
1109
	p = ts->v3_2 - 32768;
1110
	if (p < 0) p = -p;
1111
	p = ((p * 9) / 10) + 1;
1112
	return (ts->v3_1 * p) >> 15;
1113
1114
}
1115
1116
static inline short dahdi_txtone_nextsample(struct dahdi_chan *ss)
1117
{
1118
	/* follow the curves, return the sum */
1119
1120
	ss->v1_1 = ss->v2_1;
1121
	ss->v2_1 = ss->v3_1;
1122
	ss->v3_1 = (ss->txtone * ss->v2_1 >> 15) - ss->v1_1;
1123
	return ss->v3_1;
1124
}
1125
1126
/* These are the right functions to use.  */
1127
1128
#define DAHDI_MULAW(a) (__dahdi_mulaw[(a)])
1129
#define DAHDI_ALAW(a) (__dahdi_alaw[(a)])
1130
#define DAHDI_XLAW(a,c) (c->xlaw[(a)])
1131
1132
#ifdef CONFIG_CALC_XLAW
1133
#define DAHDI_LIN2MU(a) (__dahdi_lineartoulaw((a)))
1134
#define DAHDI_LIN2A(a) (__dahdi_lineartoalaw((a)))
1135
1136
#define DAHDI_LIN2X(a,c) ((c)->lineartoxlaw((a)))
1137
1138
#else
1139
/* Use tables */
1140
#define DAHDI_LIN2MU(a) (__dahdi_lin2mu[((unsigned short)(a)) >> 2])
1141
#define DAHDI_LIN2A(a) (__dahdi_lin2a[((unsigned short)(a)) >> 2])
1142
1143
/* Manipulate as appropriate for x-law */
1144
#define DAHDI_LIN2X(a,c) ((c)->lin2x[((unsigned short)(a)) >> 2])
1145
1146
#endif /* CONFIG_CALC_XLAW */
1147
1148
/* Data formats for capabilities and frames alike (from Asterisk) */
1149
/*! G.723.1 compression */
1150
#define DAHDI_FORMAT_G723_1	(1 << 0)
1151
/*! GSM compression */
1152
#define DAHDI_FORMAT_GSM		(1 << 1)
1153
/*! Raw mu-law data (G.711) */
1154
#define DAHDI_FORMAT_ULAW		(1 << 2)
1155
/*! Raw A-law data (G.711) */
1156
#define DAHDI_FORMAT_ALAW		(1 << 3)
1157
/*! ADPCM (G.726, 32kbps) */
1158
#define DAHDI_FORMAT_G726		(1 << 4)
1159
/*! ADPCM (IMA) */
1160
#define DAHDI_FORMAT_ADPCM		(1 << 5)
1161
/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
1162
#define DAHDI_FORMAT_SLINEAR	(1 << 6)
1163
/*! LPC10, 180 samples/frame */
1164
#define DAHDI_FORMAT_LPC10		(1 << 7)
1165
/*! G.729A audio */
1166
#define DAHDI_FORMAT_G729A		(1 << 8)
1167
/*! SpeeX Free Compression */
1168
#define DAHDI_FORMAT_SPEEX		(1 << 9)
1169
/*! iLBC Free Compression */
1170
#define DAHDI_FORMAT_ILBC		(1 << 10)
1171
/*! Maximum audio format */
1172
#define DAHDI_FORMAT_MAX_AUDIO	(1 << 15)
1173
/*! Maximum audio mask */
1174
#define DAHDI_FORMAT_AUDIO_MASK	((1 << 16) - 1)
1175
1176
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
1177
#define kzalloc(a, b) kcalloc(1, a, b)
1178
#endif
1179
1180
#endif /* _DAHDI_KERNEL_H */
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/modules.order (+1 lines)
Line 0 Link Here
1
kernel//usr/src/dahdi-svn/dahdi-kernel/drivers/dahdi/zaphfc/zaphfc.ko
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/user.h (+1158 lines)
Line 0 Link Here
1
/*
2
 * DAHDI Telephony Interface
3
 *
4
 * Written by Mark Spencer <markster@digium.com>
5
 * Based on previous works, designs, and architectures conceived and
6
 * written by Jim Dixon <jim@lambdatel.com>.
7
 *
8
 * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
9
 * Copyright (C) 2001 - 2008 Digium, Inc.
10
 *
11
 * All rights reserved.
12
 *
13
 */
14
15
/*
16
 * See http://www.asterisk.org for more information about
17
 * the Asterisk project. Please do not directly contact
18
 * any of the maintainers of this project for assistance;
19
 * the project provides a web site, mailing lists and IRC
20
 * channels for your use.
21
 *
22
 * This program is free software, distributed under the terms of
23
 * the GNU Lesser General Public License Version 2.1 as published
24
 * by the Free Software Foundation. See the LICENSE.LGPL file
25
 * included with this program for more details.
26
 *
27
 * In addition, when this program is distributed with Asterisk in
28
 * any form that would qualify as a 'combined work' or as a
29
 * 'derivative work' (but not mere aggregation), you can redistribute
30
 * and/or modify the combination under the terms of the license
31
 * provided with that copy of Asterisk, instead of the license
32
 * terms granted here.
33
 */
34
35
#ifndef _DAHDI_USER_H
36
#define _DAHDI_USER_H
37
38
#include <linux/types.h>
39
#include <linux/ioctl.h>
40
41
#ifndef ELAST
42
#define ELAST 500
43
#endif
44
45
/* Per-span configuration values */
46
#define DAHDI_CONFIG_TXLEVEL	7				/* bits 0-2 are tx level */
47
48
/* Line configuration */
49
/* These apply to T1 */
50
#define DAHDI_CONFIG_D4	 	(1 << 4)
51
#define DAHDI_CONFIG_ESF	(1 << 5)
52
#define DAHDI_CONFIG_AMI	(1 << 6)
53
#define DAHDI_CONFIG_B8ZS	(1 << 7)
54
/* These apply to E1 */
55
#define DAHDI_CONFIG_CCS	(1 << 8)			/* CCS (ISDN) instead of CAS (Robbed Bit) */
56
#define DAHDI_CONFIG_HDB3	(1 << 9)			/* HDB3 instead of AMI (line coding) */
57
#define DAHDI_CONFIG_CRC4	(1 << 10)			/* CRC4 framing */
58
#define DAHDI_CONFIG_NOTOPEN	(1 << 16)
59
60
/* Signalling types */
61
#define DAHDI_SIG_BROKEN	(1 << 31)			/* The port is broken and/or failed initialization */
62
63
#define __DAHDI_SIG_FXO		(1 << 12)			/* Never use directly */
64
#define __DAHDI_SIG_FXS		(1 << 13)			/* Never use directly */
65
66
#define DAHDI_SIG_NONE		(0)				/* Channel not configured */
67
#define DAHDI_SIG_FXSLS		((1 << 0) | __DAHDI_SIG_FXS)	/* FXS, Loopstart */
68
#define DAHDI_SIG_FXSGS		((1 << 1) | __DAHDI_SIG_FXS)	/* FXS, Groundstart */
69
#define DAHDI_SIG_FXSKS		((1 << 2) | __DAHDI_SIG_FXS)	/* FXS, Kewlstart */
70
71
#define DAHDI_SIG_FXOLS		((1 << 3) | __DAHDI_SIG_FXO)	/* FXO, Loopstart */
72
#define DAHDI_SIG_FXOGS		((1 << 4) | __DAHDI_SIG_FXO)	/* FXO, Groupstart */
73
#define DAHDI_SIG_FXOKS		((1 << 5) | __DAHDI_SIG_FXO)	/* FXO, Kewlstart */
74
75
#define DAHDI_SIG_EM		(1 << 6)			/* Ear & Mouth (E&M) */
76
77
/* The following are all variations on clear channel */
78
79
#define __DAHDI_SIG_DACS	(1 << 16)
80
81
#define DAHDI_SIG_CLEAR		(1 << 7)				/* Clear channel */
82
#define DAHDI_SIG_HDLCRAW	((1 << 8)  | DAHDI_SIG_CLEAR)		/* Raw unchecked HDLC */
83
#define DAHDI_SIG_HDLCFCS	((1 << 9)  | DAHDI_SIG_HDLCRAW)		/* HDLC with FCS calculation */
84
#define DAHDI_SIG_HDLCNET	((1 << 10) | DAHDI_SIG_HDLCFCS)		/* HDLC Network */
85
#define DAHDI_SIG_SLAVE		(1 << 11) 				/* Slave to another channel */
86
#define DAHDI_SIG_SF		(1 << 14)				/* Single Freq. tone only, no sig bits */
87
#define DAHDI_SIG_CAS		(1 << 15)				/* Just get bits */
88
#define DAHDI_SIG_DACS		(__DAHDI_SIG_DACS | DAHDI_SIG_CLEAR)	/* Cross connect */
89
#define DAHDI_SIG_EM_E1		(1 << 17)				/* E1 E&M Variation */
90
#define DAHDI_SIG_DACS_RBS	((1 << 18) | __DAHDI_SIG_DACS)		/* Cross connect w/ RBS */
91
#define DAHDI_SIG_HARDHDLC	((1 << 19) | DAHDI_SIG_CLEAR)
92
#define DAHDI_SIG_MTP2		((1 << 20) | DAHDI_SIG_HDLCFCS)		/* MTP2 support  Need HDLC bitstuff and FCS calcuation too */
93
94
/* tone flag values */
95
#define DAHDI_REVERSE_RXTONE	1  /* reverse polarity rx tone logic */
96
#define DAHDI_REVERSE_TXTONE	2  /* reverse polarity tx tone logic */
97
98
#define DAHDI_ABIT		(1 << 3)
99
#define DAHDI_BBIT		(1 << 2)
100
#define DAHDI_CBIT		(1 << 1)
101
#define DAHDI_DBIT		(1 << 0)
102
103
#define DAHDI_BITS_ABCD (DAHDI_ABIT | DAHDI_BBIT | DAHDI_CBIT | DAHDI_DBIT)
104
#define DAHDI_BITS_ABD (DAHDI_ABIT | DAHDI_BBIT | DAHDI_DBIT)
105
#define DAHDI_BITS_ACD (DAHDI_ABIT | DAHDI_CBIT | DAHDI_DBIT)
106
#define DAHDI_BITS_BCD (DAHDI_BBIT | DAHDI_CBIT | DAHDI_DBIT)
107
#define DAHDI_BITS_AC (DAHDI_ABIT | DAHDI_CBIT)
108
#define DAHDI_BITS_BD (DAHDI_BBIT | DAHDI_DBIT)
109
110
#define DAHDI_MAJOR		196
111
112
#define DAHDI_MAX_BLOCKSIZE	8192
113
#define DAHDI_DEFAULT_NUM_BUFS	2
114
#define DAHDI_MAX_NUM_BUFS	32
115
#define DAHDI_MAX_BUF_SPACE	32768
116
117
#define DAHDI_DEFAULT_BLOCKSIZE 1024
118
#define DAHDI_DEFAULT_MTR_MRU	2048
119
120
/*! Define the default network block size */
121
#define DAHDI_DEFAULT_MTU_MRU	2048
122
123
#define DAHDI_POLICY_IMMEDIATE	0		/* Start play/record immediately */
124
#define DAHDI_POLICY_WHEN_FULL	1		/* Start play/record when buffer is full */
125
#define DAHDI_POLICY_HALF_FULL	2		/* Start play/record when buffer is half full.
126
						   Note -- This policy only works on tx buffers */
127
128
#define DAHDI_GET_PARAMS_RETURN_MASTER 0x40000000
129
130
#define DAHDI_TONE_ZONE_MAX		128
131
132
#define DAHDI_TONE_ZONE_DEFAULT 	-1	/* To restore default */
133
134
#define DAHDI_TONE_STOP		-1
135
#define DAHDI_TONE_DIALTONE	0
136
#define DAHDI_TONE_BUSY		1
137
#define DAHDI_TONE_RINGTONE	2
138
#define DAHDI_TONE_CONGESTION	3
139
#define DAHDI_TONE_CALLWAIT	4
140
#define DAHDI_TONE_DIALRECALL	5
141
#define DAHDI_TONE_RECORDTONE	6
142
#define DAHDI_TONE_INFO		7
143
#define DAHDI_TONE_CUST1		8
144
#define DAHDI_TONE_CUST2		9
145
#define DAHDI_TONE_STUTTER		10
146
#define DAHDI_TONE_MAX		16
147
148
#define DAHDI_TONE_DTMF_BASE	64
149
#define DAHDI_TONE_MFR1_BASE	80
150
#define DAHDI_TONE_MFR2_FWD_BASE	96
151
#define DAHDI_TONE_MFR2_REV_BASE	112
152
153
enum {
154
	DAHDI_TONE_DTMF_0 = DAHDI_TONE_DTMF_BASE,
155
	DAHDI_TONE_DTMF_1,
156
	DAHDI_TONE_DTMF_2,
157
	DAHDI_TONE_DTMF_3,
158
	DAHDI_TONE_DTMF_4,
159
	DAHDI_TONE_DTMF_5,
160
	DAHDI_TONE_DTMF_6,
161
	DAHDI_TONE_DTMF_7,
162
	DAHDI_TONE_DTMF_8,
163
	DAHDI_TONE_DTMF_9,
164
	DAHDI_TONE_DTMF_s,
165
	DAHDI_TONE_DTMF_p,
166
	DAHDI_TONE_DTMF_A,
167
	DAHDI_TONE_DTMF_B,
168
	DAHDI_TONE_DTMF_C,
169
	DAHDI_TONE_DTMF_D
170
};
171
172
#define DAHDI_TONE_DTMF_MAX DAHDI_TONE_DTMF_D
173
174
enum {
175
	DAHDI_TONE_MFR1_0 = DAHDI_TONE_MFR1_BASE,
176
	DAHDI_TONE_MFR1_1,
177
	DAHDI_TONE_MFR1_2,
178
	DAHDI_TONE_MFR1_3,
179
	DAHDI_TONE_MFR1_4,
180
	DAHDI_TONE_MFR1_5,
181
	DAHDI_TONE_MFR1_6,
182
	DAHDI_TONE_MFR1_7,
183
	DAHDI_TONE_MFR1_8,
184
	DAHDI_TONE_MFR1_9,
185
	DAHDI_TONE_MFR1_KP,
186
	DAHDI_TONE_MFR1_ST,
187
	DAHDI_TONE_MFR1_STP,
188
	DAHDI_TONE_MFR1_ST2P,
189
	DAHDI_TONE_MFR1_ST3P,
190
};
191
192
#define DAHDI_TONE_MFR1_MAX DAHDI_TONE_MFR1_ST3P
193
194
enum {
195
	DAHDI_TONE_MFR2_FWD_1 = DAHDI_TONE_MFR2_FWD_BASE,
196
	DAHDI_TONE_MFR2_FWD_2,
197
	DAHDI_TONE_MFR2_FWD_3,
198
	DAHDI_TONE_MFR2_FWD_4,
199
	DAHDI_TONE_MFR2_FWD_5,
200
	DAHDI_TONE_MFR2_FWD_6,
201
	DAHDI_TONE_MFR2_FWD_7,
202
	DAHDI_TONE_MFR2_FWD_8,
203
	DAHDI_TONE_MFR2_FWD_9,
204
	DAHDI_TONE_MFR2_FWD_10,
205
	DAHDI_TONE_MFR2_FWD_11,
206
	DAHDI_TONE_MFR2_FWD_12,
207
	DAHDI_TONE_MFR2_FWD_13,
208
	DAHDI_TONE_MFR2_FWD_14,
209
	DAHDI_TONE_MFR2_FWD_15,
210
};
211
212
#define DAHDI_TONE_MFR2_FWD_MAX DAHDI_TONE_MFR2_FWD_15
213
214
enum {
215
	DAHDI_TONE_MFR2_REV_1 = DAHDI_TONE_MFR2_REV_BASE,
216
	DAHDI_TONE_MFR2_REV_2,
217
	DAHDI_TONE_MFR2_REV_3,
218
	DAHDI_TONE_MFR2_REV_4,
219
	DAHDI_TONE_MFR2_REV_5,
220
	DAHDI_TONE_MFR2_REV_6,
221
	DAHDI_TONE_MFR2_REV_7,
222
	DAHDI_TONE_MFR2_REV_8,
223
	DAHDI_TONE_MFR2_REV_9,
224
	DAHDI_TONE_MFR2_REV_10,
225
	DAHDI_TONE_MFR2_REV_11,
226
	DAHDI_TONE_MFR2_REV_12,
227
	DAHDI_TONE_MFR2_REV_13,
228
	DAHDI_TONE_MFR2_REV_14,
229
	DAHDI_TONE_MFR2_REV_15,
230
};
231
232
#define DAHDI_TONE_MFR2_REV_MAX DAHDI_TONE_MFR2_REV_15
233
234
#define DAHDI_LAW_DEFAULT	0	/* Default law for span */
235
#define DAHDI_LAW_MULAW		1	/* Mu-law */
236
#define DAHDI_LAW_ALAW		2	/* A-law */
237
238
#define DAHDI_DIAL_OP_APPEND	1
239
#define DAHDI_DIAL_OP_REPLACE	2
240
#define DAHDI_DIAL_OP_CANCEL	3
241
242
#define DAHDI_MAX_CADENCE		16
243
244
#define DAHDI_TONEDETECT_ON	(1 << 0)		/* Detect tones */
245
#define DAHDI_TONEDETECT_MUTE	(1 << 1)		/* Mute audio in received channel */
246
247
/* Define the max # of outgoing DTMF, MFR1 or MFR2 digits to queue */
248
#define DAHDI_MAX_DTMF_BUF 256
249
250
#define DAHDI_MAX_EVENTSIZE	64	/* 64 events max in buffer */
251
252
/* Value for DAHDI_HOOK, set to ON hook */
253
#define DAHDI_ONHOOK	0
254
255
/* Value for DAHDI_HOOK, set to OFF hook */
256
#define DAHDI_OFFHOOK	1
257
258
/* Value for DAHDI_HOOK, wink (off hook momentarily) */
259
#define DAHDI_WINK		2
260
261
/* Value for DAHDI_HOOK, flash (on hook momentarily) */
262
#define DAHDI_FLASH	3
263
264
/* Value for DAHDI_HOOK, start line */
265
#define DAHDI_START	4
266
267
/* Value for DAHDI_HOOK, ring line (same as start line) */
268
#define DAHDI_RING		5
269
270
/* Value for DAHDI_HOOK, turn ringer off */
271
#define DAHDI_RINGOFF  6
272
273
/* Flush and stop the read (input) process */
274
#define DAHDI_FLUSH_READ		1
275
276
/* Flush and stop the write (output) process */
277
#define DAHDI_FLUSH_WRITE		2
278
279
/* Flush and stop both (input and output) processes */
280
#define DAHDI_FLUSH_BOTH		(DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE)
281
282
/* Flush the event queue */
283
#define DAHDI_FLUSH_EVENT		4
284
285
/* Flush everything */
286
#define DAHDI_FLUSH_ALL			(DAHDI_FLUSH_BOTH | DAHDI_FLUSH_EVENT)
287
288
#define DAHDI_MAX_SPANS			128	/* Max, 128 spans */
289
#define DAHDI_MAX_CHANNELS		1024	/* Max, 1024 channels */
290
#define DAHDI_MAX_CONF			1024	/* Max, 1024 conferences */
291
292
/* Conference modes */
293
#define DAHDI_CONF_MODE_MASK		0xFF		/* mask for modes */
294
#define DAHDI_CONF_NORMAL		0		/* normal mode */
295
#define DAHDI_CONF_MONITOR		1		/* monitor mode (rx of other chan) */
296
#define DAHDI_CONF_MONITORTX		2		/* monitor mode (tx of other chan) */
297
#define DAHDI_CONF_MONITORBOTH		3		/* monitor mode (rx & tx of other chan) */
298
#define DAHDI_CONF_CONF			4		/* conference mode */
299
#define DAHDI_CONF_CONFANN		5		/* conference announce mode */
300
#define DAHDI_CONF_CONFMON		6		/* conference monitor mode */
301
#define DAHDI_CONF_CONFANNMON		7		/* conference announce/monitor mode */
302
#define DAHDI_CONF_REALANDPSEUDO	8		/* real and pseudo port both on conf */
303
#define DAHDI_CONF_DIGITALMON		9		/* Do not decode or interpret */
304
#define DAHDI_CONF_MONITOR_RX_PREECHO	10		/* monitor mode (rx of other chan) - before echo can is done */
305
#define DAHDI_CONF_MONITOR_TX_PREECHO	11		/* monitor mode (tx of other chan) - before echo can is done */
306
#define DAHDI_CONF_MONITORBOTH_PREECHO	12		/* monitor mode (rx & tx of other chan) - before echo can is done */
307
#define DAHDI_CONF_FLAG_MASK		0xFF00		/* mask for flags */
308
#define DAHDI_CONF_LISTENER		0x100		/* is a listener on the conference */
309
#define DAHDI_CONF_TALKER		0x200		/* is a talker on the conference */
310
#define DAHDI_CONF_PSEUDO_LISTENER	0x400		/* pseudo is a listener on the conference */
311
#define DAHDI_CONF_PSEUDO_TALKER	0x800		/* pseudo is a talker on the conference */
312
313
/* Alarm Condition bits */
314
#define DAHDI_ALARM_NONE		0	/* No alarms */
315
#define DAHDI_ALARM_RECOVER		1	/* Recovering from alarm */
316
#define DAHDI_ALARM_LOOPBACK		2	/* In loopback */
317
#define DAHDI_ALARM_YELLOW		4	/* Yellow Alarm */
318
#define DAHDI_ALARM_RED			8	/* Red Alarm */
319
#define DAHDI_ALARM_BLUE		16	/* Blue Alarm */
320
#define DAHDI_ALARM_NOTOPEN		32
321
322
/* Maintenance modes */
323
#define DAHDI_MAINT_NONE		0	/* Normal Mode */
324
#define DAHDI_MAINT_LOCALLOOP		1	/* Local Loopback */
325
#define DAHDI_MAINT_REMOTELOOP		2	/* Remote Loopback */
326
#define DAHDI_MAINT_LOOPUP		3	/* send loopup code */
327
#define DAHDI_MAINT_LOOPDOWN		4	/* send loopdown code */
328
#define DAHDI_MAINT_LOOPSTOP		5	/* stop sending loop codes */
329
330
/* Flag Value for IOMUX, read avail */
331
#define DAHDI_IOMUX_READ	1
332
333
/* Flag Value for IOMUX, write avail */
334
#define DAHDI_IOMUX_WRITE	2
335
336
/* Flag Value for IOMUX, write done */
337
#define DAHDI_IOMUX_WRITEEMPTY	4
338
339
/* Flag Value for IOMUX, signalling event avail */
340
#define DAHDI_IOMUX_SIGEVENT	8
341
342
/* Flag Value for IOMUX, Do Not Wait if nothing to report */
343
#define DAHDI_IOMUX_NOWAIT	0x100
344
345
/* Ret. Value for GET/WAIT Event, no event */
346
#define DAHDI_EVENT_NONE		0
347
348
/* Ret. Value for GET/WAIT Event, Went Onhook */
349
#define DAHDI_EVENT_ONHOOK		1
350
351
/* Ret. Value for GET/WAIT Event, Went Offhook or got Ring */
352
#define DAHDI_EVENT_RINGOFFHOOK		2
353
354
/* Ret. Value for GET/WAIT Event, Got Wink or Flash */
355
#define DAHDI_EVENT_WINKFLASH		3
356
357
/* Ret. Value for GET/WAIT Event, Got Alarm */
358
#define DAHDI_EVENT_ALARM		4
359
360
/* Ret. Value for GET/WAIT Event, Got No Alarm (after alarm) */
361
#define DAHDI_EVENT_NOALARM		5
362
363
/* Ret. Value for GET/WAIT Event, HDLC Abort frame */
364
#define DAHDI_EVENT_ABORT		6
365
366
/* Ret. Value for GET/WAIT Event, HDLC Frame overrun */
367
#define DAHDI_EVENT_OVERRUN		7
368
369
/* Ret. Value for GET/WAIT Event, Bad FCS */
370
#define DAHDI_EVENT_BADFCS		8
371
372
/* Ret. Value for dial complete */
373
#define DAHDI_EVENT_DIALCOMPLETE	9
374
375
/* Ret Value for ringer going on */
376
#define DAHDI_EVENT_RINGERON		10
377
378
/* Ret Value for ringer going off */
379
#define DAHDI_EVENT_RINGEROFF		11
380
381
/* Ret Value for hook change complete */
382
#define DAHDI_EVENT_HOOKCOMPLETE	12
383
384
/* Ret Value for bits changing on a CAS / User channel */
385
#define DAHDI_EVENT_BITSCHANGED		13
386
387
/* Ret value for the beginning of a pulse coming on its way */
388
#define DAHDI_EVENT_PULSE_START		14
389
390
/* Timer event -- timer expired */
391
#define DAHDI_EVENT_TIMER_EXPIRED	15
392
393
/* Timer event -- ping ready */
394
#define DAHDI_EVENT_TIMER_PING		16
395
396
/* Polarity reversal event */
397
#define DAHDI_EVENT_POLARITY		17
398
399
/* Ring Begin event */
400
#define DAHDI_EVENT_RINGBEGIN		18
401
402
/* Echo can disabled event */
403
#define DAHDI_EVENT_EC_DISABLED		19
404
405
/* Channel was disconnected. Hint user to close channel */
406
#define DAHDI_EVENT_REMOVED		20
407
408
/* A neon MWI pulse was detected */
409
#define DAHDI_EVENT_NEONMWI_ACTIVE	21
410
411
/* No neon MWI pulses were detected over some period of time */
412
#define DAHDI_EVENT_NEONMWI_INACTIVE	22
413
414
/* A CED tone was detected on the channel in the transmit direction */
415
#define DAHDI_EVENT_TX_CED_DETECTED	23
416
417
/* A CED tone was detected on the channel in the receive direction */
418
#define DAHDI_EVENT_RX_CED_DETECTED	24
419
420
/* A CNG tone was detected on the channel in the transmit direction */
421
#define DAHDI_EVENT_TX_CNG_DETECTED	25
422
423
/* A CNG tone was detected on the channel in the receive direction */
424
#define DAHDI_EVENT_RX_CNG_DETECTED	26
425
426
/* The echo canceler's NLP (only) was disabled */
427
#define DAHDI_EVENT_EC_NLP_DISABLED	27
428
429
/* The echo canceler's NLP (only) was enabled */
430
#define DAHDI_EVENT_EC_NLP_ENABLED	28
431
432
#define DAHDI_EVENT_PULSEDIGIT		(1 << 16)	/* This is OR'd with the digit received */
433
#define DAHDI_EVENT_DTMFDOWN		(1 << 17)	/* Ditto for DTMF key down event */
434
#define DAHDI_EVENT_DTMFUP		(1 << 18)	/* Ditto for DTMF key up event */
435
436
/* Transcoder related definitions */
437
438
struct dahdi_transcoder_formats {
439
	__u32	srcfmt;
440
	__u32	dstfmt;
441
};
442
struct dahdi_transcoder_info {
443
	__u32 tcnum;
444
	char name[80];
445
	__u32 numchannels;
446
	__u32 dstfmts;
447
	__u32 srcfmts;
448
};
449
450
#define DAHDI_MAX_ECHOCANPARAMS 8
451
452
/* ioctl definitions */
453
#define DAHDI_CODE		0xDA
454
455
/*
456
 * Get/Set Transfer Block Size.
457
 */
458
#define DAHDI_GET_BLOCKSIZE		_IOR(DAHDI_CODE, 1, int)
459
#define DAHDI_SET_BLOCKSIZE		_IOW(DAHDI_CODE, 1, int)
460
461
/*
462
 * Flush Buffer(s) and stop I/O
463
 */
464
#define DAHDI_FLUSH			_IOW(DAHDI_CODE, 3, int)
465
466
/*
467
 * Wait for Write to Finish
468
 */
469
#define DAHDI_SYNC			_IO(DAHDI_CODE, 4)
470
471
/*
472
 * Get/set channel parameters
473
 */
474
475
struct dahdi_params {
476
	int channo;		/* Channel number */
477
	int spanno;		/* Span itself */
478
	int chanpos;		/* Channel number in span */
479
	int sigtype;		/* read-only */
480
	int sigcap;		/* read-only */
481
	int rxisoffhook;	/* read-only */
482
	int rxbits;		/* read-only */
483
	int txbits;		/* read-only */
484
	int txhooksig;		/* read-only */
485
	int rxhooksig;		/* read-only */
486
	int curlaw;		/* read-only  -- one of DAHDI_LAW_MULAW or DAHDI_LAW_ALAW */
487
	int idlebits;		/* read-only  -- What is considered the idle state */
488
	char name[40];		/* Name of channel */
489
	int prewinktime;
490
	int preflashtime;
491
	int winktime;
492
	int flashtime;
493
	int starttime;
494
	int rxwinktime;
495
	int rxflashtime;
496
	int debouncetime;
497
	int pulsebreaktime;
498
	int pulsemaketime;
499
	int pulseaftertime;
500
	__u32 chan_alarms;	/* alarms on this channel */
501
};
502
503
#define DAHDI_GET_PARAMS_V1		_IOR(DAHDI_CODE,  5, struct dahdi_params)
504
#define DAHDI_GET_PARAMS		_IOWR(DAHDI_CODE, 5, struct dahdi_params)
505
#define DAHDI_SET_PARAMS		_IOW(DAHDI_CODE,  5, struct dahdi_params)
506
507
/*
508
 * Set Hookswitch Status
509
 */
510
#define DAHDI_HOOK			_IOW(DAHDI_CODE, 7, int)
511
512
/*
513
 * Get Signalling Event
514
 */
515
#define DAHDI_GETEVENT			_IOR(DAHDI_CODE, 8, int)
516
517
/*
518
 * Wait for something to happen (IO Mux)
519
 */
520
#define DAHDI_IOMUX			_IOWR(DAHDI_CODE, 9, int)
521
522
/*
523
 * Get Span Status
524
 */
525
struct dahdi_spaninfo {
526
	int	spanno;		/* span number */
527
	char	name[20];	/* Name */
528
	char	desc[40];	/* Description */
529
	int	alarms;		/* alarms status */
530
	int	txlevel;	/* what TX level is set to */
531
	int	rxlevel;	/* current RX level */
532
	int	bpvcount;	/* current BPV count */
533
	int	crc4count;	/* current CRC4 error count */
534
	int	ebitcount;	/* current E-bit error count */
535
	int	fascount;	/* current FAS error count */
536
	int	irqmisses;	/* current IRQ misses */
537
	int	syncsrc;	/* span # of current sync source, or 0 for free run  */
538
	int	numchans;	/* number of configured channels on this span */
539
	int	totalchans;	/* total number of channels on the span */
540
	int	totalspans;	/* total number of spans in entire system */
541
	int	lbo;		/* line build out */
542
	int	lineconfig;	/* framing/coding */
543
	char 	lboname[40];	/* line build out in text form */
544
	char	location[40];	/* span's device location in system */
545
	char	manufacturer[40]; /* manufacturer of span's device */
546
	char	devicetype[40];	/* span's device type */
547
	int	irq;		/* span's device IRQ */
548
	int	linecompat;	/* signaling modes possible on this span */
549
	char	spantype[6];	/* type of span in text form */
550
};
551
552
#define DAHDI_SPANSTAT			_IOWR(DAHDI_CODE, 10, struct dahdi_spaninfo)
553
554
/*
555
 * Set Maintenance Mode
556
 */
557
struct dahdi_maintinfo {
558
	int	spanno;		/* span number 1-2 */
559
	int	command;	/* command */
560
};
561
562
#define DAHDI_MAINT			_IOW(DAHDI_CODE, 11, struct dahdi_maintinfo)
563
564
/*
565
 * Get/Set Conference Mode
566
 */
567
struct dahdi_confinfo {
568
	int	chan;		/* channel number, 0 for current */
569
	int	confno;		/* conference number */
570
	int	confmode;	/* conferencing mode */
571
};
572
573
#define DAHDI_GETCONF_V1		_IOR(DAHDI_CODE,   12, struct dahdi_confinfo)
574
#define DAHDI_GETCONF			_IOWR(DAHDI_CODE,  12, struct dahdi_confinfo)
575
576
#define DAHDI_SETCONF_V1		_IOW(DAHDI_CODE,  12, struct dahdi_confinfo)
577
#define DAHDI_SETCONF			_IOWR(DAHDI_CODE, 13, struct dahdi_confinfo)
578
579
/*
580
 * Setup or Remove Conference Link
581
 */
582
#define DAHDI_CONFLINK			_IOW(DAHDI_CODE, 14, struct dahdi_confinfo)
583
584
/*
585
 * Display Conference Diagnostic Information on Console
586
 */
587
#define DAHDI_CONFDIAG_V1		_IOR(DAHDI_CODE, 15, int)
588
#define DAHDI_CONFDIAG			_IOW(DAHDI_CODE, 15, int)
589
590
/*
591
 * Get/Set Channel audio gains
592
 */
593
struct dahdi_gains {
594
	int	chan;			/* channel number, 0 for current */
595
	unsigned char rxgain[256];	/* Receive gain table */
596
	unsigned char txgain[256];	/* Transmit gain table */
597
};
598
599
#define DAHDI_GETGAINS_V1		_IOR(DAHDI_CODE,  16, struct dahdi_gains)
600
#define DAHDI_GETGAINS			_IOWR(DAHDI_CODE, 16, struct dahdi_gains)
601
#define DAHDI_SETGAINS			_IOW(DAHDI_CODE,  16, struct dahdi_gains)
602
603
/*
604
 * Set Line (T1) Configurations
605
 */
606
struct dahdi_lineconfig {
607
	int span;		/* Which span number (0 to use name) */
608
	char name[20];		/* Name of span to use */
609
	int	lbo;		/* line build-outs */
610
	int	lineconfig;	/* line config parameters (framing, coding) */
611
	int	sync;		/* what level of sync source we are */
612
};
613
614
#define DAHDI_SPANCONFIG		_IOW(DAHDI_CODE, 18, struct dahdi_lineconfig)
615
616
/*
617
 * Set Channel Configuration
618
 */
619
struct dahdi_chanconfig {
620
	int	chan;		/* Channel we're applying this to (0 to use name) */
621
	char	name[40];	/* Name of channel to use */
622
	int	sigtype;	/* Signal type */
623
	int	deflaw;		/* Default law (DAHDI_LAW_DEFAULT, DAHDI_LAW_MULAW, or DAHDI_LAW_ALAW) */
624
	int	master;		/* Master channel if sigtype is DAHDI_SLAVE */
625
	int	idlebits;	/* Idle bits (if this is a CAS channel) or
626
				   channel to monitor (if this is DACS channel) */
627
	char	netdev_name[16];/* name for the hdlc network device*/
628
};
629
630
#define DAHDI_CHANCONFIG		_IOW(DAHDI_CODE, 19, struct dahdi_chanconfig)
631
632
/*
633
 * Set Conference to mute mode
634
 */
635
#define DAHDI_CONFMUTE			_IOW(DAHDI_CODE, 20, int)
636
637
/*
638
 * Send a particular tone (see DAHDI_TONE_*)
639
 */
640
#define DAHDI_SENDTONE			_IOW(DAHDI_CODE, 21, int)
641
642
/*
643
 * Get/Set your region for tones
644
 */
645
#define DAHDI_GETTONEZONE		_IOR(DAHDI_CODE, 22, int)
646
#define DAHDI_SETTONEZONE		_IOW(DAHDI_CODE, 22, int)
647
648
/*
649
 * Master unit only -- set default zone (see DAHDI_TONE_ZONE_*)
650
 */
651
#define DAHDI_DEFAULTZONE		_IOW(DAHDI_CODE, 24, int)
652
653
/*
654
 * Load a tone zone from a dahdi_tone_def_header
655
 */
656
struct dahdi_tone_def {
657
	int tone;		/* See DAHDI_TONE_* */
658
	int next;		/* What the next position in the cadence is
659
				   (They're numbered by the order the appear here) */
660
	int samples;		/* How many samples to play for this cadence */
661
	int shift;		/* How much to scale down the volume (2 is nice) */
662
663
	/* Now come the constants we need to make tones */
664
665
	/* 
666
		Calculate the next 6 factors using the following equations:
667
		l = <level in dbm>, f1 = <freq1>, f2 = <freq2>
668
		gain = pow(10.0, (l - 3.14) / 20.0) * 65536.0 / 2.0;
669
670
		// Frequency factor 1 
671
		fac_1 = 2.0 * cos(2.0 * M_PI * (f1/8000.0)) * 32768.0;
672
		// Last previous two samples 
673
		init_v2_1 = sin(-4.0 * M_PI * (f1/8000.0)) * gain;
674
		init_v3_1 = sin(-2.0 * M_PI * (f1/8000.0)) * gain;
675
676
		// Frequency factor 2 
677
		fac_2 = 2.0 * cos(2.0 * M_PI * (f2/8000.0)) * 32768.0;
678
		// Last previous two samples 
679
		init_v2_2 = sin(-4.0 * M_PI * (f2/8000.0)) * gain;
680
		init_v3_2 = sin(-2.0 * M_PI * (f2/8000.0)) * gain;
681
	*/
682
	int fac1;		
683
	int init_v2_1;		
684
	int init_v3_1;		
685
	int fac2;		
686
	int init_v2_2;		
687
	int init_v3_2;
688
	int modulate;
689
};
690
691
struct dahdi_tone_def_header {
692
	int count;				/* How many samples follow */
693
	int zone;				/* Which zone we are loading */
694
	int ringcadence[DAHDI_MAX_CADENCE];	/* Ring cadence in ms (0=on, 1=off, ends with 0 value) */
695
	char name[40];				/* Informational name of zone */
696
	/* immediately follow this structure with dahdi_tone_def structures */
697
	struct dahdi_tone_def tones[0];
698
};
699
700
#define DAHDI_LOADZONE			_IOW(DAHDI_CODE, 25, struct dahdi_tone_def_header)
701
702
/*
703
 * Free a tone zone 
704
 */
705
#define DAHDI_FREEZONE			_IOW(DAHDI_CODE, 26, int)
706
707
/*
708
 * Get/Set buffer policy 
709
 */
710
struct dahdi_bufferinfo {
711
	int txbufpolicy;	/* Policy for handling receive buffers */
712
	int rxbufpolicy;	/* Policy for handling receive buffers */
713
	int numbufs;		/* How many buffers to use */
714
	int bufsize;		/* How big each buffer is */
715
	int readbufs;		/* How many read buffers are full (read-only) */
716
	int writebufs;		/* How many write buffers are full (read-only) */
717
};
718
719
#define DAHDI_GET_BUFINFO		_IOR(DAHDI_CODE, 27, struct dahdi_bufferinfo)
720
#define DAHDI_SET_BUFINFO		_IOW(DAHDI_CODE, 27, struct dahdi_bufferinfo)
721
722
/*
723
 * Get/Set dialing parameters
724
 */
725
struct dahdi_dialparams {
726
	int mfv1_tonelen;	/* MF R1 tone length for digits */
727
	int dtmf_tonelen;	/* DTMF tone length */
728
	int mfr2_tonelen;	/* MF R2 tone length */
729
	int reserved[3];	/* Reserved for future expansion -- always set to 0 */
730
};
731
732
#define DAHDI_GET_DIALPARAMS		_IOR(DAHDI_CODE, 29, struct dahdi_dialparams)
733
#define DAHDI_SET_DIALPARAMS		_IOW(DAHDI_CODE, 29, struct dahdi_dialparams)
734
735
/*
736
 * Append, replace, or cancel a dial string
737
 */
738
struct dahdi_dialoperation {
739
	int op;
740
	char dialstr[DAHDI_MAX_DTMF_BUF];
741
};
742
743
#define DAHDI_DIAL			_IOW(DAHDI_CODE, 31, struct dahdi_dialoperation)
744
745
/*
746
 * Set a clear channel into audio mode
747
 */
748
#define DAHDI_AUDIOMODE			_IOW(DAHDI_CODE, 32, int)
749
750
/*
751
 * Enable or disable echo cancellation on a channel 
752
 *
753
 * For ECHOCANCEL:
754
 * The number is zero to disable echo cancellation and non-zero
755
 * to enable echo cancellation.  If the number is between 32
756
 * and 1024, it will also set the number of taps in the echo canceller
757
 *
758
 * For ECHOCANCEL_PARAMS:
759
 * The structure contains parameters that should be passed to the
760
 * echo canceler instance for the selected channel.
761
 */
762
#define DAHDI_ECHOCANCEL		_IOW(DAHDI_CODE, 33, int)
763
764
struct dahdi_echocanparam {
765
	char name[16];
766
	__s32 value;
767
};
768
769
struct dahdi_echocanparams {
770
	/* 8 taps per millisecond */
771
	__u32 tap_length;
772
	/* number of parameters supplied */
773
	__u32 param_count;
774
	/* immediately follow this structure with dahdi_echocanparam structures */
775
	struct dahdi_echocanparam params[0];
776
};
777
778
#define DAHDI_ECHOCANCEL_PARAMS		_IOW(DAHDI_CODE, 33, struct dahdi_echocanparams)
779
780
/*
781
 * Return a channel's channel number
782
 */
783
#define DAHDI_CHANNO			_IOR(DAHDI_CODE, 34, int)
784
785
/*
786
 * Return a flag indicating whether channel is currently dialing
787
 */
788
#define DAHDI_DIALING			_IOR(DAHDI_CODE, 35, int)
789
790
/*
791
 * Set a clear channel into HDLC w/out FCS checking/calculation mode
792
 */
793
#define DAHDI_HDLCRAWMODE		_IOW(DAHDI_CODE, 36, int)
794
795
/*
796
 * Set a clear channel into HDLC w/ FCS mode
797
 */
798
#define DAHDI_HDLCFCSMODE		_IOW(DAHDI_CODE, 37, int)
799
800
/* 
801
 * Specify a channel on generic channel selector - must be done before
802
 * performing any other ioctls
803
 */
804
#define DAHDI_SPECIFY			_IOW(DAHDI_CODE, 38, int)
805
806
/*
807
 * Temporarily set the law on a channel to 
808
 * DAHDI_LAW_DEFAULT, DAHDI_LAW_ALAW, or DAHDI_LAW_MULAW.  Is reset on close.  
809
 */
810
#define DAHDI_SETLAW			_IOW(DAHDI_CODE, 39, int)
811
812
/*
813
 * Temporarily set the channel to operate in linear mode when non-zero
814
 * or default law if 0
815
 */
816
#define DAHDI_SETLINEAR			_IOW(DAHDI_CODE, 40, int)
817
818
/*
819
 * Set a clear channel into HDLC w/ PPP interface mode
820
 */
821
#define DAHDI_HDLCPPP			_IOW(DAHDI_CODE, 41, int)
822
823
/*
824
 * Set the ring cadence for FXS interfaces
825
 */
826
struct dahdi_ring_cadence {
827
	int ringcadence[DAHDI_MAX_CADENCE];
828
};
829
830
#define DAHDI_SETCADENCE		_IOW(DAHDI_CODE, 42, struct dahdi_ring_cadence)
831
832
/*
833
 * Get/Set the signaling bits for CAS interface
834
 */
835
#define DAHDI_GETRXBITS 		_IOR(DAHDI_CODE, 43, int)
836
#define DAHDI_SETTXBITS			_IOW(DAHDI_CODE, 43, int)
837
838
/*
839
 * Display Channel Diagnostic Information on Console
840
 */
841
#define DAHDI_CHANDIAG_V1		_IOR(DAHDI_CODE, 44, int)
842
#define DAHDI_CHANDIAG			_IOW(DAHDI_CODE, 44, int)
843
844
/*
845
 * Set Channel's SF Tone Configuration
846
 */
847
struct dahdi_sfconfig {
848
	int	chan;		/* Channel we're applying this to (0 to use name) */
849
	char	name[40];	/* Name of channel to use */
850
	long	rxp1;		/* receive tone det. p1 */
851
	long	rxp2;		/* receive tone det. p2 */
852
	long	rxp3;		/* receive tone det. p3 */
853
	int	txtone;		/* Tx tone factor */
854
	int	tx_v2;		/* initial v2 value */
855
	int	tx_v3;		/* initial v3 value */
856
	int	toneflag;	/* Tone flags */
857
};
858
859
#define DAHDI_SFCONFIG			_IOW(DAHDI_CODE, 46, struct dahdi_sfconfig)
860
861
/*
862
 * Set timer expiration (in samples)
863
 */
864
#define DAHDI_TIMERCONFIG		_IOW(DAHDI_CODE, 47, int)
865
866
/*
867
 * Acknowledge timer expiration (number to acknowledge, or -1 for all)
868
 */
869
#define DAHDI_TIMERACK 			_IOW(DAHDI_CODE, 48, int)
870
871
/*
872
 * Get Conference to mute mode
873
 */
874
#define DAHDI_GETCONFMUTE		_IOR(DAHDI_CODE, 49, int)
875
876
/*
877
 * Request echo training in some number of ms (with muting in the mean time)
878
 */
879
#define DAHDI_ECHOTRAIN			_IOW(DAHDI_CODE, 50, int)
880
881
/*
882
 * Set on hook transfer for n number of ms -- implemnted by low level driver
883
 */
884
#define DAHDI_ONHOOKTRANSFER		_IOW(DAHDI_CODE, 51, int)
885
886
/*
887
 * Queue Ping
888
 */
889
#define DAHDI_TIMERPING 		_IO(DAHDI_CODE, 52)
890
891
/*
892
 * Acknowledge ping
893
 */
894
#define DAHDI_TIMERPONG 		_IO(DAHDI_CODE, 53)
895
896
/*
897
 * Get/set signalling freeze
898
 */
899
#define DAHDI_GETSIGFREEZE 		_IOR(DAHDI_CODE, 54, int)
900
#define DAHDI_SETSIGFREEZE 		_IOW(DAHDI_CODE, 54, int)
901
902
/*
903
 * Perform an indirect ioctl (on a specified channel via master interface)
904
 */
905
struct dahdi_indirect_data {
906
	int	chan;
907
	int	op;
908
	void	*data;
909
};
910
911
#define DAHDI_INDIRECT 			_IOWR(DAHDI_CODE, 56, struct dahdi_indirect_data)
912
913
914
/*
915
 * Get the version of DAHDI that is running, and a description
916
 * of the compiled-in echo cancellers (if any)
917
 */
918
struct dahdi_versioninfo {
919
	char version[80];
920
	char echo_canceller[80];
921
};
922
923
#define DAHDI_GETVERSION		_IOR(DAHDI_CODE, 57, struct dahdi_versioninfo)
924
925
/*
926
 * Put the channel in loopback mode (receive from the channel is
927
 * transmitted back on the interface)
928
 */
929
#define DAHDI_LOOPBACK 			_IOW(DAHDI_CODE, 58, int)
930
931
/*
932
  Attach the desired echo canceler module (or none) to a channel in an
933
  audio-supporting mode, so that when the channel needs an echo canceler
934
  that module will be used to supply one.
935
 */
936
struct dahdi_attach_echocan {
937
	int	chan;		/* Channel we're applying this to */
938
	char	echocan[16];	/* Name of echo canceler to attach to this channel
939
				   (leave empty to have no echocan attached */
940
};
941
942
#define DAHDI_ATTACH_ECHOCAN 		_IOW(DAHDI_CODE, 59, struct dahdi_attach_echocan)
943
944
945
/*
946
 *  60-80 are reserved for private drivers
947
 *  80-85 are reserved for dynamic span stuff
948
 */
949
950
/*
951
 * Create a dynamic span
952
 */
953
struct dahdi_dynamic_span {
954
	char driver[20];	/* Which low-level driver to use */
955
	char addr[40];		/* Destination address */
956
	int numchans;		/* Number of channels */
957
	int timing;		/* Timing source preference */
958
	int spanno;		/* Span number (filled in by DAHDI) */
959
};
960
961
#define DAHDI_DYNAMIC_CREATE		_IOWR(DAHDI_CODE, 80, struct dahdi_dynamic_span)
962
963
/* 
964
 * Destroy a dynamic span 
965
 */
966
#define DAHDI_DYNAMIC_DESTROY		_IOW(DAHDI_CODE, 81, struct dahdi_dynamic_span)
967
968
/*
969
 * Set the HW gain for a device
970
 */
971
struct dahdi_hwgain {
972
	__s32 newgain;	/* desired gain in dB but x10.  -3.5dB would be -35 */
973
	__u32 tx:1;	/* 0=rx; 1=tx */
974
};
975
#define DAHDI_SET_HWGAIN		_IOW(DAHDI_CODE, 86, struct dahdi_hwgain)
976
977
/*
978
 * Enable tone detection -- implemented by low level driver
979
 */
980
#define DAHDI_TONEDETECT		_IOW(DAHDI_CODE, 91, int)
981
982
/*
983
 * Set polarity -- implemented by individual driver.  0 = forward, 1 = reverse
984
 */
985
#define DAHDI_SETPOLARITY		_IOW(DAHDI_CODE, 92, int)
986
987
/*
988
 * Transcoder operations
989
 */
990
991
/* DAHDI_TRANSCODE_OP is an older interface that is deprecated and no longer
992
 * supported.
993
 */
994
#define DAHDI_TRANSCODE_OP		_IOWR(DAHDI_CODE, 93, int)
995
996
#define DAHDI_TC_CODE			'T'
997
#define DAHDI_TC_ALLOCATE		_IOW(DAHDI_TC_CODE, 1, struct dahdi_transcoder_formats)
998
#define DAHDI_TC_GETINFO		_IOWR(DAHDI_TC_CODE, 2, struct dahdi_transcoder_info)
999
1000
/*
1001
 * VMWI Specification 
1002
 */
1003
struct dahdi_vmwi_info {
1004
	unsigned int vmwi_type;
1005
};
1006
1007
#define DAHDI_VMWI_LREV	(1 << 0)	/* Line Reversal */
1008
#define DAHDI_VMWI_HVDC	(1 << 1)	/* HV 90VDC */
1009
#define DAHDI_VMWI_HVAC	(1 << 2)	/* HV 90VAC Neon lamp */
1010
1011
/*
1012
 * VoiceMail Waiting Indication (VMWI) -- implemented by low-level driver.
1013
 * Value: number of waiting messages (hence 0: switch messages off).
1014
 */
1015
#define DAHDI_VMWI			_IOWR(DAHDI_CODE, 94, int)
1016
#define DAHDI_VMWI_CONFIG		_IOW(DAHDI_CODE, 95, struct dahdi_vmwi_info)
1017
1018
/*
1019
 * Startup or Shutdown a span
1020
 */
1021
#define DAHDI_STARTUP			_IOW(DAHDI_CODE, 99, int)
1022
#define DAHDI_SHUTDOWN			_IOW(DAHDI_CODE, 100, int)
1023
1024
#define DAHDI_HDLC_RATE			_IOW(DAHDI_CODE, 101, int)
1025
1026
/* Put a channel's echo canceller into 'FAX mode' if possible */
1027
1028
#define DAHDI_ECHOCANCEL_FAX_MODE	_IOW(DAHDI_CODE, 102, int)
1029
1030
struct torisa_debug {
1031
	unsigned int txerrors;
1032
	unsigned int irqcount;
1033
	unsigned int taskletsched;
1034
	unsigned int taskletrun;
1035
	unsigned int taskletexec;
1036
	int span1flags;
1037
	int span2flags;
1038
};
1039
1040
/* Special torisa ioctl */
1041
#define TORISA_GETDEBUG			_IOW(DAHDI_CODE, 60, struct torisa_debug)
1042
1043
/* Get current status IOCTL */
1044
/* Defines for Radio Status (dahdi_radio_stat.radstat) bits */
1045
1046
#define DAHDI_RADSTAT_RX	1	/* currently "receiving " */
1047
#define DAHDI_RADSTAT_TX	2	/* currently "transmitting" */
1048
#define DAHDI_RADSTAT_RXCT	4	/* currently receiving continuous tone with 
1049
				   current settings */
1050
#define DAHDI_RADSTAT_RXCOR	8	/* currently receiving COR (irrelevant of COR
1051
				   ignore) */
1052
#define DAHDI_RADSTAT_IGNCOR	16	/* currently ignoring COR */
1053
#define DAHDI_RADSTAT_IGNCT	32	/* currently ignoring CTCSS/DCS decode */
1054
#define DAHDI_RADSTAT_NOENCODE 64	/* currently blocking CTCSS/DCS encode */
1055
1056
struct dahdi_radio_stat {
1057
	unsigned short ctcode_rx;	/* code of currently received CTCSS 
1058
					   or DCS, 0 for none */
1059
	unsigned short ctclass;		/* class of currently received CTCSS or
1060
					    DCS code */
1061
	unsigned short ctcode_tx;	/* code of currently encoded CTCSS or
1062
					   DCS, 0 for none */
1063
	unsigned char radstat;		/* status bits of radio */
1064
};
1065
1066
#define DAHDI_RADIO_GETSTAT		_IOR(DAHDI_CODE, 57, struct dahdi_radio_stat)
1067
1068
/* Get/Set a radio channel parameter */
1069
/* Defines for Radio Parameters (dahdi_radio_param.radpar) */
1070
#define DAHDI_RADPAR_INVERTCOR 1	/* invert the COR signal (0/1) */
1071
#define DAHDI_RADPAR_IGNORECOR 2	/* ignore the COR signal (0/1) */
1072
#define DAHDI_RADPAR_IGNORECT 3	/* ignore the CTCSS/DCS decode (0/1) */
1073
#define DAHDI_RADPAR_NOENCODE 4	/* block the CTCSS/DCS encode (0/1) */
1074
#define DAHDI_RADPAR_CORTHRESH 5	/* COR trigger threshold (0-7) */
1075
1076
#define DAHDI_RADPAR_EXTRXTONE 6	/* 0 means use internal decoder, 1 means UIOA
1077
				   logic true is CT decode, 2 means UIOA logic
1078
				   false is CT decode */
1079
#define DAHDI_RADPAR_NUMTONES	7	/* returns maximum tone index (curently 15) */
1080
#define DAHDI_RADPAR_INITTONE	8	/* init all tone indexes to 0 (no tones) */
1081
#define DAHDI_RADPAR_RXTONE	9	/* CTCSS tone, (1-32) or DCS tone (1-777),
1082
				   or 0 meaning no tone, set index also (1-15) */
1083
#define DAHDI_RADPAR_RXTONECLASS 10	/* Tone class (0-65535), set index also (1-15) */
1084
#define DAHDI_RADPAR_TXTONE 11	/* CTCSS tone (1-32) or DCS tone (1-777) or 0
1085
				   to indicate no tone, to transmit 
1086
				   for this tone index (0-32, 0 disables
1087
				   transmit CTCSS), set index also (0-15) */
1088
#define DAHDI_RADPAR_DEBOUNCETIME 12	/* receive indication debounce time, 
1089
				   milliseconds (1-999) */
1090
#define DAHDI_RADPAR_BURSTTIME 13	/* end of transmit with no CT tone in
1091
				   milliseconds (0-999) */
1092
1093
1094
#define DAHDI_RADPAR_UIODATA 14	/* read/write UIOA and UIOB data. Bit 0 is
1095
				   UIOA, bit 1 is UIOB */
1096
#define DAHDI_RADPAR_UIOMODE 15	/* 0 means UIOA and UIOB are both outputs, 1
1097
				   means UIOA is input, UIOB is output, 2 
1098
				   means UIOB is input and UIOA is output,
1099
				   3 means both UIOA and UIOB are inputs. Note
1100
				   mode for UIOA is overridden when in
1101
				   EXTRXTONE mode. */
1102
1103
#define DAHDI_RADPAR_REMMODE 16	/* Remote control data mode */
1104
	#define DAHDI_RADPAR_REM_NONE 0 	/* no remote control data mode */
1105
	#define DAHDI_RADPAR_REM_RBI1 1	/* Doug Hall RBI-1 data mode */
1106
	#define DAHDI_RADPAR_REM_SERIAL 2	/* Serial Data, 9600 BPS */
1107
	#define DAHDI_RADPAR_REM_SERIAL_ASCII 3	/* Serial Ascii Data, 9600 BPS */
1108
1109
#define DAHDI_RADPAR_REMCOMMAND 17	/* Remote conrtol write data block & do cmd */
1110
1111
#define DAHDI_RADPAR_DEEMP 18 /* Audio De-empahsis (on or off) */ 
1112
1113
#define DAHDI_RADPAR_PREEMP 19 /* Audio Pre-empahsis (on or off) */ 
1114
1115
#define DAHDI_RADPAR_RXGAIN 20 /* Audio (In to system) Rx Gain */ 
1116
1117
#define DAHDI_RADPAR_TXGAIN 21 /* Audio (Out from system) Tx Gain */ 
1118
1119
#define RAD_SERIAL_BUFLEN 128
1120
1121
struct dahdi_radio_param {
1122
	unsigned short radpar;	/* param identifier */
1123
	unsigned short index;	/* tone number */
1124
	int data;		/* param */
1125
	int data2;		/* param 2 */
1126
	unsigned char buf[RAD_SERIAL_BUFLEN];
1127
};
1128
#define DAHDI_RADIO_GETPARAM		_IOR(DAHDI_CODE, 58, struct dahdi_radio_param)
1129
#define DAHDI_RADIO_SETPARAM		_IOW(DAHDI_CODE, 58, struct dahdi_radio_param)
1130
1131
1132
/*!
1133
	\brief Size-limited null-terminating string copy.
1134
	\param dst The destination buffer
1135
	\param src The source string
1136
	\param size The size of the destination buffer
1137
	\return Nothing.
1138
1139
	This is similar to \a strncpy, with two important differences:
1140
	- the destination buffer will \b always be null-terminated
1141
	- the destination buffer is not filled with zeros past the copied string length
1142
	These differences make it slightly more efficient, and safer to use since it will
1143
	not leave the destination buffer unterminated. There is no need to pass an artificially
1144
	reduced buffer size to this function (unlike \a strncpy), and the buffer does not need
1145
	to be initialized to zeroes prior to calling this function.
1146
*/
1147
static inline void dahdi_copy_string(char *dst, const char *src, unsigned int size)
1148
{
1149
	while (*src && size) {
1150
		*dst++ = *src++;
1151
		size--;
1152
	}
1153
	if (__builtin_expect(!size, 0))
1154
		dst--;
1155
	*dst = '\0';
1156
}
1157
1158
#endif /* _DAHDI_USER_H */
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/version.h (+6 lines)
Line 0 Link Here
1
/*
2
 * version.h 
3
 * Automatically generated
4
 */
5
#define DAHDI_VERSION "2.2.0-rc5"
6
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/wctdm_user.h (+68 lines)
Line 0 Link Here
1
/*
2
 * Wildcard S100P FXS Interface Driver for DAHDI Telephony interface
3
 *
4
 * Written by Mark Spencer <markster@digium.com>
5
 *
6
 * Copyright (C) 2001-2008, Digium, Inc.
7
 *
8
 * All rights reserved.
9
 *
10
 */
11
12
/*
13
 * See http://www.asterisk.org for more information about
14
 * the Asterisk project. Please do not directly contact
15
 * any of the maintainers of this project for assistance;
16
 * the project provides a web site, mailing lists and IRC
17
 * channels for your use.
18
 *
19
 * This program is free software, distributed under the terms of
20
 * the GNU General Public License Version 2 as published by the
21
 * Free Software Foundation. See the LICENSE file included with
22
 * this program for more details.
23
 */
24
25
#ifndef _WCTDM_H
26
#define _WCTDM_H
27
28
#include <linux/ioctl.h>
29
30
#define NUM_REGS	  109
31
#define NUM_INDIRECT_REGS 105
32
33
struct wctdm_stats {
34
	int tipvolt;	/* TIP voltage (mV) */
35
	int ringvolt;	/* RING voltage (mV) */
36
	int batvolt;	/* VBAT voltage (mV) */
37
};
38
39
struct wctdm_regs {
40
	unsigned char direct[NUM_REGS];
41
	unsigned short indirect[NUM_INDIRECT_REGS];
42
};
43
44
struct wctdm_regop {
45
	int indirect;
46
	unsigned char reg;
47
	unsigned short val;
48
};
49
50
struct wctdm_echo_coefs {
51
	unsigned char acim;
52
	unsigned char coef1;
53
	unsigned char coef2;
54
	unsigned char coef3;
55
	unsigned char coef4;
56
	unsigned char coef5;
57
	unsigned char coef6;
58
	unsigned char coef7;
59
	unsigned char coef8;
60
};
61
62
#define WCTDM_GET_STATS	_IOR (DAHDI_CODE, 60, struct wctdm_stats)
63
#define WCTDM_GET_REGS	_IOR (DAHDI_CODE, 61, struct wctdm_regs)
64
#define WCTDM_SET_REG	_IOW (DAHDI_CODE, 62, struct wctdm_regop)
65
#define WCTDM_SET_ECHOTUNE _IOW (DAHDI_CODE, 63, struct wctdm_echo_coefs)
66
67
68
#endif /* _WCTDM_H */
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/zaphfc.c (+905 lines)
Line 0 Link Here
1
/*
2
 * zaphfc.c - Zaptel driver for HFC-S PCI A based ISDN BRI cards
3
 *
4
 * kernel module inspired by HFC PCI ISDN4Linux and Zaptel drivers
5
 *
6
 * Copyright (C) 2002, 2003, 2004, 2005 Junghanns.NET GmbH
7
 *
8
 * Klaus-Peter Junghanns <kpj@junghanns.net>
9
 *
10
 * Copyright (C) 2004, 2005, 2006  Florian Zumbiehl <florz@gmx.de>
11
 *  - support for slave mode of the HFC-S chip which allows it to
12
 *    sync its sample clock to an external source/another HFC chip
13
 *  - support for "interrupt bundling" (let only one card generate
14
 *    8 kHz timing interrupt no matter how many cards there are
15
 *    in the system)
16
 *  - interrupt loss tolerant b channel handling
17
 *
18
 * This program is free software and may be modified and
19
 * distributed under the terms of the GNU General Public License.
20
 *
21
 */
22
23
#include <linux/kernel.h>
24
#include <linux/module.h>
25
#include <linux/pci.h>
26
#include <linux/init.h>
27
#include <linux/interrupt.h>
28
#include <linux/delay.h>
29
#include "kernel.h"
30
#include "zaphfc.h"
31
32
#include <linux/moduleparam.h>
33
34
#define log2(n) ffz(~(n))
35
36
#if CONFIG_PCI
37
38
#define CLKDEL_TE	0x0f	/* CLKDEL in TE mode */
39
#define CLKDEL_NT	0x6c	/* CLKDEL in NT mode */
40
41
typedef struct {
42
        int vendor_id;
43
        int device_id;
44
        char *vendor_name;
45
        char *card_name;
46
} PCI_ENTRY;
47
48
static const PCI_ENTRY id_list[] =
49
{
50
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, "CCD/Billion/Asuscom", "2BD0"},
51
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, "Billion", "B000"},
52
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, "Billion", "B006"},
53
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, "Billion", "B007"},
54
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, "Billion", "B008"},
55
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, "Billion", "B009"},
56
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, "Billion", "B00A"},
57
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"},
58
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"},
59
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"},
60
        {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"},
61
        {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"},
62
        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"},
63
        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, "German telekom", "A1T"},
64
        {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, "Motorola MC145575", "MC145575"},
65
        {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, "Zoltrix", "2BD0"},
66
        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,"Digi International", "Digi DataFire Micro V IOM2 (Europe)"},
67
        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"},
68
        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"},
69
        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"},
70
	{0x182d, 0x3069,"Sitecom","Isdn 128 PCI"},
71
        {0, 0, NULL, NULL},
72
};
73
74
static struct hfc_card *hfc_dev_list = NULL;
75
static int hfc_dev_count = 0;
76
static int modes = 0; // all TE
77
static int sync_slave = 0; // all master
78
static int timer_card = 0;
79
static int jitterbuffer = 1;
80
static int debug = 0;
81
static struct pci_dev *multi_hfc = NULL;
82
static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
83
84
void hfc_shutdownCard1(struct hfc_card *hfctmp) {
85
    printk(KERN_INFO "zaphfc: shutting down card at %p.\n",hfctmp->pci_io);
86
87
    /* Clear interrupt mask */
88
    hfctmp->regs.int_m2 = 0;
89
    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
90
91
    /* Remove interrupt handler */
92
    free_irq(hfctmp->irq,hfctmp);
93
}
94
95
void hfc_shutdownCard2(struct hfc_card *hfctmp) {
96
    unsigned long flags;
97
98
    spin_lock_irqsave(&hfctmp->lock,flags);
99
100
    /* Reset pending interrupts */
101
    hfc_inb(hfctmp, hfc_INT_S1);
102
103
    /* Soft-reset the card */
104
    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on
105
106
    spin_unlock_irqrestore(&hfctmp->lock, flags);
107
    set_current_state(TASK_UNINTERRUPTIBLE);
108
    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
109
    spin_lock_irqsave(&hfctmp->lock,flags);
110
111
    hfc_outb(hfctmp,hfc_CIRM,0);	// softreset off
112
113
    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0);	// disable memio and bustmaster
114
115
    if (hfctmp->fifos != NULL) {
116
	free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES));
117
    }
118
    iounmap((void *) hfctmp->pci_io);
119
    hfctmp->pci_io = NULL;
120
    if (hfctmp->pcidev != NULL) {
121
        pci_disable_device(hfctmp->pcidev);
122
    }
123
    spin_unlock_irqrestore(&hfctmp->lock,flags);
124
    if (hfctmp->ztdev != NULL) {
125
	dahdi_unregister(&hfctmp->ztdev->span);
126
	vfree(hfctmp->ztdev);
127
	printk(KERN_INFO "unregistered from DAHDI.\n");
128
    }
129
}
130
131
void hfc_shutdownCard(struct hfc_card *hfctmp) {
132
    if (hfctmp == NULL) {
133
	return;
134
    }
135
136
    if (hfctmp->pci_io == NULL) {
137
	return;
138
    }
139
140
    hfc_shutdownCard1(hfctmp);
141
    hfc_shutdownCard2(hfctmp);
142
}
143
144
void hfc_resetCard(struct hfc_card *hfctmp) {
145
    unsigned long flags;
146
147
    spin_lock_irqsave(&hfctmp->lock,flags);
148
    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
149
    hfctmp->regs.int_m2 = 0;
150
    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
151
152
//    printk(KERN_INFO "zaphfc: resetting card.\n");
153
    pci_set_master(hfctmp->pcidev);
154
    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET);	// softreset on
155
    spin_unlock_irqrestore(&hfctmp->lock, flags);
156
157
    set_current_state(TASK_UNINTERRUPTIBLE);
158
    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
159
    hfc_outb(hfctmp, hfc_CIRM, 0);	// softreset off
160
161
    set_current_state(TASK_UNINTERRUPTIBLE);
162
    schedule_timeout((20 * HZ) / 1000);	// wait 20 ms
163
    if (hfc_inb(hfctmp,hfc_STATUS) & hfc_STATUS_PCI_PROC) {
164
	printk(KERN_WARNING "zaphfc: hfc busy.\n");
165
    }
166
167
//    hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
168
//    hfctmp->regs.fifo_en = hfc_FIFOEN_D;	/* only D fifos enabled */
169
    hfctmp->regs.fifo_en = 0;	/* no fifos enabled */
170
    hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
171
172
    hfctmp->regs.trm = 2;
173
    hfc_outb(hfctmp, hfc_TRM, hfctmp->regs.trm);
174
175
    if (hfctmp->regs.nt_mode == 1) {
176
	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */
177
    } else {
178
	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_TE); /* ST-Bit delay for TE-Mode */
179
    }
180
    hfctmp->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
181
    hfc_outb(hfctmp, hfc_SCTRL_E, hfctmp->regs.sctrl_e);	/* S/T Auto awake */
182
    hfctmp->regs.bswapped = 0;	/* no exchange */
183
184
    hfctmp->regs.ctmt = hfc_CTMT_TRANSB1 | hfc_CTMT_TRANSB2; // all bchans are transparent , no freaking hdlc
185
    hfc_outb(hfctmp, hfc_CTMT, hfctmp->regs.ctmt);
186
187
    hfctmp->regs.int_m1=hfc_INTS_L1STATE;
188
    if(hfctmp->cardno==timer_card){
189
	hfctmp->regs.int_m2=hfc_M2_PROC_TRANS;
190
    }else{
191
	hfctmp->regs.int_m1|=hfc_INTS_DREC;
192
	hfctmp->regs.int_m2=0;
193
    }
194
    hfc_outb(hfctmp, hfc_INT_M1, hfctmp->regs.int_m1);
195
    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
196
197
    /* Clear already pending ints */
198
    hfc_inb(hfctmp, hfc_INT_S1);
199
200
    if (hfctmp->regs.nt_mode == 1) {
201
	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_NT;	/* set tx_lo mode, error in datasheet ! */
202
    } else {
203
	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE;	/* set tx_lo mode, error in datasheet ! */
204
    }
205
206
    hfc_outb(hfctmp, hfc_MST_MODE, hfctmp->regs.mst_mode);
207
    hfc_outb(hfctmp, hfc_MST_EMOD, hfctmp->regs.mst_emod);
208
209
    hfc_outb(hfctmp, hfc_SCTRL, hfctmp->regs.sctrl);
210
    hfctmp->regs.sctrl_r = 3;
211
    hfc_outb(hfctmp, hfc_SCTRL_R, hfctmp->regs.sctrl_r);
212
213
    hfctmp->regs.connect = 0;
214
    hfc_outb(hfctmp, hfc_CONNECT, hfctmp->regs.connect);
215
216
    hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40);	// bit order
217
218
    /* Finally enable IRQ output */
219
    hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE;
220
    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
221
222
    /* clear pending ints */
223
    hfc_inb(hfctmp, hfc_INT_S1); 
224
    hfc_inb(hfctmp, hfc_INT_S2);
225
}
226
227
void hfc_registerCard(struct hfc_card *hfccard) {
228
    spin_lock(&registerlock);
229
    if (hfccard != NULL) {
230
	hfccard->cardno = hfc_dev_count++;
231
	hfccard->next = hfc_dev_list;
232
	hfc_dev_list = hfccard;
233
    }
234
    spin_unlock(&registerlock);
235
}
236
237
/*===========================================================================*/
238
239
#if hfc_B_FIFO_SIZE%DAHDI_CHUNKSIZE
240
#error hfc_B_FIFO_SIZE is not a multiple of DAHDI_CHUNKSIZE even though the code assumes this
241
#endif
242
243
static void hfc_dch_init(struct hfc_card *hfctmp){
244
    struct dch *chtmp=&hfctmp->dch;
245
246
    chtmp->rx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DRX_F1);
247
    chtmp->rx.f2.v=0x1f;
248
    chtmp->rx.f2.z2.v=0x1ff;
249
250
    chtmp->tx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F1);
251
    chtmp->tx.f1.v=0x1f;
252
    chtmp->tx.f1.z1.v=0x1ff;
253
    chtmp->tx.f2.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F2);
254
}
255
256
static void hfc_bch_init(struct hfc_card *hfctmp){
257
    struct bch *chtmp=&hfctmp->bch;
258
259
    chtmp->checkcnt=0;
260
    chtmp->fill_fifo=0;
261
262
    chtmp->rx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1RX_Z1+0x1f*4);
263
    chtmp->rx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1RX_ZOFF);
264
    chtmp->rx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2RX_Z1+0x1f*4);
265
    chtmp->rx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2RX_ZOFF);
266
    chtmp->rx.z2=hfc_B_SUB_VAL;
267
    chtmp->rx.diff=0;
268
269
    chtmp->tx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z1+0x1f*4);
270
    chtmp->tx.c[0].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z2+0x1f*4);
271
    chtmp->tx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1TX_ZOFF);
272
    chtmp->tx.c[0].filled=0;
273
    chtmp->tx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z1+0x1f*4);
274
    chtmp->tx.c[1].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z2+0x1f*4);
275
    chtmp->tx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2TX_ZOFF);
276
    chtmp->tx.c[1].filled=0;
277
    chtmp->tx.z1=hfc_B_SUB_VAL;
278
    chtmp->tx.diff=0;
279
280
    hfc_dch_init(hfctmp);
281
282
    chtmp->initialized=0;
283
}
284
285
static int hfc_bch_check(struct hfc_card *hfctmp){
286
    struct bch *chtmp=&hfctmp->bch;
287
    int x,r;
288
289
    for(x=0;x<2;x++){
290
	chtmp->tx.c[x].filled=(chtmp->tx.z1-*chtmp->tx.c[x].z2p+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE;
291
	chtmp->rx.c[x].filled=(*chtmp->rx.c[x].z1p-chtmp->rx.z2+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE;
292
    }
293
    if(chtmp->fill_fifo){
294
	chtmp->checkcnt++;
295
	chtmp->checkcnt%=DAHDI_CHUNKSIZE;
296
	r=!chtmp->checkcnt;
297
    }else{
298
	x=chtmp->tx.c[0].filled-chtmp->tx.c[1].filled;
299
	if(abs(x-chtmp->tx.diff)>1){
300
	    printk(KERN_CRIT "zaphfc[%d]: tx sync changed: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled);
301
	    chtmp->tx.diff=x;
302
	}
303
	r=chtmp->tx.c[0].filled<=DAHDI_CHUNKSIZE*jitterbuffer&&chtmp->tx.c[1].filled<=DAHDI_CHUNKSIZE*jitterbuffer;
304
    }
305
    return(r);
306
}
307
308
#define hfc_bch_inc_z(a,b) (a)=((a)-hfc_B_SUB_VAL+(b))%hfc_B_FIFO_SIZE+hfc_B_SUB_VAL
309
310
static void hfc_bch_tx(struct hfc_card *hfctmp){
311
    struct bch *chtmp=&hfctmp->bch;
312
    int x;
313
314
    for(x=0;x<2;x++)
315
	memcpy((void *)(chtmp->tx.c[x].fifo_base+chtmp->tx.z1),hfctmp->ztdev->chans[x].writechunk,DAHDI_CHUNKSIZE);
316
    hfc_bch_inc_z(chtmp->tx.z1,DAHDI_CHUNKSIZE);
317
    if(chtmp->fill_fifo){
318
	chtmp->fill_fifo--;
319
    }else if(chtmp->tx.c[0].filled<=1||chtmp->tx.c[1].filled<=1){
320
	chtmp->fill_fifo=jitterbuffer;
321
	if(chtmp->initialized)
322
	    printk(KERN_CRIT "zaphfc[%d]: b channel buffer underrun: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled);
323
    }
324
    if(!chtmp->fill_fifo)
325
	for(x=0;x<2;x++)*chtmp->tx.c[x].z1p=chtmp->tx.z1;
326
}
327
328
static void hfc_bch_rx(struct hfc_card *hfctmp){
329
    struct bch *chtmp=&hfctmp->bch;
330
    int x;
331
332
    x=chtmp->rx.c[0].filled-chtmp->rx.c[1].filled;
333
    if(abs(x-chtmp->rx.diff)>1){
334
	printk(KERN_CRIT "zaphfc[%d]: rx sync changed: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled);
335
	chtmp->rx.diff=x;
336
    }
337
    if(chtmp->rx.c[0].filled>=DAHDI_CHUNKSIZE&&chtmp->rx.c[1].filled>=DAHDI_CHUNKSIZE){
338
	if((chtmp->rx.c[0].filled>=DAHDI_CHUNKSIZE*(jitterbuffer+2)&&chtmp->rx.c[1].filled>=DAHDI_CHUNKSIZE*(jitterbuffer+2))||!chtmp->initialized){
339
	    if(chtmp->initialized)
340
		printk(KERN_CRIT "zaphfc[%d]: b channel buffer overflow: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled);
341
	    hfc_bch_inc_z(chtmp->rx.z2,chtmp->rx.c[0].filled-chtmp->rx.c[0].filled%DAHDI_CHUNKSIZE-DAHDI_CHUNKSIZE);
342
	    chtmp->initialized=1;
343
	}
344
	for(x=0;x<2;x++){
345
	    memcpy(hfctmp->ztdev->chans[x].readchunk,(void *)(chtmp->rx.c[x].fifo_base+chtmp->rx.z2),DAHDI_CHUNKSIZE);
346
	    dahdi_ec_chunk(&hfctmp->ztdev->chans[x],hfctmp->ztdev->chans[x].readchunk,hfctmp->ztdev->chans[x].writechunk);
347
	}
348
	hfc_bch_inc_z(chtmp->rx.z2,DAHDI_CHUNKSIZE);
349
    }
350
}
351
352
/*===========================================================================*/
353
354
static void hfc_dch_tx(struct hfc_card *hfctmp){
355
    struct dch *chtmp=&hfctmp->dch;
356
    u8 tx_f2_v;
357
    u16 x;
358
359
    if(hfctmp->ztdev->chans[2].bytes2transmit){
360
	if(debug){
361
	    printk(KERN_CRIT "zaphfc[%d]: card TX [ ",hfctmp->cardno);
362
	    for(x=0;x<hfctmp->ztdev->chans[2].bytes2transmit;x++){
363
		printk("%#2x ",hfctmp->dtransbuf[x]);
364
	    }
365
	    printk("] %d bytes\n",hfctmp->ztdev->chans[2].bytes2transmit);
366
	}
367
	tx_f2_v=*chtmp->tx.f2.p;
368
	if(!(tx_f2_v-chtmp->tx.f1.v+hfc_MAX_DFRAMES+1-1)&(hfc_MAX_DFRAMES+1-1)){
369
	    printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo total number of frames exceeded!\n",hfctmp->cardno);
370
	}else{
371
	    if(((*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+tx_f2_v*4)-chtmp->tx.f1.z1.v+hfc_D_FIFO_SIZE-1)&(hfc_D_FIFO_SIZE-1))<hfctmp->ztdev->chans[2].bytes2transmit){
372
		printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo not enough space for frame!\n",hfctmp->cardno);
373
	    }else{
374
		chtmp->tx.f1.v=((chtmp->tx.f1.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1);
375
		x=min(hfctmp->ztdev->chans[2].bytes2transmit,hfc_D_FIFO_SIZE-chtmp->tx.f1.z1.v);
376
		memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF+chtmp->tx.f1.z1.v,hfctmp->ztdev->chans[2].writechunk,x);
377
		memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF,hfctmp->ztdev->chans[2].writechunk+x,hfctmp->ztdev->chans[2].bytes2transmit-x);
378
		*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v;
379
		chtmp->tx.f1.z1.v=(chtmp->tx.f1.z1.v+hfctmp->ztdev->chans[2].bytes2transmit+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1);
380
		*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z1+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v;
381
		*chtmp->tx.f1.p=chtmp->tx.f1.v;
382
	    }
383
	}
384
    }
385
}
386
387
static void hfc_dch_rx(struct hfc_card *hfctmp){
388
    struct dch *chtmp=&hfctmp->dch;
389
    u16 size;
390
391
    hfctmp->ztdev->chans[2].bytes2receive=0;
392
    hfctmp->ztdev->chans[2].eofrx=0;
393
    if(*chtmp->rx.f1.p==chtmp->rx.f2.v){
394
	hfctmp->regs.int_drec=0;
395
    }else{
396
	size=((*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DRX_Z1+chtmp->rx.f2.v*4)-chtmp->rx.f2.z2.v+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1))+1;
397
	if(size<4){
398
	    printk(KERN_CRIT "zaphfc[%d]: empty HDLC frame received.\n",hfctmp->cardno);
399
	}else{
400
	    u16 x=min(size,(u16)(hfc_D_FIFO_SIZE-chtmp->rx.f2.z2.v));
401
	    memcpy(hfctmp->drecbuf,hfctmp->fifos+hfc_FIFO_DRX_ZOFF+chtmp->rx.f2.z2.v,x);
402
	    memcpy(hfctmp->drecbuf+x,hfctmp->fifos+hfc_FIFO_DRX_ZOFF,size-x);
403
	    if(hfctmp->drecbuf[size-1]){
404
		printk(KERN_CRIT "zaphfc[%d]: received d channel frame with bad CRC.\n",hfctmp->cardno);
405
	    }else{
406
		hfctmp->ztdev->chans[2].bytes2receive=size-1;
407
		hfctmp->ztdev->chans[2].eofrx=1;
408
	    }
409
	}
410
	chtmp->rx.f2.z2.v=(chtmp->rx.f2.z2.v+size)&(hfc_D_FIFO_SIZE-1);
411
	chtmp->rx.f2.v=((chtmp->rx.f2.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1);
412
    }
413
}
414
415
DAHDI_IRQ_HANDLER(hfc_interrupt) {
416
    struct hfc_card *hfctmp = dev_id;
417
    struct hfc_card *hfctmp2;
418
    struct dahdi_hfc *zthfc;
419
    unsigned char stat, s1, s2, l1state;
420
    unsigned long flags = 0;
421
    unsigned long flags2 = 0;
422
    int x;
423
424
    if (!hfctmp) {
425
	    return IRQ_NONE;
426
    }
427
428
    if (!hfctmp->pci_io) {
429
	    printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n",
430
		   __FUNCTION__);
431
	    return IRQ_NONE;
432
    }
433
    
434
    spin_lock_irqsave(&hfctmp->lock, flags);
435
    stat = hfc_inb(hfctmp, hfc_STATUS);
436
    if ((stat & hfc_STATUS_ANYINT) == 0) {
437
        // maybe we are sharing the irq
438
	spin_unlock_irqrestore(&hfctmp->lock,flags);
439
	return IRQ_NONE;
440
    }
441
442
    s1 = hfc_inb(hfctmp, hfc_INT_S1);
443
    s2 = hfc_inb(hfctmp, hfc_INT_S2); 
444
    if (s1 != 0) {
445
	if (s1 & hfc_INTS_TIMER) {
446
	    // timer (bit 7)
447
	    // printk(KERN_CRIT "timer %d %d %d.\n", stat, s1, s2);
448
	}
449
	if (s1 & hfc_INTS_L1STATE) {
450
	    // state machine (bit 6)
451
	    // printk(KERN_CRIT "zaphfc: layer 1 state machine interrupt\n");
452
	    zthfc = hfctmp->ztdev;
453
	    l1state = hfc_inb(hfctmp,hfc_STATES)  & hfc_STATES_STATE_MASK;
454
	    if (hfctmp->regs.nt_mode == 1) {
455
		if (debug) {
456
	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = G%d\n", hfctmp->cardno, l1state);
457
		}
458
		switch (l1state) {
459
		    case 3:
460
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state);
461
			break;
462
		    default:
463
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state);
464
		}
465
		if (l1state == 2) {
466
		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3);
467
		} else if (l1state == 3) {
468
		    // fix to G3 state (see specs)
469
		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
470
		}
471
	    } else {
472
		if (debug) {
473
	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = F%d\n", hfctmp->cardno, l1state);
474
		}
475
		switch (l1state) {
476
		    case 7:
477
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state);
478
			break;
479
		    default:
480
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state);
481
		}
482
		if (l1state == 3) {
483
		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
484
		}
485
	    }
486
	    
487
	}
488
	if (s1 & hfc_INTS_DREC) {
489
	    // D chan RX (bit 5)
490
	    hfctmp->regs.int_drec = 1;
491
	    // mr. zapata there is something for you!
492
	//    printk(KERN_CRIT "d chan rx\n");		    
493
	}
494
	if (s1 & hfc_INTS_B2REC) {
495
	    // B2 chan RX (bit 4)
496
	}
497
	if (s1 & hfc_INTS_B1REC) {
498
	    // B1 chan RX (bit 3)
499
	}
500
	if (s1 & hfc_INTS_DTRANS) {
501
	    // D chan TX (bit 2)
502
//	    printk(KERN_CRIT "zaphfc: dchan frame transmitted.\n");
503
	}
504
	if (s1 & hfc_INTS_B2TRANS) {
505
	    // B2 chan TX (bit 1)
506
	}
507
	if (s1 & hfc_INTS_B1TRANS) {
508
	    // B1 chan TX (bit 0)
509
	}
510
    }
511
    if (s2 != 0) {
512
	if (s2 & hfc_M2_PMESEL) {
513
	    // kaboom irq (bit 7)
514
	    //printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n");
515
	}
516
	if (s2 & hfc_M2_GCI_MON_REC) {
517
	    // RxR monitor channel (bit 2)
518
	}
519
	if (s2 & hfc_M2_GCI_I_CHG) {
520
	    // GCI I-change  (bit 1)
521
	}
522
	if((s2&hfc_M2_PROC_TRANS)&&(hfctmp->cardno==timer_card)){
523
	    // processing/non-processing transition  (bit 0)
524
	hfctmp2=hfctmp;
525
	hfctmp=hfc_dev_list;
526
	while(hfctmp){
527
	    if(hfctmp->active){
528
	    if(hfctmp!=hfctmp2)spin_lock_irqsave(&hfctmp->lock, flags2);
529
	    if(hfc_bch_check(hfctmp)){
530
    if (hfctmp->ztdev->span.flags & DAHDI_FLAG_RUNNING) {
531
		    // clear dchan buffer
532
	//	    memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf));
533
534
		    hfctmp->ztdev->chans[2].bytes2transmit = 0;
535
		    hfctmp->ztdev->chans[2].maxbytes2transmit = hfc_D_FIFO_SIZE;
536
537
		    dahdi_transmit(&(hfctmp->ztdev->span));
538
539
		    hfc_bch_tx(hfctmp);
540
		    hfc_dch_tx(hfctmp);
541
		}
542
543
		hfc_bch_rx(hfctmp);
544
		if (hfctmp->regs.int_drec) {
545
		    // dchan data to read
546
		    hfc_dch_rx(hfctmp);
547
		    if (hfctmp->ztdev->chans[2].bytes2receive > 0) {
548
			    if (debug) {
549
    				printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno);
550
				if (hfctmp->ztdev->chans[2].eofrx) {
551
				    /* dont output CRC == less user confusion */
552
				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive - 2; x++) {
553
					printk("%#2x ", hfctmp->drecbuf[x]);
554
				    }
555
				    printk("] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive - 2);
556
				} else {
557
				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive; x++) {
558
					printk("%#2x ", hfctmp->drecbuf[x]);
559
				    }
560
				    printk("..] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive);
561
				}
562
			    }
563
		    }
564
		} else {
565
			// hmm....ok, let DAHDI receive nothing
566
		    hfctmp->ztdev->chans[2].bytes2receive = 0;
567
		}
568
		if (hfctmp->ztdev->span.flags & DAHDI_FLAG_RUNNING) {
569
		    dahdi_receive(&(hfctmp->ztdev->span));
570
		}
571
	    }
572
	    if(hfctmp!=hfctmp2)spin_unlock_irqrestore(&hfctmp->lock,flags2);
573
	    }
574
	    hfctmp=hfctmp->next;
575
	}
576
	hfctmp=hfctmp2;
577
	}
578
    }
579
    spin_unlock_irqrestore(&hfctmp->lock,flags);
580
    return IRQ_RETVAL(1);
581
}
582
583
584
static int zthfc_open(struct dahdi_chan *chan) {
585
    struct dahdi_hfc *zthfc = chan->pvt;
586
    struct hfc_card *hfctmp = zthfc->card;
587
    
588
    if (!hfctmp) {
589
    return 0;
590
    }
591
    try_module_get(THIS_MODULE);
592
    return 0;
593
}
594
595
static int zthfc_close(struct dahdi_chan *chan) {
596
    struct dahdi_hfc *zthfc = chan->pvt;
597
    struct hfc_card *hfctmp = zthfc->card;
598
599
    if (!hfctmp) {
600
	return 0;
601
    }
602
603
    module_put(THIS_MODULE);
604
    return 0;
605
}
606
607
static int zthfc_rbsbits(struct dahdi_chan *chan, int bits) {
608
    return 0;
609
}
610
611
static int zthfc_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data) {
612
        switch(cmd) {
613
        default:
614
                return -ENOTTY;
615
        }
616
        return 0;
617
}
618
619
static int zthfc_startup(struct dahdi_span *span) {
620
    struct dahdi_hfc *zthfc = span->pvt;
621
    struct hfc_card *hfctmp = zthfc->card;
622
    int alreadyrunning;
623
    
624
    if (hfctmp == NULL) {
625
	printk(KERN_INFO "zaphfc: no card for span at startup!\n");
626
    }
627
    alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
628
    
629
    if (alreadyrunning) return 0;
630
631
    span->chans[2]->flags &= ~DAHDI_FLAG_HDLC;
632
    span->chans[2]->flags |= DAHDI_FLAG_BRIDCHAN;
633
634
    span->flags |= DAHDI_FLAG_RUNNING;
635
636
    hfctmp->ticks = -2;
637
    hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
638
    hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
639
640
    hfc_bch_init(hfctmp);
641
642
    // drivers, start engines!
643
    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
644
    hfctmp->active=1;
645
    return 0;
646
}
647
648
static int zthfc_shutdown(struct dahdi_span *span) {
649
    return 0;
650
}
651
652
static int zthfc_maint(struct dahdi_span *span, int cmd) {
653
    return 0;
654
}
655
656
static int zthfc_chanconfig(struct dahdi_chan *chan, int sigtype) {
657
//    printk(KERN_CRIT "chan_config sigtype=%d\n", sigtype);
658
    return 0;
659
}
660
661
static int zthfc_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) {
662
    span->lineconfig = lc->lineconfig;
663
    return 0;
664
}
665
666
static int zthfc_initialize(struct dahdi_hfc *zthfc) {
667
    struct hfc_card *hfctmp = zthfc->card;
668
    int i;
669
670
    memset(&zthfc->span, 0x0, sizeof(struct dahdi_span)); // you never can tell...
671
672
    sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1);
673
    if (hfctmp->regs.nt_mode == 1) {
674
	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1);
675
    } else {
676
	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1);
677
    }
678
679
    zthfc->span.spanconfig = zthfc_spanconfig;
680
    zthfc->span.chanconfig = zthfc_chanconfig;
681
    zthfc->span.startup = zthfc_startup;
682
    zthfc->span.shutdown = zthfc_shutdown;
683
    zthfc->span.maint = zthfc_maint;
684
    zthfc->span.rbsbits = zthfc_rbsbits;
685
    zthfc->span.open = zthfc_open;
686
    zthfc->span.close = zthfc_close;
687
    zthfc->span.ioctl = zthfc_ioctl;
688
689
    zthfc->span.channels = 3;
690
    zthfc->span.chans = zthfc->_chans;
691
    for (i = 0; i < zthfc->span.channels; i++)
692
        zthfc->_chans[i] = &zthfc->chans[i];
693
    zthfc->span.deflaw = DAHDI_LAW_ALAW;
694
    zthfc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS; // <--- this is really BS
695
    zthfc->span.offset = 0;
696
    init_waitqueue_head(&zthfc->span.maintq);
697
    zthfc->span.pvt = zthfc;
698
699
    for (i = 0; i < zthfc->span.channels; i++) {
700
	memset(&(zthfc->chans[i]), 0x0, sizeof(struct dahdi_chan));
701
	sprintf(zthfc->chans[i].name, "ZTHFC%d/%d/%d", hfc_dev_count + 1,0,i + 1);
702
	zthfc->chans[i].pvt = zthfc;
703
	zthfc->chans[i].sigcap =  DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_SF;
704
	zthfc->chans[i].chanpos = i + 1; 
705
    }
706
707
    if (dahdi_register(&zthfc->span,0)) {
708
	printk(KERN_CRIT "unable to register DAHDI device!\n");
709
	return -1;
710
    }
711
//    printk(KERN_CRIT "zaphfc: registered DAHDI device!\n");
712
    return 0;
713
}
714
715
int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) {
716
    struct pci_dev *tmp;
717
    struct hfc_card *hfctmp = NULL;
718
    struct dahdi_hfc *zthfc = NULL;
719
720
    tmp = pci_get_device(pcivendor, pcidevice, multi_hfc);
721
    while (tmp != NULL) {
722
	multi_hfc = tmp;	// skip this next time.
723
724
	if (pci_enable_device(tmp)) {
725
	    multi_hfc = NULL;
726
	    return -1;
727
	}
728
	pci_set_master(tmp);
729
730
	hfctmp = vmalloc(sizeof(struct hfc_card));
731
	if (!hfctmp) {
732
	    printk(KERN_WARNING "zaphfc: unable to vmalloc!\n");
733
	    pci_disable_device(tmp);
734
	    multi_hfc = NULL;
735
	    return -ENOMEM;
736
	}
737
	memset(hfctmp, 0x0, sizeof(struct hfc_card));
738
	spin_lock_init(&hfctmp->lock);
739
	
740
	hfctmp->active=0;
741
	hfctmp->pcidev = tmp;
742
	hfctmp->pcibus = tmp->bus->number;
743
	hfctmp->pcidevfn = tmp->devfn; 
744
745
	if (!tmp->irq) {
746
	    printk(KERN_WARNING "zaphfc: no irq!\n");
747
	} else {
748
	    hfctmp->irq = tmp->irq;
749
	}
750
751
	hfctmp->pci_io = (char *) tmp->resource[1].start;
752
	if (!hfctmp->pci_io) {
753
	    printk(KERN_WARNING "zaphfc: no iomem!\n");
754
	    vfree(hfctmp);
755
	    pci_disable_device(tmp);
756
	    multi_hfc = NULL;
757
	    return -1;
758
	}
759
760
	hfctmp->fifos=(void *)__get_free_pages(GFP_KERNEL,log2(hfc_FIFO_MEM_SIZE_PAGES));
761
	if (!hfctmp->fifos) {
762
	    printk(KERN_WARNING "zaphfc: unable to __get_free_pages fifomem!\n");
763
	    vfree(hfctmp);
764
	    pci_disable_device(tmp);
765
	    multi_hfc = NULL;
766
	    return -ENOMEM;
767
	} else {
768
	    pci_write_config_dword(hfctmp->pcidev, 0x80, (u_int) virt_to_bus(hfctmp->fifos));
769
	    hfctmp->pci_io = ioremap((ulong) hfctmp->pci_io, 256);
770
	}
771
772
	if (request_irq(hfctmp->irq, &hfc_interrupt, DAHDI_IRQ_SHARED, "zaphfc", hfctmp)) {
773
	    printk(KERN_WARNING "zaphfc: unable to register irq\n");
774
	    free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES));
775
	    vfree(hfctmp);
776
	    iounmap((void *) hfctmp->pci_io);
777
	    pci_disable_device(tmp);
778
	    multi_hfc = NULL;
779
	    return -EIO;
780
	}
781
782
	printk(KERN_INFO
783
		       "zaphfc: %s %s configured at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n",
784
			vendor_name, card_name,
785
		       (u_int) hfctmp->pci_io,
786
		       (u_int) hfctmp->fifos,
787
		       (u_int) virt_to_bus(hfctmp->fifos),
788
		       hfctmp->irq, HZ); 
789
	pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
790
	hfctmp->regs.int_m1 = 0;	// no ints
791
	hfctmp->regs.int_m2 = 0;	// not at all
792
	hfc_outb(hfctmp,hfc_INT_M1,hfctmp->regs.int_m1);
793
	hfc_outb(hfctmp,hfc_INT_M2,hfctmp->regs.int_m2);
794
795
	if ((modes & (1 << hfc_dev_count)) != 0) {
796
	    printk(KERN_INFO "zaphfc: Card %d configured for NT mode\n",hfc_dev_count);
797
	    hfctmp->regs.nt_mode = 1;
798
	} else {
799
	    printk(KERN_INFO "zaphfc: Card %d configured for TE mode\n",hfc_dev_count);
800
	    hfctmp->regs.nt_mode = 0;
801
	}
802
803
	if(sync_slave&(1<<hfc_dev_count)){
804
	    printk(KERN_INFO "zaphfc: Card %d configured for slave mode\n",hfc_dev_count);
805
	    hfctmp->regs.mst_mode=hfc_MST_MODE_SLAVE|hfc_MST_MODE_F0_LONG_DURATION;
806
	    hfctmp->regs.mst_emod=hfc_MST_EMOD_SLOW_CLOCK_ADJ;
807
	}else{
808
	    printk(KERN_INFO "zaphfc: Card %d configured for master mode\n",hfc_dev_count);
809
	    hfctmp->regs.mst_mode=hfc_MST_MODE_MASTER|hfc_MST_MODE_F0_LONG_DURATION;
810
	    hfctmp->regs.mst_emod=0;
811
	}
812
813
	zthfc = vmalloc(sizeof(struct dahdi_hfc));
814
	if (!zthfc) {
815
	    printk(KERN_CRIT "zaphfc: unable to vmalloc!\n");
816
	    hfc_shutdownCard(hfctmp);
817
	    vfree(hfctmp);
818
	    multi_hfc = NULL;
819
	    return -ENOMEM;
820
	}
821
	memset(zthfc, 0x0, sizeof(struct dahdi_hfc));
822
823
	zthfc->card = hfctmp;
824
	zthfc_initialize(zthfc);
825
	hfctmp->ztdev = zthfc;
826
827
	memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf));
828
	hfctmp->ztdev->chans[2].readchunk = hfctmp->drecbuf;
829
830
	memset(hfctmp->dtransbuf, 0x0, sizeof(hfctmp->dtransbuf));
831
	hfctmp->ztdev->chans[2].writechunk = hfctmp->dtransbuf;
832
833
	memset(hfctmp->brecbuf[0], 0x0, sizeof(hfctmp->brecbuf[0]));
834
	hfctmp->ztdev->chans[0].readchunk = hfctmp->brecbuf[0];
835
	memset(hfctmp->btransbuf[0], 0x0, sizeof(hfctmp->btransbuf[0]));
836
	hfctmp->ztdev->chans[0].writechunk = hfctmp->btransbuf[0];
837
838
	memset(hfctmp->brecbuf[1], 0x0, sizeof(hfctmp->brecbuf[1]));
839
	hfctmp->ztdev->chans[1].readchunk = hfctmp->brecbuf[1];
840
	memset(hfctmp->btransbuf[1], 0x0, sizeof(hfctmp->btransbuf[1]));
841
	hfctmp->ztdev->chans[1].writechunk = hfctmp->btransbuf[1];
842
843
	hfc_registerCard(hfctmp);
844
	hfc_resetCard(hfctmp);
845
	tmp = pci_get_device(pcivendor, pcidevice, multi_hfc);
846
    }
847
    return 0;
848
}
849
850
int init_module(void) {
851
    int i = 0;
852
    if(jitterbuffer<1){
853
	printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to minimum of 1\n",jitterbuffer);
854
	jitterbuffer=1;
855
    }else if(jitterbuffer>500){
856
	printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to maximum of 500\n",jitterbuffer);
857
	jitterbuffer=500;
858
    }
859
    printk(KERN_INFO "zaphfc: jitterbuffer size: %d\n",jitterbuffer);
860
    while (id_list[i].vendor_id) {
861
	multi_hfc = NULL;
862
	hfc_findCards(id_list[i].vendor_id, id_list[i].device_id, id_list[i].vendor_name, id_list[i].card_name);
863
	i++;
864
    }
865
    printk(KERN_INFO "zaphfc: %d hfc-pci card(s) in this box.\n", hfc_dev_count);
866
    return 0;
867
}
868
869
void cleanup_module(void) {
870
    struct hfc_card *tmpcard;
871
872
    printk(KERN_INFO "zaphfc: stop\n");
873
//    spin_lock(&registerlock);
874
    tmpcard=hfc_dev_list;
875
    while(tmpcard){
876
	hfc_shutdownCard1(tmpcard);
877
	tmpcard=tmpcard->next;
878
    }
879
    while (hfc_dev_list != NULL) {
880
	if (hfc_dev_list == NULL) break;
881
	hfc_shutdownCard2(hfc_dev_list);
882
	tmpcard = hfc_dev_list;
883
	hfc_dev_list = hfc_dev_list->next;
884
	if (tmpcard != NULL) {
885
	    vfree(tmpcard);
886
	    tmpcard = NULL;
887
	    printk(KERN_INFO "zaphfc: freed one card.\n");
888
	}
889
    }
890
//    spin_unlock(&registerlock);
891
}
892
#endif
893
894
895
module_param(modes, int, 0400);
896
module_param(debug, int, 0600);
897
module_param(sync_slave, int, 0400);
898
module_param(timer_card, int, 0400);
899
module_param(jitterbuffer, int, 0400);
900
901
MODULE_DESCRIPTION("HFC-S PCI A Zaptel Driver");
902
MODULE_AUTHOR("Klaus-Peter Junghanns <kpj@junghanns.net>");
903
#ifdef MODULE_LICENSE
904
MODULE_LICENSE("GPL");
905
#endif	
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/zaphfc.c.orig (+1128 lines)
Line 0 Link Here
1
/*
2
 * zaphfc.c - Zaptel driver for HFC-S PCI A based ISDN BRI cards
3
 *
4
 * kernel module inspired by HFC PCI ISDN4Linux and Zaptel drivers
5
 *
6
 * Copyright (C) 2002, 2003, 2004, 2005 Junghanns.NET GmbH
7
 *
8
 * Klaus-Peter Junghanns <kpj@junghanns.net>
9
 *
10
 * This program is free software and may be modified and
11
 * distributed under the terms of the GNU Public License.
12
 *
13
 */
14
15
#include <linux/kernel.h>
16
#include <linux/module.h>
17
#ifdef RTAITIMING
18
#include <asm/io.h>
19
#include <rtai.h>
20
#include <rtai_sched.h>
21
#include <rtai_fifos.h>
22
#endif
23
#include <linux/pci.h>
24
#include <linux/init.h>
25
#include <linux/interrupt.h>
26
#include <linux/delay.h>
27
#include "kernel.h"
28
#include "zaphfc.h"
29
30
#include <linux/moduleparam.h>
31
32
#if CONFIG_PCI
33
34
#define CLKDEL_TE	0x0f	/* CLKDEL in TE mode */
35
#define CLKDEL_NT	0x6c	/* CLKDEL in NT mode */
36
37
typedef struct {
38
        int vendor_id;
39
        int device_id;
40
        char *vendor_name;
41
        char *card_name;
42
} PCI_ENTRY;
43
44
static const PCI_ENTRY id_list[] =
45
{
46
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, "CCD/Billion/Asuscom", "2BD0"},
47
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, "Billion", "B000"},
48
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, "Billion", "B006"},
49
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, "Billion", "B007"},
50
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, "Billion", "B008"},
51
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, "Billion", "B009"},
52
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, "Billion", "B00A"},
53
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"},
54
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"},
55
        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"},
56
        {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"},
57
        {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"},
58
        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"},
59
        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, "German telekom", "A1T"},
60
        {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, "Motorola MC145575", "MC145575"},
61
        {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, "Zoltrix", "2BD0"},
62
        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,"Digi International", "Digi DataFire Micro V IOM2 (Europe)"},
63
        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"},
64
        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"},
65
        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"},
66
	{0x182d, 0x3069,"Sitecom","Isdn 128 PCI"},
67
        {0, 0, NULL, NULL},
68
};
69
70
static struct hfc_card *hfc_dev_list = NULL;
71
static int hfc_dev_count = 0;
72
static int modes = 0; // all TE
73
static int debug = 0;
74
static struct pci_dev *multi_hfc = NULL;
75
static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
76
77
void hfc_shutdownCard(struct hfc_card *hfctmp) {
78
    unsigned long flags;
79
80
    if (hfctmp == NULL) {
81
	return;
82
    }
83
84
    if (hfctmp->pci_io == NULL) {
85
	return;
86
    }
87
    
88
    spin_lock_irqsave(&hfctmp->lock,flags);
89
90
    printk(KERN_INFO "zaphfc: shutting down card at %p.\n",hfctmp->pci_io);
91
92
    /* Clear interrupt mask */
93
    hfctmp->regs.int_m2 = 0;
94
    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
95
96
    /* Reset pending interrupts */
97
    hfc_inb(hfctmp, hfc_INT_S1);
98
99
    /* Wait for interrupts that might still be pending */
100
    spin_unlock_irqrestore(&hfctmp->lock, flags);
101
    set_current_state(TASK_UNINTERRUPTIBLE);
102
    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
103
    spin_lock_irqsave(&hfctmp->lock,flags);
104
105
    /* Remove interrupt handler */
106
    if (hfctmp->irq) {
107
	free_irq(hfctmp->irq, hfctmp);
108
    }
109
110
    /* Soft-reset the card */
111
    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on
112
113
    spin_unlock_irqrestore(&hfctmp->lock, flags);
114
    set_current_state(TASK_UNINTERRUPTIBLE);
115
    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
116
    spin_lock_irqsave(&hfctmp->lock,flags);
117
118
    hfc_outb(hfctmp,hfc_CIRM,0);	// softreset off
119
120
    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0);	// disable memio and bustmaster
121
122
    if (hfctmp->fifomem != NULL) {
123
        kfree(hfctmp->fifomem);
124
    }
125
    iounmap((void *) hfctmp->pci_io);
126
    hfctmp->pci_io = NULL;
127
    if (hfctmp->pcidev != NULL) {
128
        pci_disable_device(hfctmp->pcidev);
129
    }
130
    spin_unlock_irqrestore(&hfctmp->lock,flags);
131
    if (hfctmp->ztdev != NULL) {
132
	dahdi_unregister(&hfctmp->ztdev->span);
133
	kfree(hfctmp->ztdev);
134
	printk(KERN_INFO "unregistered from DAHDI.\n");
135
    }
136
}
137
138
void hfc_resetCard(struct hfc_card *hfctmp) {
139
    unsigned long flags;
140
141
    spin_lock_irqsave(&hfctmp->lock,flags);
142
    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
143
    hfctmp->regs.int_m2 = 0;
144
    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
145
146
//    printk(KERN_INFO "zaphfc: resetting card.\n");
147
    pci_set_master(hfctmp->pcidev);
148
    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET);	// softreset on
149
    spin_unlock_irqrestore(&hfctmp->lock, flags);
150
151
    set_current_state(TASK_UNINTERRUPTIBLE);
152
    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
153
    hfc_outb(hfctmp, hfc_CIRM, 0);	// softreset off
154
155
    set_current_state(TASK_UNINTERRUPTIBLE);
156
    schedule_timeout((20 * HZ) / 1000);	// wait 20 ms
157
    if (hfc_inb(hfctmp,hfc_STATUS) & hfc_STATUS_PCI_PROC) {
158
	printk(KERN_WARNING "zaphfc: hfc busy.\n");
159
    }
160
161
//    hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
162
//    hfctmp->regs.fifo_en = hfc_FIFOEN_D;	/* only D fifos enabled */
163
    hfctmp->regs.fifo_en = 0;	/* no fifos enabled */
164
    hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
165
166
    hfctmp->regs.trm = 2;
167
    hfc_outb(hfctmp, hfc_TRM, hfctmp->regs.trm);
168
169
    if (hfctmp->regs.nt_mode == 1) {
170
	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */
171
    } else {
172
	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_TE); /* ST-Bit delay for TE-Mode */
173
    }
174
    hfctmp->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
175
    hfc_outb(hfctmp, hfc_SCTRL_E, hfctmp->regs.sctrl_e);	/* S/T Auto awake */
176
    hfctmp->regs.bswapped = 0;	/* no exchange */
177
178
    hfctmp->regs.ctmt = hfc_CTMT_TRANSB1 | hfc_CTMT_TRANSB2; // all bchans are transparent , no freaking hdlc
179
    hfc_outb(hfctmp, hfc_CTMT, hfctmp->regs.ctmt);
180
181
    hfctmp->regs.int_m1 = 0;
182
    hfc_outb(hfctmp, hfc_INT_M1, hfctmp->regs.int_m1);
183
184
#ifdef RTAITIMING
185
    hfctmp->regs.int_m2 = 0;
186
#else
187
    hfctmp->regs.int_m2 = hfc_M2_PROC_TRANS;
188
#endif
189
    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
190
191
    /* Clear already pending ints */
192
    hfc_inb(hfctmp, hfc_INT_S1);
193
194
    if (hfctmp->regs.nt_mode == 1) {
195
	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_NT;	/* set tx_lo mode, error in datasheet ! */
196
    } else {
197
	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE;	/* set tx_lo mode, error in datasheet ! */
198
    }
199
200
    hfctmp->regs.mst_mode = hfc_MST_MODE_MASTER;	/* HFC Master Mode */
201
    hfc_outb(hfctmp, hfc_MST_MODE, hfctmp->regs.mst_mode);
202
203
    hfc_outb(hfctmp, hfc_SCTRL, hfctmp->regs.sctrl);
204
    hfctmp->regs.sctrl_r = 3;
205
    hfc_outb(hfctmp, hfc_SCTRL_R, hfctmp->regs.sctrl_r);
206
207
    hfctmp->regs.connect = 0;
208
    hfc_outb(hfctmp, hfc_CONNECT, hfctmp->regs.connect);
209
210
    hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40);	// bit order
211
212
    /* Finally enable IRQ output */
213
#ifndef RTAITIMING
214
    hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE;
215
    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
216
#endif
217
218
    /* clear pending ints */
219
    hfc_inb(hfctmp, hfc_INT_S1); 
220
    hfc_inb(hfctmp, hfc_INT_S2);
221
}
222
223
void hfc_registerCard(struct hfc_card *hfccard) {
224
    spin_lock(&registerlock);
225
    if (hfccard != NULL) {
226
	hfccard->cardno = hfc_dev_count++;
227
	hfccard->next = hfc_dev_list;
228
	hfc_dev_list = hfccard;
229
    }
230
    spin_unlock(&registerlock);
231
}
232
233
static void hfc_btrans(struct hfc_card *hfctmp, char whichB) {
234
    // we are called with irqs disabled from the irq handler
235
    int count, maxlen, total;
236
    unsigned char *f1, *f2;
237
    unsigned short *z1, *z2, newz1;
238
    int freebytes;
239
240
    if (whichB == 1) {
241
	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F1);
242
        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F2);
243
	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z1 + (*f1 * 4));
244
	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z2 + (*f1 * 4));
245
    } else {
246
	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F1);
247
        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F2);
248
	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z1 + (*f1 * 4));
249
	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z2 + (*f1 * 4));
250
    }
251
252
    freebytes = *z2 - *z1;
253
    if (freebytes <= 0) {
254
	freebytes += hfc_B_FIFO_SIZE;
255
    }
256
    count = DAHDI_CHUNKSIZE;
257
258
    total = count;
259
    if (freebytes < count) {
260
	hfctmp->clicks++;
261
	/* only spit out this warning once per second to not make things worse! */
262
	if (hfctmp->clicks > 100) {
263
	    printk(KERN_CRIT "zaphfc: bchan tx fifo full, dropping audio! (z1=%d, z2=%d)\n",*z1,*z2);
264
	    hfctmp->clicks = 0;
265
	}
266
	return;
267
    }
268
    
269
    maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z1;
270
    if (maxlen > count) {
271
        maxlen = count;
272
    }
273
    newz1 = *z1 + total;
274
    if (newz1 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { newz1 -= hfc_B_FIFO_SIZE; }
275
276
	if (whichB == 1) {
277
	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + *z1),hfctmp->ztdev->chans[0].writechunk, maxlen);
278
	} else {
279
	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + *z1),hfctmp->ztdev->chans[1].writechunk, maxlen);
280
	}
281
	
282
	count -= maxlen;
283
	if (count > 0) {
284
	// Buffer wrap
285
	    if (whichB == 1) {
286
	        memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[0].writechunk+maxlen, count);
287
	    } else {
288
	        memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[1].writechunk+maxlen, count);
289
	    }
290
	}
291
292
    *z1 = newz1;	/* send it now */
293
294
//    if (count > 0) printk(KERN_CRIT "zaphfc: bchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
295
    return;    
296
}
297
298
static void hfc_brec(struct hfc_card *hfctmp, char whichB) {
299
    // we are called with irqs disabled from the irq handler
300
    int count, maxlen, drop;
301
    volatile unsigned char *f1, *f2;
302
    volatile unsigned short *z1, *z2, newz2;
303
    int bytes = 0;
304
305
    if (whichB == 1) {
306
	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F1);
307
        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F2);
308
	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z1 + (*f1 * 4));
309
	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
310
    } else {
311
	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F1);
312
        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F2);
313
	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z1 + (*f1 * 4));
314
	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
315
    }
316
317
    bytes = *z1 - *z2;
318
    if (bytes < 0) {
319
	bytes += hfc_B_FIFO_SIZE;
320
    }
321
    count = DAHDI_CHUNKSIZE;
322
    
323
    if (bytes < DAHDI_CHUNKSIZE) {
324
#ifndef RTAITIMING
325
	printk(KERN_CRIT "zaphfc: bchan rx fifo not enough bytes to receive! (z1=%d, z2=%d, wanted %d got %d), probably a buffer overrun.\n",*z1,*z2,DAHDI_CHUNKSIZE,bytes);
326
#endif
327
	return;
328
    }
329
330
    /* allowing the buffering of hfc_BCHAN_BUFFER bytes of audio data works around irq jitter */
331
    if (bytes > hfc_BCHAN_BUFFER + DAHDI_CHUNKSIZE) {
332
	/* if the system is too slow to handle it, we will have to drop it all (except 1 DAHDI chunk) */
333
	drop = bytes - DAHDI_CHUNKSIZE;
334
	hfctmp->clicks++;
335
	/* only spit out this warning once per second to not make things worse! */
336
	if (hfctmp->clicks > 100) {
337
	    printk(KERN_CRIT "zaphfc: dropped audio (z1=%d, z2=%d, wanted %d got %d, dropped %d).\n",*z1,*z2,count,bytes,drop);
338
	    hfctmp->clicks = 0;
339
	}
340
	/* hm, we are processing the b chan data tooooo slowly... let's drop the lost audio */
341
	newz2 = *z2 + drop;
342
	if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
343
	    newz2 -= hfc_B_FIFO_SIZE; 
344
	}
345
	*z2 = newz2;
346
    }
347
348
    
349
    maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z2;
350
    if (maxlen > count) {
351
        maxlen = count;
352
    }
353
    if (whichB == 1) {
354
        memcpy(hfctmp->ztdev->chans[0].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + *z2), maxlen);
355
    } else {
356
        memcpy(hfctmp->ztdev->chans[1].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + *z2), maxlen);
357
    }
358
    newz2 = *z2 + count;
359
    if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
360
        newz2 -= hfc_B_FIFO_SIZE; 
361
    }
362
    *z2 = newz2;
363
	
364
    count -= maxlen;
365
    if (count > 0) {
366
    // Buffer wrap
367
        if (whichB == 1) {
368
	    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
369
    	    memcpy(hfctmp->ztdev->chans[0].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + hfc_B_SUB_VAL), count);
370
	} else {
371
	    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
372
	    memcpy(hfctmp->ztdev->chans[1].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + hfc_B_SUB_VAL), count);
373
	}
374
	newz2 = *z2 + count;
375
	if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
376
	    newz2 -= hfc_B_FIFO_SIZE; 
377
	}
378
    }
379
380
381
    if (whichB == 1) {
382
	dahdi_ec_chunk(&hfctmp->ztdev->chans[0], hfctmp->ztdev->chans[0].readchunk, hfctmp->ztdev->chans[0].writechunk);
383
    } else {
384
	dahdi_ec_chunk(&hfctmp->ztdev->chans[1], hfctmp->ztdev->chans[1].readchunk, hfctmp->ztdev->chans[1].writechunk);
385
    }
386
    return;    
387
}
388
389
390
static void hfc_dtrans(struct hfc_card *hfctmp) {
391
    // we are called with irqs disabled from the irq handler
392
    int x;
393
    int count, maxlen, total;
394
    unsigned char *f1, *f2, newf1;
395
    unsigned short *z1, *z2, newz1;
396
    int frames, freebytes;
397
398
    if (hfctmp->ztdev->chans[2].bytes2transmit == 0) {
399
	return;
400
    }
401
402
    f1 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F1);
403
    f2 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F2);
404
    z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
405
    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z2 + (*f1 * 4));
406
407
    frames = (*f1 - *f2) & hfc_FMASK;
408
    if (frames < 0) {
409
	frames += hfc_MAX_DFRAMES + 1;
410
    }
411
412
    if (frames >= hfc_MAX_DFRAMES) {
413
	printk(KERN_CRIT "zaphfc: dchan tx fifo total number of frames exceeded!\n");
414
	return;
415
    }
416
417
    freebytes = *z2 - *z1;
418
    if (freebytes <= 0) {
419
	freebytes += hfc_D_FIFO_SIZE;
420
    }
421
    count = hfctmp->ztdev->chans[2].bytes2transmit;
422
423
    total = count;
424
    if (freebytes < count) {
425
	printk(KERN_CRIT "zaphfc: dchan tx fifo not enough free bytes! (z1=%d, z2=%d)\n",*z1,*z2);
426
	return;
427
    }
428
    
429
    newz1 = (*z1 + count) & hfc_ZMASK;
430
    newf1 = ((*f1 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	// next frame
431
    
432
    if (count > 0) {
433
	if (debug) {
434
    	    printk(KERN_CRIT "zaphfc: card %d TX [ ", hfctmp->cardno);
435
	    for (x=0; x<count; x++) {
436
		printk("%#2x ",hfctmp->dtransbuf[x]);
437
	    }
438
	    if (hfctmp->ztdev->chans[2].eoftx == 1) {
439
		printk("] %d bytes\n", count);
440
	    } else {
441
		printk("..] %d bytes\n", count);
442
	    }
443
	}
444
	maxlen = hfc_D_FIFO_SIZE - *z1;
445
	if (maxlen > count) {
446
	    maxlen = count;
447
	}
448
	memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF + *z1),hfctmp->ztdev->chans[2].writechunk, maxlen);
449
	count -= maxlen;
450
	if (count > 0) {
451
	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF),(char *)(hfctmp->ztdev->chans[2].writechunk + maxlen), count);
452
	}
453
    }
454
455
    *z1 = newz1;
456
457
    if (hfctmp->ztdev->chans[2].eoftx == 1) {
458
	*f1 = newf1;
459
	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
460
	*z1 = newz1;
461
	hfctmp->ztdev->chans[2].eoftx = 0;
462
    }
463
//    printk(KERN_CRIT "zaphfc: dchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
464
    return;    
465
}
466
467
/* receive a complete hdlc frame, skip broken or short frames */
468
static void hfc_drec(struct hfc_card *hfctmp) {
469
    int count=0, maxlen=0, framelen=0;
470
    unsigned char *f1, *f2, *crcstat;
471
    unsigned short *z1, *z2, oldz2, newz2;
472
473
    hfctmp->ztdev->chans[2].bytes2receive=0;
474
    hfctmp->ztdev->chans[2].eofrx = 0;
475
476
    /* put the received data into the DAHDI buffer
477
       we'll call dahdi_receive() later when the timer fires. */
478
    f1 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F1);
479
    f2 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F2);
480
481
    if (*f1 == *f2) return; /* nothing received, strange eh? */
482
483
    z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z1 + (*f2 * 4));
484
    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
485
    
486
    /* calculate length of frame, including 2 bytes CRC and 1 byte STAT */
487
    count = *z1 - *z2;
488
    
489
    if (count < 0) { 
490
	count += hfc_D_FIFO_SIZE; /* ring buffer wrapped */
491
    }
492
    count++;
493
    framelen = count;
494
495
    crcstat = (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z1);
496
497
    if ((framelen < 4) || (*crcstat != 0x0)) {
498
	/* the frame is too short for a valid HDLC frame or the CRC is borked */
499
	printk(KERN_CRIT "zaphfc: empty HDLC frame or bad CRC received (framelen = %d, stat = %#x, card = %d).\n", framelen, *crcstat, hfctmp->cardno);
500
	oldz2 = *z2;
501
	*f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	/* NEXT!!! */
502
        // recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!!
503
	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
504
	*z2 = (oldz2 + framelen) & hfc_ZMASK;
505
	hfctmp->drecinframe = 0;
506
	hfctmp->regs.int_drec--;
507
	/* skip short or broken frames */
508
        hfctmp->ztdev->chans[2].bytes2receive = 0; 
509
	return;
510
    }
511
512
    count -= 1;	/* strip STAT */
513
    hfctmp->ztdev->chans[2].eofrx = 1;
514
515
    if (count + *z2 <= hfc_D_FIFO_SIZE) {
516
	maxlen = count;
517
    } else {
518
	maxlen = hfc_D_FIFO_SIZE - *z2;
519
    }
520
521
    /* copy first part */
522
    memcpy(hfctmp->drecbuf, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z2), maxlen);
523
    hfctmp->ztdev->chans[2].bytes2receive += maxlen; 
524
    
525
    count -= maxlen;
526
    if (count > 0) {
527
	/* ring buffer wrapped, copy rest from start of d fifo */
528
	memcpy(hfctmp->drecbuf + maxlen, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF), count);
529
	hfctmp->ztdev->chans[2].bytes2receive += count; 
530
    }
531
532
    /* frame read */
533
    oldz2 = *z2;
534
    newz2 = (oldz2 + framelen) & hfc_ZMASK;
535
    *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	/* NEXT!!! */
536
    /* recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! */
537
    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
538
    *z2 = newz2;
539
    hfctmp->drecinframe = 0;
540
    hfctmp->regs.int_drec--; 
541
}
542
543
#ifndef RTAITIMING
544
DAHDI_IRQ_HANDLER(hfc_interrupt) {
545
    struct hfc_card *hfctmp = dev_id;
546
    unsigned long flags = 0;
547
    unsigned char stat;
548
#else
549
static void hfc_service(struct hfc_card *hfctmp) {
550
#endif
551
    struct dahdi_hfc *zthfc;
552
    unsigned char s1, s2, l1state;
553
    int x;
554
555
    if (!hfctmp) {
556
#ifndef RTAITIMING
557
		return IRQ_NONE;
558
#else
559
	/* rtai */
560
	return;
561
#endif
562
    }
563
564
    if (!hfctmp->pci_io) {
565
	    printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n",
566
		   __FUNCTION__);
567
#ifndef RTAITIMING
568
	    return IRQ_NONE;
569
#else
570
	/* rtai */
571
	return;
572
#endif
573
    }
574
    
575
    /*	we assume a few things in this irq handler:
576
	- the hfc-pci will only generate "timer" irqs (proc/non-proc)
577
	- we need to use every 8th IRQ (to generate 1khz timing)
578
	OR
579
	- if we use rtai for timing the hfc-pci will not generate ANY irq,
580
	  instead rtai will call this "fake" irq with a 1khz realtime timer. :)
581
	- rtai will directly service the card, not like it used to by triggering
582
	  the linux irq
583
    */
584
585
#ifndef RTAITIMING
586
    spin_lock_irqsave(&hfctmp->lock, flags);
587
    stat = hfc_inb(hfctmp, hfc_STATUS);
588
589
    if ((stat & hfc_STATUS_ANYINT) == 0) {
590
        // maybe we are sharing the irq
591
	spin_unlock_irqrestore(&hfctmp->lock,flags);
592
	return IRQ_NONE;
593
    }
594
#endif
595
596
    s1 = hfc_inb(hfctmp, hfc_INT_S1);
597
    s2 = hfc_inb(hfctmp, hfc_INT_S2); 
598
    if (s1 != 0) {
599
	if (s1 & hfc_INTS_TIMER) {
600
	    // timer (bit 7)
601
	    // printk(KERN_CRIT "timer %d %d %d.\n", stat, s1, s2);
602
	}
603
	if (s1 & hfc_INTS_L1STATE) {
604
	    // state machine (bit 6)
605
	    // printk(KERN_CRIT "zaphfc: layer 1 state machine interrupt\n");
606
	    zthfc = hfctmp->ztdev;
607
	    l1state = hfc_inb(hfctmp,hfc_STATES)  & hfc_STATES_STATE_MASK;
608
	    if (hfctmp->regs.nt_mode == 1) {
609
		if (debug) {
610
	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = G%d\n", hfctmp->cardno, l1state);
611
		}
612
		switch (l1state) {
613
		    case 3:
614
#ifdef RTAITIMING
615
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
616
#else
617
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state);
618
#endif
619
			break;
620
		    default:
621
#ifdef RTAITIMING
622
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
623
#else
624
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state);
625
#endif
626
		}
627
		if (l1state == 2) {
628
		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3);
629
		} else if (l1state == 3) {
630
		    // fix to G3 state (see specs)
631
		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
632
		}
633
	    } else {
634
		if (debug) {
635
	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = F%d\n", hfctmp->cardno, l1state);
636
		}
637
		switch (l1state) {
638
		    case 7:
639
#ifdef RTAITIMING
640
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
641
#else
642
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state);
643
#endif
644
			break;
645
		    default:
646
#ifdef RTAITIMING
647
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
648
#else
649
			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state);
650
#endif
651
		}
652
		if (l1state == 3) {
653
		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
654
		}
655
	    }
656
	    
657
	}
658
	if (s1 & hfc_INTS_DREC) {
659
	    // D chan RX (bit 5)
660
	    hfctmp->regs.int_drec++;
661
	    // mr. zapata there is something for you!
662
	//    printk(KERN_CRIT "d chan rx\n");		    
663
	}
664
	if (s1 & hfc_INTS_B2REC) {
665
	    // B2 chan RX (bit 4)
666
	}
667
	if (s1 & hfc_INTS_B1REC) {
668
	    // B1 chan RX (bit 3)
669
	}
670
	if (s1 & hfc_INTS_DTRANS) {
671
	    // D chan TX (bit 2)
672
//	    printk(KERN_CRIT "zaphfc: dchan frame transmitted.\n");
673
	}
674
	if (s1 & hfc_INTS_B2TRANS) {
675
	    // B2 chan TX (bit 1)
676
	}
677
	if (s1 & hfc_INTS_B1TRANS) {
678
	    // B1 chan TX (bit 0)
679
	}
680
    }
681
#ifdef RTAITIMING
682
    /* fake an irq */
683
    s2 |= hfc_M2_PROC_TRANS;
684
#endif
685
    if (s2 != 0) {
686
	if (s2 & hfc_M2_PMESEL) {
687
	    // kaboom irq (bit 7)
688
	    printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n");
689
	}
690
	if (s2 & hfc_M2_GCI_MON_REC) {
691
	    // RxR monitor channel (bit 2)
692
	}
693
	if (s2 & hfc_M2_GCI_I_CHG) {
694
	    // GCI I-change  (bit 1)
695
	}
696
	if (s2 & hfc_M2_PROC_TRANS) {
697
	    // processing/non-processing transition  (bit 0)
698
	    hfctmp->ticks++;
699
#ifndef RTAITIMING
700
	    if (hfctmp->ticks > 7) {
701
		// welcome to DAHDI timing :)
702
#endif
703
	    	hfctmp->ticks = 0;
704
705
		if (hfctmp->ztdev->span.flags & DAHDI_FLAG_RUNNING) {
706
		    // clear dchan buffer
707
		    hfctmp->ztdev->chans[2].bytes2transmit = 0;
708
		    hfctmp->ztdev->chans[2].maxbytes2transmit = hfc_D_FIFO_SIZE;
709
710
		    dahdi_transmit(&(hfctmp->ztdev->span));
711
712
		    hfc_btrans(hfctmp,1);
713
		    hfc_btrans(hfctmp,2);
714
		    hfc_dtrans(hfctmp);
715
		}
716
717
		hfc_brec(hfctmp,1);
718
		hfc_brec(hfctmp,2);
719
		if (hfctmp->regs.int_drec > 0) {
720
		    // dchan data to read
721
		    hfc_drec(hfctmp);
722
		    if (hfctmp->ztdev->chans[2].bytes2receive > 0) {
723
			    if (debug) {
724
    				printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno);
725
				if (hfctmp->ztdev->chans[2].eofrx) {
726
				    /* dont output CRC == less user confusion */
727
				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive - 2; x++) {
728
					printk("%#2x ", hfctmp->drecbuf[x]);
729
				    }
730
				    printk("] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive - 2);
731
				} else {
732
				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive; x++) {
733
					printk("%#2x ", hfctmp->drecbuf[x]);
734
				    }
735
				    printk("..] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive);
736
				}
737
			    }
738
		    }
739
		} else {
740
			// hmm....ok, let DAHDI receive nothing
741
		    hfctmp->ztdev->chans[2].bytes2receive = 0;
742
		}
743
		if (hfctmp->ztdev->span.flags & DAHDI_FLAG_RUNNING) {
744
		    dahdi_receive(&(hfctmp->ztdev->span));
745
		}
746
		
747
#ifndef RTAITIMING
748
	    }
749
#endif
750
	}
751
752
    }
753
#ifndef RTAITIMING
754
    spin_unlock_irqrestore(&hfctmp->lock,flags);
755
	return IRQ_RETVAL(1);
756
#endif
757
}
758
759
760
static int zthfc_open(struct dahdi_chan *chan) {
761
    struct dahdi_hfc *zthfc = chan->pvt;
762
    struct hfc_card *hfctmp = zthfc->card;
763
    
764
    if (!hfctmp) {
765
    return 0;
766
    }
767
    try_module_get(THIS_MODULE);
768
    return 0;
769
}
770
771
static int zthfc_close(struct dahdi_chan *chan) {
772
    struct dahdi_hfc *zthfc = chan->pvt;
773
    struct hfc_card *hfctmp = zthfc->card;
774
775
    if (!hfctmp) {
776
	return 0;
777
    }
778
779
    module_put(THIS_MODULE);
780
    return 0;
781
}
782
783
static int zthfc_rbsbits(struct dahdi_chan *chan, int bits) {
784
    return 0;
785
}
786
787
static int zthfc_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data) {
788
        switch(cmd) {
789
        default:
790
                return -ENOTTY;
791
        }
792
        return 0;
793
}
794
795
static int zthfc_startup(struct dahdi_span *span) {
796
    struct dahdi_hfc *zthfc = span->pvt;
797
    struct hfc_card *hfctmp = zthfc->card;
798
    int alreadyrunning;
799
    
800
    if (hfctmp == NULL) {
801
	printk(KERN_INFO "zaphfc: no card for span at startup!\n");
802
    }
803
    alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
804
    
805
    if (!alreadyrunning) {
806
	span->chans[2]->flags &= ~DAHDI_FLAG_HDLC;
807
	span->chans[2]->flags |= DAHDI_FLAG_BRIDCHAN;
808
	
809
	span->flags |= DAHDI_FLAG_RUNNING;
810
811
	hfctmp->ticks = -2;
812
	hfctmp->clicks = 0;
813
	hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
814
        hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
815
    } else {
816
	return 0;
817
    }
818
819
    // drivers, start engines!
820
    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
821
    return 0;
822
}
823
824
static int zthfc_shutdown(struct dahdi_span *span) {
825
    return 0;
826
}
827
828
static int zthfc_maint(struct dahdi_span *span, int cmd) {
829
    return 0;
830
}
831
832
static int zthfc_chanconfig(struct dahdi_chan *chan, int sigtype) {
833
//    printk(KERN_CRIT "chan_config sigtype=%d\n", sigtype);
834
    return 0;
835
}
836
837
static int zthfc_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) {
838
    span->lineconfig = lc->lineconfig;
839
    return 0;
840
}
841
842
static int zthfc_initialize(struct dahdi_hfc *zthfc) {
843
    struct hfc_card *hfctmp = zthfc->card;
844
    int i;
845
846
    memset(&zthfc->span, 0x0, sizeof(struct dahdi_span)); // you never can tell...
847
848
    sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1);
849
    if (hfctmp->regs.nt_mode == 1) {
850
#ifdef RTAITIMING
851
	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] [realtime]", hfc_dev_count + 1);
852
#else
853
	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1);
854
#endif
855
    } else {
856
#ifdef RTAITIMING
857
	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] [realtime]", hfc_dev_count + 1);
858
#else
859
	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1);
860
#endif
861
    }
862
863
    zthfc->span.spanconfig = zthfc_spanconfig;
864
    zthfc->span.chanconfig = zthfc_chanconfig;
865
    zthfc->span.startup = zthfc_startup;
866
    zthfc->span.shutdown = zthfc_shutdown;
867
    zthfc->span.maint = zthfc_maint;
868
    zthfc->span.rbsbits = zthfc_rbsbits;
869
    zthfc->span.open = zthfc_open;
870
    zthfc->span.close = zthfc_close;
871
    zthfc->span.ioctl = zthfc_ioctl;
872
873
    zthfc->span.channels = 3;
874
    zthfc->span.chans = zthfc->_chans;
875
    for (i = 0; i < zthfc->span.channels; i++)
876
        zthfc->_chans[i] = &zthfc->chans[i];
877
    zthfc->span.deflaw = DAHDI_LAW_ALAW;
878
    zthfc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS; // <--- this is really BS
879
    zthfc->span.offset = 0;
880
    init_waitqueue_head(&zthfc->span.maintq);
881
    zthfc->span.pvt = zthfc;
882
883
    for (i = 0; i < zthfc->span.channels; i++) {
884
	memset(&(zthfc->chans[i]), 0x0, sizeof(struct dahdi_chan));
885
	sprintf(zthfc->chans[i].name, "ZTHFC%d/%d/%d", hfc_dev_count + 1,0,i + 1);
886
	zthfc->chans[i].pvt = zthfc;
887
	zthfc->chans[i].sigcap =  DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_SF;
888
	zthfc->chans[i].chanpos = i + 1; 
889
    }
890
891
    if (dahdi_register(&zthfc->span,0)) {
892
	printk(KERN_CRIT "unable to register DAHDI device!\n");
893
	return -1;
894
    }
895
//    printk(KERN_CRIT "zaphfc: registered DAHDI device!\n");
896
    return 0;
897
}
898
899
#ifdef RTAITIMING
900
#define TICK_PERIOD  1000000
901
#define TICK_PERIOD2 1000000000
902
#define TASK_PRIORITY 1
903
#define STACK_SIZE 10000
904
905
static RT_TASK rt_task;
906
static struct hfc_card *rtai_hfc_list[hfc_MAX_CARDS];
907
static unsigned char rtai_hfc_counter = 0;
908
909
static void rtai_register_hfc(struct hfc_card *hfctmp) {
910
    rtai_hfc_list[rtai_hfc_counter++] = hfctmp;
911
}
912
913
static void rtai_loop(int t) {
914
    int i=0;
915
    for (;;) {
916
	for (i=0; i < rtai_hfc_counter; i++) {
917
	    if (rtai_hfc_list[i] != NULL)
918
		hfc_service(rtai_hfc_list[i]);
919
	}
920
        rt_task_wait_period();
921
    }
922
}
923
#endif
924
925
int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) {
926
    struct pci_dev *tmp;
927
    struct hfc_card *hfctmp = NULL;
928
    struct dahdi_hfc *zthfc = NULL;
929
930
    tmp = pci_get_device(pcivendor, pcidevice, multi_hfc);
931
    while (tmp != NULL) {
932
	multi_hfc = tmp;	// skip this next time.
933
934
	if (pci_enable_device(tmp)) {
935
	    multi_hfc = NULL;
936
	    return -1;
937
	}
938
	pci_set_master(tmp);
939
940
	hfctmp = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
941
	if (!hfctmp) {
942
	    printk(KERN_WARNING "zaphfc: unable to kmalloc!\n");
943
	    pci_disable_device(tmp);
944
	    multi_hfc = NULL;
945
	    return -ENOMEM;
946
	}
947
	memset(hfctmp, 0x0, sizeof(struct hfc_card));
948
	spin_lock_init(&hfctmp->lock);
949
	
950
	hfctmp->pcidev = tmp;
951
	hfctmp->pcibus = tmp->bus->number;
952
	hfctmp->pcidevfn = tmp->devfn; 
953
954
	if (!tmp->irq) {
955
	    printk(KERN_WARNING "zaphfc: no irq!\n");
956
	} else {
957
	    hfctmp->irq = tmp->irq;
958
	}
959
960
	hfctmp->pci_io = (char *) tmp->resource[1].start;
961
	if (!hfctmp->pci_io) {
962
	    printk(KERN_WARNING "zaphfc: no iomem!\n");
963
	    kfree(hfctmp);
964
	    pci_disable_device(tmp);
965
	    multi_hfc = NULL;
966
	    return -1;
967
	}
968
	
969
	hfctmp->fifomem = kmalloc(65536, GFP_KERNEL);
970
	if (!hfctmp->fifomem) {
971
	    printk(KERN_WARNING "zaphfc: unable to kmalloc fifomem!\n");
972
	    kfree(hfctmp);
973
	    pci_disable_device(tmp);
974
	    multi_hfc = NULL;
975
	    return -ENOMEM;
976
	} else {
977
	    memset(hfctmp->fifomem, 0x0, 65536);
978
	    hfctmp->fifos = (void *)(((ulong) hfctmp->fifomem) & ~0x7FFF) + 0x8000;
979
	    pci_write_config_dword(hfctmp->pcidev, 0x80, (u_int) virt_to_bus(hfctmp->fifos));
980
	    hfctmp->pci_io = ioremap((ulong) hfctmp->pci_io, 256);
981
	}
982
983
#ifdef RTAITIMING
984
	/* we need no stinking irq */
985
	hfctmp->irq = 0;
986
#else
987
	if (request_irq(hfctmp->irq, &hfc_interrupt, DAHDI_IRQ_SHARED, "zaphfc", hfctmp)) {
988
	    printk(KERN_WARNING "zaphfc: unable to register irq\n");
989
	    kfree(hfctmp->fifomem);
990
	    kfree(hfctmp);
991
	    iounmap((void *) hfctmp->pci_io);
992
	    pci_disable_device(tmp);
993
	    multi_hfc = NULL;
994
	    return -EIO;
995
	}
996
#endif
997
998
#ifdef RTAITIMING
999
	rtai_register_hfc(hfctmp);
1000
#endif
1001
	printk(KERN_INFO
1002
		       "zaphfc: %s %s configured at mem %lx fifo %lx(%#x) IRQ %d HZ %d\n",
1003
			vendor_name, card_name,
1004
		       (unsigned long) hfctmp->pci_io,
1005
		       (unsigned long) hfctmp->fifos,
1006
		       (u_int) virt_to_bus(hfctmp->fifos),
1007
		       hfctmp->irq, HZ); 
1008
	pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
1009
	hfctmp->regs.int_m1 = 0;	// no ints
1010
	hfctmp->regs.int_m2 = 0;	// not at all
1011
	hfc_outb(hfctmp,hfc_INT_M1,hfctmp->regs.int_m1);
1012
	hfc_outb(hfctmp,hfc_INT_M2,hfctmp->regs.int_m2);
1013
1014
	if ((modes & (1 << hfc_dev_count)) != 0) {
1015
	    printk(KERN_INFO "zaphfc: Card %d configured for NT mode\n",hfc_dev_count);
1016
	    hfctmp->regs.nt_mode = 1;
1017
	} else {
1018
	    printk(KERN_INFO "zaphfc: Card %d configured for TE mode\n",hfc_dev_count);
1019
	    hfctmp->regs.nt_mode = 0;
1020
	}
1021
1022
	zthfc = kmalloc(sizeof(struct dahdi_hfc),GFP_KERNEL);
1023
	if (!zthfc) {
1024
	    printk(KERN_CRIT "zaphfc: unable to kmalloc!\n");
1025
	    hfc_shutdownCard(hfctmp);
1026
	    kfree(hfctmp);
1027
	    multi_hfc = NULL;
1028
	    return -ENOMEM;
1029
	}
1030
	memset(zthfc, 0x0, sizeof(struct dahdi_hfc));
1031
1032
	zthfc->card = hfctmp;
1033
	zthfc_initialize(zthfc);
1034
	hfctmp->ztdev = zthfc;
1035
1036
	memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf));
1037
	hfctmp->ztdev->chans[2].readchunk = hfctmp->drecbuf;
1038
1039
	memset(hfctmp->dtransbuf, 0x0, sizeof(hfctmp->dtransbuf));
1040
	hfctmp->ztdev->chans[2].writechunk = hfctmp->dtransbuf;
1041
1042
	memset(hfctmp->brecbuf[0], 0x0, sizeof(hfctmp->brecbuf[0]));
1043
	hfctmp->ztdev->chans[0].readchunk = hfctmp->brecbuf[0];
1044
	memset(hfctmp->btransbuf[0], 0x0, sizeof(hfctmp->btransbuf[0]));
1045
	hfctmp->ztdev->chans[0].writechunk = hfctmp->btransbuf[0];
1046
1047
	memset(hfctmp->brecbuf[1], 0x0, sizeof(hfctmp->brecbuf[1]));
1048
	hfctmp->ztdev->chans[1].readchunk = hfctmp->brecbuf[1];
1049
	memset(hfctmp->btransbuf[1], 0x0, sizeof(hfctmp->btransbuf[1]));
1050
	hfctmp->ztdev->chans[1].writechunk = hfctmp->btransbuf[1];
1051
1052
1053
	hfc_registerCard(hfctmp);
1054
	hfc_resetCard(hfctmp);
1055
	tmp = pci_get_device(pcivendor, pcidevice, multi_hfc);
1056
    }
1057
    return 0;
1058
}
1059
1060
1061
1062
int init_module(void) {
1063
    int i = 0;
1064
#ifdef RTAITIMING
1065
    RTIME tick_period;
1066
    for (i=0; i < hfc_MAX_CARDS; i++) {
1067
	rtai_hfc_list[i] = NULL;
1068
    }
1069
    rt_set_periodic_mode();
1070
#endif
1071
    i = 0;
1072
    while (id_list[i].vendor_id) {
1073
	multi_hfc = NULL;
1074
	hfc_findCards(id_list[i].vendor_id, id_list[i].device_id, id_list[i].vendor_name, id_list[i].card_name);
1075
	i++;
1076
    }
1077
#ifdef RTAITIMING
1078
    for (i=0; i < hfc_MAX_CARDS; i++) {
1079
        if (rtai_hfc_list[i]) {
1080
	    printk(KERN_INFO
1081
		       "zaphfc: configured %d at mem %#x fifo %#x(%#x) for realtime servicing\n",
1082
			rtai_hfc_list[i]->cardno,
1083
		       (u_int) rtai_hfc_list[i]->pci_io,
1084
		       (u_int) rtai_hfc_list[i]->fifos,
1085
		       (u_int) virt_to_bus(rtai_hfc_list[i]->fifos));
1086
1087
	}
1088
    }
1089
    rt_task_init(&rt_task, rtai_loop, 1, STACK_SIZE, TASK_PRIORITY, 0, 0);
1090
    tick_period = start_rt_timer(nano2count(TICK_PERIOD));
1091
    rt_task_make_periodic(&rt_task, rt_get_time() + tick_period, tick_period);
1092
#endif
1093
    printk(KERN_INFO "zaphfc: %d hfc-pci card(s) in this box.\n", hfc_dev_count);
1094
    return 0;
1095
}
1096
1097
void cleanup_module(void) {
1098
    struct hfc_card *tmpcard;
1099
#ifdef RTAITIMING
1100
    stop_rt_timer();
1101
    rt_task_delete(&rt_task);
1102
#endif
1103
    printk(KERN_INFO "zaphfc: stop\n");
1104
//    spin_lock(&registerlock);
1105
    while (hfc_dev_list != NULL) {
1106
	if (hfc_dev_list == NULL) break;
1107
	hfc_shutdownCard(hfc_dev_list);
1108
	tmpcard = hfc_dev_list;
1109
	hfc_dev_list = hfc_dev_list->next;
1110
	if (tmpcard != NULL) {
1111
	    kfree(tmpcard);
1112
	    tmpcard = NULL;
1113
	    printk(KERN_INFO "zaphfc: freed one card.\n");
1114
	}
1115
    }
1116
//    spin_unlock(&registerlock);
1117
}
1118
#endif
1119
1120
1121
module_param(modes, int, 0600);
1122
module_param(debug, int, 0600);
1123
1124
MODULE_DESCRIPTION("HFC-S PCI A Zaptel Driver");
1125
MODULE_AUTHOR("Klaus-Peter Junghanns <kpj@junghanns.net>");
1126
#ifdef MODULE_LICENSE
1127
MODULE_LICENSE("GPL");
1128
#endif	
(-)dahdi-linux-2.2.0/drivers/dahdi/zaphfc/zaphfc.h (+344 lines)
Line 0 Link Here
1
/*
2
 * zaphfc.h - Zaptel driver for HFC-S PCI A based ISDN BRI cards
3
 *
4
 * kernel module based on HFC PCI ISDN4Linux and Zaptel drivers
5
 *
6
 * Copyright (C) 2002, 2003, 2004, 2005 Junghanns.NET GmbH
7
 *
8
 * Klaus-Peter Junghanns <kpj@junghanns.net>
9
 *
10
 * This program is free software and may be modified and
11
 * distributed under the terms of the GNU Public License.
12
 *
13
 */
14
15
/* HFC register addresses - accessed using memory mapped I/O */
16
/* For a list, see datasheet section 3.2.1 at page 21 */
17
18
#define hfc_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
19
#define hfc_inb(a,b) (readb((a)->pci_io+(b)))
20
21
/* GCI/IOM bus monitor registers */
22
23
#define hfc_C_I       0x08
24
#define hfc_TRxR      0x0C
25
#define hfc_MON1_D    0x28
26
#define hfc_MON2_D    0x2C
27
28
29
/* GCI/IOM bus timeslot registers */
30
31
#define hfc_B1_SSL    0x80
32
#define hfc_B2_SSL    0x84
33
#define hfc_AUX1_SSL  0x88
34
#define hfc_AUX2_SSL  0x8C
35
#define hfc_B1_RSL    0x90
36
#define hfc_B2_RSL    0x94
37
#define hfc_AUX1_RSL  0x98
38
#define hfc_AUX2_RSL  0x9C
39
40
/* GCI/IOM bus data registers */
41
42
#define hfc_B1_D      0xA0
43
#define hfc_B2_D      0xA4
44
#define hfc_AUX1_D    0xA8
45
#define hfc_AUX2_D    0xAC
46
47
/* GCI/IOM bus configuration registers */
48
49
#define hfc_MST_EMOD  0xB4
50
#define hfc_MST_MODE	 0xB8
51
#define hfc_CONNECT 	 0xBC
52
53
54
/* Interrupt and status registers */
55
56
#define hfc_FIFO_EN   0x44
57
#define hfc_TRM       0x48
58
#define hfc_B_MODE    0x4C
59
#define hfc_CHIP_ID   0x58
60
#define hfc_CIRM  	 0x60
61
#define hfc_CTMT	 0x64
62
#define hfc_INT_M1  	 0x68
63
#define hfc_INT_M2  	 0x6C
64
#define hfc_INT_S1  	 0x78
65
#define hfc_INT_S2  	 0x7C
66
#define hfc_STATUS  	 0x70
67
68
/* S/T section registers */
69
70
#define hfc_STATES  	 0xC0
71
#define hfc_SCTRL  	 0xC4
72
#define hfc_SCTRL_E   0xC8
73
#define hfc_SCTRL_R   0xCC
74
#define hfc_SQ  	 0xD0
75
#define hfc_CLKDEL  	 0xDC
76
#define hfc_B1_REC    0xF0
77
#define hfc_B1_SEND   0xF0
78
#define hfc_B2_REC    0xF4
79
#define hfc_B2_SEND   0xF4
80
#define hfc_D_REC     0xF8
81
#define hfc_D_SEND    0xF8
82
#define hfc_E_REC     0xFC
83
84
/* Bits and values in various HFC PCI registers */
85
86
/* bits in status register (READ) */
87
#define hfc_STATUS_PCI_PROC   0x02
88
#define hfc_STATUS_NBUSY	  0x04 
89
#define hfc_STATUS_TIMER_ELAP 0x10
90
#define hfc_STATUS_STATINT	  0x20
91
#define hfc_STATUS_FRAMEINT	  0x40
92
#define hfc_STATUS_ANYINT	  0x80
93
94
/* bits in CTMT (Write) */
95
#define hfc_CTMT_CLTIMER    0x80
96
#define hfc_CTMT_TIM3_125   0x04
97
#define hfc_CTMT_TIM25      0x10
98
#define hfc_CTMT_TIM50      0x14
99
#define hfc_CTMT_TIM400     0x18
100
#define hfc_CTMT_TIM800     0x1C
101
#define hfc_CTMT_AUTO_TIMER 0x20
102
#define hfc_CTMT_TRANSB2    0x02
103
#define hfc_CTMT_TRANSB1    0x01
104
105
/* bits in CIRM (Write) */
106
#define hfc_CIRM_AUX_MSK    0x07
107
#define hfc_CIRM_RESET  	  0x08
108
#define hfc_CIRM_B1_REV     0x40
109
#define hfc_CIRM_B2_REV     0x80
110
111
/* bits in INT_M1 and INT_S1 */
112
#define hfc_INTS_B1TRANS  0x01
113
#define hfc_INTS_B2TRANS  0x02
114
#define hfc_INTS_DTRANS   0x04
115
#define hfc_INTS_B1REC    0x08
116
#define hfc_INTS_B2REC    0x10
117
#define hfc_INTS_DREC     0x20
118
#define hfc_INTS_L1STATE  0x40
119
#define hfc_INTS_TIMER    0x80
120
121
/* bits in INT_M2 */
122
#define hfc_M2_PROC_TRANS    0x01
123
#define hfc_M2_GCI_I_CHG     0x02
124
#define hfc_M2_GCI_MON_REC   0x04
125
#define hfc_M2_IRQ_ENABLE    0x08
126
#define hfc_M2_PMESEL        0x80
127
128
/* bits in STATES */
129
#define hfc_STATES_STATE_MASK     0x0F
130
#define hfc_STATES_LOAD_STATE    0x10
131
#define hfc_STATES_ACTIVATE	     0x20
132
#define hfc_STATES_DO_ACTION     0x40
133
#define hfc_STATES_NT_G2_G3      0x80
134
135
/* bits in HFCD_MST_MODE */
136
#define hfc_MST_MODE_MASTER	     0x01
137
#define hfc_MST_MODE_SLAVE         0x00
138
#define hfc_MST_MODE_F0_LONG_DURATION         0x08
139
/* remaining bits are for codecs control */
140
141
/* bits in HFCD_MST_EMOD */
142
#define hfc_MST_EMOD_SLOW_CLOCK_ADJ	0x01
143
144
/* bits in HFCD_SCTRL */
145
#define hfc_SCTRL_B1_ENA	     0x01
146
#define hfc_SCTRL_B2_ENA	     0x02
147
#define hfc_SCTRL_MODE_TE        0x00
148
#define hfc_SCTRL_MODE_NT        0x04
149
#define hfc_SCTRL_LOW_PRIO	     0x08
150
#define hfc_SCTRL_SQ_ENA	     0x10
151
#define hfc_SCTRL_TEST	     0x20
152
#define hfc_SCTRL_NONE_CAP	     0x40
153
#define hfc_SCTRL_PWR_DOWN	     0x80
154
155
/* bits in SCTRL_E  */
156
#define hfc_SCTRL_E_AUTO_AWAKE    0x01
157
#define hfc_SCTRL_E_DBIT_1        0x04
158
#define hfc_SCTRL_E_IGNORE_COL    0x08
159
#define hfc_SCTRL_E_CHG_B1_B2     0x80
160
161
/* bits in FIFO_EN register */
162
#define hfc_FIFOEN_B1TX   0x01
163
#define hfc_FIFOEN_B1RX   0x02
164
#define hfc_FIFOEN_B2TX   0x04
165
#define hfc_FIFOEN_B2RX   0x08
166
#define hfc_FIFOEN_DTX    0x10
167
#define hfc_FIFOEN_DRX    0x20
168
169
#define hfc_FIFOEN_B1     (hfc_FIFOEN_B1TX|hfc_FIFOEN_B1RX)
170
#define hfc_FIFOEN_B2     (hfc_FIFOEN_B2TX|hfc_FIFOEN_B2RX)
171
#define hfc_FIFOEN_D      (hfc_FIFOEN_DTX|hfc_FIFOEN_DRX)
172
173
/* bits in the CONNECT register */
174
#define hfc_CONNECT_B1_shift	0
175
#define hfc_CONNECT_B2_shift	3
176
177
#define	hfc_CONNECT_HFC_from_ST		0x0
178
#define hfc_CONNECT_HFC_from_GCI	0x1
179
#define hfc_CONNECT_ST_from_HFC		0x0
180
#define hfc_CONNECT_ST_from_GCI		0x2
181
#define hfc_CONNECT_GCI_from_HFC	0x0
182
#define	hfc_CONNECT_GCI_from_ST		0x4
183
184
/* bits in the __SSL and __RSL registers */
185
#define	hfc_SRSL_STIO	0x40
186
#define hfc_SRSL_ENABLE	0x80
187
#define hfc_SRCL_SLOT_MASK	0x1f
188
189
/* FIFO memory definitions */
190
191
#define hfc_FMASK	0x000f
192
#define hfc_ZMASK	0x01ff
193
#define hfc_ZMASKB	0x1fff
194
195
#define hfc_D_FIFO_SIZE	0x0200
196
#define hfc_B_SUB_VAL	0x0200
197
#define hfc_B_FIFO_SIZE	0x1E00
198
#define hfc_MAX_DFRAMES	0x000f
199
200
#define hfc_FIFO_DTX_Z1	0x2080
201
#define hfc_FIFO_DTX_Z2 0x2082
202
#define hfc_FIFO_DTX_F1	0x20a0
203
#define hfc_FIFO_DTX_F2	0x20a1
204
#define hfc_FIFO_DTX	0x0000
205
#define hfc_FIFO_DTX_ZOFF	0x000
206
207
#define hfc_FIFO_DRX_Z1	0x6080
208
#define hfc_FIFO_DRX_Z2 0x6082
209
#define hfc_FIFO_DRX_F1	0x60a0
210
#define hfc_FIFO_DRX_F2	0x60a1
211
#define hfc_FIFO_DRX	0x4000
212
#define hfc_FIFO_DRX_ZOFF	0x4000
213
214
#define hfc_FIFO_B1TX_Z1	0x2000
215
#define hfc_FIFO_B1TX_Z2 	0x2002
216
#define hfc_FIFO_B1RX_Z1	0x6000
217
#define hfc_FIFO_B1RX_Z2 	0x6002
218
219
#define hfc_FIFO_B1TX_F1	0x2080
220
#define hfc_FIFO_B1TX_F2	0x2081
221
#define hfc_FIFO_B1RX_F1	0x6080
222
#define hfc_FIFO_B1RX_F2	0x6081
223
224
#define hfc_FIFO_B1RX_ZOFF	0x4000
225
#define hfc_FIFO_B1TX_ZOFF	0x0000
226
227
#define hfc_FIFO_B2TX_Z1	0x2100
228
#define hfc_FIFO_B2TX_Z2 	0x2102
229
#define hfc_FIFO_B2RX_Z1	0x6100
230
#define hfc_FIFO_B2RX_Z2 	0x6102
231
232
#define hfc_FIFO_B2TX_F1	0x2180
233
#define hfc_FIFO_B2TX_F2	0x2181
234
#define hfc_FIFO_B2RX_F1	0x6180
235
#define hfc_FIFO_B2RX_F2	0x6181
236
237
#define hfc_FIFO_B2RX_ZOFF	0x6000
238
#define hfc_FIFO_B2TX_ZOFF	0x2000
239
240
#define hfc_BTRANS_THRESHOLD 128
241
#define hfc_BTRANS_THRESMASK 0x00
242
243
#define hfc_FIFO_MEM_SIZE_BYTES (32*1024)
244
#define hfc_FIFO_MEM_SIZE_PAGES ((hfc_FIFO_MEM_SIZE_BYTES+PAGE_SIZE-1)/PAGE_SIZE)
245
246
/* Structures */
247
248
typedef struct hfc_regs {
249
    unsigned char fifo_en;
250
    unsigned char ctmt;
251
    unsigned char int_m1;
252
    unsigned char int_m2;
253
    unsigned char sctrl;
254
    unsigned char sctrl_e;
255
    unsigned char sctrl_r;
256
    unsigned char connect;
257
    unsigned char trm;
258
    unsigned char mst_mode;
259
    unsigned char mst_emod;
260
    unsigned char bswapped;
261
    unsigned char nt_mode;
262
    unsigned char int_drec;
263
} hfc_regs;
264
265
struct bch {
266
    int fill_fifo,checkcnt,initialized;
267
    struct {
268
	u16 z2;
269
	struct {
270
	    volatile u16 *z1p;
271
	    volatile u8 *fifo_base;
272
	    int filled;
273
	} c[2];
274
	int diff;
275
    } rx;
276
    struct {
277
	u16 z1;
278
	struct {
279
	    volatile u16 *z1p,*z2p;
280
	    volatile u8 *fifo_base;
281
	    int filled;
282
	} c[2];
283
	int diff;
284
    } tx;
285
};
286
287
struct dch {
288
    struct {
289
	struct {
290
	    volatile u8 *p;
291
	} f1;
292
	struct {
293
	    u8 v;
294
	    struct {
295
		u16 v;
296
	    } z2;
297
	} f2;
298
    } rx;
299
    struct {
300
	struct {
301
	    u8 v;
302
	    volatile u8 *p;
303
	    struct {
304
		u16 v;
305
	    } z1;
306
	} f1;
307
	struct {
308
	    volatile u8 *p;
309
	} f2;
310
    } tx;
311
};
312
313
typedef struct hfc_card {
314
    spinlock_t lock;
315
    unsigned int irq;
316
    unsigned int iomem;
317
    int ticks;		
318
    unsigned char *pci_io;
319
    void *fifos;		// 32k aligned mem for the fifos
320
    struct hfc_regs regs;
321
    unsigned int pcibus;
322
    unsigned int pcidevfn;
323
    struct pci_dev *pcidev;
324
    struct dahdi_hfc *ztdev;
325
    int	drecinframe;
326
    unsigned char drecbuf[hfc_D_FIFO_SIZE];
327
    unsigned char dtransbuf[hfc_D_FIFO_SIZE];
328
    unsigned char brecbuf[2][DAHDI_CHUNKSIZE];
329
    unsigned char btransbuf[2][DAHDI_CHUNKSIZE];
330
    unsigned char cardno;
331
    int active;
332
    struct bch bch;
333
    struct dch dch;
334
    struct hfc_card *next;
335
} hfc_card;
336
337
typedef struct dahdi_hfc {
338
    unsigned int usecount;
339
    struct dahdi_span span;
340
    struct dahdi_chan chans[3];
341
    struct dahdi_chan *_chans[3];
342
    struct hfc_card *card;
343
} dahdi_hfc;
344
(-)dahdi-linux-2.2.0/include/dahdi/dahdi_config.h (+6 lines)
Lines 167-170 Link Here
167
 */
167
 */
168
/* #define	OPTIMIZE_CHANMUTE */
168
/* #define	OPTIMIZE_CHANMUTE */
169
169
170
/*
171
 * Uncomment the following for BRI D channels
172
 *
173
 */
174
#define CONFIG_DAHDI_BRI_DCHANS
175
170
#endif
176
#endif
(-)dahdi-linux-2.2.0/include/dahdi/kernel.h (+11 lines)
Lines 389-394 Link Here
389
	int statcount;
389
	int statcount;
390
	int lastnumbufs;
390
	int lastnumbufs;
391
#endif
391
#endif
392
#ifdef CONFIG_DAHDI_BRI_DCHANS
393
	int bytes2receive;
394
	int maxbytes2transmit; /* size of the tx buffer in the card driver */
395
	int bytes2transmit;
396
	int eofrx;
397
	int eoftx;
398
#endif
392
	spinlock_t lock;
399
	spinlock_t lock;
393
	char name[40];
400
	char name[40];
394
	/* Specified by DAHDI */
401
	/* Specified by DAHDI */
Lines 693-698 Link Here
693
	DAHDI_FLAGBIT_LOOPED	= 18,	/*!< Loopback the receive data from the channel to the transmit */
700
	DAHDI_FLAGBIT_LOOPED	= 18,	/*!< Loopback the receive data from the channel to the transmit */
694
	DAHDI_FLAGBIT_MTP2	= 19,	/*!< Repeats last message in buffer and also discards repeating messages sent to us */
701
	DAHDI_FLAGBIT_MTP2	= 19,	/*!< Repeats last message in buffer and also discards repeating messages sent to us */
695
	DAHDI_FLAGBIT_HDLC56	= 20,	/*!< Sets the given channel (if in HDLC mode) to use 56K HDLC instead of 64K  */
702
	DAHDI_FLAGBIT_HDLC56	= 20,	/*!< Sets the given channel (if in HDLC mode) to use 56K HDLC instead of 64K  */
703
#if defined(CONFIG_DAHDI_BRI_DCHANS)
704
	DAHDI_FLAGBIT_BRIDCHAN   = 21,	/*!< hardhdlc-like handling of the D channel */
705
#endif
696
};
706
};
697
707
698
/* map flagbits to flag masks */
708
/* map flagbits to flag masks */
Lines 731-736 Link Here
731
#define DAHDI_FLAG_LOOPED	DAHDI_FLAG(LOOPED)
741
#define DAHDI_FLAG_LOOPED	DAHDI_FLAG(LOOPED)
732
#define DAHDI_FLAG_MTP2		DAHDI_FLAG(MTP2)
742
#define DAHDI_FLAG_MTP2		DAHDI_FLAG(MTP2)
733
#define DAHDI_FLAG_HDLC56	DAHDI_FLAG(HDLC56)
743
#define DAHDI_FLAG_HDLC56	DAHDI_FLAG(HDLC56)
744
#define DAHDI_FLAG_BRIDCHAN	DAHDI_FLAG(BRIDCHAN)
734
745
735
struct dahdi_span {
746
struct dahdi_span {
736
	spinlock_t lock;
747
	spinlock_t lock;

Return to bug 275635