static void z8530_tx(struct z8530_channel *c) { while(c->txcount) { /* FIFO full ? */ if(!(read_zsreg(c, R0)&4)) return; c->txcount--; /* * Shovel out the byte */ write_zsreg(c, R8, *c->tx_ptr++); write_zsctrl(c, RES_H_IUS); /* We are about to underflow */ if(c->txcount==0) { write_zsctrl(c, RES_EOM_L); write_zsreg(c, R10, c->regs[10]&~ABUNDER); } } /* * End of frame TX - fire another one */ write_zsctrl(c, RES_Tx_P); z8530_tx_done(c); write_zsctrl(c, RES_H_IUS); }
static void z8530_status(struct z8530_channel *chan) { u8 status, altered; status = read_zsreg(chan, R0); altered = chan->status ^ status; chan->status = status; if (status & TxEOM) { /* printk("%s: Tx underrun.\n", chan->dev->name); */ chan->netdevice->stats.tx_fifo_errors++; write_zsctrl(chan, ERR_RES); z8530_tx_done(chan); } if (altered & chan->dcdcheck) { if (status & chan->dcdcheck) { printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3] | RxENABLE); if (chan->netdevice) netif_carrier_on(chan->netdevice); } else { printk(KERN_INFO "%s: DCD lost\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE); z8530_flush_fifo(chan); if (chan->netdevice) netif_carrier_off(chan->netdevice); } } write_zsctrl(chan, RES_EXT_INT); write_zsctrl(chan, RES_H_IUS); }
static void z8530_dma_status(struct z8530_channel *chan) { u8 status, altered; status=read_zsreg(chan, R0); altered=chan->status^status; chan->status=status; if(chan->dma_tx) { if(status&TxEOM) { unsigned long flags; flags=claim_dma_lock(); disable_dma(chan->txdma); clear_dma_ff(chan->txdma); chan->txdma_on=0; release_dma_lock(flags); z8530_tx_done(chan); } } if(altered&chan->dcdcheck) { if(status&chan->dcdcheck) { printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3]|RxENABLE); if(chan->netdevice && ((chan->netdevice->type == ARPHRD_HDLC) || (chan->netdevice->type == ARPHRD_PPP))) sppp_reopen(chan->netdevice); } else { printk(KERN_INFO "%s:DCD lost\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3]&~RxENABLE); z8530_flush_fifo(chan); } } write_zsctrl(chan, RES_EXT_INT); write_zsctrl(chan, RES_H_IUS); }