Example #1
0
static int signalinsert_inner(struct visorchannel *channel, u32 queue,
			      void *msg)
{
	struct signal_queue_header sig_hdr;
	int err;

	err = sig_read_header(channel, queue, &sig_hdr);
	if (err)
		return err;
	sig_hdr.head = (sig_hdr.head + 1) % sig_hdr.max_slots;
	if (sig_hdr.head == sig_hdr.tail) {
		sig_hdr.num_overflows++;
		err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows);
		if (err)
			return err;
		return -EIO;
	}
	err = sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg);
	if (err)
		return err;
	sig_hdr.num_sent++;
	/*
	 * For each data field in SIGNAL_QUEUE_HEADER that was modified, update
	 * host memory. Required for channel sync.
	 */
	mb();
	err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head);
	if (err)
		return err;
	err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent);
	if (err)
		return err;
	return 0;
}
Example #2
0
static int signalremove_inner(struct visorchannel *channel, u32 queue,
			      void *msg)
{
	struct signal_queue_header sig_hdr;
	int error;

	error = sig_read_header(channel, queue, &sig_hdr);
	if (error)
		return error;
	/* No signals to remove; have caller try again. */
	if (sig_hdr.head == sig_hdr.tail)
		return -EAGAIN;
	sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
	error = sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg);
	if (error)
		return error;
	sig_hdr.num_received++;
	/*
	 * For each data field in SIGNAL_QUEUE_HEADER that was modified, update
	 * host memory. Required for channel sync.
	 */
	mb();
	error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail);
	if (error)
		return error;
	error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received);
	if (error)
		return error;
	return 0;
}
Example #3
0
static BOOL
signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
{
	struct signal_queue_header sig_hdr;

	if (!sig_read_header(channel, queue, &sig_hdr)) {
		return FALSE;
	}
	if (sig_hdr.head == sig_hdr.tail)
		return FALSE;	/* no signals to remove */

	sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
	if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) {
		ERRDRV("sig_read_data failed\n");
		return FALSE;
	}
	sig_hdr.num_received++;

	/* For each data field in SIGNAL_QUEUE_HEADER that was modified,
	 * update host memory.
	 */
	mb(); /* required for channel synch */
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) {
		ERRDRV("visor_memregion_write of Tail failed\n");
		return FALSE;
	}
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) {
		ERRDRV("visor_memregion_write of NumSignalsReceived failed\n");
		return FALSE;
	}
	return TRUE;
}
Example #4
0
int
visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, U32 queue)
{
	SIGNAL_QUEUE_HEADER sig_hdr;
	if (!sig_read_header(channel, queue, &sig_hdr))
		return 0;
	return (int) sig_hdr.MaxSignals;
}
Example #5
0
static bool queue_empty(struct visorchannel *channel, u32 queue)
{
	struct signal_queue_header sig_hdr;

	if (sig_read_header(channel, queue, &sig_hdr))
		return true;
	return (sig_hdr.head == sig_hdr.tail);
}
Example #6
0
int
visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue)
{
	struct signal_queue_header sig_hdr;

	if (!sig_read_header(channel, queue, &sig_hdr))
		return 0;
	return (int)sig_hdr.max_signals;
}
Example #7
0
BOOL
visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg)
{
	BOOL rc = FALSE;
	struct signal_queue_header sig_hdr;

	if (channel->needs_lock)
		spin_lock(&channel->insert_lock);

	if (!sig_read_header(channel, queue, &sig_hdr)) {
		rc = FALSE;
		goto cleanup;
	}

	sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots);
	if (sig_hdr.head == sig_hdr.tail) {
		sig_hdr.num_overflows++;
		if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) {
			ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n",
			       rc);
			goto cleanup;
		}
		rc = FALSE;
		goto cleanup;
	}

	if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) {
		ERRDRV("sig_write_data failed: (status=%d)\n", rc);
		goto cleanup;
	}
	sig_hdr.num_sent++;

	/* For each data field in SIGNAL_QUEUE_HEADER that was modified,
	 * update host memory.
	 */
	mb(); /* required for channel synch */
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) {
		ERRDRV("visor_memregion_write of Head failed: (status=%d)\n",
		       rc);
		goto cleanup;
	}
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) {
		ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n",
		       rc);
		goto cleanup;
	}
	rc = TRUE;
cleanup:
	if (channel->needs_lock)
		spin_unlock(&channel->insert_lock);

	return rc;
}
Example #8
0
BOOL
visorchannel_signalinsert(VISORCHANNEL *channel, U32 queue, void *msg)
{
	BOOL rc = FALSE;
	SIGNAL_QUEUE_HEADER sig_hdr;

	if (channel->needs_lock)
		spin_lock(&channel->insert_lock);

	if (!sig_read_header(channel, queue, &sig_hdr)) {
		rc = FALSE;
		goto Away;
	}

	sig_hdr.Head = ((sig_hdr.Head + 1) % sig_hdr.MaxSignalSlots);
	if (sig_hdr.Head == sig_hdr.Tail) {
		sig_hdr.NumOverflows++;
		if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumOverflows)) {
			ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", rc);
			goto Away;
		}
		rc = FALSE;
		goto Away;
	}

	if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.Head, msg)) {
		ERRDRV("sig_write_data failed: (status=%d)\n", rc);
		goto Away;
	}
	sig_hdr.NumSignalsSent++;

	/* For each data field in SIGNAL_QUEUE_HEADER that was modified,
	 * update host memory.
	 */
	MEMORYBARRIER;
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Head)) {
		ERRDRV("visor_memregion_write of Head failed: (status=%d)\n",
		       rc);
		goto Away;
	}
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumSignalsSent)) {
		ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", rc);
		goto Away;
	}
	rc = TRUE;
Away:
	if (channel->needs_lock)
		spin_unlock(&channel->insert_lock);

	return rc;
}
Example #9
0
int
visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, U32 queue)
{
	SIGNAL_QUEUE_HEADER sig_hdr;
	U32 slots_avail, slots_used;
	U32 head, tail;

	if (!sig_read_header(channel, queue, &sig_hdr))
		return 0;
	head = sig_hdr.Head;
	tail = sig_hdr.Tail;
	if (head < tail)
		head = head + sig_hdr.MaxSignalSlots;
	slots_used = (head - tail);
	slots_avail = sig_hdr.MaxSignals - slots_used;
	return (int) slots_avail;
}
Example #10
0
int
visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue)
{
	struct signal_queue_header sig_hdr;
	u32 slots_avail, slots_used;
	u32 head, tail;

	if (!sig_read_header(channel, queue, &sig_hdr))
		return 0;
	head = sig_hdr.head;
	tail = sig_hdr.tail;
	if (head < tail)
		head = head + sig_hdr.max_slots;
	slots_used = (head - tail);
	slots_avail = sig_hdr.max_signals - slots_used;
	return (int)slots_avail;
}
Example #11
0
BOOL
visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg)
{
	BOOL rc = FALSE;
	struct signal_queue_header sig_hdr;

	if (channel->needs_lock)
		spin_lock(&channel->remove_lock);

	if (!sig_read_header(channel, queue, &sig_hdr)) {
		rc = FALSE;
		goto cleanup;
	}
	if (sig_hdr.head == sig_hdr.tail) {
		rc = FALSE;	/* no signals to remove */
		goto cleanup;
	}
	sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
	if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) {
		ERRDRV("sig_read_data failed: (status=%d)\n", rc);
		goto cleanup;
	}
	sig_hdr.num_received++;

	/* For each data field in SIGNAL_QUEUE_HEADER that was modified,
	 * update host memory.
	 */
	mb(); /* required for channel synch */
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) {
		ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n",
		       rc);
		goto cleanup;
	}
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) {
		ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n",
		       rc);
		goto cleanup;
	}
	rc = TRUE;
cleanup:
	if (channel->needs_lock)
		spin_unlock(&channel->remove_lock);

	return rc;
}
Example #12
0
BOOL
visorchannel_signalremove(VISORCHANNEL *channel, U32 queue, void *msg)
{
	BOOL rc = FALSE;
	SIGNAL_QUEUE_HEADER sig_hdr;

	if (channel->needs_lock)
		spin_lock(&channel->remove_lock);

	if (!sig_read_header(channel, queue, &sig_hdr)) {
		rc = FALSE;
		goto Away;
	}
	if (sig_hdr.Head == sig_hdr.Tail) {
		rc = FALSE;	/* no signals to remove */
		goto Away;
	}
	sig_hdr.Tail = (sig_hdr.Tail + 1) % sig_hdr.MaxSignalSlots;
	if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.Tail, msg)) {
		ERRDRV("sig_read_data failed: (status=%d)\n", rc);
		goto Away;
	}
	sig_hdr.NumSignalsReceived++;

	/* For each data field in SIGNAL_QUEUE_HEADER that was modified,
	 * update host memory.
	 */
	MEMORYBARRIER;
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Tail)) {
		ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n",
		       rc);
		goto Away;
	}
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumSignalsReceived)) {
		ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", rc);
		goto Away;
	}
	rc = TRUE;
Away:
	if (channel->needs_lock)
		spin_unlock(&channel->remove_lock);

	return rc;
}
Example #13
0
static BOOL
signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
{
	struct signal_queue_header sig_hdr;

	if (!sig_read_header(channel, queue, &sig_hdr)) {
		return FALSE;
	}

	sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots);
	if (sig_hdr.head == sig_hdr.tail) {
		sig_hdr.num_overflows++;
		if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows))
			ERRDRV("visor_memregion_write of NumOverflows failed\n");

		return FALSE;
	}

	if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) {
		ERRDRV("sig_write_data failed\n");
		return FALSE;
	}
	sig_hdr.num_sent++;

	/* For each data field in SIGNAL_QUEUE_HEADER that was modified,
	 * update host memory.
	 */
	mb(); /* required for channel synch */
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) {
		ERRDRV("visor_memregion_write of Head failed\n");
		return FALSE;
	}
	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) {
		ERRDRV("visor_memregion_write of NumSignalsSent failed\n");
		return FALSE;
	}

	return TRUE;
}