arch/mips/include/asm/octeon/cvmx-cmd-queue.h

Source file repositories/reference/linux-study-clean/arch/mips/include/asm/octeon/cvmx-cmd-queue.h

File Facts

System
Linux kernel
Corpus path
arch/mips/include/asm/octeon/cvmx-cmd-queue.h
Extension
.h
Size
18908 bytes
Lines
620
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (unlikely(new_buffer == NULL)) {
			if (likely(use_locking))
				__cvmx_cmd_queue_unlock(qptr);
			return CVMX_CMD_QUEUE_NO_MEMORY;
		}
		ptr =
		    (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
						  base_ptr_div128 << 7);
		/*
		 * Figure out how many command words will fit in this
		 * buffer. One location will be needed for the next
		 * buffer pointer.
		 */
		count = qptr->pool_size_m1 - qptr->index;
		ptr += qptr->index;
		cmd_count -= count;
		while (count--)
			*ptr++ = *cmds++;
		*ptr = cvmx_ptr_to_phys(new_buffer);
		/*
		 * The current buffer is full and has a link to the
		 * next buffer. Time to write the rest of the commands
		 * into the new buffer.
		 */
		qptr->base_ptr_div128 = *ptr >> 7;
		qptr->index = cmd_count;
		ptr = new_buffer;
		while (cmd_count--)
			*ptr++ = *cmds++;
	}

	/* All updates are complete. Release the lock and return */
	if (likely(use_locking))
		__cvmx_cmd_queue_unlock(qptr);
	return CVMX_CMD_QUEUE_SUCCESS;
}

/**
 * Simple function to write two command words to a command
 * queue.
 *
 * @queue_id: Hardware command queue to write to
 * @use_locking:
 *		   Use internal locking to ensure exclusive access for queue
 *		   updates. If you don't use this locking you must ensure
 *		   exclusivity some other way. Locking is strongly recommended.
 * @cmd1:     Command
 * @cmd2:     Command
 *
 * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
 */
static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write2(cvmx_cmd_queue_id_t
							    queue_id,
							    int use_locking,
							    uint64_t cmd1,
							    uint64_t cmd2)
{
	__cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);

	/* Make sure nobody else is updating the same queue */
	if (likely(use_locking))
		__cvmx_cmd_queue_lock(queue_id, qptr);

	/*
	 * If a max queue length was specified then make sure we don't
	 * exceed it. If any part of the command would be below the
	 * limit we allow it.
	 */
	if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
		if (unlikely
		    (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
			if (likely(use_locking))
				__cvmx_cmd_queue_unlock(qptr);
			return CVMX_CMD_QUEUE_FULL;
		}
	}

	/*
	 * Normally there is plenty of room in the current buffer for
	 * the command.
	 */
	if (likely(qptr->index + 2 < qptr->pool_size_m1)) {
		uint64_t *ptr =
		    (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
						  base_ptr_div128 << 7);
		ptr += qptr->index;
		qptr->index += 2;
		ptr[0] = cmd1;
		ptr[1] = cmd2;
	} else {

Annotation

Implementation Notes