!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/isdn/hisax/   drwxr-xr-x
Free 318.31 GB of 458.09 GB (69.49%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     hscx_irq.c (7.15 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* $Id: hscx_irq.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
 *
 * low level b-channel stuff for Siemens HSCX
 *
 * Author       Karsten Keil
 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
 * 
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * This is an include file for fast inline IRQ stuff
 *
 */


static inline void
waitforCEC(struct IsdnCardState *cs, int hscx)
{
    int to = 50;

    while ((READHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) {
        udelay(1);
        to--;
    }
    if (!to)
        printk(KERN_WARNING "HiSax: waitforCEC timeout\n");
}


static inline void
waitforXFW(struct IsdnCardState *cs, int hscx)
{
    int to = 50;

    while ((!(READHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) {
        udelay(1);
        to--;
    }
    if (!to)
        printk(KERN_WARNING "HiSax: waitforXFW timeout\n");
}

static inline void
WriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data)
{
    long flags;

    save_flags(flags);
    cli();
    waitforCEC(cs, hscx);
    WRITEHSCX(cs, hscx, HSCX_CMDR, data);
    restore_flags(flags);
}



static void
hscx_empty_fifo(struct BCState *bcs, int count)
{
    u_char *ptr;
    struct IsdnCardState *cs = bcs->cs;
    long flags;

    if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
        debugl1(cs, "hscx_empty_fifo");

    if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
        if (cs->debug & L1_DEB_WARN)
            debugl1(cs, "hscx_empty_fifo: incoming packet too large");
        WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
        bcs->hw.hscx.rcvidx = 0;
        return;
    }
    ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
    bcs->hw.hscx.rcvidx += count;
    save_flags(flags);
    cli();
    READHSCXFIFO(cs, bcs->hw.hscx.hscx, ptr, count);
    WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
    restore_flags(flags);
    if (cs->debug & L1_DEB_HSCX_FIFO) {
        char *t = bcs->blog;

        t += sprintf(t, "hscx_empty_fifo %c cnt %d",
                 bcs->hw.hscx.hscx ? 'B' : 'A', count);
        QuickHex(t, ptr, count);
        debugl1(cs, bcs->blog);
    }
}

static void
hscx_fill_fifo(struct BCState *bcs)
{
    struct IsdnCardState *cs = bcs->cs;
    int more, count;
    int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
    u_char *ptr;
    long flags;


    if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
        debugl1(cs, "hscx_fill_fifo");

    if (!bcs->tx_skb)
        return;
    if (bcs->tx_skb->len <= 0)
        return;

    more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
    if (bcs->tx_skb->len > fifo_size) {
        more = !0;
        count = fifo_size;
    } else
        count = bcs->tx_skb->len;

    waitforXFW(cs, bcs->hw.hscx.hscx);
    save_flags(flags);
    cli();
    ptr = bcs->tx_skb->data;
    skb_pull(bcs->tx_skb, count);
    bcs->tx_cnt -= count;
    bcs->hw.hscx.count += count;
    WRITEHSCXFIFO(cs, bcs->hw.hscx.hscx, ptr, count);
    WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa);
    restore_flags(flags);
    if (cs->debug & L1_DEB_HSCX_FIFO) {
        char *t = bcs->blog;

        t += sprintf(t, "hscx_fill_fifo %c cnt %d",
                 bcs->hw.hscx.hscx ? 'B' : 'A', count);
        QuickHex(t, ptr, count);
        debugl1(cs, bcs->blog);
    }
}

static inline void
hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
{
    u_char r;
    struct BCState *bcs = cs->bcs + hscx;
    struct sk_buff *skb;
    int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
    int count;

    if (!test_bit(BC_FLG_INIT, &bcs->Flag))
        return;

    if (val & 0x80) {    /* RME */
        r = READHSCX(cs, hscx, HSCX_RSTA);
        if ((r & 0xf0) != 0xa0) {
            if (!(r & 0x80)) {
                if (cs->debug & L1_DEB_WARN)
                    debugl1(cs, "HSCX invalid frame");
#ifdef ERROR_STATISTIC
                bcs->err_inv++;
#endif
            }
            if ((r & 0x40) && bcs->mode) {
                if (cs->debug & L1_DEB_WARN)
                    debugl1(cs, "HSCX RDO mode=%d",
                        bcs->mode);
#ifdef ERROR_STATISTIC
                bcs->err_rdo++;
#endif
            }
            if (!(r & 0x20)) {
                if (cs->debug & L1_DEB_WARN)
                    debugl1(cs, "HSCX CRC error");
#ifdef ERROR_STATISTIC
                bcs->err_crc++;
#endif
            }
            WriteHSCXCMDR(cs, hscx, 0x80);
        } else {
            count = READHSCX(cs, hscx, HSCX_RBCL) & (
                test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
            if (count == 0)
                count = fifo_size;
            hscx_empty_fifo(bcs, count);
            if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
                if (cs->debug & L1_DEB_HSCX_FIFO)
                    debugl1(cs, "HX Frame %d", count);
                if (!(skb = dev_alloc_skb(count)))
                    printk(KERN_WARNING "HSCX: receive out of memory\n");
                else {
                    memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
                    skb_queue_tail(&bcs->rqueue, skb);
                }
            }
        }
        bcs->hw.hscx.rcvidx = 0;
        hscx_sched_event(bcs, B_RCVBUFREADY);
    }
    if (val & 0x40) {    /* RPF */
        hscx_empty_fifo(bcs, fifo_size);
        if (bcs->mode == L1_MODE_TRANS) {
            /* receive audio data */
            if (!(skb = dev_alloc_skb(fifo_size)))
                printk(KERN_WARNING "HiSax: receive out of memory\n");
            else {
                memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size);
                skb_queue_tail(&bcs->rqueue, skb);
            }
            bcs->hw.hscx.rcvidx = 0;
            hscx_sched_event(bcs, B_RCVBUFREADY);
        }
    }
    if (val & 0x10) {    /* XPR */
        if (bcs->tx_skb) {
            if (bcs->tx_skb->len) {
                hscx_fill_fifo(bcs);
                return;
            } else {
                if (bcs->st->lli.l1writewakeup &&
                    (PACKET_NOACK != bcs->tx_skb->pkt_type))
                    bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count);
                dev_kfree_skb_irq(bcs->tx_skb);
                bcs->hw.hscx.count = 0; 
                bcs->tx_skb = NULL;
            }
        }
        if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
            bcs->hw.hscx.count = 0;
            test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
            hscx_fill_fifo(bcs);
        } else {
            test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
            hscx_sched_event(bcs, B_XMTBUFREADY);
        }
    }
}

static inline void
hscx_int_main(struct IsdnCardState *cs, u_char val)
{

    u_char exval;
    struct BCState *bcs;

    if (val & 0x01) {
        bcs = cs->bcs + 1;
        exval = READHSCX(cs, 1, HSCX_EXIR);
        if (exval & 0x40) {
            if (bcs->mode == 1)
                hscx_fill_fifo(bcs);
            else {
#ifdef ERROR_STATISTIC
                bcs->err_tx++;
#endif
                /* Here we lost an TX interrupt, so
                   * restart transmitting the whole frame.
                 */
                if (bcs->tx_skb) {
                    skb_push(bcs->tx_skb, bcs->hw.hscx.count);
                    bcs->tx_cnt += bcs->hw.hscx.count;
                    bcs->hw.hscx.count = 0;
                }
                WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01);
                if (cs->debug & L1_DEB_WARN)
                    debugl1(cs, "HSCX B EXIR %x Lost TX", exval);
            }
        } else if (cs->debug & L1_DEB_HSCX)
            debugl1(cs, "HSCX B EXIR %x", exval);
    }
    if (val & 0xf8) {
        if (cs->debug & L1_DEB_HSCX)
            debugl1(cs, "HSCX B interrupt %x", val);
        hscx_interrupt(cs, val, 1);
    }
    if (val & 0x02) {
        bcs = cs->bcs;
        exval = READHSCX(cs, 0, HSCX_EXIR);
        if (exval & 0x40) {
            if (bcs->mode == L1_MODE_TRANS)
                hscx_fill_fifo(bcs);
            else {
                /* Here we lost an TX interrupt, so
                   * restart transmitting the whole frame.
                 */
#ifdef ERROR_STATISTIC
                bcs->err_tx++;
#endif
                if (bcs->tx_skb) {
                    skb_push(bcs->tx_skb, bcs->hw.hscx.count);
                    bcs->tx_cnt += bcs->hw.hscx.count;
                    bcs->hw.hscx.count = 0;
                }
                WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01);
                if (cs->debug & L1_DEB_WARN)
                    debugl1(cs, "HSCX A EXIR %x Lost TX", exval);
            }
        } else if (cs->debug & L1_DEB_HSCX)
            debugl1(cs, "HSCX A EXIR %x", exval);
    }
    if (val & 0x04) {
        exval = READHSCX(cs, 0, HSCX_ISTA);
        if (cs->debug & L1_DEB_HSCX)
            debugl1(cs, "HSCX A interrupt %x", exval);
        hscx_interrupt(cs, exval, 0);
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0115 ]--