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

📄 farsync.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 4 页
字号:
static inline voidfst_cpurelease ( struct fst_card_info *card ){        (void) readb ( card->ctlmem );}/*      Clear the cards interrupt flag */static inline voidfst_clear_intr ( struct fst_card_info *card ){        /* Poke the appropriate PLX chip register (same as enabling interrupts)         */        outw ( 0x0543, card->pci_conf + 0x4C );}/*      Disable card interrupts */static inline voidfst_disable_intr ( struct fst_card_info *card ){        outw ( 0x0000, card->pci_conf + 0x4C );}/*      Issue a Mailbox command for a port. *      Note we issue them on a fire and forget basis, not expecting to see an *      error and not waiting for completion. */static voidfst_issue_cmd ( struct fst_port_info *port, unsigned short cmd ){        struct fst_card_info *card;        unsigned short mbval;        unsigned long flags;        int safety;        card = port->card;        spin_lock_irqsave ( &card->card_lock, flags );        mbval = FST_RDW ( card, portMailbox[port->index][0]);        safety = 0;        /* Wait for any previous command to complete */        while ( mbval > NAK )        {                spin_unlock_irqrestore ( &card->card_lock, flags );                schedule_timeout ( 1 );                spin_lock_irqsave ( &card->card_lock, flags );                if ( ++safety > 1000 )                {                        printk_err ("Mailbox safety timeout\n");                        break;                }                mbval = FST_RDW ( card, portMailbox[port->index][0]);        }        if ( safety > 0 )        {                dbg ( DBG_CMD,"Mailbox clear after %d jiffies\n", safety );        }        if ( mbval == NAK )        {                dbg ( DBG_CMD,"issue_cmd: previous command was NAK'd\n");        }        FST_WRW ( card, portMailbox[port->index][0], cmd );        if ( cmd == ABORTTX || cmd == STARTPORT )        {                port->txpos  = 0;                port->txipos = 0;                port->txcnt  = 0;        }        spin_unlock_irqrestore ( &card->card_lock, flags );}/*      Port output signals control */static inline voidfst_op_raise ( struct fst_port_info *port, unsigned int outputs ){        outputs |= FST_RDL ( port->card, v24OpSts[port->index]);        FST_WRL ( port->card, v24OpSts[port->index], outputs );        if ( port->run )                fst_issue_cmd ( port, SETV24O );}static inline voidfst_op_lower ( struct fst_port_info *port, unsigned int outputs ){        outputs = ~outputs & FST_RDL ( port->card, v24OpSts[port->index]);        FST_WRL ( port->card, v24OpSts[port->index], outputs );        if ( port->run )                fst_issue_cmd ( port, SETV24O );}/* *      Setup port Rx buffers */static voidfst_rx_config ( struct fst_port_info *port ){        int i;        int pi;        unsigned int offset;        unsigned long flags;        struct fst_card_info *card;        pi   = port->index;        card = port->card;        spin_lock_irqsave ( &card->card_lock, flags );        for ( i = 0 ; i < NUM_RX_BUFFER ; i++ )        {                offset = BUF_OFFSET ( rxBuffer[pi][i][0]);                FST_WRW ( card, rxDescrRing[pi][i].ladr, (u16) offset );                FST_WRB ( card, rxDescrRing[pi][i].hadr, (u8)( offset >> 16 ));                FST_WRW ( card, rxDescrRing[pi][i].bcnt,                                        cnv_bcnt ( LEN_RX_BUFFER ));                FST_WRW ( card, rxDescrRing[pi][i].mcnt, 0 );                FST_WRB ( card, rxDescrRing[pi][i].bits, DMA_OWN );        }        port->rxpos  = 0;        spin_unlock_irqrestore ( &card->card_lock, flags );}/* *      Setup port Tx buffers */static voidfst_tx_config ( struct fst_port_info *port ){        int i;        int pi;        unsigned int offset;        unsigned long flags;        struct fst_card_info *card;        pi   = port->index;        card = port->card;        spin_lock_irqsave ( &card->card_lock, flags );        for ( i = 0 ; i < NUM_TX_BUFFER ; i++ )        {                offset = BUF_OFFSET ( txBuffer[pi][i][0]);                FST_WRW ( card, txDescrRing[pi][i].ladr, (u16) offset );                FST_WRB ( card, txDescrRing[pi][i].hadr, (u8)( offset >> 16 ));                FST_WRW ( card, txDescrRing[pi][i].bcnt, 0 );                FST_WRB ( card, txDescrRing[pi][i].bits, 0 );        }        port->txpos  = 0;        port->txipos = 0;        port->txcnt  = 0;        spin_unlock_irqrestore ( &card->card_lock, flags );}/*      Control signal change interrupt event */static voidfst_intr_ctlchg ( struct fst_card_info *card, struct fst_port_info *port ){        int signals;        signals = FST_RDL ( card, v24DebouncedSts[port->index]);        if ( signals & (( port->hwif == X21 ) ? IPSTS_INDICATE : IPSTS_DCD ))        {                if ( ! netif_carrier_ok ( port->dev ))                {                        dbg ( DBG_INTR,"DCD active\n");                        /* Poke sPPP to renegotiate */                        if ( port->proto == FST_HDLC || port->proto == FST_PPP )                        {                                sppp_reopen ( port->dev );                        }                        netif_carrier_on ( port->dev );                }        }        else        {                if ( netif_carrier_ok ( port->dev ))                {                        dbg ( DBG_INTR,"DCD lost\n");                        netif_carrier_off ( port->dev );                }        }}/*      Rx complete interrupt */static voidfst_intr_rx ( struct fst_card_info *card, struct fst_port_info *port ){        unsigned char dmabits;        int pi;        int rxp;        unsigned short len;        struct sk_buff *skb;        int i;        /* Check we have a buffer to process */        pi  = port->index;        rxp = port->rxpos;        dmabits = FST_RDB ( card, rxDescrRing[pi][rxp].bits );        if ( dmabits & DMA_OWN )        {                dbg ( DBG_RX | DBG_INTR,"intr_rx: No buffer port %d pos %d\n",                                        pi, rxp );                return;        }        /* Get buffer length */        len = FST_RDW ( card, rxDescrRing[pi][rxp].mcnt );        /* Discard the CRC */        len -= 2;        /* Check buffer length and for other errors. We insist on one packet         * in one buffer. This simplifies things greatly and since we've         * allocated 8K it shouldn't be a real world limitation         */        dbg ( DBG_RX,"intr_rx: %d,%d: flags %x len %d\n", pi, rxp, dmabits,                                        len );        if ( dmabits != ( RX_STP | RX_ENP ) || len > LEN_RX_BUFFER - 2 )        {                port->stats.rx_errors++;                /* Update error stats and discard buffer */                if ( dmabits & RX_OFLO )                {                        port->stats.rx_fifo_errors++;                }                if ( dmabits & RX_CRC )                {                        port->stats.rx_crc_errors++;                }                if ( dmabits & RX_FRAM )                {                        port->stats.rx_frame_errors++;                }                if ( dmabits == ( RX_STP | RX_ENP ))                {                        port->stats.rx_length_errors++;                }                /* Discard buffer descriptors until we see the end of packet                 * marker                 */                i = 0;                while (( dmabits & ( DMA_OWN | RX_ENP )) == 0 )                {                        FST_WRB ( card, rxDescrRing[pi][rxp].bits, DMA_OWN );                        if ( ++rxp >= NUM_RX_BUFFER )                                rxp = 0;                        if ( ++i > NUM_RX_BUFFER )                        {                                dbg ( DBG_ASS,"intr_rx: Discarding more bufs"                                                " than we have\n");                                break;                        }                        dmabits = FST_RDB ( card, rxDescrRing[pi][rxp].bits );                }                /* Discard the terminal buffer */                if ( ! ( dmabits & DMA_OWN ))                {                        FST_WRB ( card, rxDescrRing[pi][rxp].bits, DMA_OWN );                        if ( ++rxp >= NUM_RX_BUFFER )                                rxp = 0;                }                port->rxpos = rxp;                return;        }        /* Allocate SKB */        if (( skb = dev_alloc_skb ( len )) == NULL )        {                dbg ( DBG_RX,"intr_rx: can't allocate buffer\n");                port->stats.rx_dropped++;                /* Return descriptor to card */                FST_WRB ( card, rxDescrRing[pi][rxp].bits, DMA_OWN );                if ( ++rxp >= NUM_RX_BUFFER )                        port->rxpos = 0;                else                        port->rxpos = rxp;                return;        }        memcpy_fromio ( skb_put ( skb, len ),                                card->mem + BUF_OFFSET ( rxBuffer[pi][rxp][0]),                                len );        /* Reset buffer descriptor */        FST_WRB ( card, rxDescrRing[pi][rxp].bits, DMA_OWN );        if ( ++rxp >= NUM_RX_BUFFER )                port->rxpos = 0;        else                port->rxpos = rxp;        /* Update stats */        port->stats.rx_packets++;        port->stats.rx_bytes += len;        /* Push upstream */        if ( port->proto == FST_HDLC || port->proto == FST_PPP )        {                /* Mark for further processing by sPPP module */                skb->protocol = htons ( ETH_P_WAN_PPP );        }        else        {                /* DEC customer specific protocol (since nothing defined for                 * marking raw data), at least one other driver uses this value                 * for this purpose.                 */                skb->protocol = htons ( ETH_P_CUST );                skb->pkt_type = PACKET_HOST;        }        skb->mac.raw = skb->data;        skb->dev = port->dev;        netif_rx ( skb );        port->dev->last_rx = jiffies;}/* *      The interrupt service routine *      Dev_id is our fst_card_info pointer */static voidfst_intr ( int irq, void *dev_id, struct pt_regs *regs ){        struct fst_card_info *card;        struct fst_port_info *port;        int rdidx;                      /* Event buffer indices */        int wridx;        int event;                      /* Actual event for processing */        int pi;        if (( card = dev_id ) == NULL )        {                dbg ( DBG_INTR,"intr: spurious %d\n", irq );                return;        }        dbg ( DBG_INTR,"intr: %d %p\n", irq, card );        spin_lock ( &card->card_lock );        /* Clear and reprime the interrupt source */        fst_clear_intr ( card );        /* Set the software acknowledge */        FST_WRB ( card, interruptHandshake, 0xEE );        /* Drain the event queue */        rdidx = FST_RDB ( card, interruptEvent.rdindex );        wridx = FST_RDB ( card, interruptEvent.wrindex );        while ( rdidx != wridx )        {                event = FST_RDB ( card, interruptEvent.evntbuff[rdidx]);                port = &card->ports[event & 0x03];                dbg ( DBG_INTR,"intr: %x\n", event );                switch ( event )                {                case CTLA_CHG:                case CTLB_CHG:                case CTLC_CHG:                case CTLD_CHG:                        if ( port->run && port->dev != NULL )                                fst_intr_ctlchg ( card, port );                        break;                case ABTA_SENT:                case ABTB_SENT:                case ABTC_SENT:                case ABTD_SENT:                        dbg ( DBG_TX,"Abort complete port %d\n", event & 0x03 );                        break;                case TXA_UNDF:                case TXB_UNDF:                case TXC_UNDF:                case TXD_UNDF:                        /* Difficult to see how we'd get this given that we                         * always load up the entire packet for DMA.                         */                        dbg ( DBG_TX,"Tx underflow port %d\n", event & 0x03 );                        port->stats.tx_errors++;                        port->stats.tx_fifo_errors++;                        break;                case INIT_CPLT:                        dbg ( DBG_INIT,"Card init OK intr\n");                        break;                case INIT_FAIL:                        dbg ( DBG_INIT,"Card init FAILED intr\n");                        card->state = FST_IFAILED;                        break;                default:                        printk_err ("intr: unknown card event code. ignored\n");                        break;                }                /* Bump and wrap the index */                if ( ++rdidx >= MAX_CIRBUFF )                        rdidx = 0;        }        FST_WRB ( card, interruptEvent.rdindex, rdidx );        for ( pi = 0, port = card->ports ; pi < card->nports ; pi++, port++ )        {                if ( port->dev == NULL || ! port->run )                        continue;                /* Check for rx completions */                while ( ! ( FST_RDB ( card, rxDescrRing[pi][port->rxpos].bits )                                                                & DMA_OWN ))                {                        fst_intr_rx ( card, port );                }                /* Check for Tx completions */                while ( port->txcnt > 0 && ! ( FST_RDB ( card,                        txDescrRing[pi][port->txipos].bits ) & DMA_OWN ))                {                        --port->txcnt;                        if ( ++port->txipos >= NUM_TX_BUFFER )                                port->txipos = 0;                        netif_wake_queue ( port->dev );                }        }        spin_unlock ( &card->card_lock );}/*      Check that the shared memory configuration is one that we can handle

⌨️ 快捷键说明

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