diff -r a64ebf373f9c -r ec6442c07549 linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Wed Nov 23 15:38:27 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Wed Nov 23 17:37:53 2005 @@ -6,3 +6,5 @@ xenidc-objs += xenidc_buffer_resource_provider.o xenidc-objs += xenidc_local_buffer_reference.o xenidc-objs += xenidc_remote_buffer_reference.o +xenidc-objs += xenidc_concatenate.o +xenidc-objs += xenidc_wrapping.o diff -r a64ebf373f9c -r ec6442c07549 linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_concatenate.c --- /dev/null Wed Nov 23 15:38:27 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_concatenate.c Wed Nov 23 17:37:53 2005 @@ -0,0 +1,91 @@ +/*****************************************************************************/ +/* Xen inter-domain communication concatenate local buffer reference type. */ +/* */ +/* Copyright (c) 2005 Harry Butterworth IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU General Public License as published by the */ +/* Free Software Foundation; either version 2 of the License, or (at your */ +/* option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */ +/* Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License along */ +/* with this program; if not, write to the Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* */ +/*****************************************************************************/ + +#include +#include +#include "xenidc_trace.h" + +static xenidc_lbr_type xenidc_concatenate_type; + +static struct xenidc_lbr +xenidc_concatenate_resolve(struct xenidc_lbr_virtual_class *class, +struct xenidc_lbr *lbr) +{ + struct xenidc_lbr resolved_lbr; + struct xenidc_concatenate_base *base; + trace(); + base = (struct xenidc_concatenate_base *)lbr->base; + if (lbr->byte_offset < base->head->byte_count) { + resolved_lbr = *base->head; + xenidc_lbr_subrange(&resolved_lbr, lbr->byte_offset, + lbr->byte_count); + } else { + resolved_lbr = *base->tail; + xenidc_lbr_subrange(&resolved_lbr, + lbr->byte_offset - base->head->byte_count, + lbr->byte_count); + } + return resolved_lbr; +} + +static void xenidc_concatenate_init(void) +{ + static int initialised = 0; + static struct xenidc_lbr_virtual_class + xenidc_concatenate_virtual_class; + static DEFINE_RWLOCK(xenidc_concatenate_lock); + unsigned long flags; + trace(); + read_lock_irqsave(&xenidc_concatenate_lock, flags); + if (initialised) { + read_unlock_irqrestore(&xenidc_concatenate_lock, flags); + return; + } + read_unlock_irqrestore(&xenidc_concatenate_lock, flags); + write_lock_irqsave(&xenidc_concatenate_lock, flags); + if (initialised) { + write_unlock_irqrestore(&xenidc_concatenate_lock, flags); + return; + } + xenidc_concatenate_type = xenidc_lbr_register_virtual_class( + &xenidc_concatenate_virtual_class, + xenidc_concatenate_resolve, NULL); + initialised = 1; + write_unlock_irqrestore(&xenidc_concatenate_lock, flags); +} + +struct xenidc_lbr +xenidc_concatenate_create_lbr(struct xenidc_concatenate_base *base, +struct xenidc_lbr *head, struct xenidc_lbr *tail) +{ + struct xenidc_lbr lbr; + trace(); + xenidc_concatenate_init(); + base->head = head; + base->tail = tail; + lbr.type = xenidc_concatenate_type; + lbr.base = base; + lbr.byte_offset = 0; + lbr.byte_count = head->byte_count + tail->byte_count; + return lbr; +} + +EXPORT_SYMBOL(xenidc_concatenate_create_lbr); diff -r a64ebf373f9c -r ec6442c07549 linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_wrapping.c --- /dev/null Wed Nov 23 15:38:27 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_wrapping.c Wed Nov 23 17:37:53 2005 @@ -0,0 +1,99 @@ +/*****************************************************************************/ +/* Xen inter-domain communication wrapping local buffer reference type. */ +/* */ +/* Copyright (c) 2005 Harry Butterworth IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU General Public License as published by the */ +/* Free Software Foundation; either version 2 of the License, or (at your */ +/* option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */ +/* Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License along */ +/* with this program; if not, write to the Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* */ +/*****************************************************************************/ + +#include +#include +#include "xenidc_trace.h" + +static xenidc_lbr_type xenidc_wrapping_type; + +static struct xenidc_lbr +xenidc_wrapping_resolve(struct xenidc_lbr_virtual_class *class, +struct xenidc_lbr *lbr) +{ + struct xenidc_lbr resolved_lbr; + trace(); + resolved_lbr = *(struct xenidc_lbr *)lbr->base; + xenidc_lbr_subrange(&resolved_lbr, lbr->byte_offset, min( + lbr->byte_count, resolved_lbr.byte_count - lbr->byte_offset)); + return resolved_lbr; +} + +static void +xenidc_wrapping_advance(struct xenidc_lbr_virtual_class *class, +struct xenidc_lbr *lbr, xenidc_buffer_byte_count byte_count) +{ + trace(); + lbr->byte_offset += byte_count; + lbr->byte_offset %= ((struct xenidc_lbr *)lbr->base)->byte_count; + lbr->byte_count -= byte_count; +} + +static void xenidc_wrapping_init(void) +{ + static int initialised = 0; + static struct xenidc_lbr_virtual_class xenidc_wrapping_virtual_class; + static DEFINE_RWLOCK(xenidc_wrapping_lock); + unsigned long flags; + trace(); + read_lock_irqsave(&xenidc_wrapping_lock, flags); + if (initialised) { + read_unlock_irqrestore(&xenidc_wrapping_lock, flags); + return; + } + read_unlock_irqrestore(&xenidc_wrapping_lock, flags); + write_lock_irqsave(&xenidc_wrapping_lock, flags); + if (initialised) { + write_unlock_irqrestore(&xenidc_wrapping_lock, flags); + return; + } + xenidc_wrapping_type = xenidc_lbr_register_virtual_class( + &xenidc_wrapping_virtual_class, + xenidc_wrapping_resolve, + xenidc_wrapping_advance); + initialised = 1; + write_unlock_irqrestore(&xenidc_wrapping_lock, flags); +} + +struct xenidc_lbr xenidc_wrapping_create_lbr( +struct xenidc_lbr *underlying_lbr, xenidc_buffer_byte_count start_offset, +xenidc_buffer_byte_count end_offset, xenidc_wrapping_client_type client_type) +{ + struct xenidc_lbr lbr; + trace(); + xenidc_wrapping_init(); + lbr.type = xenidc_wrapping_type; + lbr.base = underlying_lbr; + lbr.byte_offset = start_offset; + if (start_offset < end_offset) { + lbr.byte_count = end_offset - start_offset; + } else if (start_offset > end_offset) { + lbr.byte_count = end_offset + underlying_lbr->byte_count - + start_offset; + } else if (client_type == xenidc_wrapping_client_type_producer ) { + lbr.byte_count = underlying_lbr->byte_count; + } else { + lbr.byte_count = 0; + } + return lbr; +} + +EXPORT_SYMBOL(xenidc_wrapping_create_lbr); diff -r a64ebf373f9c -r ec6442c07549 linux-2.6-xen-sparse/include/asm-xen/xenidc_concatenate.h --- /dev/null Wed Nov 23 15:38:27 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_concatenate.h Wed Nov 23 17:37:53 2005 @@ -0,0 +1,41 @@ +/*****************************************************************************/ +/* Support for concatenating local buffer references. */ +/* */ +/* Copyright (c) 2005 Harry Butterworth IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU General Public License as published by the */ +/* Free Software Foundation; either version 2 of the License, or (at your */ +/* option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */ +/* Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License along */ +/* with this program; if not, write to the Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* */ +/*****************************************************************************/ + +#ifndef XENIDC_CONCATENATE_H +#define XENIDC_CONCATENATE_H + +#include "xenidc_local_buffer_reference.h" + +struct xenidc_concatenate_base { + struct xenidc_lbr *head; + struct xenidc_lbr *tail; +}; + +/* To create a concatenated lbr, you need a base resource which will persist */ +/* for the lifetime of the created lbr (and any lbrs copied from it). Pass */ +/* a pointer to this resource and pointers to the underlying lbrs to */ +/* concatenate. These must also persist for the lifetime of the created lbr.*/ + +extern struct xenidc_lbr +xenidc_concatenate_create_lbr(struct xenidc_concatenate_base *base, +struct xenidc_lbr *head, struct xenidc_lbr *tail); + +#endif diff -r a64ebf373f9c -r ec6442c07549 linux-2.6-xen-sparse/include/asm-xen/xenidc_wrapping.h --- /dev/null Wed Nov 23 15:38:27 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_wrapping.h Wed Nov 23 17:37:53 2005 @@ -0,0 +1,43 @@ +/*****************************************************************************/ +/* Support for accessing local buffer references with wrap-around. */ +/* */ +/* Copyright (c) 2005 Harry Butterworth IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU General Public License as published by the */ +/* Free Software Foundation; either version 2 of the License, or (at your */ +/* option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */ +/* Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License along */ +/* with this program; if not, write to the Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* */ +/*****************************************************************************/ + +#ifndef XENIDC_WRAPPING_H +#define XENIDC_WRAPPING_H + +#include "xenidc_local_buffer_reference.h" + +typedef enum { + xenidc_wrapping_client_type_producer, + xenidc_wrapping_client_type_consumer +} xenidc_wrapping_client_type; + +/* Create a reference for a wrapping buffer. Pass the start offset and the */ +/* end offset of the section of interest of the underlying buffer. If the */ +/* start and end offsets are the same then a producer will get a reference */ +/* to the whole buffer to fill whereas a consumer will get a reference to a */ +/* zero length buffer. */ + +extern struct xenidc_lbr +xenidc_wrapping_create_lbr(struct xenidc_lbr *underlying_buffer, +xenidc_buffer_byte_count start_offset, xenidc_buffer_byte_count end_offset, +xenidc_wrapping_client_type client_type); + +#endif