Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/thirdpin/libopencm3.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKarl Palsson <karlp@tweak.net.au>2018-05-03 02:20:44 +0300
committerKarl Palsson <karlp@tweak.net.au>2018-08-27 18:11:32 +0300
commit42e43515c682c58e968a134683d160b4a6a50206 (patch)
tree38981344f45d85e1eb23db00a43c3fc288fe98bb /tests
parentebcf1978106322e92a7b1f53b58a33c6ff432cbd (diff)
usb gadget0: ctrl write/read loopback tests
This is based on linux's gadget0 intel loopback tests, and also github pr: https://github.com/libopencm3/libopencm3/pull/592 Note that this captures the currently broken control loopback issues on dwc_otg devices. See https://github.com/libopencm3/libopencm3/issues/873 and all linked issues. Current status is passing on f3, f0, and failing on f4.
Diffstat (limited to 'tests')
-rw-r--r--tests/gadget-zero/test_gadget0.py38
-rw-r--r--tests/gadget-zero/usb-gadget0.c30
2 files changed, 65 insertions, 3 deletions
diff --git a/tests/gadget-zero/test_gadget0.py b/tests/gadget-zero/test_gadget0.py
index c27c10f7..064545f8 100644
--- a/tests/gadget-zero/test_gadget0.py
+++ b/tests/gadget-zero/test_gadget0.py
@@ -3,6 +3,7 @@ import datetime
import random
import usb.core
import usb.util as uu
+import random
import sys
import unittest
@@ -25,6 +26,8 @@ GZ_REQ_SET_ALIGNED=3
GZ_REQ_SET_UNALIGNED=4
GZ_REQ_WRITE_LOOPBACK_BUFFER=10
GZ_REQ_READ_LOOPBACK_BUFFER=11
+GZ_REQ_INTEL_WRITE=0x5b
+GZ_REQ_INTEL_READ=0x5c
class find_by_serial(object):
def __init__(self, serial):
@@ -83,6 +86,41 @@ class TestGadget0(unittest.TestCase):
# Note, this might not be as portable as we'd like.
self.assertIn("Pipe", e.strerror)
+class TestIntelCompliance(unittest.TestCase):
+ """
+ Part of intel's usb 2.0 compliance is writing and reading back control transfers
+ """
+ def setUp(self):
+ self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL))
+ self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device")
+
+ self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2)
+ self.assertIsNotNone(self.cfg, "Config 2 should exist")
+ self.dev.set_configuration(self.cfg)
+
+ def tearDown(self):
+ uu.dispose_resources(self.dev)
+
+ def inner_t(self, mylen):
+ data = [random.randrange(255) for x in range(mylen)]
+ written = self.dev.ctrl_transfer(uu.CTRL_OUT | uu.CTRL_RECIPIENT_INTERFACE | uu.CTRL_TYPE_VENDOR, GZ_REQ_INTEL_WRITE, 0, 0, data)
+ self.assertEqual(written, len(data), "Should have written all bytes plz")
+ # now. in _theory_ I should be able to make a bulk transfer here and have it not "interfere"
+ # fixme - try this out?
+ read = self.dev.ctrl_transfer(uu.CTRL_IN | uu.CTRL_RECIPIENT_INTERFACE | uu.CTRL_TYPE_VENDOR, GZ_REQ_INTEL_READ, 0, 0, mylen)
+ self.assertEqual(mylen, len(read))
+ expected = array.array('B', [x for x in data])
+ self.assertEqual(expected, read, "should have read back what we wrote")
+
+ def test_ctrl_loopbacks(self):
+ self.inner_t(0)
+ self.inner_t(10)
+ self.inner_t(63)
+ self.inner_t(64)
+ self.inner_t(65)
+ self.inner_t(140)
+ self.inner_t(183)
+
class TestConfigSourceSink(unittest.TestCase):
"""
diff --git a/tests/gadget-zero/usb-gadget0.c b/tests/gadget-zero/usb-gadget0.c
index d4d271bd..6e981436 100644
--- a/tests/gadget-zero/usb-gadget0.c
+++ b/tests/gadget-zero/usb-gadget0.c
@@ -280,7 +280,6 @@ static enum usbd_request_return_codes gadget0_control_request(usbd_device *usbd_
(void) usbd_dev;
(void) complete;
(void) buf;
- (void) len;
ER_DPRINTF("ctrl breq: %x, bmRT: %x, windex :%x, wlen: %x, wval :%x\n",
req->bRequest, req->bmRequestType, req->wIndex, req->wLength,
req->wValue);
@@ -292,9 +291,31 @@ static enum usbd_request_return_codes gadget0_control_request(usbd_device *usbd_
state.pattern = req->wValue;
return USBD_REQ_HANDLED;
case INTEL_COMPLIANCE_WRITE:
+ /* accept correctly formed ctrl writes */
+ if (req->bmRequestType != (USB_REQ_TYPE_VENDOR|USB_REQ_TYPE_INTERFACE)) {
+ return USBD_REQ_NOTSUPP;
+ }
+ if (req->wValue || req->wIndex) {
+ return USBD_REQ_NOTSUPP;
+ }
+ if (req->wLength > sizeof(usbd_control_buffer)) {
+ return USBD_REQ_NOTSUPP;
+ }
+ /* ok, mark it as accepted. */
+ return USBD_REQ_HANDLED;
case INTEL_COMPLIANCE_READ:
- ER_DPRINTF("unimplemented!");
- return USBD_REQ_NOTSUPP;
+ if (req->bmRequestType != (USB_REQ_TYPE_IN|USB_REQ_TYPE_VENDOR|USB_REQ_TYPE_INTERFACE)) {
+ return USBD_REQ_NOTSUPP;
+ }
+ if (req->wValue || req->wIndex) {
+ return USBD_REQ_NOTSUPP;
+ }
+ if (req->wLength > sizeof(usbd_control_buffer)) {
+ return USBD_REQ_NOTSUPP;
+ }
+ /* ok, return what they left there earlier */
+ *len = req->wLength;
+ return USBD_REQ_HANDLED;
case GZ_REQ_SET_UNALIGNED:
state.test_unaligned = 1;
return USBD_REQ_HANDLED;
@@ -316,6 +337,9 @@ static enum usbd_request_return_codes gadget0_control_request(usbd_device *usbd_
*len = req->wValue;
}
return USBD_REQ_HANDLED;
+ default:
+ ER_DPRINTF("Unhandled request!\n");
+ return USBD_REQ_NOTSUPP;
}
return USBD_REQ_NEXT_CALLBACK;
}