Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / hv / ring_buffer.c
1 /*
2  *
3  * Copyright (c) 2009, Microsoft Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16  * Place - Suite 330, Boston, MA 02111-1307 USA.
17  *
18  * Authors:
19  *   Haiyang Zhang <haiyangz@microsoft.com>
20  *   Hank Janssen  <hjanssen@microsoft.com>
21  *
22  */
23
24 #include <linux/kernel.h>
25 #include <linux/mm.h>
26 #include "osd.h"
27 #include "logging.h"
28 #include "ring_buffer.h"
29
30
31 /* #defines */
32
33
34 /* Amount of space to write to */
35 #define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
36
37
38 /*++
39
40 Name:
41         get_ringbuffer_availbytes()
42
43 Description:
44         Get number of bytes available to read and to write to
45         for the specified ring buffer
46
47 --*/
48 static inline void
49 get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
50                           u32 *read, u32 *write)
51 {
52         u32 read_loc, write_loc;
53
54         /* Capture the read/write indices before they changed */
55         read_loc = rbi->ring_buffer->read_index;
56         write_loc = rbi->ring_buffer->write_index;
57
58         *write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->ring_datasize);
59         *read = rbi->ring_datasize - *write;
60 }
61
62 /*++
63
64 Name:
65         get_next_write_location()
66
67 Description:
68         Get the next write location for the specified ring buffer
69
70 --*/
71 static inline u32
72 get_next_write_location(struct hv_ring_buffer_info *ring_info)
73 {
74         u32 next = ring_info->ring_buffer->write_index;
75
76         /* ASSERT(next < ring_info->RingDataSize); */
77
78         return next;
79 }
80
81 /*++
82
83 Name:
84         set_next_write_location()
85
86 Description:
87         Set the next write location for the specified ring buffer
88
89 --*/
90 static inline void
91 set_next_write_location(struct hv_ring_buffer_info *ring_info,
92                      u32 next_write_location)
93 {
94         ring_info->ring_buffer->write_index = next_write_location;
95 }
96
97 /*++
98
99 Name:
100         get_next_read_location()
101
102 Description:
103         Get the next read location for the specified ring buffer
104
105 --*/
106 static inline u32
107 get_next_read_location(struct hv_ring_buffer_info *ring_info)
108 {
109         u32 next = ring_info->ring_buffer->read_index;
110
111         /* ASSERT(next < ring_info->RingDataSize); */
112
113         return next;
114 }
115
116 /*++
117
118 Name:
119         get_next_readlocation_withoffset()
120
121 Description:
122         Get the next read location + offset for the specified ring buffer.
123         This allows the caller to skip
124
125 --*/
126 static inline u32
127 get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
128                                  u32 offset)
129 {
130         u32 next = ring_info->ring_buffer->read_index;
131
132         /* ASSERT(next < ring_info->RingDataSize); */
133         next += offset;
134         next %= ring_info->ring_datasize;
135
136         return next;
137 }
138
139 /*++
140
141 Name:
142         set_next_read_location()
143
144 Description:
145         Set the next read location for the specified ring buffer
146
147 --*/
148 static inline void
149 set_next_read_location(struct hv_ring_buffer_info *ring_info,
150                     u32 next_read_location)
151 {
152         ring_info->ring_buffer->read_index = next_read_location;
153 }
154
155
156 /*++
157
158 Name:
159         get_ring_buffer()
160
161 Description:
162         Get the start of the ring buffer
163
164 --*/
165 static inline void *
166 get_ring_buffer(struct hv_ring_buffer_info *ring_info)
167 {
168         return (void *)ring_info->ring_buffer->buffer;
169 }
170
171
172 /*++
173
174 Name:
175         get_ring_buffersize()
176
177 Description:
178         Get the size of the ring buffer
179
180 --*/
181 static inline u32
182 get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
183 {
184         return ring_info->ring_datasize;
185 }
186
187 /*++
188
189 Name:
190         get_ring_bufferindices()
191
192 Description:
193         Get the read and write indices as u64 of the specified ring buffer
194
195 --*/
196 static inline u64
197 get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
198 {
199         return (u64)ring_info->ring_buffer->write_index << 32;
200 }
201
202
203 /*++
204
205 Name:
206         dump_ring_info()
207
208 Description:
209         Dump out to console the ring buffer info
210
211 --*/
212 void dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
213 {
214         u32 bytes_avail_towrite;
215         u32 bytes_avail_toread;
216
217         get_ringbuffer_availbytes(ring_info,
218         &bytes_avail_toread,
219         &bytes_avail_towrite);
220
221         DPRINT(VMBUS,
222                 DEBUG_RING_LVL,
223                 "%s <<ringinfo %p buffer %p avail write %u "
224                 "avail read %u read idx %u write idx %u>>",
225                 prefix,
226                 ring_info,
227                 ring_info->ring_buffer->buffer,
228                 bytes_avail_towrite,
229                 bytes_avail_toread,
230                 ring_info->ring_buffer->read_index,
231                 ring_info->ring_buffer->write_index);
232 }
233
234
235 /* Internal routines */
236
237 static u32
238 copyto_ringbuffer(
239         struct hv_ring_buffer_info      *ring_info,
240         u32                             start_write_offset,
241         void                            *src,
242         u32                             srclen);
243
244 static u32
245 copyfrom_ringbuffer(
246         struct hv_ring_buffer_info      *ring_info,
247         void                            *dest,
248         u32                             destlen,
249         u32                             start_read_offset);
250
251
252
253 /*++
254
255 Name:
256         ringbuffer_get_debuginfo()
257
258 Description:
259         Get various debug metrics for the specified ring buffer
260
261 --*/
262 void ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
263                             struct hv_ring_buffer_debug_info *debug_info)
264 {
265         u32 bytes_avail_towrite;
266         u32 bytes_avail_toread;
267
268         if (ring_info->ring_buffer) {
269                 get_ringbuffer_availbytes(ring_info,
270                                         &bytes_avail_toread,
271                                         &bytes_avail_towrite);
272
273                 debug_info->bytes_avail_toread = bytes_avail_toread;
274                 debug_info->bytes_avail_towrite = bytes_avail_towrite;
275                 debug_info->current_read_index =
276                         ring_info->ring_buffer->read_index;
277                 debug_info->current_write_index =
278                         ring_info->ring_buffer->write_index;
279                 debug_info->current_interrupt_mask =
280                         ring_info->ring_buffer->interrupt_mask;
281         }
282 }
283
284
285 /*++
286
287 Name:
288         get_ringbuffer_interrupt_mask()
289
290 Description:
291         Get the interrupt mask for the specified ring buffer
292
293 --*/
294 u32 get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
295 {
296         return rbi->ring_buffer->interrupt_mask;
297 }
298
299 /*++
300
301 Name:
302         ringbuffer_init()
303
304 Description:
305         Initialize the ring buffer
306
307 --*/
308 int ringbuffer_init(struct hv_ring_buffer_info *ring_info,
309                    void *buffer, u32 buflen)
310 {
311         if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
312                 return -EINVAL;
313
314         memset(ring_info, 0, sizeof(struct hv_ring_buffer_info));
315
316         ring_info->ring_buffer = (struct hv_ring_buffer *)buffer;
317         ring_info->ring_buffer->read_index =
318                 ring_info->ring_buffer->write_index = 0;
319
320         ring_info->ring_size = buflen;
321         ring_info->ring_datasize = buflen - sizeof(struct hv_ring_buffer);
322
323         spin_lock_init(&ring_info->ring_lock);
324
325         return 0;
326 }
327
328 /*++
329
330 Name:
331         ringbuffer_cleanup()
332
333 Description:
334         Cleanup the ring buffer
335
336 --*/
337 void ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
338 {
339 }
340
341 /*++
342
343 Name:
344         ringbuffer_write()
345
346 Description:
347         Write to the ring buffer
348
349 --*/
350 int ringbuffer_write(struct hv_ring_buffer_info *outring_info,
351                     struct scatterlist *sglist, u32 sgcount)
352 {
353         int i = 0;
354         u32 bytes_avail_towrite;
355         u32 bytes_avail_toread;
356         u32 totalbytes_towrite = 0;
357
358         struct scatterlist *sg;
359         volatile u32 next_write_location;
360         u64 prev_indices = 0;
361         unsigned long flags;
362
363         for_each_sg(sglist, sg, sgcount, i)
364         {
365                 totalbytes_towrite += sg->length;
366         }
367
368         totalbytes_towrite += sizeof(u64);
369
370         spin_lock_irqsave(&outring_info->ring_lock, flags);
371
372         get_ringbuffer_availbytes(outring_info,
373                                 &bytes_avail_toread,
374                                 &bytes_avail_towrite);
375
376         DPRINT_DBG(VMBUS, "Writing %u bytes...", totalbytes_towrite);
377
378         /* Dumpring_info(Outring_info, "BEFORE "); */
379
380         /* If there is only room for the packet, assume it is full. */
381         /* Otherwise, the next time around, we think the ring buffer */
382         /* is empty since the read index == write index */
383         if (bytes_avail_towrite <= totalbytes_towrite) {
384                 DPRINT_DBG(VMBUS,
385                         "No more space left on outbound ring buffer "
386                         "(needed %u, avail %u)",
387                         totalbytes_towrite,
388                         bytes_avail_towrite);
389
390                 spin_unlock_irqrestore(&outring_info->ring_lock, flags);
391                 return -1;
392         }
393
394         /* Write to the ring buffer */
395         next_write_location = get_next_write_location(outring_info);
396
397         for_each_sg(sglist, sg, sgcount, i)
398         {
399                 next_write_location = copyto_ringbuffer(outring_info,
400                                                      next_write_location,
401                                                      sg_virt(sg),
402                                                      sg->length);
403         }
404
405         /* Set previous packet start */
406         prev_indices = get_ring_bufferindices(outring_info);
407
408         next_write_location = copyto_ringbuffer(outring_info,
409                                              next_write_location,
410                                              &prev_indices,
411                                              sizeof(u64));
412
413         /* Make sure we flush all writes before updating the writeIndex */
414         mb();
415
416         /* Now, update the write location */
417         set_next_write_location(outring_info, next_write_location);
418
419         /* Dumpring_info(Outring_info, "AFTER "); */
420
421         spin_unlock_irqrestore(&outring_info->ring_lock, flags);
422         return 0;
423 }
424
425
426 /*++
427
428 Name:
429         ringbuffer_peek()
430
431 Description:
432         Read without advancing the read index
433
434 --*/
435 int ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
436                    void *Buffer, u32 buflen)
437 {
438         u32 bytes_avail_towrite;
439         u32 bytes_avail_toread;
440         u32 next_read_location = 0;
441         unsigned long flags;
442
443         spin_lock_irqsave(&Inring_info->ring_lock, flags);
444
445         get_ringbuffer_availbytes(Inring_info,
446                                 &bytes_avail_toread,
447                                 &bytes_avail_towrite);
448
449         /* Make sure there is something to read */
450         if (bytes_avail_toread < buflen) {
451                 /* DPRINT_DBG(VMBUS,
452                         "got callback but not enough to read "
453                         "<avail to read %d read size %d>!!",
454                         bytes_avail_toread,
455                         BufferLen); */
456
457                 spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
458
459                 return -1;
460         }
461
462         /* Convert to byte offset */
463         next_read_location = get_next_read_location(Inring_info);
464
465         next_read_location = copyfrom_ringbuffer(Inring_info,
466                                                 Buffer,
467                                                 buflen,
468                                                 next_read_location);
469
470         spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
471
472         return 0;
473 }
474
475
476 /*++
477
478 Name:
479         ringbuffer_read()
480
481 Description:
482         Read and advance the read index
483
484 --*/
485 int ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
486                    u32 buflen, u32 offset)
487 {
488         u32 bytes_avail_towrite;
489         u32 bytes_avail_toread;
490         u32 next_read_location = 0;
491         u64 prev_indices = 0;
492         unsigned long flags;
493
494         if (buflen <= 0)
495                 return -EINVAL;
496
497         spin_lock_irqsave(&inring_info->ring_lock, flags);
498
499         get_ringbuffer_availbytes(inring_info,
500                                 &bytes_avail_toread,
501                                 &bytes_avail_towrite);
502
503         DPRINT_DBG(VMBUS, "Reading %u bytes...", buflen);
504
505         /* Dumpring_info(Inring_info, "BEFORE "); */
506
507         /* Make sure there is something to read */
508         if (bytes_avail_toread < buflen) {
509                 DPRINT_DBG(VMBUS,
510                         "got callback but not enough to read "
511                         "<avail to read %d read size %d>!!",
512                         bytes_avail_toread,
513                         buflen);
514
515                 spin_unlock_irqrestore(&inring_info->ring_lock, flags);
516
517                 return -1;
518         }
519
520         next_read_location =
521                 get_next_readlocation_withoffset(inring_info, offset);
522
523         next_read_location = copyfrom_ringbuffer(inring_info,
524                                                 buffer,
525                                                 buflen,
526                                                 next_read_location);
527
528         next_read_location = copyfrom_ringbuffer(inring_info,
529                                                 &prev_indices,
530                                                 sizeof(u64),
531                                                 next_read_location);
532
533         /* Make sure all reads are done before we update the read index since */
534         /* the writer may start writing to the read area once the read index */
535         /*is updated */
536         mb();
537
538         /* Update the read index */
539         set_next_read_location(inring_info, next_read_location);
540
541         /* Dumpring_info(Inring_info, "AFTER "); */
542
543         spin_unlock_irqrestore(&inring_info->ring_lock, flags);
544
545         return 0;
546 }
547
548
549 /*++
550
551 Name:
552         copyto_ringbuffer()
553
554 Description:
555         Helper routine to copy from source to ring buffer.
556         Assume there is enough room. Handles wrap-around in dest case only!!
557
558 --*/
559 static u32
560 copyto_ringbuffer(
561         struct hv_ring_buffer_info      *ring_info,
562         u32                             start_write_offset,
563         void                            *src,
564         u32                             srclen)
565 {
566         void *ring_buffer = get_ring_buffer(ring_info);
567         u32 ring_buffer_size = get_ring_buffersize(ring_info);
568         u32 frag_len;
569
570         /* wrap-around detected! */
571         if (srclen > ring_buffer_size - start_write_offset) {
572                 DPRINT_DBG(VMBUS, "wrap-around detected!");
573
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);
577         } else
578                 memcpy(ring_buffer + start_write_offset, src, srclen);
579
580         start_write_offset += srclen;
581         start_write_offset %= ring_buffer_size;
582
583         return start_write_offset;
584 }
585
586
587 /*++
588
589 Name:
590         copyfrom_ringbuffer()
591
592 Description:
593         Helper routine to copy to source from ring buffer.
594         Assume there is enough room. Handles wrap-around in src case only!!
595
596 --*/
597 static u32
598 copyfrom_ringbuffer(
599         struct hv_ring_buffer_info      *ring_info,
600         void                            *dest,
601         u32                             destlen,
602         u32                             start_read_offset)
603 {
604         void *ring_buffer = get_ring_buffer(ring_info);
605         u32 ring_buffer_size = get_ring_buffersize(ring_info);
606
607         u32 frag_len;
608
609         /* wrap-around detected at the src */
610         if (destlen > ring_buffer_size - start_read_offset) {
611                 DPRINT_DBG(VMBUS, "src wrap-around detected!");
612
613                 frag_len = ring_buffer_size - start_read_offset;
614
615                 memcpy(dest, ring_buffer + start_read_offset, frag_len);
616                 memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
617         } else
618
619                 memcpy(dest, ring_buffer + start_read_offset, destlen);
620
621
622         start_read_offset += destlen;
623         start_read_offset %= ring_buffer_size;
624
625         return start_read_offset;
626 }
627
628
629 /* eof */