📄 usbtarget.c
字号:
}
CYG_ASSERTC((usb_io_mechanism_usb == test->test_params.bulk.io_mechanism) || \
(usb_io_mechanism_dev == test->test_params.bulk.io_mechanism));
if (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism) {
if (((const char*)0 == usbs_testing_endpoints[ep_index].devtab_entry) ||
(0 != cyg_io_lookup(usbs_testing_endpoints[ep_index].devtab_entry, &io_handle))) {
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk OUT transfer on endpoint %d: no devtab entry", endpoint_number);
return;
}
}
// Make sure nobody else is using this endpoint
lock_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT);
for (i = 0; i < test->test_params.bulk.number_packets; i++) {
int rx_size = test->test_params.bulk.rx_size;
int tx_size = test->test_params.bulk.tx_size;
VERBOSE(2, "Bulk OUT test %d: iteration %d, rx size %d, tx size %d\n", test->id, i, rx_size, tx_size);
if (rx_size < tx_size) {
rx_size = tx_size;
VERBOSE(2, "Bulk OUT test %d: iteration %d, packet size reset to %d to match tx size\n",
test->id, i, rx_size);
}
test->recovery.endpoint = endpoint_number | USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT;
test->recovery.protocol = USB_ENDPOINT_DESCRIPTOR_ATTR_BULK;
test->recovery.size = rx_size;
// Make sure there is no old data lying around
if (usbtestdata_none != test->test_params.bulk.data.format) {
memset(buf, 0, rx_size);
}
// Do the actual transfer, using the I/O mechanism specified for this test.
switch (test->test_params.bulk.io_mechanism)
{
case usb_io_mechanism_usb :
{
test->transferred = 0;
usbs_start_rx_buffer(endpoint, buf, rx_size, &run_test_bulk_in_out_callback, (void*) test);
cyg_semaphore_wait(&(test->sem));
transferred = test->transferred;
break;
}
case usb_io_mechanism_dev :
{
int result;
transferred = rx_size;
result = cyg_io_read(io_handle, (void*) buf, &transferred);
if (result < 0) {
transferred = result;
}
break;
}
default:
CYG_FAIL("Invalid test mechanism specified");
break;
}
// Has this test been aborted for some reason?
if (current_tests_terminated) {
VERBOSE(2, "Bulk OUT test %d: iteration %d, termination detected\n", test->id, i);
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk OUT transfer on endpoint %d: transfer aborted after iteration %d", endpoint_number, i);
break;
}
// If an error occurred, abort this run
if (transferred < 0) {
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk OUT transfer on endpoint %d: transfer failed with %d", endpoint_number, transferred);
VERBOSE(2, "Bulk OUT test %d: iteration %d, error:\n %s\n", test->id, i, test->result_message);
break;
}
// Did the host send the expected amount of data?
if (transferred < test->test_params.bulk.tx_size) {
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk OUT transfer on endpoint %d : the host only sent %d bytes when %d were expected",
endpoint_number, transferred, tx_size);
VERBOSE(2, "Bulk OUT test %d: iteration %d, error:\n %s\n", test->id, i, test->result_message);
break;
}
if (verbose >= 3) {
// Output the first 32 bytes of data
char msg[256];
int index;
int j;
index = snprintf(msg, 255, "Bulk OUT test %d: iteration %d, transferred %d\n Data %s:",
test->id, i, transferred,
(usbtestdata_none == test->test_params.bulk.data.format) ? "(uninitialized)" : "");
for (j = 0; ((j + 3) < transferred) && (j < 32); j+= 4) {
index += snprintf(msg+index, 255-index, " %02x%02x%02x%02x",
buf[j], buf[j+1], buf[j+2], buf[j+3]);
}
if (j < 32) {
index += snprintf(msg+index, 255-index, " ");
for ( ; j < transferred; j++) {
index += snprintf(msg+index, 255-index, "%02x", buf[j]);
}
}
VERBOSE(3, "%s\n", msg);
}
// Is the data correct?
if (!usbtest_check_buffer(&(test->test_params.bulk.data), buf, transferred)) {
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk OUT transfer on endpoint %d : mismatch between received and expected data", endpoint_number);
VERBOSE(2, "Bulk OUt test %d: iteration %d, error:\n %s\n", test->id, i, test->result_message);
break;
}
if (0 != test->test_params.bulk.rx_delay) {
VERBOSE(2, "Bulk OUT test %d: iteration %d, sleeping for %d nanoseconds\n", test->id, \
i, test->test_params.bulk.rx_delay);
usbs_nanosleep(test->test_params.bulk.rx_delay);
}
// Move on to the next transfer
USBTEST_BULK_NEXT(test->test_params.bulk);
}
// Always unlock the endpoint on completion
unlock_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT);
// If all the packets have been transferred this test has passed.
if (i >= test->test_params.bulk.number_packets) {
test->result_pass = 1;
}
VERBOSE(1, "Test %d bulk OUT on endpoint %d, result %d\n", test->id, endpoint_number, test->result_pass);
}
/*}}}*/
/*{{{ run_test_bulk_in() */
// IN transfers, i.e. the host is expected to receive some data. These are slightly
// easier than OUT transfers because it is the host that will do the checking.
static void
run_test_bulk_in(UsbTest* test)
{
unsigned char* buf;
int endpoint_number = test->test_params.bulk.endpoint & ~USB_DEVREQ_DIRECTION_MASK;
int ep_index;
usbs_tx_endpoint* endpoint = 0;
cyg_io_handle_t io_handle = (cyg_io_handle_t)0;
int alignment;
int transferred;
int i;
VERBOSE(1, "Starting test %d, bulk IN on endpoint %d\n", test->id, endpoint_number);
ep_index = lookup_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN, USB_ENDPOINT_DESCRIPTOR_ATTR_BULK);
if (ep_index == -1) {
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk IN transfer on endpoint %d: no such bulk endpoint", endpoint_number);
return;
}
endpoint = (usbs_tx_endpoint*) usbs_testing_endpoints[ep_index].endpoint;
alignment = usbs_testing_endpoints[ep_index].alignment;
if (0 != alignment) {
buf = (unsigned char*) ((((cyg_uint32)test->buffer) + alignment - 1) & ~(alignment - 1));
} else {
buf = test->buffer;
}
CYG_ASSERTC((usb_io_mechanism_usb == test->test_params.bulk.io_mechanism) || \
(usb_io_mechanism_dev == test->test_params.bulk.io_mechanism));
if (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism) {
if (((const char*)0 == usbs_testing_endpoints[ep_index].devtab_entry) ||
(0 != cyg_io_lookup(usbs_testing_endpoints[ep_index].devtab_entry, &io_handle))) {
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk IN transfer on endpoint %d: no devtab entry", endpoint_number);
return;
}
}
// Make sure nobody else is using this endpoint
lock_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN);
for (i = 0; i < test->test_params.bulk.number_packets; i++) {
int packet_size = test->test_params.bulk.tx_size;
test->recovery.endpoint = endpoint_number | USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN;
test->recovery.protocol = USB_ENDPOINT_DESCRIPTOR_ATTR_BULK;
test->recovery.size = packet_size + usbs_testing_endpoints[ep_index].max_in_padding;
CYG_ASSERTC(sizeof(test->buffer) > packet_size);
// Make sure the buffer contains the data expected by the host
usbtest_fill_buffer(&(test->test_params.bulk.data), buf, packet_size);
if (verbose < 3) {
VERBOSE(2, "Bulk OUT test %d: iteration %d, packet size %d\n", test->id, i, packet_size);
} else {
// Output the first 32 bytes of data as well.
char msg[256];
int index;
int j;
index = snprintf(msg, 255, "Bulk IN test %d: iteration %d, packet size %d\n Data %s:",
test->id, i, packet_size,
(usbtestdata_none == test->test_params.bulk.data.format) ? "(uninitialized)" : "");
for (j = 0; ((j + 3) < packet_size) && (j < 32); j+= 4) {
index += snprintf(msg+index, 255-index, " %02x%02x%02x%02x",
buf[j], buf[j+1], buf[j+2], buf[j+3]);
}
if (j < 32) {
index += snprintf(msg+index, 255-index, " ");
for ( ; j < packet_size; j++) {
index += snprintf(msg+index, 255-index, "%02x", buf[j]);
}
}
VERBOSE(3, "%s\n", msg);
}
// Do the actual transfer, using the I/O mechanism specified for this test.
switch (test->test_params.bulk.io_mechanism)
{
case usb_io_mechanism_usb :
{
test->transferred = 0;
usbs_start_tx_buffer(endpoint, buf, packet_size, &run_test_bulk_in_out_callback, (void*) test);
cyg_semaphore_wait(&(test->sem));
transferred = test->transferred;
break;
}
case usb_io_mechanism_dev :
{
int result;
transferred = packet_size;
result = cyg_io_write(io_handle, (void*) buf, &transferred);
if (result < 0) {
transferred = result;
}
break;
}
default:
CYG_FAIL("Invalid test mechanism specified");
break;
}
// Has this test been aborted for some reason?
if (current_tests_terminated) {
VERBOSE(2, "Bulk IN test %d: iteration %d, termination detected\n", test->id, i);
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk IN transfer on endpoint %d : terminated on iteration %d, packet_size %d\n",
endpoint_number, i, packet_size);
break;
}
// If an error occurred, abort this run
if (transferred < 0) {
test->result_pass = 0;
snprintf(test->result_message, USBTEST_MAX_MESSAGE,
"Target, bulk IN transfer on endpoint %d: transfer failed with %d", endpoint_number, transferred);
VERBOSE(2, "Bulk IN test %d: iteration %d, error:\n %s\n", test->id, i, test->result_message);
break;
}
// No need to check the transfer size, the USB code is only
// allowed to send the exact amount of data requested.
if (0 != test->test_params.bulk.tx_delay) {
VERBOSE(2, "Bulk IN test %d: iteration %d, sleeping for %d nanoseconds\n", test->id, i, \
test->test_params.bulk.tx_delay);
usbs_nanosleep(test->test_params.bulk.tx_delay);
}
// Move on to the next transfer
USBTEST_BULK_NEXT(test->test_params.bulk);
}
// Always unlock the endpoint on completion
unlock_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN);
// If all the packets have been transferred this test has passed.
if (i >= test->test_params.bulk.number_packets) {
test->result_pass = 1;
}
VERBOSE(1, "Test %d bulk IN on endpoint %d, result %d\n", test->id, endpoint_number, test->result_pass);
}
/*}}}*/
/*}}}*/
/*{{{ Control IN transfers */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -