void usb_suspend_resume_test(uint16_t vid, uint16_t pid, uint32_t duration) { struct timeval sub_tv; struct timeval ref_tv; struct timeval res_tv; struct libusb20_device *pdev; time_t last_sec; int iter; int error; int ptimo; int errcnt; int power_old; ptimo = 1; /* second(s) */ error = sysctlbyname("hw.usb.power_timeout", NULL, NULL, &ptimo, sizeof(ptimo)); if (error != 0) { printf("WARNING: Could not set power " "timeout to 1 (error=%d) \n", errno); } pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 0); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } power_old = libusb20_dev_get_power_mode(pdev); printf("Starting suspend and resume " "test for VID=0x%04x PID=0x%04x\n", vid, pid); iter = 0; errcnt = 0; gettimeofday(&ref_tv, 0); last_sec = ref_tv.tv_sec; while (1) { if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } gettimeofday(&sub_tv, 0); if (last_sec != sub_tv.tv_sec) { printf("STATUS: ID=%u, ERR=%u\n", (int)iter, (int)errcnt); fflush(stdout); last_sec = sub_tv.tv_sec; } timersub(&sub_tv, &ref_tv, &res_tv); if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration)) break; error = libusb20_dev_set_power_mode(pdev, (iter & 1) ? LIBUSB20_POWER_ON : LIBUSB20_POWER_SAVE); if (error) errcnt++; /* wait before switching power mode */ usleep(4100000 + (((uint32_t)usb_ts_rand_noise()) % 2000000U)); iter++; } /* restore default power mode */ libusb20_dev_set_power_mode(pdev, power_old); libusb20_dev_free(pdev); }
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); }
static void do_io_test(struct usb_msc_params *p, uint8_t lun, uint32_t lba_max, uint8_t *buffer, uint8_t *reference) { uint32_t io_offset; uint32_t io_size; uint32_t temp; uint8_t do_read; uint8_t retval; switch (p->io_mode) { case USB_MSC_IO_MODE_WRITE_ONLY: do_read = 0; break; case USB_MSC_IO_MODE_READ_WRITE: do_read = (usb_ts_rand_noise() & 1); break; default: do_read = 1; break; } switch (p->io_offset) { case USB_MSC_IO_OFF_RANDOM: io_offset = usb_ts_rand_noise(); break; default: io_offset = 0; break; } switch (p->io_delay) { case USB_MSC_IO_DELAY_RANDOM_10MS: usleep(((uint32_t)usb_ts_rand_noise()) % 10000U); break; case USB_MSC_IO_DELAY_RANDOM_100MS: usleep(((uint32_t)usb_ts_rand_noise()) % 100000U); break; case USB_MSC_IO_DELAY_FIXED_10MS: usleep(10000); break; case USB_MSC_IO_DELAY_FIXED_100MS: usleep(100000); break; default: break; } switch (p->io_size) { case USB_MSC_IO_SIZE_RANDOM: io_size = ((uint32_t)usb_ts_rand_noise()) & 65535U; break; case USB_MSC_IO_SIZE_INCREASING: io_size = (xfer_current_id & 65535U); break; case USB_MSC_IO_SIZE_FIXED_1BLK: io_size = 1; break; case USB_MSC_IO_SIZE_FIXED_2BLK: io_size = 2; break; case USB_MSC_IO_SIZE_FIXED_4BLK: io_size = 4; break; case USB_MSC_IO_SIZE_FIXED_8BLK: io_size = 8; break; case USB_MSC_IO_SIZE_FIXED_16BLK: io_size = 16; break; case USB_MSC_IO_SIZE_FIXED_32BLK: io_size = 32; break; case USB_MSC_IO_SIZE_FIXED_64BLK: io_size = 64; break; case USB_MSC_IO_SIZE_FIXED_128BLK: io_size = 128; break; case USB_MSC_IO_SIZE_FIXED_256BLK: io_size = 256; break; case USB_MSC_IO_SIZE_FIXED_512BLK: io_size = 512; break; case USB_MSC_IO_SIZE_FIXED_1024BLK: io_size = 1024; break; default: io_size = 1; break; } if (io_size == 0) io_size = 1; io_offset %= lba_max; temp = (lba_max - io_offset); if (io_size > temp) io_size = temp; if (do_read) { retval = do_read_10(io_offset, io_size * block_size, buffer + (io_offset * block_size), lun); if (retval == 0) { if (bcmp(buffer + (io_offset * block_size), reference + (io_offset * block_size), io_size * block_size)) { printf("ERROR: Data comparison failure\n"); stats.data_error++; retval = 1; } } stats.xfer_rx_bytes += (io_size * block_size); } else { retval = do_write_10(io_offset, io_size * block_size, reference + (io_offset * block_size), lun); stats.xfer_tx_bytes += (io_size * block_size); } if ((stats.xfer_error + stats.data_error + stats.xfer_reset) >= p->max_errors) { printf("Maximum number of errors exceeded\n"); p->done = 1; } }