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

📄 sdl_acb56.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** @(#) sdl_acb56.c,v SS7AlphaRelease(0.7.8.1) 2001/12/11 13:15:02 ----------------------------------------------------------------------------- Copyright (c) 2001  OpenSS7 Corporation <http://www.openss7.com> Copyright (c) 1997-2000  Brian F. G. Bidulock <bidulock@dallas.net> All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------------------------------------------------------------------------- U.S. GOVERNMENT RESTRICTED RIGHTS.  If you are licensing this Software on behalf of the U.S. Government ("Government"), the following provisions apply to you.  If the Software is supplied by the Department of Defense ("DoD"), it is classified as "Commercial Computer Software" under paragraph 252.227-7014 of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any successor regulations) and the Government is acquiring only the license rights granted herein (the license rights customarily provided to non-Government users).  If the Software is supplied to any unit or agency of the Government other than DoD, it is classified as "Restricted Computer Software" and the Government's rights in the Software are defined in paragraph 52.227-19 of the Federal Acquisition Regulations ("FAR") (or any success regulations) or, in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR (or any successor regulations). ----------------------------------------------------------------------------- Last Modified 2001/12/11 13:15:02 by brian *****************************************************************************/#ident "@(#) sdl_acb56.c,v SS7AlphaRelease(0.7.8.1) 2001/12/11 13:15:02"static char const ident[] = "sdl_acb56.c,v SS7AlphaRelease(0.7.8.1) 2001/12/11 13:15:02";/* *  This is an implementation of the Signalling Data Link for the SeaLevel *  ACB56[tm] V.35 ISA card.  It provides the driver routines necessary for *  interface to the SDL driver kernel module. */#include <linux/config.h>#include <linux/version.h>#include <linux/modversions.h>#include <linux/module.h>#include <sys/stream.h>#include <sys/stropts.h>#include <sys/cmn_err.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/ioport.h>#include <asm/io.h>#include <asm/dma.h>#include "../debug.h"#include "../bufq.h"#include <ss7/lmi.h>#include <ss7/lmi_ioctl.h>#include <ss7/devi.h>#include <ss7/devi_ioctl.h>#include <ss7/sdli.h>#include <ss7/sdli_ioctl.h>#include "../lmi/lm.h"#include "../devi/dev.h"#include "../sdli/sdl.h"#define ACB56_DESCRIP   "ACB56: SS7/SDL (Signalling Data Link) STREAMS DRIVER."#define ACB56_COPYRIGHT "Copyright (c) 1997-2001 Brian Bidulock.  All Rights Reserved."#define ACB56_DEVICES   "Supports the SeaLevel ACB56(tm) V.35 boards."#define ACB56_CONTACT   "Brian Bidulock <bidulock@openss7.org>"#define ACB56_BANNER    ACB56_DESCRIP   "\n" \                        ACB56_COPYRIGHT "\n" \                        ACB56_DEVICES   "\n" \                        ACB56_CONTACT   "\n"#ifdef MODULEMODULE_AUTHOR(ACB56_CONTACT);MODULE_DESCRIPTION(ACB56_DESCRIP);MODULE_SUPPORTED_DEVICE(ACB56_DEVICES);#define MODULE_STATIC static#else#define MOD_INC_USE_COUNT#define MOD_DEC_USE_COUNT#define MODULE_STATIC#endif#ifdef ACB56_DEBUGint acb56_debug = ACB56_DEBUG;#elseint acb56_debug = 2;#endif#define DEBUG_LEVEL acb56_debug//#define ACB56_MOD_ID      0x1111//#define ACB56_MOD_NAME    "acb56"//#define ACB56_CMAJOR      0   /* FIXME: pick something    *///#define ACB56_NMINOR      256 /* as many as possible      */#ifndef ACB56_CMAJOR#define ACB56_CMAJOR  248   /* FIXME: pick something    */#endif#define ACB56_NMINOR  5     /* as many as possible      */#ifndef LSSU_SIB#define LSSU_SIB 0x5#endifstatic int debug = -1;static int io    [] = { -1, -1, -1, -1, -1 };static int irq   [] = { -1, -1, -1, -1, -1 };static int dma_rx[] = { -1, -1, -1, -1, -1 };static int dma_tx[] = { -1, -1, -1, -1, -1 };static int mode  [] = { -1, -1, -1, -1, -1 };static int clock [] = { -1, -1, -1, -1, -1 };MODULE_PARM(debug, "i");    /* debug flag */MODULE_PARM(io ,   "1-5i"); /* i/o port for the i'th card */MODULE_PARM(irq,   "1-5i"); /* irq for the i'th card */MODULE_PARM(dma_rx,"1-5i"); /* dma for the i'th card */MODULE_PARM(dma_tx,"1-5i"); /* dma for the i'th card */MODULE_PARM(mode,  "i-5i"); /* interface mode */MODULE_PARM(clock, "i-5i"); /* clock source */enum { ACB56_MODE_DTE,  ACB56_MODE_DCE,  ACB56_MODE_LOOP,       ACB56_MODE_JACK, ACB56_MODE_ECHO, ACB56_MODE_BOTH };static const int mode_map[] = {    -1,                 /* DEV_MODE_NONE    */    -1,                 /* DEV_MODE_DSU     */    -1,                 /* DEV_MODE_CSU     */    ACB56_MODE_DTE,     /* DEV_MODE_DTE     */    ACB56_MODE_DCE,     /* DEV_MODE_DCE     */    -1,                 /* DEV_MODE_CLIENT  */    -1,                 /* DEV_MODE_SERVER  */    -1,                 /* DEV_MODE_PEER    */    ACB56_MODE_ECHO,    /* DEV_MODE_ECHO    */    -1,                 /* DEV_MODE_REM_LB  */    ACB56_MODE_LOOP,    /* DEV_MODE_LOC_LB  */    ACB56_MODE_BOTH,    /* DEV_MODE_LB_ECHO */    ACB56_MODE_JACK     /* DEV_MODE_TEST    */};enum { ACB56_CLOCK_EXT, ACB56_CLOCK_INT, ACB56_CLOCK_DPLL };static const int clock_map[] = {    -1,                 /* DEV_CLOCK_NONE   */    ACB56_CLOCK_INT,    /* DEV_CLOCK_INT    */    ACB56_CLOCK_EXT,    /* DEV_CLOCK_EXT    */    -1,                 /* DEV_CLOCK_LOOP   */    -1,                 /* DEV_CLOCK_MASTER */    -1,                 /* DEV_CLOCK_SLAVE  */    ACB56_CLOCK_DPLL,   /* DEV_CLOCK_DPLL   */    -1,                 /* DEV_CLOCK_ABR    */    -1                  /* DEV_CLOCK_SHAPER */};static int acb56_cmajor = ACB56_CMAJOR;typedef struct acb56_stats {    dev_ulong   repeated_sus;    dev_ulong   compressed_sus;    dev_ulong   recv_fisus;    dev_ulong   recv_lssus;    dev_ulong   recv_msus;    dev_ulong   parity_errors;    dev_ulong   cts_transitions;    dev_ulong   dcd_transitions;    dev_ulong   cha_ext_status;    dev_ulong   cha_rx_char_avail;    dev_ulong   cha_rx_sp_cond;    dev_ulong   cha_tx_buf_empty;    dev_ulong   chb_ext_status;    dev_ulong   chb_rx_char_avail;    dev_ulong   chb_rx_sp_cond;    dev_ulong   chb_tx_buf_empty;    dev_ulong   interrupts;} acb56_stats_t;typedef struct acb56 {    struct dev      dev;            /* common device structure      */    int             rx_octet_mode;  /* Is octet counting on?        */    int             rx_octet_count; /* bits (not octets) counted    */    unsigned char   regs[16];       /* register images              */    unsigned char   rr0;            /* register image reg 0         */    mblk_t          *tx_msg;        /* transmit buffer              */    mblk_t          *rx_msg;        /* receive  buffer              */    mblk_t          *cp_msg;        /* compressed su buffer         */    acb56_stats_t   stats;          /* device private stats         */    unsigned char   *tx_buf;        /* current tx buffer pointer    */    unsigned char   *tx_max;        /* end of  tx buffer pointer    */    int             tx_error;       /* transmission error           */    unsigned char   *rx_buf;        /* current rx buffer pointer    */    unsigned char   *rx_max;        /* end oft rx buffer pointer    */    int             rx_error;       /* reception    error           */    bufq_t          tinputq;} acb56_t;/* *  ========================================================================= * *  BUFFER RESUPPLY * *  ========================================================================= *//* *  It is important not to attempt to free or allocate message blocks within *  the Interrupt Service Routine.  The purpose of these functions is to *  recognize when the receive buffer supply queue is running too low and *  perform a resupply of the queue by allocating buffers.  We also detect *  when the buffer supply queue is running too high and free buffers from the *  queue.  We use a single resupply queue for all of the ACB56 devices served *  by this driver. */#define ACB56_SUPQ_MAXLEN   16#ifndef SIF_MAX#define SIF_MAX 272#endifstatic bufq_t acb56_supplyq;static bufq_t acb56_returnq;static void acb56_resupply(void *unused) {    int i;    mblk_t *mp;    (void)unused;    for (i=bufq_length(&acb56_returnq); i>0; i--) {        if ( (mp = bufq_dequeue(&acb56_returnq)) )            freemsg(mp);    }    for (i=bufq_length(&acb56_supplyq); i<ACB56_SUPQ_MAXLEN; i++) {        if ( (mp = allocb(SIF_MAX+4, BPRI_HI)) ) {            mp->b_datap->db_type = M_DATA;            bufq_queue(&acb56_supplyq, mp);        }    }}static struct tq_struct acb56_resupply_tasq ={    NULL,                   /* next     */    0,                      /* sync     */    (void *)acb56_resupply, /* routine  */    NULL                    /* data     */};static inline void acb56_do_resupply(void) {    queue_task(&acb56_resupply_tasq, &tq_immediate);    mark_bh(IMMEDIATE_BH);}/* *  ========================================================================= * *  INTERRUPT SERVICE ROUTINES * *  ========================================================================= */static inline void acb56_tx_setup_next_frame(acb56_t *p) {    p->dev.module->stats.tx_sus++;    p->dev.module->stats.tx_bytes+=4;    if ( bufq_length(&p->tinputq) ) {        acb56_do_resupply(); /* mark BH for resupply */        bufq_queue(&acb56_returnq, p->tx_msg);        p->tx_msg = bufq_dequeue(&p->tinputq);    } else {        int len = msgdsize(p->tx_msg);        if ( len>5 || ( len >3 && p->tx_msg->b_rptr[3] == LSSU_SIB ) )        {   /* its an MSU or SIB, make FISU out of it */            p->tx_msg->b_wptr = p->tx_msg->b_rptr+3;            p->tx_msg->b_rptr[2] = 0;            p->stats.repeated_sus++;        }    }    p->tx_buf = p->tx_msg->b_rptr;    p->tx_max = p->tx_msg->b_wptr;}static inline void acb56_tx_underrun_eom(acb56_t *p) {    if ( p->rr0&0x40 ) { /* set */        p->tx_buf = p->tx_msg->b_rptr;        p->tx_error = 1;        p->dev.module->stats.tx_aborts++;        p->dev.module->stats.tx_underruns++;        p->dev.module->stats.tx_sus_in_error++;        p->dev.module->stats.tx_bytes+=3;        p->rr0&=~0x04;  /* clear indication */        return;    } else {        return acb56_tx_setup_next_frame(p);    }}static inline void acb56_sync_hunt(acb56_t *p){    int actrl = p->dev.iface.iobase+1;    if (p->rx_octet_mode && !p->rr0&0x10) {        p->rx_octet_mode = 0;  /* we synced */        outb(0x0f,actrl); outb(p->regs[0x0f]&=~0x02,actrl); /* turn of octet mode */    }    else if ((p->rr0&0x10) && (p->dev.iface.ifclock!=DEV_CLOCK_DPLL)) {        p->rx_octet_count = 0;        p->rx_octet_mode  = 1;        outb(0x0f,actrl); outb(p->regs[0x0f]|=0x02,actrl); /* turn on octet mode */    }    p->dev.module->stats.rx_sync_transitions++;}static inline void acb56_break_abort(acb56_t *p) {    p->dev.module->stats.rx_aborts++;}static inline void acb56_dcd(acb56_t *p) {    if ( (++p->stats.dcd_transitions) & 0x1 )        p->dev.module->stats.lead_dcd_lost++;}static inline void acb56_cts(acb56_t *p) {    if ( (++p->stats.cts_transitions) & 0x1 )        p->dev.module->stats.lead_cts_lost++;}static inline void acb56_zero_count(acb56_t *p) {    if (!p->rx_octet_count++&0x0000007f ||            (p->dev.iface.ifmode==DEV_MODE_DTE)) {        p->dev.module->stats.rx_sus_in_error++;        p->dev.ucalls->daedr_N_octets(&p->dev);    }    p->dev.module->stats.rx_bits_octet_counted++;}static inline void acb56_frame_error(acb56_t *p) {    p->rx_error = 0;    p->rx_buf = p->rx_msg->b_rptr;    if (p->rx_octet_mode) return;  /* only a good frame counts in octet mode */    p->cp_msg->b_wptr = p->cp_msg->b_rptr;    p->dev.module->stats.rx_sus++;    p->dev.module->stats.rx_bytes+=2;    p->dev.module->stats.rx_sus_in_error++;    p->dev.ucalls->daedr_error_frame(&p->dev);}static inline void acb56_parity_error(acb56_t *p) {    p->stats.parity_errors++;    p->rx_error = 1;} static inline void acb56_rx_overrun(acb56_t *p) {    p->dev.module->stats.rx_overruns++;    p->rx_error = 1;} static inline void acb56_crc_error(acb56_t *p) {    if (p->rx_octet_mode) return;  /* only a good frame counts in octet mode */    p->dev.module->stats.rx_crc_errors++;    acb56_frame_error(p);} static inline void acb56_buffer_error(acb56_t *p) {    if (p->rx_octet_mode) return;  /* only a good frame counts in octet mode */    p->dev.module->stats.rx_buffer_overflows++;    acb56_frame_error(p);} static inline void acb56_short_error(acb56_t *p) {    if (p->rx_octet_mode) return;  /* only a good frame counts in octet mode */    p->dev.module->stats.rx_frame_too_short++;    acb56_frame_error(p);} static inline void acb56_long_error(acb56_t *p) {    if (p->rx_octet_mode) return;  /* only a good frame counts in octet mode */    p->dev.module->stats.rx_frame_too_long++;    acb56_frame_error(p);} static inline void acb56_length_error(acb56_t *p) {    if (p->rx_octet_mode) return;  /* only a good frame counts in octet mode */    p->dev.module->stats.rx_length_error++;    acb56_frame_error(p);} static inline void acb56_rx_setup_next_frame(acb56_t *p) {    int len = p->rx_buf - p->rx_msg->b_rptr;    p->rx_buf = p->rx_msg->b_rptr;    p->dev.module->stats.rx_sus++;    if (len==3) p->stats.recv_fisus++;    if (len>=6) p->stats.recv_msus++;    if (len>=4) p->stats.recv_lssus++;    p->dev.module->stats.rx_bytes+=2;} static inline void acb56_residue_error(acb56_t *p) {    p->dev.module->stats.rx_residue_errors++;    acb56_frame_error(p);}static inline void acb56_end_of_frame(acb56_t *p) {    if (p->rx_error) return acb56_frame_error(p);    {

⌨️ 快捷键说明

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