void hfc_fifo_put(struct hfc_chan_simplex *chan, void *data, int size) { struct hfc_card *card = chan->chan->card; int used_bytes = hfc_fifo_used_tx(chan); int free_bytes = hfc_fifo_free_tx(chan); if (!used_bytes && !chan->fifo_underrun++) { /* * print warning only once, to make timing not worse */ printk(KERN_WARNING hfc_DRIVER_PREFIX "card %d: " "chan %s: " "TX FIFO has become empty\n", card->cardnum, chan->chan->name); } if (free_bytes < size) { printk(KERN_CRIT hfc_DRIVER_PREFIX "card %d: " "chan %s: " "TX FIFO full!\n", chan->chan->card->cardnum, chan->chan->name); chan->fifo_full++; hfc_clear_fifo_tx(chan); } hfc_fifo_mem_write(chan, data, size); chan->bytes += size; *Z1_F1(chan) = Z_inc(chan, *Z1_F1(chan), size); }
static ssize_t hfc_sys_chan_write( struct visdn_leg *visdn_leg, const void *buf, size_t count) { struct hfc_sys_chan *chan = to_sys_chan(visdn_leg->chan); struct hfc_card *card = chan->port->card; int copied_octets; int available_octets; int used_octets; hfc_card_lock(card); hfc_fifo_select(&chan->tx_fifo); available_octets = hfc_fifo_free_tx(&chan->tx_fifo); copied_octets = available_octets > count ? count : available_octets; used_octets = hfc_fifo_used_tx(&chan->tx_fifo); chan->tx_fifo.stats_cycles++; if (chan->tx_fifo.stats_cycles >= 10) { if (chan->tx_fifo.stats_min < HFC_FIFO_JITTBUFF) { u8 foo = ((u8 *)buf)[0]; hfc_fifo_mem_write(&chan->tx_fifo, &foo, 1); // printk(KERN_DEBUG "Added one sample\n"); } chan->tx_fifo.stats_cycles = 0; chan->tx_fifo.stats_min = INT_MAX; chan->tx_fifo.stats_max = 0; } if (used_octets < chan->tx_fifo.stats_min) chan->tx_fifo.stats_min = used_octets; if (used_octets + copied_octets > chan->tx_fifo.stats_max) chan->tx_fifo.stats_max = used_octets + copied_octets; hfc_fifo_mem_write(&chan->tx_fifo, buf, copied_octets); hfc_card_unlock(card); return copied_octets; }