Merge branch 'master' of https://github.com/celestinechen/fio
[fio.git] / engines / sg.c
1 /*
2  * sg engine
3  *
4  * IO engine that uses the Linux SG v3 interface to talk to SCSI devices
5  *
6  * This ioengine can operate in two modes:
7  *      sync    with block devices (/dev/sdX) or
8  *              with character devices (/dev/sgY) with direct=1 or sync=1
9  *      async   with character devices with direct=0 and sync=0
10  *
11  * What value does queue() return for the different cases?
12  *                              queue() return value
13  * In sync mode:
14  *  /dev/sdX            RWT     FIO_Q_COMPLETED
15  *  /dev/sgY            RWT     FIO_Q_COMPLETED
16  *   with direct=1 or sync=1
17  *
18  * In async mode:
19  *  /dev/sgY            RWT     FIO_Q_QUEUED
20  *   direct=0 and sync=0
21  *
22  * Because FIO_SYNCIO is set for this ioengine td_io_queue() will fill in
23  * issue_time *before* each IO is sent to queue()
24  *
25  * Where are the IO counting functions called for the different cases?
26  *
27  * In sync mode:
28  *  /dev/sdX (commit==NULL)
29  *   RWT
30  *    io_u_mark_depth()                 called in td_io_queue()
31  *    io_u_mark_submit/complete()       called in td_io_queue()
32  *    issue_time                        set in td_io_queue()
33  *
34  *  /dev/sgY with direct=1 or sync=1 (commit does nothing)
35  *   RWT
36  *    io_u_mark_depth()                 called in td_io_queue()
37  *    io_u_mark_submit/complete()       called in queue()
38  *    issue_time                        set in td_io_queue()
39  *  
40  * In async mode:
41  *  /dev/sgY with direct=0 and sync=0
42  *   RW: read and write operations are submitted in queue()
43  *    io_u_mark_depth()                 called in td_io_commit()
44  *    io_u_mark_submit()                called in queue()
45  *    issue_time                        set in td_io_queue()
46  *   T: trim operations are queued in queue() and submitted in commit()
47  *    io_u_mark_depth()                 called in td_io_commit()
48  *    io_u_mark_submit()                called in commit()
49  *    issue_time                        set in commit()
50  *
51  */
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <unistd.h>
55 #include <errno.h>
56 #include <poll.h>
57
58 #include "../fio.h"
59 #include "../optgroup.h"
60
61 #ifdef FIO_HAVE_SGIO
62
63 #ifndef SGV4_FLAG_HIPRI
64 #define SGV4_FLAG_HIPRI 0x800
65 #endif
66
67 enum {
68         FIO_SG_WRITE            = 1,
69         FIO_SG_WRITE_VERIFY,
70         FIO_SG_WRITE_SAME,
71         FIO_SG_WRITE_SAME_NDOB,
72         FIO_SG_WRITE_STREAM,
73         FIO_SG_VERIFY_BYTCHK_00,
74         FIO_SG_VERIFY_BYTCHK_01,
75         FIO_SG_VERIFY_BYTCHK_11,
76 };
77
78 struct sg_options {
79         void *pad;
80         unsigned int hipri;
81         unsigned int readfua;
82         unsigned int writefua;
83         unsigned int write_mode;
84         uint16_t stream_id;
85 };
86
87 static struct fio_option options[] = {
88         {
89                 .name   = "hipri",
90                 .lname  = "High Priority",
91                 .type   = FIO_OPT_STR_SET,
92                 .off1   = offsetof(struct sg_options, hipri),
93                 .help   = "Use polled IO completions",
94                 .category = FIO_OPT_C_ENGINE,
95                 .group  = FIO_OPT_G_SG,
96         },
97         {
98                 .name   = "readfua",
99                 .lname  = "sg engine read fua flag support",
100                 .type   = FIO_OPT_BOOL,
101                 .off1   = offsetof(struct sg_options, readfua),
102                 .help   = "Set FUA flag (force unit access) for all Read operations",
103                 .def    = "0",
104                 .category = FIO_OPT_C_ENGINE,
105                 .group  = FIO_OPT_G_SG,
106         },
107         {
108                 .name   = "writefua",
109                 .lname  = "sg engine write fua flag support",
110                 .type   = FIO_OPT_BOOL,
111                 .off1   = offsetof(struct sg_options, writefua),
112                 .help   = "Set FUA flag (force unit access) for all Write operations",
113                 .def    = "0",
114                 .category = FIO_OPT_C_ENGINE,
115                 .group  = FIO_OPT_G_SG,
116         },
117         {
118                 .name   = "sg_write_mode",
119                 .lname  = "specify sg write mode",
120                 .type   = FIO_OPT_STR,
121                 .off1   = offsetof(struct sg_options, write_mode),
122                 .help   = "Specify SCSI WRITE mode",
123                 .def    = "write",
124                 .posval = {
125                           { .ival = "write",
126                             .oval = FIO_SG_WRITE,
127                             .help = "Issue standard SCSI WRITE commands",
128                           },
129                           { .ival = "write_and_verify",
130                             .oval = FIO_SG_WRITE_VERIFY,
131                             .help = "Issue SCSI WRITE AND VERIFY commands",
132                           },
133                           { .ival = "verify",
134                             .oval = FIO_SG_WRITE_VERIFY,
135                             .help = "Issue SCSI WRITE AND VERIFY commands. This "
136                                     "option is deprecated. Use write_and_verify instead.",
137                           },
138                           { .ival = "write_same",
139                             .oval = FIO_SG_WRITE_SAME,
140                             .help = "Issue SCSI WRITE SAME commands",
141                           },
142                           { .ival = "same",
143                             .oval = FIO_SG_WRITE_SAME,
144                             .help = "Issue SCSI WRITE SAME commands. This "
145                                     "option is deprecated. Use write_same instead.",
146                           },
147                           { .ival = "write_same_ndob",
148                             .oval = FIO_SG_WRITE_SAME_NDOB,
149                             .help = "Issue SCSI WRITE SAME(16) commands with NDOB flag set",
150                           },
151                           { .ival = "verify_bytchk_00",
152                             .oval = FIO_SG_VERIFY_BYTCHK_00,
153                             .help = "Issue SCSI VERIFY commands with BYTCHK set to 00",
154                           },
155                           { .ival = "verify_bytchk_01",
156                             .oval = FIO_SG_VERIFY_BYTCHK_01,
157                             .help = "Issue SCSI VERIFY commands with BYTCHK set to 01",
158                           },
159                           { .ival = "verify_bytchk_11",
160                             .oval = FIO_SG_VERIFY_BYTCHK_11,
161                             .help = "Issue SCSI VERIFY commands with BYTCHK set to 11",
162                           },
163                           { .ival = "write_stream",
164                             .oval = FIO_SG_WRITE_STREAM,
165                             .help = "Issue SCSI WRITE STREAM(16) commands",
166                           },
167                 },
168                 .category = FIO_OPT_C_ENGINE,
169                 .group  = FIO_OPT_G_SG,
170         },
171         {
172                 .name   = "stream_id",
173                 .lname  = "stream id for WRITE STREAM(16) commands",
174                 .type   = FIO_OPT_INT,
175                 .off1   = offsetof(struct sg_options, stream_id),
176                 .help   = "Stream ID for WRITE STREAM(16) commands",
177                 .def    = "0",
178                 .category = FIO_OPT_C_ENGINE,
179                 .group  = FIO_OPT_G_SG,
180         },
181         {
182                 .name   = NULL,
183         },
184 };
185
186 #define MAX_10B_LBA  0xFFFFFFFFULL
187 #define SCSI_TIMEOUT_MS 30000   // 30 second timeout; currently no method to override
188 #define MAX_SB 64               // sense block maximum return size
189 /*
190 #define FIO_SGIO_DEBUG
191 */
192
193 struct sgio_cmd {
194         unsigned char cdb[16];      // enhanced from 10 to support 16 byte commands
195         unsigned char sb[MAX_SB];   // add sense block to commands
196         int nr;
197 };
198
199 struct sgio_trim {
200         uint8_t *unmap_param;
201         unsigned int unmap_range_count;
202         struct io_u **trim_io_us;
203 };
204
205 struct sgio_data {
206         struct sgio_cmd *cmds;
207         struct io_u **events;
208         struct pollfd *pfds;
209         int *fd_flags;
210         void *sgbuf;
211         unsigned int bs;
212         int type_checked;
213         struct sgio_trim **trim_queues;
214         int current_queue;
215 #ifdef FIO_SGIO_DEBUG
216         unsigned int *trim_queue_map;
217 #endif
218 };
219
220 static inline uint16_t sgio_get_be16(uint8_t *buf)
221 {
222         return be16_to_cpu(*((uint16_t *) buf));
223 }
224
225 static inline uint32_t sgio_get_be32(uint8_t *buf)
226 {
227         return be32_to_cpu(*((uint32_t *) buf));
228 }
229
230 static inline uint64_t sgio_get_be64(uint8_t *buf)
231 {
232         return be64_to_cpu(*((uint64_t *) buf));
233 }
234
235 static inline void sgio_set_be16(uint16_t val, uint8_t *buf)
236 {
237         uint16_t t = cpu_to_be16(val);
238
239         memcpy(buf, &t, sizeof(uint16_t));
240 }
241
242 static inline void sgio_set_be32(uint32_t val, uint8_t *buf)
243 {
244         uint32_t t = cpu_to_be32(val);
245
246         memcpy(buf, &t, sizeof(uint32_t));
247 }
248
249 static inline void sgio_set_be64(uint64_t val, uint8_t *buf)
250 {
251         uint64_t t = cpu_to_be64(val);
252
253         memcpy(buf, &t, sizeof(uint64_t));
254 }
255
256 static inline bool sgio_unbuffered(struct thread_data *td)
257 {
258         return (td->o.odirect || td->o.sync_io);
259 }
260
261 static void sgio_hdr_init(struct sgio_data *sd, struct sg_io_hdr *hdr,
262                           struct io_u *io_u, int fs)
263 {
264         struct sgio_cmd *sc = &sd->cmds[io_u->index];
265
266         memset(hdr, 0, sizeof(*hdr));
267         memset(sc->cdb, 0, sizeof(sc->cdb));
268
269         hdr->interface_id = 'S';
270         hdr->cmdp = sc->cdb;
271         hdr->cmd_len = sizeof(sc->cdb);
272         hdr->sbp = sc->sb;
273         hdr->mx_sb_len = sizeof(sc->sb);
274         hdr->pack_id = io_u->index;
275         hdr->usr_ptr = io_u;
276         hdr->timeout = SCSI_TIMEOUT_MS;
277
278         if (fs) {
279                 hdr->dxferp = io_u->xfer_buf;
280                 hdr->dxfer_len = io_u->xfer_buflen;
281         }
282 }
283
284 static int pollin_events(struct pollfd *pfds, int fds)
285 {
286         int i;
287
288         for (i = 0; i < fds; i++)
289                 if (pfds[i].revents & POLLIN)
290                         return 1;
291
292         return 0;
293 }
294
295 static int sg_fd_read(int fd, void *data, size_t size)
296 {
297         int err = 0;
298
299         while (size) {
300                 ssize_t ret;
301
302                 ret = read(fd, data, size);
303                 if (ret < 0) {
304                         if (errno == EAGAIN || errno == EINTR)
305                                 continue;
306                         err = errno;
307                         break;
308                 } else if (!ret)
309                         break;
310                 else {
311                         data += ret;
312                         size -= ret;
313                 }
314         }
315
316         if (err)
317                 return err;
318         if (size)
319                 return EAGAIN;
320
321         return 0;
322 }
323
324 static int fio_sgio_getevents(struct thread_data *td, unsigned int min,
325                               unsigned int max,
326                               const struct timespec fio_unused *t)
327 {
328         struct sgio_data *sd = td->io_ops_data;
329         int left = max, eventNum, ret, r = 0, trims = 0;
330         void *buf = sd->sgbuf;
331         unsigned int i, j, events;
332         struct fio_file *f;
333         struct io_u *io_u;
334
335         /*
336          * Fill in the file descriptors
337          */
338         for_each_file(td, f, i) {
339                 /*
340                  * don't block for min events == 0
341                  */
342                 if (!min)
343                         sd->fd_flags[i] = fio_set_fd_nonblocking(f->fd, "sg");
344                 else
345                         sd->fd_flags[i] = -1;
346
347                 sd->pfds[i].fd = f->fd;
348                 sd->pfds[i].events = POLLIN;
349         }
350
351         /*
352         ** There are two counters here:
353         **  - number of SCSI commands completed
354         **  - number of io_us completed
355         **
356         ** These are the same with reads and writes, but
357         ** could differ with trim/unmap commands because
358         ** a single unmap can include multiple io_us
359         */
360
361         while (left > 0) {
362                 char *p;
363
364                 dprint(FD_IO, "sgio_getevents: sd %p: min=%d, max=%d, left=%d\n", sd, min, max, left);
365
366                 do {
367                         if (!min)
368                                 break;
369
370                         ret = poll(sd->pfds, td->o.nr_files, -1);
371                         if (ret < 0) {
372                                 if (!r)
373                                         r = -errno;
374                                 td_verror(td, errno, "poll");
375                                 break;
376                         } else if (!ret)
377                                 continue;
378
379                         if (pollin_events(sd->pfds, td->o.nr_files))
380                                 break;
381                 } while (1);
382
383                 if (r < 0)
384                         break;
385
386 re_read:
387                 p = buf;
388                 events = 0;
389                 for_each_file(td, f, i) {
390                         for (eventNum = 0; eventNum < left; eventNum++) {
391                                 ret = sg_fd_read(f->fd, p, sizeof(struct sg_io_hdr));
392                                 dprint(FD_IO, "sgio_getevents: sg_fd_read ret: %d\n", ret);
393                                 if (ret) {
394                                         r = -ret;
395                                         td_verror(td, r, "sg_read");
396                                         break;
397                                 }
398                                 io_u = ((struct sg_io_hdr *)p)->usr_ptr;
399                                 if (io_u->ddir == DDIR_TRIM) {
400                                         events += sd->trim_queues[io_u->index]->unmap_range_count;
401                                         eventNum += sd->trim_queues[io_u->index]->unmap_range_count - 1;
402                                 } else
403                                         events++;
404
405                                 p += sizeof(struct sg_io_hdr);
406                                 dprint(FD_IO, "sgio_getevents: events: %d, eventNum: %d, left: %d\n", events, eventNum, left);
407                         }
408                 }
409
410                 if (r < 0 && !events)
411                         break;
412                 if (!events) {
413                         usleep(1000);
414                         goto re_read;
415                 }
416
417                 left -= events;
418                 r += events;
419
420                 for (i = 0; i < events; i++) {
421                         struct sg_io_hdr *hdr = (struct sg_io_hdr *) buf + i;
422                         sd->events[i + trims] = hdr->usr_ptr;
423                         io_u = (struct io_u *)(hdr->usr_ptr);
424
425                         if (hdr->info & SG_INFO_CHECK) {
426                                 /* record if an io error occurred, ignore resid */
427                                 memcpy(&io_u->hdr, hdr, sizeof(struct sg_io_hdr));
428                                 sd->events[i + trims]->error = EIO;
429                         }
430
431                         if (io_u->ddir == DDIR_TRIM) {
432                                 struct sgio_trim *st = sd->trim_queues[io_u->index];
433 #ifdef FIO_SGIO_DEBUG
434                                 assert(st->trim_io_us[0] == io_u);
435                                 assert(sd->trim_queue_map[io_u->index] == io_u->index);
436                                 dprint(FD_IO, "sgio_getevents: reaping %d io_us from trim queue %d\n", st->unmap_range_count, io_u->index);
437                                 dprint(FD_IO, "sgio_getevents: reaped io_u %d and stored in events[%d]\n", io_u->index, i+trims);
438 #endif
439                                 for (j = 1; j < st->unmap_range_count; j++) {
440                                         ++trims;
441                                         sd->events[i + trims] = st->trim_io_us[j];
442 #ifdef FIO_SGIO_DEBUG
443                                         dprint(FD_IO, "sgio_getevents: reaped io_u %d and stored in events[%d]\n", st->trim_io_us[j]->index, i+trims);
444                                         assert(sd->trim_queue_map[st->trim_io_us[j]->index] == io_u->index);
445 #endif
446                                         if (hdr->info & SG_INFO_CHECK) {
447                                                 /* record if an io error occurred, ignore resid */
448                                                 memcpy(&st->trim_io_us[j]->hdr, hdr, sizeof(struct sg_io_hdr));
449                                                 sd->events[i + trims]->error = EIO;
450                                         }
451                                 }
452                                 events -= st->unmap_range_count - 1;
453                                 st->unmap_range_count = 0;
454                         }
455                 }
456         }
457
458         if (!min) {
459                 for_each_file(td, f, i) {
460                         if (sd->fd_flags[i] == -1)
461                                 continue;
462
463                         if (fcntl(f->fd, F_SETFL, sd->fd_flags[i]) < 0)
464                                 log_err("fio: sg failed to restore fcntl flags: %s\n", strerror(errno));
465                 }
466         }
467
468         return r;
469 }
470
471 static enum fio_q_status fio_sgio_ioctl_doio(struct thread_data *td,
472                                              struct fio_file *f,
473                                              struct io_u *io_u)
474 {
475         struct sgio_data *sd = td->io_ops_data;
476         struct sg_io_hdr *hdr = &io_u->hdr;
477         int ret;
478
479         sd->events[0] = io_u;
480
481         ret = ioctl(f->fd, SG_IO, hdr);
482         if (ret < 0)
483                 return ret;
484
485         /* record if an io error occurred */
486         if (hdr->info & SG_INFO_CHECK)
487                 io_u->error = EIO;
488
489         return FIO_Q_COMPLETED;
490 }
491
492 static enum fio_q_status fio_sgio_rw_doio(struct thread_data *td,
493                                           struct fio_file *f,
494                                           struct io_u *io_u, int do_sync)
495 {
496         struct sg_io_hdr *hdr = &io_u->hdr;
497         int ret;
498
499         ret = write(f->fd, hdr, sizeof(*hdr));
500         if (ret < 0)
501                 return ret;
502
503         if (do_sync) {
504                 /*
505                  * We can't just read back the first command that completes
506                  * and assume it's the one we need, it could be any command
507                  * that is inflight.
508                  */
509                 do {
510                         struct io_u *__io_u;
511
512                         ret = read(f->fd, hdr, sizeof(*hdr));
513                         if (ret < 0)
514                                 return ret;
515
516                         __io_u = hdr->usr_ptr;
517
518                         /* record if an io error occurred */
519                         if (hdr->info & SG_INFO_CHECK)
520                                 __io_u->error = EIO;
521
522                         if (__io_u == io_u)
523                                 break;
524
525                         if (io_u_sync_complete(td, __io_u))
526                                 break;
527
528                 } while (1);
529
530                 return FIO_Q_COMPLETED;
531         }
532
533         return FIO_Q_QUEUED;
534 }
535
536 static enum fio_q_status fio_sgio_doio(struct thread_data *td,
537                                        struct io_u *io_u, int do_sync)
538 {
539         struct fio_file *f = io_u->file;
540         enum fio_q_status ret;
541
542         if (f->filetype == FIO_TYPE_BLOCK) {
543                 ret = fio_sgio_ioctl_doio(td, f, io_u);
544                 if (io_u->error)
545                         td_verror(td, io_u->error, __func__);
546         } else {
547                 ret = fio_sgio_rw_doio(td, f, io_u, do_sync);
548                 if (io_u->error && do_sync)
549                         td_verror(td, io_u->error, __func__);
550         }
551
552         return ret;
553 }
554
555 static void fio_sgio_rw_lba(struct sg_io_hdr *hdr, unsigned long long lba,
556                             unsigned long long nr_blocks, bool override16)
557 {
558         if (lba < MAX_10B_LBA && !override16) {
559                 sgio_set_be32((uint32_t) lba, &hdr->cmdp[2]);
560                 sgio_set_be16((uint16_t) nr_blocks, &hdr->cmdp[7]);
561         } else {
562                 sgio_set_be64(lba, &hdr->cmdp[2]);
563                 sgio_set_be32((uint32_t) nr_blocks, &hdr->cmdp[10]);
564         }
565
566         return;
567 }
568
569 static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u)
570 {
571         struct sg_io_hdr *hdr = &io_u->hdr;
572         struct sg_options *o = td->eo;
573         struct sgio_data *sd = td->io_ops_data;
574         unsigned long long nr_blocks, lba;
575         int offset;
576
577         if (io_u->xfer_buflen & (sd->bs - 1)) {
578                 log_err("read/write not sector aligned\n");
579                 return EINVAL;
580         }
581
582         nr_blocks = io_u->xfer_buflen / sd->bs;
583         lba = io_u->offset / sd->bs;
584
585         if (io_u->ddir == DDIR_READ) {
586                 sgio_hdr_init(sd, hdr, io_u, 1);
587
588                 hdr->dxfer_direction = SG_DXFER_FROM_DEV;
589                 if (lba < MAX_10B_LBA)
590                         hdr->cmdp[0] = 0x28; // read(10)
591                 else
592                         hdr->cmdp[0] = 0x88; // read(16)
593
594                 if (o->hipri)
595                         hdr->flags |= SGV4_FLAG_HIPRI;
596                 if (o->readfua)
597                         hdr->cmdp[1] |= 0x08;
598
599                 fio_sgio_rw_lba(hdr, lba, nr_blocks, false);
600
601         } else if (io_u->ddir == DDIR_WRITE) {
602                 sgio_hdr_init(sd, hdr, io_u, 1);
603
604                 hdr->dxfer_direction = SG_DXFER_TO_DEV;
605                 switch(o->write_mode) {
606                 case FIO_SG_WRITE:
607                         if (lba < MAX_10B_LBA)
608                                 hdr->cmdp[0] = 0x2a; // write(10)
609                         else
610                                 hdr->cmdp[0] = 0x8a; // write(16)
611                         if (o->hipri)
612                                 hdr->flags |= SGV4_FLAG_HIPRI;
613                         if (o->writefua)
614                                 hdr->cmdp[1] |= 0x08;
615                         break;
616                 case FIO_SG_WRITE_VERIFY:
617                         if (lba < MAX_10B_LBA)
618                                 hdr->cmdp[0] = 0x2e; // write and verify(10)
619                         else
620                                 hdr->cmdp[0] = 0x8e; // write and verify(16)
621                         break;
622                         // BYTCHK is disabled by virtue of the memset in sgio_hdr_init
623                 case FIO_SG_WRITE_SAME:
624                         hdr->dxfer_len = sd->bs;
625                         if (lba < MAX_10B_LBA)
626                                 hdr->cmdp[0] = 0x41; // write same(10)
627                         else
628                                 hdr->cmdp[0] = 0x93; // write same(16)
629                         break;
630                 case FIO_SG_WRITE_SAME_NDOB:
631                         hdr->cmdp[0] = 0x93; // write same(16)
632                         hdr->cmdp[1] |= 0x1; // no data output buffer
633                         hdr->dxfer_len = 0;
634                         break;
635                 case FIO_SG_WRITE_STREAM:
636                         hdr->cmdp[0] = 0x9a; // write stream (16)
637                         if (o->writefua)
638                                 hdr->cmdp[1] |= 0x08;
639                         sgio_set_be64(lba, &hdr->cmdp[2]);
640                         sgio_set_be16((uint16_t) io_u->file->engine_pos, &hdr->cmdp[10]);
641                         sgio_set_be16((uint16_t) nr_blocks, &hdr->cmdp[12]);
642                         break;
643                 case FIO_SG_VERIFY_BYTCHK_00:
644                         if (lba < MAX_10B_LBA)
645                                 hdr->cmdp[0] = 0x2f; // VERIFY(10)
646                         else
647                                 hdr->cmdp[0] = 0x8f; // VERIFY(16)
648                         hdr->dxfer_len = 0;
649                         break;
650                 case FIO_SG_VERIFY_BYTCHK_01:
651                         if (lba < MAX_10B_LBA)
652                                 hdr->cmdp[0] = 0x2f; // VERIFY(10)
653                         else
654                                 hdr->cmdp[0] = 0x8f; // VERIFY(16)
655                         hdr->cmdp[1] |= 0x02;           // BYTCHK = 01b
656                         break;
657                 case FIO_SG_VERIFY_BYTCHK_11:
658                         if (lba < MAX_10B_LBA)
659                                 hdr->cmdp[0] = 0x2f; // VERIFY(10)
660                         else
661                                 hdr->cmdp[0] = 0x8f; // VERIFY(16)
662                         hdr->cmdp[1] |= 0x06;           // BYTCHK = 11b
663                         hdr->dxfer_len = sd->bs;
664                         break;
665                 };
666
667                 if (o->write_mode != FIO_SG_WRITE_STREAM)
668                         fio_sgio_rw_lba(hdr, lba, nr_blocks,
669                                 o->write_mode == FIO_SG_WRITE_SAME_NDOB);
670
671         } else if (io_u->ddir == DDIR_TRIM) {
672                 struct sgio_trim *st;
673
674                 if (sd->current_queue == -1) {
675                         sgio_hdr_init(sd, hdr, io_u, 0);
676
677                         hdr->cmd_len = 10;
678                         hdr->dxfer_direction = SG_DXFER_TO_DEV;
679                         hdr->cmdp[0] = 0x42; // unmap
680                         sd->current_queue = io_u->index;
681                         st = sd->trim_queues[sd->current_queue];
682                         hdr->dxferp = st->unmap_param;
683 #ifdef FIO_SGIO_DEBUG
684                         assert(sd->trim_queues[io_u->index]->unmap_range_count == 0);
685                         dprint(FD_IO, "sg: creating new queue based on io_u %d\n", io_u->index);
686 #endif
687                 }
688                 else
689                         st = sd->trim_queues[sd->current_queue];
690
691                 dprint(FD_IO, "sg: adding io_u %d to trim queue %d\n", io_u->index, sd->current_queue);
692                 st->trim_io_us[st->unmap_range_count] = io_u;
693 #ifdef FIO_SGIO_DEBUG
694                 sd->trim_queue_map[io_u->index] = sd->current_queue;
695 #endif
696
697                 offset = 8 + 16 * st->unmap_range_count;
698                 sgio_set_be64(lba, &st->unmap_param[offset]);
699                 sgio_set_be32((uint32_t) nr_blocks, &st->unmap_param[offset + 8]);
700
701                 st->unmap_range_count++;
702
703         } else if (ddir_sync(io_u->ddir)) {
704                 sgio_hdr_init(sd, hdr, io_u, 0);
705                 hdr->dxfer_direction = SG_DXFER_NONE;
706                 if (lba < MAX_10B_LBA)
707                         hdr->cmdp[0] = 0x35; // synccache(10)
708                 else
709                         hdr->cmdp[0] = 0x91; // synccache(16)
710         } else
711                 assert(0);
712
713         return 0;
714 }
715
716 static void fio_sgio_unmap_setup(struct sg_io_hdr *hdr, struct sgio_trim *st)
717 {
718         uint16_t cnt = st->unmap_range_count * 16;
719
720         hdr->dxfer_len = cnt + 8;
721         sgio_set_be16(cnt + 8, &hdr->cmdp[7]);
722         sgio_set_be16(cnt + 6, st->unmap_param);
723         sgio_set_be16(cnt, &st->unmap_param[2]);
724
725         return;
726 }
727
728 static enum fio_q_status fio_sgio_queue(struct thread_data *td,
729                                         struct io_u *io_u)
730 {
731         struct sg_io_hdr *hdr = &io_u->hdr;
732         struct sgio_data *sd = td->io_ops_data;
733         int ret, do_sync = 0;
734
735         fio_ro_check(td, io_u);
736
737         if (sgio_unbuffered(td) || ddir_sync(io_u->ddir))
738                 do_sync = 1;
739
740         if (io_u->ddir == DDIR_TRIM) {
741                 if (do_sync || io_u->file->filetype == FIO_TYPE_BLOCK) {
742                         struct sgio_trim *st = sd->trim_queues[sd->current_queue];
743
744                         /* finish cdb setup for unmap because we are
745                         ** doing unmap commands synchronously */
746 #ifdef FIO_SGIO_DEBUG
747                         assert(st->unmap_range_count == 1);
748                         assert(io_u == st->trim_io_us[0]);
749 #endif
750                         hdr = &io_u->hdr;
751
752                         fio_sgio_unmap_setup(hdr, st);
753
754                         st->unmap_range_count = 0;
755                         sd->current_queue = -1;
756                 } else
757                         /* queue up trim ranges and submit in commit() */
758                         return FIO_Q_QUEUED;
759         }
760
761         ret = fio_sgio_doio(td, io_u, do_sync);
762
763         if (ret < 0)
764                 io_u->error = errno;
765         else if (hdr->status) {
766                 io_u->resid = hdr->resid;
767                 io_u->error = EIO;
768         } else if (td->io_ops->commit != NULL) {
769                 if (do_sync && !ddir_sync(io_u->ddir)) {
770                         io_u_mark_submit(td, 1);
771                         io_u_mark_complete(td, 1);
772                 } else if (io_u->ddir == DDIR_READ || io_u->ddir == DDIR_WRITE) {
773                         io_u_mark_submit(td, 1);
774                         io_u_queued(td, io_u);
775                 }
776         }
777
778         if (io_u->error) {
779                 td_verror(td, io_u->error, "xfer");
780                 return FIO_Q_COMPLETED;
781         }
782
783         return ret;
784 }
785
786 static int fio_sgio_commit(struct thread_data *td)
787 {
788         struct sgio_data *sd = td->io_ops_data;
789         struct sgio_trim *st;
790         struct io_u *io_u;
791         struct sg_io_hdr *hdr;
792         struct timespec now;
793         unsigned int i;
794         int ret;
795
796         if (sd->current_queue == -1)
797                 return 0;
798
799         st = sd->trim_queues[sd->current_queue];
800         io_u = st->trim_io_us[0];
801         hdr = &io_u->hdr;
802
803         fio_sgio_unmap_setup(hdr, st);
804
805         sd->current_queue = -1;
806
807         ret = fio_sgio_rw_doio(td, io_u->file, io_u, 0);
808
809         if (ret < 0 || hdr->status) {
810                 int error;
811
812                 if (ret < 0)
813                         error = errno;
814                 else {
815                         error = EIO;
816                         ret = -EIO;
817                 }
818
819                 for (i = 0; i < st->unmap_range_count; i++) {
820                         st->trim_io_us[i]->error = error;
821                         clear_io_u(td, st->trim_io_us[i]);
822                         if (hdr->status)
823                                 st->trim_io_us[i]->resid = hdr->resid;
824                 }
825
826                 td_verror(td, error, "xfer");
827                 return ret;
828         }
829
830         if (fio_fill_issue_time(td)) {
831                 fio_gettime(&now, NULL);
832                 for (i = 0; i < st->unmap_range_count; i++) {
833                         memcpy(&st->trim_io_us[i]->issue_time, &now, sizeof(now));
834                         io_u_queued(td, io_u);
835                 }
836         }
837         io_u_mark_submit(td, st->unmap_range_count);
838
839         return 0;
840 }
841
842 static struct io_u *fio_sgio_event(struct thread_data *td, int event)
843 {
844         struct sgio_data *sd = td->io_ops_data;
845
846         return sd->events[event];
847 }
848
849 static int fio_sgio_read_capacity(struct thread_data *td, unsigned int *bs,
850                                   unsigned long long *max_lba)
851 {
852         /*
853          * need to do read capacity operation w/o benefit of sd or
854          * io_u structures, which are not initialized until later.
855          */
856         struct sg_io_hdr hdr;
857         unsigned long long hlba;
858         unsigned int blksz = 0;
859         unsigned char cmd[16];
860         unsigned char sb[64];
861         unsigned char buf[32];  // read capacity return
862         int ret;
863         int fd = -1;
864
865         struct fio_file *f = td->files[0];
866
867         /* open file independent of rest of application */
868         fd = open(f->file_name, O_RDONLY);
869         if (fd < 0)
870                 return -errno;
871
872         memset(&hdr, 0, sizeof(hdr));
873         memset(cmd, 0, sizeof(cmd));
874         memset(sb, 0, sizeof(sb));
875         memset(buf, 0, sizeof(buf));
876
877         /* First let's try a 10 byte read capacity. */
878         hdr.interface_id = 'S';
879         hdr.cmdp = cmd;
880         hdr.cmd_len = 10;
881         hdr.sbp = sb;
882         hdr.mx_sb_len = sizeof(sb);
883         hdr.timeout = SCSI_TIMEOUT_MS;
884         hdr.cmdp[0] = 0x25;  // Read Capacity(10)
885         hdr.dxfer_direction = SG_DXFER_FROM_DEV;
886         hdr.dxferp = buf;
887         hdr.dxfer_len = sizeof(buf);
888
889         ret = ioctl(fd, SG_IO, &hdr);
890         if (ret < 0) {
891                 close(fd);
892                 return ret;
893         }
894
895         if (hdr.info & SG_INFO_CHECK) {
896                 /* RCAP(10) might be unsupported by device. Force RCAP(16) */
897                 hlba = MAX_10B_LBA;
898         } else {
899                 blksz = sgio_get_be32(&buf[4]);
900                 hlba = sgio_get_be32(buf);
901         }
902
903         /*
904          * If max lba masked by MAX_10B_LBA equals MAX_10B_LBA,
905          * then need to retry with 16 byte Read Capacity command.
906          */
907         if (hlba == MAX_10B_LBA) {
908                 hdr.cmd_len = 16;
909                 hdr.cmdp[0] = 0x9e; // service action
910                 hdr.cmdp[1] = 0x10; // Read Capacity(16)
911                 sgio_set_be32(sizeof(buf), &hdr.cmdp[10]);
912
913                 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
914                 hdr.dxferp = buf;
915                 hdr.dxfer_len = sizeof(buf);
916
917                 ret = ioctl(fd, SG_IO, &hdr);
918                 if (ret < 0) {
919                         close(fd);
920                         return ret;
921                 }
922
923                 /* record if an io error occurred */
924                 if (hdr.info & SG_INFO_CHECK)
925                         td_verror(td, EIO, "fio_sgio_read_capacity");
926
927                 blksz = sgio_get_be32(&buf[8]);
928                 hlba = sgio_get_be64(buf);
929         }
930
931         if (blksz) {
932                 *bs = blksz;
933                 *max_lba = hlba;
934                 ret = 0;
935         } else {
936                 ret = EIO;
937         }
938
939         close(fd);
940         return ret;
941 }
942
943 static void fio_sgio_cleanup(struct thread_data *td)
944 {
945         struct sgio_data *sd = td->io_ops_data;
946         int i;
947
948         if (sd) {
949                 free(sd->events);
950                 free(sd->cmds);
951                 free(sd->fd_flags);
952                 free(sd->pfds);
953                 free(sd->sgbuf);
954 #ifdef FIO_SGIO_DEBUG
955                 free(sd->trim_queue_map);
956 #endif
957
958                 for (i = 0; i < td->o.iodepth; i++) {
959                         free(sd->trim_queues[i]->unmap_param);
960                         free(sd->trim_queues[i]->trim_io_us);
961                         free(sd->trim_queues[i]);
962                 }
963
964                 free(sd->trim_queues);
965                 free(sd);
966         }
967 }
968
969 static int fio_sgio_init(struct thread_data *td)
970 {
971         struct sgio_data *sd;
972         struct sgio_trim *st;
973         struct sg_io_hdr *h3p;
974         int i;
975
976         sd = calloc(1, sizeof(*sd));
977         sd->cmds = calloc(td->o.iodepth, sizeof(struct sgio_cmd));
978         sd->sgbuf = calloc(td->o.iodepth, sizeof(struct sg_io_hdr));
979         sd->events = calloc(td->o.iodepth, sizeof(struct io_u *));
980         sd->pfds = calloc(td->o.nr_files, sizeof(struct pollfd));
981         sd->fd_flags = calloc(td->o.nr_files, sizeof(int));
982         sd->type_checked = 0;
983
984         sd->trim_queues = calloc(td->o.iodepth, sizeof(struct sgio_trim *));
985         sd->current_queue = -1;
986 #ifdef FIO_SGIO_DEBUG
987         sd->trim_queue_map = calloc(td->o.iodepth, sizeof(int));
988 #endif
989         for (i = 0, h3p = sd->sgbuf; i < td->o.iodepth; i++, ++h3p) {
990                 sd->trim_queues[i] = calloc(1, sizeof(struct sgio_trim));
991                 st = sd->trim_queues[i];
992                 st->unmap_param = calloc(td->o.iodepth + 1, sizeof(char[16]));
993                 st->unmap_range_count = 0;
994                 st->trim_io_us = calloc(td->o.iodepth, sizeof(struct io_u *));
995                 h3p->interface_id = 'S';
996         }
997
998         td->io_ops_data = sd;
999
1000         /*
1001          * we want to do it, regardless of whether odirect is set or not
1002          */
1003         td->o.override_sync = 1;
1004         return 0;
1005 }
1006
1007 static int fio_sgio_type_check(struct thread_data *td, struct fio_file *f)
1008 {
1009         struct sgio_data *sd = td->io_ops_data;
1010         unsigned int bs = 0;
1011         unsigned long long max_lba = 0;
1012
1013         if (f->filetype == FIO_TYPE_BLOCK) {
1014                 if (ioctl(f->fd, BLKSSZGET, &bs) < 0) {
1015                         td_verror(td, errno, "ioctl");
1016                         return 1;
1017                 }
1018         } else if (f->filetype == FIO_TYPE_CHAR) {
1019                 int version, ret;
1020
1021                 if (ioctl(f->fd, SG_GET_VERSION_NUM, &version) < 0) {
1022                         td_verror(td, errno, "ioctl");
1023                         return 1;
1024                 }
1025
1026                 ret = fio_sgio_read_capacity(td, &bs, &max_lba);
1027                 if (ret) {
1028                         td_verror(td, td->error, "fio_sgio_read_capacity");
1029                         log_err("ioengine sg unable to read capacity successfully\n");
1030                         return 1;
1031                 }
1032         } else {
1033                 td_verror(td, EINVAL, "wrong file type");
1034                 log_err("ioengine sg only works on block or character devices\n");
1035                 return 1;
1036         }
1037
1038         sd->bs = bs;
1039         // Determine size of commands needed based on max_lba
1040         if (max_lba >= MAX_10B_LBA) {
1041                 dprint(FD_IO, "sgio_type_check: using 16 byte read/write "
1042                         "commands for lba above 0x%016llx/0x%016llx\n",
1043                         MAX_10B_LBA, max_lba);
1044         }
1045
1046         if (f->filetype == FIO_TYPE_BLOCK) {
1047                 td->io_ops->getevents = NULL;
1048                 td->io_ops->event = NULL;
1049                 td->io_ops->commit = NULL;
1050                 /*
1051                 ** Setting these functions to null may cause problems
1052                 ** with filename=/dev/sda:/dev/sg0 since we are only
1053                 ** considering a single file
1054                 */
1055         }
1056         sd->type_checked = 1;
1057
1058         return 0;
1059 }
1060
1061 static int fio_sgio_stream_control(struct fio_file *f, bool open_stream, uint16_t *stream_id)
1062 {
1063         struct sg_io_hdr hdr;
1064         unsigned char cmd[16];
1065         unsigned char sb[64];
1066         unsigned char buf[8];
1067         int ret;
1068
1069         memset(&hdr, 0, sizeof(hdr));
1070         memset(cmd, 0, sizeof(cmd));
1071         memset(sb, 0, sizeof(sb));
1072         memset(buf, 0, sizeof(buf));
1073
1074         hdr.interface_id = 'S';
1075         hdr.cmdp = cmd;
1076         hdr.cmd_len = 16;
1077         hdr.sbp = sb;
1078         hdr.mx_sb_len = sizeof(sb);
1079         hdr.timeout = SCSI_TIMEOUT_MS;
1080         hdr.cmdp[0] = 0x9e;
1081         hdr.dxfer_direction = SG_DXFER_FROM_DEV;
1082         hdr.dxferp = buf;
1083         hdr.dxfer_len = sizeof(buf);
1084         sgio_set_be32(sizeof(buf), &hdr.cmdp[10]);
1085
1086         if (open_stream)
1087                 hdr.cmdp[1] = 0x34;
1088         else {
1089                 hdr.cmdp[1] = 0x54;
1090                 sgio_set_be16(*stream_id, &hdr.cmdp[4]);
1091         }
1092
1093         ret = ioctl(f->fd, SG_IO, &hdr);
1094
1095         if (ret < 0)
1096                 return ret;
1097
1098         if (hdr.info & SG_INFO_CHECK)
1099                 return 1;
1100
1101         if (open_stream) {
1102                 *stream_id = sgio_get_be16(&buf[4]);
1103                 dprint(FD_FILE, "sgio_stream_control: opened stream %u\n", (unsigned int) *stream_id);
1104                 assert(*stream_id != 0);
1105         } else
1106                 dprint(FD_FILE, "sgio_stream_control: closed stream %u\n", (unsigned int) *stream_id);
1107
1108         return 0;
1109 }
1110
1111 static int fio_sgio_open(struct thread_data *td, struct fio_file *f)
1112 {
1113         struct sgio_data *sd = td->io_ops_data;
1114         struct sg_options *o = td->eo;
1115         int ret;
1116
1117         ret = generic_open_file(td, f);
1118         if (ret)
1119                 return ret;
1120
1121         if (sd && !sd->type_checked && fio_sgio_type_check(td, f)) {
1122                 ret = generic_close_file(td, f);
1123                 return ret;
1124         }
1125
1126         if (o->write_mode == FIO_SG_WRITE_STREAM) {
1127                 if (o->stream_id)
1128                         f->engine_pos = o->stream_id;
1129                 else {
1130                         ret = fio_sgio_stream_control(f, true, (uint16_t *) &f->engine_pos);
1131                         if (ret)
1132                                 return ret;
1133                 }
1134         }
1135
1136         return 0;
1137 }
1138
1139 int fio_sgio_close(struct thread_data *td, struct fio_file *f)
1140 {
1141         struct sg_options *o = td->eo;
1142         int ret;
1143
1144         if (!o->stream_id && o->write_mode == FIO_SG_WRITE_STREAM) {
1145                 ret = fio_sgio_stream_control(f, false, (uint16_t *) &f->engine_pos);
1146                 if (ret)
1147                         return ret;
1148         }
1149
1150         return generic_close_file(td, f);
1151 }
1152
1153 /*
1154  * Build an error string with details about the driver, host or scsi
1155  * error contained in the sg header Caller will use as necessary.
1156  */
1157 static char *fio_sgio_errdetails(struct io_u *io_u)
1158 {
1159         struct sg_io_hdr *hdr = &io_u->hdr;
1160 #define MAXERRDETAIL 1024
1161 #define MAXMSGCHUNK  128
1162         char *msg, msgchunk[MAXMSGCHUNK];
1163         int i;
1164
1165         msg = calloc(1, MAXERRDETAIL);
1166         strcpy(msg, "");
1167
1168         /*
1169          * can't seem to find sg_err.h, so I'll just echo the define values
1170          * so others can search on internet to find clearer clues of meaning.
1171          */
1172         if (hdr->info & SG_INFO_CHECK) {
1173                 if (hdr->host_status) {
1174                         snprintf(msgchunk, MAXMSGCHUNK, "SG Host Status: 0x%02x; ", hdr->host_status);
1175                         strlcat(msg, msgchunk, MAXERRDETAIL);
1176                         switch (hdr->host_status) {
1177                         case 0x01:
1178                                 strlcat(msg, "SG_ERR_DID_NO_CONNECT", MAXERRDETAIL);
1179                                 break;
1180                         case 0x02:
1181                                 strlcat(msg, "SG_ERR_DID_BUS_BUSY", MAXERRDETAIL);
1182                                 break;
1183                         case 0x03:
1184                                 strlcat(msg, "SG_ERR_DID_TIME_OUT", MAXERRDETAIL);
1185                                 break;
1186                         case 0x04:
1187                                 strlcat(msg, "SG_ERR_DID_BAD_TARGET", MAXERRDETAIL);
1188                                 break;
1189                         case 0x05:
1190                                 strlcat(msg, "SG_ERR_DID_ABORT", MAXERRDETAIL);
1191                                 break;
1192                         case 0x06:
1193                                 strlcat(msg, "SG_ERR_DID_PARITY", MAXERRDETAIL);
1194                                 break;
1195                         case 0x07:
1196                                 strlcat(msg, "SG_ERR_DID_ERROR (internal error)", MAXERRDETAIL);
1197                                 break;
1198                         case 0x08:
1199                                 strlcat(msg, "SG_ERR_DID_RESET", MAXERRDETAIL);
1200                                 break;
1201                         case 0x09:
1202                                 strlcat(msg, "SG_ERR_DID_BAD_INTR (unexpected)", MAXERRDETAIL);
1203                                 break;
1204                         case 0x0a:
1205                                 strlcat(msg, "SG_ERR_DID_PASSTHROUGH", MAXERRDETAIL);
1206                                 break;
1207                         case 0x0b:
1208                                 strlcat(msg, "SG_ERR_DID_SOFT_ERROR (driver retry?)", MAXERRDETAIL);
1209                                 break;
1210                         case 0x0c:
1211                                 strlcat(msg, "SG_ERR_DID_IMM_RETRY", MAXERRDETAIL);
1212                                 break;
1213                         case 0x0d:
1214                                 strlcat(msg, "SG_ERR_DID_REQUEUE", MAXERRDETAIL);
1215                                 break;
1216                         case 0x0e:
1217                                 strlcat(msg, "SG_ERR_DID_TRANSPORT_DISRUPTED", MAXERRDETAIL);
1218                                 break;
1219                         case 0x0f:
1220                                 strlcat(msg, "SG_ERR_DID_TRANSPORT_FAILFAST", MAXERRDETAIL);
1221                                 break;
1222                         case 0x10:
1223                                 strlcat(msg, "SG_ERR_DID_TARGET_FAILURE", MAXERRDETAIL);
1224                                 break;
1225                         case 0x11:
1226                                 strlcat(msg, "SG_ERR_DID_NEXUS_FAILURE", MAXERRDETAIL);
1227                                 break;
1228                         case 0x12:
1229                                 strlcat(msg, "SG_ERR_DID_ALLOC_FAILURE", MAXERRDETAIL);
1230                                 break;
1231                         case 0x13:
1232                                 strlcat(msg, "SG_ERR_DID_MEDIUM_ERROR", MAXERRDETAIL);
1233                                 break;
1234                         default:
1235                                 strlcat(msg, "Unknown", MAXERRDETAIL);
1236                                 break;
1237                         }
1238                         strlcat(msg, ". ", MAXERRDETAIL);
1239                 }
1240                 if (hdr->driver_status) {
1241                         snprintf(msgchunk, MAXMSGCHUNK, "SG Driver Status: 0x%02x; ", hdr->driver_status);
1242                         strlcat(msg, msgchunk, MAXERRDETAIL);
1243                         switch (hdr->driver_status & 0x0F) {
1244                         case 0x01:
1245                                 strlcat(msg, "SG_ERR_DRIVER_BUSY", MAXERRDETAIL);
1246                                 break;
1247                         case 0x02:
1248                                 strlcat(msg, "SG_ERR_DRIVER_SOFT", MAXERRDETAIL);
1249                                 break;
1250                         case 0x03:
1251                                 strlcat(msg, "SG_ERR_DRIVER_MEDIA", MAXERRDETAIL);
1252                                 break;
1253                         case 0x04:
1254                                 strlcat(msg, "SG_ERR_DRIVER_ERROR", MAXERRDETAIL);
1255                                 break;
1256                         case 0x05:
1257                                 strlcat(msg, "SG_ERR_DRIVER_INVALID", MAXERRDETAIL);
1258                                 break;
1259                         case 0x06:
1260                                 strlcat(msg, "SG_ERR_DRIVER_TIMEOUT", MAXERRDETAIL);
1261                                 break;
1262                         case 0x07:
1263                                 strlcat(msg, "SG_ERR_DRIVER_HARD", MAXERRDETAIL);
1264                                 break;
1265                         case 0x08:
1266                                 strlcat(msg, "SG_ERR_DRIVER_SENSE", MAXERRDETAIL);
1267                                 break;
1268                         default:
1269                                 strlcat(msg, "Unknown", MAXERRDETAIL);
1270                                 break;
1271                         }
1272                         strlcat(msg, "; ", MAXERRDETAIL);
1273                         switch (hdr->driver_status & 0xF0) {
1274                         case 0x10:
1275                                 strlcat(msg, "SG_ERR_SUGGEST_RETRY", MAXERRDETAIL);
1276                                 break;
1277                         case 0x20:
1278                                 strlcat(msg, "SG_ERR_SUGGEST_ABORT", MAXERRDETAIL);
1279                                 break;
1280                         case 0x30:
1281                                 strlcat(msg, "SG_ERR_SUGGEST_REMAP", MAXERRDETAIL);
1282                                 break;
1283                         case 0x40:
1284                                 strlcat(msg, "SG_ERR_SUGGEST_DIE", MAXERRDETAIL);
1285                                 break;
1286                         case 0x80:
1287                                 strlcat(msg, "SG_ERR_SUGGEST_SENSE", MAXERRDETAIL);
1288                                 break;
1289                         }
1290                         strlcat(msg, ". ", MAXERRDETAIL);
1291                 }
1292                 if (hdr->status) {
1293                         snprintf(msgchunk, MAXMSGCHUNK, "SG SCSI Status: 0x%02x; ", hdr->status);
1294                         strlcat(msg, msgchunk, MAXERRDETAIL);
1295                         // SCSI 3 status codes
1296                         switch (hdr->status) {
1297                         case 0x02:
1298                                 strlcat(msg, "CHECK_CONDITION", MAXERRDETAIL);
1299                                 break;
1300                         case 0x04:
1301                                 strlcat(msg, "CONDITION_MET", MAXERRDETAIL);
1302                                 break;
1303                         case 0x08:
1304                                 strlcat(msg, "BUSY", MAXERRDETAIL);
1305                                 break;
1306                         case 0x10:
1307                                 strlcat(msg, "INTERMEDIATE", MAXERRDETAIL);
1308                                 break;
1309                         case 0x14:
1310                                 strlcat(msg, "INTERMEDIATE_CONDITION_MET", MAXERRDETAIL);
1311                                 break;
1312                         case 0x18:
1313                                 strlcat(msg, "RESERVATION_CONFLICT", MAXERRDETAIL);
1314                                 break;
1315                         case 0x22:
1316                                 strlcat(msg, "COMMAND_TERMINATED", MAXERRDETAIL);
1317                                 break;
1318                         case 0x28:
1319                                 strlcat(msg, "TASK_SET_FULL", MAXERRDETAIL);
1320                                 break;
1321                         case 0x30:
1322                                 strlcat(msg, "ACA_ACTIVE", MAXERRDETAIL);
1323                                 break;
1324                         case 0x40:
1325                                 strlcat(msg, "TASK_ABORTED", MAXERRDETAIL);
1326                                 break;
1327                         default:
1328                                 strlcat(msg, "Unknown", MAXERRDETAIL);
1329                                 break;
1330                         }
1331                         strlcat(msg, ". ", MAXERRDETAIL);
1332                 }
1333                 if (hdr->sb_len_wr) {
1334                         const uint8_t *const sbp = hdr->sbp;
1335
1336                         snprintf(msgchunk, MAXMSGCHUNK, "Sense Data (%d bytes):", hdr->sb_len_wr);
1337                         strlcat(msg, msgchunk, MAXERRDETAIL);
1338                         for (i = 0; i < hdr->sb_len_wr; i++) {
1339                                 snprintf(msgchunk, MAXMSGCHUNK, " %02x", sbp[i]);
1340                                 strlcat(msg, msgchunk, MAXERRDETAIL);
1341                         }
1342                         strlcat(msg, ". ", MAXERRDETAIL);
1343                 }
1344                 if (hdr->resid != 0) {
1345                         snprintf(msgchunk, MAXMSGCHUNK, "SG Driver: %d bytes out of %d not transferred. ", hdr->resid, hdr->dxfer_len);
1346                         strlcat(msg, msgchunk, MAXERRDETAIL);
1347                 }
1348                 if (hdr->cmdp) {
1349                         strlcat(msg, "cdb:", MAXERRDETAIL);
1350                         for (i = 0; i < hdr->cmd_len; i++) {
1351                                 snprintf(msgchunk, MAXMSGCHUNK, " %02x", hdr->cmdp[i]);
1352                                 strlcat(msg, msgchunk, MAXERRDETAIL);
1353                         }
1354                         strlcat(msg, ". ", MAXERRDETAIL);
1355                         if (io_u->ddir == DDIR_TRIM) {
1356                                 unsigned char *param_list = hdr->dxferp;
1357                                 strlcat(msg, "dxferp:", MAXERRDETAIL);
1358                                 for (i = 0; i < hdr->dxfer_len; i++) {
1359                                         snprintf(msgchunk, MAXMSGCHUNK, " %02x", param_list[i]);
1360                                         strlcat(msg, msgchunk, MAXERRDETAIL);
1361                                 }
1362                                 strlcat(msg, ". ", MAXERRDETAIL);
1363                         }
1364                 }
1365         }
1366
1367         if (!(hdr->info & SG_INFO_CHECK) && !strlen(msg))
1368                 snprintf(msg, MAXERRDETAIL, "%s",
1369                          "SG Driver did not report a Host, Driver or Device check");
1370
1371         return msg;
1372 }
1373
1374 /*
1375  * get max file size from read capacity.
1376  */
1377 static int fio_sgio_get_file_size(struct thread_data *td, struct fio_file *f)
1378 {
1379         /*
1380          * get_file_size is being called even before sgio_init is
1381          * called, so none of the sg_io structures are
1382          * initialized in the thread_data yet.  So we need to do the
1383          * ReadCapacity without any of those helpers.  One of the effects
1384          * is that ReadCapacity may get called 4 times on each open:
1385          * readcap(10) followed by readcap(16) if needed - just to get
1386          * the file size after the init occurs - it will be called
1387          * again when "type_check" is called during structure
1388          * initialization I'm not sure how to prevent this little
1389          * inefficiency.
1390          */
1391         unsigned int bs = 0;
1392         unsigned long long max_lba = 0;
1393         int ret;
1394
1395         if (fio_file_size_known(f))
1396                 return 0;
1397
1398         if (f->filetype != FIO_TYPE_BLOCK && f->filetype != FIO_TYPE_CHAR) {
1399                 td_verror(td, EINVAL, "wrong file type");
1400                 log_err("ioengine sg only works on block or character devices\n");
1401                 return 1;
1402         }
1403
1404         ret = fio_sgio_read_capacity(td, &bs, &max_lba);
1405         if (ret ) {
1406                 td_verror(td, td->error, "fio_sgio_read_capacity");
1407                 log_err("ioengine sg unable to successfully execute read capacity to get block size and maximum lba\n");
1408                 return 1;
1409         }
1410
1411         f->real_file_size = (max_lba + 1) * bs;
1412         fio_file_set_size_known(f);
1413         return 0;
1414 }
1415
1416
1417 static struct ioengine_ops ioengine = {
1418         .name           = "sg",
1419         .version        = FIO_IOOPS_VERSION,
1420         .init           = fio_sgio_init,
1421         .prep           = fio_sgio_prep,
1422         .queue          = fio_sgio_queue,
1423         .commit         = fio_sgio_commit,
1424         .getevents      = fio_sgio_getevents,
1425         .errdetails     = fio_sgio_errdetails,
1426         .event          = fio_sgio_event,
1427         .cleanup        = fio_sgio_cleanup,
1428         .open_file      = fio_sgio_open,
1429         .close_file     = fio_sgio_close,
1430         .get_file_size  = fio_sgio_get_file_size,
1431         .flags          = FIO_SYNCIO | FIO_RAWIO | FIO_RO_NEEDS_RW_OPEN,
1432         .options        = options,
1433         .option_struct_size     = sizeof(struct sg_options)
1434 };
1435
1436 #else /* FIO_HAVE_SGIO */
1437
1438 /*
1439  * When we have a proper configure system in place, we simply wont build
1440  * and install this io engine. For now install a crippled version that
1441  * just complains and fails to load.
1442  */
1443 static int fio_sgio_init(struct thread_data fio_unused *td)
1444 {
1445         log_err("fio: ioengine sg not available\n");
1446         return 1;
1447 }
1448
1449 static struct ioengine_ops ioengine = {
1450         .name           = "sg",
1451         .version        = FIO_IOOPS_VERSION,
1452         .init           = fio_sgio_init,
1453 };
1454
1455 #endif
1456
1457 static void fio_init fio_sgio_register(void)
1458 {
1459         register_ioengine(&ioengine);
1460 }
1461
1462 static void fio_exit fio_sgio_unregister(void)
1463 {
1464         unregister_ioengine(&ioengine);
1465 }