4 * Home page of code is: http://www.smartmontools.org
6 * Copyright (C) 2006-15 Douglas Gilbert <dgilbert@interlog.com>
7 * Copyright (C) 2009-17 Christian Franke
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 Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 4386 2017-01-28 16:35:06Z chrfranke $";
67 /* This is a slightly stretched SCSI sense "descriptor" format header.
68 The addition is to allow the 0x70 and 0x71 response codes. The idea
69 is to place the salient data of both "fixed" and "descriptor" sense
70 format into one structure to ease application processing.
71 The original sense buffer should be kept around for those cases
72 in which more information is required (e.g. the LBA of a MEDIUM ERROR). */
73 /// Abridged SCSI sense data
74 struct sg_scsi_sense_hdr
{
75 unsigned char response_code
; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
76 unsigned char sense_key
;
82 unsigned char additional_length
;
85 /* Maps the salient data from a sense buffer which is in either fixed or
86 descriptor format into a structure mimicking a descriptor format
87 header (i.e. the first 8 bytes of sense descriptor format).
88 If zero response code returns 0. Otherwise returns 1 and if 'sshp' is
89 non-NULL then zero all fields and then set the appropriate fields in
90 that structure. sshp::additional_length is always 0 for response
91 codes 0x70 and 0x71 (fixed format). */
92 static int sg_scsi_normalize_sense(const unsigned char * sensep
, int sb_len
,
93 struct sg_scsi_sense_hdr
* sshp
);
95 #define SAT_ATA_PASSTHROUGH_12LEN 12
96 #define SAT_ATA_PASSTHROUGH_16LEN 16
98 #define DEF_SAT_ATA_PASSTHRU_SIZE 16
99 #define ATA_RETURN_DESCRIPTOR 9
102 namespace sat
{ // no need to publish anything, name provided for Doxygen
105 /// Implements ATA by tunnelling through SCSI.
108 : public tunnelled_device
<
109 /*implements*/ ata_device
110 /*by tunnelling through a*/, scsi_device
112 virtual public /*implements*/ scsi_device
115 sat_device(smart_interface
* intf
, scsi_device
* scsidev
,
116 const char * req_type
, int passthrulen
= 0, bool enable_auto
= false);
118 virtual ~sat_device() throw();
120 virtual smart_device
* autodetect_open();
122 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
124 virtual bool scsi_pass_through(scsi_cmnd_io
* iop
);
132 sat_device::sat_device(smart_interface
* intf
, scsi_device
* scsidev
,
133 const char * req_type
, int passthrulen
/* = 0 */, bool enable_auto
/* = false */)
134 : smart_device(intf
, scsidev
->get_dev_name(),
135 (enable_auto
? "sat,auto" : "sat"), req_type
),
136 tunnelled_device
<ata_device
, scsi_device
>(scsidev
),
137 m_passthrulen(passthrulen
),
138 m_enable_auto(enable_auto
)
141 hide_ata(); // Start as SCSI, switch to ATA in autodetect_open()
143 hide_scsi(); // ATA always
144 if (strcmp(scsidev
->get_dev_type(), "scsi"))
145 set_info().dev_type
+= strprintf("+%s", scsidev
->get_dev_type());
147 set_info().info_name
= strprintf("%s [%sSAT]", scsidev
->get_info_name(),
148 (enable_auto
? "SCSI/" : ""));
151 sat_device::~sat_device() throw()
156 // cdb[0]: ATA PASS THROUGH (16) SCSI command opcode byte (0x85)
157 // cdb[1]: multiple_count, protocol + extend
158 // cdb[2]: offline, ck_cond, t_dir, byte_block + t_length
159 // cdb[3]: features (15:8)
160 // cdb[4]: features (7:0)
161 // cdb[5]: sector_count (15:8)
162 // cdb[6]: sector_count (7:0)
163 // cdb[7]: lba_low (15:8)
164 // cdb[8]: lba_low (7:0)
165 // cdb[9]: lba_mid (15:8)
166 // cdb[10]: lba_mid (7:0)
167 // cdb[11]: lba_high (15:8)
168 // cdb[12]: lba_high (7:0)
170 // cdb[14]: (ata) command
171 // cdb[15]: control (SCSI, leave as zero)
173 // 24 bit lba (from MSB): cdb[12] cdb[10] cdb[8]
174 // 48 bit lba (from MSB): cdb[11] cdb[9] cdb[7] cdb[12] cdb[10] cdb[8]
177 // cdb[0]: ATA PASS THROUGH (12) SCSI command opcode byte (0xa1)
178 // cdb[1]: multiple_count, protocol + extend
179 // cdb[2]: offline, ck_cond, t_dir, byte_block + t_length
180 // cdb[3]: features (7:0)
181 // cdb[4]: sector_count (7:0)
182 // cdb[5]: lba_low (7:0)
183 // cdb[6]: lba_mid (7:0)
184 // cdb[7]: lba_high (7:0)
186 // cdb[9]: (ata) command
188 // cdb[11]: control (SCSI, leave as zero)
191 // ATA Return Descriptor (component of descriptor sense data)
192 // des[0]: descriptor code (0x9)
193 // des[1]: additional descriptor length (0xc)
194 // des[2]: extend (bit 0)
196 // des[4]: sector_count (15:8)
197 // des[5]: sector_count (7:0)
198 // des[6]: lba_low (15:8)
199 // des[7]: lba_low (7:0)
200 // des[8]: lba_mid (15:8)
201 // des[9]: lba_mid (7:0)
202 // des[10]: lba_high (15:8)
203 // des[11]: lba_high (7:0)
208 // ATA registers returned via fixed format sense (allowed >= SAT-2)
209 // fxs[0]: info_valid (bit 7); response_code (6:0)
210 // fxs[1]: (obsolete)
211 // fxs[2]: sense_key (3:0) --> recovered error (formerly 'no sense')
212 // fxs[3]: information (31:24) --> ATA Error register
213 // fxs[4]: information (23:16) --> ATA Status register
214 // fxs[5]: information (15:8) --> ATA Device register
215 // fxs[6]: information (7:0) --> ATA Count (7:0)
216 // fxs[7]: additional sense length [should be >= 10]
217 // fxs[8]: command specific info (31:24) --> Extend (7), count_upper_nonzero
218 // (6), lba_upper_nonzero(5), log_index (3:0)
219 // fxs[9]: command specific info (23:16) --> ATA LBA (7:0)
220 // fxs[10]: command specific info (15:8) --> ATA LBA (15:8)
221 // fxs[11]: command specific info (7:0) --> ATA LBA (23:16)
222 // fxs[12]: additional sense code (asc) --> 0x0
223 // fxs[13]: additional sense code qualifier (ascq) --> 0x1d
224 // asc,ascq = 0x0,0x1d --> 'ATA pass through information available'
229 // This interface routine takes ATA SMART commands and packages
230 // them in the SAT-defined ATA PASS THROUGH SCSI commands. There are
231 // two available SCSI commands: a 12 byte and 16 byte variant; the
232 // one used is chosen via this->m_passthrulen .
233 // DETAILED DESCRIPTION OF ARGUMENTS
234 // device: is the file descriptor provided by (a SCSI dvice type) open()
235 // command: defines the different ATA operations.
236 // select: additional input data if needed (which log, which type of
238 // data: location to write output data, if needed (512 bytes).
239 // Note: not all commands use all arguments.
241 // -1 if the command failed
242 // 0 if the command succeeded,
243 // STATUS_CHECK routine:
244 // -1 if the command failed
245 // 0 if the command succeeded and disk SMART status is "OK"
246 // 1 if the command succeeded and disk SMART status is "FAILING"
248 bool sat_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
250 if (!ata_cmd_is_supported(in
,
251 ata_device::supports_data_out
|
252 ata_device::supports_output_regs
|
253 ata_device::supports_multi_sector
|
254 ata_device::supports_48bit
,
259 struct scsi_cmnd_io io_hdr
;
260 struct scsi_sense_disect sinfo
;
261 struct sg_scsi_sense_hdr ssh
;
262 unsigned char cdb
[SAT_ATA_PASSTHROUGH_16LEN
];
263 unsigned char sense
[32];
264 const unsigned char * ardp
;
265 int ard_len
, have_sense
;
267 int ck_cond
= 0; /* set to 1 to read register(s) back */
268 int protocol
= 3; /* non-data */
269 int t_dir
= 1; /* 0 -> to device, 1 -> from device */
270 int byte_block
= 1; /* 0 -> bytes, 1 -> 512 byte blocks */
271 int t_length
= 0; /* 0 -> no data transferred */
272 int passthru_size
= DEF_SAT_ATA_PASSTHRU_SIZE
;
273 bool sense_descriptor
= true;
275 memset(cdb
, 0, sizeof(cdb
));
276 memset(sense
, 0, sizeof(sense
));
278 // Set data direction
279 // TODO: This works only for commands where sector_count holds count!
280 switch (in
.direction
) {
281 case ata_cmd_in::no_data
:
283 case ata_cmd_in::data_in
:
284 protocol
= 4; // PIO data-in
285 t_length
= 2; // sector_count holds count
287 case ata_cmd_in::data_out
:
288 protocol
= 5; // PIO data-out
289 t_length
= 2; // sector_count holds count
290 t_dir
= 0; // to device
293 return set_err(EINVAL
, "sat_device::ata_pass_through: invalid direction=%d",
297 // Check condition if any output register needed
298 if (in
.out_needed
.is_set())
301 if ((SAT_ATA_PASSTHROUGH_12LEN
== m_passthrulen
) ||
302 (SAT_ATA_PASSTHROUGH_16LEN
== m_passthrulen
))
303 passthru_size
= m_passthrulen
;
305 // Set extend bit on 48-bit ATA command
306 if (in
.in_regs
.is_48bit_cmd()) {
307 if (passthru_size
!= SAT_ATA_PASSTHROUGH_16LEN
)
308 return set_err(ENOSYS
, "48-bit ATA commands require SAT ATA PASS-THROUGH (16)");
312 cdb
[0] = (SAT_ATA_PASSTHROUGH_12LEN
== passthru_size
) ?
313 SAT_ATA_PASSTHROUGH_12
: SAT_ATA_PASSTHROUGH_16
;
315 cdb
[1] = (protocol
<< 1) | extend
;
316 cdb
[2] = (ck_cond
<< 5) | (t_dir
<< 3) |
317 (byte_block
<< 2) | t_length
;
319 if (passthru_size
== SAT_ATA_PASSTHROUGH_12LEN
) {
320 // ATA PASS-THROUGH (12)
321 const ata_in_regs
& lo
= in
.in_regs
;
322 cdb
[3] = lo
.features
;
323 cdb
[4] = lo
.sector_count
;
326 cdb
[7] = lo
.lba_high
;
331 // ATA PASS-THROUGH (16)
332 const ata_in_regs
& lo
= in
.in_regs
;
333 const ata_in_regs
& hi
= in
.in_regs
.prev
;
334 // Note: all 'in.in_regs.prev.*' are always zero for 28-bit commands
335 cdb
[ 3] = hi
.features
;
336 cdb
[ 4] = lo
.features
;
337 cdb
[ 5] = hi
.sector_count
;
338 cdb
[ 6] = lo
.sector_count
;
339 cdb
[ 7] = hi
.lba_low
;
340 cdb
[ 8] = lo
.lba_low
;
341 cdb
[ 9] = hi
.lba_mid
;
342 cdb
[10] = lo
.lba_mid
;
343 cdb
[11] = hi
.lba_high
;
344 cdb
[12] = lo
.lba_high
;
346 cdb
[14] = lo
.command
;
349 memset(&io_hdr
, 0, sizeof(io_hdr
));
351 io_hdr
.dxfer_dir
= DXFER_NONE
;
352 io_hdr
.dxfer_len
= 0;
353 } else if (t_dir
) { /* from device */
354 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
355 io_hdr
.dxfer_len
= in
.size
;
356 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
357 memset(in
.buffer
, 0, in
.size
); // prefill with zeroes
358 } else { /* to device */
359 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
360 io_hdr
.dxfer_len
= in
.size
;
361 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
364 io_hdr
.cmnd_len
= passthru_size
;
365 io_hdr
.sensep
= sense
;
366 io_hdr
.max_sense_len
= sizeof(sense
);
367 io_hdr
.timeout
= SCSI_TIMEOUT_DEFAULT
;
369 scsi_device
* scsidev
= get_tunnel_dev();
370 if (!scsidev
->scsi_pass_through(&io_hdr
)) {
371 if (scsi_debugmode
> 0)
372 pout("sat_device::ata_pass_through: scsi_pass_through() failed, "
373 "errno=%d [%s]\n", scsidev
->get_errno(), scsidev
->get_errmsg());
374 return set_err(scsidev
->get_err());
378 have_sense
= sg_scsi_normalize_sense(io_hdr
.sensep
, io_hdr
.resp_sense_len
,
381 sense_descriptor
= ssh
.response_code
>= 0x72;
382 if (sense_descriptor
) {
383 /* look for SAT ATA Return Descriptor */
384 ardp
= sg_scsi_sense_desc_find(io_hdr
.sensep
,
385 io_hdr
.resp_sense_len
,
386 ATA_RETURN_DESCRIPTOR
);
388 ard_len
= ardp
[1] + 2;
391 else if (ard_len
> 14)
395 scsi_do_sense_disect(&io_hdr
, &sinfo
);
396 int status
= scsiSimpleSenseFilter(&sinfo
);
398 // Workaround for bogus sense_key in sense data with SAT ATA Return Descriptor
399 if ( status
&& ck_cond
&& ardp
&& ard_len
> 13
400 && (ardp
[13] & 0xc1) == 0x40 /* !BSY && DRDY && !ERR */) {
401 if (scsi_debugmode
> 0)
402 pout("ATA status (0x%02x) indicates success, ignoring SCSI sense_key\n",
407 if (0 != status
) { /* other than no_sense and recovered_error */
408 if (scsi_debugmode
> 0) {
409 pout("sat_device::ata_pass_through: scsi error: %s\n",
410 scsiErrString(status
));
411 if (ardp
&& (scsi_debugmode
> 1)) {
412 pout("Values from ATA Return Descriptor are:\n");
413 dStrHex((const char *)ardp
, ard_len
, 1);
416 if (t_dir
&& (t_length
> 0) && (in
.direction
== ata_cmd_in::data_in
))
417 memset(in
.buffer
, 0, in
.size
);
418 return set_err(EIO
, "scsi error %s", scsiErrString(status
));
421 if (ck_cond
) { /* expecting SAT specific sense data */
424 if (scsi_debugmode
> 1) {
425 pout("Values from ATA Return Descriptor are:\n");
426 dStrHex((const char *)ardp
, ard_len
, 1);
428 // Set output registers
429 ata_out_regs
& lo
= out
.out_regs
;
431 lo
.sector_count
= ardp
[ 5];
432 lo
.lba_low
= ardp
[ 7];
433 lo
.lba_mid
= ardp
[ 9];
434 lo
.lba_high
= ardp
[11];
435 lo
.device
= ardp
[12];
436 lo
.status
= ardp
[13];
437 if (in
.in_regs
.is_48bit_cmd()) {
438 ata_out_regs
& hi
= out
.out_regs
.prev
;
439 hi
.sector_count
= ardp
[ 4];
440 hi
.lba_low
= ardp
[ 6];
441 hi
.lba_mid
= ardp
[ 8];
442 hi
.lba_high
= ardp
[10];
444 } else if ((! sense_descriptor
) &&
446 (SCSI_ASCQ_ATA_PASS_THROUGH
== ssh
.ascq
) &&
447 (0 != io_hdr
.sensep
[4] /* Some ATA STATUS bit must be set */)) {
448 /* in SAT-2 and later, ATA registers may be passed back via
449 * fixed format sense data [ref: sat3r07 section 12.2.2.7] */
450 ata_out_regs
& lo
= out
.out_regs
;
451 lo
.error
= io_hdr
.sensep
[ 3];
452 lo
.status
= io_hdr
.sensep
[ 4];
453 lo
.device
= io_hdr
.sensep
[ 5];
454 lo
.sector_count
= io_hdr
.sensep
[ 6];
455 lo
.lba_low
= io_hdr
.sensep
[ 9];
456 lo
.lba_mid
= io_hdr
.sensep
[10];
457 lo
.lba_high
= io_hdr
.sensep
[11];
458 if (in
.in_regs
.is_48bit_cmd()) {
459 if (0 == (0x60 & io_hdr
.sensep
[8])) {
460 ata_out_regs
& hi
= out
.out_regs
.prev
;
466 /* getting the "hi." values when either
467 * count_upper_nonzero or lba_upper_nonzero are set
468 * involves fetching the SCSI ATA PASS-THROUGH
469 * Results log page and decoding the descriptor with
470 * the matching log_index field. Painful. */
475 } else { /* ck_cond == 0 */
477 if (((SCSI_SK_NO_SENSE
== ssh
.sense_key
) ||
478 (SCSI_SK_RECOVERED_ERR
== ssh
.sense_key
)) &&
480 (SCSI_ASCQ_ATA_PASS_THROUGH
== ssh
.ascq
)) {
481 if (scsi_debugmode
> 0) {
482 if (sense_descriptor
&& ardp
) {
483 pout("Values from ATA Return Descriptor are:\n");
484 dStrHex((const char *)ardp
, ard_len
, 1);
485 } else if (! sense_descriptor
) {
486 pout("Values from ATA fixed format sense are:\n");
487 pout(" Error: 0x%x\n", io_hdr
.sensep
[3]);
488 pout(" Status: 0x%x\n", io_hdr
.sensep
[4]);
489 pout(" Device: 0x%x\n", io_hdr
.sensep
[5]);
490 pout(" Count: 0x%x\n", io_hdr
.sensep
[6]);
494 return set_err(EIO
, "SAT command failed");
500 bool sat_device::scsi_pass_through(scsi_cmnd_io
* iop
)
502 scsi_device
* scsidev
= get_tunnel_dev();
503 if (!scsidev
->scsi_pass_through(iop
)) {
504 set_err(scsidev
->get_err());
510 smart_device
* sat_device::autodetect_open()
512 if (!open() || !m_enable_auto
)
515 scsi_device
* scsidev
= get_tunnel_dev();
517 unsigned char inqdata
[36] = {0, };
518 if (scsiStdInquiry(scsidev
, inqdata
, sizeof(inqdata
))) {
519 smart_device::error_info err
= scsidev
->get_err();
521 set_err(err
.no
, "INQUIRY [SAT]: %s", err
.msg
.c_str());
525 // Check for SAT "VENDOR"
526 int inqsize
= inqdata
[4] + 5;
527 bool sat
= (inqsize
>= 36 && !memcmp(inqdata
+ 8, "ATA ", 8));
533 set_info().dev_type
= (sat
? "sat" : scsidev
->get_dev_type());
534 set_info().info_name
= strprintf("%s [%s]", scsidev
->get_info_name(),
535 (sat
? "SAT" : "SCSI"));
541 /////////////////////////////////////////////////////////////////////////////
543 /* Attempt an IDENTIFY DEVICE ATA command via SATL when packet_interface
544 is false otherwise attempt IDENTIFY PACKET DEVICE. If successful
545 return true, else false */
547 static bool has_sat_pass_through(ata_device
* dev
, bool packet_interface
= false)
549 /* Note: malloc() ensures the read buffer lands on a single
550 page. This avoids some bugs seen on LSI controlers under
552 char *data
= (char *)malloc(512);
554 in
.in_regs
.command
= (packet_interface
? ATA_IDENTIFY_PACKET_DEVICE
: ATA_IDENTIFY_DEVICE
);
555 in
.set_data_in(data
, 1);
556 bool ret
= dev
->ata_pass_through(in
);
561 /////////////////////////////////////////////////////////////////////////////
563 /* Next two functions are borrowed from sg_lib.c in the sg3_utils
564 package. Same copyrght owner, same license as this file. */
565 static int sg_scsi_normalize_sense(const unsigned char * sensep
, int sb_len
,
566 struct sg_scsi_sense_hdr
* sshp
)
569 memset(sshp
, 0, sizeof(struct sg_scsi_sense_hdr
));
570 if ((NULL
== sensep
) || (0 == sb_len
) || (0x70 != (0x70 & sensep
[0])))
573 sshp
->response_code
= (0x7f & sensep
[0]);
574 if (sshp
->response_code
>= 0x72) { /* descriptor format */
576 sshp
->sense_key
= (0xf & sensep
[1]);
578 sshp
->asc
= sensep
[2];
580 sshp
->ascq
= sensep
[3];
582 sshp
->additional_length
= sensep
[7];
583 } else { /* fixed format */
585 sshp
->sense_key
= (0xf & sensep
[2]);
587 sb_len
= (sb_len
< (sensep
[7] + 8)) ? sb_len
:
590 sshp
->asc
= sensep
[12];
592 sshp
->ascq
= sensep
[13];
600 // Call scsi_pass_through and check sense.
601 // TODO: Provide as member function of class scsi_device (?)
602 static bool scsi_pass_through_and_check(scsi_device
* scsidev
, scsi_cmnd_io
* iop
,
603 const char * msg
= "")
605 // Provide sense buffer
606 unsigned char sense
[32] = {0, };
608 iop
->max_sense_len
= sizeof(sense
);
609 iop
->timeout
= SCSI_TIMEOUT_DEFAULT
;
612 if (!scsidev
->scsi_pass_through(iop
)) {
613 if (scsi_debugmode
> 0)
614 pout("%sscsi_pass_through() failed, errno=%d [%s]\n",
615 msg
, scsidev
->get_errno(), scsidev
->get_errmsg());
620 scsi_sense_disect sinfo
;
621 scsi_do_sense_disect(iop
, &sinfo
);
622 int err
= scsiSimpleSenseFilter(&sinfo
);
624 if (scsi_debugmode
> 0)
625 pout("%sscsi error: %s\n", msg
, scsiErrString(err
));
626 return scsidev
->set_err(EIO
, "scsi error %s", scsiErrString(err
));
633 /////////////////////////////////////////////////////////////////////////////
637 /// Cypress USB Brigde support.
639 class usbcypress_device
640 : public tunnelled_device
<
641 /*implements*/ ata_device_with_command_set
642 /*by tunnelling through a*/, scsi_device
646 usbcypress_device(smart_interface
* intf
, scsi_device
* scsidev
,
647 const char * req_type
, unsigned char signature
);
649 virtual ~usbcypress_device() throw();
652 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
654 unsigned char m_signature
;
658 usbcypress_device::usbcypress_device(smart_interface
* intf
, scsi_device
* scsidev
,
659 const char * req_type
, unsigned char signature
)
660 : smart_device(intf
, scsidev
->get_dev_name(), "sat", req_type
),
661 tunnelled_device
<ata_device_with_command_set
, scsi_device
>(scsidev
),
662 m_signature(signature
)
664 set_info().info_name
= strprintf("%s [USB Cypress]", scsidev
->get_info_name());
667 usbcypress_device::~usbcypress_device() throw()
672 /* see cy7c68300c_8.pdf for more information */
673 #define USBCYPRESS_PASSTHROUGH_LEN 16
674 int usbcypress_device::ata_command_interface(smart_command_set command
, int select
, char *data
)
676 struct scsi_cmnd_io io_hdr
;
677 unsigned char cdb
[USBCYPRESS_PASSTHROUGH_LEN
];
678 unsigned char sense
[32];
681 int ck_cond
= 0; /* set to 1 to read register(s) back */
682 int t_dir
= 1; /* 0 -> to device, 1 -> from device */
683 int byte_block
= 1; /* 0 -> bytes, 1 -> 512 byte blocks */
684 int t_length
= 0; /* 0 -> no data transferred */
687 int sector_count
= 0;
691 int passthru_size
= USBCYPRESS_PASSTHROUGH_LEN
;
693 memset(cdb
, 0, sizeof(cdb
));
694 memset(sense
, 0, sizeof(sense
));
696 ata_command
= ATA_SMART_CMD
;
698 case CHECK_POWER_MODE
:
699 ata_command
= ATA_CHECK_POWER_MODE
;
703 case READ_VALUES
: /* READ DATA */
704 feature
= ATA_SMART_READ_VALUES
;
705 sector_count
= 1; /* one (512 byte) block */
706 t_length
= 2; /* sector count holds count */
709 case READ_THRESHOLDS
: /* obsolete */
710 feature
= ATA_SMART_READ_THRESHOLDS
;
711 sector_count
= 1; /* one (512 byte) block */
713 t_length
= 2; /* sector count holds count */
717 feature
= ATA_SMART_READ_LOG_SECTOR
;
718 sector_count
= 1; /* one (512 byte) block */
720 t_length
= 2; /* sector count holds count */
724 feature
= ATA_SMART_WRITE_LOG_SECTOR
;
725 sector_count
= 1; /* one (512 byte) block */
727 t_length
= 2; /* sector count holds count */
728 t_dir
= 0; /* to device */
732 ata_command
= ATA_IDENTIFY_DEVICE
;
733 sector_count
= 1; /* one (512 byte) block */
734 t_length
= 2; /* sector count holds count */
738 ata_command
= ATA_IDENTIFY_PACKET_DEVICE
;
739 sector_count
= 1; /* one (512 byte) block */
740 t_length
= 2; /* sector count (7:0) holds count */
744 feature
= ATA_SMART_ENABLE
;
748 feature
= ATA_SMART_DISABLE
;
752 // this command only says if SMART is working. It could be
753 // replaced with STATUS_CHECK below.
754 feature
= ATA_SMART_STATUS
;
758 feature
= ATA_SMART_AUTO_OFFLINE
;
759 sector_count
= select
; // YET NOTE - THIS IS A NON-DATA COMMAND!!
762 feature
= ATA_SMART_AUTOSAVE
;
763 sector_count
= select
; // YET NOTE - THIS IS A NON-DATA COMMAND!!
765 case IMMEDIATE_OFFLINE
:
766 feature
= ATA_SMART_IMMEDIATE_OFFLINE
;
770 // This command uses HDIO_DRIVE_TASK and has different syntax than
771 // the other commands.
772 feature
= ATA_SMART_STATUS
; /* SMART RETURN STATUS */
776 pout("Unrecognized command %d in usbcypress_device::ata_command_interface()\n"
777 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
781 if (ATA_SMART_CMD
== ata_command
) {
786 cdb
[0] = m_signature
; // bVSCBSignature : vendor-specific command
787 cdb
[1] = 0x24; // bVSCBSubCommand : 0x24 for ATACB
789 if (ata_command
== ATA_IDENTIFY_DEVICE
|| ata_command
== ATA_IDENTIFY_PACKET_DEVICE
)
790 cdb
[2] |= (1<<7); //set IdentifyPacketDevice for these cmds
791 cdb
[3] = 0xff - (1<<0) - (1<<6); //features, sector count, lba low, lba med
792 // lba high, command are valid
793 cdb
[4] = byte_block
; //TransferBlockCount : 512
797 cdb
[7] = sector_count
;
801 cdb
[12] = ata_command
;
803 memset(&io_hdr
, 0, sizeof(io_hdr
));
805 io_hdr
.dxfer_dir
= DXFER_NONE
;
806 io_hdr
.dxfer_len
= 0;
807 } else if (t_dir
) { /* from device */
808 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
809 io_hdr
.dxfer_len
= copydata
;
810 io_hdr
.dxferp
= (unsigned char *)data
;
811 memset(data
, 0, copydata
); /* prefill with zeroes */
812 } else { /* to device */
813 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
814 io_hdr
.dxfer_len
= outlen
;
815 io_hdr
.dxferp
= (unsigned char *)data
;
818 io_hdr
.cmnd_len
= passthru_size
;
819 io_hdr
.sensep
= sense
;
820 io_hdr
.max_sense_len
= sizeof(sense
);
821 io_hdr
.timeout
= SCSI_TIMEOUT_DEFAULT
;
823 scsi_device
* scsidev
= get_tunnel_dev();
824 if (!scsidev
->scsi_pass_through(&io_hdr
)) {
825 if (scsi_debugmode
> 0)
826 pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
827 "errno=%d [%s]\n", scsidev
->get_errno(), scsidev
->get_errmsg());
828 set_err(scsidev
->get_err());
832 // if there is a sense the command failed or the
833 // device doesn't support usbcypress
834 if (io_hdr
.scsi_status
== SCSI_STATUS_CHECK_CONDITION
&&
835 sg_scsi_normalize_sense(io_hdr
.sensep
, io_hdr
.resp_sense_len
, NULL
)) {
839 unsigned char ardp
[8];
841 /* XXX this is racy if there other scsi command between
842 * the first usbcypress command and this one
844 //pout("If you got strange result, please retry without traffic on the disc\n");
845 /* we use the same command as before, but we set
846 * * the read taskfile bit, for not executing usbcypress command,
847 * * but reading register selected in srb->cmnd[4]
849 cdb
[2] = (1<<0); /* ask read taskfile */
850 memset(sense
, 0, sizeof(sense
));
852 /* transfert 8 bytes */
853 memset(&io_hdr
, 0, sizeof(io_hdr
));
854 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
855 io_hdr
.dxfer_len
= ard_len
;
856 io_hdr
.dxferp
= (unsigned char *)ardp
;
857 memset(ardp
, 0, ard_len
); /* prefill with zeroes */
860 io_hdr
.cmnd_len
= passthru_size
;
861 io_hdr
.sensep
= sense
;
862 io_hdr
.max_sense_len
= sizeof(sense
);
863 io_hdr
.timeout
= SCSI_TIMEOUT_DEFAULT
;
866 if (!scsidev
->scsi_pass_through(&io_hdr
)) {
867 if (scsi_debugmode
> 0)
868 pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
869 "errno=%d [%s]\n", scsidev
->get_errno(), scsidev
->get_errmsg());
870 set_err(scsidev
->get_err());
873 // if there is a sense the command failed or the
874 // device doesn't support usbcypress
875 if (io_hdr
.scsi_status
== SCSI_STATUS_CHECK_CONDITION
&&
876 sg_scsi_normalize_sense(io_hdr
.sensep
, io_hdr
.resp_sense_len
, NULL
)) {
881 if (scsi_debugmode
> 1) {
882 pout("Values from ATA Return Descriptor are:\n");
883 dStrHex((const char *)ardp
, ard_len
, 1);
886 if (ATA_CHECK_POWER_MODE
== ata_command
)
887 data
[0] = ardp
[2]; /* sector count (0:7) */
888 else if (STATUS_CHECK
== command
) {
889 if ((ardp
[4] == 0x4f) && (ardp
[5] == 0xc2))
890 return 0; /* GOOD smart status */
891 if ((ardp
[4] == 0xf4) && (ardp
[5] == 0x2c))
892 return 1; // smart predicting failure, "bad" status
893 // We haven't gotten output that makes sense so
894 // print out some debugging info
895 syserror("Error SMART Status command failed");
896 pout("This may be due to a race in usbcypress\n");
897 pout("Retry without other disc access\n");
898 pout("Please get assistance from " PACKAGE_HOMEPAGE
"\n");
899 pout("Values from ATA Return Descriptor are:\n");
900 dStrHex((const char *)ardp
, ard_len
, 1);
907 #if 0 // Not used, see autodetect_sat_device() below.
908 static int isprint_string(const char *s
)
911 if (isprint(*s
) == 0)
918 /* Attempt an IDENTIFY DEVICE ATA or IDENTIFY PACKET DEVICE command
919 If successful return 1, else 0 */
920 // TODO: Combine with has_sat_pass_through above
921 static int has_usbcypress_pass_through(ata_device
* atadev
, const char *manufacturer
, const char *product
)
923 struct ata_identify_device drive
;
924 char model
[40], serial
[20], firm
[8];
926 /* issue the command and do a checksum if possible */
927 if (ataReadHDIdentity(atadev
, &drive
) < 0)
930 /* check if model string match, revision doesn't work for me */
931 format_ata_string(model
, drive
.model
, 40);
932 if (*model
== 0 || isprint_string(model
) == 0)
935 if (manufacturer
&& strncmp(manufacturer
, model
, 8))
936 pout("manufacturer doesn't match in pass_through test\n");
938 strlen(model
) > 8 && strncmp(product
, model
+8, strlen(model
)-8))
939 pout("product doesn't match in pass_through test\n");
942 format_ata_string(serial
, drive
.serial_no
, 20);
943 if (isprint_string(serial
) == 0)
945 format_ata_string(firm
, drive
.fw_rev
, 8);
946 if (isprint_string(firm
) == 0)
952 /////////////////////////////////////////////////////////////////////////////
954 /// JMicron USB Bridge support.
956 class usbjmicron_device
957 : public tunnelled_device
<
958 /*implements*/ ata_device
,
959 /*by tunnelling through a*/ scsi_device
963 usbjmicron_device(smart_interface
* intf
, scsi_device
* scsidev
,
964 const char * req_type
, bool prolific
,
965 bool ata_48bit_support
, int port
);
967 virtual ~usbjmicron_device() throw();
971 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
974 bool get_registers(unsigned short addr
, unsigned char * buf
, unsigned short size
);
977 bool m_ata_48bit_support
;
982 usbjmicron_device::usbjmicron_device(smart_interface
* intf
, scsi_device
* scsidev
,
983 const char * req_type
, bool prolific
,
984 bool ata_48bit_support
, int port
)
985 : smart_device(intf
, scsidev
->get_dev_name(), "usbjmicron", req_type
),
986 tunnelled_device
<ata_device
, scsi_device
>(scsidev
),
987 m_prolific(prolific
), m_ata_48bit_support(ata_48bit_support
),
988 m_port(port
>= 0 || !prolific
? port
: 0)
990 set_info().info_name
= strprintf("%s [USB JMicron]", scsidev
->get_info_name());
993 usbjmicron_device::~usbjmicron_device() throw()
998 bool usbjmicron_device::open()
1001 if (!tunnelled_device
<ata_device
, scsi_device
>::open())
1004 // Detect port if not specified
1006 unsigned char regbuf
[1] = {0};
1007 if (!get_registers(0x720f, regbuf
, sizeof(regbuf
))) {
1012 switch (regbuf
[0] & 0x44) {
1019 return set_err(EINVAL
, "Two devices connected, try '-d usbjmicron,[01]'");
1022 return set_err(ENODEV
, "No device connected");
1030 bool usbjmicron_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
1032 if (!ata_cmd_is_supported(in
,
1033 ata_device::supports_data_out
|
1034 ata_device::supports_smart_status
|
1035 (m_ata_48bit_support
? ata_device::supports_48bit_hi_null
: 0),
1041 return set_err(EIO
, "Unknown JMicron port");
1043 scsi_cmnd_io io_hdr
;
1044 memset(&io_hdr
, 0, sizeof(io_hdr
));
1047 unsigned char smart_status
= 0xff;
1049 bool is_smart_status
= ( in
.in_regs
.command
== ATA_SMART_CMD
1050 && in
.in_regs
.features
== ATA_SMART_STATUS
);
1052 if (is_smart_status
&& in
.out_needed
.is_set()) {
1053 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1054 io_hdr
.dxfer_len
= 1;
1055 io_hdr
.dxferp
= &smart_status
;
1057 else switch (in
.direction
) {
1058 case ata_cmd_in::no_data
:
1059 io_hdr
.dxfer_dir
= DXFER_NONE
;
1061 case ata_cmd_in::data_in
:
1062 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1063 io_hdr
.dxfer_len
= in
.size
;
1064 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1065 memset(in
.buffer
, 0, in
.size
);
1067 case ata_cmd_in::data_out
:
1068 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
1069 io_hdr
.dxfer_len
= in
.size
;
1070 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1074 return set_err(EINVAL
);
1077 // Build pass through command
1078 unsigned char cdb
[14];
1080 cdb
[ 1] = (rwbit
? 0x10 : 0x00);
1082 cdb
[ 3] = (unsigned char)(io_hdr
.dxfer_len
>> 8);
1083 cdb
[ 4] = (unsigned char)(io_hdr
.dxfer_len
);
1084 cdb
[ 5] = in
.in_regs
.features
;
1085 cdb
[ 6] = in
.in_regs
.sector_count
;
1086 cdb
[ 7] = in
.in_regs
.lba_low
;
1087 cdb
[ 8] = in
.in_regs
.lba_mid
;
1088 cdb
[ 9] = in
.in_regs
.lba_high
;
1089 cdb
[10] = in
.in_regs
.device
| (m_port
== 0 ? 0xa0 : 0xb0);
1090 cdb
[11] = in
.in_regs
.command
;
1096 io_hdr
.cmnd_len
= (!m_prolific
? 12 : 14);
1098 scsi_device
* scsidev
= get_tunnel_dev();
1099 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1100 "usbjmicron_device::ata_pass_through: "))
1101 return set_err(scsidev
->get_err());
1103 if (in
.out_needed
.is_set()) {
1104 if (is_smart_status
) {
1105 if (io_hdr
.resid
== 1)
1106 // Some (Prolific) USB bridges do not transfer a status byte
1107 return set_err(ENOSYS
, "Incomplete response, status byte missing [JMicron]");
1109 switch (smart_status
) {
1111 out
.out_regs
.lba_high
= 0xc2;
1112 out
.out_regs
.lba_mid
= 0x4f;
1115 out
.out_regs
.lba_high
= 0x2c;
1116 out
.out_regs
.lba_mid
= 0xf4;
1119 // Some (JM20336) USB bridges always return 0x01, regardless of SMART Status
1120 return set_err(ENOSYS
, "Invalid status byte (0x%02x) [JMicron]", smart_status
);
1124 #if 0 // Not needed for SMART STATUS, see also notes below
1126 // Read ATA output registers
1127 // NOTE: The register addresses are not valid for some older chip revisions
1128 // NOTE: There is a small race condition here!
1129 unsigned char regbuf
[16] = {0, };
1130 if (!get_registers((m_port
== 0 ? 0x8000 : 0x9000), regbuf
, sizeof(regbuf
)))
1133 out
.out_regs
.sector_count
= regbuf
[ 0];
1134 out
.out_regs
.lba_mid
= regbuf
[ 4];
1135 out
.out_regs
.lba_low
= regbuf
[ 6];
1136 out
.out_regs
.device
= regbuf
[ 9];
1137 out
.out_regs
.lba_high
= regbuf
[10];
1138 out
.out_regs
.error
= regbuf
[13];
1139 out
.out_regs
.status
= regbuf
[14];
1147 bool usbjmicron_device::get_registers(unsigned short addr
,
1148 unsigned char * buf
, unsigned short size
)
1150 unsigned char cdb
[14];
1154 cdb
[ 3] = (unsigned char)(size
>> 8);
1155 cdb
[ 4] = (unsigned char)(size
);
1157 cdb
[ 6] = (unsigned char)(addr
>> 8);
1158 cdb
[ 7] = (unsigned char)(addr
);
1167 scsi_cmnd_io io_hdr
;
1168 memset(&io_hdr
, 0, sizeof(io_hdr
));
1169 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1170 io_hdr
.dxfer_len
= size
;
1171 io_hdr
.dxferp
= buf
;
1173 io_hdr
.cmnd_len
= (!m_prolific
? 12 : 14);
1175 scsi_device
* scsidev
= get_tunnel_dev();
1176 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1177 "usbjmicron_device::get_registers: "))
1178 return set_err(scsidev
->get_err());
1184 /////////////////////////////////////////////////////////////////////////////
1186 /// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
1188 class usbprolific_device
1189 : public tunnelled_device
<
1190 /*implements*/ ata_device
,
1191 /*by tunnelling through a*/ scsi_device
1195 usbprolific_device(smart_interface
* intf
, scsi_device
* scsidev
,
1196 const char * req_type
);
1198 virtual ~usbprolific_device() throw();
1200 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
1204 usbprolific_device::usbprolific_device(smart_interface
* intf
, scsi_device
* scsidev
,
1205 const char * req_type
)
1206 : smart_device(intf
, scsidev
->get_dev_name(), "usbprolific", req_type
),
1207 tunnelled_device
<ata_device
, scsi_device
>(scsidev
)
1209 set_info().info_name
= strprintf("%s [USB Prolific]", scsidev
->get_info_name());
1212 usbprolific_device::~usbprolific_device() throw()
1216 bool usbprolific_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
1218 if (!ata_cmd_is_supported(in
,
1219 ata_device::supports_data_out
|
1220 ata_device::supports_48bit_hi_null
|
1221 ata_device::supports_output_regs
|
1222 ata_device::supports_smart_status
,
1227 scsi_cmnd_io io_hdr
;
1228 memset(&io_hdr
, 0, sizeof(io_hdr
));
1229 unsigned char cmd_rw
= 0x10; // Read
1231 switch (in
.direction
) {
1232 case ata_cmd_in::no_data
:
1233 io_hdr
.dxfer_dir
= DXFER_NONE
;
1235 case ata_cmd_in::data_in
:
1236 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1237 io_hdr
.dxfer_len
= in
.size
;
1238 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1239 memset(in
.buffer
, 0, in
.size
);
1241 case ata_cmd_in::data_out
:
1242 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
1243 io_hdr
.dxfer_len
= in
.size
;
1244 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1245 cmd_rw
= 0x0; // Write
1248 return set_err(EINVAL
);
1251 // Based on reverse engineering of iSmart.exe with API Monitor.
1253 // D0 0 0 0 06 7B 0 0 0 0 0 0 // Read Firmware info?, reads 16 bytes
1254 // F4 0 0 0 06 7B // ??
1255 // D8 15 0 D8 06 7B 0 0 0 0 1 1 4F C2 A0 B0 // SMART Enable
1256 // D8 15 0 D0 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read values
1257 // D8 15 0 D1 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read thresholds
1258 // D8 15 0 D4 06 7B 0 0 0 0 0 1 4F C2 A0 B0 // SMART Execute self test
1259 // D7 0 0 0 06 7B 0 0 0 0 0 0 0 0 0 0 // Read status registers, Reads 16 bytes of data
1260 // Additional DATA OUT support based on document from Prolific
1262 // Build pass through command
1263 unsigned char cdb
[16];
1264 cdb
[ 0] = 0xD8; // Operation Code (D8 = Prolific ATA pass through)
1265 cdb
[ 1] = cmd_rw
|0x5; // Read(0x10)/Write(0x0) | NORMAL(0x5)/PREFIX(0x0)(?)
1266 cdb
[ 2] = 0x0; // Reserved
1267 cdb
[ 3] = in
.in_regs
.features
; // Feature register (SMART command)
1268 cdb
[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1269 cdb
[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1270 cdb
[ 6] = (unsigned char)(io_hdr
.dxfer_len
>> 24); // Length MSB
1271 cdb
[ 7] = (unsigned char)(io_hdr
.dxfer_len
>> 16); // Length ...
1272 cdb
[ 8] = (unsigned char)(io_hdr
.dxfer_len
>> 8); // Length ...
1273 cdb
[ 9] = (unsigned char)(io_hdr
.dxfer_len
); // Length LSB
1274 cdb
[10] = in
.in_regs
.sector_count
; // Sector Count
1275 cdb
[11] = in
.in_regs
.lba_low
; // LBA Low (7:0)
1276 cdb
[12] = in
.in_regs
.lba_mid
; // LBA Mid (15:8)
1277 cdb
[13] = in
.in_regs
.lba_high
; // LBA High (23:16)
1278 cdb
[14] = in
.in_regs
.device
| 0xA0; // Device/Head
1279 cdb
[15] = in
.in_regs
.command
; // ATA Command Register (only PIO supported)
1280 // Use '-r scsiioctl,1' to print CDB for debug purposes
1283 io_hdr
.cmnd_len
= 16;
1285 scsi_device
* scsidev
= get_tunnel_dev();
1286 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1287 "usbprolific_device::ata_pass_through: "))
1288 return set_err(scsidev
->get_err());
1290 if (in
.out_needed
.is_set()) {
1291 // Read ATA output registers
1292 unsigned char regbuf
[16] = {0, };
1293 memset(&io_hdr
, 0, sizeof(io_hdr
));
1294 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1295 io_hdr
.dxfer_len
= sizeof(regbuf
);
1296 io_hdr
.dxferp
= regbuf
;
1298 memset(cdb
, 0, sizeof(cdb
));
1299 cdb
[ 0] = 0xD7; // Prolific read registers
1300 cdb
[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1301 cdb
[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1303 io_hdr
.cmnd_len
= sizeof(cdb
);
1305 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1306 "usbprolific_device::scsi_pass_through (get registers): "))
1307 return set_err(scsidev
->get_err());
1309 // Use '-r scsiioctl,2' to print input registers for debug purposes
1310 // Example: 50 00 00 00 00 01 4f 00 c2 00 a0 da 00 b0 00 50
1311 out
.out_regs
.status
= regbuf
[0]; // Status
1312 out
.out_regs
.error
= regbuf
[1]; // Error
1313 out
.out_regs
.sector_count
= regbuf
[2]; // Sector Count (7:0)
1314 out
.out_regs
.lba_low
= regbuf
[4]; // LBA Low (7:0)
1315 out
.out_regs
.lba_mid
= regbuf
[6]; // LBA Mid (7:0)
1316 out
.out_regs
.lba_high
= regbuf
[8]; // LBA High (7:0)
1317 out
.out_regs
.device
= regbuf
[10]; // Device/Head
1318 // = regbuf[11]; // ATA Feature (7:0)
1319 // = regbuf[13]; // ATA Command
1326 /////////////////////////////////////////////////////////////////////////////
1328 /// SunplusIT USB Bridge support.
1330 class usbsunplus_device
1331 : public tunnelled_device
<
1332 /*implements*/ ata_device
,
1333 /*by tunnelling through a*/ scsi_device
1337 usbsunplus_device(smart_interface
* intf
, scsi_device
* scsidev
,
1338 const char * req_type
);
1340 virtual ~usbsunplus_device() throw();
1342 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
1346 usbsunplus_device::usbsunplus_device(smart_interface
* intf
, scsi_device
* scsidev
,
1347 const char * req_type
)
1348 : smart_device(intf
, scsidev
->get_dev_name(), "usbsunplus", req_type
),
1349 tunnelled_device
<ata_device
, scsi_device
>(scsidev
)
1351 set_info().info_name
= strprintf("%s [USB Sunplus]", scsidev
->get_info_name());
1354 usbsunplus_device::~usbsunplus_device() throw()
1358 bool usbsunplus_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
1360 if (!ata_cmd_is_supported(in
,
1361 ata_device::supports_data_out
|
1362 ata_device::supports_output_regs
|
1363 ata_device::supports_48bit
,
1368 scsi_cmnd_io io_hdr
;
1369 unsigned char cdb
[12];
1371 if (in
.in_regs
.is_48bit_cmd()) {
1372 // Set "previous" registers
1373 memset(&io_hdr
, 0, sizeof(io_hdr
));
1374 io_hdr
.dxfer_dir
= DXFER_NONE
;
1378 cdb
[ 2] = 0x23; // Subcommand: Pass through presetting
1381 cdb
[ 5] = in
.in_regs
.prev
.features
;
1382 cdb
[ 6] = in
.in_regs
.prev
.sector_count
;
1383 cdb
[ 7] = in
.in_regs
.prev
.lba_low
;
1384 cdb
[ 8] = in
.in_regs
.prev
.lba_mid
;
1385 cdb
[ 9] = in
.in_regs
.prev
.lba_high
;
1390 io_hdr
.cmnd_len
= sizeof(cdb
);
1392 scsi_device
* scsidev
= get_tunnel_dev();
1393 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1394 "usbsunplus_device::scsi_pass_through (presetting): "))
1395 return set_err(scsidev
->get_err());
1398 // Run Pass through command
1399 memset(&io_hdr
, 0, sizeof(io_hdr
));
1400 unsigned char protocol
;
1401 switch (in
.direction
) {
1402 case ata_cmd_in::no_data
:
1403 io_hdr
.dxfer_dir
= DXFER_NONE
;
1406 case ata_cmd_in::data_in
:
1407 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1408 io_hdr
.dxfer_len
= in
.size
;
1409 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1410 memset(in
.buffer
, 0, in
.size
);
1413 case ata_cmd_in::data_out
:
1414 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
1415 io_hdr
.dxfer_len
= in
.size
;
1416 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1420 return set_err(EINVAL
);
1425 cdb
[ 2] = 0x22; // Subcommand: Pass through
1427 cdb
[ 4] = (unsigned char)(io_hdr
.dxfer_len
>> 9);
1428 cdb
[ 5] = in
.in_regs
.features
;
1429 cdb
[ 6] = in
.in_regs
.sector_count
;
1430 cdb
[ 7] = in
.in_regs
.lba_low
;
1431 cdb
[ 8] = in
.in_regs
.lba_mid
;
1432 cdb
[ 9] = in
.in_regs
.lba_high
;
1433 cdb
[10] = in
.in_regs
.device
| 0xa0;
1434 cdb
[11] = in
.in_regs
.command
;
1437 io_hdr
.cmnd_len
= sizeof(cdb
);
1439 scsi_device
* scsidev
= get_tunnel_dev();
1440 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1441 "usbsunplus_device::scsi_pass_through: "))
1442 // Returns sense key 0x03 (medium error) on ATA command error
1443 return set_err(scsidev
->get_err());
1445 if (in
.out_needed
.is_set()) {
1446 // Read ATA output registers
1447 unsigned char regbuf
[8] = {0, };
1448 memset(&io_hdr
, 0, sizeof(io_hdr
));
1449 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1450 io_hdr
.dxfer_len
= sizeof(regbuf
);
1451 io_hdr
.dxferp
= regbuf
;
1455 cdb
[ 2] = 0x21; // Subcommand: Get status
1456 memset(cdb
+3, 0, sizeof(cdb
)-3);
1458 io_hdr
.cmnd_len
= sizeof(cdb
);
1460 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1461 "usbsunplus_device::scsi_pass_through (get registers): "))
1462 return set_err(scsidev
->get_err());
1464 out
.out_regs
.error
= regbuf
[1];
1465 out
.out_regs
.sector_count
= regbuf
[2];
1466 out
.out_regs
.lba_low
= regbuf
[3];
1467 out
.out_regs
.lba_mid
= regbuf
[4];
1468 out
.out_regs
.lba_high
= regbuf
[5];
1469 out
.out_regs
.device
= regbuf
[6];
1470 out
.out_regs
.status
= regbuf
[7];
1479 using namespace sat
;
1482 /////////////////////////////////////////////////////////////////////////////
1484 // Return ATA->SCSI filter for SAT or USB.
1486 ata_device
* smart_interface::get_sat_device(const char * type
, scsi_device
* scsidev
)
1489 throw std::logic_error("smart_interface: get_sat_device() called with scsidev=0");
1491 // Take temporary ownership of 'scsidev' to delete it on error
1492 scsi_device_auto_ptr
scsidev_holder(scsidev
);
1493 ata_device
* satdev
= 0;
1495 if (!strncmp(type
, "sat", 3)) {
1496 const char * t
= type
+ 3;
1497 bool enable_auto
= false;
1498 if (!strncmp(t
, ",auto", 5)) {
1502 int ptlen
= 0, n
= -1;
1503 if (*t
&& !(sscanf(t
, ",%d%n", &ptlen
, &n
) == 1 && n
== (int)strlen(t
)
1504 && (ptlen
== 0 || ptlen
== 12 || ptlen
== 16))) {
1505 set_err(EINVAL
, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16");
1508 satdev
= new sat_device(this, scsidev
, type
, ptlen
, enable_auto
);
1511 else if (!strncmp(type
, "usbcypress", 10)) {
1512 unsigned signature
= 0x24; int n1
= -1, n2
= -1;
1513 if (!(((sscanf(type
, "usbcypress%n,0x%x%n", &n1
, &signature
, &n2
) == 1 && n2
== (int)strlen(type
)) || n1
== (int)strlen(type
))
1514 && signature
<= 0xff)) {
1515 set_err(EINVAL
, "Option '-d usbcypress,<n>' requires <n> to be "
1516 "an hexadecimal number between 0x0 and 0xff");
1519 satdev
= new usbcypress_device(this, scsidev
, type
, signature
);
1522 else if (!strncmp(type
, "usbjmicron", 10)) {
1523 const char * t
= type
+ 10;
1524 bool prolific
= false;
1525 if (!strncmp(t
, ",p", 2)) {
1529 bool ata_48bit_support
= false;
1530 if (!strncmp(t
, ",x", 2)) {
1532 ata_48bit_support
= true;
1534 int port
= -1, n
= -1;
1535 if (*t
&& !( (sscanf(t
, ",%d%n", &port
, &n
) == 1
1536 && n
== (int)strlen(t
) && 0 <= port
&& port
<= 1))) {
1537 set_err(EINVAL
, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
1540 satdev
= new usbjmicron_device(this, scsidev
, type
, prolific
, ata_48bit_support
, port
);
1543 else if (!strcmp(type
, "usbprolific")) {
1544 satdev
= new usbprolific_device(this, scsidev
, type
);
1547 else if (!strcmp(type
, "usbsunplus")) {
1548 satdev
= new usbsunplus_device(this, scsidev
, type
);
1552 set_err(EINVAL
, "Unknown USB device type '%s'", type
);
1556 // 'scsidev' is now owned by 'satdev'
1557 scsidev_holder
.release();
1561 // Try to detect a SAT device behind a SCSI interface.
1563 ata_device
* smart_interface::autodetect_sat_device(scsi_device
* scsidev
,
1564 const unsigned char * inqdata
, unsigned inqsize
)
1566 if (!scsidev
->is_open())
1570 if (inqdata
&& inqsize
>= 36 && !memcmp(inqdata
+ 8, "ATA ", 8)) { // TODO: Linux-specific?
1571 ata_device_auto_ptr
atadev( new sat_device(this, scsidev
, "") , scsidev
);
1572 if (has_sat_pass_through(atadev
.get()))
1573 return atadev
.release(); // Detected SAT
1580 /////////////////////////////////////////////////////////////////////////////
1581 // USB device type detection
1583 // Format USB ID for error messages
1584 static std::string
format_usb_id(int vendor_id
, int product_id
, int version
)
1587 return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id
, product_id
, version
);
1589 return strprintf("[0x%04x:0x%04x]", vendor_id
, product_id
);
1592 // Get type name for USB device with known VENDOR:PRODUCT ID.
1593 const char * smart_interface::get_usb_dev_type_by_id(int vendor_id
, int product_id
,
1594 int version
/*= -1*/)
1596 usb_dev_info info
, info2
;
1597 int n
= lookup_usb_device(vendor_id
, product_id
, version
, info
, info2
);
1600 set_err(EINVAL
, "Unknown USB bridge %s",
1601 format_usb_id(vendor_id
, product_id
, version
).c_str());
1606 set_err(EINVAL
, "USB bridge %s type is ambiguous: '%s' or '%s'",
1607 format_usb_id(vendor_id
, product_id
, version
).c_str(),
1608 (!info
.usb_type
.empty() ? info
.usb_type
.c_str() : "[unsupported]"),
1609 (!info2
.usb_type
.empty() ? info2
.usb_type
.c_str() : "[unsupported]"));
1613 if (info
.usb_type
.empty()) {
1614 set_err(ENOSYS
, "Unsupported USB bridge %s",
1615 format_usb_id(vendor_id
, product_id
, version
).c_str());
1619 // TODO: change return type to std::string
1620 static std::string type
;
1621 type
= info
.usb_type
;
1622 return type
.c_str();