smartmontools  SVN Rev 4071
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://smartmontools.sourceforge.net
5  *
6  * Copyright (C) 2006-12 Douglas Gilbert <dgilbert@interlog.com>
7  * Copyright (C) 2009-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
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 4041 2015-03-14 00:50:20Z dpgilbert $";
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  if (0 != status) { /* other than no_sense and recovered_error */
398  if (scsi_debugmode > 0) {
399  pout("sat_device::ata_pass_through: scsi error: %s\n",
400  scsiErrString(status));
401  if (ardp && (scsi_debugmode > 1)) {
402  pout("Values from ATA Return Descriptor are:\n");
403  dStrHex((const char *)ardp, ard_len, 1);
404  }
405  }
406  if (t_dir && (t_length > 0) && (in.direction == ata_cmd_in::data_in))
407  memset(in.buffer, 0, in.size);
408  return set_err(EIO, "scsi error %s", scsiErrString(status));
409  }
410  }
411  if (ck_cond) { /* expecting SAT specific sense data */
412  if (have_sense) {
413  if (ardp) {
414  if (scsi_debugmode > 1) {
415  pout("Values from ATA Return Descriptor are:\n");
416  dStrHex((const char *)ardp, ard_len, 1);
417  }
418  // Set output registers
419  ata_out_regs & lo = out.out_regs;
420  lo.error = ardp[ 3];
421  lo.sector_count = ardp[ 5];
422  lo.lba_low = ardp[ 7];
423  lo.lba_mid = ardp[ 9];
424  lo.lba_high = ardp[11];
425  lo.device = ardp[12];
426  lo.status = ardp[13];
427  if (in.in_regs.is_48bit_cmd()) {
428  ata_out_regs & hi = out.out_regs.prev;
429  hi.sector_count = ardp[ 4];
430  hi.lba_low = ardp[ 6];
431  hi.lba_mid = ardp[ 8];
432  hi.lba_high = ardp[10];
433  }
434  } else if ((! sense_descriptor) &&
435  (0 == ssh.asc) &&
436  (SCSI_ASCQ_ATA_PASS_THROUGH == ssh.ascq)) {
437  /* in SAT-2 and later, ATA registers may be passed back via
438  * fixed format sense data [ref: sat3r07 section 12.2.2.7] */
439  ata_out_regs & lo = out.out_regs;
440  lo.error = io_hdr.sensep[ 3];
441  lo.status = io_hdr.sensep[ 4];
442  lo.device = io_hdr.sensep[ 5];
443  lo.sector_count = io_hdr.sensep[ 6];
444  lo.lba_low = io_hdr.sensep[ 9];
445  lo.lba_mid = io_hdr.sensep[10];
446  lo.lba_high = io_hdr.sensep[11];
447  if (in.in_regs.is_48bit_cmd()) {
448  if (0 == (0x60 & io_hdr.sensep[8])) {
449  ata_out_regs & hi = out.out_regs.prev;
450  hi.sector_count = 0;
451  hi.lba_low = 0;
452  hi.lba_mid = 0;
453  hi.lba_high = 0;
454  } else {
455  /* getting the "hi." values when either
456  * count_upper_nonzero or lba_upper_nonzero are set
457  * involves fetching the SCSI ATA PASS-THROUGH
458  * Results log page and decoding the descriptor with
459  * the matching log_index field. Painful. */
460  }
461  }
462  }
463  }
464  } else { /* ck_cond == 0 */
465  if (have_sense) {
466  if (((SCSI_SK_NO_SENSE == ssh.sense_key) ||
467  (SCSI_SK_RECOVERED_ERR == ssh.sense_key)) &&
468  (0 == ssh.asc) &&
469  (SCSI_ASCQ_ATA_PASS_THROUGH == ssh.ascq)) {
470  if (scsi_debugmode > 0) {
471  if (sense_descriptor && ardp) {
472  pout("Values from ATA Return Descriptor are:\n");
473  dStrHex((const char *)ardp, ard_len, 1);
474  } else if (! sense_descriptor) {
475  pout("Values from ATA fixed format sense are:\n");
476  pout(" Error: 0x%x\n", io_hdr.sensep[3]);
477  pout(" Status: 0x%x\n", io_hdr.sensep[4]);
478  pout(" Device: 0x%x\n", io_hdr.sensep[5]);
479  pout(" Count: 0x%x\n", io_hdr.sensep[6]);
480  }
481  }
482  }
483  return set_err(EIO, "SAT command failed");
484  }
485  }
486  return true;
487 }
488 
490 {
491  scsi_device * scsidev = get_tunnel_dev();
492  if (!scsidev->scsi_pass_through(iop)) {
493  set_err(scsidev->get_err());
494  return false;
495  }
496  return true;
497 }
498 
500 {
501  if (!open() || !m_enable_auto)
502  return this;
503 
504  scsi_device * scsidev = get_tunnel_dev();
505 
506  unsigned char inqdata[36] = {0, };
507  if (scsiStdInquiry(scsidev, inqdata, sizeof(inqdata))) {
508  smart_device::error_info err = scsidev->get_err();
509  close();
510  set_err(err.no, "INQUIRY [SAT]: %s", err.msg.c_str());
511  return this;
512  }
513 
514  // Check for SAT "VENDOR"
515  int inqsize = inqdata[4] + 5;
516  bool sat = (inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8));
517 
518  // Change interface
519  hide_ata(!sat);
520  hide_scsi(sat);
521 
522  set_info().dev_type = (sat ? "sat" : scsidev->get_dev_type());
523  set_info().info_name = strprintf("%s [%s]", scsidev->get_info_name(),
524  (sat ? "SAT" : "SCSI"));
525  return this;
526 }
527 
528 } // namespace
529 
530 /////////////////////////////////////////////////////////////////////////////
531 
532 /* Attempt an IDENTIFY DEVICE ATA command via SATL when packet_interface
533  is false otherwise attempt IDENTIFY PACKET DEVICE. If successful
534  return true, else false */
535 
536 static bool has_sat_pass_through(ata_device * dev, bool packet_interface = false)
537 {
538  /* Note: malloc() ensures the read buffer lands on a single
539  page. This avoids some bugs seen on LSI controlers under
540  FreeBSD */
541  char *data = (char *)malloc(512);
542  ata_cmd_in in;
544  in.set_data_in(data, 1);
545  bool ret = dev->ata_pass_through(in);
546  free(data);
547  return ret;
548 }
549 
550 /////////////////////////////////////////////////////////////////////////////
551 
552 /* Next two functions are borrowed from sg_lib.c in the sg3_utils
553  package. Same copyrght owner, same license as this file. */
554 static int sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len,
555  struct sg_scsi_sense_hdr * sshp)
556 {
557  if (sshp)
558  memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr));
559  if ((NULL == sensep) || (0 == sb_len) || (0x70 != (0x70 & sensep[0])))
560  return 0;
561  if (sshp) {
562  sshp->response_code = (0x7f & sensep[0]);
563  if (sshp->response_code >= 0x72) { /* descriptor format */
564  if (sb_len > 1)
565  sshp->sense_key = (0xf & sensep[1]);
566  if (sb_len > 2)
567  sshp->asc = sensep[2];
568  if (sb_len > 3)
569  sshp->ascq = sensep[3];
570  if (sb_len > 7)
571  sshp->additional_length = sensep[7];
572  } else { /* fixed format */
573  if (sb_len > 2)
574  sshp->sense_key = (0xf & sensep[2]);
575  if (sb_len > 7) {
576  sb_len = (sb_len < (sensep[7] + 8)) ? sb_len :
577  (sensep[7] + 8);
578  if (sb_len > 12)
579  sshp->asc = sensep[12];
580  if (sb_len > 13)
581  sshp->ascq = sensep[13];
582  }
583  }
584  }
585  return 1;
586 }
587 
588 
589 // Call scsi_pass_through and check sense.
590 // TODO: Provide as member function of class scsi_device (?)
592  const char * msg = "")
593 {
594  // Provide sense buffer
595  unsigned char sense[32] = {0, };
596  iop->sensep = sense;
597  iop->max_sense_len = sizeof(sense);
599 
600  // Run cmd
601  if (!scsidev->scsi_pass_through(iop)) {
602  if (scsi_debugmode > 0)
603  pout("%sscsi_pass_through() failed, errno=%d [%s]\n",
604  msg, scsidev->get_errno(), scsidev->get_errmsg());
605  return false;
606  }
607 
608  // Check sense
609  scsi_sense_disect sinfo;
610  scsi_do_sense_disect(iop, &sinfo);
611  int err = scsiSimpleSenseFilter(&sinfo);
612  if (err) {
613  if (scsi_debugmode > 0)
614  pout("%sscsi error: %s\n", msg, scsiErrString(err));
615  return scsidev->set_err(EIO, "scsi error %s", scsiErrString(err));
616  }
617 
618  return true;
619 }
620 
621 
622 /////////////////////////////////////////////////////////////////////////////
623 
624 namespace sat {
625 
626 /// Cypress USB Brigde support.
627 
629 : public tunnelled_device<
630  /*implements*/ ata_device_with_command_set
631  /*by tunnelling through a*/, scsi_device
632  >
633 {
634 public:
636  const char * req_type, unsigned char signature);
637 
638  virtual ~usbcypress_device() throw();
639 
640 protected:
641  virtual int ata_command_interface(smart_command_set command, int select, char * data);
642 
643  unsigned char m_signature;
644 };
645 
646 
648  const char * req_type, unsigned char signature)
649 : smart_device(intf, scsidev->get_dev_name(), "sat", req_type),
651  m_signature(signature)
652 {
653  set_info().info_name = strprintf("%s [USB Cypress]", scsidev->get_info_name());
654 }
655 
657 {
658 }
659 
660 
661 /* see cy7c68300c_8.pdf for more information */
662 #define USBCYPRESS_PASSTHROUGH_LEN 16
664 {
665  struct scsi_cmnd_io io_hdr;
666  unsigned char cdb[USBCYPRESS_PASSTHROUGH_LEN];
667  unsigned char sense[32];
668  int copydata = 0;
669  int outlen = 0;
670  int ck_cond = 0; /* set to 1 to read register(s) back */
671  int t_dir = 1; /* 0 -> to device, 1 -> from device */
672  int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
673  int t_length = 0; /* 0 -> no data transferred */
674  int feature = 0;
675  int ata_command = 0;
676  int sector_count = 0;
677  int lba_low = 0;
678  int lba_mid = 0;
679  int lba_high = 0;
680  int passthru_size = USBCYPRESS_PASSTHROUGH_LEN;
681 
682  memset(cdb, 0, sizeof(cdb));
683  memset(sense, 0, sizeof(sense));
684 
685  ata_command = ATA_SMART_CMD;
686  switch (command) {
687  case CHECK_POWER_MODE:
688  ata_command = ATA_CHECK_POWER_MODE;
689  ck_cond = 1;
690  copydata = 1;
691  break;
692  case READ_VALUES: /* READ DATA */
693  feature = ATA_SMART_READ_VALUES;
694  sector_count = 1; /* one (512 byte) block */
695  t_length = 2; /* sector count holds count */
696  copydata = 512;
697  break;
698  case READ_THRESHOLDS: /* obsolete */
699  feature = ATA_SMART_READ_THRESHOLDS;
700  sector_count = 1; /* one (512 byte) block */
701  lba_low = 1;
702  t_length = 2; /* sector count holds count */
703  copydata=512;
704  break;
705  case READ_LOG:
706  feature = ATA_SMART_READ_LOG_SECTOR;
707  sector_count = 1; /* one (512 byte) block */
708  lba_low = select;
709  t_length = 2; /* sector count holds count */
710  copydata = 512;
711  break;
712  case WRITE_LOG:
713  feature = ATA_SMART_WRITE_LOG_SECTOR;
714  sector_count = 1; /* one (512 byte) block */
715  lba_low = select;
716  t_length = 2; /* sector count holds count */
717  t_dir = 0; /* to device */
718  outlen = 512;
719  break;
720  case IDENTIFY:
721  ata_command = ATA_IDENTIFY_DEVICE;
722  sector_count = 1; /* one (512 byte) block */
723  t_length = 2; /* sector count holds count */
724  copydata = 512;
725  break;
726  case PIDENTIFY:
727  ata_command = ATA_IDENTIFY_PACKET_DEVICE;
728  sector_count = 1; /* one (512 byte) block */
729  t_length = 2; /* sector count (7:0) holds count */
730  copydata = 512;
731  break;
732  case ENABLE:
733  feature = ATA_SMART_ENABLE;
734  lba_low = 1;
735  break;
736  case DISABLE:
737  feature = ATA_SMART_DISABLE;
738  lba_low = 1;
739  break;
740  case STATUS:
741  // this command only says if SMART is working. It could be
742  // replaced with STATUS_CHECK below.
743  feature = ATA_SMART_STATUS;
744  ck_cond = 1;
745  break;
746  case AUTO_OFFLINE:
747  feature = ATA_SMART_AUTO_OFFLINE;
748  sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
749  break;
750  case AUTOSAVE:
751  feature = ATA_SMART_AUTOSAVE;
752  sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
753  break;
754  case IMMEDIATE_OFFLINE:
755  feature = ATA_SMART_IMMEDIATE_OFFLINE;
756  lba_low = select;
757  break;
758  case STATUS_CHECK:
759  // This command uses HDIO_DRIVE_TASK and has different syntax than
760  // the other commands.
761  feature = ATA_SMART_STATUS; /* SMART RETURN STATUS */
762  ck_cond = 1;
763  break;
764  default:
765  pout("Unrecognized command %d in usbcypress_device::ata_command_interface()\n"
766  "Please contact " PACKAGE_BUGREPORT "\n", command);
767  errno=ENOSYS;
768  return -1;
769  }
770  if (ATA_SMART_CMD == ata_command) {
771  lba_mid = 0x4f;
772  lba_high = 0xc2;
773  }
774 
775  cdb[0] = m_signature; // bVSCBSignature : vendor-specific command
776  cdb[1] = 0x24; // bVSCBSubCommand : 0x24 for ATACB
777  cdb[2] = 0x0;
778  if (ata_command == ATA_IDENTIFY_DEVICE || ata_command == ATA_IDENTIFY_PACKET_DEVICE)
779  cdb[2] |= (1<<7); //set IdentifyPacketDevice for these cmds
780  cdb[3] = 0xff - (1<<0) - (1<<6); //features, sector count, lba low, lba med
781  // lba high, command are valid
782  cdb[4] = byte_block; //TransferBlockCount : 512
783 
784 
785  cdb[6] = feature;
786  cdb[7] = sector_count;
787  cdb[8] = lba_low;
788  cdb[9] = lba_mid;
789  cdb[10] = lba_high;
790  cdb[12] = ata_command;
791 
792  memset(&io_hdr, 0, sizeof(io_hdr));
793  if (0 == t_length) {
794  io_hdr.dxfer_dir = DXFER_NONE;
795  io_hdr.dxfer_len = 0;
796  } else if (t_dir) { /* from device */
797  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
798  io_hdr.dxfer_len = copydata;
799  io_hdr.dxferp = (unsigned char *)data;
800  memset(data, 0, copydata); /* prefill with zeroes */
801  } else { /* to device */
802  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
803  io_hdr.dxfer_len = outlen;
804  io_hdr.dxferp = (unsigned char *)data;
805  }
806  io_hdr.cmnd = cdb;
807  io_hdr.cmnd_len = passthru_size;
808  io_hdr.sensep = sense;
809  io_hdr.max_sense_len = sizeof(sense);
810  io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
811 
812  scsi_device * scsidev = get_tunnel_dev();
813  if (!scsidev->scsi_pass_through(&io_hdr)) {
814  if (scsi_debugmode > 0)
815  pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
816  "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
817  set_err(scsidev->get_err());
818  return -1;
819  }
820 
821  // if there is a sense the command failed or the
822  // device doesn't support usbcypress
823  if (io_hdr.scsi_status == SCSI_STATUS_CHECK_CONDITION &&
824  sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
825  return -1;
826  }
827  if (ck_cond) {
828  unsigned char ardp[8];
829  int ard_len = 8;
830  /* XXX this is racy if there other scsi command between
831  * the first usbcypress command and this one
832  */
833  //pout("If you got strange result, please retry without traffic on the disc\n");
834  /* we use the same command as before, but we set
835  * * the read taskfile bit, for not executing usbcypress command,
836  * * but reading register selected in srb->cmnd[4]
837  */
838  cdb[2] = (1<<0); /* ask read taskfile */
839  memset(sense, 0, sizeof(sense));
840 
841  /* transfert 8 bytes */
842  memset(&io_hdr, 0, sizeof(io_hdr));
843  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
844  io_hdr.dxfer_len = ard_len;
845  io_hdr.dxferp = (unsigned char *)ardp;
846  memset(ardp, 0, ard_len); /* prefill with zeroes */
847 
848  io_hdr.cmnd = cdb;
849  io_hdr.cmnd_len = passthru_size;
850  io_hdr.sensep = sense;
851  io_hdr.max_sense_len = sizeof(sense);
852  io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
853 
854 
855  if (!scsidev->scsi_pass_through(&io_hdr)) {
856  if (scsi_debugmode > 0)
857  pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
858  "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
859  set_err(scsidev->get_err());
860  return -1;
861  }
862  // if there is a sense the command failed or the
863  // device doesn't support usbcypress
864  if (io_hdr.scsi_status == SCSI_STATUS_CHECK_CONDITION &&
865  sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
866  return -1;
867  }
868 
869 
870  if (scsi_debugmode > 1) {
871  pout("Values from ATA Return Descriptor are:\n");
872  dStrHex((const char *)ardp, ard_len, 1);
873  }
874 
875  if (ATA_CHECK_POWER_MODE == ata_command)
876  data[0] = ardp[2]; /* sector count (0:7) */
877  else if (STATUS_CHECK == command) {
878  if ((ardp[4] == 0x4f) && (ardp[5] == 0xc2))
879  return 0; /* GOOD smart status */
880  if ((ardp[4] == 0xf4) && (ardp[5] == 0x2c))
881  return 1; // smart predicting failure, "bad" status
882  // We haven't gotten output that makes sense so
883  // print out some debugging info
884  syserror("Error SMART Status command failed");
885  pout("This may be due to a race in usbcypress\n");
886  pout("Retry without other disc access\n");
887  pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
888  pout("Values from ATA Return Descriptor are:\n");
889  dStrHex((const char *)ardp, ard_len, 1);
890  return -1;
891  }
892  }
893  return 0;
894 }
895 
896 #if 0 // Not used, see autodetect_sat_device() below.
897 static int isprint_string(const char *s)
898 {
899  while (*s) {
900  if (isprint(*s) == 0)
901  return 0;
902  s++;
903  }
904  return 1;
905 }
906 
907 /* Attempt an IDENTIFY DEVICE ATA or IDENTIFY PACKET DEVICE command
908  If successful return 1, else 0 */
909 // TODO: Combine with has_sat_pass_through above
910 static int has_usbcypress_pass_through(ata_device * atadev, const char *manufacturer, const char *product)
911 {
912  struct ata_identify_device drive;
913  char model[40], serial[20], firm[8];
914 
915  /* issue the command and do a checksum if possible */
916  if (ataReadHDIdentity(atadev, &drive) < 0)
917  return 0;
918 
919  /* check if model string match, revision doesn't work for me */
920  format_ata_string(model, drive.model, 40);
921  if (*model == 0 || isprint_string(model) == 0)
922  return 0;
923 
924  if (manufacturer && strncmp(manufacturer, model, 8))
925  pout("manufacturer doesn't match in pass_through test\n");
926  if (product &&
927  strlen(model) > 8 && strncmp(product, model+8, strlen(model)-8))
928  pout("product doesn't match in pass_through test\n");
929 
930  /* check serial */
931  format_ata_string(serial, drive.serial_no, 20);
932  if (isprint_string(serial) == 0)
933  return 0;
934  format_ata_string(firm, drive.fw_rev, 8);
935  if (isprint_string(firm) == 0)
936  return 0;
937  return 1;
938 }
939 #endif
940 
941 /////////////////////////////////////////////////////////////////////////////
942 
943 /// JMicron USB Bridge support.
944 
946 : public tunnelled_device<
947  /*implements*/ ata_device,
948  /*by tunnelling through a*/ scsi_device
949  >
950 {
951 public:
953  const char * req_type, bool prolific,
954  bool ata_48bit_support, int port);
955 
956  virtual ~usbjmicron_device() throw();
957 
958  virtual bool open();
959 
960  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
961 
962 private:
963  bool get_registers(unsigned short addr, unsigned char * buf, unsigned short size);
964 
967  int m_port;
968 };
969 
970 
972  const char * req_type, bool prolific,
973  bool ata_48bit_support, int port)
974 : smart_device(intf, scsidev->get_dev_name(), "usbjmicron", req_type),
976  m_prolific(prolific), m_ata_48bit_support(ata_48bit_support),
977  m_port(port >= 0 || !prolific ? port : 0)
978 {
979  set_info().info_name = strprintf("%s [USB JMicron]", scsidev->get_info_name());
980 }
981 
983 {
984 }
985 
986 
988 {
989  // Open USB first
991  return false;
992 
993  // Detect port if not specified
994  if (m_port < 0) {
995  unsigned char regbuf[1] = {0};
996  if (!get_registers(0x720f, regbuf, sizeof(regbuf))) {
997  close();
998  return false;
999  }
1000 
1001  switch (regbuf[0] & 0x44) {
1002  case 0x04:
1003  m_port = 0; break;
1004  case 0x40:
1005  m_port = 1; break;
1006  case 0x44:
1007  close();
1008  return set_err(EINVAL, "Two devices connected, try '-d usbjmicron,[01]'");
1009  default:
1010  close();
1011  return set_err(ENODEV, "No device connected");
1012  }
1013  }
1014 
1015  return true;
1016 }
1017 
1018 
1020 {
1021  if (!ata_cmd_is_supported(in,
1025  "JMicron")
1026  )
1027  return false;
1028 
1029  if (m_port < 0)
1030  return set_err(EIO, "Unknown JMicron port");
1031 
1032  scsi_cmnd_io io_hdr;
1033  memset(&io_hdr, 0, sizeof(io_hdr));
1034 
1035  bool rwbit = true;
1036  unsigned char smart_status = 0xff;
1037 
1038  bool is_smart_status = ( in.in_regs.command == ATA_SMART_CMD
1039  && in.in_regs.features == ATA_SMART_STATUS);
1040 
1041  if (is_smart_status && in.out_needed.is_set()) {
1042  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1043  io_hdr.dxfer_len = 1;
1044  io_hdr.dxferp = &smart_status;
1045  }
1046  else switch (in.direction) {
1047  case ata_cmd_in::no_data:
1048  io_hdr.dxfer_dir = DXFER_NONE;
1049  break;
1050  case ata_cmd_in::data_in:
1051  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1052  io_hdr.dxfer_len = in.size;
1053  io_hdr.dxferp = (unsigned char *)in.buffer;
1054  memset(in.buffer, 0, in.size);
1055  break;
1056  case ata_cmd_in::data_out:
1057  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1058  io_hdr.dxfer_len = in.size;
1059  io_hdr.dxferp = (unsigned char *)in.buffer;
1060  rwbit = false;
1061  break;
1062  default:
1063  return set_err(EINVAL);
1064  }
1065 
1066  // Build pass through command
1067  unsigned char cdb[14];
1068  cdb[ 0] = 0xdf;
1069  cdb[ 1] = (rwbit ? 0x10 : 0x00);
1070  cdb[ 2] = 0x00;
1071  cdb[ 3] = (unsigned char)(io_hdr.dxfer_len >> 8);
1072  cdb[ 4] = (unsigned char)(io_hdr.dxfer_len );
1073  cdb[ 5] = in.in_regs.features;
1074  cdb[ 6] = in.in_regs.sector_count;
1075  cdb[ 7] = in.in_regs.lba_low;
1076  cdb[ 8] = in.in_regs.lba_mid;
1077  cdb[ 9] = in.in_regs.lba_high;
1078  cdb[10] = in.in_regs.device | (m_port == 0 ? 0xa0 : 0xb0);
1079  cdb[11] = in.in_regs.command;
1080  // Prolific PL3507
1081  cdb[12] = 0x06;
1082  cdb[13] = 0x7b;
1083 
1084  io_hdr.cmnd = cdb;
1085  io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
1086 
1087  scsi_device * scsidev = get_tunnel_dev();
1088  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1089  "usbjmicron_device::ata_pass_through: "))
1090  return set_err(scsidev->get_err());
1091 
1092  if (in.out_needed.is_set()) {
1093  if (is_smart_status) {
1094  if (io_hdr.resid == 1)
1095  // Some (Prolific) USB bridges do not transfer a status byte
1096  return set_err(ENOSYS, "Incomplete response, status byte missing [JMicron]");
1097 
1098  switch (smart_status) {
1099  case 0xc2:
1100  out.out_regs.lba_high = 0xc2;
1101  out.out_regs.lba_mid = 0x4f;
1102  break;
1103  case 0x2c:
1104  out.out_regs.lba_high = 0x2c;
1105  out.out_regs.lba_mid = 0xf4;
1106  break;
1107  default:
1108  // Some (JM20336) USB bridges always return 0x01, regardless of SMART Status
1109  return set_err(ENOSYS, "Invalid status byte (0x%02x) [JMicron]", smart_status);
1110  }
1111  }
1112 
1113 #if 0 // Not needed for SMART STATUS, see also notes below
1114  else {
1115  // Read ATA output registers
1116  // NOTE: The register addresses are not valid for some older chip revisions
1117  // NOTE: There is a small race condition here!
1118  unsigned char regbuf[16] = {0, };
1119  if (!get_registers((m_port == 0 ? 0x8000 : 0x9000), regbuf, sizeof(regbuf)))
1120  return false;
1121 
1122  out.out_regs.sector_count = regbuf[ 0];
1123  out.out_regs.lba_mid = regbuf[ 4];
1124  out.out_regs.lba_low = regbuf[ 6];
1125  out.out_regs.device = regbuf[ 9];
1126  out.out_regs.lba_high = regbuf[10];
1127  out.out_regs.error = regbuf[13];
1128  out.out_regs.status = regbuf[14];
1129  }
1130 #endif
1131  }
1132 
1133  return true;
1134 }
1135 
1137  unsigned char * buf, unsigned short size)
1138 {
1139  unsigned char cdb[14];
1140  cdb[ 0] = 0xdf;
1141  cdb[ 1] = 0x10;
1142  cdb[ 2] = 0x00;
1143  cdb[ 3] = (unsigned char)(size >> 8);
1144  cdb[ 4] = (unsigned char)(size );
1145  cdb[ 5] = 0x00;
1146  cdb[ 6] = (unsigned char)(addr >> 8);
1147  cdb[ 7] = (unsigned char)(addr );
1148  cdb[ 8] = 0x00;
1149  cdb[ 9] = 0x00;
1150  cdb[10] = 0x00;
1151  cdb[11] = 0xfd;
1152  // Prolific PL3507
1153  cdb[12] = 0x06;
1154  cdb[13] = 0x7b;
1155 
1156  scsi_cmnd_io io_hdr;
1157  memset(&io_hdr, 0, sizeof(io_hdr));
1158  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1159  io_hdr.dxfer_len = size;
1160  io_hdr.dxferp = buf;
1161  io_hdr.cmnd = cdb;
1162  io_hdr.cmnd_len = sizeof(cdb);
1163  io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
1164 
1165  scsi_device * scsidev = get_tunnel_dev();
1166  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1167  "usbjmicron_device::get_registers: "))
1168  return set_err(scsidev->get_err());
1169 
1170  return true;
1171 }
1172 
1173 
1174 /////////////////////////////////////////////////////////////////////////////
1175 
1176 /// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
1177 
1179 : public tunnelled_device<
1180  /*implements*/ ata_device,
1181  /*by tunnelling through a*/ scsi_device
1182  >
1183 {
1184 public:
1186  const char * req_type);
1187 
1188  virtual ~usbprolific_device() throw();
1189 
1190  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
1191 };
1192 
1193 
1195  const char * req_type)
1196 : smart_device(intf, scsidev->get_dev_name(), "usbprolific", req_type),
1198 {
1199  set_info().info_name = strprintf("%s [USB Prolific]", scsidev->get_info_name());
1200 }
1201 
1203 {
1204 }
1205 
1207 {
1208  if (!ata_cmd_is_supported(in,
1213  "Prolific" )
1214  )
1215  return false;
1216 
1217  scsi_cmnd_io io_hdr;
1218  memset(&io_hdr, 0, sizeof(io_hdr));
1219  unsigned char cmd_rw = 0x10; // Read
1220 
1221  switch (in.direction) {
1222  case ata_cmd_in::no_data:
1223  io_hdr.dxfer_dir = DXFER_NONE;
1224  break;
1225  case ata_cmd_in::data_in:
1226  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1227  io_hdr.dxfer_len = in.size;
1228  io_hdr.dxferp = (unsigned char *)in.buffer;
1229  memset(in.buffer, 0, in.size);
1230  break;
1231  case ata_cmd_in::data_out:
1232  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1233  io_hdr.dxfer_len = in.size;
1234  io_hdr.dxferp = (unsigned char *)in.buffer;
1235  cmd_rw = 0x0; // Write
1236  break;
1237  default:
1238  return set_err(EINVAL);
1239  }
1240 
1241  // Based on reverse engineering of iSmart.exe with API Monitor.
1242  // Seen commands:
1243  // D0 0 0 0 06 7B 0 0 0 0 0 0 // Read Firmware info?, reads 16 bytes
1244  // F4 0 0 0 06 7B // ??
1245  // D8 15 0 D8 06 7B 0 0 0 0 1 1 4F C2 A0 B0 // SMART Enable
1246  // D8 15 0 D0 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read values
1247  // D8 15 0 D1 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read thresholds
1248  // D8 15 0 D4 06 7B 0 0 0 0 0 1 4F C2 A0 B0 // SMART Execute self test
1249  // D7 0 0 0 06 7B 0 0 0 0 0 0 0 0 0 0 // Read status registers, Reads 16 bytes of data
1250  // Additional DATA OUT support based on document from Prolific
1251 
1252  // Build pass through command
1253  unsigned char cdb[16];
1254  cdb[ 0] = 0xD8; // Operation Code (D8 = Prolific ATA pass through)
1255  cdb[ 1] = cmd_rw|0x5; // Read(0x10)/Write(0x0) | NORMAL(0x5)/PREFIX(0x0)(?)
1256  cdb[ 2] = 0x0; // Reserved
1257  cdb[ 3] = in.in_regs.features; // Feature register (SMART command)
1258  cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1259  cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1260  cdb[ 6] = (unsigned char)(io_hdr.dxfer_len >> 24); // Length MSB
1261  cdb[ 7] = (unsigned char)(io_hdr.dxfer_len >> 16); // Length ...
1262  cdb[ 8] = (unsigned char)(io_hdr.dxfer_len >> 8); // Length ...
1263  cdb[ 9] = (unsigned char)(io_hdr.dxfer_len ); // Length LSB
1264  cdb[10] = in.in_regs.sector_count; // Sector Count
1265  cdb[11] = in.in_regs.lba_low; // LBA Low (7:0)
1266  cdb[12] = in.in_regs.lba_mid; // LBA Mid (15:8)
1267  cdb[13] = in.in_regs.lba_high; // LBA High (23:16)
1268  cdb[14] = in.in_regs.device | 0xA0; // Device/Head
1269  cdb[15] = in.in_regs.command; // ATA Command Register (only PIO supported)
1270  // Use '-r scsiioctl,1' to print CDB for debug purposes
1271 
1272  io_hdr.cmnd = cdb;
1273  io_hdr.cmnd_len = 16;
1274 
1275  scsi_device * scsidev = get_tunnel_dev();
1276  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1277  "usbprolific_device::ata_pass_through: "))
1278  return set_err(scsidev->get_err());
1279 
1280  if (in.out_needed.is_set()) {
1281  // Read ATA output registers
1282  unsigned char regbuf[16] = {0, };
1283  memset(&io_hdr, 0, sizeof(io_hdr));
1284  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1285  io_hdr.dxfer_len = sizeof(regbuf);
1286  io_hdr.dxferp = regbuf;
1287 
1288  memset(cdb, 0, sizeof(cdb));
1289  cdb[ 0] = 0xD7; // Prolific read registers
1290  cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1291  cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1292  io_hdr.cmnd = cdb;
1293  io_hdr.cmnd_len = sizeof(cdb);
1294 
1295  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1296  "usbprolific_device::scsi_pass_through (get registers): "))
1297  return set_err(scsidev->get_err());
1298 
1299  // Use '-r scsiioctl,2' to print input registers for debug purposes
1300  // Example: 50 00 00 00 00 01 4f 00 c2 00 a0 da 00 b0 00 50
1301  out.out_regs.status = regbuf[0]; // Status
1302  out.out_regs.error = regbuf[1]; // Error
1303  out.out_regs.sector_count = regbuf[2]; // Sector Count (7:0)
1304  out.out_regs.lba_low = regbuf[4]; // LBA Low (7:0)
1305  out.out_regs.lba_mid = regbuf[6]; // LBA Mid (7:0)
1306  out.out_regs.lba_high = regbuf[8]; // LBA High (7:0)
1307  out.out_regs.device = regbuf[10]; // Device/Head
1308  // = regbuf[11]; // ATA Feature (7:0)
1309  // = regbuf[13]; // ATA Command
1310  }
1311 
1312  return true;
1313 }
1314 
1315 
1316 /////////////////////////////////////////////////////////////////////////////
1317 
1318 /// SunplusIT USB Bridge support.
1319 
1321 : public tunnelled_device<
1322  /*implements*/ ata_device,
1323  /*by tunnelling through a*/ scsi_device
1324  >
1325 {
1326 public:
1327  usbsunplus_device(smart_interface * intf, scsi_device * scsidev,
1328  const char * req_type);
1329 
1330  virtual ~usbsunplus_device() throw();
1331 
1332  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
1333 };
1334 
1335 
1337  const char * req_type)
1338 : smart_device(intf, scsidev->get_dev_name(), "usbsunplus", req_type),
1340 {
1341  set_info().info_name = strprintf("%s [USB Sunplus]", scsidev->get_info_name());
1342 }
1343 
1345 {
1346 }
1347 
1349 {
1350  if (!ata_cmd_is_supported(in,
1354  "Sunplus")
1355  )
1356  return false;
1357 
1358  scsi_cmnd_io io_hdr;
1359  unsigned char cdb[12];
1360 
1361  if (in.in_regs.is_48bit_cmd()) {
1362  // Set "previous" registers
1363  memset(&io_hdr, 0, sizeof(io_hdr));
1364  io_hdr.dxfer_dir = DXFER_NONE;
1365 
1366  cdb[ 0] = 0xf8;
1367  cdb[ 1] = 0x00;
1368  cdb[ 2] = 0x23; // Subcommand: Pass through presetting
1369  cdb[ 3] = 0x00;
1370  cdb[ 4] = 0x00;
1371  cdb[ 5] = in.in_regs.prev.features;
1372  cdb[ 6] = in.in_regs.prev.sector_count;
1373  cdb[ 7] = in.in_regs.prev.lba_low;
1374  cdb[ 8] = in.in_regs.prev.lba_mid;
1375  cdb[ 9] = in.in_regs.prev.lba_high;
1376  cdb[10] = 0x00;
1377  cdb[11] = 0x00;
1378 
1379  io_hdr.cmnd = cdb;
1380  io_hdr.cmnd_len = sizeof(cdb);
1381 
1382  scsi_device * scsidev = get_tunnel_dev();
1383  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1384  "usbsunplus_device::scsi_pass_through (presetting): "))
1385  return set_err(scsidev->get_err());
1386  }
1387 
1388  // Run Pass through command
1389  memset(&io_hdr, 0, sizeof(io_hdr));
1390  unsigned char protocol;
1391  switch (in.direction) {
1392  case ata_cmd_in::no_data:
1393  io_hdr.dxfer_dir = DXFER_NONE;
1394  protocol = 0x00;
1395  break;
1396  case ata_cmd_in::data_in:
1397  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1398  io_hdr.dxfer_len = in.size;
1399  io_hdr.dxferp = (unsigned char *)in.buffer;
1400  memset(in.buffer, 0, in.size);
1401  protocol = 0x10;
1402  break;
1403  case ata_cmd_in::data_out:
1404  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1405  io_hdr.dxfer_len = in.size;
1406  io_hdr.dxferp = (unsigned char *)in.buffer;
1407  protocol = 0x11;
1408  break;
1409  default:
1410  return set_err(EINVAL);
1411  }
1412 
1413  cdb[ 0] = 0xf8;
1414  cdb[ 1] = 0x00;
1415  cdb[ 2] = 0x22; // Subcommand: Pass through
1416  cdb[ 3] = protocol;
1417  cdb[ 4] = (unsigned char)(io_hdr.dxfer_len >> 9);
1418  cdb[ 5] = in.in_regs.features;
1419  cdb[ 6] = in.in_regs.sector_count;
1420  cdb[ 7] = in.in_regs.lba_low;
1421  cdb[ 8] = in.in_regs.lba_mid;
1422  cdb[ 9] = in.in_regs.lba_high;
1423  cdb[10] = in.in_regs.device | 0xa0;
1424  cdb[11] = in.in_regs.command;
1425 
1426  io_hdr.cmnd = cdb;
1427  io_hdr.cmnd_len = sizeof(cdb);
1428 
1429  scsi_device * scsidev = get_tunnel_dev();
1430  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1431  "usbsunplus_device::scsi_pass_through: "))
1432  // Returns sense key 0x03 (medium error) on ATA command error
1433  return set_err(scsidev->get_err());
1434 
1435  if (in.out_needed.is_set()) {
1436  // Read ATA output registers
1437  unsigned char regbuf[8] = {0, };
1438  memset(&io_hdr, 0, sizeof(io_hdr));
1439  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1440  io_hdr.dxfer_len = sizeof(regbuf);
1441  io_hdr.dxferp = regbuf;
1442 
1443  cdb[ 0] = 0xf8;
1444  cdb[ 1] = 0x00;
1445  cdb[ 2] = 0x21; // Subcommand: Get status
1446  memset(cdb+3, 0, sizeof(cdb)-3);
1447  io_hdr.cmnd = cdb;
1448  io_hdr.cmnd_len = sizeof(cdb);
1449 
1450  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1451  "usbsunplus_device::scsi_pass_through (get registers): "))
1452  return set_err(scsidev->get_err());
1453 
1454  out.out_regs.error = regbuf[1];
1455  out.out_regs.sector_count = regbuf[2];
1456  out.out_regs.lba_low = regbuf[3];
1457  out.out_regs.lba_mid = regbuf[4];
1458  out.out_regs.lba_high = regbuf[5];
1459  out.out_regs.device = regbuf[6];
1460  out.out_regs.status = regbuf[7];
1461  }
1462 
1463  return true;
1464 }
1465 
1466 
1467 } // namespace
1468 
1469 using namespace sat;
1470 
1471 
1472 /////////////////////////////////////////////////////////////////////////////
1473 
1474 // Return ATA->SCSI filter for SAT or USB.
1475 
1477 {
1478  if (!strncmp(type, "sat", 3)) {
1479  const char * t = type + 3;
1480  bool enable_auto = false;
1481  if (!strncmp(t, ",auto", 5)) {
1482  t += 5;
1483  enable_auto = true;
1484  }
1485  int ptlen = 0, n = -1;
1486  if (*t && !(sscanf(t, ",%d%n", &ptlen, &n) == 1 && n == (int)strlen(t)
1487  && (ptlen == 0 || ptlen == 12 || ptlen == 16))) {
1488  set_err(EINVAL, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16");
1489  return 0;
1490  }
1491  return new sat_device(this, scsidev, type, ptlen, enable_auto);
1492  }
1493 
1494  else if (!strncmp(type, "usbcypress", 10)) {
1495  unsigned signature = 0x24; int n1 = -1, n2 = -1;
1496  if (!(((sscanf(type, "usbcypress%n,0x%x%n", &n1, &signature, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type))
1497  && signature <= 0xff)) {
1498  set_err(EINVAL, "Option '-d usbcypress,<n>' requires <n> to be "
1499  "an hexadecimal number between 0x0 and 0xff");
1500  return 0;
1501  }
1502  return new usbcypress_device(this, scsidev, type, signature);
1503  }
1504 
1505  else if (!strncmp(type, "usbjmicron", 10)) {
1506  const char * t = type + 10;
1507  bool prolific = false;
1508  if (!strncmp(t, ",p", 2)) {
1509  t += 2;
1510  prolific = true;
1511  }
1512  bool ata_48bit_support = false;
1513  if (!strncmp(t, ",x", 2)) {
1514  t += 2;
1515  ata_48bit_support = true;
1516  }
1517  int port = -1, n = -1;
1518  if (*t && !( (sscanf(t, ",%d%n", &port, &n) == 1
1519  && n == (int)strlen(t) && 0 <= port && port <= 1))) {
1520  set_err(EINVAL, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
1521  return 0;
1522  }
1523  return new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
1524  }
1525 
1526  else if (!strcmp(type, "usbprolific")) {
1527  return new usbprolific_device(this, scsidev, type);
1528  }
1529 
1530  else if (!strcmp(type, "usbsunplus")) {
1531  return new usbsunplus_device(this, scsidev, type);
1532  }
1533 
1534  else {
1535  set_err(EINVAL, "Unknown USB device type '%s'", type);
1536  return 0;
1537  }
1538 }
1539 
1540 // Try to detect a SAT device behind a SCSI interface.
1541 
1543  const unsigned char * inqdata, unsigned inqsize)
1544 {
1545  if (!scsidev->is_open())
1546  return 0;
1547 
1548  // SAT ?
1549  if (inqdata && inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8)) { // TODO: Linux-specific?
1550  ata_device_auto_ptr atadev( new sat_device(this, scsidev, "") , scsidev);
1551  if (has_sat_pass_through(atadev.get()))
1552  return atadev.release(); // Detected SAT
1553  }
1554 
1555  return 0;
1556 }
1557 
1558 
1559 /////////////////////////////////////////////////////////////////////////////
1560 // USB device type detection
1561 
1562 // Format USB ID for error messages
1563 static std::string format_usb_id(int vendor_id, int product_id, int version)
1564 {
1565  if (version >= 0)
1566  return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id, product_id, version);
1567  else
1568  return strprintf("[0x%04x:0x%04x]", vendor_id, product_id);
1569 }
1570 
1571 // Get type name for USB device with known VENDOR:PRODUCT ID.
1572 const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
1573  int version /*= -1*/)
1574 {
1575  usb_dev_info info, info2;
1576  int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
1577 
1578  if (n <= 0) {
1579  set_err(EINVAL, "Unknown USB bridge %s",
1580  format_usb_id(vendor_id, product_id, version).c_str());
1581  return 0;
1582  }
1583 
1584  if (n > 1) {
1585  set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
1586  format_usb_id(vendor_id, product_id, version).c_str(),
1587  (!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"),
1588  (!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
1589  return 0;
1590  }
1591 
1592  if (info.usb_type.empty()) {
1593  set_err(ENOSYS, "Unsupported USB bridge %s",
1594  format_usb_id(vendor_id, product_id, version).c_str());
1595  return 0;
1596  }
1597 
1598  // TODO: change return type to std::string
1599  static std::string type;
1600  type = info.usb_type;
1601  return type.c_str();
1602 }
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:100
Error (number,message) pair.
Definition: dev_interface.h:58
#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:1542
void scsi_do_sense_disect(const struct scsi_cmnd_io *io_buf, struct scsi_sense_disect *out)
Definition: scsicmds.cpp:195
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:67
#define SAT_ATA_PASSTHROUGH_12
Definition: scsicmds.h:101
#define SCSI_STATUS_CHECK_CONDITION
Definition: scsicmds.h:260
const char * get_dev_type() const
Get device type.
UINT8 * sensep
Definition: scsicmds.h:124
#define SCSI_ASCQ_ATA_PASS_THROUGH
Definition: scsicmds.h:281
virtual ata_device * get_sat_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI filter for SAT or USB.
Definition: scsiata.cpp:1476
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:264
int get_errno() const
Get last error number.
#define DXFER_FROM_DEVICE
Definition: scsicmds.h:113
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:499
ata_register device
virtual bool close()=0
Close device, return false on error.
Cypress USB Brigde support.
Definition: scsiata.cpp:628
ata_register sector_count
unsigned timeout
Definition: scsicmds.h:127
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:663
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:128
usbcypress_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, unsigned char signature)
Definition: scsiata.cpp:647
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: scsiata.cpp:1019
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:72
ata_register lba_mid
int scsiSimpleSenseFilter(const struct scsi_sense_disect *sinfo)
Definition: scsicmds.cpp:219
#define ATA_IDENTIFY_PACKET_DEVICE
Definition: atacmds.h:73
usbsunplus_device(smart_interface *intf, scsi_device *scsidev, const char *req_type)
Definition: scsiata.cpp:1336
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:122
Definition: scsiata.cpp:102
ata_out_regs_48bit out_regs
Output registers.
std::string dev_type
Actual device type.
Definition: dev_interface.h:53
UINT8 * cmnd
Definition: scsicmds.h:118
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:1194
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:489
void syserror(const char *message)
Definition: utility.cpp:348
virtual ~usbprolific_device()
Definition: scsiata.cpp:1202
Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
Definition: scsiata.cpp:1178
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: scsiata.cpp:1348
const char * get_errmsg() const
Get last error message.
#define SAT_ATA_PASSTHROUGH_16
Definition: scsicmds.h:104
std::string usb_type
Definition: knowndrives.h:39
unsigned char sense_key
Definition: scsiata.cpp:76
void dStrHex(const char *str, int len, int no_ascii)
Definition: scsicmds.cpp:91
uint32_t outlen
Definition: megaraid.h:80
SunplusIT USB Bridge support.
Definition: scsiata.cpp:1320
unsigned char scsi_debugmode
Definition: scsicmds.cpp:56
#define SAT_ATA_PASSTHROUGH_16LEN
Definition: scsiata.cpp:96
void pout(const char *fmt,...)
Definition: smartctl.cpp:1091
size_t max_sense_len
Definition: scsicmds.h:126
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:971
ata_register status
int dxfer_dir
Definition: scsicmds.h:120
#define USBCYPRESS_PASSTHROUGH_LEN
Definition: scsiata.cpp:662
#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:554
#define DXFER_NONE
Definition: scsicmds.h:112
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:945
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:1206
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:114
#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:1572
SAT support.
Definition: scsiata.cpp:107
ata_register device
Base class for all devices.
Definition: dev_interface.h:38
virtual ~sat_device()
Definition: scsiata.cpp:151
ata_register lba_high
int no
Error number.
Definition: dev_interface.h:66
unsigned char m_signature
Definition: scsiata.cpp:643
size_t cmnd_len
Definition: scsicmds.h:119
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:1344
static bool has_sat_pass_through(ata_device *dev, bool packet_interface=false)
Definition: scsiata.cpp:536
#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:129
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:780
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:787
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:2745
#define SCSI_SK_NO_SENSE
Definition: scsicmds.h:263
ata_register lba_high
static std::string format_usb_id(int vendor_id, int product_id, int version)
Definition: scsiata.cpp:1563
size_t dxfer_len
Definition: scsicmds.h:123
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:52
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:656
virtual bool open()
Open device, return false on error.
Definition: scsiata.cpp:987
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:591
const char * scsiErrString(int scsiErr)
Definition: scsicmds.cpp:257
#define SCSI_TIMEOUT_DEFAULT
Definition: scsicmds.h:309
virtual ~usbjmicron_device()
Definition: scsiata.cpp:982
const char * get_info_name() const
Get informal name.
bool get_registers(unsigned short addr, unsigned char *buf, unsigned short size)
Definition: scsiata.cpp:1136
const char * scsiata_cpp_cvsid
Definition: scsiata.cpp:65
#define ATA_SMART_STATUS
Definition: atacmds.h:105