summaryrefslogtreecommitdiffstats
path: root/drivers/usb/class
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-04-20 11:32:26 +1000
committerDave Airlie <airlied@redhat.com>2015-04-20 13:05:20 +1000
commit2c33ce009ca2389dbf0535d0672214d09738e35e (patch)
tree6186a6458c3c160385d794a23eaf07c786a9e61b /drivers/usb/class
parentcec32a47010647e8b0603726ebb75b990a4057a4 (diff)
parent09d51602cf84a1264946711dd4ea0dddbac599a1 (diff)
downloadlinux-stable-2c33ce009ca2389dbf0535d0672214d09738e35e.tar.gz
linux-stable-2c33ce009ca2389dbf0535d0672214d09738e35e.tar.bz2
linux-stable-2c33ce009ca2389dbf0535d0672214d09738e35e.zip
Merge Linus master into drm-next
The merge is clean, but the arm build fails afterwards, due to API changes in the regulator tree. I've included the patch into the merge to fix the build. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/usb/class')
-rw-r--r--drivers/usb/class/cdc-acm.c21
-rw-r--r--drivers/usb/class/cdc-wdm.c47
2 files changed, 40 insertions, 28 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 683617714e7c..3e15add665e2 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -360,7 +360,7 @@ static void acm_ctrl_irq(struct urb *urb)
}
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
+ if (retval && retval != -EPERM)
dev_err(&acm->control->dev, "%s - usb_submit_urb failed: %d\n",
__func__, retval);
}
@@ -417,25 +417,33 @@ static void acm_read_bulk_callback(struct urb *urb)
struct acm_rb *rb = urb->context;
struct acm *acm = rb->instance;
unsigned long flags;
+ int status = urb->status;
dev_vdbg(&acm->data->dev, "%s - urb %d, len %d\n", __func__,
rb->index, urb->actual_length);
- set_bit(rb->index, &acm->read_urbs_free);
if (!acm->dev) {
+ set_bit(rb->index, &acm->read_urbs_free);
dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__);
return;
}
- if (urb->status) {
+ if (status) {
+ set_bit(rb->index, &acm->read_urbs_free);
dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n",
- __func__, urb->status);
+ __func__, status);
return;
}
usb_mark_last_busy(acm->dev);
acm_process_read_urb(acm, urb);
+ /*
+ * Unthrottle may run on another CPU which needs to see events
+ * in the same order. Submission has an implict barrier
+ */
+ smp_mb__before_atomic();
+ set_bit(rb->index, &acm->read_urbs_free);
/* throttle device if requested by tty */
spin_lock_irqsave(&acm->read_lock, flags);
@@ -454,13 +462,14 @@ static void acm_write_bulk(struct urb *urb)
struct acm_wb *wb = urb->context;
struct acm *acm = wb->instance;
unsigned long flags;
+ int status = urb->status;
- if (urb->status || (urb->actual_length != urb->transfer_buffer_length))
+ if (status || (urb->actual_length != urb->transfer_buffer_length))
dev_vdbg(&acm->data->dev, "%s - len %d/%d, status %d\n",
__func__,
urb->actual_length,
urb->transfer_buffer_length,
- urb->status);
+ status);
spin_lock_irqsave(&acm->write_lock, flags);
acm_write_done(acm, wb);
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index a051a7a2b1bd..61ea87917433 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -245,7 +245,7 @@ static void wdm_int_callback(struct urb *urb)
case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
dev_dbg(&desc->intf->dev,
"NOTIFY_RESPONSE_AVAILABLE received: index %d len %d",
- dr->wIndex, dr->wLength);
+ le16_to_cpu(dr->wIndex), le16_to_cpu(dr->wLength));
break;
case USB_CDC_NOTIFY_NETWORK_CONNECTION:
@@ -262,7 +262,9 @@ static void wdm_int_callback(struct urb *urb)
clear_bit(WDM_POLL_RUNNING, &desc->flags);
dev_err(&desc->intf->dev,
"unknown notification %d received: index %d len %d\n",
- dr->bNotificationType, dr->wIndex, dr->wLength);
+ dr->bNotificationType,
+ le16_to_cpu(dr->wIndex),
+ le16_to_cpu(dr->wLength));
goto exit;
}
@@ -339,7 +341,7 @@ static ssize_t wdm_write
desc->werr = 0;
spin_unlock_irq(&desc->iuspin);
if (we < 0)
- return -EIO;
+ return usb_translate_errors(we);
buf = kmalloc(count, GFP_KERNEL);
if (!buf) {
@@ -349,30 +351,25 @@ static ssize_t wdm_write
r = copy_from_user(buf, buffer, count);
if (r > 0) {
- kfree(buf);
rv = -EFAULT;
- goto outnl;
+ goto out_free_mem;
}
/* concurrent writes and disconnect */
r = mutex_lock_interruptible(&desc->wlock);
rv = -ERESTARTSYS;
- if (r) {
- kfree(buf);
- goto outnl;
- }
+ if (r)
+ goto out_free_mem;
if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
- kfree(buf);
rv = -ENODEV;
- goto outnp;
+ goto out_free_mem_lock;
}
r = usb_autopm_get_interface(desc->intf);
if (r < 0) {
- kfree(buf);
rv = usb_translate_errors(r);
- goto outnp;
+ goto out_free_mem_lock;
}
if (!(file->f_flags & O_NONBLOCK))
@@ -386,9 +383,8 @@ static ssize_t wdm_write
r = -EIO;
if (r < 0) {
- kfree(buf);
rv = r;
- goto out;
+ goto out_free_mem_pm;
}
req = desc->orq;
@@ -408,28 +404,35 @@ static ssize_t wdm_write
USB_RECIP_INTERFACE);
req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
req->wValue = 0;
- req->wIndex = desc->inum;
+ req->wIndex = desc->inum; /* already converted */
req->wLength = cpu_to_le16(count);
set_bit(WDM_IN_USE, &desc->flags);
desc->outbuf = buf;
rv = usb_submit_urb(desc->command, GFP_KERNEL);
if (rv < 0) {
- kfree(buf);
desc->outbuf = NULL;
clear_bit(WDM_IN_USE, &desc->flags);
dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
rv = usb_translate_errors(rv);
+ goto out_free_mem_pm;
} else {
dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
- req->wIndex);
+ le16_to_cpu(req->wIndex));
}
-out:
+
usb_autopm_put_interface(desc->intf);
-outnp:
mutex_unlock(&desc->wlock);
outnl:
return rv < 0 ? rv : count;
+
+out_free_mem_pm:
+ usb_autopm_put_interface(desc->intf);
+out_free_mem_lock:
+ mutex_unlock(&desc->wlock);
+out_free_mem:
+ kfree(buf);
+ return rv;
}
/*
@@ -519,9 +522,9 @@ retry:
spin_lock_irq(&desc->iuspin);
if (desc->rerr) { /* read completed, error happened */
+ rv = usb_translate_errors(desc->rerr);
desc->rerr = 0;
spin_unlock_irq(&desc->iuspin);
- rv = -EIO;
goto err;
}
/*
@@ -820,7 +823,7 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
desc->irq->wValue = 0;
- desc->irq->wIndex = desc->inum;
+ desc->irq->wIndex = desc->inum; /* already converted */
desc->irq->wLength = cpu_to_le16(desc->wMaxCommand);
usb_fill_control_urb(