ia64/linux-2.6.18-xen.hg

annotate drivers/xen/usbback/usbback.c @ 829:f799db0570f2

PVUSB: backend driver

Signed-off-by: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Mar 18 11:43:24 2009 +0000 (2009-03-18)
parents
children 4c7eb2e71e9d
rev   line source
keir@829 1 /*
keir@829 2 * usbback.c
keir@829 3 *
keir@829 4 * Xen USB backend driver
keir@829 5 *
keir@829 6 * Copyright (C) 2009, FUJITSU LABORATORIES LTD.
keir@829 7 * Author: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
keir@829 8 *
keir@829 9 * This program is free software; you can redistribute it and/or modify
keir@829 10 * it under the terms of the GNU General Public License as published by
keir@829 11 * the Free Software Foundation; either version 2 of the License, or
keir@829 12 * (at your option) any later version.
keir@829 13 *
keir@829 14 * This program is distributed in the hope that it will be useful,
keir@829 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
keir@829 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
keir@829 17 * GNU General Public License for more details.
keir@829 18 *
keir@829 19 * You should have received a copy of the GNU General Public License
keir@829 20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
keir@829 21 *
keir@829 22 * or,
keir@829 23 *
keir@829 24 * When distributed separately from the Linux kernel or incorporated into
keir@829 25 * other software packages, subject to the following license:
keir@829 26 *
keir@829 27 * Permission is hereby granted, free of charge, to any person obtaining a copy
keir@829 28 * of this software and associated documentation files (the "Software"), to
keir@829 29 * deal in the Software without restriction, including without limitation the
keir@829 30 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
keir@829 31 * sell copies of the Software, and to permit persons to whom the Software is
keir@829 32 * furnished to do so, subject to the following conditions:
keir@829 33 *
keir@829 34 * The above copyright notice and this permission notice shall be included in
keir@829 35 * all copies or substantial portions of the Software.
keir@829 36 *
keir@829 37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
keir@829 38 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
keir@829 39 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
keir@829 40 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
keir@829 41 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
keir@829 42 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
keir@829 43 * DEALINGS IN THE SOFTWARE.
keir@829 44 */
keir@829 45
keir@829 46 #include <linux/mm.h>
keir@829 47 #include <xen/balloon.h>
keir@829 48 #include "usbback.h"
keir@829 49
keir@829 50 #if 0
keir@829 51 #include "../../usb/core/hub.h"
keir@829 52 #endif
keir@829 53
keir@829 54 int usbif_reqs = USBIF_BACK_MAX_PENDING_REQS;
keir@829 55 module_param_named(reqs, usbif_reqs, int, 0);
keir@829 56 MODULE_PARM_DESC(reqs, "Number of usbback requests to allocate");
keir@829 57
keir@829 58 struct pending_req_segment {
keir@829 59 uint16_t offset;
keir@829 60 uint16_t length;
keir@829 61 };
keir@829 62
keir@829 63 typedef struct {
keir@829 64 usbif_t *usbif;
keir@829 65
keir@829 66 uint16_t id; /* request id */
keir@829 67
keir@829 68 struct usbstub *stub;
keir@829 69 struct list_head urb_list;
keir@829 70
keir@829 71 /* urb */
keir@829 72 struct urb *urb;
keir@829 73 void *buffer;
keir@829 74 dma_addr_t transfer_dma;
keir@829 75 struct usb_ctrlrequest *setup;
keir@829 76 dma_addr_t setup_dma;
keir@829 77
keir@829 78 /* request segments */
keir@829 79 uint16_t nr_buffer_segs; /* number of urb->transfer_buffer segments */
keir@829 80 uint16_t nr_extra_segs; /* number of iso_frame_desc segments (ISO) */
keir@829 81 struct pending_req_segment *seg;
keir@829 82
keir@829 83 struct list_head free_list;
keir@829 84 } pending_req_t;
keir@829 85
keir@829 86 static pending_req_t *pending_reqs;
keir@829 87 static struct list_head pending_free;
keir@829 88 static DEFINE_SPINLOCK(pending_free_lock);
keir@829 89 static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq);
keir@829 90
keir@829 91 #define USBBACK_INVALID_HANDLE (~0)
keir@829 92
keir@829 93 static struct page **pending_pages;
keir@829 94 static grant_handle_t *pending_grant_handles;
keir@829 95
keir@829 96 static inline int vaddr_pagenr(pending_req_t *req, int seg)
keir@829 97 {
keir@829 98 return (req - pending_reqs) * USBIF_MAX_SEGMENTS_PER_REQUEST + seg;
keir@829 99 }
keir@829 100
keir@829 101 static inline unsigned long vaddr(pending_req_t *req, int seg)
keir@829 102 {
keir@829 103 unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]);
keir@829 104 return (unsigned long)pfn_to_kaddr(pfn);
keir@829 105 }
keir@829 106
keir@829 107 #define pending_handle(_req, _seg) \
keir@829 108 (pending_grant_handles[vaddr_pagenr(_req, _seg)])
keir@829 109
keir@829 110 static pending_req_t* alloc_req(void)
keir@829 111 {
keir@829 112 pending_req_t *req = NULL;
keir@829 113 unsigned long flags;
keir@829 114
keir@829 115 spin_lock_irqsave(&pending_free_lock, flags);
keir@829 116 if (!list_empty(&pending_free)) {
keir@829 117 req = list_entry(pending_free.next, pending_req_t, free_list);
keir@829 118 list_del(&req->free_list);
keir@829 119 }
keir@829 120 spin_unlock_irqrestore(&pending_free_lock, flags);
keir@829 121 return req;
keir@829 122 }
keir@829 123
keir@829 124 static void free_req(pending_req_t *req)
keir@829 125 {
keir@829 126 unsigned long flags;
keir@829 127 int was_empty;
keir@829 128
keir@829 129 spin_lock_irqsave(&pending_free_lock, flags);
keir@829 130 was_empty = list_empty(&pending_free);
keir@829 131 list_add(&req->free_list, &pending_free);
keir@829 132 spin_unlock_irqrestore(&pending_free_lock, flags);
keir@829 133 if (was_empty)
keir@829 134 wake_up(&pending_free_wq);
keir@829 135 }
keir@829 136
keir@829 137 static inline void add_req_to_submitting_list(struct usbstub *stub, pending_req_t *pending_req)
keir@829 138 {
keir@829 139 unsigned long flags;
keir@829 140
keir@829 141 spin_lock_irqsave(&stub->submitting_lock, flags);
keir@829 142 list_add_tail(&pending_req->urb_list, &stub->submitting_list);
keir@829 143 spin_unlock_irqrestore(&stub->submitting_lock, flags);
keir@829 144 }
keir@829 145
keir@829 146 static inline void remove_req_from_submitting_list(struct usbstub *stub, pending_req_t *pending_req)
keir@829 147 {
keir@829 148 unsigned long flags;
keir@829 149
keir@829 150 spin_lock_irqsave(&stub->submitting_lock, flags);
keir@829 151 list_del_init(&pending_req->urb_list);
keir@829 152 spin_unlock_irqrestore(&stub->submitting_lock, flags);
keir@829 153 }
keir@829 154
keir@829 155 void usbbk_unlink_urbs(struct usbstub *stub)
keir@829 156 {
keir@829 157 pending_req_t *req, *tmp;
keir@829 158 unsigned long flags;
keir@829 159
keir@829 160 spin_lock_irqsave(&stub->submitting_lock, flags);
keir@829 161 list_for_each_entry_safe(req, tmp, &stub->submitting_list, urb_list) {
keir@829 162 usb_unlink_urb(req->urb);
keir@829 163 }
keir@829 164 spin_unlock_irqrestore(&stub->submitting_lock, flags);
keir@829 165 }
keir@829 166
keir@829 167 static void fast_flush_area(pending_req_t *pending_req)
keir@829 168 {
keir@829 169 struct gnttab_unmap_grant_ref unmap[USBIF_MAX_SEGMENTS_PER_REQUEST];
keir@829 170 unsigned int i, nr_segs, invcount = 0;
keir@829 171 grant_handle_t handle;
keir@829 172 int ret;
keir@829 173
keir@829 174 nr_segs = pending_req->nr_buffer_segs + pending_req->nr_extra_segs;
keir@829 175
keir@829 176 if (nr_segs) {
keir@829 177 for (i = 0; i < nr_segs; i++) {
keir@829 178 handle = pending_handle(pending_req, i);
keir@829 179 if (handle == USBBACK_INVALID_HANDLE)
keir@829 180 continue;
keir@829 181 gnttab_set_unmap_op(&unmap[invcount], vaddr(pending_req, i),
keir@829 182 GNTMAP_host_map, handle);
keir@829 183 pending_handle(pending_req, i) = USBBACK_INVALID_HANDLE;
keir@829 184 invcount++;
keir@829 185 }
keir@829 186
keir@829 187 ret = HYPERVISOR_grant_table_op(
keir@829 188 GNTTABOP_unmap_grant_ref, unmap, invcount);
keir@829 189 BUG_ON(ret);
keir@829 190
keir@829 191 kfree(pending_req->seg);
keir@829 192 }
keir@829 193
keir@829 194 return;
keir@829 195 }
keir@829 196
keir@829 197 static void copy_buff_to_pages(void *buff, pending_req_t *pending_req,
keir@829 198 int start, int nr_pages)
keir@829 199 {
keir@829 200 unsigned long copied = 0;
keir@829 201 int i;
keir@829 202
keir@829 203 for (i = start; i < start + nr_pages; i++) {
keir@829 204 memcpy((void *) vaddr(pending_req, i) + pending_req->seg[i].offset,
keir@829 205 buff + copied,
keir@829 206 pending_req->seg[i].length);
keir@829 207 copied += pending_req->seg[i].length;
keir@829 208 }
keir@829 209 }
keir@829 210
keir@829 211 static void copy_pages_to_buff(void *buff, pending_req_t *pending_req,
keir@829 212 int start, int nr_pages)
keir@829 213 {
keir@829 214 unsigned long copied = 0;
keir@829 215 int i;
keir@829 216
keir@829 217 for (i = start; i < start + nr_pages; i++) {
keir@829 218 memcpy(buff + copied,
keir@829 219 (void *) vaddr(pending_req, i) + pending_req->seg[i].offset,
keir@829 220 pending_req->seg[i].length);
keir@829 221 copied += pending_req->seg[i].length;
keir@829 222 }
keir@829 223 }
keir@829 224
keir@829 225 static int usbbk_alloc_urb(usbif_request_t *req, pending_req_t *pending_req)
keir@829 226 {
keir@829 227 int ret;
keir@829 228
keir@829 229 if (usb_pipeisoc(req->pipe))
keir@829 230 pending_req->urb = usb_alloc_urb(req->u.isoc.number_of_packets, GFP_KERNEL);
keir@829 231 else
keir@829 232 pending_req->urb = usb_alloc_urb(0, GFP_KERNEL);
keir@829 233 if (!pending_req->urb) {
keir@829 234 printk(KERN_ERR "usbback: can't alloc urb\n");
keir@829 235 ret = -ENOMEM;
keir@829 236 goto fail;
keir@829 237 }
keir@829 238
keir@829 239 if (req->buffer_length) {
keir@829 240 pending_req->buffer = usb_buffer_alloc(pending_req->stub->udev,
keir@829 241 req->buffer_length, GFP_KERNEL,
keir@829 242 &pending_req->transfer_dma);
keir@829 243 if (!pending_req->buffer) {
keir@829 244 printk(KERN_ERR "usbback: can't alloc urb buffer\n");
keir@829 245 ret = -ENOMEM;
keir@829 246 goto fail_free_urb;
keir@829 247 }
keir@829 248 }
keir@829 249
keir@829 250 if (usb_pipecontrol(req->pipe)) {
keir@829 251 pending_req->setup = usb_buffer_alloc(pending_req->stub->udev,
keir@829 252 sizeof(struct usb_ctrlrequest), GFP_KERNEL,
keir@829 253 &pending_req->setup_dma);
keir@829 254 if (!pending_req->setup) {
keir@829 255 printk(KERN_ERR "usbback: can't alloc usb_ctrlrequest\n");
keir@829 256 ret = -ENOMEM;
keir@829 257 goto fail_free_buffer;
keir@829 258 }
keir@829 259 }
keir@829 260
keir@829 261 return 0;
keir@829 262
keir@829 263 fail_free_buffer:
keir@829 264 if (req->buffer_length)
keir@829 265 usb_buffer_free(pending_req->stub->udev, req->buffer_length,
keir@829 266 pending_req->buffer, pending_req->transfer_dma);
keir@829 267 fail_free_urb:
keir@829 268 usb_free_urb(pending_req->urb);
keir@829 269 fail:
keir@829 270 return ret;
keir@829 271 }
keir@829 272
keir@829 273 static void usbbk_free_urb(struct urb *urb)
keir@829 274 {
keir@829 275 if (usb_pipecontrol(urb->pipe))
keir@829 276 usb_buffer_free(urb->dev, sizeof(struct usb_ctrlrequest),
keir@829 277 urb->setup_packet, urb->setup_dma);
keir@829 278 if (urb->transfer_buffer_length)
keir@829 279 usb_buffer_free(urb->dev, urb->transfer_buffer_length,
keir@829 280 urb->transfer_buffer, urb->transfer_dma);
keir@829 281 barrier();
keir@829 282 usb_free_urb(urb);
keir@829 283 }
keir@829 284
keir@829 285 static void usbbk_notify_work(usbif_t *usbif)
keir@829 286 {
keir@829 287 usbif->waiting_reqs = 1;
keir@829 288 wake_up(&usbif->wq);
keir@829 289 }
keir@829 290
keir@829 291 irqreturn_t usbbk_be_int(int irq, void *dev_id, struct pt_regs *regs)
keir@829 292 {
keir@829 293 usbbk_notify_work(dev_id);
keir@829 294 return IRQ_HANDLED;
keir@829 295 }
keir@829 296
keir@829 297 static void usbbk_do_response(pending_req_t *pending_req, int32_t status,
keir@829 298 int32_t actual_length, int32_t error_count, uint16_t start_frame)
keir@829 299 {
keir@829 300 usbif_t *usbif = pending_req->usbif;
keir@829 301 usbif_response_t *ring_res;
keir@829 302 unsigned long flags;
keir@829 303 int notify;
keir@829 304
keir@829 305 spin_lock_irqsave(&usbif->ring_lock, flags);
keir@829 306 ring_res = RING_GET_RESPONSE(&usbif->ring, usbif->ring.rsp_prod_pvt);
keir@829 307 ring_res->id = pending_req->id;
keir@829 308 ring_res->status = status;
keir@829 309 ring_res->actual_length = actual_length;
keir@829 310 ring_res->error_count = error_count;
keir@829 311 ring_res->start_frame = start_frame;
keir@829 312 usbif->ring.rsp_prod_pvt++;
keir@829 313 barrier();
keir@829 314 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->ring, notify);
keir@829 315 spin_unlock_irqrestore(&usbif->ring_lock, flags);
keir@829 316
keir@829 317 if (notify)
keir@829 318 notify_remote_via_irq(usbif->irq);
keir@829 319 }
keir@829 320
keir@829 321 static void usbbk_urb_complete(struct urb *urb, struct pt_regs *regs)
keir@829 322 {
keir@829 323 pending_req_t *pending_req = (pending_req_t *)urb->context;
keir@829 324
keir@829 325 if (usb_pipein(urb->pipe) && urb->status == 0 && urb->actual_length > 0)
keir@829 326 copy_buff_to_pages(pending_req->buffer, pending_req,
keir@829 327 0, pending_req->nr_buffer_segs);
keir@829 328
keir@829 329 if (usb_pipeisoc(urb->pipe))
keir@829 330 copy_buff_to_pages(&urb->iso_frame_desc[0], pending_req,
keir@829 331 pending_req->nr_buffer_segs, pending_req->nr_extra_segs);
keir@829 332
keir@829 333 barrier();
keir@829 334
keir@829 335 fast_flush_area(pending_req);
keir@829 336
keir@829 337 usbbk_do_response(pending_req, urb->status, urb->actual_length,
keir@829 338 urb->error_count, urb->start_frame);
keir@829 339
keir@829 340 remove_req_from_submitting_list(pending_req->stub, pending_req);
keir@829 341
keir@829 342 barrier();
keir@829 343 usbbk_free_urb(urb);
keir@829 344 usbif_put(pending_req->usbif);
keir@829 345 free_req(pending_req);
keir@829 346 }
keir@829 347
keir@829 348 static int usbbk_gnttab_map(usbif_t *usbif,
keir@829 349 usbif_request_t *req, pending_req_t *pending_req)
keir@829 350 {
keir@829 351 int i, ret;
keir@829 352 unsigned int nr_segs;
keir@829 353 uint32_t flags;
keir@829 354 struct gnttab_map_grant_ref map[USBIF_MAX_SEGMENTS_PER_REQUEST];
keir@829 355
keir@829 356 nr_segs = pending_req->nr_buffer_segs + pending_req->nr_extra_segs;
keir@829 357
keir@829 358 if (nr_segs > USBIF_MAX_SEGMENTS_PER_REQUEST) {
keir@829 359 printk(KERN_ERR "Bad number of segments in request\n");
keir@829 360 ret = -EINVAL;
keir@829 361 goto fail;
keir@829 362 }
keir@829 363
keir@829 364 if (nr_segs) {
keir@829 365 pending_req->seg = kmalloc(sizeof(struct pending_req_segment)
keir@829 366 * nr_segs, GFP_KERNEL);
keir@829 367 if (!pending_req->seg) {
keir@829 368 ret = -ENOMEM;
keir@829 369 goto fail;
keir@829 370 }
keir@829 371
keir@829 372 if (pending_req->nr_buffer_segs) {
keir@829 373 flags = GNTMAP_host_map;
keir@829 374 if (usb_pipeout(req->pipe))
keir@829 375 flags |= GNTMAP_readonly;
keir@829 376 for (i = 0; i < pending_req->nr_buffer_segs; i++)
keir@829 377 gnttab_set_map_op(&map[i], vaddr(
keir@829 378 pending_req, i), flags,
keir@829 379 req->seg[i].gref,
keir@829 380 usbif->domid);
keir@829 381 }
keir@829 382
keir@829 383 if (pending_req->nr_extra_segs) {
keir@829 384 flags = GNTMAP_host_map;
keir@829 385 for (i = req->nr_buffer_segs; i < nr_segs; i++)
keir@829 386 gnttab_set_map_op(&map[i], vaddr(
keir@829 387 pending_req, i), flags,
keir@829 388 req->seg[i].gref,
keir@829 389 usbif->domid);
keir@829 390 }
keir@829 391
keir@829 392 ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
keir@829 393 map, nr_segs);
keir@829 394 BUG_ON(ret);
keir@829 395
keir@829 396 for (i = 0; i < nr_segs; i++) {
keir@829 397 if (unlikely(map[i].status != 0)) {
keir@829 398 printk(KERN_ERR "usbback: invalid buffer -- could not remap it\n");
keir@829 399 map[i].handle = USBBACK_INVALID_HANDLE;
keir@829 400 ret |= 1;
keir@829 401 }
keir@829 402
keir@829 403 pending_handle(pending_req, i) = map[i].handle;
keir@829 404
keir@829 405 if (ret)
keir@829 406 continue;
keir@829 407
keir@829 408 set_phys_to_machine(__pa(vaddr(
keir@829 409 pending_req, i)) >> PAGE_SHIFT,
keir@829 410 FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
keir@829 411
keir@829 412 pending_req->seg[i].offset = req->seg[i].offset;
keir@829 413 pending_req->seg[i].length = req->seg[i].length;
keir@829 414
keir@829 415 barrier();
keir@829 416
keir@829 417 if (pending_req->seg[i].offset >= PAGE_SIZE ||
keir@829 418 pending_req->seg[i].length > PAGE_SIZE ||
keir@829 419 pending_req->seg[i].offset + pending_req->seg[i].length > PAGE_SIZE)
keir@829 420 ret |= 1;
keir@829 421 }
keir@829 422
keir@829 423 if (ret)
keir@829 424 goto fail_flush;
keir@829 425 }
keir@829 426
keir@829 427 return 0;
keir@829 428
keir@829 429 fail_flush:
keir@829 430 fast_flush_area(pending_req);
keir@829 431 ret = -ENOMEM;
keir@829 432
keir@829 433 fail:
keir@829 434 return ret;
keir@829 435 }
keir@829 436
keir@829 437 static void usbbk_init_urb(usbif_request_t *req, pending_req_t *pending_req)
keir@829 438 {
keir@829 439 unsigned int pipe;
keir@829 440 struct usb_device *udev = pending_req->stub->udev;
keir@829 441 struct urb *urb = pending_req->urb;
keir@829 442
keir@829 443 switch (usb_pipetype(req->pipe)) {
keir@829 444 case PIPE_ISOCHRONOUS:
keir@829 445 if (usb_pipein(req->pipe))
keir@829 446 pipe = usb_rcvisocpipe(udev, usb_pipeendpoint(req->pipe));
keir@829 447 else
keir@829 448 pipe = usb_sndisocpipe(udev, usb_pipeendpoint(req->pipe));
keir@829 449
keir@829 450 urb->dev = udev;
keir@829 451 urb->pipe = pipe;
keir@829 452 urb->transfer_flags = req->transfer_flags;
keir@829 453 urb->transfer_flags |= URB_ISO_ASAP;
keir@829 454 urb->transfer_buffer = pending_req->buffer;
keir@829 455 urb->transfer_buffer_length = req->buffer_length;
keir@829 456 urb->complete = usbbk_urb_complete;
keir@829 457 urb->context = pending_req;
keir@829 458 urb->interval = req->u.isoc.interval;
keir@829 459 urb->start_frame = req->u.isoc.start_frame;
keir@829 460 urb->number_of_packets = req->u.isoc.number_of_packets;
keir@829 461
keir@829 462 break;
keir@829 463 case PIPE_INTERRUPT:
keir@829 464 if (usb_pipein(req->pipe))
keir@829 465 pipe = usb_rcvintpipe(udev, usb_pipeendpoint(req->pipe));
keir@829 466 else
keir@829 467 pipe = usb_sndintpipe(udev, usb_pipeendpoint(req->pipe));
keir@829 468
keir@829 469 usb_fill_int_urb(urb, udev, pipe,
keir@829 470 pending_req->buffer, req->buffer_length,
keir@829 471 usbbk_urb_complete,
keir@829 472 pending_req, req->u.intr.interval);
keir@829 473 urb->transfer_flags = req->transfer_flags;
keir@829 474
keir@829 475 break;
keir@829 476 case PIPE_CONTROL:
keir@829 477 if (usb_pipein(req->pipe))
keir@829 478 pipe = usb_rcvctrlpipe(udev, 0);
keir@829 479 else
keir@829 480 pipe = usb_sndctrlpipe(udev, 0);
keir@829 481
keir@829 482 usb_fill_control_urb(urb, udev, pipe,
keir@829 483 (unsigned char *) pending_req->setup,
keir@829 484 pending_req->buffer, req->buffer_length,
keir@829 485 usbbk_urb_complete, pending_req);
keir@829 486 memcpy(pending_req->setup, req->u.ctrl, 8);
keir@829 487 urb->setup_dma = pending_req->setup_dma;
keir@829 488 urb->transfer_flags = req->transfer_flags;
keir@829 489 urb->transfer_flags |= URB_NO_SETUP_DMA_MAP;
keir@829 490
keir@829 491 break;
keir@829 492 case PIPE_BULK:
keir@829 493 if (usb_pipein(req->pipe))
keir@829 494 pipe = usb_rcvbulkpipe(udev, usb_pipeendpoint(req->pipe));
keir@829 495 else
keir@829 496 pipe = usb_sndbulkpipe(udev, usb_pipeendpoint(req->pipe));
keir@829 497
keir@829 498 usb_fill_bulk_urb(urb, udev, pipe,
keir@829 499 pending_req->buffer, req->buffer_length,
keir@829 500 usbbk_urb_complete, pending_req);
keir@829 501 urb->transfer_flags = req->transfer_flags;
keir@829 502
keir@829 503 break;
keir@829 504 default:
keir@829 505 break;
keir@829 506 }
keir@829 507
keir@829 508 if (req->buffer_length) {
keir@829 509 urb->transfer_dma = pending_req->transfer_dma;
keir@829 510 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
keir@829 511 }
keir@829 512 }
keir@829 513
keir@829 514 struct set_interface_request {
keir@829 515 pending_req_t *pending_req;
keir@829 516 int interface;
keir@829 517 int alternate;
keir@829 518 struct work_struct work;
keir@829 519 };
keir@829 520
keir@829 521 static void usbbk_set_interface_work(void *data)
keir@829 522 {
keir@829 523 struct set_interface_request *req = (struct set_interface_request *) data;
keir@829 524 pending_req_t *pending_req = req->pending_req;
keir@829 525 struct usb_device *udev = req->pending_req->stub->udev;
keir@829 526
keir@829 527 int ret;
keir@829 528
keir@829 529 usb_lock_device(udev);
keir@829 530 ret = usb_set_interface(udev, req->interface, req->alternate);
keir@829 531 usb_unlock_device(udev);
keir@829 532 usb_put_dev(udev);
keir@829 533
keir@829 534 usbbk_do_response(pending_req, ret, 0, 0, 0);
keir@829 535 usbif_put(pending_req->usbif);
keir@829 536 free_req(pending_req);
keir@829 537 kfree(req);
keir@829 538 }
keir@829 539
keir@829 540 static int usbbk_set_interface(pending_req_t *pending_req, int interface, int alternate)
keir@829 541 {
keir@829 542 struct set_interface_request *req;
keir@829 543 struct usb_device *udev = pending_req->stub->udev;
keir@829 544
keir@829 545 req = kmalloc(sizeof(*req), GFP_KERNEL);
keir@829 546 if (!req)
keir@829 547 return -ENOMEM;
keir@829 548 req->pending_req = pending_req;
keir@829 549 req->interface = interface;
keir@829 550 req->alternate = alternate;
keir@829 551 INIT_WORK(&req->work, usbbk_set_interface_work, req);
keir@829 552 usb_get_dev(udev);
keir@829 553 schedule_work(&req->work);
keir@829 554 return 0;
keir@829 555 }
keir@829 556
keir@829 557 struct clear_halt_request {
keir@829 558 pending_req_t *pending_req;
keir@829 559 int pipe;
keir@829 560 struct work_struct work;
keir@829 561 };
keir@829 562
keir@829 563 static void usbbk_clear_halt_work(void *data)
keir@829 564 {
keir@829 565 struct clear_halt_request *req = (struct clear_halt_request *) data;
keir@829 566 pending_req_t *pending_req = req->pending_req;
keir@829 567 struct usb_device *udev = req->pending_req->stub->udev;
keir@829 568 int ret;
keir@829 569
keir@829 570 usb_lock_device(udev);
keir@829 571 ret = usb_clear_halt(req->pending_req->stub->udev, req->pipe);
keir@829 572 usb_unlock_device(udev);
keir@829 573 usb_put_dev(udev);
keir@829 574
keir@829 575 usbbk_do_response(pending_req, ret, 0, 0, 0);
keir@829 576 usbif_put(pending_req->usbif);
keir@829 577 free_req(pending_req);
keir@829 578 kfree(req);
keir@829 579 }
keir@829 580
keir@829 581 static int usbbk_clear_halt(pending_req_t *pending_req, int pipe)
keir@829 582 {
keir@829 583 struct clear_halt_request *req;
keir@829 584 struct usb_device *udev = pending_req->stub->udev;
keir@829 585
keir@829 586 req = kmalloc(sizeof(*req), GFP_KERNEL);
keir@829 587 if (!req)
keir@829 588 return -ENOMEM;
keir@829 589 req->pending_req = pending_req;
keir@829 590 req->pipe = pipe;
keir@829 591 INIT_WORK(&req->work, usbbk_clear_halt_work, req);
keir@829 592
keir@829 593 usb_get_dev(udev);
keir@829 594 schedule_work(&req->work);
keir@829 595 return 0;
keir@829 596 }
keir@829 597
keir@829 598 #if 0
keir@829 599 struct port_reset_request {
keir@829 600 pending_req_t *pending_req;
keir@829 601 struct work_struct work;
keir@829 602 };
keir@829 603
keir@829 604 static void usbbk_port_reset_work(void *data)
keir@829 605 {
keir@829 606 struct port_reset_request *req = (struct port_reset_request *) data;
keir@829 607 pending_req_t *pending_req = req->pending_req;
keir@829 608 struct usb_device *udev = pending_req->stub->udev;
keir@829 609 int ret, ret_lock;
keir@829 610
keir@829 611 ret = ret_lock = usb_lock_device_for_reset(udev, NULL);
keir@829 612 if (ret_lock >= 0) {
keir@829 613 ret = usb_reset_device(udev);
keir@829 614 if (ret_lock)
keir@829 615 usb_unlock_device(udev);
keir@829 616 }
keir@829 617 usb_put_dev(udev);
keir@829 618
keir@829 619 usbbk_do_response(pending_req, ret, 0, 0, 0);
keir@829 620 usbif_put(pending_req->usbif);
keir@829 621 free_req(pending_req);
keir@829 622 kfree(req);
keir@829 623 }
keir@829 624
keir@829 625 static int usbbk_port_reset(pending_req_t *pending_req)
keir@829 626 {
keir@829 627 struct port_reset_request *req;
keir@829 628 struct usb_device *udev = pending_req->stub->udev;
keir@829 629
keir@829 630 req = kmalloc(sizeof(*req), GFP_KERNEL);
keir@829 631 if (!req)
keir@829 632 return -ENOMEM;
keir@829 633
keir@829 634 req->pending_req = pending_req;
keir@829 635 INIT_WORK(&req->work, usbbk_port_reset_work, req);
keir@829 636
keir@829 637 usb_get_dev(udev);
keir@829 638 schedule_work(&req->work);
keir@829 639 return 0;
keir@829 640 }
keir@829 641 #endif
keir@829 642
keir@829 643 static void usbbk_set_address(usbif_t *usbif, struct usbstub *stub, int cur_addr, int new_addr)
keir@829 644 {
keir@829 645 unsigned long flags;
keir@829 646
keir@829 647 spin_lock_irqsave(&usbif->addr_lock, flags);
keir@829 648 if (cur_addr)
keir@829 649 usbif->addr_table[cur_addr] = NULL;
keir@829 650 if (new_addr)
keir@829 651 usbif->addr_table[new_addr] = stub;
keir@829 652 stub->addr = new_addr;
keir@829 653 spin_unlock_irqrestore(&usbif->addr_lock, flags);
keir@829 654 }
keir@829 655
keir@829 656 struct usbstub *find_attached_device(usbif_t *usbif, int portnum)
keir@829 657 {
keir@829 658 struct usbstub *stub;
keir@829 659 int found = 0;
keir@829 660 unsigned long flags;
keir@829 661
keir@829 662 spin_lock_irqsave(&usbif->plug_lock, flags);
keir@829 663 list_for_each_entry(stub, &usbif->plugged_devices, plugged_list) {
keir@829 664 if (stub->id->portnum == portnum) {
keir@829 665 found = 1;
keir@829 666 break;
keir@829 667 }
keir@829 668 }
keir@829 669 spin_unlock_irqrestore(&usbif->plug_lock, flags);
keir@829 670
keir@829 671 if (found)
keir@829 672 return stub;
keir@829 673
keir@829 674 return NULL;
keir@829 675 }
keir@829 676
keir@829 677 static int check_and_submit_special_ctrlreq(usbif_t *usbif, usbif_request_t *req, pending_req_t *pending_req)
keir@829 678 {
keir@829 679 int devnum;
keir@829 680 struct usbstub *stub = NULL;
keir@829 681 struct usb_ctrlrequest *ctrl = (struct usb_ctrlrequest *) req->u.ctrl;
keir@829 682 int ret;
keir@829 683 int done = 0;
keir@829 684
keir@829 685 devnum = usb_pipedevice(req->pipe);
keir@829 686
keir@829 687 /*
keir@829 688 * When the device is first connected or reseted, USB device has no address.
keir@829 689 * In this initial state, following requests are send to device address (#0),
keir@829 690 *
keir@829 691 * 1. GET_DESCRIPTOR (with Descriptor Type is "DEVICE") is send,
keir@829 692 * and OS knows what device is connected to.
keir@829 693 *
keir@829 694 * 2. SET_ADDRESS is send, and then, device has its address.
keir@829 695 *
keir@829 696 * In the next step, SET_CONFIGURATION is send to addressed device, and then,
keir@829 697 * the device is finally ready to use.
keir@829 698 */
keir@829 699 if (unlikely(devnum == 0)) {
keir@829 700 stub = find_attached_device(usbif, usbif_pipeportnum(req->pipe));
keir@829 701 if (unlikely(!stub)) {
keir@829 702 ret = -ENODEV;
keir@829 703 goto fail_response;
keir@829 704 }
keir@829 705
keir@829 706 switch (ctrl->bRequest) {
keir@829 707 case USB_REQ_GET_DESCRIPTOR:
keir@829 708 /*
keir@829 709 * GET_DESCRIPTOR request to device #0.
keir@829 710 * through to normal urb transfer.
keir@829 711 */
keir@829 712 pending_req->stub = stub;
keir@829 713 return 0;
keir@829 714 break;
keir@829 715 case USB_REQ_SET_ADDRESS:
keir@829 716 /*
keir@829 717 * SET_ADDRESS request to device #0.
keir@829 718 * add attached device to addr_table.
keir@829 719 */
keir@829 720 {
keir@829 721 __u16 addr = le16_to_cpu(ctrl->wValue);
keir@829 722 usbbk_set_address(usbif, stub, 0, addr);
keir@829 723 }
keir@829 724 ret = 0;
keir@829 725 goto fail_response;
keir@829 726 break;
keir@829 727 default:
keir@829 728 ret = -EINVAL;
keir@829 729 goto fail_response;
keir@829 730 }
keir@829 731 } else {
keir@829 732 if (unlikely(!usbif->addr_table[devnum])) {
keir@829 733 ret = -ENODEV;
keir@829 734 goto fail_response;
keir@829 735 }
keir@829 736 pending_req->stub = usbif->addr_table[devnum];
keir@829 737 }
keir@829 738
keir@829 739 /*
keir@829 740 * Check special request
keir@829 741 */
keir@829 742 switch (ctrl->bRequest) {
keir@829 743 case USB_REQ_SET_ADDRESS:
keir@829 744 /*
keir@829 745 * SET_ADDRESS request to addressed device.
keir@829 746 * change addr or remove from addr_table.
keir@829 747 */
keir@829 748 {
keir@829 749 __u16 addr = le16_to_cpu(ctrl->wValue);
keir@829 750 usbbk_set_address(usbif, stub, devnum, addr);
keir@829 751 }
keir@829 752 ret = 0;
keir@829 753 goto fail_response;
keir@829 754 break;
keir@829 755 #if 0
keir@829 756 case USB_REQ_SET_CONFIGURATION:
keir@829 757 /*
keir@829 758 * linux 2.6.27 or later version only!
keir@829 759 */
keir@829 760 if (ctrl->RequestType == USB_RECIP_DEVICE) {
keir@829 761 __u16 config = le16_to_cpu(ctrl->wValue);
keir@829 762 usb_driver_set_configuration(pending_req->stub->udev, config);
keir@829 763 done = 1;
keir@829 764 }
keir@829 765 break;
keir@829 766 #endif
keir@829 767 case USB_REQ_SET_INTERFACE:
keir@829 768 if (ctrl->bRequestType == USB_RECIP_INTERFACE) {
keir@829 769 __u16 alt = le16_to_cpu(ctrl->wValue);
keir@829 770 __u16 intf = le16_to_cpu(ctrl->wIndex);
keir@829 771 usbbk_set_interface(pending_req, intf, alt);
keir@829 772 done = 1;
keir@829 773 }
keir@829 774 break;
keir@829 775 case USB_REQ_CLEAR_FEATURE:
keir@829 776 if (ctrl->bRequestType == USB_RECIP_ENDPOINT
keir@829 777 && ctrl->wValue == USB_ENDPOINT_HALT) {
keir@829 778 int pipe;
keir@829 779 int ep = le16_to_cpu(ctrl->wIndex) & 0x0f;
keir@829 780 int dir = le16_to_cpu(ctrl->wIndex)
keir@829 781 & USB_DIR_IN;
keir@829 782 if (dir)
keir@829 783 pipe = usb_rcvctrlpipe(pending_req->stub->udev, ep);
keir@829 784 else
keir@829 785 pipe = usb_sndctrlpipe(pending_req->stub->udev, ep);
keir@829 786 usbbk_clear_halt(pending_req, pipe);
keir@829 787 done = 1;
keir@829 788 }
keir@829 789 break;
keir@829 790 #if 0 /* not tested yet */
keir@829 791 case USB_REQ_SET_FEATURE:
keir@829 792 if (ctrl->bRequestType == USB_RT_PORT) {
keir@829 793 __u16 feat = le16_to_cpu(ctrl->wValue);
keir@829 794 if (feat == USB_PORT_FEAT_RESET) {
keir@829 795 usbbk_port_reset(pending_req);
keir@829 796 done = 1;
keir@829 797 }
keir@829 798 }
keir@829 799 break;
keir@829 800 #endif
keir@829 801 default:
keir@829 802 break;
keir@829 803 }
keir@829 804
keir@829 805 return done;
keir@829 806
keir@829 807 fail_response:
keir@829 808 usbbk_do_response(pending_req, ret, 0, 0, 0);
keir@829 809 usbif_put(usbif);
keir@829 810 free_req(pending_req);
keir@829 811 return 1;
keir@829 812 }
keir@829 813
keir@829 814 static void dispatch_request_to_pending_reqs(usbif_t *usbif,
keir@829 815 usbif_request_t *req,
keir@829 816 pending_req_t *pending_req)
keir@829 817 {
keir@829 818 int ret;
keir@829 819
keir@829 820 pending_req->id = req->id;
keir@829 821 pending_req->usbif = usbif;
keir@829 822
keir@829 823 barrier();
keir@829 824
keir@829 825 /*
keir@829 826 * TODO:
keir@829 827 * receive unlink request and cancel the urb in backend
keir@829 828 */
keir@829 829 #if 0
keir@829 830 if (unlikely(usb_pipeunlink(req->pipe))) {
keir@829 831
keir@829 832 }
keir@829 833 #endif
keir@829 834
keir@829 835 usbif_get(usbif);
keir@829 836
keir@829 837 if (usb_pipecontrol(req->pipe)) {
keir@829 838 if (check_and_submit_special_ctrlreq(usbif, req, pending_req))
keir@829 839 return;
keir@829 840 } else {
keir@829 841 int devnum = usb_pipedevice(req->pipe);
keir@829 842 if (unlikely(!usbif->addr_table[devnum])) {
keir@829 843 ret = -ENODEV;
keir@829 844 goto fail_response;
keir@829 845 }
keir@829 846 pending_req->stub = usbif->addr_table[devnum];
keir@829 847 }
keir@829 848
keir@829 849 barrier();
keir@829 850
keir@829 851 ret = usbbk_alloc_urb(req, pending_req);
keir@829 852 if (ret) {
keir@829 853 ret = -ESHUTDOWN;
keir@829 854 goto fail_response;
keir@829 855 }
keir@829 856
keir@829 857 add_req_to_submitting_list(pending_req->stub, pending_req);
keir@829 858
keir@829 859 barrier();
keir@829 860
keir@829 861 usbbk_init_urb(req, pending_req);
keir@829 862
keir@829 863 barrier();
keir@829 864
keir@829 865 pending_req->nr_buffer_segs = req->nr_buffer_segs;
keir@829 866 if (usb_pipeisoc(req->pipe))
keir@829 867 pending_req->nr_extra_segs = req->u.isoc.nr_frame_desc_segs;
keir@829 868 else
keir@829 869 pending_req->nr_extra_segs = 0;
keir@829 870
keir@829 871 barrier();
keir@829 872
keir@829 873 ret = usbbk_gnttab_map(usbif, req, pending_req);
keir@829 874 if (ret) {
keir@829 875 printk(KERN_ERR "usbback: invalid buffer\n");
keir@829 876 ret = -ESHUTDOWN;
keir@829 877 goto fail_free_urb;
keir@829 878 }
keir@829 879
keir@829 880 barrier();
keir@829 881
keir@829 882 if (usb_pipeout(req->pipe) && req->buffer_length)
keir@829 883 copy_pages_to_buff(pending_req->buffer,
keir@829 884 pending_req,
keir@829 885 0,
keir@829 886 pending_req->nr_buffer_segs);
keir@829 887 if (usb_pipeisoc(req->pipe)) {
keir@829 888 copy_pages_to_buff(&pending_req->urb->iso_frame_desc[0],
keir@829 889 pending_req,
keir@829 890 pending_req->nr_buffer_segs,
keir@829 891 pending_req->nr_extra_segs);
keir@829 892 }
keir@829 893
keir@829 894 barrier();
keir@829 895
keir@829 896 ret = usb_submit_urb(pending_req->urb, GFP_KERNEL);
keir@829 897 if (ret) {
keir@829 898 printk(KERN_ERR "usbback: failed submitting urb, error %d\n", ret);
keir@829 899 ret = -ESHUTDOWN;
keir@829 900 goto fail_flush_area;
keir@829 901 }
keir@829 902 return;
keir@829 903
keir@829 904 fail_flush_area:
keir@829 905 fast_flush_area(pending_req);
keir@829 906 fail_free_urb:
keir@829 907 remove_req_from_submitting_list(pending_req->stub, pending_req);
keir@829 908 barrier();
keir@829 909 usbbk_free_urb(pending_req->urb);
keir@829 910 fail_response:
keir@829 911 usbbk_do_response(pending_req, ret, 0, 0, 0);
keir@829 912 usbif_put(usbif);
keir@829 913 free_req(pending_req);
keir@829 914 }
keir@829 915
keir@829 916 static int usbbk_start_submit_urb(usbif_t *usbif)
keir@829 917 {
keir@829 918 usbif_back_ring_t *usb_ring = &usbif->ring;
keir@829 919 usbif_request_t *ring_req;
keir@829 920 pending_req_t *pending_req;
keir@829 921 RING_IDX rc, rp;
keir@829 922 int more_to_do = 0;
keir@829 923
keir@829 924 rc = usb_ring->req_cons;
keir@829 925 rp = usb_ring->sring->req_prod;
keir@829 926 rmb();
keir@829 927
keir@829 928 while (rc != rp) {
keir@829 929 if (RING_REQUEST_CONS_OVERFLOW(usb_ring, rc)) {
keir@829 930 printk(KERN_WARNING "RING_REQUEST_CONS_OVERFLOW\n");
keir@829 931 break;
keir@829 932 }
keir@829 933
keir@829 934 pending_req = alloc_req();
keir@829 935 if (NULL == pending_req) {
keir@829 936 more_to_do = 1;
keir@829 937 break;
keir@829 938 }
keir@829 939
keir@829 940 ring_req = RING_GET_REQUEST(usb_ring, rc);
keir@829 941 usb_ring->req_cons = ++rc;
keir@829 942
keir@829 943 dispatch_request_to_pending_reqs(usbif, ring_req,
keir@829 944 pending_req);
keir@829 945 }
keir@829 946
keir@829 947 RING_FINAL_CHECK_FOR_REQUESTS(&usbif->ring, more_to_do);
keir@829 948
keir@829 949 cond_resched();
keir@829 950
keir@829 951 return more_to_do;
keir@829 952 }
keir@829 953
keir@829 954 int usbbk_schedule(void *arg)
keir@829 955 {
keir@829 956 usbif_t *usbif = (usbif_t *)arg;
keir@829 957
keir@829 958 usbif_get(usbif);
keir@829 959
keir@829 960 while(!kthread_should_stop()) {
keir@829 961 wait_event_interruptible(
keir@829 962 usbif->wq,
keir@829 963 usbif->waiting_reqs || kthread_should_stop());
keir@829 964 wait_event_interruptible(
keir@829 965 pending_free_wq,
keir@829 966 !list_empty(&pending_free) || kthread_should_stop());
keir@829 967 usbif->waiting_reqs = 0;
keir@829 968 smp_mb();
keir@829 969
keir@829 970 if (usbbk_start_submit_urb(usbif))
keir@829 971 usbif->waiting_reqs = 1;
keir@829 972 }
keir@829 973
keir@829 974 usbif->xenusbd = NULL;
keir@829 975 usbif_put(usbif);
keir@829 976
keir@829 977 return 0;
keir@829 978 }
keir@829 979
keir@829 980 /*
keir@829 981 * attach the grabbed device to usbif.
keir@829 982 */
keir@829 983 void usbbk_plug_device(usbif_t *usbif, struct usbstub *stub)
keir@829 984 {
keir@829 985 unsigned long flags;
keir@829 986
keir@829 987 spin_lock_irqsave(&usbif->plug_lock, flags);
keir@829 988 list_add(&stub->plugged_list, &usbif->plugged_devices);
keir@829 989 spin_unlock_irqrestore(&usbif->plug_lock, flags);
keir@829 990 stub->plugged = 1;
keir@829 991 stub->usbif = usbif;
keir@829 992 }
keir@829 993
keir@829 994 /*
keir@829 995 * detach the grabbed device from usbif.
keir@829 996 */
keir@829 997 void usbbk_unplug_device(usbif_t *usbif, struct usbstub *stub)
keir@829 998 {
keir@829 999 unsigned long flags;
keir@829 1000
keir@829 1001 if (stub->addr)
keir@829 1002 usbbk_set_address(usbif, stub, stub->addr, 0);
keir@829 1003 spin_lock_irqsave(&usbif->plug_lock, flags);
keir@829 1004 list_del(&stub->plugged_list);
keir@829 1005 spin_unlock_irqrestore(&usbif->plug_lock, flags);
keir@829 1006 stub->plugged = 0;
keir@829 1007 stub->usbif = NULL;
keir@829 1008 }
keir@829 1009
keir@829 1010 void detach_device_without_lock(usbif_t *usbif, struct usbstub *stub)
keir@829 1011 {
keir@829 1012 if (stub->addr)
keir@829 1013 usbbk_set_address(usbif, stub, stub->addr, 0);
keir@829 1014 list_del(&stub->plugged_list);
keir@829 1015 stub->plugged = 0;
keir@829 1016 stub->usbif = NULL;
keir@829 1017 }
keir@829 1018
keir@829 1019 static int __init usbback_init(void)
keir@829 1020 {
keir@829 1021 int i, mmap_pages;
keir@829 1022
keir@829 1023 if (!is_running_on_xen())
keir@829 1024 return -ENODEV;
keir@829 1025
keir@829 1026 if (usbstub_init())
keir@829 1027 return -ENODEV;
keir@829 1028
keir@829 1029 mmap_pages = usbif_reqs * USBIF_MAX_SEGMENTS_PER_REQUEST;
keir@829 1030 pending_reqs = kmalloc(sizeof(pending_reqs[0]) *
keir@829 1031 usbif_reqs, GFP_KERNEL);
keir@829 1032 pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
keir@829 1033 mmap_pages, GFP_KERNEL);
keir@829 1034 pending_pages = alloc_empty_pages_and_pagevec(mmap_pages);
keir@829 1035
keir@829 1036 if (!pending_reqs || !pending_grant_handles || !pending_pages)
keir@829 1037 goto out_of_memory;
keir@829 1038
keir@829 1039 for (i = 0; i < mmap_pages; i++)
keir@829 1040 pending_grant_handles[i] = USBBACK_INVALID_HANDLE;
keir@829 1041
keir@829 1042 memset(pending_reqs, 0, sizeof(pending_reqs));
keir@829 1043 INIT_LIST_HEAD(&pending_free);
keir@829 1044
keir@829 1045 for (i = 0; i < usbif_reqs; i++) {
keir@829 1046 list_add_tail(&pending_reqs[i].free_list, &pending_free);
keir@829 1047 }
keir@829 1048
keir@829 1049 usbback_xenbus_init();
keir@829 1050
keir@829 1051 return 0;
keir@829 1052
keir@829 1053 out_of_memory:
keir@829 1054 kfree(pending_reqs);
keir@829 1055 kfree(pending_grant_handles);
keir@829 1056 free_empty_pages_and_pagevec(pending_pages, mmap_pages);
keir@829 1057 printk("%s: out of memory\n", __FUNCTION__);
keir@829 1058 return -ENOMEM;
keir@829 1059 }
keir@829 1060
keir@829 1061 static void __exit usbback_exit(void)
keir@829 1062 {
keir@829 1063 usbback_xenbus_exit();
keir@829 1064 usbstub_exit();
keir@829 1065 kfree(pending_reqs);
keir@829 1066 kfree(pending_grant_handles);
keir@829 1067 free_empty_pages_and_pagevec(pending_pages, usbif_reqs * USBIF_MAX_SEGMENTS_PER_REQUEST);
keir@829 1068 }
keir@829 1069
keir@829 1070 module_init(usbback_init);
keir@829 1071 module_exit(usbback_exit);
keir@829 1072
keir@829 1073 MODULE_AUTHOR("");
keir@829 1074 MODULE_DESCRIPTION("Xen USB backend driver (usbback)");
keir@829 1075 MODULE_LICENSE("Dual BSD/GPL");