Beispiel #1
0
static irqreturn_t tsc2005_irq_handler(int irq, void *dev_id)
{
	struct tsc2005 *ts = dev_id;

	/* update the penup timer only if it's pending */
	mod_timer_pending(&ts->penup_timer,
			  jiffies + msecs_to_jiffies(TSC2005_PENUP_TIME_MS));

	return IRQ_WAKE_THREAD;
}
Beispiel #2
0
static void xen_net_rate_changed(struct xenbus_watch *watch,
				const char **vec, unsigned int len)
{
	struct xenvif *vif = container_of(watch, struct xenvif, credit_watch);
	struct xenbus_device *dev = xenvif_to_xenbus_device(vif);
	unsigned long   credit_bytes;
	unsigned long   credit_usec;
	unsigned int queue_index;

	xen_net_read_rate(dev, &credit_bytes, &credit_usec);
	for (queue_index = 0; queue_index < vif->num_queues; queue_index++) {
		struct xenvif_queue *queue = &vif->queues[queue_index];

		queue->credit_bytes = credit_bytes;
		queue->credit_usec = credit_usec;
		if (!mod_timer_pending(&queue->credit_timeout, jiffies) &&
			queue->remaining_credit > queue->credit_bytes) {
			queue->remaining_credit = queue->credit_bytes;
		}
	}
}
static void cfhsi_rx_done(struct cfhsi *cfhsi)
{
	int res;
	int desc_pld_len = 0;
	struct cfhsi_desc *desc = NULL;

	desc = (struct cfhsi_desc *)cfhsi->rx_buf;

	dev_dbg(&cfhsi->ndev->dev, "%s\n", __func__);

	if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
		return;

	/* Update inactivity timer if pending. */
	spin_lock_bh(&cfhsi->lock);
	mod_timer_pending(&cfhsi->timer, jiffies + CFHSI_INACTIVITY_TOUT);
	spin_unlock_bh(&cfhsi->lock);

	if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) {
		desc_pld_len = cfhsi_rx_desc(desc, cfhsi);
		if (desc_pld_len == -ENOMEM)
			goto restart;
		if (desc_pld_len == -EPROTO)
			goto out_of_sync;
	} else {
		int pld_len;

		if (!cfhsi->rx_state.piggy_desc) {
			pld_len = cfhsi_rx_pld(desc, cfhsi);
			if (pld_len == -ENOMEM)
				goto restart;
			if (pld_len == -EPROTO)
				goto out_of_sync;
			cfhsi->rx_state.pld_len = pld_len;
		} else {
			pld_len = cfhsi->rx_state.pld_len;
		}

		if ((pld_len > 0) && (desc->header & CFHSI_PIGGY_DESC)) {
			struct cfhsi_desc *piggy_desc;
			piggy_desc = (struct cfhsi_desc *)
				(desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ +
						pld_len);
			cfhsi->rx_state.piggy_desc = true;

			/* Extract piggy-backed descriptor. */
			desc_pld_len = cfhsi_rx_desc(piggy_desc, cfhsi);
			if (desc_pld_len == -ENOMEM)
				goto restart;

			/*
			 * Copy needed information from the piggy-backed
			 * descriptor to the descriptor in the start.
			 */
			memcpy((u8 *)desc, (u8 *)piggy_desc,
					CFHSI_DESC_SHORT_SZ);

			if (desc_pld_len == -EPROTO)
				goto out_of_sync;
		}
	}

	memset(&cfhsi->rx_state, 0, sizeof(cfhsi->rx_state));
	if (desc_pld_len) {
		set_bit(CFHSI_RX_PAYLOAD, &cfhsi->bits);
		cfhsi->rx_state.state = CFHSI_RX_STATE_PAYLOAD;
		cfhsi->rx_ptr = cfhsi->rx_buf + CFHSI_DESC_SZ;
		cfhsi->rx_len = desc_pld_len;
	} else {
		clear_bit(CFHSI_RX_PAYLOAD, &cfhsi->bits);
		cfhsi->rx_state.state = CFHSI_RX_STATE_DESC;
		cfhsi->rx_ptr = cfhsi->rx_buf;
		cfhsi->rx_len = CFHSI_DESC_SZ;
	}

	if (test_bit(CFHSI_AWAKE, &cfhsi->bits)) {
		/* Set up new transfer. */
		dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n",
			__func__);
		res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len,
				cfhsi->dev);
		if (WARN_ON(res < 0)) {
			dev_err(&cfhsi->ndev->dev, "%s: RX error %d.\n",
				__func__, res);
			cfhsi->ndev->stats.rx_errors++;
			cfhsi->ndev->stats.rx_dropped++;
		}
	}
	return;

restart:
	if (++cfhsi->rx_state.retries > CFHSI_MAX_RX_RETRIES) {
		dev_err(&cfhsi->ndev->dev, "%s: No memory available "
			"in %d iterations.\n",
			__func__, CFHSI_MAX_RX_RETRIES);
		BUG();
	}
	mod_timer(&cfhsi->rx_slowpath_timer, jiffies + 1);
	return;

out_of_sync:
	dev_err(&cfhsi->ndev->dev, "%s: Out of sync.\n", __func__);
	print_hex_dump_bytes("--> ", DUMP_PREFIX_NONE,
			cfhsi->rx_buf, CFHSI_DESC_SZ);
	schedule_work(&cfhsi->out_of_sync_work);
}