sg: 16-byte cdb support and lots of fixes
[fio.git] / engines / sg.c
CommitLineData
2866c82d 1/*
da751ca9
JA
2 * sg engine
3 *
4 * IO engine that uses the Linux SG v3 interface to talk to SCSI devices
2866c82d
JA
5 *
6 */
7#include <stdio.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <errno.h>
11#include <assert.h>
12#include <sys/poll.h>
5f350952
JA
13
14#include "../fio.h"
2866c82d 15
34cfcdaf
JA
16#ifdef FIO_HAVE_SGIO
17
5ad7be56
KD
18#define MAX_10B_LBA 0xFFFFFFFFULL
19#define SCSI_TIMEOUT_MS 30000 // 30 second timeout; currently no method to override
20#define MAX_SB 64 // sense block maximum return size
21
2866c82d 22struct sgio_cmd {
5ad7be56
KD
23 unsigned char cdb[16]; // increase to support 16 byte commands
24 unsigned char sb[MAX_SB]; // add sense block to commands
2866c82d
JA
25 int nr;
26};
27
28struct sgio_data {
29 struct sgio_cmd *cmds;
30 struct io_u **events;
dc0deca2
JA
31 struct pollfd *pfds;
32 int *fd_flags;
33 void *sgbuf;
2866c82d 34 unsigned int bs;
5ad7be56 35 long long max_lba;
b5af8293 36 int type_checked;
2866c82d
JA
37};
38
39static void sgio_hdr_init(struct sgio_data *sd, struct sg_io_hdr *hdr,
40 struct io_u *io_u, int fs)
41{
42 struct sgio_cmd *sc = &sd->cmds[io_u->index];
43
44 memset(hdr, 0, sizeof(*hdr));
45 memset(sc->cdb, 0, sizeof(sc->cdb));
46
47 hdr->interface_id = 'S';
48 hdr->cmdp = sc->cdb;
49 hdr->cmd_len = sizeof(sc->cdb);
5ad7be56
KD
50 hdr->sbp = sc->sb;
51 hdr->mx_sb_len = sizeof(sc->sb);
2866c82d
JA
52 hdr->pack_id = io_u->index;
53 hdr->usr_ptr = io_u;
54
55 if (fs) {
cec6b55d
JA
56 hdr->dxferp = io_u->xfer_buf;
57 hdr->dxfer_len = io_u->xfer_buflen;
2866c82d
JA
58 }
59}
60
adee86c5
JA
61static int pollin_events(struct pollfd *pfds, int fds)
62{
63 int i;
64
65 for (i = 0; i < fds; i++)
66 if (pfds[i].revents & POLLIN)
67 return 1;
68
69 return 0;
70}
2866c82d 71
e7d2e616 72static int fio_sgio_getevents(struct thread_data *td, unsigned int min,
1f440ece
JA
73 unsigned int max,
74 const struct timespec fio_unused *t)
2866c82d
JA
75{
76 struct sgio_data *sd = td->io_ops->data;
5ad7be56 77 int left = max, eventNum, ret, r = 0;
dc0deca2 78 void *buf = sd->sgbuf;
af52b345 79 unsigned int i, events;
946ff865 80 struct fio_file *f;
2866c82d
JA
81
82 /*
adee86c5 83 * Fill in the file descriptors
2866c82d 84 */
adee86c5
JA
85 for_each_file(td, f, i) {
86 /*
87 * don't block for min events == 0
88 */
4a851614 89 if (!min)
3a35845f
JA
90 sd->fd_flags[i] = fio_set_fd_nonblocking(f->fd, "sg");
91 else
92 sd->fd_flags[i] = -1;
4a851614 93
dc0deca2
JA
94 sd->pfds[i].fd = f->fd;
95 sd->pfds[i].events = POLLIN;
2866c82d
JA
96 }
97
98 while (left) {
adee86c5
JA
99 void *p;
100
5ad7be56
KD
101 dprint(FD_IO, "sgio_getevents: sd %p: left=%d\n", sd, left);
102
2866c82d
JA
103 do {
104 if (!min)
105 break;
adee86c5 106
2dc1bbeb 107 ret = poll(sd->pfds, td->o.nr_files, -1);
adee86c5 108 if (ret < 0) {
adee86c5 109 if (!r)
22819ec2 110 r = -errno;
e1161c32 111 td_verror(td, errno, "poll");
adee86c5
JA
112 break;
113 } else if (!ret)
114 continue;
115
2dc1bbeb 116 if (pollin_events(sd->pfds, td->o.nr_files))
2866c82d
JA
117 break;
118 } while (1);
119
adee86c5 120 if (r < 0)
2866c82d 121 break;
adee86c5
JA
122
123re_read:
124 p = buf;
125 events = 0;
126 for_each_file(td, f, i) {
5ad7be56
KD
127 for (eventNum = 0; eventNum < left; eventNum++) {
128 ret = read(f->fd, p, sizeof(struct sg_io_hdr));
129 dprint(FD_IO, "sgio_getevents: ret: %d\n", ret);
130 if (ret < 0) {
131 /*
132 * not sure if EINTR is needed,
133 * but seems like it should be.
134 */
135 if (errno == EAGAIN || errno == EINTR)
136 continue;
137 r = -errno;
138 td_verror(td, errno, "read");
139 break;
140 } else if (ret) {
141 p += ret;
142 events += 1; /* ret / sizeof(struct sg_io_hdr); */
143 dprint(FD_IO, "sgio_getevents: events: %d\n", events);
144 }
adee86c5
JA
145 }
146 }
147
148 if (r < 0)
2866c82d 149 break;
adee86c5
JA
150 if (!events) {
151 usleep(1000);
152 goto re_read;
153 }
2866c82d 154
2866c82d
JA
155 left -= events;
156 r += events;
157
158 for (i = 0; i < events; i++) {
159 struct sg_io_hdr *hdr = (struct sg_io_hdr *) buf + i;
2866c82d 160 sd->events[i] = hdr->usr_ptr;
5ad7be56
KD
161
162 /* record if an io error occurred, ignore resid */
163 if (hdr->info & SG_INFO_CHECK) {
164 struct io_u *io_u;
165 io_u = (struct io_u *)(hdr->usr_ptr);
166 memcpy((void*)&(io_u->hdr), (void*)hdr, sizeof(struct sg_io_hdr));
167 sd->events[i]->error = EIO;
168 }
2866c82d
JA
169 }
170 }
171
adee86c5 172 if (!min) {
affe05a9 173 for_each_file(td, f, i) {
3a35845f
JA
174 if (sd->fd_flags[i] == -1)
175 continue;
176
affe05a9
JA
177 if (fcntl(f->fd, F_SETFL, sd->fd_flags[i]) < 0)
178 log_err("fio: sg failed to restore fcntl flags: %s\n", strerror(errno));
179 }
adee86c5 180 }
2866c82d 181
2866c82d
JA
182 return r;
183}
184
7a16dd02
JA
185static int fio_sgio_ioctl_doio(struct thread_data *td,
186 struct fio_file *f, struct io_u *io_u)
2866c82d
JA
187{
188 struct sgio_data *sd = td->io_ops->data;
189 struct sg_io_hdr *hdr = &io_u->hdr;
36167d82 190 int ret;
2866c82d
JA
191
192 sd->events[0] = io_u;
193
36167d82
JA
194 ret = ioctl(f->fd, SG_IO, hdr);
195 if (ret < 0)
a05bd42d 196 return ret;
36167d82 197
5ad7be56
KD
198 /* record if an io error occurred */
199 if (hdr->info & SG_INFO_CHECK)
200 io_u->error = EIO;
201
36167d82 202 return FIO_Q_COMPLETED;
2866c82d
JA
203}
204
2b13e716 205static int fio_sgio_rw_doio(struct fio_file *f, struct io_u *io_u, int do_sync)
2866c82d
JA
206{
207 struct sg_io_hdr *hdr = &io_u->hdr;
208 int ret;
209
53cdc686 210 ret = write(f->fd, hdr, sizeof(*hdr));
2866c82d 211 if (ret < 0)
a05bd42d 212 return ret;
2866c82d 213
2b13e716 214 if (do_sync) {
53cdc686 215 ret = read(f->fd, hdr, sizeof(*hdr));
2866c82d 216 if (ret < 0)
a05bd42d 217 return ret;
5ad7be56
KD
218
219 /* record if an io error occurred */
220 if (hdr->info & SG_INFO_CHECK)
221 io_u->error = EIO;
222
36167d82 223 return FIO_Q_COMPLETED;
2866c82d
JA
224 }
225
36167d82 226 return FIO_Q_QUEUED;
2866c82d
JA
227}
228
2b13e716 229static int fio_sgio_doio(struct thread_data *td, struct io_u *io_u, int do_sync)
2866c82d 230{
53cdc686 231 struct fio_file *f = io_u->file;
5ad7be56 232 int ret;
53cdc686 233
5ad7be56
KD
234 if (f->filetype == FIO_TYPE_BD) {
235 ret = fio_sgio_ioctl_doio(td, f, io_u);
236 td->error = io_u->error;
237 } else {
238 ret = fio_sgio_rw_doio(f, io_u, do_sync);
239 if (do_sync)
240 td->error = io_u->error;
241 }
2866c82d 242
5ad7be56 243 return ret;
2866c82d
JA
244}
245
2866c82d
JA
246static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u)
247{
248 struct sg_io_hdr *hdr = &io_u->hdr;
249 struct sgio_data *sd = td->io_ops->data;
5ad7be56 250 long long nr_blocks, lba;
2866c82d 251
cec6b55d 252 if (io_u->xfer_buflen & (sd->bs - 1)) {
2866c82d
JA
253 log_err("read/write not sector aligned\n");
254 return EINVAL;
255 }
256
5ad7be56
KD
257 nr_blocks = io_u->xfer_buflen / sd->bs;
258 lba = io_u->offset / sd->bs;
259
2866c82d 260 if (io_u->ddir == DDIR_READ) {
87dc1ab1
JA
261 sgio_hdr_init(sd, hdr, io_u, 1);
262
2866c82d 263 hdr->dxfer_direction = SG_DXFER_FROM_DEV;
5ad7be56
KD
264 if (lba < MAX_10B_LBA)
265 hdr->cmdp[0] = 0x28; // read(10)
266 else
267 hdr->cmdp[0] = 0x88; // read(16)
87dc1ab1
JA
268 } else if (io_u->ddir == DDIR_WRITE) {
269 sgio_hdr_init(sd, hdr, io_u, 1);
270
2866c82d 271 hdr->dxfer_direction = SG_DXFER_TO_DEV;
5ad7be56
KD
272 if (lba < MAX_10B_LBA)
273 hdr->cmdp[0] = 0x2a; // write(10)
274 else
275 hdr->cmdp[0] = 0x8a; // write(16)
87dc1ab1
JA
276 } else {
277 sgio_hdr_init(sd, hdr, io_u, 0);
87dc1ab1 278 hdr->dxfer_direction = SG_DXFER_NONE;
5ad7be56
KD
279 if (lba < MAX_10B_LBA)
280 hdr->cmdp[0] = 0x35; // synccache(10)
281 else
282 hdr->cmdp[0] = 0x91; // synccache(16)
87dc1ab1
JA
283 }
284
5ad7be56
KD
285 /*
286 * for synccache, we leave lba and length to 0 to sync all
287 * blocks on medium.
288 */
87dc1ab1 289 if (hdr->dxfer_direction != SG_DXFER_NONE) {
5ad7be56
KD
290
291 if (lba < MAX_10B_LBA) {
292 hdr->cmdp[2] = (unsigned char) ((lba >> 24) & 0xff);
293 hdr->cmdp[3] = (unsigned char) ((lba >> 16) & 0xff);
294 hdr->cmdp[4] = (unsigned char) ((lba >> 8) & 0xff);
295 hdr->cmdp[5] = (unsigned char) (lba & 0xff);
296 hdr->cmdp[7] = (unsigned char) ((nr_blocks >> 8) & 0xff);
297 hdr->cmdp[8] = (unsigned char) (nr_blocks & 0xff);
298 } else {
299 hdr->cmdp[2] = (unsigned char) ((lba >> 56) & 0xff);
300 hdr->cmdp[3] = (unsigned char) ((lba >> 48) & 0xff);
301 hdr->cmdp[4] = (unsigned char) ((lba >> 40) & 0xff);
302 hdr->cmdp[5] = (unsigned char) ((lba >> 32) & 0xff);
303 hdr->cmdp[6] = (unsigned char) ((lba >> 24) & 0xff);
304 hdr->cmdp[7] = (unsigned char) ((lba >> 16) & 0xff);
305 hdr->cmdp[8] = (unsigned char) ((lba >> 8) & 0xff);
306 hdr->cmdp[9] = (unsigned char) (lba & 0xff);
307 hdr->cmdp[10] = (unsigned char) ((nr_blocks >> 32) & 0xff);
308 hdr->cmdp[11] = (unsigned char) ((nr_blocks >> 16) & 0xff);
309 hdr->cmdp[12] = (unsigned char) ((nr_blocks >> 8) & 0xff);
310 hdr->cmdp[13] = (unsigned char) (nr_blocks & 0xff);
311 }
2866c82d
JA
312 }
313
5ad7be56 314 hdr->timeout = SCSI_TIMEOUT_MS;
2866c82d
JA
315 return 0;
316}
317
318static int fio_sgio_queue(struct thread_data *td, struct io_u *io_u)
319{
320 struct sg_io_hdr *hdr = &io_u->hdr;
f6db4fa5 321 int ret, do_sync = 0;
2866c82d 322
7101d9c2
JA
323 fio_ro_check(td, io_u);
324
f6db4fa5
JA
325 if (td->o.sync_io || td->o.odirect || ddir_sync(io_u->ddir))
326 do_sync = 1;
327
328 ret = fio_sgio_doio(td, io_u, do_sync);
2866c82d
JA
329
330 if (ret < 0)
331 io_u->error = errno;
332 else if (hdr->status) {
333 io_u->resid = hdr->resid;
334 io_u->error = EIO;
335 }
336
95bcd815 337 if (io_u->error) {
e1161c32 338 td_verror(td, io_u->error, "xfer");
36167d82 339 return FIO_Q_COMPLETED;
95bcd815
JA
340 }
341
36167d82 342 return ret;
2866c82d
JA
343}
344
345static struct io_u *fio_sgio_event(struct thread_data *td, int event)
346{
347 struct sgio_data *sd = td->io_ops->data;
348
349 return sd->events[event];
350}
351
5ad7be56
KD
352static int fio_sgio_read_capacity(struct thread_data *td, unsigned int *bs,
353 unsigned long long *max_lba)
2866c82d 354{
5ad7be56
KD
355 /*
356 * need to do read capacity operation w/o benefit of sd or
357 * io_u structures, which are not initialized until later.
358 */
359 struct sg_io_hdr hdr;
360 unsigned char cmd[16];
361 unsigned char sb[64];
362 unsigned char buf[32]; // read capacity return
2866c82d 363 int ret;
5ad7be56 364 int fd = -1;
2866c82d 365
5ad7be56 366 struct fio_file *f = td->files[0];
2866c82d 367
5ad7be56
KD
368 /* open file independent of rest of application */
369 fd = open(f->file_name, O_RDONLY);
370 if (fd < 0)
371 return -errno;
2866c82d 372
5ad7be56
KD
373 memset(&hdr, 0, sizeof(hdr));
374 memset(cmd, 0, sizeof(cmd));
375 memset(sb, 0, sizeof(sb));
376 memset(buf, 0, sizeof(buf));
2866c82d 377
5ad7be56
KD
378 /* First let's try a 10 byte read capacity. */
379 hdr.interface_id = 'S';
380 hdr.cmdp = cmd;
381 hdr.cmd_len = 10;
382 hdr.sbp = sb;
383 hdr.mx_sb_len = sizeof(sb);
384 hdr.timeout = SCSI_TIMEOUT_MS;
385 hdr.cmdp[0] = 0x25; // Read Capacity(10)
386 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
387 hdr.dxferp = buf;
388 hdr.dxfer_len = sizeof(buf);
389
390 ret = ioctl(fd, SG_IO, &hdr);
391 if (ret < 0) {
392 close(fd);
2866c82d 393 return ret;
5ad7be56 394 }
2866c82d 395
5ad7be56
KD
396 *bs = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
397 *max_lba = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]) & 0x00000000FFFFFFFFULL; // for some reason max_lba is being sign extended even though unsigned.
398
399
400 /*
401 * If max lba is 0xFFFFFFFF, then need to retry with
402 * 16 byteread capacity
403 */
404 if (*max_lba == MAX_10B_LBA) {
405 hdr.cmd_len = 16;
406 hdr.cmdp[0] = 0x9e; // Read Capacity(16)
407 hdr.cmdp[1] = 0x10; // service action
408 hdr.cmdp[10] = (unsigned char) ((sizeof(buf) >> 24) & 0xff);
409 hdr.cmdp[11] = (unsigned char) ((sizeof(buf) >> 16) & 0xff);
410 hdr.cmdp[12] = (unsigned char) ((sizeof(buf) >> 8) & 0xff);
411 hdr.cmdp[13] = (unsigned char) (sizeof(buf) & 0xff);
412
413 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
414 hdr.dxferp = buf;
415 hdr.dxfer_len = sizeof(buf);
416
417 ret = ioctl(fd, SG_IO, &hdr);
418 if (ret < 0) {
419 close(fd);
420 return ret;
421 }
422
423 /* record if an io error occurred */
424 if (hdr.info & SG_INFO_CHECK)
425 td_verror(td, EIO, "fio_sgio_read_capacity");
426
427 *bs = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
428 *max_lba = ((unsigned long long)buf[0] << 56) |
429 ((unsigned long long)buf[1] << 48) |
430 ((unsigned long long)buf[2] << 40) |
431 ((unsigned long long)buf[3] << 32) |
432 ((unsigned long long)buf[4] << 24) |
433 ((unsigned long long)buf[5] << 16) |
434 ((unsigned long long)buf[6] << 8) |
435 (unsigned long long)buf[7];
436 }
437
438 close(fd);
2866c82d
JA
439 return 0;
440}
441
442static void fio_sgio_cleanup(struct thread_data *td)
443{
dc0deca2
JA
444 struct sgio_data *sd = td->io_ops->data;
445
446 if (sd) {
447 free(sd->events);
448 free(sd->cmds);
449 free(sd->fd_flags);
450 free(sd->pfds);
451 free(sd->sgbuf);
452 free(sd);
2866c82d
JA
453 }
454}
455
456static int fio_sgio_init(struct thread_data *td)
457{
458 struct sgio_data *sd;
2866c82d
JA
459
460 sd = malloc(sizeof(*sd));
cb781c75 461 memset(sd, 0, sizeof(*sd));
2dc1bbeb
JA
462 sd->cmds = malloc(td->o.iodepth * sizeof(struct sgio_cmd));
463 memset(sd->cmds, 0, td->o.iodepth * sizeof(struct sgio_cmd));
464 sd->events = malloc(td->o.iodepth * sizeof(struct io_u *));
465 memset(sd->events, 0, td->o.iodepth * sizeof(struct io_u *));
466 sd->pfds = malloc(sizeof(struct pollfd) * td->o.nr_files);
467 memset(sd->pfds, 0, sizeof(struct pollfd) * td->o.nr_files);
468 sd->fd_flags = malloc(sizeof(int) * td->o.nr_files);
469 memset(sd->fd_flags, 0, sizeof(int) * td->o.nr_files);
470 sd->sgbuf = malloc(sizeof(struct sg_io_hdr) * td->o.iodepth);
471 memset(sd->sgbuf, 0, sizeof(struct sg_io_hdr) * td->o.iodepth);
5ad7be56 472 sd->type_checked = 0;
2866c82d
JA
473 td->io_ops->data = sd;
474
b5af8293
JA
475 /*
476 * we want to do it, regardless of whether odirect is set or not
477 */
2dc1bbeb 478 td->o.override_sync = 1;
b5af8293
JA
479 return 0;
480}
481
482static int fio_sgio_type_check(struct thread_data *td, struct fio_file *f)
483{
484 struct sgio_data *sd = td->io_ops->data;
5ad7be56
KD
485 unsigned int bs = 0;
486 unsigned long long max_lba = 0;
487
b5af8293 488
af52b345 489 if (f->filetype == FIO_TYPE_BD) {
53cdc686 490 if (ioctl(f->fd, BLKSSZGET, &bs) < 0) {
e1161c32 491 td_verror(td, errno, "ioctl");
b5af8293 492 return 1;
2866c82d 493 }
af52b345 494 } else if (f->filetype == FIO_TYPE_CHAR) {
b5af8293 495 int version, ret;
2866c82d 496
53cdc686 497 if (ioctl(f->fd, SG_GET_VERSION_NUM, &version) < 0) {
e1161c32 498 td_verror(td, errno, "ioctl");
b5af8293 499 return 1;
2866c82d
JA
500 }
501
5ad7be56
KD
502 ret = fio_sgio_read_capacity(td, &bs, &max_lba);
503 if (ret) {
504 td_verror(td, td->error, "fio_sgio_read_capacity");
505 log_err("ioengine sg unable to read capacity successfully\n");
b5af8293 506 return 1;
5ad7be56 507 }
2866c82d 508 } else {
16ada754 509 td_verror(td, EINVAL, "wrong file type");
d0c70934 510 log_err("ioengine sg only works on block devices\n");
b5af8293 511 return 1;
2866c82d
JA
512 }
513
514 sd->bs = bs;
5ad7be56
KD
515 // Determine size of commands needed based on max_lba
516 sd->max_lba = max_lba;
517 if (max_lba > MAX_10B_LBA) {
518 dprint(FD_IO, "sgio_type_check: using 16 byte operations: max_lba = 0x%016llx\n", max_lba);
519 }
520
2866c82d 521
af52b345 522 if (f->filetype == FIO_TYPE_BD) {
36167d82
JA
523 td->io_ops->getevents = NULL;
524 td->io_ops->event = NULL;
525 }
5ad7be56 526 sd->type_checked = 1;
2866c82d 527
2866c82d 528 return 0;
b5af8293
JA
529}
530
531static int fio_sgio_open(struct thread_data *td, struct fio_file *f)
532{
533 struct sgio_data *sd = td->io_ops->data;
534 int ret;
535
536 ret = generic_open_file(td, f);
537 if (ret)
538 return ret;
539
15ba640a 540 if (sd && !sd->type_checked && fio_sgio_type_check(td, f)) {
6977bcd0 541 ret = generic_close_file(td, f);
b5af8293
JA
542 return 1;
543 }
544
545 return 0;
2866c82d
JA
546}
547
5ad7be56
KD
548/*
549 * Build an error string with details about the driver, host or scsi
550 * error contained in the sg header Caller will use as necessary.
551 */
552static char *fio_sgio_errdetails(struct io_u *io_u)
553{
554 struct sg_io_hdr *hdr = &io_u->hdr;
555#define MAXERRDETAIL 1024
556#define MAXMSGCHUNK 128
557 char *msg, msgchunk[MAXMSGCHUNK], *ret = NULL;
558 int i;
559
560 msg = calloc(MAXERRDETAIL, 1);
561
562 /*
563 * can't seem to find sg_err.h, so I'll just echo the define values
564 * so others can search on internet to find clearer clues of meaning.
565 */
566 if (hdr->info & SG_INFO_CHECK) {
567 ret = msg;
568 if (hdr->host_status) {
569 snprintf(msgchunk, MAXMSGCHUNK, "SG Host Status: 0x%02x; ", hdr->host_status);
570 strlcat(msg, msgchunk, MAXERRDETAIL);
571 switch (hdr->host_status) {
572 case 0x01:
573 strlcat(msg, "SG_ERR_DID_NO_CONNECT", MAXERRDETAIL);
574 break;
575 case 0x02:
576 strlcat(msg, "SG_ERR_DID_BUS_BUSY", MAXERRDETAIL);
577 break;
578 case 0x03:
579 strlcat(msg, "SG_ERR_DID_TIME_OUT", MAXERRDETAIL);
580 break;
581 case 0x04:
582 strlcat(msg, "SG_ERR_DID_BAD_TARGET", MAXERRDETAIL);
583 break;
584 case 0x05:
585 strlcat(msg, "SG_ERR_DID_ABORT", MAXERRDETAIL);
586 break;
587 case 0x06:
588 strlcat(msg, "SG_ERR_DID_PARITY", MAXERRDETAIL);
589 break;
590 case 0x07:
591 strlcat(msg, "SG_ERR_DID_ERROR (internal error)", MAXERRDETAIL);
592 break;
593 case 0x08:
594 strlcat(msg, "SG_ERR_DID_RESET", MAXERRDETAIL);
595 break;
596 case 0x09:
597 strlcat(msg, "SG_ERR_DID_BAD_INTR (unexpected)", MAXERRDETAIL);
598 break;
599 case 0x0a:
600 strlcat(msg, "SG_ERR_DID_PASSTHROUGH", MAXERRDETAIL);
601 break;
602 case 0x0b:
603 strlcat(msg, "SG_ERR_DID_SOFT_ERROR (driver retry?)", MAXERRDETAIL);
604 break;
605 case 0x0c:
606 strlcat(msg, "SG_ERR_DID_IMM_RETRY", MAXERRDETAIL);
607 break;
608 case 0x0d:
609 strlcat(msg, "SG_ERR_DID_REQUEUE", MAXERRDETAIL);
610 break;
611 default:
612 strlcat(msg, "Unknown", MAXERRDETAIL);
613 break;
614 }
615 strlcat(msg, ". ", MAXERRDETAIL);
616 }
617 if (hdr->driver_status) {
618 snprintf(msgchunk, MAXMSGCHUNK, "SG Driver Status: 0x%02x; ", hdr->driver_status);
619 strlcat(msg, msgchunk, MAXERRDETAIL);
620 switch (hdr->driver_status & 0x0F) {
621 case 0x01:
622 strlcat(msg, "SG_ERR_DRIVER_BUSY", MAXERRDETAIL);
623 break;
624 case 0x02:
625 strlcat(msg, "SG_ERR_DRIVER_SOFT", MAXERRDETAIL);
626 break;
627 case 0x03:
628 strlcat(msg, "SG_ERR_DRIVER_MEDIA", MAXERRDETAIL);
629 break;
630 case 0x04:
631 strlcat(msg, "SG_ERR_DRIVER_ERROR", MAXERRDETAIL);
632 break;
633 case 0x05:
634 strlcat(msg, "SG_ERR_DRIVER_INVALID", MAXERRDETAIL);
635 break;
636 case 0x06:
637 strlcat(msg, "SG_ERR_DRIVER_TIMEOUT", MAXERRDETAIL);
638 break;
639 case 0x07:
640 strlcat(msg, "SG_ERR_DRIVER_HARD", MAXERRDETAIL);
641 break;
642 case 0x08:
643 strlcat(msg, "SG_ERR_DRIVER_SENSE", MAXERRDETAIL);
644 break;
645 default:
646 strlcat(msg, "Unknown", MAXERRDETAIL);
647 break;
648 }
649 strlcat(msg, "; ", MAXERRDETAIL);
650 switch (hdr->driver_status & 0xF0) {
651 case 0x10:
652 strlcat(msg, "SG_ERR_SUGGEST_RETRY", MAXERRDETAIL);
653 break;
654 case 0x20:
655 strlcat(msg, "SG_ERR_SUGGEST_ABORT", MAXERRDETAIL);
656 break;
657 case 0x30:
658 strlcat(msg, "SG_ERR_SUGGEST_REMAP", MAXERRDETAIL);
659 break;
660 case 0x40:
661 strlcat(msg, "SG_ERR_SUGGEST_DIE", MAXERRDETAIL);
662 break;
663 case 0x80:
664 strlcat(msg, "SG_ERR_SUGGEST_SENSE", MAXERRDETAIL);
665 break;
666 }
667 strlcat(msg, ". ", MAXERRDETAIL);
668 }
669 if (hdr->status) {
670 snprintf(msgchunk, MAXMSGCHUNK, "SG SCSI Status: 0x%02x; ", hdr->status);
671 strlcat(msg, msgchunk, MAXERRDETAIL);
672 // SCSI 3 status codes
673 switch (hdr->status) {
674 case 0x02:
675 strlcat(msg, "CHECK_CONDITION", MAXERRDETAIL);
676 break;
677 case 0x04:
678 strlcat(msg, "CONDITION_MET", MAXERRDETAIL);
679 break;
680 case 0x08:
681 strlcat(msg, "BUSY", MAXERRDETAIL);
682 break;
683 case 0x10:
684 strlcat(msg, "INTERMEDIATE", MAXERRDETAIL);
685 break;
686 case 0x14:
687 strlcat(msg, "INTERMEDIATE_CONDITION_MET", MAXERRDETAIL);
688 break;
689 case 0x18:
690 strlcat(msg, "RESERVATION_CONFLICT", MAXERRDETAIL);
691 break;
692 case 0x22:
693 strlcat(msg, "COMMAND_TERMINATED", MAXERRDETAIL);
694 break;
695 case 0x28:
696 strlcat(msg, "TASK_SET_FULL", MAXERRDETAIL);
697 break;
698 case 0x30:
699 strlcat(msg, "ACA_ACTIVE", MAXERRDETAIL);
700 break;
701 case 0x40:
702 strlcat(msg, "TASK_ABORTED", MAXERRDETAIL);
703 break;
704 default:
705 strlcat(msg, "Unknown", MAXERRDETAIL);
706 break;
707 }
708 strlcat(msg, ". ", MAXERRDETAIL);
709 }
710 if (hdr->sb_len_wr) {
711 snprintf(msgchunk, MAXMSGCHUNK, "Sense Data (%d bytes):", hdr->sb_len_wr);
712 strlcat(msg, msgchunk, MAXERRDETAIL);
713 for (i = 0; i < hdr->sb_len_wr; i++) {
714 snprintf(msgchunk, MAXMSGCHUNK, " %02x", hdr->sbp[i]);
715 strlcat(msg, msgchunk, MAXERRDETAIL);
716 }
717 strlcat(msg, ". ", MAXERRDETAIL);
718 }
719 if (hdr->resid != 0) {
720 snprintf(msgchunk, MAXMSGCHUNK, "SG Driver: %d bytes out of %d not transferred. ", hdr->resid, hdr->dxfer_len);
721 strlcat(msg, msgchunk, MAXERRDETAIL);
722 ret = msg;
723 }
724 }
725
726 if (!ret)
727 ret = strdup("SG Driver did not report a Host, Driver or Device check");
728
729 return ret;
730}
731
732/*
733 * get max file size from read capacity.
734 */
735static int fio_sgio_get_file_size(struct thread_data *td, struct fio_file *f)
736{
737 /*
738 * get_file_size is being called even before sgio_init is
739 * called, so none of the sg_io structures are
740 * initialized in the thread_data yet. So we need to do the
741 * ReadCapacity without any of those helpers. One of the effects
742 * is that ReadCapacity may get called 4 times on each open:
743 * readcap(10) followed by readcap(16) if needed - just to get
744 * the file size after the init occurs - it will be called
745 * again when "type_check" is called during structure
746 * initialization I'm not sure how to prevent this little
747 * inefficiency.
748 */
749 unsigned int bs = 0;
750 unsigned long long max_lba = 0;
751 int ret;
752
753 if (fio_file_size_known(f))
754 return 0;
755
756 ret = fio_sgio_read_capacity(td, &bs, &max_lba);
757 if (ret ) {
758 td_verror(td, td->error, "fio_sgio_read_capacity");
759 log_err("ioengine sg unable to successfully execute read capacity to get block size and maximum lba\n");
760 return 1;
761 }
762
763 f->real_file_size = (max_lba + 1) * bs;
764 fio_file_set_size_known(f);
765 return 0;
766}
767
768
5f350952 769static struct ioengine_ops ioengine = {
2866c82d
JA
770 .name = "sg",
771 .version = FIO_IOOPS_VERSION,
772 .init = fio_sgio_init,
773 .prep = fio_sgio_prep,
774 .queue = fio_sgio_queue,
775 .getevents = fio_sgio_getevents,
5ad7be56 776 .errdetails = fio_sgio_errdetails,
2866c82d
JA
777 .event = fio_sgio_event,
778 .cleanup = fio_sgio_cleanup,
b5af8293
JA
779 .open_file = fio_sgio_open,
780 .close_file = generic_close_file,
5ad7be56 781 .get_file_size = fio_sgio_get_file_size, // generic_get_file_size
b2a15192 782 .flags = FIO_SYNCIO | FIO_RAWIO,
2866c82d 783};
34cfcdaf
JA
784
785#else /* FIO_HAVE_SGIO */
786
787/*
788 * When we have a proper configure system in place, we simply wont build
789 * and install this io engine. For now install a crippled version that
790 * just complains and fails to load.
791 */
792static int fio_sgio_init(struct thread_data fio_unused *td)
793{
a3edaf76 794 log_err("fio: ioengine sg not available\n");
34cfcdaf
JA
795 return 1;
796}
797
5f350952 798static struct ioengine_ops ioengine = {
d0c70934 799 .name = "sg",
34cfcdaf
JA
800 .version = FIO_IOOPS_VERSION,
801 .init = fio_sgio_init,
802};
803
804#endif
5f350952
JA
805
806static void fio_init fio_sgio_register(void)
807{
808 register_ioengine(&ioengine);
809}
810
811static void fio_exit fio_sgio_unregister(void)
812{
813 unregister_ioengine(&ioengine);
814}