406#define DEFINE_XEN_FLEX_RING(name) \
407static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \
408{ \
409 return idx & (ring_size - 1); \
410} \
411 \
412static inline unsigned char *name##_get_ring_ptr(unsigned char *buf, \
413 RING_IDX idx, \
414 RING_IDX ring_size) \
415{ \
416 return buf + name##_mask(idx, ring_size); \
417} \
418 \
419static inline void name##_read_packet(void *opaque, \
420 const unsigned char *buf, \
421 size_t size, \
422 RING_IDX masked_prod, \
423 RING_IDX *masked_cons, \
424 RING_IDX ring_size) \
425{ \
426 if (*masked_cons < masked_prod || \
427 size <= ring_size - *masked_cons) { \
428 memcpy(opaque, buf + *masked_cons, size); \
429 } else { \
430 memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \
431 memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \
432 size - (ring_size - *masked_cons)); \
433 } \
434 *masked_cons = name##_mask(*masked_cons + size, ring_size); \
435} \
436 \
437static inline void name##_write_packet(unsigned char *buf, \
438 const void *opaque, \
439 size_t size, \
440 RING_IDX *masked_prod, \
441 RING_IDX masked_cons, \
442 RING_IDX ring_size) \
443{ \
444 if (*masked_prod < masked_cons || \
445 size <= ring_size - *masked_prod) { \
446 memcpy(buf + *masked_prod, opaque, size); \
447 } else { \
448 memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \
449 memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \
450 size - (ring_size - *masked_prod)); \
451 } \
452 *masked_prod = name##_mask(*masked_prod + size, ring_size); \
453} \
454 \
455static inline RING_IDX name##_queued(RING_IDX prod, \
456 RING_IDX cons, \
457 RING_IDX ring_size) \
458{ \
459 RING_IDX size; \
460 \
461 if (prod == cons) \
462 return 0; \
463 \
464 prod = name##_mask(prod, ring_size); \
465 cons = name##_mask(cons, ring_size); \
466 \
467 if (prod == cons) \
468 return ring_size; \
469 \
470 if (prod > cons) \
471 size = prod - cons; \
472 else \
473 size = ring_size - (cons - prod); \
474 return size; \
475} \
476 \
477struct name##_data { \
478 unsigned char *in; \
479 unsigned char *out; \
480}