4 * Home page of code is: http://smartmontools.sourceforge.net
6 * Copyright (C) 2006-10 Douglas Gilbert <dgilbert@interlog.com>
7 * Copyright (C) 2009-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
14 * You should have received a copy of the GNU General Public License
15 * (for example COPYING); if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * The code in this file is based on the SCSI to ATA Translation (SAT)
19 * draft found at http://www.t10.org . The original draft used for this
20 * code is sat-r08.pdf which is not too far away from becoming a
21 * standard. The SAT commands of interest to smartmontools are the
22 * ATA PASS THROUGH SCSI (16) and ATA PASS THROUGH SCSI (12) defined in
23 * section 12 of that document.
25 * sat-r09.pdf is the most recent, easily accessible draft prior to the
26 * original SAT standard (ANSI INCITS 431-2007). By mid-2009 the second
27 * version of the SAT standard (SAT-2) is nearing standardization. In
28 * their wisdom an incompatible change has been introduced in draft
29 * sat2r08a.pdf in the area of the ATA RETURN DESCRIPTOR. A new "fixed
30 * format" ATA RETURN buffer has been defined (sat2r08b.pdf section
31 * 12.2.7) for the case when DSENSE=0 in the Control mode page.
32 * Unfortunately this is the normal case. If the change stands our
33 * code will need to be extended for this case.
35 * With more transports "hiding" SATA disks (and other S-ATAPI devices)
36 * behind a SCSI command set, accessing special features like SMART
37 * information becomes a challenge. The SAT standard offers ATA PASS
38 * THROUGH commands for special usages. Note that the SAT layer may
39 * be inside a generic OS layer (e.g. libata in linux), in a host
40 * adapter (HA or HBA) firmware, or somewhere on the interconnect
41 * between the host computer and the SATA devices (e.g. a RAID made
42 * of SATA disks and the RAID talks "SCSI" to the host computer).
43 * Note that in the latter case, this code does not solve the
44 * addressing issue (i.e. which SATA disk to address behind the logical
45 * SCSI (RAID) interface).
58 #include "atacmds.h" // ataReadHDIdentity()
59 #include "knowndrives.h" // lookup_usb_device()
61 #include "dev_interface.h"
62 #include "dev_ata_cmd_set.h" // ata_device_with_command_set
63 #include "dev_tunnelled.h" // tunnelled_device<>
65 const char * scsiata_cpp_cvsid
= "$Id: scsiata.cpp 3095 2010-04-30 12:33:27Z dpgilbert $";
67 /* for passing global control variables */
68 extern smartmonctrl
*con
;
70 /* This is a slightly stretched SCSI sense "descriptor" format header.
71 The addition is to allow the 0x70 and 0x71 response codes. The idea
72 is to place the salient data of both "fixed" and "descriptor" sense
73 format into one structure to ease application processing.
74 The original sense buffer should be kept around for those cases
75 in which more information is required (e.g. the LBA of a MEDIUM ERROR). */
76 /// Abridged SCSI sense data
77 struct sg_scsi_sense_hdr
{
78 unsigned char response_code
; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
79 unsigned char sense_key
;
85 unsigned char additional_length
;
88 /* Maps the salient data from a sense buffer which is in either fixed or
89 descriptor format into a structure mimicking a descriptor format
90 header (i.e. the first 8 bytes of sense descriptor format).
91 If zero response code returns 0. Otherwise returns 1 and if 'sshp' is
92 non-NULL then zero all fields and then set the appropriate fields in
93 that structure. sshp::additional_length is always 0 for response
94 codes 0x70 and 0x71 (fixed format). */
95 static int sg_scsi_normalize_sense(const unsigned char * sensep
, int sb_len
,
96 struct sg_scsi_sense_hdr
* sshp
);
98 /* Attempt to find the first SCSI sense data descriptor that matches the
99 given 'desc_type'. If found return pointer to start of sense data
100 descriptor; otherwise (including fixed format sense data) returns NULL. */
101 static const unsigned char * sg_scsi_sense_desc_find(const unsigned char * sensep
,
102 int sense_len
, int desc_type
);
104 #define SAT_ATA_PASSTHROUGH_12LEN 12
105 #define SAT_ATA_PASSTHROUGH_16LEN 16
107 #define DEF_SAT_ATA_PASSTHRU_SIZE 16
108 #define ATA_RETURN_DESCRIPTOR 9
111 namespace sat
{ // no need to publish anything, name provided for Doxygen
114 /// Implements ATA by tunnelling through SCSI.
117 : public tunnelled_device
<
118 /*implements*/ ata_device
119 /*by tunnelling through a*/, scsi_device
123 sat_device(smart_interface
* intf
, scsi_device
* scsidev
,
124 const char * req_type
, int passthrulen
= 0);
126 virtual ~sat_device() throw();
128 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
135 sat_device::sat_device(smart_interface
* intf
, scsi_device
* scsidev
,
136 const char * req_type
, int passthrulen
/*= 0*/)
137 : smart_device(intf
, scsidev
->get_dev_name(), "sat", req_type
),
138 tunnelled_device
<ata_device
, scsi_device
>(scsidev
),
139 m_passthrulen(passthrulen
)
141 set_info().info_name
= strprintf("%s [SAT]", scsidev
->get_info_name());
144 sat_device::~sat_device() throw()
149 // cdb[0]: ATA PASS THROUGH (16) SCSI command opcode byte (0x85)
150 // cdb[1]: multiple_count, protocol + extend
151 // cdb[2]: offline, ck_cond, t_dir, byte_block + t_length
152 // cdb[3]: features (15:8)
153 // cdb[4]: features (7:0)
154 // cdb[5]: sector_count (15:8)
155 // cdb[6]: sector_count (7:0)
156 // cdb[7]: lba_low (15:8)
157 // cdb[8]: lba_low (7:0)
158 // cdb[9]: lba_mid (15:8)
159 // cdb[10]: lba_mid (7:0)
160 // cdb[11]: lba_high (15:8)
161 // cdb[12]: lba_high (7:0)
163 // cdb[14]: (ata) command
164 // cdb[15]: control (SCSI, leave as zero)
166 // 24 bit lba (from MSB): cdb[12] cdb[10] cdb[8]
167 // 48 bit lba (from MSB): cdb[11] cdb[9] cdb[7] cdb[12] cdb[10] cdb[8]
170 // cdb[0]: ATA PASS THROUGH (12) SCSI command opcode byte (0xa1)
171 // cdb[1]: multiple_count, protocol + extend
172 // cdb[2]: offline, ck_cond, t_dir, byte_block + t_length
173 // cdb[3]: features (7:0)
174 // cdb[4]: sector_count (7:0)
175 // cdb[5]: lba_low (7:0)
176 // cdb[6]: lba_mid (7:0)
177 // cdb[7]: lba_high (7:0)
179 // cdb[9]: (ata) command
181 // cdb[11]: control (SCSI, leave as zero)
184 // ATA Return Descriptor (component of descriptor sense data)
185 // des[0]: descriptor code (0x9)
186 // des[1]: additional descriptor length (0xc)
187 // des[2]: extend (bit 0)
189 // des[4]: sector_count (15:8)
190 // des[5]: sector_count (7:0)
191 // des[6]: lba_low (15:8)
192 // des[7]: lba_low (7:0)
193 // des[8]: lba_mid (15:8)
194 // des[9]: lba_mid (7:0)
195 // des[10]: lba_high (15:8)
196 // des[11]: lba_high (7:0)
203 // This interface routine takes ATA SMART commands and packages
204 // them in the SAT-defined ATA PASS THROUGH SCSI commands. There are
205 // two available SCSI commands: a 12 byte and 16 byte variant; the
206 // one used is chosen via this->m_passthrulen .
207 // DETAILED DESCRIPTION OF ARGUMENTS
208 // device: is the file descriptor provided by (a SCSI dvice type) open()
209 // command: defines the different ATA operations.
210 // select: additional input data if needed (which log, which type of
212 // data: location to write output data, if needed (512 bytes).
213 // Note: not all commands use all arguments.
215 // -1 if the command failed
216 // 0 if the command succeeded,
217 // STATUS_CHECK routine:
218 // -1 if the command failed
219 // 0 if the command succeeded and disk SMART status is "OK"
220 // 1 if the command succeeded and disk SMART status is "FAILING"
222 bool sat_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
224 if (!ata_cmd_is_ok(in
,
225 true, // data_out_support
226 true, // multi_sector_support
227 true) // ata_48bit_support
231 struct scsi_cmnd_io io_hdr
;
232 struct scsi_sense_disect sinfo
;
233 struct sg_scsi_sense_hdr ssh
;
234 unsigned char cdb
[SAT_ATA_PASSTHROUGH_16LEN
];
235 unsigned char sense
[32];
236 const unsigned char * ardp
;
237 int status
, ard_len
, have_sense
;
239 int ck_cond
= 0; /* set to 1 to read register(s) back */
240 int protocol
= 3; /* non-data */
241 int t_dir
= 1; /* 0 -> to device, 1 -> from device */
242 int byte_block
= 1; /* 0 -> bytes, 1 -> 512 byte blocks */
243 int t_length
= 0; /* 0 -> no data transferred */
244 int passthru_size
= DEF_SAT_ATA_PASSTHRU_SIZE
;
246 memset(cdb
, 0, sizeof(cdb
));
247 memset(sense
, 0, sizeof(sense
));
249 // Set data direction
250 // TODO: This works only for commands where sector_count holds count!
251 switch (in
.direction
) {
252 case ata_cmd_in::no_data
:
254 case ata_cmd_in::data_in
:
255 protocol
= 4; // PIO data-in
256 t_length
= 2; // sector_count holds count
258 case ata_cmd_in::data_out
:
259 protocol
= 5; // PIO data-out
260 t_length
= 2; // sector_count holds count
261 t_dir
= 0; // to device
264 return set_err(EINVAL
, "sat_device::ata_pass_through: invalid direction=%d",
268 // Check condition if any output register needed
269 if (in
.out_needed
.is_set())
272 if ((SAT_ATA_PASSTHROUGH_12LEN
== m_passthrulen
) ||
273 (SAT_ATA_PASSTHROUGH_16LEN
== m_passthrulen
))
274 passthru_size
= m_passthrulen
;
276 // Set extend bit on 48-bit ATA command
277 if (in
.in_regs
.is_48bit_cmd()) {
278 if (passthru_size
!= SAT_ATA_PASSTHROUGH_16LEN
)
279 return set_err(ENOSYS
, "48-bit ATA commands require SAT ATA PASS-THROUGH (16)");
283 cdb
[0] = (SAT_ATA_PASSTHROUGH_12LEN
== passthru_size
) ?
284 SAT_ATA_PASSTHROUGH_12
: SAT_ATA_PASSTHROUGH_16
;
286 cdb
[1] = (protocol
<< 1) | extend
;
287 cdb
[2] = (ck_cond
<< 5) | (t_dir
<< 3) |
288 (byte_block
<< 2) | t_length
;
290 if (passthru_size
== SAT_ATA_PASSTHROUGH_12LEN
) {
291 // ATA PASS-THROUGH (12)
292 const ata_in_regs
& lo
= in
.in_regs
;
293 cdb
[3] = lo
.features
;
294 cdb
[4] = lo
.sector_count
;
297 cdb
[7] = lo
.lba_high
;
302 // ATA PASS-THROUGH (16)
303 const ata_in_regs
& lo
= in
.in_regs
;
304 const ata_in_regs
& hi
= in
.in_regs
.prev
;
305 // Note: all 'in.in_regs.prev.*' are always zero for 28-bit commands
306 cdb
[ 3] = hi
.features
;
307 cdb
[ 4] = lo
.features
;
308 cdb
[ 5] = hi
.sector_count
;
309 cdb
[ 6] = lo
.sector_count
;
310 cdb
[ 7] = hi
.lba_low
;
311 cdb
[ 8] = lo
.lba_low
;
312 cdb
[ 9] = hi
.lba_mid
;
313 cdb
[10] = lo
.lba_mid
;
314 cdb
[11] = hi
.lba_high
;
315 cdb
[12] = lo
.lba_high
;
317 cdb
[14] = lo
.command
;
320 memset(&io_hdr
, 0, sizeof(io_hdr
));
322 io_hdr
.dxfer_dir
= DXFER_NONE
;
323 io_hdr
.dxfer_len
= 0;
324 } else if (t_dir
) { /* from device */
325 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
326 io_hdr
.dxfer_len
= in
.size
;
327 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
328 memset(in
.buffer
, 0, in
.size
); // prefill with zeroes
329 } else { /* to device */
330 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
331 io_hdr
.dxfer_len
= in
.size
;
332 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
335 io_hdr
.cmnd_len
= passthru_size
;
336 io_hdr
.sensep
= sense
;
337 io_hdr
.max_sense_len
= sizeof(sense
);
338 io_hdr
.timeout
= SCSI_TIMEOUT_DEFAULT
;
340 scsi_device
* scsidev
= get_tunnel_dev();
341 if (!scsidev
->scsi_pass_through(&io_hdr
)) {
342 if (con
->reportscsiioctl
> 0)
343 pout("sat_device::ata_pass_through: scsi_pass_through() failed, "
344 "errno=%d [%s]\n", scsidev
->get_errno(), scsidev
->get_errmsg());
345 return set_err(scsidev
->get_err());
349 have_sense
= sg_scsi_normalize_sense(io_hdr
.sensep
, io_hdr
.resp_sense_len
,
352 /* look for SAT ATA Return Descriptor */
353 ardp
= sg_scsi_sense_desc_find(io_hdr
.sensep
,
354 io_hdr
.resp_sense_len
,
355 ATA_RETURN_DESCRIPTOR
);
357 ard_len
= ardp
[1] + 2;
360 else if (ard_len
> 14)
363 scsi_do_sense_disect(&io_hdr
, &sinfo
);
364 status
= scsiSimpleSenseFilter(&sinfo
);
366 if (con
->reportscsiioctl
> 0) {
367 pout("sat_device::ata_pass_through: scsi error: %s\n",
368 scsiErrString(status
));
369 if (ardp
&& (con
->reportscsiioctl
> 1)) {
370 pout("Values from ATA Return Descriptor are:\n");
371 dStrHex((const char *)ardp
, ard_len
, 1);
374 if (t_dir
&& (t_length
> 0) && (in
.direction
== ata_cmd_in::data_in
))
375 memset(in
.buffer
, 0, in
.size
);
376 return set_err(EIO
, "scsi error %s", scsiErrString(status
));
379 if (ck_cond
) { /* expecting SAT specific sense data */
382 if (con
->reportscsiioctl
> 1) {
383 pout("Values from ATA Return Descriptor are:\n");
384 dStrHex((const char *)ardp
, ard_len
, 1);
386 // Set output registers
387 ata_out_regs
& lo
= out
.out_regs
;
389 lo
.sector_count
= ardp
[ 5];
390 lo
.lba_low
= ardp
[ 7];
391 lo
.lba_mid
= ardp
[ 9];
392 lo
.lba_high
= ardp
[11];
393 lo
.device
= ardp
[12];
394 lo
.status
= ardp
[13];
395 if (in
.in_regs
.is_48bit_cmd()) {
396 ata_out_regs
& hi
= out
.out_regs
.prev
;
397 hi
.sector_count
= ardp
[ 4];
398 hi
.lba_low
= ardp
[ 6];
399 hi
.lba_mid
= ardp
[ 8];
400 hi
.lba_high
= ardp
[10];
405 ck_cond
= 0; /* not the type of sense data expected */
409 if ((ssh
.response_code
>= 0x72) &&
410 ((SCSI_SK_NO_SENSE
== ssh
.sense_key
) ||
411 (SCSI_SK_RECOVERED_ERR
== ssh
.sense_key
)) &&
413 (SCSI_ASCQ_ATA_PASS_THROUGH
== ssh
.ascq
)) {
415 if (con
->reportscsiioctl
> 0) {
416 pout("Values from ATA Return Descriptor are:\n");
417 dStrHex((const char *)ardp
, ard_len
, 1);
419 return set_err(EIO
, "SAT command failed");
429 /////////////////////////////////////////////////////////////////////////////
431 /* Attempt an IDENTIFY DEVICE ATA command via SATL when packet_interface
432 is false otherwise attempt IDENTIFY PACKET DEVICE. If successful
433 return true, else false */
435 static bool has_sat_pass_through(ata_device
* dev
, bool packet_interface
= false)
437 /* Note: malloc() ensures the read buffer lands on a single
438 page. This avoids some bugs seen on LSI controlers under
440 char *data
= (char *)malloc(512);
442 in
.in_regs
.command
= (packet_interface
? ATA_IDENTIFY_PACKET_DEVICE
: ATA_IDENTIFY_DEVICE
);
443 in
.set_data_in(data
, 1);
444 bool ret
= dev
->ata_pass_through(in
);
449 /////////////////////////////////////////////////////////////////////////////
451 /* Next two functions are borrowed from sg_lib.c in the sg3_utils
452 package. Same copyrght owner, same license as this file. */
453 static int sg_scsi_normalize_sense(const unsigned char * sensep
, int sb_len
,
454 struct sg_scsi_sense_hdr
* sshp
)
457 memset(sshp
, 0, sizeof(struct sg_scsi_sense_hdr
));
458 if ((NULL
== sensep
) || (0 == sb_len
) || (0x70 != (0x70 & sensep
[0])))
461 sshp
->response_code
= (0x7f & sensep
[0]);
462 if (sshp
->response_code
>= 0x72) { /* descriptor format */
464 sshp
->sense_key
= (0xf & sensep
[1]);
466 sshp
->asc
= sensep
[2];
468 sshp
->ascq
= sensep
[3];
470 sshp
->additional_length
= sensep
[7];
471 } else { /* fixed format */
473 sshp
->sense_key
= (0xf & sensep
[2]);
475 sb_len
= (sb_len
< (sensep
[7] + 8)) ? sb_len
:
478 sshp
->asc
= sensep
[12];
480 sshp
->ascq
= sensep
[13];
488 static const unsigned char * sg_scsi_sense_desc_find(const unsigned char * sensep
,
489 int sense_len
, int desc_type
)
491 int add_sen_len
, add_len
, desc_len
, k
;
492 const unsigned char * descp
;
494 if ((sense_len
< 8) || (0 == (add_sen_len
= sensep
[7])))
496 if ((sensep
[0] < 0x72) || (sensep
[0] > 0x73))
498 add_sen_len
= (add_sen_len
< (sense_len
- 8)) ?
499 add_sen_len
: (sense_len
- 8);
501 for (desc_len
= 0, k
= 0; k
< add_sen_len
; k
+= desc_len
) {
503 add_len
= (k
< (add_sen_len
- 1)) ? descp
[1]: -1;
504 desc_len
= add_len
+ 2;
505 if (descp
[0] == desc_type
)
507 if (add_len
< 0) /* short descriptor ?? */
514 // Call scsi_pass_through and check sense.
515 // TODO: Provide as member function of class scsi_device (?)
516 static bool scsi_pass_through_and_check(scsi_device
* scsidev
, scsi_cmnd_io
* iop
,
517 const char * msg
= "")
519 // Provide sense buffer
520 unsigned char sense
[32] = {0, };
522 iop
->max_sense_len
= sizeof(sense
);
523 iop
->timeout
= SCSI_TIMEOUT_DEFAULT
;
526 if (!scsidev
->scsi_pass_through(iop
)) {
527 if (con
->reportscsiioctl
> 0)
528 pout("%sscsi_pass_through() failed, errno=%d [%s]\n",
529 msg
, scsidev
->get_errno(), scsidev
->get_errmsg());
534 scsi_sense_disect sinfo
;
535 scsi_do_sense_disect(iop
, &sinfo
);
536 int err
= scsiSimpleSenseFilter(&sinfo
);
538 if (con
->reportscsiioctl
> 0)
539 pout("%sscsi error: %s\n", msg
, scsiErrString(err
));
540 return scsidev
->set_err(EIO
, "scsi error %s", scsiErrString(err
));
547 /////////////////////////////////////////////////////////////////////////////
551 /// Cypress USB Brigde support.
553 class usbcypress_device
554 : public tunnelled_device
<
555 /*implements*/ ata_device_with_command_set
556 /*by tunnelling through a*/, scsi_device
560 usbcypress_device(smart_interface
* intf
, scsi_device
* scsidev
,
561 const char * req_type
, unsigned char signature
);
563 virtual ~usbcypress_device() throw();
566 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
568 unsigned char m_signature
;
572 usbcypress_device::usbcypress_device(smart_interface
* intf
, scsi_device
* scsidev
,
573 const char * req_type
, unsigned char signature
)
574 : smart_device(intf
, scsidev
->get_dev_name(), "sat", req_type
),
575 tunnelled_device
<ata_device_with_command_set
, scsi_device
>(scsidev
),
576 m_signature(signature
)
578 set_info().info_name
= strprintf("%s [USB Cypress]", scsidev
->get_info_name());
581 usbcypress_device::~usbcypress_device() throw()
586 /* see cy7c68300c_8.pdf for more information */
587 #define USBCYPRESS_PASSTHROUGH_LEN 16
588 int usbcypress_device::ata_command_interface(smart_command_set command
, int select
, char *data
)
590 struct scsi_cmnd_io io_hdr
;
591 unsigned char cdb
[USBCYPRESS_PASSTHROUGH_LEN
];
592 unsigned char sense
[32];
595 int ck_cond
= 0; /* set to 1 to read register(s) back */
596 int protocol
= 3; /* non-data */
597 int t_dir
= 1; /* 0 -> to device, 1 -> from device */
598 int byte_block
= 1; /* 0 -> bytes, 1 -> 512 byte blocks */
599 int t_length
= 0; /* 0 -> no data transferred */
602 int sector_count
= 0;
606 int passthru_size
= USBCYPRESS_PASSTHROUGH_LEN
;
608 memset(cdb
, 0, sizeof(cdb
));
609 memset(sense
, 0, sizeof(sense
));
611 ata_command
= ATA_SMART_CMD
;
613 case CHECK_POWER_MODE
:
614 ata_command
= ATA_CHECK_POWER_MODE
;
618 case READ_VALUES
: /* READ DATA */
619 feature
= ATA_SMART_READ_VALUES
;
620 sector_count
= 1; /* one (512 byte) block */
621 protocol
= 4; /* PIO data-in */
622 t_length
= 2; /* sector count holds count */
625 case READ_THRESHOLDS
: /* obsolete */
626 feature
= ATA_SMART_READ_THRESHOLDS
;
627 sector_count
= 1; /* one (512 byte) block */
629 protocol
= 4; /* PIO data-in */
630 t_length
= 2; /* sector count holds count */
634 feature
= ATA_SMART_READ_LOG_SECTOR
;
635 sector_count
= 1; /* one (512 byte) block */
637 protocol
= 4; /* PIO data-in */
638 t_length
= 2; /* sector count holds count */
642 feature
= ATA_SMART_WRITE_LOG_SECTOR
;
643 sector_count
= 1; /* one (512 byte) block */
645 protocol
= 5; /* PIO data-out */
646 t_length
= 2; /* sector count holds count */
647 t_dir
= 0; /* to device */
651 ata_command
= ATA_IDENTIFY_DEVICE
;
652 sector_count
= 1; /* one (512 byte) block */
653 protocol
= 4; /* PIO data-in */
654 t_length
= 2; /* sector count holds count */
658 ata_command
= ATA_IDENTIFY_PACKET_DEVICE
;
659 sector_count
= 1; /* one (512 byte) block */
660 protocol
= 4; /* PIO data-in */
661 t_length
= 2; /* sector count (7:0) holds count */
665 feature
= ATA_SMART_ENABLE
;
669 feature
= ATA_SMART_DISABLE
;
673 // this command only says if SMART is working. It could be
674 // replaced with STATUS_CHECK below.
675 feature
= ATA_SMART_STATUS
;
679 feature
= ATA_SMART_AUTO_OFFLINE
;
680 sector_count
= select
; // YET NOTE - THIS IS A NON-DATA COMMAND!!
683 feature
= ATA_SMART_AUTOSAVE
;
684 sector_count
= select
; // YET NOTE - THIS IS A NON-DATA COMMAND!!
686 case IMMEDIATE_OFFLINE
:
687 feature
= ATA_SMART_IMMEDIATE_OFFLINE
;
691 // This command uses HDIO_DRIVE_TASK and has different syntax than
692 // the other commands.
693 feature
= ATA_SMART_STATUS
; /* SMART RETURN STATUS */
697 pout("Unrecognized command %d in usbcypress_device::ata_command_interface()\n"
698 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
702 if (ATA_SMART_CMD
== ata_command
) {
707 cdb
[0] = m_signature
; // bVSCBSignature : vendor-specific command
708 cdb
[1] = 0x24; // bVSCBSubCommand : 0x24 for ATACB
710 if (ata_command
== ATA_IDENTIFY_DEVICE
|| ata_command
== ATA_IDENTIFY_PACKET_DEVICE
)
711 cdb
[2] |= (1<<7); //set IdentifyPacketDevice for these cmds
712 cdb
[3] = 0xff - (1<<0) - (1<<6); //features, sector count, lba low, lba med
713 // lba high, command are valid
714 cdb
[4] = byte_block
; //TransferBlockCount : 512
718 cdb
[7] = sector_count
;
722 cdb
[12] = ata_command
;
724 memset(&io_hdr
, 0, sizeof(io_hdr
));
726 io_hdr
.dxfer_dir
= DXFER_NONE
;
727 io_hdr
.dxfer_len
= 0;
728 } else if (t_dir
) { /* from device */
729 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
730 io_hdr
.dxfer_len
= copydata
;
731 io_hdr
.dxferp
= (unsigned char *)data
;
732 memset(data
, 0, copydata
); /* prefill with zeroes */
733 } else { /* to device */
734 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
735 io_hdr
.dxfer_len
= outlen
;
736 io_hdr
.dxferp
= (unsigned char *)data
;
739 io_hdr
.cmnd_len
= passthru_size
;
740 io_hdr
.sensep
= sense
;
741 io_hdr
.max_sense_len
= sizeof(sense
);
742 io_hdr
.timeout
= SCSI_TIMEOUT_DEFAULT
;
744 scsi_device
* scsidev
= get_tunnel_dev();
745 if (!scsidev
->scsi_pass_through(&io_hdr
)) {
746 if (con
->reportscsiioctl
> 0)
747 pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
748 "errno=%d [%s]\n", scsidev
->get_errno(), scsidev
->get_errmsg());
749 set_err(scsidev
->get_err());
753 // if there is a sense the command failed or the
754 // device doesn't support usbcypress
755 if (io_hdr
.scsi_status
== SCSI_STATUS_CHECK_CONDITION
&&
756 sg_scsi_normalize_sense(io_hdr
.sensep
, io_hdr
.resp_sense_len
, NULL
)) {
760 unsigned char ardp
[8];
762 /* XXX this is racy if there other scsi command between
763 * the first usbcypress command and this one
765 //pout("If you got strange result, please retry without traffic on the disc\n");
766 /* we use the same command as before, but we set
767 * * the read taskfile bit, for not executing usbcypress command,
768 * * but reading register selected in srb->cmnd[4]
770 cdb
[2] = (1<<0); /* ask read taskfile */
771 memset(sense
, 0, sizeof(sense
));
773 /* transfert 8 bytes */
774 memset(&io_hdr
, 0, sizeof(io_hdr
));
775 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
776 io_hdr
.dxfer_len
= ard_len
;
777 io_hdr
.dxferp
= (unsigned char *)ardp
;
778 memset(ardp
, 0, ard_len
); /* prefill with zeroes */
781 io_hdr
.cmnd_len
= passthru_size
;
782 io_hdr
.sensep
= sense
;
783 io_hdr
.max_sense_len
= sizeof(sense
);
784 io_hdr
.timeout
= SCSI_TIMEOUT_DEFAULT
;
787 if (!scsidev
->scsi_pass_through(&io_hdr
)) {
788 if (con
->reportscsiioctl
> 0)
789 pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
790 "errno=%d [%s]\n", scsidev
->get_errno(), scsidev
->get_errmsg());
791 set_err(scsidev
->get_err());
794 // if there is a sense the command failed or the
795 // device doesn't support usbcypress
796 if (io_hdr
.scsi_status
== SCSI_STATUS_CHECK_CONDITION
&&
797 sg_scsi_normalize_sense(io_hdr
.sensep
, io_hdr
.resp_sense_len
, NULL
)) {
802 if (con
->reportscsiioctl
> 1) {
803 pout("Values from ATA Return Descriptor are:\n");
804 dStrHex((const char *)ardp
, ard_len
, 1);
807 if (ATA_CHECK_POWER_MODE
== ata_command
)
808 data
[0] = ardp
[2]; /* sector count (0:7) */
809 else if (STATUS_CHECK
== command
) {
810 if ((ardp
[4] == 0x4f) && (ardp
[5] == 0xc2))
811 return 0; /* GOOD smart status */
812 if ((ardp
[4] == 0xf4) && (ardp
[5] == 0x2c))
813 return 1; // smart predicting failure, "bad" status
814 // We haven't gotten output that makes sense so
815 // print out some debugging info
816 syserror("Error SMART Status command failed");
817 pout("This may be due to a race in usbcypress\n");
818 pout("Retry without other disc access\n");
819 pout("Please get assistance from " PACKAGE_HOMEPAGE
"\n");
820 pout("Values from ATA Return Descriptor are:\n");
821 dStrHex((const char *)ardp
, ard_len
, 1);
828 #if 0 // Not used, see autodetect_sat_device() below.
829 static int isprint_string(const char *s
)
832 if (isprint(*s
) == 0)
839 /* Attempt an IDENTIFY DEVICE ATA or IDENTIFY PACKET DEVICE command
840 If successful return 1, else 0 */
841 // TODO: Combine with has_sat_pass_through above
842 static int has_usbcypress_pass_through(ata_device
* atadev
, const char *manufacturer
, const char *product
)
844 struct ata_identify_device drive
;
845 char model
[40], serial
[20], firm
[8];
847 /* issue the command and do a checksum if possible */
848 if (ataReadHDIdentity(atadev
, &drive
) < 0)
851 /* check if model string match, revision doesn't work for me */
852 format_ata_string(model
, drive
.model
, 40);
853 if (*model
== 0 || isprint_string(model
) == 0)
856 if (manufacturer
&& strncmp(manufacturer
, model
, 8))
857 pout("manufacturer doesn't match in pass_through test\n");
859 strlen(model
) > 8 && strncmp(product
, model
+8, strlen(model
)-8))
860 pout("product doesn't match in pass_through test\n");
863 format_ata_string(serial
, drive
.serial_no
, 20);
864 if (isprint_string(serial
) == 0)
866 format_ata_string(firm
, drive
.fw_rev
, 8);
867 if (isprint_string(firm
) == 0)
873 /////////////////////////////////////////////////////////////////////////////
875 /// JMicron USB Bridge support.
877 class usbjmicron_device
878 : public tunnelled_device
<
879 /*implements*/ ata_device
,
880 /*by tunnelling through a*/ scsi_device
884 usbjmicron_device(smart_interface
* intf
, scsi_device
* scsidev
,
885 const char * req_type
, bool ata_48bit_support
, int port
);
887 virtual ~usbjmicron_device() throw();
891 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
894 bool get_registers(unsigned short addr
, unsigned char * buf
, unsigned short size
);
896 bool m_ata_48bit_support
;
901 usbjmicron_device::usbjmicron_device(smart_interface
* intf
, scsi_device
* scsidev
,
902 const char * req_type
, bool ata_48bit_support
, int port
)
903 : smart_device(intf
, scsidev
->get_dev_name(), "usbjmicron", req_type
),
904 tunnelled_device
<ata_device
, scsi_device
>(scsidev
),
905 m_ata_48bit_support(ata_48bit_support
), m_port(port
)
907 set_info().info_name
= strprintf("%s [USB JMicron]", scsidev
->get_info_name());
910 usbjmicron_device::~usbjmicron_device() throw()
915 bool usbjmicron_device::open()
918 if (!tunnelled_device
<ata_device
, scsi_device
>::open())
921 // Detect port if not specified
923 unsigned char regbuf
[1] = {0};
924 if (!get_registers(0x720f, regbuf
, sizeof(regbuf
))) {
929 switch (regbuf
[0] & 0x44) {
936 return set_err(EINVAL
, "Two devices connected, try '-d usbjmicron,[01]'");
939 return set_err(ENODEV
, "No device connected");
947 bool usbjmicron_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
949 if (!ata_cmd_is_ok(in
,
950 true, // data_out_support
951 false, // !multi_sector_support
952 m_ata_48bit_support
) // limited, see below
956 bool is_smart_status
= ( in
.in_regs
.command
== ATA_SMART_CMD
957 && in
.in_regs
.features
== ATA_SMART_STATUS
);
959 // Support output registers for SMART STATUS
960 if (in
.out_needed
.is_set() && !is_smart_status
)
961 return set_err(ENOSYS
, "ATA output registers not supported");
963 // Support 48-bit commands with zero high bytes
964 if (in
.in_regs
.is_real_48bit_cmd())
965 return set_err(ENOSYS
, "48-bit ATA commands not fully supported");
968 return set_err(EIO
, "Unknown JMicron port");
971 memset(&io_hdr
, 0, sizeof(io_hdr
));
974 unsigned char smart_status
= 0;
976 if (is_smart_status
&& in
.out_needed
.is_set()) {
977 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
978 io_hdr
.dxfer_len
= 1;
979 io_hdr
.dxferp
= &smart_status
;
981 else switch (in
.direction
) {
982 case ata_cmd_in::no_data
:
983 io_hdr
.dxfer_dir
= DXFER_NONE
;
985 case ata_cmd_in::data_in
:
986 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
987 io_hdr
.dxfer_len
= in
.size
;
988 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
989 memset(in
.buffer
, 0, in
.size
);
991 case ata_cmd_in::data_out
:
992 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
993 io_hdr
.dxfer_len
= in
.size
;
994 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
998 return set_err(EINVAL
);
1001 // Build pass through command
1002 unsigned char cdb
[12];
1004 cdb
[ 1] = (rwbit
? 0x10 : 0x00);
1006 cdb
[ 3] = (unsigned char)(io_hdr
.dxfer_len
>> 8);
1007 cdb
[ 4] = (unsigned char)(io_hdr
.dxfer_len
);
1008 cdb
[ 5] = in
.in_regs
.features
;
1009 cdb
[ 6] = in
.in_regs
.sector_count
;
1010 cdb
[ 7] = in
.in_regs
.lba_low
;
1011 cdb
[ 8] = in
.in_regs
.lba_mid
;
1012 cdb
[ 9] = in
.in_regs
.lba_high
;
1013 cdb
[10] = in
.in_regs
.device
| (m_port
== 0 ? 0xa0 : 0xb0);
1014 cdb
[11] = in
.in_regs
.command
;
1017 io_hdr
.cmnd_len
= sizeof(cdb
);
1019 scsi_device
* scsidev
= get_tunnel_dev();
1020 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1021 "usbjmicron_device::ata_pass_through: "))
1022 return set_err(scsidev
->get_err());
1024 if (in
.out_needed
.is_set()) {
1025 if (is_smart_status
) {
1026 switch (smart_status
) {
1027 case 0x01: case 0xc2:
1028 out
.out_regs
.lba_high
= 0xc2;
1029 out
.out_regs
.lba_mid
= 0x4f;
1031 case 0x00: case 0x2c:
1032 out
.out_regs
.lba_high
= 0x2c;
1033 out
.out_regs
.lba_mid
= 0xf4;
1038 #if 0 // Not needed for SMART STATUS, see also notes below
1040 // Read ATA output registers
1041 // NOTE: The register addresses are not valid for some older chip revisions
1042 // NOTE: There is a small race condition here!
1043 unsigned char regbuf
[16] = {0, };
1044 if (!get_registers((m_port
== 0 ? 0x8000 : 0x9000), regbuf
, sizeof(regbuf
)))
1047 out
.out_regs
.sector_count
= regbuf
[ 0];
1048 out
.out_regs
.lba_mid
= regbuf
[ 4];
1049 out
.out_regs
.lba_low
= regbuf
[ 6];
1050 out
.out_regs
.device
= regbuf
[ 9];
1051 out
.out_regs
.lba_high
= regbuf
[10];
1052 out
.out_regs
.error
= regbuf
[13];
1053 out
.out_regs
.status
= regbuf
[14];
1061 bool usbjmicron_device::get_registers(unsigned short addr
,
1062 unsigned char * buf
, unsigned short size
)
1064 unsigned char cdb
[12];
1068 cdb
[ 3] = (unsigned char)(size
>> 8);
1069 cdb
[ 4] = (unsigned char)(size
);
1071 cdb
[ 6] = (unsigned char)(addr
>> 8);
1072 cdb
[ 7] = (unsigned char)(addr
);
1078 scsi_cmnd_io io_hdr
;
1079 memset(&io_hdr
, 0, sizeof(io_hdr
));
1080 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1081 io_hdr
.dxfer_len
= size
;
1082 io_hdr
.dxferp
= buf
;
1084 io_hdr
.cmnd_len
= sizeof(cdb
);
1086 scsi_device
* scsidev
= get_tunnel_dev();
1087 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1088 "usbjmicron_device::get_registers: "))
1089 return set_err(scsidev
->get_err());
1095 /////////////////////////////////////////////////////////////////////////////
1097 /// SunplusIT USB Bridge support.
1099 class usbsunplus_device
1100 : public tunnelled_device
<
1101 /*implements*/ ata_device
,
1102 /*by tunnelling through a*/ scsi_device
1106 usbsunplus_device(smart_interface
* intf
, scsi_device
* scsidev
,
1107 const char * req_type
);
1109 virtual ~usbsunplus_device() throw();
1111 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
1115 usbsunplus_device::usbsunplus_device(smart_interface
* intf
, scsi_device
* scsidev
,
1116 const char * req_type
)
1117 : smart_device(intf
, scsidev
->get_dev_name(), "usbsunplus", req_type
),
1118 tunnelled_device
<ata_device
, scsi_device
>(scsidev
)
1120 set_info().info_name
= strprintf("%s [USB Sunplus]", scsidev
->get_info_name());
1123 usbsunplus_device::~usbsunplus_device() throw()
1127 bool usbsunplus_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
1129 if (!ata_cmd_is_ok(in
,
1130 true, // data_out_support
1131 false, // !multi_sector_support
1132 true) // ata_48bit_support
1136 scsi_cmnd_io io_hdr
;
1137 unsigned char cdb
[12];
1139 if (in
.in_regs
.is_48bit_cmd()) {
1140 // Set "previous" registers
1141 memset(&io_hdr
, 0, sizeof(io_hdr
));
1142 io_hdr
.dxfer_dir
= DXFER_NONE
;
1146 cdb
[ 2] = 0x23; // Subcommand: Pass through presetting
1149 cdb
[ 5] = in
.in_regs
.prev
.features
;
1150 cdb
[ 6] = in
.in_regs
.prev
.sector_count
;
1151 cdb
[ 7] = in
.in_regs
.prev
.lba_low
;
1152 cdb
[ 8] = in
.in_regs
.prev
.lba_mid
;
1153 cdb
[ 9] = in
.in_regs
.prev
.lba_high
;
1158 io_hdr
.cmnd_len
= sizeof(cdb
);
1160 scsi_device
* scsidev
= get_tunnel_dev();
1161 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1162 "usbsunplus_device::scsi_pass_through (presetting): "))
1163 return set_err(scsidev
->get_err());
1166 // Run Pass through command
1167 memset(&io_hdr
, 0, sizeof(io_hdr
));
1168 unsigned char protocol
;
1169 switch (in
.direction
) {
1170 case ata_cmd_in::no_data
:
1171 io_hdr
.dxfer_dir
= DXFER_NONE
;
1174 case ata_cmd_in::data_in
:
1175 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1176 io_hdr
.dxfer_len
= in
.size
;
1177 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1178 memset(in
.buffer
, 0, in
.size
);
1181 case ata_cmd_in::data_out
:
1182 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
1183 io_hdr
.dxfer_len
= in
.size
;
1184 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1188 return set_err(EINVAL
);
1193 cdb
[ 2] = 0x22; // Subcommand: Pass through
1195 cdb
[ 4] = (unsigned char)(io_hdr
.dxfer_len
>> 9);
1196 cdb
[ 5] = in
.in_regs
.features
;
1197 cdb
[ 6] = in
.in_regs
.sector_count
;
1198 cdb
[ 7] = in
.in_regs
.lba_low
;
1199 cdb
[ 8] = in
.in_regs
.lba_mid
;
1200 cdb
[ 9] = in
.in_regs
.lba_high
;
1201 cdb
[10] = in
.in_regs
.device
| 0xa0;
1202 cdb
[11] = in
.in_regs
.command
;
1205 io_hdr
.cmnd_len
= sizeof(cdb
);
1207 scsi_device
* scsidev
= get_tunnel_dev();
1208 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1209 "usbsunplus_device::scsi_pass_through: "))
1210 // Returns sense key 0x03 (medium error) on ATA command error
1211 return set_err(scsidev
->get_err());
1213 if (in
.out_needed
.is_set()) {
1214 // Read ATA output registers
1215 unsigned char regbuf
[8] = {0, };
1216 memset(&io_hdr
, 0, sizeof(io_hdr
));
1217 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1218 io_hdr
.dxfer_len
= sizeof(regbuf
);
1219 io_hdr
.dxferp
= regbuf
;
1223 cdb
[ 2] = 0x21; // Subcommand: Get status
1224 memset(cdb
+3, 0, sizeof(cdb
)-3);
1226 io_hdr
.cmnd_len
= sizeof(cdb
);
1228 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1229 "usbsunplus_device::scsi_pass_through (get registers): "))
1230 return set_err(scsidev
->get_err());
1232 out
.out_regs
.error
= regbuf
[1];
1233 out
.out_regs
.sector_count
= regbuf
[2];
1234 out
.out_regs
.lba_low
= regbuf
[3];
1235 out
.out_regs
.lba_mid
= regbuf
[4];
1236 out
.out_regs
.lba_high
= regbuf
[5];
1237 out
.out_regs
.device
= regbuf
[6];
1238 out
.out_regs
.status
= regbuf
[7];
1247 using namespace sat
;
1250 /////////////////////////////////////////////////////////////////////////////
1252 // Return ATA->SCSI filter for SAT or USB.
1254 ata_device
* smart_interface::get_sat_device(const char * type
, scsi_device
* scsidev
)
1256 if (!strncmp(type
, "sat", 3)) {
1257 int ptlen
= 0, n1
= -1, n2
= -1;
1258 if (!(((sscanf(type
, "sat%n,%d%n", &n1
, &ptlen
, &n2
) == 1 && n2
== (int)strlen(type
)) || n1
== (int)strlen(type
))
1259 && (ptlen
== 0 || ptlen
== 12 || ptlen
== 16))) {
1260 set_err(EINVAL
, "Option '-d sat,<n>' requires <n> to be 0, 12 or 16");
1263 return new sat_device(this, scsidev
, type
, ptlen
);
1266 else if (!strncmp(type
, "usbcypress", 10)) {
1267 unsigned signature
= 0x24; int n1
= -1, n2
= -1;
1268 if (!(((sscanf(type
, "usbcypress%n,0x%x%n", &n1
, &signature
, &n2
) == 1 && n2
== (int)strlen(type
)) || n1
== (int)strlen(type
))
1269 && signature
<= 0xff)) {
1270 set_err(EINVAL
, "Option '-d usbcypress,<n>' requires <n> to be "
1271 "an hexadecimal number between 0x0 and 0xff");
1274 return new usbcypress_device(this, scsidev
, type
, signature
);
1277 else if (!strncmp(type
, "usbjmicron", 10)) {
1278 const char * t
= type
+ 10;
1279 bool ata_48bit_support
= false;
1280 if (!strncmp(t
, ",x", 2)) {
1282 ata_48bit_support
= true;
1284 int port
= -1, n
= -1;
1285 if (*t
&& !( (sscanf(t
, ",%d%n", &port
, &n
) == 1
1286 && n
== (int)strlen(t
) && 0 <= port
&& port
<= 1))) {
1287 set_err(EINVAL
, "Option '-d usbmicron[,x],<n>' requires <n> to be 0 or 1");
1290 return new usbjmicron_device(this, scsidev
, type
, ata_48bit_support
, port
);
1293 else if (!strcmp(type
, "usbsunplus")) {
1294 return new usbsunplus_device(this, scsidev
, type
);
1298 set_err(EINVAL
, "Unknown USB device type '%s'", type
);
1303 // Try to detect a SAT device behind a SCSI interface.
1305 ata_device
* smart_interface::autodetect_sat_device(scsi_device
* scsidev
,
1306 const unsigned char * inqdata
, unsigned inqsize
)
1308 if (!scsidev
->is_open())
1312 if (inqdata
&& inqsize
>= 36 && !memcmp(inqdata
+ 8, "ATA ", 8)) { // TODO: Linux-specific?
1313 ata_device_auto_ptr
atadev( new sat_device(this, scsidev
, "") , scsidev
);
1314 if (has_sat_pass_through(atadev
.get()))
1315 return atadev
.release(); // Detected SAT
1322 /////////////////////////////////////////////////////////////////////////////
1323 // USB device type detection
1325 // Format USB ID for error messages
1326 static std::string
format_usb_id(int vendor_id
, int product_id
, int version
)
1329 return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id
, product_id
, version
);
1331 return strprintf("[0x%04x:0x%04x]", vendor_id
, product_id
);
1334 // Get type name for USB device with known VENDOR:PRODUCT ID.
1335 const char * smart_interface::get_usb_dev_type_by_id(int vendor_id
, int product_id
,
1336 int version
/*= -1*/)
1338 usb_dev_info info
, info2
;
1339 int n
= lookup_usb_device(vendor_id
, product_id
, version
, info
, info2
);
1342 set_err(EINVAL
, "Unknown USB bridge %s",
1343 format_usb_id(vendor_id
, product_id
, version
).c_str());
1348 set_err(EINVAL
, "USB bridge %s type is ambiguous: '%s' or '%s'",
1349 format_usb_id(vendor_id
, product_id
, version
).c_str(),
1350 (!info
.usb_type
.empty() ? info
.usb_type
.c_str() : "[unsupported]"),
1351 (!info2
.usb_type
.empty() ? info2
.usb_type
.c_str() : "[unsupported]"));
1355 if (info
.usb_type
.empty()) {
1356 set_err(ENOSYS
, "Unsupported USB bridge %s",
1357 format_usb_id(vendor_id
, product_id
, version
).c_str());
1361 // TODO: change return type to std::string
1362 static std::string type
;
1363 type
= info
.usb_type
;
1364 return type
.c_str();