/* * * hv_copyfrom_ringbuffer() * * Helper routine to copy to source from ring buffer. * Assume there is enough room. Handles wrap-around in src case only!! * */ static u32 hv_copyfrom_ringbuffer( struct hv_ring_buffer_info *ring_info, void *dest, u32 destlen, u32 start_read_offset) { void *ring_buffer = hv_get_ring_buffer(ring_info); u32 ring_buffer_size = hv_get_ring_buffersize(ring_info); u32 frag_len; /* wrap-around detected at the src */ if (destlen > ring_buffer_size - start_read_offset) { frag_len = ring_buffer_size - start_read_offset; memcpy(dest, ring_buffer + start_read_offset, frag_len); memcpy(dest + frag_len, ring_buffer, destlen - frag_len); } else memcpy(dest, ring_buffer + start_read_offset, destlen); start_read_offset += destlen; start_read_offset %= ring_buffer_size; return start_read_offset; }
/* * Get first vmbus packet from ring buffer after read_index * * If ring buffer is empty, returns NULL and no other action needed. */ struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel) { struct hv_ring_buffer_info *rbi = &channel->inbound; struct vmpacket_descriptor *desc; if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor)) return NULL; desc = hv_get_ring_buffer(rbi) + rbi->priv_read_index; if (desc) prefetch((char *)desc + (desc->len8 << 3)); return desc; }
/* * Helper routine to copy from source to ring buffer. * Assume there is enough room. Handles wrap-around in dest case only!! */ static u32 hv_copyto_ringbuffer( struct hv_ring_buffer_info *ring_info, u32 start_write_offset, void *src, u32 srclen) { void *ring_buffer = hv_get_ring_buffer(ring_info); u32 ring_buffer_size = hv_get_ring_buffersize(ring_info); memcpy(ring_buffer + start_write_offset, src, srclen); start_write_offset += srclen; start_write_offset %= ring_buffer_size; return start_write_offset; }
/* * Helper routine to copy to source from ring buffer. * Assume there is enough room. Handles wrap-around in src case only!! */ static u32 hv_copyfrom_ringbuffer( struct hv_ring_buffer_info *ring_info, void *dest, u32 destlen, u32 start_read_offset) { void *ring_buffer = hv_get_ring_buffer(ring_info); u32 ring_buffer_size = hv_get_ring_buffersize(ring_info); memcpy(dest, ring_buffer + start_read_offset, destlen); start_read_offset += destlen; start_read_offset %= ring_buffer_size; return start_read_offset; }
/* * * hv_copyto_ringbuffer() * * Helper routine to copy from source to ring buffer. * Assume there is enough room. Handles wrap-around in dest case only!! * */ static u32 hv_copyto_ringbuffer( struct hv_ring_buffer_info *ring_info, u32 start_write_offset, void *src, u32 srclen) { void *ring_buffer = hv_get_ring_buffer(ring_info); u32 ring_buffer_size = hv_get_ring_buffersize(ring_info); u32 frag_len; /* wrap-around detected! */ if (srclen > ring_buffer_size - start_write_offset) { frag_len = ring_buffer_size - start_write_offset; memcpy(ring_buffer + start_write_offset, src, frag_len); memcpy(ring_buffer, src + frag_len, srclen - frag_len); } else memcpy(ring_buffer + start_write_offset, src, srclen); start_write_offset += srclen; start_write_offset %= ring_buffer_size; return start_write_offset; }