diff -r 8e86098d98b8 -r 884447d31e86 linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_channel_ring.h --- /dev/null Sun Nov 20 17:28:25 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_channel_ring.h Sun Nov 20 17:43:54 2005 @@ -0,0 +1,63 @@ +/*****************************************************************************/ +/* Xen inter-domain communication channel ring structure definitions. */ +/* */ +/* 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_CHANNEL_RING_H +#define _XENIDC_CHANNEL_RING_H + +#include + +/* The ring consists of two pages, one provided by each side mapped rw into */ +/* the provider's address space and ro into the other side's address space. */ +/* Each page contains a header with wrapping buffer offsets in it. The */ +/* remainder of the page is used as a wrapping buffer. One of the offsets in */ +/* the header refers to the wrapping buffer in the same page as the header, */ +/* the other one refers to the wrapping buffer in the other page. This is */ +/* because the offsets which a side updates need to be in the page for which */ +/* that side has write access. */ +/* The offets are zero initially which indicates the start of the wrapping */ +/* buffer (at the first byte after the header). */ +/* */ +/* I chose this ring structure because it is symmetrical and if the ring */ +/* gets corrupted (by a scribbler for example) it will be easier to isolate */ +/* the problem to a domain. */ + +typedef struct xenidc_channel_ring_header_struct xenidc_channel_ring_header; + +struct xenidc_channel_ring_header_struct { + u16 this_ring_producer_offset; + u16 other_ring_consumer_offset; +}; + +/* Elements in the ring are variable length and all start with a header */ +/* which indicates how long they are. The next element starts directly */ +/* afterwards irrespective of byte alignment. Elements may span the wrap */ +/* around point of the buffer. The local buffer reference code is used to */ +/* copy into and out of the wrapping buffers so none of this is a problem. */ + +typedef struct xenidc_channel_ring_element_header_struct + xenidc_channel_ring_element_header; + +struct xenidc_channel_ring_element_header_struct { + u16 length; + u8 reserved1[6]; +}; + +#endif diff -r 8e86098d98b8 -r 884447d31e86 linux-2.6-xen-sparse/include/asm-xen/xenidc_channel.h --- /dev/null Sun Nov 20 17:28:25 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_channel.h Sun Nov 20 17:43:54 2005 @@ -0,0 +1,157 @@ +/*****************************************************************************/ +/* Xen inter-domain communication channel abstract base class. */ +/* */ +/* 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 */ +/* */ +/*****************************************************************************/ +/* */ +/* The xenidc_channel code defines an interface. This interface is used */ +/* between the xenidc_gateway and the xenidc_xbgt_channel objects that */ +/* implement the xenidc_endpoint object. The main point of this code is to */ +/* decouple the xenidc_gateway code from the xenidc_xbgt_channel code to */ +/* make it easier to implement them and subsequently review them */ +/* independently. The presence of this interface would also make it */ +/* possible to use the same gateway code on-top of a different channel */ +/* implementation. */ + +#ifndef _XENIDC_CHANNEL_H +#define _XENIDC_CHANNEL_H + +#include +#include + +/* The xenidc_channel_message structure is used to submit a message to a */ +/* channel and also passed to the client to represent a message when one is */ +/* received. Both submission and receipt are asynchronous so the party */ +/* passed the message has the opportunity to hold onto it (and the buffer of */ +/* the message body referenced by the message_lbr field) as long as */ +/* necessary to wait for resources to process the message. */ +/* The message structure is returned to the other party by completing the */ +/* callback. */ + +typedef struct xenidc_channel_message_struct xenidc_channel_message; + +struct xenidc_channel_message_struct { + xenidc_callback callback; + xenidc_local_buffer_reference message_lbr; +}; + +#define XENIDC_CHANNEL_MESSAGE_LINK callback.XENIDC_CALLBACK_LINK + +static inline struct list_head *xenidc_channel_message_to_link + (xenidc_channel_message * message) { + return &message->XENIDC_CHANNEL_MESSAGE_LINK; +} + +static inline xenidc_callback *xenidc_channel_message_to_callback + (xenidc_channel_message * message) { + return &message->callback; +} + +static inline xenidc_channel_message *xenidc_channel_message_callback_to + (xenidc_callback * callback) { + return container_of(callback, xenidc_channel_message, callback); +} + +static inline void xenidc_channel_message_init + (xenidc_channel_message * message, xenidc_callback_function * callback) { + xenidc_callback_init + (xenidc_channel_message_to_callback(message), callback); +} + +static inline void xenidc_channel_message_set_message_lbr + (xenidc_channel_message * message, xenidc_local_buffer_reference lbr) { + message->message_lbr = lbr; +} + +typedef struct xenidc_channel_struct xenidc_channel; + +struct xenidc_channel_struct { + void (*submit_message) + (xenidc_channel * channel, xenidc_channel_message * message); + void *client_context; + void (*connect) (void *client_context); + void (*handle_message) + (void *client_context, xenidc_channel_message * message); + void (*disconnect) + (void *client_context, xenidc_callback * callback); +}; + +/* Called by a derived class to initialise the base class. */ + +static inline void xenidc_channel_init + (xenidc_channel * channel, void (*submit_message) + (xenidc_channel * channel, xenidc_channel_message * message) + ) { + channel->submit_message = submit_message; +} + +/* Called by a derived class to notify the client. The client may submit */ +/* messages between the connect call and the completion of the disconnect */ +/* callback. The channel may submit messages to the client between the */ +/* connect call and the disconnect call. */ + +static inline void xenidc_channel_connect(xenidc_channel * channel) +{ + channel->connect(channel->client_context); +} + +/* Called by a derived class to notify the client. Called between connect */ +/* and disconnect. */ + +static inline void xenidc_channel_handle_message + (xenidc_channel * channel, xenidc_channel_message * message) { + channel->handle_message(channel->client_context, message); +} + +/* Called by a derived class to notify the client. */ + +static inline void xenidc_channel_disconnect + (xenidc_channel * channel, xenidc_callback * callback) { + channel->disconnect(channel->client_context, callback); +} + +/* Called by the client class during init before derived class first calls */ +/* connect (sequencing enforced by first connect call being an indirect */ +/* result of a client call to the derived class guaranteed to happen after */ +/* client calls install). */ + +static inline void xenidc_channel_install_client + (xenidc_channel * channel, + void *client_context, + void (*connect) (void *client_context), void (*handle_message) + (void *client_context, xenidc_channel_message * message), + void (*disconnect) + (void *client_context, xenidc_callback * callback) + ) { + channel->client_context = client_context; + channel->connect = connect; + channel->handle_message = handle_message; + channel->disconnect = disconnect; +} + +/* Called by the client class between connect and disconnect callback to */ +/* submit a message. */ + +static inline void xenidc_channel_submit_message + (xenidc_channel * channel, xenidc_channel_message * message) { + /* MUST MAINTAIN RELATIVE REQUEST ORDER ON THE SUBMISSION PATH */ + + channel->submit_message(channel, message); +} + +#endif