Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / bluetooth / bfusb.c
index 81c216e..23f9621 100644 (file)
@@ -21,7 +21,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -47,6 +46,8 @@
 
 #define VERSION "1.1"
 
+static int ignore = 0;
+
 static struct usb_driver bfusb_driver;
 
 static struct usb_device_id bfusb_table[] = {
@@ -61,7 +62,7 @@ MODULE_DEVICE_TABLE(usb, bfusb_table);
 
 #define BFUSB_MAX_BLOCK_SIZE   256
 
-#define BFUSB_BLOCK_TIMEOUT    (HZ * 3)
+#define BFUSB_BLOCK_TIMEOUT    3000
 
 #define BFUSB_TX_PROCESS       1
 #define BFUSB_TX_WAKEUP                2
@@ -98,14 +99,6 @@ struct bfusb_scb {
 static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs);
 static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs);
 
-static inline void bfusb_wait_for_urb(struct urb *urb)
-{
-       while (atomic_read(&urb->count) > 1) {
-               current->state = TASK_UNINTERRUPTIBLE;
-               schedule_timeout((5 * HZ + 999) / 1000);
-       }
-}
-
 static struct urb *bfusb_get_completed(struct bfusb *bfusb)
 {
        struct sk_buff *skb;
@@ -131,8 +124,7 @@ static void bfusb_unlink_urbs(struct bfusb *bfusb)
 
        while ((skb = skb_dequeue(&bfusb->pending_q))) {
                urb = ((struct bfusb_scb *) skb->cb)->urb;
-               usb_unlink_urb(urb);
-               bfusb_wait_for_urb(urb);
+               usb_kill_urb(urb);
                skb_queue_tail(&bfusb->completed_q, skb);
        }
 
@@ -165,7 +157,7 @@ static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
        if (err) {
                BT_ERR("%s bulk tx submit failed urb %p err %d", 
                                        bfusb->hdev->name, urb, err);
-               skb_unlink(skb);
+               skb_unlink(skb, &bfusb->pending_q);
                usb_free_urb(urb);
        } else
                atomic_inc(&bfusb->pending_tx);
@@ -219,7 +211,7 @@ static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs)
 
        read_lock(&bfusb->lock);
 
-       skb_unlink(skb);
+       skb_unlink(skb, &bfusb->pending_q);
        skb_queue_tail(&bfusb->completed_q, skb);
 
        bfusb_tx_wakeup(bfusb);
@@ -260,7 +252,7 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
        if (err) {
                BT_ERR("%s bulk rx submit failed urb %p err %d",
                                        bfusb->hdev->name, urb, err);
-               skb_unlink(skb);
+               skb_unlink(skb, &bfusb->pending_q);
                kfree_skb(skb);
                usb_free_urb(urb);
        }
@@ -337,7 +329,7 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
                }
 
                skb->dev = (void *) bfusb->hdev;
-               skb->pkt_type = pkt_type;
+               bt_cb(skb)->pkt_type = pkt_type;
 
                bfusb->reassembly = skb;
        } else {
@@ -405,7 +397,7 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
                buf   += len;
        }
 
-       skb_unlink(skb);
+       skb_unlink(skb, &bfusb->pending_q);
        kfree_skb(skb);
 
        bfusb_rx_submit(bfusb, urb);
@@ -492,7 +484,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
        unsigned char buf[3];
        int sent = 0, size, count;
 
-       BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
+       BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
 
        if (!hdev) {
                BT_ERR("Frame for unknown HCI device (hdev=NULL)");
@@ -504,7 +496,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
 
        bfusb = (struct bfusb *) hdev->driver_data;
 
-       switch (skb->pkt_type) {
+       switch (bt_cb(skb)->pkt_type) {
        case HCI_COMMAND_PKT:
                hdev->stat.cmd_tx++;
                break;
@@ -517,7 +509,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
        };
 
        /* Prepend skb with frame type */
-       memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
+       memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
 
        count = skb->len;
 
@@ -589,11 +581,13 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int
        pipe = usb_sndctrlpipe(bfusb->udev, 0);
 
        if (usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
-                               0, 1, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT) < 0) {
+                               0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
                BT_ERR("Can't change to loading configuration");
                return -EBUSY;
        }
 
+       bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0;
+
        buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
        if (!buf) {
                BT_ERR("Can't allocate memory chunk for firmware");
@@ -628,11 +622,13 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int
        pipe = usb_sndctrlpipe(bfusb->udev, 0);
 
         if ((err = usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
-                               0, 2, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0) {
+                               0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
                BT_ERR("Can't change to running configuration");
                goto error;
        }
 
+       bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0;
+
        BT_INFO("BlueFRITZ! USB device ready");
 
        kfree(buf);
@@ -644,7 +640,7 @@ error:
        pipe = usb_sndctrlpipe(bfusb->udev, 0);
 
        usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
-                               0, 0, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+                               0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
 
        return err;
 }
@@ -660,12 +656,15 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        BT_DBG("intf %p id %p", intf, id);
 
+       if (ignore)
+               return -ENODEV;
+
        /* Check number of endpoints */
-       if (intf->altsetting[0].desc.bNumEndpoints < 2)
+       if (intf->cur_altsetting->desc.bNumEndpoints < 2)
                return -EIO;
 
-       bulk_out_ep = &intf->altsetting[0].endpoint[0];
-       bulk_in_ep  = &intf->altsetting[0].endpoint[1];
+       bulk_out_ep = &intf->cur_altsetting->endpoint[0];
+       bulk_in_ep  = &intf->cur_altsetting->endpoint[1];
 
        if (!bulk_out_ep || !bulk_in_ep) {
                BT_ERR("Bulk endpoints not found");
@@ -673,19 +672,17 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        }
 
        /* Initialize control structure and load firmware */
-       if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
+       if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) {
                BT_ERR("Can't allocate memory for control structure");
                goto done;
        }
 
-       memset(bfusb, 0, sizeof(struct bfusb));
-
        bfusb->udev = udev;
        bfusb->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
        bfusb->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
-       bfusb->bulk_pkt_size = bulk_out_ep->desc.wMaxPacketSize;
+       bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
 
-       bfusb->lock = RW_LOCK_UNLOCKED;
+       rwlock_init(&bfusb->lock);
 
        bfusb->reassembly = NULL;
 
@@ -770,7 +767,6 @@ static void bfusb_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver bfusb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "bfusb",
        .probe          = bfusb_probe,
        .disconnect     = bfusb_disconnect,
@@ -797,6 +793,9 @@ static void __exit bfusb_exit(void)
 module_init(bfusb_init);
 module_exit(bfusb_exit);
 
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
+
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
 MODULE_VERSION(VERSION);