Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[cascardo/linux.git] / drivers / staging / gdm72xx / gdm_usb.c
index 0c9e895..e0cb2ff 100644 (file)
@@ -186,6 +186,7 @@ static int init_usb(struct usbwm_dev *udev)
        struct rx_cxt   *rx = &udev->rx;
        struct usb_tx   *t;
        struct usb_rx   *r;
+       unsigned long flags;
 
        INIT_LIST_HEAD(&tx->free_list);
        INIT_LIST_HEAD(&tx->sdu_list);
@@ -200,14 +201,17 @@ static int init_usb(struct usbwm_dev *udev)
        spin_lock_init(&tx->lock);
        spin_lock_init(&rx->lock);
 
+       spin_lock_irqsave(&tx->lock, flags);
        for (i = 0; i < MAX_NR_SDU_BUF; i++) {
                t = alloc_tx_struct(tx);
                if (t == NULL) {
+                       spin_unlock_irqrestore(&tx->lock, flags);
                        ret = -ENOMEM;
                        goto fail;
                }
                list_add(&t->list, &tx->free_list);
        }
+       spin_unlock_irqrestore(&tx->lock, flags);
 
        r = alloc_rx_struct(rx);
        if (r == NULL) {
@@ -215,7 +219,9 @@ static int init_usb(struct usbwm_dev *udev)
                goto fail;
        }
 
+       spin_lock_irqsave(&rx->lock, flags);
        list_add(&r->list, &rx->free_list);
+       spin_unlock_irqrestore(&rx->lock, flags);
        return ret;
 
 fail:
@@ -229,6 +235,9 @@ static void release_usb(struct usbwm_dev *udev)
        struct rx_cxt   *rx = &udev->rx;
        struct usb_tx   *t, *t_next;
        struct usb_rx   *r, *r_next;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tx->lock, flags);
 
        list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) {
                list_del(&t->list);
@@ -245,6 +254,10 @@ static void release_usb(struct usbwm_dev *udev)
                free_tx_struct(t);
        }
 
+       spin_unlock_irqrestore(&tx->lock, flags);
+
+       spin_lock_irqsave(&rx->lock, flags);
+
        list_for_each_entry_safe(r, r_next, &rx->free_list, list) {
                list_del(&r->list);
                free_rx_struct(r);
@@ -254,6 +267,8 @@ static void release_usb(struct usbwm_dev *udev)
                list_del(&r->list);
                free_rx_struct(r);
        }
+
+       spin_unlock_irqrestore(&rx->lock, flags);
 }
 
 static void __gdm_usb_send_complete(struct urb *urb)
@@ -303,9 +318,12 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
        u8 *pkt = data;
        u16 cmd_evt;
        unsigned long flags;
+#ifdef CONFIG_WIMAX_GDM72XX_K_MODE
+       unsigned long flags2;
+#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */
 
        if (!udev->usbdev) {
-               printk(KERN_ERR "%s: No such device\n", __func__);
+               dev_err(&usbdev->dev, "%s: No such device\n", __func__);
                return -ENODEV;
        }
 
@@ -371,13 +389,16 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
 
                rx = &udev->rx;
 
+               spin_lock_irqsave(&rx->lock, flags2);
                list_for_each_entry(r, &rx->used_list, list)
                        usb_unlink_urb(r->urb);
+               spin_unlock_irqrestore(&rx->lock, flags2);
+
                udev->bw_switch = 1;
 
-               spin_lock(&k_lock);
+               spin_lock_irqsave(&k_lock, flags2);
                list_add_tail(&udev->list, &k_list);
-               spin_unlock(&k_lock);
+               spin_unlock_irqrestore(&k_lock, flags2);
 
                wake_up(&k_wait);
        }
@@ -416,7 +437,7 @@ static void gdm_usb_rcv_complete(struct urb *urb)
        struct tx_cxt *tx = &udev->tx;
        struct usb_tx *t;
        u16 cmd_evt;
-       unsigned long flags;
+       unsigned long flags, flags2;
 
 #ifdef CONFIG_WIMAX_GDM72XX_USB_PM
        struct usb_device *dev = urb->dev;
@@ -462,9 +483,9 @@ static void gdm_usb_rcv_complete(struct urb *urb)
        if (!urb->status && r->callback)
                r->callback(r->cb_data, r->buf, urb->actual_length);
 
-       spin_lock(&rx->lock);
+       spin_lock_irqsave(&rx->lock, flags2);
        put_rx_struct(rx, r);
-       spin_unlock(&rx->lock);
+       spin_unlock_irqrestore(&rx->lock, flags2);
 
        spin_unlock_irqrestore(&tx->lock, flags);
 
@@ -484,7 +505,7 @@ static int gdm_usb_receive(void *priv_dev,
        unsigned long flags;
 
        if (!udev->usbdev) {
-               printk(KERN_ERR "%s: No such device\n", __func__);
+               dev_err(&usbdev->dev, "%s: No such device\n", __func__);
                return -ENODEV;
        }
 
@@ -559,9 +580,9 @@ static int gdm_usb_probe(struct usb_interface *intf,
        idProduct = L2H(usbdev->descriptor.idProduct);
        bcdDevice = L2H(usbdev->descriptor.bcdDevice);
 
-       printk(KERN_INFO "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
-               idVendor, idProduct);
-       printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION);
+       dev_info(&intf->dev, "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
+                idVendor, idProduct);
+       dev_info(&intf->dev, "GCT WiMax driver version %s\n", DRIVER_VERSION);
 
 
        if (idProduct == EMERGENCY_PID) {
@@ -619,8 +640,9 @@ out:
        if (ret) {
                kfree(phy_dev);
                kfree(udev);
+       } else {
+               usb_set_intfdata(intf, phy_dev);
        }
-       usb_set_intfdata(intf, phy_dev);
        return ret;
 }
 
@@ -660,14 +682,22 @@ static int gdm_suspend(struct usb_interface *intf, pm_message_t pm_msg)
        struct usbwm_dev *udev;
        struct rx_cxt *rx;
        struct usb_rx *r;
+       unsigned long flags;
 
        phy_dev = usb_get_intfdata(intf);
+       if (!phy_dev)
+               return 0;
+
        udev = phy_dev->priv_dev;
        rx = &udev->rx;
 
+       spin_lock_irqsave(&rx->lock, flags);
+
        list_for_each_entry(r, &rx->used_list, list)
                usb_unlink_urb(r->urb);
 
+       spin_unlock_irqrestore(&rx->lock, flags);
+
        return 0;
 }
 
@@ -677,14 +707,22 @@ static int gdm_resume(struct usb_interface *intf)
        struct usbwm_dev *udev;
        struct rx_cxt *rx;
        struct usb_rx *r;
+       unsigned long flags;
 
        phy_dev = usb_get_intfdata(intf);
+       if (!phy_dev)
+               return 0;
+
        udev = phy_dev->priv_dev;
        rx = &udev->rx;
 
+       spin_lock_irqsave(&rx->lock, flags);
+
        list_for_each_entry(r, &rx->used_list, list)
                usb_submit_urb(r->urb, GFP_ATOMIC);
 
+       spin_unlock_irqrestore(&rx->lock, flags);
+
        return 0;
 }
 
@@ -701,8 +739,6 @@ static int k_mode_thread(void *arg)
        unsigned long flags, flags2, expire;
        int ret;
 
-       daemonize("k_mode_wimax");
-
        while (!k_mode_stop) {
 
                spin_lock_irqsave(&k_lock, flags2);
@@ -719,9 +755,13 @@ static int k_mode_thread(void *arg)
                        while (jiffies < expire)
                                schedule_timeout(K_WAIT_TIME);
 
+                       spin_lock_irqsave(&rx->lock, flags);
+
                        list_for_each_entry(r, &rx->used_list, list)
                                usb_submit_urb(r->urb, GFP_ATOMIC);
 
+                       spin_unlock_irqrestore(&rx->lock, flags);
+
                        spin_lock_irqsave(&tx->lock, flags);
 
                        list_for_each_entry_safe(t, temp, &tx->pending_list,
@@ -764,7 +804,7 @@ static struct usb_driver gdm_usb_driver = {
 static int __init usb_gdm_wimax_init(void)
 {
 #ifdef CONFIG_WIMAX_GDM72XX_K_MODE
-       kthread_run(k_mode_thread, NULL, "WiMax_thread");
+       kthread_run(k_mode_thread, NULL, "k_mode_wimax");
 #endif /* CONFIG_WIMAX_GDM72XX_K_MODE */
        return usb_register(&gdm_usb_driver);
 }