Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.15-rc8 849 lines 23 kB view raw
1/* 2 * Frontier Designs Alphatrack driver 3 * 4 * Copyright (C) 2007 Michael Taht (m@taht.net) 5 * 6 * Based on the usbled driver and ldusb drivers by 7 * 8 * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com) 9 * Copyright (C) 2005 Michael Hund <mhund@ld-didactic.de> 10 * 11 * The ldusb driver was, in turn, derived from Lego USB Tower driver 12 * Copyright (C) 2003 David Glance <advidgsf@sourceforge.net> 13 * 2001-2004 Juergen Stuber <starblue@users.sourceforge.net> 14 * 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License as 17 * published by the Free Software Foundation, version 2. 18 * 19 */ 20 21/** 22 * This driver uses a ring buffer for time critical reading of 23 * interrupt in reports and provides read and write methods for 24 * raw interrupt reports. 25 */ 26 27/* 28 * Note: this currently uses a dumb ringbuffer for reads and writes. 29 * A more optimal driver would cache and kill off outstanding urbs that are 30 * now invalid, and ignore ones that already were in the queue but valid 31 * as we only have 30 commands for the alphatrack. In particular this is 32 * key for getting lights to flash in time as otherwise many commands 33 * can be buffered up before the light change makes it to the interface. 34 */ 35 36#include <linux/kernel.h> 37#include <linux/errno.h> 38#include <linux/slab.h> 39#include <linux/module.h> 40#include <linux/kobject.h> 41#include <linux/mutex.h> 42 43#include <linux/uaccess.h> 44#include <linux/input.h> 45#include <linux/usb.h> 46#include <linux/poll.h> 47 48#include "alphatrack.h" 49 50#define VENDOR_ID 0x165b 51#define PRODUCT_ID 0xfad1 52 53#ifdef CONFIG_USB_DYNAMIC_MINORS 54#define USB_ALPHATRACK_MINOR_BASE 0 55#else 56/* FIXME 176 - is another driver's minor - apply for that */ 57#define USB_ALPHATRACK_MINOR_BASE 176 58#endif 59 60/* table of devices that work with this driver */ 61static const struct usb_device_id usb_alphatrack_table[] = { 62 {USB_DEVICE(VENDOR_ID, PRODUCT_ID)}, 63 {} /* Terminating entry */ 64}; 65 66MODULE_DEVICE_TABLE(usb, usb_alphatrack_table); 67MODULE_VERSION("0.41"); 68MODULE_AUTHOR("Mike Taht <m@taht.net>"); 69MODULE_DESCRIPTION("Alphatrack USB Driver"); 70MODULE_LICENSE("GPL"); 71MODULE_SUPPORTED_DEVICE("Frontier Designs Alphatrack Control Surface"); 72 73/* These aren't done yet */ 74 75#define SUPPRESS_EXTRA_ONLINE_EVENTS 0 76#define BUFFERED_WRITES 0 77#define SUPPRESS_EXTRA_OFFLINE_EVENTS 0 78#define COMPRESS_FADER_EVENTS 0 79 80#define BUFFERED_READS 1 81#define RING_BUFFER_SIZE 512 82#define WRITE_BUFFER_SIZE 34 83#define ALPHATRACK_USB_TIMEOUT 10 84#define OUTPUT_CMD_SIZE 8 85#define INPUT_CMD_SIZE 12 86#define ALPHATRACK_DEBUG 0 87 88static int debug = ALPHATRACK_DEBUG; 89 90/* Use our own dbg macro */ 91#define dbg_info(dev, format, arg...) do \ 92 { if (debug) dev_info(dev , format , ## arg); } while (0) 93 94#define alphatrack_ocmd_info(dev, cmd, format, arg...) 95 96#define alphatrack_icmd_info(dev, cmd, format, arg...) 97 98/* Module parameters */ 99 100module_param(debug, int, S_IRUGO | S_IWUSR); 101MODULE_PARM_DESC(debug, "Debug enabled or not"); 102 103/* 104 * All interrupt in transfers are collected in a ring buffer to 105 * avoid racing conditions and get better performance of the driver. 106 */ 107 108static int ring_buffer_size = RING_BUFFER_SIZE; 109 110module_param(ring_buffer_size, int, S_IRUGO); 111MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size"); 112 113/* The write_buffer can one day contain more than one interrupt out transfer.*/ 114 115static int write_buffer_size = WRITE_BUFFER_SIZE; 116module_param(write_buffer_size, int, S_IRUGO); 117MODULE_PARM_DESC(write_buffer_size, "Write buffer size"); 118 119/* 120 * Increase the interval for debugging purposes. 121 * or set to 1 to use the standard interval from the endpoint descriptors. 122 */ 123 124static int min_interrupt_in_interval = ALPHATRACK_USB_TIMEOUT; 125module_param(min_interrupt_in_interval, int, 0); 126MODULE_PARM_DESC(min_interrupt_in_interval, 127 "Minimum interrupt in interval in ms"); 128 129static int min_interrupt_out_interval = ALPHATRACK_USB_TIMEOUT; 130module_param(min_interrupt_out_interval, int, 0); 131MODULE_PARM_DESC(min_interrupt_out_interval, 132 "Minimum interrupt out interval in ms"); 133 134/* Structure to hold all of our device specific stuff */ 135 136struct usb_alphatrack { 137 struct mutex mtx; /* locks this structure */ 138 struct usb_interface *intf; /* save off the usb interface pointer */ 139 int open_count; /* number of times this port has been opened */ 140 141 /* make gcc happy */ 142 struct alphatrack_icmd (*ring_buffer)[RING_BUFFER_SIZE]; 143 struct alphatrack_ocmd (*write_buffer)[WRITE_BUFFER_SIZE]; 144 unsigned int ring_head; 145 unsigned int ring_tail; 146 147 wait_queue_head_t read_wait; 148 wait_queue_head_t write_wait; 149 150 unsigned char *interrupt_in_buffer; 151 unsigned char *oldi_buffer; 152 struct usb_endpoint_descriptor *interrupt_in_endpoint; 153 struct urb *interrupt_in_urb; 154 int interrupt_in_interval; 155 size_t interrupt_in_endpoint_size; 156 int interrupt_in_running; 157 int interrupt_in_done; 158 159 char *interrupt_out_buffer; 160 struct usb_endpoint_descriptor *interrupt_out_endpoint; 161 struct urb *interrupt_out_urb; 162 int interrupt_out_interval; 163 size_t interrupt_out_endpoint_size; 164 int interrupt_out_busy; 165 166 atomic_t writes_pending; 167 int event; /* alternate interface to events */ 168 int fader; /* 10 bits */ 169 int lights; /* 23 bits */ 170 unsigned char dump_state; /* 0 if disabled 1 if enabled */ 171 unsigned char enable; /* 0 if disabled 1 if enabled */ 172 unsigned char offline; /* if the device is out of range or asleep */ 173 unsigned char verbose; /* be verbose in error reporting */ 174 unsigned char last_cmd[OUTPUT_CMD_SIZE]; 175 unsigned char screen[32]; 176}; 177 178/* prevent races between open() and disconnect() */ 179static DEFINE_MUTEX(disconnect_mutex); 180 181/* forward declaration */ 182 183static struct usb_driver usb_alphatrack_driver; 184 185/** 186 * usb_alphatrack_abort_transfers 187 * aborts transfers and frees associated data structures 188 */ 189static void usb_alphatrack_abort_transfers(struct usb_alphatrack *dev) 190{ 191 /* shutdown transfer */ 192 if (dev->interrupt_in_running) { 193 dev->interrupt_in_running = 0; 194 if (dev->intf) 195 usb_kill_urb(dev->interrupt_in_urb); 196 } 197 if (dev->interrupt_out_busy) 198 if (dev->intf) 199 usb_kill_urb(dev->interrupt_out_urb); 200} 201 202/** usb_alphatrack_delete */ 203static void usb_alphatrack_delete(struct usb_alphatrack *dev) 204{ 205 usb_alphatrack_abort_transfers(dev); 206 usb_free_urb(dev->interrupt_in_urb); 207 usb_free_urb(dev->interrupt_out_urb); 208 kfree(dev->ring_buffer); 209 kfree(dev->interrupt_in_buffer); 210 kfree(dev->interrupt_out_buffer); 211 kfree(dev->oldi_buffer); 212 kfree(dev->write_buffer); 213 kfree(dev); 214} 215 216/** usb_alphatrack_interrupt_in_callback */ 217 218static void usb_alphatrack_interrupt_in_callback(struct urb *urb) 219{ 220 struct usb_alphatrack *dev = urb->context; 221 unsigned int next_ring_head; 222 int retval = -1; 223 224 if (urb->status) { 225 if (urb->status == -ENOENT || 226 urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) { 227 goto exit; 228 } else { 229 dbg_info(&dev->intf->dev, 230 "%s: nonzero status received: %d\n", __func__, 231 urb->status); 232 goto resubmit; /* maybe we can recover */ 233 } 234 } 235 236 if (urb->actual_length != INPUT_CMD_SIZE) { 237 dev_warn(&dev->intf->dev, 238 "Urb length was %d bytes!! Do something intelligent\n", 239 urb->actual_length); 240 } else { 241 alphatrack_ocmd_info(&dev->intf->dev, 242 &(*dev->ring_buffer)[dev->ring_tail].cmd, 243 "%s", "bla"); 244 if (memcmp 245 (dev->interrupt_in_buffer, dev->oldi_buffer, 246 INPUT_CMD_SIZE) == 0) { 247 goto resubmit; 248 } 249 memcpy(dev->oldi_buffer, dev->interrupt_in_buffer, 250 INPUT_CMD_SIZE); 251 252#if SUPPRESS_EXTRA_OFFLINE_EVENTS 253 if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) 254 goto resubmit; 255 if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { 256 dev->offline = 2; 257 goto resubmit; 258 } 259/* Always pass one offline event up the stack */ 260 if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) 261 dev->offline = 0; 262 if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) 263 dev->offline = 1; 264#endif 265 dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", 266 __func__, dev->ring_head, dev->ring_tail); 267 next_ring_head = (dev->ring_head + 1) % ring_buffer_size; 268 269 if (next_ring_head != dev->ring_tail) { 270 memcpy(&((*dev->ring_buffer)[dev->ring_head]), 271 dev->interrupt_in_buffer, urb->actual_length); 272 dev->ring_head = next_ring_head; 273 retval = 0; 274 memset(dev->interrupt_in_buffer, 0, urb->actual_length); 275 } else { 276 dev_warn(&dev->intf->dev, 277 "Ring buffer overflow, %d bytes dropped\n", 278 urb->actual_length); 279 memset(dev->interrupt_in_buffer, 0, urb->actual_length); 280 } 281 } 282 283resubmit: 284 /* resubmit if we're still running */ 285 if (dev->interrupt_in_running && dev->intf) { 286 retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); 287 if (retval) 288 dev_err(&dev->intf->dev, 289 "usb_submit_urb failed (%d)\n", retval); 290 } 291 292exit: 293 dev->interrupt_in_done = 1; 294 wake_up_interruptible(&dev->read_wait); 295} 296 297/** usb_alphatrack_interrupt_out_callback */ 298static void usb_alphatrack_interrupt_out_callback(struct urb *urb) 299{ 300 struct usb_alphatrack *dev = urb->context; 301 302 /* sync/async unlink faults aren't errors */ 303 if (urb->status && !(urb->status == -ENOENT || 304 urb->status == -ECONNRESET || 305 urb->status == -ESHUTDOWN)) 306 dbg_info(&dev->intf->dev, 307 "%s - nonzero write interrupt status received: %d\n", 308 __func__, urb->status); 309 atomic_dec(&dev->writes_pending); 310 dev->interrupt_out_busy = 0; 311 wake_up_interruptible(&dev->write_wait); 312} 313 314/** usb_alphatrack_open */ 315static int usb_alphatrack_open(struct inode *inode, struct file *file) 316{ 317 struct usb_alphatrack *dev; 318 int subminor; 319 int retval = 0; 320 struct usb_interface *interface; 321 322 nonseekable_open(inode, file); 323 subminor = iminor(inode); 324 325 mutex_lock(&disconnect_mutex); 326 327 interface = usb_find_interface(&usb_alphatrack_driver, subminor); 328 329 if (!interface) { 330 pr_err("%s - error, can't find device for minor %d\n", 331 __func__, subminor); 332 retval = -ENODEV; 333 goto unlock_disconnect_exit; 334 } 335 336 dev = usb_get_intfdata(interface); 337 338 if (!dev) { 339 retval = -ENODEV; 340 goto unlock_disconnect_exit; 341 } 342 343 /* lock this device */ 344 if (mutex_lock_interruptible(&dev->mtx)) { 345 retval = -ERESTARTSYS; 346 goto unlock_disconnect_exit; 347 } 348 349 /* allow opening only once */ 350 if (dev->open_count) { 351 retval = -EBUSY; 352 goto unlock_exit; 353 } 354 dev->open_count = 1; 355 356 /* initialize in direction */ 357 dev->ring_head = 0; 358 dev->ring_tail = 0; 359 usb_fill_int_urb(dev->interrupt_in_urb, 360 interface_to_usbdev(interface), 361 usb_rcvintpipe(interface_to_usbdev(interface), 362 dev->interrupt_in_endpoint-> 363 bEndpointAddress), 364 dev->interrupt_in_buffer, 365 dev->interrupt_in_endpoint_size, 366 usb_alphatrack_interrupt_in_callback, dev, 367 dev->interrupt_in_interval); 368 369 dev->interrupt_in_running = 1; 370 dev->interrupt_in_done = 0; 371 dev->enable = 1; 372 dev->offline = 0; 373 374 retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); 375 if (retval) { 376 dev_err(&interface->dev, 377 "Couldn't submit interrupt_in_urb %d\n", retval); 378 dev->interrupt_in_running = 0; 379 dev->open_count = 0; 380 goto unlock_exit; 381 } 382 383 /* save device in the file's private structure */ 384 file->private_data = dev; 385 386unlock_exit: 387 mutex_unlock(&dev->mtx); 388 389unlock_disconnect_exit: 390 mutex_unlock(&disconnect_mutex); 391 392 return retval; 393} 394 395/** usb_alphatrack_release */ 396static int usb_alphatrack_release(struct inode *inode, struct file *file) 397{ 398 struct usb_alphatrack *dev; 399 int retval = 0; 400 401 dev = file->private_data; 402 403 if (dev == NULL) { 404 retval = -ENODEV; 405 goto exit; 406 } 407 408 if (mutex_lock_interruptible(&dev->mtx)) { 409 retval = -ERESTARTSYS; 410 goto exit; 411 } 412 413 if (dev->open_count != 1) { 414 retval = -ENODEV; 415 goto unlock_exit; 416 } 417 418 if (dev->intf == NULL) { 419 /* the device was unplugged before the file was released */ 420 mutex_unlock(&dev->mtx); 421 /* unlock here as usb_alphatrack_delete frees dev */ 422 usb_alphatrack_delete(dev); 423 retval = -ENODEV; 424 goto exit; 425 } 426 427 /* wait until write transfer is finished */ 428 if (dev->interrupt_out_busy) 429 wait_event_interruptible_timeout(dev->write_wait, 430 !dev->interrupt_out_busy, 431 2 * HZ); 432 usb_alphatrack_abort_transfers(dev); 433 dev->open_count = 0; 434 435unlock_exit: 436 mutex_unlock(&dev->mtx); 437 438exit: 439 return retval; 440} 441 442/** usb_alphatrack_poll */ 443static unsigned int usb_alphatrack_poll(struct file *file, poll_table *wait) 444{ 445 struct usb_alphatrack *dev; 446 unsigned int mask = 0; 447 448 dev = file->private_data; 449 450 poll_wait(file, &dev->read_wait, wait); 451 poll_wait(file, &dev->write_wait, wait); 452 453 if (dev->ring_head != dev->ring_tail) 454 mask |= POLLIN | POLLRDNORM; 455 if (!dev->interrupt_out_busy) 456 mask |= POLLOUT | POLLWRNORM; 457 458 return mask; 459} 460 461/** usb_alphatrack_read */ 462static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, 463 size_t count, loff_t *ppos) 464{ 465 struct usb_alphatrack *dev; 466 int retval = 0; 467 468 int c = 0; 469 470 dev = file->private_data; 471 472 /* verify that we actually have some data to read */ 473 if (count == 0) 474 goto exit; 475 476 /* lock this object */ 477 if (mutex_lock_interruptible(&dev->mtx)) { 478 retval = -ERESTARTSYS; 479 goto exit; 480 } 481 482 /* verify that the device wasn't unplugged */ 483 if (dev->intf == NULL) { 484 retval = -ENODEV; 485 pr_err("%s: No device or device unplugged %d\n", 486 __func__, retval); 487 goto unlock_exit; 488 } 489 490 while (dev->ring_head == dev->ring_tail) { 491 if (file->f_flags & O_NONBLOCK) { 492 retval = -EAGAIN; 493 goto unlock_exit; 494 } 495 dev->interrupt_in_done = 0; 496 retval = 497 wait_event_interruptible(dev->read_wait, 498 dev->interrupt_in_done); 499 if (retval < 0) 500 goto unlock_exit; 501 } 502 503 alphatrack_ocmd_info(&dev->intf->dev, 504 &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s", 505 ": copying to userspace"); 506 507 c = 0; 508 while ((c < count) && (dev->ring_tail != dev->ring_head)) { 509 if (copy_to_user 510 (&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], 511 INPUT_CMD_SIZE)) { 512 retval = -EFAULT; 513 goto unlock_exit; 514 } 515 dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size; 516 c += INPUT_CMD_SIZE; 517 dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", 518 __func__, dev->ring_head, dev->ring_tail); 519 } 520 retval = c; 521 522unlock_exit: 523 /* unlock the device */ 524 mutex_unlock(&dev->mtx); 525 526exit: 527 return retval; 528} 529 530/** usb_alphatrack_write */ 531static ssize_t usb_alphatrack_write(struct file *file, 532 const char __user *buffer, size_t count, 533 loff_t *ppos) 534{ 535 struct usb_alphatrack *dev; 536 size_t bytes_to_write; 537 int retval = 0; 538 539 dev = file->private_data; 540 541 /* verify that we actually have some data to write */ 542 if (count == 0) 543 goto exit; 544 545 /* lock this object */ 546 if (mutex_lock_interruptible(&dev->mtx)) { 547 retval = -ERESTARTSYS; 548 goto exit; 549 } 550 551 /* verify that the device wasn't unplugged */ 552 if (dev->intf == NULL) { 553 retval = -ENODEV; 554 pr_err("%s: No device or device unplugged %d\n", 555 __func__, retval); 556 goto unlock_exit; 557 } 558 559 /* wait until previous transfer is finished */ 560 if (dev->interrupt_out_busy) { 561 if (file->f_flags & O_NONBLOCK) { 562 retval = -EAGAIN; 563 goto unlock_exit; 564 } 565 retval = 566 wait_event_interruptible(dev->write_wait, 567 !dev->interrupt_out_busy); 568 if (retval < 0) 569 goto unlock_exit; 570 } 571 572 /* write the data into interrupt_out_buffer from userspace */ 573 /* FIXME - if you write more than 12 bytes this breaks */ 574 bytes_to_write = 575 min(count, write_buffer_size * dev->interrupt_out_endpoint_size); 576 if (bytes_to_write < count) 577 dev_warn(&dev->intf->dev, 578 "Write buffer overflow, %zd bytes dropped\n", 579 count - bytes_to_write); 580 581 dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", 582 __func__, count, bytes_to_write); 583 584 if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { 585 retval = -EFAULT; 586 goto unlock_exit; 587 } 588 589 if (dev->interrupt_out_endpoint == NULL) { 590 dev_err(&dev->intf->dev, "Endpoint should not be null!\n"); 591 goto unlock_exit; 592 } 593 594 /* send off the urb */ 595 usb_fill_int_urb(dev->interrupt_out_urb, 596 interface_to_usbdev(dev->intf), 597 usb_sndintpipe(interface_to_usbdev(dev->intf), 598 dev->interrupt_out_endpoint-> 599 bEndpointAddress), 600 dev->interrupt_out_buffer, bytes_to_write, 601 usb_alphatrack_interrupt_out_callback, dev, 602 dev->interrupt_out_interval); 603 dev->interrupt_out_busy = 1; 604 atomic_inc(&dev->writes_pending); 605 wmb(); 606 607 retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); 608 if (retval) { 609 dev->interrupt_out_busy = 0; 610 dev_err(&dev->intf->dev, 611 "Couldn't submit interrupt_out_urb %d\n", retval); 612 atomic_dec(&dev->writes_pending); 613 goto unlock_exit; 614 } 615 retval = bytes_to_write; 616 617unlock_exit: 618 /* unlock the device */ 619 mutex_unlock(&dev->mtx); 620 621exit: 622 return retval; 623} 624 625/* file operations needed when we register this driver */ 626static const struct file_operations usb_alphatrack_fops = { 627 .owner = THIS_MODULE, 628 .read = usb_alphatrack_read, 629 .write = usb_alphatrack_write, 630 .open = usb_alphatrack_open, 631 .release = usb_alphatrack_release, 632 .poll = usb_alphatrack_poll, 633 .llseek = no_llseek, 634}; 635 636/* 637 * usb class driver info in order to get a minor number from the usb core, 638 * and to have the device registered with the driver core 639 */ 640 641static struct usb_class_driver usb_alphatrack_class = { 642 .name = "alphatrack%d", 643 .fops = &usb_alphatrack_fops, 644 .minor_base = USB_ALPHATRACK_MINOR_BASE, 645}; 646 647/** 648 * usb_alphatrack_probe 649 * 650 * Called by the usb core when a new device is connected that it thinks 651 * this driver might be interested in. 652 */ 653static int usb_alphatrack_probe(struct usb_interface *intf, 654 const struct usb_device_id *id) 655{ 656 struct usb_device *udev = interface_to_usbdev(intf); 657 struct usb_alphatrack *dev = NULL; 658 struct usb_host_interface *iface_desc; 659 struct usb_endpoint_descriptor *endpoint; 660 int i; 661 int true_size; 662 int retval = -ENOMEM; 663 664 /* allocate memory for our device state and initialize it */ 665 666 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 667 if (dev == NULL) 668 goto exit; 669 670 mutex_init(&dev->mtx); 671 dev->intf = intf; 672 init_waitqueue_head(&dev->read_wait); 673 init_waitqueue_head(&dev->write_wait); 674 675 iface_desc = intf->cur_altsetting; 676 677 /* set up the endpoint information */ 678 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 679 endpoint = &iface_desc->endpoint[i].desc; 680 681 if (usb_endpoint_is_int_in(endpoint)) 682 dev->interrupt_in_endpoint = endpoint; 683 684 if (usb_endpoint_is_int_out(endpoint)) 685 dev->interrupt_out_endpoint = endpoint; 686 } 687 if (dev->interrupt_in_endpoint == NULL) { 688 dev_err(&intf->dev, "Interrupt in endpoint not found\n"); 689 goto error; 690 } 691 if (dev->interrupt_out_endpoint == NULL) 692 dev_warn(&intf->dev, 693 "Interrupt out endpoint not found (using control endpoint instead)\n"); 694 695 dev->interrupt_in_endpoint_size = 696 le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize); 697 698 if (dev->interrupt_in_endpoint_size != 64) 699 dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n"); 700 701 if (ring_buffer_size == 0) 702 ring_buffer_size = RING_BUFFER_SIZE; 703 704 true_size = min(ring_buffer_size, RING_BUFFER_SIZE); 705 706 /* 707 * FIXME - there are more usb_alloc routines for dma correctness. 708 * Needed? 709 */ 710 dev->ring_buffer = kmalloc_array(true_size, 711 sizeof(struct alphatrack_icmd), 712 GFP_KERNEL); 713 if (!dev->ring_buffer) 714 goto error; 715 716 dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, 717 GFP_KERNEL); 718 if (!dev->interrupt_in_buffer) 719 goto error; 720 721 dev->oldi_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); 722 if (!dev->oldi_buffer) 723 goto error; 724 725 dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); 726 if (!dev->interrupt_in_urb) { 727 dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n"); 728 goto error; 729 } 730 731 dev->interrupt_out_endpoint_size = 732 dev->interrupt_out_endpoint ? le16_to_cpu(dev-> 733 interrupt_out_endpoint-> 734 wMaxPacketSize) : udev-> 735 descriptor.bMaxPacketSize0; 736 737 if (dev->interrupt_out_endpoint_size != 64) 738 dev_warn(&intf->dev, 739 "Interrupt out endpoint size is not 64!)\n"); 740 741 if (write_buffer_size == 0) 742 write_buffer_size = WRITE_BUFFER_SIZE; 743 true_size = min(write_buffer_size, WRITE_BUFFER_SIZE); 744 745 dev->interrupt_out_buffer = 746 kmalloc_array(true_size, 747 dev->interrupt_out_endpoint_size, 748 GFP_KERNEL); 749 if (!dev->interrupt_out_buffer) 750 goto error; 751 752 dev->write_buffer = kmalloc_array(true_size, 753 sizeof(struct alphatrack_ocmd), 754 GFP_KERNEL); 755 if (!dev->write_buffer) 756 goto error; 757 758 dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); 759 if (!dev->interrupt_out_urb) { 760 dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n"); 761 goto error; 762 } 763 dev->interrupt_in_interval = 764 min_interrupt_in_interval > 765 dev->interrupt_in_endpoint-> 766 bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint-> 767 bInterval; 768 if (dev->interrupt_out_endpoint) 769 dev->interrupt_out_interval = 770 min_interrupt_out_interval > 771 dev->interrupt_out_endpoint-> 772 bInterval ? min_interrupt_out_interval : dev-> 773 interrupt_out_endpoint->bInterval; 774 775 /* we can register the device now, as it is ready */ 776 usb_set_intfdata(intf, dev); 777 778 atomic_set(&dev->writes_pending, 0); 779 retval = usb_register_dev(intf, &usb_alphatrack_class); 780 if (retval) { 781 /* something prevented us from registering this driver */ 782 dev_err(&intf->dev, 783 "Not able to get a minor for this device.\n"); 784 usb_set_intfdata(intf, NULL); 785 goto error; 786 } 787 788 /* let the user know what node this device is now attached to */ 789 dev_info(&intf->dev, 790 "Alphatrack Device #%d now attached to major %d minor %d\n", 791 (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR, 792 intf->minor); 793 794exit: 795 return retval; 796 797error: 798 usb_alphatrack_delete(dev); 799 800 return retval; 801} 802 803/** 804 * usb_alphatrack_disconnect 805 * 806 * Called by the usb core when the device is removed from the system. 807 */ 808static void usb_alphatrack_disconnect(struct usb_interface *intf) 809{ 810 struct usb_alphatrack *dev; 811 int minor; 812 813 mutex_lock(&disconnect_mutex); 814 815 dev = usb_get_intfdata(intf); 816 usb_set_intfdata(intf, NULL); 817 818 mutex_lock(&dev->mtx); 819 820 minor = intf->minor; 821 822 /* give back our minor */ 823 usb_deregister_dev(intf, &usb_alphatrack_class); 824 825 /* if the device is not opened, then we clean up right now */ 826 if (!dev->open_count) { 827 mutex_unlock(&dev->mtx); 828 usb_alphatrack_delete(dev); 829 } else { 830 atomic_set(&dev->writes_pending, 0); 831 dev->intf = NULL; 832 mutex_unlock(&dev->mtx); 833 } 834 835 mutex_unlock(&disconnect_mutex); 836 837 dev_info(&intf->dev, "Alphatrack Surface #%d now disconnected\n", 838 (minor - USB_ALPHATRACK_MINOR_BASE)); 839} 840 841/* usb specific object needed to register this driver with the usb subsystem */ 842static struct usb_driver usb_alphatrack_driver = { 843 .name = "alphatrack", 844 .probe = usb_alphatrack_probe, 845 .disconnect = usb_alphatrack_disconnect, 846 .id_table = usb_alphatrack_table, 847}; 848 849module_usb_driver(usb_alphatrack_driver);