"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 }