Skip to content

Commit 18fc4eb

Browse files
deepa-hubgregkh
authored andcommitted
usb: misc: usbtest: Remove timeval usage
timeval is deprecated and not y2038 safe. Its size also changes according to 32 bit/ 64 bit compilation. Replace it with 32 and 64 bit versions of its individual fields, giving two ioctls with different code values. The two ioctls are necessary to maintain the 32 bit and 64 bit userspace compatibility with a 64/32 bit kernel. Change unsigned to __u32 types for a definitive userspace interface. This is in accordance with the psABI that the unsigned type is always 32 bits. Also use motonic timer instead of real time to ensure positive delta values. Refactor usbtest_ioctl for readability to isolate the handling of the testing timing measurement. The official testusb userspace tool can be changed in a separate patch to reflect the __u32 changes as well. It can use the usbtest_param_32 struct, since 32 bit seconds is long enough for test durations. Signed-off-by: Deepa Dinamani <[email protected]> Reviewed-by: Arnd Bergmann <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ec4dca8 commit 18fc4eb

File tree

1 file changed

+147
-82
lines changed

1 file changed

+147
-82
lines changed

drivers/usb/misc/usbtest.c

Lines changed: 147 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,42 @@ static void complicated_callback(struct urb *urb);
2222
/*-------------------------------------------------------------------------*/
2323

2424
/* FIXME make these public somewhere; usbdevfs.h? */
25-
struct usbtest_param {
25+
26+
/* Parameter for usbtest driver. */
27+
struct usbtest_param_32 {
2628
/* inputs */
27-
unsigned test_num; /* 0..(TEST_CASES-1) */
28-
unsigned iterations;
29-
unsigned length;
30-
unsigned vary;
31-
unsigned sglen;
29+
__u32 test_num; /* 0..(TEST_CASES-1) */
30+
__u32 iterations;
31+
__u32 length;
32+
__u32 vary;
33+
__u32 sglen;
3234

3335
/* outputs */
34-
struct timeval duration;
36+
__s32 duration_sec;
37+
__s32 duration_usec;
3538
};
36-
#define USBTEST_REQUEST _IOWR('U', 100, struct usbtest_param)
39+
40+
/*
41+
* Compat parameter to the usbtest driver.
42+
* This supports older user space binaries compiled with 64 bit compiler.
43+
*/
44+
struct usbtest_param_64 {
45+
/* inputs */
46+
__u32 test_num; /* 0..(TEST_CASES-1) */
47+
__u32 iterations;
48+
__u32 length;
49+
__u32 vary;
50+
__u32 sglen;
51+
52+
/* outputs */
53+
__s64 duration_sec;
54+
__s64 duration_usec;
55+
};
56+
57+
/* IOCTL interface to the driver. */
58+
#define USBTEST_REQUEST_32 _IOWR('U', 100, struct usbtest_param_32)
59+
/* COMPAT IOCTL interface to the driver. */
60+
#define USBTEST_REQUEST_64 _IOWR('U', 100, struct usbtest_param_64)
3761

3862
/*-------------------------------------------------------------------------*/
3963

@@ -1030,7 +1054,7 @@ struct ctrl_ctx {
10301054
unsigned pending;
10311055
int status;
10321056
struct urb **urb;
1033-
struct usbtest_param *param;
1057+
struct usbtest_param_32 *param;
10341058
int last;
10351059
};
10361060

@@ -1155,7 +1179,7 @@ static void ctrl_complete(struct urb *urb)
11551179
}
11561180

11571181
static int
1158-
test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
1182+
test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param)
11591183
{
11601184
struct usb_device *udev = testdev_to_usbdev(dev);
11611185
struct urb **urb;
@@ -1930,7 +1954,7 @@ static struct urb *iso_alloc_urb(
19301954
}
19311955

19321956
static int
1933-
test_queue(struct usbtest_dev *dev, struct usbtest_param *param,
1957+
test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param,
19341958
int pipe, struct usb_endpoint_descriptor *desc, unsigned offset)
19351959
{
19361960
struct transfer_context context;
@@ -2049,81 +2073,20 @@ static int test_unaligned_bulk(
20492073
return retval;
20502074
}
20512075

2052-
/*-------------------------------------------------------------------------*/
2053-
2054-
/* We only have this one interface to user space, through usbfs.
2055-
* User mode code can scan usbfs to find N different devices (maybe on
2056-
* different busses) to use when testing, and allocate one thread per
2057-
* test. So discovery is simplified, and we have no device naming issues.
2058-
*
2059-
* Don't use these only as stress/load tests. Use them along with with
2060-
* other USB bus activity: plugging, unplugging, mousing, mp3 playback,
2061-
* video capture, and so on. Run different tests at different times, in
2062-
* different sequences. Nothing here should interact with other devices,
2063-
* except indirectly by consuming USB bandwidth and CPU resources for test
2064-
* threads and request completion. But the only way to know that for sure
2065-
* is to test when HC queues are in use by many devices.
2066-
*
2067-
* WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(),
2068-
* it locks out usbcore in certain code paths. Notably, if you disconnect
2069-
* the device-under-test, hub_wq will wait block forever waiting for the
2070-
* ioctl to complete ... so that usb_disconnect() can abort the pending
2071-
* urbs and then call usbtest_disconnect(). To abort a test, you're best
2072-
* off just killing the userspace task and waiting for it to exit.
2073-
*/
2074-
2076+
/* Run tests. */
20752077
static int
2076-
usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2078+
usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param)
20772079
{
20782080
struct usbtest_dev *dev = usb_get_intfdata(intf);
20792081
struct usb_device *udev = testdev_to_usbdev(dev);
2080-
struct usbtest_param *param = buf;
2081-
int retval = -EOPNOTSUPP;
20822082
struct urb *urb;
20832083
struct scatterlist *sg;
20842084
struct usb_sg_request req;
2085-
struct timeval start;
20862085
unsigned i;
2087-
2088-
/* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */
2089-
2090-
pattern = mod_pattern;
2091-
2092-
if (code != USBTEST_REQUEST)
2093-
return -EOPNOTSUPP;
2086+
int retval = -EOPNOTSUPP;
20942087

20952088
if (param->iterations <= 0)
20962089
return -EINVAL;
2097-
2098-
if (param->sglen > MAX_SGLEN)
2099-
return -EINVAL;
2100-
2101-
if (mutex_lock_interruptible(&dev->lock))
2102-
return -ERESTARTSYS;
2103-
2104-
/* FIXME: What if a system sleep starts while a test is running? */
2105-
2106-
/* some devices, like ez-usb default devices, need a non-default
2107-
* altsetting to have any active endpoints. some tests change
2108-
* altsettings; force a default so most tests don't need to check.
2109-
*/
2110-
if (dev->info->alt >= 0) {
2111-
int res;
2112-
2113-
if (intf->altsetting->desc.bInterfaceNumber) {
2114-
mutex_unlock(&dev->lock);
2115-
return -ENODEV;
2116-
}
2117-
res = set_altsetting(dev, dev->info->alt);
2118-
if (res) {
2119-
dev_err(&intf->dev,
2120-
"set altsetting to %d failed, %d\n",
2121-
dev->info->alt, res);
2122-
mutex_unlock(&dev->lock);
2123-
return res;
2124-
}
2125-
}
2126-
21272090
/*
21282091
* Just a bunch of test cases that every HCD is expected to handle.
21292092
*
@@ -2133,7 +2096,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
21332096
* FIXME add more tests! cancel requests, verify the data, control
21342097
* queueing, concurrent read+write threads, and so on.
21352098
*/
2136-
do_gettimeofday(&start);
21372099
switch (param->test_num) {
21382100

21392101
case 0:
@@ -2548,13 +2510,116 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
25482510
dev->in_pipe, NULL, 0);
25492511
break;
25502512
}
2551-
do_gettimeofday(&param->duration);
2552-
param->duration.tv_sec -= start.tv_sec;
2553-
param->duration.tv_usec -= start.tv_usec;
2554-
if (param->duration.tv_usec < 0) {
2555-
param->duration.tv_usec += 1000 * 1000;
2556-
param->duration.tv_sec -= 1;
2513+
return retval;
2514+
}
2515+
2516+
/*-------------------------------------------------------------------------*/
2517+
2518+
/* We only have this one interface to user space, through usbfs.
2519+
* User mode code can scan usbfs to find N different devices (maybe on
2520+
* different busses) to use when testing, and allocate one thread per
2521+
* test. So discovery is simplified, and we have no device naming issues.
2522+
*
2523+
* Don't use these only as stress/load tests. Use them along with with
2524+
* other USB bus activity: plugging, unplugging, mousing, mp3 playback,
2525+
* video capture, and so on. Run different tests at different times, in
2526+
* different sequences. Nothing here should interact with other devices,
2527+
* except indirectly by consuming USB bandwidth and CPU resources for test
2528+
* threads and request completion. But the only way to know that for sure
2529+
* is to test when HC queues are in use by many devices.
2530+
*
2531+
* WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(),
2532+
* it locks out usbcore in certain code paths. Notably, if you disconnect
2533+
* the device-under-test, hub_wq will wait block forever waiting for the
2534+
* ioctl to complete ... so that usb_disconnect() can abort the pending
2535+
* urbs and then call usbtest_disconnect(). To abort a test, you're best
2536+
* off just killing the userspace task and waiting for it to exit.
2537+
*/
2538+
2539+
static int
2540+
usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2541+
{
2542+
2543+
struct usbtest_dev *dev = usb_get_intfdata(intf);
2544+
struct usbtest_param_64 *param_64 = buf;
2545+
struct usbtest_param_32 temp;
2546+
struct usbtest_param_32 *param_32 = buf;
2547+
struct timespec64 start;
2548+
struct timespec64 end;
2549+
struct timespec64 duration;
2550+
int retval = -EOPNOTSUPP;
2551+
2552+
/* FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is. */
2553+
2554+
pattern = mod_pattern;
2555+
2556+
if (mutex_lock_interruptible(&dev->lock))
2557+
return -ERESTARTSYS;
2558+
2559+
/* FIXME: What if a system sleep starts while a test is running? */
2560+
2561+
/* some devices, like ez-usb default devices, need a non-default
2562+
* altsetting to have any active endpoints. some tests change
2563+
* altsettings; force a default so most tests don't need to check.
2564+
*/
2565+
if (dev->info->alt >= 0) {
2566+
if (intf->altsetting->desc.bInterfaceNumber) {
2567+
retval = -ENODEV;
2568+
goto free_mutex;
2569+
}
2570+
retval = set_altsetting(dev, dev->info->alt);
2571+
if (retval) {
2572+
dev_err(&intf->dev,
2573+
"set altsetting to %d failed, %d\n",
2574+
dev->info->alt, retval);
2575+
goto free_mutex;
2576+
}
2577+
}
2578+
2579+
switch (code) {
2580+
case USBTEST_REQUEST_64:
2581+
temp.test_num = param_64->test_num;
2582+
temp.iterations = param_64->iterations;
2583+
temp.length = param_64->length;
2584+
temp.sglen = param_64->sglen;
2585+
temp.vary = param_64->vary;
2586+
param_32 = &temp;
2587+
break;
2588+
2589+
case USBTEST_REQUEST_32:
2590+
break;
2591+
2592+
default:
2593+
retval = -EOPNOTSUPP;
2594+
goto free_mutex;
2595+
}
2596+
2597+
ktime_get_ts64(&start);
2598+
2599+
retval = usbtest_do_ioctl(intf, param_32);
2600+
if (retval)
2601+
goto free_mutex;
2602+
2603+
ktime_get_ts64(&end);
2604+
2605+
duration = timespec64_sub(end, start);
2606+
2607+
temp.duration_sec = duration.tv_sec;
2608+
temp.duration_usec = duration.tv_nsec/NSEC_PER_USEC;
2609+
2610+
switch (code) {
2611+
case USBTEST_REQUEST_32:
2612+
param_32->duration_sec = temp.duration_sec;
2613+
param_32->duration_usec = temp.duration_usec;
2614+
break;
2615+
2616+
case USBTEST_REQUEST_64:
2617+
param_64->duration_sec = temp.duration_sec;
2618+
param_64->duration_usec = temp.duration_usec;
2619+
break;
25572620
}
2621+
2622+
free_mutex:
25582623
mutex_unlock(&dev->lock);
25592624
return retval;
25602625
}

0 commit comments

Comments
 (0)