usb: misc: ehset: update to use the usb_control_msg_{send|recv}() API

The newer usb_control_msg_{send|recv}() API ensures that a short read
is treated as an error, data can be used off the stack, and raw usb
pipes need not be created in the calling functions.
For this reason, instances of usb_control_msg() have been replaced with
usb_control_msg_{recv|send}() appropriately.

Now, we also test for a short device descriptor (which USB core
should already have fetched if you get to probe this driver), but which
wasn't verified again here before.

Reviewed-by: Peter Chen <peter.chen@nxp.com>
Reviewed-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Anant Thazhemadam <anant.thazhemadam@gmail.com>
Link: https://lore.kernel.org/r/20210326223251.753952-2-anant.thazhemadam@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Anant Thazhemadam 2021-03-27 04:02:49 +05:30 committed by Greg Kroah-Hartman
parent c21161e40e
commit f5ffdd3b75
1 changed files with 32 additions and 44 deletions

View File

@ -24,68 +24,57 @@ static int ehset_probe(struct usb_interface *intf,
int ret = -EINVAL;
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_device *hub_udev = dev->parent;
struct usb_device_descriptor *buf;
struct usb_device_descriptor buf;
u8 portnum = dev->portnum;
u16 test_pid = le16_to_cpu(dev->descriptor.idProduct);
switch (test_pid) {
case TEST_SE0_NAK_PID:
ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
USB_REQ_SET_FEATURE, USB_RT_PORT,
USB_PORT_FEAT_TEST,
(USB_TEST_SE0_NAK << 8) | portnum,
NULL, 0, 1000);
ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE,
USB_RT_PORT, USB_PORT_FEAT_TEST,
(USB_TEST_SE0_NAK << 8) | portnum,
NULL, 0, 1000, GFP_KERNEL);
break;
case TEST_J_PID:
ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
USB_REQ_SET_FEATURE, USB_RT_PORT,
USB_PORT_FEAT_TEST,
(USB_TEST_J << 8) | portnum,
NULL, 0, 1000);
ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE,
USB_RT_PORT, USB_PORT_FEAT_TEST,
(USB_TEST_J << 8) | portnum, NULL, 0,
1000, GFP_KERNEL);
break;
case TEST_K_PID:
ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
USB_REQ_SET_FEATURE, USB_RT_PORT,
USB_PORT_FEAT_TEST,
(USB_TEST_K << 8) | portnum,
NULL, 0, 1000);
ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE,
USB_RT_PORT, USB_PORT_FEAT_TEST,
(USB_TEST_K << 8) | portnum, NULL, 0,
1000, GFP_KERNEL);
break;
case TEST_PACKET_PID:
ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
USB_REQ_SET_FEATURE, USB_RT_PORT,
USB_PORT_FEAT_TEST,
(USB_TEST_PACKET << 8) | portnum,
NULL, 0, 1000);
ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE,
USB_RT_PORT, USB_PORT_FEAT_TEST,
(USB_TEST_PACKET << 8) | portnum,
NULL, 0, 1000, GFP_KERNEL);
break;
case TEST_HS_HOST_PORT_SUSPEND_RESUME:
/* Test: wait for 15secs -> suspend -> 15secs delay -> resume */
msleep(15 * 1000);
ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
USB_REQ_SET_FEATURE, USB_RT_PORT,
USB_PORT_FEAT_SUSPEND, portnum,
NULL, 0, 1000);
ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE,
USB_RT_PORT, USB_PORT_FEAT_SUSPEND,
portnum, NULL, 0, 1000, GFP_KERNEL);
if (ret < 0)
break;
msleep(15 * 1000);
ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
USB_REQ_CLEAR_FEATURE, USB_RT_PORT,
USB_PORT_FEAT_SUSPEND, portnum,
NULL, 0, 1000);
ret = usb_control_msg_send(hub_udev, 0, USB_REQ_CLEAR_FEATURE,
USB_RT_PORT, USB_PORT_FEAT_SUSPEND,
portnum, NULL, 0, 1000, GFP_KERNEL);
break;
case TEST_SINGLE_STEP_GET_DEV_DESC:
/* Test: wait for 15secs -> GetDescriptor request */
msleep(15 * 1000);
buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
USB_DT_DEVICE << 8, 0,
buf, USB_DT_DEVICE_SIZE,
USB_CTRL_GET_TIMEOUT);
kfree(buf);
ret = usb_control_msg_recv(dev, 0, USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN, USB_DT_DEVICE << 8, 0,
&buf, USB_DT_DEVICE_SIZE,
USB_CTRL_GET_TIMEOUT, GFP_KERNEL);
break;
case TEST_SINGLE_STEP_SET_FEATURE:
/*
@ -100,11 +89,10 @@ static int ehset_probe(struct usb_interface *intf,
break;
}
ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
USB_REQ_SET_FEATURE, USB_RT_PORT,
USB_PORT_FEAT_TEST,
(6 << 8) | portnum,
NULL, 0, 60 * 1000);
ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE,
USB_RT_PORT, USB_PORT_FEAT_TEST,
(6 << 8) | portnum, NULL, 0,
60 * 1000, GFP_KERNEL);
break;
default:
@ -112,7 +100,7 @@ static int ehset_probe(struct usb_interface *intf,
__func__, test_pid);
}
return (ret < 0) ? ret : 0;
return ret;
}
static void ehset_disconnect(struct usb_interface *intf)