From: harry Subject: [PATCH][14/17] REV 2 USB virt 2.6 split driver---USB interdomain protocol Date: Wed, 30 Nov 2005 12:00:43 +0000 Message-ID: <1133352043.5960.9.camel@localhost.localdomain> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-BcKOgWmacmOC6QFrPCEv" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org --=-BcKOgWmacmOC6QFrPCEv Content-Type: text/plain Content-Transfer-Encoding: 7bit This patch picks up all the fixes to the previous 13 patches that were required to get the code working now that the last four patches are reformatted and I'm able to test the code again. These fixes will go into the correct patches if I do another revision. Aside from the fixes, this patch defines the USB interdomain protocol which consists of a number of transactions and a message sent using the xenidc_endpoint code. This protocol is a direct translation of the 2.4 protocol and uses polling for device detection. There is an issue with queued commands during error recovery. The queued commands need to be stalled during the unlink process but currently they are not. Both the polling and the queued commands issues need to be fixed. This may affect the protocol. The current protocol is good enough for read only access to USB devices and works for read-write access but is not safe for write access during error recovery. Signed-off-by: Harry Butterworth --=-BcKOgWmacmOC6QFrPCEv Content-Disposition: attachment; filename=p14-usb-protocol.patch Content-Type: text/x-patch; name=p14-usb-protocol.patch; charset=us-ascii Content-Transfer-Encoding: 7bit diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Tue Nov 29 17:11:59 2005 @@ -18,3 +18,4 @@ xenidc-objs += xenidc_endpoint.o xenidc-objs += xenidc_rbr_provider_pool.o xenidc-objs += xenidc_rbr_mapper_pool.o + diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_buffer_resource_provider.c --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_buffer_resource_provider.c Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_buffer_resource_provider.c Tue Nov 29 17:11:59 2005 @@ -215,7 +215,7 @@ { trace(); (void)xenidc_buffer_resource_provider_init_or_exit(provider, 1); - vfree(provider); + kfree(provider); } struct xenidc_buffer_resource_list diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_rbr_provider_pool.c --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_rbr_provider_pool.c Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_rbr_provider_pool.c Tue Nov 29 17:11:59 2005 @@ -20,7 +20,6 @@ /*****************************************************************************/ #include -#include #include #include "xenidc_trace.h" diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_remote_buffer_reference.c --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_remote_buffer_reference.c Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_remote_buffer_reference.c Tue Nov 29 17:11:59 2005 @@ -51,7 +51,7 @@ xenidc_rbr_calculate_map_resources_function *calculate_map_resources, xenidc_rbr_map_function *map, xenidc_rbr_unmap_function *unmap) { - int i = (class->type % XENIDC_RBR_HASH_COUNT); + int i = type % XENIDC_RBR_HASH_COUNT; unsigned long flags; trace(); xenidc_rbr_init(); diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_vaddress.c --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_vaddress.c Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_vaddress.c Tue Nov 29 17:11:59 2005 @@ -193,6 +193,7 @@ read_unlock_irqrestore(&xenidc_vaddress_lock, flags); return; } + read_unlock_irqrestore(&xenidc_vaddress_lock, flags); write_lock_irqsave(&xenidc_vaddress_lock, flags); if (initialised) { write_unlock_irqrestore(&xenidc_vaddress_lock, flags); diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_work.c --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_work.c Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_work.c Tue Nov 29 17:11:59 2005 @@ -79,6 +79,7 @@ EXPORT_SYMBOL(xenidc_work_schedule); EXPORT_SYMBOL(xenidc_work_list); +EXPORT_SYMBOL(xenidc_work_list_lock); EXPORT_SYMBOL(xenidc_work_condition); EXPORT_SYMBOL(xenidc_work_waitqueue); EXPORT_SYMBOL(xenidc_work_wake_up); diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_xbgt_channel.c --- a/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_xbgt_channel.c Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_xbgt_channel.c Tue Nov 29 17:11:59 2005 @@ -954,9 +954,11 @@ (struct xenidc_xbgt_channel *)data; int return_value; unsigned long flags; - trace(); channel->watch.node = channel->remote_path; channel->watch.callback = xenidc_xbgt_channel_watch; + trace_info( "channel:%p, watch.node:%s", channel, + channel->watch.node ); + return_value = register_xenbus_watch(&channel->watch); spin_lock_irqsave(&channel->lock, flags); if (return_value == 0) { @@ -982,7 +984,8 @@ struct xenidc_xbgt_channel *channel = (struct xenidc_xbgt_channel *)data; unsigned long flags; - trace(); + trace_info( "channel:%p, watch.node:%s", channel, + channel->watch.node ); unregister_xenbus_watch(&channel->watch); spin_lock_irqsave(&channel->lock, flags); xenidc_xbgt_channel_handle_stimulus(channel, diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/include/asm-xen/xenidc_endpoint.h --- a/linux-2.6-xen-sparse/include/asm-xen/xenidc_endpoint.h Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_endpoint.h Tue Nov 29 17:11:59 2005 @@ -155,7 +155,8 @@ /* 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 +#define XENIDC_ENDPOINT_TRANSACTION_LINK \ +gateway_transaction.XENIDC_GATEWAY_TRANSACTION_LINK static inline struct list_head * xenidc_endpoint_transaction_to_link( diff -r 9fd760c9e92c -r 0dab7be3b83a linux-2.6-xen-sparse/include/asm-xen/xenidc_work.h --- a/linux-2.6-xen-sparse/include/asm-xen/xenidc_work.h Fri Nov 25 18:50:14 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_work.h Tue Nov 29 17:11:59 2005 @@ -125,7 +125,7 @@ while (!list_empty(&xenidc_work_list) && !(condition)) { \ struct xenidc_work *work; \ work = list_entry(xenidc_work_list.next, \ - struct xenidc_work, link); \ + struct xenidc_work, link); \ list_del_init(&work->link); \ spin_unlock_irqrestore(&xenidc_work_list_lock, flags);\ xenidc_work_perform_synchronously(work); \ diff -r 9fd760c9e92c -r 0dab7be3b83a xen/include/public/io/usbif.h --- /dev/null Fri Nov 25 18:50:14 2005 +++ b/xen/include/public/io/usbif.h Tue Nov 29 17:11:59 2005 @@ -0,0 +1,297 @@ +/*****************************************************************************/ +/* FE->BE transactions for the USB split driver interface. */ +/* */ +/* 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 */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Based on the previous usbif.h by Mark Williamson and blkif.h, original */ +/* copyright notice follows... */ +/*****************************************************************************/ + +/****************************************************************************** + * usbif.h + * + * Unified block-device I/O interface for Xen guest OSes. + * + * Copyright (c) 2003-2004, Keir Fraser + */ + +#ifndef USBIF_H +#define USBIF_H + +#include + +/* All transactions have the same header which specifies the type of the */ +/* transaction. */ + +struct usbif_transaction_parameters_header { + u8 transaction_type; + u8 reserved[7]; +}; + +/* There are three types of transaction: */ + +#define USBIF_TRANSACTION_TYPE_PROBE 0 +#define USBIF_TRANSACTION_TYPE_RESET 1 +#define USBIF_TRANSACTION_TYPE_IO 2 + +/* The probe transaction is used to test whether a USB device is connected */ +/* to a port. */ +/* Port numbers start at 1. */ + +struct usbif_probe_transaction_parameters { + struct usbif_transaction_parameters_header header; + u32 port; + u8 reserved[4]; +}; + +struct usbif_probe_transaction_status { + u8 result; + u8 reserved[7]; +}; + +#define USBIF_PROBE_RESULT_NO_DEVICE 0 +#define USBIF_PROBE_RESULT_DEVICE_PRESENT 1 + +/* The reset transaction is used to reset a port. On success, the speed the */ +/* port is operating at after the reset is returned. */ + +struct usbif_reset_transaction_parameters { + struct usbif_transaction_parameters_header header; + u32 port; + u8 reserved[4]; +}; + +/* On success, the reset returns status... */ + +struct usbif_reset_transaction_status { + u8 result; + u8 reserved[7]; +}; + +#define USBIF_RESET_RESULT_FULL_SPEED 0 +#define USBIF_RESET_RESULT_LOW_SPEED 1 +#define USBIF_RESET_RESULT_HIGH_SPEED 2 + +/* Aside from the usual transport errors, the reset transaction might fail */ +/* if there is no device. */ + +/* All IO transactions have a header which specifies the type of IO */ +/* transaction and contains parameters common to all types of IO transaction.*/ + +struct usbif_io_transaction_parameters_header { + struct usbif_transaction_parameters_header header; + u8 io_transaction_type; + u8 device_number; + u8 endpoint; + u8 direction; + u32 unlink_id; + u32 flags; + u32 reserved; + struct xenidc_rbr rbr; +}; + +#define USBIF_IO_TRANSACTION_TYPE_CONTROL 0 +#define USBIF_IO_TRANSACTION_TYPE_BULK 1 +#define USBIF_IO_TRANSACTION_TYPE_INTERRUPT 2 +#define USBIF_IO_TRANSACTION_TYPE_ISOCHRONOUS 3 +/* Not a transaction type. For array bounds: */ +#define USBIF_IO_TRANSACTION_TYPE_LIMIT 4 + +#define USBIF_IO_TRANSACTION_DIRECTION_OUT 0 +#define USBIF_IO_TRANSACTION_DIRECTION_IN 1 + +#define USBIF_IO_FLAGS_SHORT_NOT_OK 0x00000001 +#define USBIF_IO_FLAGS_ZERO_PACKET 0x00000002 + +struct usbif_control_io_transaction_parameters { + struct usbif_io_transaction_parameters_header header; + u8 setup[8]; +}; + +struct usbif_bulk_io_transaction_parameters { + struct usbif_io_transaction_parameters_header header; +}; + +struct usbif_interrupt_io_transaction_parameters { + struct usbif_io_transaction_parameters_header header; + u32 interval; +}; + +struct usbif_isochronous_io_transaction_parameters { + struct usbif_io_transaction_parameters_header header; + u32 interval; + struct xenidc_rbr schedule_rbr; + u32 packet_count; +}; + +struct usbif_isochronous_io_schedule_element { + xenidc_buffer_byte_count offset; /* IN offset into header's rbr */ + xenidc_buffer_byte_count length; /* IN = expected, OUT = actual */ + xenidc_error error; /* OUT for this packet. */ +}; + +struct usbif_io_transaction_status { + xenidc_buffer_byte_count length; +}; + +/* These are the error values that have some significant meaning for the USB */ +/* protocol and might be tested for explicitly in error recovery code. */ +/* These error values are either used in xenidc_error form by the FE or BE */ +/* driver code or must be carefully translated to the local form of error */ +/* value for use higher up the USB stack in the FE. */ + +#define USBIF_XENIDC_ERROR_NO_DEVICE \ + ( XENIDC_ERROR_PROTOCOL_SPECIFIC_FIRST + 1 ) +#define USBIF_XENIDC_ERROR_UNLINKED \ + ( XENIDC_ERROR_PROTOCOL_SPECIFIC_FIRST + 2 ) +#define USBIF_XENIDC_ERROR_PIPE \ + ( XENIDC_ERROR_PROTOCOL_SPECIFIC_FIRST + 3 ) + +static inline xenidc_error usbif_error_map_local_to(int error) +{ + switch (error) { + case -ENODEV: + return USBIF_XENIDC_ERROR_NO_DEVICE; + case -ECONNRESET: + return USBIF_XENIDC_ERROR_UNLINKED; + case -EPIPE: + return USBIF_XENIDC_ERROR_PIPE; + default: + return xenidc_error_map_local_to(error); + } +} + +static inline int usbif_error_map_to_local(xenidc_error error) +{ + switch (error) { + case USBIF_XENIDC_ERROR_NO_DEVICE: + return -ENODEV; + case USBIF_XENIDC_ERROR_UNLINKED: + return -ECONNRESET; + case USBIF_XENIDC_ERROR_PIPE: + return -EPIPE; + default: + return xenidc_error_map_to_local(error); + } +} + +/* Lookup table for sizes of io parameters structures. */ + +static const xenidc_buffer_byte_count usbif_io_parameters_byte_count + [USBIF_IO_TRANSACTION_TYPE_LIMIT] = { + [USBIF_IO_TRANSACTION_TYPE_CONTROL] = + sizeof(struct usbif_control_io_transaction_parameters), + [USBIF_IO_TRANSACTION_TYPE_BULK] = + sizeof(struct usbif_bulk_io_transaction_parameters), + [USBIF_IO_TRANSACTION_TYPE_INTERRUPT] = + sizeof(struct usbif_interrupt_io_transaction_parameters), + [USBIF_IO_TRANSACTION_TYPE_ISOCHRONOUS] = + sizeof(struct usbif_isochronous_io_transaction_parameters) +}; + +union usbif_io_transaction_parameters { + struct usbif_io_transaction_parameters_header header; + struct usbif_control_io_transaction_parameters control; + struct usbif_bulk_io_transaction_parameters bulk; + struct usbif_interrupt_io_transaction_parameters interrupt; + struct usbif_isochronous_io_transaction_parameters isochronous; +}; + +union usbif_max_transaction { + struct { + struct usbif_probe_transaction_parameters parameters; + struct usbif_probe_transaction_status status; + } probe; + struct { + struct usbif_reset_transaction_parameters parameters; + struct usbif_reset_transaction_status status; + } reset; + struct { + struct usbif_control_io_transaction_parameters parameters; + struct usbif_io_transaction_status status; + } control_io; + struct { + struct usbif_bulk_io_transaction_parameters parameters; + struct usbif_io_transaction_status status; + } bulk_io; + struct { + struct usbif_interrupt_io_transaction_parameters parameters; + struct usbif_io_transaction_status status; + } interrupt_io; + struct { + struct usbif_isochronous_io_transaction_parameters parameters; + struct usbif_io_transaction_status status; + } isochronous_io; +}; + +/* All messages have the same header which specifies the type of the */ +/* message. */ + +struct usbif_message_header { + u8 message_type; + u8 reserved[7]; +}; + +/* There is only one type of message: */ + +#define USBIF_MESSAGE_TYPE_UNLINK 0 + +/* The unlink message is sent to unlink an IO operation. The backend will */ +/* ensure it completes or is failed out as quickly as possible. */ +/* This is a send and forget message: the client should wait for the */ +/* completion of the IO transaction as normal. */ + +struct usbif_unlink_message_body { + struct usbif_message_header header; + u32 unlink_id; + u32 reserved; +}; + +union usbif_max_message { + struct usbif_unlink_message_body unlink; +}; + +union usbif_max_transaction_or_message { + union usbif_max_transaction transaction; + union usbif_max_message message; +}; + +#define USBIF_MAX_BULK_BYTE_COUNT 65536 /* FIXME: what value here? */ +#define USBIF_BULK_BYTE_ALIGNMENT 1 /* FIXME: what value here? */ +#define USBIF_MAX_SCHEDULE_BYTE_COUNT 65536 /* FIXME: what value here? */ +#define USBIF_SCHEDULE_BYTE_ALIGNMENT 1 /* FIXME: what value here? */ +#define USBIF_MAX_SCHEDULE_PACKET_COUNT 64 /* FIXME: what value here? */ + +#define USBIF_BE_INITIATOR_QUOTA 0 +#define USBIF_BE_INITIATOR_MAXIMUM_BYTE_COUNT 0 + +#define USBIF_BE_TARGET_QUOTA 32 +#define USBIF_BE_TARGET_MAXIMUM_BYTE_COUNT \ +( sizeof( union usbif_max_transaction_or_message ) ) + +#define USBIF_FE_INITIATOR_QUOTA USBIF_BE_TARGET_QUOTA +#define USBIF_FE_INITIATOR_MAXIMUM_BYTE_COUNT \ +USBIF_BE_TARGET_MAXIMUM_BYTE_COUNT + +#define USBIF_FE_TARGET_QUOTA USBIF_BE_INITIATOR_QUOTA +#define USBIF_FE_TARGET_MAXIMUM_BYTE_COUNT \ +USBIF_BE_INITIATOR_MAXIMUM_BYTE_COUNT + +#endif --=-BcKOgWmacmOC6QFrPCEv Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --=-BcKOgWmacmOC6QFrPCEv--