"Fossies" - the Fresh Open Source Software Archive

Member "hdparm-9.60/sgio.c" (3 Jan 2019, 16192 Bytes) of package /linux/misc/hdparm-9.60.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sgio.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 9.58_vs_9.60.

    1 /* sgio.c - by Mark Lord (C) 2007 -- freely distributable */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #include <unistd.h>
    5 #include <fcntl.h>
    6 #include <errno.h>
    7 #include <string.h>
    8 #include <sys/ioctl.h>
    9 #include <sys/stat.h>
   10 #include <sys/types.h>
   11 
   12 #include <scsi/scsi.h>
   13 #include <scsi/sg.h>
   14 
   15 #include "sgio.h"
   16 #include "hdparm.h"
   17 
   18 #include <linux/hdreg.h>
   19 
   20 extern int verbose;
   21 extern int prefer_ata12;
   22 
   23 static const unsigned int default_timeout_secs = 15;
   24 
   25 /*
   26  * Taskfile layout for SG_ATA_16 cdb:
   27  *
   28  * LBA48:
   29  * cdb[ 3] = hob_feat
   30  * cdb[ 5] = hob_nsect
   31  * cdb[ 7] = hob_lbal
   32  * cdb[ 9] = hob_lbam
   33  * cdb[11] = hob_lbah
   34  *
   35  * LBA28/LBA48:
   36  * cdb[ 4] = feat
   37  * cdb[ 6] = nsect
   38  * cdb[ 8] = lbal
   39  * cdb[10] = lbam
   40  * cdb[12] = lbah
   41  * cdb[13] = device
   42  * cdb[14] = command
   43  *
   44  * Taskfile layout for SG_ATA_12 cdb:
   45  *
   46  * cdb[ 3] = feat
   47  * cdb[ 4] = nsect
   48  * cdb[ 5] = lbal
   49  * cdb[ 6] = lbam
   50  * cdb[ 7] = lbah
   51  * cdb[ 8] = device
   52  * cdb[ 9] = command
   53  *
   54  * dxfer_direction choices:
   55  *  SG_DXFER_TO_DEV, SG_DXFER_FROM_DEV, SG_DXFER_NONE
   56  */
   57 
   58 #if 0  /* maybe use this in sg16 later.. ? */
   59 static inline int get_rw (__u8 ata_op)
   60 {
   61     switch (ata_op) {
   62         case ATA_OP_DSM:
   63         case ATA_OP_WRITE_PIO:
   64         case ATA_OP_WRITE_LONG:
   65         case ATA_OP_WRITE_LONG_ONCE:
   66         case ATA_OP_WRITE_PIO_EXT:
   67         case ATA_OP_WRITE_DMA_EXT:
   68         case ATA_OP_WRITE_FPDMA:
   69         case ATA_OP_WRITE_UNC_EXT:
   70         case ATA_OP_WRITE_DMA:
   71         case ATA_OP_SECURITY_UNLOCK:
   72         case ATA_OP_SECURITY_DISABLE:
   73         case ATA_OP_SECURITY_ERASE_UNIT:
   74         case ATA_OP_SECURITY_SET_PASS:
   75             return SG_WRITE;
   76         default:
   77             return SG_READ;
   78     }
   79 }
   80 #endif
   81 
   82 static inline int needs_lba48 (__u8 ata_op, __u64 lba, unsigned int nsect)
   83 {
   84     switch (ata_op) {
   85         case ATA_OP_DSM:
   86         case ATA_OP_READ_PIO_EXT:
   87         case ATA_OP_READ_DMA_EXT:
   88         case ATA_OP_WRITE_PIO_EXT:
   89         case ATA_OP_WRITE_DMA_EXT:
   90         case ATA_OP_READ_VERIFY_EXT:
   91         case ATA_OP_WRITE_UNC_EXT:
   92         case ATA_OP_READ_NATIVE_MAX_EXT:
   93         case ATA_OP_SET_MAX_EXT:
   94         case ATA_OP_FLUSHCACHE_EXT:
   95             return 1;
   96         case ATA_OP_SECURITY_ERASE_PREPARE:
   97         case ATA_OP_SECURITY_ERASE_UNIT:
   98         case ATA_OP_VENDOR_SPECIFIC_0x80:
   99         case ATA_OP_SMART:
  100             return 0;
  101     }
  102     if (lba >= lba28_limit)
  103         return 1;
  104     if (nsect) {
  105         if (nsect > 0xff)
  106             return 1;
  107         if ((lba + nsect - 1) >= lba28_limit)
  108             return 1;
  109     }
  110     return 0;
  111 }
  112 
  113 static inline int is_dma (__u8 ata_op)
  114 {
  115     switch (ata_op) {
  116         case ATA_OP_DSM:
  117         case ATA_OP_READ_DMA_EXT:
  118         case ATA_OP_READ_FPDMA:
  119         case ATA_OP_WRITE_DMA_EXT:
  120         case ATA_OP_WRITE_FPDMA:
  121         case ATA_OP_READ_DMA:
  122         case ATA_OP_WRITE_DMA:
  123             return SG_DMA;
  124         default:
  125             return SG_PIO;
  126     }
  127 }
  128 
  129 void tf_init (struct ata_tf *tf, __u8 ata_op, __u64 lba, unsigned int nsect)
  130 {
  131     memset(tf, 0, sizeof(*tf));
  132     tf->command  = ata_op;
  133     tf->dev      = ATA_USING_LBA;
  134     tf->lob.lbal = lba;
  135     tf->lob.lbam = lba >>  8;
  136     tf->lob.lbah = lba >> 16;
  137     tf->lob.nsect = nsect;
  138     if (needs_lba48(ata_op, lba, nsect)) {
  139         tf->is_lba48 = 1;
  140         tf->hob.nsect = nsect >> 8;
  141         tf->hob.lbal = lba >> 24;
  142         tf->hob.lbam = lba >> 32;
  143         tf->hob.lbah = lba >> 40;
  144     } else {
  145         tf->dev |= (lba >> 24) & 0x0f;
  146     }
  147 }
  148 
  149 #ifdef SG_IO
  150 
  151 __u64 tf_to_lba (struct ata_tf *tf)
  152 {
  153     __u32 lba24, lbah;
  154     __u64 lba64;
  155 
  156     lba24 = (tf->lob.lbah << 16) | (tf->lob.lbam << 8) | (tf->lob.lbal);
  157     if (tf->is_lba48)
  158         lbah = (tf->hob.lbah << 16) | (tf->hob.lbam << 8) | (tf->hob.lbal);
  159     else
  160         lbah = (tf->dev & 0x0f);
  161     lba64 = (((__u64)lbah) << 24) | (__u64)lba24;
  162     return lba64;
  163 }
  164 
  165 enum {
  166     SG_CDB2_TLEN_NODATA = 0 << 0,
  167     SG_CDB2_TLEN_FEAT   = 1 << 0,
  168     SG_CDB2_TLEN_NSECT  = 2 << 0,
  169 
  170     SG_CDB2_TLEN_BYTES  = 0 << 2,
  171     SG_CDB2_TLEN_SECTORS    = 1 << 2,
  172 
  173     SG_CDB2_TDIR_TO_DEV = 0 << 3,
  174     SG_CDB2_TDIR_FROM_DEV   = 1 << 3,
  175 
  176     SG_CDB2_CHECK_COND  = 1 << 5,
  177 };
  178 
  179 static void dump_bytes (const char *prefix, unsigned char *p, int len)
  180 {
  181     int i;
  182 
  183     if (prefix)
  184         fprintf(stderr, "%s: ", prefix);
  185     for (i = 0; i < len; ++i)
  186         fprintf(stderr, " %02x", p[i]);
  187     fprintf(stderr, "\n");
  188 }
  189 
  190 int sg16 (int fd, int rw, int dma, struct ata_tf *tf,
  191     void *data, unsigned int data_bytes, unsigned int timeout_secs)
  192 {
  193     unsigned char cdb[SG_ATA_16_LEN];
  194     unsigned char sb[32], *desc;
  195     struct scsi_sg_io_hdr io_hdr;
  196     int prefer12 = prefer_ata12, demanded_sense = 0;
  197 
  198     if (tf->command == ATA_OP_PIDENTIFY)
  199         prefer12 = 0;
  200 
  201     if (apt_is_apt()) {
  202         return apt_sg16(fd, rw, dma, tf, data, data_bytes, timeout_secs);
  203     }
  204 
  205     memset(&cdb, 0, sizeof(cdb));
  206     memset(&sb,     0, sizeof(sb));
  207     memset(&io_hdr, 0, sizeof(struct scsi_sg_io_hdr));
  208     if (data && data_bytes && !rw)
  209         memset(data, 0, data_bytes);
  210 
  211     if (dma) {
  212         //cdb[1] = data ? (rw ? SG_ATA_PROTO_UDMA_OUT : SG_ATA_PROTO_UDMA_IN) : SG_ATA_PROTO_NON_DATA;
  213         cdb[1] = data ? SG_ATA_PROTO_DMA : SG_ATA_PROTO_NON_DATA;
  214     } else {
  215         cdb[1] = data ? (rw ? SG_ATA_PROTO_PIO_OUT : SG_ATA_PROTO_PIO_IN) : SG_ATA_PROTO_NON_DATA;
  216     }
  217 
  218     /* libata/AHCI workaround: don't demand sense data for IDENTIFY commands */
  219     if (data) {
  220         cdb[2] |= SG_CDB2_TLEN_NSECT | SG_CDB2_TLEN_SECTORS;
  221         cdb[2] |= rw ? SG_CDB2_TDIR_TO_DEV : SG_CDB2_TDIR_FROM_DEV;
  222     } else {
  223         cdb[2] = SG_CDB2_CHECK_COND;
  224     }
  225 
  226     if (!prefer12 || tf->is_lba48) {
  227         cdb[ 0] = SG_ATA_16;
  228         cdb[ 4] = tf->lob.feat;
  229         cdb[ 6] = tf->lob.nsect;
  230         cdb[ 8] = tf->lob.lbal;
  231         cdb[10] = tf->lob.lbam;
  232         cdb[12] = tf->lob.lbah;
  233         cdb[13] = tf->dev;
  234         cdb[14] = tf->command;
  235         if (tf->is_lba48) {
  236             cdb[ 1] |= SG_ATA_LBA48;
  237             cdb[ 3]  = tf->hob.feat;
  238             cdb[ 5]  = tf->hob.nsect;
  239             cdb[ 7]  = tf->hob.lbal;
  240             cdb[ 9]  = tf->hob.lbam;
  241             cdb[11]  = tf->hob.lbah;
  242         }
  243         io_hdr.cmd_len = SG_ATA_16_LEN;
  244     } else {
  245         cdb[ 0] = SG_ATA_12;
  246         cdb[ 3] = tf->lob.feat;
  247         cdb[ 4] = tf->lob.nsect;
  248         cdb[ 5] = tf->lob.lbal;
  249         cdb[ 6] = tf->lob.lbam;
  250         cdb[ 7] = tf->lob.lbah;
  251         cdb[ 8] = tf->dev;
  252         cdb[ 9] = tf->command;
  253         io_hdr.cmd_len = SG_ATA_12_LEN;
  254     }
  255 
  256     io_hdr.interface_id = 'S';
  257     io_hdr.mx_sb_len    = sizeof(sb);
  258     io_hdr.dxfer_direction  = data ? (rw ? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV) : SG_DXFER_NONE;
  259     io_hdr.dxfer_len    = data ? data_bytes : 0;
  260     io_hdr.dxferp       = data;
  261     io_hdr.cmdp     = cdb;
  262     io_hdr.sbp      = sb;
  263     io_hdr.pack_id      = tf_to_lba(tf);
  264     io_hdr.timeout      = (timeout_secs ? timeout_secs : default_timeout_secs) * 1000; /* msecs */
  265 
  266     if (verbose) {
  267         dump_bytes("outgoing cdb", cdb, sizeof(cdb));
  268         if (rw && data)
  269             dump_bytes("outgoing_data", data, data_bytes);
  270     }
  271 
  272     if (ioctl(fd, SG_IO, &io_hdr) == -1) {
  273         if (verbose)
  274             perror("ioctl(fd,SG_IO)");
  275         return -1;  /* SG_IO not supported */
  276     }
  277 
  278     if (verbose)
  279         fprintf(stderr, "SG_IO: ATA_%u status=0x%x, host_status=0x%x, driver_status=0x%x\n",
  280             io_hdr.cmd_len, io_hdr.status, io_hdr.host_status, io_hdr.driver_status);
  281 
  282     if (io_hdr.status && io_hdr.status != SG_CHECK_CONDITION) {
  283         if (verbose)
  284             fprintf(stderr, "SG_IO: bad status: 0x%x\n", io_hdr.status);
  285         errno = EBADE;
  286         return -1;
  287     }
  288     if (io_hdr.host_status) {
  289         if (verbose)
  290             fprintf(stderr, "SG_IO: bad host status: 0x%x\n", io_hdr.host_status);
  291         errno = EBADE;
  292         return -1;
  293     }
  294     if (verbose) {
  295         dump_bytes("SG_IO: sb[]", sb, sizeof(sb));
  296         if (!rw && data)
  297             dump_bytes("incoming_data", data, data_bytes);
  298     }
  299 
  300     if (io_hdr.driver_status && (io_hdr.driver_status != SG_DRIVER_SENSE)) {
  301         if (verbose)
  302             fprintf(stderr, "SG_IO: bad driver status: 0x%x\n", io_hdr.driver_status);
  303         errno = EBADE;
  304         return -1;
  305     }
  306 
  307     desc = sb + 8;
  308     if (io_hdr.driver_status != SG_DRIVER_SENSE) {
  309         if (sb[0] | sb[1] | sb[2] | sb[3] | sb[4] | sb[5] | sb[6] | sb[7] | sb[8] | sb[9]) {
  310             static int second_try = 0;
  311             if (!second_try++)
  312                 fprintf(stderr, "SG_IO: questionable sense data, results may be incorrect\n");
  313         } else if (demanded_sense) {
  314             static int second_try = 0;
  315             if (!second_try++)
  316                 fprintf(stderr, "SG_IO: missing sense data, results may be incorrect\n");
  317         }
  318     } else if (sb[0] != 0x72 || sb[7] < 14 || desc[0] != 0x09 || desc[1] < 0x0c) {
  319         if (verbose || tf->command != ATA_OP_IDENTIFY)
  320             dump_bytes("SG_IO: bad/missing sense data, sb[]", sb, sizeof(sb));
  321     }
  322 
  323     if (verbose) {
  324         unsigned int len = desc[1] + 2, maxlen = sizeof(sb) - 8 - 2;
  325         if (len > maxlen)
  326             len = maxlen;
  327         dump_bytes("SG_IO: desc[]", desc, len);
  328     }
  329 
  330     tf->is_lba48  = desc[ 2] & 1;
  331     tf->error     = desc[ 3];
  332     tf->lob.nsect = desc[ 5];
  333     tf->lob.lbal  = desc[ 7];
  334     tf->lob.lbam  = desc[ 9];
  335     tf->lob.lbah  = desc[11];
  336     tf->dev       = desc[12];
  337     tf->status    = desc[13];
  338     tf->hob.feat  = 0;
  339     if (tf->is_lba48) {
  340         tf->hob.nsect = desc[ 4];
  341         tf->hob.lbal  = desc[ 6];
  342         tf->hob.lbam  = desc[ 8];
  343         tf->hob.lbah  = desc[10];
  344     } else {
  345         tf->hob.nsect = 0;
  346         tf->hob.lbal  = 0;
  347         tf->hob.lbam  = 0;
  348         tf->hob.lbah  = 0;
  349     }
  350 
  351     if (verbose)
  352         fprintf(stderr, "      ATA_%u stat=%02x err=%02x nsect=%02x lbal=%02x lbam=%02x lbah=%02x dev=%02x\n",
  353                 io_hdr.cmd_len, tf->status, tf->error, tf->lob.nsect, tf->lob.lbal, tf->lob.lbam, tf->lob.lbah, tf->dev);
  354 
  355     if (tf->status & (ATA_STAT_ERR | ATA_STAT_DRQ)) {
  356         if (verbose) {
  357             fprintf(stderr, "I/O error, ata_op=0x%02x ata_status=0x%02x ata_error=0x%02x\n",
  358                 tf->command, tf->status, tf->error);
  359         }
  360         errno = EIO;
  361         return -1;
  362     }
  363     return 0;
  364 }
  365 
  366 #endif /* SG_IO */
  367 
  368 int do_drive_cmd (int fd, unsigned char *args, unsigned int timeout_secs)
  369 {
  370 #ifdef SG_IO
  371 
  372     struct ata_tf tf;
  373     void *data = NULL;
  374     unsigned int data_bytes = 0;
  375     int rc;
  376 
  377     if (args == NULL)
  378         goto use_legacy_ioctl;
  379     /*
  380      * Reformat and try to issue via SG_IO:
  381      * args[0]: command in; status out.
  382      * args[1]: lbal for SMART, nsect for all others; error out
  383      * args[2]: feat in; nsect out.
  384      * args[3]: data-count (512 multiple) for all cmds.
  385      */
  386     tf_init(&tf, args[0], 0, 0);
  387     tf.lob.nsect = args[1];
  388     tf.lob.feat  = args[2];
  389     if (args[3]) {
  390         data_bytes   = args[3] * 512;
  391         data         = args + 4;
  392         if (!tf.lob.nsect)
  393             tf.lob.nsect = args[3];
  394     }
  395     if (tf.command == ATA_OP_SMART) {
  396         tf.lob.nsect = args[3];
  397         tf.lob.lbal  = args[1];
  398         tf.lob.lbam  = 0x4f;
  399         tf.lob.lbah  = 0xc2;
  400     }
  401 
  402     rc = sg16(fd, SG_READ, is_dma(tf.command), &tf, data, data_bytes, timeout_secs);
  403     if (rc == -1) {
  404         if (errno == EINVAL || errno == ENODEV || errno == EBADE)
  405             goto use_legacy_ioctl;
  406     }
  407 
  408     if (rc == 0 || errno == EIO) {
  409         args[0] = tf.status;
  410         args[1] = tf.error;
  411         args[2] = tf.lob.nsect;
  412     }
  413     return rc;
  414 
  415 use_legacy_ioctl:
  416 #endif /* SG_IO */
  417     if (verbose) {
  418         if (args)
  419             fprintf(stderr, "Trying legacy HDIO_DRIVE_CMD\n");
  420     }
  421     return ioctl(fd, HDIO_DRIVE_CMD, args);
  422 }
  423 
  424 int do_taskfile_cmd (int fd, struct hdio_taskfile *r, unsigned int timeout_secs)
  425 {
  426     int rc;
  427 #ifdef SG_IO
  428     struct ata_tf tf;
  429     void *data = NULL;
  430     unsigned int data_bytes = 0;
  431     int rw = SG_READ;
  432     /*
  433      * Reformat and try to issue via SG_IO:
  434      */
  435     tf_init(&tf, 0, 0, 0);
  436 #if 1 /* debugging */
  437     if (verbose) {
  438         printf("oflags.bits.lob_all=0x%02x, flags={", r->oflags.bits.lob_all);
  439         if (r->oflags.bits.lob.feat)    printf(" feat");
  440         if (r->oflags.bits.lob.nsect)   printf(" nsect");
  441         if (r->oflags.bits.lob.lbal)    printf(" lbal");
  442         if (r->oflags.bits.lob.lbam)    printf(" lbam");
  443         if (r->oflags.bits.lob.lbah)    printf(" lbah");
  444         if (r->oflags.bits.lob.dev) printf(" dev");
  445         if (r->oflags.bits.lob.command) printf(" command");
  446         printf(" }\n");
  447         printf("oflags.bits.hob_all=0x%02x, flags={", r->oflags.bits.hob_all);
  448         if (r->oflags.bits.hob.feat)    printf(" feat");
  449         if (r->oflags.bits.hob.nsect)   printf(" nsect");
  450         if (r->oflags.bits.hob.lbal)    printf(" lbal");
  451         if (r->oflags.bits.hob.lbam)    printf(" lbam");
  452         if (r->oflags.bits.hob.lbah)    printf(" lbah");
  453         printf(" }\n");
  454     }
  455 #endif
  456     if (r->oflags.bits.lob.feat)        tf.lob.feat  = r->lob.feat;
  457     if (r->oflags.bits.lob.lbal)        tf.lob.lbal  = r->lob.lbal;
  458     if (r->oflags.bits.lob.nsect)       tf.lob.nsect = r->lob.nsect;
  459     if (r->oflags.bits.lob.lbam)        tf.lob.lbam  = r->lob.lbam;
  460     if (r->oflags.bits.lob.lbah)        tf.lob.lbah  = r->lob.lbah;
  461     if (r->oflags.bits.lob.dev)     tf.dev       = r->lob.dev;
  462     if (r->oflags.bits.lob.command) tf.command   = r->lob.command;
  463     if (needs_lba48(tf.command,0,0) || r->oflags.bits.hob_all || r->iflags.bits.hob_all) {
  464         tf.is_lba48 = 1;
  465         if (r->oflags.bits.hob.feat)    tf.hob.feat  = r->hob.feat;
  466         if (r->oflags.bits.hob.lbal)    tf.hob.lbal  = r->hob.lbal;
  467         if (r->oflags.bits.hob.nsect)   tf.hob.nsect = r->hob.nsect;
  468         if (r->oflags.bits.hob.lbam)    tf.hob.lbam  = r->hob.lbam;
  469         if (r->oflags.bits.hob.lbah)    tf.hob.lbah  = r->hob.lbah;
  470         if (verbose)
  471             fprintf(stderr, "using LBA48 taskfile\n");
  472     }
  473     switch (r->cmd_req) {
  474         case TASKFILE_CMD_REQ_OUT:
  475         case TASKFILE_CMD_REQ_RAW_OUT:
  476             data_bytes = r->obytes;
  477             data       = r->data;
  478             rw         = SG_WRITE;
  479             break;
  480         case TASKFILE_CMD_REQ_IN:
  481             data_bytes = r->ibytes;
  482             data       = r->data;
  483             break;
  484     }
  485 
  486     rc = sg16(fd, rw, is_dma(tf.command), &tf, data, data_bytes, timeout_secs);
  487     if (rc == -1) {
  488         if (errno == EINVAL || errno == ENODEV || errno == EBADE)
  489             goto use_legacy_ioctl;
  490     }
  491 
  492     if (rc == 0 || errno == EIO) {
  493         if (r->iflags.bits.lob.feat)    r->lob.feat  = tf.error;
  494         if (r->iflags.bits.lob.lbal)    r->lob.lbal  = tf.lob.lbal;
  495         if (r->iflags.bits.lob.nsect)   r->lob.nsect = tf.lob.nsect;
  496         if (r->iflags.bits.lob.lbam)    r->lob.lbam  = tf.lob.lbam;
  497         if (r->iflags.bits.lob.lbah)    r->lob.lbah  = tf.lob.lbah;
  498         if (r->iflags.bits.lob.dev) r->lob.dev   = tf.dev;
  499         if (r->iflags.bits.lob.command) r->lob.command = tf.status;
  500         if (r->iflags.bits.hob.feat)    r->hob.feat  = tf.hob.feat;
  501         if (r->iflags.bits.hob.lbal)    r->hob.lbal  = tf.hob.lbal;
  502         if (r->iflags.bits.hob.nsect)   r->hob.nsect = tf.hob.nsect;
  503         if (r->iflags.bits.hob.lbam)    r->hob.lbam  = tf.hob.lbam;
  504         if (r->iflags.bits.hob.lbah)    r->hob.lbah  = tf.hob.lbah;
  505     }
  506     return rc;
  507 
  508 use_legacy_ioctl:
  509 #else
  510     timeout_secs = 0;   /* keep compiler happy */
  511 #endif /* SG_IO */
  512     if (verbose)
  513         fprintf(stderr, "trying legacy HDIO_DRIVE_TASKFILE\n");
  514     errno = 0;
  515 
  516     rc = ioctl(fd, HDIO_DRIVE_TASKFILE, r);
  517     if (verbose) {
  518         int err = errno;
  519         fprintf(stderr, "rc=%d, errno=%d, returned ATA registers: ", rc, err);
  520         if (r->iflags.bits.lob.feat)    fprintf(stderr, " er=%02x", r->lob.feat);
  521         if (r->iflags.bits.lob.nsect)   fprintf(stderr, " ns=%02x", r->lob.nsect);
  522         if (r->iflags.bits.lob.lbal)    fprintf(stderr, " ll=%02x", r->lob.lbal);
  523         if (r->iflags.bits.lob.lbam)    fprintf(stderr, " lm=%02x", r->lob.lbam);
  524         if (r->iflags.bits.lob.lbah)    fprintf(stderr, " lh=%02x", r->lob.lbah);
  525         if (r->iflags.bits.lob.dev) fprintf(stderr, " dh=%02x", r->lob.dev);
  526         if (r->iflags.bits.lob.command) fprintf(stderr, " st=%02x", r->lob.command);
  527         if (r->iflags.bits.hob.feat)    fprintf(stderr, " err=%02x", r->hob.feat);
  528         if (r->iflags.bits.hob.nsect)   fprintf(stderr, " err=%02x", r->hob.nsect);
  529         if (r->iflags.bits.hob.lbal)    fprintf(stderr, " err=%02x", r->hob.lbal);
  530         if (r->iflags.bits.hob.lbam)    fprintf(stderr, " err=%02x", r->hob.lbam);
  531         if (r->iflags.bits.hob.lbah)    fprintf(stderr, " err=%02x", r->hob.lbah);
  532         fprintf(stderr, "\n");
  533         errno = err;
  534     }
  535     if (rc == -1 && errno == EINVAL) {
  536         fprintf(stderr, "The running kernel lacks CONFIG_IDE_TASK_IOCTL support for this device.\n");
  537         errno = EINVAL;
  538     }
  539     return rc;
  540 }
  541 
  542 void init_hdio_taskfile (struct hdio_taskfile *r, __u8 ata_op, int rw, int force_lba48,
  543                 __u64 lba, unsigned int nsect, int data_bytes)
  544 {
  545     memset(r, 0, sizeof(struct hdio_taskfile) + data_bytes);
  546     if (!data_bytes) {
  547         r->dphase  = TASKFILE_DPHASE_NONE;
  548         r->cmd_req = TASKFILE_CMD_REQ_NODATA;
  549     } else if (rw == RW_WRITE) {
  550         r->dphase  = TASKFILE_DPHASE_PIO_OUT;
  551         r->cmd_req = TASKFILE_CMD_REQ_RAW_OUT;
  552         r->obytes  = data_bytes;
  553     } else { /* rw == RW_READ */
  554         r->dphase  = TASKFILE_DPHASE_PIO_IN;
  555         r->cmd_req = TASKFILE_CMD_REQ_IN;
  556         r->ibytes  = data_bytes;
  557     }
  558     r->lob.command      = ata_op;
  559     r->oflags.bits.lob.command = 1;
  560     r->oflags.bits.lob.dev     = 1;
  561     r->oflags.bits.lob.lbal    = 1;
  562     r->oflags.bits.lob.lbam    = 1;
  563     r->oflags.bits.lob.lbah    = 1;
  564     r->oflags.bits.lob.nsect   = 1;
  565 
  566     r->iflags.bits.lob.command = 1;
  567     r->iflags.bits.lob.feat    = 1;
  568 
  569     r->lob.nsect = nsect;
  570     r->lob.lbal  = lba;
  571     r->lob.lbam  = lba >>  8;
  572     r->lob.lbah  = lba >> 16;
  573     r->lob.dev   = 0xa0 | ATA_USING_LBA;
  574 
  575     if (needs_lba48(ata_op, lba, nsect) || force_lba48) {
  576         r->hob.nsect = nsect >>  8;
  577         r->hob.lbal  = lba   >> 24;
  578         r->hob.lbam  = lba   >> 32;
  579         r->hob.lbah  = lba   >> 40;
  580         r->oflags.bits.hob.nsect = 1;
  581         r->oflags.bits.hob.lbal  = 1;
  582         r->oflags.bits.hob.lbam  = 1;
  583         r->oflags.bits.hob.lbah  = 1;
  584     } else {
  585         r->lob.dev |= (lba >> 24) & 0x0f;
  586     }
  587 }