예제 #1
0
static void pp_pong(struct pp_ctx *pp)
{
	u32 msg_data = -1, spad_data = -1;
	int pidx = 0;

	/* Read pong data */
	spad_data = ntb_spad_read(pp->ntb, 0);
	msg_data = ntb_msg_read(pp->ntb, &pidx, 0);
	ntb_msg_clear_sts(pp->ntb, -1);

	/*
	 * Scratchpad and message data may differ, since message register can't
	 * be rewritten unless status is cleared. Additionally either of them
	 * might be unsupported
	 */
	dev_dbg(&pp->ntb->dev, "Pong spad %#x, msg %#x (port %d)\n",
		spad_data, msg_data, ntb_peer_port_number(pp->ntb, pidx));

	atomic_inc(&pp->count);

	ntb_db_set_mask(pp->ntb, pp->in_db);
	ntb_db_clear(pp->ntb, pp->in_db);

	hrtimer_start(&pp->timer, ms_to_ktime(delay_ms), HRTIMER_MODE_REL);
}
예제 #2
0
static void
ntb_transport_free_queue(struct ntb_transport_qp *qp)
{
	struct ntb_queue_entry *entry;

	if (qp == NULL)
		return;

	callout_drain(&qp->link_work);

	ntb_db_set_mask(qp->ntb, 1ull << qp->qp_num);
	taskqueue_drain(taskqueue_swi, &qp->rxc_db_work);
	taskqueue_drain(taskqueue_swi, &qp->rx_completion_task);

	qp->cb_data = NULL;
	qp->rx_handler = NULL;
	qp->tx_handler = NULL;
	qp->event_handler = NULL;

	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_pend_q)))
		free(entry, M_NTB_IF);

	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_post_q)))
		free(entry, M_NTB_IF);

	while ((entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q)))
		free(entry, M_NTB_IF);

	set_bit(qp->qp_num, &qp->transport->qp_bitmap_free);
}
예제 #3
0
static void pp_clear(struct pp_ctx *pp)
{
	hrtimer_cancel(&pp->timer);

	ntb_db_set_mask(pp->ntb, pp->in_db);

	dev_dbg(&pp->ntb->dev, "Ping-pong cancelled\n");
}
예제 #4
0
static int pp_mask_events(struct pp_ctx *pp)
{
	u64 db_mask, msg_mask;
	int ret;

	db_mask = ntb_db_valid_mask(pp->ntb);
	ret = ntb_db_set_mask(pp->ntb, db_mask);
	if (ret)
		return ret;

	/* Skip message events masking if unsupported */
	if (ntb_msg_count(pp->ntb) < 1)
		return 0;

	msg_mask = ntb_msg_outbits(pp->ntb) | ntb_msg_inbits(pp->ntb);
	return ntb_msg_set_mask(pp->ntb, msg_mask);
}
예제 #5
0
static void pp_setup(struct pp_ctx *pp)
{
	int ret;

	ntb_db_set_mask(pp->ntb, pp->in_db);

	hrtimer_cancel(&pp->timer);

	ret = pp_find_next_peer(pp);
	if (ret == -ENODEV) {
		dev_dbg(&pp->ntb->dev, "Got no peers, so cancel\n");
		return;
	}

	dev_dbg(&pp->ntb->dev, "Ping-pong started with port %d, db %#llx\n",
		ntb_peer_port_number(pp->ntb, pp->out_pidx), pp->out_db);

	hrtimer_start(&pp->timer, ms_to_ktime(delay_ms), HRTIMER_MODE_REL);
}