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

📄 sdl_acb56.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 3 页
字号:
        mblk_t *mp = p->rx_msg, *mc = p->cp_msg;        unsigned int len = (unsigned int)(p->rx_buf - mp->b_rptr);        unsigned char li = mp->b_rptr[2]&0x3f;        if (len<3)            return acb56_short_error(p);        if (len>p->dev.module->config.m+4)            return acb56_long_error(p);        if (li!=(len>63+3?63+3:len))            return acb56_length_error(p);        mp->b_wptr = mp->b_rptr + len;        if (len<6) {            int clen = mc->b_wptr - mc->b_rptr;            if (len==clen && !memcmp(mc->b_rptr,mp->b_rptr,len)) {                p->stats.compressed_sus++;                acb56_rx_setup_next_frame(p);                p->dev.ucalls->daedr_compr_frame(&p->dev,1);                return;            } else {                memcpy(mc->b_rptr,mp->b_rptr,len);                mc->b_wptr = mc->b_rptr + len;            }        } else mc->b_wptr = mc->b_rptr;        p->rx_octet_mode = 0;        acb56_rx_setup_next_frame(p);        p->dev.ucalls->daedr_recvd_frame(&p->dev, mp);        acb56_do_resupply(); /* mark BH for resupply */        if ( !(p->rx_msg = bufq_dequeue(&acb56_supplyq)) &&             !(p->rx_msg = bufq_dequeue(&acb56_returnq)) )            return acb56_buffer_error(p);        p->rx_buf = p->rx_msg->b_wptr = p->rx_msg->b_rptr;        p->rx_max = p->rx_msg->b_datap->db_lim;        return;    }} static inline void acb56_frame_overflow_check(acb56_t *p) {    int actrl = p->dev.iface.iobase+1;    /* check for frame overflow */    if (p->rx_buf>p->rx_max) {        /* FIGURE 11/Q.703 (sheet 1 of 2) "m+7 octets without flags" */        if (!p->rx_octet_mode &&                p->dev.iface.ifclock!=DEV_CLOCK_DPLL) { /* can't octet count on DPLL! */            p->rx_octet_count = 0;            p->rx_octet_mode  = 1;            outb(0x0f,actrl); outb(p->regs[0x0f]|=0x02,actrl);  /* octet counting isr */            outb(0x03,actrl); outb(p->regs[0x03]|=0x10,actrl);  /* force flag hunt */            acb56_rx_setup_next_frame(p);            p->dev.ucalls->daedr_loss_of_sync(&p->dev);        }    }} static void acb56_isr_cha_tx_buf_empty(acb56_t *p) {    p->stats.cha_tx_buf_empty++;} static void acb56_isr_cha_ext_status(acb56_t *p) {    unsigned char rr0;    register int actrl = p->dev.iface.iobase+1;        rr0 = p->rr0&~0x02 ;    outb(0x00,actrl); p->rr0=inb(actrl);    outb(0x00,actrl); outb(0x10,actrl);    outb(0x00,actrl); outb(0x10,actrl); /* debounce */    rr0 ^= p->rr0 & 0xfa;    if (rr0) {        if (rr0 & 0x40) acb56_tx_underrun_eom (p);        if (rr0 & 0x10) acb56_sync_hunt       (p);        if (rr0 & 0x80) acb56_break_abort     (p);        if (rr0 & 0x08) acb56_dcd             (p);        if (rr0 & 0x20) acb56_cts             (p);    } else              acb56_zero_count      (p);    p->stats.cha_ext_status++;} static void acb56_isr_cha_rx_char_avail(acb56_t *p) {    register int adata = p->dev.iface.iobase;    register int i=0;    if ( p->rx_buf ) {    /* collect bytes */        for (i=0; i<4; i++) *(p->rx_buf++) = inb(adata);        acb56_frame_overflow_check(p);    }    p->dev.module->stats.rx_bytes+=4;    p->stats.cha_rx_char_avail++;} static void acb56_isr_cha_rx_sp_cond(acb56_t *p) {    unsigned char rr1 = 0;    register int adata = p->dev.iface.iobase;    register int actrl = p->dev.iface.iobase+1;    register int i=0;    p->stats.cha_rx_sp_cond++;    /* collect bytes */    outb(0x00,actrl);    for (i=0; i<4 && (inb(actrl)&0x01); i++) {        *(p->rx_buf++) = inb(adata);        p->dev.module->stats.rx_bytes++;        outb(0x00,actrl);    }    acb56_frame_overflow_check(p);    /* check for special conditions */    outb(0x07,actrl); if (inb(actrl)&0x40) {    outb(0x01,actrl); if ((rr1=inb(actrl))&0xf0) {        outb(0x00,actrl); outb(0x30,actrl); /* reset error */        if (rr1 & 0x10 ) { return acb56_parity_error  (p); }        if (rr1 & 0x20 ) { return acb56_rx_overrun    (p); }        if (rr1 & 0x80 ) {        if (rr1 & 0x40 ) { return acb56_crc_error     (p); }        else             {        if((rr1&0xe)^0x6){ return acb56_residue_error (p); }        else             { return acb56_end_of_frame  (p); } } }    } }}static void acb56_isr_donothing(acb56_t *p) { (void)p; };static void acb56_isr_chb_tx_buf_empty(acb56_t *p) { p->stats.chb_tx_buf_empty++; }static void acb56_isr_chb_ext_status(acb56_t *p)   { p->stats.chb_ext_status++; }static void acb56_isr_chb_rx_char_avail(acb56_t *p){ p->stats.chb_rx_char_avail++; }static void acb56_isr_chb_rx_sp_cond(acb56_t *p)   { p->stats.chb_rx_sp_cond++; }static void acb56_isr(int irq, void *dev_id, struct pt_regs *regs) {    static void (*vector_map[])(acb56_t *) = {        acb56_isr_chb_tx_buf_empty,  acb56_isr_chb_ext_status,        acb56_isr_chb_rx_char_avail, acb56_isr_chb_rx_sp_cond,        acb56_isr_cha_tx_buf_empty,  acb56_isr_cha_ext_status,        acb56_isr_cha_rx_char_avail, acb56_isr_cha_rx_sp_cond    };    unsigned char rr3;    register int i;    register int actrl = ((acb56_t *)dev_id)->dev.iface.iobase+1;    for (i=0,outb(0x03,actrl),rr3=inb(actrl);i<4&&rr3;i++,outb(0x03,actrl),rr3=inb(actrl))    {        outb(0x02,actrl+2);        (*vector_map[inb(actrl+2)>>1])(dev_id);        /* reset highest interrupt under service */        outb(0x00,actrl); outb(0x38,actrl);    }    ((acb56_t *)dev_id)->stats.interrupts++;};/* *  ========================================================================= * *  DRIVER SERVICE CALLS * *  ========================================================================= */static dev_device_t dev_acbdev_default ={    SPIN_LOCK_UNLOCKED, /* iflock   */    0,                  /* ifflags  */    DEV_TYPE_V35,       /* iftype   */    DEV_GTYPE_NONE,     /* ifgtype  */    DEV_MODE_DTE,       /* ifmode   */    56000,              /* ifrate   */    DEV_CLOCK_DPLL,     /* ifclock  */    DEV_CODING_NRZI,    /* ifcoding */    0,                  /* ifleads  */    0,                  /* ifindex  */    0,                  /* irq      */    0,                  /* dma_rx   */    0                   /* dma_tx   */};static const unsigned char preamble[] = {    0x09, 0xC0, 0x0F, 0x01, 0x07, 0x6B, 0x0F, 0x00, 0x00, 0x00, 0x04, 0x20,    0x01, 0x00, 0x02, 0x00, 0x03, 0xCA, 0x05, 0x63, 0x06, 0x00, 0x07, 0x7e,     0x09, 0x00, 0x0A, 0x00, 0x0B, 0x16, 0x0C, 0x40, 0x0D, 0x00, 0x0E, 0x02,    0x0E, 0x02, 0x0E, 0x02, 0x0E, 0x03, 0x03, 0xCB, 0x05, 0x6B, 0x00, 0x80,     0x00, 0x30, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x00,     0x09, 0x00 };static const unsigned char preset[] = {    0x09, 0xc0, 0x00, 0x00, 0x04, 0x20, 0x03, 0xca, 0x05, 0xe3, 0x07, 0x7e,    0x06, 0x00, 0x0F, 0x01, 0x07, 0x6b, 0x0F, 0x00, 0x01, 0x00, 0x02, 0x00,    0x09, 0x00, 0x0A, 0x80 };static const unsigned char mode_clock[6][3] = {    { 0x08, 0x05, 0x7f }, { 0x08, 0x56, 0x7f }, { 0x50, 0x50, 0x78 },    { 0x16, 0x50, 0x1f }, { 0x50, 0x50, 0x78 }, { 0x50, 0x50, 0x78 } };static unsigned char irqprobe[] = {    0x01, 0x19, 0x0F, 0xFA, 0x00, 0x10, 0x00, 0x10, 0x09, 0x08, 0x0E, 0x03};static void dummy_isr(int irq, void *dev_id, struct pt_regs *regs) {    volatile int *p; (void)irq; (void)dev_id; (void)regs; p = NULL; p++;}static int board = 0;static int ports[] = { 0x238, 0x280, 0x2A0, 0x300, 0x328, 0 };/* *  DEVICE-ATTACH: This is the device attach.  It should probe for the device *  as specified by the minor device number and determine whether the device *  is there and all of the resources for the device can be acquired.  All *  resources associated with the device (except the allocated structure, *  which is freed by the caller) should be freed at the end of this routine *  so that the device may be used by some other module if required. */static lmi_t *acb56_devatt(dev_t dev){    int iobase, _irq, actrl, _dma_rx, _dma_tx, i, err;    unsigned long time, cookie;    acb56_t *p = NULL;    board = getminor(dev)-1;    if ((iobase=io[board])==-1) iobase=ports[board];    if ((err=check_region(iobase,8))) return NULL;    actrl = iobase+1;    outb(0x02,actrl); outb(0x55,actrl); /* write to unallocated 8530 bit in WR2 */    outb(0x02,actrl); if (inb(actrl)!=0x55) return NULL; /* probably an 8530 */    outb(0x09,actrl); outb(0xc0,actrl); /* force hardware reset */    outb(0x0f,actrl); outb(0x01,actrl); /* Access W7P register */    outb(0x0f,actrl); if (!inb(actrl)&0x01) return NULL; /* probably an 8530 */    outb(0x0f,actrl); outb(0x00,actrl); /* Remove accss to W7P register */    outb(0x0f,actrl); if (inb(actrl)&0x01) return NULL; /* probably an 8530 */    /* check assigned irq */    if ((_irq=irq[board])!=-1) {        if ((err = request_irq(_irq,dummy_isr,SA_SHIRQ,"acb56_dummy",NULL))) return NULL;        else goto acb_probe_dma;    }    for (i=0;i<sizeof(preamble);) { /* setup chip */        outb(preamble[i],actrl); i++; outb(preamble[i],actrl); i++; }    cookie = probe_irq_on();    for (i=0;i<sizeof(irqprobe);) { /* setup for guaranteed interrupt */        outb(irqprobe[i],actrl); i++; outb(irqprobe[i],actrl); i++; }    /* fill tx fifo to get an interrupt */    outb(0x55,iobase); outb(0x55,iobase); outb(0x55,iobase);    outb(0x55,iobase); outb(0x55,iobase); outb(0x55,iobase);    outb(0x55,iobase); outb(0x55,iobase); outb(0x55,iobase);    for (time=jiffies;jiffies-time<100;i++);    if (!(_irq = probe_irq_off(cookie))) return NULL;   /* no irq! */    outb(0x03,actrl); if (!inb(actrl)) return NULL;    /* it wasn't us */    outb(0x09,actrl); outb(0x00,actrl);    outb(0x09,actrl); outb(0xc0,actrl); /* force hardware reset */    if ((err=request_irq(_irq,dummy_isr,SA_SHIRQ,"acb56_dummy",NULL))) return NULL;acb_probe_dma:    free_irq(_irq,NULL);    /* check for dma */    if ((_dma_rx=dma_rx[board])&&_dma_rx!=-1&&!(request_dma(_dma_rx,"acb56_probe")))        free_dma(_dma_rx); else _dma_rx=0;    if ((_dma_tx=dma_tx[board])&&_dma_tx!=-1&&!(request_dma(_dma_tx,"acb56_probe")))        free_dma(_dma_tx); else _dma_tx=0;    if (!(p = kmalloc(sizeof(*p),GFP_KERNEL))) return NULL;    bzero(p, sizeof(*p));    bcopy(&dev_acbdev_default, &p->dev.iface, sizeof(p->dev.iface));    p->dev.iface.ifindex = board;    p->dev.iface.irq     = _irq;    p->dev.iface.iobase  = iobase;    p->dev.iface.dma_tx  = _dma_tx;    p->dev.iface.dma_rx  = _dma_rx;    if (mode [board]!=-1) p->dev.iface.ifmode  = mode [board];    if (clock[board]!=-1) p->dev.iface.ifclock = clock[board];    ptrace(("sucessful:\n"));    ptrace(("  ifindex = %lu\n",   p->dev.iface.ifindex));    ptrace(("  irq     = %lu\n",   p->dev.iface.irq));    ptrace(("  iobase  = 0x%lx\n", p->dev.iface.iobase));    ptrace(("  dma_tx  = %lu\n",   p->dev.iface.dma_tx));    ptrace(("  dma_rx  = %lu\n",   p->dev.iface.dma_rx));    return((lmi_t *)p);}/* *  DEVICE-OPEN: Using the information contained in the device structure *  created at device attach, this function should reacquire all of the *  resources associated with the device (e.g., irqs).  The device is left in *  the quiescent state. */static intacb56_open(lmi_t *lmi){    acb56_t *p = (acb56_t *)lmi;    dev_device_t *dev = &p->dev.iface;    int err=0;    unsigned long flags;    spin_lock_irqsave(&dev->iflock, flags);    MOD_INC_USE_COUNT;    /* get io region */    if ((err=check_region(dev->iobase,8))) {        MOD_DEC_USE_COUNT;        spin_unlock_irqrestore(&dev->iflock, flags);        return err;    }    request_region(dev->iobase,8,"acb56");    /* get dma channels */    if (dev->dma_rx && request_dma(dev->dma_rx,"acb56")) dev->dma_rx=0;    if (dev->dma_tx && request_dma(dev->dma_tx,"acb56")) dev->dma_tx=0;    /* get interrupt */    if ((err=request_irq(dev->irq,acb56_isr,SA_SHIRQ,"acb56",p))) {        if (dev->dma_rx) free_dma(dev->dma_rx);        if (dev->dma_tx) free_dma(dev->dma_tx);        MOD_DEC_USE_COUNT;        spin_unlock_irqrestore(&dev->iflock, flags);        return err;    }    spin_unlock_irqrestore(&dev->iflock, flags);    return(0);}/* *  DEVICE-CLOSE: Using the information contained in the device structure *  created at device attach, this function should deallocate all of the *  driver resources associated with the device with the exception of the *  device structure itself.  The device will be in the quiescent state when *  the procedure is called. */static intacb56_close(lmi_t *lmi){    acb56_t *p = (acb56_t *)lmi;    dev_device_t *dev = &p->dev.iface;    unsigned long flags;    spin_lock_irqsave(&dev->iflock, flags);    free_irq(dev->irq,p);    if (dev->dma_tx) free_dma(dev->dma_tx);    if (dev->dma_rx) free_dma(dev->dma_rx);    release_region(dev->iobase,8);    MOD_DEC_USE_COUNT;    spin_unlock_irqrestore(&dev->iflock, flags);    return(0);}/* *  INFO: This is for Style 2 device drivers for returning PPAs.  Since this *  is only a single-port card, the Signalling Data Link is determined at open *  time and we simply return a zero-length PPA. */static intacb56_info(lmi_t *lmi, void **ppap, int *lenp){    acb56_t *p = (acb56_t *)lmi;    dev_device_t *dev = &p->dev.iface;    unsigned long flags;    (void)dev;    spin_lock_irqsave(&dev->iflock, flags);    *lenp = 0;    *ppap = NULL;    spin_unlock_irqrestore(&dev->iflock, flags);    return(0);}/* *  ATTACH: This is for Style 2 device drivers.  Since this is only a *  single-port card, the Signalling Data Link is determined at open time and *  we simply agree with any attach command. */static intacb56_attach(lmi_t *lmi, void *ppa, int len){    acb56_t *p = (acb56_t *)lmi;    dev_device_t *dev = &p->dev.iface;    unsigned long flags;    (void)dev;    (void)ppa;    (void)len;    spin_lock_irqsave(&dev->iflock, flags);    spin_unlock_irqrestore(&dev->iflock, flags);    return(0);}/* *  DETACH: This is for Style 2 device drivers.  Since this is only a *  single-port card, the Signalling Data LInk was determined at open time and *  cannot be detached, so, we simply agree with any detach command. */static intacb56_detach(lmi_t *lmi){    acb56_t *p = (acb56_t *)lmi;    dev_device_t *dev = &p->dev.iface;    unsigned long flags;    (void)dev;    spin_lock_irqsave(&dev->iflock, flags);    spin_unlock_irqrestore(&dev->iflock, flags);    return(0);}#ifndef abs#define abs(x) ((x)<0 ? -(x):(x))#endif/* *  ENABLE: This should set up the hardware for the device using the resources *  which were reserved during the open.  The device should be activated and *  made ready for operation.  Interrupt service routines should be enabled. */static intacb56_enable(lmi_t *lmi){    acb56_t *p = (acb56_t *)lmi;    dev_device_t *dev = &p->dev.iface;    int i, actrl;    unsigned long flags;    spin_lock_irqsave(&dev->iflock, flags);    actrl = dev->iobase+1;    for (i=0;i<16;i++) p->regs[i] = 0; /* register images */    /* setup chip */

⌨️ 快捷键说明

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