summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/class/cdc-wdm.c17
-rw-r--r--drivers/usb/core/hcd.c12
-rw-r--r--drivers/usb/gadget/udc/core.c9
-rw-r--r--drivers/usb/host/ehci-sched.c2
-rw-r--r--drivers/usb/misc/iowarrior.c11
-rw-r--r--drivers/usb/storage/ene_ub6250.c87
-rw-r--r--drivers/usb/typec/typec.c11
7 files changed, 86 insertions, 63 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 08669fee6d7f..8f972247b1c1 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -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);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5dea98358c05..e72cbc751619 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -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,
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index efce68e9a8e0..a03aec574f64 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -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);
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 980a6b3b2da2..6bc6304672bc 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -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);
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 83b05a287b0c..7ca4c7e0ea0d 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -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);
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
index 44af719194b2..28100374f7bd 100644
--- a/drivers/usb/storage/ene_ub6250.c
+++ b/drivers/usb/storage/ene_ub6250.c
@@ -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;
diff --git a/drivers/usb/typec/typec.c b/drivers/usb/typec/typec.c
index 89e540bb7ff3..db5ee730ad24 100644
--- a/drivers/usb/typec/typec.c
+++ b/drivers/usb/typec/typec.c
@@ -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);
}