]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge 4.12-rc2 into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 07:00:23 +0000 (09:00 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 07:00:23 +0000 (09:00 +0200)
We want the USB fixes in here as well to handle testing and merge
issues.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/class/cdc-wdm.c
drivers/usb/core/hcd.c
drivers/usb/gadget/udc/core.c
drivers/usb/host/ehci-sched.c
drivers/usb/misc/iowarrior.c
drivers/usb/storage/ene_ub6250.c
drivers/usb/typec/typec.c
include/linux/usb/typec.h

index 08669fee6d7f646c4a52816a9d240c441edd21bf..8f972247b1c1ac4d41faebe390a4c9ac9a308960 100644 (file)
@@ -361,17 +361,9 @@ static ssize_t wdm_write
        if (we < 0)
                return usb_translate_errors(we);
 
-       buf = kmalloc(count, GFP_KERNEL);
-       if (!buf) {
-               rv = -ENOMEM;
-               goto outnl;
-       }
-
-       r = copy_from_user(buf, buffer, count);
-       if (r > 0) {
-               rv = -EFAULT;
-               goto out_free_mem;
-       }
+       buf = memdup_user(buffer, count);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        /* concurrent writes and disconnect */
        r = mutex_lock_interruptible(&desc->wlock);
@@ -441,8 +433,7 @@ static ssize_t wdm_write
 
        usb_autopm_put_interface(desc->intf);
        mutex_unlock(&desc->wlock);
-outnl:
-       return rv < 0 ? rv : count;
+       return count;
 
 out_free_mem_pm:
        usb_autopm_put_interface(desc->intf);
index 5dea98358c05c46b09f913fee8b7c48d9f2c4f85..e72cbc75161919622e517c2d74d9deb04ef43367 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
+#include <linux/sched/task_stack.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/utsname.h>
@@ -1523,6 +1524,14 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
                if (hcd->self.uses_pio_for_control)
                        return ret;
                if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
+                       if (is_vmalloc_addr(urb->setup_packet)) {
+                               WARN_ONCE(1, "setup packet is not dma capable\n");
+                               return -EAGAIN;
+                       } else if (object_is_on_stack(urb->setup_packet)) {
+                               WARN_ONCE(1, "setup packet is on stack\n");
+                               return -EAGAIN;
+                       }
+
                        urb->setup_dma = dma_map_single(
                                        hcd->self.sysdev,
                                        urb->setup_packet,
@@ -1587,6 +1596,9 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
                        } else if (is_vmalloc_addr(urb->transfer_buffer)) {
                                WARN_ONCE(1, "transfer buffer not dma capable\n");
                                ret = -EAGAIN;
+                       } else if (object_is_on_stack(urb->transfer_buffer)) {
+                               WARN_ONCE(1, "transfer buffer is on stack\n");
+                               ret = -EAGAIN;
                        } else {
                                urb->transfer_dma = dma_map_single(
                                                hcd->self.sysdev,
index efce68e9a8e038557bdc36c8263bad03cef7e108..a03aec574f64a1375be3ccad9a8cc2a5dbe3913d 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/err.h>
 #include <linux/dma-mapping.h>
+#include <linux/sched/task_stack.h>
 #include <linux/workqueue.h>
 
 #include <linux/usb/ch9.h>
@@ -798,6 +799,14 @@ int usb_gadget_map_request_by_dev(struct device *dev,
 
                req->num_mapped_sgs = mapped;
        } else {
+               if (is_vmalloc_addr(req->buf)) {
+                       dev_err(dev, "buffer is not dma capable\n");
+                       return -EFAULT;
+               } else if (object_is_on_stack(req->buf)) {
+                       dev_err(dev, "buffer is on stack\n");
+                       return -EFAULT;
+               }
+
                req->dma = dma_map_single(dev, req->buf, req->length,
                                is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
index 980a6b3b2da20587ff8577f074a74f0db5901e05..6bc6304672bc2b1e83fe758ed9d74e10dc91f52d 100644 (file)
@@ -1105,7 +1105,7 @@ iso_stream_init(
                addr |= epnum << 8;
                addr |= dev->devnum;
                stream->ps.usecs = HS_USECS_ISO(maxp);
-               think_time = dev->tt ? dev->tt->think_time : 0;
+               think_time = dev->tt->think_time;
                stream->ps.tt_usecs = NS_TO_US(think_time + usb_calc_bus_time(
                                dev->speed, is_input, 1, maxp));
                hs_transfers = max(1u, (maxp + 187) / 188);
index 83b05a287b0c58f2b0b29f91fcddd0f307510b88..7ca4c7e0ea0ded0a651707546dc3eb04e71cc7bb 100644 (file)
@@ -368,14 +368,9 @@ static ssize_t iowarrior_write(struct file *file,
        case USB_DEVICE_ID_CODEMERCS_IOWPV2:
        case USB_DEVICE_ID_CODEMERCS_IOW40:
                /* IOW24 and IOW40 use a synchronous call */
-               buf = kmalloc(count, GFP_KERNEL);
-               if (!buf) {
-                       retval = -ENOMEM;
-                       goto exit;
-               }
-               if (copy_from_user(buf, user_buffer, count)) {
-                       retval = -EFAULT;
-                       kfree(buf);
+               buf = memdup_user(user_buffer, count);
+               if (IS_ERR(buf)) {
+                       retval = PTR_ERR(buf);
                        goto exit;
                }
                retval = usb_set_report(dev->interface, 2, 0, buf, count);
index 44af719194b239f760c77919bf7cf5bad19ed9d7..28100374f7bdec1e9f0f8eea1fb4923b32a97e62 100644 (file)
@@ -95,12 +95,12 @@ static struct us_unusual_dev ene_ub6250_unusual_dev_list[] = {
 #define REG_HW_TRAP1        0xFF89
 
 /* SRB Status */
-#define SS_SUCCESS                  0x00      /* No Sense */
-#define SS_NOT_READY                0x02
-#define SS_MEDIUM_ERR               0x03
-#define SS_HW_ERR                   0x04
-#define SS_ILLEGAL_REQUEST          0x05
-#define SS_UNIT_ATTENTION           0x06
+#define SS_SUCCESS             0x000000        /* No Sense */
+#define SS_NOT_READY           0x023A00        /* Medium not present */
+#define SS_MEDIUM_ERR          0x031100        /* Unrecovered read error */
+#define SS_HW_ERR              0x040800        /* Communication failure */
+#define SS_ILLEGAL_REQUEST     0x052000        /* Invalid command */
+#define SS_UNIT_ATTENTION      0x062900        /* Reset occurred */
 
 /* ENE Load FW Pattern */
 #define SD_INIT1_PATTERN   1
@@ -584,24 +584,26 @@ static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
-static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
+static int do_scsi_request_sense(struct us_data *us, struct scsi_cmnd *srb)
 {
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       unsigned char buf[18];
 
-       if (info->SD_Status.Insert && info->SD_Status.Ready)
-               return USB_STOR_TRANSPORT_GOOD;
-       else {
-               ene_sd_init(us);
-               return USB_STOR_TRANSPORT_GOOD;
-       }
+       memset(buf, 0, 18);
+       buf[0] = 0x70;                          /* Current error */
+       buf[2] = info->SrbStatus >> 16;         /* Sense key */
+       buf[7] = 10;                            /* Additional length */
+       buf[12] = info->SrbStatus >> 8;         /* ASC */
+       buf[13] = info->SrbStatus;              /* ASCQ */
 
+       usb_stor_set_xfer_buf(buf, sizeof(buf), srb);
        return USB_STOR_TRANSPORT_GOOD;
 }
 
-static int sd_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
+static int do_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
 {
        unsigned char data_ptr[36] = {
-               0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
+               0x00, 0x00, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
                0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
                0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20,
                0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30 };
@@ -610,6 +612,20 @@ static int sd_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
+static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
+{
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+
+       if (info->SD_Status.Insert && info->SD_Status.Ready)
+               return USB_STOR_TRANSPORT_GOOD;
+       else {
+               ene_sd_init(us);
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
 static int sd_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)
 {
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
@@ -1455,19 +1471,6 @@ static int ms_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
-static int ms_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
-{
-       /* pr_info("MS_SCSI_Inquiry\n"); */
-       unsigned char data_ptr[36] = {
-               0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
-               0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
-               0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20,
-               0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
-
-       usb_stor_set_xfer_buf(data_ptr, 36, srb);
-       return USB_STOR_TRANSPORT_GOOD;
-}
-
 static int ms_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)
 {
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
@@ -1940,6 +1943,8 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag)
        bcb->CDB[0] = 0xEF;
 
        result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0);
+       if (us->srb != NULL)
+               scsi_set_resid(us->srb, 0);
        info->BIN_FLAG = flag;
        kfree(buf);
 
@@ -2223,13 +2228,15 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
        int    result;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
 
-       info->SrbStatus = SS_SUCCESS;
        switch (srb->cmnd[0]) {
        case TEST_UNIT_READY:
                result = sd_scsi_test_unit_ready(us, srb);
                break; /* 0x00 */
+       case REQUEST_SENSE:
+               result = do_scsi_request_sense(us, srb);
+               break; /* 0x03 */
        case INQUIRY:
-               result = sd_scsi_inquiry(us, srb);
+               result = do_scsi_inquiry(us, srb);
                break; /* 0x12 */
        case MODE_SENSE:
                result = sd_scsi_mode_sense(us, srb);
@@ -2253,6 +2260,8 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
                result = USB_STOR_TRANSPORT_FAILED;
                break;
        }
+       if (result == USB_STOR_TRANSPORT_GOOD)
+               info->SrbStatus = SS_SUCCESS;
        return result;
 }
 
@@ -2263,13 +2272,16 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
 {
        int result;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
-       info->SrbStatus = SS_SUCCESS;
+
        switch (srb->cmnd[0]) {
        case TEST_UNIT_READY:
                result = ms_scsi_test_unit_ready(us, srb);
                break; /* 0x00 */
+       case REQUEST_SENSE:
+               result = do_scsi_request_sense(us, srb);
+               break; /* 0x03 */
        case INQUIRY:
-               result = ms_scsi_inquiry(us, srb);
+               result = do_scsi_inquiry(us, srb);
                break; /* 0x12 */
        case MODE_SENSE:
                result = ms_scsi_mode_sense(us, srb);
@@ -2288,26 +2300,29 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
                result = USB_STOR_TRANSPORT_FAILED;
                break;
        }
+       if (result == USB_STOR_TRANSPORT_GOOD)
+               info->SrbStatus = SS_SUCCESS;
        return result;
 }
 
 static int ene_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
-       int result = 0;
+       int result = USB_STOR_XFER_GOOD;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
 
        /*US_DEBUG(usb_stor_show_command(us, srb)); */
        scsi_set_resid(srb, 0);
-       if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) {
+       if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready)))
                result = ene_init(us);
-       } else {
+       if (result == USB_STOR_XFER_GOOD) {
+               result = USB_STOR_TRANSPORT_ERROR;
                if (info->SD_Status.Ready)
                        result = sd_scsi_irp(us, srb);
 
                if (info->MS_Status.Ready)
                        result = ms_scsi_irp(us, srb);
        }
-       return 0;
+       return result;
 }
 
 static struct scsi_host_template ene_ub6250_host_template;
index 89e540bb7ff3a688621223eb7a9fd4252f21404b..db5ee730ad24cfaefd8e5b089cec3b1ec10fc00f 100644 (file)
@@ -291,7 +291,7 @@ typec_altmode_roles_show(struct device *dev, struct device_attribute *attr,
 }
 
 static void typec_init_modes(struct typec_altmode *alt,
-                            struct typec_mode_desc *desc, bool is_port)
+                            const struct typec_mode_desc *desc, bool is_port)
 {
        int i;
 
@@ -378,7 +378,8 @@ static const struct device_type typec_altmode_dev_type = {
 };
 
 static struct typec_altmode *
-typec_register_altmode(struct device *parent, struct typec_altmode_desc *desc)
+typec_register_altmode(struct device *parent,
+                      const struct typec_altmode_desc *desc)
 {
        struct typec_altmode *alt;
        int ret;
@@ -495,7 +496,7 @@ EXPORT_SYMBOL_GPL(typec_partner_set_identity);
  */
 struct typec_altmode *
 typec_partner_register_altmode(struct typec_partner *partner,
-                              struct typec_altmode_desc *desc)
+                              const struct typec_altmode_desc *desc)
 {
        return typec_register_altmode(&partner->dev, desc);
 }
@@ -590,7 +591,7 @@ static const struct device_type typec_plug_dev_type = {
  */
 struct typec_altmode *
 typec_plug_register_altmode(struct typec_plug *plug,
-                           struct typec_altmode_desc *desc)
+                           const struct typec_altmode_desc *desc)
 {
        return typec_register_altmode(&plug->dev, desc);
 }
@@ -1159,7 +1160,7 @@ EXPORT_SYMBOL_GPL(typec_set_pwr_opmode);
  */
 struct typec_altmode *
 typec_port_register_altmode(struct typec_port *port,
-                           struct typec_altmode_desc *desc)
+                           const struct typec_altmode_desc *desc)
 {
        return typec_register_altmode(&port->dev, desc);
 }
index ec78204964ab806d1f807515e8976c385c661181..d1d2ebcf36ec13f19216d255b2ad837d59414234 100644 (file)
@@ -117,13 +117,13 @@ struct typec_altmode_desc {
 
 struct typec_altmode
 *typec_partner_register_altmode(struct typec_partner *partner,
-                               struct typec_altmode_desc *desc);
+                               const struct typec_altmode_desc *desc);
 struct typec_altmode
 *typec_plug_register_altmode(struct typec_plug *plug,
-                            struct typec_altmode_desc *desc);
+                            const struct typec_altmode_desc *desc);
 struct typec_altmode
 *typec_port_register_altmode(struct typec_port *port,
-                            struct typec_altmode_desc *desc);
+                            const struct typec_altmode_desc *desc);
 void typec_unregister_altmode(struct typec_altmode *altmode);
 
 struct typec_port *typec_altmode2port(struct typec_altmode *alt);