diff -r 2055d5e00d68 -r a7aae84b171f linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Sun Nov 20 14:54:21 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Sun Nov 20 14:54:45 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 2055d5e00d68 -r a7aae84b171f linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_concatenate.c --- /dev/null Sun Nov 20 14:54:21 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_concatenate.c Sun Nov 20 14:54:45 2005 @@ -0,0 +1,124 @@ +/*****************************************************************************/ +/* 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_buffer_type xenidc_concatenate_type; + +static xenidc_local_buffer_reference xenidc_concatenate_resolve + (xenidc_buffer_virtual_class * class, xenidc_local_buffer_reference * lbr) { + trace(); + + { + xenidc_local_buffer_reference resolved_lbr; + + xenidc_concatenate_base *base = + (xenidc_concatenate_base *) lbr->base; + + if (lbr->byte_offset < base->head->byte_count) { + resolved_lbr = *base->head; + + xenidc_local_buffer_reference_subrange + (&resolved_lbr, lbr->byte_offset, lbr->byte_count); + } else { + resolved_lbr = *base->tail; + + xenidc_local_buffer_reference_subrange + (&resolved_lbr, + lbr->byte_offset - base->head->byte_count, + lbr->byte_count); + } + + return resolved_lbr; + } +} + +static void xenidc_concatenate_init(void) +{ + trace(); + + { + static DEFINE_RWLOCK(xenidc_concatenate_lock); + + unsigned long flags; + + read_lock_irqsave(&xenidc_concatenate_lock, flags); + + { + static int initialised = 0; + + if (!initialised) { + read_unlock_irqrestore + (&xenidc_concatenate_lock, flags); + + write_lock_irqsave + (&xenidc_concatenate_lock, flags); + + if (!initialised) { + static xenidc_buffer_virtual_class + xenidc_concatenate_virtual_class; + + xenidc_concatenate_type = + xenidc_local_buffer_reference_register_buffer_virtual_class + (&xenidc_concatenate_virtual_class, + xenidc_concatenate_resolve, NULL); + + initialised = 1; + } + + write_unlock_irqrestore + (&xenidc_concatenate_lock, flags); + + read_lock_irqsave + (&xenidc_concatenate_lock, flags); + } + } + + read_unlock_irqrestore(&xenidc_concatenate_lock, flags); + } +} + +xenidc_local_buffer_reference xenidc_concatenate_create_lbr + (xenidc_concatenate_base * base, + xenidc_local_buffer_reference * head, + xenidc_local_buffer_reference * tail) { + trace(); + + xenidc_concatenate_init(); + + base->head = head; + base->tail = tail; + + { + xenidc_local_buffer_reference lbr; + + 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 2055d5e00d68 -r a7aae84b171f linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_wrapping.c --- /dev/null Sun Nov 20 14:54:21 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_wrapping.c Sun Nov 20 14:54:45 2005 @@ -0,0 +1,141 @@ +/*****************************************************************************/ +/* 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" + +#ifdef MIN +#undef MIN +#endif + +#define MIN( X, Y ) ( ( (X) < (Y) ) ? (X) : (Y) ) + +static xenidc_buffer_type xenidc_wrapping_type; + +static xenidc_local_buffer_reference xenidc_wrapping_resolve + (xenidc_buffer_virtual_class * class, xenidc_local_buffer_reference * lbr) { + trace(); + + { + xenidc_local_buffer_reference resolved_lbr = + *(xenidc_local_buffer_reference *) lbr->base; + + xenidc_local_buffer_reference_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 + (xenidc_buffer_virtual_class * class, + xenidc_local_buffer_reference * lbr, xenidc_buffer_byte_count byte_count) { + trace(); + + lbr->byte_offset += byte_count; + lbr->byte_offset %= + ((xenidc_local_buffer_reference *) lbr->base)->byte_count; + lbr->byte_count -= byte_count; +} + +static void xenidc_wrapping_init(void) +{ + trace(); + + { + static DEFINE_RWLOCK(xenidc_wrapping_lock); + + unsigned long flags; + + read_lock_irqsave(&xenidc_wrapping_lock, flags); + + { + static int initialised = 0; + + if (!initialised) { + read_unlock_irqrestore + (&xenidc_wrapping_lock, flags); + + write_lock_irqsave + (&xenidc_wrapping_lock, flags); + + if (!initialised) { + static xenidc_buffer_virtual_class + xenidc_wrapping_virtual_class; + + xenidc_wrapping_type = + xenidc_local_buffer_reference_register_buffer_virtual_class + (&xenidc_wrapping_virtual_class, + xenidc_wrapping_resolve, + xenidc_wrapping_advance); + + initialised = 1; + } + + write_unlock_irqrestore + (&xenidc_wrapping_lock, flags); + + read_lock_irqsave(&xenidc_wrapping_lock, flags); + } + } + + read_unlock_irqrestore(&xenidc_wrapping_lock, flags); + } +} + +xenidc_local_buffer_reference xenidc_wrapping_create_lbr + (xenidc_local_buffer_reference * underlying_buffer, + xenidc_buffer_byte_count start_offset, + xenidc_buffer_byte_count end_offset, + xenidc_wrapping_client_type client_type) { + trace(); + + xenidc_wrapping_init(); + + { + xenidc_local_buffer_reference lbr; + + lbr.type = xenidc_wrapping_type; + lbr.base = underlying_buffer; + lbr.byte_offset = start_offset; + lbr.byte_count = ((start_offset < end_offset) + ? (end_offset - start_offset) + : ((start_offset > end_offset) + ? + (end_offset + + underlying_buffer->byte_count - + start_offset) + : ((client_type == + xenidc_wrapping_client_type_producer) + ? underlying_buffer->byte_count : 0) + ) + ); + + return lbr; + } +} + +EXPORT_SYMBOL(xenidc_wrapping_create_lbr); diff -r 2055d5e00d68 -r a7aae84b171f linux-2.6-xen-sparse/include/asm-xen/xenidc_concatenate.h --- /dev/null Sun Nov 20 14:54:21 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_concatenate.h Sun Nov 20 14:54:45 2005 @@ -0,0 +1,44 @@ +/*****************************************************************************/ +/* 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" + +typedef struct xenidc_concatenate_base_struct xenidc_concatenate_base; + +struct xenidc_concatenate_base_struct { + xenidc_local_buffer_reference *head; + xenidc_local_buffer_reference *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 xenidc_local_buffer_reference xenidc_concatenate_create_lbr + (xenidc_concatenate_base * base, + xenidc_local_buffer_reference * head, + xenidc_local_buffer_reference * tail); + +#endif diff -r 2055d5e00d68 -r a7aae84b171f linux-2.6-xen-sparse/include/asm-xen/xenidc_wrapping.h --- /dev/null Sun Nov 20 14:54:21 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_wrapping.h Sun Nov 20 14:54:45 2005 @@ -0,0 +1,44 @@ +/*****************************************************************************/ +/* 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 xenidc_local_buffer_reference xenidc_wrapping_create_lbr + (xenidc_local_buffer_reference * underlying_buffer, + xenidc_buffer_byte_count start_offset, + xenidc_buffer_byte_count end_offset, + xenidc_wrapping_client_type client_type); + +#endif