35
37
#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
41
get_ringbuffer_availbytes()
44
Get number of bytes available to read and to write to
45
for the specified ring buffer
42
* hv_get_ringbuffer_availbytes()
44
* Get number of bytes available to read and to write to
45
* for the specified ring buffer
49
get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
48
hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
50
49
u32 *read, u32 *write)
52
51
u32 read_loc, write_loc;
59
58
*read = rbi->ring_datasize - *write;
65
get_next_write_location()
68
Get the next write location for the specified ring buffer
62
* hv_get_next_write_location()
64
* Get the next write location for the specified ring buffer
72
get_next_write_location(struct hv_ring_buffer_info *ring_info)
68
hv_get_next_write_location(struct hv_ring_buffer_info *ring_info)
74
70
u32 next = ring_info->ring_buffer->write_index;
76
/* ASSERT(next < ring_info->RingDataSize); */
84
set_next_write_location()
87
Set the next write location for the specified ring buffer
76
* hv_set_next_write_location()
78
* Set the next write location for the specified ring buffer
91
set_next_write_location(struct hv_ring_buffer_info *ring_info,
82
hv_set_next_write_location(struct hv_ring_buffer_info *ring_info,
92
83
u32 next_write_location)
94
85
ring_info->ring_buffer->write_index = next_write_location;
100
get_next_read_location()
103
Get the next read location for the specified ring buffer
89
* hv_get_next_read_location()
91
* Get the next read location for the specified ring buffer
107
get_next_read_location(struct hv_ring_buffer_info *ring_info)
94
hv_get_next_read_location(struct hv_ring_buffer_info *ring_info)
109
96
u32 next = ring_info->ring_buffer->read_index;
111
/* ASSERT(next < ring_info->RingDataSize); */
119
get_next_readlocation_withoffset()
122
Get the next read location + offset for the specified ring buffer.
123
This allows the caller to skip
102
* hv_get_next_readlocation_withoffset()
104
* Get the next read location + offset for the specified ring buffer.
105
* This allows the caller to skip
126
107
static inline u32
127
get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
108
hv_get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
130
111
u32 next = ring_info->ring_buffer->read_index;
132
/* ASSERT(next < ring_info->RingDataSize); */
134
114
next %= ring_info->ring_datasize;
142
set_next_read_location()
145
Set the next read location for the specified ring buffer
121
* hv_set_next_read_location()
123
* Set the next read location for the specified ring buffer
148
126
static inline void
149
set_next_read_location(struct hv_ring_buffer_info *ring_info,
127
hv_set_next_read_location(struct hv_ring_buffer_info *ring_info,
150
128
u32 next_read_location)
152
130
ring_info->ring_buffer->read_index = next_read_location;
162
Get the start of the ring buffer
136
* hv_get_ring_buffer()
138
* Get the start of the ring buffer
165
140
static inline void *
166
get_ring_buffer(struct hv_ring_buffer_info *ring_info)
141
hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
168
143
return (void *)ring_info->ring_buffer->buffer;
175
get_ring_buffersize()
178
Get the size of the ring buffer
149
* hv_get_ring_buffersize()
151
* Get the size of the ring buffer
181
153
static inline u32
182
get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
154
hv_get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
184
156
return ring_info->ring_datasize;
190
get_ring_bufferindices()
193
Get the read and write indices as u64 of the specified ring buffer
161
* hv_get_ring_bufferindices()
163
* Get the read and write indices as u64 of the specified ring buffer
196
166
static inline u64
197
get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
167
hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
199
169
return (u64)ring_info->ring_buffer->write_index << 32;
209
Dump out to console the ring buffer info
212
void dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
175
* hv_dump_ring_info()
177
* Dump out to console the ring buffer info
180
void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
214
182
u32 bytes_avail_towrite;
215
183
u32 bytes_avail_toread;
217
get_ringbuffer_availbytes(ring_info,
185
hv_get_ringbuffer_availbytes(ring_info,
218
186
&bytes_avail_toread,
219
187
&bytes_avail_towrite);
235
/* Internal routines */
205
* hv_copyfrom_ringbuffer()
207
* Helper routine to copy to source from ring buffer.
208
* Assume there is enough room. Handles wrap-around in src case only!!
211
static u32 hv_copyfrom_ringbuffer(
212
struct hv_ring_buffer_info *ring_info,
215
u32 start_read_offset)
217
void *ring_buffer = hv_get_ring_buffer(ring_info);
218
u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
222
/* wrap-around detected at the src */
223
if (destlen > ring_buffer_size - start_read_offset) {
224
frag_len = ring_buffer_size - start_read_offset;
226
memcpy(dest, ring_buffer + start_read_offset, frag_len);
227
memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
230
memcpy(dest, ring_buffer + start_read_offset, destlen);
233
start_read_offset += destlen;
234
start_read_offset %= ring_buffer_size;
236
return start_read_offset;
242
* hv_copyto_ringbuffer()
244
* Helper routine to copy from source to ring buffer.
245
* Assume there is enough room. Handles wrap-around in dest case only!!
248
static u32 hv_copyto_ringbuffer(
239
249
struct hv_ring_buffer_info *ring_info,
240
250
u32 start_write_offset,
246
struct hv_ring_buffer_info *ring_info,
249
u32 start_read_offset);
256
ringbuffer_get_debuginfo()
259
Get various debug metrics for the specified ring buffer
262
void ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
254
void *ring_buffer = hv_get_ring_buffer(ring_info);
255
u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
258
/* wrap-around detected! */
259
if (srclen > ring_buffer_size - start_write_offset) {
260
frag_len = ring_buffer_size - start_write_offset;
261
memcpy(ring_buffer + start_write_offset, src, frag_len);
262
memcpy(ring_buffer, src + frag_len, srclen - frag_len);
264
memcpy(ring_buffer + start_write_offset, src, srclen);
266
start_write_offset += srclen;
267
start_write_offset %= ring_buffer_size;
269
return start_write_offset;
274
* hv_ringbuffer_get_debuginfo()
276
* Get various debug metrics for the specified ring buffer
279
void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
263
280
struct hv_ring_buffer_debug_info *debug_info)
265
282
u32 bytes_avail_towrite;
266
283
u32 bytes_avail_toread;
268
285
if (ring_info->ring_buffer) {
269
get_ringbuffer_availbytes(ring_info,
286
hv_get_ringbuffer_availbytes(ring_info,
270
287
&bytes_avail_toread,
271
288
&bytes_avail_towrite);
288
get_ringbuffer_interrupt_mask()
291
Get the interrupt mask for the specified ring buffer
294
u32 get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
304
* hv_get_ringbuffer_interrupt_mask()
306
* Get the interrupt mask for the specified ring buffer
309
u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
296
311
return rbi->ring_buffer->interrupt_mask;
305
Initialize the ring buffer
308
int ringbuffer_init(struct hv_ring_buffer_info *ring_info,
316
* hv_ringbuffer_init()
318
*Initialize the ring buffer
321
int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
309
322
void *buffer, u32 buflen)
311
324
if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
370
379
spin_lock_irqsave(&outring_info->ring_lock, flags);
372
get_ringbuffer_availbytes(outring_info,
381
hv_get_ringbuffer_availbytes(outring_info,
373
382
&bytes_avail_toread,
374
383
&bytes_avail_towrite);
376
DPRINT_DBG(VMBUS, "Writing %u bytes...", totalbytes_towrite);
378
/* Dumpring_info(Outring_info, "BEFORE "); */
380
386
/* If there is only room for the packet, assume it is full. */
381
387
/* Otherwise, the next time around, we think the ring buffer */
382
388
/* is empty since the read index == write index */
383
389
if (bytes_avail_towrite <= totalbytes_towrite) {
385
"No more space left on outbound ring buffer "
386
"(needed %u, avail %u)",
388
bytes_avail_towrite);
390
390
spin_unlock_irqrestore(&outring_info->ring_lock, flags);
394
394
/* Write to the ring buffer */
395
next_write_location = get_next_write_location(outring_info);
395
next_write_location = hv_get_next_write_location(outring_info);
397
397
for_each_sg(sglist, sg, sgcount, i)
399
next_write_location = copyto_ringbuffer(outring_info,
399
next_write_location = hv_copyto_ringbuffer(outring_info,
400
400
next_write_location,
405
405
/* Set previous packet start */
406
prev_indices = get_ring_bufferindices(outring_info);
406
prev_indices = hv_get_ring_bufferindices(outring_info);
408
next_write_location = copyto_ringbuffer(outring_info,
408
next_write_location = hv_copyto_ringbuffer(outring_info,
409
409
next_write_location,
416
416
/* Now, update the write location */
417
set_next_write_location(outring_info, next_write_location);
417
hv_set_next_write_location(outring_info, next_write_location);
419
/* Dumpring_info(Outring_info, "AFTER "); */
421
420
spin_unlock_irqrestore(&outring_info->ring_lock, flags);
432
Read without advancing the read index
435
int ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
427
* hv_ringbuffer_peek()
429
* Read without advancing the read index
432
int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
436
433
void *Buffer, u32 buflen)
438
435
u32 bytes_avail_towrite;
497
487
spin_lock_irqsave(&inring_info->ring_lock, flags);
499
get_ringbuffer_availbytes(inring_info,
489
hv_get_ringbuffer_availbytes(inring_info,
500
490
&bytes_avail_toread,
501
491
&bytes_avail_towrite);
503
DPRINT_DBG(VMBUS, "Reading %u bytes...", buflen);
505
/* Dumpring_info(Inring_info, "BEFORE "); */
507
493
/* Make sure there is something to read */
508
494
if (bytes_avail_toread < buflen) {
510
"got callback but not enough to read "
511
"<avail to read %d read size %d>!!",
515
495
spin_unlock_irqrestore(&inring_info->ring_lock, flags);
520
500
next_read_location =
521
get_next_readlocation_withoffset(inring_info, offset);
501
hv_get_next_readlocation_withoffset(inring_info, offset);
523
next_read_location = copyfrom_ringbuffer(inring_info,
503
next_read_location = hv_copyfrom_ringbuffer(inring_info,
526
506
next_read_location);
528
next_read_location = copyfrom_ringbuffer(inring_info,
508
next_read_location = hv_copyfrom_ringbuffer(inring_info,
531
511
next_read_location);
538
518
/* Update the read index */
539
set_next_read_location(inring_info, next_read_location);
541
/* Dumpring_info(Inring_info, "AFTER "); */
519
hv_set_next_read_location(inring_info, next_read_location);
543
521
spin_unlock_irqrestore(&inring_info->ring_lock, flags);
555
Helper routine to copy from source to ring buffer.
556
Assume there is enough room. Handles wrap-around in dest case only!!
561
struct hv_ring_buffer_info *ring_info,
562
u32 start_write_offset,
566
void *ring_buffer = get_ring_buffer(ring_info);
567
u32 ring_buffer_size = get_ring_buffersize(ring_info);
570
/* wrap-around detected! */
571
if (srclen > ring_buffer_size - start_write_offset) {
572
DPRINT_DBG(VMBUS, "wrap-around detected!");
574
frag_len = ring_buffer_size - start_write_offset;
575
memcpy(ring_buffer + start_write_offset, src, frag_len);
576
memcpy(ring_buffer, src + frag_len, srclen - frag_len);
578
memcpy(ring_buffer + start_write_offset, src, srclen);
580
start_write_offset += srclen;
581
start_write_offset %= ring_buffer_size;
583
return start_write_offset;
590
copyfrom_ringbuffer()
593
Helper routine to copy to source from ring buffer.
594
Assume there is enough room. Handles wrap-around in src case only!!
599
struct hv_ring_buffer_info *ring_info,
602
u32 start_read_offset)
604
void *ring_buffer = get_ring_buffer(ring_info);
605
u32 ring_buffer_size = get_ring_buffersize(ring_info);
609
/* wrap-around detected at the src */
610
if (destlen > ring_buffer_size - start_read_offset) {
611
DPRINT_DBG(VMBUS, "src wrap-around detected!");
613
frag_len = ring_buffer_size - start_read_offset;
615
memcpy(dest, ring_buffer + start_read_offset, frag_len);
616
memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
619
memcpy(dest, ring_buffer + start_read_offset, destlen);
622
start_read_offset += destlen;
623
start_read_offset %= ring_buffer_size;
625
return start_read_offset;