2 * Copyright (c) 1997 by Simon Shapiro
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 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * $FreeBSD: src/usr.sbin/dpt/dpt_dm/dpt_dm.c,v 1.3 1999/08/28 01:16:07 peter Exp $
30 * $DragonFly: src/usr.sbin/dpt/dpt_dm/dpt_dm.c,v 1.3 2004/12/18 22:48:03 swildner Exp $
33 /* dpt_dm.c: Dump a DPT metrics structure */
42 #include <sys/queue.h>
43 #include <sys/ioctl.h>
44 #include <scsi/scsi_all.h>
45 #include <scsi/scsi_message.h>
46 #include <scsi/scsiconf.h>
48 #define DPT_MEASURE_PERFORMANCE
53 scsi_cmd_name(u_int8_t cmd)
57 return ("Change Definition [7.1]");
60 return ("Compare [7,2]");
63 return ("Copy [7.3]");
66 return ("Copy and Verify [7.4]");
69 return ("Format Unit [6.1.1]");
72 return ("Inquiry [7.5]");
75 return ("lock/Unlock Cache [6.1.2]");
78 return ("Log Select [7.6]");
81 return ("Log Sense [7.7]");
84 return ("Mode select (6) [7.8]");
87 return ("Mode Select (10) [7.9]");
90 return ("Mode Sense (6) [7.10]");
93 return ("Mode Sense (10) [7.11]");
96 return ("Move Medium Attached [SMC]");
99 return ("Persistent Reserve In [7.12]");
102 return ("Persistent Reserve Out [7.13]");
105 return ("Prevent/Allow Medium Removal [7.14]");
108 return ("Read, Receive (6) [6.1.5]");
111 return ("Read (10) [6.1.5]");
114 return ("Read (12) [6.1.5]");
117 return ("Read Buffer [7.15]");
120 return ("Read Capacity [6.1.6]");
123 return ("Read Defect Data (10) [6.1.7]");
126 return ("Read Defect Data (12) [6.2.5]");
129 return ("Read Element Status Attached [SMC]");
132 return ("Read Long [6.1.8]");
135 return ("Reassign Blocks [6.1.9]");
138 return ("Rebuild [6.1.10]");
141 return ("Receive Diagnostics Result [7.16]");
144 return ("Regenerate [6.1.11]");
147 return ("Release(6) [7.17]");
150 return ("Release(10) [7.18]");
153 return ("Report LUNs [7.19]");
156 return ("Request Sense [7.20]");
159 return ("Resereve (6) [7.21]");
162 return ("Reserve(10) [7.22]");
165 return ("Reserve(10) [6.1.12]");
168 return ("Send Disagnostics [7.23]");
171 return ("Set Limit (10) [6.1.13]");
174 return ("Set Limit (12) [6.2.8]");
177 return ("Start/Stop Unit [6.1.14]");
180 return ("Synchronize Cache [6.1.15]");
183 return ("Test Unit Ready [7.24]");
186 return ("Update Block (6.2.9");
189 return ("Verify (10) [6.1.16, 6.2.10]");
192 return ("Verify (12) [6.2.11]");
195 return ("Write, Send (6) [6.1.17, 9.2]");
198 return ("Write (10) [6.1.18]");
201 return ("Write (12) [6.2.13]");
204 return ("Write and Verify (10) [6.1.19, 6.2.14]");
207 return ("Write and Verify (12) [6.1.19, 6.2.15]");
210 return ("Write Buffer [7.25]");
213 return ("Write Long [6.1.20]");
216 return ("Write Same [6.1.21]");
219 return ("XD Read [6.1.22]");
222 return ("XD Write [6.1.22]");
225 return ("XD Write Extended [6.1.22]");
228 return ("XO Write [6.1.22]");
231 return ("Unknown SCSI Command");
236 tmpsprintf(int buffer, const char *format, ...)
238 static char buffers[16][16];
241 va_start(ap, format);
242 vsnprintf(buffers[buffer], 16, format, ap);
244 return buffers[buffer];
249 main(int argc, char **argv, char **argp)
256 if ( (fd = open(argv[1], O_RDWR, S_IRUSR | S_IWUSR)) == -1 ) {
257 fprintf(stderr, "%s ERROR: Failed to open \"%s\" - %s\n",
258 argv[0], argv[1], strerror(errno));
262 if ( (result = ioctl(fd, DPT_IOCTL_INTERNAL_METRICS, &metrics)) != 0 ) {
263 fprintf(stderr, "%s ERROR: Failed to send IOCTL %lx - %s\n",
264 argv[0], DPT_IOCTL_INTERNAL_METRICS,
269 /* Interrupt related measurements */
270 fprintf(stdout, "Interrupts:%u:%u:%s:%u\n\nCommands:\n",
271 metrics.aborted_interrupts,
272 metrics.spurious_interrupts,
273 metrics.min_intr_time == BIG_ENOUGH ?
275 tmpsprintf(0, "%u", metrics.min_intr_time),
276 metrics.max_intr_time);
278 /* SCSI Commands, can be no more than 256 of them */
279 for (ndx = 0; ndx < 256; ndx++) {
280 if (metrics.command_count[ndx] != 0) {
281 fprintf(stdout, "%u:%s:%u:%s:%d\n",
283 scsi_cmd_name((u_int8_t)ndx),
284 metrics.command_count[ndx],
285 metrics.min_command_time[ndx] == BIG_ENOUGH ?
287 tmpsprintf(0, "%u", metrics.min_command_time[ndx]),
288 metrics.max_command_time[ndx]);
292 fprintf(stdout, "\nREAD by size:\n");
294 /* READ/WRITE statistics, per block size */
296 for ( ndx = 0; ndx < 10; ndx++) {
297 if (metrics.read_by_size_count[ndx] != 0) {
326 block_size = "BIGGER";
329 block_size = "OTHER";
332 block_size = "Gcc, shut up!";
335 fprintf(stdout, "%s:%u:%u:%u\n", block_size,
336 metrics.read_by_size_count[ndx],
337 metrics.read_by_size_min_time[ndx],
338 metrics.read_by_size_max_time[ndx]);
342 fprintf(stdout, "\nWRITE by size:\n");
344 for ( ndx = 0; ndx < 10; ndx++) {
345 if (metrics.write_by_size_count[ndx] != 0) {
374 block_size = "BIGGER";
377 block_size = "OTHER";
380 block_size = "Gcc, shut up!";
383 fprintf(stdout, "%s:%u:%u:%u\n", block_size,
384 metrics.write_by_size_count[ndx],
385 metrics.write_by_size_min_time[ndx],
386 metrics.write_by_size_max_time[ndx]);
391 fprintf(stdout, "\nQueues:%u:%s:%u:%u:%s:%u:%u:%s:%u\n",
392 metrics.max_waiting_count,
393 metrics.min_waiting_time == BIG_ENOUGH ?
395 tmpsprintf(0, "%u", metrics.min_waiting_time),
396 metrics.max_waiting_time,
397 metrics.max_submit_count,
398 metrics.min_submit_time == BIG_ENOUGH ?
400 tmpsprintf(1, "%u", metrics.min_submit_time),
401 metrics.max_submit_time,
402 metrics.max_complete_count,
403 metrics.min_complete_time == BIG_ENOUGH ?
405 tmpsprintf(2, "%u", metrics.min_complete_time),
406 metrics.max_complete_time);
408 fprintf(stdout, "Hardware Ports:%u:%u:%u:%s\n",
409 metrics.command_collisions,
410 metrics.command_too_busy,
411 metrics.max_eata_tries,
412 metrics.min_eata_tries == BIG_ENOUGH ?
414 tmpsprintf(0, "%u", metrics.min_eata_tries));