Skip to content

Commit 84f9e53

Browse files
author
Filip Jagodzinski
committed
Tests: USB: Fix 'endpoint halt' test
Abort all endpoint transfers before running the test again. Use an updated vendor request to explicitly restart device reads.
1 parent 15f9389 commit 84f9e53

File tree

3 files changed

+32
-66
lines changed

3 files changed

+32
-66
lines changed

TESTS/host_tests/pyusb_basic.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def get_interface(dev, interface, alternate=0):
5656
VENDOR_TEST_CTRL_OUT_STATUS_DELAY = 8
5757
VENDOR_TEST_CTRL_IN_SIZES = 9
5858
VENDOR_TEST_CTRL_OUT_SIZES = 10
59-
VENDOR_TEST_READ_START = 11
59+
VENDOR_TEST_RW_RESTART = 11
6060
VENDOR_TEST_ABORT_BUFF_CHECK = 12
6161
VENDOR_TEST_UNSUPPORTED_REQUEST = 32
6262

@@ -984,7 +984,7 @@ def random_size_loopback_ep_test(ep_out, ep_in, failure, error, seconds, log, mi
984984
time.sleep(0.01)
985985

986986

987-
def halt_ep_test(dev, ep_out, ep_in, ep_to_halt, log):
987+
def halt_ep_test(dev, ep_out, ep_in, log):
988988
"""OUT/IN endpoint halt test.
989989
990990
Verify that halting an endpoint at a random point of OUT or IN transfer
@@ -1003,6 +1003,8 @@ def halt_ep_test(dev, ep_out, ep_in, ep_to_halt, log):
10031003
except usb.core.USBError as err:
10041004
raise_unconditionally(lineno(), 'Unable to get endpoint status ({!r}).'.format(err))
10051005

1006+
ep_to_halt = random.choice([ep_out, ep_in])
1007+
10061008
def timer_handler():
10071009
"""Halt an endpoint using a USB control request."""
10081010
try:
@@ -1044,17 +1046,19 @@ def timer_handler():
10441046
finally:
10451047
# Always wait for the Timer thread created above.
10461048
delayed_halt.join()
1049+
ep_out.clear_halt()
1050+
ep_in.clear_halt()
10471051
raise_unconditionally(lineno(), 'Halting endpoint {0.bEndpointAddress:#04x}'
10481052
' during transmission did not raise USBError.'
10491053
.format(ep_to_halt))
10501054

10511055

1052-
def request_endpoint_read_start(dev, ep):
1056+
def request_endpoint_loops_restart(dev):
10531057
ctrl_kwargs = {
1054-
'bmRequestType': build_request_type(CTRL_OUT, CTRL_TYPE_VENDOR, CTRL_RECIPIENT_ENDPOINT),
1055-
'bRequest': VENDOR_TEST_READ_START,
1058+
'bmRequestType': build_request_type(CTRL_OUT, CTRL_TYPE_VENDOR, CTRL_RECIPIENT_DEVICE),
1059+
'bRequest': VENDOR_TEST_RW_RESTART,
10561060
'wValue': 0,
1057-
'wIndex': ep.bEndpointAddress}
1061+
'wIndex': 0}
10581062
dev.ctrl_transfer(**ctrl_kwargs)
10591063

10601064

@@ -1149,35 +1153,26 @@ def ep_test_halt(dev, log, verbose=False):
11491153

11501154
bulk_out, bulk_in = find_ep_pair(intf, usb.ENDPOINT_TYPE_BULK)
11511155
interrupt_out, interrupt_in = find_ep_pair(intf, usb.ENDPOINT_TYPE_INTERRUPT)
1152-
iso_out, iso_in = find_ep_pair(intf, usb.ENDPOINT_TYPE_ISOCHRONOUS)
11531156

11541157
if verbose:
11551158
log('\tbulk_out {0.bEndpointAddress:#04x}, {0.wMaxPacketSize:02} B'.format(bulk_out))
11561159
log('\tbulk_in {0.bEndpointAddress:#04x}, {0.wMaxPacketSize:02} B'.format(bulk_in))
11571160
log('\tinterrupt_out {0.bEndpointAddress:#04x}, {0.wMaxPacketSize:02} B'.format(interrupt_out))
11581161
log('\tinterrupt_in {0.bEndpointAddress:#04x}, {0.wMaxPacketSize:02} B'.format(interrupt_in))
1159-
log('\tiso_out {0.bEndpointAddress:#04x}, {0.wMaxPacketSize:02} B'.format(iso_out))
1160-
log('\tiso_in {0.bEndpointAddress:#04x}, {0.wMaxPacketSize:02} B'.format(iso_in))
11611162

11621163
if verbose:
11631164
log('Testing endpoint halt at a random point of bulk transmission.')
11641165
end_ts = time.time() + 1.0
11651166
while time.time() < end_ts:
1166-
halt_ep_test(dev, bulk_out, bulk_in, bulk_out, log)
1167-
bulk_out.clear_halt()
1168-
request_endpoint_read_start(dev, bulk_out)
1169-
halt_ep_test(dev, bulk_out, bulk_in, bulk_in, log)
1170-
bulk_in.clear_halt()
1167+
halt_ep_test(dev, bulk_out, bulk_in, log)
1168+
request_endpoint_loops_restart(dev)
11711169

11721170
if verbose:
11731171
log('Testing endpoint halt at a random point of interrupt transmission.')
11741172
end_ts = time.time() + 1.0
11751173
while time.time() < end_ts:
1176-
halt_ep_test(dev, interrupt_out, interrupt_in, interrupt_out, log)
1177-
interrupt_out.clear_halt()
1178-
request_endpoint_read_start(dev, interrupt_out)
1179-
halt_ep_test(dev, interrupt_out, interrupt_in, interrupt_in, log)
1180-
interrupt_in.clear_halt()
1174+
halt_ep_test(dev, interrupt_out, interrupt_in, log)
1175+
request_endpoint_loops_restart(dev)
11811176

11821177

11831178
def ep_test_parallel_transfers(dev, log, verbose=False):
@@ -1466,7 +1461,10 @@ def ep_test_data_toggle(dev, log, verbose=False):
14661461
# ClearFeature(ENDPOINT_HALT) request always results in the data toggle being reinitialized to DATA0.
14671462
# "
14681463
bulk_out.clear_halt()
1469-
# request_endpoint_read_start(dev, bulk_out)
1464+
# The ClearFeature(ENDPOINT_HALT) terminates a pending read operation on the device end.
1465+
# Use a custom vendor request to restart reading on the OUT endpoint.
1466+
# This does not impact the state of the data toggle bit.
1467+
request_endpoint_loops_restart(dev)
14701468

14711469
# 2.4 verify that host and USB device are still in sync with respect to data toggle
14721470
try:

TESTS/usb_device/basic/USBEndpointTester.cpp

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#define VENDOR_TEST_CTRL_OUT 2
3737
#define VENDOR_TEST_CTRL_IN_SIZES 9
3838
#define VENDOR_TEST_CTRL_OUT_SIZES 10
39-
#define VENDOR_TEST_READ_START 11
39+
#define VENDOR_TEST_RW_RESTART 11
4040
#define VENDOR_TEST_ABORT_BUFF_CHECK 12
4141

4242
#define EVENT_READY (1 << 0)
@@ -241,8 +241,8 @@ void USBEndpointTester::callback_request(const setup_packet_t *setup)
241241
data = ctrl_buf;
242242
size = setup->wValue;
243243
break;
244-
case VENDOR_TEST_READ_START:
245-
result = (_request_read_start(setup)) ? Success : Failure;
244+
case VENDOR_TEST_RW_RESTART:
245+
result = (_request_rw_restart(setup)) ? Success : Failure;
246246
break;
247247
case VENDOR_TEST_ABORT_BUFF_CHECK:
248248
result = Send;
@@ -254,54 +254,23 @@ void USBEndpointTester::callback_request(const setup_packet_t *setup)
254254
result = PassThrough;
255255
break;
256256
}
257-
} else if ((setup->bmRequestType.Type == STANDARD_TYPE) && (setup->bmRequestType.Recipient == ENDPOINT_RECIPIENT)) {
258-
if (setup->bRequest == CLEAR_FEATURE) {
259-
usb_ep_t ep = setup->wIndex;
260-
bool valid = false;
261-
uint32_t ep_index = 0;
262-
if (ep == _endpoints[EP_BULK_OUT]) {
263-
valid = true;
264-
ep_index = EP_BULK_OUT;
265-
} else if (ep == _endpoints[EP_INT_OUT]) {
266-
valid = true;
267-
ep_index = EP_INT_OUT;
268-
} else if (ep == _endpoints[EP_ISO_OUT]) {
269-
valid = true;
270-
ep_index = EP_ISO_OUT;
271-
}
272-
273-
if (valid) {
274-
// Restart reads when an OUT endpoint is unstalled
275-
result = Success;
276-
endpoint_unstall(ep);
277-
read_start(_endpoints[ep_index], _endpoint_buffs[ep_index], (*_endpoint_configs)[ep_index].max_packet);
278-
}
279-
}
280257
}
281258
complete_request(result, data, size);
282259
}
283260

284-
bool USBEndpointTester::_request_read_start(const setup_packet_t *setup)
261+
bool USBEndpointTester::_request_rw_restart(const setup_packet_t *setup)
285262
{
286263
assert_locked();
287-
if (setup->bmRequestType.Recipient != ENDPOINT_RECIPIENT) {
288-
return false;
289-
}
290-
size_t ep_index = NUM_ENDPOINTS;
264+
ep_config_t *epc = NULL;
291265
for (size_t i = 0; i < NUM_ENDPOINTS; i++) {
292-
if (_endpoints[i] == setup->wIndex) {
293-
ep_index = i;
294-
break;
266+
epc = &((*_endpoint_configs)[i]);
267+
endpoint_abort(_endpoints[i]);
268+
if (epc->dir_in == false) {
269+
// Wait for data on every OUT endpoint
270+
read_start(_endpoints[i], _endpoint_buffs[i], epc->max_packet);
295271
}
296272
}
297-
if (ep_index == NUM_ENDPOINTS) {
298-
return false;
299-
}
300-
if (_endpoint_buffs[ep_index] == NULL) {
301-
return false;
302-
}
303-
endpoint_abort(_endpoints[ep_index]);
304-
return read_start(_endpoints[ep_index], _endpoint_buffs[ep_index], (*_endpoint_configs)[ep_index].max_packet);
273+
return true;
305274
}
306275

307276
bool USBEndpointTester::_request_abort_buff_check(const setup_packet_t *setup)
@@ -424,9 +393,8 @@ void USBEndpointTester::_setup_non_zero_endpoints()
424393
if (epc->callback == NULL) {
425394
continue;
426395
}
427-
if (epc->dir_in == true) {
428-
// write_start(_endpoints[i], _endpoint_buffs[i], epc->max_packet);
429-
} else {
396+
if (epc->dir_in == false) {
397+
// Wait for data on every OUT endpoint
430398
read_start(_endpoints[i], _endpoint_buffs[i], epc->max_packet);
431399
}
432400
}

TESTS/usb_device/basic/USBEndpointTester.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class USBEndpointTester: public USBDevice {
103103

104104
private:
105105
const char *get_desc_string(const uint8_t *desc);
106-
bool _request_read_start(const setup_packet_t *setup);
106+
bool _request_rw_restart(const setup_packet_t *setup);
107107
bool _request_abort_buff_check(const setup_packet_t *setup);
108108
};
109109

0 commit comments

Comments
 (0)