patch-2.3.13 linux/drivers/char/hfmodem/modem.c

Next file: linux/drivers/char/hfmodem/refclock.c
Previous file: linux/drivers/char/hfmodem/main.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.12/linux/drivers/char/hfmodem/modem.c linux/drivers/char/hfmodem/modem.c
@@ -1,792 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      modem.c  --  Linux soundcard HF FSK driver,
- *                   Modem code.
- *
- *      Copyright (C) 1997  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *        Swiss Federal Institute of Technology (ETH), Electronics Lab
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- */
-
-/*****************************************************************************/
-      
-
-#include <linux/wait.h>
-#include <linux/malloc.h>
-#include <linux/hfmodem.h>
-
-/* --------------------------------------------------------------------- */
-
-/*
- * currently this module is supposed to support both module styles, i.e.
- * the old one present up to about 2.1.9, and the new one functioning
- * starting with 2.1.21. The reason is I have a kit allowing to compile
- * this module also under 2.0.x which was requested by several people.
- * This will go in 2.2
- */
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= 0x20100
-#include <asm/uaccess.h>
-#else
-#include <asm/segment.h>
-#include <linux/mm.h>
-
-#undef put_user
-#undef get_user
-
-#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
-#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
-
-extern inline int copy_from_user(void *to, const void *from, unsigned long n)
-{
-        int i = verify_area(VERIFY_READ, from, n);
-        if (i)
-                return i;
-        memcpy_fromfs(to, from, n);
-        return 0;
-}
-
-extern inline int copy_to_user(void *to, const void *from, unsigned long n)
-{
-        int i = verify_area(VERIFY_WRITE, to, n);
-        if (i)
-                return i;
-        memcpy_tofs(to, from, n);
-        return 0;
-}
-#endif
-
-#if LINUX_VERSION_CODE >= 0x20123
-#include <linux/init.h>
-#else
-#define __init
-#define __initdata
-#define __initfunc(x) x
-#endif
-
-/* --------------------------------------------------------------------- */
-
-struct hfmodem_correlator_cache hfmodem_correlator_cache[HFMODEM_CORRELATOR_CACHE];
-
-/* --------------------------------------------------------------------- */
-
-#include "tables.h"
-
-#define M_PI        3.14159265358979323846      /* pi */
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ int isimplecos(unsigned int arg)
-{
-	return isintab[((arg+0x4000) >> (16-SINTABBITS)) & (SINTABSIZE-1)];
-}
-
-extern __inline__ int isimplesin(unsigned int arg)
-{
-	return isintab[(arg >> (16-SINTABBITS)) & (SINTABSIZE-1)];
-}
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ int itblcos(unsigned int arg)
-{
-	unsigned int x;
-	int dx;
-	int s, c;
-
-	x = (arg + (0x8000 >> SINTABBITS)) & (0xffffu & (0xffffu << (16-SINTABBITS)));
-	dx = arg - x;
-	x >>= (16-SINTABBITS);
-	c = isintab[x+(0x4000 >> (16-SINTABBITS))];
-	s = isintab[x];
-	return c - ((s * dx * (int)(M_PI*64.0)) >> 21);
-}
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ void itblcossin(unsigned int arg, int *cos, int *sin)
-{
-	unsigned int x;
-	int dx;
-	int s, c;
-
-	x = (arg + (0x8000 >> SINTABBITS)) & (0xffffu & (0xffffu << (16-SINTABBITS)));
-	dx = arg - x;
-	x >>= (16-SINTABBITS);
-	c = isintab[x+(0x4000 >> (16-SINTABBITS))];
-	s = isintab[x];
-	*cos = c - ((s * dx * (int)(M_PI*64.0)) >> 21);
-	*sin = s + ((c * dx * (int)(M_PI*64.0)) >> 21);
-}
-
-/* --------------------------------------------------------------------- */
-
-static unsigned short random_seed;
-
-extern __inline__ unsigned short random_num(void)
-{
-        random_seed = 28629 * random_seed + 157;
-        return random_seed;
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * correlator cache routines
- */
-
-extern __inline__ void cc_lock(unsigned int u)
-{
-	if (u >= HFMODEM_CORRELATOR_CACHE)
-		return;
-	hfmodem_correlator_cache[u].refcnt++;
-}
-
-extern __inline__ void cc_unlock(unsigned int u)
-{
-	if (u >= HFMODEM_CORRELATOR_CACHE)
-		return;
-	if ((--hfmodem_correlator_cache[u].refcnt) <= 0) {
-		unsigned int i;
-
-		for (i = 0; i < HFMODEM_CORRELATOR_CACHE; i++) 
-			if (hfmodem_correlator_cache[i].lru < 32767)
-				hfmodem_correlator_cache[i].lru++;
-		hfmodem_correlator_cache[u].lru = 0;
-		hfmodem_correlator_cache[u].refcnt = 0;
-	}
-}
-
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ unsigned int cc_lookup(unsigned short phinc0, unsigned short phinc1)
-{
-	unsigned int j;
-
-	/* find correlator cache entry */
-	for (j = 0; j < HFMODEM_CORRELATOR_CACHE; j++) 
-		if (hfmodem_correlator_cache[j].phase_incs[0] == phinc0 &&
-		    hfmodem_correlator_cache[j].phase_incs[1] == phinc1)
-			return j;
-	return ~0;
-}
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ unsigned int cc_replace(void)
-{
-	unsigned int j, k = HFMODEM_CORRELATOR_CACHE;
-	int l = -1;
-
-	for (j = 0; j < HFMODEM_CORRELATOR_CACHE; j++)
-		if (hfmodem_correlator_cache[j].refcnt <= 0 && hfmodem_correlator_cache[j].lru > l) {
-			k = j;
-			l = hfmodem_correlator_cache[j].lru;
-		}
-	if (k < HFMODEM_CORRELATOR_CACHE)
-		return k;
-	printk(KERN_ERR "%s: modem: out of filter coefficient cache entries\n", hfmodem_drvname);
-	return random_num() % HFMODEM_CORRELATOR_CACHE;
-}
-
-/* --------------------------------------------------------------------- */
-
-#define SH1  8     /* min. ceil(log2(L1CORR_LEN)) - (31-(2*15-1)) */
-#define SH2  (3*15-2*SH1)
-
-#ifdef __i386__
-
-extern __inline__ int icorr(int n, const int *coeff, const short *inp)
-{
-	int ret, rethi, tmp1 = 0, tmp2 = 0;
-
-	__asm__("\n1:\n\t"
-		"movswl (%0),%%eax\n\t"
-		"imull (%1)\n\t"
-		"subl $2,%0\n\t"
-		"addl $4,%1\n\t"
-		"addl %%eax,%3\n\t"
-		"adcl %%edx,%4\n\t"
-		"decl %2\n\t"
-		"jne 1b\n\t"
-		: "=&S" (inp), "=&D" (coeff), "=&c" (n), "=m" (tmp1), "=m" (tmp2)
-		: "0" (inp), "1" (coeff), "2" (n)
-		: "ax", "dx");
-	__asm__("shrdl %2,%1,%0\n\t"
-		"# sarl %2,%1\n\t"
-		: "=&r" (ret), "=&r" (rethi)
-		: "i" (SH1), "0" (tmp1), "1" (tmp2));
-
-
-	return ret;
-}
-
-#else /* __i386__ */
-
-extern __inline__ int icorr(int n, const int *coeff, const short *inp)
-{
-	long long sum = 0;
-	int i;
-
-	for (i = n; i > 0; i--, coeff++, inp--)
-		sum += (*coeff) * (*inp);
-	sum >>= SH1;
-	return sum;
-}
-
-#endif /* __i386__ */
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ long long isqr(int x) __attribute__ ((const));
-
-extern __inline__ long long isqr(int x)
-{
-	return ((long long)x) * ((long long)x);
-}
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ hfmodem_soft_t do_filter(struct hfmodem_l1_rxslot *slot, short *s)
-{
-	unsigned int cc = slot->corr_cache;
-	long long ll;
-
-	if (cc >= HFMODEM_CORRELATOR_CACHE) {
-		printk(KERN_ERR "do_filter: correlator cache index overrange\n");
-		return 0;
-	}
-	ll = isqr(icorr(slot->corrlen, hfmodem_correlator_cache[cc].correlator[1][0], s)) +
-		isqr(icorr(slot->corrlen, hfmodem_correlator_cache[cc].correlator[1][1], s)) -
-		isqr(icorr(slot->corrlen, hfmodem_correlator_cache[cc].correlator[0][0], s)) -
-		isqr(icorr(slot->corrlen, hfmodem_correlator_cache[cc].correlator[0][1], s));
-	ll >>= SH2;
-       	return (ll * slot->scale) >> 23;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void cc_prepare(struct hfmodem_l1_rxslot *slot, unsigned short phinc0, unsigned short phinc1)
-{
-	unsigned int j, k, l, ph, phinc;
-
-	slot->scale = (1<<23) / (slot->corrlen*slot->corrlen);
-
-	j = cc_lookup(phinc0, phinc1);
-	if (j >= HFMODEM_CORRELATOR_CACHE) {
-		j = cc_replace();
-		/* calculate the correlator values */
-		printk(KERN_DEBUG "%s: corr cache calc: %u  phases: 0x%04x 0x%04x\n", 
-		       hfmodem_drvname, j, phinc0, phinc1);
-		hfmodem_correlator_cache[j].phase_incs[0] = phinc0;
-		hfmodem_correlator_cache[j].phase_incs[1] = phinc1;
-		for (k = 0; k < 2; k++) {
-			phinc = hfmodem_correlator_cache[j].phase_incs[k];
-			for (ph = l = 0; l < HFMODEM_MAXCORRLEN; l++, ph = (ph + phinc) & 0xffff)
-				itblcossin(ph, &hfmodem_correlator_cache[j].correlator[k][0][l],
-					   &hfmodem_correlator_cache[j].correlator[k][1][l]);
-		}
-		hfmodem_correlator_cache[j].refcnt = 0;
-
-#if 0
-		printk(KERN_DEBUG "%s: corr: %u ph: 0x%04x 0x%04x\n", hfmodem_drvname, j, 
-		       hfmodem_correlator_cache[j].phase_incs[0],
-		       hfmodem_correlator_cache[j].phase_incs[1]);
-		for (l = 0; l < HFMODEM_MAXCORRLEN; l++)
-			printk(KERN_DEBUG "%s: corr: %6d %6d %6d %6d\n", hfmodem_drvname, 
-			       hfmodem_correlator_cache[j].correlator[0][0][l],
-			       hfmodem_correlator_cache[j].correlator[0][1][l],
-			       hfmodem_correlator_cache[j].correlator[1][0][l],
-			       hfmodem_correlator_cache[j].correlator[1][1][l]);
-#endif
-	}
-	slot->corr_cache = j;
-	cc_lock(j);
-}
-
-/* --------------------------------------------------------------------- */
-
-void hfmodem_clear_rq(struct hfmodem_state *dev)
-{
-	unsigned long flags;
-	unsigned int i;
-
-	save_flags(flags);
-	cli();
-	for (i = 0; i < HFMODEM_NUMRXSLOTS; i++) {
-		if (dev->l1.rxslots[i].state == ss_unused)
-			continue;
-		dev->l1.rxslots[i].state = ss_unused;
-		kfree_s(dev->l1.rxslots[i].data, dev->l1.rxslots[i].nbits * sizeof(hfmodem_soft_t));
-	}
-	for (i = 0; i < HFMODEM_NUMTXSLOTS; i++) {
-		if (dev->l1.txslots[i].state == ss_unused)
-			continue;
-		dev->l1.txslots[i].state = ss_unused;
-		kfree_s(dev->l1.txslots[i].data, (dev->l1.txslots[i].nbits + 7) >> 3);
-	}
-	for (i = 0; i < HFMODEM_CORRELATOR_CACHE; i++)
-		hfmodem_correlator_cache[i].refcnt = 0;
-	restore_flags(flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-int hfmodem_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct hfmodem_state *dev = &hfmodem_state[0];
-	struct hfmodem_ioctl_fsk_tx_request txrq;
-	struct hfmodem_ioctl_fsk_rx_request rxrq;
-	struct hfmodem_ioctl_mixer_params mix;
-	struct hfmodem_ioctl_sample_params spar;
-	unsigned long flags;
-	unsigned int len;
-	int ret, i, idx;
-	void *data, *userdata;
-	hfmodem_id_t id;
-	hfmodem_time_t tm = 0;
-	
-	if (!dev->active)
-		return -EBUSY;
-	switch(cmd) {
-	default:
-		return -EINVAL;
-		
-	case HFMODEM_IOCTL_FSKTXREQUEST:
-		if ((ret = copy_from_user(&txrq, (void *)arg, sizeof(txrq))))
-			return ret;
-		if (txrq.nbits > HFMODEM_MAXBITS)
-			return -EINVAL;
-		len = (txrq.nbits + 7) >> 3;
-		if (!(data = kmalloc(len, GFP_KERNEL)))
-			return -ENOMEM;
-		if (copy_from_user(data, txrq.data, len)) {
-			kfree_s(data, len);
-			return -EFAULT;
-		}
-		save_flags(flags);
-		cli();
-		for (i = 0; i < HFMODEM_NUMTXSLOTS && dev->l1.txslots[i].state != ss_unused; i++);
-		if (i >= HFMODEM_NUMTXSLOTS) {
-			restore_flags(flags);
-			kfree_s(data, len);
-			return -EBUSY;
-		}
-		dev->l1.txslots[i].state = ss_ready;
-		dev->l1.txslots[i].tstart = txrq.tstart;
-		dev->l1.txslots[i].tinc = txrq.tinc;
-		dev->l1.txslots[i].data = data;
-		dev->l1.txslots[i].nbits = txrq.nbits;
-		dev->l1.txslots[i].cntbits = 0;
-		dev->l1.txslots[i].inv = txrq.inv ? 0xff : 0;
-		dev->l1.txslots[i].id = txrq.id;
-		dev->l1.txslots[i].phase_incs[0] = ((txrq.freq[0]*0x10000+(HFMODEM_SRATE/2))/HFMODEM_SRATE)
-			& 0xffff;
-		dev->l1.txslots[i].phase_incs[1] = ((txrq.freq[1]*0x10000+(HFMODEM_SRATE/2))/HFMODEM_SRATE)
-			& 0xffff;
-		restore_flags(flags);
-		return 0;
-		
-	case HFMODEM_IOCTL_FSKRXREQUEST:
-		if ((ret = copy_from_user(&rxrq, (void *)arg, sizeof(rxrq))))
-			return ret;
-		if (rxrq.nbits > HFMODEM_MAXBITS)
-			return -EINVAL;
-		if (rxrq.baud < HFMODEM_MINBAUD || rxrq.baud > HFMODEM_MAXBAUD)
-			return -EINVAL;
-		len = rxrq.nbits * sizeof(hfmodem_soft_t);
-		if (verify_area(VERIFY_WRITE, rxrq.data, len))
-			return -EFAULT;
-		if (!(data = kmalloc(len, GFP_KERNEL)))
-			return -ENOMEM;
-		save_flags(flags);
-		cli();
-		for (i = 0; i < HFMODEM_NUMRXSLOTS && dev->l1.rxslots[i].state != ss_unused; i++);
-		if (i >= HFMODEM_NUMRXSLOTS) {
-			restore_flags(flags);
-			kfree_s(data, len);
-			return -EBUSY;
-		}
-		dev->l1.rxslots[i].state = ss_ready;
-		dev->l1.rxslots[i].tstart = rxrq.tstart;
-		dev->l1.rxslots[i].tinc = rxrq.tinc;
-		dev->l1.rxslots[i].data = data;
-		dev->l1.rxslots[i].userdata = rxrq.data;
-		dev->l1.rxslots[i].nbits = rxrq.nbits;
-		dev->l1.rxslots[i].cntbits = 0;
-		dev->l1.rxslots[i].id = rxrq.id;
-		dev->l1.rxslots[i].corrlen = HFMODEM_SRATE/rxrq.baud;
-		cc_prepare(dev->l1.rxslots+i, 
-			   ((rxrq.freq[0]*0x10000+(HFMODEM_SRATE/2))/HFMODEM_SRATE) & 0xffff,
-			   ((rxrq.freq[1]*0x10000+(HFMODEM_SRATE/2))/HFMODEM_SRATE) & 0xffff);
-		restore_flags(flags);
-		return 0;
-		
-	case HFMODEM_IOCTL_CLEARRQ:
-		hfmodem_clear_rq(dev);
-		return 0;
-		
-	case HFMODEM_IOCTL_GETCURTIME:
-		return put_user(dev->l1.last_time + 20000L, (hfmodem_time_t *)arg); /* heuristic */
-	
-	case HFMODEM_IOCTL_WAITRQ:
-		save_flags(flags);
-		cli();
-		ret = 0;
-		for (idx = -1, i = 0; i < HFMODEM_NUMRXSLOTS; i++) {
-			if (dev->l1.rxslots[i].state == ss_unused)
-				continue;
-			if (dev->l1.rxslots[i].state != ss_retired) {
-				ret++;
-				continue;
-			}
-			if (idx < 0 || (signed)(tm - dev->l1.rxslots[i].tstart) > 0) {
-				idx = i;
-				tm = dev->l1.rxslots[i].tstart;
-			}
-		}
-		if (idx >= 0) {
-			cc_unlock(dev->l1.rxslots[idx].corr_cache);
-			id = dev->l1.rxslots[idx].id;
-			data = dev->l1.rxslots[idx].data;
-			userdata = dev->l1.rxslots[idx].userdata;
-			len = dev->l1.rxslots[idx].nbits * sizeof(hfmodem_soft_t);
-			dev->l1.rxslots[idx].state = ss_unused;
-			restore_flags(flags);
-			ret = copy_to_user(userdata, data, len);
-			kfree_s(data, len);
-			return (put_user(id, (hfmodem_id_t *)arg)) ? -EFAULT : ret;
-		}
-		for (idx = -1, i = 0; i < HFMODEM_NUMTXSLOTS; i++) {
-			if (dev->l1.txslots[i].state == ss_unused)
-				continue;
-			if (dev->l1.txslots[i].state != ss_retired) {
-				ret++;
-				continue;
-			}
-			if (idx < 0 || (signed)(tm - dev->l1.txslots[i].tstart) > 0) {
-				idx = i;
-				tm = dev->l1.txslots[i].tstart;
-			}
-		}
-		if (idx >= 0) {
-			id = dev->l1.txslots[idx].id;
-			data = dev->l1.txslots[idx].data;
-			len = (dev->l1.txslots[idx].nbits + 7) >> 3;
-			dev->l1.txslots[idx].state = ss_unused;
-			restore_flags(flags);
-			kfree_s(data, len);
-			return put_user(id, (hfmodem_id_t *)arg);
-		}
-		restore_flags(flags);
-		return ret ? -EAGAIN : -EPIPE;
-
-	case HFMODEM_IOCTL_MIXERPARAMS:
-		if ((ret = copy_from_user(&mix, (void *)arg, sizeof(mix))))
-			return ret;
-		dev->scops->mixer(dev, mix.src, mix.igain, mix.ogain);
-		return 0;
-		
-	case HFMODEM_IOCTL_SAMPLESTART:
-		save_flags(flags);
-		cli();
-		if (dev->sbuf.kbuf) 
-			kfree_s(dev->sbuf.kbuf, dev->sbuf.size);
-		dev->sbuf.kbuf = dev->sbuf.kptr = NULL;
-		dev->sbuf.size = dev->sbuf.rem = 0;
-		restore_flags(flags);
-		if ((ret = copy_from_user(&spar, (void *)arg, sizeof(spar))))
-			return ret;
-		if (spar.len == 0)
-			return 0;
-		if (spar.len < 2 || spar.len > 8192)
-			return -EINVAL;
-		if (verify_area(VERIFY_WRITE, spar.data, spar.len * sizeof(__s16)))
-			return -EFAULT;
-		if (!(dev->sbuf.kbuf = kmalloc(spar.len * sizeof(__s16), GFP_KERNEL)))
-			return -ENOMEM;
-		save_flags(flags);
-		cli();
-		dev->sbuf.kptr = dev->sbuf.kbuf;
-		dev->sbuf.size = spar.len * sizeof(__s16);
-		dev->sbuf.rem = spar.len;
-		dev->sbuf.ubuf = spar.data;
-		restore_flags(flags);
-		return 0;
-		
-	case HFMODEM_IOCTL_SAMPLEFINISHED:
-		save_flags(flags);
-		cli();
-		if (dev->sbuf.rem > 0) {
-			restore_flags(flags);
-			return -EAGAIN;
-		}
-		if (!dev->sbuf.kbuf || !dev->sbuf.size) {
-			restore_flags(flags);
-			return -EPIPE;
-		}
-		restore_flags(flags);
-		ret = copy_to_user(dev->sbuf.ubuf, dev->sbuf.kbuf, dev->sbuf.size);
-		kfree_s(dev->sbuf.kbuf, dev->sbuf.size);
-		dev->sbuf.kbuf = dev->sbuf.kptr = NULL;
-		dev->sbuf.size = dev->sbuf.rem = 0;
-		return ret;
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-#if LINUX_VERSION_CODE >= 0x20100
-
-unsigned int hfmodem_poll(struct file *file, poll_table *wait)
-{
-	struct hfmodem_state *dev = &hfmodem_state[0];
-	unsigned long flags;
-	int i, cnt1, cnt2;
-	
-	poll_wait(file, &dev->wait, wait);
-	save_flags(flags);
-	cli();
-	for (i = cnt1 = cnt2 = 0; i < HFMODEM_NUMTXSLOTS; i++) {
-		if (dev->l1.txslots[i].state == ss_retired)
-			cnt1++;
-		if (dev->l1.txslots[i].state != ss_unused)
-			cnt2++;
-	}
-	for (i = 0; i < HFMODEM_NUMRXSLOTS; i++) {
-		if (dev->l1.rxslots[i].state == ss_retired)
-			cnt1++;
-		if (dev->l1.rxslots[i].state != ss_unused)
-			cnt2++;
-	}
-	restore_flags(flags);
-        if (cnt1 || !cnt2)
-                return POLLIN | POLLRDNORM;
-        return 0;
-}
-
-#else 
-
-int hfmodem_select(struct inode *inode, struct file *file, int sel_type, select_table *wait)
-{
-	struct hfmodem_state *dev = &hfmodem_state[0];
-	unsigned long flags;
-	int i, cnt1, cnt2;
-	
-	if (sel_type == SEL_IN) {
-		save_flags(flags);
-		cli();
-		for (i = cnt1 = cnt2 = 0; i < HFMODEM_NUMTXSLOTS; i++) {
-			if (dev->l1.txslots[i].state == ss_retired)
-				cnt1++;
-			if (dev->l1.txslots[i].state != ss_unused)
-				cnt2++;
-		}
-		for (i = 0; i < HFMODEM_NUMRXSLOTS; i++) {
-			if (dev->l1.rxslots[i].state == ss_retired)
-				cnt1++;
-			if (dev->l1.rxslots[i].state != ss_unused)
-				cnt2++;
-		}
-		restore_flags(flags);
-		if (cnt1 || !cnt2)
-			return 1;
-		select_wait(&dev->wait, wait);
-    	}
-	return 0;
-}
-
-#endif
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ unsigned int l1fsk_phinc(struct hfmodem_l1_txslot *txs, unsigned int nbit)
-{
-	return txs->phase_incs[!!((txs->data[nbit >> 3] ^ txs->inv) & (1 << (nbit & 7)))];
-}
-
-/* --------------------------------------------------------------------- */
-
-void hfmodem_input_samples(struct hfmodem_state *dev, hfmodem_time_t tstart, 
-			 hfmodem_time_t tinc, __s16 *samples)
-{
-	hfmodem_time_t tst, tend;
-	__s16 *s;
-	int i, j;
-	hfmodem_soft_t sample;
-
-	dev->l1.last_time = tstart + (HFMODEM_FRAGSAMPLES-1) * tinc;
-	for (i = 0; i < HFMODEM_NUMRXSLOTS; i++) {
-		struct hfmodem_l1_rxslot *rxs = dev->l1.rxslots + i;
-
-		if (rxs->state == ss_unused || rxs->state == ss_retired)
-			continue;
-		tst = tstart - (rxs->corrlen-1) * tinc;
-		tend = tst + (HFMODEM_FRAGSAMPLES-1) * tinc;
-		if (rxs->state == ss_ready) {
-			if ((signed)(rxs->tstart - tend) > 0) 
-				continue;
-			rxs->state = ss_oper;
-		}
-		for (s = samples, j = 0; j < HFMODEM_FRAGSAMPLES; j++, s++, tst += tinc)
-			if ((signed)(rxs->tstart - tst) <= 0) {
-				sample = do_filter(rxs, s);
-				while ((signed)(rxs->tstart - tst) <= 0 && 
-				       rxs->cntbits < rxs->nbits) {
-					rxs->data[rxs->cntbits] = sample;
-					rxs->cntbits++;
-					rxs->tstart += rxs->tinc;
-				}
-				if (rxs->cntbits >= rxs->nbits) {
-					rxs->state = ss_retired;
-					break;
-				}
-			}
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-extern __inline__ unsigned int output_one_sample(struct hfmodem_state *dev, hfmodem_time_t tm)
-{
-	int i, j, k;
-	struct hfmodem_l1_txslot *txs;
-	/*
-	 * first activate new output slots
-	 */
-	for (j = -1, i = 0; i < HFMODEM_NUMTXSLOTS; i++) {
-		txs = dev->l1.txslots + i;
-		if (txs->state == ss_ready && (signed)(txs->tstart - tm) <= 0) {
-			for (k = 0; k < HFMODEM_NUMTXSLOTS; k++) {
-				if (dev->l1.txslots[k].state != ss_oper)
-					continue;
-				dev->l1.txslots[k].state = ss_retired;
-			}
-			txs->state = ss_oper;
-			txs->tstart += txs->tinc;
-			txs->phinc = l1fsk_phinc(txs, 0);
-			txs->cntbits = 1;
-		};
-		if (txs->state != ss_oper)
-			continue;
-		j = i;
-	}
-	if (j < 0 || j >= HFMODEM_NUMTXSLOTS)
-		return 0;
-	/*
-	 * calculate the current slot
-	 */
-	txs = dev->l1.txslots + j;
-	while ((signed)(txs->tstart - tm) <= 0) {
-		if (txs->cntbits >= txs->nbits) {
-			txs->state = ss_retired;
-			return 0;
-		}
-		txs->tstart += txs->tinc;
-		txs->phinc = l1fsk_phinc(txs, txs->cntbits);
-		txs->cntbits++;
-	}
-	return txs->phinc;
-}
-
-/* --------------------------------------------------------------------- */
-
-int hfmodem_output_samples(struct hfmodem_state *dev, hfmodem_time_t tstart, 
-			   hfmodem_time_t tinc, __s16 *samples)
-{
-	int i, j;
-	hfmodem_time_t tend = tstart + (HFMODEM_FRAGSAMPLES-1) * tinc;
-
-	for (i = 0; i < HFMODEM_NUMTXSLOTS; i++) {
-		if (dev->l1.txslots[i].state == ss_oper)
-			break;
-		if (dev->l1.txslots[i].state == ss_ready && 
-		    (signed)(dev->l1.txslots[i].tstart - tend) <= 0)
-			break;
-	}
-	if (i >= HFMODEM_NUMTXSLOTS)
-		return 0;
-	for (j = 0; j < HFMODEM_FRAGSAMPLES; j++, tstart += tinc, samples++) {
-		*samples = isimplecos(dev->l1.tx_phase);
-		dev->l1.tx_phase += output_one_sample(dev, tstart);
-	}
-	return 1;
-}
-
-/* --------------------------------------------------------------------- */
-
-long hfmodem_next_tx_event(struct hfmodem_state *dev, hfmodem_time_t curr)
-{
-	long diff = LONG_MAX, t;
-	int i;
-
-	for (i = 0; i < HFMODEM_NUMTXSLOTS; i++) {
-		if (dev->l1.txslots[i].state == ss_oper)
-			if (diff > 0)
-				diff = 0;
-		if (dev->l1.txslots[i].state == ss_ready) {
-			t = dev->l1.txslots[i].tstart - curr;
-			if (t < diff)
-				diff = t;
-		}
-	}
-	return diff;
-}
-
-/* --------------------------------------------------------------------- */
-
-void hfmodem_finish_pending_rx_requests(struct hfmodem_state *dev)
-{
-	int i;
-
-	for (i = 0; i < HFMODEM_NUMRXSLOTS; i++) {
-		if (dev->l1.rxslots[i].state != ss_oper)
-			continue;
-		while (dev->l1.rxslots[i].cntbits < dev->l1.rxslots[i].nbits) {
-			dev->l1.rxslots[i].data[dev->l1.rxslots[i].cntbits] = 0;
-			dev->l1.rxslots[i].cntbits++;
-		}
-		dev->l1.rxslots[i].state = ss_retired;
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-void hfmodem_wakeup(struct hfmodem_state *dev)
-{
-	int i, cnt1, cnt2;
-	
-	for (i = cnt1 = cnt2 = 0; i < HFMODEM_NUMTXSLOTS; i++) {
-		if (dev->l1.txslots[i].state == ss_retired)
-			cnt1++;
-		if (dev->l1.txslots[i].state != ss_unused)
-			cnt2++;
-	}
-	for (i = 0; i < HFMODEM_NUMRXSLOTS; i++) {
-		if (dev->l1.rxslots[i].state == ss_retired)
-			cnt1++;
-		if (dev->l1.rxslots[i].state != ss_unused)
-			cnt2++;
-	}
-	if (cnt1 || !cnt2)
-		wake_up_interruptible(&dev->wait);
-}
-
-/* --------------------------------------------------------------------- */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)