fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / usb / misc / legousbtower.c
index 06c4bfa..5dce797 100644 (file)
@@ -75,7 +75,6 @@
  *   - move reset into open to clean out spurious data
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -83,6 +82,7 @@
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 #include <linux/poll.h>
@@ -248,18 +248,18 @@ static loff_t tower_llseek        (struct file *file, loff_t off, int whence);
 
 static void tower_abort_transfers (struct lego_usb_tower *dev);
 static void tower_check_for_read_packet (struct lego_usb_tower *dev);
-static void tower_interrupt_in_callback (struct urb *urb, struct pt_regs *regs);
-static void tower_interrupt_out_callback (struct urb *urb, struct pt_regs *regs);
+static void tower_interrupt_in_callback (struct urb *urb);
+static void tower_interrupt_out_callback (struct urb *urb);
 
 static int  tower_probe        (struct usb_interface *interface, const struct usb_device_id *id);
 static void tower_disconnect   (struct usb_interface *interface);
 
 
 /* prevent races between open() and disconnect */
-static DECLARE_MUTEX (disconnect_sem);
+static DEFINE_MUTEX (disconnect_mutex);
 
 /* file operations needed when we register this driver */
-static struct file_operations tower_fops = {
+static const struct file_operations tower_fops = {
        .owner =        THIS_MODULE,
        .read  =        tower_read,
        .write =        tower_write,
@@ -271,19 +271,17 @@ static struct file_operations tower_fops = {
 
 /*
  * usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with devfs and the driver core
+ * and to have the device registered with the driver core
  */
 static struct usb_class_driver tower_class = {
-       .name =         "usb/legousbtower%d",
+       .name =         "legousbtower%d",
        .fops =         &tower_fops,
-       .mode =         S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
        .minor_base =   LEGO_USB_TOWER_MINOR_BASE,
 };
 
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver tower_driver = {
-       .owner =        THIS_MODULE,
        .name =         "legousbtower",
        .probe =        tower_probe,
        .disconnect =   tower_disconnect,
@@ -319,12 +317,8 @@ static inline void tower_delete (struct lego_usb_tower *dev)
        tower_abort_transfers (dev);
 
        /* free data structures */
-       if (dev->interrupt_in_urb != NULL) {
-               usb_free_urb (dev->interrupt_in_urb);
-       }
-       if (dev->interrupt_out_urb != NULL) {
-               usb_free_urb (dev->interrupt_out_urb);
-       }
+       usb_free_urb(dev->interrupt_in_urb);
+       usb_free_urb(dev->interrupt_out_urb);
        kfree (dev->read_buffer);
        kfree (dev->interrupt_in_buffer);
        kfree (dev->interrupt_out_buffer);
@@ -351,7 +345,7 @@ static int tower_open (struct inode *inode, struct file *file)
        nonseekable_open(inode, file);
        subminor = iminor(inode);
 
-       down (&disconnect_sem);
+       mutex_lock (&disconnect_mutex);
 
        interface = usb_find_interface (&tower_driver, subminor);
 
@@ -391,7 +385,7 @@ static int tower_open (struct inode *inode, struct file *file)
                                  0,
                                  &reset_reply,
                                  sizeof(reset_reply),
-                                 HZ);
+                                 1000);
        if (result < 0) {
                err("LEGO USB Tower reset control request failed");
                retval = result;
@@ -405,7 +399,7 @@ static int tower_open (struct inode *inode, struct file *file)
                          dev->udev,
                          usb_rcvintpipe(dev->udev, dev->interrupt_in_endpoint->bEndpointAddress),
                          dev->interrupt_in_buffer,
-                         dev->interrupt_in_endpoint->wMaxPacketSize,
+                         le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
                          tower_interrupt_in_callback,
                          dev,
                          dev->interrupt_in_interval);
@@ -429,7 +423,7 @@ unlock_exit:
        up (&dev->sem);
 
 unlock_disconnect_exit:
-       up (&disconnect_sem);
+       mutex_unlock (&disconnect_mutex);
 
        dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval);
 
@@ -504,15 +498,11 @@ static void tower_abort_transfers (struct lego_usb_tower *dev)
        if (dev->interrupt_in_running) {
                dev->interrupt_in_running = 0;
                mb();
-               if (dev->interrupt_in_urb != NULL && dev->udev) {
-                       usb_unlink_urb (dev->interrupt_in_urb);
-               }
-       }
-       if (dev->interrupt_out_busy) {
-               if (dev->interrupt_out_urb != NULL && dev->udev) {
-                       usb_unlink_urb (dev->interrupt_out_urb);
-               }
+               if (dev->udev)
+                       usb_kill_urb (dev->interrupt_in_urb);
        }
+       if (dev->interrupt_out_busy && dev->udev)
+               usb_kill_urb(dev->interrupt_out_urb);
 
 exit:
        dbg(2, "%s: leave", __FUNCTION__);
@@ -757,7 +747,7 @@ exit:
 /**
  *     tower_interrupt_in_callback
  */
-static void tower_interrupt_in_callback (struct urb *urb, struct pt_regs *regs)
+static void tower_interrupt_in_callback (struct urb *urb)
 {
        struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context;
        int retval;
@@ -813,7 +803,7 @@ exit:
 /**
  *     tower_interrupt_out_callback
  */
-static void tower_interrupt_out_callback (struct urb *urb, struct pt_regs *regs)
+static void tower_interrupt_out_callback (struct urb *urb)
 {
        struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context;
 
@@ -859,14 +849,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
                info ("udev is NULL.");
        }
 
-       /* See if the device offered us matches what we can accept */
-       if ((udev->descriptor.idVendor != LEGO_USB_TOWER_VENDOR_ID) ||
-           (udev->descriptor.idProduct != LEGO_USB_TOWER_PRODUCT_ID)) {
-               return -ENODEV;
-       }
-
-
-       /* allocate memory for our device state and intialize it */
+       /* allocate memory for our device state and initialize it */
 
        dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL);
 
@@ -907,14 +890,11 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
                endpoint = &iface_desc->endpoint[i].desc;
 
-               if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
-                   ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
-                       dev->interrupt_in_endpoint = endpoint;
-               }
-
-               if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
-                   ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
-                       dev->interrupt_out_endpoint = endpoint;
+               if (usb_endpoint_xfer_int(endpoint)) {
+                       if (usb_endpoint_dir_in(endpoint))
+                               dev->interrupt_in_endpoint = endpoint;
+                       else
+                               dev->interrupt_out_endpoint = endpoint;
                }
        }
        if(dev->interrupt_in_endpoint == NULL) {
@@ -931,7 +911,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
                err("Couldn't allocate read_buffer");
                goto error;
        }
-       dev->interrupt_in_buffer = kmalloc (dev->interrupt_in_endpoint->wMaxPacketSize, GFP_KERNEL);
+       dev->interrupt_in_buffer = kmalloc (le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), GFP_KERNEL);
        if (!dev->interrupt_in_buffer) {
                err("Couldn't allocate interrupt_in_buffer");
                goto error;
@@ -979,7 +959,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
                                  0,
                                  &get_version_reply,
                                  sizeof(get_version_reply),
-                                 HZ);
+                                 1000);
        if (result < 0) {
                err("LEGO USB Tower get version control request failed");
                retval = result;
@@ -1014,7 +994,7 @@ static void tower_disconnect (struct usb_interface *interface)
 
        dbg(2, "%s: enter", __FUNCTION__);
 
-       down (&disconnect_sem);
+       mutex_lock (&disconnect_mutex);
 
        dev = usb_get_intfdata (interface);
        usb_set_intfdata (interface, NULL);
@@ -1036,7 +1016,7 @@ static void tower_disconnect (struct usb_interface *interface)
                up (&dev->sem);
        }
 
-       up (&disconnect_sem);
+       mutex_unlock (&disconnect_mutex);
 
        info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE));