FreeBSD/sys/dev/hyperv/vmbus/hv_ring_buffer.c
/**
 * @brief Write to the ring buffer.
 */
@brief Write to the ring buffer.
@brief Write to the ring buffer .
int
hv_ring_buffer_write(
	hv_vmbus_ring_buffer_info*	out_ring_info,
	hv_vmbus_sg_buffer_list		sg_buffers[],
	uint32_t			sg_buffer_count,
	boolean_t			*need_sig)
{
	int i = 0;
	uint32_t byte_avail_to_write;
	uint32_t byte_avail_to_read;
	uint32_t old_write_location;
	uint32_t total_bytes_to_write = 0;
	volatile uint32_t next_write_location;
	uint64_t prev_indices = 0;
	for (i = 0; i < sg_buffer_count; i++) {
	    total_bytes_to_write += sg_buffers[i].length;
	}
	total_bytes_to_write += sizeof(uint64_t);
	mtx_lock_spin(&out_ring_info->ring_lock);
	get_ring_buffer_avail_bytes(out_ring_info, &byte_avail_to_read,
	    &byte_avail_to_write);
	if (byte_avail_to_write <= total_bytes_to_write) {
	    mtx_unlock_spin(&out_ring_info->ring_lock);
	    return (EAGAIN);
	}
	next_write_location = get_next_write_location(out_ring_info);
	old_write_location = next_write_location;
	for (i = 0; i < sg_buffer_count; i++) {
	    next_write_location = copy_to_ring_buffer(out_ring_info,
		next_write_location, (char *) sg_buffers[i].data,
		sg_buffers[i].length);
	}
	prev_indices = get_ring_buffer_indices(out_ring_info);
	next_write_location = copy_to_ring_buffer(
		out_ring_info, next_write_location,
		(char *) &prev_indices, sizeof(uint64_t));
	mb();
	set_next_write_location(out_ring_info, next_write_location);
	mtx_unlock_spin(&out_ring_info->ring_lock);
	*need_sig = hv_ring_buffer_needsig_on_write(old_write_location,
	    out_ring_info);
	return (0);
}
int hv_ring_buffer_write ( hv_vmbus_ring_buffer_info * out_ring_info , hv_vmbus_sg_buffer_list sg_buffers [ ] , uint32_t sg_buffer_count , boolean_t * need_sig ) { int i = 0 ; uint32_t byte_avail_to_write ; uint32_t byte_avail_to_read ; uint32_t old_write_location ; uint32_t total_bytes_to_write = 0 ; volatile uint32_t next_write_location ; uint64_t prev_indices = 0 ; for ( i = 0 ; i < sg_buffer_count ; i ++ ) { total_bytes_to_write += sg_buffers [ i ] . length ; } total_bytes_to_write += sizeof ( uint64_t ) ; mtx_lock_spin ( & out_ring_info -> ring_lock ) ; get_ring_buffer_avail_bytes ( out_ring_info , & byte_avail_to_read , & byte_avail_to_write ) ; if ( byte_avail_to_write <= total_bytes_to_write ) { mtx_unlock_spin ( & out_ring_info -> ring_lock ) ; return ( EAGAIN ) ; } next_write_location = get_next_write_location ( out_ring_info ) ; old_write_location = next_write_location ; for ( i = 0 ; i < sg_buffer_count ; i ++ ) { next_write_location = copy_to_ring_buffer ( out_ring_info , next_write_location , ( char * ) sg_buffers [ i ] . data , sg_buffers [ i ] . length ) ; } prev_indices = get_ring_buffer_indices ( out_ring_info ) ; next_write_location = copy_to_ring_buffer ( out_ring_info , next_write_location , ( char * ) & prev_indices , sizeof ( uint64_t ) ) ; mb ( ) ; set_next_write_location ( out_ring_info , next_write_location ) ; mtx_unlock_spin ( & out_ring_info -> ring_lock ) ; * need_sig = hv_ring_buffer_needsig_on_write ( old_write_location , out_ring_info ) ; return ( 0 ) ; }
@brief Write to the ring buffer.
@brief Write to the ring buffer .
/*
	 * If there is only room for the packet, assume it is full.
	 * Otherwise, the next time around, we think the ring buffer
	 * is empty since the read index == write index
	 */ /*
	 * Write to the ring buffer
	 */ /*
	 * Set previous packet start
	 */ /*
	 * Full memory barrier before upding the write index. 
	 */ /*
	 * Now, update the write location
	 */