diff options
Diffstat (limited to 'drivers/staging/gdm72xx/gdm_usb.c')
-rw-r--r-- | drivers/staging/gdm72xx/gdm_usb.c | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 39db582ab1a6..e0cb2ffb41be 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -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; } @@ -717,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, |