debuggers.hg
changeset 3681: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
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 }