]> err.no Git - linux-2.6/blobdiff - drivers/net/wireless/zd1211rw/zd_usb.c
[PATCH] zd1211rw: Reset device in the probe call
[linux-2.6] / drivers / net / wireless / zd1211rw / zd_usb.c
index 3faaeb2b7c89c9843c71cc1b5d953ba872a0be3c..3ac308af24aecf737c9ad953f729061bfb098583 100644 (file)
@@ -47,11 +47,17 @@ static struct usb_device_id usb_ids[] = {
        { USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x0586, 0x3409), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x0b3b, 0x1630), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
        /* ZD1211B */
        { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
        { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
        { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
        { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
+       { USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B },
        /* "Driverless" devices that need ejecting */
        { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
        {}
@@ -366,15 +372,6 @@ error:
        return r;
 }
 
-static void disable_read_regs_int(struct zd_usb *usb)
-{
-       struct zd_usb_interrupt *intr = &usb->intr;
-
-       spin_lock(&intr->lock);
-       intr->read_regs_enabled = 0;
-       spin_unlock(&intr->lock);
-}
-
 #define urb_dev(urb) (&(urb)->dev->dev)
 
 static inline void handle_regs_int(struct urb *urb)
@@ -596,16 +593,18 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
                unsigned int l, k, n;
                for (i = 0, l = 0;; i++) {
                        k = le16_to_cpu(get_unaligned(&length_info->length[i]));
+                       if (k == 0)
+                               return;
                        n = l+k;
                        if (n > length)
                                return;
-                       zd_mac_rx(mac, buffer+l, k);
+                       zd_mac_rx_irq(mac, buffer+l, k);
                        if (i >= 2)
                                return;
                        l = (n+3) & ~3;
                }
        } else {
-               zd_mac_rx(mac, buffer, length);
+               zd_mac_rx_irq(mac, buffer, length);
        }
 }
 
@@ -1028,6 +1027,8 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
                goto error;
        }
 
+       usb_reset_device(interface_to_usbdev(intf));
+
        netdev = zd_netdev_alloc(intf);
        if (netdev == NULL) {
                r = -ENOMEM;
@@ -1119,27 +1120,29 @@ static int __init usb_init(void)
 {
        int r;
 
-       pr_debug("usb_init()\n");
+       pr_debug("%s usb_init()\n", driver.name);
 
        zd_workqueue = create_singlethread_workqueue(driver.name);
        if (zd_workqueue == NULL) {
-               printk(KERN_ERR "%s: couldn't create workqueue\n", driver.name);
+               printk(KERN_ERR "%s couldn't create workqueue\n", driver.name);
                return -ENOMEM;
        }
 
        r = usb_register(&driver);
        if (r) {
-               printk(KERN_ERR "usb_register() failed. Error number %d\n", r);
+               destroy_workqueue(zd_workqueue);
+               printk(KERN_ERR "%s usb_register() failed. Error number %d\n",
+                      driver.name, r);
                return r;
        }
 
-       pr_debug("zd1211rw initialized\n");
+       pr_debug("%s initialized\n", driver.name);
        return 0;
 }
 
 static void __exit usb_exit(void)
 {
-       pr_debug("usb_exit()\n");
+       pr_debug("%s usb_exit()\n", driver.name);
        usb_deregister(&driver);
        destroy_workqueue(zd_workqueue);
 }
@@ -1156,10 +1159,19 @@ static void prepare_read_regs_int(struct zd_usb *usb)
 {
        struct zd_usb_interrupt *intr = &usb->intr;
 
-       spin_lock(&intr->lock);
+       spin_lock_irq(&intr->lock);
        intr->read_regs_enabled = 1;
        INIT_COMPLETION(intr->read_regs.completion);
-       spin_unlock(&intr->lock);
+       spin_unlock_irq(&intr->lock);
+}
+
+static void disable_read_regs_int(struct zd_usb *usb)
+{
+       struct zd_usb_interrupt *intr = &usb->intr;
+
+       spin_lock_irq(&intr->lock);
+       intr->read_regs_enabled = 0;
+       spin_unlock_irq(&intr->lock);
 }
 
 static int get_results(struct zd_usb *usb, u16 *values,
@@ -1171,7 +1183,7 @@ static int get_results(struct zd_usb *usb, u16 *values,
        struct read_regs_int *rr = &intr->read_regs;
        struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer;
 
-       spin_lock(&intr->lock);
+       spin_lock_irq(&intr->lock);
 
        r = -EIO;
        /* The created block size seems to be larger than expected.
@@ -1204,7 +1216,7 @@ static int get_results(struct zd_usb *usb, u16 *values,
 
        r = 0;
 error_unlock:
-       spin_unlock(&intr->lock);
+       spin_unlock_irq(&intr->lock);
        return r;
 }