4 * Home page of code is: http://www.smartmontools.org
6 * Copyright (C) 2006-15 Douglas Gilbert <dgilbert@interlog.com>
7 * Copyright (C) 2009-15 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 4130 2015-09-25 15:08: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
= sizeof(cdb
);
1174 io_hdr
.cmnd_len
= (!m_prolific
? 12 : 14);
1176 scsi_device
* scsidev
= get_tunnel_dev();
1177 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1178 "usbjmicron_device::get_registers: "))
1179 return set_err(scsidev
->get_err());
1185 /////////////////////////////////////////////////////////////////////////////
1187 /// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
1189 class usbprolific_device
1190 : public tunnelled_device
<
1191 /*implements*/ ata_device
,
1192 /*by tunnelling through a*/ scsi_device
1196 usbprolific_device(smart_interface
* intf
, scsi_device
* scsidev
,
1197 const char * req_type
);
1199 virtual ~usbprolific_device() throw();
1201 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
1205 usbprolific_device::usbprolific_device(smart_interface
* intf
, scsi_device
* scsidev
,
1206 const char * req_type
)
1207 : smart_device(intf
, scsidev
->get_dev_name(), "usbprolific", req_type
),
1208 tunnelled_device
<ata_device
, scsi_device
>(scsidev
)
1210 set_info().info_name
= strprintf("%s [USB Prolific]", scsidev
->get_info_name());
1213 usbprolific_device::~usbprolific_device() throw()
1217 bool usbprolific_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
1219 if (!ata_cmd_is_supported(in
,
1220 ata_device::supports_data_out
|
1221 ata_device::supports_48bit_hi_null
|
1222 ata_device::supports_output_regs
|
1223 ata_device::supports_smart_status
,
1228 scsi_cmnd_io io_hdr
;
1229 memset(&io_hdr
, 0, sizeof(io_hdr
));
1230 unsigned char cmd_rw
= 0x10; // Read
1232 switch (in
.direction
) {
1233 case ata_cmd_in::no_data
:
1234 io_hdr
.dxfer_dir
= DXFER_NONE
;
1236 case ata_cmd_in::data_in
:
1237 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1238 io_hdr
.dxfer_len
= in
.size
;
1239 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1240 memset(in
.buffer
, 0, in
.size
);
1242 case ata_cmd_in::data_out
:
1243 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
1244 io_hdr
.dxfer_len
= in
.size
;
1245 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1246 cmd_rw
= 0x0; // Write
1249 return set_err(EINVAL
);
1252 // Based on reverse engineering of iSmart.exe with API Monitor.
1254 // D0 0 0 0 06 7B 0 0 0 0 0 0 // Read Firmware info?, reads 16 bytes
1255 // F4 0 0 0 06 7B // ??
1256 // D8 15 0 D8 06 7B 0 0 0 0 1 1 4F C2 A0 B0 // SMART Enable
1257 // D8 15 0 D0 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read values
1258 // D8 15 0 D1 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read thresholds
1259 // D8 15 0 D4 06 7B 0 0 0 0 0 1 4F C2 A0 B0 // SMART Execute self test
1260 // D7 0 0 0 06 7B 0 0 0 0 0 0 0 0 0 0 // Read status registers, Reads 16 bytes of data
1261 // Additional DATA OUT support based on document from Prolific
1263 // Build pass through command
1264 unsigned char cdb
[16];
1265 cdb
[ 0] = 0xD8; // Operation Code (D8 = Prolific ATA pass through)
1266 cdb
[ 1] = cmd_rw
|0x5; // Read(0x10)/Write(0x0) | NORMAL(0x5)/PREFIX(0x0)(?)
1267 cdb
[ 2] = 0x0; // Reserved
1268 cdb
[ 3] = in
.in_regs
.features
; // Feature register (SMART command)
1269 cdb
[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1270 cdb
[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1271 cdb
[ 6] = (unsigned char)(io_hdr
.dxfer_len
>> 24); // Length MSB
1272 cdb
[ 7] = (unsigned char)(io_hdr
.dxfer_len
>> 16); // Length ...
1273 cdb
[ 8] = (unsigned char)(io_hdr
.dxfer_len
>> 8); // Length ...
1274 cdb
[ 9] = (unsigned char)(io_hdr
.dxfer_len
); // Length LSB
1275 cdb
[10] = in
.in_regs
.sector_count
; // Sector Count
1276 cdb
[11] = in
.in_regs
.lba_low
; // LBA Low (7:0)
1277 cdb
[12] = in
.in_regs
.lba_mid
; // LBA Mid (15:8)
1278 cdb
[13] = in
.in_regs
.lba_high
; // LBA High (23:16)
1279 cdb
[14] = in
.in_regs
.device
| 0xA0; // Device/Head
1280 cdb
[15] = in
.in_regs
.command
; // ATA Command Register (only PIO supported)
1281 // Use '-r scsiioctl,1' to print CDB for debug purposes
1284 io_hdr
.cmnd_len
= 16;
1286 scsi_device
* scsidev
= get_tunnel_dev();
1287 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1288 "usbprolific_device::ata_pass_through: "))
1289 return set_err(scsidev
->get_err());
1291 if (in
.out_needed
.is_set()) {
1292 // Read ATA output registers
1293 unsigned char regbuf
[16] = {0, };
1294 memset(&io_hdr
, 0, sizeof(io_hdr
));
1295 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1296 io_hdr
.dxfer_len
= sizeof(regbuf
);
1297 io_hdr
.dxferp
= regbuf
;
1299 memset(cdb
, 0, sizeof(cdb
));
1300 cdb
[ 0] = 0xD7; // Prolific read registers
1301 cdb
[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1302 cdb
[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1304 io_hdr
.cmnd_len
= sizeof(cdb
);
1306 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1307 "usbprolific_device::scsi_pass_through (get registers): "))
1308 return set_err(scsidev
->get_err());
1310 // Use '-r scsiioctl,2' to print input registers for debug purposes
1311 // Example: 50 00 00 00 00 01 4f 00 c2 00 a0 da 00 b0 00 50
1312 out
.out_regs
.status
= regbuf
[0]; // Status
1313 out
.out_regs
.error
= regbuf
[1]; // Error
1314 out
.out_regs
.sector_count
= regbuf
[2]; // Sector Count (7:0)
1315 out
.out_regs
.lba_low
= regbuf
[4]; // LBA Low (7:0)
1316 out
.out_regs
.lba_mid
= regbuf
[6]; // LBA Mid (7:0)
1317 out
.out_regs
.lba_high
= regbuf
[8]; // LBA High (7:0)
1318 out
.out_regs
.device
= regbuf
[10]; // Device/Head
1319 // = regbuf[11]; // ATA Feature (7:0)
1320 // = regbuf[13]; // ATA Command
1327 /////////////////////////////////////////////////////////////////////////////
1329 /// SunplusIT USB Bridge support.
1331 class usbsunplus_device
1332 : public tunnelled_device
<
1333 /*implements*/ ata_device
,
1334 /*by tunnelling through a*/ scsi_device
1338 usbsunplus_device(smart_interface
* intf
, scsi_device
* scsidev
,
1339 const char * req_type
);
1341 virtual ~usbsunplus_device() throw();
1343 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
1347 usbsunplus_device::usbsunplus_device(smart_interface
* intf
, scsi_device
* scsidev
,
1348 const char * req_type
)
1349 : smart_device(intf
, scsidev
->get_dev_name(), "usbsunplus", req_type
),
1350 tunnelled_device
<ata_device
, scsi_device
>(scsidev
)
1352 set_info().info_name
= strprintf("%s [USB Sunplus]", scsidev
->get_info_name());
1355 usbsunplus_device::~usbsunplus_device() throw()
1359 bool usbsunplus_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
1361 if (!ata_cmd_is_supported(in
,
1362 ata_device::supports_data_out
|
1363 ata_device::supports_output_regs
|
1364 ata_device::supports_48bit
,
1369 scsi_cmnd_io io_hdr
;
1370 unsigned char cdb
[12];
1372 if (in
.in_regs
.is_48bit_cmd()) {
1373 // Set "previous" registers
1374 memset(&io_hdr
, 0, sizeof(io_hdr
));
1375 io_hdr
.dxfer_dir
= DXFER_NONE
;
1379 cdb
[ 2] = 0x23; // Subcommand: Pass through presetting
1382 cdb
[ 5] = in
.in_regs
.prev
.features
;
1383 cdb
[ 6] = in
.in_regs
.prev
.sector_count
;
1384 cdb
[ 7] = in
.in_regs
.prev
.lba_low
;
1385 cdb
[ 8] = in
.in_regs
.prev
.lba_mid
;
1386 cdb
[ 9] = in
.in_regs
.prev
.lba_high
;
1391 io_hdr
.cmnd_len
= sizeof(cdb
);
1393 scsi_device
* scsidev
= get_tunnel_dev();
1394 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1395 "usbsunplus_device::scsi_pass_through (presetting): "))
1396 return set_err(scsidev
->get_err());
1399 // Run Pass through command
1400 memset(&io_hdr
, 0, sizeof(io_hdr
));
1401 unsigned char protocol
;
1402 switch (in
.direction
) {
1403 case ata_cmd_in::no_data
:
1404 io_hdr
.dxfer_dir
= DXFER_NONE
;
1407 case ata_cmd_in::data_in
:
1408 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1409 io_hdr
.dxfer_len
= in
.size
;
1410 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1411 memset(in
.buffer
, 0, in
.size
);
1414 case ata_cmd_in::data_out
:
1415 io_hdr
.dxfer_dir
= DXFER_TO_DEVICE
;
1416 io_hdr
.dxfer_len
= in
.size
;
1417 io_hdr
.dxferp
= (unsigned char *)in
.buffer
;
1421 return set_err(EINVAL
);
1426 cdb
[ 2] = 0x22; // Subcommand: Pass through
1428 cdb
[ 4] = (unsigned char)(io_hdr
.dxfer_len
>> 9);
1429 cdb
[ 5] = in
.in_regs
.features
;
1430 cdb
[ 6] = in
.in_regs
.sector_count
;
1431 cdb
[ 7] = in
.in_regs
.lba_low
;
1432 cdb
[ 8] = in
.in_regs
.lba_mid
;
1433 cdb
[ 9] = in
.in_regs
.lba_high
;
1434 cdb
[10] = in
.in_regs
.device
| 0xa0;
1435 cdb
[11] = in
.in_regs
.command
;
1438 io_hdr
.cmnd_len
= sizeof(cdb
);
1440 scsi_device
* scsidev
= get_tunnel_dev();
1441 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1442 "usbsunplus_device::scsi_pass_through: "))
1443 // Returns sense key 0x03 (medium error) on ATA command error
1444 return set_err(scsidev
->get_err());
1446 if (in
.out_needed
.is_set()) {
1447 // Read ATA output registers
1448 unsigned char regbuf
[8] = {0, };
1449 memset(&io_hdr
, 0, sizeof(io_hdr
));
1450 io_hdr
.dxfer_dir
= DXFER_FROM_DEVICE
;
1451 io_hdr
.dxfer_len
= sizeof(regbuf
);
1452 io_hdr
.dxferp
= regbuf
;
1456 cdb
[ 2] = 0x21; // Subcommand: Get status
1457 memset(cdb
+3, 0, sizeof(cdb
)-3);
1459 io_hdr
.cmnd_len
= sizeof(cdb
);
1461 if (!scsi_pass_through_and_check(scsidev
, &io_hdr
,
1462 "usbsunplus_device::scsi_pass_through (get registers): "))
1463 return set_err(scsidev
->get_err());
1465 out
.out_regs
.error
= regbuf
[1];
1466 out
.out_regs
.sector_count
= regbuf
[2];
1467 out
.out_regs
.lba_low
= regbuf
[3];
1468 out
.out_regs
.lba_mid
= regbuf
[4];
1469 out
.out_regs
.lba_high
= regbuf
[5];
1470 out
.out_regs
.device
= regbuf
[6];
1471 out
.out_regs
.status
= regbuf
[7];
1480 using namespace sat
;
1483 /////////////////////////////////////////////////////////////////////////////
1485 // Return ATA->SCSI filter for SAT or USB.
1487 ata_device
* smart_interface::get_sat_device(const char * type
, scsi_device
* scsidev
)
1489 if (!strncmp(type
, "sat", 3)) {
1490 const char * t
= type
+ 3;
1491 bool enable_auto
= false;
1492 if (!strncmp(t
, ",auto", 5)) {
1496 int ptlen
= 0, n
= -1;
1497 if (*t
&& !(sscanf(t
, ",%d%n", &ptlen
, &n
) == 1 && n
== (int)strlen(t
)
1498 && (ptlen
== 0 || ptlen
== 12 || ptlen
== 16))) {
1499 set_err(EINVAL
, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16");
1502 return new sat_device(this, scsidev
, type
, ptlen
, enable_auto
);
1505 else if (!strncmp(type
, "usbcypress", 10)) {
1506 unsigned signature
= 0x24; int n1
= -1, n2
= -1;
1507 if (!(((sscanf(type
, "usbcypress%n,0x%x%n", &n1
, &signature
, &n2
) == 1 && n2
== (int)strlen(type
)) || n1
== (int)strlen(type
))
1508 && signature
<= 0xff)) {
1509 set_err(EINVAL
, "Option '-d usbcypress,<n>' requires <n> to be "
1510 "an hexadecimal number between 0x0 and 0xff");
1513 return new usbcypress_device(this, scsidev
, type
, signature
);
1516 else if (!strncmp(type
, "usbjmicron", 10)) {
1517 const char * t
= type
+ 10;
1518 bool prolific
= false;
1519 if (!strncmp(t
, ",p", 2)) {
1523 bool ata_48bit_support
= false;
1524 if (!strncmp(t
, ",x", 2)) {
1526 ata_48bit_support
= true;
1528 int port
= -1, n
= -1;
1529 if (*t
&& !( (sscanf(t
, ",%d%n", &port
, &n
) == 1
1530 && n
== (int)strlen(t
) && 0 <= port
&& port
<= 1))) {
1531 set_err(EINVAL
, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
1534 return new usbjmicron_device(this, scsidev
, type
, prolific
, ata_48bit_support
, port
);
1537 else if (!strcmp(type
, "usbprolific")) {
1538 return new usbprolific_device(this, scsidev
, type
);
1541 else if (!strcmp(type
, "usbsunplus")) {
1542 return new usbsunplus_device(this, scsidev
, type
);
1546 set_err(EINVAL
, "Unknown USB device type '%s'", type
);
1551 // Try to detect a SAT device behind a SCSI interface.
1553 ata_device
* smart_interface::autodetect_sat_device(scsi_device
* scsidev
,
1554 const unsigned char * inqdata
, unsigned inqsize
)
1556 if (!scsidev
->is_open())
1560 if (inqdata
&& inqsize
>= 36 && !memcmp(inqdata
+ 8, "ATA ", 8)) { // TODO: Linux-specific?
1561 ata_device_auto_ptr
atadev( new sat_device(this, scsidev
, "") , scsidev
);
1562 if (has_sat_pass_through(atadev
.get()))
1563 return atadev
.release(); // Detected SAT
1570 /////////////////////////////////////////////////////////////////////////////
1571 // USB device type detection
1573 // Format USB ID for error messages
1574 static std::string
format_usb_id(int vendor_id
, int product_id
, int version
)
1577 return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id
, product_id
, version
);
1579 return strprintf("[0x%04x:0x%04x]", vendor_id
, product_id
);
1582 // Get type name for USB device with known VENDOR:PRODUCT ID.
1583 const char * smart_interface::get_usb_dev_type_by_id(int vendor_id
, int product_id
,
1584 int version
/*= -1*/)
1586 usb_dev_info info
, info2
;
1587 int n
= lookup_usb_device(vendor_id
, product_id
, version
, info
, info2
);
1590 set_err(EINVAL
, "Unknown USB bridge %s",
1591 format_usb_id(vendor_id
, product_id
, version
).c_str());
1596 set_err(EINVAL
, "USB bridge %s type is ambiguous: '%s' or '%s'",
1597 format_usb_id(vendor_id
, product_id
, version
).c_str(),
1598 (!info
.usb_type
.empty() ? info
.usb_type
.c_str() : "[unsupported]"),
1599 (!info2
.usb_type
.empty() ? info2
.usb_type
.c_str() : "[unsupported]"));
1603 if (info
.usb_type
.empty()) {
1604 set_err(ENOSYS
, "Unsupported USB bridge %s",
1605 format_usb_id(vendor_id
, product_id
, version
).c_str());
1609 // TODO: change return type to std::string
1610 static std::string type
;
1611 type
= info
.usb_type
;
1612 return type
.c_str();