本文整理汇总了C++中dev_kfree_skb_irq函数的典型用法代码示例。如果您正苦于以下问题:C++ dev_kfree_skb_irq函数的具体用法?C++ dev_kfree_skb_irq怎么用?C++ dev_kfree_skb_irq使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了dev_kfree_skb_irq函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: iwch_ev_dispatch
//.........这里部分代码省略.........
spin_unlock(&rnicp->lock);
/*
* 1) completion of our sending a TERMINATE.
* 2) incoming TERMINATE message.
*/
if ((CQE_OPCODE(rsp_msg->cqe) == T3_TERMINATE) &&
(CQE_STATUS(rsp_msg->cqe) == 0)) {
if (SQ_TYPE(rsp_msg->cqe)) {
PDBG("%s QPID 0x%x ep %p disconnecting\n",
__func__, qhp->wq.qpid, qhp->ep);
iwch_ep_disconnect(qhp->ep, 0, GFP_ATOMIC);
} else {
PDBG("%s post REQ_ERR AE QPID 0x%x\n", __func__,
qhp->wq.qpid);
post_qp_event(rnicp, chp, rsp_msg,
IB_EVENT_QP_REQ_ERR, 0);
iwch_ep_disconnect(qhp->ep, 0, GFP_ATOMIC);
}
goto done;
}
/* Bad incoming Read request */
if (SQ_TYPE(rsp_msg->cqe) &&
(CQE_OPCODE(rsp_msg->cqe) == T3_READ_RESP)) {
post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_REQ_ERR, 1);
goto done;
}
/* Bad incoming write */
if (RQ_TYPE(rsp_msg->cqe) &&
(CQE_OPCODE(rsp_msg->cqe) == T3_RDMA_WRITE)) {
post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_REQ_ERR, 1);
goto done;
}
switch (CQE_STATUS(rsp_msg->cqe)) {
/* Completion Events */
case TPT_ERR_SUCCESS:
/*
* Confirm the destination entry if this is a RECV completion.
*/
if (qhp->ep && SQ_TYPE(rsp_msg->cqe))
dst_confirm(qhp->ep->dst);
(*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
break;
case TPT_ERR_STAG:
case TPT_ERR_PDID:
case TPT_ERR_QPID:
case TPT_ERR_ACCESS:
case TPT_ERR_WRAP:
case TPT_ERR_BOUND:
case TPT_ERR_INVALIDATE_SHARED_MR:
case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1);
break;
/* Device Fatal Errors */
case TPT_ERR_ECC:
case TPT_ERR_ECC_PSTAG:
case TPT_ERR_INTERNAL_ERR:
post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_DEVICE_FATAL, 1);
break;
/* QP Fatal Errors */
case TPT_ERR_OUT_OF_RQE:
case TPT_ERR_PBL_ADDR_BOUND:
case TPT_ERR_CRC:
case TPT_ERR_MARKER:
case TPT_ERR_PDU_LEN_ERR:
case TPT_ERR_DDP_VERSION:
case TPT_ERR_RDMA_VERSION:
case TPT_ERR_OPCODE:
case TPT_ERR_DDP_QUEUE_NUM:
case TPT_ERR_MSN:
case TPT_ERR_TBIT:
case TPT_ERR_MO:
case TPT_ERR_MSN_GAP:
case TPT_ERR_MSN_RANGE:
case TPT_ERR_RQE_ADDR_BOUND:
case TPT_ERR_IRD_OVERFLOW:
post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_FATAL, 1);
break;
default:
printk(KERN_ERR MOD "Unknown T3 status 0x%x QPID 0x%x\n",
CQE_STATUS(rsp_msg->cqe), qhp->wq.qpid);
post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_FATAL, 1);
break;
}
done:
if (atomic_dec_and_test(&chp->refcnt))
wake_up(&chp->wait);
iwch_qp_rem_ref(&qhp->ibqp);
out:
dev_kfree_skb_irq(skb);
}
开发者ID:710leo,项目名称:LVS,代码行数:101,代码来源:iwch_ev.c
示例2: elp_interrupt
static void elp_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr)
{
int len;
int dlen;
int icount = 0;
struct net_device *dev;
elp_device *adapter;
int timeout;
dev = dev_id;
adapter = (elp_device *) dev->priv;
spin_lock(&adapter->lock);
do {
/*
* has a DMA transfer finished?
*/
if (inb_status(dev->base_addr) & DONE) {
if (!adapter->dmaing) {
printk("%s: phantom DMA completed\n", dev->name);
}
if (elp_debug >= 3) {
printk("%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr));
}
outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
if (adapter->current_dma.direction) {
dev_kfree_skb_irq(adapter->current_dma.skb);
} else {
struct sk_buff *skb = adapter->current_dma.skb;
if (skb) {
if (adapter->current_dma.target) {
/* have already done the skb_put() */
memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length);
}
skb->protocol = eth_type_trans(skb,dev);
adapter->stats.rx_bytes += skb->len;
netif_rx(skb);
dev->last_rx = jiffies;
}
}
adapter->dmaing = 0;
if (adapter->rx_backlog.in != adapter->rx_backlog.out) {
int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
if (elp_debug >= 2)
printk("%s: receiving backlogged packet (%d)\n", dev->name, t);
receive_packet(dev, t);
} else {
adapter->busy = 0;
}
} else {
/* has one timed out? */
check_3c505_dma(dev);
}
/*
* receive a PCB from the adapter
*/
timeout = jiffies + 3*HZ/100;
while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) {
if (receive_pcb(dev, &adapter->irx_pcb)) {
switch (adapter->irx_pcb.command)
{
case 0:
break;
/*
* received a packet - this must be handled fast
*/
case 0xff:
case CMD_RECEIVE_PACKET_COMPLETE:
/* if the device isn't open, don't pass packets up the stack */
if (!netif_running(dev))
break;
len = adapter->irx_pcb.data.rcv_resp.pkt_len;
dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
printk(KERN_ERR "%s: interrupt - packet not received correctly\n", dev->name);
} else {
if (elp_debug >= 3) {
printk("%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
}
if (adapter->irx_pcb.command == 0xff) {
if (elp_debug >= 2)
printk("%s: adding packet to backlog (len = %d)\n", dev->name, dlen);
adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
} else {
receive_packet(dev, dlen);
}
if (elp_debug >= 3)
printk("%s: packet received\n", dev->name);
}
break;
/*
* 82586 configured correctly
*/
case CMD_CONFIGURE_82586_RESPONSE:
//.........这里部分代码省略.........
开发者ID:SimonKagstrom,项目名称:mci500h-linux-2.4.27,代码行数:101,代码来源:3c505.c
示例3: fs_enet_tx
static void fs_enet_tx(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
cbd_t __iomem *bdp;
struct sk_buff *skb;
int dirtyidx, do_wake, do_restart;
u16 sc;
spin_lock(&fep->tx_lock);
bdp = fep->dirty_tx;
do_wake = do_restart = 0;
while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
dirtyidx = bdp - fep->tx_bd_base;
if (fep->tx_free == fep->tx_ring)
break;
skb = fep->tx_skbuff[dirtyidx];
/*
* Check for errors.
*/
if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
if (sc & BD_ENET_TX_HB) /* No heartbeat */
fep->stats.tx_heartbeat_errors++;
if (sc & BD_ENET_TX_LC) /* Late collision */
fep->stats.tx_window_errors++;
if (sc & BD_ENET_TX_RL) /* Retrans limit */
fep->stats.tx_aborted_errors++;
if (sc & BD_ENET_TX_UN) /* Underrun */
fep->stats.tx_fifo_errors++;
if (sc & BD_ENET_TX_CSL) /* Carrier lost */
fep->stats.tx_carrier_errors++;
if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
fep->stats.tx_errors++;
do_restart = 1;
}
} else
fep->stats.tx_packets++;
if (sc & BD_ENET_TX_READY) {
dev_warn(fep->dev,
"HEY! Enet xmit interrupt and TX_READY.\n");
}
/*
* Deferred means some collisions occurred during transmit,
* but we eventually sent the packet OK.
*/
if (sc & BD_ENET_TX_DEF)
fep->stats.collisions++;
/* unmap */
dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
skb->len, DMA_TO_DEVICE);
/*
* Free the sk buffer associated with this last transmit.
*/
dev_kfree_skb_irq(skb);
fep->tx_skbuff[dirtyidx] = NULL;
/*
* Update pointer to next buffer descriptor to be transmitted.
*/
if ((sc & BD_ENET_TX_WRAP) == 0)
bdp++;
else
bdp = fep->tx_bd_base;
/*
* Since we have freed up a buffer, the ring is no longer
* full.
*/
if (!fep->tx_free++)
do_wake = 1;
}
fep->dirty_tx = bdp;
if (do_restart)
(*fep->ops->tx_restart)(dev);
spin_unlock(&fep->tx_lock);
if (do_wake)
netif_wake_queue(dev);
}
开发者ID:AdrianHuang,项目名称:linux-3.8.13,代码行数:92,代码来源:fs_enet-main.c
示例4: sonic_interrupt
/*
* The typical workload of the driver:
* Handle the network interface interrupts.
*/
static irqreturn_t sonic_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct sonic_local *lp = netdev_priv(dev);
int status;
if (!(status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT))
return IRQ_NONE;
do {
if (status & SONIC_INT_PKTRX) {
if (sonic_debug > 2)
printk("%s: packet rx\n", dev->name);
sonic_rx(dev); /* got packet(s) */
SONIC_WRITE(SONIC_ISR, SONIC_INT_PKTRX); /* clear the interrupt */
}
if (status & SONIC_INT_TXDN) {
int entry = lp->cur_tx;
int td_status;
int freed_some = 0;
/* At this point, cur_tx is the index of a TD that is one of:
* unallocated/freed (status set & tx_skb[entry] clear)
* allocated and sent (status set & tx_skb[entry] set )
* allocated and not yet sent (status clear & tx_skb[entry] set )
* still being allocated by sonic_send_packet (status clear & tx_skb[entry] clear)
*/
if (sonic_debug > 2)
printk("%s: tx done\n", dev->name);
while (lp->tx_skb[entry] != NULL) {
if ((td_status = sonic_tda_get(dev, entry, SONIC_TD_STATUS)) == 0)
break;
if (td_status & 0x0001) {
lp->stats.tx_packets++;
lp->stats.tx_bytes += sonic_tda_get(dev, entry, SONIC_TD_PKTSIZE);
} else {
lp->stats.tx_errors++;
if (td_status & 0x0642)
lp->stats.tx_aborted_errors++;
if (td_status & 0x0180)
lp->stats.tx_carrier_errors++;
if (td_status & 0x0020)
lp->stats.tx_window_errors++;
if (td_status & 0x0004)
lp->stats.tx_fifo_errors++;
}
/* We must free the original skb */
dev_kfree_skb_irq(lp->tx_skb[entry]);
lp->tx_skb[entry] = NULL;
/* and unmap DMA buffer */
dma_unmap_single(lp->device, lp->tx_laddr[entry], lp->tx_len[entry], DMA_TO_DEVICE);
lp->tx_laddr[entry] = (dma_addr_t)0;
freed_some = 1;
if (sonic_tda_get(dev, entry, SONIC_TD_LINK) & SONIC_EOL) {
entry = (entry + 1) & SONIC_TDS_MASK;
break;
}
entry = (entry + 1) & SONIC_TDS_MASK;
}
if (freed_some || lp->tx_skb[entry] == NULL)
netif_wake_queue(dev); /* The ring is no longer full */
lp->cur_tx = entry;
SONIC_WRITE(SONIC_ISR, SONIC_INT_TXDN); /* clear the interrupt */
}
/*
* check error conditions
*/
if (status & SONIC_INT_RFO) {
if (sonic_debug > 1)
printk("%s: rx fifo overrun\n", dev->name);
lp->stats.rx_fifo_errors++;
SONIC_WRITE(SONIC_ISR, SONIC_INT_RFO); /* clear the interrupt */
}
if (status & SONIC_INT_RDE) {
if (sonic_debug > 1)
printk("%s: rx descriptors exhausted\n", dev->name);
lp->stats.rx_dropped++;
SONIC_WRITE(SONIC_ISR, SONIC_INT_RDE); /* clear the interrupt */
}
if (status & SONIC_INT_RBAE) {
if (sonic_debug > 1)
printk("%s: rx buffer area exceeded\n", dev->name);
lp->stats.rx_dropped++;
SONIC_WRITE(SONIC_ISR, SONIC_INT_RBAE); /* clear the interrupt */
}
/* counter overruns; all counters are 16bit wide */
if (status & SONIC_INT_FAE) {
//.........这里部分代码省略.........
开发者ID:CSCLOG,项目名称:beaglebone,代码行数:101,代码来源:sonic.c
示例5: receive_dmsg
static
int receive_dmsg(struct IsdnCardState *cs)
{
struct sk_buff *skb;
int idx;
int rcnt, z1, z2;
u_char stat, cip, f1, f2;
int chksum;
int count=5;
u_char *ptr;
if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
debugl1(cs, "rec_dmsg blocked");
return(1);
}
SelFiFo(cs, 4 | HFCD_REC);
cip = HFCD_FIFO | HFCD_F1 | HFCD_REC;
WaitNoBusy(cs);
f1 = cs->readisac(cs, cip) & 0xf;
cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
WaitNoBusy(cs);
f2 = cs->readisac(cs, cip) & 0xf;
while ((f1 != f2) && count--) {
z1 = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_REC);
z2 = ReadZReg(cs, HFCD_FIFO | HFCD_Z2 | HFCD_REC);
rcnt = z1 - z2;
if (rcnt < 0)
rcnt += cs->hw.hfcD.dfifosize;
rcnt++;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "hfcd recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)",
f1, f2, z1, z2, rcnt);
idx = 0;
cip = HFCD_FIFO | HFCD_FIFO_OUT | HFCD_REC;
if (rcnt > MAX_DFRAME_LEN + 3) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "empty_fifo d: incoming packet too large");
while (idx < rcnt) {
if (!(WaitNoBusy(cs)))
break;
ReadReg(cs, HFCD_DATA_NODEB, cip);
idx++;
}
} else if (rcnt < 4) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "empty_fifo d: incoming packet too small");
while ((idx++ < rcnt) && WaitNoBusy(cs))
ReadReg(cs, HFCD_DATA_NODEB, cip);
} else if ((skb = dev_alloc_skb(rcnt - 3))) {
ptr = skb_put(skb, rcnt - 3);
while (idx < (rcnt - 3)) {
if (!(WaitNoBusy(cs)))
break;
*ptr = ReadReg(cs, HFCD_DATA_NODEB, cip);
idx++;
ptr++;
}
if (idx != (rcnt - 3)) {
debugl1(cs, "RFIFO D BUSY error");
printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n");
dev_kfree_skb_irq(skb);
skb = NULL;
#ifdef ERROR_STATISTIC
cs->err_rx++;
#endif
} else {
WaitNoBusy(cs);
chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
WaitNoBusy(cs);
chksum += ReadReg(cs, HFCD_DATA, cip);
WaitNoBusy(cs);
stat = ReadReg(cs, HFCD_DATA, cip);
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "empty_dfifo chksum %x stat %x",
chksum, stat);
if (stat) {
debugl1(cs, "FIFO CRC error");
dev_kfree_skb_irq(skb);
skb = NULL;
#ifdef ERROR_STATISTIC
cs->err_crc++;
#endif
} else {
skb_queue_tail(&cs->rq, skb);
schedule_event(cs, D_RCVBUFREADY);
}
}
} else
printk(KERN_WARNING "HFC: D receive out of memory\n");
WaitForBusy(cs);
cip = HFCD_FIFO | HFCD_F2_INC | HFCD_REC;
WaitNoBusy(cs);
stat = ReadReg(cs, HFCD_DATA, cip);
WaitForBusy(cs);
cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
WaitNoBusy(cs);
f2 = cs->readisac(cs, cip) & 0xf;
}
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
return(1);
//.........这里部分代码省略.........
开发者ID:ManiacTwister,项目名称:linux-hnd,代码行数:101,代码来源:hfc_2bds0.c
示例6: Memhscx_interrupt
static inline void
Memhscx_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 = MemReadHSCX(cs, hscx, HSCX_RSTA);
if ((r & 0xf0) != 0xa0) {
if (!(r & 0x80))
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX invalid frame");
if ((r & 0x40) && bcs->mode)
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX RDO mode=%d",
bcs->mode);
if (!(r & 0x20))
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX CRC error");
MemWriteHSCXCMDR(cs, hscx, 0x80);
} else {
count = MemReadHSCX(cs, hscx, HSCX_RBCL) & (
test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
if (count == 0)
count = fifo_size;
Memhscx_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 */
Memhscx_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) {
Memhscx_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);
Memhscx_fill_fifo(bcs);
} else {
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
hscx_sched_event(bcs, B_XMTBUFREADY);
}
}
}
开发者ID:nhanh0,项目名称:hah,代码行数:84,代码来源:diva.c
示例7: mc32_tx_ring
static void mc32_tx_ring(struct net_device *dev)
{
struct mc32_local *lp = netdev_priv(dev);
volatile struct skb_header *np;
/*
* We rely on head==tail to mean 'queue empty'.
* This is why lp->tx_count=TX_RING_LEN-1: in order to prevent
* tx_ring_head wrapping to tail and confusing a 'queue empty'
* condition with 'queue full'
*/
while (lp->tx_ring_tail != atomic_read(&lp->tx_ring_head))
{
u16 t;
t=next_tx(lp->tx_ring_tail);
np=lp->tx_ring[t].p;
if(!(np->status & (1<<7)))
{
/* Not COMPLETED */
break;
}
lp->net_stats.tx_packets++;
if(!(np->status & (1<<6))) /* Not COMPLETED_OK */
{
lp->net_stats.tx_errors++;
switch(np->status&0x0F)
{
case 1:
lp->net_stats.tx_aborted_errors++;
break; /* Max collisions */
case 2:
lp->net_stats.tx_fifo_errors++;
break;
case 3:
lp->net_stats.tx_carrier_errors++;
break;
case 4:
lp->net_stats.tx_window_errors++;
break; /* CTS Lost */
case 5:
lp->net_stats.tx_aborted_errors++;
break; /* Transmit timeout */
}
}
/* Packets are sent in order - this is
basically a FIFO queue of buffers matching
the card ring */
lp->net_stats.tx_bytes+=lp->tx_ring[t].skb->len;
dev_kfree_skb_irq(lp->tx_ring[t].skb);
lp->tx_ring[t].skb=NULL;
atomic_inc(&lp->tx_count);
netif_wake_queue(dev);
lp->tx_ring_tail=t;
}
}
开发者ID:mrtos,项目名称:Logitech-Revue,代码行数:61,代码来源:3c527.c
示例8: W6692B_interrupt
//.........这里部分代码省略.........
cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
} else {
count = cs->BC_Read_Reg(cs, bchan, W_B_RBCL) & (W_B_FIFO_THRESH - 1);
if (count == 0)
count = W_B_FIFO_THRESH;
W6692B_empty_fifo(bcs, count);
if ((count = bcs->hw.w6692.rcvidx) > 0) {
if (cs->debug & L1_DEB_HSCX_FIFO)
debugl1(cs, "W6692 Bchan Frame %d", count);
if (!(skb = dev_alloc_skb(count)))
printk(KERN_WARNING "W6692: Bchan receive out of memory\n");
else {
memcpy(skb_put(skb, count), bcs->hw.w6692.rcvbuf, count);
skb_queue_tail(&bcs->rqueue, skb);
}
}
}
bcs->hw.w6692.rcvidx = 0;
schedule_event(bcs, B_RCVBUFREADY);
}
if (val & W_B_EXI_RMR) { /* RMR */
W6692B_empty_fifo(bcs, W_B_FIFO_THRESH);
r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
if (r & W_B_STAR_RDOV) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 B RDOV(RMR) mode=%d",bcs->mode);
cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
if (bcs->mode != L1_MODE_TRANS)
bcs->hw.w6692.rcvidx = 0;
}
if (bcs->mode == L1_MODE_TRANS) {
/* receive audio data */
if (!(skb = dev_alloc_skb(W_B_FIFO_THRESH)))
printk(KERN_WARNING "HiSax: receive out of memory\n");
else {
memcpy(skb_put(skb, W_B_FIFO_THRESH), bcs->hw.w6692.rcvbuf, W_B_FIFO_THRESH);
skb_queue_tail(&bcs->rqueue, skb);
}
bcs->hw.w6692.rcvidx = 0;
schedule_event(bcs, B_RCVBUFREADY);
}
}
if (val & W_B_EXI_XDUN) { /* XDUN */
cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 B EXIR %x Lost TX", val);
if (bcs->mode == 1)
W6692B_fill_fifo(bcs);
else {
/* Here we lost an TX interrupt, so
* restart transmitting the whole frame.
*/
if (bcs->tx_skb) {
skb_push(bcs->tx_skb, bcs->hw.w6692.count);
bcs->tx_cnt += bcs->hw.w6692.count;
bcs->hw.w6692.count = 0;
}
}
return;
}
if (val & W_B_EXI_XFR) { /* XFR */
r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
if (r & W_B_STAR_XDOW) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 B STAR %x XDOW", r);
cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
if (bcs->tx_skb && (bcs->mode != 1)) {
skb_push(bcs->tx_skb, bcs->hw.w6692.count);
bcs->tx_cnt += bcs->hw.w6692.count;
bcs->hw.w6692.count = 0;
}
}
if (bcs->tx_skb) {
if (bcs->tx_skb->len) {
W6692B_fill_fifo(bcs);
return;
} else {
if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
u_long flags;
spin_lock_irqsave(&bcs->aclock, flags);
bcs->ackcnt += bcs->hw.w6692.count;
spin_unlock_irqrestore(&bcs->aclock, flags);
schedule_event(bcs, B_ACKPENDING);
}
dev_kfree_skb_irq(bcs->tx_skb);
bcs->hw.w6692.count = 0;
bcs->tx_skb = NULL;
}
}
if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
bcs->hw.w6692.count = 0;
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
W6692B_fill_fifo(bcs);
} else {
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
schedule_event(bcs, B_XMTBUFREADY);
}
}
}
开发者ID:ManiacTwister,项目名称:linux-hnd,代码行数:101,代码来源:w6692.c
示例9: ctcm_transmit_skb
/**
* Transmit a packet.
* This is a helper function for ctcm_tx().
*
* ch Channel to be used for sending.
* skb Pointer to struct sk_buff of packet to send.
* The linklevel header has already been set up
* by ctcm_tx().
*
* returns 0 on success, -ERRNO on failure. (Never fails.)
*/
static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
{
unsigned long saveflags;
struct ll_header header;
int rc = 0;
__u16 block_len;
int ccw_idx;
struct sk_buff *nskb;
unsigned long hi;
/* we need to acquire the lock for testing the state
* otherwise we can have an IRQ changing the state to
* TXIDLE after the test but before acquiring the lock.
*/
spin_lock_irqsave(&ch->collect_lock, saveflags);
if (fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) {
int l = skb->len + LL_HEADER_LENGTH;
if (ch->collect_len + l > ch->max_bufsize - 2) {
spin_unlock_irqrestore(&ch->collect_lock, saveflags);
return -EBUSY;
} else {
atomic_inc(&skb->users);
header.length = l;
header.type = skb->protocol;
header.unused = 0;
memcpy(skb_push(skb, LL_HEADER_LENGTH), &header,
LL_HEADER_LENGTH);
skb_queue_tail(&ch->collect_queue, skb);
ch->collect_len += l;
}
spin_unlock_irqrestore(&ch->collect_lock, saveflags);
goto done;
}
spin_unlock_irqrestore(&ch->collect_lock, saveflags);
/*
* Protect skb against beeing free'd by upper
* layers.
*/
atomic_inc(&skb->users);
ch->prof.txlen += skb->len;
header.length = skb->len + LL_HEADER_LENGTH;
header.type = skb->protocol;
header.unused = 0;
memcpy(skb_push(skb, LL_HEADER_LENGTH), &header, LL_HEADER_LENGTH);
block_len = skb->len + 2;
*((__u16 *)skb_push(skb, 2)) = block_len;
/*
* IDAL support in CTCM is broken, so we have to
* care about skb's above 2G ourselves.
*/
hi = ((unsigned long)skb_tail_pointer(skb) + LL_HEADER_LENGTH) >> 31;
if (hi) {
nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
if (!nskb) {
atomic_dec(&skb->users);
skb_pull(skb, LL_HEADER_LENGTH + 2);
ctcm_clear_busy(ch->netdev);
return -ENOMEM;
} else {
memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
atomic_inc(&nskb->users);
atomic_dec(&skb->users);
dev_kfree_skb_irq(skb);
skb = nskb;
}
}
ch->ccw[4].count = block_len;
if (set_normalized_cda(&ch->ccw[4], skb->data)) {
/*
* idal allocation failed, try via copying to
* trans_skb. trans_skb usually has a pre-allocated
* idal.
*/
if (ctcm_checkalloc_buffer(ch)) {
/*
* Remove our header. It gets added
* again on retransmit.
*/
atomic_dec(&skb->users);
skb_pull(skb, LL_HEADER_LENGTH + 2);
ctcm_clear_busy(ch->netdev);
return -ENOMEM;
}
skb_reset_tail_pointer(ch->trans_skb);
ch->trans_skb->len = 0;
//.........这里部分代码省略.........
开发者ID:3null,项目名称:fastsocket,代码行数:101,代码来源:ctcm_main.c
示例10: intr_handler
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
{
struct net_device *dev = (struct net_device *)dev_instance;
struct netdev_private *np;
long ioaddr;
int boguscnt = max_interrupt_work;
ioaddr = dev->base_addr;
np = dev->priv;
spin_lock(&np->lock);
do {
int intr_status = readw(ioaddr + IntrStatus);
writew(intr_status & (IntrRxDone | IntrRxDMADone | IntrPCIErr |
IntrDrvRqst | IntrTxDone | IntrTxDMADone | StatsMax |
LinkChange), ioaddr + IntrStatus);
if (debug > 4)
printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
dev->name, intr_status);
if (intr_status == 0)
break;
if (intr_status & (IntrRxDone|IntrRxDMADone))
netdev_rx(dev);
if (intr_status & IntrTxDone) {
int boguscnt = 32;
int tx_status = readw(ioaddr + TxStatus);
while (tx_status & 0x80) {
if (debug > 4)
printk("%s: Transmit status is %2.2x.\n",
dev->name, tx_status);
if (tx_status & 0x1e) {
np->stats.tx_errors++;
if (tx_status & 0x10) np->stats.tx_fifo_errors++;
#ifdef ETHER_STATS
if (tx_status & 0x08) np->stats.collisions16++;
#else
if (tx_status & 0x08) np->stats.collisions++;
#endif
if (tx_status & 0x04) np->stats.tx_fifo_errors++;
if (tx_status & 0x02) np->stats.tx_window_errors++;
/* This reset has not been verified!. */
if (tx_status & 0x10) { /* Reset the Tx. */
writew(0x001c, ioaddr + ASICCtrl + 2);
#if 0 /* Do we need to reset the Tx pointer here? */
writel(np->tx_ring_dma
+ np->dirty_tx*sizeof(*np->tx_ring),
dev->base_addr + TxListPtr);
#endif
}
if (tx_status & 0x1e) /* Restart the Tx. */
writew(TxEnable, ioaddr + MACCtrl1);
}
/* Yup, this is a documentation bug. It cost me *hours*. */
writew(0, ioaddr + TxStatus);
tx_status = readb(ioaddr + TxStatus);
if (--boguscnt < 0)
break;
}
}
for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
int entry = np->dirty_tx % TX_RING_SIZE;
struct sk_buff *skb;
if ( ! (np->tx_ring[entry].status & 0x00010000))
break;
skb = np->tx_skbuff[entry];
/* Free the original skb. */
pci_unmap_single(np->pci_dev,
np->tx_ring[entry].frag[0].addr,
skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb_irq(skb);
np->tx_skbuff[entry] = 0;
}
if (np->tx_full
&& np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
/* The ring is no longer full, clear tbusy. */
np->tx_full = 0;
netif_wake_queue(dev);
}
/* Abnormal error summary/uncommon events handlers. */
if (intr_status & (IntrDrvRqst | IntrPCIErr | LinkChange | StatsMax))
netdev_error(dev, intr_status);
if (--boguscnt < 0) {
get_stats(dev);
if (debug > 1)
printk(KERN_WARNING "%s: Too much work at interrupt, "
"status=0x%4.4x / 0x%4.4x.\n",
dev->name, intr_status, readw(ioaddr + IntrClear));
/* Re-enable us in 3.2msec. */
writew(0, ioaddr + IntrEnable);
writew(1000, ioaddr + DownCounter);
writew(IntrDrvRqst, ioaddr + IntrEnable);
break;
//.........这里部分代码省略.........
开发者ID:liexusong,项目名称:Linux-2.4.16,代码行数:101,代码来源:sundance.c
示例11: dev_kfree_skb_irq
struct sk_buff *acd_venet_drop_rx(acd_venet_rx_info_t *info)
{
dev_kfree_skb_irq(info->avri_skb);
info->avri_skb = NULL;
return NULL;
}
开发者ID:thechinh,项目名称:play-with-code,代码行数:6,代码来源:acd_oam_fltr.c
示例12: W6692_interrupt
static irqreturn_t
W6692_interrupt(int intno, void *dev_id)
{
struct IsdnCardState *cs = dev_id;
u_char val, exval, v1;
struct sk_buff *skb;
u_int count;
u_long flags;
int icnt = 5;
spin_lock_irqsave(&cs->lock, flags);
val = cs->readW6692(cs, W_ISTA);
if (!val) {
spin_unlock_irqrestore(&cs->lock, flags);
return IRQ_NONE;
}
StartW6692:
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "W6692 ISTA %x", val);
if (val & W_INT_D_RME) { /* RME */
exval = cs->readW6692(cs, W_D_RSTA);
if (exval & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
if (exval & W_D_RSTA_RDOV)
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 RDOV");
if (exval & W_D_RSTA_CRCE)
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 D-channel CRC error");
if (exval & W_D_RSTA_RMB)
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 D-channel ABORT");
cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
} else {
count = cs->readW6692(cs, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
if (count == 0)
count = W_D_FIFO_THRESH;
W6692_empty_fifo(cs, count);
if ((count = cs->rcvidx) > 0) {
cs->rcvidx = 0;
if (!(skb = alloc_skb(count, GFP_ATOMIC)))
printk(KERN_WARNING "HiSax: D receive out of memory\n");
else {
memcpy(skb_put(skb, count), cs->rcvbuf, count);
skb_queue_tail(&cs->rq, skb);
}
}
}
cs->rcvidx = 0;
schedule_event(cs, D_RCVBUFREADY);
}
if (val & W_INT_D_RMR) { /* RMR */
W6692_empty_fifo(cs, W_D_FIFO_THRESH);
}
if (val & W_INT_D_XFR) { /* XFR */
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
schedule_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len) {
W6692_fill_fifo(cs);
goto afterXFR;
} else {
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_cnt = 0;
cs->tx_skb = NULL;
}
}
if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
cs->tx_cnt = 0;
W6692_fill_fifo(cs);
} else
schedule_event(cs, D_XMTBUFREADY);
}
afterXFR:
if (val & (W_INT_XINT0 | W_INT_XINT1)) { /* XINT0/1 - never */
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "W6692 spurious XINT!");
}
if (val & W_INT_D_EXI) { /* EXI */
exval = cs->readW6692(cs, W_D_EXIR);
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 D_EXIR %02x", exval);
if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) { /* Transmit underrun/collision */
debugl1(cs, "W6692 D-chan underrun/collision");
printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL\n");
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
schedule_event(cs, D_CLEARBUSY);
if (cs->tx_skb) { /* Restart frame */
skb_push(cs->tx_skb, cs->tx_cnt);
cs->tx_cnt = 0;
W6692_fill_fifo(cs);
} else {
printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL no skb\n");
debugl1(cs, "W6692 XDUN/XCOL no skb");
cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST);
}
//.........这里部分代码省略.........
开发者ID:ManiacTwister,项目名称:linux-hnd,代码行数:101,代码来源:w6692.c
示例13: smd_net_data_handler
/* Called in soft-irq context */
static void smd_net_data_handler(unsigned long arg)
{
struct net_device *dev = (struct net_device *) arg;
struct rmnet_private *p = netdev_priv(dev);
struct sk_buff *skb;
void *ptr = 0;
int sz;
u32 opmode = p->operation_mode;
unsigned long flags;
for (;;) {
sz = smd_cur_packet_size(p->ch);
if (sz == 0) break;
if (smd_read_avail(p->ch) < sz) break;
if (RMNET_IS_MODE_IP(opmode) ? (sz > dev->mtu) :
(sz > (dev->mtu + ETH_HLEN))) {
pr_err("rmnet_recv() discarding %d len (%d mtu)\n",
sz, RMNET_IS_MODE_IP(opmode) ?
dev->mtu : (dev->mtu + ETH_HLEN));
ptr = 0;
} else {
skb = dev_alloc_skb(sz + NET_IP_ALIGN);
if (skb == NULL) {
pr_err("rmnet_recv() cannot allocate skb\n");
} else {
skb->dev = dev;
skb_reserve(skb, NET_IP_ALIGN);
ptr = skb_put(skb, sz);
wake_lock_timeout(&p->wake_lock, HZ / 2);
if (smd_read(p->ch, ptr, sz) != sz) {
pr_err("rmnet_recv() smd lied about avail?!");
ptr = 0;
dev_kfree_skb_irq(skb);
} else {
/* Handle Rx frame format */
spin_lock_irqsave(&p->lock, flags);
opmode = p->operation_mode;
spin_unlock_irqrestore(&p->lock, flags);
if (RMNET_IS_MODE_IP(opmode)) {
/* Driver in IP mode */
skb->protocol =
rmnet_ip_type_trans(skb, dev);
} else {
/* Driver in Ethernet mode */
skb->protocol =
eth_type_trans(skb, dev);
}
if (RMNET_IS_MODE_IP(opmode) ||
count_this_packet(ptr, skb->len)) {
#if 0
p->wakeups_rcv +=
rmnet_cause_wakeup(p);
#endif
p->stats.rx_packets++;
p->stats.rx_bytes += skb->len;
}
netif_rx(skb);
}
continue;
}
}
if (smd_read(p->ch, ptr, sz) != sz)
pr_err("rmnet_recv() smd lied about avail?!");
}
}
开发者ID:vinylfreak89,项目名称:leanKernel-tbolt-aosp,代码行数:68,代码来源:msm_rmnet.c
示例14: icc_interrupt
void
icc_interrupt(struct IsdnCardState *cs, u_char val)
{
u_char exval, v1;
struct sk_buff *skb;
unsigned int count;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ICC interrupt %x", val);
if (val & 0x80) { /* RME */
exval = cs->readisac(cs, ICC_RSTA);
if ((exval & 0x70) != 0x20) {
if (exval & 0x40) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "ICC RDO");
#ifdef ERROR_STATISTIC
cs->err_rx++;
#endif
}
if (!(exval & 0x20)) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "ICC CRC error");
#ifdef ERROR_STATISTIC
cs->err_crc++;
#endif
}
cs->writeisac(cs, ICC_CMDR, 0x80);
} else {
count = cs->readisac(cs, ICC_RBCL) & 0x1f;
if (count == 0)
count = 32;
icc_empty_fifo(cs, count);
if ((count = cs->rcvidx) > 0) {
cs->rcvidx = 0;
if (!(skb = alloc_skb(count, GFP_ATOMIC)))
printk(KERN_WARNING "HiSax: D receive out of memory\n");
else {
memcpy(skb_put(skb, count), cs->rcvbuf, count);
skb_queue_tail(&cs->rq, skb);
}
}
}
cs->rcvidx = 0;
schedule_event(cs, D_RCVBUFREADY);
}
if (val & 0x40) { /* RPF */
icc_empty_fifo(cs, 32);
}
if (val & 0x20) { /* RSC */
/* never */
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "ICC RSC interrupt");
}
if (val & 0x10) { /* XPR */
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
schedule_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len) {
icc_fill_fifo(cs);
goto afterXPR;
} else {
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_cnt = 0;
cs->tx_skb = NULL;
}
}
if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
cs->tx_cnt = 0;
icc_fill_fifo(cs);
} else
schedule_event(cs, D_XMTBUFREADY);
}
afterXPR:
if (val & 0x04) { /* CISQ */
exval = cs->readisac(cs, ICC_CIR0);
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ICC CIR0 %02X", exval );
if (exval & 2) {
cs->dc.icc.ph_state = (exval >> 2) & 0xf;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ph_state change %x", cs->dc.icc.ph_state);
schedule_event(cs, D_L1STATECHANGE);
}
开发者ID:DentonGentry,项目名称:gfiber-gfrg100,代码行数:85,代码来源:icc.c
示例15: Amd7930_interrupt
//.........这里部分代码省略.........
}
/* remove damaged data from fifo */
Amd7930_empty_Dfifo(cs, 1);
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
schedule_event(cs, D_CLEARBUSY);
/* restart TX-Frame */
if (cs->tx_skb) {
skb_push(cs->tx_skb, cs->tx_cnt);
cs->tx_cnt = 0;
cs->dc.amd7930.tx_xmtlen = 0;
Amd7930_fill_Dfifo(cs);
}
}
/* D TX FIFO empty -> fill */
if (irflags & 1) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: interrupt: clear Timer and fill D-TX-FIFO if data");
/* AMD interrupts off */
AmdIrqOff(cs);
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
schedule_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len)
Amd7930_fill_Dfifo(cs);
}
/* AMD interrupts on */
AmdIrqOn(cs);
}
/* D RX FIFO full or tiny packet in Fifo -> empty */
if ((irflags & 2) || (dsr1 & 2)) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: interrupt: empty D-FIFO");
Amd7930_empty_Dfifo(cs, 0);
}
/* D-Frame transmit complete */
if (dsr1 & 64) {
if (cs->debug & L1_DEB_ISAC) {
debugl1(cs, "Amd7930: interrupt: transmit packet ready");
}
/* AMD interrupts off */
AmdIrqOff(cs);
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
schedule_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: interrupt: TX-Packet ready, freeing skb");
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_cnt = 0;
cs->dc.amd7930.tx_xmtlen=0;
cs->tx_skb = NULL;
}
if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: interrupt: TX-Packet ready, next packet dequeued");
cs->tx_cnt = 0;
cs->dc.amd7930.tx_xmtlen=0;
Amd7930_fill_Dfifo(cs);
}
else
schedule_event(cs, D_XMTBUFREADY);
/* AMD interrupts on */
AmdIrqOn(cs);
}
/* LIU status interrupt -> read LSR, check statechanges */
if (lsr & 0x38) {
/* AMD interrupts off */
AmdIrqOff(cs);
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd: interrupt: LSR=0x%02X, LIU is in state %d", lsr, ((lsr & 0x7) +2));
cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
schedule_event(cs, D_L1STATECHANGE);
/* AMD interrupts on */
AmdIrqOn(cs);
}
/* reads Interrupt-Register again. If there is a new interrupt-flag: restart handler */
irflags = rByteAMD(cs, 0x00);
}
}
开发者ID:Medvedroid,项目名称:OT_903D-kernel-2.6.35.7,代码行数:101,代码来源:amd7930_fn.c
示例16: scc_enet_interrupt
/* The interrupt handler.
* This is called from the CPM handler, not the MPC core interrupt.
*/
static void
scc_enet_interrupt(void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
volatile struct scc_enet_private *cep;
volatile cbd_t *bdp;
ushort int_events;
int must_restart;
cep = (struct scc_enet_private *)dev->priv;
/* Get the interrupt events that caused us to be here.
*/
int_events = cep->sccp->scc_scce;
cep->sccp->scc_scce = int_events;
must_restart = 0;
/* Handle receive event in its own function.
*/
if (int_events & SCCE_ENET_RXF)
scc_enet_rx(dev_id);
/* Check for a transmit error. The manual is a little unclear
* about this, so the debug code until I get it figured out. It
* appears that if TXE is set, then TXB is not set. However,
* if carrier sense is lost during frame transmission, the TXE
* bit is set, "and continues the buffer transmission normally."
* I don't know if "normally" implies TXB is set when the buffer
* descriptor is closed.....trial and error :-).
*/
/* Transmit OK, or non-fatal error. Update the buffer descriptors.
*/
if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
spin_lock(&cep->lock);
bdp = cep->dirty_tx;
while ((bdp->cbd_sc&BD_ENET_TX
|
请发表评论