void libusb20_tr_drain(struct libusb20_transfer *xfer) { if (!xfer->is_opened) { /* transfer is not opened */ return; } /* make sure that we are cancelling */ libusb20_tr_stop(xfer); if (xfer->is_pending) { xfer->is_draining = 1; } return; }
static void usb_modem_data_stress_test(struct modem *p, uint32_t duration) { struct timeval sub_tv; struct timeval ref_tv; struct timeval res_tv; time_t last_sec; uint8_t in_pending = 0; uint8_t in_ready = 0; uint8_t out_pending = 0; uint32_t id = 0; uint32_t in_max; uint32_t out_max; uint32_t io_max; uint8_t *in_buffer = 0; uint8_t *out_buffer = 0; gettimeofday(&ref_tv, 0); last_sec = ref_tv.tv_sec; printf("\n"); in_max = libusb20_tr_get_max_total_length(p->xfer_in); out_max = libusb20_tr_get_max_total_length(p->xfer_out); /* get the smallest buffer size and use that */ io_max = (in_max < out_max) ? in_max : out_max; if (in_max != out_max) printf("WARNING: Buffer sizes are un-equal: %u vs %u\n", in_max, out_max); in_buffer = malloc(io_max); if (in_buffer == NULL) goto fail; out_buffer = malloc(io_max); if (out_buffer == NULL) goto fail; while (1) { gettimeofday(&sub_tv, 0); if (last_sec != sub_tv.tv_sec) { printf("STATUS: ID=%u, RX=%u bytes/sec, TX=%u bytes/sec, ERR=%d\n", (int)id, (int)p->rx_bytes.bytes, (int)p->tx_bytes.bytes, (int)p->errors); p->rx_bytes.bytes = 0; p->tx_bytes.bytes = 0; fflush(stdout); last_sec = sub_tv.tv_sec; id++; } timersub(&sub_tv, &ref_tv, &res_tv); if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration)) break; libusb20_dev_process(p->usb_dev); if (!libusb20_tr_pending(p->xfer_in)) { if (in_pending) { if (libusb20_tr_get_status(p->xfer_in) == 0) { modem_read(in_buffer, libusb20_tr_get_length(p->xfer_in, 0)); } else { p->errors++; usleep(10000); } in_pending = 0; in_ready = 1; } if (p->loop_data == 0) { libusb20_tr_setup_bulk(p->xfer_in, in_buffer, io_max, 0); libusb20_tr_start(p->xfer_in); in_pending = 1; in_ready = 0; } } if (!libusb20_tr_pending(p->xfer_out)) { uint32_t len; uint32_t dly; if (out_pending) { if (libusb20_tr_get_status(p->xfer_out) != 0) { p->errors++; usleep(10000); } } if (p->random_tx_length) { len = ((uint32_t)usb_ts_rand_noise()) % ((uint32_t)io_max); } else { len = io_max; } if (p->random_tx_delay) { dly = ((uint32_t)usb_ts_rand_noise()) % 16000U; } else { dly = 0; } if (p->loop_data != 0) { if (in_ready != 0) { len = libusb20_tr_get_length(p->xfer_in, 0); memcpy(out_buffer, in_buffer, len); in_ready = 0; } else { len = io_max + 1; } if (!libusb20_tr_pending(p->xfer_in)) { libusb20_tr_setup_bulk(p->xfer_in, in_buffer, io_max, 0); libusb20_tr_start(p->xfer_in); in_pending = 1; } } else { modem_write(out_buffer, len); } if (len <= io_max) { libusb20_tr_setup_bulk(p->xfer_out, out_buffer, len, 0); if (dly != 0) usleep(dly); libusb20_tr_start(p->xfer_out); out_pending = 1; } } libusb20_dev_wait_process(p->usb_dev, 500); if (libusb20_dev_check_connected(p->usb_dev) != 0) { printf("Device disconnected\n"); break; } } libusb20_tr_stop(p->xfer_in); libusb20_tr_stop(p->xfer_out); printf("\nData stress test done!\n"); fail: if (in_buffer) free(in_buffer); if (out_buffer) free(out_buffer); }