⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icn.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 /* $Id: icn.c,v 1.1.1.1 1999/11/15 13:42:15 vadim Exp $ * ISDN low-level module for the ICN active ISDN-Card. * * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) * * 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, 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. * * $Log: icn.c,v $ * Revision 1.1.1.1  1999/11/15 13:42:15  vadim * Initial import * * Revision 1.45.2.4  1998/11/05 22:13:02  fritz * Changed mail-address. * * Revision 1.45.2.3  1998/06/07 13:32:04  fritz * Minor bugfixes for broken Switches. * * Revision 1.45.2.2  1998/03/07 23:35:36  detabc * added the abc-extension to the linux isdn-kernel * for kernel-version 2.0.xx * DO NOT USE FOR HIGHER KERNELS-VERSIONS * all source-lines are switched with the define  CONFIG_ISDN_WITH_ABC * (make config and answer ABC-Ext. Support (Compress,TCP-Keepalive ...) with yes * * you need also a modified isdnctrl-source the switch on the * features of the abc-extension * * please use carefully. more detail will be follow. * thanks * * Revision 1.45.2.1  1997/08/21 15:56:50  fritz * Synchronized 2.0.X branch with 2.0.31-pre7 * * Revision 1.45  1997/06/21 10:42:06  fritz * Added availability to select leased mode on only one channel. * * Revision 1.44  1997/03/30 16:51:26  calle * changed calls to copy_from_user/copy_to_user and removed verify_area * were possible. * * Revision 1.43  1997/03/21 18:27:04  fritz * Corrected parsing of incoming setup. * * Revision 1.42  1997/03/05 21:13:18  fritz * Bugfix: sndcount was not reset on hangup. * * Revision 1.41  1997/02/24 23:34:29  fritz * Bugfix in Layer1 error-recovery. * * Revision 1.40  1997/02/23 23:34:45  fritz * Minor bugfixes in debugging code. * * Revision 1.39  1997/02/23 16:21:56  fritz * Bugfix: Check for NULL pointer in icn_parse_status(). * * Revision 1.38  1997/02/11 18:29:31  fritz * Bugfix in D64S initialization. * * Revision 1.37  1997/02/10 22:43:20  fritz * Added plan and screen elements on ISDN_STAT_ICALL * * Revision 1.36  1997/02/10 21:31:20  fritz * Changed setup-interface (incoming and outgoing). * * Revision 1.35  1997/02/10 10:10:28  fritz * Changes for Kernel 2.1.X compatibility. * Enhanced initialization, can recover from * misconfiguration by other autoprobing drivers. * * Revision 1.34  1997/01/29 22:34:44  fritz * Cleanup, Corrected D64S setup of 2nd channel. * * Revision 1.33  1996/12/05 20:31:48  tsbogend * added handling of L2: DATA LINK LOST messages * * Revision 1.32  1996/11/14 23:49:18  fritz * Bugfix: copy_to_user/copy_from_user mismatch in debugging-ioctl. * * Revision 1.31  1996/11/13 02:36:25  fritz * Fixed a race condition in writecmd. * Some optimizations and cleanup. * * Revision 1.30  1996/10/22 23:14:09  fritz * Changes for compatibility to 2.0.X and 2.1.X kernels. * * Revision 1.29  1996/08/29 20:34:54  fritz * Bugfix in send queue management: * sndcount was not updated correctly. * Minor Bugfixes. * * Revision 1.28  1996/06/28 17:02:53  fritz * replaced memcpy_fromfs_toio. * * Revision 1.27  1996/06/25 18:38:59  fritz * Fixed function name in error message. * * Revision 1.26  1996/06/24 17:20:35  fritz * Bugfixes in pollbchan_send(): *   - Using lock field of skbuff breaks networking. *   - Added channel locking *   - changed dequeuing scheme. * Eliminated misc. compiler warnings. * * Revision 1.25  1996/06/11 22:53:35  tsbogend * fixed problem with large array on stack * made the driver working on Linux/alpha * * Revision 1.24  1996/06/06 13:58:33  fritz * Changed code to be architecture independent * * Revision 1.23  1996/06/03 19:59:00  fritz * Fixed typos. * * Revision 1.22  1996/05/17 15:46:41  fritz * Removed own queue management. * Changed queue management to use sk_buffs. * * Revision 1.21  1996/05/02 04:01:20  fritz * Bugfix: *  - icn_addcard() evaluated wrong driverId. * * Revision 1.20  1996/05/02 00:40:27  fritz * Major rewrite to support more than one card * with a single module. * Support for new firmware. * * Revision 1.19  1996/04/21 17:43:32  fritz * Changes for Support of new Firmware BRV3.02 * * Revision 1.18  1996/04/20 16:50:26  fritz * Fixed status-buffer overrun. * Misc. typos * * Revision 1.17  1996/02/11 02:39:04  fritz * Increased Buffer for status-messages. * Removed conditionals for HDLC-firmware. * * Revision 1.16  1996/01/22 05:01:55  fritz * Revert to GPL. * * Revision 1.15  1996/01/10 20:57:39  fritz * Bugfix: Loading firmware twice caused the device stop working. * * Revision 1.14  1995/12/18  18:23:37  fritz * Support for ICN-2B Cards. * Change for supporting user-settable service-octet. * * Revision 1.13  1995/10/29  21:41:07  fritz * Added support for DriverId's, added Jan's patches for Kernel versions. * * Revision 1.12  1995/04/29  13:07:35  fritz * Added support for new Euro-ISDN-firmware * * Revision 1.11  1995/04/23  13:40:45  fritz * Added support for SPV's. * Changed Dial-Command to support MSN's on DSS1-Lines. * * Revision 1.10  1995/03/25  23:23:24  fritz * Changed configurable Ports, to allow settings for DIP-Switch Cardversions. * * Revision 1.9  1995/03/25  23:17:30  fritz * Fixed race-condition in pollbchan_send * * Revision 1.8  1995/03/15  12:49:44  fritz * Added support for SPV's * Split pollbchan_work for calling send-routine directly * * Revision 1.7  1995/02/20  03:48:03  fritz * Added support of new request_region-function. * Minor bugfixes. * * Revision 1.6  1995/01/31  15:48:45  fritz * Added Cause-Messages to be signaled to upper layers. * Added Revision-Info on load. * * Revision 1.5  1995/01/29  23:34:59  fritz * Added stopdriver() and appropriate calls. * Changed printk-statements to support loglevels. * * Revision 1.4  1995/01/09  07:40:46  fritz * Added GPL-Notice * * Revision 1.3  1995/01/04  05:15:18  fritz * Added undocumented "bootload-finished"-command in download-code * to satisfy some brain-damaged icn card-versions. * * Revision 1.2  1995/01/02  02:14:45  fritz * Misc Bugfixes * * Revision 1.1  1994/12/14  17:56:06  fritz * Initial revision * */#include "icn.h"/* * Verbose bootcode- and protocol-downloading. */#undef BOOT_DEBUG/* * Verbose Shmem-Mapping. */#undef MAP_DEBUGstatic char*revision = "$Revision: 1.1.1.1 $";static int icn_addcard(int, char *, char *);/* * Free send-queue completely. * Parameter: *   card   = pointer to card struct *   channel = channel number */static voidicn_free_queue(icn_card * card, int channel){	struct sk_buff_head *queue = &card->spqueue[channel];	struct sk_buff *skb;	while ((skb = skb_dequeue(queue)))		dev_kfree_skb(skb, FREE_WRITE);	card->sndcount[channel] = 0;}/* Put a value into a shift-register, highest bit first. * Parameters: *            port     = port for output (bit 0 is significant) *            val      = value to be output *            firstbit = Bit-Number of highest bit *            bitcount = Number of bits to output */static inline voidicn_shiftout(unsigned short port,	     unsigned long val,	     int firstbit,	     int bitcount){	register u_char s;	register u_char c;	for (s = firstbit, c = bitcount; c > 0; s--, c--)		OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port);}/* * disable a cards shared memory */static inline voidicn_disable_ram(icn_card * card){	OUTB_P(0, ICN_MAPRAM);}/* * enable a cards shared memory */static inline voidicn_enable_ram(icn_card * card){	OUTB_P(0xff, ICN_MAPRAM);}/* * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12) */static inline voidicn_map_channel(icn_card * card, int channel){#ifdef MAP_DEBUG	printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel);#endif	if ((channel == dev.channel) && (card == dev.mcard))		return;	if (dev.mcard)		icn_disable_ram(dev.mcard);	icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4);	/* Select Bank          */	icn_enable_ram(card);	dev.mcard = card;	dev.channel = channel;#ifdef MAP_DEBUG	printk(KERN_DEBUG "icn_map_channel done\n");#endif}/* * Lock a cards channel. * Return 0 if requested card/channel is unmapped (failure). * Return 1 on success. */static inline inticn_lock_channel(icn_card * card, int channel){	register int retval;	ulong flags;#ifdef MAP_DEBUG	printk(KERN_DEBUG "icn_lock_channel %d\n", channel);#endif	save_flags(flags);	cli();	if ((dev.channel == channel) && (card == dev.mcard)) {		dev.chanlock++;		retval = 1;#ifdef MAP_DEBUG		printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel);#endif	} else {		retval = 0;#ifdef MAP_DEBUG		printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel);#endif	}	restore_flags(flags);	return retval;}/* * Release current card/channel lock */static inline voidicn_release_channel(void){	ulong flags;#ifdef MAP_DEBUG	printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock);#endif	save_flags(flags);	cli();	if (dev.chanlock > 0)		dev.chanlock--;	restore_flags(flags);}/* * Try to map and lock a cards channel. * Return 1 on success, 0 on failure. */static inline inticn_trymaplock_channel(icn_card * card, int channel){	ulong flags;#ifdef MAP_DEBUG	printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel,	       dev.chanlock);#endif	save_flags(flags);	cli();	if ((!dev.chanlock) ||	    ((dev.channel == channel) && (dev.mcard == card))) {		dev.chanlock++;		icn_map_channel(card, channel);		restore_flags(flags);#ifdef MAP_DEBUG		printk(KERN_DEBUG "trymaplock %d OK\n", channel);#endif		return 1;	}	restore_flags(flags);#ifdef MAP_DEBUG	printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);#endif	return 0;}/* * Release current card/channel lock, * then map same or other channel without locking. */static inline voidicn_maprelease_channel(icn_card * card, int channel){	ulong flags;#ifdef MAP_DEBUG	printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock);#endif	save_flags(flags);	cli();	if (dev.chanlock > 0)		dev.chanlock--;	if (!dev.chanlock)		icn_map_channel(card, channel);	restore_flags(flags);}/* Get Data from the B-Channel, assemble fragmented packets and put them * into receive-queue. Wake up any B-Channel-reading processes. * This routine is called via timer-callback from icn_pollbchan(). */static voidicn_pollbchan_receive(int channel, icn_card * card){	int mch = channel + ((card->secondhalf) ? 2 : 0);	int eflag;	int cnt;	struct sk_buff *skb;	if (icn_trymaplock_channel(card, mch)) {		while (rbavl) {			cnt = readb(&rbuf_l);			if ((card->rcvidx[channel] + cnt) > 4000) {				printk(KERN_WARNING				       "icn: (%s) bogus packet on ch%d, dropping.\n",				       CID,				       channel + 1);				card->rcvidx[channel] = 0;				eflag = 0;			} else {				memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],					      &rbuf_d, cnt);				card->rcvidx[channel] += cnt;				eflag = readb(&rbuf_f);			}			rbnext;			icn_maprelease_channel(card, mch & 2);			if (!eflag) {				if ((cnt = card->rcvidx[channel])) {					if (!(skb = dev_alloc_skb(cnt))) {						printk(KERN_WARNING "颿n: receive out of memory\n");						break;					}					memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt);					card->rcvidx[channel] = 0;					card->interface.rcvcallb_skb(card->myid, channel, skb);				}			}			if (!icn_trymaplock_channel(card, mch))				break;		}		icn_maprelease_channel(card, mch & 2);	}}/* Send data-packet to B-Channel, split it up into fragments of * ICN_FRAGSIZE length. If last fragment is sent out, signal * success to upper layers via statcallb with ISDN_STAT_BSENT argument. * This routine is called via timer-callback from icn_pollbchan() or * directly from icn_sendbuf(). */static voidicn_pollbchan_send(int channel, icn_card * card){	int mch = channel + ((card->secondhalf) ? 2 : 0);	int cnt;	unsigned long flags;	struct sk_buff *skb;	isdn_ctrl cmd;	if (!(card->sndcount[channel] ||	      skb_queue_len(&card->spqueue[channel])))		return;	if (icn_trymaplock_channel(card, mch)) {		while (sbfree && (card->sndcount[channel] ||			       skb_queue_len(&card->spqueue[channel]))) {			save_flags(flags);			cli();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -