📄 usbtarget.c
字号:
} } // 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 voidrun_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; // 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 */// Control-IN transfers. These have to be handled a little bit differently// from bulk transfers. The target never actually initiates anything. Instead// the host will send reserved control messages which are handled at DSR// level and passed to handle_reserved_control_messages() below. Assuming// a control-IN test is in progress, that will take appropriate action. The// thread will be woken up only once all packets have been transferred, or// on abnormal termination.// Is a control-IN test currently in progress?static UsbTest* control_in_test = 0;// What is the expected packet size?static int control_in_test_packet_size = 0;// How many packets have been transferred so far?static int control_in_packets_transferred = 0;// Cancel a control-in test. handle_test_control_in() will have updated the static// control_in_test so that handle_reserved_control_messages() knows what to do.// If the test is not actually going to be run then system consistency demands
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -