diff options
author | Stefano Stabellini <sstabellini@kernel.org> | 2017-04-05 15:03:55 -0400 |
---|---|---|
committer | Juergen Gross <jgross@suse.com> | 2017-05-02 05:10:59 -0400 |
commit | 564f7dfde24a405d877168f150ae5d29d3ad99c7 (patch) | |
tree | 05439bc6e0383aad3fcf30717e46a7bd93bc4ca8 | |
parent | ab1570a427551be2d3eeb30b09834ba01c6109eb (diff) |
xen: import new ring macros in ring.h
Sync the ring.h file with upstream Xen, to introduce the new ring macros.
They will be used by the Xen transport for 9pfs.
CC: konrad.wilk@oracle.com
CC: boris.ostrovsky@oracle.com
CC: jgross@suse.com
CC: groug@kaod.org
Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
Acked-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
-rw-r--r-- | include/xen/interface/io/ring.h | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h index 21f4fbd55e48..c79456855539 100644 --- a/include/xen/interface/io/ring.h +++ b/include/xen/interface/io/ring.h | |||
@@ -283,4 +283,147 @@ struct __name##_back_ring { \ | |||
283 | (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ | 283 | (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ |
284 | } while (0) | 284 | } while (0) |
285 | 285 | ||
286 | |||
287 | /* | ||
288 | * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and | ||
289 | * functions to check if there is data on the ring, and to read and | ||
290 | * write to them. | ||
291 | * | ||
292 | * DEFINE_XEN_FLEX_RING is similar to DEFINE_XEN_FLEX_RING_AND_INTF, but | ||
293 | * does not define the indexes page. As different protocols can have | ||
294 | * extensions to the basic format, this macro allow them to define their | ||
295 | * own struct. | ||
296 | * | ||
297 | * XEN_FLEX_RING_SIZE | ||
298 | * Convenience macro to calculate the size of one of the two rings | ||
299 | * from the overall order. | ||
300 | * | ||
301 | * $NAME_mask | ||
302 | * Function to apply the size mask to an index, to reduce the index | ||
303 | * within the range [0-size]. | ||
304 | * | ||
305 | * $NAME_read_packet | ||
306 | * Function to read data from the ring. The amount of data to read is | ||
307 | * specified by the "size" argument. | ||
308 | * | ||
309 | * $NAME_write_packet | ||
310 | * Function to write data to the ring. The amount of data to write is | ||
311 | * specified by the "size" argument. | ||
312 | * | ||
313 | * $NAME_get_ring_ptr | ||
314 | * Convenience function that returns a pointer to read/write to the | ||
315 | * ring at the right location. | ||
316 | * | ||
317 | * $NAME_data_intf | ||
318 | * Indexes page, shared between frontend and backend. It also | ||
319 | * contains the array of grant refs. | ||
320 | * | ||
321 | * $NAME_queued | ||
322 | * Function to calculate how many bytes are currently on the ring, | ||
323 | * ready to be read. It can also be used to calculate how much free | ||
324 | * space is currently on the ring (XEN_FLEX_RING_SIZE() - | ||
325 | * $NAME_queued()). | ||
326 | */ | ||
327 | |||
328 | #ifndef XEN_PAGE_SHIFT | ||
329 | /* The PAGE_SIZE for ring protocols and hypercall interfaces is always | ||
330 | * 4K, regardless of the architecture, and page granularity chosen by | ||
331 | * operating systems. | ||
332 | */ | ||
333 | #define XEN_PAGE_SHIFT 12 | ||
334 | #endif | ||
335 | #define XEN_FLEX_RING_SIZE(order) \ | ||
336 | (1UL << ((order) + XEN_PAGE_SHIFT - 1)) | ||
337 | |||
338 | #define DEFINE_XEN_FLEX_RING(name) \ | ||
339 | static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \ | ||
340 | { \ | ||
341 | return idx & (ring_size - 1); \ | ||
342 | } \ | ||
343 | \ | ||
344 | static inline unsigned char *name##_get_ring_ptr(unsigned char *buf, \ | ||
345 | RING_IDX idx, \ | ||
346 | RING_IDX ring_size) \ | ||
347 | { \ | ||
348 | return buf + name##_mask(idx, ring_size); \ | ||
349 | } \ | ||
350 | \ | ||
351 | static inline void name##_read_packet(void *opaque, \ | ||
352 | const unsigned char *buf, \ | ||
353 | size_t size, \ | ||
354 | RING_IDX masked_prod, \ | ||
355 | RING_IDX *masked_cons, \ | ||
356 | RING_IDX ring_size) \ | ||
357 | { \ | ||
358 | if (*masked_cons < masked_prod || \ | ||
359 | size <= ring_size - *masked_cons) { \ | ||
360 | memcpy(opaque, buf + *masked_cons, size); \ | ||
361 | } else { \ | ||
362 | memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \ | ||
363 | memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \ | ||
364 | size - (ring_size - *masked_cons)); \ | ||
365 | } \ | ||
366 | *masked_cons = name##_mask(*masked_cons + size, ring_size); \ | ||
367 | } \ | ||
368 | \ | ||
369 | static inline void name##_write_packet(unsigned char *buf, \ | ||
370 | const void *opaque, \ | ||
371 | size_t size, \ | ||
372 | RING_IDX *masked_prod, \ | ||
373 | RING_IDX masked_cons, \ | ||
374 | RING_IDX ring_size) \ | ||
375 | { \ | ||
376 | if (*masked_prod < masked_cons || \ | ||
377 | size <= ring_size - *masked_prod) { \ | ||
378 | memcpy(buf + *masked_prod, opaque, size); \ | ||
379 | } else { \ | ||
380 | memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \ | ||
381 | memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \ | ||
382 | size - (ring_size - *masked_prod)); \ | ||
383 | } \ | ||
384 | *masked_prod = name##_mask(*masked_prod + size, ring_size); \ | ||
385 | } \ | ||
386 | \ | ||
387 | static inline RING_IDX name##_queued(RING_IDX prod, \ | ||
388 | RING_IDX cons, \ | ||
389 | RING_IDX ring_size) \ | ||
390 | { \ | ||
391 | RING_IDX size; \ | ||
392 | \ | ||
393 | if (prod == cons) \ | ||
394 | return 0; \ | ||
395 | \ | ||
396 | prod = name##_mask(prod, ring_size); \ | ||
397 | cons = name##_mask(cons, ring_size); \ | ||
398 | \ | ||
399 | if (prod == cons) \ | ||
400 | return ring_size; \ | ||
401 | \ | ||
402 | if (prod > cons) \ | ||
403 | size = prod - cons; \ | ||
404 | else \ | ||
405 | size = ring_size - (cons - prod); \ | ||
406 | return size; \ | ||
407 | } \ | ||
408 | \ | ||
409 | struct name##_data { \ | ||
410 | unsigned char *in; /* half of the allocation */ \ | ||
411 | unsigned char *out; /* half of the allocation */ \ | ||
412 | } | ||
413 | |||
414 | #define DEFINE_XEN_FLEX_RING_AND_INTF(name) \ | ||
415 | struct name##_data_intf { \ | ||
416 | RING_IDX in_cons, in_prod; \ | ||
417 | \ | ||
418 | uint8_t pad1[56]; \ | ||
419 | \ | ||
420 | RING_IDX out_cons, out_prod; \ | ||
421 | \ | ||
422 | uint8_t pad2[56]; \ | ||
423 | \ | ||
424 | RING_IDX ring_order; \ | ||
425 | grant_ref_t ref[]; \ | ||
426 | }; \ | ||
427 | DEFINE_XEN_FLEX_RING(name) | ||
428 | |||
286 | #endif /* __XEN_PUBLIC_IO_RING_H__ */ | 429 | #endif /* __XEN_PUBLIC_IO_RING_H__ */ |