3 /*=================================================================
7 // USB testing - code common to host and target
9 //==========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //==========================================================================
43 //#####DESCRIPTIONBEGIN####
45 // This module contains some definitions and functions that are common to
46 // both the host and target side of USB testing, for example filling in
47 // a buffer with well-known data and validating the contents at the other end.
48 // The module is #include'd by other code rather than compiled separately,
49 // which simplifies the build process.
53 //####DESCRIPTIONEND####
54 //==========================================================================
59 /*{{{ Simple data pack and unpack operations */
61 // ----------------------------------------------------------------------------
62 // Utilities to pack and unpack data into buffers.
64 // Integers are transferred with 32 bits of precision, irrespective
65 // of the capabilities of either target and host.
68 pack_int(int datum, unsigned char* buffer, int* index_ptr)
70 int index = *index_ptr;
71 buffer[index++] = (datum >> 0) & 0x0FF;
72 buffer[index++] = (datum >> 8) & 0x0FF;
73 buffer[index++] = (datum >> 16) & 0x0FF;
74 buffer[index++] = (datum >> 24) & 0x0FF;
79 unpack_int(unsigned char* buffer, int* index_ptr)
81 int index = *index_ptr;
84 result = (buffer[index++] << 0);
85 result |= (buffer[index++] << 8);
86 result |= (buffer[index++] << 16);
87 result |= (buffer[index++] << 24);
93 /*{{{ Buffer data and validation */
95 // ----------------------------------------------------------------------------
96 // The data required for a given test. For some test cases, for
97 // example when trying to achieve maximum throughput, it does not
98 // matter what data is transferred. For other tests it is important to
99 // validate that the data sent and received match up, and there should
100 // be some control over the actual data: some tests might want to send
101 // a long sequence of byte 0, while others want to send more random data
102 // for which a simple random number generator is useful.
104 // Exactly the same routines are used on both host and target to fill in
105 // and check buffers, and they are sufficiently simple that the routines
106 // should get compiled in compatible ways.
108 // There is no support at present for sending specific data, e.g. a
109 // specific ethernet packet that appears to be causing problems. Knowledge
110 // of specific data cannot be compiled into the test code, so the only
111 // way to implement something like this would be to transfer the
112 // problematical data over the USB bus in order to determine whether or
113 // not the bus is capable of reliably transferring this data. That is
114 // not entirely impossible (checksums, use of alternative endpoints),
115 // but it is not implemented.
117 // An alternative approach would be to support a bounce operation
118 // involving both an IN and an OUT endpoint, doing validation only on
119 // the host. Again that is not yet implemented.
121 // The byte_fill and int_fill options are actually redundant because the
122 // same effect can be achieved using a multiplier of 1 and an increment
123 // of 0, but they can be implemented much more efficiently so may be
124 // useful for benchmarks.
126 typedef enum usbtestdata {
127 usbtestdata_none = 0, // There is nothing useful in the data
128 usbtestdata_bytefill = 1, // The data consists of a single byte, repeated
129 usbtestdata_wordfill = 2, // Or a single integer
130 usbtestdata_byteseq = 3, // Or a pseudo-random sequence (a * seed) + b
131 usbtestdata_wordseq = 4 // as either bytes or integers
134 typedef struct UsbTestData {
137 int multiplier; // 1103515245
138 int increment; // 12345
139 int transfer_seed_multiplier;
140 int transfer_seed_increment;
141 int transfer_multiplier_multiplier;
142 int transfer_multiplier_increment;
143 int transfer_increment_multiplier;
144 int transfer_increment_increment;
148 usbtest_fill_buffer(UsbTestData* how, unsigned char* buffer, int length)
152 case usbtestdata_none:
155 case usbtestdata_bytefill:
156 // Leave it to the system to optimise memset().
157 memset(buffer, (how->seed & 0x0FF), length);
160 case usbtestdata_wordfill:
162 // The buffer may not be a multiple of four bytes, so the last entry is always
166 for (i = 0; i < (length / 4); i++) {
167 pack_int(how->seed, buffer, &index);
169 pack_int(0, buffer, &index);
173 case usbtestdata_byteseq:
176 for (i = 0; i < length; i++) {
177 buffer[i] = (how->seed & 0x00FF);
178 how->seed *= how->multiplier;
179 how->seed += how->increment;
184 case usbtestdata_wordseq:
188 for (i = 0; i < (length / 4); i++) {
189 pack_int(how->seed, buffer, &index);
190 how->seed *= how->multiplier;
191 how->seed += how->increment;
193 pack_int(0, buffer, &index);
198 // After each transfer update the seed, multiplier and increment
199 // ready for the next one.
200 how->seed *= how->transfer_seed_multiplier;
201 how->seed += how->transfer_seed_increment;
202 how->multiplier *= how->transfer_multiplier_multiplier;
203 how->multiplier += how->transfer_multiplier_increment;
204 how->increment *= how->transfer_increment_multiplier;
205 how->increment += how->transfer_increment_increment;
209 usbtest_check_buffer(UsbTestData* how, unsigned char* buffer, int length)
213 switch(how->format) {
214 case usbtestdata_none:
217 case usbtestdata_bytefill:
221 for (i = 0; i < length; i++) {
222 if (buffer[i] != (how->seed & 0x00FF)) {
230 case usbtestdata_wordfill:
234 for (i = 0; i < (length / 4); i++) {
235 int datum = unpack_int(buffer, &index);
236 if (datum != (how->seed & 0x0FFFFFFFF)) {
241 for (i = 4 * i; result && (i < length); i++) {
242 if (0 != buffer[i]) {
250 case usbtestdata_byteseq:
253 for (i = 0; i < length; i++) {
254 if (buffer[i] != (how->seed & 0x00FF)) {
258 how->seed *= how->multiplier;
259 how->seed += how->increment;
264 case usbtestdata_wordseq:
269 for (i = 0; i < (length / 4); i++) {
270 int datum = unpack_int(buffer, &index);
271 if (datum != (how->seed & 0x0FFFFFFFF)) {
275 how->seed *= how->multiplier;
276 how->seed += how->increment;
278 for (i = 4 * i; result && (i < length); i++) {
279 if (0 != buffer[i]) {
288 // After each transfer update the seed, multiplier and increment
289 // ready for the next transfer.
290 how->seed *= how->transfer_seed_multiplier;
291 how->seed += how->transfer_seed_increment;
292 how->multiplier *= how->transfer_multiplier_multiplier;
293 how->multiplier += how->transfer_multiplier_increment;
294 how->increment *= how->transfer_increment_multiplier;
295 how->increment += how->transfer_increment_increment;
302 pack_usbtestdata(UsbTestData* data, unsigned char* buf, int* index)
304 pack_int((int)data->format, buf, index);
305 pack_int((int)data->seed, buf, index);
306 pack_int((int)data->multiplier, buf, index);
307 pack_int((int)data->increment, buf, index);
308 pack_int((int)data->transfer_seed_multiplier, buf, index);
309 pack_int((int)data->transfer_seed_increment, buf, index);
310 pack_int((int)data->transfer_multiplier_multiplier, buf, index);
311 pack_int((int)data->transfer_multiplier_increment, buf, index);
312 pack_int((int)data->transfer_increment_multiplier, buf, index);
313 pack_int((int)data->transfer_increment_increment, buf, index);
319 unpack_usbtestdata(UsbTestData* data, unsigned char* buf, int* index)
321 data->format = (usbtestdata) unpack_int(buf, index);
322 data->seed = unpack_int(buf, index);
323 data->multiplier = unpack_int(buf, index);
324 data->increment = unpack_int(buf, index);
325 data->transfer_seed_multiplier = unpack_int(buf, index);
326 data->transfer_seed_increment = unpack_int(buf, index);
327 data->transfer_multiplier_multiplier= unpack_int(buf, index);
328 data->transfer_multiplier_increment = unpack_int(buf, index);
329 data->transfer_increment_multiplier = unpack_int(buf, index);
330 data->transfer_increment_increment = unpack_int(buf, index);
335 /*{{{ Testcase definitions */
337 // ----------------------------------------------------------------------------
338 // Definitions of the supported test cases. The actual implementations need
339 // to vary between host and target.
341 typedef enum usbtest {
343 usbtest_bulk_out = 1,
345 usbtest_control_in = 3
348 // What I/O mechanism should be used on the target to process data?
349 typedef enum usb_io_mechanism {
350 usb_io_mechanism_usb = 1, // The low-level USB-specific API
351 usb_io_mechanism_dev = 2 // cyg_devio_cread() et al
354 // Bulk transfers. The same structure can be used for IN and OUT transfers.
355 // The endpoint number will be or'd with either USB_DIR_IN or USB_DIR_OUT,
356 // or the equivalent under eCos.
357 typedef struct UsbTest_Bulk {
363 int tx_size_multiplier;
365 int tx_size_increment;
369 int rx_size_multiplier;
371 int rx_size_increment;
376 int tx_delay_multiplier;
377 int tx_delay_divisor;
378 int tx_delay_increment;
382 int rx_delay_multiplier;
383 int rx_delay_divisor;
384 int rx_delay_increment;
385 usb_io_mechanism io_mechanism;
391 pack_usbtest_bulk(UsbTest_Bulk* test, unsigned char* buffer, int* index)
393 pack_int(test->number_packets, buffer, index);
394 pack_int(test->endpoint, buffer, index);
395 pack_int(test->tx_size, buffer, index);
396 pack_int(test->tx_size_min, buffer, index);
397 pack_int(test->tx_size_max, buffer, index);
398 pack_int(test->tx_size_multiplier, buffer, index);
399 pack_int(test->tx_size_divisor, buffer, index);
400 pack_int(test->tx_size_increment, buffer, index);
401 pack_int(test->rx_size, buffer, index);
402 pack_int(test->rx_size_min, buffer, index);
403 pack_int(test->rx_size_max, buffer, index);
404 pack_int(test->rx_size_multiplier, buffer, index);
405 pack_int(test->rx_size_divisor, buffer, index);
406 pack_int(test->rx_size_increment, buffer, index);
407 // There is no need to transfer the padding field. It is only of
408 // interest on the host, and this message is being packed
409 // for the target side.
410 pack_int(test->tx_delay, buffer, index);
411 pack_int(test->tx_delay_min, buffer, index);
412 pack_int(test->tx_delay_max, buffer, index);
413 pack_int(test->tx_delay_multiplier, buffer, index);
414 pack_int(test->tx_delay_divisor, buffer, index);
415 pack_int(test->tx_delay_increment, buffer, index);
416 pack_int(test->rx_delay, buffer, index);
417 pack_int(test->rx_delay_min, buffer, index);
418 pack_int(test->rx_delay_max, buffer, index);
419 pack_int(test->rx_delay_multiplier, buffer, index);
420 pack_int(test->rx_delay_divisor, buffer, index);
421 pack_int(test->rx_delay_increment, buffer, index);
422 pack_int((int)test->io_mechanism, buffer, index);
423 pack_usbtestdata(&(test->data), buffer, index);
429 unpack_usbtest_bulk(UsbTest_Bulk* test, unsigned char* buffer, int* index)
431 test->number_packets = unpack_int(buffer, index);
432 test->endpoint = unpack_int(buffer, index);
433 test->tx_size = unpack_int(buffer, index);
434 test->tx_size_min = unpack_int(buffer, index);
435 test->tx_size_max = unpack_int(buffer, index);
436 test->tx_size_multiplier = unpack_int(buffer, index);
437 test->tx_size_divisor = unpack_int(buffer, index);
438 test->tx_size_increment = unpack_int(buffer, index);
439 test->rx_size = unpack_int(buffer, index);
440 test->rx_size_min = unpack_int(buffer, index);
441 test->rx_size_max = unpack_int(buffer, index);
442 test->rx_size_multiplier = unpack_int(buffer, index);
443 test->rx_size_divisor = unpack_int(buffer, index);
444 test->rx_size_increment = unpack_int(buffer, index);
445 test->tx_delay = unpack_int(buffer, index);
446 test->tx_delay_min = unpack_int(buffer, index);
447 test->tx_delay_max = unpack_int(buffer, index);
448 test->tx_delay_multiplier = unpack_int(buffer, index);
449 test->tx_delay_divisor = unpack_int(buffer, index);
450 test->tx_delay_increment = unpack_int(buffer, index);
451 test->rx_delay = unpack_int(buffer, index);
452 test->rx_delay_min = unpack_int(buffer, index);
453 test->rx_delay_max = unpack_int(buffer, index);
454 test->rx_delay_multiplier = unpack_int(buffer, index);
455 test->rx_delay_divisor = unpack_int(buffer, index);
456 test->rx_delay_increment = unpack_int(buffer, index);
457 test->io_mechanism = (usb_io_mechanism) unpack_int(buffer, index);
458 unpack_usbtestdata(&(test->data), buffer, index);
462 // A macro for moving on the next packet size. This also has to be shared between host
463 // and target, if the two got out of synch then testing would go horribly wrong.
465 // The new packet size is determined using a multiplier and increment,
466 // so to e.g. increase packet sizes by 4 bytes each time the
467 // multiplier would be 1 and the increment would be 4, or to double
468 // packet sizes the multiplier would be 2 and the increment would be
469 // 0. On underflow or overflow the code tries to adjust the packet size
470 // back to within the accepted range.
472 #define USBTEST_NEXT_TX_SIZE(_x_) \
474 _x_.tx_size *= _x_.tx_size_multiplier; \
475 _x_.tx_size /= _x_.tx_size_divisor; \
476 _x_.tx_size += _x_.tx_size_increment; \
477 if (_x_.tx_size < _x_.tx_size_min) { \
478 if (_x_.tx_size_min == _x_.tx_size_max) { \
479 _x_.tx_size = _x_.tx_size_min; \
481 int tmp = _x_.tx_size_min - _x_.tx_size; \
482 tmp %= _x_.tx_size_max - _x_.tx_size_min; \
483 _x_.tx_size = tmp + _x_.tx_size_min; \
485 } else if (_x_.tx_size > _x_.tx_size_max) { \
486 if (_x_.tx_size_min == _x_.tx_size_max) { \
487 _x_.tx_size = _x_.tx_size_max; \
489 int tmp = _x_.tx_size - _x_.tx_size_max; \
490 tmp %= _x_.tx_size_max - _x_.tx_size_min; \
491 _x_.tx_size = tmp + _x_.tx_size_min; \
496 // A similar macro for moving on to the next receive size. This is less
497 // critical since care is taken to always receive at least the current
498 // tx size plus padding.
499 // Note that padding needs to be added by the calling code, not here,
500 // since padding is only applicable on the host-side and this macro
501 // is used on both host and target.
502 #define USBTEST_NEXT_RX_SIZE(_x_) \
504 _x_.rx_size *= _x_.rx_size_multiplier; \
505 _x_.rx_size /= _x_.rx_size_divisor; \
506 _x_.rx_size += _x_.rx_size_increment; \
507 if (_x_.rx_size < _x_.rx_size_min) { \
508 if (_x_.rx_size_min == _x_.rx_size_max) { \
509 _x_.rx_size = _x_.rx_size_min; \
511 int tmp = _x_.rx_size_min - _x_.rx_size; \
512 tmp %= _x_.rx_size_max - _x_.rx_size_min; \
513 _x_.rx_size = tmp + _x_.rx_size_min; \
515 } else if (_x_.rx_size > _x_.rx_size_max) { \
516 if (_x_.rx_size_min == _x_.rx_size_max) { \
517 _x_.rx_size = _x_.rx_size_max; \
519 int tmp = _x_.rx_size - _x_.rx_size_max; \
520 tmp %= _x_.rx_size_max - _x_.rx_size_min; \
521 _x_.rx_size = tmp + _x_.rx_size_min; \
526 // And a macro for adjusting the transmit delay.
527 #define USBTEST_NEXT_TX_DELAY(_x_) \
529 _x_.tx_delay *= _x_.tx_delay_multiplier; \
530 _x_.tx_delay /= _x_.tx_delay_divisor; \
531 _x_.tx_delay += _x_.tx_delay_increment; \
532 if (_x_.tx_delay < _x_.tx_delay_min) { \
533 if (_x_.tx_delay_min == _x_.tx_delay_max) { \
534 _x_.tx_delay = _x_.tx_delay_min; \
536 int tmp = _x_.tx_delay_min - _x_.tx_delay; \
537 tmp %= _x_.tx_delay_max - _x_.tx_delay_min; \
538 _x_.tx_delay = tmp + _x_.tx_delay_min; \
540 } else if (_x_.tx_delay > _x_.tx_delay_max) { \
541 if (_x_.tx_delay_min == _x_.tx_delay_max) { \
542 _x_.tx_delay = _x_.tx_delay_max; \
544 int tmp = _x_.tx_delay - _x_.tx_delay_max; \
545 tmp %= _x_.tx_delay_max - _x_.tx_delay_min; \
546 _x_.tx_delay = tmp + _x_.tx_delay_min; \
551 #define USBTEST_NEXT_RX_DELAY(_x_) \
553 _x_.rx_delay *= _x_.rx_delay_multiplier; \
554 _x_.rx_delay /= _x_.rx_delay_divisor; \
555 _x_.rx_delay += _x_.rx_delay_increment; \
556 if (_x_.rx_delay < _x_.rx_delay_min) { \
557 if (_x_.rx_delay_min == _x_.rx_delay_max) { \
558 _x_.rx_delay = _x_.rx_delay_min; \
560 int tmp = _x_.rx_delay_min - _x_.rx_delay; \
561 tmp %= _x_.rx_delay_max - _x_.rx_delay_min; \
562 _x_.rx_delay = tmp + _x_.rx_delay_min; \
564 } else if (_x_.rx_delay > _x_.rx_delay_max) { \
565 if (_x_.rx_delay_min == _x_.rx_delay_max) { \
566 _x_.rx_delay = _x_.rx_delay_max; \
568 int tmp = _x_.rx_delay - _x_.rx_delay_max; \
569 tmp %= _x_.rx_delay_max - _x_.rx_delay_min; \
570 _x_.rx_delay = tmp + _x_.rx_delay_min; \
575 #define USBTEST_BULK_NEXT(_bulk_) \
576 USBTEST_NEXT_TX_SIZE(_bulk_); \
577 USBTEST_NEXT_RX_SIZE(_bulk_); \
578 USBTEST_NEXT_TX_DELAY(_bulk_); \
579 USBTEST_NEXT_RX_DELAY(_bulk_);
581 // Control transfers, receives
582 typedef struct UsbTest_ControlIn {
584 int packet_size_initial;
587 int packet_size_multiplier;
588 int packet_size_increment;
594 pack_usbtest_control_in(UsbTest_ControlIn* test, unsigned char* buffer, int* index)
596 pack_int(test->number_packets, buffer, index);
597 pack_int(test->packet_size_initial, buffer, index);
598 pack_int(test->packet_size_min, buffer, index);
599 pack_int(test->packet_size_max, buffer, index);
600 pack_int(test->packet_size_multiplier, buffer, index);
601 pack_int(test->packet_size_increment, buffer, index);
602 pack_usbtestdata(&(test->data), buffer, index);
608 unpack_usbtest_control_in(UsbTest_ControlIn* test, unsigned char* buffer, int* index)
610 test->number_packets = unpack_int(buffer, index);
611 test->packet_size_initial = unpack_int(buffer, index);
612 test->packet_size_min = unpack_int(buffer, index);
613 test->packet_size_max = unpack_int(buffer, index);
614 test->packet_size_multiplier = unpack_int(buffer, index);
615 test->packet_size_increment = unpack_int(buffer, index);
616 unpack_usbtestdata(&(test->data), buffer, index);
620 // For now control packet sizes are adjusted in exactly the same way as bulk transfers.
621 #define USBTEST_CONTROL_NEXT_PACKET_SIZE(_packet_size_, _control_) \
622 _packet_size_ = (_packet_size_ * _control_.packet_size_multiplier) + _control_.packet_size_increment; \
623 if (_packet_size_ < _control_.packet_size_min) { \
624 _packet_size_ += _control_.packet_size_max - _control_.packet_size_min; \
625 if (_packet_size_ < _control_.packet_size_min) { \
626 _packet_size_ = _control_.packet_size_initial; \
628 } else if (_packet_size_ > _control_.packet_size_max) { \
629 _packet_size_ -= _control_.packet_size_max - _control_.packet_size_min; \
630 if (_packet_size_ > _control_.packet_size_max) { \
631 _packet_size_ = _control_.packet_size_initial; \
636 /*{{{ Recovery support */
638 // ----------------------------------------------------------------------------
639 // When things go wrong threads on either the host or the target may get
640 // locked up waiting for further communication that never happens, because
641 // the other side has already raised an error. Recovery is possible by
642 // performing an extra I/O operation. For example, if a thread on the
643 // target is blocked waiting on an OUT endpoint then recovery is possible
644 // by the host sending some data to that endpoint. Similarly if a thread
645 // on the host is blocked then recovery involves the target either sending
646 // or receiving some additional data. There are alternative approaches such
647 // as stalling endpoints, but making sure that the requested communication
648 // actually happens involves fewer dependencies on exactly how those
649 // operations behave.
651 typedef struct UsbTest_Recovery {
652 int endpoint; // Top bit indicates direction, -1 indicates invalid
658 pack_usbtest_recovery(UsbTest_Recovery* recovery, unsigned char* buffer, int* index)
660 pack_int(recovery->endpoint, buffer, index);
661 pack_int(recovery->protocol, buffer, index);
662 pack_int(recovery->size, buffer, index);
666 unpack_usbtest_recovery(UsbTest_Recovery* recovery, unsigned char* buffer, int *index)
668 recovery->endpoint = unpack_int(buffer, index);
669 recovery->protocol = unpack_int(buffer, index);
670 recovery->size = unpack_int(buffer, index);
674 usbtest_recovery_reset(UsbTest_Recovery* recovery)
676 recovery->endpoint = -1;
677 recovery->protocol = 0;