示例#1
0
文件: fifo.c 项目: iedemam/AskoziaPBX
void hfc_fifo_put_frame(struct hfc_chan_simplex *chan,
		 void *data, int size)
{
	u16 newz1;
	int available_frames;

#ifdef DEBUG
	if (debug_level == 3) {
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
			"card %d: "
			"chan %s: "
			"TX len %2d: ",
			chan->chan->card->cardnum,
			chan->chan->name,
			size);
	} else if (debug_level >= 4) {
		printk(KERN_DEBUG hfc_DRIVER_PREFIX
			"card %d: "
			"chan %s: "
			"TX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
			chan->chan->card->cardnum,
			chan->chan->name,
			*chan->f1, *chan->f2, *Z1_F1(chan), *Z2_F1(chan),
			size);
	}

	if (debug_level >= 3) {
		int i;
		for (i = 0; i < size; i++)
			printk("%02x", ((u8 *)data)[i]);

		printk("\n");
	}
#endif

	available_frames = hfc_fifo_free_frames(chan);

	if (available_frames >= chan->f_num) {
		printk(KERN_CRIT hfc_DRIVER_PREFIX
			"card %d: "
			"chan %s: "
			"TX FIFO total number of frames exceeded!\n",
			chan->chan->card->cardnum,
			chan->chan->name);

		chan->fifo_full++;

		return;
	}

	hfc_fifo_put(chan, data, size);

	newz1 = *Z1_F1(chan);

	*chan->f1 = F_inc(chan, *chan->f1, 1);

	*Z1_F1(chan) = newz1;

	chan->frames++;
}
示例#2
0
static int hfc_sys_chan_frame_xmit(
	struct visdn_leg *visdn_leg,
	struct sk_buff *skb)
{
	struct hfc_sys_chan *chan = to_sys_chan(visdn_leg->chan);
	struct hfc_card *card = chan->port->card;
	struct hfc_fifo *fifo = &chan->tx_fifo;

	hfc_card_lock(card);

	hfc_fifo_select(fifo);
	/*
	 * hfc_fifo_select() updates F/Z cache, so,
	 * size calculations are allowed
	 */

	if (hfc_fifo_free_frames(fifo) <= 1) {
		hfc_debug_sys_chan(chan, 3,
			"TX FIFO frames full, throttling\n");

		visdn_leg_stop_queue(&chan->visdn_chan.leg_b);
	}

	if (hfc_fifo_free_tx(fifo) < skb->len) {
		hfc_debug_sys_chan(chan, 3,
			"TX FIFO full (%d < %d), throttling\n",
			hfc_fifo_free_tx(fifo), skb->len);

		visdn_leg_stop_queue(&chan->visdn_chan.leg_b);

		visdn_leg_tx_error(&chan->visdn_chan.leg_b,
				VISDN_TX_ERROR_FIFO_FULL);

		goto err_no_free_tx;
	}

#ifdef DEBUG_CODE
	if (debug_level == 3) {
		hfc_fifo_refresh_fz_cache(fifo);
		hfc_debug_sys_chan(chan, 3, "TX len %2d: ", skb->len);

	} else if (debug_level >= 4) {
		hfc_fifo_refresh_fz_cache(fifo);
		hfc_debug_sys_chan(chan, 4,
			"TX (f1=%02x, f2=%02x, z1(f1)=%04x, z2(f2)=%04x)"
			" len %2d: ",
			fifo->f1, fifo->f2, fifo->z1, fifo->z2,
			skb->len);
	}

	if (debug_level >= 3) {
		int i;
		for (i=0; i<skb->len; i++)
			printk("%02x",((u8 *)skb->data)[i]);

		printk("\n");
	}
#endif

	hfc_fifo_mem_write(fifo, skb->data, skb->len);
	hfc_fifo_next_frame(fifo);

	hfc_card_unlock(card);

	visdn_kfree_skb(skb);

#if 0
	if (chan->connected_e1_chan) {
		struct hfc_led *led =
			&card->leds[chan->connected_e1_chan->port->id];

		led->alt_color = HFC_LED_OFF;
		led->flashing_freq = HZ / 10;
		led->flashes = 1;
		hfc_led_update(led);
	}
#endif

	return VISDN_TX_OK;

err_no_free_tx:
	hfc_card_unlock(card);

	return VISDN_TX_BUSY;
}