2 * Copyright (C) 2012 Intel Corporation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/ioctl.h>
31 #include <sys/queue.h>
44 #include "ioat_test.h"
46 static int prettyprint(struct ioat_test *);
52 printf("Usage: %s [-c period] [-EfmVz] channel-number num-txns [<bufsize> "
53 "[<chain-len> [duration]]]\n", getprogname());
54 printf(" %s -r [-c period] [-vVwz] channel-number address [<bufsize>]\n\n",
56 printf(" -c period - Enable interrupt coalescing (us) (default: 0)\n");
57 printf(" -E - Test non-contiguous 8k copy.\n");
58 printf(" -f - Test block fill (default: DMA copy).\n");
59 printf(" -m - Test memcpy instead of DMA.\n");
60 printf(" -r - Issue DMA to or from a specific address.\n");
61 printf(" -V - Enable verification\n");
62 printf(" -v - <address> is a kernel virtual address\n");
63 printf(" -w - Write to the specified address\n");
64 printf(" -z - Zero device stats before test\n");
69 main_raw(struct ioat_test *t, int argc, char **argv)
73 /* Raw DMA defaults */
74 t->testkind = IOAT_TEST_RAW_DMA;
77 t->buffer_size = 4 * 1024;
79 t->raw_target = strtoull(argv[1], NULL, 0);
80 if (t->raw_target == 0) {
81 printf("Target shoudln't be NULL\n");
86 t->buffer_size = atoi(argv[2]);
87 if (t->buffer_size == 0) {
88 printf("Buffer size must be greater than zero\n");
93 fd = open("/dev/ioat_test", O_RDWR);
95 printf("Cannot open /dev/ioat_test\n");
99 (void)ioctl(fd, IOAT_DMATEST, t);
102 exit(prettyprint(t));
106 main(int argc, char **argv)
110 bool fflag, rflag, Eflag, mflag;
113 memset(&t, 0, sizeof(t));
115 fflag = rflag = Eflag = mflag = false;
118 while ((ch = getopt(argc, argv, "c:EfmrvVwz")) != -1) {
121 t.coalesce_period = atoi(optarg);
140 t.raw_is_virtual = true;
162 printf("Invalid: Cannot use >1 mode flag (-E, -f, -m, or -r)\n");
166 /* Defaults for optional args */
167 t.buffer_size = 256 * 1024;
170 t.testkind = IOAT_TEST_DMA;
173 t.testkind = IOAT_TEST_FILL;
175 t.testkind = IOAT_TEST_DMA_8K;
176 t.buffer_size = 8 * 1024;
178 t.testkind = IOAT_TEST_MEMCPY;
180 t.channel_index = atoi(argv[0]);
181 if (t.channel_index > 8) {
182 printf("Channel number must be between 0 and 7.\n");
187 main_raw(&t, argc, argv);
191 t.transactions = atoi(argv[1]);
194 t.buffer_size = atoi(argv[2]);
195 if (t.buffer_size == 0) {
196 printf("Buffer size must be greater than zero\n");
202 t.chain_depth = atoi(argv[3]);
203 if (t.chain_depth < 1) {
204 printf("Chain length must be greater than zero\n");
210 t.duration = atoi(argv[4]);
211 if (t.duration < 1) {
212 printf("Duration must be greater than zero\n");
217 fd = open("/dev/ioat_test", O_RDWR);
219 printf("Cannot open /dev/ioat_test\n");
220 return (EX_UNAVAILABLE);
223 (void)ioctl(fd, IOAT_DMATEST, &t);
226 return (prettyprint(&t));
230 prettyprint(struct ioat_test *t)
232 char bps[10], bytesh[10];
235 if (t->status[IOAT_TEST_NO_DMA_ENGINE] != 0 ||
236 t->status[IOAT_TEST_NO_MEMORY] != 0 ||
237 t->status[IOAT_TEST_MISCOMPARE] != 0) {
239 if (t->status[IOAT_TEST_NO_DMA_ENGINE] != 0)
240 printf("\tNo DMA engine present: %u\n",
241 (unsigned)t->status[IOAT_TEST_NO_DMA_ENGINE]);
242 if (t->status[IOAT_TEST_NO_MEMORY] != 0)
243 printf("\tOut of memory: %u\n",
244 (unsigned)t->status[IOAT_TEST_NO_MEMORY]);
245 if (t->status[IOAT_TEST_MISCOMPARE] != 0)
246 printf("\tMiscompares: %u\n",
247 (unsigned)t->status[IOAT_TEST_MISCOMPARE]);
250 printf("Processed %u txns\n", (unsigned)t->status[IOAT_TEST_OK] /
252 bytes = (uintmax_t)t->buffer_size * t->status[IOAT_TEST_OK];
254 humanize_number(bytesh, sizeof(bytesh), (int64_t)bytes, "B",
255 HN_AUTOSCALE, HN_DECIMAL);
257 humanize_number(bps, sizeof(bps),
258 (int64_t)1000 * bytes / t->duration, "B/s", HN_AUTOSCALE,
260 printf("%ju (%s) copied in %u ms (%s)\n", bytes, bytesh,
261 (unsigned)t->duration, bps);
263 printf("%ju (%s) copied\n", bytes, bytesh);