smartmontools  SVN Rev 4345
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: http://www.smartmontools.org
5  *
6  * Copyright (C) 2006-15 Douglas Gilbert <dgilbert@interlog.com>
7  * Copyright (C) 2009-16 Christian Franke
8  *
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)
12  * any later version.
13  *
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.
17  *
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.
24  *
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.
34  *
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).
46  *
47  */
48 
49 #include <stdio.h>
50 #include <string.h>
51 #include <stdlib.h>
52 #include <ctype.h>
53 #include <errno.h>
54 
55 #include "config.h"
56 #include "int64.h"
57 #include "scsicmds.h"
58 #include "atacmds.h" // ataReadHDIdentity()
59 #include "knowndrives.h" // lookup_usb_device()
60 #include "utility.h"
61 #include "dev_interface.h"
62 #include "dev_ata_cmd_set.h" // ata_device_with_command_set
63 #include "dev_tunnelled.h" // tunnelled_device<>
64 
65 const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 4276 2016-04-02 19:13:39Z chrfranke $";
66 
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
75  unsigned char response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
76  unsigned char sense_key;
77  unsigned char asc;
78  unsigned char ascq;
79  unsigned char byte4;
80  unsigned char byte5;
81  unsigned char byte6;
82  unsigned char additional_length;
83 };
84 
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);
94 
95 #define SAT_ATA_PASSTHROUGH_12LEN 12
96 #define SAT_ATA_PASSTHROUGH_16LEN 16
97 
98 #define DEF_SAT_ATA_PASSTHRU_SIZE 16
99 #define ATA_RETURN_DESCRIPTOR 9
100 
101 
102 namespace sat { // no need to publish anything, name provided for Doxygen
103 
104 /// SAT support.
105 /// Implements ATA by tunnelling through SCSI.
106 
108 : public tunnelled_device<
109  /*implements*/ ata_device
110  /*by tunnelling through a*/, scsi_device
111  >,
112  virtual public /*implements*/ scsi_device
113 {
114 public:
115  sat_device(smart_interface * intf, scsi_device * scsidev,
116  const char * req_type, int passthrulen = 0, bool enable_auto = false);
117 
118  virtual ~sat_device() throw();
119 
120  virtual smart_device * autodetect_open();
121 
122  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
123 
124  virtual bool scsi_pass_through(scsi_cmnd_io * iop);
125 
126 private:
129 };
130 
131 
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),
137  m_passthrulen(passthrulen),
138  m_enable_auto(enable_auto)
139 {
140  if (enable_auto)
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 [%sSAT]", scsidev->get_info_name(),
148  (enable_auto ? "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  memset(cdb, 0, sizeof(cdb));
276  memset(sense, 0, sizeof(sense));
277 
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:
282  break;
283  case ata_cmd_in::data_in:
284  protocol = 4; // PIO data-in
285  t_length = 2; // sector_count holds count
286  break;
288  protocol = 5; // PIO data-out
289  t_length = 2; // sector_count holds count
290  t_dir = 0; // to device
291  break;
292  default:
293  return set_err(EINVAL, "sat_device::ata_pass_through: invalid direction=%d",
294  (int)in.direction);
295  }
296 
297  // Check condition if any output register needed
298  if (in.out_needed.is_set())
299  ck_cond = 1;
300 
303  passthru_size = m_passthrulen;
304 
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)");
309  extend = 1;
310  }
311 
312  cdb[0] = (SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ?
314 
315  cdb[1] = (protocol << 1) | extend;
316  cdb[2] = (ck_cond << 5) | (t_dir << 3) |
317  (byte_block << 2) | t_length;
318 
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;
324  cdb[5] = lo.lba_low;
325  cdb[6] = lo.lba_mid;
326  cdb[7] = lo.lba_high;
327  cdb[8] = lo.device;
328  cdb[9] = lo.command;
329  }
330  else {
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;
345  cdb[13] = lo.device;
346  cdb[14] = lo.command;
347  }
348 
349  memset(&io_hdr, 0, sizeof(io_hdr));
350  if (0 == t_length) {
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;
362  }
363  io_hdr.cmnd = cdb;
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;
368 
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());
375  }
376  ardp = NULL;
377  ard_len = 0;
378  have_sense = sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len,
379  &ssh);
380  if (have_sense) {
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,
387  if (ardp) {
388  ard_len = ardp[1] + 2;
389  if (ard_len < 12)
390  ard_len = 12;
391  else if (ard_len > 14)
392  ard_len = 14;
393  }
394  }
395  scsi_do_sense_disect(&io_hdr, &sinfo);
396  int status = scsiSimpleSenseFilter(&sinfo);
397 
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",
403  ardp[13]);
404  status = 0;
405  }
406 
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);
414  }
415  }
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));
419  }
420  }
421  if (ck_cond) { /* expecting SAT specific sense data */
422  if (have_sense) {
423  if (ardp) {
424  if (scsi_debugmode > 1) {
425  pout("Values from ATA Return Descriptor are:\n");
426  dStrHex((const char *)ardp, ard_len, 1);
427  }
428  // Set output registers
429  ata_out_regs & lo = out.out_regs;
430  lo.error = ardp[ 3];
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];
443  }
444  } else if ((! sense_descriptor) &&
445  (0 == ssh.asc) &&
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;
461  hi.sector_count = 0;
462  hi.lba_low = 0;
463  hi.lba_mid = 0;
464  hi.lba_high = 0;
465  } else {
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. */
471  }
472  }
473  }
474  }
475  } else { /* ck_cond == 0 */
476  if (have_sense) {
477  if (((SCSI_SK_NO_SENSE == ssh.sense_key) ||
478  (SCSI_SK_RECOVERED_ERR == ssh.sense_key)) &&
479  (0 == ssh.asc) &&
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]);
491  }
492  }
493  }
494  return set_err(EIO, "SAT command failed");
495  }
496  }
497  return true;
498 }
499 
501 {
502  scsi_device * scsidev = get_tunnel_dev();
503  if (!scsidev->scsi_pass_through(iop)) {
504  set_err(scsidev->get_err());
505  return false;
506  }
507  return true;
508 }
509 
511 {
512  if (!open() || !m_enable_auto)
513  return this;
514 
515  scsi_device * scsidev = get_tunnel_dev();
516 
517  unsigned char inqdata[36] = {0, };
518  if (scsiStdInquiry(scsidev, inqdata, sizeof(inqdata))) {
519  smart_device::error_info err = scsidev->get_err();
520  close();
521  set_err(err.no, "INQUIRY [SAT]: %s", err.msg.c_str());
522  return this;
523  }
524 
525  // Check for SAT "VENDOR"
526  int inqsize = inqdata[4] + 5;
527  bool sat = (inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8));
528 
529  // Change interface
530  hide_ata(!sat);
531  hide_scsi(sat);
532 
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"));
536  return this;
537 }
538 
539 } // namespace
540 
541 /////////////////////////////////////////////////////////////////////////////
542 
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 */
546 
547 static bool has_sat_pass_through(ata_device * dev, bool packet_interface = false)
548 {
549  /* Note: malloc() ensures the read buffer lands on a single
550  page. This avoids some bugs seen on LSI controlers under
551  FreeBSD */
552  char *data = (char *)malloc(512);
553  ata_cmd_in in;
555  in.set_data_in(data, 1);
556  bool ret = dev->ata_pass_through(in);
557  free(data);
558  return ret;
559 }
560 
561 /////////////////////////////////////////////////////////////////////////////
562 
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)
567 {
568  if (sshp)
569  memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr));
570  if ((NULL == sensep) || (0 == sb_len) || (0x70 != (0x70 & sensep[0])))
571  return 0;
572  if (sshp) {
573  sshp->response_code = (0x7f & sensep[0]);
574  if (sshp->response_code >= 0x72) { /* descriptor format */
575  if (sb_len > 1)
576  sshp->sense_key = (0xf & sensep[1]);
577  if (sb_len > 2)
578  sshp->asc = sensep[2];
579  if (sb_len > 3)
580  sshp->ascq = sensep[3];
581  if (sb_len > 7)
582  sshp->additional_length = sensep[7];
583  } else { /* fixed format */
584  if (sb_len > 2)
585  sshp->sense_key = (0xf & sensep[2]);
586  if (sb_len > 7) {
587  sb_len = (sb_len < (sensep[7] + 8)) ? sb_len :
588  (sensep[7] + 8);
589  if (sb_len > 12)
590  sshp->asc = sensep[12];
591  if (sb_len > 13)
592  sshp->ascq = sensep[13];
593  }
594  }
595  }
596  return 1;
597 }
598 
599 
600 // Call scsi_pass_through and check sense.
601 // TODO: Provide as member function of class scsi_device (?)
603  const char * msg = "")
604 {
605  // Provide sense buffer
606  unsigned char sense[32] = {0, };
607  iop->sensep = sense;
608  iop->max_sense_len = sizeof(sense);
610 
611  // Run cmd
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());
616  return false;
617  }
618 
619  // Check sense
620  scsi_sense_disect sinfo;
621  scsi_do_sense_disect(iop, &sinfo);
622  int err = scsiSimpleSenseFilter(&sinfo);
623  if (err) {
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));
627  }
628 
629  return true;
630 }
631 
632 
633 /////////////////////////////////////////////////////////////////////////////
634 
635 namespace sat {
636 
637 /// Cypress USB Brigde support.
638 
640 : public tunnelled_device<
641  /*implements*/ ata_device_with_command_set
642  /*by tunnelling through a*/, scsi_device
643  >
644 {
645 public:
647  const char * req_type, unsigned char signature);
648 
649  virtual ~usbcypress_device() throw();
650 
651 protected:
652  virtual int ata_command_interface(smart_command_set command, int select, char * data);
653 
654  unsigned char m_signature;
655 };
656 
657 
659  const char * req_type, unsigned char signature)
660 : smart_device(intf, scsidev->get_dev_name(), "sat", req_type),
662  m_signature(signature)
663 {
664  set_info().info_name = strprintf("%s [USB Cypress]", scsidev->get_info_name());
665 }
666 
668 {
669 }
670 
671 
672 /* see cy7c68300c_8.pdf for more information */
673 #define USBCYPRESS_PASSTHROUGH_LEN 16
675 {
676  struct scsi_cmnd_io io_hdr;
677  unsigned char cdb[USBCYPRESS_PASSTHROUGH_LEN];
678  unsigned char sense[32];
679  int copydata = 0;
680  int outlen = 0;
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 */
685  int feature = 0;
686  int ata_command = 0;
687  int sector_count = 0;
688  int lba_low = 0;
689  int lba_mid = 0;
690  int lba_high = 0;
691  int passthru_size = USBCYPRESS_PASSTHROUGH_LEN;
692 
693  memset(cdb, 0, sizeof(cdb));
694  memset(sense, 0, sizeof(sense));
695 
696  ata_command = ATA_SMART_CMD;
697  switch (command) {
698  case CHECK_POWER_MODE:
699  ata_command = ATA_CHECK_POWER_MODE;
700  ck_cond = 1;
701  copydata = 1;
702  break;
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 */
707  copydata = 512;
708  break;
709  case READ_THRESHOLDS: /* obsolete */
710  feature = ATA_SMART_READ_THRESHOLDS;
711  sector_count = 1; /* one (512 byte) block */
712  lba_low = 1;
713  t_length = 2; /* sector count holds count */
714  copydata=512;
715  break;
716  case READ_LOG:
717  feature = ATA_SMART_READ_LOG_SECTOR;
718  sector_count = 1; /* one (512 byte) block */
719  lba_low = select;
720  t_length = 2; /* sector count holds count */
721  copydata = 512;
722  break;
723  case WRITE_LOG:
724  feature = ATA_SMART_WRITE_LOG_SECTOR;
725  sector_count = 1; /* one (512 byte) block */
726  lba_low = select;
727  t_length = 2; /* sector count holds count */
728  t_dir = 0; /* to device */
729  outlen = 512;
730  break;
731  case IDENTIFY:
732  ata_command = ATA_IDENTIFY_DEVICE;
733  sector_count = 1; /* one (512 byte) block */
734  t_length = 2; /* sector count holds count */
735  copydata = 512;
736  break;
737  case PIDENTIFY:
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 */
741  copydata = 512;
742  break;
743  case ENABLE:
744  feature = ATA_SMART_ENABLE;
745  lba_low = 1;
746  break;
747  case DISABLE:
748  feature = ATA_SMART_DISABLE;
749  lba_low = 1;
750  break;
751  case STATUS:
752  // this command only says if SMART is working. It could be
753  // replaced with STATUS_CHECK below.
754  feature = ATA_SMART_STATUS;
755  ck_cond = 1;
756  break;
757  case AUTO_OFFLINE:
758  feature = ATA_SMART_AUTO_OFFLINE;
759  sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
760  break;
761  case AUTOSAVE:
762  feature = ATA_SMART_AUTOSAVE;
763  sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
764  break;
765  case IMMEDIATE_OFFLINE:
766  feature = ATA_SMART_IMMEDIATE_OFFLINE;
767  lba_low = select;
768  break;
769  case STATUS_CHECK:
770  // This command uses HDIO_DRIVE_TASK and has different syntax than
771  // the other commands.
772  feature = ATA_SMART_STATUS; /* SMART RETURN STATUS */
773  ck_cond = 1;
774  break;
775  default:
776  pout("Unrecognized command %d in usbcypress_device::ata_command_interface()\n"
777  "Please contact " PACKAGE_BUGREPORT "\n", command);
778  errno=ENOSYS;
779  return -1;
780  }
781  if (ATA_SMART_CMD == ata_command) {
782  lba_mid = 0x4f;
783  lba_high = 0xc2;
784  }
785 
786  cdb[0] = m_signature; // bVSCBSignature : vendor-specific command
787  cdb[1] = 0x24; // bVSCBSubCommand : 0x24 for ATACB
788  cdb[2] = 0x0;
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
794 
795 
796  cdb[6] = feature;
797  cdb[7] = sector_count;
798  cdb[8] = lba_low;
799  cdb[9] = lba_mid;
800  cdb[10] = lba_high;
801  cdb[12] = ata_command;
802 
803  memset(&io_hdr, 0, sizeof(io_hdr));
804  if (0 == t_length) {
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;
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);
821  io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
822 
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());
829  return -1;
830  }
831 
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)) {
836  return -1;
837  }
838  if (ck_cond) {
839  unsigned char ardp[8];
840  int ard_len = 8;
841  /* XXX this is racy if there other scsi command between
842  * the first usbcypress command and this one
843  */
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]
848  */
849  cdb[2] = (1<<0); /* ask read taskfile */
850  memset(sense, 0, sizeof(sense));
851 
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 */
858 
859  io_hdr.cmnd = cdb;
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;
864 
865 
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());
871  return -1;
872  }
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)) {
877  return -1;
878  }
879 
880 
881  if (scsi_debugmode > 1) {
882  pout("Values from ATA Return Descriptor are:\n");
883  dStrHex((const char *)ardp, ard_len, 1);
884  }
885 
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);
901  return -1;
902  }
903  }
904  return 0;
905 }
906 
907 #if 0 // Not used, see autodetect_sat_device() below.
908 static int isprint_string(const char *s)
909 {
910  while (*s) {
911  if (isprint(*s) == 0)
912  return 0;
913  s++;
914  }
915  return 1;
916 }
917 
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)
922 {
923  struct ata_identify_device drive;
924  char model[40], serial[20], firm[8];
925 
926  /* issue the command and do a checksum if possible */
927  if (ataReadHDIdentity(atadev, &drive) < 0)
928  return 0;
929 
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)
933  return 0;
934 
935  if (manufacturer && strncmp(manufacturer, model, 8))
936  pout("manufacturer doesn't match in pass_through test\n");
937  if (product &&
938  strlen(model) > 8 && strncmp(product, model+8, strlen(model)-8))
939  pout("product doesn't match in pass_through test\n");
940 
941  /* check serial */
942  format_ata_string(serial, drive.serial_no, 20);
943  if (isprint_string(serial) == 0)
944  return 0;
945  format_ata_string(firm, drive.fw_rev, 8);
946  if (isprint_string(firm) == 0)
947  return 0;
948  return 1;
949 }
950 #endif
951 
952 /////////////////////////////////////////////////////////////////////////////
953 
954 /// JMicron USB Bridge support.
955 
957 : public tunnelled_device<
958  /*implements*/ ata_device,
959  /*by tunnelling through a*/ scsi_device
960  >
961 {
962 public:
964  const char * req_type, bool prolific,
965  bool ata_48bit_support, int port);
966 
967  virtual ~usbjmicron_device() throw();
968 
969  virtual bool open();
970 
971  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
972 
973 private:
974  bool get_registers(unsigned short addr, unsigned char * buf, unsigned short size);
975 
978  int m_port;
979 };
980 
981 
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),
987  m_prolific(prolific), m_ata_48bit_support(ata_48bit_support),
988  m_port(port >= 0 || !prolific ? port : 0)
989 {
990  set_info().info_name = strprintf("%s [USB JMicron]", scsidev->get_info_name());
991 }
992 
994 {
995 }
996 
997 
999 {
1000  // Open USB first
1002  return false;
1003 
1004  // Detect port if not specified
1005  if (m_port < 0) {
1006  unsigned char regbuf[1] = {0};
1007  if (!get_registers(0x720f, regbuf, sizeof(regbuf))) {
1008  close();
1009  return false;
1010  }
1011 
1012  switch (regbuf[0] & 0x44) {
1013  case 0x04:
1014  m_port = 0; break;
1015  case 0x40:
1016  m_port = 1; break;
1017  case 0x44:
1018  close();
1019  return set_err(EINVAL, "Two devices connected, try '-d usbjmicron,[01]'");
1020  default:
1021  close();
1022  return set_err(ENODEV, "No device connected");
1023  }
1024  }
1025 
1026  return true;
1027 }
1028 
1029 
1031 {
1032  if (!ata_cmd_is_supported(in,
1036  "JMicron")
1037  )
1038  return false;
1039 
1040  if (m_port < 0)
1041  return set_err(EIO, "Unknown JMicron port");
1042 
1043  scsi_cmnd_io io_hdr;
1044  memset(&io_hdr, 0, sizeof(io_hdr));
1045 
1046  bool rwbit = true;
1047  unsigned char smart_status = 0xff;
1048 
1049  bool is_smart_status = ( in.in_regs.command == ATA_SMART_CMD
1050  && in.in_regs.features == ATA_SMART_STATUS);
1051 
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;
1056  }
1057  else switch (in.direction) {
1058  case ata_cmd_in::no_data:
1059  io_hdr.dxfer_dir = DXFER_NONE;
1060  break;
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);
1066  break;
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;
1071  rwbit = false;
1072  break;
1073  default:
1074  return set_err(EINVAL);
1075  }
1076 
1077  // Build pass through command
1078  unsigned char cdb[14];
1079  cdb[ 0] = 0xdf;
1080  cdb[ 1] = (rwbit ? 0x10 : 0x00);
1081  cdb[ 2] = 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;
1091  // Prolific PL3507
1092  cdb[12] = 0x06;
1093  cdb[13] = 0x7b;
1094 
1095  io_hdr.cmnd = cdb;
1096  io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
1097 
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());
1102 
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]");
1108 
1109  switch (smart_status) {
1110  case 0xc2:
1111  out.out_regs.lba_high = 0xc2;
1112  out.out_regs.lba_mid = 0x4f;
1113  break;
1114  case 0x2c:
1115  out.out_regs.lba_high = 0x2c;
1116  out.out_regs.lba_mid = 0xf4;
1117  break;
1118  default:
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);
1121  }
1122  }
1123 
1124 #if 0 // Not needed for SMART STATUS, see also notes below
1125  else {
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)))
1131  return false;
1132 
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];
1140  }
1141 #endif
1142  }
1143 
1144  return true;
1145 }
1146 
1148  unsigned char * buf, unsigned short size)
1149 {
1150  unsigned char cdb[14];
1151  cdb[ 0] = 0xdf;
1152  cdb[ 1] = 0x10;
1153  cdb[ 2] = 0x00;
1154  cdb[ 3] = (unsigned char)(size >> 8);
1155  cdb[ 4] = (unsigned char)(size );
1156  cdb[ 5] = 0x00;
1157  cdb[ 6] = (unsigned char)(addr >> 8);
1158  cdb[ 7] = (unsigned char)(addr );
1159  cdb[ 8] = 0x00;
1160  cdb[ 9] = 0x00;
1161  cdb[10] = 0x00;
1162  cdb[11] = 0xfd;
1163  // Prolific PL3507
1164  cdb[12] = 0x06;
1165  cdb[13] = 0x7b;
1166 
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;
1172  io_hdr.cmnd = cdb;
1173  io_hdr.cmnd_len = sizeof(cdb);
1174  io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
1175 
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());
1180 
1181  return true;
1182 }
1183 
1184 
1185 /////////////////////////////////////////////////////////////////////////////
1186 
1187 /// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
1188 
1190 : public tunnelled_device<
1191  /*implements*/ ata_device,
1192  /*by tunnelling through a*/ scsi_device
1193  >
1194 {
1195 public:
1197  const char * req_type);
1198 
1199  virtual ~usbprolific_device() throw();
1200 
1201  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
1202 };
1203 
1204 
1206  const char * req_type)
1207 : smart_device(intf, scsidev->get_dev_name(), "usbprolific", req_type),
1209 {
1210  set_info().info_name = strprintf("%s [USB Prolific]", scsidev->get_info_name());
1211 }
1212 
1214 {
1215 }
1216 
1218 {
1219  if (!ata_cmd_is_supported(in,
1224  "Prolific" )
1225  )
1226  return false;
1227 
1228  scsi_cmnd_io io_hdr;
1229  memset(&io_hdr, 0, sizeof(io_hdr));
1230  unsigned char cmd_rw = 0x10; // Read
1231 
1232  switch (in.direction) {
1233  case ata_cmd_in::no_data:
1234  io_hdr.dxfer_dir = DXFER_NONE;
1235  break;
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);
1241  break;
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
1247  break;
1248  default:
1249  return set_err(EINVAL);
1250  }
1251 
1252  // Based on reverse engineering of iSmart.exe with API Monitor.
1253  // Seen commands:
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
1262 
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
1282 
1283  io_hdr.cmnd = cdb;
1284  io_hdr.cmnd_len = 16;
1285 
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());
1290 
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;
1298 
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)
1303  io_hdr.cmnd = cdb;
1304  io_hdr.cmnd_len = sizeof(cdb);
1305 
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());
1309 
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
1321  }
1322 
1323  return true;
1324 }
1325 
1326 
1327 /////////////////////////////////////////////////////////////////////////////
1328 
1329 /// SunplusIT USB Bridge support.
1330 
1332 : public tunnelled_device<
1333  /*implements*/ ata_device,
1334  /*by tunnelling through a*/ scsi_device
1335  >
1336 {
1337 public:
1338  usbsunplus_device(smart_interface * intf, scsi_device * scsidev,
1339  const char * req_type);
1340 
1341  virtual ~usbsunplus_device() throw();
1342 
1343  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
1344 };
1345 
1346 
1348  const char * req_type)
1349 : smart_device(intf, scsidev->get_dev_name(), "usbsunplus", req_type),
1351 {
1352  set_info().info_name = strprintf("%s [USB Sunplus]", scsidev->get_info_name());
1353 }
1354 
1356 {
1357 }
1358 
1360 {
1361  if (!ata_cmd_is_supported(in,
1365  "Sunplus")
1366  )
1367  return false;
1368 
1369  scsi_cmnd_io io_hdr;
1370  unsigned char cdb[12];
1371 
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;
1376 
1377  cdb[ 0] = 0xf8;
1378  cdb[ 1] = 0x00;
1379  cdb[ 2] = 0x23; // Subcommand: Pass through presetting
1380  cdb[ 3] = 0x00;
1381  cdb[ 4] = 0x00;
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;
1387  cdb[10] = 0x00;
1388  cdb[11] = 0x00;
1389 
1390  io_hdr.cmnd = cdb;
1391  io_hdr.cmnd_len = sizeof(cdb);
1392 
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());
1397  }
1398 
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;
1405  protocol = 0x00;
1406  break;
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);
1412  protocol = 0x10;
1413  break;
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;
1418  protocol = 0x11;
1419  break;
1420  default:
1421  return set_err(EINVAL);
1422  }
1423 
1424  cdb[ 0] = 0xf8;
1425  cdb[ 1] = 0x00;
1426  cdb[ 2] = 0x22; // Subcommand: Pass through
1427  cdb[ 3] = protocol;
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;
1436 
1437  io_hdr.cmnd = cdb;
1438  io_hdr.cmnd_len = sizeof(cdb);
1439 
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());
1445 
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;
1453 
1454  cdb[ 0] = 0xf8;
1455  cdb[ 1] = 0x00;
1456  cdb[ 2] = 0x21; // Subcommand: Get status
1457  memset(cdb+3, 0, sizeof(cdb)-3);
1458  io_hdr.cmnd = cdb;
1459  io_hdr.cmnd_len = sizeof(cdb);
1460 
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());
1464 
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];
1472  }
1473 
1474  return true;
1475 }
1476 
1477 
1478 } // namespace
1479 
1480 using namespace sat;
1481 
1482 
1483 /////////////////////////////////////////////////////////////////////////////
1484 
1485 // Return ATA->SCSI filter for SAT or USB.
1486 
1488 {
1489  if (!scsidev)
1490  throw std::logic_error("smart_interface: get_sat_device() called with scsidev=0");
1491 
1492  // Take temporary ownership of 'scsidev' to delete it on error
1493  scsi_device_auto_ptr scsidev_holder(scsidev);
1494  ata_device * satdev = 0;
1495 
1496  if (!strncmp(type, "sat", 3)) {
1497  const char * t = type + 3;
1498  bool enable_auto = false;
1499  if (!strncmp(t, ",auto", 5)) {
1500  t += 5;
1501  enable_auto = true;
1502  }
1503  int ptlen = 0, n = -1;
1504  if (*t && !(sscanf(t, ",%d%n", &ptlen, &n) == 1 && n == (int)strlen(t)
1505  && (ptlen == 0 || ptlen == 12 || ptlen == 16))) {
1506  set_err(EINVAL, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16");
1507  return 0;
1508  }
1509  satdev = new sat_device(this, scsidev, type, ptlen, enable_auto);
1510  }
1511 
1512  else if (!strncmp(type, "usbcypress", 10)) {
1513  unsigned signature = 0x24; int n1 = -1, n2 = -1;
1514  if (!(((sscanf(type, "usbcypress%n,0x%x%n", &n1, &signature, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type))
1515  && signature <= 0xff)) {
1516  set_err(EINVAL, "Option '-d usbcypress,<n>' requires <n> to be "
1517  "an hexadecimal number between 0x0 and 0xff");
1518  return 0;
1519  }
1520  satdev = new usbcypress_device(this, scsidev, type, signature);
1521  }
1522 
1523  else if (!strncmp(type, "usbjmicron", 10)) {
1524  const char * t = type + 10;
1525  bool prolific = false;
1526  if (!strncmp(t, ",p", 2)) {
1527  t += 2;
1528  prolific = true;
1529  }
1530  bool ata_48bit_support = false;
1531  if (!strncmp(t, ",x", 2)) {
1532  t += 2;
1533  ata_48bit_support = true;
1534  }
1535  int port = -1, n = -1;
1536  if (*t && !( (sscanf(t, ",%d%n", &port, &n) == 1
1537  && n == (int)strlen(t) && 0 <= port && port <= 1))) {
1538  set_err(EINVAL, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
1539  return 0;
1540  }
1541  satdev = new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
1542  }
1543 
1544  else if (!strcmp(type, "usbprolific")) {
1545  satdev = new usbprolific_device(this, scsidev, type);
1546  }
1547 
1548  else if (!strcmp(type, "usbsunplus")) {
1549  satdev = new usbsunplus_device(this, scsidev, type);
1550  }
1551 
1552  else {
1553  set_err(EINVAL, "Unknown USB device type '%s'", type);
1554  return 0;
1555  }
1556 
1557  // 'scsidev' is now owned by 'satdev'
1558  scsidev_holder.release();
1559  return satdev;
1560 }
1561 
1562 // Try to detect a SAT device behind a SCSI interface.
1563 
1565  const unsigned char * inqdata, unsigned inqsize)
1566 {
1567  if (!scsidev->is_open())
1568  return 0;
1569 
1570  // SAT ?
1571  if (inqdata && inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8)) { // TODO: Linux-specific?
1572  ata_device_auto_ptr atadev( new sat_device(this, scsidev, "") , scsidev);
1573  if (has_sat_pass_through(atadev.get()))
1574  return atadev.release(); // Detected SAT
1575  }
1576 
1577  return 0;
1578 }
1579 
1580 
1581 /////////////////////////////////////////////////////////////////////////////
1582 // USB device type detection
1583 
1584 // Format USB ID for error messages
1585 static std::string format_usb_id(int vendor_id, int product_id, int version)
1586 {
1587  if (version >= 0)
1588  return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id, product_id, version);
1589  else
1590  return strprintf("[0x%04x:0x%04x]", vendor_id, product_id);
1591 }
1592 
1593 // Get type name for USB device with known VENDOR:PRODUCT ID.
1594 const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
1595  int version /*= -1*/)
1596 {
1597  usb_dev_info info, info2;
1598  int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
1599 
1600  if (n <= 0) {
1601  set_err(EINVAL, "Unknown USB bridge %s",
1602  format_usb_id(vendor_id, product_id, version).c_str());
1603  return 0;
1604  }
1605 
1606  if (n > 1) {
1607  set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
1608  format_usb_id(vendor_id, product_id, version).c_str(),
1609  (!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"),
1610  (!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
1611  return 0;
1612  }
1613 
1614  if (info.usb_type.empty()) {
1615  set_err(ENOSYS, "Unsupported USB bridge %s",
1616  format_usb_id(vendor_id, product_id, version).c_str());
1617  return 0;
1618  }
1619 
1620  // TODO: change return type to std::string
1621  static std::string type;
1622  type = info.usb_type;
1623  return type.c_str();
1624 }
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:100
Error (number,message) pair.
Definition: dev_interface.h:59
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:101
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:1564
void scsi_do_sense_disect(const struct scsi_cmnd_io *io_buf, struct scsi_sense_disect *out)
Definition: scsicmds.cpp:194
u16 s[6]
Definition: megaraid.h:97
ata_out_regs_flags out_needed
True if output register value needed.
bool m_enable_auto
Definition: scsiata.cpp:128
u32 size
Definition: megaraid.h:79
std::string msg
Error message.
Definition: dev_interface.h:68
#define SAT_ATA_PASSTHROUGH_12
Definition: scsicmds.h:99
#define SCSI_STATUS_CHECK_CONDITION
Definition: scsicmds.h:258
const char * get_dev_type() const
Get device type.
UINT8 * sensep
Definition: scsicmds.h:122
#define SCSI_ASCQ_ATA_PASS_THROUGH
Definition: scsicmds.h:279
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:1487
ata_in_regs prev
"previous content"
ata_register error
#define ATA_SMART_CMD
Definition: atacmds.h:75
ata_register lba_mid
#define SCSI_SK_RECOVERED_ERR
Definition: scsicmds.h:262
int get_errno() const
Get last error number.
#define DXFER_FROM_DEVICE
Definition: scsicmds.h:111
virtual bool open()=0
Open device, return false on error.
virtual bool scsi_pass_through(scsi_cmnd_io *iop)=0
SCSI pass through.
Smart pointer class for device pointers.
void hide_scsi(bool hide=true)
Hide/unhide SCSI interface.
virtual smart_device * autodetect_open()
Open device with autodetection support.
Definition: scsiata.cpp:510
ata_register device
virtual bool close()=0
Close device, return false on error.
Cypress USB Brigde support.
Definition: scsiata.cpp:639
ata_register sector_count
unsigned timeout
Definition: scsicmds.h:125
int lookup_usb_device(int vendor_id, int product_id, int bcd_device, usb_dev_info &info, usb_dev_info &info2)
#define ATA_SMART_DISABLE
Definition: atacmds.h:104
Adapter class to implement new ATA pass through old interface.
ATA Input registers (for 28-bit commands)
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:97
virtual int ata_command_interface(smart_command_set command, int select, char *data)
Old ATA interface called by ata_pass_through()
Definition: scsiata.cpp:674
device_info & set_info()
R/W access to device info struct.
unsigned char byte6
Definition: scsiata.cpp:81
#define ATA_RETURN_DESCRIPTOR
Definition: scsiata.cpp:99
void * buffer
Pointer to data buffer.
size_t resp_sense_len
Definition: scsicmds.h:126
usbcypress_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, unsigned char signature)
Definition: scsiata.cpp:658
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: scsiata.cpp:1030
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:72
ata_register lba_mid
int scsiSimpleSenseFilter(const struct scsi_sense_disect *sinfo)
Definition: scsicmds.cpp:216
#define ATA_IDENTIFY_PACKET_DEVICE
Definition: atacmds.h:73
usbsunplus_device(smart_interface *intf, scsi_device *scsidev, const char *req_type)
Definition: scsiata.cpp:1347
bool ata_cmd_is_supported(const ata_cmd_in &in, unsigned flags, const char *type=0)
Check command input parameters.
ata_in_regs_48bit in_regs
Input registers.
UINT8 * dxferp
Definition: scsicmds.h:120
Definition: scsiata.cpp:102
ata_out_regs_48bit out_regs
Output registers.
std::string dev_type
Actual device type.
Definition: dev_interface.h:54
UINT8 * cmnd
Definition: scsicmds.h:116
int smart_status(int fd)
unsigned char byte5
Definition: scsiata.cpp:80
ptr_t data
Definition: megaraid.h:94
enum ata_cmd_in::@27 direction
I/O direction.
void set_data_in(void *buf, unsigned nsectors)
Prepare for 28-bit DATA IN command.
device_type * release()
Return the pointer and release ownership.
#define ATA_CHECK_POWER_MODE
Definition: atacmds.h:71
device_type * get() const
Return the pointer.
virtual bool is_open() const =0
Return true if device is open.
usbprolific_device(smart_interface *intf, scsi_device *scsidev, const char *req_type)
Definition: scsiata.cpp:1205
ata_out_regs prev
read with HOB=1
u8 cdb[16]
Definition: megaraid.h:100
The platform interface abstraction.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)=0
ATA pass through.
unsigned char byte4
Definition: scsiata.cpp:79
virtual bool scsi_pass_through(scsi_cmnd_io *iop)
SCSI pass through.
Definition: scsiata.cpp:500
void syserror(const char *message)
Definition: utility.cpp:360
virtual ~usbprolific_device()
Definition: scsiata.cpp:1213
Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
Definition: scsiata.cpp:1189
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: scsiata.cpp:1359
const char * get_errmsg() const
Get last error message.
#define SAT_ATA_PASSTHROUGH_16
Definition: scsicmds.h:102
std::string usb_type
Definition: knowndrives.h:38
unsigned char sense_key
Definition: scsiata.cpp:76
void dStrHex(const char *str, int len, int no_ascii)
Definition: scsicmds.cpp:87
uint32_t outlen
Definition: megaraid.h:80
SunplusIT USB Bridge support.
Definition: scsiata.cpp:1331
unsigned char scsi_debugmode
Definition: scsicmds.cpp:54
#define SAT_ATA_PASSTHROUGH_16LEN
Definition: scsiata.cpp:96
void pout(const char *fmt,...)
Definition: smartctl.cpp:1170
size_t max_sense_len
Definition: scsicmds.h:124
unsigned char additional_length
Definition: scsiata.cpp:82
struct megasas_pd_address addr[MAX_SYS_PDS]
Definition: megaraid.h:81
usbjmicron_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, bool prolific, bool ata_48bit_support, int port)
Definition: scsiata.cpp:982
ata_register status
int dxfer_dir
Definition: scsicmds.h:118
#define USBCYPRESS_PASSTHROUGH_LEN
Definition: scsiata.cpp:673
#define ATA_SMART_READ_VALUES
Definition: atacmds.h:95
bool is_set() const
Return true if any flag is set.
unsigned size
Size of buffer.
ata_register lba_low
SCSI device access.
Implement a device by tunneling through another device.
Definition: dev_tunnelled.h:60
Definition: atacmds.h:55
ata_register features
static int sg_scsi_normalize_sense(const unsigned char *sensep, int sb_len, struct sg_scsi_sense_hdr *sshp)
Definition: scsiata.cpp:565
#define DXFER_NONE
Definition: scsicmds.h:110
void hide_ata(bool hide=true)
Hide/unhide ATA interface.
#define ATA_SMART_AUTO_OFFLINE
Definition: atacmds.h:108
JMicron USB Bridge support.
Definition: scsiata.cpp:956
Abridged SCSI sense data.
Definition: scsiata.cpp:74
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: scsiata.cpp:1217
smart_command_set
Definition: atacmds.h:48
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: scsiata.cpp:248
unsigned char ascq
Definition: scsiata.cpp:78
#define DXFER_TO_DEVICE
Definition: scsicmds.h:112
#define ATA_SMART_READ_THRESHOLDS
Definition: atacmds.h:96
bool is_48bit_cmd() const
Return true if 48-bit command.
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:1594
SAT support.
Definition: scsiata.cpp:107
ata_register device
Base class for all devices.
Definition: dev_interface.h:39
virtual ~sat_device()
Definition: scsiata.cpp:151
ata_register lba_high
int no
Error number.
Definition: dev_interface.h:67
unsigned char m_signature
Definition: scsiata.cpp:654
size_t cmnd_len
Definition: scsicmds.h:117
ATA device access.
ata_register sector_count
#define ATA_SMART_IMMEDIATE_OFFLINE
Definition: atacmds.h:99
unsigned char asc
Definition: scsiata.cpp:77
virtual ~usbsunplus_device()
Definition: scsiata.cpp:1355
static bool has_sat_pass_through(ata_device *dev, bool packet_interface=false)
Definition: scsiata.cpp:547
#define DEF_SAT_ATA_PASSTHRU_SIZE
Definition: scsiata.cpp:98
#define SAT_ATA_PASSTHROUGH_12LEN
Definition: scsiata.cpp:95
ata_register command
virtual bool close()
Close device, return false on error.
UINT8 scsi_status
Definition: scsicmds.h:127
unsigned char response_code
Definition: scsiata.cpp:75
ATA pass through input parameters.
#define ATA_SMART_ENABLE
Definition: atacmds.h:103
int scsiStdInquiry(scsi_device *device, UINT8 *pBuf, int bufLen)
Definition: scsicmds.cpp:774
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:750
ata_register lba_low
unsigned char model[40]
Definition: atacmds.h:134
const unsigned char * sg_scsi_sense_desc_find(const unsigned char *sensep, int sense_len, int desc_type)
Definition: scsicmds.cpp:2667
#define SCSI_SK_NO_SENSE
Definition: scsicmds.h:261
ata_register lba_high
static std::string format_usb_id(int vendor_id, int product_id, int version)
Definition: scsiata.cpp:1585
size_t dxfer_len
Definition: scsicmds.h:121
sat_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, int passthrulen=0, bool enable_auto=false)
Definition: scsiata.cpp:132
const error_info & get_err() const
Get last error info struct.
Definition: atacmds.h:50
std::string info_name
Informal name.
Definition: dev_interface.h:53
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
ATA Output registers (for 28-bit commands)
virtual ~usbcypress_device()
Definition: scsiata.cpp:667
virtual bool open()
Open device, return false on error.
Definition: scsiata.cpp:998
ATA pass through output parameters.
static bool scsi_pass_through_and_check(scsi_device *scsidev, scsi_cmnd_io *iop, const char *msg="")
Definition: scsiata.cpp:602
const char * scsiErrString(int scsiErr)
Definition: scsicmds.cpp:254
#define SCSI_TIMEOUT_DEFAULT
Definition: scsicmds.h:307
virtual ~usbjmicron_device()
Definition: scsiata.cpp:993
const char * get_info_name() const
Get informal name.
bool get_registers(unsigned short addr, unsigned char *buf, unsigned short size)
Definition: scsiata.cpp:1147
const char * scsiata_cpp_cvsid
Definition: scsiata.cpp:65
#define ATA_SMART_STATUS
Definition: atacmds.h:105