sg: 16-byte cdb support and lots of fixes
[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  */
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>
13
14 #include "../fio.h"
15
16 #ifdef FIO_HAVE_SGIO
17
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
22 struct sgio_cmd {
23         unsigned char cdb[16];          // increase to support 16 byte commands
24         unsigned char sb[MAX_SB];   // add sense block to commands
25         int nr;
26 };
27
28 struct sgio_data {
29         struct sgio_cmd *cmds;
30         struct io_u **events;
31         struct pollfd *pfds;
32         int *fd_flags;
33         void *sgbuf;
34         unsigned int bs;
35         long long max_lba;
36         int type_checked;
37 };
38
39 static 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);
50         hdr->sbp = sc->sb;
51         hdr->mx_sb_len = sizeof(sc->sb);
52         hdr->pack_id = io_u->index;
53         hdr->usr_ptr = io_u;
54
55         if (fs) {
56                 hdr->dxferp = io_u->xfer_buf;
57                 hdr->dxfer_len = io_u->xfer_buflen;
58         }
59 }
60
61 static 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 }
71
72 static int fio_sgio_getevents(struct thread_data *td, unsigned int min,
73                               unsigned int max,
74                               const struct timespec fio_unused *t)
75 {
76         struct sgio_data *sd = td->io_ops->data;
77         int left = max, eventNum, ret, r = 0;
78         void *buf = sd->sgbuf;
79         unsigned int i, events;
80         struct fio_file *f;
81
82         /*
83          * Fill in the file descriptors
84          */
85         for_each_file(td, f, i) {
86                 /*
87                  * don't block for min events == 0
88                  */
89                 if (!min)
90                         sd->fd_flags[i] = fio_set_fd_nonblocking(f->fd, "sg");
91                 else
92                         sd->fd_flags[i] = -1;
93
94                 sd->pfds[i].fd = f->fd;
95                 sd->pfds[i].events = POLLIN;
96         }
97
98         while (left) {
99                 void *p;
100
101                 dprint(FD_IO, "sgio_getevents: sd %p: left=%d\n", sd, left);
102
103                 do {
104                         if (!min)
105                                 break;
106
107                         ret = poll(sd->pfds, td->o.nr_files, -1);
108                         if (ret < 0) {
109                                 if (!r)
110                                         r = -errno;
111                                 td_verror(td, errno, "poll");
112                                 break;
113                         } else if (!ret)
114                                 continue;
115
116                         if (pollin_events(sd->pfds, td->o.nr_files))
117                                 break;
118                 } while (1);
119
120                 if (r < 0)
121                         break;
122
123 re_read:
124                 p = buf;
125                 events = 0;
126                 for_each_file(td, f, i) {
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                                 }
145                         }
146                 }
147
148                 if (r < 0)
149                         break;
150                 if (!events) {
151                         usleep(1000);
152                         goto re_read;
153                 }
154
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;
160                         sd->events[i] = hdr->usr_ptr;
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                         }
169                 }
170         }
171
172         if (!min) {
173                 for_each_file(td, f, i) {
174                         if (sd->fd_flags[i] == -1)
175                                 continue;
176
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                 }
180         }
181
182         return r;
183 }
184
185 static int fio_sgio_ioctl_doio(struct thread_data *td,
186                                struct fio_file *f, struct io_u *io_u)
187 {
188         struct sgio_data *sd = td->io_ops->data;
189         struct sg_io_hdr *hdr = &io_u->hdr;
190         int ret;
191
192         sd->events[0] = io_u;
193
194         ret = ioctl(f->fd, SG_IO, hdr);
195         if (ret < 0)
196                 return ret;
197
198         /* record if an io error occurred */
199         if (hdr->info & SG_INFO_CHECK)
200                 io_u->error = EIO;
201
202         return FIO_Q_COMPLETED;
203 }
204
205 static int fio_sgio_rw_doio(struct fio_file *f, struct io_u *io_u, int do_sync)
206 {
207         struct sg_io_hdr *hdr = &io_u->hdr;
208         int ret;
209
210         ret = write(f->fd, hdr, sizeof(*hdr));
211         if (ret < 0)
212                 return ret;
213
214         if (do_sync) {
215                 ret = read(f->fd, hdr, sizeof(*hdr));
216                 if (ret < 0)
217                         return ret;
218
219                 /* record if an io error occurred */
220                 if (hdr->info & SG_INFO_CHECK)
221                         io_u->error = EIO;
222
223                 return FIO_Q_COMPLETED;
224         }
225
226         return FIO_Q_QUEUED;
227 }
228
229 static int fio_sgio_doio(struct thread_data *td, struct io_u *io_u, int do_sync)
230 {
231         struct fio_file *f = io_u->file;
232         int ret;
233
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         }
242
243         return ret;
244 }
245
246 static 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;
250         long long nr_blocks, lba;
251
252         if (io_u->xfer_buflen & (sd->bs - 1)) {
253                 log_err("read/write not sector aligned\n");
254                 return EINVAL;
255         }
256
257         nr_blocks = io_u->xfer_buflen / sd->bs;
258         lba = io_u->offset / sd->bs;
259
260         if (io_u->ddir == DDIR_READ) {
261                 sgio_hdr_init(sd, hdr, io_u, 1);
262
263                 hdr->dxfer_direction = SG_DXFER_FROM_DEV;
264                 if (lba < MAX_10B_LBA)
265                         hdr->cmdp[0] = 0x28; // read(10)
266                 else
267                         hdr->cmdp[0] = 0x88; // read(16)
268         } else if (io_u->ddir == DDIR_WRITE) {
269                 sgio_hdr_init(sd, hdr, io_u, 1);
270
271                 hdr->dxfer_direction = SG_DXFER_TO_DEV;
272                 if (lba < MAX_10B_LBA)
273                         hdr->cmdp[0] = 0x2a; // write(10)
274                 else
275                         hdr->cmdp[0] = 0x8a; // write(16)
276         } else {
277                 sgio_hdr_init(sd, hdr, io_u, 0);
278                 hdr->dxfer_direction = SG_DXFER_NONE;
279                 if (lba < MAX_10B_LBA)
280                         hdr->cmdp[0] = 0x35; // synccache(10)
281                 else
282                         hdr->cmdp[0] = 0x91; // synccache(16)
283         }
284
285         /*
286          * for synccache, we leave lba and length to 0 to sync all
287          * blocks on medium.
288          */
289         if (hdr->dxfer_direction != SG_DXFER_NONE) {
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                 }
312         }
313
314         hdr->timeout = SCSI_TIMEOUT_MS;
315         return 0;
316 }
317
318 static int fio_sgio_queue(struct thread_data *td, struct io_u *io_u)
319 {
320         struct sg_io_hdr *hdr = &io_u->hdr;
321         int ret, do_sync = 0;
322
323         fio_ro_check(td, io_u);
324
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);
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
337         if (io_u->error) {
338                 td_verror(td, io_u->error, "xfer");
339                 return FIO_Q_COMPLETED;
340         }
341
342         return ret;
343 }
344
345 static 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
352 static int fio_sgio_read_capacity(struct thread_data *td, unsigned int *bs,
353                                   unsigned long long *max_lba)
354 {
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
363         int ret;
364         int fd = -1;
365
366         struct fio_file *f = td->files[0];
367
368         /* open file independent of rest of application */
369         fd = open(f->file_name, O_RDONLY);
370         if (fd < 0)
371                 return -errno;
372
373         memset(&hdr, 0, sizeof(hdr));
374         memset(cmd, 0, sizeof(cmd));
375         memset(sb, 0, sizeof(sb));
376         memset(buf, 0, sizeof(buf));
377
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);
393                 return ret;
394         }
395
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);
439         return 0;
440 }
441
442 static void fio_sgio_cleanup(struct thread_data *td)
443 {
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);
453         }
454 }
455
456 static int fio_sgio_init(struct thread_data *td)
457 {
458         struct sgio_data *sd;
459
460         sd = malloc(sizeof(*sd));
461         memset(sd, 0, sizeof(*sd));
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);
472         sd->type_checked = 0;
473         td->io_ops->data = sd;
474
475         /*
476          * we want to do it, regardless of whether odirect is set or not
477          */
478         td->o.override_sync = 1;
479         return 0;
480 }
481
482 static int fio_sgio_type_check(struct thread_data *td, struct fio_file *f)
483 {
484         struct sgio_data *sd = td->io_ops->data;
485         unsigned int bs = 0;
486         unsigned long long max_lba = 0;
487
488
489         if (f->filetype == FIO_TYPE_BD) {
490                 if (ioctl(f->fd, BLKSSZGET, &bs) < 0) {
491                         td_verror(td, errno, "ioctl");
492                         return 1;
493                 }
494         } else if (f->filetype == FIO_TYPE_CHAR) {
495                 int version, ret;
496
497                 if (ioctl(f->fd, SG_GET_VERSION_NUM, &version) < 0) {
498                         td_verror(td, errno, "ioctl");
499                         return 1;
500                 }
501
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");
506                         return 1;
507                 }
508         } else {
509                 td_verror(td, EINVAL, "wrong file type");
510                 log_err("ioengine sg only works on block devices\n");
511                 return 1;
512         }
513
514         sd->bs = bs;
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
521
522         if (f->filetype == FIO_TYPE_BD) {
523                 td->io_ops->getevents = NULL;
524                 td->io_ops->event = NULL;
525         }
526         sd->type_checked = 1;
527
528         return 0;
529 }
530
531 static 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
540         if (sd && !sd->type_checked && fio_sgio_type_check(td, f)) {
541                 ret = generic_close_file(td, f);
542                 return 1;
543         }
544
545         return 0;
546 }
547
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  */
552 static 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  */
735 static 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
769 static struct ioengine_ops ioengine = {
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,
776         .errdetails     = fio_sgio_errdetails,
777         .event          = fio_sgio_event,
778         .cleanup        = fio_sgio_cleanup,
779         .open_file      = fio_sgio_open,
780         .close_file     = generic_close_file,
781         .get_file_size  = fio_sgio_get_file_size, // generic_get_file_size
782         .flags          = FIO_SYNCIO | FIO_RAWIO,
783 };
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  */
792 static int fio_sgio_init(struct thread_data fio_unused *td)
793 {
794         log_err("fio: ioengine sg not available\n");
795         return 1;
796 }
797
798 static struct ioengine_ops ioengine = {
799         .name           = "sg",
800         .version        = FIO_IOOPS_VERSION,
801         .init           = fio_sgio_init,
802 };
803
804 #endif
805
806 static void fio_init fio_sgio_register(void)
807 {
808         register_ioengine(&ioengine);
809 }
810
811 static void fio_exit fio_sgio_unregister(void)
812 {
813         unregister_ioengine(&ioengine);
814 }