diff -r 7c011e163562 -r 961eaf493021 linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_channel_ring.h --- /dev/null Wed Nov 23 19:30:40 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_channel_ring.h Thu Nov 24 16:27:47 2005 @@ -0,0 +1,58 @@ +/*****************************************************************************/ +/* 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. */ + +struct xenidc_channel_ring_header { + 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. */ + +struct xenidc_channel_ring_element_header { + u16 length; + u8 reserved1[6]; +}; + +#endif diff -r 7c011e163562 -r 961eaf493021 linux-2.6-xen-sparse/include/asm-xen/xenidc_channel.h --- /dev/null Wed Nov 23 19:30:40 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_channel.h Thu Nov 24 16:27:47 2005 @@ -0,0 +1,178 @@ +/*****************************************************************************/ +/* 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. */ + +struct xenidc_channel_message { + struct xenidc_callback callback; + struct xenidc_lbr message_lbr; +}; + +#define XENIDC_CHANNEL_MESSAGE_LINK callback.XENIDC_CALLBACK_LINK + +static inline struct list_head * +xenidc_channel_message_to_link(struct xenidc_channel_message *message) +{ + return &message->XENIDC_CHANNEL_MESSAGE_LINK; +} + +static inline struct xenidc_callback * +xenidc_channel_message_to_callback(struct xenidc_channel_message *message) +{ + return &message->callback; +} + +static inline struct xenidc_channel_message * +xenidc_channel_message_callback_to(struct xenidc_callback *callback) +{ + return container_of(callback, struct xenidc_channel_message, callback); +} + +static inline void +xenidc_channel_message_init(struct 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(struct xenidc_channel_message *message, +struct xenidc_lbr lbr) +{ + message->message_lbr = lbr; +} + +struct xenidc_channel; + +typedef void +xenidc_channel_submit_message_function(struct xenidc_channel *channel, +struct xenidc_channel_message *message); + +typedef void +xenidc_channel_connect_function(void *client_context); + +typedef void +xenidc_channel_handle_message_function(void *client_context, +struct xenidc_channel_message *message); + +typedef void +xenidc_channel_disconnect_function(void *client_context, +struct xenidc_callback *callback); + +struct xenidc_channel { + xenidc_channel_submit_message_function *submit_message; + void *client_context; + xenidc_channel_connect_function *connect; + xenidc_channel_handle_message_function *handle_message; + xenidc_channel_disconnect_function *disconnect; +}; + +/* Called by a derived class to initialise the base class. */ + +static inline void +xenidc_channel_init(struct xenidc_channel *channel, +xenidc_channel_submit_message_function *submit_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(struct 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(struct xenidc_channel *channel, +struct 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(struct xenidc_channel *channel, +struct 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(struct xenidc_channel *channel, +void *client_context, xenidc_channel_connect_function *connect, +xenidc_channel_handle_message_function *handle_message, +xenidc_channel_disconnect_function *disconnect) +{ + 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(struct xenidc_channel *channel, +struct xenidc_channel_message *message) +{ + /* MUST MAINTAIN RELATIVE REQUEST ORDER ON THE SUBMISSION PATH */ + + channel->submit_message(channel, message); +} + +#endif