ia64/xen-unstable
changeset 3577:e8d6036117fd
bitkeeper revision 1.1159.1.541 (41fa51ecY_wTV-Rnc5CzoxSj38uvJw)
Merge tempest.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into tempest.cl.cam.ac.uk:/local/scratch/smh22/xen-unstable.bk
Merge tempest.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into tempest.cl.cam.ac.uk:/local/scratch/smh22/xen-unstable.bk
line diff
1.1 --- a/.rootkeys Fri Jan 28 07:59:39 2005 +0000 1.2 +++ b/.rootkeys Fri Jan 28 14:53:32 2005 +0000 1.3 @@ -65,14 +65,7 @@ 4083dc16UmHXxS9g_UFVnkUpN-oP2Q linux-2.4 1.4 405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.29-xen-sparse/arch/xen/drivers/netif/frontend/Makefile 1.5 41ee5e8b_2rt-qHzbDXtIoBzOli0EA linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/Makefile 1.6 41ee5e8bUhF4tH7OoJaVbUxdXqneVw linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/Makefile 1.7 -41ee5e8bYDQkjRVKnFn5uFyy0KreCw linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/common.h 1.8 -41ee5e8bt7xeBUJqG5XJS-ofukdsgA linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/control.c 1.9 -41ee5e8bSs3BGC7yegM_ek2Tn0Ahvw linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/interface.c 1.10 -41ee5e8bglvqKvZSY5uJ5JGQejEwyQ linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/main.c 1.11 41ee5e8bSPpxzhGO6TrY20TegW3cZg linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/frontend/Makefile 1.12 -41ee5e8ckZ9xVNvu9NHIZDK7JqApmQ linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/frontend/main.c 1.13 -41ee5e8ck9scpGirfqEZRARbGDyTXA linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/frontend/xhci.h 1.14 -41ee5e8c6mLxIx82KPsbpt_uts_vSA linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/usbif.h 1.15 3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.29-xen-sparse/arch/xen/kernel/Makefile 1.16 3e5a4e65_hqfuxtGG8IUy6wRM86Ecg linux-2.4.29-xen-sparse/arch/xen/kernel/entry.S 1.17 3e5a4e65Hy_1iUvMTPsNqGNXd9uFpg linux-2.4.29-xen-sparse/arch/xen/kernel/head.S 1.18 @@ -97,6 +90,7 @@ 40d70c24-Dy2HUMrwSZagfXvAPnI4w linux-2.4 1.19 3f108aeaLcGDgQdFAANLTUEid0a05w linux-2.4.29-xen-sparse/drivers/char/mem.c 1.20 3e5a4e66rw65CxyolW9PKz4GG42RcA linux-2.4.29-xen-sparse/drivers/char/tty_io.c 1.21 40c9c0c1pPwYE3-4i-oI3ubUu7UgvQ linux-2.4.29-xen-sparse/drivers/scsi/aic7xxx/Makefile 1.22 +41f97f64nW0wmgLxhwzPTzkF4E5ERA linux-2.4.29-xen-sparse/drivers/usb/hcd.c 1.23 3e5a4e669uzIE54VwucPYtGwXLAbzA linux-2.4.29-xen-sparse/fs/exec.c 1.24 3e5a4e66wbeCpsJgVf_U8Jde-CNcsA linux-2.4.29-xen-sparse/include/asm-xen/bugs.h 1.25 3e5a4e66HdSkvIV6SJ1evG_xmTmXHA linux-2.4.29-xen-sparse/include/asm-xen/desc.h 1.26 @@ -228,6 +222,12 @@ 40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6 1.27 405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c 1.28 4108f5c1ppFXVpQzCOAZ6xXYubsjKA linux-2.6.10-xen-sparse/drivers/xen/privcmd/Makefile 1.29 3e5a4e65IUfzzMu2kZFlGEB8-rpTaA linux-2.6.10-xen-sparse/drivers/xen/privcmd/privcmd.c 1.30 +41ee5e8bYDQkjRVKnFn5uFyy0KreCw linux-2.6.10-xen-sparse/drivers/xen/usbback/common.h 1.31 +41ee5e8bt7xeBUJqG5XJS-ofukdsgA linux-2.6.10-xen-sparse/drivers/xen/usbback/control.c 1.32 +41ee5e8bSs3BGC7yegM_ek2Tn0Ahvw linux-2.6.10-xen-sparse/drivers/xen/usbback/interface.c 1.33 +41ee5e8bglvqKvZSY5uJ5JGQejEwyQ linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c 1.34 +41ee5e8ckZ9xVNvu9NHIZDK7JqApmQ linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c 1.35 +41ee5e8ck9scpGirfqEZRARbGDyTXA linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h 1.36 412f47e4RKD-R5IS5gEXvcT8L4v8gA linux-2.6.10-xen-sparse/include/asm-generic/pgtable.h 1.37 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h 1.38 4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h 1.39 @@ -1054,6 +1054,7 @@ 40dc4076pVeE1kEEWzcUaNZin65kCA xen/inclu 1.40 41c0c412FLc0gunlJl91qMYscFtXVA xen/include/public/io/ioreq.h 1.41 40f5623cTZ80EwjWUBlh44A9F9i_Lg xen/include/public/io/netif.h 1.42 41d40e9b8zCk5VDqhVbuQyhc7G3lqA xen/include/public/io/ring.h 1.43 +41ee5e8c6mLxIx82KPsbpt_uts_vSA xen/include/public/io/usbif.h 1.44 4051db79512nOCGweabrFWO2M2h5ng xen/include/public/physdev.h 1.45 40589968wmhPmV5-ENbBYmMjnedgKw xen/include/public/sched_ctl.h 1.46 404f3d2eR2Owk-ZcGOx9ULGHg3nrww xen/include/public/trace.h
2.1 --- a/BitKeeper/etc/logging_ok Fri Jan 28 07:59:39 2005 +0000 2.2 +++ b/BitKeeper/etc/logging_ok Fri Jan 28 14:53:32 2005 +0000 2.3 @@ -17,6 +17,7 @@ cwc22@centipede.cl.cam.ac.uk 2.4 djm@kirby.fc.hp.com 2.5 gm281@boulderdash.cl.cam.ac.uk 2.6 gm281@tetrapod.cl.cam.ac.uk 2.7 +harry@dory.(none) 2.8 iap10@freefall.cl.cam.ac.uk 2.9 iap10@labyrinth.cl.cam.ac.uk 2.10 iap10@nidd.cl.cam.ac.uk 2.11 @@ -26,6 +27,7 @@ iap10@tetris.cl.cam.ac.uk 2.12 jws22@gauntlet.cl.cam.ac.uk 2.13 jws@cairnwell.research 2.14 kaf24@camelot.eng.3leafnetworks.com 2.15 +kaf24@firebug.cl.cam.ac.uk 2.16 kaf24@freefall.cl.cam.ac.uk 2.17 kaf24@labyrinth.cl.cam.ac.uk 2.18 kaf24@pb001.cl.cam.ac.uk
3.1 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/common.h Fri Jan 28 07:59:39 2005 +0000 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,87 +0,0 @@ 3.4 - 3.5 -#ifndef __USBIF__BACKEND__COMMON_H__ 3.6 -#define __USBIF__BACKEND__COMMON_H__ 3.7 - 3.8 -#include <linux/config.h> 3.9 -#include <linux/version.h> 3.10 -#include <linux/module.h> 3.11 -#include <linux/rbtree.h> 3.12 -#include <linux/interrupt.h> 3.13 -#include <linux/slab.h> 3.14 -#include <linux/blkdev.h> 3.15 -#include <asm/io.h> 3.16 -#include <asm/setup.h> 3.17 -#include <asm/pgalloc.h> 3.18 -#include <asm-xen/ctrl_if.h> 3.19 -#include <asm-xen/hypervisor.h> 3.20 - 3.21 -#include "../usbif.h" 3.22 - 3.23 -#if 0 3.24 -#define ASSERT(_p) \ 3.25 - if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \ 3.26 - __LINE__, __FILE__); *(int*)0=0; } 3.27 -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \ 3.28 - __FILE__ , __LINE__ , ## _a ) 3.29 -#else 3.30 -#define ASSERT(_p) ((void)0) 3.31 -#define DPRINTK(_f, _a...) ((void)0) 3.32 -#endif 3.33 - 3.34 -typedef struct usbif_priv_st usbif_priv_t; 3.35 - 3.36 -struct usbif_priv_st { 3.37 - /* Unique identifier for this interface. */ 3.38 - domid_t domid; 3.39 - unsigned int handle; 3.40 - /* Physical parameters of the comms window. */ 3.41 - unsigned long shmem_frame; 3.42 - unsigned int evtchn; 3.43 - int irq; 3.44 - /* Comms information. */ 3.45 - usbif_t *usb_ring_base; /* ioremap()'ed ptr to shmem_frame. */ 3.46 - USBIF_RING_IDX usb_req_cons; /* Request consumer. */ 3.47 - USBIF_RING_IDX usb_resp_prod; /* Private version of resp. producer. */ 3.48 - /* Private fields. */ 3.49 - enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; 3.50 - /* 3.51 - * DISCONNECT response is deferred until pending requests are ack'ed. 3.52 - * We therefore need to store the id from the original request. 3.53 - */ 3.54 - u8 disconnect_rspid; 3.55 - usbif_priv_t *hash_next; 3.56 - struct list_head usbif_list; 3.57 - spinlock_t usb_ring_lock; 3.58 - atomic_t refcnt; 3.59 - atomic_t work_scheduled; 3.60 - 3.61 - struct work_struct work; 3.62 -}; 3.63 - 3.64 -void usbif_create(usbif_be_create_t *create); 3.65 -void usbif_destroy(usbif_be_destroy_t *destroy); 3.66 -void usbif_connect(usbif_be_connect_t *connect); 3.67 -int usbif_disconnect(usbif_be_disconnect_t *disconnect, u8 rsp_id); 3.68 -void usbif_disconnect_complete(usbif_priv_t *up); 3.69 - 3.70 -void usbif_release_port(usbif_be_release_port_t *msg); 3.71 -int usbif_claim_port(usbif_be_claim_port_t *msg); 3.72 -void usbif_release_ports(usbif_priv_t *up); 3.73 - 3.74 -usbif_priv_t *usbif_find(domid_t domid); 3.75 -#define usbif_get(_b) (atomic_inc(&(_b)->refcnt)) 3.76 -#define usbif_put(_b) \ 3.77 - do { \ 3.78 - if ( atomic_dec_and_test(&(_b)->refcnt) ) \ 3.79 - usbif_disconnect_complete(_b); \ 3.80 - } while (0) 3.81 - 3.82 - 3.83 -void usbif_interface_init(void); 3.84 -void usbif_ctrlif_init(void); 3.85 - 3.86 -void usbif_deschedule(usbif_priv_t *usbif); 3.87 - 3.88 -irqreturn_t usbif_be_int(int irq, void *dev_id, struct pt_regs *regs); 3.89 - 3.90 -#endif /* __USBIF__BACKEND__COMMON_H__ */
4.1 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/control.c Fri Jan 28 07:59:39 2005 +0000 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,77 +0,0 @@ 4.4 -/****************************************************************************** 4.5 - * arch/xen/drivers/usbif/backend/control.c 4.6 - * 4.7 - * Routines for interfacing with the control plane. 4.8 - * 4.9 - * Copyright (c) 2004, Keir Fraser 4.10 - */ 4.11 - 4.12 -#include "common.h" 4.13 - 4.14 -static void usbif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 4.15 -{ 4.16 - DPRINTK("Received usbif backend message, subtype=%d\n", msg->subtype); 4.17 - 4.18 - switch ( msg->subtype ) 4.19 - { 4.20 - case CMSG_USBIF_BE_CREATE: 4.21 - if ( msg->length != sizeof(usbif_be_create_t) ) 4.22 - goto parse_error; 4.23 - usbif_create((usbif_be_create_t *)&msg->msg[0]); 4.24 - break; 4.25 - case CMSG_USBIF_BE_DESTROY: 4.26 - if ( msg->length != sizeof(usbif_be_destroy_t) ) 4.27 - goto parse_error; 4.28 - usbif_destroy((usbif_be_destroy_t *)&msg->msg[0]); 4.29 - break; 4.30 - case CMSG_USBIF_BE_CONNECT: 4.31 - if ( msg->length != sizeof(usbif_be_connect_t) ) 4.32 - goto parse_error; 4.33 - usbif_connect((usbif_be_connect_t *)&msg->msg[0]); 4.34 - break; 4.35 - case CMSG_USBIF_BE_DISCONNECT: 4.36 - if ( msg->length != sizeof(usbif_be_disconnect_t) ) 4.37 - goto parse_error; 4.38 - if ( !usbif_disconnect((usbif_be_disconnect_t *)&msg->msg[0],msg->id) ) 4.39 - return; /* Sending the response is deferred until later. */ 4.40 - break; 4.41 - case CMSG_USBIF_BE_CLAIM_PORT: 4.42 - if ( msg->length != sizeof(usbif_be_claim_port_t) ) 4.43 - goto parse_error; 4.44 - usbif_claim_port((usbif_be_claim_port_t *)&msg->msg[0]); 4.45 - break; 4.46 - case CMSG_USBIF_BE_RELEASE_PORT: 4.47 - if ( msg->length != sizeof(usbif_be_release_port_t) ) 4.48 - goto parse_error; 4.49 - usbif_release_port((usbif_be_release_port_t *)&msg->msg[0]); 4.50 - break; 4.51 - default: 4.52 - goto parse_error; 4.53 - } 4.54 - 4.55 - ctrl_if_send_response(msg); 4.56 - return; 4.57 - 4.58 - parse_error: 4.59 - DPRINTK("Parse error while reading message subtype %d, len %d\n", 4.60 - msg->subtype, msg->length); 4.61 - msg->length = 0; 4.62 - ctrl_if_send_response(msg); 4.63 -} 4.64 - 4.65 -void usbif_ctrlif_init(void) 4.66 -{ 4.67 - ctrl_msg_t cmsg; 4.68 - usbif_be_driver_status_changed_t st; 4.69 - 4.70 - (void)ctrl_if_register_receiver(CMSG_USBIF_BE, usbif_ctrlif_rx, 4.71 - CALLBACK_IN_BLOCKING_CONTEXT); 4.72 - 4.73 - /* Send a driver-UP notification to the domain controller. */ 4.74 - cmsg.type = CMSG_USBIF_BE; 4.75 - cmsg.subtype = CMSG_USBIF_BE_DRIVER_STATUS_CHANGED; 4.76 - cmsg.length = sizeof(usbif_be_driver_status_changed_t); 4.77 - st.status = USBIF_DRIVER_STATUS_UP; 4.78 - memcpy(cmsg.msg, &st, sizeof(st)); 4.79 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 4.80 -}
5.1 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/interface.c Fri Jan 28 07:59:39 2005 +0000 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,248 +0,0 @@ 5.4 -/****************************************************************************** 5.5 - * arch/xen/drivers/usbif/backend/interface.c 5.6 - * 5.7 - * USB device interface management. 5.8 - * 5.9 - * by Mark Williamson, Copyright (c) 2004 5.10 - */ 5.11 - 5.12 - 5.13 -/****************************************************************************** 5.14 - * arch/xen/drivers/blkif/backend/interface.c 5.15 - * 5.16 - * Block-device interface management. 5.17 - * 5.18 - * Copyright (c) 2004, Keir Fraser 5.19 - */ 5.20 - 5.21 -#include "common.h" 5.22 - 5.23 -#define USBIF_HASHSZ 1024 5.24 -#define USBIF_HASH(_d) (((int)(_d))&(USBIF_HASHSZ-1)) 5.25 - 5.26 -static kmem_cache_t *usbif_priv_cachep; 5.27 -static usbif_priv_t *usbif_priv_hash[USBIF_HASHSZ]; 5.28 - 5.29 -usbif_priv_t *usbif_find(domid_t domid) 5.30 -{ 5.31 - usbif_priv_t *up = usbif_priv_hash[USBIF_HASH(domid)]; 5.32 - while ( (up != NULL ) && ( up->domid != domid ) ) 5.33 - up = up->hash_next; 5.34 - return up; 5.35 -} 5.36 - 5.37 -static void __usbif_disconnect_complete(void *arg) 5.38 -{ 5.39 - usbif_priv_t *usbif = (usbif_priv_t *)arg; 5.40 - ctrl_msg_t cmsg; 5.41 - usbif_be_disconnect_t disc; 5.42 - 5.43 - /* 5.44 - * These can't be done in usbif_disconnect() because at that point there 5.45 - * may be outstanding requests at the device whose asynchronous responses 5.46 - * must still be notified to the remote driver. 5.47 - */ 5.48 - unbind_evtchn_from_irq(usbif->evtchn); 5.49 - vfree(usbif->usb_ring_base); 5.50 - 5.51 - /* Construct the deferred response message. */ 5.52 - cmsg.type = CMSG_USBIF_BE; 5.53 - cmsg.subtype = CMSG_USBIF_BE_DISCONNECT; 5.54 - cmsg.id = usbif->disconnect_rspid; 5.55 - cmsg.length = sizeof(usbif_be_disconnect_t); 5.56 - disc.domid = usbif->domid; 5.57 - disc.status = USBIF_BE_STATUS_OKAY; 5.58 - memcpy(cmsg.msg, &disc, sizeof(disc)); 5.59 - 5.60 - /* 5.61 - * Make sure message is constructed /before/ status change, because 5.62 - * after the status change the 'usbif' structure could be deallocated at 5.63 - * any time. Also make sure we send the response /after/ status change, 5.64 - * as otherwise a subsequent CONNECT request could spuriously fail if 5.65 - * another CPU doesn't see the status change yet. 5.66 - */ 5.67 - mb(); 5.68 - if ( usbif->status != DISCONNECTING ) 5.69 - BUG(); 5.70 - usbif->status = DISCONNECTED; 5.71 - mb(); 5.72 - 5.73 - /* Send the successful response. */ 5.74 - ctrl_if_send_response(&cmsg); 5.75 -} 5.76 - 5.77 -void usbif_disconnect_complete(usbif_priv_t *up) 5.78 -{ 5.79 - INIT_WORK(&up->work, __usbif_disconnect_complete, (void *)up); 5.80 - schedule_work(&up->work); 5.81 -} 5.82 - 5.83 -void usbif_create(usbif_be_create_t *create) 5.84 -{ 5.85 - domid_t domid = create->domid; 5.86 - usbif_priv_t **pup, *up; 5.87 - 5.88 - if ( (up = kmem_cache_alloc(usbif_priv_cachep, GFP_KERNEL)) == NULL ) 5.89 - { 5.90 - DPRINTK("Could not create usbif: out of memory\n"); 5.91 - create->status = USBIF_BE_STATUS_OUT_OF_MEMORY; 5.92 - return; 5.93 - } 5.94 - 5.95 - memset(up, 0, sizeof(*up)); 5.96 - up->domid = domid; 5.97 - up->status = DISCONNECTED; 5.98 - spin_lock_init(&up->usb_ring_lock); 5.99 - atomic_set(&up->refcnt, 0); 5.100 - 5.101 - pup = &usbif_priv_hash[USBIF_HASH(domid)]; 5.102 - while ( *pup != NULL ) 5.103 - { 5.104 - if ( (*pup)->domid == domid ) 5.105 - { 5.106 - create->status = USBIF_BE_STATUS_INTERFACE_EXISTS; 5.107 - kmem_cache_free(usbif_priv_cachep, up); 5.108 - return; 5.109 - } 5.110 - pup = &(*pup)->hash_next; 5.111 - } 5.112 - 5.113 - up->hash_next = *pup; 5.114 - *pup = up; 5.115 - 5.116 - create->status = USBIF_BE_STATUS_OKAY; 5.117 -} 5.118 - 5.119 -void usbif_destroy(usbif_be_destroy_t *destroy) 5.120 -{ 5.121 - domid_t domid = destroy->domid; 5.122 - usbif_priv_t **pup, *up; 5.123 - 5.124 - pup = &usbif_priv_hash[USBIF_HASH(domid)]; 5.125 - while ( (up = *pup) != NULL ) 5.126 - { 5.127 - if ( up->domid == domid ) 5.128 - { 5.129 - if ( up->status != DISCONNECTED ) 5.130 - goto still_connected; 5.131 - goto destroy; 5.132 - } 5.133 - pup = &up->hash_next; 5.134 - } 5.135 - 5.136 - destroy->status = USBIF_BE_STATUS_INTERFACE_NOT_FOUND; 5.137 - return; 5.138 - 5.139 - still_connected: 5.140 - destroy->status = USBIF_BE_STATUS_INTERFACE_CONNECTED; 5.141 - return; 5.142 - 5.143 - destroy: 5.144 - *pup = up->hash_next; 5.145 - usbif_release_ports(up); 5.146 - kmem_cache_free(usbif_priv_cachep, up); 5.147 - destroy->status = USBIF_BE_STATUS_OKAY; 5.148 -} 5.149 - 5.150 -void usbif_connect(usbif_be_connect_t *connect) 5.151 -{ 5.152 - domid_t domid = connect->domid; 5.153 - unsigned int evtchn = connect->evtchn; 5.154 - unsigned long shmem_frame = connect->shmem_frame; 5.155 - struct vm_struct *vma; 5.156 - pgprot_t prot; 5.157 - int error; 5.158 - usbif_priv_t *up; 5.159 - 5.160 - up = usbif_find(domid); 5.161 - if ( unlikely(up == NULL) ) 5.162 - { 5.163 - DPRINTK("usbif_connect attempted for non-existent usbif (%u)\n", 5.164 - connect->domid); 5.165 - connect->status = USBIF_BE_STATUS_INTERFACE_NOT_FOUND; 5.166 - return; 5.167 - } 5.168 - 5.169 - if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL ) 5.170 - { 5.171 - connect->status = USBIF_BE_STATUS_OUT_OF_MEMORY; 5.172 - return; 5.173 - } 5.174 - 5.175 - prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED); 5.176 - error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr), 5.177 - shmem_frame<<PAGE_SHIFT, PAGE_SIZE, 5.178 - prot, domid); 5.179 - if ( error != 0 ) 5.180 - { 5.181 - if ( error == -ENOMEM ) 5.182 - connect->status = USBIF_BE_STATUS_OUT_OF_MEMORY; 5.183 - else if ( error == -EFAULT ) 5.184 - connect->status = USBIF_BE_STATUS_MAPPING_ERROR; 5.185 - else 5.186 - connect->status = USBIF_BE_STATUS_ERROR; 5.187 - vfree(vma->addr); 5.188 - return; 5.189 - } 5.190 - 5.191 - if ( up->status != DISCONNECTED ) 5.192 - { 5.193 - connect->status = USBIF_BE_STATUS_INTERFACE_CONNECTED; 5.194 - vfree(vma->addr); 5.195 - return; 5.196 - } 5.197 - 5.198 - up->evtchn = evtchn; 5.199 - up->irq = bind_evtchn_to_irq(evtchn); 5.200 - up->shmem_frame = shmem_frame; 5.201 - up->usb_ring_base = (usbif_t *)vma->addr; 5.202 - up->status = CONNECTED; 5.203 - usbif_get(up); 5.204 - 5.205 - request_irq(up->irq, usbif_be_int, 0, "usbif-backend", up); 5.206 - 5.207 - connect->status = USBIF_BE_STATUS_OKAY; 5.208 -} 5.209 - 5.210 -/* Remove URBs for this interface before destroying it. */ 5.211 -void usbif_deschedule(usbif_priv_t *up) 5.212 -{ 5.213 - remove_from_usbif_list(up); 5.214 -} 5.215 - 5.216 -int usbif_disconnect(usbif_be_disconnect_t *disconnect, u8 rsp_id) 5.217 -{ 5.218 - domid_t domid = disconnect->domid; 5.219 - usbif_priv_t *up; 5.220 - 5.221 - up = usbif_find(domid); 5.222 - if ( unlikely(up == NULL) ) 5.223 - { 5.224 - DPRINTK("usbif_disconnect attempted for non-existent usbif" 5.225 - " (%u)\n", disconnect->domid); 5.226 - disconnect->status = USBIF_BE_STATUS_INTERFACE_NOT_FOUND; 5.227 - return 1; /* Caller will send response error message. */ 5.228 - } 5.229 - 5.230 - if ( up->status == CONNECTED ) 5.231 - { 5.232 - up->status = DISCONNECTING; 5.233 - up->disconnect_rspid = rsp_id; 5.234 - wmb(); /* Let other CPUs see the status change. */ 5.235 - free_irq(up->irq, up); 5.236 - usbif_deschedule(up); 5.237 - usbif_put(up); 5.238 - return 0; /* Caller should not send response message. */ 5.239 - } 5.240 - 5.241 - disconnect->status = USBIF_BE_STATUS_OKAY; 5.242 - return 1; 5.243 -} 5.244 - 5.245 -void __init usbif_interface_init(void) 5.246 -{ 5.247 - usbif_priv_cachep = kmem_cache_create("usbif_priv_cache", 5.248 - sizeof(usbif_priv_t), 5.249 - 0, 0, NULL, NULL); 5.250 - memset(usbif_priv_hash, 0, sizeof(usbif_priv_hash)); 5.251 -}
6.1 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/main.c Fri Jan 28 07:59:39 2005 +0000 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,1011 +0,0 @@ 6.4 -/****************************************************************************** 6.5 - * arch/xen/drivers/usbif/backend/main.c 6.6 - * 6.7 - * Backend for the Xen virtual USB driver - provides an abstraction of a 6.8 - * USB host controller to the corresponding frontend driver. 6.9 - * 6.10 - * by Mark Williamson, Copyright (c) 2004 Intel Research Cambridge 6.11 - * 6.12 - * Based on arch/xen/drivers/blkif/backend/main.c 6.13 - * Copyright (c) 2003-2004, Keir Fraser & Steve Hand 6.14 - */ 6.15 - 6.16 -#include "common.h" 6.17 - 6.18 - 6.19 -#include <linux/list.h> 6.20 -#include <linux/usb.h> 6.21 -#include <linux/spinlock.h> 6.22 -#include <linux/module.h> 6.23 -#include <linux/tqueue.h> 6.24 - 6.25 -/* 6.26 - * This is rather arbitrary. 6.27 - */ 6.28 -#define MAX_PENDING_REQS 4 6.29 -#define BATCH_PER_DOMAIN 1 6.30 - 6.31 -static unsigned long mmap_vstart; 6.32 - 6.33 -/* Needs to be sufficiently large that we can map the (large) buffers 6.34 - * the USB mass storage driver wants. */ 6.35 -#define MMAP_PAGES_PER_REQUEST \ 6.36 - (128) 6.37 -#define MMAP_PAGES \ 6.38 - (MAX_PENDING_REQS * MMAP_PAGES_PER_REQUEST) 6.39 - 6.40 -#define MMAP_VADDR(_req,_seg) \ 6.41 - (mmap_vstart + \ 6.42 - ((_req) * MMAP_PAGES_PER_REQUEST * PAGE_SIZE) + \ 6.43 - ((_seg) * PAGE_SIZE)) 6.44 - 6.45 -#define MIN(x,y) ( ( x < y ) ? x : y ) 6.46 - 6.47 -static spinlock_t owned_ports_lock; 6.48 -LIST_HEAD(owned_ports); 6.49 - 6.50 -/* A list of these structures is used to track ownership of physical USB 6.51 - * ports. */ 6.52 -typedef struct 6.53 -{ 6.54 - usbif_priv_t *usbif_priv; 6.55 - char path[16]; 6.56 - int guest_port; 6.57 - int enabled; 6.58 - struct list_head list; 6.59 - unsigned long guest_address; /* The USB device address that has been 6.60 - * assigned by the guest. */ 6.61 - int dev_present; /* Is there a device present? */ 6.62 - struct usb_device * dev; 6.63 - unsigned long ifaces; /* What interfaces are present on this device? */ 6.64 -} owned_port_t; 6.65 - 6.66 - 6.67 -/* 6.68 - * Each outstanding request that we've passed to the lower device layers has a 6.69 - * 'pending_req' allocated to it. The request is complete, the specified 6.70 - * domain has a response queued for it, with the saved 'id' passed back. 6.71 - */ 6.72 -typedef struct { 6.73 - usbif_priv_t *usbif_priv; 6.74 - usbif_iso_t *iso_sched; 6.75 - unsigned long id; 6.76 - int nr_pages; 6.77 - unsigned short operation; 6.78 - int status; 6.79 -} pending_req_t; 6.80 - 6.81 -/* 6.82 - * We can't allocate pending_req's in order, since they may complete out of 6.83 - * order. We therefore maintain an allocation ring. This ring also indicates 6.84 - * when enough work has been passed down -- at that point the allocation ring 6.85 - * will be empty. 6.86 - */ 6.87 -static pending_req_t pending_reqs[MAX_PENDING_REQS]; 6.88 -static unsigned char pending_ring[MAX_PENDING_REQS]; 6.89 -static spinlock_t pend_prod_lock = SPIN_LOCK_UNLOCKED; 6.90 - 6.91 -/* NB. We use a different index type to differentiate from shared blk rings. */ 6.92 -typedef unsigned int PEND_RING_IDX; 6.93 -#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1)) 6.94 -static PEND_RING_IDX pending_prod, pending_cons; 6.95 -#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons) 6.96 - 6.97 -static int do_usb_io_op(usbif_priv_t *usbif, int max_to_do); 6.98 -static void make_response(usbif_priv_t *usbif, unsigned long id, 6.99 - unsigned short op, int st, int inband, 6.100 - unsigned long actual_length); 6.101 -static void dispatch_usb_probe(usbif_priv_t *up, unsigned long id, unsigned long port); 6.102 -static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req); 6.103 -static void dispatch_usb_reset(usbif_priv_t *up, unsigned long portid); 6.104 -static owned_port_t *usbif_find_port(char *); 6.105 - 6.106 - 6.107 -void dump_port(owned_port_t *p) 6.108 -{ 6.109 - printk("owned_port_t @ %p\n", p); 6.110 - printk(" usbif_priv @ %p\n", p->usbif_priv); 6.111 - printk(" path: %s\n", p->path); 6.112 - printk(" guest_port: %d\n", p->guest_port); 6.113 - printk(" guest_address: %ld\n", p->guest_address); 6.114 - printk(" dev_present: %d\n", p->dev_present); 6.115 - printk(" dev @ %p\n", p->dev); 6.116 - printk(" ifaces: 0x%lx\n", p->ifaces); 6.117 -} 6.118 - 6.119 - 6.120 - 6.121 -static void fast_flush_area(int idx, int nr_pages) 6.122 -{ 6.123 - multicall_entry_t mcl[MMAP_PAGES_PER_REQUEST]; 6.124 - int i; 6.125 - 6.126 - for ( i = 0; i < nr_pages; i++ ) 6.127 - { 6.128 - mcl[i].op = __HYPERVISOR_update_va_mapping; 6.129 - mcl[i].args[0] = MMAP_VADDR(idx, i) >> PAGE_SHIFT; 6.130 - mcl[i].args[1] = 0; 6.131 - mcl[i].args[2] = 0; 6.132 - } 6.133 - 6.134 - mcl[nr_pages-1].args[2] = UVMF_FLUSH_TLB; 6.135 - if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) ) 6.136 - BUG(); 6.137 -} 6.138 - 6.139 - 6.140 -/****************************************************************** 6.141 - * USB INTERFACE SCHEDULER LIST MAINTENANCE 6.142 - */ 6.143 - 6.144 -static struct list_head usbio_schedule_list; 6.145 -static spinlock_t usbio_schedule_list_lock; 6.146 - 6.147 -static int __on_usbif_list(usbif_priv_t *up) 6.148 -{ 6.149 - return up->usbif_list.next != NULL; 6.150 -} 6.151 - 6.152 -void remove_from_usbif_list(usbif_priv_t *up) 6.153 -{ 6.154 - unsigned long flags; 6.155 - if ( !__on_usbif_list(up) ) return; 6.156 - spin_lock_irqsave(&usbio_schedule_list_lock, flags); 6.157 - if ( __on_usbif_list(up) ) 6.158 - { 6.159 - list_del(&up->usbif_list); 6.160 - up->usbif_list.next = NULL; 6.161 - usbif_put(up); 6.162 - } 6.163 - spin_unlock_irqrestore(&usbio_schedule_list_lock, flags); 6.164 -} 6.165 - 6.166 -static void add_to_usbif_list_tail(usbif_priv_t *up) 6.167 -{ 6.168 - unsigned long flags; 6.169 - if ( __on_usbif_list(up) ) return; 6.170 - spin_lock_irqsave(&usbio_schedule_list_lock, flags); 6.171 - if ( !__on_usbif_list(up) && (up->status == CONNECTED) ) 6.172 - { 6.173 - list_add_tail(&up->usbif_list, &usbio_schedule_list); 6.174 - usbif_get(up); 6.175 - } 6.176 - spin_unlock_irqrestore(&usbio_schedule_list_lock, flags); 6.177 -} 6.178 - 6.179 - 6.180 -/****************************************************************** 6.181 - * COMPLETION CALLBACK -- Called as urb->complete() 6.182 - */ 6.183 - 6.184 -static void maybe_trigger_usbio_schedule(void); 6.185 - 6.186 -static void __end_usb_io_op(struct urb *purb) 6.187 -{ 6.188 - unsigned long flags; 6.189 - pending_req_t *pending_req; 6.190 - int pending_idx; 6.191 - 6.192 - pending_req = purb->context; 6.193 - 6.194 -/* printk("Completed for id = %p to 0x%lx - 0x%lx\n", pending_req->id, */ 6.195 -/* virt_to_machine(purb->transfer_buffer), */ 6.196 -/* virt_to_machine(purb->transfer_buffer) */ 6.197 -/* + pending_req->nr_pages * PAGE_SIZE); */ 6.198 - 6.199 - pending_idx = pending_req - pending_reqs; 6.200 - 6.201 - ASSERT(purb->actual_length <= purb->transfer_buffer_length); 6.202 - ASSERT(purb->actual_length <= pending_req->nr_pages * PAGE_SIZE); 6.203 - 6.204 - /* An error fails the entire request. */ 6.205 - if ( purb->status ) 6.206 - { 6.207 - printk("URB @ %p failed. Status %d\n", purb, purb->status); 6.208 - } 6.209 - 6.210 - if ( usb_pipetype(purb->pipe) == 0 ) 6.211 - { 6.212 - int i; 6.213 - usbif_iso_t *sched = (usbif_iso_t *)MMAP_VADDR(pending_idx, pending_req->nr_pages - 1); 6.214 - 6.215 - ASSERT(sched == pending_req->sched); 6.216 - 6.217 - // printk("writing back schedule at %p\n", sched); 6.218 - 6.219 - /* If we're dealing with an iso pipe, we need to copy back the schedule. */ 6.220 - for ( i = 0; i < purb->number_of_packets; i++ ) 6.221 - { 6.222 - sched[i].length = purb->iso_frame_desc[i].actual_length; 6.223 - ASSERT(sched[i].buffer_offset == 6.224 - purb->iso_frame_desc[i].offset); 6.225 - sched[i].status = purb->iso_frame_desc[i].status; 6.226 - } 6.227 - } 6.228 - 6.229 - // printk("Flushing %d pages\n", pending_req->nr_pages); 6.230 - fast_flush_area(pending_req - pending_reqs, pending_req->nr_pages); 6.231 - 6.232 - kfree(purb->setup_packet); 6.233 - 6.234 - spin_lock_irqsave(&pending_req->usbif_priv->usb_ring_lock, flags); 6.235 - make_response(pending_req->usbif_priv, pending_req->id, 6.236 - pending_req->operation, pending_req->status, 0, purb->actual_length); 6.237 - spin_unlock_irqrestore(&pending_req->usbif_priv->usb_ring_lock, flags); 6.238 - usbif_put(pending_req->usbif_priv); 6.239 - 6.240 - usb_free_urb(purb); 6.241 - 6.242 - /* Free the pending request. */ 6.243 - spin_lock_irqsave(&pend_prod_lock, flags); 6.244 - pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; 6.245 - spin_unlock_irqrestore(&pend_prod_lock, flags); 6.246 - 6.247 - rmb(); 6.248 - 6.249 - /* Check for anything still waiting in the rings, having freed a request... */ 6.250 - maybe_trigger_usbio_schedule(); 6.251 -} 6.252 - 6.253 -/****************************************************************** 6.254 - * SCHEDULER FUNCTIONS 6.255 - */ 6.256 - 6.257 -static DECLARE_WAIT_QUEUE_HEAD(usbio_schedule_wait); 6.258 - 6.259 -static int usbio_schedule(void *arg) 6.260 -{ 6.261 - DECLARE_WAITQUEUE(wq, current); 6.262 - 6.263 - usbif_priv_t *up; 6.264 - struct list_head *ent; 6.265 - 6.266 - daemonize(); 6.267 - 6.268 - for ( ; ; ) 6.269 - { 6.270 - /* Wait for work to do. */ 6.271 - add_wait_queue(&usbio_schedule_wait, &wq); 6.272 - set_current_state(TASK_INTERRUPTIBLE); 6.273 - if ( (NR_PENDING_REQS == MAX_PENDING_REQS) || 6.274 - list_empty(&usbio_schedule_list) ) 6.275 - schedule(); 6.276 - __set_current_state(TASK_RUNNING); 6.277 - remove_wait_queue(&usbio_schedule_wait, &wq); 6.278 - 6.279 - /* Queue up a batch of requests. */ 6.280 - while ( (NR_PENDING_REQS < MAX_PENDING_REQS) && 6.281 - !list_empty(&usbio_schedule_list) ) 6.282 - { 6.283 - ent = usbio_schedule_list.next; 6.284 - up = list_entry(ent, usbif_priv_t, usbif_list); 6.285 - usbif_get(up); 6.286 - remove_from_usbif_list(up); 6.287 - if ( do_usb_io_op(up, BATCH_PER_DOMAIN) ) 6.288 - add_to_usbif_list_tail(up); 6.289 - usbif_put(up); 6.290 - } 6.291 - } 6.292 -} 6.293 - 6.294 -static void maybe_trigger_usbio_schedule(void) 6.295 -{ 6.296 - /* 6.297 - * Needed so that two processes, who together make the following predicate 6.298 - * true, don't both read stale values and evaluate the predicate 6.299 - * incorrectly. Incredibly unlikely to stall the scheduler on x86, but... 6.300 - */ 6.301 - smp_mb(); 6.302 - 6.303 - if ( !list_empty(&usbio_schedule_list) ) 6.304 - wake_up(&usbio_schedule_wait); 6.305 -} 6.306 - 6.307 - 6.308 -/****************************************************************************** 6.309 - * NOTIFICATION FROM GUEST OS. 6.310 - */ 6.311 - 6.312 -irqreturn_t usbif_be_int(int irq, void *dev_id, struct pt_regs *regs) 6.313 -{ 6.314 - usbif_priv_t *up = dev_id; 6.315 - 6.316 - smp_mb(); 6.317 - 6.318 - add_to_usbif_list_tail(up); 6.319 - 6.320 - /* Will in fact /always/ trigger an io schedule in this case. */ 6.321 - maybe_trigger_usbio_schedule(); 6.322 - 6.323 - return IRQ_HANDLED; 6.324 -} 6.325 - 6.326 - 6.327 - 6.328 -/****************************************************************** 6.329 - * DOWNWARD CALLS -- These interface with the usb-device layer proper. 6.330 - */ 6.331 - 6.332 -static int do_usb_io_op(usbif_priv_t *up, int max_to_do) 6.333 -{ 6.334 - usbif_t *usb_ring = up->usb_ring_base; 6.335 - usbif_request_t *req; 6.336 - USBIF_RING_IDX i, rp; 6.337 - int more_to_do = 0; 6.338 - unsigned long flags; 6.339 - 6.340 - spin_lock_irqsave(&up->usb_ring_lock, flags); 6.341 - 6.342 - rp = usb_ring->req_prod; 6.343 - rmb(); /* Ensure we see queued requests up to 'rp'. */ 6.344 - 6.345 - /* Take items off the comms ring, taking care not to overflow. */ 6.346 - for ( i = up->usb_req_cons; 6.347 - (i != rp) && ((i-up->usb_resp_prod) != USBIF_RING_SIZE); 6.348 - i++ ) 6.349 - { 6.350 - if ( (max_to_do-- == 0) || (NR_PENDING_REQS == MAX_PENDING_REQS) ) 6.351 - { 6.352 - more_to_do = 1; 6.353 - break; 6.354 - } 6.355 - 6.356 - req = &usb_ring->ring[MASK_USBIF_IDX(i)].req; 6.357 - 6.358 - switch ( req->operation ) 6.359 - { 6.360 - case USBIF_OP_PROBE: 6.361 - dispatch_usb_probe(up, req->id, req->port); 6.362 - break; 6.363 - 6.364 - case USBIF_OP_IO: 6.365 - /* Assemble an appropriate URB. */ 6.366 - dispatch_usb_io(up, req); 6.367 - break; 6.368 - 6.369 - case USBIF_OP_RESET: 6.370 - dispatch_usb_reset(up, req->port); 6.371 - break; 6.372 - 6.373 - default: 6.374 - DPRINTK("error: unknown USB io operation [%d]\n", 6.375 - req->operation); 6.376 - make_response(up, req->id, req->operation, -EINVAL, 0, 0); 6.377 - break; 6.378 - } 6.379 - } 6.380 - 6.381 - up->usb_req_cons = i; 6.382 - 6.383 - spin_unlock_irqrestore(&up->usb_ring_lock, flags); 6.384 - 6.385 - return more_to_do; 6.386 -} 6.387 - 6.388 -static owned_port_t *find_guest_port(usbif_priv_t *up, int port) 6.389 -{ 6.390 - unsigned long flags; 6.391 - struct list_head *l; 6.392 - 6.393 - spin_lock_irqsave(&owned_ports_lock, flags); 6.394 - list_for_each(l, &owned_ports) 6.395 - { 6.396 - owned_port_t *p = list_entry(l, owned_port_t, list); 6.397 - if(p->usbif_priv == up && p->guest_port == port) 6.398 - { 6.399 - spin_unlock_irqrestore(&owned_ports_lock, flags); 6.400 - return p; 6.401 - } 6.402 - } 6.403 - spin_unlock_irqrestore(&owned_ports_lock, flags); 6.404 - 6.405 - return NULL; 6.406 -} 6.407 - 6.408 -static void dispatch_usb_reset(usbif_priv_t *up, unsigned long portid) 6.409 -{ 6.410 - owned_port_t *port = find_guest_port(up, portid); 6.411 - int ret = 0; 6.412 - 6.413 - 6.414 - /* Allowing the guest to actually reset the device causes more problems 6.415 - * than it's worth. We just fake it out in software but we will do a real 6.416 - * reset when the interface is destroyed. */ 6.417 - 6.418 -#if 0 6.419 - printk("Reset port %d\n", portid); 6.420 - 6.421 - dump_port(port); 6.422 -#endif 6.423 - 6.424 - port->guest_address = 0; 6.425 - /* If there's an attached device then the port is now enabled. */ 6.426 - if ( port->dev_present ) 6.427 - port->enabled = 1; 6.428 - else 6.429 - port->enabled = 0; 6.430 - 6.431 - make_response(up, 0, USBIF_OP_RESET, ret, 0, 0); 6.432 -} 6.433 - 6.434 -static void dispatch_usb_probe(usbif_priv_t *up, unsigned long id, unsigned long portid) 6.435 -{ 6.436 - owned_port_t *port = find_guest_port(up, portid); 6.437 - int ret; 6.438 - 6.439 - if ( port != NULL ) 6.440 - ret = port->dev_present; 6.441 - else 6.442 - { 6.443 - ret = -EINVAL; 6.444 - printk("dispatch_usb_probe(): invalid port probe request (port %ld)\n", 6.445 - portid); 6.446 - } 6.447 - 6.448 - /* Probe result is sent back in-band. Probes don't have an associated id 6.449 - * right now... */ 6.450 - make_response(up, id, USBIF_OP_PROBE, ret, portid, 0); 6.451 -} 6.452 - 6.453 -owned_port_t *find_port_for_request(usbif_priv_t *up, usbif_request_t *req); 6.454 - 6.455 -static void dump_request(usbif_request_t *req) 6.456 -{ 6.457 - printk("id = 0x%lx\n", req->id); 6.458 - 6.459 - printk("devnum %d\n", req->devnum); 6.460 - printk("endpoint 0x%x\n", req->endpoint); 6.461 - printk("direction %d\n", req->direction); 6.462 - printk("speed %d\n", req->speed); 6.463 - printk("pipe_type 0x%x\n", req->pipe_type); 6.464 - printk("transfer_buffer 0x%lx\n", req->transfer_buffer); 6.465 - printk("length 0x%lx\n", req->length); 6.466 - printk("transfer_flags 0x%lx\n", req->transfer_flags); 6.467 - printk("setup = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", 6.468 - req->setup[0], req->setup[1], req->setup[2], req->setup[3], 6.469 - req->setup[4], req->setup[5], req->setup[6], req->setup[7]); 6.470 - printk("iso_schedule = 0x%lx\n", req->iso_schedule); 6.471 - printk("num_iso %ld\n", req->num_iso); 6.472 -} 6.473 - 6.474 -void dump_urb(struct urb *urb) 6.475 -{ 6.476 - printk("dumping urb @ %p\n", urb); 6.477 - 6.478 -#define DUMP_URB_FIELD(name, format) printk(" " # name " " format "\n", urb-> name) 6.479 - 6.480 - DUMP_URB_FIELD(pipe, "0x%x"); 6.481 - DUMP_URB_FIELD(status, "%d"); 6.482 - DUMP_URB_FIELD(transfer_flags, "0x%x"); 6.483 - DUMP_URB_FIELD(transfer_buffer, "%p"); 6.484 - DUMP_URB_FIELD(transfer_buffer_length, "%d"); 6.485 - DUMP_URB_FIELD(actual_length, "%d"); 6.486 -} 6.487 - 6.488 - 6.489 -static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req) 6.490 -{ 6.491 - unsigned long buffer_mach; 6.492 - int i = 0, offset = 0, 6.493 - pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; 6.494 - pending_req_t *pending_req; 6.495 - unsigned long remap_prot; 6.496 - multicall_entry_t mcl[MMAP_PAGES_PER_REQUEST]; 6.497 - struct urb *purb = NULL; 6.498 - owned_port_t *port; 6.499 - unsigned char *setup; 6.500 - 6.501 -// dump_request(req); 6.502 - 6.503 - if ( NR_PENDING_REQS == MAX_PENDING_REQS ) 6.504 - { 6.505 - printk("usbback: Max requests already queued. Now giving up!\n"); 6.506 - 6.507 - return; 6.508 - } 6.509 - 6.510 - port = find_port_for_request(up, req); 6.511 - 6.512 - if(port == NULL) 6.513 - { 6.514 - printk("No such device! (%d)\n", req->devnum); 6.515 - dump_request(req); 6.516 - 6.517 - make_response(up, req->id, req->operation, -ENODEV, 0, 0); 6.518 - return; 6.519 - } 6.520 - 6.521 - setup = kmalloc(8, GFP_ATOMIC | GFP_NOIO); 6.522 - 6.523 - if ( setup == NULL ) 6.524 - goto no_mem; 6.525 - 6.526 - /* Copy request out for safety. */ 6.527 - memcpy(setup, req->setup, 8); 6.528 - 6.529 - if( setup[0] == 0x0 && setup[1] == 0x5) 6.530 - { 6.531 - /* To virtualise the USB address space, we need to intercept 6.532 - * set_address messages and emulate. From the USB specification: 6.533 - * bmRequestType = 0x0; 6.534 - * Brequest = SET_ADDRESS (i.e. 0x5) 6.535 - * wValue = device address 6.536 - * wIndex = 0 6.537 - * wLength = 0 6.538 - * data = None 6.539 - */ 6.540 - /* Store into the guest transfer buffer using cpu_to_le16 */ 6.541 - port->guest_address = le16_to_cpu(*(u16 *)(setup + 2)); 6.542 - /* Make a successful response. That was easy! */ 6.543 - 6.544 - make_response(up, req->id, req->operation, 0, 0, 0); 6.545 - 6.546 - kfree(setup); 6.547 - return; 6.548 - } 6.549 - else if ( setup[0] == 0x0 && setup[1] == 0x9 ) 6.550 - { 6.551 - /* The host kernel needs to know what device configuration is in use 6.552 - * because various error checks get confused otherwise. We just do 6.553 - * configuration settings here, under controlled conditions. 6.554 - */ 6.555 - usb_set_configuration(port->dev, setup[2]); 6.556 - 6.557 - make_response(up, req->id, req->operation, 0, 0, 0); 6.558 - 6.559 - kfree(setup); 6.560 - return; 6.561 - } 6.562 - 6.563 - else if ( setup[0] == 0x1 && setup[1] == 0xB ) 6.564 - { 6.565 - /* The host kernel needs to know what device interface is in use 6.566 - * because various error checks get confused otherwise. We just do 6.567 - * configuration settings here, under controlled conditions. 6.568 - */ 6.569 - usb_set_interface(port->dev, (setup[4] | setup[5] << 8), 6.570 - (setup[2] | setup[3] << 8) ); 6.571 - 6.572 - make_response(up, req->id, req->operation, 0, 0, 0); 6.573 - 6.574 - kfree(setup); 6.575 - return; 6.576 - } 6.577 - 6.578 - if ( ( req->transfer_buffer - (req->transfer_buffer & PAGE_MASK) 6.579 - + req->length ) 6.580 - > MMAP_PAGES_PER_REQUEST * PAGE_SIZE ) 6.581 - { 6.582 - printk("usbback: request of %d bytes too large, failing it\n", req->length); 6.583 - make_response(up, req->id, req->operation, -EINVAL, 0, 0); 6.584 - kfree(setup); 6.585 - return; 6.586 - } 6.587 - 6.588 - buffer_mach = req->transfer_buffer; 6.589 - 6.590 - if( buffer_mach == 0 ) 6.591 - goto no_remap; 6.592 - 6.593 - ASSERT((req->length >> PAGE_SHIFT) <= MMAP_PAGES_PER_REQUEST); 6.594 - ASSERT(buffer_mach); 6.595 - 6.596 - /* Always map writeable for now. */ 6.597 - remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_RW; 6.598 - 6.599 - for ( i = 0, offset = 0; offset < req->length; 6.600 - i++, offset += PAGE_SIZE ) 6.601 - { 6.602 - // printk("length = %d, offset = %d, looping!\n", req->length, offset); 6.603 - 6.604 - mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain; 6.605 - mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT; 6.606 - mcl[i].args[1] = ((buffer_mach & PAGE_MASK) + offset) | remap_prot; 6.607 - mcl[i].args[2] = 0; 6.608 - mcl[i].args[3] = up->domid; 6.609 - 6.610 - phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] = 6.611 - FOREIGN_FRAME((buffer_mach + offset) >> PAGE_SHIFT); 6.612 - // printk("i = %d\n", i); 6.613 - 6.614 - ASSERT(virt_to_machine(MMAP_VADDR(pending_idx, i)) 6.615 - == buffer_mach + i << PAGE_SHIFT); 6.616 - } 6.617 - 6.618 - if ( req->pipe_type == 0 && req->num_iso > 0 ) /* Maybe schedule ISO... */ 6.619 - { 6.620 - // printk("for iso, i = %d\n", i); 6.621 - /* Map in ISO schedule, if necessary. */ 6.622 - mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain; 6.623 - mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT; 6.624 - mcl[i].args[1] = (req->iso_schedule & PAGE_MASK) | remap_prot; 6.625 - mcl[i].args[2] = 0; 6.626 - mcl[i].args[3] = up->domid; 6.627 - 6.628 - phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] = 6.629 - FOREIGN_FRAME(req->iso_schedule >> PAGE_SHIFT); 6.630 - 6.631 - // printk("Mapped iso at %p\n", MMAP_VADDR(pending_idx, i)); 6.632 - i++; 6.633 - } 6.634 - 6.635 - // printk("Well we got this far!\n"); 6.636 - 6.637 - if ( unlikely(HYPERVISOR_multicall(mcl, i) != 0) ) 6.638 - BUG(); 6.639 - 6.640 - { 6.641 - int j; 6.642 - for ( j = 0; j < i; j++ ) 6.643 - { 6.644 - if ( unlikely(mcl[j].args[5] != 0) ) 6.645 - { 6.646 - printk("invalid buffer %d -- could not remap it\n", j); 6.647 - fast_flush_area(pending_idx, i); 6.648 - printk("sending invalid descriptor\n"); 6.649 - goto bad_descriptor; 6.650 - } 6.651 - } 6.652 - } 6.653 - 6.654 - no_remap: 6.655 - 6.656 - ASSERT(i <= MMAP_PAGES_PER_REQUEST); 6.657 - ASSERT(i * PAGE_SIZE >= req->length); 6.658 - 6.659 - /* We have to do this because some things might complete out of order. */ 6.660 - pending_req = &pending_reqs[pending_idx]; 6.661 - pending_req->usbif_priv= up; 6.662 - pending_req->id = req->id; 6.663 - pending_req->operation = req->operation; 6.664 - pending_req->nr_pages = i; 6.665 - 6.666 - 6.667 - 6.668 - pending_cons++; 6.669 - 6.670 - usbif_get(up); 6.671 - 6.672 - /* Fill out an actual request for the USB layer. */ 6.673 - purb = usb_alloc_urb(req->num_iso); 6.674 - 6.675 - if ( purb == NULL ) 6.676 - goto no_mem; 6.677 - 6.678 - purb->dev = port->dev; 6.679 - purb->context = pending_req; 6.680 - purb->transfer_buffer = (void *)MMAP_VADDR(pending_idx, 0) + (buffer_mach & ~PAGE_MASK); 6.681 - if(buffer_mach == 0) 6.682 - purb->transfer_buffer = NULL; 6.683 - purb->complete = __end_usb_io_op; 6.684 - purb->transfer_buffer_length = req->length; 6.685 - purb->transfer_flags = req->transfer_flags; 6.686 - 6.687 -/* if ( req->transfer_flags != 0 ) */ 6.688 -/* dump_request(req); */ 6.689 - 6.690 - purb->pipe = 0; 6.691 - purb->pipe |= req->direction << 7; 6.692 - purb->pipe |= port->dev->devnum << 8; 6.693 - purb->pipe |= req->speed << 26; 6.694 - purb->pipe |= req->pipe_type << 30; 6.695 - purb->pipe |= req->endpoint << 15; 6.696 - 6.697 - purb->number_of_packets = req->num_iso; 6.698 - 6.699 - /* Make sure there's always some kind of timeout. */ 6.700 - purb->timeout = ( req->timeout > 0 ) ? (req->timeout * HZ) / 1000 6.701 - : 1000; 6.702 - 6.703 - purb->setup_packet = setup; 6.704 - 6.705 - if ( req->pipe_type == 0 ) /* ISO */ 6.706 - { 6.707 - int j; 6.708 - usbif_iso_t *iso_sched = (usbif_iso_t *)MMAP_VADDR(pending_idx, i - 1); 6.709 - 6.710 - // printk("Reading iso sched at %p\n", iso_sched); 6.711 - 6.712 - /* If we're dealing with an iso pipe, we need to copy in a schedule. */ 6.713 - for ( j = 0; j < req->num_iso; j++ ) 6.714 - { 6.715 - purb->iso_frame_desc[j].length = iso_sched[j].length; 6.716 - purb->iso_frame_desc[j].offset = iso_sched[j].buffer_offset; 6.717 - iso_sched[j].status = 0; 6.718 - } 6.719 - pending_req->iso_sched = iso_sched; 6.720 - } 6.721 - 6.722 - { 6.723 - int ret; 6.724 - ret = usb_submit_urb(purb); 6.725 - 6.726 - // dump_urb(purb); 6.727 - 6.728 - if ( ret != 0 ) 6.729 - goto bad_descriptor; /* XXX free pending here! */ 6.730 - } 6.731 - 6.732 - return; 6.733 - 6.734 - bad_descriptor: 6.735 - kfree ( setup ); 6.736 - if ( purb != NULL ) 6.737 - usb_free_urb(purb); 6.738 - make_response(up, req->id, req->operation, -EINVAL, 0, 0); 6.739 - return; 6.740 - 6.741 - no_mem: 6.742 - if ( setup != NULL ) 6.743 - kfree(setup); 6.744 - make_response(up, req->id, req->operation, -ENOMEM, 0, 0); 6.745 - return; 6.746 -} 6.747 - 6.748 - 6.749 - 6.750 -/****************************************************************** 6.751 - * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING 6.752 - */ 6.753 - 6.754 - 6.755 -static void make_response(usbif_priv_t *up, unsigned long id, 6.756 - unsigned short op, int st, int inband, 6.757 - unsigned long length) 6.758 -{ 6.759 - usbif_response_t *resp; 6.760 - unsigned long flags; 6.761 - 6.762 -#if 0 6.763 - printk("usbback: Sending response:\n"); 6.764 - printk(" id = 0x%x\n", id); 6.765 - printk(" op = %d\n", op); 6.766 - printk(" status = %d\n", st); 6.767 - printk(" data = %d\n", inband); 6.768 - printk(" length = %d\n", length); 6.769 -#endif 6.770 - 6.771 - /* Place on the response ring for the relevant domain. */ 6.772 - spin_lock_irqsave(&up->usb_ring_lock, flags); 6.773 - resp = &up->usb_ring_base-> 6.774 - ring[MASK_USBIF_IDX(up->usb_resp_prod)].resp; 6.775 - resp->id = id; 6.776 - resp->operation = op; 6.777 - resp->status = st; 6.778 - resp->data = inband; 6.779 - resp->length = length; 6.780 - wmb(); /* Ensure other side can see the response fields. */ 6.781 - up->usb_ring_base->resp_prod = ++up->usb_resp_prod; 6.782 - spin_unlock_irqrestore(&up->usb_ring_lock, flags); 6.783 - 6.784 - /* Kick the relevant domain. */ 6.785 - notify_via_evtchn(up->evtchn); 6.786 -} 6.787 - 6.788 -/** 6.789 - * usbif_claim_port - claim devices on a port on behalf of guest 6.790 - * 6.791 - * Once completed, this will ensure that any device attached to that 6.792 - * port is claimed by this driver for use by the guest. 6.793 - */ 6.794 -int usbif_claim_port(usbif_be_claim_port_t *msg) 6.795 -{ 6.796 - owned_port_t *o_p; 6.797 - 6.798 - /* Sanity... */ 6.799 - if ( usbif_find_port(msg->path) != NULL ) 6.800 - { 6.801 - printk("usbback: Attempted to claim USB port " 6.802 - "we already own!\n"); 6.803 - return -EINVAL; 6.804 - } 6.805 - 6.806 - spin_lock_irq(&owned_ports_lock); 6.807 - 6.808 - /* No need for a slab cache - this should be infrequent. */ 6.809 - o_p = kmalloc(sizeof(owned_port_t), GFP_KERNEL); 6.810 - 6.811 - o_p->enabled = 0; 6.812 - o_p->usbif_priv = usbif_find(msg->domid); 6.813 - o_p->guest_port = msg->usbif_port; 6.814 - o_p->dev_present = 0; 6.815 - o_p->guest_address = 0; /* Default address. */ 6.816 - 6.817 - strcpy(o_p->path, msg->path); 6.818 - 6.819 - list_add(&o_p->list, &owned_ports); 6.820 - 6.821 - printk("usbback: Claimed USB port (%s) for %d.%d\n", o_p->path, 6.822 - msg->domid, msg->usbif_port); 6.823 - 6.824 - spin_unlock_irq(&owned_ports_lock); 6.825 - 6.826 - /* Force a reprobe for unclaimed devices. */ 6.827 - usb_scan_devices(); 6.828 - 6.829 - return 0; 6.830 -} 6.831 - 6.832 -owned_port_t *find_port_for_request(usbif_priv_t *up, usbif_request_t *req) 6.833 -{ 6.834 - unsigned long flags; 6.835 - struct list_head *port; 6.836 - 6.837 - /* I'm assuming this is not called from IRQ context - correct? I think 6.838 - * it's probably only called in response to control messages or plug events 6.839 - * in the USB hub kernel thread, so should be OK. */ 6.840 - spin_lock_irqsave(&owned_ports_lock, flags); 6.841 - list_for_each(port, &owned_ports) 6.842 - { 6.843 - owned_port_t *p = list_entry(port, owned_port_t, list); 6.844 - if(p->usbif_priv == up && p->guest_address == req->devnum && p->enabled ) 6.845 - { 6.846 -#if 0 6.847 - printk("Found port for devnum %d\n", req->devnum); 6.848 - 6.849 - dump_port(p); 6.850 -#endif 6.851 - return p; 6.852 - } 6.853 - } 6.854 - spin_unlock_irqrestore(&owned_ports_lock, flags); 6.855 - 6.856 - return NULL; 6.857 -} 6.858 - 6.859 -owned_port_t *usbif_find_port(char *path) 6.860 -{ 6.861 - struct list_head *port; 6.862 - unsigned long flags; 6.863 - 6.864 - spin_lock_irqsave(&owned_ports_lock, flags); 6.865 - list_for_each(port, &owned_ports) 6.866 - { 6.867 - owned_port_t *p = list_entry(port, owned_port_t, list); 6.868 - if(!strcmp(path, p->path)) 6.869 - { 6.870 - spin_unlock_irqrestore(&owned_ports_lock, flags); 6.871 - return p; 6.872 - } 6.873 - } 6.874 - spin_unlock_irqrestore(&owned_ports_lock, flags); 6.875 - 6.876 - return NULL; 6.877 -} 6.878 - 6.879 - 6.880 -static void *probe(struct usb_device *dev, unsigned iface, 6.881 - const struct usb_device_id *id) 6.882 -{ 6.883 - owned_port_t *p; 6.884 - 6.885 - /* We don't care what the device is - if we own the port, we want it. We 6.886 - * don't deal with device-specifics in this driver, so we don't care what 6.887 - * the device actually is ;-) */ 6.888 - if ( ( p = usbif_find_port(dev->devpath) ) != NULL ) 6.889 - { 6.890 - printk("usbback: claimed device attached to owned port\n"); 6.891 - 6.892 - p->dev_present = 1; 6.893 - p->dev = dev; 6.894 - set_bit(iface, &p->ifaces); 6.895 - 6.896 - return p->usbif_priv; 6.897 - } 6.898 - else 6.899 - printk("usbback: hotplug for non-owned port (%s), ignoring\n", dev->devpath); 6.900 - 6.901 - 6.902 - return NULL; 6.903 -} 6.904 - 6.905 -static void disconnect(struct usb_device *dev, void *usbif) 6.906 -{ 6.907 - /* Note the device is removed so we can tell the guest when it probes. */ 6.908 - owned_port_t *port = usbif_find_port(dev->devpath); 6.909 - port->dev_present = 0; 6.910 - port->dev = NULL; 6.911 - port->ifaces = 0; 6.912 -} 6.913 - 6.914 - 6.915 -struct usb_driver driver = 6.916 -{ 6.917 - .owner = THIS_MODULE, 6.918 - .name = "Xen USB Backend", 6.919 - .probe = probe, 6.920 - .disconnect = disconnect, 6.921 - .id_table = NULL, 6.922 -}; 6.923 - 6.924 -/* __usbif_release_port - internal mechanics for releasing a port */ 6.925 -void __usbif_release_port(owned_port_t *p) 6.926 -{ 6.927 - int i; 6.928 - 6.929 - for ( i = 0; p->ifaces != 0; i++) 6.930 - if ( p->ifaces & 1 << i ) 6.931 - { 6.932 - usb_driver_release_interface(&driver, usb_ifnum_to_if(p->dev, i)); 6.933 - clear_bit(i, &p->ifaces); 6.934 - } 6.935 - list_del(&p->list); 6.936 - 6.937 - /* Reset the real device. We don't simulate disconnect / probe for other 6.938 - * drivers in this kernel because we assume the device is completely under 6.939 - * the control of ourselves (i.e. the guest!). This should ensure that the 6.940 - * device is in a sane state for the next customer ;-) */ 6.941 -/* if ( p->dev != NULL) */ 6.942 -/* usb_reset_device(p->dev); */ 6.943 - 6.944 - kfree(p); 6.945 -} 6.946 - 6.947 - 6.948 -/** 6.949 - * usbif_release_port - stop claiming devices on a port on behalf of guest 6.950 - */ 6.951 -void usbif_release_port(usbif_be_release_port_t *msg) 6.952 -{ 6.953 - owned_port_t *p; 6.954 - 6.955 - spin_lock_irq(&owned_ports_lock); 6.956 - p = usbif_find_port(msg->path); 6.957 - __usbif_release_port(p); 6.958 - spin_unlock_irq(&owned_ports_lock); 6.959 -} 6.960 - 6.961 -void usbif_release_ports(usbif_priv_t *up) 6.962 -{ 6.963 - struct list_head *port, *tmp; 6.964 - unsigned long flags; 6.965 - 6.966 - spin_lock_irqsave(&owned_ports_lock, flags); 6.967 - list_for_each_safe(port, tmp, &owned_ports) 6.968 - { 6.969 - owned_port_t *p = list_entry(port, owned_port_t, list); 6.970 - if ( p->usbif_priv == up ) 6.971 - __usbif_release_port(p); 6.972 - } 6.973 - spin_unlock_irqrestore(&owned_ports_lock, flags); 6.974 -} 6.975 - 6.976 -static int __init usbif_init(void) 6.977 -{ 6.978 - int i; 6.979 - 6.980 - if ( !(xen_start_info.flags & SIF_INITDOMAIN) && 6.981 - !(xen_start_info.flags & SIF_USB_BE_DOMAIN) ) 6.982 - return 0; 6.983 - 6.984 - INIT_LIST_HEAD(&owned_ports); 6.985 - 6.986 - usb_register(&driver); 6.987 - 6.988 - usbif_interface_init(); 6.989 - 6.990 - if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 ) 6.991 - BUG(); 6.992 - 6.993 - pending_cons = 0; 6.994 - pending_prod = MAX_PENDING_REQS; 6.995 - memset(pending_reqs, 0, sizeof(pending_reqs)); 6.996 - for ( i = 0; i < MAX_PENDING_REQS; i++ ) 6.997 - pending_ring[i] = i; 6.998 - 6.999 - spin_lock_init(&usbio_schedule_list_lock); 6.1000 - INIT_LIST_HEAD(&usbio_schedule_list); 6.1001 - 6.1002 - if ( kernel_thread(usbio_schedule, 0, CLONE_FS | CLONE_FILES) < 0 ) 6.1003 - BUG(); 6.1004 - 6.1005 - usbif_ctrlif_init(); 6.1006 - 6.1007 - spin_lock_init(&owned_ports_lock); 6.1008 - 6.1009 - printk("Xen USB Backend Initialised"); 6.1010 - 6.1011 - return 0; 6.1012 -} 6.1013 - 6.1014 -__initcall(usbif_init);
7.1 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/frontend/main.c Fri Jan 28 07:59:39 2005 +0000 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,1720 +0,0 @@ 7.4 -/* 7.5 - * Xen Virtual USB Frontend Driver 7.6 - * 7.7 - * This file contains the first version of the Xen virtual USB hub 7.8 - * that I've managed not to delete by mistake (3rd time lucky!). 7.9 - * 7.10 - * Based on Linux's uhci.c, original copyright notices are displayed 7.11 - * below. Portions also (c) 2004 Intel Research Cambridge 7.12 - * and (c) 2004 Mark Williamson 7.13 - * 7.14 - * Contact <mark.williamson@cl.cam.ac.uk> or 7.15 - * <xen-devel@lists.sourceforge.net> regarding this code. 7.16 - * 7.17 - * Still to be (maybe) implemented: 7.18 - * - multiple port 7.19 - * - multiple interfaces 7.20 - * - migration / backend restart support? 7.21 - * - unloading support 7.22 - * 7.23 - * Differences to a normal host controller: 7.24 - * - the backend does most of the mucky stuff so we don't have to do various 7.25 - * things that are necessary for a normal host controller (e.g. FSBR). 7.26 - * - we don't have any hardware, so status registers are simulated in software. 7.27 - */ 7.28 - 7.29 -/* 7.30 - * Universal Host Controller Interface driver for USB. 7.31 - * 7.32 - * Maintainer: Johannes Erdfelt <johannes@erdfelt.com> 7.33 - * 7.34 - * (C) Copyright 1999 Linus Torvalds 7.35 - * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com 7.36 - * (C) Copyright 1999 Randy Dunlap 7.37 - * (C) Copyright 1999 Georg Acher, acher@in.tum.de 7.38 - * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de 7.39 - * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch 7.40 - * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at 7.41 - * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface 7.42 - * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). 7.43 - * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) 7.44 - * 7.45 - * Intel documents this fairly well, and as far as I know there 7.46 - * are no royalties or anything like that, but even so there are 7.47 - * people who decided that they want to do the same thing in a 7.48 - * completely different way. 7.49 - * 7.50 - * WARNING! The USB documentation is downright evil. Most of it 7.51 - * is just crap, written by a committee. You're better off ignoring 7.52 - * most of it, the important stuff is: 7.53 - * - the low-level protocol (fairly simple but lots of small details) 7.54 - * - working around the horridness of the rest 7.55 - */ 7.56 - 7.57 -#include <linux/config.h> 7.58 -#include <linux/module.h> 7.59 -#include <linux/kernel.h> 7.60 -#include <linux/init.h> 7.61 -#include <linux/delay.h> 7.62 -#include <linux/ioport.h> 7.63 -#include <linux/sched.h> 7.64 -#include <linux/slab.h> 7.65 -#include <linux/smp_lock.h> 7.66 -#include <linux/errno.h> 7.67 -#include <linux/unistd.h> 7.68 -#include <linux/interrupt.h> 7.69 -#include <linux/spinlock.h> 7.70 -#ifdef CONFIG_USB_DEBUG 7.71 -#define DEBUG 7.72 -#else 7.73 -#undef DEBUG 7.74 -#endif 7.75 -#include <linux/usb.h> 7.76 - 7.77 -#include <asm/uaccess.h> 7.78 -#include <asm/irq.h> 7.79 -#include <asm/system.h> 7.80 - 7.81 -#include "xhci.h" 7.82 - 7.83 -#include <linux/pm.h> 7.84 - 7.85 -#include "../../../../../drivers/usb/hcd.h" 7.86 - 7.87 -#include "../usbif.h" 7.88 -#include <asm/ctrl_if.h> 7.89 -#include <asm/xen-public/io/domain_controller.h> 7.90 - 7.91 -/* 7.92 - * Version Information 7.93 - */ 7.94 -#define DRIVER_VERSION "v1.0" 7.95 -#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, Mark Williamson" 7.96 -#define DRIVER_DESC "Xen Virtual USB Host Controller Interface driver" 7.97 - 7.98 -/* 7.99 - * debug = 0, no debugging messages 7.100 - * debug = 1, dump failed URB's except for stalls 7.101 - * debug = 2, dump all failed URB's (including stalls) 7.102 - */ 7.103 -#ifdef DEBUG 7.104 -static int debug = 1; 7.105 -#else 7.106 -static int debug = 0; 7.107 -#endif 7.108 -MODULE_PARM(debug, "i"); 7.109 -MODULE_PARM_DESC(debug, "Debug level"); 7.110 -static char *errbuf; 7.111 -#define ERRBUF_LEN (PAGE_SIZE * 8) 7.112 - 7.113 -static kmem_cache_t *xhci_up_cachep; /* urb_priv */ 7.114 - 7.115 -static int rh_submit_urb(struct urb *urb); 7.116 -static int rh_unlink_urb(struct urb *urb); 7.117 -//static int xhci_get_current_frame_number(struct usb_device *dev); 7.118 -static int xhci_unlink_urb(struct urb *urb); 7.119 -static void xhci_unlink_generic(struct urb *urb); 7.120 -static void xhci_call_completion(struct urb *urb); 7.121 -static void xhci_drain_ring(void); 7.122 - 7.123 -#define MAX_URB_LOOP 2048 /* Maximum number of linked URB's */ 7.124 - 7.125 -struct xhci *xhci; 7.126 - 7.127 -enum { USBIF_STATE_CONNECTED = 2, 7.128 - USBIF_STATE_DISCONNECTED = 1, 7.129 - USBIF_STATE_CLOSED =0 7.130 -}; 7.131 - 7.132 -static int awaiting_reset = 0; 7.133 - 7.134 -/** 7.135 - * xhci_construct_isoc - add isochronous information to a request 7.136 - */ 7.137 -int xhci_construct_isoc(usbif_request_t *req, struct urb *urb) 7.138 -{ 7.139 - usbif_iso_t *schedule; 7.140 - int i; 7.141 - struct urb_priv *urb_priv = urb->hcpriv; 7.142 - 7.143 - req->num_iso = urb->number_of_packets; 7.144 - schedule = (usbif_iso_t *)__get_free_page(GFP_KERNEL); 7.145 - 7.146 - if ( schedule == NULL ) 7.147 - return -ENOMEM; 7.148 - 7.149 - for ( i = 0; i < req->num_iso; i++ ) 7.150 - { 7.151 - schedule[i].buffer_offset = urb->iso_frame_desc[i].offset; 7.152 - schedule[i].length = urb->iso_frame_desc[i].length; 7.153 - } 7.154 - 7.155 - urb_priv->schedule = schedule; 7.156 - req->iso_schedule = virt_to_machine(schedule); 7.157 - 7.158 - return 0; 7.159 -} 7.160 - 7.161 -#define USBIF_RING_FULL ((xhci->usbif->req_prod - xhci->usb_resp_cons) == USBIF_RING_SIZE) 7.162 - 7.163 -static void dump_urb(struct urb *urb) 7.164 -{ 7.165 - printk("dumping urb @ %p\n", urb); 7.166 - 7.167 - printk("hcpriv = %p\n", urb->hcpriv); 7.168 - printk("next = %p\n", urb->next); 7.169 - printk("dev = %p\n", urb->dev); 7.170 - printk("pipe = 0x%lx\n", urb->pipe); 7.171 - printk("status = %d\n", urb->status); 7.172 - printk("transfer_flags = 0x%lx\n", urb->transfer_flags); 7.173 - printk("transfer_buffer = %p\n", urb->transfer_buffer); 7.174 - printk("transfer_buffer_length = %d\n", urb->transfer_buffer_length); 7.175 - printk("actual_length = %d\n", urb->actual_length); 7.176 - printk("bandwidth = %d\n", urb->bandwidth); 7.177 - printk("setup_packet = %p\n", urb->setup_packet); 7.178 - if ( urb->setup_packet != NULL ) 7.179 - printk("setup = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", 7.180 - urb->setup_packet[0], urb->setup_packet[1], urb->setup_packet[2], urb->setup_packet[3], 7.181 - urb->setup_packet[4], urb->setup_packet[5], urb->setup_packet[6], urb->setup_packet[7]); 7.182 - printk("complete = %p\n", urb->complete); 7.183 - printk("interval = %d\n", urb->interval); 7.184 - 7.185 -} 7.186 - 7.187 - 7.188 -static int 7.189 -xhci_queue_req(struct urb *urb) 7.190 -{ 7.191 - usbif_request_t *req; 7.192 - usbif_t *usbif = xhci->usbif; 7.193 - 7.194 -#if 0 7.195 - printk("usbif = %p, req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons = %d\n", 7.196 - usbif, usbif->req_prod, virt_to_machine(&usbif->req_prod), 7.197 - usbif->resp_prod, xhci->usb_resp_cons); 7.198 -#endif 7.199 - 7.200 - 7.201 -/* printk("Usbif_priv %p, want IO at 0x%lx\n", urb->hcpriv, virt_to_machine(urb->transfer_buffer)); */ 7.202 - 7.203 - if ( USBIF_RING_FULL ) 7.204 - { 7.205 - printk("xhci_queue_req(): USB ring full, not queuing request\n"); 7.206 - return -ENOBUFS; 7.207 - } 7.208 - 7.209 - /* Stick something in the shared communications ring. */ 7.210 - req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 7.211 - 7.212 - req->operation = USBIF_OP_IO; 7.213 - req->port = 0; /* We don't care what the port is. */ 7.214 - req->id = (unsigned long) urb->hcpriv; 7.215 - req->transfer_buffer = virt_to_machine(urb->transfer_buffer); 7.216 - req->devnum = usb_pipedevice(urb->pipe); 7.217 - req->direction = usb_pipein(urb->pipe); 7.218 - req->speed = usb_pipeslow(urb->pipe); 7.219 - req->pipe_type = usb_pipetype(urb->pipe); 7.220 - req->length = urb->transfer_buffer_length; 7.221 - req->transfer_flags = urb->transfer_flags; 7.222 - req->endpoint = usb_pipeendpoint(urb->pipe); 7.223 - req->speed = usb_pipeslow(urb->pipe); 7.224 - req->timeout = urb->timeout * (1000 / HZ); 7.225 - 7.226 - if ( usb_pipetype(urb->pipe) == 0 ) /* ISO */ 7.227 - { 7.228 - int ret = xhci_construct_isoc(req, urb); 7.229 - if ( ret != 0 ) 7.230 - return ret; 7.231 - } 7.232 - 7.233 - if(urb->setup_packet != NULL) 7.234 - memcpy(req->setup, urb->setup_packet, 8); 7.235 - else 7.236 - memset(req->setup, 0, 8); 7.237 - 7.238 - wmb(); 7.239 - 7.240 - usbif->req_prod++; 7.241 - 7.242 - notify_via_evtchn(xhci->evtchn); 7.243 - 7.244 - // dump_urb(urb); 7.245 - 7.246 - return -EINPROGRESS; 7.247 -} 7.248 - 7.249 -static inline usbif_request_t * 7.250 -xhci_queue_probe(usbif_vdev_t port) 7.251 -{ 7.252 - usbif_request_t *req; 7.253 - usbif_t *usbif = xhci->usbif; 7.254 - 7.255 -#if 0 7.256 - printk("queuing probe: req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons = %d\n", 7.257 - usbif->req_prod, virt_to_machine(&usbif->req_prod), 7.258 - usbif->resp_prod, xhci->usb_resp_cons); 7.259 -#endif 7.260 - 7.261 - if ( USBIF_RING_FULL ) 7.262 - { 7.263 - printk("xhci_queue_probe(): USB ring full, not queuing request\n"); 7.264 - return NULL; 7.265 - } 7.266 - 7.267 - /* Stick something in the shared communications ring. */ 7.268 - req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 7.269 - 7.270 - req->operation = USBIF_OP_PROBE; 7.271 - req->port = port; 7.272 - req->id = 0; 7.273 - req->transfer_buffer = 0; 7.274 - req->devnum = 0; 7.275 - req->direction = 0; 7.276 - req->speed = 0; 7.277 - req->pipe_type = 0; 7.278 - req->length = 0; 7.279 - req->transfer_flags = 0; 7.280 - req->endpoint = 0; 7.281 - req->speed = 0; 7.282 - 7.283 - wmb(); 7.284 - 7.285 - usbif->req_prod++; 7.286 - 7.287 - notify_via_evtchn(xhci->evtchn); 7.288 - 7.289 - return req; 7.290 -} 7.291 - 7.292 -static int 7.293 -xhci_port_reset(usbif_vdev_t port) 7.294 -{ 7.295 - usbif_request_t *req; 7.296 - usbif_t *usbif = xhci->usbif; 7.297 - 7.298 - /* We only reset one port at a time, so we only need one variable per 7.299 - * hub. */ 7.300 - awaiting_reset = 1; 7.301 - 7.302 - /* Stick something in the shared communications ring. */ 7.303 - req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 7.304 - 7.305 - req->operation = USBIF_OP_RESET; 7.306 - req->port = port; 7.307 - 7.308 - wmb(); 7.309 - 7.310 - usbif->req_prod++; 7.311 - 7.312 - notify_via_evtchn(xhci->evtchn); 7.313 - 7.314 - while ( awaiting_reset > 0 ) 7.315 - { 7.316 - mdelay(1); 7.317 - xhci_drain_ring(); 7.318 - } 7.319 - 7.320 - return awaiting_reset; 7.321 -} 7.322 - 7.323 -static void xhci_show_resp(usbif_response_t *r) 7.324 -{ 7.325 - printk("id=0x%lx, op=0x%x, data=0x%x, status=0x%x, length=0x%lx\n", 7.326 - r->id, r->operation, r->data, r->status, r->length); 7.327 -} 7.328 - 7.329 - 7.330 -/* 7.331 - * Only the USB core should call xhci_alloc_dev and xhci_free_dev 7.332 - */ 7.333 -static int xhci_alloc_dev(struct usb_device *dev) 7.334 -{ 7.335 - return 0; 7.336 -} 7.337 - 7.338 -static int xhci_free_dev(struct usb_device *dev) 7.339 -{ 7.340 - return 0; 7.341 -} 7.342 - 7.343 -static inline void xhci_add_complete(struct urb *urb) 7.344 -{ 7.345 - struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 7.346 - unsigned long flags; 7.347 - 7.348 - spin_lock_irqsave(&xhci->complete_list_lock, flags); 7.349 - list_add_tail(&urbp->complete_list, &xhci->complete_list); 7.350 - spin_unlock_irqrestore(&xhci->complete_list_lock, flags); 7.351 -} 7.352 - 7.353 -/* When this returns, the owner of the URB may free its 7.354 - * storage. 7.355 - * 7.356 - * We spin and wait for the URB to complete before returning. 7.357 - */ 7.358 -static void xhci_delete_urb(struct urb *urb) 7.359 -{ 7.360 - struct urb_priv *urbp; 7.361 - 7.362 - urbp = urb->hcpriv; 7.363 - 7.364 - /* If there's no urb_priv structure for this URB then it can't have 7.365 - * been submitted at all. */ 7.366 - if ( urbp == NULL ) 7.367 - return; 7.368 - 7.369 - /* For now we just spin until the URB completes. It shouldn't take too 7.370 - * long and we don't expect to have to do this very often. */ 7.371 - while ( urb->status == -EINPROGRESS ) 7.372 - { 7.373 - xhci_drain_ring(); 7.374 - mdelay(1); 7.375 - } 7.376 - 7.377 - /* Now we know that further transfers to the buffer won't 7.378 - * occur, so we can safely return. */ 7.379 -} 7.380 - 7.381 -static struct urb_priv *xhci_alloc_urb_priv(struct urb *urb) 7.382 -{ 7.383 - struct urb_priv *urbp; 7.384 - 7.385 - urbp = kmem_cache_alloc(xhci_up_cachep, SLAB_ATOMIC); 7.386 - if (!urbp) { 7.387 - err("xhci_alloc_urb_priv: couldn't allocate memory for urb_priv\n"); 7.388 - return NULL; 7.389 - } 7.390 - 7.391 - memset((void *)urbp, 0, sizeof(*urbp)); 7.392 - 7.393 - urbp->inserttime = jiffies; 7.394 - urbp->urb = urb; 7.395 - urbp->dev = urb->dev; 7.396 - 7.397 - INIT_LIST_HEAD(&urbp->complete_list); 7.398 - 7.399 - urb->hcpriv = urbp; 7.400 - 7.401 - return urbp; 7.402 -} 7.403 - 7.404 -/* 7.405 - * MUST be called with urb->lock acquired 7.406 - */ 7.407 -/* When is this called? Do we need to stop the transfer (as we 7.408 - * currently do)? */ 7.409 -static void xhci_destroy_urb_priv(struct urb *urb) 7.410 -{ 7.411 - struct urb_priv *urbp; 7.412 - 7.413 - urbp = (struct urb_priv *)urb->hcpriv; 7.414 - if (!urbp) 7.415 - return; 7.416 - 7.417 - if (!list_empty(&urb->urb_list)) 7.418 - warn("xhci_destroy_urb_priv: urb %p still on xhci->urb_list or xhci->remove_list", urb); 7.419 - 7.420 - if (!list_empty(&urbp->complete_list)) 7.421 - warn("xhci_destroy_urb_priv: urb %p still on xhci->complete_list", urb); 7.422 - 7.423 - kmem_cache_free(xhci_up_cachep, urb->hcpriv); 7.424 - 7.425 - urb->hcpriv = NULL; 7.426 -} 7.427 - 7.428 -/** 7.429 - * Try to find URBs in progress on the same pipe to the same device. 7.430 - * 7.431 - * MUST be called with xhci->urb_list_lock acquired 7.432 - */ 7.433 -static struct urb *xhci_find_urb_ep(struct xhci *xhci, struct urb *urb) 7.434 -{ 7.435 - struct list_head *tmp, *head; 7.436 - 7.437 - /* We don't match Isoc transfers since they are special */ 7.438 - if (usb_pipeisoc(urb->pipe)) 7.439 - return NULL; 7.440 - 7.441 - head = &xhci->urb_list; 7.442 - tmp = head->next; 7.443 - while (tmp != head) { 7.444 - struct urb *u = list_entry(tmp, struct urb, urb_list); 7.445 - 7.446 - tmp = tmp->next; 7.447 - 7.448 - if (u->dev == urb->dev && u->pipe == urb->pipe && 7.449 - u->status == -EINPROGRESS) 7.450 - return u; 7.451 - } 7.452 - 7.453 - return NULL; 7.454 -} 7.455 - 7.456 -static int xhci_submit_urb(struct urb *urb) 7.457 -{ 7.458 - int ret = -EINVAL; 7.459 - unsigned long flags; 7.460 - struct urb *eurb; 7.461 - int bustime; 7.462 - 7.463 -#if 0 7.464 - printk("submitting urb @ %p for dev @ %p, devnum = %d path %s\n", 7.465 - urb, urb->dev, urb->dev->devnum, urb->dev->devpath); 7.466 -#endif 7.467 - 7.468 - if (!urb) 7.469 - return -EINVAL; 7.470 - 7.471 - if (!urb->dev || !urb->dev->bus || !urb->dev->bus->hcpriv) { 7.472 - warn("xhci_submit_urb: urb %p belongs to disconnected device or bus?", urb); 7.473 - return -ENODEV; 7.474 - } 7.475 - 7.476 - if ( urb->dev->devpath == NULL ) 7.477 - { 7.478 - printk("BARF!\n"); 7.479 - BUG(); 7.480 - } 7.481 - 7.482 - 7.483 - 7.484 - usb_inc_dev_use(urb->dev); 7.485 - 7.486 - spin_lock_irqsave(&xhci->urb_list_lock, flags); 7.487 - spin_lock(&urb->lock); 7.488 - 7.489 - if (urb->status == -EINPROGRESS || urb->status == -ECONNRESET || 7.490 - urb->status == -ECONNABORTED) { 7.491 - dbg("xhci_submit_urb: urb not available to submit (status = %d)", urb->status); 7.492 - /* Since we can have problems on the out path */ 7.493 - spin_unlock(&urb->lock); 7.494 - spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 7.495 - usb_dec_dev_use(urb->dev); 7.496 - 7.497 - return ret; 7.498 - } 7.499 - 7.500 - INIT_LIST_HEAD(&urb->urb_list); 7.501 - if (!xhci_alloc_urb_priv(urb)) { 7.502 - ret = -ENOMEM; 7.503 - 7.504 - goto out; 7.505 - } 7.506 - 7.507 - ( (struct urb_priv *)urb->hcpriv )->in_progress = 1; 7.508 - 7.509 - eurb = xhci_find_urb_ep(xhci, urb); 7.510 - if (eurb && !(urb->transfer_flags & USB_QUEUE_BULK)) { 7.511 - ret = -ENXIO; 7.512 - 7.513 - goto out; 7.514 - } 7.515 - 7.516 - /* Short circuit the virtual root hub */ 7.517 - if (urb->dev == xhci->rh.dev) { 7.518 - ret = rh_submit_urb(urb); 7.519 - 7.520 - goto out; 7.521 - } 7.522 - 7.523 - if ( usb_pipedevice(urb->pipe) == 1 ) 7.524 - printk("dev = %p, dev->path = %s, rh.dev = %p, rh.dev.devnum = %d rh.dev->path = %s!\n", 7.525 - urb->dev, urb->dev->devpath, xhci->rh.dev, xhci->rh.dev->devnum, xhci->rh.dev->devpath); 7.526 - 7.527 - switch (usb_pipetype(urb->pipe)) { 7.528 - case PIPE_CONTROL: 7.529 - ret = xhci_queue_req(urb); 7.530 - break; 7.531 - case PIPE_INTERRUPT: 7.532 - if (urb->bandwidth == 0) { /* not yet checked/allocated */ 7.533 - bustime = usb_check_bandwidth(urb->dev, urb); 7.534 - if (bustime < 0) 7.535 - ret = bustime; 7.536 - else { 7.537 - ret = xhci_queue_req(urb); 7.538 - if (ret == -EINPROGRESS) 7.539 - usb_claim_bandwidth(urb->dev, urb, bustime, 0); 7.540 - } 7.541 - } else /* bandwidth is already set */ 7.542 - ret = xhci_queue_req(urb); 7.543 - break; 7.544 - case PIPE_BULK: 7.545 - ret = xhci_queue_req(urb); 7.546 - break; 7.547 - case PIPE_ISOCHRONOUS: 7.548 - if (urb->bandwidth == 0) { /* not yet checked/allocated */ 7.549 - if (urb->number_of_packets <= 0) { 7.550 - ret = -EINVAL; 7.551 - break; 7.552 - } 7.553 - bustime = usb_check_bandwidth(urb->dev, urb); 7.554 - if (bustime < 0) { 7.555 - ret = bustime; 7.556 - break; 7.557 - } 7.558 - 7.559 - ret = xhci_queue_req(urb); 7.560 - if (ret == -EINPROGRESS) 7.561 - usb_claim_bandwidth(urb->dev, urb, bustime, 1); 7.562 - } else /* bandwidth is already set */ 7.563 - ret = xhci_queue_req(urb); 7.564 - break; 7.565 - } 7.566 - 7.567 -out: 7.568 - urb->status = ret; 7.569 - 7.570 - if (ret == -EINPROGRESS) { 7.571 - /* We use _tail to make find_urb_ep more efficient */ 7.572 - list_add_tail(&urb->urb_list, &xhci->urb_list); 7.573 - 7.574 - spin_unlock(&urb->lock); 7.575 - spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 7.576 - 7.577 - return 0; 7.578 - } 7.579 - 7.580 - xhci_unlink_generic(urb); 7.581 - 7.582 - spin_unlock(&urb->lock); 7.583 - spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 7.584 - 7.585 - /* Only call completion if it was successful */ 7.586 - if (!ret) 7.587 - xhci_call_completion(urb); 7.588 - 7.589 - return ret; 7.590 -} 7.591 - 7.592 -/* 7.593 - * Return the result of a transfer 7.594 - * 7.595 - * MUST be called with urb_list_lock acquired 7.596 - */ 7.597 -static void xhci_transfer_result(struct xhci *xhci, struct urb *urb) 7.598 -{ 7.599 - int ret = 0; 7.600 - unsigned long flags; 7.601 - struct urb_priv *urbp; 7.602 - 7.603 - /* The root hub is special */ 7.604 - if (urb->dev == xhci->rh.dev) 7.605 - return; 7.606 - 7.607 - spin_lock_irqsave(&urb->lock, flags); 7.608 - 7.609 - urbp = (struct urb_priv *)urb->hcpriv; 7.610 - 7.611 - if ( ( (struct urb_priv *)urb->hcpriv )->in_progress ) 7.612 - ret = -EINPROGRESS; 7.613 - 7.614 - if (urb->actual_length < urb->transfer_buffer_length) { 7.615 - if (urb->transfer_flags & USB_DISABLE_SPD) { 7.616 - ret = -EREMOTEIO; 7.617 - } 7.618 - } 7.619 - 7.620 - if (urb->status == -EPIPE) 7.621 - { 7.622 - ret = urb->status; 7.623 - /* endpoint has stalled - mark it halted */ 7.624 - usb_endpoint_halt(urb->dev, usb_pipeendpoint(urb->pipe), 7.625 - usb_pipeout(urb->pipe)); 7.626 - } 7.627 - 7.628 - if ((debug == 1 && ret != 0 && ret != -EPIPE) || 7.629 - (ret != 0 && debug > 1)) { 7.630 - /* Some debugging code */ 7.631 - dbg("xhci_result_interrupt/bulk() failed with status %x", 7.632 - status); 7.633 - } 7.634 - 7.635 - if (ret == -EINPROGRESS) 7.636 - goto out; 7.637 - 7.638 - switch (usb_pipetype(urb->pipe)) { 7.639 - case PIPE_CONTROL: 7.640 - case PIPE_BULK: 7.641 - case PIPE_ISOCHRONOUS: 7.642 - /* Release bandwidth for Interrupt or Isoc. transfers */ 7.643 - /* Spinlock needed ? */ 7.644 - if (urb->bandwidth) 7.645 - usb_release_bandwidth(urb->dev, urb, 1); 7.646 - xhci_unlink_generic(urb); 7.647 - break; 7.648 - case PIPE_INTERRUPT: 7.649 - /* Interrupts are an exception */ 7.650 - if (urb->interval) 7.651 - goto out_complete; 7.652 - 7.653 - /* Release bandwidth for Interrupt or Isoc. transfers */ 7.654 - /* Spinlock needed ? */ 7.655 - if (urb->bandwidth) 7.656 - usb_release_bandwidth(urb->dev, urb, 0); 7.657 - xhci_unlink_generic(urb); 7.658 - break; 7.659 - default: 7.660 - info("xhci_transfer_result: unknown pipe type %d for urb %p\n", 7.661 - usb_pipetype(urb->pipe), urb); 7.662 - } 7.663 - 7.664 - /* Remove it from xhci->urb_list */ 7.665 - list_del_init(&urb->urb_list); 7.666 - 7.667 -out_complete: 7.668 - xhci_add_complete(urb); 7.669 - 7.670 -out: 7.671 - spin_unlock_irqrestore(&urb->lock, flags); 7.672 -} 7.673 - 7.674 -/* 7.675 - * MUST be called with urb->lock acquired 7.676 - */ 7.677 -static void xhci_unlink_generic(struct urb *urb) 7.678 -{ 7.679 - struct urb_priv *urbp = urb->hcpriv; 7.680 - 7.681 - /* We can get called when urbp allocation fails, so check */ 7.682 - if (!urbp) 7.683 - return; 7.684 - 7.685 - /* ??? This function is now so minimal it doesn't do much. Do we really 7.686 - * need it? */ 7.687 - 7.688 - xhci_delete_urb(urb); 7.689 -} 7.690 - 7.691 -static int xhci_unlink_urb(struct urb *urb) 7.692 -{ 7.693 - unsigned long flags; 7.694 - struct urb_priv *urbp = urb->hcpriv; 7.695 - 7.696 - if (!urb) 7.697 - return -EINVAL; 7.698 - 7.699 - if (!urb->dev || !urb->dev->bus || !urb->dev->bus->hcpriv) 7.700 - return -ENODEV; 7.701 - 7.702 - spin_lock_irqsave(&xhci->urb_list_lock, flags); 7.703 - spin_lock(&urb->lock); 7.704 - 7.705 - /* Release bandwidth for Interrupt or Isoc. transfers */ 7.706 - /* Spinlock needed ? */ 7.707 - if (urb->bandwidth) { 7.708 - switch (usb_pipetype(urb->pipe)) { 7.709 - case PIPE_INTERRUPT: 7.710 - usb_release_bandwidth(urb->dev, urb, 0); 7.711 - break; 7.712 - case PIPE_ISOCHRONOUS: 7.713 - usb_release_bandwidth(urb->dev, urb, 1); 7.714 - break; 7.715 - default: 7.716 - break; 7.717 - } 7.718 - } 7.719 - 7.720 - if (urb->status != -EINPROGRESS) { 7.721 - spin_unlock(&urb->lock); 7.722 - spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 7.723 - return 0; 7.724 - } 7.725 - 7.726 - list_del_init(&urb->urb_list); 7.727 - 7.728 - xhci_unlink_generic(urb); 7.729 - 7.730 - /* Short circuit the virtual root hub */ 7.731 - if (urb->dev == xhci->rh.dev) { 7.732 - rh_unlink_urb(urb); 7.733 - 7.734 - spin_unlock(&urb->lock); 7.735 - spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 7.736 - 7.737 - xhci_call_completion(urb); 7.738 - } else { 7.739 - if (urb->transfer_flags & USB_ASYNC_UNLINK) { 7.740 - urbp->status = urb->status = -ECONNABORTED; 7.741 - 7.742 - spin_lock(&xhci->urb_remove_list_lock); 7.743 - 7.744 - list_add(&urb->urb_list, &xhci->urb_remove_list); 7.745 - 7.746 - spin_unlock(&xhci->urb_remove_list_lock); 7.747 - 7.748 - spin_unlock(&urb->lock); 7.749 - spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 7.750 - 7.751 - } else { 7.752 - urb->status = -ENOENT; 7.753 - 7.754 - spin_unlock(&urb->lock); 7.755 - spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 7.756 - 7.757 - if (in_interrupt()) { /* wait at least 1 frame */ 7.758 - static int errorcount = 10; 7.759 - 7.760 - if (errorcount--) 7.761 - dbg("xhci_unlink_urb called from interrupt for urb %p", urb); 7.762 - udelay(1000); 7.763 - } else 7.764 - schedule_timeout(1+1*HZ/1000); 7.765 - 7.766 - xhci_call_completion(urb); 7.767 - } 7.768 - } 7.769 - 7.770 - return 0; 7.771 -} 7.772 - 7.773 - 7.774 -struct usb_operations xhci_device_operations = { 7.775 - .allocate = xhci_alloc_dev, 7.776 - .deallocate = xhci_free_dev, 7.777 - /* It doesn't look like any drivers actually care what the frame number 7.778 - * is at the moment! If necessary, we could approximate the current 7.779 - * frame nubmer by passing it from the backend in response messages. */ 7.780 - .get_frame_number = NULL, 7.781 - .submit_urb = xhci_submit_urb, 7.782 - .unlink_urb = xhci_unlink_urb 7.783 -}; 7.784 - 7.785 -/* Virtual Root Hub */ 7.786 - 7.787 -static __u8 root_hub_dev_des[] = 7.788 -{ 7.789 - 0x12, /* __u8 bLength; */ 7.790 - 0x01, /* __u8 bDescriptorType; Device */ 7.791 - 0x00, /* __u16 bcdUSB; v1.0 */ 7.792 - 0x01, 7.793 - 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 7.794 - 0x00, /* __u8 bDeviceSubClass; */ 7.795 - 0x00, /* __u8 bDeviceProtocol; */ 7.796 - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ 7.797 - 0x00, /* __u16 idVendor; */ 7.798 - 0x00, 7.799 - 0x00, /* __u16 idProduct; */ 7.800 - 0x00, 7.801 - 0x00, /* __u16 bcdDevice; */ 7.802 - 0x00, 7.803 - 0x00, /* __u8 iManufacturer; */ 7.804 - 0x02, /* __u8 iProduct; */ 7.805 - 0x01, /* __u8 iSerialNumber; */ 7.806 - 0x01 /* __u8 bNumConfigurations; */ 7.807 -}; 7.808 - 7.809 - 7.810 -/* Configuration descriptor */ 7.811 -static __u8 root_hub_config_des[] = 7.812 -{ 7.813 - 0x09, /* __u8 bLength; */ 7.814 - 0x02, /* __u8 bDescriptorType; Configuration */ 7.815 - 0x19, /* __u16 wTotalLength; */ 7.816 - 0x00, 7.817 - 0x01, /* __u8 bNumInterfaces; */ 7.818 - 0x01, /* __u8 bConfigurationValue; */ 7.819 - 0x00, /* __u8 iConfiguration; */ 7.820 - 0x40, /* __u8 bmAttributes; 7.821 - Bit 7: Bus-powered, 6: Self-powered, 7.822 - Bit 5 Remote-wakeup, 4..0: resvd */ 7.823 - 0x00, /* __u8 MaxPower; */ 7.824 - 7.825 - /* interface */ 7.826 - 0x09, /* __u8 if_bLength; */ 7.827 - 0x04, /* __u8 if_bDescriptorType; Interface */ 7.828 - 0x00, /* __u8 if_bInterfaceNumber; */ 7.829 - 0x00, /* __u8 if_bAlternateSetting; */ 7.830 - 0x01, /* __u8 if_bNumEndpoints; */ 7.831 - 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ 7.832 - 0x00, /* __u8 if_bInterfaceSubClass; */ 7.833 - 0x00, /* __u8 if_bInterfaceProtocol; */ 7.834 - 0x00, /* __u8 if_iInterface; */ 7.835 - 7.836 - /* endpoint */ 7.837 - 0x07, /* __u8 ep_bLength; */ 7.838 - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 7.839 - 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 7.840 - 0x03, /* __u8 ep_bmAttributes; Interrupt */ 7.841 - 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */ 7.842 - 0x00, 7.843 - 0xff /* __u8 ep_bInterval; 255 ms */ 7.844 -}; 7.845 - 7.846 -static __u8 root_hub_hub_des[] = 7.847 -{ 7.848 - 0x09, /* __u8 bLength; */ 7.849 - 0x29, /* __u8 bDescriptorType; Hub-descriptor */ 7.850 - 0x02, /* __u8 bNbrPorts; */ 7.851 - 0x00, /* __u16 wHubCharacteristics; */ 7.852 - 0x00, 7.853 - 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ 7.854 - 0x00, /* __u8 bHubContrCurrent; 0 mA */ 7.855 - 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */ 7.856 - 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ 7.857 -}; 7.858 - 7.859 -/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */ 7.860 -static int rh_send_irq(struct urb *urb) 7.861 -{ 7.862 - struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 7.863 - xhci_port_t *ports = xhci->rh.ports; 7.864 - unsigned long flags; 7.865 - int i, len = 1; 7.866 - __u16 data = 0; 7.867 - 7.868 - spin_lock_irqsave(&urb->lock, flags); 7.869 - for (i = 0; i < xhci->rh.numports; i++) { 7.870 - /* MAW: No idea what the old code was doing here or why it worked. 7.871 - * This implementation sets a bit if anything at all has changed on the 7.872 - * port, as per USB spec 11.12 */ 7.873 - data |= (ports[i].cs_chg || ports[i].pe_chg ) 7.874 - ? (1 << (i + 1)) 7.875 - : 0; 7.876 - 7.877 - len = (i + 1) / 8 + 1; 7.878 - } 7.879 - 7.880 - *(__u16 *) urb->transfer_buffer = cpu_to_le16(data); 7.881 - urb->actual_length = len; 7.882 - urbp->status = 0; 7.883 - 7.884 - spin_unlock_irqrestore(&urb->lock, flags); 7.885 - 7.886 - if ((data > 0) && (xhci->rh.send != 0)) { 7.887 - dbg("root-hub INT complete: data: %x", data); 7.888 - xhci_call_completion(urb); 7.889 - } 7.890 - 7.891 - return 0; 7.892 -} 7.893 - 7.894 -/* Virtual Root Hub INTs are polled by this timer every "interval" ms */ 7.895 -static int rh_init_int_timer(struct urb *urb); 7.896 - 7.897 -static void rh_int_timer_do(unsigned long ptr) 7.898 -{ 7.899 - struct urb *urb = (struct urb *)ptr; 7.900 - struct list_head list, *tmp, *head; 7.901 - unsigned long flags; 7.902 - int i; 7.903 - 7.904 - for ( i = 0; i < xhci->rh.numports; i++) 7.905 - xhci_queue_probe(i); 7.906 - 7.907 - if (xhci->rh.send) 7.908 - rh_send_irq(urb); 7.909 - 7.910 - INIT_LIST_HEAD(&list); 7.911 - 7.912 - spin_lock_irqsave(&xhci->urb_list_lock, flags); 7.913 - head = &xhci->urb_list; 7.914 - tmp = head->next; 7.915 - while (tmp != head) { 7.916 - struct urb *u = list_entry(tmp, struct urb, urb_list); 7.917 - struct urb_priv *up = (struct urb_priv *)u->hcpriv; 7.918 - 7.919 - tmp = tmp->next; 7.920 - 7.921 - spin_lock(&u->lock); 7.922 - 7.923 - /* Check if the URB timed out */ 7.924 - if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout)) { 7.925 - list_del(&u->urb_list); 7.926 - list_add_tail(&u->urb_list, &list); 7.927 - } 7.928 - 7.929 - spin_unlock(&u->lock); 7.930 - } 7.931 - spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 7.932 - 7.933 - head = &list; 7.934 - tmp = head->next; 7.935 - while (tmp != head) { 7.936 - struct urb *u = list_entry(tmp, struct urb, urb_list); 7.937 - 7.938 - tmp = tmp->next; 7.939 - 7.940 - u->transfer_flags |= USB_ASYNC_UNLINK | USB_TIMEOUT_KILLED; 7.941 - xhci_unlink_urb(u); 7.942 - } 7.943 - 7.944 - rh_init_int_timer(urb); 7.945 -} 7.946 - 7.947 -/* Root Hub INTs are polled by this timer */ 7.948 -static int rh_init_int_timer(struct urb *urb) 7.949 -{ 7.950 - xhci->rh.interval = urb->interval; 7.951 - init_timer(&xhci->rh.rh_int_timer); 7.952 - xhci->rh.rh_int_timer.function = rh_int_timer_do; 7.953 - xhci->rh.rh_int_timer.data = (unsigned long)urb; 7.954 - xhci->rh.rh_int_timer.expires = jiffies + (HZ * (urb->interval < 30 ? 30 : urb->interval)) / 1000; 7.955 - add_timer(&xhci->rh.rh_int_timer); 7.956 - 7.957 - return 0; 7.958 -} 7.959 - 7.960 -#define OK(x) len = (x); break 7.961 - 7.962 -/* Root Hub Control Pipe */ 7.963 -static int rh_submit_urb(struct urb *urb) 7.964 -{ 7.965 - unsigned int pipe = urb->pipe; 7.966 - struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *)urb->setup_packet; 7.967 - void *data = urb->transfer_buffer; 7.968 - int leni = urb->transfer_buffer_length; 7.969 - int len = 0; 7.970 - xhci_port_t *status; 7.971 - int stat = 0; 7.972 - int i; 7.973 - int retstatus; 7.974 - unsigned long flags; 7.975 - 7.976 - __u16 cstatus; 7.977 - __u16 bmRType_bReq; 7.978 - __u16 wValue; 7.979 - __u16 wIndex; 7.980 - __u16 wLength; 7.981 - 7.982 - if (usb_pipetype(pipe) == PIPE_INTERRUPT) { 7.983 - xhci->rh.urb = urb; 7.984 - xhci->rh.send = 1; 7.985 - xhci->rh.interval = urb->interval; 7.986 - rh_init_int_timer(urb); 7.987 - 7.988 - return -EINPROGRESS; 7.989 - } 7.990 - 7.991 - bmRType_bReq = cmd->bRequestType | cmd->bRequest << 8; 7.992 - wValue = le16_to_cpu(cmd->wValue); 7.993 - wIndex = le16_to_cpu(cmd->wIndex); 7.994 - wLength = le16_to_cpu(cmd->wLength); 7.995 - 7.996 - for (i = 0; i < 8; i++) 7.997 - xhci->rh.c_p_r[i] = 0; 7.998 - 7.999 - status = &xhci->rh.ports[wIndex - 1]; 7.1000 - 7.1001 - spin_lock_irqsave(&xhci->rh.port_state_lock, flags); 7.1002 - 7.1003 - switch (bmRType_bReq) { 7.1004 - /* Request Destination: 7.1005 - without flags: Device, 7.1006 - RH_INTERFACE: interface, 7.1007 - RH_ENDPOINT: endpoint, 7.1008 - RH_CLASS means HUB here, 7.1009 - RH_OTHER | RH_CLASS almost ever means HUB_PORT here 7.1010 - */ 7.1011 - 7.1012 - case RH_GET_STATUS: 7.1013 - *(__u16 *)data = cpu_to_le16(1); 7.1014 - OK(2); 7.1015 - case RH_GET_STATUS | RH_INTERFACE: 7.1016 - *(__u16 *)data = cpu_to_le16(0); 7.1017 - OK(2); 7.1018 - case RH_GET_STATUS | RH_ENDPOINT: 7.1019 - *(__u16 *)data = cpu_to_le16(0); 7.1020 - OK(2); 7.1021 - case RH_GET_STATUS | RH_CLASS: 7.1022 - *(__u32 *)data = cpu_to_le32(0); 7.1023 - OK(4); /* hub power */ 7.1024 - case RH_GET_STATUS | RH_OTHER | RH_CLASS: 7.1025 - cstatus = (status->cs_chg) | 7.1026 - (status->pe_chg << 1) | 7.1027 - (xhci->rh.c_p_r[wIndex - 1] << 4); 7.1028 - retstatus = (status->ccs) | 7.1029 - (status->pe << 1) | 7.1030 - (status->susp << 2) | 7.1031 - (status->pr << 8) | 7.1032 - (1 << 8) | /* power on */ 7.1033 - (status->lsda << 9); 7.1034 - *(__u16 *)data = cpu_to_le16(retstatus); 7.1035 - *(__u16 *)(data + 2) = cpu_to_le16(cstatus); 7.1036 - OK(4); 7.1037 - case RH_CLEAR_FEATURE | RH_ENDPOINT: 7.1038 - switch (wValue) { 7.1039 - case RH_ENDPOINT_STALL: 7.1040 - OK(0); 7.1041 - } 7.1042 - break; 7.1043 - case RH_CLEAR_FEATURE | RH_CLASS: 7.1044 - switch (wValue) { 7.1045 - case RH_C_HUB_OVER_CURRENT: 7.1046 - OK(0); /* hub power over current */ 7.1047 - } 7.1048 - break; 7.1049 - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: 7.1050 - switch (wValue) { 7.1051 - case RH_PORT_ENABLE: 7.1052 - status->pe = 0; 7.1053 - OK(0); 7.1054 - case RH_PORT_SUSPEND: 7.1055 - status->susp = 0; 7.1056 - OK(0); 7.1057 - case RH_PORT_POWER: 7.1058 - OK(0); /* port power */ 7.1059 - case RH_C_PORT_CONNECTION: 7.1060 - status->cs_chg = 0; 7.1061 - OK(0); 7.1062 - case RH_C_PORT_ENABLE: 7.1063 - status->pe_chg = 0; 7.1064 - OK(0); 7.1065 - case RH_C_PORT_SUSPEND: 7.1066 - /*** WR_RH_PORTSTAT(RH_PS_PSSC); */ 7.1067 - OK(0); 7.1068 - case RH_C_PORT_OVER_CURRENT: 7.1069 - OK(0); /* port power over current */ 7.1070 - case RH_C_PORT_RESET: 7.1071 - xhci->rh.c_p_r[wIndex - 1] = 0; 7.1072 - OK(0); 7.1073 - } 7.1074 - break; 7.1075 - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: 7.1076 - switch (wValue) { 7.1077 - case RH_PORT_SUSPEND: 7.1078 - status->susp = 1; 7.1079 - OK(0); 7.1080 - case RH_PORT_RESET: 7.1081 - { 7.1082 - int ret; 7.1083 - xhci->rh.c_p_r[wIndex - 1] = 1; 7.1084 - status->pr = 0; 7.1085 - status->pe = 1; 7.1086 - ret = xhci_port_reset(wIndex - 1); 7.1087 - /* XXX MAW: should probably cancel queued transfers during reset... *\/ */ 7.1088 - if ( ret == 0 ) { OK(0); } 7.1089 - else { return ret; } 7.1090 - } 7.1091 - break; 7.1092 - case RH_PORT_POWER: 7.1093 - OK(0); /* port power ** */ 7.1094 - case RH_PORT_ENABLE: 7.1095 - status->pe = 1; 7.1096 - OK(0); 7.1097 - } 7.1098 - break; 7.1099 - case RH_SET_ADDRESS: 7.1100 - printk("setting root hub device to %d\n", wValue); 7.1101 - xhci->rh.devnum = wValue; 7.1102 - OK(0); 7.1103 - case RH_GET_DESCRIPTOR: 7.1104 - switch ((wValue & 0xff00) >> 8) { 7.1105 - case 0x01: /* device descriptor */ 7.1106 - len = min_t(unsigned int, leni, 7.1107 - min_t(unsigned int, 7.1108 - sizeof(root_hub_dev_des), wLength)); 7.1109 - memcpy(data, root_hub_dev_des, len); 7.1110 - OK(len); 7.1111 - case 0x02: /* configuration descriptor */ 7.1112 - len = min_t(unsigned int, leni, 7.1113 - min_t(unsigned int, 7.1114 - sizeof(root_hub_config_des), wLength)); 7.1115 - memcpy (data, root_hub_config_des, len); 7.1116 - OK(len); 7.1117 - case 0x03: /* string descriptors */ 7.1118 - len = usb_root_hub_string (wValue & 0xff, 7.1119 - 0, "XHCI-alt", 7.1120 - data, wLength); 7.1121 - if (len > 0) { 7.1122 - OK(min_t(int, leni, len)); 7.1123 - } else 7.1124 - stat = -EPIPE; 7.1125 - } 7.1126 - break; 7.1127 - case RH_GET_DESCRIPTOR | RH_CLASS: 7.1128 - root_hub_hub_des[2] = xhci->rh.numports; 7.1129 - len = min_t(unsigned int, leni, 7.1130 - min_t(unsigned int, sizeof(root_hub_hub_des), wLength)); 7.1131 - memcpy(data, root_hub_hub_des, len); 7.1132 - OK(len); 7.1133 - case RH_GET_CONFIGURATION: 7.1134 - *(__u8 *)data = 0x01; 7.1135 - OK(1); 7.1136 - case RH_SET_CONFIGURATION: 7.1137 - OK(0); 7.1138 - case RH_GET_INTERFACE | RH_INTERFACE: 7.1139 - *(__u8 *)data = 0x00; 7.1140 - OK(1); 7.1141 - case RH_SET_INTERFACE | RH_INTERFACE: 7.1142 - OK(0); 7.1143 - default: 7.1144 - stat = -EPIPE; 7.1145 - } 7.1146 - 7.1147 - spin_unlock_irqrestore(&xhci->rh.port_state_lock, flags); 7.1148 - 7.1149 - urb->actual_length = len; 7.1150 - 7.1151 - return stat; 7.1152 -} 7.1153 - 7.1154 -/* 7.1155 - * MUST be called with urb->lock acquired 7.1156 - */ 7.1157 -static int rh_unlink_urb(struct urb *urb) 7.1158 -{ 7.1159 - if (xhci->rh.urb == urb) { 7.1160 - urb->status = -ENOENT; 7.1161 - xhci->rh.send = 0; 7.1162 - xhci->rh.urb = NULL; 7.1163 - del_timer(&xhci->rh.rh_int_timer); 7.1164 - } 7.1165 - return 0; 7.1166 -} 7.1167 - 7.1168 -static void xhci_call_completion(struct urb *urb) 7.1169 -{ 7.1170 - struct urb_priv *urbp; 7.1171 - struct usb_device *dev = urb->dev; 7.1172 - int is_ring = 0, killed, resubmit_interrupt, status; 7.1173 - struct urb *nurb; 7.1174 - unsigned long flags; 7.1175 - 7.1176 - spin_lock_irqsave(&urb->lock, flags); 7.1177 - 7.1178 - urbp = (struct urb_priv *)urb->hcpriv; 7.1179 - if (!urbp || !urb->dev) { 7.1180 - spin_unlock_irqrestore(&urb->lock, flags); 7.1181 - return; 7.1182 - } 7.1183 - 7.1184 - killed = (urb->status == -ENOENT || urb->status == -ECONNABORTED || 7.1185 - urb->status == -ECONNRESET); 7.1186 - resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT && 7.1187 - urb->interval); 7.1188 - 7.1189 - nurb = urb->next; 7.1190 - if (nurb && !killed) { 7.1191 - int count = 0; 7.1192 - 7.1193 - while (nurb && nurb != urb && count < MAX_URB_LOOP) { 7.1194 - if (nurb->status == -ENOENT || 7.1195 - nurb->status == -ECONNABORTED || 7.1196 - nurb->status == -ECONNRESET) { 7.1197 - killed = 1; 7.1198 - break; 7.1199 - } 7.1200 - 7.1201 - nurb = nurb->next; 7.1202 - count++; 7.1203 - } 7.1204 - 7.1205 - if (count == MAX_URB_LOOP) 7.1206 - err("xhci_call_completion: too many linked URB's, loop? (first loop)"); 7.1207 - 7.1208 - /* Check to see if chain is a ring */ 7.1209 - is_ring = (nurb == urb); 7.1210 - } 7.1211 - 7.1212 - status = urbp->status; 7.1213 - if (!resubmit_interrupt || killed) 7.1214 - /* We don't need urb_priv anymore */ 7.1215 - xhci_destroy_urb_priv(urb); 7.1216 - 7.1217 - if (!killed) 7.1218 - urb->status = status; 7.1219 - 7.1220 - spin_unlock_irqrestore(&urb->lock, flags); 7.1221 - 7.1222 - if (urb->complete) 7.1223 - urb->complete(urb); 7.1224 - 7.1225 - if (resubmit_interrupt) 7.1226 - /* Recheck the status. The completion handler may have */ 7.1227 - /* unlinked the resubmitting interrupt URB */ 7.1228 - killed = (urb->status == -ENOENT || 7.1229 - urb->status == -ECONNABORTED || 7.1230 - urb->status == -ECONNRESET); 7.1231 - 7.1232 - if (resubmit_interrupt && !killed) { 7.1233 - if ( urb->dev != xhci->rh.dev ) 7.1234 - xhci_queue_req(urb); /* XXX What if this fails? */ 7.1235 - /* Don't need to resubmit URBs for the virtual root dev. */ 7.1236 - } else { 7.1237 - if (is_ring && !killed) { 7.1238 - urb->dev = dev; 7.1239 - xhci_submit_urb(urb); 7.1240 - } else { 7.1241 - /* We decrement the usage count after we're done */ 7.1242 - /* with everything */ 7.1243 - usb_dec_dev_use(dev); 7.1244 - } 7.1245 - } 7.1246 -} 7.1247 - 7.1248 -static void xhci_finish_completion(void) 7.1249 -{ 7.1250 - struct list_head *tmp, *head; 7.1251 - unsigned long flags; 7.1252 - 7.1253 - spin_lock_irqsave(&xhci->complete_list_lock, flags); 7.1254 - head = &xhci->complete_list; 7.1255 - tmp = head->next; 7.1256 - while (tmp != head) { 7.1257 - struct urb_priv *urbp = list_entry(tmp, struct urb_priv, complete_list); 7.1258 - struct urb *urb = urbp->urb; 7.1259 - 7.1260 - list_del_init(&urbp->complete_list); 7.1261 - spin_unlock_irqrestore(&xhci->complete_list_lock, flags); 7.1262 - 7.1263 - xhci_call_completion(urb); 7.1264 - 7.1265 - spin_lock_irqsave(&xhci->complete_list_lock, flags); 7.1266 - head = &xhci->complete_list; 7.1267 - tmp = head->next; 7.1268 - } 7.1269 - spin_unlock_irqrestore(&xhci->complete_list_lock, flags); 7.1270 -} 7.1271 - 7.1272 -void receive_usb_reset(usbif_response_t *resp) 7.1273 -{ 7.1274 - awaiting_reset = resp->status; 7.1275 - rmb(); 7.1276 - 7.1277 -} 7.1278 - 7.1279 -void receive_usb_probe(usbif_response_t *resp) 7.1280 -{ 7.1281 - spin_lock(&xhci->rh.port_state_lock); 7.1282 - 7.1283 - if ( resp->status > 0 ) 7.1284 - { 7.1285 - if ( resp->status == 1 ) 7.1286 - { 7.1287 -/* printk("hey hey, there's a device on port %d\n", resp->data); */ 7.1288 - 7.1289 - /* If theres a device there and there wasn't one before there must 7.1290 - * have been a connection status change. */ 7.1291 - if( xhci->rh.ports[resp->data].cs == 0 ) 7.1292 - { 7.1293 - xhci->rh.ports[resp->data].cs = 1; 7.1294 - xhci->rh.ports[resp->data].ccs = 1; 7.1295 - xhci->rh.ports[resp->data].cs_chg = 1; 7.1296 -/* printk("Look at device on port %d that wasn't there before\n", resp->data); */ 7.1297 - } 7.1298 - } 7.1299 - else 7.1300 - printk("receive_usb_probe(): unexpected status %d for port %d\n", 7.1301 - resp->status, resp->data); 7.1302 - } 7.1303 - else if ( resp->status < 0) 7.1304 - printk("receive_usb_probe(): got error status %d\n", resp->status); 7.1305 - 7.1306 - spin_unlock(&xhci->rh.port_state_lock); 7.1307 -} 7.1308 - 7.1309 -void receive_usb_io(usbif_response_t *resp) 7.1310 -{ 7.1311 - struct urb_priv *urbp = (struct urb_priv *)resp->id; 7.1312 - struct urb *urb = urbp->urb; 7.1313 - 7.1314 - urb->actual_length = resp->length; 7.1315 - urb->status = resp->status; 7.1316 - urbp->status = resp->status; 7.1317 - urbp->in_progress = 0; 7.1318 - 7.1319 - if( usb_pipetype(urb->pipe) == 0 ) /* ISO */ 7.1320 - { 7.1321 - int i; 7.1322 - 7.1323 - /* Copy ISO schedule results back in. */ 7.1324 - 7.1325 - for ( i = 0; i < urb->number_of_packets; i++ ) 7.1326 - { 7.1327 - urb->iso_frame_desc[i].status 7.1328 - = urbp->schedule[i].status; 7.1329 - urb->iso_frame_desc[i].actual_length 7.1330 - = urbp->schedule[i].length; 7.1331 - } 7.1332 - free_page((unsigned long)urbp->schedule); 7.1333 - } 7.1334 -} 7.1335 - 7.1336 -static void xhci_drain_ring(void) 7.1337 -{ 7.1338 - struct list_head *tmp, *head; 7.1339 - usbif_t *usb_ring = xhci->usbif; 7.1340 - usbif_response_t *resp; 7.1341 - USBIF_RING_IDX i, rp; 7.1342 - 7.1343 - /* Walk the ring here to get responses, updating URBs to show what 7.1344 - * completed. */ 7.1345 - 7.1346 - rp = usb_ring->resp_prod; 7.1347 - rmb(); /* Ensure we see queued requests up to 'rp'. */ 7.1348 - 7.1349 - /* Take items off the comms ring, taking care not to overflow. */ 7.1350 - for ( i = xhci->usb_resp_cons; 7.1351 - (i != rp) && ((i-usb_ring->req_prod) != USBIF_RING_SIZE); 7.1352 - i++ ) 7.1353 - { 7.1354 - resp = &usb_ring->ring[MASK_USBIF_IDX(i)].resp; 7.1355 - 7.1356 - /* May need to deal with batching and with putting a ceiling on 7.1357 - the number dispatched for performance and anti-dos reasons */ 7.1358 - 7.1359 -#if 0 7.1360 - printk("usbfront: Processing response:\n"); 7.1361 - printk(" id = 0x%x\n", resp->id); 7.1362 - printk(" op = %d\n", resp->operation); 7.1363 - printk(" status = %d\n", resp->status); 7.1364 - printk(" length = %d\n", resp->length); 7.1365 -#endif 7.1366 - 7.1367 - switch ( resp->operation ) 7.1368 - { 7.1369 - case USBIF_OP_PROBE: 7.1370 - receive_usb_probe(resp); 7.1371 - break; 7.1372 - 7.1373 - case USBIF_OP_IO: 7.1374 - receive_usb_io(resp); 7.1375 - break; 7.1376 - 7.1377 - case USBIF_OP_RESET: 7.1378 - receive_usb_reset(resp); 7.1379 - break; 7.1380 - 7.1381 - default: 7.1382 - printk("error: unknown USB io operation response [%d]\n", 7.1383 - usb_ring->ring[i].req.operation); 7.1384 - break; 7.1385 - } 7.1386 - } 7.1387 - 7.1388 - xhci->usb_resp_cons = i; 7.1389 - 7.1390 - /* Walk the list of pending URB's to see which ones completed and do 7.1391 - * callbacks, etc. */ 7.1392 - spin_lock(&xhci->urb_list_lock); 7.1393 - head = &xhci->urb_list; 7.1394 - tmp = head->next; 7.1395 - while (tmp != head) { 7.1396 - 7.1397 - struct urb *urb = list_entry(tmp, struct urb, urb_list); 7.1398 - 7.1399 - tmp = tmp->next; 7.1400 - 7.1401 - /* Checks the status and does all of the magic necessary */ 7.1402 - xhci_transfer_result(xhci, urb); 7.1403 - } 7.1404 - spin_unlock(&xhci->urb_list_lock); 7.1405 - 7.1406 - xhci_finish_completion(); 7.1407 -} 7.1408 - 7.1409 - 7.1410 -static void xhci_interrupt(int irq, void *__xhci, struct pt_regs *regs) 7.1411 -{ 7.1412 - xhci_drain_ring(); 7.1413 -} 7.1414 - 7.1415 -static void free_xhci(struct xhci *xhci) 7.1416 -{ 7.1417 - kfree(xhci); 7.1418 -} 7.1419 - 7.1420 -/* /\* */ 7.1421 -/* * De-allocate all resources.. */ 7.1422 -/* *\/ */ 7.1423 -/* static void release_xhci(struct xhci *xhci) */ 7.1424 -/* { */ 7.1425 -/* if (xhci->irq >= 0) { */ 7.1426 -/* free_irq(xhci->irq, xhci); */ 7.1427 -/* xhci->irq = -1; */ 7.1428 -/* } */ 7.1429 - 7.1430 -/* /\* Get the ring back from the backend domain. Then free it. Hmmmm. */ 7.1431 -/* * Lets ignore this for now - not particularly useful. *\/ */ 7.1432 - 7.1433 -/* free_xhci(xhci); */ 7.1434 -/* } */ 7.1435 - 7.1436 -/** 7.1437 - * Initialise a new virtual root hub for a new USB device channel. 7.1438 - */ 7.1439 -static int alloc_xhci(void) 7.1440 -{ 7.1441 - int retval; 7.1442 - struct usb_bus *bus; 7.1443 - 7.1444 - retval = -EBUSY; 7.1445 - 7.1446 - xhci = kmalloc(sizeof(*xhci), GFP_KERNEL); 7.1447 - if (!xhci) { 7.1448 - err("couldn't allocate xhci structure"); 7.1449 - retval = -ENOMEM; 7.1450 - goto err_alloc_xhci; 7.1451 - } 7.1452 - 7.1453 - /* Reset here so we don't get any interrupts from an old setup */ 7.1454 - /* or broken setup */ 7.1455 - // reset_hc(xhci); 7.1456 - 7.1457 - 7.1458 - xhci->state = USBIF_STATE_CLOSED; 7.1459 - xhci->is_suspended = 0; 7.1460 - 7.1461 - spin_lock_init(&xhci->urb_remove_list_lock); 7.1462 - INIT_LIST_HEAD(&xhci->urb_remove_list); 7.1463 - 7.1464 - spin_lock_init(&xhci->urb_list_lock); 7.1465 - INIT_LIST_HEAD(&xhci->urb_list); 7.1466 - 7.1467 - spin_lock_init(&xhci->complete_list_lock); 7.1468 - INIT_LIST_HEAD(&xhci->complete_list); 7.1469 - 7.1470 - spin_lock_init(&xhci->frame_list_lock); 7.1471 - 7.1472 - /* We need exactly one page (per XHCI specs), how convenient */ 7.1473 - /* We assume that one page is atleast 4k (1024 frames * 4 bytes) */ 7.1474 -#if PAGE_SIZE < (4 * 1024) 7.1475 -#error PAGE_SIZE is not atleast 4k 7.1476 -#endif 7.1477 - bus = usb_alloc_bus(&xhci_device_operations); 7.1478 - if (!bus) { 7.1479 - err("unable to allocate bus"); 7.1480 - goto err_alloc_bus; 7.1481 - } 7.1482 - 7.1483 - xhci->bus = bus; 7.1484 - bus->bus_name = "XHCI"; 7.1485 - bus->hcpriv = xhci; 7.1486 - 7.1487 - usb_register_bus(xhci->bus); 7.1488 - 7.1489 - /* Initialize the root hub */ 7.1490 - 7.1491 - xhci->rh.numports = 0; 7.1492 - 7.1493 - xhci->bus->root_hub = xhci->rh.dev = usb_alloc_dev(NULL, xhci->bus); 7.1494 - if (!xhci->rh.dev) { 7.1495 - err("unable to allocate root hub"); 7.1496 - goto err_alloc_root_hub; 7.1497 - } 7.1498 - 7.1499 - xhci->state = 0; 7.1500 - 7.1501 - return 0; 7.1502 - 7.1503 -/* 7.1504 - * error exits: 7.1505 - */ 7.1506 -err_start_root_hub: 7.1507 - free_irq(xhci->irq, xhci); 7.1508 - xhci->irq = -1; 7.1509 - 7.1510 -err_alloc_root_hub: 7.1511 - usb_free_bus(xhci->bus); 7.1512 - xhci->bus = NULL; 7.1513 - 7.1514 -err_alloc_bus: 7.1515 - free_xhci(xhci); 7.1516 - 7.1517 -err_alloc_xhci: 7.1518 - return retval; 7.1519 -} 7.1520 - 7.1521 -static void usbif_status_change(usbif_fe_interface_status_changed_t *status) 7.1522 -{ 7.1523 - ctrl_msg_t cmsg; 7.1524 - usbif_fe_interface_connect_t up; 7.1525 - long rc; 7.1526 - usbif_t *usbif; 7.1527 - 7.1528 - switch ( status->status ) 7.1529 - { 7.1530 - case USBIF_INTERFACE_STATUS_DESTROYED: 7.1531 - printk(KERN_WARNING "Unexpected usbif-DESTROYED message in state %d\n", 7.1532 - xhci->state); 7.1533 - break; 7.1534 - 7.1535 - case USBIF_INTERFACE_STATUS_DISCONNECTED: 7.1536 - if ( xhci->state != USBIF_STATE_CLOSED ) 7.1537 - { 7.1538 - printk(KERN_WARNING "Unexpected usbif-DISCONNECTED message" 7.1539 - " in state %d\n", xhci->state); 7.1540 - break; 7.1541 - /* Not bothering to do recovery here for now. Keep things 7.1542 - * simple. */ 7.1543 - } 7.1544 - 7.1545 - /* Move from CLOSED to DISCONNECTED state. */ 7.1546 - xhci->usbif = usbif = (usbif_t *)__get_free_page(GFP_KERNEL); 7.1547 - usbif->req_prod = usbif->resp_prod = 0; 7.1548 - xhci->state = USBIF_STATE_DISCONNECTED; 7.1549 - 7.1550 - /* Construct an interface-CONNECT message for the domain controller. */ 7.1551 - cmsg.type = CMSG_USBIF_FE; 7.1552 - cmsg.subtype = CMSG_USBIF_FE_INTERFACE_CONNECT; 7.1553 - cmsg.length = sizeof(usbif_fe_interface_connect_t); 7.1554 - up.shmem_frame = virt_to_machine(usbif) >> PAGE_SHIFT; 7.1555 - memcpy(cmsg.msg, &up, sizeof(up)); 7.1556 - 7.1557 - /* Tell the controller to bring up the interface. */ 7.1558 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 7.1559 - break; 7.1560 - 7.1561 - case USBIF_INTERFACE_STATUS_CONNECTED: 7.1562 - if ( xhci->state == USBIF_STATE_CLOSED ) 7.1563 - { 7.1564 - printk(KERN_WARNING "Unexpected usbif-CONNECTED message" 7.1565 - " in state %d\n", xhci->state); 7.1566 - break; 7.1567 - } 7.1568 - 7.1569 - xhci->evtchn = status->evtchn; 7.1570 - xhci->irq = bind_evtchn_to_irq(xhci->evtchn); 7.1571 - xhci->bandwidth = status->bandwidth; 7.1572 - xhci->rh.numports = status->num_ports; 7.1573 - 7.1574 - xhci->rh.ports = kmalloc (sizeof(xhci_port_t) * xhci->rh.numports, GFP_KERNEL); 7.1575 - memset(xhci->rh.ports, 0, sizeof(xhci_port_t) * xhci->rh.numports); 7.1576 - 7.1577 - printk("rh.dev @ %p\n", xhci->rh.dev); 7.1578 - 7.1579 - usb_connect(xhci->rh.dev); 7.1580 - 7.1581 - if (usb_new_device(xhci->rh.dev) != 0) { 7.1582 - err("unable to start root hub"); 7.1583 - } 7.1584 - 7.1585 - /* Allocate the appropriate USB bandwidth here... Need to 7.1586 - * somehow know what the total available is thought to be so we 7.1587 - * can calculate the reservation correctly. */ 7.1588 - usb_claim_bandwidth(xhci->rh.dev, xhci->rh.urb, 7.1589 - 1000 - xhci->bandwidth, 0); 7.1590 - 7.1591 - if ( (rc = request_irq(xhci->irq, xhci_interrupt, 7.1592 - SA_SAMPLE_RANDOM, "usbif", xhci)) ) 7.1593 - printk(KERN_ALERT"usbfront request_irq failed (%ld)\n",rc); 7.1594 - 7.1595 - printk(KERN_INFO __FILE__ ": USB XHCI: SHM at %p (0x%lx), EVTCHN %d IRQ %d\n", 7.1596 - xhci->usbif, virt_to_machine(xhci->usbif), xhci->evtchn, xhci->irq); 7.1597 - 7.1598 - xhci->state = USBIF_STATE_CONNECTED; 7.1599 - 7.1600 - break; 7.1601 - 7.1602 - default: 7.1603 - printk(KERN_WARNING "Status change to unknown value %d\n", 7.1604 - status->status); 7.1605 - break; 7.1606 - } 7.1607 -} 7.1608 - 7.1609 - 7.1610 -static void usbif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 7.1611 -{ 7.1612 - switch ( msg->subtype ) 7.1613 - { 7.1614 - case CMSG_USBIF_FE_INTERFACE_STATUS_CHANGED: 7.1615 - if ( msg->length != sizeof(usbif_fe_interface_status_changed_t) ) 7.1616 - goto parse_error; 7.1617 - usbif_status_change((usbif_fe_interface_status_changed_t *) 7.1618 - &msg->msg[0]); 7.1619 - break; 7.1620 - 7.1621 - /* New interface...? */ 7.1622 - default: 7.1623 - goto parse_error; 7.1624 - } 7.1625 - 7.1626 - ctrl_if_send_response(msg); 7.1627 - return; 7.1628 - 7.1629 - parse_error: 7.1630 - msg->length = 0; 7.1631 - ctrl_if_send_response(msg); 7.1632 -} 7.1633 - 7.1634 - 7.1635 -static int __init xhci_hcd_init(void) 7.1636 -{ 7.1637 - int retval = -ENOMEM, i; 7.1638 - usbif_fe_interface_status_changed_t st; 7.1639 - control_msg_t cmsg; 7.1640 - 7.1641 - if ( (xen_start_info.flags & SIF_INITDOMAIN) 7.1642 - || (xen_start_info.flags & SIF_USB_BE_DOMAIN) ) 7.1643 - return 0; 7.1644 - 7.1645 - info(DRIVER_DESC " " DRIVER_VERSION); 7.1646 - 7.1647 - if (debug) { 7.1648 - errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); 7.1649 - if (!errbuf) 7.1650 - goto errbuf_failed; 7.1651 - } 7.1652 - 7.1653 - xhci_up_cachep = kmem_cache_create("xhci_urb_priv", 7.1654 - sizeof(struct urb_priv), 0, 0, NULL, NULL); 7.1655 - if (!xhci_up_cachep) 7.1656 - goto up_failed; 7.1657 - 7.1658 - /* Lazily avoid unloading issues for now. ;-)*/ 7.1659 - MOD_INC_USE_COUNT; 7.1660 - 7.1661 - /* Let the domain controller know we're here. For now we wait until 7.1662 - * connection, as for the block and net drivers. This is only strictly 7.1663 - * necessary if we're going to boot off a USB device. */ 7.1664 - printk(KERN_INFO "Initialising Xen virtual USB hub\n"); 7.1665 - 7.1666 - (void)ctrl_if_register_receiver(CMSG_USBIF_FE, usbif_ctrlif_rx, 7.1667 - CALLBACK_IN_BLOCKING_CONTEXT); 7.1668 - 7.1669 - alloc_xhci(); 7.1670 - 7.1671 - /* Send a driver-UP notification to the domain controller. */ 7.1672 - cmsg.type = CMSG_USBIF_FE; 7.1673 - cmsg.subtype = CMSG_USBIF_FE_DRIVER_STATUS_CHANGED; 7.1674 - cmsg.length = sizeof(usbif_fe_driver_status_changed_t); 7.1675 - st.status = USBIF_DRIVER_STATUS_UP; 7.1676 - memcpy(cmsg.msg, &st, sizeof(st)); 7.1677 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 7.1678 - 7.1679 - /* 7.1680 - * We should read 'nr_interfaces' from response message and wait 7.1681 - * for notifications before proceeding. For now we assume that we 7.1682 - * will be notified of exactly one interface. 7.1683 - */ 7.1684 - for ( i=0; (xhci->state != USBIF_STATE_CONNECTED) && (i < 10*HZ); i++ ) 7.1685 - { 7.1686 - set_current_state(TASK_INTERRUPTIBLE); 7.1687 - schedule_timeout(1); 7.1688 - } 7.1689 - 7.1690 - if (xhci->state != USBIF_STATE_CONNECTED) 7.1691 - printk(KERN_INFO "Timeout connecting USB frontend driver!\n"); 7.1692 - 7.1693 - return 0; 7.1694 - 7.1695 -up_failed: 7.1696 - 7.1697 - if (errbuf) 7.1698 - kfree(errbuf); 7.1699 - 7.1700 -errbuf_failed: 7.1701 - 7.1702 - return retval; 7.1703 -} 7.1704 - 7.1705 -static void __exit xhci_hcd_cleanup(void) 7.1706 -{ 7.1707 - if (kmem_cache_destroy(xhci_up_cachep)) 7.1708 - printk(KERN_INFO "xhci: not all urb_priv's were freed\n"); 7.1709 - 7.1710 -// release_xhci(); do some calls here 7.1711 - 7.1712 - 7.1713 - if (errbuf) 7.1714 - kfree(errbuf); 7.1715 -} 7.1716 - 7.1717 -module_init(xhci_hcd_init); 7.1718 -module_exit(xhci_hcd_cleanup); 7.1719 - 7.1720 -MODULE_AUTHOR(DRIVER_AUTHOR); 7.1721 -MODULE_DESCRIPTION(DRIVER_DESC); 7.1722 -MODULE_LICENSE("GPL"); 7.1723 -
8.1 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/frontend/xhci.h Fri Jan 28 07:59:39 2005 +0000 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,210 +0,0 @@ 8.4 -#ifndef __LINUX_XHCI_H 8.5 -#define __LINUX_XHCI_H 8.6 - 8.7 -#include <linux/list.h> 8.8 -#include <linux/usb.h> 8.9 -#include "../usbif.h" 8.10 -#include <linux/spinlock.h> 8.11 - 8.12 -#define XHCI_NUMFRAMES 1024 /* in the frame list [array] */ 8.13 -#define XHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ 8.14 -#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ 8.15 - 8.16 -/* In the absence of actual hardware state, we maintain the current known state 8.17 - * of the virtual hub ports in this data structure. 8.18 - */ 8.19 -typedef struct 8.20 -{ 8.21 - unsigned int cs :1; /* Connection status. do we really need this /and/ ccs? */ 8.22 - unsigned int cs_chg :1; /* Connection status change. */ 8.23 - unsigned int pe :1; /* Port enable. */ 8.24 - unsigned int pe_chg :1; /* Port enable change. */ 8.25 - unsigned int ccs :1; /* Current connect status. */ 8.26 - unsigned int susp :1; /* Suspended. */ 8.27 - unsigned int lsda :1; /* Low speed device attached. */ 8.28 - unsigned int pr :1; /* Port reset. */ 8.29 - 8.30 - /* Device info? */ 8.31 -} xhci_port_t; 8.32 - 8.33 -struct xhci_frame_list { 8.34 - __u32 frame[XHCI_NUMFRAMES]; 8.35 - 8.36 - void *frame_cpu[XHCI_NUMFRAMES]; 8.37 -}; 8.38 - 8.39 -struct urb_priv; 8.40 - 8.41 -#define xhci_status_bits(ctrl_sts) (ctrl_sts & 0xFE0000) 8.42 -#define xhci_actual_length(ctrl_sts) ((ctrl_sts + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */ 8.43 - 8.44 -#define xhci_maxlen(token) ((token) >> 21) 8.45 -#define xhci_expected_length(info) (((info >> 21) + 1) & TD_TOKEN_EXPLEN_MASK) /* 1-based */ 8.46 -#define xhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1) 8.47 -#define xhci_endpoint(token) (((token) >> 15) & 0xf) 8.48 -#define xhci_devaddr(token) (((token) >> 8) & 0x7f) 8.49 -#define xhci_devep(token) (((token) >> 8) & 0x7ff) 8.50 -#define xhci_packetid(token) ((token) & TD_TOKEN_PID_MASK) 8.51 -#define xhci_packetout(token) (xhci_packetid(token) != USB_PID_IN) 8.52 -#define xhci_packetin(token) (xhci_packetid(token) == USB_PID_IN) 8.53 - 8.54 -struct virt_root_hub { 8.55 - struct usb_device *dev; 8.56 - int devnum; /* Address of Root Hub endpoint */ 8.57 - struct urb *urb; 8.58 - void *int_addr; 8.59 - int send; 8.60 - int interval; 8.61 - int numports; 8.62 - int c_p_r[8]; 8.63 - struct timer_list rh_int_timer; 8.64 - spinlock_t port_state_lock; 8.65 - xhci_port_t *ports; /* */ 8.66 -}; 8.67 - 8.68 -/* 8.69 - * This describes the full xhci information. 8.70 - * 8.71 - * Note how the "proper" USB information is just 8.72 - * a subset of what the full implementation needs. 8.73 - */ 8.74 -struct xhci { 8.75 - 8.76 -#ifdef CONFIG_PROC_FS 8.77 - /* procfs */ 8.78 - int num; 8.79 - struct proc_dir_entry *proc_entry; 8.80 -#endif 8.81 - 8.82 - int evtchn; /* Interdom channel to backend */ 8.83 - int irq; /* Bound to evtchn */ 8.84 - int state; /* State of this USB interface */ 8.85 - unsigned long bandwidth; 8.86 - int handle; 8.87 - 8.88 - struct usb_bus *bus; 8.89 - 8.90 - spinlock_t frame_list_lock; 8.91 - struct xhci_frame_list *fl; /* P: xhci->frame_list_lock */ 8.92 - int is_suspended; 8.93 - 8.94 - /* Main list of URB's currently controlled by this HC */ 8.95 - spinlock_t urb_list_lock; 8.96 - struct list_head urb_list; /* P: xhci->urb_list_lock */ 8.97 - 8.98 - /* List of asynchronously unlinked URB's */ 8.99 - spinlock_t urb_remove_list_lock; 8.100 - struct list_head urb_remove_list; /* P: xhci->urb_remove_list_lock */ 8.101 - 8.102 - /* List of URB's awaiting completion callback */ 8.103 - spinlock_t complete_list_lock; 8.104 - struct list_head complete_list; /* P: xhci->complete_list_lock */ 8.105 - 8.106 - struct virt_root_hub rh; /* private data of the virtual root hub */ 8.107 - 8.108 - spinlock_t response_lock; 8.109 - 8.110 - usbif_t *usbif; 8.111 - int usb_resp_cons; 8.112 -}; 8.113 - 8.114 -struct urb_priv { 8.115 - struct urb *urb; 8.116 - usbif_iso_t *schedule; 8.117 - struct usb_device *dev; 8.118 - 8.119 - int in_progress : 1; /* QH was queued (not linked in) */ 8.120 - int short_control_packet : 1; /* If we get a short packet during */ 8.121 - /* a control transfer, retrigger */ 8.122 - /* the status phase */ 8.123 - 8.124 - int status; /* Final status */ 8.125 - 8.126 - unsigned long inserttime; /* In jiffies */ 8.127 - 8.128 - struct list_head queue_list; /* P: xhci->frame_list_lock */ 8.129 - struct list_head complete_list; /* P: xhci->complete_list_lock */ 8.130 -}; 8.131 - 8.132 -/* 8.133 - * Locking in xhci.c 8.134 - * 8.135 - * spinlocks are used extensively to protect the many lists and data 8.136 - * structures we have. It's not that pretty, but it's necessary. We 8.137 - * need to be done with all of the locks (except complete_list_lock) when 8.138 - * we call urb->complete. I've tried to make it simple enough so I don't 8.139 - * have to spend hours racking my brain trying to figure out if the 8.140 - * locking is safe. 8.141 - * 8.142 - * Here's the safe locking order to prevent deadlocks: 8.143 - * 8.144 - * #1 xhci->urb_list_lock 8.145 - * #2 urb->lock 8.146 - * #3 xhci->urb_remove_list_lock, xhci->frame_list_lock, 8.147 - * xhci->qh_remove_list_lock 8.148 - * #4 xhci->complete_list_lock 8.149 - * 8.150 - * If you're going to grab 2 or more locks at once, ALWAYS grab the lock 8.151 - * at the lowest level FIRST and NEVER grab locks at the same level at the 8.152 - * same time. 8.153 - * 8.154 - * So, if you need xhci->urb_list_lock, grab it before you grab urb->lock 8.155 - */ 8.156 - 8.157 -/* ------------------------------------------------------------------------- 8.158 - Virtual Root HUB 8.159 - ------------------------------------------------------------------------- */ 8.160 -/* destination of request */ 8.161 -#define RH_DEVICE 0x00 8.162 -#define RH_INTERFACE 0x01 8.163 -#define RH_ENDPOINT 0x02 8.164 -#define RH_OTHER 0x03 8.165 - 8.166 -#define RH_CLASS 0x20 8.167 -#define RH_VENDOR 0x40 8.168 - 8.169 -/* Requests: bRequest << 8 | bmRequestType */ 8.170 -#define RH_GET_STATUS 0x0080 8.171 -#define RH_CLEAR_FEATURE 0x0100 8.172 -#define RH_SET_FEATURE 0x0300 8.173 -#define RH_SET_ADDRESS 0x0500 8.174 -#define RH_GET_DESCRIPTOR 0x0680 8.175 -#define RH_SET_DESCRIPTOR 0x0700 8.176 -#define RH_GET_CONFIGURATION 0x0880 8.177 -#define RH_SET_CONFIGURATION 0x0900 8.178 -#define RH_GET_STATE 0x0280 8.179 -#define RH_GET_INTERFACE 0x0A80 8.180 -#define RH_SET_INTERFACE 0x0B00 8.181 -#define RH_SYNC_FRAME 0x0C80 8.182 -/* Our Vendor Specific Request */ 8.183 -#define RH_SET_EP 0x2000 8.184 - 8.185 -/* Hub port features */ 8.186 -#define RH_PORT_CONNECTION 0x00 8.187 -#define RH_PORT_ENABLE 0x01 8.188 -#define RH_PORT_SUSPEND 0x02 8.189 -#define RH_PORT_OVER_CURRENT 0x03 8.190 -#define RH_PORT_RESET 0x04 8.191 -#define RH_PORT_POWER 0x08 8.192 -#define RH_PORT_LOW_SPEED 0x09 8.193 -#define RH_C_PORT_CONNECTION 0x10 8.194 -#define RH_C_PORT_ENABLE 0x11 8.195 -#define RH_C_PORT_SUSPEND 0x12 8.196 -#define RH_C_PORT_OVER_CURRENT 0x13 8.197 -#define RH_C_PORT_RESET 0x14 8.198 - 8.199 -/* Hub features */ 8.200 -#define RH_C_HUB_LOCAL_POWER 0x00 8.201 -#define RH_C_HUB_OVER_CURRENT 0x01 8.202 -#define RH_DEVICE_REMOTE_WAKEUP 0x00 8.203 -#define RH_ENDPOINT_STALL 0x01 8.204 - 8.205 -/* Our Vendor Specific feature */ 8.206 -#define RH_REMOVE_EP 0x00 8.207 - 8.208 -#define RH_ACK 0x01 8.209 -#define RH_REQ_ERR -1 8.210 -#define RH_NACK 0x00 8.211 - 8.212 -#endif 8.213 -
9.1 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/usbif.h Fri Jan 28 07:59:39 2005 +0000 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,111 +0,0 @@ 9.4 -/****************************************************************************** 9.5 - * usbif.h 9.6 - * 9.7 - * Unified block-device I/O interface for Xen guest OSes. 9.8 - * 9.9 - * Copyright (c) 2003-2004, Keir Fraser 9.10 - */ 9.11 - 9.12 -#ifndef __SHARED_USBIF_H__ 9.13 -#define __SHARED_USBIF_H__ 9.14 - 9.15 -#define usbif_vdev_t u16 9.16 -#define usbif_sector_t u64 9.17 - 9.18 -#define USBIF_OP_IO 0 9.19 -#define USBIF_OP_PROBE 1 /* Is there a device on this port? */ 9.20 -#define USBIF_OP_RESET 2 /* Reset a virtual USB port. */ 9.21 - 9.22 -/* NB. Ring size must be small enough for sizeof(usbif_ring_t) <= PAGE_SIZE. */ 9.23 -#define USBIF_RING_SIZE 64 9.24 - 9.25 -/* XXX this does not want to be here! it really ought to be dynamic but it can 9.26 - * live here for now */ 9.27 -#define NUM_PORTS 1 9.28 - 9.29 -typedef struct { 9.30 - unsigned long id; /* 0: private guest value, echoed in resp */ 9.31 - u8 operation; /* 4: USBIF_OP_??? */ 9.32 - u8 __pad1; 9.33 - usbif_vdev_t port; /* 6 : guest virtual USB port */ 9.34 - unsigned long devnum :7; /* 8 : Device address, as seen by the guest.*/ 9.35 - unsigned long endpoint :4; /* Device endpoint. */ 9.36 - unsigned long direction :1; /* Pipe direction. */ 9.37 - unsigned long speed :1; /* Pipe speed. */ 9.38 - unsigned long pipe_type :2; /* Pipe type (iso, bulk, int, ctrl) */ 9.39 - unsigned long __pad2 :18; 9.40 - unsigned long transfer_buffer; /* 12: Machine address */ 9.41 - unsigned long length; /* 16: Buffer length */ 9.42 - unsigned long transfer_flags; /* 20: For now just pass Linux transfer 9.43 - * flags - this may change. */ 9.44 - unsigned char setup[8]; /* 22 Embed setup packets directly. */ 9.45 - unsigned long iso_schedule; /* 30 Machine address of transfer sched (iso 9.46 - * only) */ 9.47 - unsigned long num_iso; /* 34 : length of iso schedule */ 9.48 - unsigned long timeout; /* 38: timeout in ms */ 9.49 -} PACKED usbif_request_t; /* 42 */ 9.50 -/* Data we need to pass: 9.51 - * - Transparently handle short packets or complain at us? 9.52 - */ 9.53 - 9.54 -typedef struct { 9.55 - unsigned long id; /* 0: copied from request */ 9.56 - u8 operation; /* 4: copied from request */ 9.57 - u8 data; /* 5: Small chunk of in-band data */ 9.58 - s16 status; /* 6: USBIF_RSP_??? */ 9.59 - unsigned long transfer_mutex; /* Used for cancelling requests atomically. */ 9.60 - unsigned long length; /* 8: How much data we really got */ 9.61 -} PACKED usbif_response_t; 9.62 - 9.63 -#define USBIF_RSP_ERROR -1 /* non-specific 'error' */ 9.64 -#define USBIF_RSP_OKAY 0 /* non-specific 'okay' */ 9.65 - 9.66 -/* 9.67 - * We use a special capitalised type name because it is _essential_ that all 9.68 - * arithmetic on indexes is done on an integer type of the correct size. 9.69 - */ 9.70 -typedef u32 USBIF_RING_IDX; 9.71 - 9.72 -/* 9.73 - * Ring indexes are 'free running'. That is, they are not stored modulo the 9.74 - * size of the ring buffer. The following macro converts a free-running counter 9.75 - * into a value that can directly index a ring-buffer array. 9.76 - */ 9.77 -#define MASK_USBIF_IDX(_i) ((_i)&(USBIF_RING_SIZE-1)) 9.78 - 9.79 -typedef struct { 9.80 - USBIF_RING_IDX req_prod; /* 0: Request producer. Updated by front-end. */ 9.81 - USBIF_RING_IDX resp_prod; /* 4: Response producer. Updated by back-end. */ 9.82 - 9.83 - union { /* 8 */ 9.84 - usbif_request_t req; 9.85 - usbif_response_t resp; 9.86 - } PACKED ring[USBIF_RING_SIZE]; 9.87 -} PACKED usbif_t; 9.88 - 9.89 - 9.90 - 9.91 -/* 9.92 - * USBIF_OP_PROBE: 9.93 - * The request format for a probe request is constrained as follows: 9.94 - * @operation == USBIF_OP_PROBE 9.95 - * @nr_segments == size of probe buffer in pages 9.96 - * @device == unused (zero) 9.97 - * @id == any value (echoed in response message) 9.98 - * @sector_num == unused (zero) 9.99 - * @frame_and_sects == list of page-sized buffers. 9.100 - * (i.e., @first_sect == 0, @last_sect == 7). 9.101 - * 9.102 - * The response is a list of vdisk_t elements copied into the out-of-band 9.103 - * probe buffer. On success the response status field contains the number 9.104 - * of vdisk_t elements. 9.105 - */ 9.106 - 9.107 -typedef struct { 9.108 - unsigned long length; /* IN = expected, OUT = actual */ 9.109 - unsigned long buffer_offset; /* IN offset in buffer specified in main 9.110 - packet */ 9.111 - unsigned long status; /* OUT Status for this packet. */ 9.112 -} usbif_iso_t; 9.113 - 9.114 -#endif /* __SHARED_USBIF_H__ */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/linux-2.4.29-xen-sparse/drivers/usb/hcd.c Fri Jan 28 14:53:32 2005 +0000 10.3 @@ -0,0 +1,1511 @@ 10.4 +/* 10.5 + * Copyright (c) 2001-2002 by David Brownell 10.6 + * 10.7 + * This program is free software; you can redistribute it and/or modify it 10.8 + * under the terms of the GNU General Public License as published by the 10.9 + * Free Software Foundation; either version 2 of the License, or (at your 10.10 + * option) any later version. 10.11 + * 10.12 + * This program is distributed in the hope that it will be useful, but 10.13 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 10.14 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.15 + * for more details. 10.16 + * 10.17 + * You should have received a copy of the GNU General Public License 10.18 + * along with this program; if not, write to the Free Software Foundation, 10.19 + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 10.20 + */ 10.21 + 10.22 +#include <linux/config.h> 10.23 +#include <linux/module.h> 10.24 +#include <linux/pci.h> 10.25 +#include <linux/kernel.h> 10.26 +#include <linux/delay.h> 10.27 +#include <linux/ioport.h> 10.28 +#include <linux/sched.h> 10.29 +#include <linux/slab.h> 10.30 +#include <linux/smp_lock.h> 10.31 +#include <linux/errno.h> 10.32 +#include <linux/kmod.h> 10.33 +#include <linux/init.h> 10.34 +#include <linux/timer.h> 10.35 +#include <linux/list.h> 10.36 +#include <linux/interrupt.h> 10.37 +#include <linux/completion.h> 10.38 +#include <linux/uts.h> /* for UTS_SYSNAME */ 10.39 + 10.40 + 10.41 +#ifdef CONFIG_USB_DEBUG 10.42 + #define DEBUG 10.43 +#else 10.44 + #undef DEBUG 10.45 +#endif 10.46 + 10.47 +#include <linux/usb.h> 10.48 +#include "hcd.h" 10.49 + 10.50 +#include <asm/io.h> 10.51 +#include <asm/irq.h> 10.52 +#include <asm/system.h> 10.53 +#include <asm/unaligned.h> 10.54 + 10.55 + 10.56 +/*-------------------------------------------------------------------------*/ 10.57 + 10.58 +/* 10.59 + * USB Host Controller Driver framework 10.60 + * 10.61 + * Plugs into usbcore (usb_bus) and lets HCDs share code, minimizing 10.62 + * HCD-specific behaviors/bugs. Think of it as the "upper level" of 10.63 + * some drivers, where the "lower level" is hardware-specific. 10.64 + * 10.65 + * This does error checks, tracks devices and urbs, and delegates to a 10.66 + * "hc_driver" only for code (and data) that really needs to know about 10.67 + * hardware differences. That includes root hub registers, i/o queues, 10.68 + * and so on ... but as little else as possible. 10.69 + * 10.70 + * Shared code includes most of the "root hub" code (these are emulated, 10.71 + * though each HC's hardware works differently) and PCI glue, plus request 10.72 + * tracking overhead. The HCD code should only block on spinlocks or on 10.73 + * hardware handshaking; blocking on software events (such as other kernel 10.74 + * threads releasing resources, or completing actions) is all generic. 10.75 + * 10.76 + * Happens the USB 2.0 spec says this would be invisible inside the "USBD", 10.77 + * and includes mostly a "HCDI" (HCD Interface) along with some APIs used 10.78 + * only by the hub driver ... and that neither should be seen or used by 10.79 + * usb client device drivers. 10.80 + * 10.81 + * Contributors of ideas or unattributed patches include: David Brownell, 10.82 + * Roman Weissgaerber, Rory Bolt, ... 10.83 + * 10.84 + * HISTORY: 10.85 + * 2002-sept Merge some 2.5 updates so we can share hardware level HCD 10.86 + * code between the 2.4.20+ and 2.5 trees. 10.87 + * 2002-feb merge to 2.4.19 10.88 + * 2001-12-12 Initial patch version for Linux 2.5.1 kernel. 10.89 + */ 10.90 + 10.91 +/*-------------------------------------------------------------------------*/ 10.92 + 10.93 +/* host controllers we manage */ 10.94 +static LIST_HEAD (hcd_list); 10.95 + 10.96 +/* used when updating list of hcds */ 10.97 +static DECLARE_MUTEX (hcd_list_lock); 10.98 + 10.99 +/* used when updating hcd data */ 10.100 +static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED; 10.101 + 10.102 +static struct usb_operations hcd_operations; 10.103 + 10.104 +/*-------------------------------------------------------------------------*/ 10.105 + 10.106 +/* 10.107 + * Sharable chunks of root hub code. 10.108 + */ 10.109 + 10.110 +/*-------------------------------------------------------------------------*/ 10.111 + 10.112 +#define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff) 10.113 +#define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff) 10.114 + 10.115 +/* usb 2.0 root hub device descriptor */ 10.116 +static const u8 usb2_rh_dev_descriptor [18] = { 10.117 + 0x12, /* __u8 bLength; */ 10.118 + 0x01, /* __u8 bDescriptorType; Device */ 10.119 + 0x00, 0x02, /* __u16 bcdUSB; v2.0 */ 10.120 + 10.121 + 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 10.122 + 0x00, /* __u8 bDeviceSubClass; */ 10.123 + 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ 10.124 + 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ 10.125 + 10.126 + 0x00, 0x00, /* __u16 idVendor; */ 10.127 + 0x00, 0x00, /* __u16 idProduct; */ 10.128 + KERNEL_VER, KERNEL_REL, /* __u16 bcdDevice */ 10.129 + 10.130 + 0x03, /* __u8 iManufacturer; */ 10.131 + 0x02, /* __u8 iProduct; */ 10.132 + 0x01, /* __u8 iSerialNumber; */ 10.133 + 0x01 /* __u8 bNumConfigurations; */ 10.134 +}; 10.135 + 10.136 +/* no usb 2.0 root hub "device qualifier" descriptor: one speed only */ 10.137 + 10.138 +/* usb 1.1 root hub device descriptor */ 10.139 +static const u8 usb11_rh_dev_descriptor [18] = { 10.140 + 0x12, /* __u8 bLength; */ 10.141 + 0x01, /* __u8 bDescriptorType; Device */ 10.142 + 0x10, 0x01, /* __u16 bcdUSB; v1.1 */ 10.143 + 10.144 + 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 10.145 + 0x00, /* __u8 bDeviceSubClass; */ 10.146 + 0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ 10.147 + 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ 10.148 + 10.149 + 0x00, 0x00, /* __u16 idVendor; */ 10.150 + 0x00, 0x00, /* __u16 idProduct; */ 10.151 + KERNEL_VER, KERNEL_REL, /* __u16 bcdDevice */ 10.152 + 10.153 + 0x03, /* __u8 iManufacturer; */ 10.154 + 0x02, /* __u8 iProduct; */ 10.155 + 0x01, /* __u8 iSerialNumber; */ 10.156 + 0x01 /* __u8 bNumConfigurations; */ 10.157 +}; 10.158 + 10.159 + 10.160 +/*-------------------------------------------------------------------------*/ 10.161 + 10.162 +/* Configuration descriptors for our root hubs */ 10.163 + 10.164 +static const u8 fs_rh_config_descriptor [] = { 10.165 + 10.166 + /* one configuration */ 10.167 + 0x09, /* __u8 bLength; */ 10.168 + 0x02, /* __u8 bDescriptorType; Configuration */ 10.169 + 0x19, 0x00, /* __u16 wTotalLength; */ 10.170 + 0x01, /* __u8 bNumInterfaces; (1) */ 10.171 + 0x01, /* __u8 bConfigurationValue; */ 10.172 + 0x00, /* __u8 iConfiguration; */ 10.173 + 0x40, /* __u8 bmAttributes; 10.174 + Bit 7: Bus-powered, 10.175 + 6: Self-powered, 10.176 + 5 Remote-wakwup, 10.177 + 4..0: resvd */ 10.178 + 0x00, /* __u8 MaxPower; */ 10.179 + 10.180 + /* USB 1.1: 10.181 + * USB 2.0, single TT organization (mandatory): 10.182 + * one interface, protocol 0 10.183 + * 10.184 + * USB 2.0, multiple TT organization (optional): 10.185 + * two interfaces, protocols 1 (like single TT) 10.186 + * and 2 (multiple TT mode) ... config is 10.187 + * sometimes settable 10.188 + * NOT IMPLEMENTED 10.189 + */ 10.190 + 10.191 + /* one interface */ 10.192 + 0x09, /* __u8 if_bLength; */ 10.193 + 0x04, /* __u8 if_bDescriptorType; Interface */ 10.194 + 0x00, /* __u8 if_bInterfaceNumber; */ 10.195 + 0x00, /* __u8 if_bAlternateSetting; */ 10.196 + 0x01, /* __u8 if_bNumEndpoints; */ 10.197 + 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ 10.198 + 0x00, /* __u8 if_bInterfaceSubClass; */ 10.199 + 0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ 10.200 + 0x00, /* __u8 if_iInterface; */ 10.201 + 10.202 + /* one endpoint (status change endpoint) */ 10.203 + 0x07, /* __u8 ep_bLength; */ 10.204 + 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 10.205 + 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 10.206 + 0x03, /* __u8 ep_bmAttributes; Interrupt */ 10.207 + 0x02, 0x00, /* __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ 10.208 + 0xff /* __u8 ep_bInterval; (255ms -- usb 2.0 spec) */ 10.209 +}; 10.210 + 10.211 +static const u8 hs_rh_config_descriptor [] = { 10.212 + 10.213 + /* one configuration */ 10.214 + 0x09, /* __u8 bLength; */ 10.215 + 0x02, /* __u8 bDescriptorType; Configuration */ 10.216 + 0x19, 0x00, /* __u16 wTotalLength; */ 10.217 + 0x01, /* __u8 bNumInterfaces; (1) */ 10.218 + 0x01, /* __u8 bConfigurationValue; */ 10.219 + 0x00, /* __u8 iConfiguration; */ 10.220 + 0x40, /* __u8 bmAttributes; 10.221 + Bit 7: Bus-powered, 10.222 + 6: Self-powered, 10.223 + 5 Remote-wakwup, 10.224 + 4..0: resvd */ 10.225 + 0x00, /* __u8 MaxPower; */ 10.226 + 10.227 + /* USB 1.1: 10.228 + * USB 2.0, single TT organization (mandatory): 10.229 + * one interface, protocol 0 10.230 + * 10.231 + * USB 2.0, multiple TT organization (optional): 10.232 + * two interfaces, protocols 1 (like single TT) 10.233 + * and 2 (multiple TT mode) ... config is 10.234 + * sometimes settable 10.235 + * NOT IMPLEMENTED 10.236 + */ 10.237 + 10.238 + /* one interface */ 10.239 + 0x09, /* __u8 if_bLength; */ 10.240 + 0x04, /* __u8 if_bDescriptorType; Interface */ 10.241 + 0x00, /* __u8 if_bInterfaceNumber; */ 10.242 + 0x00, /* __u8 if_bAlternateSetting; */ 10.243 + 0x01, /* __u8 if_bNumEndpoints; */ 10.244 + 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ 10.245 + 0x00, /* __u8 if_bInterfaceSubClass; */ 10.246 + 0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ 10.247 + 0x00, /* __u8 if_iInterface; */ 10.248 + 10.249 + /* one endpoint (status change endpoint) */ 10.250 + 0x07, /* __u8 ep_bLength; */ 10.251 + 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 10.252 + 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 10.253 + 0x03, /* __u8 ep_bmAttributes; Interrupt */ 10.254 + 0x02, 0x00, /* __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ 10.255 + 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ 10.256 +}; 10.257 + 10.258 +/*-------------------------------------------------------------------------*/ 10.259 + 10.260 +/* 10.261 + * helper routine for returning string descriptors in UTF-16LE 10.262 + * input can actually be ISO-8859-1; ASCII is its 7-bit subset 10.263 + */ 10.264 +static int ascii2utf (char *s, u8 *utf, int utfmax) 10.265 +{ 10.266 + int retval; 10.267 + 10.268 + for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { 10.269 + *utf++ = *s++; 10.270 + *utf++ = 0; 10.271 + } 10.272 + return retval; 10.273 +} 10.274 + 10.275 +/* 10.276 + * rh_string - provides manufacturer, product and serial strings for root hub 10.277 + * @id: the string ID number (1: serial number, 2: product, 3: vendor) 10.278 + * @pci_desc: PCI device descriptor for the relevant HC 10.279 + * @type: string describing our driver 10.280 + * @data: return packet in UTF-16 LE 10.281 + * @len: length of the return packet 10.282 + * 10.283 + * Produces either a manufacturer, product or serial number string for the 10.284 + * virtual root hub device. 10.285 + */ 10.286 +static int rh_string ( 10.287 + int id, 10.288 + struct usb_hcd *hcd, 10.289 + u8 *data, 10.290 + int len 10.291 +) { 10.292 + char buf [100]; 10.293 + 10.294 + // language ids 10.295 + if (id == 0) { 10.296 + *data++ = 4; *data++ = 3; /* 4 bytes string data */ 10.297 + *data++ = 0; *data++ = 0; /* some language id */ 10.298 + return 4; 10.299 + 10.300 + // serial number 10.301 + } else if (id == 1) { 10.302 + strcpy (buf, hcd->bus->bus_name); 10.303 + 10.304 + // product description 10.305 + } else if (id == 2) { 10.306 + strcpy (buf, hcd->product_desc); 10.307 + 10.308 + // id 3 == vendor description 10.309 + } else if (id == 3) { 10.310 + sprintf (buf, "%s %s %s", UTS_SYSNAME, UTS_RELEASE, 10.311 + hcd->description); 10.312 + 10.313 + // unsupported IDs --> "protocol stall" 10.314 + } else 10.315 + return 0; 10.316 + 10.317 + data [0] = 2 * (strlen (buf) + 1); 10.318 + data [1] = 3; /* type == string */ 10.319 + return 2 + ascii2utf (buf, data + 2, len - 2); 10.320 +} 10.321 + 10.322 + 10.323 +/* Root hub control transfers execute synchronously */ 10.324 +static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) 10.325 +{ 10.326 + struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet; 10.327 + u16 typeReq, wValue, wIndex, wLength; 10.328 + const u8 *bufp = 0; 10.329 + u8 *ubuf = urb->transfer_buffer; 10.330 + int len = 0; 10.331 + 10.332 + typeReq = (cmd->bRequestType << 8) | cmd->bRequest; 10.333 + wValue = le16_to_cpu (cmd->wValue); 10.334 + wIndex = le16_to_cpu (cmd->wIndex); 10.335 + wLength = le16_to_cpu (cmd->wLength); 10.336 + 10.337 + if (wLength > urb->transfer_buffer_length) 10.338 + goto error; 10.339 + 10.340 + /* set up for success */ 10.341 + urb->status = 0; 10.342 + urb->actual_length = wLength; 10.343 + switch (typeReq) { 10.344 + 10.345 + /* DEVICE REQUESTS */ 10.346 + 10.347 + case DeviceRequest | USB_REQ_GET_STATUS: 10.348 + // DEVICE_REMOTE_WAKEUP 10.349 + ubuf [0] = 1; // selfpowered 10.350 + ubuf [1] = 0; 10.351 + /* FALLTHROUGH */ 10.352 + case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: 10.353 + case DeviceOutRequest | USB_REQ_SET_FEATURE: 10.354 + dbg ("no device features yet yet"); 10.355 + break; 10.356 + case DeviceRequest | USB_REQ_GET_CONFIGURATION: 10.357 + ubuf [0] = 1; 10.358 + /* FALLTHROUGH */ 10.359 + case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: 10.360 + break; 10.361 + case DeviceRequest | USB_REQ_GET_DESCRIPTOR: 10.362 + switch (wValue & 0xff00) { 10.363 + case USB_DT_DEVICE << 8: 10.364 + if (hcd->driver->flags & HCD_USB2) 10.365 + bufp = usb2_rh_dev_descriptor; 10.366 + else if (hcd->driver->flags & HCD_USB11) 10.367 + bufp = usb11_rh_dev_descriptor; 10.368 + else 10.369 + goto error; 10.370 + len = 18; 10.371 + break; 10.372 + case USB_DT_CONFIG << 8: 10.373 + if (hcd->driver->flags & HCD_USB2) { 10.374 + bufp = hs_rh_config_descriptor; 10.375 + len = sizeof hs_rh_config_descriptor; 10.376 + } else { 10.377 + bufp = fs_rh_config_descriptor; 10.378 + len = sizeof fs_rh_config_descriptor; 10.379 + } 10.380 + break; 10.381 + case USB_DT_STRING << 8: 10.382 + urb->actual_length = rh_string ( 10.383 + wValue & 0xff, hcd, 10.384 + ubuf, wLength); 10.385 + break; 10.386 + default: 10.387 + goto error; 10.388 + } 10.389 + break; 10.390 + case DeviceRequest | USB_REQ_GET_INTERFACE: 10.391 + ubuf [0] = 0; 10.392 + /* FALLTHROUGH */ 10.393 + case DeviceOutRequest | USB_REQ_SET_INTERFACE: 10.394 + break; 10.395 + case DeviceOutRequest | USB_REQ_SET_ADDRESS: 10.396 + // wValue == urb->dev->devaddr 10.397 + dbg ("%s root hub device address %d", 10.398 + hcd->bus->bus_name, wValue); 10.399 + break; 10.400 + 10.401 + /* INTERFACE REQUESTS (no defined feature/status flags) */ 10.402 + 10.403 + /* ENDPOINT REQUESTS */ 10.404 + 10.405 + case EndpointRequest | USB_REQ_GET_STATUS: 10.406 + // ENDPOINT_HALT flag 10.407 + ubuf [0] = 0; 10.408 + ubuf [1] = 0; 10.409 + /* FALLTHROUGH */ 10.410 + case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: 10.411 + case EndpointOutRequest | USB_REQ_SET_FEATURE: 10.412 + dbg ("no endpoint features yet"); 10.413 + break; 10.414 + 10.415 + /* CLASS REQUESTS (and errors) */ 10.416 + 10.417 + default: 10.418 + /* non-generic request */ 10.419 + urb->status = hcd->driver->hub_control (hcd, 10.420 + typeReq, wValue, wIndex, 10.421 + ubuf, wLength); 10.422 + break; 10.423 +error: 10.424 + /* "protocol stall" on error */ 10.425 + urb->status = -EPIPE; 10.426 + dbg ("unsupported hub control message (maxchild %d)", 10.427 + urb->dev->maxchild); 10.428 + } 10.429 + if (urb->status) { 10.430 + urb->actual_length = 0; 10.431 + dbg ("CTRL: TypeReq=0x%x val=0x%x idx=0x%x len=%d ==> %d", 10.432 + typeReq, wValue, wIndex, wLength, urb->status); 10.433 + } 10.434 + if (bufp) { 10.435 + if (urb->transfer_buffer_length < len) 10.436 + len = urb->transfer_buffer_length; 10.437 + urb->actual_length = len; 10.438 + // always USB_DIR_IN, toward host 10.439 + memcpy (ubuf, bufp, len); 10.440 + } 10.441 + 10.442 + /* any errors get returned through the urb completion */ 10.443 + usb_hcd_giveback_urb (hcd, urb, 0); 10.444 + return 0; 10.445 +} 10.446 + 10.447 +/*-------------------------------------------------------------------------*/ 10.448 + 10.449 +/* 10.450 + * Root Hub interrupt transfers are synthesized with a timer. 10.451 + * Completions are called in_interrupt() but not in_irq(). 10.452 + */ 10.453 + 10.454 +static void rh_report_status (unsigned long ptr); 10.455 + 10.456 +static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb) 10.457 +{ 10.458 + int len = 1 + (urb->dev->maxchild / 8); 10.459 + 10.460 + /* rh_timer protected by hcd_data_lock */ 10.461 + if (timer_pending (&hcd->rh_timer) 10.462 + || urb->status != -EINPROGRESS 10.463 + || !HCD_IS_RUNNING (hcd->state) 10.464 + || urb->transfer_buffer_length < len) { 10.465 + dbg ("not queuing status urb, stat %d", urb->status); 10.466 + return -EINVAL; 10.467 + } 10.468 + 10.469 + urb->hcpriv = hcd; /* nonzero to indicate it's queued */ 10.470 + init_timer (&hcd->rh_timer); 10.471 + hcd->rh_timer.function = rh_report_status; 10.472 + hcd->rh_timer.data = (unsigned long) urb; 10.473 + /* USB 2.0 spec says 256msec; this is close enough */ 10.474 + hcd->rh_timer.expires = jiffies + HZ/4; 10.475 + add_timer (&hcd->rh_timer); 10.476 + return 0; 10.477 +} 10.478 + 10.479 +/* timer callback */ 10.480 + 10.481 +static void rh_report_status (unsigned long ptr) 10.482 +{ 10.483 + struct urb *urb; 10.484 + struct usb_hcd *hcd; 10.485 + int length; 10.486 + unsigned long flags; 10.487 + 10.488 + urb = (struct urb *) ptr; 10.489 + spin_lock_irqsave (&urb->lock, flags); 10.490 + if (!urb->dev) { 10.491 + spin_unlock_irqrestore (&urb->lock, flags); 10.492 + return; 10.493 + } 10.494 + 10.495 + hcd = urb->dev->bus->hcpriv; 10.496 + if (urb->status == -EINPROGRESS) { 10.497 + if (HCD_IS_RUNNING (hcd->state)) { 10.498 + length = hcd->driver->hub_status_data (hcd, 10.499 + urb->transfer_buffer); 10.500 + spin_unlock_irqrestore (&urb->lock, flags); 10.501 + if (length > 0) { 10.502 + urb->actual_length = length; 10.503 + urb->status = 0; 10.504 + urb->complete (urb); 10.505 + } 10.506 + spin_lock_irqsave (&hcd_data_lock, flags); 10.507 + urb->status = -EINPROGRESS; 10.508 + if (HCD_IS_RUNNING (hcd->state) 10.509 + && rh_status_urb (hcd, urb) != 0) { 10.510 + /* another driver snuck in? */ 10.511 + dbg ("%s, can't resubmit roothub status urb?", 10.512 + hcd->bus->bus_name); 10.513 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.514 + BUG (); 10.515 + } 10.516 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.517 + } else 10.518 + spin_unlock_irqrestore (&urb->lock, flags); 10.519 + } else { 10.520 + /* this urb's been unlinked */ 10.521 + urb->hcpriv = 0; 10.522 + spin_unlock_irqrestore (&urb->lock, flags); 10.523 + 10.524 + usb_hcd_giveback_urb (hcd, urb, 0); 10.525 + } 10.526 +} 10.527 + 10.528 +/*-------------------------------------------------------------------------*/ 10.529 + 10.530 +static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) 10.531 +{ 10.532 + if (usb_pipeint (urb->pipe)) { 10.533 + int retval; 10.534 + unsigned long flags; 10.535 + 10.536 + spin_lock_irqsave (&hcd_data_lock, flags); 10.537 + retval = rh_status_urb (hcd, urb); 10.538 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.539 + return retval; 10.540 + } 10.541 + if (usb_pipecontrol (urb->pipe)) 10.542 + return rh_call_control (hcd, urb); 10.543 + else 10.544 + return -EINVAL; 10.545 +} 10.546 + 10.547 +/*-------------------------------------------------------------------------*/ 10.548 + 10.549 +static void rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb) 10.550 +{ 10.551 + unsigned long flags; 10.552 + 10.553 + spin_lock_irqsave (&hcd_data_lock, flags); 10.554 + del_timer_sync (&hcd->rh_timer); 10.555 + hcd->rh_timer.data = 0; 10.556 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.557 + 10.558 + /* we rely on RH callback code not unlinking its URB! */ 10.559 + usb_hcd_giveback_urb (hcd, urb, 0); 10.560 +} 10.561 + 10.562 +/*-------------------------------------------------------------------------*/ 10.563 + 10.564 +#ifdef CONFIG_PCI 10.565 + 10.566 +/* PCI-based HCs are normal, but custom bus glue should be ok */ 10.567 + 10.568 +static void hcd_irq (int irq, void *__hcd, struct pt_regs *r); 10.569 +static void hc_died (struct usb_hcd *hcd); 10.570 + 10.571 +/*-------------------------------------------------------------------------*/ 10.572 + 10.573 +/* configure so an HC device and id are always provided */ 10.574 +/* always called with process context; sleeping is OK */ 10.575 + 10.576 +/** 10.577 + * usb_hcd_pci_probe - initialize PCI-based HCDs 10.578 + * @dev: USB Host Controller being probed 10.579 + * @id: pci hotplug id connecting controller to HCD framework 10.580 + * Context: !in_interrupt() 10.581 + * 10.582 + * Allocates basic PCI resources for this USB host controller, and 10.583 + * then invokes the start() method for the HCD associated with it 10.584 + * through the hotplug entry's driver_data. 10.585 + * 10.586 + * Store this function in the HCD's struct pci_driver as probe(). 10.587 + */ 10.588 +int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) 10.589 +{ 10.590 + struct hc_driver *driver; 10.591 + unsigned long resource, len; 10.592 + void *base; 10.593 + struct usb_bus *bus; 10.594 + struct usb_hcd *hcd; 10.595 + int retval, region; 10.596 + char buf [8], *bufp = buf; 10.597 + 10.598 + if (!id || !(driver = (struct hc_driver *) id->driver_data)) 10.599 + return -EINVAL; 10.600 + 10.601 + if (pci_enable_device (dev) < 0) 10.602 + return -ENODEV; 10.603 + 10.604 + if (!dev->irq) { 10.605 + err ("Found HC with no IRQ. Check BIOS/PCI %s setup!", 10.606 + dev->slot_name); 10.607 + return -ENODEV; 10.608 + } 10.609 + 10.610 + if (driver->flags & HCD_MEMORY) { // EHCI, OHCI 10.611 + region = 0; 10.612 + resource = pci_resource_start (dev, 0); 10.613 + len = pci_resource_len (dev, 0); 10.614 + if (!request_mem_region (resource, len, driver->description)) { 10.615 + dbg ("controller already in use"); 10.616 + return -EBUSY; 10.617 + } 10.618 + base = ioremap_nocache (resource, len); 10.619 + if (base == NULL) { 10.620 + dbg ("error mapping memory"); 10.621 + retval = -EFAULT; 10.622 +clean_1: 10.623 + release_mem_region (resource, len); 10.624 + err ("init %s fail, %d", dev->slot_name, retval); 10.625 + return retval; 10.626 + } 10.627 + 10.628 + } else { // UHCI 10.629 + resource = len = 0; 10.630 + for (region = 0; region < PCI_ROM_RESOURCE; region++) { 10.631 + if (!(pci_resource_flags (dev, region) & IORESOURCE_IO)) 10.632 + continue; 10.633 + 10.634 + resource = pci_resource_start (dev, region); 10.635 + len = pci_resource_len (dev, region); 10.636 + if (request_region (resource, len, 10.637 + driver->description)) 10.638 + break; 10.639 + } 10.640 + if (region == PCI_ROM_RESOURCE) { 10.641 + dbg ("no i/o regions available"); 10.642 + return -EBUSY; 10.643 + } 10.644 + base = (void *) resource; 10.645 + } 10.646 + 10.647 + // driver->start(), later on, will transfer device from 10.648 + // control by SMM/BIOS to control by Linux (if needed) 10.649 + 10.650 + pci_set_master (dev); 10.651 + hcd = driver->hcd_alloc (); 10.652 + if (hcd == NULL){ 10.653 + dbg ("hcd alloc fail"); 10.654 + retval = -ENOMEM; 10.655 +clean_2: 10.656 + if (driver->flags & HCD_MEMORY) { 10.657 + iounmap (base); 10.658 + goto clean_1; 10.659 + } else { 10.660 + release_region (resource, len); 10.661 + err ("init %s fail, %d", dev->slot_name, retval); 10.662 + return retval; 10.663 + } 10.664 + } 10.665 + pci_set_drvdata(dev, hcd); 10.666 + hcd->driver = driver; 10.667 + hcd->description = driver->description; 10.668 + hcd->pdev = dev; 10.669 + printk (KERN_INFO "%s %s: %s\n", 10.670 + hcd->description, dev->slot_name, dev->name); 10.671 + 10.672 +#ifndef __sparc__ 10.673 + sprintf (buf, "%d", dev->irq); 10.674 +#else 10.675 + bufp = __irq_itoa(dev->irq); 10.676 +#endif 10.677 + if (request_irq (dev->irq, hcd_irq, SA_SHIRQ, hcd->description, hcd) 10.678 + != 0) { 10.679 + err ("request interrupt %s failed", bufp); 10.680 + retval = -EBUSY; 10.681 +clean_3: 10.682 + driver->hcd_free (hcd); 10.683 + goto clean_2; 10.684 + } 10.685 + hcd->irq = dev->irq; 10.686 + 10.687 + hcd->regs = base; 10.688 + hcd->region = region; 10.689 + printk (KERN_INFO "%s %s: irq %s, %s %p\n", 10.690 + hcd->description, dev->slot_name, bufp, 10.691 + (driver->flags & HCD_MEMORY) ? "pci mem" : "io base", 10.692 + base); 10.693 + 10.694 +// FIXME simpler: make "bus" be that data, not pointer to it. 10.695 +// (fixed in 2.5) 10.696 + bus = usb_alloc_bus (&hcd_operations); 10.697 + if (bus == NULL) { 10.698 + dbg ("usb_alloc_bus fail"); 10.699 + retval = -ENOMEM; 10.700 + free_irq (dev->irq, hcd); 10.701 + goto clean_3; 10.702 + } 10.703 + hcd->bus = bus; 10.704 + bus->bus_name = dev->slot_name; 10.705 + hcd->product_desc = dev->name; 10.706 + bus->hcpriv = (void *) hcd; 10.707 + 10.708 + INIT_LIST_HEAD (&hcd->dev_list); 10.709 + INIT_LIST_HEAD (&hcd->hcd_list); 10.710 + 10.711 + down (&hcd_list_lock); 10.712 + list_add (&hcd->hcd_list, &hcd_list); 10.713 + up (&hcd_list_lock); 10.714 + 10.715 + usb_register_bus (bus); 10.716 + 10.717 + if ((retval = driver->start (hcd)) < 0) 10.718 + usb_hcd_pci_remove (dev); 10.719 + 10.720 + return retval; 10.721 +} 10.722 +EXPORT_SYMBOL (usb_hcd_pci_probe); 10.723 + 10.724 + 10.725 +/* may be called without controller electrically present */ 10.726 +/* may be called with controller, bus, and devices active */ 10.727 + 10.728 +/** 10.729 + * usb_hcd_pci_remove - shutdown processing for PCI-based HCDs 10.730 + * @dev: USB Host Controller being removed 10.731 + * Context: !in_interrupt() 10.732 + * 10.733 + * Reverses the effect of usb_hcd_pci_probe(), first invoking 10.734 + * the HCD's stop() method. It is always called from a thread 10.735 + * context, normally "rmmod", "apmd", or something similar. 10.736 + * 10.737 + * Store this function in the HCD's struct pci_driver as remove(). 10.738 + */ 10.739 +void usb_hcd_pci_remove (struct pci_dev *dev) 10.740 +{ 10.741 + struct usb_hcd *hcd; 10.742 + struct usb_device *hub; 10.743 + 10.744 + hcd = pci_get_drvdata(dev); 10.745 + if (!hcd) 10.746 + return; 10.747 + printk (KERN_INFO "%s %s: remove state %x\n", 10.748 + hcd->description, dev->slot_name, hcd->state); 10.749 + 10.750 + if (in_interrupt ()) BUG (); 10.751 + 10.752 + hub = hcd->bus->root_hub; 10.753 + hcd->state = USB_STATE_QUIESCING; 10.754 + 10.755 + dbg ("%s: roothub graceful disconnect", hcd->bus->bus_name); 10.756 + usb_disconnect (&hub); 10.757 + // usb_disconnect (&hcd->bus->root_hub); 10.758 + 10.759 + hcd->driver->stop (hcd); 10.760 + hcd->state = USB_STATE_HALT; 10.761 + 10.762 + free_irq (hcd->irq, hcd); 10.763 + if (hcd->driver->flags & HCD_MEMORY) { 10.764 + iounmap (hcd->regs); 10.765 + release_mem_region (pci_resource_start (dev, 0), 10.766 + pci_resource_len (dev, 0)); 10.767 + } else { 10.768 + release_region (pci_resource_start (dev, hcd->region), 10.769 + pci_resource_len (dev, hcd->region)); 10.770 + } 10.771 + 10.772 + down (&hcd_list_lock); 10.773 + list_del (&hcd->hcd_list); 10.774 + up (&hcd_list_lock); 10.775 + 10.776 + usb_deregister_bus (hcd->bus); 10.777 + usb_free_bus (hcd->bus); 10.778 + hcd->bus = NULL; 10.779 + 10.780 + hcd->driver->hcd_free (hcd); 10.781 +} 10.782 +EXPORT_SYMBOL (usb_hcd_pci_remove); 10.783 + 10.784 + 10.785 +#ifdef CONFIG_PM 10.786 + 10.787 +/* 10.788 + * Some "sleep" power levels imply updating struct usb_driver 10.789 + * to include a callback asking hcds to do their bit by checking 10.790 + * if all the drivers can suspend. Gets involved with remote wakeup. 10.791 + * 10.792 + * If there are pending urbs, then HCs will need to access memory, 10.793 + * causing extra power drain. New sleep()/wakeup() PM calls might 10.794 + * be needed, beyond PCI suspend()/resume(). The root hub timer 10.795 + * still be accessing memory though ... 10.796 + * 10.797 + * FIXME: USB should have some power budgeting support working with 10.798 + * all kinds of hubs. 10.799 + * 10.800 + * FIXME: This assumes only D0->D3 suspend and D3->D0 resume. 10.801 + * D1 and D2 states should do something, yes? 10.802 + * 10.803 + * FIXME: Should provide generic enable_wake(), calling pci_enable_wake() 10.804 + * for all supported states, so that USB remote wakeup can work for any 10.805 + * devices that support it (and are connected via powered hubs). 10.806 + * 10.807 + * FIXME: resume doesn't seem to work right any more... 10.808 + */ 10.809 + 10.810 + 10.811 +// 2.4 kernels have issued concurrent resumes (w/APM) 10.812 +// we defend against that error; PCI doesn't yet. 10.813 + 10.814 +/** 10.815 + * usb_hcd_pci_suspend - power management suspend of a PCI-based HCD 10.816 + * @dev: USB Host Controller being suspended 10.817 + * 10.818 + * Store this function in the HCD's struct pci_driver as suspend(). 10.819 + */ 10.820 +int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state) 10.821 +{ 10.822 + struct usb_hcd *hcd; 10.823 + int retval; 10.824 + 10.825 + hcd = pci_get_drvdata(dev); 10.826 + printk (KERN_INFO "%s %s: suspend to state %d\n", 10.827 + hcd->description, dev->slot_name, state); 10.828 + 10.829 + pci_save_state (dev, hcd->pci_state); 10.830 + 10.831 + // FIXME for all connected devices, leaf-to-root: 10.832 + // driver->suspend() 10.833 + // proposed "new 2.5 driver model" will automate that 10.834 + 10.835 + /* driver may want to disable DMA etc */ 10.836 + retval = hcd->driver->suspend (hcd, state); 10.837 + hcd->state = USB_STATE_SUSPENDED; 10.838 + 10.839 + pci_set_power_state (dev, state); 10.840 + return retval; 10.841 +} 10.842 +EXPORT_SYMBOL (usb_hcd_pci_suspend); 10.843 + 10.844 +/** 10.845 + * usb_hcd_pci_resume - power management resume of a PCI-based HCD 10.846 + * @dev: USB Host Controller being resumed 10.847 + * 10.848 + * Store this function in the HCD's struct pci_driver as resume(). 10.849 + */ 10.850 +int usb_hcd_pci_resume (struct pci_dev *dev) 10.851 +{ 10.852 + struct usb_hcd *hcd; 10.853 + int retval; 10.854 + 10.855 + hcd = pci_get_drvdata(dev); 10.856 + printk (KERN_INFO "%s %s: resume\n", 10.857 + hcd->description, dev->slot_name); 10.858 + 10.859 + /* guard against multiple resumes (APM bug?) */ 10.860 + atomic_inc (&hcd->resume_count); 10.861 + if (atomic_read (&hcd->resume_count) != 1) { 10.862 + err ("concurrent PCI resumes for %s", hcd->bus->bus_name); 10.863 + retval = 0; 10.864 + goto done; 10.865 + } 10.866 + 10.867 + retval = -EBUSY; 10.868 + if (hcd->state != USB_STATE_SUSPENDED) { 10.869 + dbg ("can't resume, not suspended!"); 10.870 + goto done; 10.871 + } 10.872 + hcd->state = USB_STATE_RESUMING; 10.873 + 10.874 + pci_set_power_state (dev, 0); 10.875 + pci_restore_state (dev, hcd->pci_state); 10.876 + 10.877 + retval = hcd->driver->resume (hcd); 10.878 + if (!HCD_IS_RUNNING (hcd->state)) { 10.879 + dbg ("resume %s failure, retval %d", 10.880 + hcd->bus->bus_name, retval); 10.881 + hc_died (hcd); 10.882 +// FIXME: recover, reset etc. 10.883 + } else { 10.884 + // FIXME for all connected devices, root-to-leaf: 10.885 + // driver->resume (); 10.886 + // proposed "new 2.5 driver model" will automate that 10.887 + } 10.888 + 10.889 +done: 10.890 + atomic_dec (&hcd->resume_count); 10.891 + return retval; 10.892 +} 10.893 +EXPORT_SYMBOL (usb_hcd_pci_resume); 10.894 + 10.895 +#endif /* CONFIG_PM */ 10.896 + 10.897 +#endif 10.898 + 10.899 +/*-------------------------------------------------------------------------*/ 10.900 + 10.901 +/* 10.902 + * Generic HC operations. 10.903 + */ 10.904 + 10.905 +/*-------------------------------------------------------------------------*/ 10.906 + 10.907 +/* called from khubd, or root hub init threads for hcd-private init */ 10.908 +static int hcd_alloc_dev (struct usb_device *udev) 10.909 +{ 10.910 + struct hcd_dev *dev; 10.911 + struct usb_hcd *hcd; 10.912 + unsigned long flags; 10.913 + 10.914 + if (!udev || udev->hcpriv) 10.915 + return -EINVAL; 10.916 + if (!udev->bus || !udev->bus->hcpriv) 10.917 + return -ENODEV; 10.918 + hcd = udev->bus->hcpriv; 10.919 + if (hcd->state == USB_STATE_QUIESCING) 10.920 + return -ENOLINK; 10.921 + 10.922 + dev = (struct hcd_dev *) kmalloc (sizeof *dev, GFP_KERNEL); 10.923 + if (dev == NULL) 10.924 + return -ENOMEM; 10.925 + memset (dev, 0, sizeof *dev); 10.926 + 10.927 + INIT_LIST_HEAD (&dev->dev_list); 10.928 + INIT_LIST_HEAD (&dev->urb_list); 10.929 + 10.930 + spin_lock_irqsave (&hcd_data_lock, flags); 10.931 + list_add (&dev->dev_list, &hcd->dev_list); 10.932 + // refcount is implicit 10.933 + udev->hcpriv = dev; 10.934 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.935 + 10.936 + return 0; 10.937 +} 10.938 + 10.939 +/*-------------------------------------------------------------------------*/ 10.940 + 10.941 +static void hcd_panic (void *_hcd) 10.942 +{ 10.943 + struct usb_hcd *hcd = _hcd; 10.944 + hcd->driver->stop (hcd); 10.945 +} 10.946 + 10.947 +static void hc_died (struct usb_hcd *hcd) 10.948 +{ 10.949 + struct list_head *devlist, *urblist; 10.950 + struct hcd_dev *dev; 10.951 + struct urb *urb; 10.952 + unsigned long flags; 10.953 + 10.954 + /* flag every pending urb as done */ 10.955 + spin_lock_irqsave (&hcd_data_lock, flags); 10.956 + list_for_each (devlist, &hcd->dev_list) { 10.957 + dev = list_entry (devlist, struct hcd_dev, dev_list); 10.958 + list_for_each (urblist, &dev->urb_list) { 10.959 + urb = list_entry (urblist, struct urb, urb_list); 10.960 + dbg ("shutdown %s urb %p pipe %x, current status %d", 10.961 + hcd->bus->bus_name, 10.962 + urb, urb->pipe, urb->status); 10.963 + if (urb->status == -EINPROGRESS) 10.964 + urb->status = -ESHUTDOWN; 10.965 + } 10.966 + } 10.967 + urb = (struct urb *) hcd->rh_timer.data; 10.968 + if (urb) 10.969 + urb->status = -ESHUTDOWN; 10.970 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.971 + 10.972 + if (urb) 10.973 + rh_status_dequeue (hcd, urb); 10.974 + 10.975 + /* hcd->stop() needs a task context */ 10.976 + INIT_TQUEUE (&hcd->work, hcd_panic, hcd); 10.977 + (void) schedule_task (&hcd->work); 10.978 +} 10.979 + 10.980 +/*-------------------------------------------------------------------------*/ 10.981 + 10.982 +static void urb_unlink (struct urb *urb) 10.983 +{ 10.984 + unsigned long flags; 10.985 + struct usb_device *dev; 10.986 + 10.987 + /* Release any periodic transfer bandwidth */ 10.988 + if (urb->bandwidth) 10.989 + usb_release_bandwidth (urb->dev, urb, 10.990 + usb_pipeisoc (urb->pipe)); 10.991 + 10.992 + /* clear all state linking urb to this dev (and hcd) */ 10.993 + 10.994 + spin_lock_irqsave (&hcd_data_lock, flags); 10.995 + list_del_init (&urb->urb_list); 10.996 + dev = urb->dev; 10.997 + urb->dev = NULL; 10.998 + usb_dec_dev_use (dev); 10.999 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.1000 +} 10.1001 + 10.1002 + 10.1003 +/* may be called in any context with a valid urb->dev usecount */ 10.1004 +/* caller surrenders "ownership" of urb */ 10.1005 + 10.1006 +static int hcd_submit_urb (struct urb *urb) 10.1007 +{ 10.1008 + int status; 10.1009 + struct usb_hcd *hcd; 10.1010 + struct hcd_dev *dev; 10.1011 + unsigned long flags; 10.1012 + int pipe, temp, max; 10.1013 + int mem_flags; 10.1014 + 10.1015 + if (!urb || urb->hcpriv || !urb->complete) 10.1016 + return -EINVAL; 10.1017 + 10.1018 + urb->status = -EINPROGRESS; 10.1019 + urb->actual_length = 0; 10.1020 + urb->bandwidth = 0; 10.1021 + INIT_LIST_HEAD (&urb->urb_list); 10.1022 + 10.1023 + if (!urb->dev || !urb->dev->bus || urb->dev->devnum <= 0) 10.1024 + return -ENODEV; 10.1025 + hcd = urb->dev->bus->hcpriv; 10.1026 + dev = urb->dev->hcpriv; 10.1027 + if (!hcd || !dev) 10.1028 + return -ENODEV; 10.1029 + 10.1030 + /* can't submit new urbs when quiescing, halted, ... */ 10.1031 + if (hcd->state == USB_STATE_QUIESCING || !HCD_IS_RUNNING (hcd->state)) 10.1032 + return -ESHUTDOWN; 10.1033 + pipe = urb->pipe; 10.1034 + temp = usb_pipetype (urb->pipe); 10.1035 + if (usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), 10.1036 + usb_pipeout (pipe))) 10.1037 + return -EPIPE; 10.1038 + 10.1039 + /* NOTE: 2.5 passes this value explicitly in submit() */ 10.1040 + mem_flags = GFP_ATOMIC; 10.1041 + 10.1042 + /* FIXME there should be a sharable lock protecting us against 10.1043 + * config/altsetting changes and disconnects, kicking in here. 10.1044 + */ 10.1045 + 10.1046 + /* Sanity check, so HCDs can rely on clean data */ 10.1047 + max = usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe)); 10.1048 + if (max <= 0) { 10.1049 + err ("bogus endpoint (bad maxpacket)"); 10.1050 + return -EINVAL; 10.1051 + } 10.1052 + 10.1053 + /* "high bandwidth" mode, 1-3 packets/uframe? */ 10.1054 + if (urb->dev->speed == USB_SPEED_HIGH) { 10.1055 + int mult; 10.1056 + switch (temp) { 10.1057 + case PIPE_ISOCHRONOUS: 10.1058 + case PIPE_INTERRUPT: 10.1059 + mult = 1 + ((max >> 11) & 0x03); 10.1060 + max &= 0x03ff; 10.1061 + max *= mult; 10.1062 + } 10.1063 + } 10.1064 + 10.1065 + /* periodic transfers limit size per frame/uframe */ 10.1066 + switch (temp) { 10.1067 + case PIPE_ISOCHRONOUS: { 10.1068 + int n, len; 10.1069 + 10.1070 + if (urb->number_of_packets <= 0) 10.1071 + return -EINVAL; 10.1072 + for (n = 0; n < urb->number_of_packets; n++) { 10.1073 + len = urb->iso_frame_desc [n].length; 10.1074 + if (len < 0 || len > max) 10.1075 + return -EINVAL; 10.1076 + } 10.1077 + 10.1078 + } 10.1079 + break; 10.1080 + case PIPE_INTERRUPT: 10.1081 + if (urb->transfer_buffer_length > max) 10.1082 + return -EINVAL; 10.1083 + } 10.1084 + 10.1085 + /* the I/O buffer must usually be mapped/unmapped */ 10.1086 + if (urb->transfer_buffer_length < 0) 10.1087 + return -EINVAL; 10.1088 + 10.1089 + if (urb->next) { 10.1090 + warn ("use explicit queuing not urb->next"); 10.1091 + return -EINVAL; 10.1092 + } 10.1093 + 10.1094 +#ifdef DEBUG 10.1095 + /* stuff that drivers shouldn't do, but which shouldn't 10.1096 + * cause problems in HCDs if they get it wrong. 10.1097 + */ 10.1098 + { 10.1099 + unsigned int orig_flags = urb->transfer_flags; 10.1100 + unsigned int allowed; 10.1101 + 10.1102 + /* enforce simple/standard policy */ 10.1103 + allowed = USB_ASYNC_UNLINK; // affects later unlinks 10.1104 + allowed |= USB_NO_FSBR; // only affects UHCI 10.1105 + switch (temp) { 10.1106 + case PIPE_CONTROL: 10.1107 + allowed |= USB_DISABLE_SPD; 10.1108 + break; 10.1109 + case PIPE_BULK: 10.1110 + allowed |= USB_DISABLE_SPD | USB_QUEUE_BULK 10.1111 + | USB_ZERO_PACKET | URB_NO_INTERRUPT; 10.1112 + break; 10.1113 + case PIPE_INTERRUPT: 10.1114 + allowed |= USB_DISABLE_SPD; 10.1115 + break; 10.1116 + case PIPE_ISOCHRONOUS: 10.1117 + allowed |= USB_ISO_ASAP; 10.1118 + break; 10.1119 + } 10.1120 + urb->transfer_flags &= allowed; 10.1121 + 10.1122 + /* fail if submitter gave bogus flags */ 10.1123 + if (urb->transfer_flags != orig_flags) { 10.1124 + err ("BOGUS urb flags, %x --> %x", 10.1125 + orig_flags, urb->transfer_flags); 10.1126 + return -EINVAL; 10.1127 + } 10.1128 + } 10.1129 +#endif 10.1130 + /* 10.1131 + * Force periodic transfer intervals to be legal values that are 10.1132 + * a power of two (so HCDs don't need to). 10.1133 + * 10.1134 + * FIXME want bus->{intr,iso}_sched_horizon values here. Each HC 10.1135 + * supports different values... this uses EHCI/UHCI defaults (and 10.1136 + * EHCI can use smaller non-default values). 10.1137 + */ 10.1138 + switch (temp) { 10.1139 + case PIPE_ISOCHRONOUS: 10.1140 + case PIPE_INTERRUPT: 10.1141 + /* too small? */ 10.1142 + if (urb->interval <= 0) 10.1143 + return -EINVAL; 10.1144 + /* too big? */ 10.1145 + switch (urb->dev->speed) { 10.1146 + case USB_SPEED_HIGH: /* units are microframes */ 10.1147 + // NOTE usb handles 2^15 10.1148 + if (urb->interval > (1024 * 8)) 10.1149 + urb->interval = 1024 * 8; 10.1150 + temp = 1024 * 8; 10.1151 + break; 10.1152 + case USB_SPEED_FULL: /* units are frames/msec */ 10.1153 + case USB_SPEED_LOW: 10.1154 + if (temp == PIPE_INTERRUPT) { 10.1155 + if (urb->interval > 255) 10.1156 + return -EINVAL; 10.1157 + // NOTE ohci only handles up to 32 10.1158 + temp = 128; 10.1159 + } else { 10.1160 + if (urb->interval > 1024) 10.1161 + urb->interval = 1024; 10.1162 + // NOTE usb and ohci handle up to 2^15 10.1163 + temp = 1024; 10.1164 + } 10.1165 + break; 10.1166 + default: 10.1167 + return -EINVAL; 10.1168 + } 10.1169 + /* power of two? */ 10.1170 + while (temp > urb->interval) 10.1171 + temp >>= 1; 10.1172 + urb->interval = temp; 10.1173 + } 10.1174 + 10.1175 + 10.1176 + /* 10.1177 + * FIXME: make urb timeouts be generic, keeping the HCD cores 10.1178 + * as simple as possible. 10.1179 + */ 10.1180 + 10.1181 + // NOTE: a generic device/urb monitoring hook would go here. 10.1182 + // hcd_monitor_hook(MONITOR_URB_SUBMIT, urb) 10.1183 + // It would catch submission paths for all urbs. 10.1184 + 10.1185 + /* 10.1186 + * Atomically queue the urb, first to our records, then to the HCD. 10.1187 + * Access to urb->status is controlled by urb->lock ... changes on 10.1188 + * i/o completion (normal or fault) or unlinking. 10.1189 + */ 10.1190 + 10.1191 + // FIXME: verify that quiescing hc works right (RH cleans up) 10.1192 + 10.1193 + spin_lock_irqsave (&hcd_data_lock, flags); 10.1194 + if (HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_QUIESCING) { 10.1195 + usb_inc_dev_use (urb->dev); 10.1196 + list_add (&urb->urb_list, &dev->urb_list); 10.1197 + status = 0; 10.1198 + } else { 10.1199 + INIT_LIST_HEAD (&urb->urb_list); 10.1200 + status = -ESHUTDOWN; 10.1201 + } 10.1202 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.1203 + if (status) 10.1204 + return status; 10.1205 + 10.1206 + // NOTE: 2.5 does this if !URB_NO_DMA_MAP transfer flag 10.1207 + 10.1208 + /* For 2.4, don't map bounce buffer if it's a root hub operation. */ 10.1209 + if (urb->dev == hcd->bus->root_hub) { 10.1210 + status = rh_urb_enqueue (hcd, urb); 10.1211 + } else { 10.1212 +#ifdef CONFIG_PCI 10.1213 + if (usb_pipecontrol (urb->pipe)) 10.1214 + urb->setup_dma = pci_map_single ( 10.1215 + hcd->pdev, 10.1216 + urb->setup_packet, 10.1217 + sizeof (struct usb_ctrlrequest), 10.1218 + PCI_DMA_TODEVICE); 10.1219 + if (urb->transfer_buffer_length != 0) 10.1220 + urb->transfer_dma = pci_map_single ( 10.1221 + hcd->pdev, 10.1222 + urb->transfer_buffer, 10.1223 + urb->transfer_buffer_length, 10.1224 + usb_pipein (urb->pipe) 10.1225 + ? PCI_DMA_FROMDEVICE 10.1226 + : PCI_DMA_TODEVICE); 10.1227 +#endif 10.1228 + status = hcd->driver->urb_enqueue (hcd, urb, mem_flags); 10.1229 + } 10.1230 + return status; 10.1231 +} 10.1232 + 10.1233 +/*-------------------------------------------------------------------------*/ 10.1234 + 10.1235 +/* called in any context */ 10.1236 +static int hcd_get_frame_number (struct usb_device *udev) 10.1237 +{ 10.1238 + struct usb_hcd *hcd = (struct usb_hcd *)udev->bus->hcpriv; 10.1239 + return hcd->driver->get_frame_number (hcd); 10.1240 +} 10.1241 + 10.1242 +/*-------------------------------------------------------------------------*/ 10.1243 + 10.1244 +struct completion_splice { // modified urb context: 10.1245 + /* did we complete? */ 10.1246 + struct completion done; 10.1247 + 10.1248 + /* original urb data */ 10.1249 + void (*complete)(struct urb *); 10.1250 + void *context; 10.1251 +}; 10.1252 + 10.1253 +static void unlink_complete (struct urb *urb) 10.1254 +{ 10.1255 + struct completion_splice *splice; 10.1256 + 10.1257 + splice = (struct completion_splice *) urb->context; 10.1258 + 10.1259 + /* issue original completion call */ 10.1260 + urb->complete = splice->complete; 10.1261 + urb->context = splice->context; 10.1262 + urb->complete (urb); 10.1263 + 10.1264 + /* then let the synchronous unlink call complete */ 10.1265 + complete (&splice->done); 10.1266 +} 10.1267 + 10.1268 +/* 10.1269 + * called in any context; note ASYNC_UNLINK restrictions 10.1270 + * 10.1271 + * caller guarantees urb won't be recycled till both unlink() 10.1272 + * and the urb's completion function return 10.1273 + */ 10.1274 +static int hcd_unlink_urb (struct urb *urb) 10.1275 +{ 10.1276 + struct hcd_dev *dev; 10.1277 + struct usb_hcd *hcd = 0; 10.1278 + unsigned long flags; 10.1279 + struct completion_splice splice; 10.1280 + int retval; 10.1281 + 10.1282 + if (!urb) 10.1283 + return -EINVAL; 10.1284 + 10.1285 + /* 10.1286 + * we contend for urb->status with the hcd core, 10.1287 + * which changes it while returning the urb. 10.1288 + * 10.1289 + * Caller guaranteed that the urb pointer hasn't been freed, and 10.1290 + * that it was submitted. But as a rule it can't know whether or 10.1291 + * not it's already been unlinked ... so we respect the reversed 10.1292 + * lock sequence needed for the usb_hcd_giveback_urb() code paths 10.1293 + * (urb lock, then hcd_data_lock) in case some other CPU is now 10.1294 + * unlinking it. 10.1295 + */ 10.1296 + spin_lock_irqsave (&urb->lock, flags); 10.1297 + spin_lock (&hcd_data_lock); 10.1298 + if (!urb->hcpriv || urb->transfer_flags & USB_TIMEOUT_KILLED) { 10.1299 + retval = -EINVAL; 10.1300 + goto done; 10.1301 + } 10.1302 + 10.1303 + if (!urb->dev || !urb->dev->bus) { 10.1304 + retval = -ENODEV; 10.1305 + goto done; 10.1306 + } 10.1307 + 10.1308 + /* giveback clears dev; non-null means it's linked at this level */ 10.1309 + dev = urb->dev->hcpriv; 10.1310 + hcd = urb->dev->bus->hcpriv; 10.1311 + if (!dev || !hcd) { 10.1312 + retval = -ENODEV; 10.1313 + goto done; 10.1314 + } 10.1315 + 10.1316 + /* Any status except -EINPROGRESS means the HCD has already started 10.1317 + * to return this URB to the driver. In that case, there's no 10.1318 + * more work for us to do. 10.1319 + * 10.1320 + * There's much magic because of "automagic resubmit" of interrupt 10.1321 + * transfers, stopped only by explicit unlinking. We won't issue 10.1322 + * an "it's unlinked" callback more than once, but device drivers 10.1323 + * can need to retry (SMP, -EAGAIN) an unlink request as well as 10.1324 + * fake out the "not yet completed" state (set -EINPROGRESS) if 10.1325 + * unlinking from complete(). Automagic eventually vanishes. 10.1326 + * 10.1327 + * FIXME use an URB_UNLINKED flag to match URB_TIMEOUT_KILLED 10.1328 + */ 10.1329 + if (urb->status != -EINPROGRESS) { 10.1330 + if (usb_pipetype (urb->pipe) == PIPE_INTERRUPT) 10.1331 + retval = -EAGAIN; 10.1332 + else 10.1333 + retval = -EBUSY; 10.1334 + goto done; 10.1335 + } 10.1336 + 10.1337 + /* maybe set up to block on completion notification */ 10.1338 + if ((urb->transfer_flags & USB_TIMEOUT_KILLED)) 10.1339 + urb->status = -ETIMEDOUT; 10.1340 + else if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) { 10.1341 + if (in_interrupt ()) { 10.1342 + dbg ("non-async unlink in_interrupt"); 10.1343 + retval = -EWOULDBLOCK; 10.1344 + goto done; 10.1345 + } 10.1346 + /* synchronous unlink: block till we see the completion */ 10.1347 + init_completion (&splice.done); 10.1348 + splice.complete = urb->complete; 10.1349 + splice.context = urb->context; 10.1350 + urb->complete = unlink_complete; 10.1351 + urb->context = &splice; 10.1352 + urb->status = -ENOENT; 10.1353 + } else { 10.1354 + /* asynchronous unlink */ 10.1355 + urb->status = -ECONNRESET; 10.1356 + } 10.1357 + spin_unlock (&hcd_data_lock); 10.1358 + spin_unlock_irqrestore (&urb->lock, flags); 10.1359 + 10.1360 + if (urb == (struct urb *) hcd->rh_timer.data) { 10.1361 + rh_status_dequeue (hcd, urb); 10.1362 + retval = 0; 10.1363 + } else { 10.1364 + retval = hcd->driver->urb_dequeue (hcd, urb); 10.1365 +// FIXME: if retval and we tried to splice, whoa!! 10.1366 +if (retval && urb->status == -ENOENT) err ("whoa! retval %d", retval); 10.1367 + } 10.1368 + 10.1369 + /* block till giveback, if needed */ 10.1370 + if (!(urb->transfer_flags & (USB_ASYNC_UNLINK|USB_TIMEOUT_KILLED)) 10.1371 + && HCD_IS_RUNNING (hcd->state) 10.1372 + && !retval) { 10.1373 + wait_for_completion (&splice.done); 10.1374 + } else if ((urb->transfer_flags & USB_ASYNC_UNLINK) && retval == 0) { 10.1375 + return -EINPROGRESS; 10.1376 + } 10.1377 + goto bye; 10.1378 +done: 10.1379 + spin_unlock (&hcd_data_lock); 10.1380 + spin_unlock_irqrestore (&urb->lock, flags); 10.1381 +bye: 10.1382 + if (retval) 10.1383 + dbg ("%s: hcd_unlink_urb fail %d", 10.1384 + hcd ? hcd->bus->bus_name : "(no bus?)", 10.1385 + retval); 10.1386 + return retval; 10.1387 +} 10.1388 + 10.1389 +/*-------------------------------------------------------------------------*/ 10.1390 + 10.1391 +/* called by khubd, rmmod, apmd, or other thread for hcd-private cleanup */ 10.1392 + 10.1393 +// FIXME: likely best to have explicit per-setting (config+alt) 10.1394 +// setup primitives in the usbcore-to-hcd driver API, so nothing 10.1395 +// is implicit. kernel 2.5 needs a bunch of config cleanup... 10.1396 + 10.1397 +static int hcd_free_dev (struct usb_device *udev) 10.1398 +{ 10.1399 + struct hcd_dev *dev; 10.1400 + struct usb_hcd *hcd; 10.1401 + unsigned long flags; 10.1402 + 10.1403 + if (!udev || !udev->hcpriv) 10.1404 + return -EINVAL; 10.1405 + 10.1406 + if (!udev->bus || !udev->bus->hcpriv) 10.1407 + return -ENODEV; 10.1408 + 10.1409 + // should udev->devnum == -1 ?? 10.1410 + 10.1411 + dev = udev->hcpriv; 10.1412 + hcd = udev->bus->hcpriv; 10.1413 + 10.1414 + /* device driver problem with refcounts? */ 10.1415 + if (!list_empty (&dev->urb_list)) { 10.1416 + dbg ("free busy dev, %s devnum %d (bug!)", 10.1417 + hcd->bus->bus_name, udev->devnum); 10.1418 + return -EINVAL; 10.1419 + } 10.1420 + 10.1421 + hcd->driver->free_config (hcd, udev); 10.1422 + 10.1423 + spin_lock_irqsave (&hcd_data_lock, flags); 10.1424 + list_del (&dev->dev_list); 10.1425 + udev->hcpriv = NULL; 10.1426 + spin_unlock_irqrestore (&hcd_data_lock, flags); 10.1427 + 10.1428 + kfree (dev); 10.1429 + return 0; 10.1430 +} 10.1431 + 10.1432 +static struct usb_operations hcd_operations = { 10.1433 + allocate: hcd_alloc_dev, 10.1434 + get_frame_number: hcd_get_frame_number, 10.1435 + submit_urb: hcd_submit_urb, 10.1436 + unlink_urb: hcd_unlink_urb, 10.1437 + deallocate: hcd_free_dev, 10.1438 +}; 10.1439 + 10.1440 +/*-------------------------------------------------------------------------*/ 10.1441 + 10.1442 +static void hcd_irq (int irq, void *__hcd, struct pt_regs * r) 10.1443 +{ 10.1444 + struct usb_hcd *hcd = __hcd; 10.1445 + int start = hcd->state; 10.1446 + 10.1447 + if (unlikely (hcd->state == USB_STATE_HALT)) /* irq sharing? */ 10.1448 + return; 10.1449 + 10.1450 + hcd->driver->irq (hcd, r); 10.1451 + if (hcd->state != start && hcd->state == USB_STATE_HALT) 10.1452 + hc_died (hcd); 10.1453 +} 10.1454 + 10.1455 +/*-------------------------------------------------------------------------*/ 10.1456 + 10.1457 +/** 10.1458 + * usb_hcd_giveback_urb - return URB from HCD to device driver 10.1459 + * @hcd: host controller returning the URB 10.1460 + * @urb: urb being returned to the USB device driver. 10.1461 + * @regs: saved hardware registers (ignored on 2.4 kernels) 10.1462 + * Context: in_interrupt() 10.1463 + * 10.1464 + * This hands the URB from HCD to its USB device driver, using its 10.1465 + * completion function. The HCD has freed all per-urb resources 10.1466 + * (and is done using urb->hcpriv). It also released all HCD locks; 10.1467 + * the device driver won't cause deadlocks if it resubmits this URB, 10.1468 + * and won't confuse things by modifying and resubmitting this one. 10.1469 + * Bandwidth and other resources will be deallocated. 10.1470 + * 10.1471 + * HCDs must not use this for periodic URBs that are still scheduled 10.1472 + * and will be reissued. They should just call their completion handlers 10.1473 + * until the urb is returned to the device driver by unlinking. 10.1474 + * 10.1475 + * NOTE that no urb->next processing is done, even for isochronous URBs. 10.1476 + * ISO streaming functionality can be achieved by having completion handlers 10.1477 + * re-queue URBs. Such explicit queuing doesn't discard error reports. 10.1478 + */ 10.1479 +void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs) 10.1480 +{ 10.1481 + int is_root_hub_operation; 10.1482 + 10.1483 + /* Work this out here as urb_unlink clears urb->dev */ 10.1484 + is_root_hub_operation = (urb->dev == hcd->bus->root_hub); 10.1485 + 10.1486 + urb_unlink (urb); 10.1487 + 10.1488 + // NOTE: a generic device/urb monitoring hook would go here. 10.1489 + // hcd_monitor_hook(MONITOR_URB_FINISH, urb, dev) 10.1490 + // It would catch exit/unlink paths for all urbs, but non-exit 10.1491 + // completions for periodic urbs need hooks inside the HCD. 10.1492 + // hcd_monitor_hook(MONITOR_URB_UPDATE, urb, dev) 10.1493 + 10.1494 + // NOTE: 2.5 does this if !URB_NO_DMA_MAP transfer flag 10.1495 + 10.1496 +#ifdef CONFIG_PCI 10.1497 + /* For 2.4, don't unmap bounce buffer if it's a root hub operation. */ 10.1498 + if (usb_pipecontrol (urb->pipe) && !is_root_hub_operation) 10.1499 + pci_unmap_single (hcd->pdev, urb->setup_dma, 10.1500 + sizeof (struct usb_ctrlrequest), 10.1501 + PCI_DMA_TODEVICE); 10.1502 + 10.1503 + if ((urb->transfer_buffer_length != 0) && !is_root_hub_operation) 10.1504 + pci_unmap_single (hcd->pdev, urb->transfer_dma, 10.1505 + urb->transfer_buffer_length, 10.1506 + usb_pipein (urb->pipe) 10.1507 + ? PCI_DMA_FROMDEVICE 10.1508 + : PCI_DMA_TODEVICE); 10.1509 +#endif 10.1510 + 10.1511 + /* pass ownership to the completion handler */ 10.1512 + urb->complete (urb); 10.1513 +} 10.1514 +EXPORT_SYMBOL (usb_hcd_giveback_urb);
11.1 --- a/linux-2.4.29-xen-sparse/mkbuildtree Fri Jan 28 07:59:39 2005 +0000 11.2 +++ b/linux-2.4.29-xen-sparse/mkbuildtree Fri Jan 28 14:53:32 2005 +0000 11.3 @@ -282,4 +282,12 @@ ln -sf ../../../../../${LINUX_26}/driver 11.4 cd ${AD}/arch/xen/drivers/blkif/frontend 11.5 ln -sf ../../../../../${LINUX_26}/drivers/xen/blkfront/blkfront.c 11.6 11.7 +cd ${AD}/arch/xen/drivers/usbif/frontend 11.8 +ln -sf ../../../../../${LINUX_26}/drivers/xen/usbfront/usbfront.c main.c 11.9 +ln -sf ../../../../../${LINUX_26}/drivers/xen/usbfront/xhci.h 11.10 11.11 +cd ${AD}/arch/xen/drivers/usbif/backend 11.12 +ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/common.h 11.13 +ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/control.c 11.14 +ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/interface.c 11.15 +ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/usbback.c main.c
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/common.h Fri Jan 28 14:53:32 2005 +0000 12.3 @@ -0,0 +1,87 @@ 12.4 + 12.5 +#ifndef __USBIF__BACKEND__COMMON_H__ 12.6 +#define __USBIF__BACKEND__COMMON_H__ 12.7 + 12.8 +#include <linux/config.h> 12.9 +#include <linux/version.h> 12.10 +#include <linux/module.h> 12.11 +#include <linux/rbtree.h> 12.12 +#include <linux/interrupt.h> 12.13 +#include <linux/slab.h> 12.14 +#include <linux/blkdev.h> 12.15 +#include <asm/io.h> 12.16 +#include <asm/setup.h> 12.17 +#include <asm/pgalloc.h> 12.18 +#include <asm-xen/ctrl_if.h> 12.19 +#include <asm-xen/hypervisor.h> 12.20 + 12.21 +#include <asm-xen/xen-public/io/usbif.h> 12.22 + 12.23 +#if 0 12.24 +#define ASSERT(_p) \ 12.25 + if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \ 12.26 + __LINE__, __FILE__); *(int*)0=0; } 12.27 +#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \ 12.28 + __FILE__ , __LINE__ , ## _a ) 12.29 +#else 12.30 +#define ASSERT(_p) ((void)0) 12.31 +#define DPRINTK(_f, _a...) ((void)0) 12.32 +#endif 12.33 + 12.34 +typedef struct usbif_priv_st usbif_priv_t; 12.35 + 12.36 +struct usbif_priv_st { 12.37 + /* Unique identifier for this interface. */ 12.38 + domid_t domid; 12.39 + unsigned int handle; 12.40 + /* Physical parameters of the comms window. */ 12.41 + unsigned long shmem_frame; 12.42 + unsigned int evtchn; 12.43 + int irq; 12.44 + /* Comms information. */ 12.45 + usbif_t *usb_ring_base; /* ioremap()'ed ptr to shmem_frame. */ 12.46 + USBIF_RING_IDX usb_req_cons; /* Request consumer. */ 12.47 + USBIF_RING_IDX usb_resp_prod; /* Private version of resp. producer. */ 12.48 + /* Private fields. */ 12.49 + enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; 12.50 + /* 12.51 + * DISCONNECT response is deferred until pending requests are ack'ed. 12.52 + * We therefore need to store the id from the original request. 12.53 + */ 12.54 + u8 disconnect_rspid; 12.55 + usbif_priv_t *hash_next; 12.56 + struct list_head usbif_list; 12.57 + spinlock_t usb_ring_lock; 12.58 + atomic_t refcnt; 12.59 + atomic_t work_scheduled; 12.60 + 12.61 + struct work_struct work; 12.62 +}; 12.63 + 12.64 +void usbif_create(usbif_be_create_t *create); 12.65 +void usbif_destroy(usbif_be_destroy_t *destroy); 12.66 +void usbif_connect(usbif_be_connect_t *connect); 12.67 +int usbif_disconnect(usbif_be_disconnect_t *disconnect, u8 rsp_id); 12.68 +void usbif_disconnect_complete(usbif_priv_t *up); 12.69 + 12.70 +void usbif_release_port(usbif_be_release_port_t *msg); 12.71 +int usbif_claim_port(usbif_be_claim_port_t *msg); 12.72 +void usbif_release_ports(usbif_priv_t *up); 12.73 + 12.74 +usbif_priv_t *usbif_find(domid_t domid); 12.75 +#define usbif_get(_b) (atomic_inc(&(_b)->refcnt)) 12.76 +#define usbif_put(_b) \ 12.77 + do { \ 12.78 + if ( atomic_dec_and_test(&(_b)->refcnt) ) \ 12.79 + usbif_disconnect_complete(_b); \ 12.80 + } while (0) 12.81 + 12.82 + 12.83 +void usbif_interface_init(void); 12.84 +void usbif_ctrlif_init(void); 12.85 + 12.86 +void usbif_deschedule(usbif_priv_t *usbif); 12.87 + 12.88 +irqreturn_t usbif_be_int(int irq, void *dev_id, struct pt_regs *regs); 12.89 + 12.90 +#endif /* __USBIF__BACKEND__COMMON_H__ */
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/control.c Fri Jan 28 14:53:32 2005 +0000 13.3 @@ -0,0 +1,77 @@ 13.4 +/****************************************************************************** 13.5 + * arch/xen/drivers/usbif/backend/control.c 13.6 + * 13.7 + * Routines for interfacing with the control plane. 13.8 + * 13.9 + * Copyright (c) 2004, Keir Fraser 13.10 + */ 13.11 + 13.12 +#include "common.h" 13.13 + 13.14 +static void usbif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 13.15 +{ 13.16 + DPRINTK("Received usbif backend message, subtype=%d\n", msg->subtype); 13.17 + 13.18 + switch ( msg->subtype ) 13.19 + { 13.20 + case CMSG_USBIF_BE_CREATE: 13.21 + if ( msg->length != sizeof(usbif_be_create_t) ) 13.22 + goto parse_error; 13.23 + usbif_create((usbif_be_create_t *)&msg->msg[0]); 13.24 + break; 13.25 + case CMSG_USBIF_BE_DESTROY: 13.26 + if ( msg->length != sizeof(usbif_be_destroy_t) ) 13.27 + goto parse_error; 13.28 + usbif_destroy((usbif_be_destroy_t *)&msg->msg[0]); 13.29 + break; 13.30 + case CMSG_USBIF_BE_CONNECT: 13.31 + if ( msg->length != sizeof(usbif_be_connect_t) ) 13.32 + goto parse_error; 13.33 + usbif_connect((usbif_be_connect_t *)&msg->msg[0]); 13.34 + break; 13.35 + case CMSG_USBIF_BE_DISCONNECT: 13.36 + if ( msg->length != sizeof(usbif_be_disconnect_t) ) 13.37 + goto parse_error; 13.38 + if ( !usbif_disconnect((usbif_be_disconnect_t *)&msg->msg[0],msg->id) ) 13.39 + return; /* Sending the response is deferred until later. */ 13.40 + break; 13.41 + case CMSG_USBIF_BE_CLAIM_PORT: 13.42 + if ( msg->length != sizeof(usbif_be_claim_port_t) ) 13.43 + goto parse_error; 13.44 + usbif_claim_port((usbif_be_claim_port_t *)&msg->msg[0]); 13.45 + break; 13.46 + case CMSG_USBIF_BE_RELEASE_PORT: 13.47 + if ( msg->length != sizeof(usbif_be_release_port_t) ) 13.48 + goto parse_error; 13.49 + usbif_release_port((usbif_be_release_port_t *)&msg->msg[0]); 13.50 + break; 13.51 + default: 13.52 + goto parse_error; 13.53 + } 13.54 + 13.55 + ctrl_if_send_response(msg); 13.56 + return; 13.57 + 13.58 + parse_error: 13.59 + DPRINTK("Parse error while reading message subtype %d, len %d\n", 13.60 + msg->subtype, msg->length); 13.61 + msg->length = 0; 13.62 + ctrl_if_send_response(msg); 13.63 +} 13.64 + 13.65 +void usbif_ctrlif_init(void) 13.66 +{ 13.67 + ctrl_msg_t cmsg; 13.68 + usbif_be_driver_status_changed_t st; 13.69 + 13.70 + (void)ctrl_if_register_receiver(CMSG_USBIF_BE, usbif_ctrlif_rx, 13.71 + CALLBACK_IN_BLOCKING_CONTEXT); 13.72 + 13.73 + /* Send a driver-UP notification to the domain controller. */ 13.74 + cmsg.type = CMSG_USBIF_BE; 13.75 + cmsg.subtype = CMSG_USBIF_BE_DRIVER_STATUS_CHANGED; 13.76 + cmsg.length = sizeof(usbif_be_driver_status_changed_t); 13.77 + st.status = USBIF_DRIVER_STATUS_UP; 13.78 + memcpy(cmsg.msg, &st, sizeof(st)); 13.79 + ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 13.80 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/interface.c Fri Jan 28 14:53:32 2005 +0000 14.3 @@ -0,0 +1,248 @@ 14.4 +/****************************************************************************** 14.5 + * arch/xen/drivers/usbif/backend/interface.c 14.6 + * 14.7 + * USB device interface management. 14.8 + * 14.9 + * by Mark Williamson, Copyright (c) 2004 14.10 + */ 14.11 + 14.12 + 14.13 +/****************************************************************************** 14.14 + * arch/xen/drivers/blkif/backend/interface.c 14.15 + * 14.16 + * Block-device interface management. 14.17 + * 14.18 + * Copyright (c) 2004, Keir Fraser 14.19 + */ 14.20 + 14.21 +#include "common.h" 14.22 + 14.23 +#define USBIF_HASHSZ 1024 14.24 +#define USBIF_HASH(_d) (((int)(_d))&(USBIF_HASHSZ-1)) 14.25 + 14.26 +static kmem_cache_t *usbif_priv_cachep; 14.27 +static usbif_priv_t *usbif_priv_hash[USBIF_HASHSZ]; 14.28 + 14.29 +usbif_priv_t *usbif_find(domid_t domid) 14.30 +{ 14.31 + usbif_priv_t *up = usbif_priv_hash[USBIF_HASH(domid)]; 14.32 + while ( (up != NULL ) && ( up->domid != domid ) ) 14.33 + up = up->hash_next; 14.34 + return up; 14.35 +} 14.36 + 14.37 +static void __usbif_disconnect_complete(void *arg) 14.38 +{ 14.39 + usbif_priv_t *usbif = (usbif_priv_t *)arg; 14.40 + ctrl_msg_t cmsg; 14.41 + usbif_be_disconnect_t disc; 14.42 + 14.43 + /* 14.44 + * These can't be done in usbif_disconnect() because at that point there 14.45 + * may be outstanding requests at the device whose asynchronous responses 14.46 + * must still be notified to the remote driver. 14.47 + */ 14.48 + unbind_evtchn_from_irq(usbif->evtchn); 14.49 + vfree(usbif->usb_ring_base); 14.50 + 14.51 + /* Construct the deferred response message. */ 14.52 + cmsg.type = CMSG_USBIF_BE; 14.53 + cmsg.subtype = CMSG_USBIF_BE_DISCONNECT; 14.54 + cmsg.id = usbif->disconnect_rspid; 14.55 + cmsg.length = sizeof(usbif_be_disconnect_t); 14.56 + disc.domid = usbif->domid; 14.57 + disc.status = USBIF_BE_STATUS_OKAY; 14.58 + memcpy(cmsg.msg, &disc, sizeof(disc)); 14.59 + 14.60 + /* 14.61 + * Make sure message is constructed /before/ status change, because 14.62 + * after the status change the 'usbif' structure could be deallocated at 14.63 + * any time. Also make sure we send the response /after/ status change, 14.64 + * as otherwise a subsequent CONNECT request could spuriously fail if 14.65 + * another CPU doesn't see the status change yet. 14.66 + */ 14.67 + mb(); 14.68 + if ( usbif->status != DISCONNECTING ) 14.69 + BUG(); 14.70 + usbif->status = DISCONNECTED; 14.71 + mb(); 14.72 + 14.73 + /* Send the successful response. */ 14.74 + ctrl_if_send_response(&cmsg); 14.75 +} 14.76 + 14.77 +void usbif_disconnect_complete(usbif_priv_t *up) 14.78 +{ 14.79 + INIT_WORK(&up->work, __usbif_disconnect_complete, (void *)up); 14.80 + schedule_work(&up->work); 14.81 +} 14.82 + 14.83 +void usbif_create(usbif_be_create_t *create) 14.84 +{ 14.85 + domid_t domid = create->domid; 14.86 + usbif_priv_t **pup, *up; 14.87 + 14.88 + if ( (up = kmem_cache_alloc(usbif_priv_cachep, GFP_KERNEL)) == NULL ) 14.89 + { 14.90 + DPRINTK("Could not create usbif: out of memory\n"); 14.91 + create->status = USBIF_BE_STATUS_OUT_OF_MEMORY; 14.92 + return; 14.93 + } 14.94 + 14.95 + memset(up, 0, sizeof(*up)); 14.96 + up->domid = domid; 14.97 + up->status = DISCONNECTED; 14.98 + spin_lock_init(&up->usb_ring_lock); 14.99 + atomic_set(&up->refcnt, 0); 14.100 + 14.101 + pup = &usbif_priv_hash[USBIF_HASH(domid)]; 14.102 + while ( *pup != NULL ) 14.103 + { 14.104 + if ( (*pup)->domid == domid ) 14.105 + { 14.106 + create->status = USBIF_BE_STATUS_INTERFACE_EXISTS; 14.107 + kmem_cache_free(usbif_priv_cachep, up); 14.108 + return; 14.109 + } 14.110 + pup = &(*pup)->hash_next; 14.111 + } 14.112 + 14.113 + up->hash_next = *pup; 14.114 + *pup = up; 14.115 + 14.116 + create->status = USBIF_BE_STATUS_OKAY; 14.117 +} 14.118 + 14.119 +void usbif_destroy(usbif_be_destroy_t *destroy) 14.120 +{ 14.121 + domid_t domid = destroy->domid; 14.122 + usbif_priv_t **pup, *up; 14.123 + 14.124 + pup = &usbif_priv_hash[USBIF_HASH(domid)]; 14.125 + while ( (up = *pup) != NULL ) 14.126 + { 14.127 + if ( up->domid == domid ) 14.128 + { 14.129 + if ( up->status != DISCONNECTED ) 14.130 + goto still_connected; 14.131 + goto destroy; 14.132 + } 14.133 + pup = &up->hash_next; 14.134 + } 14.135 + 14.136 + destroy->status = USBIF_BE_STATUS_INTERFACE_NOT_FOUND; 14.137 + return; 14.138 + 14.139 + still_connected: 14.140 + destroy->status = USBIF_BE_STATUS_INTERFACE_CONNECTED; 14.141 + return; 14.142 + 14.143 + destroy: 14.144 + *pup = up->hash_next; 14.145 + usbif_release_ports(up); 14.146 + kmem_cache_free(usbif_priv_cachep, up); 14.147 + destroy->status = USBIF_BE_STATUS_OKAY; 14.148 +} 14.149 + 14.150 +void usbif_connect(usbif_be_connect_t *connect) 14.151 +{ 14.152 + domid_t domid = connect->domid; 14.153 + unsigned int evtchn = connect->evtchn; 14.154 + unsigned long shmem_frame = connect->shmem_frame; 14.155 + struct vm_struct *vma; 14.156 + pgprot_t prot; 14.157 + int error; 14.158 + usbif_priv_t *up; 14.159 + 14.160 + up = usbif_find(domid); 14.161 + if ( unlikely(up == NULL) ) 14.162 + { 14.163 + DPRINTK("usbif_connect attempted for non-existent usbif (%u)\n", 14.164 + connect->domid); 14.165 + connect->status = USBIF_BE_STATUS_INTERFACE_NOT_FOUND; 14.166 + return; 14.167 + } 14.168 + 14.169 + if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL ) 14.170 + { 14.171 + connect->status = USBIF_BE_STATUS_OUT_OF_MEMORY; 14.172 + return; 14.173 + } 14.174 + 14.175 + prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED); 14.176 + error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr), 14.177 + shmem_frame<<PAGE_SHIFT, PAGE_SIZE, 14.178 + prot, domid); 14.179 + if ( error != 0 ) 14.180 + { 14.181 + if ( error == -ENOMEM ) 14.182 + connect->status = USBIF_BE_STATUS_OUT_OF_MEMORY; 14.183 + else if ( error == -EFAULT ) 14.184 + connect->status = USBIF_BE_STATUS_MAPPING_ERROR; 14.185 + else 14.186 + connect->status = USBIF_BE_STATUS_ERROR; 14.187 + vfree(vma->addr); 14.188 + return; 14.189 + } 14.190 + 14.191 + if ( up->status != DISCONNECTED ) 14.192 + { 14.193 + connect->status = USBIF_BE_STATUS_INTERFACE_CONNECTED; 14.194 + vfree(vma->addr); 14.195 + return; 14.196 + } 14.197 + 14.198 + up->evtchn = evtchn; 14.199 + up->irq = bind_evtchn_to_irq(evtchn); 14.200 + up->shmem_frame = shmem_frame; 14.201 + up->usb_ring_base = (usbif_t *)vma->addr; 14.202 + up->status = CONNECTED; 14.203 + usbif_get(up); 14.204 + 14.205 + request_irq(up->irq, usbif_be_int, 0, "usbif-backend", up); 14.206 + 14.207 + connect->status = USBIF_BE_STATUS_OKAY; 14.208 +} 14.209 + 14.210 +/* Remove URBs for this interface before destroying it. */ 14.211 +void usbif_deschedule(usbif_priv_t *up) 14.212 +{ 14.213 + remove_from_usbif_list(up); 14.214 +} 14.215 + 14.216 +int usbif_disconnect(usbif_be_disconnect_t *disconnect, u8 rsp_id) 14.217 +{ 14.218 + domid_t domid = disconnect->domid; 14.219 + usbif_priv_t *up; 14.220 + 14.221 + up = usbif_find(domid); 14.222 + if ( unlikely(up == NULL) ) 14.223 + { 14.224 + DPRINTK("usbif_disconnect attempted for non-existent usbif" 14.225 + " (%u)\n", disconnect->domid); 14.226 + disconnect->status = USBIF_BE_STATUS_INTERFACE_NOT_FOUND; 14.227 + return 1; /* Caller will send response error message. */ 14.228 + } 14.229 + 14.230 + if ( up->status == CONNECTED ) 14.231 + { 14.232 + up->status = DISCONNECTING; 14.233 + up->disconnect_rspid = rsp_id; 14.234 + wmb(); /* Let other CPUs see the status change. */ 14.235 + free_irq(up->irq, up); 14.236 + usbif_deschedule(up); 14.237 + usbif_put(up); 14.238 + return 0; /* Caller should not send response message. */ 14.239 + } 14.240 + 14.241 + disconnect->status = USBIF_BE_STATUS_OKAY; 14.242 + return 1; 14.243 +} 14.244 + 14.245 +void __init usbif_interface_init(void) 14.246 +{ 14.247 + usbif_priv_cachep = kmem_cache_create("usbif_priv_cache", 14.248 + sizeof(usbif_priv_t), 14.249 + 0, 0, NULL, NULL); 14.250 + memset(usbif_priv_hash, 0, sizeof(usbif_priv_hash)); 14.251 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c Fri Jan 28 14:53:32 2005 +0000 15.3 @@ -0,0 +1,1011 @@ 15.4 +/****************************************************************************** 15.5 + * arch/xen/drivers/usbif/backend/main.c 15.6 + * 15.7 + * Backend for the Xen virtual USB driver - provides an abstraction of a 15.8 + * USB host controller to the corresponding frontend driver. 15.9 + * 15.10 + * by Mark Williamson, Copyright (c) 2004 Intel Research Cambridge 15.11 + * 15.12 + * Based on arch/xen/drivers/blkif/backend/main.c 15.13 + * Copyright (c) 2003-2004, Keir Fraser & Steve Hand 15.14 + */ 15.15 + 15.16 +#include "common.h" 15.17 + 15.18 + 15.19 +#include <linux/list.h> 15.20 +#include <linux/usb.h> 15.21 +#include <linux/spinlock.h> 15.22 +#include <linux/module.h> 15.23 +#include <linux/tqueue.h> 15.24 + 15.25 +/* 15.26 + * This is rather arbitrary. 15.27 + */ 15.28 +#define MAX_PENDING_REQS 4 15.29 +#define BATCH_PER_DOMAIN 1 15.30 + 15.31 +static unsigned long mmap_vstart; 15.32 + 15.33 +/* Needs to be sufficiently large that we can map the (large) buffers 15.34 + * the USB mass storage driver wants. */ 15.35 +#define MMAP_PAGES_PER_REQUEST \ 15.36 + (128) 15.37 +#define MMAP_PAGES \ 15.38 + (MAX_PENDING_REQS * MMAP_PAGES_PER_REQUEST) 15.39 + 15.40 +#define MMAP_VADDR(_req,_seg) \ 15.41 + (mmap_vstart + \ 15.42 + ((_req) * MMAP_PAGES_PER_REQUEST * PAGE_SIZE) + \ 15.43 + ((_seg) * PAGE_SIZE)) 15.44 + 15.45 +#define MIN(x,y) ( ( x < y ) ? x : y ) 15.46 + 15.47 +static spinlock_t owned_ports_lock; 15.48 +LIST_HEAD(owned_ports); 15.49 + 15.50 +/* A list of these structures is used to track ownership of physical USB 15.51 + * ports. */ 15.52 +typedef struct 15.53 +{ 15.54 + usbif_priv_t *usbif_priv; 15.55 + char path[16]; 15.56 + int guest_port; 15.57 + int enabled; 15.58 + struct list_head list; 15.59 + unsigned long guest_address; /* The USB device address that has been 15.60 + * assigned by the guest. */ 15.61 + int dev_present; /* Is there a device present? */ 15.62 + struct usb_device * dev; 15.63 + unsigned long ifaces; /* What interfaces are present on this device? */ 15.64 +} owned_port_t; 15.65 + 15.66 + 15.67 +/* 15.68 + * Each outstanding request that we've passed to the lower device layers has a 15.69 + * 'pending_req' allocated to it. The request is complete, the specified 15.70 + * domain has a response queued for it, with the saved 'id' passed back. 15.71 + */ 15.72 +typedef struct { 15.73 + usbif_priv_t *usbif_priv; 15.74 + usbif_iso_t *iso_sched; 15.75 + unsigned long id; 15.76 + int nr_pages; 15.77 + unsigned short operation; 15.78 + int status; 15.79 +} pending_req_t; 15.80 + 15.81 +/* 15.82 + * We can't allocate pending_req's in order, since they may complete out of 15.83 + * order. We therefore maintain an allocation ring. This ring also indicates 15.84 + * when enough work has been passed down -- at that point the allocation ring 15.85 + * will be empty. 15.86 + */ 15.87 +static pending_req_t pending_reqs[MAX_PENDING_REQS]; 15.88 +static unsigned char pending_ring[MAX_PENDING_REQS]; 15.89 +static spinlock_t pend_prod_lock = SPIN_LOCK_UNLOCKED; 15.90 + 15.91 +/* NB. We use a different index type to differentiate from shared blk rings. */ 15.92 +typedef unsigned int PEND_RING_IDX; 15.93 +#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1)) 15.94 +static PEND_RING_IDX pending_prod, pending_cons; 15.95 +#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons) 15.96 + 15.97 +static int do_usb_io_op(usbif_priv_t *usbif, int max_to_do); 15.98 +static void make_response(usbif_priv_t *usbif, unsigned long id, 15.99 + unsigned short op, int st, int inband, 15.100 + unsigned long actual_length); 15.101 +static void dispatch_usb_probe(usbif_priv_t *up, unsigned long id, unsigned long port); 15.102 +static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req); 15.103 +static void dispatch_usb_reset(usbif_priv_t *up, unsigned long portid); 15.104 +static owned_port_t *usbif_find_port(char *); 15.105 + 15.106 + 15.107 +void dump_port(owned_port_t *p) 15.108 +{ 15.109 + printk("owned_port_t @ %p\n", p); 15.110 + printk(" usbif_priv @ %p\n", p->usbif_priv); 15.111 + printk(" path: %s\n", p->path); 15.112 + printk(" guest_port: %d\n", p->guest_port); 15.113 + printk(" guest_address: %ld\n", p->guest_address); 15.114 + printk(" dev_present: %d\n", p->dev_present); 15.115 + printk(" dev @ %p\n", p->dev); 15.116 + printk(" ifaces: 0x%lx\n", p->ifaces); 15.117 +} 15.118 + 15.119 + 15.120 + 15.121 +static void fast_flush_area(int idx, int nr_pages) 15.122 +{ 15.123 + multicall_entry_t mcl[MMAP_PAGES_PER_REQUEST]; 15.124 + int i; 15.125 + 15.126 + for ( i = 0; i < nr_pages; i++ ) 15.127 + { 15.128 + mcl[i].op = __HYPERVISOR_update_va_mapping; 15.129 + mcl[i].args[0] = MMAP_VADDR(idx, i) >> PAGE_SHIFT; 15.130 + mcl[i].args[1] = 0; 15.131 + mcl[i].args[2] = 0; 15.132 + } 15.133 + 15.134 + mcl[nr_pages-1].args[2] = UVMF_FLUSH_TLB; 15.135 + if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) ) 15.136 + BUG(); 15.137 +} 15.138 + 15.139 + 15.140 +/****************************************************************** 15.141 + * USB INTERFACE SCHEDULER LIST MAINTENANCE 15.142 + */ 15.143 + 15.144 +static struct list_head usbio_schedule_list; 15.145 +static spinlock_t usbio_schedule_list_lock; 15.146 + 15.147 +static int __on_usbif_list(usbif_priv_t *up) 15.148 +{ 15.149 + return up->usbif_list.next != NULL; 15.150 +} 15.151 + 15.152 +void remove_from_usbif_list(usbif_priv_t *up) 15.153 +{ 15.154 + unsigned long flags; 15.155 + if ( !__on_usbif_list(up) ) return; 15.156 + spin_lock_irqsave(&usbio_schedule_list_lock, flags); 15.157 + if ( __on_usbif_list(up) ) 15.158 + { 15.159 + list_del(&up->usbif_list); 15.160 + up->usbif_list.next = NULL; 15.161 + usbif_put(up); 15.162 + } 15.163 + spin_unlock_irqrestore(&usbio_schedule_list_lock, flags); 15.164 +} 15.165 + 15.166 +static void add_to_usbif_list_tail(usbif_priv_t *up) 15.167 +{ 15.168 + unsigned long flags; 15.169 + if ( __on_usbif_list(up) ) return; 15.170 + spin_lock_irqsave(&usbio_schedule_list_lock, flags); 15.171 + if ( !__on_usbif_list(up) && (up->status == CONNECTED) ) 15.172 + { 15.173 + list_add_tail(&up->usbif_list, &usbio_schedule_list); 15.174 + usbif_get(up); 15.175 + } 15.176 + spin_unlock_irqrestore(&usbio_schedule_list_lock, flags); 15.177 +} 15.178 + 15.179 + 15.180 +/****************************************************************** 15.181 + * COMPLETION CALLBACK -- Called as urb->complete() 15.182 + */ 15.183 + 15.184 +static void maybe_trigger_usbio_schedule(void); 15.185 + 15.186 +static void __end_usb_io_op(struct urb *purb) 15.187 +{ 15.188 + unsigned long flags; 15.189 + pending_req_t *pending_req; 15.190 + int pending_idx; 15.191 + 15.192 + pending_req = purb->context; 15.193 + 15.194 +/* printk("Completed for id = %p to 0x%lx - 0x%lx\n", pending_req->id, */ 15.195 +/* virt_to_machine(purb->transfer_buffer), */ 15.196 +/* virt_to_machine(purb->transfer_buffer) */ 15.197 +/* + pending_req->nr_pages * PAGE_SIZE); */ 15.198 + 15.199 + pending_idx = pending_req - pending_reqs; 15.200 + 15.201 + ASSERT(purb->actual_length <= purb->transfer_buffer_length); 15.202 + ASSERT(purb->actual_length <= pending_req->nr_pages * PAGE_SIZE); 15.203 + 15.204 + /* An error fails the entire request. */ 15.205 + if ( purb->status ) 15.206 + { 15.207 + printk("URB @ %p failed. Status %d\n", purb, purb->status); 15.208 + } 15.209 + 15.210 + if ( usb_pipetype(purb->pipe) == 0 ) 15.211 + { 15.212 + int i; 15.213 + usbif_iso_t *sched = (usbif_iso_t *)MMAP_VADDR(pending_idx, pending_req->nr_pages - 1); 15.214 + 15.215 + ASSERT(sched == pending_req->sched); 15.216 + 15.217 + // printk("writing back schedule at %p\n", sched); 15.218 + 15.219 + /* If we're dealing with an iso pipe, we need to copy back the schedule. */ 15.220 + for ( i = 0; i < purb->number_of_packets; i++ ) 15.221 + { 15.222 + sched[i].length = purb->iso_frame_desc[i].actual_length; 15.223 + ASSERT(sched[i].buffer_offset == 15.224 + purb->iso_frame_desc[i].offset); 15.225 + sched[i].status = purb->iso_frame_desc[i].status; 15.226 + } 15.227 + } 15.228 + 15.229 + // printk("Flushing %d pages\n", pending_req->nr_pages); 15.230 + fast_flush_area(pending_req - pending_reqs, pending_req->nr_pages); 15.231 + 15.232 + kfree(purb->setup_packet); 15.233 + 15.234 + spin_lock_irqsave(&pending_req->usbif_priv->usb_ring_lock, flags); 15.235 + make_response(pending_req->usbif_priv, pending_req->id, 15.236 + pending_req->operation, pending_req->status, 0, purb->actual_length); 15.237 + spin_unlock_irqrestore(&pending_req->usbif_priv->usb_ring_lock, flags); 15.238 + usbif_put(pending_req->usbif_priv); 15.239 + 15.240 + usb_free_urb(purb); 15.241 + 15.242 + /* Free the pending request. */ 15.243 + spin_lock_irqsave(&pend_prod_lock, flags); 15.244 + pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; 15.245 + spin_unlock_irqrestore(&pend_prod_lock, flags); 15.246 + 15.247 + rmb(); 15.248 + 15.249 + /* Check for anything still waiting in the rings, having freed a request... */ 15.250 + maybe_trigger_usbio_schedule(); 15.251 +} 15.252 + 15.253 +/****************************************************************** 15.254 + * SCHEDULER FUNCTIONS 15.255 + */ 15.256 + 15.257 +static DECLARE_WAIT_QUEUE_HEAD(usbio_schedule_wait); 15.258 + 15.259 +static int usbio_schedule(void *arg) 15.260 +{ 15.261 + DECLARE_WAITQUEUE(wq, current); 15.262 + 15.263 + usbif_priv_t *up; 15.264 + struct list_head *ent; 15.265 + 15.266 + daemonize(); 15.267 + 15.268 + for ( ; ; ) 15.269 + { 15.270 + /* Wait for work to do. */ 15.271 + add_wait_queue(&usbio_schedule_wait, &wq); 15.272 + set_current_state(TASK_INTERRUPTIBLE); 15.273 + if ( (NR_PENDING_REQS == MAX_PENDING_REQS) || 15.274 + list_empty(&usbio_schedule_list) ) 15.275 + schedule(); 15.276 + __set_current_state(TASK_RUNNING); 15.277 + remove_wait_queue(&usbio_schedule_wait, &wq); 15.278 + 15.279 + /* Queue up a batch of requests. */ 15.280 + while ( (NR_PENDING_REQS < MAX_PENDING_REQS) && 15.281 + !list_empty(&usbio_schedule_list) ) 15.282 + { 15.283 + ent = usbio_schedule_list.next; 15.284 + up = list_entry(ent, usbif_priv_t, usbif_list); 15.285 + usbif_get(up); 15.286 + remove_from_usbif_list(up); 15.287 + if ( do_usb_io_op(up, BATCH_PER_DOMAIN) ) 15.288 + add_to_usbif_list_tail(up); 15.289 + usbif_put(up); 15.290 + } 15.291 + } 15.292 +} 15.293 + 15.294 +static void maybe_trigger_usbio_schedule(void) 15.295 +{ 15.296 + /* 15.297 + * Needed so that two processes, who together make the following predicate 15.298 + * true, don't both read stale values and evaluate the predicate 15.299 + * incorrectly. Incredibly unlikely to stall the scheduler on x86, but... 15.300 + */ 15.301 + smp_mb(); 15.302 + 15.303 + if ( !list_empty(&usbio_schedule_list) ) 15.304 + wake_up(&usbio_schedule_wait); 15.305 +} 15.306 + 15.307 + 15.308 +/****************************************************************************** 15.309 + * NOTIFICATION FROM GUEST OS. 15.310 + */ 15.311 + 15.312 +irqreturn_t usbif_be_int(int irq, void *dev_id, struct pt_regs *regs) 15.313 +{ 15.314 + usbif_priv_t *up = dev_id; 15.315 + 15.316 + smp_mb(); 15.317 + 15.318 + add_to_usbif_list_tail(up); 15.319 + 15.320 + /* Will in fact /always/ trigger an io schedule in this case. */ 15.321 + maybe_trigger_usbio_schedule(); 15.322 + 15.323 + return IRQ_HANDLED; 15.324 +} 15.325 + 15.326 + 15.327 + 15.328 +/****************************************************************** 15.329 + * DOWNWARD CALLS -- These interface with the usb-device layer proper. 15.330 + */ 15.331 + 15.332 +static int do_usb_io_op(usbif_priv_t *up, int max_to_do) 15.333 +{ 15.334 + usbif_t *usb_ring = up->usb_ring_base; 15.335 + usbif_request_t *req; 15.336 + USBIF_RING_IDX i, rp; 15.337 + int more_to_do = 0; 15.338 + unsigned long flags; 15.339 + 15.340 + spin_lock_irqsave(&up->usb_ring_lock, flags); 15.341 + 15.342 + rp = usb_ring->req_prod; 15.343 + rmb(); /* Ensure we see queued requests up to 'rp'. */ 15.344 + 15.345 + /* Take items off the comms ring, taking care not to overflow. */ 15.346 + for ( i = up->usb_req_cons; 15.347 + (i != rp) && ((i-up->usb_resp_prod) != USBIF_RING_SIZE); 15.348 + i++ ) 15.349 + { 15.350 + if ( (max_to_do-- == 0) || (NR_PENDING_REQS == MAX_PENDING_REQS) ) 15.351 + { 15.352 + more_to_do = 1; 15.353 + break; 15.354 + } 15.355 + 15.356 + req = &usb_ring->ring[MASK_USBIF_IDX(i)].req; 15.357 + 15.358 + switch ( req->operation ) 15.359 + { 15.360 + case USBIF_OP_PROBE: 15.361 + dispatch_usb_probe(up, req->id, req->port); 15.362 + break; 15.363 + 15.364 + case USBIF_OP_IO: 15.365 + /* Assemble an appropriate URB. */ 15.366 + dispatch_usb_io(up, req); 15.367 + break; 15.368 + 15.369 + case USBIF_OP_RESET: 15.370 + dispatch_usb_reset(up, req->port); 15.371 + break; 15.372 + 15.373 + default: 15.374 + DPRINTK("error: unknown USB io operation [%d]\n", 15.375 + req->operation); 15.376 + make_response(up, req->id, req->operation, -EINVAL, 0, 0); 15.377 + break; 15.378 + } 15.379 + } 15.380 + 15.381 + up->usb_req_cons = i; 15.382 + 15.383 + spin_unlock_irqrestore(&up->usb_ring_lock, flags); 15.384 + 15.385 + return more_to_do; 15.386 +} 15.387 + 15.388 +static owned_port_t *find_guest_port(usbif_priv_t *up, int port) 15.389 +{ 15.390 + unsigned long flags; 15.391 + struct list_head *l; 15.392 + 15.393 + spin_lock_irqsave(&owned_ports_lock, flags); 15.394 + list_for_each(l, &owned_ports) 15.395 + { 15.396 + owned_port_t *p = list_entry(l, owned_port_t, list); 15.397 + if(p->usbif_priv == up && p->guest_port == port) 15.398 + { 15.399 + spin_unlock_irqrestore(&owned_ports_lock, flags); 15.400 + return p; 15.401 + } 15.402 + } 15.403 + spin_unlock_irqrestore(&owned_ports_lock, flags); 15.404 + 15.405 + return NULL; 15.406 +} 15.407 + 15.408 +static void dispatch_usb_reset(usbif_priv_t *up, unsigned long portid) 15.409 +{ 15.410 + owned_port_t *port = find_guest_port(up, portid); 15.411 + int ret = 0; 15.412 + 15.413 + 15.414 + /* Allowing the guest to actually reset the device causes more problems 15.415 + * than it's worth. We just fake it out in software but we will do a real 15.416 + * reset when the interface is destroyed. */ 15.417 + 15.418 +#if 0 15.419 + printk("Reset port %d\n", portid); 15.420 + 15.421 + dump_port(port); 15.422 +#endif 15.423 + 15.424 + port->guest_address = 0; 15.425 + /* If there's an attached device then the port is now enabled. */ 15.426 + if ( port->dev_present ) 15.427 + port->enabled = 1; 15.428 + else 15.429 + port->enabled = 0; 15.430 + 15.431 + make_response(up, 0, USBIF_OP_RESET, ret, 0, 0); 15.432 +} 15.433 + 15.434 +static void dispatch_usb_probe(usbif_priv_t *up, unsigned long id, unsigned long portid) 15.435 +{ 15.436 + owned_port_t *port = find_guest_port(up, portid); 15.437 + int ret; 15.438 + 15.439 + if ( port != NULL ) 15.440 + ret = port->dev_present; 15.441 + else 15.442 + { 15.443 + ret = -EINVAL; 15.444 + printk("dispatch_usb_probe(): invalid port probe request (port %ld)\n", 15.445 + portid); 15.446 + } 15.447 + 15.448 + /* Probe result is sent back in-band. Probes don't have an associated id 15.449 + * right now... */ 15.450 + make_response(up, id, USBIF_OP_PROBE, ret, portid, 0); 15.451 +} 15.452 + 15.453 +owned_port_t *find_port_for_request(usbif_priv_t *up, usbif_request_t *req); 15.454 + 15.455 +static void dump_request(usbif_request_t *req) 15.456 +{ 15.457 + printk("id = 0x%lx\n", req->id); 15.458 + 15.459 + printk("devnum %d\n", req->devnum); 15.460 + printk("endpoint 0x%x\n", req->endpoint); 15.461 + printk("direction %d\n", req->direction); 15.462 + printk("speed %d\n", req->speed); 15.463 + printk("pipe_type 0x%x\n", req->pipe_type); 15.464 + printk("transfer_buffer 0x%lx\n", req->transfer_buffer); 15.465 + printk("length 0x%lx\n", req->length); 15.466 + printk("transfer_flags 0x%lx\n", req->transfer_flags); 15.467 + printk("setup = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", 15.468 + req->setup[0], req->setup[1], req->setup[2], req->setup[3], 15.469 + req->setup[4], req->setup[5], req->setup[6], req->setup[7]); 15.470 + printk("iso_schedule = 0x%lx\n", req->iso_schedule); 15.471 + printk("num_iso %ld\n", req->num_iso); 15.472 +} 15.473 + 15.474 +void dump_urb(struct urb *urb) 15.475 +{ 15.476 + printk("dumping urb @ %p\n", urb); 15.477 + 15.478 +#define DUMP_URB_FIELD(name, format) printk(" " # name " " format "\n", urb-> name) 15.479 + 15.480 + DUMP_URB_FIELD(pipe, "0x%x"); 15.481 + DUMP_URB_FIELD(status, "%d"); 15.482 + DUMP_URB_FIELD(transfer_flags, "0x%x"); 15.483 + DUMP_URB_FIELD(transfer_buffer, "%p"); 15.484 + DUMP_URB_FIELD(transfer_buffer_length, "%d"); 15.485 + DUMP_URB_FIELD(actual_length, "%d"); 15.486 +} 15.487 + 15.488 + 15.489 +static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req) 15.490 +{ 15.491 + unsigned long buffer_mach; 15.492 + int i = 0, offset = 0, 15.493 + pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; 15.494 + pending_req_t *pending_req; 15.495 + unsigned long remap_prot; 15.496 + multicall_entry_t mcl[MMAP_PAGES_PER_REQUEST]; 15.497 + struct urb *purb = NULL; 15.498 + owned_port_t *port; 15.499 + unsigned char *setup; 15.500 + 15.501 +// dump_request(req); 15.502 + 15.503 + if ( NR_PENDING_REQS == MAX_PENDING_REQS ) 15.504 + { 15.505 + printk("usbback: Max requests already queued. Now giving up!\n"); 15.506 + 15.507 + return; 15.508 + } 15.509 + 15.510 + port = find_port_for_request(up, req); 15.511 + 15.512 + if(port == NULL) 15.513 + { 15.514 + printk("No such device! (%d)\n", req->devnum); 15.515 + dump_request(req); 15.516 + 15.517 + make_response(up, req->id, req->operation, -ENODEV, 0, 0); 15.518 + return; 15.519 + } 15.520 + 15.521 + setup = kmalloc(8, GFP_ATOMIC | GFP_NOIO); 15.522 + 15.523 + if ( setup == NULL ) 15.524 + goto no_mem; 15.525 + 15.526 + /* Copy request out for safety. */ 15.527 + memcpy(setup, req->setup, 8); 15.528 + 15.529 + if( setup[0] == 0x0 && setup[1] == 0x5) 15.530 + { 15.531 + /* To virtualise the USB address space, we need to intercept 15.532 + * set_address messages and emulate. From the USB specification: 15.533 + * bmRequestType = 0x0; 15.534 + * Brequest = SET_ADDRESS (i.e. 0x5) 15.535 + * wValue = device address 15.536 + * wIndex = 0 15.537 + * wLength = 0 15.538 + * data = None 15.539 + */ 15.540 + /* Store into the guest transfer buffer using cpu_to_le16 */ 15.541 + port->guest_address = le16_to_cpu(*(u16 *)(setup + 2)); 15.542 + /* Make a successful response. That was easy! */ 15.543 + 15.544 + make_response(up, req->id, req->operation, 0, 0, 0); 15.545 + 15.546 + kfree(setup); 15.547 + return; 15.548 + } 15.549 + else if ( setup[0] == 0x0 && setup[1] == 0x9 ) 15.550 + { 15.551 + /* The host kernel needs to know what device configuration is in use 15.552 + * because various error checks get confused otherwise. We just do 15.553 + * configuration settings here, under controlled conditions. 15.554 + */ 15.555 + usb_set_configuration(port->dev, setup[2]); 15.556 + 15.557 + make_response(up, req->id, req->operation, 0, 0, 0); 15.558 + 15.559 + kfree(setup); 15.560 + return; 15.561 + } 15.562 + 15.563 + else if ( setup[0] == 0x1 && setup[1] == 0xB ) 15.564 + { 15.565 + /* The host kernel needs to know what device interface is in use 15.566 + * because various error checks get confused otherwise. We just do 15.567 + * configuration settings here, under controlled conditions. 15.568 + */ 15.569 + usb_set_interface(port->dev, (setup[4] | setup[5] << 8), 15.570 + (setup[2] | setup[3] << 8) ); 15.571 + 15.572 + make_response(up, req->id, req->operation, 0, 0, 0); 15.573 + 15.574 + kfree(setup); 15.575 + return; 15.576 + } 15.577 + 15.578 + if ( ( req->transfer_buffer - (req->transfer_buffer & PAGE_MASK) 15.579 + + req->length ) 15.580 + > MMAP_PAGES_PER_REQUEST * PAGE_SIZE ) 15.581 + { 15.582 + printk("usbback: request of %d bytes too large, failing it\n", req->length); 15.583 + make_response(up, req->id, req->operation, -EINVAL, 0, 0); 15.584 + kfree(setup); 15.585 + return; 15.586 + } 15.587 + 15.588 + buffer_mach = req->transfer_buffer; 15.589 + 15.590 + if( buffer_mach == 0 ) 15.591 + goto no_remap; 15.592 + 15.593 + ASSERT((req->length >> PAGE_SHIFT) <= MMAP_PAGES_PER_REQUEST); 15.594 + ASSERT(buffer_mach); 15.595 + 15.596 + /* Always map writeable for now. */ 15.597 + remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_RW; 15.598 + 15.599 + for ( i = 0, offset = 0; offset < req->length; 15.600 + i++, offset += PAGE_SIZE ) 15.601 + { 15.602 + // printk("length = %d, offset = %d, looping!\n", req->length, offset); 15.603 + 15.604 + mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain; 15.605 + mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT; 15.606 + mcl[i].args[1] = ((buffer_mach & PAGE_MASK) + offset) | remap_prot; 15.607 + mcl[i].args[2] = 0; 15.608 + mcl[i].args[3] = up->domid; 15.609 + 15.610 + phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] = 15.611 + FOREIGN_FRAME((buffer_mach + offset) >> PAGE_SHIFT); 15.612 + // printk("i = %d\n", i); 15.613 + 15.614 + ASSERT(virt_to_machine(MMAP_VADDR(pending_idx, i)) 15.615 + == buffer_mach + i << PAGE_SHIFT); 15.616 + } 15.617 + 15.618 + if ( req->pipe_type == 0 && req->num_iso > 0 ) /* Maybe schedule ISO... */ 15.619 + { 15.620 + // printk("for iso, i = %d\n", i); 15.621 + /* Map in ISO schedule, if necessary. */ 15.622 + mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain; 15.623 + mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT; 15.624 + mcl[i].args[1] = (req->iso_schedule & PAGE_MASK) | remap_prot; 15.625 + mcl[i].args[2] = 0; 15.626 + mcl[i].args[3] = up->domid; 15.627 + 15.628 + phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] = 15.629 + FOREIGN_FRAME(req->iso_schedule >> PAGE_SHIFT); 15.630 + 15.631 + // printk("Mapped iso at %p\n", MMAP_VADDR(pending_idx, i)); 15.632 + i++; 15.633 + } 15.634 + 15.635 + // printk("Well we got this far!\n"); 15.636 + 15.637 + if ( unlikely(HYPERVISOR_multicall(mcl, i) != 0) ) 15.638 + BUG(); 15.639 + 15.640 + { 15.641 + int j; 15.642 + for ( j = 0; j < i; j++ ) 15.643 + { 15.644 + if ( unlikely(mcl[j].args[5] != 0) ) 15.645 + { 15.646 + printk("invalid buffer %d -- could not remap it\n", j); 15.647 + fast_flush_area(pending_idx, i); 15.648 + printk("sending invalid descriptor\n"); 15.649 + goto bad_descriptor; 15.650 + } 15.651 + } 15.652 + } 15.653 + 15.654 + no_remap: 15.655 + 15.656 + ASSERT(i <= MMAP_PAGES_PER_REQUEST); 15.657 + ASSERT(i * PAGE_SIZE >= req->length); 15.658 + 15.659 + /* We have to do this because some things might complete out of order. */ 15.660 + pending_req = &pending_reqs[pending_idx]; 15.661 + pending_req->usbif_priv= up; 15.662 + pending_req->id = req->id; 15.663 + pending_req->operation = req->operation; 15.664 + pending_req->nr_pages = i; 15.665 + 15.666 + 15.667 + 15.668 + pending_cons++; 15.669 + 15.670 + usbif_get(up); 15.671 + 15.672 + /* Fill out an actual request for the USB layer. */ 15.673 + purb = usb_alloc_urb(req->num_iso); 15.674 + 15.675 + if ( purb == NULL ) 15.676 + goto no_mem; 15.677 + 15.678 + purb->dev = port->dev; 15.679 + purb->context = pending_req; 15.680 + purb->transfer_buffer = (void *)MMAP_VADDR(pending_idx, 0) + (buffer_mach & ~PAGE_MASK); 15.681 + if(buffer_mach == 0) 15.682 + purb->transfer_buffer = NULL; 15.683 + purb->complete = __end_usb_io_op; 15.684 + purb->transfer_buffer_length = req->length; 15.685 + purb->transfer_flags = req->transfer_flags; 15.686 + 15.687 +/* if ( req->transfer_flags != 0 ) */ 15.688 +/* dump_request(req); */ 15.689 + 15.690 + purb->pipe = 0; 15.691 + purb->pipe |= req->direction << 7; 15.692 + purb->pipe |= port->dev->devnum << 8; 15.693 + purb->pipe |= req->speed << 26; 15.694 + purb->pipe |= req->pipe_type << 30; 15.695 + purb->pipe |= req->endpoint << 15; 15.696 + 15.697 + purb->number_of_packets = req->num_iso; 15.698 + 15.699 + /* Make sure there's always some kind of timeout. */ 15.700 + purb->timeout = ( req->timeout > 0 ) ? (req->timeout * HZ) / 1000 15.701 + : 1000; 15.702 + 15.703 + purb->setup_packet = setup; 15.704 + 15.705 + if ( req->pipe_type == 0 ) /* ISO */ 15.706 + { 15.707 + int j; 15.708 + usbif_iso_t *iso_sched = (usbif_iso_t *)MMAP_VADDR(pending_idx, i - 1); 15.709 + 15.710 + // printk("Reading iso sched at %p\n", iso_sched); 15.711 + 15.712 + /* If we're dealing with an iso pipe, we need to copy in a schedule. */ 15.713 + for ( j = 0; j < req->num_iso; j++ ) 15.714 + { 15.715 + purb->iso_frame_desc[j].length = iso_sched[j].length; 15.716 + purb->iso_frame_desc[j].offset = iso_sched[j].buffer_offset; 15.717 + iso_sched[j].status = 0; 15.718 + } 15.719 + pending_req->iso_sched = iso_sched; 15.720 + } 15.721 + 15.722 + { 15.723 + int ret; 15.724 + ret = usb_submit_urb(purb); 15.725 + 15.726 + // dump_urb(purb); 15.727 + 15.728 + if ( ret != 0 ) 15.729 + goto bad_descriptor; /* XXX free pending here! */ 15.730 + } 15.731 + 15.732 + return; 15.733 + 15.734 + bad_descriptor: 15.735 + kfree ( setup ); 15.736 + if ( purb != NULL ) 15.737 + usb_free_urb(purb); 15.738 + make_response(up, req->id, req->operation, -EINVAL, 0, 0); 15.739 + return; 15.740 + 15.741 + no_mem: 15.742 + if ( setup != NULL ) 15.743 + kfree(setup); 15.744 + make_response(up, req->id, req->operation, -ENOMEM, 0, 0); 15.745 + return; 15.746 +} 15.747 + 15.748 + 15.749 + 15.750 +/****************************************************************** 15.751 + * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING 15.752 + */ 15.753 + 15.754 + 15.755 +static void make_response(usbif_priv_t *up, unsigned long id, 15.756 + unsigned short op, int st, int inband, 15.757 + unsigned long length) 15.758 +{ 15.759 + usbif_response_t *resp; 15.760 + unsigned long flags; 15.761 + 15.762 +#if 0 15.763 + printk("usbback: Sending response:\n"); 15.764 + printk(" id = 0x%x\n", id); 15.765 + printk(" op = %d\n", op); 15.766 + printk(" status = %d\n", st); 15.767 + printk(" data = %d\n", inband); 15.768 + printk(" length = %d\n", length); 15.769 +#endif 15.770 + 15.771 + /* Place on the response ring for the relevant domain. */ 15.772 + spin_lock_irqsave(&up->usb_ring_lock, flags); 15.773 + resp = &up->usb_ring_base-> 15.774 + ring[MASK_USBIF_IDX(up->usb_resp_prod)].resp; 15.775 + resp->id = id; 15.776 + resp->operation = op; 15.777 + resp->status = st; 15.778 + resp->data = inband; 15.779 + resp->length = length; 15.780 + wmb(); /* Ensure other side can see the response fields. */ 15.781 + up->usb_ring_base->resp_prod = ++up->usb_resp_prod; 15.782 + spin_unlock_irqrestore(&up->usb_ring_lock, flags); 15.783 + 15.784 + /* Kick the relevant domain. */ 15.785 + notify_via_evtchn(up->evtchn); 15.786 +} 15.787 + 15.788 +/** 15.789 + * usbif_claim_port - claim devices on a port on behalf of guest 15.790 + * 15.791 + * Once completed, this will ensure that any device attached to that 15.792 + * port is claimed by this driver for use by the guest. 15.793 + */ 15.794 +int usbif_claim_port(usbif_be_claim_port_t *msg) 15.795 +{ 15.796 + owned_port_t *o_p; 15.797 + 15.798 + /* Sanity... */ 15.799 + if ( usbif_find_port(msg->path) != NULL ) 15.800 + { 15.801 + printk("usbback: Attempted to claim USB port " 15.802 + "we already own!\n"); 15.803 + return -EINVAL; 15.804 + } 15.805 + 15.806 + spin_lock_irq(&owned_ports_lock); 15.807 + 15.808 + /* No need for a slab cache - this should be infrequent. */ 15.809 + o_p = kmalloc(sizeof(owned_port_t), GFP_KERNEL); 15.810 + 15.811 + o_p->enabled = 0; 15.812 + o_p->usbif_priv = usbif_find(msg->domid); 15.813 + o_p->guest_port = msg->usbif_port; 15.814 + o_p->dev_present = 0; 15.815 + o_p->guest_address = 0; /* Default address. */ 15.816 + 15.817 + strcpy(o_p->path, msg->path); 15.818 + 15.819 + list_add(&o_p->list, &owned_ports); 15.820 + 15.821 + printk("usbback: Claimed USB port (%s) for %d.%d\n", o_p->path, 15.822 + msg->domid, msg->usbif_port); 15.823 + 15.824 + spin_unlock_irq(&owned_ports_lock); 15.825 + 15.826 + /* Force a reprobe for unclaimed devices. */ 15.827 + usb_scan_devices(); 15.828 + 15.829 + return 0; 15.830 +} 15.831 + 15.832 +owned_port_t *find_port_for_request(usbif_priv_t *up, usbif_request_t *req) 15.833 +{ 15.834 + unsigned long flags; 15.835 + struct list_head *port; 15.836 + 15.837 + /* I'm assuming this is not called from IRQ context - correct? I think 15.838 + * it's probably only called in response to control messages or plug events 15.839 + * in the USB hub kernel thread, so should be OK. */ 15.840 + spin_lock_irqsave(&owned_ports_lock, flags); 15.841 + list_for_each(port, &owned_ports) 15.842 + { 15.843 + owned_port_t *p = list_entry(port, owned_port_t, list); 15.844 + if(p->usbif_priv == up && p->guest_address == req->devnum && p->enabled ) 15.845 + { 15.846 +#if 0 15.847 + printk("Found port for devnum %d\n", req->devnum); 15.848 + 15.849 + dump_port(p); 15.850 +#endif 15.851 + return p; 15.852 + } 15.853 + } 15.854 + spin_unlock_irqrestore(&owned_ports_lock, flags); 15.855 + 15.856 + return NULL; 15.857 +} 15.858 + 15.859 +owned_port_t *usbif_find_port(char *path) 15.860 +{ 15.861 + struct list_head *port; 15.862 + unsigned long flags; 15.863 + 15.864 + spin_lock_irqsave(&owned_ports_lock, flags); 15.865 + list_for_each(port, &owned_ports) 15.866 + { 15.867 + owned_port_t *p = list_entry(port, owned_port_t, list); 15.868 + if(!strcmp(path, p->path)) 15.869 + { 15.870 + spin_unlock_irqrestore(&owned_ports_lock, flags); 15.871 + return p; 15.872 + } 15.873 + } 15.874 + spin_unlock_irqrestore(&owned_ports_lock, flags); 15.875 + 15.876 + return NULL; 15.877 +} 15.878 + 15.879 + 15.880 +static void *probe(struct usb_device *dev, unsigned iface, 15.881 + const struct usb_device_id *id) 15.882 +{ 15.883 + owned_port_t *p; 15.884 + 15.885 + /* We don't care what the device is - if we own the port, we want it. We 15.886 + * don't deal with device-specifics in this driver, so we don't care what 15.887 + * the device actually is ;-) */ 15.888 + if ( ( p = usbif_find_port(dev->devpath) ) != NULL ) 15.889 + { 15.890 + printk("usbback: claimed device attached to owned port\n"); 15.891 + 15.892 + p->dev_present = 1; 15.893 + p->dev = dev; 15.894 + set_bit(iface, &p->ifaces); 15.895 + 15.896 + return p->usbif_priv; 15.897 + } 15.898 + else 15.899 + printk("usbback: hotplug for non-owned port (%s), ignoring\n", dev->devpath); 15.900 + 15.901 + 15.902 + return NULL; 15.903 +} 15.904 + 15.905 +static void disconnect(struct usb_device *dev, void *usbif) 15.906 +{ 15.907 + /* Note the device is removed so we can tell the guest when it probes. */ 15.908 + owned_port_t *port = usbif_find_port(dev->devpath); 15.909 + port->dev_present = 0; 15.910 + port->dev = NULL; 15.911 + port->ifaces = 0; 15.912 +} 15.913 + 15.914 + 15.915 +struct usb_driver driver = 15.916 +{ 15.917 + .owner = THIS_MODULE, 15.918 + .name = "Xen USB Backend", 15.919 + .probe = probe, 15.920 + .disconnect = disconnect, 15.921 + .id_table = NULL, 15.922 +}; 15.923 + 15.924 +/* __usbif_release_port - internal mechanics for releasing a port */ 15.925 +void __usbif_release_port(owned_port_t *p) 15.926 +{ 15.927 + int i; 15.928 + 15.929 + for ( i = 0; p->ifaces != 0; i++) 15.930 + if ( p->ifaces & 1 << i ) 15.931 + { 15.932 + usb_driver_release_interface(&driver, usb_ifnum_to_if(p->dev, i)); 15.933 + clear_bit(i, &p->ifaces); 15.934 + } 15.935 + list_del(&p->list); 15.936 + 15.937 + /* Reset the real device. We don't simulate disconnect / probe for other 15.938 + * drivers in this kernel because we assume the device is completely under 15.939 + * the control of ourselves (i.e. the guest!). This should ensure that the 15.940 + * device is in a sane state for the next customer ;-) */ 15.941 +/* if ( p->dev != NULL) */ 15.942 +/* usb_reset_device(p->dev); */ 15.943 + 15.944 + kfree(p); 15.945 +} 15.946 + 15.947 + 15.948 +/** 15.949 + * usbif_release_port - stop claiming devices on a port on behalf of guest 15.950 + */ 15.951 +void usbif_release_port(usbif_be_release_port_t *msg) 15.952 +{ 15.953 + owned_port_t *p; 15.954 + 15.955 + spin_lock_irq(&owned_ports_lock); 15.956 + p = usbif_find_port(msg->path); 15.957 + __usbif_release_port(p); 15.958 + spin_unlock_irq(&owned_ports_lock); 15.959 +} 15.960 + 15.961 +void usbif_release_ports(usbif_priv_t *up) 15.962 +{ 15.963 + struct list_head *port, *tmp; 15.964 + unsigned long flags; 15.965 + 15.966 + spin_lock_irqsave(&owned_ports_lock, flags); 15.967 + list_for_each_safe(port, tmp, &owned_ports) 15.968 + { 15.969 + owned_port_t *p = list_entry(port, owned_port_t, list); 15.970 + if ( p->usbif_priv == up ) 15.971 + __usbif_release_port(p); 15.972 + } 15.973 + spin_unlock_irqrestore(&owned_ports_lock, flags); 15.974 +} 15.975 + 15.976 +static int __init usbif_init(void) 15.977 +{ 15.978 + int i; 15.979 + 15.980 + if ( !(xen_start_info.flags & SIF_INITDOMAIN) && 15.981 + !(xen_start_info.flags & SIF_USB_BE_DOMAIN) ) 15.982 + return 0; 15.983 + 15.984 + INIT_LIST_HEAD(&owned_ports); 15.985 + 15.986 + usb_register(&driver); 15.987 + 15.988 + usbif_interface_init(); 15.989 + 15.990 + if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 ) 15.991 + BUG(); 15.992 + 15.993 + pending_cons = 0; 15.994 + pending_prod = MAX_PENDING_REQS; 15.995 + memset(pending_reqs, 0, sizeof(pending_reqs)); 15.996 + for ( i = 0; i < MAX_PENDING_REQS; i++ ) 15.997 + pending_ring[i] = i; 15.998 + 15.999 + spin_lock_init(&usbio_schedule_list_lock); 15.1000 + INIT_LIST_HEAD(&usbio_schedule_list); 15.1001 + 15.1002 + if ( kernel_thread(usbio_schedule, 0, CLONE_FS | CLONE_FILES) < 0 ) 15.1003 + BUG(); 15.1004 + 15.1005 + usbif_ctrlif_init(); 15.1006 + 15.1007 + spin_lock_init(&owned_ports_lock); 15.1008 + 15.1009 + printk("Xen USB Backend Initialised"); 15.1010 + 15.1011 + return 0; 15.1012 +} 15.1013 + 15.1014 +__initcall(usbif_init);
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c Fri Jan 28 14:53:32 2005 +0000 16.3 @@ -0,0 +1,1720 @@ 16.4 +/* 16.5 + * Xen Virtual USB Frontend Driver 16.6 + * 16.7 + * This file contains the first version of the Xen virtual USB hub 16.8 + * that I've managed not to delete by mistake (3rd time lucky!). 16.9 + * 16.10 + * Based on Linux's uhci.c, original copyright notices are displayed 16.11 + * below. Portions also (c) 2004 Intel Research Cambridge 16.12 + * and (c) 2004 Mark Williamson 16.13 + * 16.14 + * Contact <mark.williamson@cl.cam.ac.uk> or 16.15 + * <xen-devel@lists.sourceforge.net> regarding this code. 16.16 + * 16.17 + * Still to be (maybe) implemented: 16.18 + * - multiple port 16.19 + * - multiple interfaces 16.20 + * - migration / backend restart support? 16.21 + * - unloading support 16.22 + * 16.23 + * Differences to a normal host controller: 16.24 + * - the backend does most of the mucky stuff so we don't have to do various 16.25 + * things that are necessary for a normal host controller (e.g. FSBR). 16.26 + * - we don't have any hardware, so status registers are simulated in software. 16.27 + */ 16.28 + 16.29 +/* 16.30 + * Universal Host Controller Interface driver for USB. 16.31 + * 16.32 + * Maintainer: Johannes Erdfelt <johannes@erdfelt.com> 16.33 + * 16.34 + * (C) Copyright 1999 Linus Torvalds 16.35 + * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com 16.36 + * (C) Copyright 1999 Randy Dunlap 16.37 + * (C) Copyright 1999 Georg Acher, acher@in.tum.de 16.38 + * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de 16.39 + * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch 16.40 + * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at 16.41 + * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface 16.42 + * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). 16.43 + * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) 16.44 + * 16.45 + * Intel documents this fairly well, and as far as I know there 16.46 + * are no royalties or anything like that, but even so there are 16.47 + * people who decided that they want to do the same thing in a 16.48 + * completely different way. 16.49 + * 16.50 + * WARNING! The USB documentation is downright evil. Most of it 16.51 + * is just crap, written by a committee. You're better off ignoring 16.52 + * most of it, the important stuff is: 16.53 + * - the low-level protocol (fairly simple but lots of small details) 16.54 + * - working around the horridness of the rest 16.55 + */ 16.56 + 16.57 +#include <linux/config.h> 16.58 +#include <linux/module.h> 16.59 +#include <linux/kernel.h> 16.60 +#include <linux/init.h> 16.61 +#include <linux/delay.h> 16.62 +#include <linux/ioport.h> 16.63 +#include <linux/sched.h> 16.64 +#include <linux/slab.h> 16.65 +#include <linux/smp_lock.h> 16.66 +#include <linux/errno.h> 16.67 +#include <linux/unistd.h> 16.68 +#include <linux/interrupt.h> 16.69 +#include <linux/spinlock.h> 16.70 +#ifdef CONFIG_USB_DEBUG 16.71 +#define DEBUG 16.72 +#else 16.73 +#undef DEBUG 16.74 +#endif 16.75 +#include <linux/usb.h> 16.76 + 16.77 +#include <asm/uaccess.h> 16.78 +#include <asm/irq.h> 16.79 +#include <asm/system.h> 16.80 + 16.81 +#include "xhci.h" 16.82 + 16.83 +#include <linux/pm.h> 16.84 + 16.85 +#include "../../../../../drivers/usb/hcd.h" 16.86 + 16.87 +#include <asm-xen/xen-public/io/usbif.h> 16.88 +#include <asm/ctrl_if.h> 16.89 +#include <asm/xen-public/io/domain_controller.h> 16.90 + 16.91 +/* 16.92 + * Version Information 16.93 + */ 16.94 +#define DRIVER_VERSION "v1.0" 16.95 +#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, Mark Williamson" 16.96 +#define DRIVER_DESC "Xen Virtual USB Host Controller Interface driver" 16.97 + 16.98 +/* 16.99 + * debug = 0, no debugging messages 16.100 + * debug = 1, dump failed URB's except for stalls 16.101 + * debug = 2, dump all failed URB's (including stalls) 16.102 + */ 16.103 +#ifdef DEBUG 16.104 +static int debug = 1; 16.105 +#else 16.106 +static int debug = 0; 16.107 +#endif 16.108 +MODULE_PARM(debug, "i"); 16.109 +MODULE_PARM_DESC(debug, "Debug level"); 16.110 +static char *errbuf; 16.111 +#define ERRBUF_LEN (PAGE_SIZE * 8) 16.112 + 16.113 +static kmem_cache_t *xhci_up_cachep; /* urb_priv */ 16.114 + 16.115 +static int rh_submit_urb(struct urb *urb); 16.116 +static int rh_unlink_urb(struct urb *urb); 16.117 +//static int xhci_get_current_frame_number(struct usb_device *dev); 16.118 +static int xhci_unlink_urb(struct urb *urb); 16.119 +static void xhci_unlink_generic(struct urb *urb); 16.120 +static void xhci_call_completion(struct urb *urb); 16.121 +static void xhci_drain_ring(void); 16.122 + 16.123 +#define MAX_URB_LOOP 2048 /* Maximum number of linked URB's */ 16.124 + 16.125 +struct xhci *xhci; 16.126 + 16.127 +enum { USBIF_STATE_CONNECTED = 2, 16.128 + USBIF_STATE_DISCONNECTED = 1, 16.129 + USBIF_STATE_CLOSED =0 16.130 +}; 16.131 + 16.132 +static int awaiting_reset = 0; 16.133 + 16.134 +/** 16.135 + * xhci_construct_isoc - add isochronous information to a request 16.136 + */ 16.137 +int xhci_construct_isoc(usbif_request_t *req, struct urb *urb) 16.138 +{ 16.139 + usbif_iso_t *schedule; 16.140 + int i; 16.141 + struct urb_priv *urb_priv = urb->hcpriv; 16.142 + 16.143 + req->num_iso = urb->number_of_packets; 16.144 + schedule = (usbif_iso_t *)__get_free_page(GFP_KERNEL); 16.145 + 16.146 + if ( schedule == NULL ) 16.147 + return -ENOMEM; 16.148 + 16.149 + for ( i = 0; i < req->num_iso; i++ ) 16.150 + { 16.151 + schedule[i].buffer_offset = urb->iso_frame_desc[i].offset; 16.152 + schedule[i].length = urb->iso_frame_desc[i].length; 16.153 + } 16.154 + 16.155 + urb_priv->schedule = schedule; 16.156 + req->iso_schedule = virt_to_machine(schedule); 16.157 + 16.158 + return 0; 16.159 +} 16.160 + 16.161 +#define USBIF_RING_FULL ((xhci->usbif->req_prod - xhci->usb_resp_cons) == USBIF_RING_SIZE) 16.162 + 16.163 +static void dump_urb(struct urb *urb) 16.164 +{ 16.165 + printk("dumping urb @ %p\n", urb); 16.166 + 16.167 + printk("hcpriv = %p\n", urb->hcpriv); 16.168 + printk("next = %p\n", urb->next); 16.169 + printk("dev = %p\n", urb->dev); 16.170 + printk("pipe = 0x%lx\n", urb->pipe); 16.171 + printk("status = %d\n", urb->status); 16.172 + printk("transfer_flags = 0x%lx\n", urb->transfer_flags); 16.173 + printk("transfer_buffer = %p\n", urb->transfer_buffer); 16.174 + printk("transfer_buffer_length = %d\n", urb->transfer_buffer_length); 16.175 + printk("actual_length = %d\n", urb->actual_length); 16.176 + printk("bandwidth = %d\n", urb->bandwidth); 16.177 + printk("setup_packet = %p\n", urb->setup_packet); 16.178 + if ( urb->setup_packet != NULL ) 16.179 + printk("setup = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", 16.180 + urb->setup_packet[0], urb->setup_packet[1], urb->setup_packet[2], urb->setup_packet[3], 16.181 + urb->setup_packet[4], urb->setup_packet[5], urb->setup_packet[6], urb->setup_packet[7]); 16.182 + printk("complete = %p\n", urb->complete); 16.183 + printk("interval = %d\n", urb->interval); 16.184 + 16.185 +} 16.186 + 16.187 + 16.188 +static int 16.189 +xhci_queue_req(struct urb *urb) 16.190 +{ 16.191 + usbif_request_t *req; 16.192 + usbif_t *usbif = xhci->usbif; 16.193 + 16.194 +#if 0 16.195 + printk("usbif = %p, req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons = %d\n", 16.196 + usbif, usbif->req_prod, virt_to_machine(&usbif->req_prod), 16.197 + usbif->resp_prod, xhci->usb_resp_cons); 16.198 +#endif 16.199 + 16.200 + 16.201 +/* printk("Usbif_priv %p, want IO at 0x%lx\n", urb->hcpriv, virt_to_machine(urb->transfer_buffer)); */ 16.202 + 16.203 + if ( USBIF_RING_FULL ) 16.204 + { 16.205 + printk("xhci_queue_req(): USB ring full, not queuing request\n"); 16.206 + return -ENOBUFS; 16.207 + } 16.208 + 16.209 + /* Stick something in the shared communications ring. */ 16.210 + req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 16.211 + 16.212 + req->operation = USBIF_OP_IO; 16.213 + req->port = 0; /* We don't care what the port is. */ 16.214 + req->id = (unsigned long) urb->hcpriv; 16.215 + req->transfer_buffer = virt_to_machine(urb->transfer_buffer); 16.216 + req->devnum = usb_pipedevice(urb->pipe); 16.217 + req->direction = usb_pipein(urb->pipe); 16.218 + req->speed = usb_pipeslow(urb->pipe); 16.219 + req->pipe_type = usb_pipetype(urb->pipe); 16.220 + req->length = urb->transfer_buffer_length; 16.221 + req->transfer_flags = urb->transfer_flags; 16.222 + req->endpoint = usb_pipeendpoint(urb->pipe); 16.223 + req->speed = usb_pipeslow(urb->pipe); 16.224 + req->timeout = urb->timeout * (1000 / HZ); 16.225 + 16.226 + if ( usb_pipetype(urb->pipe) == 0 ) /* ISO */ 16.227 + { 16.228 + int ret = xhci_construct_isoc(req, urb); 16.229 + if ( ret != 0 ) 16.230 + return ret; 16.231 + } 16.232 + 16.233 + if(urb->setup_packet != NULL) 16.234 + memcpy(req->setup, urb->setup_packet, 8); 16.235 + else 16.236 + memset(req->setup, 0, 8); 16.237 + 16.238 + wmb(); 16.239 + 16.240 + usbif->req_prod++; 16.241 + 16.242 + notify_via_evtchn(xhci->evtchn); 16.243 + 16.244 + // dump_urb(urb); 16.245 + 16.246 + return -EINPROGRESS; 16.247 +} 16.248 + 16.249 +static inline usbif_request_t * 16.250 +xhci_queue_probe(usbif_vdev_t port) 16.251 +{ 16.252 + usbif_request_t *req; 16.253 + usbif_t *usbif = xhci->usbif; 16.254 + 16.255 +#if 0 16.256 + printk("queuing probe: req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons = %d\n", 16.257 + usbif->req_prod, virt_to_machine(&usbif->req_prod), 16.258 + usbif->resp_prod, xhci->usb_resp_cons); 16.259 +#endif 16.260 + 16.261 + if ( USBIF_RING_FULL ) 16.262 + { 16.263 + printk("xhci_queue_probe(): USB ring full, not queuing request\n"); 16.264 + return NULL; 16.265 + } 16.266 + 16.267 + /* Stick something in the shared communications ring. */ 16.268 + req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 16.269 + 16.270 + req->operation = USBIF_OP_PROBE; 16.271 + req->port = port; 16.272 + req->id = 0; 16.273 + req->transfer_buffer = 0; 16.274 + req->devnum = 0; 16.275 + req->direction = 0; 16.276 + req->speed = 0; 16.277 + req->pipe_type = 0; 16.278 + req->length = 0; 16.279 + req->transfer_flags = 0; 16.280 + req->endpoint = 0; 16.281 + req->speed = 0; 16.282 + 16.283 + wmb(); 16.284 + 16.285 + usbif->req_prod++; 16.286 + 16.287 + notify_via_evtchn(xhci->evtchn); 16.288 + 16.289 + return req; 16.290 +} 16.291 + 16.292 +static int 16.293 +xhci_port_reset(usbif_vdev_t port) 16.294 +{ 16.295 + usbif_request_t *req; 16.296 + usbif_t *usbif = xhci->usbif; 16.297 + 16.298 + /* We only reset one port at a time, so we only need one variable per 16.299 + * hub. */ 16.300 + awaiting_reset = 1; 16.301 + 16.302 + /* Stick something in the shared communications ring. */ 16.303 + req = &usbif->ring[MASK_USBIF_IDX(usbif->req_prod)].req; 16.304 + 16.305 + req->operation = USBIF_OP_RESET; 16.306 + req->port = port; 16.307 + 16.308 + wmb(); 16.309 + 16.310 + usbif->req_prod++; 16.311 + 16.312 + notify_via_evtchn(xhci->evtchn); 16.313 + 16.314 + while ( awaiting_reset > 0 ) 16.315 + { 16.316 + mdelay(1); 16.317 + xhci_drain_ring(); 16.318 + } 16.319 + 16.320 + return awaiting_reset; 16.321 +} 16.322 + 16.323 +static void xhci_show_resp(usbif_response_t *r) 16.324 +{ 16.325 + printk("id=0x%lx, op=0x%x, data=0x%x, status=0x%x, length=0x%lx\n", 16.326 + r->id, r->operation, r->data, r->status, r->length); 16.327 +} 16.328 + 16.329 + 16.330 +/* 16.331 + * Only the USB core should call xhci_alloc_dev and xhci_free_dev 16.332 + */ 16.333 +static int xhci_alloc_dev(struct usb_device *dev) 16.334 +{ 16.335 + return 0; 16.336 +} 16.337 + 16.338 +static int xhci_free_dev(struct usb_device *dev) 16.339 +{ 16.340 + return 0; 16.341 +} 16.342 + 16.343 +static inline void xhci_add_complete(struct urb *urb) 16.344 +{ 16.345 + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 16.346 + unsigned long flags; 16.347 + 16.348 + spin_lock_irqsave(&xhci->complete_list_lock, flags); 16.349 + list_add_tail(&urbp->complete_list, &xhci->complete_list); 16.350 + spin_unlock_irqrestore(&xhci->complete_list_lock, flags); 16.351 +} 16.352 + 16.353 +/* When this returns, the owner of the URB may free its 16.354 + * storage. 16.355 + * 16.356 + * We spin and wait for the URB to complete before returning. 16.357 + */ 16.358 +static void xhci_delete_urb(struct urb *urb) 16.359 +{ 16.360 + struct urb_priv *urbp; 16.361 + 16.362 + urbp = urb->hcpriv; 16.363 + 16.364 + /* If there's no urb_priv structure for this URB then it can't have 16.365 + * been submitted at all. */ 16.366 + if ( urbp == NULL ) 16.367 + return; 16.368 + 16.369 + /* For now we just spin until the URB completes. It shouldn't take too 16.370 + * long and we don't expect to have to do this very often. */ 16.371 + while ( urb->status == -EINPROGRESS ) 16.372 + { 16.373 + xhci_drain_ring(); 16.374 + mdelay(1); 16.375 + } 16.376 + 16.377 + /* Now we know that further transfers to the buffer won't 16.378 + * occur, so we can safely return. */ 16.379 +} 16.380 + 16.381 +static struct urb_priv *xhci_alloc_urb_priv(struct urb *urb) 16.382 +{ 16.383 + struct urb_priv *urbp; 16.384 + 16.385 + urbp = kmem_cache_alloc(xhci_up_cachep, SLAB_ATOMIC); 16.386 + if (!urbp) { 16.387 + err("xhci_alloc_urb_priv: couldn't allocate memory for urb_priv\n"); 16.388 + return NULL; 16.389 + } 16.390 + 16.391 + memset((void *)urbp, 0, sizeof(*urbp)); 16.392 + 16.393 + urbp->inserttime = jiffies; 16.394 + urbp->urb = urb; 16.395 + urbp->dev = urb->dev; 16.396 + 16.397 + INIT_LIST_HEAD(&urbp->complete_list); 16.398 + 16.399 + urb->hcpriv = urbp; 16.400 + 16.401 + return urbp; 16.402 +} 16.403 + 16.404 +/* 16.405 + * MUST be called with urb->lock acquired 16.406 + */ 16.407 +/* When is this called? Do we need to stop the transfer (as we 16.408 + * currently do)? */ 16.409 +static void xhci_destroy_urb_priv(struct urb *urb) 16.410 +{ 16.411 + struct urb_priv *urbp; 16.412 + 16.413 + urbp = (struct urb_priv *)urb->hcpriv; 16.414 + if (!urbp) 16.415 + return; 16.416 + 16.417 + if (!list_empty(&urb->urb_list)) 16.418 + warn("xhci_destroy_urb_priv: urb %p still on xhci->urb_list or xhci->remove_list", urb); 16.419 + 16.420 + if (!list_empty(&urbp->complete_list)) 16.421 + warn("xhci_destroy_urb_priv: urb %p still on xhci->complete_list", urb); 16.422 + 16.423 + kmem_cache_free(xhci_up_cachep, urb->hcpriv); 16.424 + 16.425 + urb->hcpriv = NULL; 16.426 +} 16.427 + 16.428 +/** 16.429 + * Try to find URBs in progress on the same pipe to the same device. 16.430 + * 16.431 + * MUST be called with xhci->urb_list_lock acquired 16.432 + */ 16.433 +static struct urb *xhci_find_urb_ep(struct xhci *xhci, struct urb *urb) 16.434 +{ 16.435 + struct list_head *tmp, *head; 16.436 + 16.437 + /* We don't match Isoc transfers since they are special */ 16.438 + if (usb_pipeisoc(urb->pipe)) 16.439 + return NULL; 16.440 + 16.441 + head = &xhci->urb_list; 16.442 + tmp = head->next; 16.443 + while (tmp != head) { 16.444 + struct urb *u = list_entry(tmp, struct urb, urb_list); 16.445 + 16.446 + tmp = tmp->next; 16.447 + 16.448 + if (u->dev == urb->dev && u->pipe == urb->pipe && 16.449 + u->status == -EINPROGRESS) 16.450 + return u; 16.451 + } 16.452 + 16.453 + return NULL; 16.454 +} 16.455 + 16.456 +static int xhci_submit_urb(struct urb *urb) 16.457 +{ 16.458 + int ret = -EINVAL; 16.459 + unsigned long flags; 16.460 + struct urb *eurb; 16.461 + int bustime; 16.462 + 16.463 +#if 0 16.464 + printk("submitting urb @ %p for dev @ %p, devnum = %d path %s\n", 16.465 + urb, urb->dev, urb->dev->devnum, urb->dev->devpath); 16.466 +#endif 16.467 + 16.468 + if (!urb) 16.469 + return -EINVAL; 16.470 + 16.471 + if (!urb->dev || !urb->dev->bus || !urb->dev->bus->hcpriv) { 16.472 + warn("xhci_submit_urb: urb %p belongs to disconnected device or bus?", urb); 16.473 + return -ENODEV; 16.474 + } 16.475 + 16.476 + if ( urb->dev->devpath == NULL ) 16.477 + { 16.478 + printk("BARF!\n"); 16.479 + BUG(); 16.480 + } 16.481 + 16.482 + 16.483 + 16.484 + usb_inc_dev_use(urb->dev); 16.485 + 16.486 + spin_lock_irqsave(&xhci->urb_list_lock, flags); 16.487 + spin_lock(&urb->lock); 16.488 + 16.489 + if (urb->status == -EINPROGRESS || urb->status == -ECONNRESET || 16.490 + urb->status == -ECONNABORTED) { 16.491 + dbg("xhci_submit_urb: urb not available to submit (status = %d)", urb->status); 16.492 + /* Since we can have problems on the out path */ 16.493 + spin_unlock(&urb->lock); 16.494 + spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 16.495 + usb_dec_dev_use(urb->dev); 16.496 + 16.497 + return ret; 16.498 + } 16.499 + 16.500 + INIT_LIST_HEAD(&urb->urb_list); 16.501 + if (!xhci_alloc_urb_priv(urb)) { 16.502 + ret = -ENOMEM; 16.503 + 16.504 + goto out; 16.505 + } 16.506 + 16.507 + ( (struct urb_priv *)urb->hcpriv )->in_progress = 1; 16.508 + 16.509 + eurb = xhci_find_urb_ep(xhci, urb); 16.510 + if (eurb && !(urb->transfer_flags & USB_QUEUE_BULK)) { 16.511 + ret = -ENXIO; 16.512 + 16.513 + goto out; 16.514 + } 16.515 + 16.516 + /* Short circuit the virtual root hub */ 16.517 + if (urb->dev == xhci->rh.dev) { 16.518 + ret = rh_submit_urb(urb); 16.519 + 16.520 + goto out; 16.521 + } 16.522 + 16.523 + if ( usb_pipedevice(urb->pipe) == 1 ) 16.524 + printk("dev = %p, dev->path = %s, rh.dev = %p, rh.dev.devnum = %d rh.dev->path = %s!\n", 16.525 + urb->dev, urb->dev->devpath, xhci->rh.dev, xhci->rh.dev->devnum, xhci->rh.dev->devpath); 16.526 + 16.527 + switch (usb_pipetype(urb->pipe)) { 16.528 + case PIPE_CONTROL: 16.529 + ret = xhci_queue_req(urb); 16.530 + break; 16.531 + case PIPE_INTERRUPT: 16.532 + if (urb->bandwidth == 0) { /* not yet checked/allocated */ 16.533 + bustime = usb_check_bandwidth(urb->dev, urb); 16.534 + if (bustime < 0) 16.535 + ret = bustime; 16.536 + else { 16.537 + ret = xhci_queue_req(urb); 16.538 + if (ret == -EINPROGRESS) 16.539 + usb_claim_bandwidth(urb->dev, urb, bustime, 0); 16.540 + } 16.541 + } else /* bandwidth is already set */ 16.542 + ret = xhci_queue_req(urb); 16.543 + break; 16.544 + case PIPE_BULK: 16.545 + ret = xhci_queue_req(urb); 16.546 + break; 16.547 + case PIPE_ISOCHRONOUS: 16.548 + if (urb->bandwidth == 0) { /* not yet checked/allocated */ 16.549 + if (urb->number_of_packets <= 0) { 16.550 + ret = -EINVAL; 16.551 + break; 16.552 + } 16.553 + bustime = usb_check_bandwidth(urb->dev, urb); 16.554 + if (bustime < 0) { 16.555 + ret = bustime; 16.556 + break; 16.557 + } 16.558 + 16.559 + ret = xhci_queue_req(urb); 16.560 + if (ret == -EINPROGRESS) 16.561 + usb_claim_bandwidth(urb->dev, urb, bustime, 1); 16.562 + } else /* bandwidth is already set */ 16.563 + ret = xhci_queue_req(urb); 16.564 + break; 16.565 + } 16.566 + 16.567 +out: 16.568 + urb->status = ret; 16.569 + 16.570 + if (ret == -EINPROGRESS) { 16.571 + /* We use _tail to make find_urb_ep more efficient */ 16.572 + list_add_tail(&urb->urb_list, &xhci->urb_list); 16.573 + 16.574 + spin_unlock(&urb->lock); 16.575 + spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 16.576 + 16.577 + return 0; 16.578 + } 16.579 + 16.580 + xhci_unlink_generic(urb); 16.581 + 16.582 + spin_unlock(&urb->lock); 16.583 + spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 16.584 + 16.585 + /* Only call completion if it was successful */ 16.586 + if (!ret) 16.587 + xhci_call_completion(urb); 16.588 + 16.589 + return ret; 16.590 +} 16.591 + 16.592 +/* 16.593 + * Return the result of a transfer 16.594 + * 16.595 + * MUST be called with urb_list_lock acquired 16.596 + */ 16.597 +static void xhci_transfer_result(struct xhci *xhci, struct urb *urb) 16.598 +{ 16.599 + int ret = 0; 16.600 + unsigned long flags; 16.601 + struct urb_priv *urbp; 16.602 + 16.603 + /* The root hub is special */ 16.604 + if (urb->dev == xhci->rh.dev) 16.605 + return; 16.606 + 16.607 + spin_lock_irqsave(&urb->lock, flags); 16.608 + 16.609 + urbp = (struct urb_priv *)urb->hcpriv; 16.610 + 16.611 + if ( ( (struct urb_priv *)urb->hcpriv )->in_progress ) 16.612 + ret = -EINPROGRESS; 16.613 + 16.614 + if (urb->actual_length < urb->transfer_buffer_length) { 16.615 + if (urb->transfer_flags & USB_DISABLE_SPD) { 16.616 + ret = -EREMOTEIO; 16.617 + } 16.618 + } 16.619 + 16.620 + if (urb->status == -EPIPE) 16.621 + { 16.622 + ret = urb->status; 16.623 + /* endpoint has stalled - mark it halted */ 16.624 + usb_endpoint_halt(urb->dev, usb_pipeendpoint(urb->pipe), 16.625 + usb_pipeout(urb->pipe)); 16.626 + } 16.627 + 16.628 + if ((debug == 1 && ret != 0 && ret != -EPIPE) || 16.629 + (ret != 0 && debug > 1)) { 16.630 + /* Some debugging code */ 16.631 + dbg("xhci_result_interrupt/bulk() failed with status %x", 16.632 + status); 16.633 + } 16.634 + 16.635 + if (ret == -EINPROGRESS) 16.636 + goto out; 16.637 + 16.638 + switch (usb_pipetype(urb->pipe)) { 16.639 + case PIPE_CONTROL: 16.640 + case PIPE_BULK: 16.641 + case PIPE_ISOCHRONOUS: 16.642 + /* Release bandwidth for Interrupt or Isoc. transfers */ 16.643 + /* Spinlock needed ? */ 16.644 + if (urb->bandwidth) 16.645 + usb_release_bandwidth(urb->dev, urb, 1); 16.646 + xhci_unlink_generic(urb); 16.647 + break; 16.648 + case PIPE_INTERRUPT: 16.649 + /* Interrupts are an exception */ 16.650 + if (urb->interval) 16.651 + goto out_complete; 16.652 + 16.653 + /* Release bandwidth for Interrupt or Isoc. transfers */ 16.654 + /* Spinlock needed ? */ 16.655 + if (urb->bandwidth) 16.656 + usb_release_bandwidth(urb->dev, urb, 0); 16.657 + xhci_unlink_generic(urb); 16.658 + break; 16.659 + default: 16.660 + info("xhci_transfer_result: unknown pipe type %d for urb %p\n", 16.661 + usb_pipetype(urb->pipe), urb); 16.662 + } 16.663 + 16.664 + /* Remove it from xhci->urb_list */ 16.665 + list_del_init(&urb->urb_list); 16.666 + 16.667 +out_complete: 16.668 + xhci_add_complete(urb); 16.669 + 16.670 +out: 16.671 + spin_unlock_irqrestore(&urb->lock, flags); 16.672 +} 16.673 + 16.674 +/* 16.675 + * MUST be called with urb->lock acquired 16.676 + */ 16.677 +static void xhci_unlink_generic(struct urb *urb) 16.678 +{ 16.679 + struct urb_priv *urbp = urb->hcpriv; 16.680 + 16.681 + /* We can get called when urbp allocation fails, so check */ 16.682 + if (!urbp) 16.683 + return; 16.684 + 16.685 + /* ??? This function is now so minimal it doesn't do much. Do we really 16.686 + * need it? */ 16.687 + 16.688 + xhci_delete_urb(urb); 16.689 +} 16.690 + 16.691 +static int xhci_unlink_urb(struct urb *urb) 16.692 +{ 16.693 + unsigned long flags; 16.694 + struct urb_priv *urbp = urb->hcpriv; 16.695 + 16.696 + if (!urb) 16.697 + return -EINVAL; 16.698 + 16.699 + if (!urb->dev || !urb->dev->bus || !urb->dev->bus->hcpriv) 16.700 + return -ENODEV; 16.701 + 16.702 + spin_lock_irqsave(&xhci->urb_list_lock, flags); 16.703 + spin_lock(&urb->lock); 16.704 + 16.705 + /* Release bandwidth for Interrupt or Isoc. transfers */ 16.706 + /* Spinlock needed ? */ 16.707 + if (urb->bandwidth) { 16.708 + switch (usb_pipetype(urb->pipe)) { 16.709 + case PIPE_INTERRUPT: 16.710 + usb_release_bandwidth(urb->dev, urb, 0); 16.711 + break; 16.712 + case PIPE_ISOCHRONOUS: 16.713 + usb_release_bandwidth(urb->dev, urb, 1); 16.714 + break; 16.715 + default: 16.716 + break; 16.717 + } 16.718 + } 16.719 + 16.720 + if (urb->status != -EINPROGRESS) { 16.721 + spin_unlock(&urb->lock); 16.722 + spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 16.723 + return 0; 16.724 + } 16.725 + 16.726 + list_del_init(&urb->urb_list); 16.727 + 16.728 + xhci_unlink_generic(urb); 16.729 + 16.730 + /* Short circuit the virtual root hub */ 16.731 + if (urb->dev == xhci->rh.dev) { 16.732 + rh_unlink_urb(urb); 16.733 + 16.734 + spin_unlock(&urb->lock); 16.735 + spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 16.736 + 16.737 + xhci_call_completion(urb); 16.738 + } else { 16.739 + if (urb->transfer_flags & USB_ASYNC_UNLINK) { 16.740 + urbp->status = urb->status = -ECONNABORTED; 16.741 + 16.742 + spin_lock(&xhci->urb_remove_list_lock); 16.743 + 16.744 + list_add(&urb->urb_list, &xhci->urb_remove_list); 16.745 + 16.746 + spin_unlock(&xhci->urb_remove_list_lock); 16.747 + 16.748 + spin_unlock(&urb->lock); 16.749 + spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 16.750 + 16.751 + } else { 16.752 + urb->status = -ENOENT; 16.753 + 16.754 + spin_unlock(&urb->lock); 16.755 + spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 16.756 + 16.757 + if (in_interrupt()) { /* wait at least 1 frame */ 16.758 + static int errorcount = 10; 16.759 + 16.760 + if (errorcount--) 16.761 + dbg("xhci_unlink_urb called from interrupt for urb %p", urb); 16.762 + udelay(1000); 16.763 + } else 16.764 + schedule_timeout(1+1*HZ/1000); 16.765 + 16.766 + xhci_call_completion(urb); 16.767 + } 16.768 + } 16.769 + 16.770 + return 0; 16.771 +} 16.772 + 16.773 + 16.774 +struct usb_operations xhci_device_operations = { 16.775 + .allocate = xhci_alloc_dev, 16.776 + .deallocate = xhci_free_dev, 16.777 + /* It doesn't look like any drivers actually care what the frame number 16.778 + * is at the moment! If necessary, we could approximate the current 16.779 + * frame nubmer by passing it from the backend in response messages. */ 16.780 + .get_frame_number = NULL, 16.781 + .submit_urb = xhci_submit_urb, 16.782 + .unlink_urb = xhci_unlink_urb 16.783 +}; 16.784 + 16.785 +/* Virtual Root Hub */ 16.786 + 16.787 +static __u8 root_hub_dev_des[] = 16.788 +{ 16.789 + 0x12, /* __u8 bLength; */ 16.790 + 0x01, /* __u8 bDescriptorType; Device */ 16.791 + 0x00, /* __u16 bcdUSB; v1.0 */ 16.792 + 0x01, 16.793 + 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 16.794 + 0x00, /* __u8 bDeviceSubClass; */ 16.795 + 0x00, /* __u8 bDeviceProtocol; */ 16.796 + 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ 16.797 + 0x00, /* __u16 idVendor; */ 16.798 + 0x00, 16.799 + 0x00, /* __u16 idProduct; */ 16.800 + 0x00, 16.801 + 0x00, /* __u16 bcdDevice; */ 16.802 + 0x00, 16.803 + 0x00, /* __u8 iManufacturer; */ 16.804 + 0x02, /* __u8 iProduct; */ 16.805 + 0x01, /* __u8 iSerialNumber; */ 16.806 + 0x01 /* __u8 bNumConfigurations; */ 16.807 +}; 16.808 + 16.809 + 16.810 +/* Configuration descriptor */ 16.811 +static __u8 root_hub_config_des[] = 16.812 +{ 16.813 + 0x09, /* __u8 bLength; */ 16.814 + 0x02, /* __u8 bDescriptorType; Configuration */ 16.815 + 0x19, /* __u16 wTotalLength; */ 16.816 + 0x00, 16.817 + 0x01, /* __u8 bNumInterfaces; */ 16.818 + 0x01, /* __u8 bConfigurationValue; */ 16.819 + 0x00, /* __u8 iConfiguration; */ 16.820 + 0x40, /* __u8 bmAttributes; 16.821 + Bit 7: Bus-powered, 6: Self-powered, 16.822 + Bit 5 Remote-wakeup, 4..0: resvd */ 16.823 + 0x00, /* __u8 MaxPower; */ 16.824 + 16.825 + /* interface */ 16.826 + 0x09, /* __u8 if_bLength; */ 16.827 + 0x04, /* __u8 if_bDescriptorType; Interface */ 16.828 + 0x00, /* __u8 if_bInterfaceNumber; */ 16.829 + 0x00, /* __u8 if_bAlternateSetting; */ 16.830 + 0x01, /* __u8 if_bNumEndpoints; */ 16.831 + 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ 16.832 + 0x00, /* __u8 if_bInterfaceSubClass; */ 16.833 + 0x00, /* __u8 if_bInterfaceProtocol; */ 16.834 + 0x00, /* __u8 if_iInterface; */ 16.835 + 16.836 + /* endpoint */ 16.837 + 0x07, /* __u8 ep_bLength; */ 16.838 + 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 16.839 + 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 16.840 + 0x03, /* __u8 ep_bmAttributes; Interrupt */ 16.841 + 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */ 16.842 + 0x00, 16.843 + 0xff /* __u8 ep_bInterval; 255 ms */ 16.844 +}; 16.845 + 16.846 +static __u8 root_hub_hub_des[] = 16.847 +{ 16.848 + 0x09, /* __u8 bLength; */ 16.849 + 0x29, /* __u8 bDescriptorType; Hub-descriptor */ 16.850 + 0x02, /* __u8 bNbrPorts; */ 16.851 + 0x00, /* __u16 wHubCharacteristics; */ 16.852 + 0x00, 16.853 + 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ 16.854 + 0x00, /* __u8 bHubContrCurrent; 0 mA */ 16.855 + 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */ 16.856 + 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ 16.857 +}; 16.858 + 16.859 +/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */ 16.860 +static int rh_send_irq(struct urb *urb) 16.861 +{ 16.862 + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 16.863 + xhci_port_t *ports = xhci->rh.ports; 16.864 + unsigned long flags; 16.865 + int i, len = 1; 16.866 + __u16 data = 0; 16.867 + 16.868 + spin_lock_irqsave(&urb->lock, flags); 16.869 + for (i = 0; i < xhci->rh.numports; i++) { 16.870 + /* MAW: No idea what the old code was doing here or why it worked. 16.871 + * This implementation sets a bit if anything at all has changed on the 16.872 + * port, as per USB spec 11.12 */ 16.873 + data |= (ports[i].cs_chg || ports[i].pe_chg ) 16.874 + ? (1 << (i + 1)) 16.875 + : 0; 16.876 + 16.877 + len = (i + 1) / 8 + 1; 16.878 + } 16.879 + 16.880 + *(__u16 *) urb->transfer_buffer = cpu_to_le16(data); 16.881 + urb->actual_length = len; 16.882 + urbp->status = 0; 16.883 + 16.884 + spin_unlock_irqrestore(&urb->lock, flags); 16.885 + 16.886 + if ((data > 0) && (xhci->rh.send != 0)) { 16.887 + dbg("root-hub INT complete: data: %x", data); 16.888 + xhci_call_completion(urb); 16.889 + } 16.890 + 16.891 + return 0; 16.892 +} 16.893 + 16.894 +/* Virtual Root Hub INTs are polled by this timer every "interval" ms */ 16.895 +static int rh_init_int_timer(struct urb *urb); 16.896 + 16.897 +static void rh_int_timer_do(unsigned long ptr) 16.898 +{ 16.899 + struct urb *urb = (struct urb *)ptr; 16.900 + struct list_head list, *tmp, *head; 16.901 + unsigned long flags; 16.902 + int i; 16.903 + 16.904 + for ( i = 0; i < xhci->rh.numports; i++) 16.905 + xhci_queue_probe(i); 16.906 + 16.907 + if (xhci->rh.send) 16.908 + rh_send_irq(urb); 16.909 + 16.910 + INIT_LIST_HEAD(&list); 16.911 + 16.912 + spin_lock_irqsave(&xhci->urb_list_lock, flags); 16.913 + head = &xhci->urb_list; 16.914 + tmp = head->next; 16.915 + while (tmp != head) { 16.916 + struct urb *u = list_entry(tmp, struct urb, urb_list); 16.917 + struct urb_priv *up = (struct urb_priv *)u->hcpriv; 16.918 + 16.919 + tmp = tmp->next; 16.920 + 16.921 + spin_lock(&u->lock); 16.922 + 16.923 + /* Check if the URB timed out */ 16.924 + if (u->timeout && time_after_eq(jiffies, up->inserttime + u->timeout)) { 16.925 + list_del(&u->urb_list); 16.926 + list_add_tail(&u->urb_list, &list); 16.927 + } 16.928 + 16.929 + spin_unlock(&u->lock); 16.930 + } 16.931 + spin_unlock_irqrestore(&xhci->urb_list_lock, flags); 16.932 + 16.933 + head = &list; 16.934 + tmp = head->next; 16.935 + while (tmp != head) { 16.936 + struct urb *u = list_entry(tmp, struct urb, urb_list); 16.937 + 16.938 + tmp = tmp->next; 16.939 + 16.940 + u->transfer_flags |= USB_ASYNC_UNLINK | USB_TIMEOUT_KILLED; 16.941 + xhci_unlink_urb(u); 16.942 + } 16.943 + 16.944 + rh_init_int_timer(urb); 16.945 +} 16.946 + 16.947 +/* Root Hub INTs are polled by this timer */ 16.948 +static int rh_init_int_timer(struct urb *urb) 16.949 +{ 16.950 + xhci->rh.interval = urb->interval; 16.951 + init_timer(&xhci->rh.rh_int_timer); 16.952 + xhci->rh.rh_int_timer.function = rh_int_timer_do; 16.953 + xhci->rh.rh_int_timer.data = (unsigned long)urb; 16.954 + xhci->rh.rh_int_timer.expires = jiffies + (HZ * (urb->interval < 30 ? 30 : urb->interval)) / 1000; 16.955 + add_timer(&xhci->rh.rh_int_timer); 16.956 + 16.957 + return 0; 16.958 +} 16.959 + 16.960 +#define OK(x) len = (x); break 16.961 + 16.962 +/* Root Hub Control Pipe */ 16.963 +static int rh_submit_urb(struct urb *urb) 16.964 +{ 16.965 + unsigned int pipe = urb->pipe; 16.966 + struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *)urb->setup_packet; 16.967 + void *data = urb->transfer_buffer; 16.968 + int leni = urb->transfer_buffer_length; 16.969 + int len = 0; 16.970 + xhci_port_t *status; 16.971 + int stat = 0; 16.972 + int i; 16.973 + int retstatus; 16.974 + unsigned long flags; 16.975 + 16.976 + __u16 cstatus; 16.977 + __u16 bmRType_bReq; 16.978 + __u16 wValue; 16.979 + __u16 wIndex; 16.980 + __u16 wLength; 16.981 + 16.982 + if (usb_pipetype(pipe) == PIPE_INTERRUPT) { 16.983 + xhci->rh.urb = urb; 16.984 + xhci->rh.send = 1; 16.985 + xhci->rh.interval = urb->interval; 16.986 + rh_init_int_timer(urb); 16.987 + 16.988 + return -EINPROGRESS; 16.989 + } 16.990 + 16.991 + bmRType_bReq = cmd->bRequestType | cmd->bRequest << 8; 16.992 + wValue = le16_to_cpu(cmd->wValue); 16.993 + wIndex = le16_to_cpu(cmd->wIndex); 16.994 + wLength = le16_to_cpu(cmd->wLength); 16.995 + 16.996 + for (i = 0; i < 8; i++) 16.997 + xhci->rh.c_p_r[i] = 0; 16.998 + 16.999 + status = &xhci->rh.ports[wIndex - 1]; 16.1000 + 16.1001 + spin_lock_irqsave(&xhci->rh.port_state_lock, flags); 16.1002 + 16.1003 + switch (bmRType_bReq) { 16.1004 + /* Request Destination: 16.1005 + without flags: Device, 16.1006 + RH_INTERFACE: interface, 16.1007 + RH_ENDPOINT: endpoint, 16.1008 + RH_CLASS means HUB here, 16.1009 + RH_OTHER | RH_CLASS almost ever means HUB_PORT here 16.1010 + */ 16.1011 + 16.1012 + case RH_GET_STATUS: 16.1013 + *(__u16 *)data = cpu_to_le16(1); 16.1014 + OK(2); 16.1015 + case RH_GET_STATUS | RH_INTERFACE: 16.1016 + *(__u16 *)data = cpu_to_le16(0); 16.1017 + OK(2); 16.1018 + case RH_GET_STATUS | RH_ENDPOINT: 16.1019 + *(__u16 *)data = cpu_to_le16(0); 16.1020 + OK(2); 16.1021 + case RH_GET_STATUS | RH_CLASS: 16.1022 + *(__u32 *)data = cpu_to_le32(0); 16.1023 + OK(4); /* hub power */ 16.1024 + case RH_GET_STATUS | RH_OTHER | RH_CLASS: 16.1025 + cstatus = (status->cs_chg) | 16.1026 + (status->pe_chg << 1) | 16.1027 + (xhci->rh.c_p_r[wIndex - 1] << 4); 16.1028 + retstatus = (status->ccs) | 16.1029 + (status->pe << 1) | 16.1030 + (status->susp << 2) | 16.1031 + (status->pr << 8) | 16.1032 + (1 << 8) | /* power on */ 16.1033 + (status->lsda << 9); 16.1034 + *(__u16 *)data = cpu_to_le16(retstatus); 16.1035 + *(__u16 *)(data + 2) = cpu_to_le16(cstatus); 16.1036 + OK(4); 16.1037 + case RH_CLEAR_FEATURE | RH_ENDPOINT: 16.1038 + switch (wValue) { 16.1039 + case RH_ENDPOINT_STALL: 16.1040 + OK(0); 16.1041 + } 16.1042 + break; 16.1043 + case RH_CLEAR_FEATURE | RH_CLASS: 16.1044 + switch (wValue) { 16.1045 + case RH_C_HUB_OVER_CURRENT: 16.1046 + OK(0); /* hub power over current */ 16.1047 + } 16.1048 + break; 16.1049 + case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: 16.1050 + switch (wValue) { 16.1051 + case RH_PORT_ENABLE: 16.1052 + status->pe = 0; 16.1053 + OK(0); 16.1054 + case RH_PORT_SUSPEND: 16.1055 + status->susp = 0; 16.1056 + OK(0); 16.1057 + case RH_PORT_POWER: 16.1058 + OK(0); /* port power */ 16.1059 + case RH_C_PORT_CONNECTION: 16.1060 + status->cs_chg = 0; 16.1061 + OK(0); 16.1062 + case RH_C_PORT_ENABLE: 16.1063 + status->pe_chg = 0; 16.1064 + OK(0); 16.1065 + case RH_C_PORT_SUSPEND: 16.1066 + /*** WR_RH_PORTSTAT(RH_PS_PSSC); */ 16.1067 + OK(0); 16.1068 + case RH_C_PORT_OVER_CURRENT: 16.1069 + OK(0); /* port power over current */ 16.1070 + case RH_C_PORT_RESET: 16.1071 + xhci->rh.c_p_r[wIndex - 1] = 0; 16.1072 + OK(0); 16.1073 + } 16.1074 + break; 16.1075 + case RH_SET_FEATURE | RH_OTHER | RH_CLASS: 16.1076 + switch (wValue) { 16.1077 + case RH_PORT_SUSPEND: 16.1078 + status->susp = 1; 16.1079 + OK(0); 16.1080 + case RH_PORT_RESET: 16.1081 + { 16.1082 + int ret; 16.1083 + xhci->rh.c_p_r[wIndex - 1] = 1; 16.1084 + status->pr = 0; 16.1085 + status->pe = 1; 16.1086 + ret = xhci_port_reset(wIndex - 1); 16.1087 + /* XXX MAW: should probably cancel queued transfers during reset... *\/ */ 16.1088 + if ( ret == 0 ) { OK(0); } 16.1089 + else { return ret; } 16.1090 + } 16.1091 + break; 16.1092 + case RH_PORT_POWER: 16.1093 + OK(0); /* port power ** */ 16.1094 + case RH_PORT_ENABLE: 16.1095 + status->pe = 1; 16.1096 + OK(0); 16.1097 + } 16.1098 + break; 16.1099 + case RH_SET_ADDRESS: 16.1100 + printk("setting root hub device to %d\n", wValue); 16.1101 + xhci->rh.devnum = wValue; 16.1102 + OK(0); 16.1103 + case RH_GET_DESCRIPTOR: 16.1104 + switch ((wValue & 0xff00) >> 8) { 16.1105 + case 0x01: /* device descriptor */ 16.1106 + len = min_t(unsigned int, leni, 16.1107 + min_t(unsigned int, 16.1108 + sizeof(root_hub_dev_des), wLength)); 16.1109 + memcpy(data, root_hub_dev_des, len); 16.1110 + OK(len); 16.1111 + case 0x02: /* configuration descriptor */ 16.1112 + len = min_t(unsigned int, leni, 16.1113 + min_t(unsigned int, 16.1114 + sizeof(root_hub_config_des), wLength)); 16.1115 + memcpy (data, root_hub_config_des, len); 16.1116 + OK(len); 16.1117 + case 0x03: /* string descriptors */ 16.1118 + len = usb_root_hub_string (wValue & 0xff, 16.1119 + 0, "XHCI-alt", 16.1120 + data, wLength); 16.1121 + if (len > 0) { 16.1122 + OK(min_t(int, leni, len)); 16.1123 + } else 16.1124 + stat = -EPIPE; 16.1125 + } 16.1126 + break; 16.1127 + case RH_GET_DESCRIPTOR | RH_CLASS: 16.1128 + root_hub_hub_des[2] = xhci->rh.numports; 16.1129 + len = min_t(unsigned int, leni, 16.1130 + min_t(unsigned int, sizeof(root_hub_hub_des), wLength)); 16.1131 + memcpy(data, root_hub_hub_des, len); 16.1132 + OK(len); 16.1133 + case RH_GET_CONFIGURATION: 16.1134 + *(__u8 *)data = 0x01; 16.1135 + OK(1); 16.1136 + case RH_SET_CONFIGURATION: 16.1137 + OK(0); 16.1138 + case RH_GET_INTERFACE | RH_INTERFACE: 16.1139 + *(__u8 *)data = 0x00; 16.1140 + OK(1); 16.1141 + case RH_SET_INTERFACE | RH_INTERFACE: 16.1142 + OK(0); 16.1143 + default: 16.1144 + stat = -EPIPE; 16.1145 + } 16.1146 + 16.1147 + spin_unlock_irqrestore(&xhci->rh.port_state_lock, flags); 16.1148 + 16.1149 + urb->actual_length = len; 16.1150 + 16.1151 + return stat; 16.1152 +} 16.1153 + 16.1154 +/* 16.1155 + * MUST be called with urb->lock acquired 16.1156 + */ 16.1157 +static int rh_unlink_urb(struct urb *urb) 16.1158 +{ 16.1159 + if (xhci->rh.urb == urb) { 16.1160 + urb->status = -ENOENT; 16.1161 + xhci->rh.send = 0; 16.1162 + xhci->rh.urb = NULL; 16.1163 + del_timer(&xhci->rh.rh_int_timer); 16.1164 + } 16.1165 + return 0; 16.1166 +} 16.1167 + 16.1168 +static void xhci_call_completion(struct urb *urb) 16.1169 +{ 16.1170 + struct urb_priv *urbp; 16.1171 + struct usb_device *dev = urb->dev; 16.1172 + int is_ring = 0, killed, resubmit_interrupt, status; 16.1173 + struct urb *nurb; 16.1174 + unsigned long flags; 16.1175 + 16.1176 + spin_lock_irqsave(&urb->lock, flags); 16.1177 + 16.1178 + urbp = (struct urb_priv *)urb->hcpriv; 16.1179 + if (!urbp || !urb->dev) { 16.1180 + spin_unlock_irqrestore(&urb->lock, flags); 16.1181 + return; 16.1182 + } 16.1183 + 16.1184 + killed = (urb->status == -ENOENT || urb->status == -ECONNABORTED || 16.1185 + urb->status == -ECONNRESET); 16.1186 + resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT && 16.1187 + urb->interval); 16.1188 + 16.1189 + nurb = urb->next; 16.1190 + if (nurb && !killed) { 16.1191 + int count = 0; 16.1192 + 16.1193 + while (nurb && nurb != urb && count < MAX_URB_LOOP) { 16.1194 + if (nurb->status == -ENOENT || 16.1195 + nurb->status == -ECONNABORTED || 16.1196 + nurb->status == -ECONNRESET) { 16.1197 + killed = 1; 16.1198 + break; 16.1199 + } 16.1200 + 16.1201 + nurb = nurb->next; 16.1202 + count++; 16.1203 + } 16.1204 + 16.1205 + if (count == MAX_URB_LOOP) 16.1206 + err("xhci_call_completion: too many linked URB's, loop? (first loop)"); 16.1207 + 16.1208 + /* Check to see if chain is a ring */ 16.1209 + is_ring = (nurb == urb); 16.1210 + } 16.1211 + 16.1212 + status = urbp->status; 16.1213 + if (!resubmit_interrupt || killed) 16.1214 + /* We don't need urb_priv anymore */ 16.1215 + xhci_destroy_urb_priv(urb); 16.1216 + 16.1217 + if (!killed) 16.1218 + urb->status = status; 16.1219 + 16.1220 + spin_unlock_irqrestore(&urb->lock, flags); 16.1221 + 16.1222 + if (urb->complete) 16.1223 + urb->complete(urb); 16.1224 + 16.1225 + if (resubmit_interrupt) 16.1226 + /* Recheck the status. The completion handler may have */ 16.1227 + /* unlinked the resubmitting interrupt URB */ 16.1228 + killed = (urb->status == -ENOENT || 16.1229 + urb->status == -ECONNABORTED || 16.1230 + urb->status == -ECONNRESET); 16.1231 + 16.1232 + if (resubmit_interrupt && !killed) { 16.1233 + if ( urb->dev != xhci->rh.dev ) 16.1234 + xhci_queue_req(urb); /* XXX What if this fails? */ 16.1235 + /* Don't need to resubmit URBs for the virtual root dev. */ 16.1236 + } else { 16.1237 + if (is_ring && !killed) { 16.1238 + urb->dev = dev; 16.1239 + xhci_submit_urb(urb); 16.1240 + } else { 16.1241 + /* We decrement the usage count after we're done */ 16.1242 + /* with everything */ 16.1243 + usb_dec_dev_use(dev); 16.1244 + } 16.1245 + } 16.1246 +} 16.1247 + 16.1248 +static void xhci_finish_completion(void) 16.1249 +{ 16.1250 + struct list_head *tmp, *head; 16.1251 + unsigned long flags; 16.1252 + 16.1253 + spin_lock_irqsave(&xhci->complete_list_lock, flags); 16.1254 + head = &xhci->complete_list; 16.1255 + tmp = head->next; 16.1256 + while (tmp != head) { 16.1257 + struct urb_priv *urbp = list_entry(tmp, struct urb_priv, complete_list); 16.1258 + struct urb *urb = urbp->urb; 16.1259 + 16.1260 + list_del_init(&urbp->complete_list); 16.1261 + spin_unlock_irqrestore(&xhci->complete_list_lock, flags); 16.1262 + 16.1263 + xhci_call_completion(urb); 16.1264 + 16.1265 + spin_lock_irqsave(&xhci->complete_list_lock, flags); 16.1266 + head = &xhci->complete_list; 16.1267 + tmp = head->next; 16.1268 + } 16.1269 + spin_unlock_irqrestore(&xhci->complete_list_lock, flags); 16.1270 +} 16.1271 + 16.1272 +void receive_usb_reset(usbif_response_t *resp) 16.1273 +{ 16.1274 + awaiting_reset = resp->status; 16.1275 + rmb(); 16.1276 + 16.1277 +} 16.1278 + 16.1279 +void receive_usb_probe(usbif_response_t *resp) 16.1280 +{ 16.1281 + spin_lock(&xhci->rh.port_state_lock); 16.1282 + 16.1283 + if ( resp->status > 0 ) 16.1284 + { 16.1285 + if ( resp->status == 1 ) 16.1286 + { 16.1287 +/* printk("hey hey, there's a device on port %d\n", resp->data); */ 16.1288 + 16.1289 + /* If theres a device there and there wasn't one before there must 16.1290 + * have been a connection status change. */ 16.1291 + if( xhci->rh.ports[resp->data].cs == 0 ) 16.1292 + { 16.1293 + xhci->rh.ports[resp->data].cs = 1; 16.1294 + xhci->rh.ports[resp->data].ccs = 1; 16.1295 + xhci->rh.ports[resp->data].cs_chg = 1; 16.1296 +/* printk("Look at device on port %d that wasn't there before\n", resp->data); */ 16.1297 + } 16.1298 + } 16.1299 + else 16.1300 + printk("receive_usb_probe(): unexpected status %d for port %d\n", 16.1301 + resp->status, resp->data); 16.1302 + } 16.1303 + else if ( resp->status < 0) 16.1304 + printk("receive_usb_probe(): got error status %d\n", resp->status); 16.1305 + 16.1306 + spin_unlock(&xhci->rh.port_state_lock); 16.1307 +} 16.1308 + 16.1309 +void receive_usb_io(usbif_response_t *resp) 16.1310 +{ 16.1311 + struct urb_priv *urbp = (struct urb_priv *)resp->id; 16.1312 + struct urb *urb = urbp->urb; 16.1313 + 16.1314 + urb->actual_length = resp->length; 16.1315 + urb->status = resp->status; 16.1316 + urbp->status = resp->status; 16.1317 + urbp->in_progress = 0; 16.1318 + 16.1319 + if( usb_pipetype(urb->pipe) == 0 ) /* ISO */ 16.1320 + { 16.1321 + int i; 16.1322 + 16.1323 + /* Copy ISO schedule results back in. */ 16.1324 + 16.1325 + for ( i = 0; i < urb->number_of_packets; i++ ) 16.1326 + { 16.1327 + urb->iso_frame_desc[i].status 16.1328 + = urbp->schedule[i].status; 16.1329 + urb->iso_frame_desc[i].actual_length 16.1330 + = urbp->schedule[i].length; 16.1331 + } 16.1332 + free_page((unsigned long)urbp->schedule); 16.1333 + } 16.1334 +} 16.1335 + 16.1336 +static void xhci_drain_ring(void) 16.1337 +{ 16.1338 + struct list_head *tmp, *head; 16.1339 + usbif_t *usb_ring = xhci->usbif; 16.1340 + usbif_response_t *resp; 16.1341 + USBIF_RING_IDX i, rp; 16.1342 + 16.1343 + /* Walk the ring here to get responses, updating URBs to show what 16.1344 + * completed. */ 16.1345 + 16.1346 + rp = usb_ring->resp_prod; 16.1347 + rmb(); /* Ensure we see queued requests up to 'rp'. */ 16.1348 + 16.1349 + /* Take items off the comms ring, taking care not to overflow. */ 16.1350 + for ( i = xhci->usb_resp_cons; 16.1351 + (i != rp) && ((i-usb_ring->req_prod) != USBIF_RING_SIZE); 16.1352 + i++ ) 16.1353 + { 16.1354 + resp = &usb_ring->ring[MASK_USBIF_IDX(i)].resp; 16.1355 + 16.1356 + /* May need to deal with batching and with putting a ceiling on 16.1357 + the number dispatched for performance and anti-dos reasons */ 16.1358 + 16.1359 +#if 0 16.1360 + printk("usbfront: Processing response:\n"); 16.1361 + printk(" id = 0x%x\n", resp->id); 16.1362 + printk(" op = %d\n", resp->operation); 16.1363 + printk(" status = %d\n", resp->status); 16.1364 + printk(" length = %d\n", resp->length); 16.1365 +#endif 16.1366 + 16.1367 + switch ( resp->operation ) 16.1368 + { 16.1369 + case USBIF_OP_PROBE: 16.1370 + receive_usb_probe(resp); 16.1371 + break; 16.1372 + 16.1373 + case USBIF_OP_IO: 16.1374 + receive_usb_io(resp); 16.1375 + break; 16.1376 + 16.1377 + case USBIF_OP_RESET: 16.1378 + receive_usb_reset(resp); 16.1379 + break; 16.1380 + 16.1381 + default: 16.1382 + printk("error: unknown USB io operation response [%d]\n", 16.1383 + usb_ring->ring[i].req.operation); 16.1384 + break; 16.1385 + } 16.1386 + } 16.1387 + 16.1388 + xhci->usb_resp_cons = i; 16.1389 + 16.1390 + /* Walk the list of pending URB's to see which ones completed and do 16.1391 + * callbacks, etc. */ 16.1392 + spin_lock(&xhci->urb_list_lock); 16.1393 + head = &xhci->urb_list; 16.1394 + tmp = head->next; 16.1395 + while (tmp != head) { 16.1396 + 16.1397 + struct urb *urb = list_entry(tmp, struct urb, urb_list); 16.1398 + 16.1399 + tmp = tmp->next; 16.1400 + 16.1401 + /* Checks the status and does all of the magic necessary */ 16.1402 + xhci_transfer_result(xhci, urb); 16.1403 + } 16.1404 + spin_unlock(&xhci->urb_list_lock); 16.1405 + 16.1406 + xhci_finish_completion(); 16.1407 +} 16.1408 + 16.1409 + 16.1410 +static void xhci_interrupt(int irq, void *__xhci, struct pt_regs *regs) 16.1411 +{ 16.1412 + xhci_drain_ring(); 16.1413 +} 16.1414 + 16.1415 +static void free_xhci(struct xhci *xhci) 16.1416 +{ 16.1417 + kfree(xhci); 16.1418 +} 16.1419 + 16.1420 +/* /\* */ 16.1421 +/* * De-allocate all resources.. */ 16.1422 +/* *\/ */ 16.1423 +/* static void release_xhci(struct xhci *xhci) */ 16.1424 +/* { */ 16.1425 +/* if (xhci->irq >= 0) { */ 16.1426 +/* free_irq(xhci->irq, xhci); */ 16.1427 +/* xhci->irq = -1; */ 16.1428 +/* } */ 16.1429 + 16.1430 +/* /\* Get the ring back from the backend domain. Then free it. Hmmmm. */ 16.1431 +/* * Lets ignore this for now - not particularly useful. *\/ */ 16.1432 + 16.1433 +/* free_xhci(xhci); */ 16.1434 +/* } */ 16.1435 + 16.1436 +/** 16.1437 + * Initialise a new virtual root hub for a new USB device channel. 16.1438 + */ 16.1439 +static int alloc_xhci(void) 16.1440 +{ 16.1441 + int retval; 16.1442 + struct usb_bus *bus; 16.1443 + 16.1444 + retval = -EBUSY; 16.1445 + 16.1446 + xhci = kmalloc(sizeof(*xhci), GFP_KERNEL); 16.1447 + if (!xhci) { 16.1448 + err("couldn't allocate xhci structure"); 16.1449 + retval = -ENOMEM; 16.1450 + goto err_alloc_xhci; 16.1451 + } 16.1452 + 16.1453 + /* Reset here so we don't get any interrupts from an old setup */ 16.1454 + /* or broken setup */ 16.1455 + // reset_hc(xhci); 16.1456 + 16.1457 + 16.1458 + xhci->state = USBIF_STATE_CLOSED; 16.1459 + xhci->is_suspended = 0; 16.1460 + 16.1461 + spin_lock_init(&xhci->urb_remove_list_lock); 16.1462 + INIT_LIST_HEAD(&xhci->urb_remove_list); 16.1463 + 16.1464 + spin_lock_init(&xhci->urb_list_lock); 16.1465 + INIT_LIST_HEAD(&xhci->urb_list); 16.1466 + 16.1467 + spin_lock_init(&xhci->complete_list_lock); 16.1468 + INIT_LIST_HEAD(&xhci->complete_list); 16.1469 + 16.1470 + spin_lock_init(&xhci->frame_list_lock); 16.1471 + 16.1472 + /* We need exactly one page (per XHCI specs), how convenient */ 16.1473 + /* We assume that one page is atleast 4k (1024 frames * 4 bytes) */ 16.1474 +#if PAGE_SIZE < (4 * 1024) 16.1475 +#error PAGE_SIZE is not atleast 4k 16.1476 +#endif 16.1477 + bus = usb_alloc_bus(&xhci_device_operations); 16.1478 + if (!bus) { 16.1479 + err("unable to allocate bus"); 16.1480 + goto err_alloc_bus; 16.1481 + } 16.1482 + 16.1483 + xhci->bus = bus; 16.1484 + bus->bus_name = "XHCI"; 16.1485 + bus->hcpriv = xhci; 16.1486 + 16.1487 + usb_register_bus(xhci->bus); 16.1488 + 16.1489 + /* Initialize the root hub */ 16.1490 + 16.1491 + xhci->rh.numports = 0; 16.1492 + 16.1493 + xhci->bus->root_hub = xhci->rh.dev = usb_alloc_dev(NULL, xhci->bus); 16.1494 + if (!xhci->rh.dev) { 16.1495 + err("unable to allocate root hub"); 16.1496 + goto err_alloc_root_hub; 16.1497 + } 16.1498 + 16.1499 + xhci->state = 0; 16.1500 + 16.1501 + return 0; 16.1502 + 16.1503 +/* 16.1504 + * error exits: 16.1505 + */ 16.1506 +err_start_root_hub: 16.1507 + free_irq(xhci->irq, xhci); 16.1508 + xhci->irq = -1; 16.1509 + 16.1510 +err_alloc_root_hub: 16.1511 + usb_free_bus(xhci->bus); 16.1512 + xhci->bus = NULL; 16.1513 + 16.1514 +err_alloc_bus: 16.1515 + free_xhci(xhci); 16.1516 + 16.1517 +err_alloc_xhci: 16.1518 + return retval; 16.1519 +} 16.1520 + 16.1521 +static void usbif_status_change(usbif_fe_interface_status_changed_t *status) 16.1522 +{ 16.1523 + ctrl_msg_t cmsg; 16.1524 + usbif_fe_interface_connect_t up; 16.1525 + long rc; 16.1526 + usbif_t *usbif; 16.1527 + 16.1528 + switch ( status->status ) 16.1529 + { 16.1530 + case USBIF_INTERFACE_STATUS_DESTROYED: 16.1531 + printk(KERN_WARNING "Unexpected usbif-DESTROYED message in state %d\n", 16.1532 + xhci->state); 16.1533 + break; 16.1534 + 16.1535 + case USBIF_INTERFACE_STATUS_DISCONNECTED: 16.1536 + if ( xhci->state != USBIF_STATE_CLOSED ) 16.1537 + { 16.1538 + printk(KERN_WARNING "Unexpected usbif-DISCONNECTED message" 16.1539 + " in state %d\n", xhci->state); 16.1540 + break; 16.1541 + /* Not bothering to do recovery here for now. Keep things 16.1542 + * simple. */ 16.1543 + } 16.1544 + 16.1545 + /* Move from CLOSED to DISCONNECTED state. */ 16.1546 + xhci->usbif = usbif = (usbif_t *)__get_free_page(GFP_KERNEL); 16.1547 + usbif->req_prod = usbif->resp_prod = 0; 16.1548 + xhci->state = USBIF_STATE_DISCONNECTED; 16.1549 + 16.1550 + /* Construct an interface-CONNECT message for the domain controller. */ 16.1551 + cmsg.type = CMSG_USBIF_FE; 16.1552 + cmsg.subtype = CMSG_USBIF_FE_INTERFACE_CONNECT; 16.1553 + cmsg.length = sizeof(usbif_fe_interface_connect_t); 16.1554 + up.shmem_frame = virt_to_machine(usbif) >> PAGE_SHIFT; 16.1555 + memcpy(cmsg.msg, &up, sizeof(up)); 16.1556 + 16.1557 + /* Tell the controller to bring up the interface. */ 16.1558 + ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 16.1559 + break; 16.1560 + 16.1561 + case USBIF_INTERFACE_STATUS_CONNECTED: 16.1562 + if ( xhci->state == USBIF_STATE_CLOSED ) 16.1563 + { 16.1564 + printk(KERN_WARNING "Unexpected usbif-CONNECTED message" 16.1565 + " in state %d\n", xhci->state); 16.1566 + break; 16.1567 + } 16.1568 + 16.1569 + xhci->evtchn = status->evtchn; 16.1570 + xhci->irq = bind_evtchn_to_irq(xhci->evtchn); 16.1571 + xhci->bandwidth = status->bandwidth; 16.1572 + xhci->rh.numports = status->num_ports; 16.1573 + 16.1574 + xhci->rh.ports = kmalloc (sizeof(xhci_port_t) * xhci->rh.numports, GFP_KERNEL); 16.1575 + memset(xhci->rh.ports, 0, sizeof(xhci_port_t) * xhci->rh.numports); 16.1576 + 16.1577 + printk("rh.dev @ %p\n", xhci->rh.dev); 16.1578 + 16.1579 + usb_connect(xhci->rh.dev); 16.1580 + 16.1581 + if (usb_new_device(xhci->rh.dev) != 0) { 16.1582 + err("unable to start root hub"); 16.1583 + } 16.1584 + 16.1585 + /* Allocate the appropriate USB bandwidth here... Need to 16.1586 + * somehow know what the total available is thought to be so we 16.1587 + * can calculate the reservation correctly. */ 16.1588 + usb_claim_bandwidth(xhci->rh.dev, xhci->rh.urb, 16.1589 + 1000 - xhci->bandwidth, 0); 16.1590 + 16.1591 + if ( (rc = request_irq(xhci->irq, xhci_interrupt, 16.1592 + SA_SAMPLE_RANDOM, "usbif", xhci)) ) 16.1593 + printk(KERN_ALERT"usbfront request_irq failed (%ld)\n",rc); 16.1594 + 16.1595 + printk(KERN_INFO __FILE__ ": USB XHCI: SHM at %p (0x%lx), EVTCHN %d IRQ %d\n", 16.1596 + xhci->usbif, virt_to_machine(xhci->usbif), xhci->evtchn, xhci->irq); 16.1597 + 16.1598 + xhci->state = USBIF_STATE_CONNECTED; 16.1599 + 16.1600 + break; 16.1601 + 16.1602 + default: 16.1603 + printk(KERN_WARNING "Status change to unknown value %d\n", 16.1604 + status->status); 16.1605 + break; 16.1606 + } 16.1607 +} 16.1608 + 16.1609 + 16.1610 +static void usbif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 16.1611 +{ 16.1612 + switch ( msg->subtype ) 16.1613 + { 16.1614 + case CMSG_USBIF_FE_INTERFACE_STATUS_CHANGED: 16.1615 + if ( msg->length != sizeof(usbif_fe_interface_status_changed_t) ) 16.1616 + goto parse_error; 16.1617 + usbif_status_change((usbif_fe_interface_status_changed_t *) 16.1618 + &msg->msg[0]); 16.1619 + break; 16.1620 + 16.1621 + /* New interface...? */ 16.1622 + default: 16.1623 + goto parse_error; 16.1624 + } 16.1625 + 16.1626 + ctrl_if_send_response(msg); 16.1627 + return; 16.1628 + 16.1629 + parse_error: 16.1630 + msg->length = 0; 16.1631 + ctrl_if_send_response(msg); 16.1632 +} 16.1633 + 16.1634 + 16.1635 +static int __init xhci_hcd_init(void) 16.1636 +{ 16.1637 + int retval = -ENOMEM, i; 16.1638 + usbif_fe_interface_status_changed_t st; 16.1639 + control_msg_t cmsg; 16.1640 + 16.1641 + if ( (xen_start_info.flags & SIF_INITDOMAIN) 16.1642 + || (xen_start_info.flags & SIF_USB_BE_DOMAIN) ) 16.1643 + return 0; 16.1644 + 16.1645 + info(DRIVER_DESC " " DRIVER_VERSION); 16.1646 + 16.1647 + if (debug) { 16.1648 + errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); 16.1649 + if (!errbuf) 16.1650 + goto errbuf_failed; 16.1651 + } 16.1652 + 16.1653 + xhci_up_cachep = kmem_cache_create("xhci_urb_priv", 16.1654 + sizeof(struct urb_priv), 0, 0, NULL, NULL); 16.1655 + if (!xhci_up_cachep) 16.1656 + goto up_failed; 16.1657 + 16.1658 + /* Lazily avoid unloading issues for now. ;-)*/ 16.1659 + MOD_INC_USE_COUNT; 16.1660 + 16.1661 + /* Let the domain controller know we're here. For now we wait until 16.1662 + * connection, as for the block and net drivers. This is only strictly 16.1663 + * necessary if we're going to boot off a USB device. */ 16.1664 + printk(KERN_INFO "Initialising Xen virtual USB hub\n"); 16.1665 + 16.1666 + (void)ctrl_if_register_receiver(CMSG_USBIF_FE, usbif_ctrlif_rx, 16.1667 + CALLBACK_IN_BLOCKING_CONTEXT); 16.1668 + 16.1669 + alloc_xhci(); 16.1670 + 16.1671 + /* Send a driver-UP notification to the domain controller. */ 16.1672 + cmsg.type = CMSG_USBIF_FE; 16.1673 + cmsg.subtype = CMSG_USBIF_FE_DRIVER_STATUS_CHANGED; 16.1674 + cmsg.length = sizeof(usbif_fe_driver_status_changed_t); 16.1675 + st.status = USBIF_DRIVER_STATUS_UP; 16.1676 + memcpy(cmsg.msg, &st, sizeof(st)); 16.1677 + ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 16.1678 + 16.1679 + /* 16.1680 + * We should read 'nr_interfaces' from response message and wait 16.1681 + * for notifications before proceeding. For now we assume that we 16.1682 + * will be notified of exactly one interface. 16.1683 + */ 16.1684 + for ( i=0; (xhci->state != USBIF_STATE_CONNECTED) && (i < 10*HZ); i++ ) 16.1685 + { 16.1686 + set_current_state(TASK_INTERRUPTIBLE); 16.1687 + schedule_timeout(1); 16.1688 + } 16.1689 + 16.1690 + if (xhci->state != USBIF_STATE_CONNECTED) 16.1691 + printk(KERN_INFO "Timeout connecting USB frontend driver!\n"); 16.1692 + 16.1693 + return 0; 16.1694 + 16.1695 +up_failed: 16.1696 + 16.1697 + if (errbuf) 16.1698 + kfree(errbuf); 16.1699 + 16.1700 +errbuf_failed: 16.1701 + 16.1702 + return retval; 16.1703 +} 16.1704 + 16.1705 +static void __exit xhci_hcd_cleanup(void) 16.1706 +{ 16.1707 + if (kmem_cache_destroy(xhci_up_cachep)) 16.1708 + printk(KERN_INFO "xhci: not all urb_priv's were freed\n"); 16.1709 + 16.1710 +// release_xhci(); do some calls here 16.1711 + 16.1712 + 16.1713 + if (errbuf) 16.1714 + kfree(errbuf); 16.1715 +} 16.1716 + 16.1717 +module_init(xhci_hcd_init); 16.1718 +module_exit(xhci_hcd_cleanup); 16.1719 + 16.1720 +MODULE_AUTHOR(DRIVER_AUTHOR); 16.1721 +MODULE_DESCRIPTION(DRIVER_DESC); 16.1722 +MODULE_LICENSE("GPL"); 16.1723 +
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h Fri Jan 28 14:53:32 2005 +0000 17.3 @@ -0,0 +1,210 @@ 17.4 +#ifndef __LINUX_XHCI_H 17.5 +#define __LINUX_XHCI_H 17.6 + 17.7 +#include <linux/list.h> 17.8 +#include <linux/usb.h> 17.9 +#include <asm-xen/xen-public/io/usbif.h> 17.10 +#include <linux/spinlock.h> 17.11 + 17.12 +#define XHCI_NUMFRAMES 1024 /* in the frame list [array] */ 17.13 +#define XHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ 17.14 +#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ 17.15 + 17.16 +/* In the absence of actual hardware state, we maintain the current known state 17.17 + * of the virtual hub ports in this data structure. 17.18 + */ 17.19 +typedef struct 17.20 +{ 17.21 + unsigned int cs :1; /* Connection status. do we really need this /and/ ccs? */ 17.22 + unsigned int cs_chg :1; /* Connection status change. */ 17.23 + unsigned int pe :1; /* Port enable. */ 17.24 + unsigned int pe_chg :1; /* Port enable change. */ 17.25 + unsigned int ccs :1; /* Current connect status. */ 17.26 + unsigned int susp :1; /* Suspended. */ 17.27 + unsigned int lsda :1; /* Low speed device attached. */ 17.28 + unsigned int pr :1; /* Port reset. */ 17.29 + 17.30 + /* Device info? */ 17.31 +} xhci_port_t; 17.32 + 17.33 +struct xhci_frame_list { 17.34 + __u32 frame[XHCI_NUMFRAMES]; 17.35 + 17.36 + void *frame_cpu[XHCI_NUMFRAMES]; 17.37 +}; 17.38 + 17.39 +struct urb_priv; 17.40 + 17.41 +#define xhci_status_bits(ctrl_sts) (ctrl_sts & 0xFE0000) 17.42 +#define xhci_actual_length(ctrl_sts) ((ctrl_sts + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */ 17.43 + 17.44 +#define xhci_maxlen(token) ((token) >> 21) 17.45 +#define xhci_expected_length(info) (((info >> 21) + 1) & TD_TOKEN_EXPLEN_MASK) /* 1-based */ 17.46 +#define xhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1) 17.47 +#define xhci_endpoint(token) (((token) >> 15) & 0xf) 17.48 +#define xhci_devaddr(token) (((token) >> 8) & 0x7f) 17.49 +#define xhci_devep(token) (((token) >> 8) & 0x7ff) 17.50 +#define xhci_packetid(token) ((token) & TD_TOKEN_PID_MASK) 17.51 +#define xhci_packetout(token) (xhci_packetid(token) != USB_PID_IN) 17.52 +#define xhci_packetin(token) (xhci_packetid(token) == USB_PID_IN) 17.53 + 17.54 +struct virt_root_hub { 17.55 + struct usb_device *dev; 17.56 + int devnum; /* Address of Root Hub endpoint */ 17.57 + struct urb *urb; 17.58 + void *int_addr; 17.59 + int send; 17.60 + int interval; 17.61 + int numports; 17.62 + int c_p_r[8]; 17.63 + struct timer_list rh_int_timer; 17.64 + spinlock_t port_state_lock; 17.65 + xhci_port_t *ports; /* */ 17.66 +}; 17.67 + 17.68 +/* 17.69 + * This describes the full xhci information. 17.70 + * 17.71 + * Note how the "proper" USB information is just 17.72 + * a subset of what the full implementation needs. 17.73 + */ 17.74 +struct xhci { 17.75 + 17.76 +#ifdef CONFIG_PROC_FS 17.77 + /* procfs */ 17.78 + int num; 17.79 + struct proc_dir_entry *proc_entry; 17.80 +#endif 17.81 + 17.82 + int evtchn; /* Interdom channel to backend */ 17.83 + int irq; /* Bound to evtchn */ 17.84 + int state; /* State of this USB interface */ 17.85 + unsigned long bandwidth; 17.86 + int handle; 17.87 + 17.88 + struct usb_bus *bus; 17.89 + 17.90 + spinlock_t frame_list_lock; 17.91 + struct xhci_frame_list *fl; /* P: xhci->frame_list_lock */ 17.92 + int is_suspended; 17.93 + 17.94 + /* Main list of URB's currently controlled by this HC */ 17.95 + spinlock_t urb_list_lock; 17.96 + struct list_head urb_list; /* P: xhci->urb_list_lock */ 17.97 + 17.98 + /* List of asynchronously unlinked URB's */ 17.99 + spinlock_t urb_remove_list_lock; 17.100 + struct list_head urb_remove_list; /* P: xhci->urb_remove_list_lock */ 17.101 + 17.102 + /* List of URB's awaiting completion callback */ 17.103 + spinlock_t complete_list_lock; 17.104 + struct list_head complete_list; /* P: xhci->complete_list_lock */ 17.105 + 17.106 + struct virt_root_hub rh; /* private data of the virtual root hub */ 17.107 + 17.108 + spinlock_t response_lock; 17.109 + 17.110 + usbif_t *usbif; 17.111 + int usb_resp_cons; 17.112 +}; 17.113 + 17.114 +struct urb_priv { 17.115 + struct urb *urb; 17.116 + usbif_iso_t *schedule; 17.117 + struct usb_device *dev; 17.118 + 17.119 + int in_progress : 1; /* QH was queued (not linked in) */ 17.120 + int short_control_packet : 1; /* If we get a short packet during */ 17.121 + /* a control transfer, retrigger */ 17.122 + /* the status phase */ 17.123 + 17.124 + int status; /* Final status */ 17.125 + 17.126 + unsigned long inserttime; /* In jiffies */ 17.127 + 17.128 + struct list_head queue_list; /* P: xhci->frame_list_lock */ 17.129 + struct list_head complete_list; /* P: xhci->complete_list_lock */ 17.130 +}; 17.131 + 17.132 +/* 17.133 + * Locking in xhci.c 17.134 + * 17.135 + * spinlocks are used extensively to protect the many lists and data 17.136 + * structures we have. It's not that pretty, but it's necessary. We 17.137 + * need to be done with all of the locks (except complete_list_lock) when 17.138 + * we call urb->complete. I've tried to make it simple enough so I don't 17.139 + * have to spend hours racking my brain trying to figure out if the 17.140 + * locking is safe. 17.141 + * 17.142 + * Here's the safe locking order to prevent deadlocks: 17.143 + * 17.144 + * #1 xhci->urb_list_lock 17.145 + * #2 urb->lock 17.146 + * #3 xhci->urb_remove_list_lock, xhci->frame_list_lock, 17.147 + * xhci->qh_remove_list_lock 17.148 + * #4 xhci->complete_list_lock 17.149 + * 17.150 + * If you're going to grab 2 or more locks at once, ALWAYS grab the lock 17.151 + * at the lowest level FIRST and NEVER grab locks at the same level at the 17.152 + * same time. 17.153 + * 17.154 + * So, if you need xhci->urb_list_lock, grab it before you grab urb->lock 17.155 + */ 17.156 + 17.157 +/* ------------------------------------------------------------------------- 17.158 + Virtual Root HUB 17.159 + ------------------------------------------------------------------------- */ 17.160 +/* destination of request */ 17.161 +#define RH_DEVICE 0x00 17.162 +#define RH_INTERFACE 0x01 17.163 +#define RH_ENDPOINT 0x02 17.164 +#define RH_OTHER 0x03 17.165 + 17.166 +#define RH_CLASS 0x20 17.167 +#define RH_VENDOR 0x40 17.168 + 17.169 +/* Requests: bRequest << 8 | bmRequestType */ 17.170 +#define RH_GET_STATUS 0x0080 17.171 +#define RH_CLEAR_FEATURE 0x0100 17.172 +#define RH_SET_FEATURE 0x0300 17.173 +#define RH_SET_ADDRESS 0x0500 17.174 +#define RH_GET_DESCRIPTOR 0x0680 17.175 +#define RH_SET_DESCRIPTOR 0x0700 17.176 +#define RH_GET_CONFIGURATION 0x0880 17.177 +#define RH_SET_CONFIGURATION 0x0900 17.178 +#define RH_GET_STATE 0x0280 17.179 +#define RH_GET_INTERFACE 0x0A80 17.180 +#define RH_SET_INTERFACE 0x0B00 17.181 +#define RH_SYNC_FRAME 0x0C80 17.182 +/* Our Vendor Specific Request */ 17.183 +#define RH_SET_EP 0x2000 17.184 + 17.185 +/* Hub port features */ 17.186 +#define RH_PORT_CONNECTION 0x00 17.187 +#define RH_PORT_ENABLE 0x01 17.188 +#define RH_PORT_SUSPEND 0x02 17.189 +#define RH_PORT_OVER_CURRENT 0x03 17.190 +#define RH_PORT_RESET 0x04 17.191 +#define RH_PORT_POWER 0x08 17.192 +#define RH_PORT_LOW_SPEED 0x09 17.193 +#define RH_C_PORT_CONNECTION 0x10 17.194 +#define RH_C_PORT_ENABLE 0x11 17.195 +#define RH_C_PORT_SUSPEND 0x12 17.196 +#define RH_C_PORT_OVER_CURRENT 0x13 17.197 +#define RH_C_PORT_RESET 0x14 17.198 + 17.199 +/* Hub features */ 17.200 +#define RH_C_HUB_LOCAL_POWER 0x00 17.201 +#define RH_C_HUB_OVER_CURRENT 0x01 17.202 +#define RH_DEVICE_REMOTE_WAKEUP 0x00 17.203 +#define RH_ENDPOINT_STALL 0x01 17.204 + 17.205 +/* Our Vendor Specific feature */ 17.206 +#define RH_REMOVE_EP 0x00 17.207 + 17.208 +#define RH_ACK 0x01 17.209 +#define RH_REQ_ERR -1 17.210 +#define RH_NACK 0x00 17.211 + 17.212 +#endif 17.213 +
19.1 --- a/xen/arch/x86/Makefile Fri Jan 28 07:59:39 2005 +0000 19.2 +++ b/xen/arch/x86/Makefile Fri Jan 28 14:53:32 2005 +0000 19.3 @@ -15,6 +15,7 @@ OBJS := $(subst $(TARGET_SUBARCH)/asm-of 19.4 ifneq ($(TARGET_SUBARCH),x86_32) 19.5 OBJS := $(subst vmx.o,,$(OBJS)) 19.6 OBJS := $(subst vmx_io.o,,$(OBJS)) 19.7 +OBJS := $(subst vmx_platform.o,,$(OBJS)) 19.8 OBJS := $(subst vmx_vmcs.o,,$(OBJS)) 19.9 endif 19.10
20.1 --- a/xen/arch/x86/boot/x86_64.S Fri Jan 28 07:59:39 2005 +0000 20.2 +++ b/xen/arch/x86/boot/x86_64.S Fri Jan 28 14:53:32 2005 +0000 20.3 @@ -156,7 +156,8 @@ 1: mov %eax,(%rdi) 20.4 lea start(%rip),%rax 20.5 sub $0x100000,%rax 20.6 add %rax,%rdi 20.7 - call cmain 20.8 + call __start_xen 20.9 + ud2 /* Force a panic (invalid opcode). */ 20.10 20.11 /* This is the default interrupt handler. */ 20.12 int_msg: 20.13 @@ -264,10 +265,9 @@ phys_to_machine_mapping: 20.14 copy_from_user: 20.15 show_registers: 20.16 do_iopl: 20.17 -.globl idt_table, copy_user_generic, memcmp, idt_tables, new_thread 20.18 +.globl idt_table, copy_user_generic, idt_tables, new_thread 20.19 idt_table: 20.20 copy_user_generic: 20.21 -memcmp: 20.22 idt_tables: 20.23 new_thread: 20.24 .globl switch_to, __get_user_1, __get_user_4, __get_user_8, trap_init
21.1 --- a/xen/arch/x86/domain.c Fri Jan 28 07:59:39 2005 +0000 21.2 +++ b/xen/arch/x86/domain.c Fri Jan 28 14:53:32 2005 +0000 21.3 @@ -364,8 +364,6 @@ static void monitor_rm_pagetable(struct 21.4 l2_pgentry_t *mpl2e; 21.5 unsigned long mpfn; 21.6 21.7 - ASSERT( m->monitor_table ); 21.8 - 21.9 mpl2e = (l2_pgentry_t *) map_domain_mem(pagetable_val(m->monitor_table)); 21.10 /* 21.11 * First get the pfn for guest_pl2e_cache by looking at monitor_table 21.12 @@ -510,8 +508,10 @@ int arch_final_setup_guestos(struct exec 21.13 } 21.14 } 21.15 21.16 +#ifdef CONFIG_VMX 21.17 if (c->flags & ECF_VMX_GUEST) 21.18 return vmx_final_setup_guestos(d, c); 21.19 +#endif 21.20 21.21 return 0; 21.22 } 21.23 @@ -747,6 +747,7 @@ static void relinquish_list(struct domai 21.24 spin_unlock_recursive(&d->page_alloc_lock); 21.25 } 21.26 21.27 +#ifdef CONFIG_VMX 21.28 static void vmx_domain_relinquish_memory(struct exec_domain *ed) 21.29 { 21.30 struct domain *d = ed->domain; 21.31 @@ -776,6 +777,7 @@ static void vmx_domain_relinquish_memory 21.32 } 21.33 21.34 } 21.35 +#endif 21.36 21.37 void domain_relinquish_memory(struct domain *d) 21.38 { 21.39 @@ -788,15 +790,18 @@ void domain_relinquish_memory(struct dom 21.40 shadow_mode_disable(d); 21.41 21.42 /* Drop the in-use reference to the page-table base. */ 21.43 - for_each_exec_domain(d, ed) { 21.44 + for_each_exec_domain ( d, ed ) 21.45 + { 21.46 if ( pagetable_val(ed->mm.pagetable) != 0 ) 21.47 put_page_and_type(&frame_table[pagetable_val(ed->mm.pagetable) >> 21.48 PAGE_SHIFT]); 21.49 } 21.50 21.51 - if (VMX_DOMAIN(d->exec_domain[0])) 21.52 - for_each_exec_domain(d, ed) 21.53 +#ifdef CONFIG_VMX 21.54 + if ( VMX_DOMAIN(d->exec_domain[0]) ) 21.55 + for_each_exec_domain ( d, ed ) 21.56 vmx_domain_relinquish_memory(ed); 21.57 +#endif 21.58 21.59 /* 21.60 * Relinquish GDT mappings. No need for explicit unmapping of the LDT as
22.1 --- a/xen/arch/x86/e820.c Fri Jan 28 07:59:39 2005 +0000 22.2 +++ b/xen/arch/x86/e820.c Fri Jan 28 14:53:32 2005 +0000 22.3 @@ -305,17 +305,11 @@ static unsigned long __init find_max_pfn 22.4 return max_pfn; 22.5 } 22.6 22.7 -static void __init machine_specific_memory_setup( 22.8 - struct e820entry *raw, int raw_nr) 22.9 +#ifdef __i386__ 22.10 +static void __init clip_4gb(void) 22.11 { 22.12 - char nr = (char)raw_nr; 22.13 int i; 22.14 22.15 - sanitize_e820_map(raw, &nr); 22.16 - 22.17 - (void)copy_e820_map(raw, nr); 22.18 - 22.19 -#ifdef __i386__ 22.20 /* 32-bit systems restricted to a 4GB physical memory map. */ 22.21 for ( i = 0; i < e820.nr_map; i++ ) 22.22 { 22.23 @@ -335,7 +329,18 @@ static void __init machine_specific_memo 22.24 e820.nr_map = i + 1; 22.25 } 22.26 } 22.27 +} 22.28 +#else 22.29 +#define clip_4gb() ((void)0) 22.30 #endif 22.31 + 22.32 +static void __init machine_specific_memory_setup( 22.33 + struct e820entry *raw, int raw_nr) 22.34 +{ 22.35 + char nr = (char)raw_nr; 22.36 + sanitize_e820_map(raw, &nr); 22.37 + (void)copy_e820_map(raw, nr); 22.38 + clip_4gb(); 22.39 } 22.40 22.41 unsigned long init_e820(struct e820entry *raw, int raw_nr)
23.1 --- a/xen/arch/x86/memory.c Fri Jan 28 07:59:39 2005 +0000 23.2 +++ b/xen/arch/x86/memory.c Fri Jan 28 14:53:32 2005 +0000 23.3 @@ -148,6 +148,7 @@ unsigned long max_page; 23.4 23.5 void __init init_frametable(void) 23.6 { 23.7 +#ifdef __i386__ 23.8 unsigned long i, p; 23.9 23.10 frame_table = (struct pfn_info *)FRAMETABLE_VIRT_START; 23.11 @@ -164,6 +165,7 @@ void __init init_frametable(void) 23.12 } 23.13 23.14 memset(frame_table, 0, frame_table_size); 23.15 +#endif 23.16 } 23.17 23.18 void arch_init_memory(void)
24.1 --- a/xen/arch/x86/x86_32/xen.lds Fri Jan 28 07:59:39 2005 +0000 24.2 +++ b/xen/arch/x86/x86_32/xen.lds Fri Jan 28 14:53:32 2005 +0000 24.3 @@ -25,12 +25,12 @@ SECTIONS 24.4 .rodata : { *(.rodata) *(.rodata.*) } :text 24.5 .kstrtab : { *(.kstrtab) } :text 24.6 24.7 - . = ALIGN(16); /* Exception table */ 24.8 + . = ALIGN(32); /* Exception table */ 24.9 __start___ex_table = .; 24.10 __ex_table : { *(__ex_table) } :text 24.11 __stop___ex_table = .; 24.12 24.13 - . = ALIGN(16); /* Pre-exception table */ 24.14 + . = ALIGN(32); /* Pre-exception table */ 24.15 __start___pre_ex_table = .; 24.16 __pre_ex_table : { *(__pre_ex_table) } :text 24.17 __stop___pre_ex_table = .; 24.18 @@ -57,7 +57,7 @@ SECTIONS 24.19 __init_begin = .; 24.20 .text.init : { *(.text.init) } :text 24.21 .data.init : { *(.data.init) } :text 24.22 - . = ALIGN(16); 24.23 + . = ALIGN(32); 24.24 __setup_start = .; 24.25 .setup.init : { *(.setup.init) } :text 24.26 __setup_end = .;
25.1 --- a/xen/arch/x86/x86_64/xen.lds Fri Jan 28 07:59:39 2005 +0000 25.2 +++ b/xen/arch/x86/x86_64/xen.lds Fri Jan 28 14:53:32 2005 +0000 25.3 @@ -23,12 +23,12 @@ SECTIONS 25.4 .rodata : { *(.rodata) *(.rodata.*) } :text 25.5 .kstrtab : { *(.kstrtab) } :text 25.6 25.7 - . = ALIGN(16); /* Exception table */ 25.8 + . = ALIGN(32); /* Exception table */ 25.9 __start___ex_table = .; 25.10 __ex_table : { *(__ex_table) } :text 25.11 __stop___ex_table = .; 25.12 25.13 - . = ALIGN(16); /* Pre-exception table */ 25.14 + . = ALIGN(32); /* Pre-exception table */ 25.15 __start___pre_ex_table = .; 25.16 __pre_ex_table : { *(__pre_ex_table) } :text 25.17 __stop___pre_ex_table = .; 25.18 @@ -55,7 +55,7 @@ SECTIONS 25.19 __init_begin = .; 25.20 .text.init : { *(.text.init) } :text 25.21 .data.init : { *(.data.init) } :text 25.22 - . = ALIGN(16); 25.23 + . = ALIGN(32); 25.24 __setup_start = .; 25.25 .setup.init : { *(.setup.init) } :text 25.26 __setup_end = .;
26.1 --- a/xen/include/asm-x86/mm.h Fri Jan 28 07:59:39 2005 +0000 26.2 +++ b/xen/include/asm-x86/mm.h Fri Jan 28 14:53:32 2005 +0000 26.3 @@ -225,6 +225,7 @@ void synchronise_pagetables(unsigned lon 26.4 #ifdef __x86_64__ 26.5 extern unsigned long *machine_to_phys_mapping; 26.6 extern unsigned long *phys_to_machine_mapping; 26.7 +#define m2p_start_mfn virt_to_phys(machine_to_phys_mapping) 26.8 #else 26.9 /* Don't call virt_to_phys on this: it isn't direct mapped. Using 26.10 m2p_start_mfn instead. */
27.1 --- a/xen/include/public/arch-x86_64.h Fri Jan 28 07:59:39 2005 +0000 27.2 +++ b/xen/include/public/arch-x86_64.h Fri Jan 28 14:53:32 2005 +0000 27.3 @@ -115,6 +115,7 @@ typedef u64 tsc_timestamp_t; /* RDTSC ti 27.4 */ 27.5 typedef struct { 27.6 #define ECF_I387_VALID (1<<0) 27.7 +#define ECF_VMX_GUEST (2<<0) 27.8 unsigned long flags; 27.9 execution_context_t cpu_ctxt; /* User-level CPU registers */ 27.10 char fpu_ctxt[512]; /* User-level FPU registers */
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/xen/include/public/io/usbif.h Fri Jan 28 14:53:32 2005 +0000 28.3 @@ -0,0 +1,111 @@ 28.4 +/****************************************************************************** 28.5 + * usbif.h 28.6 + * 28.7 + * Unified block-device I/O interface for Xen guest OSes. 28.8 + * 28.9 + * Copyright (c) 2003-2004, Keir Fraser 28.10 + */ 28.11 + 28.12 +#ifndef __SHARED_USBIF_H__ 28.13 +#define __SHARED_USBIF_H__ 28.14 + 28.15 +#define usbif_vdev_t u16 28.16 +#define usbif_sector_t u64 28.17 + 28.18 +#define USBIF_OP_IO 0 28.19 +#define USBIF_OP_PROBE 1 /* Is there a device on this port? */ 28.20 +#define USBIF_OP_RESET 2 /* Reset a virtual USB port. */ 28.21 + 28.22 +/* NB. Ring size must be small enough for sizeof(usbif_ring_t) <= PAGE_SIZE. */ 28.23 +#define USBIF_RING_SIZE 64 28.24 + 28.25 +/* XXX this does not want to be here! it really ought to be dynamic but it can 28.26 + * live here for now */ 28.27 +#define NUM_PORTS 1 28.28 + 28.29 +typedef struct { 28.30 + unsigned long id; /* 0: private guest value, echoed in resp */ 28.31 + u8 operation; /* 4: USBIF_OP_??? */ 28.32 + u8 __pad1; 28.33 + usbif_vdev_t port; /* 6 : guest virtual USB port */ 28.34 + unsigned long devnum :7; /* 8 : Device address, as seen by the guest.*/ 28.35 + unsigned long endpoint :4; /* Device endpoint. */ 28.36 + unsigned long direction :1; /* Pipe direction. */ 28.37 + unsigned long speed :1; /* Pipe speed. */ 28.38 + unsigned long pipe_type :2; /* Pipe type (iso, bulk, int, ctrl) */ 28.39 + unsigned long __pad2 :18; 28.40 + unsigned long transfer_buffer; /* 12: Machine address */ 28.41 + unsigned long length; /* 16: Buffer length */ 28.42 + unsigned long transfer_flags; /* 20: For now just pass Linux transfer 28.43 + * flags - this may change. */ 28.44 + unsigned char setup[8]; /* 22 Embed setup packets directly. */ 28.45 + unsigned long iso_schedule; /* 30 Machine address of transfer sched (iso 28.46 + * only) */ 28.47 + unsigned long num_iso; /* 34 : length of iso schedule */ 28.48 + unsigned long timeout; /* 38: timeout in ms */ 28.49 +} PACKED usbif_request_t; /* 42 */ 28.50 +/* Data we need to pass: 28.51 + * - Transparently handle short packets or complain at us? 28.52 + */ 28.53 + 28.54 +typedef struct { 28.55 + unsigned long id; /* 0: copied from request */ 28.56 + u8 operation; /* 4: copied from request */ 28.57 + u8 data; /* 5: Small chunk of in-band data */ 28.58 + s16 status; /* 6: USBIF_RSP_??? */ 28.59 + unsigned long transfer_mutex; /* Used for cancelling requests atomically. */ 28.60 + unsigned long length; /* 8: How much data we really got */ 28.61 +} PACKED usbif_response_t; 28.62 + 28.63 +#define USBIF_RSP_ERROR -1 /* non-specific 'error' */ 28.64 +#define USBIF_RSP_OKAY 0 /* non-specific 'okay' */ 28.65 + 28.66 +/* 28.67 + * We use a special capitalised type name because it is _essential_ that all 28.68 + * arithmetic on indexes is done on an integer type of the correct size. 28.69 + */ 28.70 +typedef u32 USBIF_RING_IDX; 28.71 + 28.72 +/* 28.73 + * Ring indexes are 'free running'. That is, they are not stored modulo the 28.74 + * size of the ring buffer. The following macro converts a free-running counter 28.75 + * into a value that can directly index a ring-buffer array. 28.76 + */ 28.77 +#define MASK_USBIF_IDX(_i) ((_i)&(USBIF_RING_SIZE-1)) 28.78 + 28.79 +typedef struct { 28.80 + USBIF_RING_IDX req_prod; /* 0: Request producer. Updated by front-end. */ 28.81 + USBIF_RING_IDX resp_prod; /* 4: Response producer. Updated by back-end. */ 28.82 + 28.83 + union { /* 8 */ 28.84 + usbif_request_t req; 28.85 + usbif_response_t resp; 28.86 + } PACKED ring[USBIF_RING_SIZE]; 28.87 +} PACKED usbif_t; 28.88 + 28.89 + 28.90 + 28.91 +/* 28.92 + * USBIF_OP_PROBE: 28.93 + * The request format for a probe request is constrained as follows: 28.94 + * @operation == USBIF_OP_PROBE 28.95 + * @nr_segments == size of probe buffer in pages 28.96 + * @device == unused (zero) 28.97 + * @id == any value (echoed in response message) 28.98 + * @sector_num == unused (zero) 28.99 + * @frame_and_sects == list of page-sized buffers. 28.100 + * (i.e., @first_sect == 0, @last_sect == 7). 28.101 + * 28.102 + * The response is a list of vdisk_t elements copied into the out-of-band 28.103 + * probe buffer. On success the response status field contains the number 28.104 + * of vdisk_t elements. 28.105 + */ 28.106 + 28.107 +typedef struct { 28.108 + unsigned long length; /* IN = expected, OUT = actual */ 28.109 + unsigned long buffer_offset; /* IN offset in buffer specified in main 28.110 + packet */ 28.111 + unsigned long status; /* OUT Status for this packet. */ 28.112 +} usbif_iso_t; 28.113 + 28.114 +#endif /* __SHARED_USBIF_H__ */