diff -r b4eca2889318 -r e7efce6f371c linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Sun Nov 20 17:45:16 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Sun Nov 20 17:45:28 2005 @@ -15,3 +15,4 @@ xenidc-objs += xenidc_gateway.o xenidc-objs += xenidc_gateway_initiator_resource.o xenidc-objs += xenidc_gateway_target_resource.o +xenidc-objs += xenidc_endpoint.o diff -r b4eca2889318 -r e7efce6f371c linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_endpoint.c --- /dev/null Sun Nov 20 17:45:16 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_endpoint.c Sun Nov 20 17:45:28 2005 @@ -0,0 +1,160 @@ +/*****************************************************************************/ +/* Xen inter-domain communication API, endpoint object. */ +/* */ +/* 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" + +int xenidc_endpoint_init + (xenidc_endpoint * endpoint, + void (*connect) (xenidc_endpoint * endpoint), void (*handle_message) + (xenidc_endpoint * endpoint, xenidc_endpoint_message * message), + void (*handle_transaction) + (xenidc_endpoint * endpoint, + xenidc_endpoint_transaction * transaction), void (*disconnect) + (xenidc_endpoint * endpoint, xenidc_callback * callback), + u32 initiator_quota, + xenidc_buffer_byte_count initiator_maximum_byte_count, + u32 target_quota, xenidc_buffer_byte_count target_maximum_byte_count) { + trace(); + + { + int return_value = xenidc_xbgt_channel_init(&endpoint->channel); + + if (return_value != 0) { + goto EXIT_NO_CHANNEL; + } + + return_value = xenidc_gateway_init + (&endpoint->gateway, + xenidc_xbgt_channel_to_channel(&endpoint->channel), + (void (*)(xenidc_gateway *))connect, + (void (*)(xenidc_gateway *, xenidc_endpoint_message *)) + handle_message, + (void (*)(xenidc_gateway *, xenidc_endpoint_transaction *)) + handle_transaction, + (void (*)(xenidc_gateway *, xenidc_callback *))disconnect, + initiator_quota, + initiator_maximum_byte_count, + target_quota, target_maximum_byte_count); + + if (return_value != 0) { + goto EXIT_NO_GATEWAY; + } + + return 0; + + EXIT_NO_GATEWAY: + + xenidc_xbgt_channel_exit(&endpoint->channel); + + EXIT_NO_CHANNEL: + + return return_value; + } +} + +void xenidc_endpoint_create(xenidc_endpoint * endpoint, xenidc_address address) { + trace(); + + xenidc_xbgt_channel_connect + (&endpoint->channel, + xenidc_address_query_local_domain(&address), + xenidc_address_query_remote_domain(&address), + xenidc_address_query_remote_domain_id(&address) + ); +} + +void xenidc_endpoint_submit_message + (xenidc_endpoint * endpoint, xenidc_endpoint_message * message) { + trace(); + + /* MUST MAINTAIN RELATIVE REQUEST ORDER ON THE SUBMISSION PATH */ + + xenidc_gateway_submit_message(&endpoint->gateway, message); +} + +void xenidc_endpoint_submit_transaction + (xenidc_endpoint * endpoint, xenidc_endpoint_transaction * transaction) { + trace(); + + /* MUST MAINTAIN RELATIVE REQUEST ORDER ON THE SUBMISSION PATH */ + + xenidc_gateway_submit_transaction(&endpoint->gateway, transaction); +} + +typedef struct xenidc_endpoint_callback_struct xenidc_endpoint_callback; + +struct xenidc_endpoint_callback_struct { + xenidc_callback callback; + int destroyed; +}; + +static void xenidc_endpoint_destroy_1(xenidc_callback * callback); + +void xenidc_endpoint_destroy(xenidc_endpoint * endpoint) +{ + trace(); + + { + xenidc_endpoint_callback endpoint_callback; + + xenidc_callback_init + (&endpoint_callback.callback, xenidc_endpoint_destroy_1); + + endpoint_callback.destroyed = 0; + + xenidc_xbgt_channel_disconnect + (&endpoint->channel, &endpoint_callback.callback); + + xenidc_work_until(endpoint_callback.destroyed); + } +} + +static void xenidc_endpoint_destroy_1(xenidc_callback * callback) +{ + trace(); + + { + xenidc_endpoint_callback *endpoint_callback = + container_of(callback, xenidc_endpoint_callback, callback); + + endpoint_callback->destroyed = 1; + + xenidc_work_wake_up(); + } +} + +void xenidc_endpoint_exit(xenidc_endpoint * endpoint) +{ + trace(); + + xenidc_gateway_exit(&endpoint->gateway); + + xenidc_xbgt_channel_exit(&endpoint->channel); +} + +EXPORT_SYMBOL(xenidc_endpoint_init); +EXPORT_SYMBOL(xenidc_endpoint_create); +EXPORT_SYMBOL(xenidc_endpoint_submit_message); +EXPORT_SYMBOL(xenidc_endpoint_submit_transaction); +EXPORT_SYMBOL(xenidc_endpoint_destroy); +EXPORT_SYMBOL(xenidc_endpoint_exit); diff -r b4eca2889318 -r e7efce6f371c linux-2.6-xen-sparse/include/asm-xen/xenidc_endpoint.h --- /dev/null Sun Nov 20 17:45:16 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_endpoint.h Sun Nov 20 17:45:28 2005 @@ -0,0 +1,282 @@ +/*****************************************************************************/ +/* Xen inter-domain communication endpoint. */ +/* */ +/* 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 __ASM_XEN_XENIDC_ENDPOINT_H__ +#define __ASM_XEN_XENIDC_ENDPOINT_H__ + +#include "xenidc_address.h" +#include "xenidc_gateway.h" +#include "xenidc_xbgt_channel.h" + +/* A xenidc_endpoint_message structure is used by the client of an endpoint */ +/* to send a message from the local domain to the remote domain. This */ +/* structure is also used by the endpoint to deliver a message received from */ +/* the remote domain to the client. */ + +typedef struct xenidc_gateway_message_struct xenidc_endpoint_message; + +/* The xenidc_endpoint_message structure contains a callback which is */ +/* completed by the endpoint to return outgoing messages to the client and */ +/* completed by the client to return inbound messages to the endpoint. */ + +static inline xenidc_callback *xenidc_endpoint_message_to_callback + (xenidc_endpoint_message * message) { + return xenidc_gateway_message_to_callback(message); +} + +static inline xenidc_endpoint_message *xenidc_endpoint_message_callback_to + (xenidc_callback * callback) { + return xenidc_gateway_message_callback_to(callback); +} + +/* The xenidc_endpoint_message structure contains a list_head type link */ +/* which in the case of outbound messages may be used by the client once the */ +/* message is initialised before it is submitted to the endpoint for */ +/* transmission and after the completion callback is called. For inbound */ +/* messages, the link may be used by the client between the time the */ +/* endpoint submits the message to the client's message handler and when the */ +/* client completes the message callback after handling the message. */ +/* The client must leave the link initialised after use. */ + +#define XENIDC_ENDPOINT_MESSAGE_LINK XENIDC_GATEWAY_MESSAGE_LINK + +static inline struct list_head *xenidc_endpoint_message_to_link + (xenidc_endpoint_message * message) { + return xenidc_callback_to_link + (xenidc_endpoint_message_to_callback(message)); +} + +static inline xenidc_endpoint_message *xenidc_endpoint_message_link_to + (struct list_head *link) { + return xenidc_endpoint_message_callback_to + (xenidc_callback_link_to(link)); +} + +/* The client is responsible for allocating xenidc_endpoint_message */ +/* structures for outgoing messages and must initialise them with the */ +/* callback function called by the endpoint when a message submitted for */ +/* transmission has been sent. */ + +static inline void xenidc_endpoint_message_init + (xenidc_endpoint_message * message, xenidc_callback_function * callback) { + xenidc_gateway_message_init(message, callback); +} + +/* The client must set a local buffer reference in the message structure to */ +/* refer to a buffer containing the body of the message for transmission. */ + +static inline void xenidc_endpoint_message_set_message_lbr + (xenidc_endpoint_message * message, xenidc_local_buffer_reference lbr) { + message->message_lbr = lbr; +} + +/* When a message is passed to the client's message handler, the client may */ +/* call xenidc_endpoint_message_to_message_lbr to get a pointer to a */ +/* local buffer reference for the body of the message. */ + +static inline xenidc_local_buffer_reference + *xenidc_endpoint_message_to_message_lbr(xenidc_endpoint_message * message) +{ + return &message->message_lbr; +} + +/* A xenidc_endpoint_transaction structure is used by the client of an */ +/* endpoint to send a transaction from the local domain to the remote */ +/* domain. This structure is also used by the endpoint to deliver a */ +/* transaction received from the remote domain to the client. */ + +typedef struct xenidc_gateway_transaction_struct xenidc_endpoint_transaction; + +/* The xenidc_endpoint_transaction contains a callback which is used as */ +/* follows: */ +/* */ +/* The initiator client allocates a xenidc_endpoint_transaction structure */ +/* and initialises the contained callback with its transaction completion */ +/* function. */ +/* The initiator submits the transaction to the endpoint which delivers the */ +/* transaction parameters to the remote domain and constructs a new */ +/* xenidc_endpoint_transaction structure in the remote domain containing a */ +/* callback initialised with the endpoint's transaction completion function. */ +/* This transaction is submitted to the target client. */ +/* The target client processes the transaction and completes the callback. */ +/* The endpoint in the remote domain handles the completion of the remote */ +/* transaction, transfers the transaction status back and completes the */ +/* callback of the initiator client's transaction passing the same error */ +/* return value. */ + +static inline xenidc_callback *xenidc_endpoint_transaction_to_callback + (xenidc_endpoint_transaction * transaction) { + return xenidc_gateway_transaction_to_callback(transaction); +} + +static inline xenidc_endpoint_transaction + *xenidc_endpoint_transaction_callback_to(xenidc_callback * callback) +{ + return xenidc_gateway_transaction_callback_to(callback); +} + +/* The xenidc_endpoint_transaction contains a struct list_head link which */ +/* may be used by the current owner of the transaction. */ + +#define XENIDC_ENDPOINT_TRANSACTION_LINK XENIDC_GATEWAY_TRANSACTION_LINK + +static inline struct list_head *xenidc_endpoint_transaction_to_link + (xenidc_endpoint_transaction * transaction) { + return xenidc_callback_to_link + (xenidc_endpoint_transaction_to_callback(transaction)); +} + +static inline xenidc_endpoint_transaction *xenidc_endpoint_transaction_link_to + (struct list_head *link) { + return xenidc_endpoint_transaction_callback_to + (xenidc_callback_link_to(link)); +} + +/* The xenidc_endpoint_transaction_init function is passed the callback for */ +/* transaction completion. */ + +static inline void xenidc_endpoint_transaction_init + (xenidc_endpoint_transaction * transaction, + xenidc_callback_function * callback) { + xenidc_gateway_transaction_init(transaction, callback); +} + +/* The client must set up a local buffer reference for the parameters before */ +/* submitting the transaction. */ + +static inline void xenidc_endpoint_transaction_set_parameters_lbr + (xenidc_endpoint_transaction * transaction, + xenidc_local_buffer_reference lbr) { + transaction->parameters_lbr = lbr; +} + +/* The client must set up a local buffer reference for a buffer to receive */ +/* the status before submitting the transaction. */ + +static inline void xenidc_endpoint_transaction_set_status_lbr + (xenidc_endpoint_transaction * transaction, + xenidc_local_buffer_reference lbr) { + transaction->status_lbr = lbr; +} + +/* The client may use xenidc_endpoint_transaction_to_parameters_lbr to get a */ +/* pointer to the local buffer reference for the parameters buffer. */ + +static inline xenidc_local_buffer_reference + *xenidc_endpoint_transaction_to_parameters_lbr(xenidc_endpoint_transaction * + transaction) { + return &transaction->parameters_lbr; +} + +/* The client may use xenidc_endpoint_transaction_to_status_lbr to get a */ +/* pointer to the local buffer reference for the status buffer. */ + +static inline xenidc_local_buffer_reference + *xenidc_endpoint_transaction_to_status_lbr(xenidc_endpoint_transaction * + transaction) { + return &transaction->status_lbr; +} + +/* The client target must call xenidc_endpoint_transaction_complete to */ +/* complete a received transaction once the transaction has been processed. */ + +static inline void xenidc_endpoint_transaction_complete + (xenidc_endpoint_transaction * transaction, xenidc_error error) { + xenidc_callback_complete + (xenidc_endpoint_transaction_to_callback(transaction), error); +} + +/* The client initiator may call xenidc_endpoint_transaction_query_error */ +/* to determine the error value returned by the client target on completion */ +/* of the transaction. The error value may alternatively indicate a */ +/* transport error. */ + +static inline xenidc_error xenidc_endpoint_transaction_query_error + (xenidc_endpoint_transaction * transaction) { + return xenidc_callback_query_error + (xenidc_endpoint_transaction_to_callback(transaction)); +} + +/* The client is responsible for allocating the xenidc_endpoint structure. */ + +typedef struct xenidc_endpoint_struct xenidc_endpoint; + +struct xenidc_endpoint_struct { + xenidc_gateway gateway; + xenidc_xbgt_channel channel; +}; + +/* The client calls xenidc_endpoint_init to initialise the endpoint and */ +/* allocate all the endpoint resources. This may block. */ + +extern int xenidc_endpoint_init + (xenidc_endpoint * endpoint, + void (*connect) (xenidc_endpoint * endpoint), void (*handle_message) + (xenidc_endpoint * endpoint, xenidc_endpoint_message * message), + void (*handle_transaction) + (xenidc_endpoint * endpoint, + xenidc_endpoint_transaction * transaction), void (*disconnect) + (xenidc_endpoint * endpoint, xenidc_callback * callback), + u32 initiator_quota, + xenidc_buffer_byte_count initiator_maximum_byte_count, + u32 target_quota, xenidc_buffer_byte_count target_maximum_byte_count); + +/* The client calls xenidc_endpoint_create to allow the endpoint to attempt */ +/* to make a connection with an endpoint in a remote domain. After this call */ +/* the endpoint will call the client's connect and disconnect calls as the */ +/* connection is made, broken and reestablished. */ + +extern void xenidc_endpoint_create + (xenidc_endpoint * endpoint, xenidc_address address); + +/* The client calls xenidc_endpoint_submit_message to submit a message for */ +/* the remote domain. The message's callback is called when the endpoint */ +/* has finished with the message structure; the callback does not indicate */ +/* that the message has been received. */ + +extern void xenidc_endpoint_submit_message + (xenidc_endpoint * endpoint, xenidc_endpoint_message * message); + +/* The client calls xenidc_endpoint_submit_transaction to submit a */ +/* transaction for the remote domain. The client sets the parameters_lbr to */ +/* reference a buffer containing the transaction parameters and sets the */ +/* status_lbr to reference a buffer for receipt of transaction status. The */ +/* endpoint submits the transaction to the client target on the remote */ +/* domain. The client target reads the parameters, processes the */ +/* transaction, writes the status and completes the callback with an error */ +/* code. The client initiators callback is completed with the error code as */ +/* provided by the client target or a transport error if the endpoint */ +/* disconnected. */ + +extern void xenidc_endpoint_submit_transaction + (xenidc_endpoint * endpoint, xenidc_endpoint_transaction * transaction); + +/* The client calls xenidc_endpoint_destroy to destroy the connection. This */ +/* call blocks until the client has completed the disconnect callback. */ + +extern void xenidc_endpoint_destroy(xenidc_endpoint * endpoint); + +/* The client calls xenidc_endpoint_exit to free up any resources allocated */ +/* by the endpoint init function. */ + +extern void xenidc_endpoint_exit(xenidc_endpoint * endpoint); + +#endif