direct-io.hg

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
author smh22@tempest.cl.cam.ac.uk
date Fri Jan 28 14:53:32 2005 +0000 (2005-01-28)
parents bc0fbb38cb25 eef1949801b8
children bbe8541361dd
files .rootkeys BitKeeper/etc/logging_ok linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/common.h linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/control.c linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/interface.c linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/main.c linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/frontend/main.c linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/frontend/xhci.h linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/usbif.h linux-2.4.29-xen-sparse/drivers/usb/hcd.c linux-2.4.29-xen-sparse/mkbuildtree linux-2.6.10-xen-sparse/drivers/xen/usbback/common.h linux-2.6.10-xen-sparse/drivers/xen/usbback/control.c linux-2.6.10-xen-sparse/drivers/xen/usbback/interface.c linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c linux-2.6.10-xen-sparse/drivers/xen/usbfront/usbfront.c linux-2.6.10-xen-sparse/drivers/xen/usbfront/xhci.h tools/python/xen/xend/XendDomainInfo.py xen/arch/x86/Makefile xen/arch/x86/boot/x86_64.S xen/arch/x86/domain.c xen/arch/x86/e820.c xen/arch/x86/memory.c xen/arch/x86/x86_32/xen.lds xen/arch/x86/x86_64/xen.lds xen/include/asm-x86/mm.h xen/include/public/arch-x86_64.h xen/include/public/io/usbif.h
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__ */