smartmontools  SVN Rev 4430
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-17 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 4386 2017-01-28 16:35:06Z 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 = (!m_prolific ? 12 : 14);
1174 
1175  scsi_device * scsidev = get_tunnel_dev();
1176  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1177  "usbjmicron_device::get_registers: "))
1178  return set_err(scsidev->get_err());
1179 
1180  return true;
1181 }
1182 
1183 
1184 /////////////////////////////////////////////////////////////////////////////
1185 
1186 /// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
1187 
1189 : public tunnelled_device<
1190  /*implements*/ ata_device,
1191  /*by tunnelling through a*/ scsi_device
1192  >
1193 {
1194 public:
1196  const char * req_type);
1197 
1198  virtual ~usbprolific_device() throw();
1199 
1200  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
1201 };
1202 
1203 
1205  const char * req_type)
1206 : smart_device(intf, scsidev->get_dev_name(), "usbprolific", req_type),
1208 {
1209  set_info().info_name = strprintf("%s [USB Prolific]", scsidev->get_info_name());
1210 }
1211 
1213 {
1214 }
1215 
1217 {
1218  if (!ata_cmd_is_supported(in,
1223  "Prolific" )
1224  )
1225  return false;
1226 
1227  scsi_cmnd_io io_hdr;
1228  memset(&io_hdr, 0, sizeof(io_hdr));
1229  unsigned char cmd_rw = 0x10; // Read
1230 
1231  switch (in.direction) {
1232  case ata_cmd_in::no_data:
1233  io_hdr.dxfer_dir = DXFER_NONE;
1234  break;
1235  case ata_cmd_in::data_in:
1236  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1237  io_hdr.dxfer_len = in.size;
1238  io_hdr.dxferp = (unsigned char *)in.buffer;
1239  memset(in.buffer, 0, in.size);
1240  break;
1241  case ata_cmd_in::data_out:
1242  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1243  io_hdr.dxfer_len = in.size;
1244  io_hdr.dxferp = (unsigned char *)in.buffer;
1245  cmd_rw = 0x0; // Write
1246  break;
1247  default:
1248  return set_err(EINVAL);
1249  }
1250 
1251  // Based on reverse engineering of iSmart.exe with API Monitor.
1252  // Seen commands:
1253  // D0 0 0 0 06 7B 0 0 0 0 0 0 // Read Firmware info?, reads 16 bytes
1254  // F4 0 0 0 06 7B // ??
1255  // D8 15 0 D8 06 7B 0 0 0 0 1 1 4F C2 A0 B0 // SMART Enable
1256  // D8 15 0 D0 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read values
1257  // D8 15 0 D1 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read thresholds
1258  // D8 15 0 D4 06 7B 0 0 0 0 0 1 4F C2 A0 B0 // SMART Execute self test
1259  // D7 0 0 0 06 7B 0 0 0 0 0 0 0 0 0 0 // Read status registers, Reads 16 bytes of data
1260  // Additional DATA OUT support based on document from Prolific
1261 
1262  // Build pass through command
1263  unsigned char cdb[16];
1264  cdb[ 0] = 0xD8; // Operation Code (D8 = Prolific ATA pass through)
1265  cdb[ 1] = cmd_rw|0x5; // Read(0x10)/Write(0x0) | NORMAL(0x5)/PREFIX(0x0)(?)
1266  cdb[ 2] = 0x0; // Reserved
1267  cdb[ 3] = in.in_regs.features; // Feature register (SMART command)
1268  cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1269  cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1270  cdb[ 6] = (unsigned char)(io_hdr.dxfer_len >> 24); // Length MSB
1271  cdb[ 7] = (unsigned char)(io_hdr.dxfer_len >> 16); // Length ...
1272  cdb[ 8] = (unsigned char)(io_hdr.dxfer_len >> 8); // Length ...
1273  cdb[ 9] = (unsigned char)(io_hdr.dxfer_len ); // Length LSB
1274  cdb[10] = in.in_regs.sector_count; // Sector Count
1275  cdb[11] = in.in_regs.lba_low; // LBA Low (7:0)
1276  cdb[12] = in.in_regs.lba_mid; // LBA Mid (15:8)
1277  cdb[13] = in.in_regs.lba_high; // LBA High (23:16)
1278  cdb[14] = in.in_regs.device | 0xA0; // Device/Head
1279  cdb[15] = in.in_regs.command; // ATA Command Register (only PIO supported)
1280  // Use '-r scsiioctl,1' to print CDB for debug purposes
1281 
1282  io_hdr.cmnd = cdb;
1283  io_hdr.cmnd_len = 16;
1284 
1285  scsi_device * scsidev = get_tunnel_dev();
1286  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1287  "usbprolific_device::ata_pass_through: "))
1288  return set_err(scsidev->get_err());
1289 
1290  if (in.out_needed.is_set()) {
1291  // Read ATA output registers
1292  unsigned char regbuf[16] = {0, };
1293  memset(&io_hdr, 0, sizeof(io_hdr));
1294  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1295  io_hdr.dxfer_len = sizeof(regbuf);
1296  io_hdr.dxferp = regbuf;
1297 
1298  memset(cdb, 0, sizeof(cdb));
1299  cdb[ 0] = 0xD7; // Prolific read registers
1300  cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1301  cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1302  io_hdr.cmnd = cdb;
1303  io_hdr.cmnd_len = sizeof(cdb);
1304 
1305  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1306  "usbprolific_device::scsi_pass_through (get registers): "))
1307  return set_err(scsidev->get_err());
1308 
1309  // Use '-r scsiioctl,2' to print input registers for debug purposes
1310  // Example: 50 00 00 00 00 01 4f 00 c2 00 a0 da 00 b0 00 50
1311  out.out_regs.status = regbuf[0]; // Status
1312  out.out_regs.error = regbuf[1]; // Error
1313  out.out_regs.sector_count = regbuf[2]; // Sector Count (7:0)
1314  out.out_regs.lba_low = regbuf[4]; // LBA Low (7:0)
1315  out.out_regs.lba_mid = regbuf[6]; // LBA Mid (7:0)
1316  out.out_regs.lba_high = regbuf[8]; // LBA High (7:0)
1317  out.out_regs.device = regbuf[10]; // Device/Head
1318  // = regbuf[11]; // ATA Feature (7:0)
1319  // = regbuf[13]; // ATA Command
1320  }
1321 
1322  return true;
1323 }
1324 
1325 
1326 /////////////////////////////////////////////////////////////////////////////
1327 
1328 /// SunplusIT USB Bridge support.
1329 
1331 : public tunnelled_device<
1332  /*implements*/ ata_device,
1333  /*by tunnelling through a*/ scsi_device
1334  >
1335 {
1336 public:
1337  usbsunplus_device(smart_interface * intf, scsi_device * scsidev,
1338  const char * req_type);
1339 
1340  virtual ~usbsunplus_device() throw();
1341 
1342  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
1343 };
1344 
1345 
1347  const char * req_type)
1348 : smart_device(intf, scsidev->get_dev_name(), "usbsunplus", req_type),
1350 {
1351  set_info().info_name = strprintf("%s [USB Sunplus]", scsidev->get_info_name());
1352 }
1353 
1355 {
1356 }
1357 
1359 {
1360  if (!ata_cmd_is_supported(in,
1364  "Sunplus")
1365  )
1366  return false;
1367 
1368  scsi_cmnd_io io_hdr;
1369  unsigned char cdb[12];
1370 
1371  if (in.in_regs.is_48bit_cmd()) {
1372  // Set "previous" registers
1373  memset(&io_hdr, 0, sizeof(io_hdr));
1374  io_hdr.dxfer_dir = DXFER_NONE;
1375 
1376  cdb[ 0] = 0xf8;
1377  cdb[ 1] = 0x00;
1378  cdb[ 2] = 0x23; // Subcommand: Pass through presetting
1379  cdb[ 3] = 0x00;
1380  cdb[ 4] = 0x00;
1381  cdb[ 5] = in.in_regs.prev.features;
1382  cdb[ 6] = in.in_regs.prev.sector_count;
1383  cdb[ 7] = in.in_regs.prev.lba_low;
1384  cdb[ 8] = in.in_regs.prev.lba_mid;
1385  cdb[ 9] = in.in_regs.prev.lba_high;
1386  cdb[10] = 0x00;
1387  cdb[11] = 0x00;
1388 
1389  io_hdr.cmnd = cdb;
1390  io_hdr.cmnd_len = sizeof(cdb);
1391 
1392  scsi_device * scsidev = get_tunnel_dev();
1393  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1394  "usbsunplus_device::scsi_pass_through (presetting): "))
1395  return set_err(scsidev->get_err());
1396  }
1397 
1398  // Run Pass through command
1399  memset(&io_hdr, 0, sizeof(io_hdr));
1400  unsigned char protocol;
1401  switch (in.direction) {
1402  case ata_cmd_in::no_data:
1403  io_hdr.dxfer_dir = DXFER_NONE;
1404  protocol = 0x00;
1405  break;
1406  case ata_cmd_in::data_in:
1407  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1408  io_hdr.dxfer_len = in.size;
1409  io_hdr.dxferp = (unsigned char *)in.buffer;
1410  memset(in.buffer, 0, in.size);
1411  protocol = 0x10;
1412  break;
1413  case ata_cmd_in::data_out:
1414  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1415  io_hdr.dxfer_len = in.size;
1416  io_hdr.dxferp = (unsigned char *)in.buffer;
1417  protocol = 0x11;
1418  break;
1419  default:
1420  return set_err(EINVAL);
1421  }
1422 
1423  cdb[ 0] = 0xf8;
1424  cdb[ 1] = 0x00;
1425  cdb[ 2] = 0x22; // Subcommand: Pass through
1426  cdb[ 3] = protocol;
1427  cdb[ 4] = (unsigned char)(io_hdr.dxfer_len >> 9);
1428  cdb[ 5] = in.in_regs.features;
1429  cdb[ 6] = in.in_regs.sector_count;
1430  cdb[ 7] = in.in_regs.lba_low;
1431  cdb[ 8] = in.in_regs.lba_mid;
1432  cdb[ 9] = in.in_regs.lba_high;
1433  cdb[10] = in.in_regs.device | 0xa0;
1434  cdb[11] = in.in_regs.command;
1435 
1436  io_hdr.cmnd = cdb;
1437  io_hdr.cmnd_len = sizeof(cdb);
1438 
1439  scsi_device * scsidev = get_tunnel_dev();
1440  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1441  "usbsunplus_device::scsi_pass_through: "))
1442  // Returns sense key 0x03 (medium error) on ATA command error
1443  return set_err(scsidev->get_err());
1444 
1445  if (in.out_needed.is_set()) {
1446  // Read ATA output registers
1447  unsigned char regbuf[8] = {0, };
1448  memset(&io_hdr, 0, sizeof(io_hdr));
1449  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1450  io_hdr.dxfer_len = sizeof(regbuf);
1451  io_hdr.dxferp = regbuf;
1452 
1453  cdb[ 0] = 0xf8;
1454  cdb[ 1] = 0x00;
1455  cdb[ 2] = 0x21; // Subcommand: Get status
1456  memset(cdb+3, 0, sizeof(cdb)-3);
1457  io_hdr.cmnd = cdb;
1458  io_hdr.cmnd_len = sizeof(cdb);
1459 
1460  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1461  "usbsunplus_device::scsi_pass_through (get registers): "))
1462  return set_err(scsidev->get_err());
1463 
1464  out.out_regs.error = regbuf[1];
1465  out.out_regs.sector_count = regbuf[2];
1466  out.out_regs.lba_low = regbuf[3];
1467  out.out_regs.lba_mid = regbuf[4];
1468  out.out_regs.lba_high = regbuf[5];
1469  out.out_regs.device = regbuf[6];
1470  out.out_regs.status = regbuf[7];
1471  }
1472 
1473  return true;
1474 }
1475 
1476 
1477 } // namespace
1478 
1479 using namespace sat;
1480 
1481 
1482 /////////////////////////////////////////////////////////////////////////////
1483 
1484 // Return ATA->SCSI filter for SAT or USB.
1485 
1487 {
1488  if (!scsidev)
1489  throw std::logic_error("smart_interface: get_sat_device() called with scsidev=0");
1490 
1491  // Take temporary ownership of 'scsidev' to delete it on error
1492  scsi_device_auto_ptr scsidev_holder(scsidev);
1493  ata_device * satdev = 0;
1494 
1495  if (!strncmp(type, "sat", 3)) {
1496  const char * t = type + 3;
1497  bool enable_auto = false;
1498  if (!strncmp(t, ",auto", 5)) {
1499  t += 5;
1500  enable_auto = true;
1501  }
1502  int ptlen = 0, n = -1;
1503  if (*t && !(sscanf(t, ",%d%n", &ptlen, &n) == 1 && n == (int)strlen(t)
1504  && (ptlen == 0 || ptlen == 12 || ptlen == 16))) {
1505  set_err(EINVAL, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16");
1506  return 0;
1507  }
1508  satdev = new sat_device(this, scsidev, type, ptlen, enable_auto);
1509  }
1510 
1511  else if (!strncmp(type, "usbcypress", 10)) {
1512  unsigned signature = 0x24; int n1 = -1, n2 = -1;
1513  if (!(((sscanf(type, "usbcypress%n,0x%x%n", &n1, &signature, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type))
1514  && signature <= 0xff)) {
1515  set_err(EINVAL, "Option '-d usbcypress,<n>' requires <n> to be "
1516  "an hexadecimal number between 0x0 and 0xff");
1517  return 0;
1518  }
1519  satdev = new usbcypress_device(this, scsidev, type, signature);
1520  }
1521 
1522  else if (!strncmp(type, "usbjmicron", 10)) {
1523  const char * t = type + 10;
1524  bool prolific = false;
1525  if (!strncmp(t, ",p", 2)) {
1526  t += 2;
1527  prolific = true;
1528  }
1529  bool ata_48bit_support = false;
1530  if (!strncmp(t, ",x", 2)) {
1531  t += 2;
1532  ata_48bit_support = true;
1533  }
1534  int port = -1, n = -1;
1535  if (*t && !( (sscanf(t, ",%d%n", &port, &n) == 1
1536  && n == (int)strlen(t) && 0 <= port && port <= 1))) {
1537  set_err(EINVAL, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
1538  return 0;
1539  }
1540  satdev = new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
1541  }
1542 
1543  else if (!strcmp(type, "usbprolific")) {
1544  satdev = new usbprolific_device(this, scsidev, type);
1545  }
1546 
1547  else if (!strcmp(type, "usbsunplus")) {
1548  satdev = new usbsunplus_device(this, scsidev, type);
1549  }
1550 
1551  else {
1552  set_err(EINVAL, "Unknown USB device type '%s'", type);
1553  return 0;
1554  }
1555 
1556  // 'scsidev' is now owned by 'satdev'
1557  scsidev_holder.release();
1558  return satdev;
1559 }
1560 
1561 // Try to detect a SAT device behind a SCSI interface.
1562 
1564  const unsigned char * inqdata, unsigned inqsize)
1565 {
1566  if (!scsidev->is_open())
1567  return 0;
1568 
1569  // SAT ?
1570  if (inqdata && inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8)) { // TODO: Linux-specific?
1571  ata_device_auto_ptr atadev( new sat_device(this, scsidev, "") , scsidev);
1572  if (has_sat_pass_through(atadev.get()))
1573  return atadev.release(); // Detected SAT
1574  }
1575 
1576  return 0;
1577 }
1578 
1579 
1580 /////////////////////////////////////////////////////////////////////////////
1581 // USB device type detection
1582 
1583 // Format USB ID for error messages
1584 static std::string format_usb_id(int vendor_id, int product_id, int version)
1585 {
1586  if (version >= 0)
1587  return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id, product_id, version);
1588  else
1589  return strprintf("[0x%04x:0x%04x]", vendor_id, product_id);
1590 }
1591 
1592 // Get type name for USB device with known VENDOR:PRODUCT ID.
1593 const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
1594  int version /*= -1*/)
1595 {
1596  usb_dev_info info, info2;
1597  int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
1598 
1599  if (n <= 0) {
1600  set_err(EINVAL, "Unknown USB bridge %s",
1601  format_usb_id(vendor_id, product_id, version).c_str());
1602  return 0;
1603  }
1604 
1605  if (n > 1) {
1606  set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
1607  format_usb_id(vendor_id, product_id, version).c_str(),
1608  (!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"),
1609  (!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
1610  return 0;
1611  }
1612 
1613  if (info.usb_type.empty()) {
1614  set_err(ENOSYS, "Unsupported USB bridge %s",
1615  format_usb_id(vendor_id, product_id, version).c_str());
1616  return 0;
1617  }
1618 
1619  // TODO: change return type to std::string
1620  static std::string type;
1621  type = info.usb_type;
1622  return type.c_str();
1623 }
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:105
Error (number,message) pair.
Definition: dev_interface.h:59
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:106
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:1563
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:1486
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:109
Adapter class to implement new ATA pass through old interface.
ATA Input registers (for 28-bit commands)
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:102
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:1346
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
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:1204
ata_out_regs prev
read with HOB=1
u8 cdb[16]
Definition: megaraid.h:100
enum ata_cmd_in::@29 direction
I/O direction.
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:1212
Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
Definition: scsiata.cpp:1188
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: scsiata.cpp:1358
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:1330
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:1196
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:100
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:113
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:1216
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:101
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:1593
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:104
unsigned char asc
Definition: scsiata.cpp:77
virtual ~usbsunplus_device()
Definition: scsiata.cpp:1354
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:108
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:139
const unsigned char * sg_scsi_sense_desc_find(const unsigned char *sensep, int sense_len, int desc_type)
Definition: scsicmds.cpp:2666
#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:1584
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:110