smartmontools SVN Rev 5407
Utility to control and monitor storage systems with "S.M.A.R.T."
scsiata.cpp
Go to the documentation of this file.
1/*
2 * scsiata.cpp
3 *
4 * Home page of code is: https://www.smartmontools.org
5 *
6 * Copyright (C) 2006-15 Douglas Gilbert <dgilbert@interlog.com>
7 * Copyright (C) 2009-21 Christian Franke
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 * The code in this file is based on the SCSI to ATA Translation (SAT)
11 * draft found at http://www.t10.org . The original draft used for this
12 * code is sat-r08.pdf which is not too far away from becoming a
13 * standard. The SAT commands of interest to smartmontools are the
14 * ATA PASS THROUGH SCSI (16) and ATA PASS THROUGH SCSI (12) defined in
15 * section 12 of that document.
16 *
17 * sat-r09.pdf is the most recent, easily accessible draft prior to the
18 * original SAT standard (ANSI INCITS 431-2007). By mid-2009 the second
19 * version of the SAT standard (SAT-2) is nearing standardization. In
20 * their wisdom an incompatible change has been introduced in draft
21 * sat2r08a.pdf in the area of the ATA RETURN DESCRIPTOR. A new "fixed
22 * format" ATA RETURN buffer has been defined (sat2r08b.pdf section
23 * 12.2.7) for the case when DSENSE=0 in the Control mode page.
24 * Unfortunately this is the normal case. If the change stands our
25 * code will need to be extended for this case.
26 *
27 * With more transports "hiding" SATA disks (and other S-ATAPI devices)
28 * behind a SCSI command set, accessing special features like SMART
29 * information becomes a challenge. The SAT standard offers ATA PASS
30 * THROUGH commands for special usages. Note that the SAT layer may
31 * be inside a generic OS layer (e.g. libata in linux), in a host
32 * adapter (HA or HBA) firmware, or somewhere on the interconnect
33 * between the host computer and the SATA devices (e.g. a RAID made
34 * of SATA disks and the RAID talks "SCSI" to the host computer).
35 * Note that in the latter case, this code does not solve the
36 * addressing issue (i.e. which SATA disk to address behind the logical
37 * SCSI (RAID) interface).
38 *
39 */
40
41#include <stdio.h>
42#include <string.h>
43#include <stdlib.h>
44#include <ctype.h>
45#include <errno.h>
46
47#include "config.h"
48
49#include "scsicmds.h"
50#include "atacmds.h" // ataReadHDIdentity()
51#include "knowndrives.h" // lookup_usb_device()
52#include "utility.h"
53#include "dev_interface.h"
54#include "dev_ata_cmd_set.h" // ata_device_with_command_set
55#include "dev_tunnelled.h" // tunnelled_device<>
56#include "sg_unaligned.h"
57
58const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 5397 2022-07-17 02:22:29Z dpgilbert $";
59
60/* This is a slightly stretched SCSI sense "descriptor" format header.
61 The addition is to allow the 0x70 and 0x71 response codes. The idea
62 is to place the salient data of both "fixed" and "descriptor" sense
63 format into one structure to ease application processing.
64 The original sense buffer should be kept around for those cases
65 in which more information is required (e.g. the LBA of a MEDIUM ERROR). */
66/// Abridged SCSI sense data
68 unsigned char response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
69 unsigned char sense_key;
70 unsigned char asc;
71 unsigned char ascq;
72 unsigned char byte4;
73 unsigned char byte5;
74 unsigned char byte6;
75 unsigned char additional_length;
76};
77
78/* Maps the salient data from a sense buffer which is in either fixed or
79 descriptor format into a structure mimicking a descriptor format
80 header (i.e. the first 8 bytes of sense descriptor format).
81 If zero response code returns 0. Otherwise returns 1 and if 'sshp' is
82 non-NULL then zero all fields and then set the appropriate fields in
83 that structure. sshp::additional_length is always 0 for response
84 codes 0x70 and 0x71 (fixed format). */
85static int sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len,
86 struct sg_scsi_sense_hdr * sshp);
87
88#define SAT_ATA_PASSTHROUGH_12LEN 12
89#define SAT_ATA_PASSTHROUGH_16LEN 16
90
91#define DEF_SAT_ATA_PASSTHRU_SIZE 16
92#define ATA_RETURN_DESCRIPTOR 9
93
94
95namespace sat { // no need to publish anything, name provided for Doxygen
96
97/// SAT support.
98/// Implements ATA by tunnelling through SCSI.
99
101: public tunnelled_device<
102 /*implements*/ ata_device
103 /*by tunnelling through a*/, scsi_device
104 >,
105 virtual public /*implements*/ scsi_device
106{
107public:
112 };
113
114 sat_device(smart_interface * intf, scsi_device * scsidev,
115 const char * req_type, sat_scsi_mode mode = sat_always, int passthrulen = 0);
116
117 virtual ~sat_device();
118
119 virtual smart_device * autodetect_open() override;
120
121 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
122
123 virtual bool scsi_pass_through(scsi_cmnd_io * iop) override;
124
125private:
128};
129
130
132 const char * req_type, sat_scsi_mode mode /* = sat_always */,
133 int passthrulen /* = 0 */)
134: smart_device(intf, scsidev->get_dev_name(),
135 (mode == sat_always ? "sat" : mode == sat_auto ? "sat,auto" : "scsi"), req_type),
137 m_passthrulen(passthrulen),
138 m_mode(mode)
139{
140 if (mode != sat_always)
141 hide_ata(); // Start as SCSI, switch to ATA in autodetect_open()
142 else
143 hide_scsi(); // ATA always
144 if (strcmp(scsidev->get_dev_type(), "scsi"))
145 set_info().dev_type += strprintf("+%s", scsidev->get_dev_type());
146
147 set_info().info_name = strprintf("%s [%s]", scsidev->get_info_name(),
148 (mode == sat_always ? "SAT" : mode == sat_auto ? "SCSI/SAT" : "SCSI"));
149}
150
152{
153}
154
155
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)
169// cdb[13]: device
170// cdb[14]: (ata) command
171// cdb[15]: control (SCSI, leave as zero)
172//
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]
175//
176//
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)
185// cdb[8]: device
186// cdb[9]: (ata) command
187// cdb[10]: reserved
188// cdb[11]: control (SCSI, leave as zero)
189//
190//
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)
195// des[3]: error
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)
204// des[12]: device
205// des[13]: status
206//
207//
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'
225
226
227
228// PURPOSE
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
237// self-test).
238// data: location to write output data, if needed (512 bytes).
239// Note: not all commands use all arguments.
240// RETURN VALUES
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"
247
249{
250 if (!ata_cmd_is_supported(in,
255 "SAT")
256 )
257 return false;
258
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;
266 int extend = 0;
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;
274
275 // Set data direction
276 // TODO: This works only for commands where sector_count holds count!
277 switch (in.direction) {
279 break;
281 protocol = 4; // PIO data-in
282 t_length = 2; // sector_count holds count
283 break;
285 protocol = 5; // PIO data-out
286 t_length = 2; // sector_count holds count
287 t_dir = 0; // to device
288 break;
289 default:
290 return set_err(EINVAL, "sat_device::ata_pass_through: invalid direction=%d",
291 (int)in.direction);
292 }
293
294 // Check condition if any output register needed
295 if (in.out_needed.is_set())
296 ck_cond = 1;
297
300 passthru_size = m_passthrulen;
301
302 // Set extend bit on 48-bit ATA command
303 if (in.in_regs.is_48bit_cmd()) {
304 if (passthru_size != SAT_ATA_PASSTHROUGH_16LEN)
305 return set_err(ENOSYS, "48-bit ATA commands require SAT ATA PASS-THROUGH (16)");
306 extend = 1;
307 }
308
309 cdb[0] = (SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ?
311
312 cdb[1] = (protocol << 1) | extend;
313 cdb[2] = (ck_cond << 5) | (t_dir << 3) |
314 (byte_block << 2) | t_length;
315
316 if (passthru_size == SAT_ATA_PASSTHROUGH_12LEN) {
317 // ATA PASS-THROUGH (12)
318 const ata_in_regs & lo = in.in_regs;
319 cdb[3] = lo.features;
320 cdb[4] = lo.sector_count;
321 cdb[5] = lo.lba_low;
322 cdb[6] = lo.lba_mid;
323 cdb[7] = lo.lba_high;
324 cdb[8] = lo.device;
325 cdb[9] = lo.command;
326 }
327 else {
328 // ATA PASS-THROUGH (16)
329 const ata_in_regs & lo = in.in_regs;
330 const ata_in_regs & hi = in.in_regs.prev;
331 // Note: all 'in.in_regs.prev.*' are always zero for 28-bit commands
332 cdb[ 3] = hi.features;
333 cdb[ 4] = lo.features;
334 cdb[ 5] = hi.sector_count;
335 cdb[ 6] = lo.sector_count;
336 cdb[ 7] = hi.lba_low;
337 cdb[ 8] = lo.lba_low;
338 cdb[ 9] = hi.lba_mid;
339 cdb[10] = lo.lba_mid;
340 cdb[11] = hi.lba_high;
341 cdb[12] = lo.lba_high;
342 cdb[13] = lo.device;
343 cdb[14] = lo.command;
344 }
345
346 if (0 == t_length) {
347 io_hdr.dxfer_dir = DXFER_NONE;
348 io_hdr.dxfer_len = 0;
349 } else if (t_dir) { /* from device */
351 io_hdr.dxfer_len = in.size;
352 io_hdr.dxferp = (unsigned char *)in.buffer;
353 memset(in.buffer, 0, in.size); // prefill with zeroes
354 } else { /* to device */
355 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
356 io_hdr.dxfer_len = in.size;
357 io_hdr.dxferp = (unsigned char *)in.buffer;
358 }
359 io_hdr.cmnd = cdb;
360 io_hdr.cmnd_len = passthru_size;
361 io_hdr.sensep = sense;
362 io_hdr.max_sense_len = sizeof(sense);
364
365 scsi_device * scsidev = get_tunnel_dev();
366 if (!scsidev->scsi_pass_through(&io_hdr)) {
367 if (scsi_debugmode > 0)
368 pout("sat_device::ata_pass_through: scsi_pass_through() failed, "
369 "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
370 return set_err(scsidev->get_err());
371 }
372 ardp = NULL;
373 ard_len = 0;
374 have_sense = sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len,
375 &ssh);
376 if (have_sense) {
377 sense_descriptor = ssh.response_code >= 0x72;
378 if (sense_descriptor) {
379 /* look for SAT ATA Return Descriptor */
380 ardp = sg_scsi_sense_desc_find(io_hdr.sensep,
381 io_hdr.resp_sense_len,
383 if (ardp) {
384 ard_len = ardp[1] + 2;
385 if (ard_len < 12)
386 ard_len = 12;
387 else if (ard_len > 14)
388 ard_len = 14;
389 }
390 }
391 scsi_do_sense_disect(&io_hdr, &sinfo);
392 int status = scsiSimpleSenseFilter(&sinfo);
393
394 // Workaround for bogus sense_key in sense data with SAT ATA Return Descriptor
395 if ( status && ck_cond && ardp && ard_len > 13
396 && (ardp[13] & 0xc1) == 0x40 /* !BSY && DRDY && !ERR */) {
397 if (scsi_debugmode > 0)
398 pout("ATA status (0x%02x) indicates success, ignoring SCSI sense_key\n",
399 ardp[13]);
400 status = 0;
401 }
402
403 if (0 != status) { /* other than no_sense and recovered_error */
404 if (scsi_debugmode > 0) {
405 pout("sat_device::ata_pass_through: scsi error: %s\n",
406 scsiErrString(status));
407 if (ardp && (scsi_debugmode > 1)) {
408 pout("Values from ATA Return Descriptor are:\n");
409 dStrHex((const uint8_t *)ardp, ard_len, 1);
410 }
411 }
412 if (t_dir && (t_length > 0) && (in.direction == ata_cmd_in::data_in))
413 memset(in.buffer, 0, in.size);
414 return set_err(EIO, "scsi error %s", scsiErrString(status));
415 }
416 }
417 if (ck_cond) { /* expecting SAT specific sense data */
418 if (have_sense) {
419 if (ardp) {
420 if (scsi_debugmode > 1) {
421 pout("Values from ATA Return Descriptor are:\n");
422 dStrHex((const uint8_t *)ardp, ard_len, 1);
423 }
424 // Set output registers
425 ata_out_regs & lo = out.out_regs;
426 lo.error = ardp[ 3];
427 lo.sector_count = ardp[ 5];
428 lo.lba_low = ardp[ 7];
429 lo.lba_mid = ardp[ 9];
430 lo.lba_high = ardp[11];
431 lo.device = ardp[12];
432 lo.status = ardp[13];
433 if (in.in_regs.is_48bit_cmd()) {
434 ata_out_regs & hi = out.out_regs.prev;
435 hi.sector_count = ardp[ 4];
436 hi.lba_low = ardp[ 6];
437 hi.lba_mid = ardp[ 8];
438 hi.lba_high = ardp[10];
439 }
440 } else if ((! sense_descriptor) &&
441 (0 == ssh.asc) &&
443 (0 != io_hdr.sensep[4] /* Some ATA STATUS bit must be set */)) {
444 /* in SAT-2 and later, ATA registers may be passed back via
445 * fixed format sense data [ref: sat3r07 section 12.2.2.7] */
446 ata_out_regs & lo = out.out_regs;
447 lo.error = io_hdr.sensep[ 3];
448 lo.status = io_hdr.sensep[ 4];
449 lo.device = io_hdr.sensep[ 5];
450 lo.sector_count = io_hdr.sensep[ 6];
451 lo.lba_low = io_hdr.sensep[ 9];
452 lo.lba_mid = io_hdr.sensep[10];
453 lo.lba_high = io_hdr.sensep[11];
454 if (in.in_regs.is_48bit_cmd()) {
455 if (0 == (0x60 & io_hdr.sensep[8])) {
456 ata_out_regs & hi = out.out_regs.prev;
457 hi.sector_count = 0;
458 hi.lba_low = 0;
459 hi.lba_mid = 0;
460 hi.lba_high = 0;
461 } else {
462 /* getting the "hi." values when either
463 * count_upper_nonzero or lba_upper_nonzero are set
464 * involves fetching the SCSI ATA PASS-THROUGH
465 * Results log page and decoding the descriptor with
466 * the matching log_index field. Painful. */
467 }
468 }
469 }
470 }
471 } else { /* ck_cond == 0 */
472 if (have_sense) {
473 if (((SCSI_SK_NO_SENSE == ssh.sense_key) ||
475 (0 == ssh.asc) &&
477 if (scsi_debugmode > 0) {
478 if (sense_descriptor && ardp) {
479 pout("Values from ATA Return Descriptor are:\n");
480 dStrHex((const uint8_t *)ardp, ard_len, 1);
481 } else if (! sense_descriptor) {
482 pout("Values from ATA fixed format sense are:\n");
483 pout(" Error: 0x%x\n", io_hdr.sensep[3]);
484 pout(" Status: 0x%x\n", io_hdr.sensep[4]);
485 pout(" Device: 0x%x\n", io_hdr.sensep[5]);
486 pout(" Count: 0x%x\n", io_hdr.sensep[6]);
487 }
488 }
489 }
490 return set_err(EIO, "SAT command failed");
491 }
492 }
493 return true;
494}
495
497{
498 scsi_device * scsidev = get_tunnel_dev();
499 if (!scsidev->scsi_pass_through(iop)) {
500 set_err(scsidev->get_err());
501 return false;
502 }
503 return true;
504}
505
507{
508 if (!open() || m_mode != sat_auto)
509 return this;
510
511 scsi_device * scsidev = get_tunnel_dev();
512
513 unsigned char inqdata[36] = {0, };
514 if (scsiStdInquiry(scsidev, inqdata, sizeof(inqdata))) {
515 smart_device::error_info err = scsidev->get_err();
516 close();
517 set_err(err.no, "INQUIRY [SAT]: %s", err.msg.c_str());
518 return this;
519 }
520
521 // Check for SAT "VENDOR"
522 int inqsize = inqdata[4] + 5;
523 bool sat = (inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8));
524
525 // Change interface
526 hide_ata(!sat);
527 hide_scsi(sat);
528
529 set_info().dev_type = (sat ? "sat" : scsidev->get_dev_type());
530 set_info().info_name = strprintf("%s [%s]", scsidev->get_info_name(),
531 (sat ? "SAT" : "SCSI"));
532 return this;
533}
534
535} // namespace
536
537/////////////////////////////////////////////////////////////////////////////
538
539/* Attempt an IDENTIFY DEVICE ATA command via SATL when packet_interface
540 is false otherwise attempt IDENTIFY PACKET DEVICE. If successful
541 return true, else false */
542
543static bool has_sat_pass_through(ata_device * dev, bool packet_interface = false)
544{
545 /* Note: malloc() ensures the read buffer lands on a single
546 page. This avoids some bugs seen on LSI controllers under
547 FreeBSD */
548 char *data = (char *)malloc(512);
549 ata_cmd_in in;
551 in.set_data_in(data, 1);
552 bool ret = dev->ata_pass_through(in);
553 free(data);
554 return ret;
555}
556
557/////////////////////////////////////////////////////////////////////////////
558
559/* Next two functions are borrowed from sg_lib.c in the sg3_utils
560 package. Same copyrght owner, same license as this file. */
561static int sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len,
562 struct sg_scsi_sense_hdr * sshp)
563{
564 if (sshp)
565 memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr));
566 if ((NULL == sensep) || (0 == sb_len) || (0x70 != (0x70 & sensep[0])))
567 return 0;
568 if (sshp) {
569 sshp->response_code = (0x7f & sensep[0]);
570 if (sshp->response_code >= 0x72) { /* descriptor format */
571 if (sb_len > 1)
572 sshp->sense_key = (0xf & sensep[1]);
573 if (sb_len > 2)
574 sshp->asc = sensep[2];
575 if (sb_len > 3)
576 sshp->ascq = sensep[3];
577 if (sb_len > 7)
578 sshp->additional_length = sensep[7];
579 } else { /* fixed format */
580 if (sb_len > 2)
581 sshp->sense_key = (0xf & sensep[2]);
582 if (sb_len > 7) {
583 sb_len = (sb_len < (sensep[7] + 8)) ? sb_len :
584 (sensep[7] + 8);
585 if (sb_len > 12)
586 sshp->asc = sensep[12];
587 if (sb_len > 13)
588 sshp->ascq = sensep[13];
589 }
590 }
591 }
592 return 1;
593}
594
595/////////////////////////////////////////////////////////////////////////////
596
597namespace sat {
598
599/// Cypress USB Bridge support.
600
602: public tunnelled_device<
603 /*implements*/ ata_device_with_command_set
604 /*by tunnelling through a*/, scsi_device
605 >
606{
607public:
609 const char * req_type, unsigned char signature);
610
611 virtual ~usbcypress_device();
612
613protected:
614 virtual int ata_command_interface(smart_command_set command, int select, char * data) override;
615
616 unsigned char m_signature;
617};
618
619
621 const char * req_type, unsigned char signature)
622: smart_device(intf, scsidev->get_dev_name(), "usbcypress", req_type),
624 m_signature(signature)
625{
626 set_info().info_name = strprintf("%s [USB Cypress]", scsidev->get_info_name());
627}
628
630{
631}
632
633
634/* see cy7c68300c_8.pdf for more information */
635#define USBCYPRESS_PASSTHROUGH_LEN 16
637{
638 struct scsi_cmnd_io io_hdr = {};
639 unsigned char cdb[USBCYPRESS_PASSTHROUGH_LEN] = {};
640 unsigned char sense[32] = {};
641 int copydata = 0;
642 int outlen = 0;
643 int ck_cond = 0; /* set to 1 to read register(s) back */
644 int t_dir = 1; /* 0 -> to device, 1 -> from device */
645 int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
646 int t_length = 0; /* 0 -> no data transferred */
647 int feature = 0;
648 int ata_command = 0;
649 int sector_count = 0;
650 int lba_low = 0;
651 int lba_mid = 0;
652 int lba_high = 0;
653 int passthru_size = USBCYPRESS_PASSTHROUGH_LEN;
654
655 ata_command = ATA_SMART_CMD;
656 switch (command) {
657 case CHECK_POWER_MODE:
658 ata_command = ATA_CHECK_POWER_MODE;
659 ck_cond = 1;
660 copydata = 1;
661 break;
662 case READ_VALUES: /* READ DATA */
663 feature = ATA_SMART_READ_VALUES;
664 sector_count = 1; /* one (512 byte) block */
665 t_length = 2; /* sector count holds count */
666 copydata = 512;
667 break;
668 case READ_THRESHOLDS: /* obsolete */
670 sector_count = 1; /* one (512 byte) block */
671 lba_low = 1;
672 t_length = 2; /* sector count holds count */
673 copydata=512;
674 break;
675 case READ_LOG:
677 sector_count = 1; /* one (512 byte) block */
678 lba_low = select;
679 t_length = 2; /* sector count holds count */
680 copydata = 512;
681 break;
682 case WRITE_LOG:
684 sector_count = 1; /* one (512 byte) block */
685 lba_low = select;
686 t_length = 2; /* sector count holds count */
687 t_dir = 0; /* to device */
688 outlen = 512;
689 break;
690 case IDENTIFY:
691 ata_command = ATA_IDENTIFY_DEVICE;
692 sector_count = 1; /* one (512 byte) block */
693 t_length = 2; /* sector count holds count */
694 copydata = 512;
695 break;
696 case PIDENTIFY:
697 ata_command = ATA_IDENTIFY_PACKET_DEVICE;
698 sector_count = 1; /* one (512 byte) block */
699 t_length = 2; /* sector count (7:0) holds count */
700 copydata = 512;
701 break;
702 case ENABLE:
703 feature = ATA_SMART_ENABLE;
704 lba_low = 1;
705 break;
706 case DISABLE:
707 feature = ATA_SMART_DISABLE;
708 lba_low = 1;
709 break;
710 case STATUS:
711 // this command only says if SMART is working. It could be
712 // replaced with STATUS_CHECK below.
713 feature = ATA_SMART_STATUS;
714 ck_cond = 1;
715 break;
716 case AUTO_OFFLINE:
717 feature = ATA_SMART_AUTO_OFFLINE;
718 sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
719 break;
720 case AUTOSAVE:
721 feature = ATA_SMART_AUTOSAVE;
722 sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
723 break;
726 lba_low = select;
727 break;
728 case STATUS_CHECK:
729 // This command uses HDIO_DRIVE_TASK and has different syntax than
730 // the other commands.
731 feature = ATA_SMART_STATUS; /* SMART RETURN STATUS */
732 ck_cond = 1;
733 break;
734 default:
735 pout("Unrecognized command %d in usbcypress_device::ata_command_interface()\n"
736 "Please contact " PACKAGE_BUGREPORT "\n", command);
737 errno=ENOSYS;
738 return -1;
739 }
740 if (ATA_SMART_CMD == ata_command) {
741 lba_mid = 0x4f;
742 lba_high = 0xc2;
743 }
744
745 cdb[0] = m_signature; // bVSCBSignature : vendor-specific command
746 cdb[1] = 0x24; // bVSCBSubCommand : 0x24 for ATACB
747 cdb[2] = 0x0;
748 if (ata_command == ATA_IDENTIFY_DEVICE || ata_command == ATA_IDENTIFY_PACKET_DEVICE)
749 cdb[2] |= (1<<7); //set IdentifyPacketDevice for these cmds
750 cdb[3] = 0xff - (1<<0) - (1<<6); //features, sector count, lba low, lba med
751 // lba high, command are valid
752 cdb[4] = byte_block; //TransferBlockCount : 512
753
754
755 cdb[6] = feature;
756 cdb[7] = sector_count;
757 cdb[8] = lba_low;
758 cdb[9] = lba_mid;
759 cdb[10] = lba_high;
760 cdb[12] = ata_command;
761
762 if (0 == t_length) {
763 io_hdr.dxfer_dir = DXFER_NONE;
764 io_hdr.dxfer_len = 0;
765 } else if (t_dir) { /* from device */
767 io_hdr.dxfer_len = copydata;
768 io_hdr.dxferp = (unsigned char *)data;
769 memset(data, 0, copydata); /* prefill with zeroes */
770 } else { /* to device */
771 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
772 io_hdr.dxfer_len = outlen;
773 io_hdr.dxferp = (unsigned char *)data;
774 }
775 io_hdr.cmnd = cdb;
776 io_hdr.cmnd_len = passthru_size;
777 io_hdr.sensep = sense;
778 io_hdr.max_sense_len = sizeof(sense);
780
781 scsi_device * scsidev = get_tunnel_dev();
782 if (!scsidev->scsi_pass_through(&io_hdr)) {
783 if (scsi_debugmode > 0)
784 pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
785 "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
786 set_err(scsidev->get_err());
787 return -1;
788 }
789
790 // if there is a sense the command failed or the
791 // device doesn't support usbcypress
793 sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
794 return -1;
795 }
796 if (ck_cond) {
797 unsigned char ardp[8];
798 int ard_len = 8;
799 /* XXX this is racy if there other scsi command between
800 * the first usbcypress command and this one
801 */
802 //pout("If you got strange result, please retry without traffic on the disc\n");
803 /* we use the same command as before, but we set
804 * * the read taskfile bit, for not executing usbcypress command,
805 * * but reading register selected in srb->cmnd[4]
806 */
807 cdb[2] = (1<<0); /* ask read taskfile */
808 memset(sense, 0, sizeof(sense));
809
810 /* transfer 8 bytes */
811 memset(&io_hdr, 0, sizeof(io_hdr));
813 io_hdr.dxfer_len = ard_len;
814 io_hdr.dxferp = (unsigned char *)ardp;
815 memset(ardp, 0, ard_len); /* prefill with zeroes */
816
817 io_hdr.cmnd = cdb;
818 io_hdr.cmnd_len = passthru_size;
819 io_hdr.sensep = sense;
820 io_hdr.max_sense_len = sizeof(sense);
822
823
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());
829 return -1;
830 }
831 // if there is a sense the command failed or the
832 // device doesn't support usbcypress
834 sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
835 return -1;
836 }
837
838
839 if (scsi_debugmode > 1) {
840 pout("Values from ATA Return Descriptor are:\n");
841 dStrHex((const uint8_t *)ardp, ard_len, 1);
842 }
843
844 if (ATA_CHECK_POWER_MODE == ata_command)
845 data[0] = ardp[2]; /* sector count (0:7) */
846 else if (STATUS_CHECK == command) {
847 if ((ardp[4] == 0x4f) && (ardp[5] == 0xc2))
848 return 0; /* GOOD smart status */
849 if ((ardp[4] == 0xf4) && (ardp[5] == 0x2c))
850 return 1; // smart predicting failure, "bad" status
851 // We haven't gotten output that makes sense so
852 // print out some debugging info
853 syserror("Error SMART Status command failed");
854 pout("This may be due to a race in usbcypress\n");
855 pout("Retry without other disc access\n");
856 pout("Please get assistance from " PACKAGE_URL "\n");
857 pout("Values from ATA Return Descriptor are:\n");
858 dStrHex((const uint8_t *)ardp, ard_len, 1);
859 return -1;
860 }
861 }
862 return 0;
863}
864
865/////////////////////////////////////////////////////////////////////////////
866
867/// JMicron USB Bridge support.
868
870: public tunnelled_device<
871 /*implements*/ ata_device,
872 /*by tunnelling through a*/ scsi_device
873 >
874{
875public:
877 const char * req_type, bool prolific,
878 bool ata_48bit_support, int port);
879
880 virtual ~usbjmicron_device();
881
882 virtual bool open() override;
883
884 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
885
886private:
887 bool get_registers(unsigned short addr, unsigned char * buf, unsigned short size);
888
892};
893
894
896 const char * req_type, bool prolific,
897 bool ata_48bit_support, int port)
898: smart_device(intf, scsidev->get_dev_name(), "usbjmicron", req_type),
900 m_prolific(prolific), m_ata_48bit_support(ata_48bit_support),
901 m_port(port >= 0 || !prolific ? port : 0)
902{
903 set_info().info_name = strprintf("%s [USB JMicron]", scsidev->get_info_name());
904}
905
907{
908}
909
910
912{
913 // Open USB first
915 return false;
916
917 // Detect port if not specified
918 if (m_port < 0) {
919 unsigned char regbuf[1] = {0};
920 if (!get_registers(0x720f, regbuf, sizeof(regbuf))) {
921 close();
922 return false;
923 }
924
925 switch (regbuf[0] & 0x44) {
926 case 0x04:
927 m_port = 0; break;
928 case 0x40:
929 m_port = 1; break;
930 case 0x44:
931 close();
932 return set_err(EINVAL, "Two devices connected, try '-d usbjmicron,[01]'");
933 default:
934 close();
935 return set_err(ENODEV, "No device connected");
936 }
937 }
938
939 return true;
940}
941
942
944{
945 if (!ata_cmd_is_supported(in,
949 "JMicron")
950 )
951 return false;
952
953 if (m_port < 0)
954 return set_err(EIO, "Unknown JMicron port");
955
956 scsi_cmnd_io io_hdr = {};
957
958 bool rwbit = true;
959 unsigned char smart_status = 0xff;
960
961 bool is_smart_status = ( in.in_regs.command == ATA_SMART_CMD
963
964 if (is_smart_status && in.out_needed.is_set()) {
966 io_hdr.dxfer_len = 1;
967 io_hdr.dxferp = &smart_status;
968 }
969 else switch (in.direction) {
971 io_hdr.dxfer_dir = DXFER_NONE;
972 break;
975 io_hdr.dxfer_len = in.size;
976 io_hdr.dxferp = (unsigned char *)in.buffer;
977 memset(in.buffer, 0, in.size);
978 break;
980 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
981 io_hdr.dxfer_len = in.size;
982 io_hdr.dxferp = (unsigned char *)in.buffer;
983 rwbit = false;
984 break;
985 default:
986 return set_err(EINVAL);
987 }
988
989 // Build pass through command
990 unsigned char cdb[14];
991 cdb[ 0] = 0xdf;
992 cdb[ 1] = (rwbit ? 0x10 : 0x00);
993 cdb[ 2] = 0x00;
995 cdb[ 5] = in.in_regs.features;
996 cdb[ 6] = in.in_regs.sector_count;
997 cdb[ 7] = in.in_regs.lba_low;
998 cdb[ 8] = in.in_regs.lba_mid;
999 cdb[ 9] = in.in_regs.lba_high;
1000 cdb[10] = in.in_regs.device | (m_port == 0 ? 0xa0 : 0xb0);
1001 cdb[11] = in.in_regs.command;
1002 // Prolific PL3507
1003 cdb[12] = 0x06;
1004 cdb[13] = 0x7b;
1005
1006 io_hdr.cmnd = cdb;
1007 io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
1008
1009 scsi_device * scsidev = get_tunnel_dev();
1010 if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1011 "usbjmicron_device::ata_pass_through: "))
1012 return set_err(scsidev->get_err());
1013
1014 if (in.out_needed.is_set()) {
1015 if (is_smart_status) {
1016 if (io_hdr.resid == 1)
1017 // Some (Prolific) USB bridges do not transfer a status byte
1018 return set_err(ENOSYS, "Incomplete response, status byte missing [JMicron]");
1019
1020 switch (smart_status) {
1021 case 0xc2:
1022 out.out_regs.lba_high = 0xc2;
1023 out.out_regs.lba_mid = 0x4f;
1024 break;
1025 case 0x2c:
1026 out.out_regs.lba_high = 0x2c;
1027 out.out_regs.lba_mid = 0xf4;
1028 break;
1029 default:
1030 // Some (JM20336) USB bridges always return 0x01, regardless of SMART Status
1031 return set_err(ENOSYS, "Invalid status byte (0x%02x) [JMicron]", smart_status);
1032 }
1033 }
1034
1035#if 0 // Not needed for SMART STATUS, see also notes below
1036 else {
1037 // Read ATA output registers
1038 // NOTE: The register addresses are not valid for some older chip revisions
1039 // NOTE: There is a small race condition here!
1040 unsigned char regbuf[16] = {0, };
1041 if (!get_registers((m_port == 0 ? 0x8000 : 0x9000), regbuf, sizeof(regbuf)))
1042 return false;
1043
1044 out.out_regs.sector_count = regbuf[ 0];
1045 out.out_regs.lba_mid = regbuf[ 4];
1046 out.out_regs.lba_low = regbuf[ 6];
1047 out.out_regs.device = regbuf[ 9];
1048 out.out_regs.lba_high = regbuf[10];
1049 out.out_regs.error = regbuf[13];
1050 out.out_regs.status = regbuf[14];
1051 }
1052#endif
1053 }
1054
1055 return true;
1056}
1057
1059 unsigned char * buf, unsigned short size)
1060{
1061 unsigned char cdb[14];
1062 cdb[ 0] = 0xdf;
1063 cdb[ 1] = 0x10;
1064 cdb[ 2] = 0x00;
1066 cdb[ 5] = 0x00;
1068 cdb[ 8] = 0x00;
1069 cdb[ 9] = 0x00;
1070 cdb[10] = 0x00;
1071 cdb[11] = 0xfd;
1072 // Prolific PL3507
1073 cdb[12] = 0x06;
1074 cdb[13] = 0x7b;
1075
1076 scsi_cmnd_io io_hdr = {};
1078 io_hdr.dxfer_len = size;
1079 io_hdr.dxferp = buf;
1080 io_hdr.cmnd = cdb;
1081 io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
1082
1083 scsi_device * scsidev = get_tunnel_dev();
1084 if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1085 "usbjmicron_device::get_registers: "))
1086 return set_err(scsidev->get_err());
1087
1088 return true;
1089}
1090
1091
1092/////////////////////////////////////////////////////////////////////////////
1093
1094/// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
1095
1097: public tunnelled_device<
1098 /*implements*/ ata_device,
1099 /*by tunnelling through a*/ scsi_device
1100 >
1101{
1102public:
1104 const char * req_type);
1105
1106 virtual ~usbprolific_device();
1107
1108 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
1109};
1110
1111
1113 const char * req_type)
1114: smart_device(intf, scsidev->get_dev_name(), "usbprolific", req_type),
1116{
1117 set_info().info_name = strprintf("%s [USB Prolific]", scsidev->get_info_name());
1118}
1119
1121{
1122}
1123
1125{
1126 if (!ata_cmd_is_supported(in,
1131 "Prolific" )
1132 )
1133 return false;
1134
1135 scsi_cmnd_io io_hdr = {};
1136 unsigned char cmd_rw = 0x10; // Read
1137
1138 switch (in.direction) {
1140 io_hdr.dxfer_dir = DXFER_NONE;
1141 break;
1144 io_hdr.dxfer_len = in.size;
1145 io_hdr.dxferp = (unsigned char *)in.buffer;
1146 memset(in.buffer, 0, in.size);
1147 break;
1149 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1150 io_hdr.dxfer_len = in.size;
1151 io_hdr.dxferp = (unsigned char *)in.buffer;
1152 cmd_rw = 0x0; // Write
1153 break;
1154 default:
1155 return set_err(EINVAL);
1156 }
1157
1158 // Based on reverse engineering of iSmart.exe with API Monitor.
1159 // Seen commands:
1160 // D0 0 0 0 06 7B 0 0 0 0 0 0 // Read Firmware info?, reads 16 bytes
1161 // F4 0 0 0 06 7B // ??
1162 // D8 15 0 D8 06 7B 0 0 0 0 1 1 4F C2 A0 B0 // SMART Enable
1163 // D8 15 0 D0 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read values
1164 // D8 15 0 D1 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read thresholds
1165 // D8 15 0 D4 06 7B 0 0 0 0 0 1 4F C2 A0 B0 // SMART Execute self test
1166 // D7 0 0 0 06 7B 0 0 0 0 0 0 0 0 0 0 // Read status registers, Reads 16 bytes of data
1167 // Additional DATA OUT support based on document from Prolific
1168
1169 // Build pass through command
1170 unsigned char cdb[16];
1171 cdb[ 0] = 0xD8; // Operation Code (D8 = Prolific ATA pass through)
1172 cdb[ 1] = cmd_rw|0x5; // Read(0x10)/Write(0x0) | NORMAL(0x5)/PREFIX(0x0)(?)
1173 cdb[ 2] = 0x0; // Reserved
1174 cdb[ 3] = in.in_regs.features; // Feature register (SMART command)
1175 cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1176 cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1177 sg_put_unaligned_be32(io_hdr.dxfer_len, cdb + 6);
1178 cdb[10] = in.in_regs.sector_count; // Sector Count
1179 cdb[11] = in.in_regs.lba_low; // LBA Low (7:0)
1180 cdb[12] = in.in_regs.lba_mid; // LBA Mid (15:8)
1181 cdb[13] = in.in_regs.lba_high; // LBA High (23:16)
1182 cdb[14] = in.in_regs.device | 0xA0; // Device/Head
1183 cdb[15] = in.in_regs.command; // ATA Command Register (only PIO supported)
1184 // Use '-r scsiioctl,1' to print CDB for debug purposes
1185
1186 io_hdr.cmnd = cdb;
1187 io_hdr.cmnd_len = 16;
1188
1189 scsi_device * scsidev = get_tunnel_dev();
1190 if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1191 "usbprolific_device::ata_pass_through: "))
1192 return set_err(scsidev->get_err());
1193
1194 if (in.out_needed.is_set()) {
1195 // Read ATA output registers
1196 unsigned char regbuf[16] = {0, };
1197 memset(&io_hdr, 0, sizeof(io_hdr));
1199 io_hdr.dxfer_len = sizeof(regbuf);
1200 io_hdr.dxferp = regbuf;
1201
1202 memset(cdb, 0, sizeof(cdb));
1203 cdb[ 0] = 0xD7; // Prolific read registers
1204 cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1205 cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1206 io_hdr.cmnd = cdb;
1207 io_hdr.cmnd_len = sizeof(cdb);
1208
1209 if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1210 "usbprolific_device::scsi_pass_through (get registers): "))
1211 return set_err(scsidev->get_err());
1212
1213 // Use '-r scsiioctl,2' to print input registers for debug purposes
1214 // Example: 50 00 00 00 00 01 4f 00 c2 00 a0 da 00 b0 00 50
1215 out.out_regs.status = regbuf[0]; // Status
1216 out.out_regs.error = regbuf[1]; // Error
1217 out.out_regs.sector_count = regbuf[2]; // Sector Count (7:0)
1218 out.out_regs.lba_low = regbuf[4]; // LBA Low (7:0)
1219 out.out_regs.lba_mid = regbuf[6]; // LBA Mid (7:0)
1220 out.out_regs.lba_high = regbuf[8]; // LBA High (7:0)
1221 out.out_regs.device = regbuf[10]; // Device/Head
1222 // = regbuf[11]; // ATA Feature (7:0)
1223 // = regbuf[13]; // ATA Command
1224 }
1225
1226 return true;
1227}
1228
1229
1230/////////////////////////////////////////////////////////////////////////////
1231
1232/// SunplusIT USB Bridge support.
1233
1235: public tunnelled_device<
1236 /*implements*/ ata_device,
1237 /*by tunnelling through a*/ scsi_device
1238 >
1239{
1240public:
1242 const char * req_type);
1243
1244 virtual ~usbsunplus_device();
1245
1246 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
1247};
1248
1249
1251 const char * req_type)
1252: smart_device(intf, scsidev->get_dev_name(), "usbsunplus", req_type),
1254{
1255 set_info().info_name = strprintf("%s [USB Sunplus]", scsidev->get_info_name());
1256}
1257
1259{
1260}
1261
1263{
1264 if (!ata_cmd_is_supported(in,
1268 "Sunplus")
1269 )
1270 return false;
1271
1272 scsi_cmnd_io io_hdr = {};
1273 unsigned char cdb[12];
1274
1275 if (in.in_regs.is_48bit_cmd()) {
1276 // Set "previous" registers
1277 io_hdr.dxfer_dir = DXFER_NONE;
1278
1279 cdb[ 0] = 0xf8;
1280 cdb[ 1] = 0x00;
1281 cdb[ 2] = 0x23; // Subcommand: Pass through presetting
1282 cdb[ 3] = 0x00;
1283 cdb[ 4] = 0x00;
1284 cdb[ 5] = in.in_regs.prev.features;
1285 cdb[ 6] = in.in_regs.prev.sector_count;
1286 cdb[ 7] = in.in_regs.prev.lba_low;
1287 cdb[ 8] = in.in_regs.prev.lba_mid;
1288 cdb[ 9] = in.in_regs.prev.lba_high;
1289 cdb[10] = 0x00;
1290 cdb[11] = 0x00;
1291
1292 io_hdr.cmnd = cdb;
1293 io_hdr.cmnd_len = sizeof(cdb);
1294
1295 scsi_device * scsidev = get_tunnel_dev();
1296 if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1297 "usbsunplus_device::scsi_pass_through (presetting): "))
1298 return set_err(scsidev->get_err());
1299 }
1300
1301 // Run Pass through command
1302 memset(&io_hdr, 0, sizeof(io_hdr));
1303 unsigned char protocol;
1304 switch (in.direction) {
1306 io_hdr.dxfer_dir = DXFER_NONE;
1307 protocol = 0x00;
1308 break;
1311 io_hdr.dxfer_len = in.size;
1312 io_hdr.dxferp = (unsigned char *)in.buffer;
1313 memset(in.buffer, 0, in.size);
1314 protocol = 0x10;
1315 break;
1317 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1318 io_hdr.dxfer_len = in.size;
1319 io_hdr.dxferp = (unsigned char *)in.buffer;
1320 protocol = 0x11;
1321 break;
1322 default:
1323 return set_err(EINVAL);
1324 }
1325
1326 cdb[ 0] = 0xf8;
1327 cdb[ 1] = 0x00;
1328 cdb[ 2] = 0x22; // Subcommand: Pass through
1329 cdb[ 3] = protocol;
1330 cdb[ 4] = (unsigned char)(io_hdr.dxfer_len >> 9);
1331 cdb[ 5] = in.in_regs.features;
1332 cdb[ 6] = in.in_regs.sector_count;
1333 cdb[ 7] = in.in_regs.lba_low;
1334 cdb[ 8] = in.in_regs.lba_mid;
1335 cdb[ 9] = in.in_regs.lba_high;
1336 cdb[10] = in.in_regs.device | 0xa0;
1337 cdb[11] = in.in_regs.command;
1338
1339 io_hdr.cmnd = cdb;
1340 io_hdr.cmnd_len = sizeof(cdb);
1341
1342 scsi_device * scsidev = get_tunnel_dev();
1343 if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1344 "usbsunplus_device::scsi_pass_through: "))
1345 // Returns sense key 0x03 (medium error) on ATA command error
1346 return set_err(scsidev->get_err());
1347
1348 if (in.out_needed.is_set()) {
1349 // Read ATA output registers
1350 unsigned char regbuf[8] = {0, };
1351 memset(&io_hdr, 0, sizeof(io_hdr));
1353 io_hdr.dxfer_len = sizeof(regbuf);
1354 io_hdr.dxferp = regbuf;
1355
1356 cdb[ 0] = 0xf8;
1357 cdb[ 1] = 0x00;
1358 cdb[ 2] = 0x21; // Subcommand: Get status
1359 memset(cdb+3, 0, sizeof(cdb)-3);
1360 io_hdr.cmnd = cdb;
1361 io_hdr.cmnd_len = sizeof(cdb);
1362
1363 if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1364 "usbsunplus_device::scsi_pass_through (get registers): "))
1365 return set_err(scsidev->get_err());
1366
1367 out.out_regs.error = regbuf[1];
1368 out.out_regs.sector_count = regbuf[2];
1369 out.out_regs.lba_low = regbuf[3];
1370 out.out_regs.lba_mid = regbuf[4];
1371 out.out_regs.lba_high = regbuf[5];
1372 out.out_regs.device = regbuf[6];
1373 out.out_regs.status = regbuf[7];
1374 }
1375
1376 return true;
1377}
1378
1379
1380} // namespace
1381
1382using namespace sat;
1383
1384
1385/////////////////////////////////////////////////////////////////////////////
1386
1387// Return ATA->SCSI filter for SAT or USB.
1388
1390{
1391 if (!scsidev)
1392 throw std::logic_error("smart_interface: get_sat_device() called with scsidev=0");
1393
1394 // Take temporary ownership of 'scsidev' to delete it on error
1395 scsi_device_auto_ptr scsidev_holder(scsidev);
1396 ata_device * satdev = 0;
1397
1398 if (!strncmp(type, "sat", 3)) {
1399 const char * t = type + 3;
1400 sat_device::sat_scsi_mode mode = sat_device::sat_always;
1401 if (!strncmp(t, ",auto", 5)) {
1402 t += 5;
1403 mode = sat_device::sat_auto;
1404 }
1405 int ptlen = 0, n = -1;
1406 if (*t && !(sscanf(t, ",%d%n", &ptlen, &n) == 1 && n == (int)strlen(t)
1407 && (ptlen == 0 || ptlen == 12 || ptlen == 16))) {
1408 set_err(EINVAL, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16");
1409 return 0;
1410 }
1411 satdev = new sat_device(this, scsidev, type, mode, ptlen);
1412 }
1413
1414 else if (!strcmp(type, "scsi")) {
1415 satdev = new sat_device(this, scsidev, type, sat_device::scsi_always);
1416 }
1417
1418 else if (!strncmp(type, "usbcypress", 10)) {
1419 unsigned signature = 0x24; int n1 = -1, n2 = -1;
1420 if (!(((sscanf(type, "usbcypress%n,0x%x%n", &n1, &signature, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type))
1421 && signature <= 0xff)) {
1422 set_err(EINVAL, "Option '-d usbcypress,<n>' requires <n> to be "
1423 "an hexadecimal number between 0x0 and 0xff");
1424 return 0;
1425 }
1426 satdev = new usbcypress_device(this, scsidev, type, signature);
1427 }
1428
1429 else if (!strncmp(type, "usbjmicron", 10)) {
1430 const char * t = type + 10;
1431 bool prolific = false;
1432 if (!strncmp(t, ",p", 2)) {
1433 t += 2;
1434 prolific = true;
1435 }
1436 bool ata_48bit_support = false;
1437 if (!strncmp(t, ",x", 2)) {
1438 t += 2;
1439 ata_48bit_support = true;
1440 }
1441 int port = -1, n = -1;
1442 if (*t && !( (sscanf(t, ",%d%n", &port, &n) == 1
1443 && n == (int)strlen(t) && 0 <= port && port <= 1))) {
1444 set_err(EINVAL, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
1445 return 0;
1446 }
1447 satdev = new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
1448 }
1449
1450 else if (!strcmp(type, "usbprolific")) {
1451 satdev = new usbprolific_device(this, scsidev, type);
1452 }
1453
1454 else if (!strcmp(type, "usbsunplus")) {
1455 satdev = new usbsunplus_device(this, scsidev, type);
1456 }
1457
1458 else {
1459 set_err(EINVAL, "Unknown USB device type '%s'", type);
1460 return 0;
1461 }
1462
1463 // 'scsidev' is now owned by 'satdev'
1464 scsidev_holder.release();
1465 return satdev;
1466}
1467
1468// Try to detect a SAT device behind a SCSI interface.
1469
1471 const unsigned char * inqdata, unsigned inqsize)
1472{
1473 if (!scsidev->is_open())
1474 return 0;
1475
1476 // SAT ?
1477 if (inqdata && inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8)) {
1478 // TODO: Linux-specific? No, all SAT standards say the 'T10 Vendor
1479 // Identification' field shall be 'ATA '.
1480 ata_device_auto_ptr atadev( new sat_device(this, scsidev, "") , scsidev);
1481 if (has_sat_pass_through(atadev.get()))
1482 return atadev.release(); // Detected SAT
1483 }
1484
1485 return 0;
1486}
1487
1488
1489/////////////////////////////////////////////////////////////////////////////
1490// USB device type detection
1491
1492// Format USB ID for error messages
1493static std::string format_usb_id(int vendor_id, int product_id, int version)
1494{
1495 if (version >= 0)
1496 return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id, product_id, version);
1497 else
1498 return strprintf("[0x%04x:0x%04x]", vendor_id, product_id);
1499}
1500
1501// Get type name for USB device with known VENDOR:PRODUCT ID.
1502const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
1503 int version /*= -1*/)
1504{
1505 usb_dev_info info, info2;
1506 int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
1507
1508 if (n <= 0) {
1509 set_err(EINVAL, "Unknown USB bridge %s",
1510 format_usb_id(vendor_id, product_id, version).c_str());
1511 return 0;
1512 }
1513
1514 if (n > 1) {
1515 set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
1516 format_usb_id(vendor_id, product_id, version).c_str(),
1517 (!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"),
1518 (!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
1519 return 0;
1520 }
1521
1522 if (info.usb_type.empty()) {
1523 set_err(ENOSYS, "Unsupported USB bridge %s",
1524 format_usb_id(vendor_id, product_id, version).c_str());
1525 return 0;
1526 }
1527
1528 // TODO: change return type to std::string
1529 static std::string type;
1530 type = info.usb_type;
1531 return type.c_str();
1532}
#define ATA_SMART_AUTO_OFFLINE
Definition: atacmds.h:94
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:53
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:87
#define ATA_IDENTIFY_PACKET_DEVICE
Definition: atacmds.h:54
#define ATA_SMART_STATUS
Definition: atacmds.h:91
#define ATA_SMART_READ_VALUES
Definition: atacmds.h:81
#define ATA_SMART_READ_THRESHOLDS
Definition: atacmds.h:82
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:86
#define ATA_SMART_CMD
Definition: atacmds.h:56
#define ATA_SMART_IMMEDIATE_OFFLINE
Definition: atacmds.h:85
smart_command_set
Definition: atacmds.h:29
@ PIDENTIFY
Definition: atacmds.h:43
@ CHECK_POWER_MODE
Definition: atacmds.h:45
@ IDENTIFY
Definition: atacmds.h:42
@ STATUS_CHECK
Definition: atacmds.h:37
@ IMMEDIATE_OFFLINE
Definition: atacmds.h:34
@ AUTO_OFFLINE
Definition: atacmds.h:35
@ ENABLE
Definition: atacmds.h:31
@ WRITE_LOG
Definition: atacmds.h:47
@ READ_VALUES
Definition: atacmds.h:39
@ AUTOSAVE
Definition: atacmds.h:33
@ STATUS
Definition: atacmds.h:36
@ READ_THRESHOLDS
Definition: atacmds.h:40
@ DISABLE
Definition: atacmds.h:32
@ READ_LOG
Definition: atacmds.h:41
#define ATA_SMART_ENABLE
Definition: atacmds.h:89
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:83
#define ATA_SMART_DISABLE
Definition: atacmds.h:90
#define ATA_CHECK_POWER_MODE
Definition: atacmds.h:52
Smart pointer class for device pointers.
device_type * release()
Return the pointer and release ownership.
device_type * get() const
Return the pointer.
Adapter class to implement new ATA pass through old interface.
ATA device access.
@ supports_output_regs
@ supports_48bit_hi_null
@ supports_multi_sector
@ supports_smart_status
bool ata_cmd_is_supported(const ata_cmd_in &in, unsigned flags, const char *type=0)
Check command input parameters.
void hide_ata(bool hide=true)
Hide/unhide ATA interface.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)=0
ATA pass through.
SAT support.
Definition: scsiata.cpp:106
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: scsiata.cpp:248
virtual ~sat_device()
Definition: scsiata.cpp:151
virtual smart_device * autodetect_open() override
Open device with autodetection support.
Definition: scsiata.cpp:506
sat_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, sat_scsi_mode mode=sat_always, int passthrulen=0)
Definition: scsiata.cpp:131
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
Definition: scsiata.cpp:496
sat_scsi_mode m_mode
Definition: scsiata.cpp:127
Cypress USB Bridge support.
Definition: scsiata.cpp:606
unsigned char m_signature
Definition: scsiata.cpp:616
virtual ~usbcypress_device()
Definition: scsiata.cpp:629
virtual int ata_command_interface(smart_command_set command, int select, char *data) override
Old ATA interface called by ata_pass_through()
Definition: scsiata.cpp:636
usbcypress_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, unsigned char signature)
Definition: scsiata.cpp:620
JMicron USB Bridge support.
Definition: scsiata.cpp:874
virtual ~usbjmicron_device()
Definition: scsiata.cpp:906
bool get_registers(unsigned short addr, unsigned char *buf, unsigned short size)
Definition: scsiata.cpp:1058
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: scsiata.cpp:943
virtual bool open() override
Open device, return false on error.
Definition: scsiata.cpp:911
usbjmicron_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, bool prolific, bool ata_48bit_support, int port)
Definition: scsiata.cpp:895
Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
Definition: scsiata.cpp:1101
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: scsiata.cpp:1124
usbprolific_device(smart_interface *intf, scsi_device *scsidev, const char *req_type)
Definition: scsiata.cpp:1112
virtual ~usbprolific_device()
Definition: scsiata.cpp:1120
SunplusIT USB Bridge support.
Definition: scsiata.cpp:1239
virtual ~usbsunplus_device()
Definition: scsiata.cpp:1258
usbsunplus_device(smart_interface *intf, scsi_device *scsidev, const char *req_type)
Definition: scsiata.cpp:1250
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: scsiata.cpp:1262
SCSI device access.
void hide_scsi(bool hide=true)
Hide/unhide SCSI interface.
bool scsi_pass_through_and_check(scsi_cmnd_io *iop, const char *msg="")
virtual bool scsi_pass_through(scsi_cmnd_io *iop)=0
SCSI pass through.
Base class for all devices.
Definition: dev_interface.h:33
int get_errno() const
Get last error number.
const error_info & get_err() const
Get last error info struct.
const char * get_dev_type() const
Get device type.
const char * get_errmsg() const
Get last error message.
virtual bool close()=0
Close device, return false on error.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
const char * get_info_name() const
Get informal name.
virtual bool is_open() const =0
Return true if device is open.
device_info & set_info()
R/W access to device info struct.
virtual bool open()=0
Open device, return false on error.
The platform interface abstraction.
virtual const char * get_usb_dev_type_by_id(int vendor_id, int product_id, int version=-1)
Get type name for USB device with known VENDOR:PRODUCT ID.
Definition: scsiata.cpp:1502
virtual ata_device * get_sat_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI filter for a SAT or USB 'type'.
Definition: scsiata.cpp:1389
virtual ata_device * autodetect_sat_device(scsi_device *scsidev, const unsigned char *inqdata, unsigned inqsize)
Try to detect a SAT device behind a SCSI interface.
Definition: scsiata.cpp:1470
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
virtual bool close() override
Close device, return false on error.
Implement a device by tunneling through another device.
Definition: dev_tunnelled.h:56
int lookup_usb_device(int vendor_id, int product_id, int bcd_device, usb_dev_info &info, usb_dev_info &info2)
u8 cdb[16]
Definition: megaraid.h:21
struct megasas_pd_address addr[MAX_SYS_PDS]
Definition: megaraid.h:2
ptr_t data
Definition: megaraid.h:15
u32 size
Definition: megaraid.h:0
uint32_t outlen
Definition: megaraid.h:1
Definition: scsiata.cpp:95
#define SAT_ATA_PASSTHROUGH_16LEN
Definition: scsiata.cpp:89
#define ATA_RETURN_DESCRIPTOR
Definition: scsiata.cpp:92
#define USBCYPRESS_PASSTHROUGH_LEN
Definition: scsiata.cpp:635
#define SAT_ATA_PASSTHROUGH_12LEN
Definition: scsiata.cpp:88
const char * scsiata_cpp_cvsid
Definition: scsiata.cpp:58
#define DEF_SAT_ATA_PASSTHRU_SIZE
Definition: scsiata.cpp:91
static bool has_sat_pass_through(ata_device *dev, bool packet_interface=false)
Definition: scsiata.cpp:543
static int sg_scsi_normalize_sense(const unsigned char *sensep, int sb_len, struct sg_scsi_sense_hdr *sshp)
Definition: scsiata.cpp:561
static std::string format_usb_id(int vendor_id, int product_id, int version)
Definition: scsiata.cpp:1493
int scsiSimpleSenseFilter(const struct scsi_sense_disect *sinfo)
Definition: scsicmds.cpp:347
void scsi_do_sense_disect(const struct scsi_cmnd_io *io_buf, struct scsi_sense_disect *out)
Definition: scsicmds.cpp:325
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
Definition: scsicmds.cpp:923
const unsigned char * sg_scsi_sense_desc_find(const unsigned char *sensep, int sense_len, int desc_type)
Definition: scsicmds.cpp:2798
void dStrHex(const uint8_t *up, int len, int no_ascii)
Definition: scsicmds.cpp:78
const char * scsiErrString(int scsiErr)
Definition: scsicmds.cpp:390
unsigned char scsi_debugmode
Definition: scsicmds.cpp:45
#define SAT_ATA_PASSTHROUGH_12
Definition: scsicmds.h:98
#define DXFER_NONE
Definition: scsicmds.h:105
#define SCSI_ASCQ_ATA_PASS_THROUGH
Definition: scsicmds.h:337
#define DXFER_FROM_DEVICE
Definition: scsicmds.h:106
#define SCSI_TIMEOUT_DEFAULT
Definition: scsicmds.h:372
#define SAT_ATA_PASSTHROUGH_16
Definition: scsicmds.h:101
#define DXFER_TO_DEVICE
Definition: scsicmds.h:107
#define SCSI_STATUS_CHECK_CONDITION
Definition: scsicmds.h:313
#define SCSI_SK_NO_SENSE
Definition: scsicmds.h:316
#define SCSI_SK_RECOVERED_ERR
Definition: scsicmds.h:317
static void sg_put_unaligned_be32(uint32_t val, void *p)
Definition: sg_unaligned.h:279
static void sg_put_unaligned_be16(uint16_t val, void *p)
Definition: sg_unaligned.h:273
void pout(const char *fmt,...)
Definition: smartd.cpp:1326
ATA pass through input parameters.
enum ata_cmd_in::@29 direction
I/O direction.
void * buffer
Pointer to data buffer.
ata_in_regs_48bit in_regs
Input registers.
unsigned size
Size of buffer.
ata_out_regs_flags out_needed
True if output register value needed.
void set_data_in(void *buf, unsigned nsectors)
Prepare for 28-bit DATA IN command.
ATA pass through output parameters.
ata_out_regs_48bit out_regs
Output registers.
bool is_48bit_cmd() const
Return true if 48-bit command.
ata_in_regs prev
"previous content"
ATA Input registers (for 28-bit commands)
ata_register device
ata_register lba_high
ata_register sector_count
ata_register lba_low
ata_register features
ata_register command
ata_register lba_mid
ata_out_regs prev
read with HOB=1
bool is_set() const
Return true if any flag is set.
ATA Output registers (for 28-bit commands)
ata_register sector_count
ata_register lba_low
ata_register lba_mid
ata_register error
ata_register lba_high
ata_register device
ata_register status
uint8_t * sensep
Definition: scsicmds.h:120
uint8_t * dxferp
Definition: scsicmds.h:118
int dxfer_dir
Definition: scsicmds.h:116
size_t cmnd_len
Definition: scsicmds.h:115
size_t resp_sense_len
Definition: scsicmds.h:124
size_t dxfer_len
Definition: scsicmds.h:119
size_t max_sense_len
Definition: scsicmds.h:122
uint8_t scsi_status
Definition: scsicmds.h:125
uint8_t * cmnd
Definition: scsicmds.h:114
unsigned timeout
Definition: scsicmds.h:123
Abridged SCSI sense data.
Definition: scsiata.cpp:67
unsigned char byte4
Definition: scsiata.cpp:72
unsigned char byte6
Definition: scsiata.cpp:74
unsigned char asc
Definition: scsiata.cpp:70
unsigned char ascq
Definition: scsiata.cpp:71
unsigned char additional_length
Definition: scsiata.cpp:75
unsigned char sense_key
Definition: scsiata.cpp:69
unsigned char response_code
Definition: scsiata.cpp:68
unsigned char byte5
Definition: scsiata.cpp:73
std::string info_name
Informal name.
Definition: dev_interface.h:46
std::string dev_type
Actual device type.
Definition: dev_interface.h:47
Error (number,message) pair.
Definition: dev_interface.h:52
std::string msg
Error message.
Definition: dev_interface.h:61
int no
Error number.
Definition: dev_interface.h:60
std::string usb_type
Definition: knowndrives.h:31
void syserror(const char *message)
Definition: utility.cpp:390
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:780