@@ -290,6 +290,19 @@ def _callback_ep_test_abort(self, key, value, timestamp):
290
290
except (RuntimeError ) as exc :
291
291
self .report_error (exc )
292
292
293
+ def _callback_ep_test_data_toggle (self , key , value , timestamp ):
294
+ self .log ("Received serial %s" % (value ))
295
+
296
+ dev = self .find_device (value )
297
+ if (dev == None ):
298
+ return
299
+
300
+ try :
301
+ ep_test_data_toggle (dev , log = print )
302
+ self .report_success ()
303
+ except (RuntimeError ) as exc :
304
+ self .report_error (exc )
305
+
293
306
def _callback_reset_support (self , key , value , timestamp ):
294
307
status = "false" if sys .platform == "darwin" else "true"
295
308
self .log ("Reset supported: %s" % status )
@@ -345,6 +358,7 @@ def setup(self):
345
358
self .register_callback ('ep_test_parallel_transfers' , self ._callback_ep_test_parallel_transfers )
346
359
self .register_callback ('ep_test_parallel_transfers_ctrl' , self ._callback_ep_test_parallel_transfers_ctrl )
347
360
self .register_callback ('ep_test_abort' , self ._callback_ep_test_abort )
361
+ self .register_callback ('ep_test_data_toggle' , self ._callback_ep_test_data_toggle )
348
362
349
363
self .register_callback ('reset_support' , self ._callback_reset_support )
350
364
@@ -1354,6 +1368,106 @@ def ep_test_abort(dev, log, verbose=False):
1354
1368
NUM_PACKETS_UNTIL_ABORT * ep_out .wMaxPacketSize , payload_size ))
1355
1369
1356
1370
1371
+ def ep_test_data_toggle (dev , log , verbose = False ):
1372
+ """Test data toggle reset for bulk OUT/IN endpoint pairs.
1373
+
1374
+ Given a USB device
1375
+ When an interface is set
1376
+ Then the data toggle bits for all endpoints are reset to DATA0
1377
+ When clear feature is called for an endpoint that *IS NOT* stalled
1378
+ Then the data toggle is reset to DATA0 for that endpoint
1379
+ When clear halt is called for an endpoint that *IS* stalled
1380
+ Then the data toggle is reset to DATA0 for that endpoint
1381
+ """
1382
+ cfg = dev .get_active_configuration ()
1383
+ for intf in cfg :
1384
+ log ('interface {}, alt {} -- ' .format (intf .bInterfaceNumber , intf .bAlternateSetting ), end = '' )
1385
+ if intf .bAlternateSetting == 0 :
1386
+ log ('skipping the default AlternateSetting' )
1387
+ continue
1388
+ log ('running tests' )
1389
+
1390
+ if verbose :
1391
+ log ('Testing data toggle reset for bulk endpoint pair.' )
1392
+
1393
+ # 1.1 reset OUT and IN data toggle to DATA0
1394
+ intf .set_altsetting ()
1395
+ bulk_out , bulk_in = find_ep_pair (intf , usb .ENDPOINT_TYPE_BULK )
1396
+
1397
+ # 1.2 send and receive a single data packet,
1398
+ # so both OUT and IN endpoints switch to DATA1
1399
+ loopback_ep_test (bulk_out , bulk_in , bulk_out .wMaxPacketSize )
1400
+
1401
+ # 1.3 reset OUT and IN data toggle to DATA0
1402
+ # USB spec, section 9.1.1.5
1403
+ # "
1404
+ # Configuring a device or changing an alternate setting causes all of the status and
1405
+ # configuration values associated with endpoints in the affected interfaces to be set to their default values.
1406
+ # This includes setting the data toggle of any endpoint using data toggles to the value DATA0.
1407
+ # "
1408
+ intf .set_altsetting ()
1409
+ bulk_out , bulk_in = find_ep_pair (intf , usb .ENDPOINT_TYPE_BULK )
1410
+
1411
+ # 1.4 verify that host and USB device are still in sync with respect to data toggle
1412
+ try :
1413
+ loopback_ep_test (bulk_out , bulk_in , bulk_out .wMaxPacketSize )
1414
+ except usb .USBError as err :
1415
+ if verbose :
1416
+ log (USB_ERROR_FMT .format (err , bulk_out , bulk_in , bulk_out .wMaxPacketSize ))
1417
+ raise_unconditionally (lineno (), 'Data toggle not reset when setting interface.' )
1418
+
1419
+ # 2.1 reset OUT and IN data toggle to DATA0
1420
+ intf .set_altsetting ()
1421
+ bulk_out , bulk_in = find_ep_pair (intf , usb .ENDPOINT_TYPE_BULK )
1422
+
1423
+ # 2.2 send and receive a single data packet,
1424
+ # so both OUT and IN endpoints switch to DATA1
1425
+ loopback_ep_test (bulk_out , bulk_in , bulk_out .wMaxPacketSize )
1426
+
1427
+ # 2.3 reset OUT data toggle to DATA0
1428
+ # USB spec, section 9.4.5
1429
+ # "
1430
+ # For endpoints using data toggle, regardless of whether an endpoint has the Halt feature set, a
1431
+ # ClearFeature(ENDPOINT_HALT) request always results in the data toggle being reinitialized to DATA0.
1432
+ # "
1433
+ bulk_out .clear_halt ()
1434
+ # request_endpoint_read_start(dev, bulk_out)
1435
+
1436
+ # 2.4 verify that host and USB device are still in sync with respect to data toggle
1437
+ try :
1438
+ loopback_ep_test (bulk_out , bulk_in , bulk_out .wMaxPacketSize )
1439
+ except usb .USBError as err :
1440
+ if verbose :
1441
+ log (USB_ERROR_FMT .format (err , bulk_out , bulk_in , bulk_out .wMaxPacketSize ))
1442
+ raise_unconditionally (lineno (), 'Data toggle not reset when calling ClearFeature(ENDPOINT_HALT) '
1443
+ 'on an endpoint that has not been halted.' )
1444
+
1445
+ # 3.1 reset OUT and IN data toggle to DATA0
1446
+ intf .set_altsetting ()
1447
+ bulk_out , bulk_in = find_ep_pair (intf , usb .ENDPOINT_TYPE_BULK )
1448
+
1449
+ # 3.2 send and receive a single data packet,
1450
+ # so both OUT and IN endpoints switch to DATA1
1451
+ loopback_ep_test (bulk_out , bulk_in , bulk_out .wMaxPacketSize )
1452
+
1453
+ # 3.3 reset IN data toggle to DATA0
1454
+ # USB spec, section 9.4.5
1455
+ # "
1456
+ # For endpoints using data toggle, regardless of whether an endpoint has the Halt feature set, a
1457
+ # ClearFeature(ENDPOINT_HALT) request always results in the data toggle being reinitialized to DATA0.
1458
+ # "
1459
+ usb .control .set_feature (dev , FEATURE_ENDPOINT_HALT , bulk_in )
1460
+ bulk_in .clear_halt ()
1461
+
1462
+ # 3.4 verify that host and USB device are still in sync with respect to data toggle
1463
+ try :
1464
+ loopback_ep_test (bulk_out , bulk_in , bulk_out .wMaxPacketSize )
1465
+ except usb .USBError as err :
1466
+ if verbose :
1467
+ log (USB_ERROR_FMT .format (err , bulk_out , bulk_in , bulk_out .wMaxPacketSize ))
1468
+ raise_unconditionally (lineno (), 'Data toggle not reset when clearing endpoint halt.' )
1469
+
1470
+
1357
1471
def device_reset_test (log ):
1358
1472
"""
1359
1473
Test USB implementation against repeated reset
0 commit comments