예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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;
	}
}