ia64/xen-unstable

changeset 3643:c5a71e081a54

bitkeeper revision 1.1159.212.82 (4202dcc3h_cg7sFBNwdIyCk_2qkX0A)

Beginning a sprean clean of the USB code.

Lots of cleanups and fixes (thanks to Harry Butterworth for pointing out several
locking and allocation errors).

Signed-off-by: mark.williamson@cl.cam.ac.uk
author mwilli2@equilibrium.research
date Fri Feb 04 02:24:03 2005 +0000 (2005-02-04)
parents dbc41aaba297
children d3f0465c034e
files linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c
line diff
     1.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c	Thu Feb 03 23:26:30 2005 +0000
     1.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c	Fri Feb 04 02:24:03 2005 +0000
     1.3 @@ -4,7 +4,9 @@
     1.4   * Backend for the Xen virtual USB driver - provides an abstraction of a
     1.5   * USB host controller to the corresponding frontend driver.
     1.6   *
     1.7 - * by Mark Williamson, Copyright (c) 2004 Intel Research Cambridge
     1.8 + * by Mark Williamson
     1.9 + * Copyright (c) 2004 Intel Research Cambridge
    1.10 + * Copyright (c) 2004, 2005 Mark Williamson
    1.11   *
    1.12   * Based on arch/xen/drivers/blkif/backend/main.c
    1.13   * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
    1.14 @@ -39,7 +41,6 @@ static unsigned long mmap_vstart;
    1.15       ((_req) * MMAP_PAGES_PER_REQUEST * PAGE_SIZE) + \
    1.16       ((_seg) * PAGE_SIZE))
    1.17  
    1.18 -#define MIN(x,y) ( ( x < y ) ? x : y )
    1.19  
    1.20  static spinlock_t owned_ports_lock;
    1.21  LIST_HEAD(owned_ports);
    1.22 @@ -83,7 +84,7 @@ typedef struct {
    1.23   */
    1.24  static pending_req_t pending_reqs[MAX_PENDING_REQS];
    1.25  static unsigned char pending_ring[MAX_PENDING_REQS];
    1.26 -static spinlock_t pend_prod_lock = SPIN_LOCK_UNLOCKED;
    1.27 +static spinlock_t pend_prod_lock;
    1.28  
    1.29  /* NB. We use a different index type to differentiate from shared blk rings. */
    1.30  typedef unsigned int PEND_RING_IDX;
    1.31 @@ -100,20 +101,87 @@ static void dispatch_usb_io(usbif_priv_t
    1.32  static void dispatch_usb_reset(usbif_priv_t *up, unsigned long portid);
    1.33  static owned_port_t *usbif_find_port(char *);
    1.34  
    1.35 +/******************************************************************
    1.36 + * PRIVATE DEBUG FUNCTIONS
    1.37 + */
    1.38  
    1.39 -void dump_port(owned_port_t *p)
    1.40 +#undef DEBUG
    1.41 +#ifdef DEBUG
    1.42 +
    1.43 +static void dump_port(owned_port_t *p)
    1.44  {
    1.45 -    printk("owned_port_t @ %p\n", p);
    1.46 -    printk("  usbif_priv @ %p\n", p->usbif_priv);
    1.47 -    printk("  path: %s\n", p->path);
    1.48 -    printk("  guest_port: %d\n", p->guest_port);
    1.49 -    printk("  guest_address: %ld\n", p->guest_address);
    1.50 -    printk("  dev_present: %d\n", p->dev_present);
    1.51 -    printk("  dev @ %p\n", p->dev);
    1.52 -    printk("  ifaces: 0x%lx\n", p->ifaces);
    1.53 +    printk(KERN_DEBUG "owned_port_t @ %p\n"
    1.54 +	   "  usbif_priv @ %p\n"
    1.55 +	   "  path: %s\n"
    1.56 +	   "  guest_port: %d\n"
    1.57 +	   "  guest_address: %ld\n"
    1.58 +	   "  dev_present: %d\n"
    1.59 +	   "  dev @ %p\n"
    1.60 +	   "  ifaces: 0x%lx\n",
    1.61 +	   p, p->usbif_priv, p->path, p->guest_port, p->guest_address,
    1.62 +	   p->dev_present, p->dev, p->ifaces);
    1.63  }
    1.64  
    1.65  
    1.66 +static void dump_request(usbif_request_t *req)
    1.67 +{    
    1.68 +    printk(KERN_DEBUG "id = 0x%lx\n"
    1.69 +	   "devnum %d\n"
    1.70 +	   "endpoint 0x%x\n"
    1.71 +	   "direction %d\n"
    1.72 +	   "speed %d\n"
    1.73 +	   "pipe_type 0x%x\n"
    1.74 +	   "transfer_buffer 0x%lx\n"
    1.75 +	   "length 0x%lx\n"
    1.76 +	   "transfer_flags 0x%lx\n"
    1.77 +	   "setup = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }\n"
    1.78 +	   "iso_schedule = 0x%lx\n"
    1.79 +	   "num_iso %ld\n",
    1.80 +	   req->id, req->devnum, req->endpoint, req->direction, req->speed,
    1.81 +	   req->pipe_type, req->transfer_buffer, req->length,
    1.82 +	   req->transfer_flags, req->setup[0], req->setup[1], req->setup[2],
    1.83 +	   req->setup[3], req->setup[4], req->setup[5], req->setup[6],
    1.84 +	   req->setup[7], req->iso_schedule, req->num_iso);
    1.85 +}
    1.86 +
    1.87 +static void dump_urb(struct urb *urb)
    1.88 +{
    1.89 +    printk(KERN_DEBUG "dumping urb @ %p\n", urb);
    1.90 +
    1.91 +#define DUMP_URB_FIELD(name, format) \
    1.92 +    printk(KERN_DEBUG "  " # name " " format "\n", urb-> name)
    1.93 +    
    1.94 +    DUMP_URB_FIELD(pipe, "0x%x");
    1.95 +    DUMP_URB_FIELD(status, "%d");
    1.96 +    DUMP_URB_FIELD(transfer_flags, "0x%x");    
    1.97 +    DUMP_URB_FIELD(transfer_buffer, "%p");
    1.98 +    DUMP_URB_FIELD(transfer_buffer_length, "%d");
    1.99 +    DUMP_URB_FIELD(actual_length, "%d");
   1.100 +}
   1.101 +
   1.102 +static void dump_response(usbif_response_t *resp)
   1.103 +{
   1.104 +    printk(KERN_DEBUG "usbback: Sending response:\n"
   1.105 +	   "         id = 0x%x\n"
   1.106 +	   "         op = %d\n"
   1.107 +	   "         status = %d\n"
   1.108 +	   "         data = %d\n"
   1.109 +	   "         length = %d\n",
   1.110 +	   resp->id, resp->op, resp->status, resp->data, resp->length);
   1.111 +}
   1.112 +
   1.113 +#else /* DEBUG */
   1.114 +
   1.115 +#define dump_port(blah)     ((void)0)
   1.116 +#define dump_request(blah)   ((void)0)
   1.117 +#define dump_urb(blah)      ((void)0)
   1.118 +#define dump_response(blah) ((void)0)
   1.119 +
   1.120 +#endif /* DEBUG */
   1.121 +
   1.122 +/******************************************************************
   1.123 + * MEMORY MANAGEMENT
   1.124 + */
   1.125  
   1.126  static void fast_flush_area(int idx, int nr_pages)
   1.127  {
   1.128 @@ -173,6 +241,15 @@ static void add_to_usbif_list_tail(usbif
   1.129      spin_unlock_irqrestore(&usbio_schedule_list_lock, flags);
   1.130  }
   1.131  
   1.132 +void free_pending(int pending_idx)
   1.133 +{
   1.134 +    unsigned long flags;
   1.135 +
   1.136 +    /* Free the pending request. */
   1.137 +    spin_lock_irqsave(&pend_prod_lock, flags);
   1.138 +    pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   1.139 +    spin_unlock_irqrestore(&pend_prod_lock, flags);
   1.140 +}
   1.141  
   1.142  /******************************************************************
   1.143   * COMPLETION CALLBACK -- Called as urb->complete()
   1.144 @@ -182,17 +259,11 @@ static void maybe_trigger_usbio_schedule
   1.145  
   1.146  static void __end_usb_io_op(struct urb *purb)
   1.147  {
   1.148 -    unsigned long flags;
   1.149      pending_req_t *pending_req;
   1.150      int pending_idx;
   1.151  
   1.152      pending_req = purb->context;
   1.153  
   1.154 -/*     printk("Completed for id = %p to 0x%lx - 0x%lx\n", pending_req->id, */
   1.155 -/*            virt_to_machine(purb->transfer_buffer), */
   1.156 -/*            virt_to_machine(purb->transfer_buffer) */
   1.157 -/*            + pending_req->nr_pages * PAGE_SIZE); */
   1.158 -
   1.159      pending_idx = pending_req - pending_reqs;
   1.160  
   1.161      ASSERT(purb->actual_length <= purb->transfer_buffer_length);
   1.162 @@ -201,7 +272,7 @@ static void __end_usb_io_op(struct urb *
   1.163      /* An error fails the entire request. */
   1.164      if ( purb->status )
   1.165      {
   1.166 -        printk("URB @ %p failed. Status %d\n", purb, purb->status);
   1.167 +        printk(KERN_WARNING "URB @ %p failed. Status %d\n", purb, purb->status);
   1.168      }
   1.169  
   1.170      if ( usb_pipetype(purb->pipe) == 0 )
   1.171 @@ -211,8 +282,6 @@ static void __end_usb_io_op(struct urb *
   1.172  
   1.173          ASSERT(sched == pending_req->sched);
   1.174  
   1.175 -	//	printk("writing back schedule at %p\n", sched);
   1.176 -
   1.177          /* If we're dealing with an iso pipe, we need to copy back the schedule. */
   1.178          for ( i = 0; i < purb->number_of_packets; i++ )
   1.179          {
   1.180 @@ -223,24 +292,18 @@ static void __end_usb_io_op(struct urb *
   1.181          }
   1.182      }
   1.183      
   1.184 -    //    printk("Flushing %d pages\n", pending_req->nr_pages);
   1.185      fast_flush_area(pending_req - pending_reqs, pending_req->nr_pages);
   1.186  
   1.187      kfree(purb->setup_packet);
   1.188  
   1.189 -    spin_lock_irqsave(&pending_req->usbif_priv->usb_ring_lock, flags);
   1.190      make_response(pending_req->usbif_priv, pending_req->id,
   1.191  		  pending_req->operation, pending_req->status, 0, purb->actual_length);
   1.192 -    spin_unlock_irqrestore(&pending_req->usbif_priv->usb_ring_lock, flags);
   1.193      usbif_put(pending_req->usbif_priv);
   1.194  
   1.195      usb_free_urb(purb);
   1.196  
   1.197 -    /* Free the pending request. */
   1.198 -    spin_lock_irqsave(&pend_prod_lock, flags);
   1.199 -    pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   1.200 -    spin_unlock_irqrestore(&pend_prod_lock, flags);
   1.201 -
   1.202 +    free_pending(pending_idx);
   1.203 +    
   1.204      rmb();
   1.205  
   1.206      /* Check for anything still waiting in the rings, having freed a request... */
   1.207 @@ -332,9 +395,6 @@ static int do_usb_io_op(usbif_priv_t *up
   1.208      usbif_request_t *req;
   1.209      USBIF_RING_IDX i, rp;
   1.210      int more_to_do = 0;
   1.211 -    unsigned long flags;
   1.212 -
   1.213 -    spin_lock_irqsave(&up->usb_ring_lock, flags);
   1.214  
   1.215      rp = usb_ring->req_prod;
   1.216      rmb(); /* Ensure we see queued requests up to 'rp'. */
   1.217 @@ -377,8 +437,6 @@ static int do_usb_io_op(usbif_priv_t *up
   1.218  
   1.219      up->usb_req_cons = i;
   1.220  
   1.221 -    spin_unlock_irqrestore(&up->usb_ring_lock, flags);
   1.222 -
   1.223      return more_to_do;
   1.224  }
   1.225  
   1.226 @@ -412,11 +470,7 @@ static void dispatch_usb_reset(usbif_pri
   1.227       * than it's worth.  We just fake it out in software but we will do a real
   1.228       * reset when the interface is destroyed. */
   1.229  
   1.230 -#if 0
   1.231 -    printk("Reset port %d\n", portid);
   1.232 -
   1.233      dump_port(port);
   1.234 -#endif
   1.235  
   1.236      port->guest_address = 0;
   1.237      /* If there's an attached device then the port is now enabled. */
   1.238 @@ -438,8 +492,8 @@ static void dispatch_usb_probe(usbif_pri
   1.239      else
   1.240      {
   1.241          ret = -EINVAL;
   1.242 -        printk("dispatch_usb_probe(): invalid port probe request (port %ld)\n",
   1.243 -	       portid);
   1.244 +        printk(KERN_INFO "dispatch_usb_probe(): invalid port probe request "
   1.245 +	       "(port %ld)\n", portid);
   1.246      }
   1.247  
   1.248      /* Probe result is sent back in-band.  Probes don't have an associated id
   1.249 @@ -449,40 +503,6 @@ static void dispatch_usb_probe(usbif_pri
   1.250  
   1.251  owned_port_t *find_port_for_request(usbif_priv_t *up, usbif_request_t *req);
   1.252  
   1.253 -static void dump_request(usbif_request_t *req)
   1.254 -{    
   1.255 -    printk("id = 0x%lx\n", req->id);
   1.256 -    
   1.257 -	printk("devnum %d\n", req->devnum);
   1.258 -	printk("endpoint 0x%x\n", req->endpoint);
   1.259 -	printk("direction %d\n", req->direction);
   1.260 -	printk("speed %d\n", req->speed);
   1.261 -        printk("pipe_type 0x%x\n", req->pipe_type);
   1.262 -        printk("transfer_buffer 0x%lx\n", req->transfer_buffer);
   1.263 -        printk("length 0x%lx\n", req->length);
   1.264 -        printk("transfer_flags 0x%lx\n", req->transfer_flags);
   1.265 -        printk("setup = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
   1.266 -               req->setup[0], req->setup[1], req->setup[2], req->setup[3],
   1.267 -               req->setup[4], req->setup[5], req->setup[6], req->setup[7]);
   1.268 -        printk("iso_schedule = 0x%lx\n", req->iso_schedule);
   1.269 -        printk("num_iso %ld\n", req->num_iso);
   1.270 -}
   1.271 -
   1.272 -void dump_urb(struct urb *urb)
   1.273 -{
   1.274 -    printk("dumping urb @ %p\n", urb);
   1.275 -
   1.276 -#define DUMP_URB_FIELD(name, format) printk("  " # name " " format "\n", urb-> name)
   1.277 -    
   1.278 -    DUMP_URB_FIELD(pipe, "0x%x");
   1.279 -    DUMP_URB_FIELD(status, "%d");
   1.280 -    DUMP_URB_FIELD(transfer_flags, "0x%x");    
   1.281 -    DUMP_URB_FIELD(transfer_buffer, "%p");
   1.282 -    DUMP_URB_FIELD(transfer_buffer_length, "%d");
   1.283 -    DUMP_URB_FIELD(actual_length, "%d");
   1.284 -}
   1.285 -
   1.286 -
   1.287  static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req)
   1.288  {
   1.289      unsigned long buffer_mach;
   1.290 @@ -495,27 +515,36 @@ static void dispatch_usb_io(usbif_priv_t
   1.291      owned_port_t *port;
   1.292      unsigned char *setup;    
   1.293  
   1.294 -//    dump_request(req);
   1.295 +    dump_request(req);
   1.296  
   1.297      if ( NR_PENDING_REQS == MAX_PENDING_REQS )
   1.298      {
   1.299 -        printk("usbback: Max requests already queued.  Now giving up!\n");
   1.300 +        printk(KERN_WARNING "usbback: Max requests already queued. "
   1.301 +	       "Giving up!\n");
   1.302          
   1.303          return;
   1.304      }
   1.305  
   1.306      port = find_port_for_request(up, req);
   1.307  
   1.308 -    if(port == NULL)
   1.309 +    if ( port == NULL )
   1.310      {
   1.311 -	printk("No such device! (%d)\n", req->devnum);
   1.312 +	printk(KERN_WARNING "No such device! (%d)\n", req->devnum);
   1.313  	dump_request(req);
   1.314  
   1.315          make_response(up, req->id, req->operation, -ENODEV, 0, 0);
   1.316  	return;
   1.317      }
   1.318 +    else if ( !port->dev_present )
   1.319 +    {
   1.320 +        /* In normal operation, we'll only get here if a device is unplugged
   1.321 +         * and the frontend hasn't noticed yet. */
   1.322 +        make_response(up, req->id, req->operation, -ENODEV, 0, 0);
   1.323 +	return;
   1.324 +    }
   1.325 +        
   1.326  
   1.327 -    setup = kmalloc(8, GFP_ATOMIC | GFP_NOIO);
   1.328 +    setup = kmalloc(8, GFP_KERNEL);
   1.329  
   1.330      if ( setup == NULL )
   1.331          goto no_mem;
   1.332 @@ -552,7 +581,7 @@ static void dispatch_usb_io(usbif_priv_t
   1.333  
   1.334        /* Ignore configuration setting and hope that the host kernel
   1.335  	 did it right. */
   1.336 -      //        usb_set_configuration(port->dev, setup[2]);
   1.337 +        /* usb_set_configuration(port->dev, setup[2]); */
   1.338  
   1.339          make_response(up, req->id, req->operation, 0, 0, 0);
   1.340  
   1.341 @@ -579,7 +608,8 @@ static void dispatch_usb_io(usbif_priv_t
   1.342  	   + req->length )
   1.343  	 > MMAP_PAGES_PER_REQUEST * PAGE_SIZE )
   1.344      {
   1.345 -        printk("usbback: request of %d bytes too large, failing it\n", req->length);
   1.346 +        printk(KERN_WARNING "usbback: request of %lu bytes too large\n",
   1.347 +	       req->length);
   1.348          make_response(up, req->id, req->operation, -EINVAL, 0, 0);
   1.349          kfree(setup);
   1.350          return;
   1.351 @@ -599,8 +629,6 @@ static void dispatch_usb_io(usbif_priv_t
   1.352      for ( i = 0, offset = 0; offset < req->length;
   1.353            i++, offset += PAGE_SIZE )
   1.354      {
   1.355 -      //        printk("length = %d, offset = %d, looping!\n", req->length, offset);
   1.356 -        
   1.357  	mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
   1.358  	mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT;
   1.359          mcl[i].args[1] = ((buffer_mach & PAGE_MASK) + offset) | remap_prot;
   1.360 @@ -609,7 +637,6 @@ static void dispatch_usb_io(usbif_priv_t
   1.361          
   1.362          phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] =
   1.363              FOREIGN_FRAME((buffer_mach + offset) >> PAGE_SHIFT);
   1.364 -	//	printk("i = %d\n", i);
   1.365  
   1.366          ASSERT(virt_to_machine(MMAP_VADDR(pending_idx, i))
   1.367                 == buffer_mach + i << PAGE_SHIFT);
   1.368 @@ -617,7 +644,6 @@ static void dispatch_usb_io(usbif_priv_t
   1.369  
   1.370      if ( req->pipe_type == 0 && req->num_iso > 0 ) /* Maybe schedule ISO... */
   1.371      {
   1.372 -      //      printk("for iso, i = %d\n", i);
   1.373          /* Map in ISO schedule, if necessary. */
   1.374          mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
   1.375          mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT;
   1.376 @@ -628,12 +654,9 @@ static void dispatch_usb_io(usbif_priv_t
   1.377          phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] =
   1.378              FOREIGN_FRAME(req->iso_schedule >> PAGE_SHIFT);
   1.379      
   1.380 -        //    printk("Mapped iso at %p\n", MMAP_VADDR(pending_idx, i));
   1.381          i++;
   1.382      }
   1.383  
   1.384 -    //    printk("Well we got this far!\n");
   1.385 -
   1.386      if ( unlikely(HYPERVISOR_multicall(mcl, i) != 0) )
   1.387          BUG();
   1.388      
   1.389 @@ -643,9 +666,9 @@ static void dispatch_usb_io(usbif_priv_t
   1.390          {
   1.391              if ( unlikely(mcl[j].args[5] != 0) )
   1.392              {
   1.393 -                printk("invalid buffer %d -- could not remap it\n", j);
   1.394 +                printk(KERN_WARNING
   1.395 +		       "invalid buffer %d -- could not remap it\n", j);
   1.396                  fast_flush_area(pending_idx, i);
   1.397 -		printk("sending invalid descriptor\n");
   1.398                  goto bad_descriptor;
   1.399              }
   1.400  	}
   1.401 @@ -663,8 +686,6 @@ static void dispatch_usb_io(usbif_priv_t
   1.402      pending_req->operation = req->operation;
   1.403      pending_req->nr_pages  = i;
   1.404  
   1.405 -
   1.406 -
   1.407      pending_cons++;
   1.408  
   1.409      usbif_get(up);
   1.410 @@ -673,20 +694,22 @@ static void dispatch_usb_io(usbif_priv_t
   1.411      purb = usb_alloc_urb(req->num_iso);
   1.412  
   1.413      if ( purb == NULL )
   1.414 +    {
   1.415 +        usbif_put(up);
   1.416 +        free_pending(pending_idx);
   1.417          goto no_mem;
   1.418 +    }
   1.419  
   1.420      purb->dev = port->dev;
   1.421      purb->context = pending_req;
   1.422 -    purb->transfer_buffer = (void *)MMAP_VADDR(pending_idx, 0) + (buffer_mach & ~PAGE_MASK);
   1.423 +    purb->transfer_buffer =
   1.424 +        (void *)MMAP_VADDR(pending_idx, 0) + (buffer_mach & ~PAGE_MASK);
   1.425      if(buffer_mach == 0)
   1.426        purb->transfer_buffer = NULL;
   1.427      purb->complete = __end_usb_io_op;
   1.428      purb->transfer_buffer_length = req->length;
   1.429      purb->transfer_flags = req->transfer_flags;
   1.430  
   1.431 -/*     if ( req->transfer_flags != 0 ) */
   1.432 -/*       dump_request(req); */
   1.433 -
   1.434      purb->pipe = 0;
   1.435      purb->pipe |= req->direction << 7;
   1.436      purb->pipe |= port->dev->devnum << 8;
   1.437 @@ -707,8 +730,6 @@ static void dispatch_usb_io(usbif_priv_t
   1.438          int j;
   1.439          usbif_iso_t *iso_sched = (usbif_iso_t *)MMAP_VADDR(pending_idx, i - 1);
   1.440  
   1.441 -	//	printk("Reading iso sched at %p\n", iso_sched);
   1.442 -
   1.443          /* If we're dealing with an iso pipe, we need to copy in a schedule. */
   1.444          for ( j = 0; j < req->num_iso; j++ )
   1.445          {
   1.446 @@ -720,13 +741,17 @@ static void dispatch_usb_io(usbif_priv_t
   1.447      }
   1.448  
   1.449      {
   1.450 -      int ret;
   1.451 -      ret = usb_submit_urb(purb);
   1.452 -
   1.453 -      //      dump_urb(purb);
   1.454 -
   1.455 -      if ( ret != 0 )
   1.456 -          goto bad_descriptor; /* XXX free pending here! */
   1.457 +        int ret;
   1.458 +        ret = usb_submit_urb(purb);
   1.459 +        
   1.460 +        dump_urb(purb);
   1.461 +        
   1.462 +        if ( ret != 0 )
   1.463 +        {
   1.464 +            usbif_put(up);
   1.465 +            free_pending(pending_idx);
   1.466 +            goto bad_descriptor;
   1.467 +        }
   1.468      }
   1.469      
   1.470      return;
   1.471 @@ -759,15 +784,6 @@ static void make_response(usbif_priv_t *
   1.472      usbif_response_t *resp;
   1.473      unsigned long     flags;
   1.474  
   1.475 -#if 0
   1.476 -    printk("usbback: Sending response:\n");
   1.477 -    printk("         id = 0x%x\n", id);
   1.478 -    printk("         op = %d\n", op);
   1.479 -    printk("         status = %d\n", st);
   1.480 -    printk("         data = %d\n", inband);
   1.481 -    printk("         length = %d\n", length);
   1.482 -#endif
   1.483 -
   1.484      /* Place on the response ring for the relevant domain. */ 
   1.485      spin_lock_irqsave(&up->usb_ring_lock, flags);
   1.486      resp = &up->usb_ring_base->
   1.487 @@ -778,6 +794,9 @@ static void make_response(usbif_priv_t *
   1.488      resp->data      = inband;
   1.489      resp->length = length;
   1.490      wmb(); /* Ensure other side can see the response fields. */
   1.491 +
   1.492 +    dump_response(resp);
   1.493 +
   1.494      up->usb_ring_base->resp_prod = ++up->usb_resp_prod;
   1.495      spin_unlock_irqrestore(&up->usb_ring_lock, flags);
   1.496  
   1.497 @@ -798,16 +817,17 @@ int usbif_claim_port(usbif_be_claim_port
   1.498      /* Sanity... */
   1.499      if ( usbif_find_port(msg->path) != NULL )
   1.500      {
   1.501 -        printk("usbback: Attempted to claim USB port "
   1.502 +        printk(KERN_WARNING "usbback: Attempted to claim USB port "
   1.503                 "we already own!\n");
   1.504          return -EINVAL;
   1.505      }
   1.506  
   1.507 -    spin_lock_irq(&owned_ports_lock);
   1.508 -    
   1.509      /* No need for a slab cache - this should be infrequent. */
   1.510      o_p = kmalloc(sizeof(owned_port_t), GFP_KERNEL);
   1.511  
   1.512 +    if ( o_p == NULL )
   1.513 +        return -ENOMEM;
   1.514 +
   1.515      o_p->enabled = 0;
   1.516      o_p->usbif_priv = usbif_find(msg->domid);
   1.517      o_p->guest_port = msg->usbif_port;
   1.518 @@ -816,13 +836,15 @@ int usbif_claim_port(usbif_be_claim_port
   1.519  
   1.520      strcpy(o_p->path, msg->path);
   1.521  
   1.522 +    spin_lock_irq(&owned_ports_lock);
   1.523 +    
   1.524      list_add(&o_p->list, &owned_ports);
   1.525  
   1.526 -    printk("usbback: Claimed USB port (%s) for %d.%d\n", o_p->path,
   1.527 +    spin_unlock_irq(&owned_ports_lock);
   1.528 +
   1.529 +    printk(KERN_INFO "usbback: Claimed USB port (%s) for %d.%d\n", o_p->path,
   1.530  	   msg->domid, msg->usbif_port);
   1.531  
   1.532 -    spin_unlock_irq(&owned_ports_lock);
   1.533 -
   1.534      /* Force a reprobe for unclaimed devices. */
   1.535      usb_scan_devices();
   1.536  
   1.537 @@ -843,11 +865,9 @@ owned_port_t *find_port_for_request(usbi
   1.538          owned_port_t *p = list_entry(port, owned_port_t, list);
   1.539          if(p->usbif_priv == up && p->guest_address == req->devnum && p->enabled )
   1.540  	  {
   1.541 -#if 0
   1.542 -              printk("Found port for devnum %d\n", req->devnum);
   1.543 +              dump_port(p);
   1.544  
   1.545 -              dump_port(p);
   1.546 -#endif
   1.547 +	      spin_unlock_irqrestore(&owned_ports_lock, flags);
   1.548                return p;
   1.549  	  }
   1.550      }
   1.551 @@ -856,29 +876,37 @@ owned_port_t *find_port_for_request(usbi
   1.552      return NULL;    
   1.553  }
   1.554  
   1.555 -owned_port_t *usbif_find_port(char *path)
   1.556 +owned_port_t *__usbif_find_port(char *path)
   1.557  {
   1.558      struct list_head *port;
   1.559 -    unsigned long flags;
   1.560  
   1.561 -    spin_lock_irqsave(&owned_ports_lock, flags);
   1.562      list_for_each(port, &owned_ports)
   1.563      {
   1.564          owned_port_t *p = list_entry(port, owned_port_t, list);
   1.565          if(!strcmp(path, p->path))
   1.566          {
   1.567 -            spin_unlock_irqrestore(&owned_ports_lock, flags);
   1.568              return p;
   1.569          }
   1.570      }
   1.571 -    spin_unlock_irqrestore(&owned_ports_lock, flags);
   1.572  
   1.573      return NULL;
   1.574  }
   1.575  
   1.576 +owned_port_t *usbif_find_port(char *path)
   1.577 +{
   1.578 +    owned_port_t *ret;
   1.579 +    unsigned long flags;
   1.580 +
   1.581 +    spin_lock_irqsave(&owned_ports_lock, flags);
   1.582 +    ret = __usbif_find_port(path);    
   1.583 +    spin_unlock_irqrestore(&owned_ports_lock, flags);
   1.584 +
   1.585 +    return ret;
   1.586 +}
   1.587 +
   1.588  
   1.589  static void *probe(struct usb_device *dev, unsigned iface,
   1.590 -	    const struct usb_device_id *id)
   1.591 +                   const struct usb_device_id *id)
   1.592  {
   1.593      owned_port_t *p;
   1.594  
   1.595 @@ -887,7 +915,7 @@ static void *probe(struct usb_device *de
   1.596       * the device actually is ;-) */
   1.597      if ( ( p = usbif_find_port(dev->devpath) ) != NULL )
   1.598      {
   1.599 -        printk("usbback: claimed device attached to owned port\n");
   1.600 +        printk(KERN_INFO "usbback: claimed device attached to owned port\n");
   1.601  
   1.602          p->dev_present = 1;
   1.603          p->dev = dev;
   1.604 @@ -896,7 +924,8 @@ static void *probe(struct usb_device *de
   1.605          return p->usbif_priv;
   1.606      }
   1.607      else
   1.608 -        printk("usbback: hotplug for non-owned port (%s), ignoring\n", dev->devpath);
   1.609 +        printk(KERN_INFO "usbback: hotplug for non-owned port (%s), ignoring\n",
   1.610 +	       dev->devpath);
   1.611     
   1.612  
   1.613      return NULL;
   1.614 @@ -938,6 +967,10 @@ void __usbif_release_port(owned_port_t *
   1.615       * drivers in this kernel because we assume the device is completely under
   1.616       * the control of ourselves (i.e. the guest!).  This should ensure that the
   1.617       * device is in a sane state for the next customer ;-) */
   1.618 +
   1.619 +    /* MAW NB: we're not resetting the real device here.  This looks perfectly
   1.620 +     * valid to me but it causes memory corruption.  We seem to get away with not
   1.621 +     * resetting for now, although it'd be nice to have this tracked down. */
   1.622  /*     if ( p->dev != NULL) */
   1.623  /*         usb_reset_device(p->dev); */
   1.624  
   1.625 @@ -953,7 +986,7 @@ void usbif_release_port(usbif_be_release
   1.626      owned_port_t *p;
   1.627  
   1.628      spin_lock_irq(&owned_ports_lock);
   1.629 -    p = usbif_find_port(msg->path);
   1.630 +    p = __usbif_find_port(msg->path);
   1.631      __usbif_release_port(p);
   1.632      spin_unlock_irq(&owned_ports_lock);
   1.633  }
   1.634 @@ -981,12 +1014,6 @@ static int __init usbif_init(void)
   1.635           !(xen_start_info.flags & SIF_USB_BE_DOMAIN) )
   1.636          return 0;
   1.637      
   1.638 -    INIT_LIST_HEAD(&owned_ports);
   1.639 -
   1.640 -    usb_register(&driver);
   1.641 -
   1.642 -    usbif_interface_init();
   1.643 -
   1.644      if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 )
   1.645          BUG();
   1.646  
   1.647 @@ -996,17 +1023,24 @@ static int __init usbif_init(void)
   1.648      for ( i = 0; i < MAX_PENDING_REQS; i++ )
   1.649          pending_ring[i] = i;
   1.650  
   1.651 +    spin_lock_init(&pend_prod_lock);
   1.652 +
   1.653 +    spin_lock_init(&owned_ports_lock);
   1.654 +    INIT_LIST_HEAD(&owned_ports);
   1.655 +
   1.656      spin_lock_init(&usbio_schedule_list_lock);
   1.657      INIT_LIST_HEAD(&usbio_schedule_list);
   1.658  
   1.659      if ( kernel_thread(usbio_schedule, 0, CLONE_FS | CLONE_FILES) < 0 )
   1.660          BUG();
   1.661      
   1.662 +    usbif_interface_init();
   1.663 +
   1.664      usbif_ctrlif_init();
   1.665  
   1.666 -    spin_lock_init(&owned_ports_lock);
   1.667 +    usb_register(&driver);
   1.668  
   1.669 -    printk("Xen USB Backend Initialised");
   1.670 +    printk(KERN_INFO "Xen USB Backend Initialised");
   1.671  
   1.672      return 0;
   1.673  }