smartmontools  SVN Rev 5304
Utility to control and monitor storage systems with "S.M.A.R.T."
scsiata.cpp
Go to the documentation of this file.
1 /*
2  * scsiata.cpp
3  *
4  * Home page of code is: https://www.smartmontools.org
5  *
6  * Copyright (C) 2006-15 Douglas Gilbert <dgilbert@interlog.com>
7  * Copyright (C) 2009-21 Christian Franke
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  * The code in this file is based on the SCSI to ATA Translation (SAT)
11  * draft found at http://www.t10.org . The original draft used for this
12  * code is sat-r08.pdf which is not too far away from becoming a
13  * standard. The SAT commands of interest to smartmontools are the
14  * ATA PASS THROUGH SCSI (16) and ATA PASS THROUGH SCSI (12) defined in
15  * section 12 of that document.
16  *
17  * sat-r09.pdf is the most recent, easily accessible draft prior to the
18  * original SAT standard (ANSI INCITS 431-2007). By mid-2009 the second
19  * version of the SAT standard (SAT-2) is nearing standardization. In
20  * their wisdom an incompatible change has been introduced in draft
21  * sat2r08a.pdf in the area of the ATA RETURN DESCRIPTOR. A new "fixed
22  * format" ATA RETURN buffer has been defined (sat2r08b.pdf section
23  * 12.2.7) for the case when DSENSE=0 in the Control mode page.
24  * Unfortunately this is the normal case. If the change stands our
25  * code will need to be extended for this case.
26  *
27  * With more transports "hiding" SATA disks (and other S-ATAPI devices)
28  * behind a SCSI command set, accessing special features like SMART
29  * information becomes a challenge. The SAT standard offers ATA PASS
30  * THROUGH commands for special usages. Note that the SAT layer may
31  * be inside a generic OS layer (e.g. libata in linux), in a host
32  * adapter (HA or HBA) firmware, or somewhere on the interconnect
33  * between the host computer and the SATA devices (e.g. a RAID made
34  * of SATA disks and the RAID talks "SCSI" to the host computer).
35  * Note that in the latter case, this code does not solve the
36  * addressing issue (i.e. which SATA disk to address behind the logical
37  * SCSI (RAID) interface).
38  *
39  */
40 
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <ctype.h>
45 #include <errno.h>
46 
47 #include "config.h"
48 
49 #include "scsicmds.h"
50 #include "atacmds.h" // ataReadHDIdentity()
51 #include "knowndrives.h" // lookup_usb_device()
52 #include "utility.h"
53 #include "dev_interface.h"
54 #include "dev_ata_cmd_set.h" // ata_device_with_command_set
55 #include "dev_tunnelled.h" // tunnelled_device<>
56 #include "sg_unaligned.h"
57 
58 const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 5202 2021-02-07 16:34:57Z chrfranke $";
59 
60 /* This is a slightly stretched SCSI sense "descriptor" format header.
61  The addition is to allow the 0x70 and 0x71 response codes. The idea
62  is to place the salient data of both "fixed" and "descriptor" sense
63  format into one structure to ease application processing.
64  The original sense buffer should be kept around for those cases
65  in which more information is required (e.g. the LBA of a MEDIUM ERROR). */
66 /// Abridged SCSI sense data
68  unsigned char response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
69  unsigned char sense_key;
70  unsigned char asc;
71  unsigned char ascq;
72  unsigned char byte4;
73  unsigned char byte5;
74  unsigned char byte6;
75  unsigned char additional_length;
76 };
77 
78 /* Maps the salient data from a sense buffer which is in either fixed or
79  descriptor format into a structure mimicking a descriptor format
80  header (i.e. the first 8 bytes of sense descriptor format).
81  If zero response code returns 0. Otherwise returns 1 and if 'sshp' is
82  non-NULL then zero all fields and then set the appropriate fields in
83  that structure. sshp::additional_length is always 0 for response
84  codes 0x70 and 0x71 (fixed format). */
85 static int sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len,
86  struct sg_scsi_sense_hdr * sshp);
87 
88 #define SAT_ATA_PASSTHROUGH_12LEN 12
89 #define SAT_ATA_PASSTHROUGH_16LEN 16
90 
91 #define DEF_SAT_ATA_PASSTHRU_SIZE 16
92 #define ATA_RETURN_DESCRIPTOR 9
93 
94 
95 namespace sat { // no need to publish anything, name provided for Doxygen
96 
97 /// SAT support.
98 /// Implements ATA by tunnelling through SCSI.
99 
101 : public tunnelled_device<
102  /*implements*/ ata_device
103  /*by tunnelling through a*/, scsi_device
104  >,
105  virtual public /*implements*/ scsi_device
106 {
107 public:
112  };
113 
114  sat_device(smart_interface * intf, scsi_device * scsidev,
115  const char * req_type, sat_scsi_mode mode = sat_always, int passthrulen = 0);
116 
117  virtual ~sat_device();
118 
119  virtual smart_device * autodetect_open() override;
120 
121  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
122 
123  virtual bool scsi_pass_through(scsi_cmnd_io * iop) override;
124 
125 private:
128 };
129 
130 
132  const char * req_type, sat_scsi_mode mode /* = sat_always */,
133  int passthrulen /* = 0 */)
134 : smart_device(intf, scsidev->get_dev_name(),
135  (mode == sat_always ? "sat" : mode == sat_auto ? "sat,auto" : "scsi"), req_type),
137  m_passthrulen(passthrulen),
138  m_mode(mode)
139 {
140  if (mode != sat_always)
141  hide_ata(); // Start as SCSI, switch to ATA in autodetect_open()
142  else
143  hide_scsi(); // ATA always
144  if (strcmp(scsidev->get_dev_type(), "scsi"))
145  set_info().dev_type += strprintf("+%s", scsidev->get_dev_type());
146 
147  set_info().info_name = strprintf("%s [%s]", scsidev->get_info_name(),
148  (mode == sat_always ? "SAT" : mode == sat_auto ? "SCSI/SAT" : "SCSI"));
149 }
150 
152 {
153 }
154 
155 
156 // cdb[0]: ATA PASS THROUGH (16) SCSI command opcode byte (0x85)
157 // cdb[1]: multiple_count, protocol + extend
158 // cdb[2]: offline, ck_cond, t_dir, byte_block + t_length
159 // cdb[3]: features (15:8)
160 // cdb[4]: features (7:0)
161 // cdb[5]: sector_count (15:8)
162 // cdb[6]: sector_count (7:0)
163 // cdb[7]: lba_low (15:8)
164 // cdb[8]: lba_low (7:0)
165 // cdb[9]: lba_mid (15:8)
166 // cdb[10]: lba_mid (7:0)
167 // cdb[11]: lba_high (15:8)
168 // cdb[12]: lba_high (7:0)
169 // cdb[13]: device
170 // cdb[14]: (ata) command
171 // cdb[15]: control (SCSI, leave as zero)
172 //
173 // 24 bit lba (from MSB): cdb[12] cdb[10] cdb[8]
174 // 48 bit lba (from MSB): cdb[11] cdb[9] cdb[7] cdb[12] cdb[10] cdb[8]
175 //
176 //
177 // cdb[0]: ATA PASS THROUGH (12) SCSI command opcode byte (0xa1)
178 // cdb[1]: multiple_count, protocol + extend
179 // cdb[2]: offline, ck_cond, t_dir, byte_block + t_length
180 // cdb[3]: features (7:0)
181 // cdb[4]: sector_count (7:0)
182 // cdb[5]: lba_low (7:0)
183 // cdb[6]: lba_mid (7:0)
184 // cdb[7]: lba_high (7:0)
185 // cdb[8]: device
186 // cdb[9]: (ata) command
187 // cdb[10]: reserved
188 // cdb[11]: control (SCSI, leave as zero)
189 //
190 //
191 // ATA Return Descriptor (component of descriptor sense data)
192 // des[0]: descriptor code (0x9)
193 // des[1]: additional descriptor length (0xc)
194 // des[2]: extend (bit 0)
195 // des[3]: error
196 // des[4]: sector_count (15:8)
197 // des[5]: sector_count (7:0)
198 // des[6]: lba_low (15:8)
199 // des[7]: lba_low (7:0)
200 // des[8]: lba_mid (15:8)
201 // des[9]: lba_mid (7:0)
202 // des[10]: lba_high (15:8)
203 // des[11]: lba_high (7:0)
204 // des[12]: device
205 // des[13]: status
206 //
207 //
208 // ATA registers returned via fixed format sense (allowed >= SAT-2)
209 // fxs[0]: info_valid (bit 7); response_code (6:0)
210 // fxs[1]: (obsolete)
211 // fxs[2]: sense_key (3:0) --> recovered error (formerly 'no sense')
212 // fxs[3]: information (31:24) --> ATA Error register
213 // fxs[4]: information (23:16) --> ATA Status register
214 // fxs[5]: information (15:8) --> ATA Device register
215 // fxs[6]: information (7:0) --> ATA Count (7:0)
216 // fxs[7]: additional sense length [should be >= 10]
217 // fxs[8]: command specific info (31:24) --> Extend (7), count_upper_nonzero
218 // (6), lba_upper_nonzero(5), log_index (3:0)
219 // fxs[9]: command specific info (23:16) --> ATA LBA (7:0)
220 // fxs[10]: command specific info (15:8) --> ATA LBA (15:8)
221 // fxs[11]: command specific info (7:0) --> ATA LBA (23:16)
222 // fxs[12]: additional sense code (asc) --> 0x0
223 // fxs[13]: additional sense code qualifier (ascq) --> 0x1d
224 // asc,ascq = 0x0,0x1d --> 'ATA pass through information available'
225 
226 
227 
228 // PURPOSE
229 // This interface routine takes ATA SMART commands and packages
230 // them in the SAT-defined ATA PASS THROUGH SCSI commands. There are
231 // two available SCSI commands: a 12 byte and 16 byte variant; the
232 // one used is chosen via this->m_passthrulen .
233 // DETAILED DESCRIPTION OF ARGUMENTS
234 // device: is the file descriptor provided by (a SCSI dvice type) open()
235 // command: defines the different ATA operations.
236 // select: additional input data if needed (which log, which type of
237 // self-test).
238 // data: location to write output data, if needed (512 bytes).
239 // Note: not all commands use all arguments.
240 // RETURN VALUES
241 // -1 if the command failed
242 // 0 if the command succeeded,
243 // STATUS_CHECK routine:
244 // -1 if the command failed
245 // 0 if the command succeeded and disk SMART status is "OK"
246 // 1 if the command succeeded and disk SMART status is "FAILING"
247 
249 {
250  if (!ata_cmd_is_supported(in,
255  "SAT")
256  )
257  return false;
258 
259  struct scsi_cmnd_io io_hdr;
260  struct scsi_sense_disect sinfo;
261  struct sg_scsi_sense_hdr ssh;
262  unsigned char cdb[SAT_ATA_PASSTHROUGH_16LEN];
263  unsigned char sense[32];
264  const unsigned char * ardp;
265  int ard_len, have_sense;
266  int extend = 0;
267  int ck_cond = 0; /* set to 1 to read register(s) back */
268  int protocol = 3; /* non-data */
269  int t_dir = 1; /* 0 -> to device, 1 -> from device */
270  int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
271  int t_length = 0; /* 0 -> no data transferred */
272  int passthru_size = DEF_SAT_ATA_PASSTHRU_SIZE;
273  bool sense_descriptor = true;
274 
275  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 uint8_t *)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 uint8_t *)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 uint8_t *)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_mode != sat_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 controllers 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 
601 namespace sat {
602 
603 /// Cypress USB Brigde support.
604 
606 : public tunnelled_device<
607  /*implements*/ ata_device_with_command_set
608  /*by tunnelling through a*/, scsi_device
609  >
610 {
611 public:
613  const char * req_type, unsigned char signature);
614 
615  virtual ~usbcypress_device();
616 
617 protected:
618  virtual int ata_command_interface(smart_command_set command, int select, char * data) override;
619 
620  unsigned char m_signature;
621 };
622 
623 
625  const char * req_type, unsigned char signature)
626 : smart_device(intf, scsidev->get_dev_name(), "usbcypress", req_type),
628  m_signature(signature)
629 {
630  set_info().info_name = strprintf("%s [USB Cypress]", scsidev->get_info_name());
631 }
632 
634 {
635 }
636 
637 
638 /* see cy7c68300c_8.pdf for more information */
639 #define USBCYPRESS_PASSTHROUGH_LEN 16
641 {
642  struct scsi_cmnd_io io_hdr;
643  unsigned char cdb[USBCYPRESS_PASSTHROUGH_LEN];
644  unsigned char sense[32];
645  int copydata = 0;
646  int outlen = 0;
647  int ck_cond = 0; /* set to 1 to read register(s) back */
648  int t_dir = 1; /* 0 -> to device, 1 -> from device */
649  int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
650  int t_length = 0; /* 0 -> no data transferred */
651  int feature = 0;
652  int ata_command = 0;
653  int sector_count = 0;
654  int lba_low = 0;
655  int lba_mid = 0;
656  int lba_high = 0;
657  int passthru_size = USBCYPRESS_PASSTHROUGH_LEN;
658 
659  memset(cdb, 0, sizeof(cdb));
660  memset(sense, 0, sizeof(sense));
661 
662  ata_command = ATA_SMART_CMD;
663  switch (command) {
664  case CHECK_POWER_MODE:
665  ata_command = ATA_CHECK_POWER_MODE;
666  ck_cond = 1;
667  copydata = 1;
668  break;
669  case READ_VALUES: /* READ DATA */
670  feature = ATA_SMART_READ_VALUES;
671  sector_count = 1; /* one (512 byte) block */
672  t_length = 2; /* sector count holds count */
673  copydata = 512;
674  break;
675  case READ_THRESHOLDS: /* obsolete */
676  feature = ATA_SMART_READ_THRESHOLDS;
677  sector_count = 1; /* one (512 byte) block */
678  lba_low = 1;
679  t_length = 2; /* sector count holds count */
680  copydata=512;
681  break;
682  case READ_LOG:
683  feature = ATA_SMART_READ_LOG_SECTOR;
684  sector_count = 1; /* one (512 byte) block */
685  lba_low = select;
686  t_length = 2; /* sector count holds count */
687  copydata = 512;
688  break;
689  case WRITE_LOG:
690  feature = ATA_SMART_WRITE_LOG_SECTOR;
691  sector_count = 1; /* one (512 byte) block */
692  lba_low = select;
693  t_length = 2; /* sector count holds count */
694  t_dir = 0; /* to device */
695  outlen = 512;
696  break;
697  case IDENTIFY:
698  ata_command = ATA_IDENTIFY_DEVICE;
699  sector_count = 1; /* one (512 byte) block */
700  t_length = 2; /* sector count holds count */
701  copydata = 512;
702  break;
703  case PIDENTIFY:
704  ata_command = ATA_IDENTIFY_PACKET_DEVICE;
705  sector_count = 1; /* one (512 byte) block */
706  t_length = 2; /* sector count (7:0) holds count */
707  copydata = 512;
708  break;
709  case ENABLE:
710  feature = ATA_SMART_ENABLE;
711  lba_low = 1;
712  break;
713  case DISABLE:
714  feature = ATA_SMART_DISABLE;
715  lba_low = 1;
716  break;
717  case STATUS:
718  // this command only says if SMART is working. It could be
719  // replaced with STATUS_CHECK below.
720  feature = ATA_SMART_STATUS;
721  ck_cond = 1;
722  break;
723  case AUTO_OFFLINE:
724  feature = ATA_SMART_AUTO_OFFLINE;
725  sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
726  break;
727  case AUTOSAVE:
728  feature = ATA_SMART_AUTOSAVE;
729  sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
730  break;
731  case IMMEDIATE_OFFLINE:
732  feature = ATA_SMART_IMMEDIATE_OFFLINE;
733  lba_low = select;
734  break;
735  case STATUS_CHECK:
736  // This command uses HDIO_DRIVE_TASK and has different syntax than
737  // the other commands.
738  feature = ATA_SMART_STATUS; /* SMART RETURN STATUS */
739  ck_cond = 1;
740  break;
741  default:
742  pout("Unrecognized command %d in usbcypress_device::ata_command_interface()\n"
743  "Please contact " PACKAGE_BUGREPORT "\n", command);
744  errno=ENOSYS;
745  return -1;
746  }
747  if (ATA_SMART_CMD == ata_command) {
748  lba_mid = 0x4f;
749  lba_high = 0xc2;
750  }
751 
752  cdb[0] = m_signature; // bVSCBSignature : vendor-specific command
753  cdb[1] = 0x24; // bVSCBSubCommand : 0x24 for ATACB
754  cdb[2] = 0x0;
755  if (ata_command == ATA_IDENTIFY_DEVICE || ata_command == ATA_IDENTIFY_PACKET_DEVICE)
756  cdb[2] |= (1<<7); //set IdentifyPacketDevice for these cmds
757  cdb[3] = 0xff - (1<<0) - (1<<6); //features, sector count, lba low, lba med
758  // lba high, command are valid
759  cdb[4] = byte_block; //TransferBlockCount : 512
760 
761 
762  cdb[6] = feature;
763  cdb[7] = sector_count;
764  cdb[8] = lba_low;
765  cdb[9] = lba_mid;
766  cdb[10] = lba_high;
767  cdb[12] = ata_command;
768 
769  memset(&io_hdr, 0, sizeof(io_hdr));
770  if (0 == t_length) {
771  io_hdr.dxfer_dir = DXFER_NONE;
772  io_hdr.dxfer_len = 0;
773  } else if (t_dir) { /* from device */
774  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
775  io_hdr.dxfer_len = copydata;
776  io_hdr.dxferp = (unsigned char *)data;
777  memset(data, 0, copydata); /* prefill with zeroes */
778  } else { /* to device */
779  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
780  io_hdr.dxfer_len = outlen;
781  io_hdr.dxferp = (unsigned char *)data;
782  }
783  io_hdr.cmnd = cdb;
784  io_hdr.cmnd_len = passthru_size;
785  io_hdr.sensep = sense;
786  io_hdr.max_sense_len = sizeof(sense);
787  io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
788 
789  scsi_device * scsidev = get_tunnel_dev();
790  if (!scsidev->scsi_pass_through(&io_hdr)) {
791  if (scsi_debugmode > 0)
792  pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
793  "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
794  set_err(scsidev->get_err());
795  return -1;
796  }
797 
798  // if there is a sense the command failed or the
799  // device doesn't support usbcypress
801  sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
802  return -1;
803  }
804  if (ck_cond) {
805  unsigned char ardp[8];
806  int ard_len = 8;
807  /* XXX this is racy if there other scsi command between
808  * the first usbcypress command and this one
809  */
810  //pout("If you got strange result, please retry without traffic on the disc\n");
811  /* we use the same command as before, but we set
812  * * the read taskfile bit, for not executing usbcypress command,
813  * * but reading register selected in srb->cmnd[4]
814  */
815  cdb[2] = (1<<0); /* ask read taskfile */
816  memset(sense, 0, sizeof(sense));
817 
818  /* transfer 8 bytes */
819  memset(&io_hdr, 0, sizeof(io_hdr));
820  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
821  io_hdr.dxfer_len = ard_len;
822  io_hdr.dxferp = (unsigned char *)ardp;
823  memset(ardp, 0, ard_len); /* prefill with zeroes */
824 
825  io_hdr.cmnd = cdb;
826  io_hdr.cmnd_len = passthru_size;
827  io_hdr.sensep = sense;
828  io_hdr.max_sense_len = sizeof(sense);
829  io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
830 
831 
832  if (!scsidev->scsi_pass_through(&io_hdr)) {
833  if (scsi_debugmode > 0)
834  pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
835  "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
836  set_err(scsidev->get_err());
837  return -1;
838  }
839  // if there is a sense the command failed or the
840  // device doesn't support usbcypress
842  sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
843  return -1;
844  }
845 
846 
847  if (scsi_debugmode > 1) {
848  pout("Values from ATA Return Descriptor are:\n");
849  dStrHex((const uint8_t *)ardp, ard_len, 1);
850  }
851 
852  if (ATA_CHECK_POWER_MODE == ata_command)
853  data[0] = ardp[2]; /* sector count (0:7) */
854  else if (STATUS_CHECK == command) {
855  if ((ardp[4] == 0x4f) && (ardp[5] == 0xc2))
856  return 0; /* GOOD smart status */
857  if ((ardp[4] == 0xf4) && (ardp[5] == 0x2c))
858  return 1; // smart predicting failure, "bad" status
859  // We haven't gotten output that makes sense so
860  // print out some debugging info
861  syserror("Error SMART Status command failed");
862  pout("This may be due to a race in usbcypress\n");
863  pout("Retry without other disc access\n");
864  pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
865  pout("Values from ATA Return Descriptor are:\n");
866  dStrHex((const uint8_t *)ardp, ard_len, 1);
867  return -1;
868  }
869  }
870  return 0;
871 }
872 
873 /////////////////////////////////////////////////////////////////////////////
874 
875 /// JMicron USB Bridge support.
876 
878 : public tunnelled_device<
879  /*implements*/ ata_device,
880  /*by tunnelling through a*/ scsi_device
881  >
882 {
883 public:
885  const char * req_type, bool prolific,
886  bool ata_48bit_support, int port);
887 
888  virtual ~usbjmicron_device();
889 
890  virtual bool open() override;
891 
892  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
893 
894 private:
895  bool get_registers(unsigned short addr, unsigned char * buf, unsigned short size);
896 
899  int m_port;
900 };
901 
902 
904  const char * req_type, bool prolific,
905  bool ata_48bit_support, int port)
906 : smart_device(intf, scsidev->get_dev_name(), "usbjmicron", req_type),
908  m_prolific(prolific), m_ata_48bit_support(ata_48bit_support),
909  m_port(port >= 0 || !prolific ? port : 0)
910 {
911  set_info().info_name = strprintf("%s [USB JMicron]", scsidev->get_info_name());
912 }
913 
915 {
916 }
917 
918 
920 {
921  // Open USB first
923  return false;
924 
925  // Detect port if not specified
926  if (m_port < 0) {
927  unsigned char regbuf[1] = {0};
928  if (!get_registers(0x720f, regbuf, sizeof(regbuf))) {
929  close();
930  return false;
931  }
932 
933  switch (regbuf[0] & 0x44) {
934  case 0x04:
935  m_port = 0; break;
936  case 0x40:
937  m_port = 1; break;
938  case 0x44:
939  close();
940  return set_err(EINVAL, "Two devices connected, try '-d usbjmicron,[01]'");
941  default:
942  close();
943  return set_err(ENODEV, "No device connected");
944  }
945  }
946 
947  return true;
948 }
949 
950 
952 {
953  if (!ata_cmd_is_supported(in,
957  "JMicron")
958  )
959  return false;
960 
961  if (m_port < 0)
962  return set_err(EIO, "Unknown JMicron port");
963 
964  scsi_cmnd_io io_hdr;
965  memset(&io_hdr, 0, sizeof(io_hdr));
966 
967  bool rwbit = true;
968  unsigned char smart_status = 0xff;
969 
970  bool is_smart_status = ( in.in_regs.command == ATA_SMART_CMD
972 
973  if (is_smart_status && in.out_needed.is_set()) {
974  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
975  io_hdr.dxfer_len = 1;
976  io_hdr.dxferp = &smart_status;
977  }
978  else switch (in.direction) {
979  case ata_cmd_in::no_data:
980  io_hdr.dxfer_dir = DXFER_NONE;
981  break;
982  case ata_cmd_in::data_in:
983  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
984  io_hdr.dxfer_len = in.size;
985  io_hdr.dxferp = (unsigned char *)in.buffer;
986  memset(in.buffer, 0, in.size);
987  break;
989  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
990  io_hdr.dxfer_len = in.size;
991  io_hdr.dxferp = (unsigned char *)in.buffer;
992  rwbit = false;
993  break;
994  default:
995  return set_err(EINVAL);
996  }
997 
998  // Build pass through command
999  unsigned char cdb[14];
1000  cdb[ 0] = 0xdf;
1001  cdb[ 1] = (rwbit ? 0x10 : 0x00);
1002  cdb[ 2] = 0x00;
1003  sg_put_unaligned_be16(io_hdr.dxfer_len, cdb + 3);
1004  cdb[ 5] = in.in_regs.features;
1005  cdb[ 6] = in.in_regs.sector_count;
1006  cdb[ 7] = in.in_regs.lba_low;
1007  cdb[ 8] = in.in_regs.lba_mid;
1008  cdb[ 9] = in.in_regs.lba_high;
1009  cdb[10] = in.in_regs.device | (m_port == 0 ? 0xa0 : 0xb0);
1010  cdb[11] = in.in_regs.command;
1011  // Prolific PL3507
1012  cdb[12] = 0x06;
1013  cdb[13] = 0x7b;
1014 
1015  io_hdr.cmnd = cdb;
1016  io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
1017 
1018  scsi_device * scsidev = get_tunnel_dev();
1019  if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1020  "usbjmicron_device::ata_pass_through: "))
1021  return set_err(scsidev->get_err());
1022 
1023  if (in.out_needed.is_set()) {
1024  if (is_smart_status) {
1025  if (io_hdr.resid == 1)
1026  // Some (Prolific) USB bridges do not transfer a status byte
1027  return set_err(ENOSYS, "Incomplete response, status byte missing [JMicron]");
1028 
1029  switch (smart_status) {
1030  case 0xc2:
1031  out.out_regs.lba_high = 0xc2;
1032  out.out_regs.lba_mid = 0x4f;
1033  break;
1034  case 0x2c:
1035  out.out_regs.lba_high = 0x2c;
1036  out.out_regs.lba_mid = 0xf4;
1037  break;
1038  default:
1039  // Some (JM20336) USB bridges always return 0x01, regardless of SMART Status
1040  return set_err(ENOSYS, "Invalid status byte (0x%02x) [JMicron]", smart_status);
1041  }
1042  }
1043 
1044 #if 0 // Not needed for SMART STATUS, see also notes below
1045  else {
1046  // Read ATA output registers
1047  // NOTE: The register addresses are not valid for some older chip revisions
1048  // NOTE: There is a small race condition here!
1049  unsigned char regbuf[16] = {0, };
1050  if (!get_registers((m_port == 0 ? 0x8000 : 0x9000), regbuf, sizeof(regbuf)))
1051  return false;
1052 
1053  out.out_regs.sector_count = regbuf[ 0];
1054  out.out_regs.lba_mid = regbuf[ 4];
1055  out.out_regs.lba_low = regbuf[ 6];
1056  out.out_regs.device = regbuf[ 9];
1057  out.out_regs.lba_high = regbuf[10];
1058  out.out_regs.error = regbuf[13];
1059  out.out_regs.status = regbuf[14];
1060  }
1061 #endif
1062  }
1063 
1064  return true;
1065 }
1066 
1068  unsigned char * buf, unsigned short size)
1069 {
1070  unsigned char cdb[14];
1071  cdb[ 0] = 0xdf;
1072  cdb[ 1] = 0x10;
1073  cdb[ 2] = 0x00;
1075  cdb[ 5] = 0x00;
1077  cdb[ 8] = 0x00;
1078  cdb[ 9] = 0x00;
1079  cdb[10] = 0x00;
1080  cdb[11] = 0xfd;
1081  // Prolific PL3507
1082  cdb[12] = 0x06;
1083  cdb[13] = 0x7b;
1084 
1085  scsi_cmnd_io io_hdr;
1086  memset(&io_hdr, 0, sizeof(io_hdr));
1087  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1088  io_hdr.dxfer_len = size;
1089  io_hdr.dxferp = buf;
1090  io_hdr.cmnd = cdb;
1091  io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
1092 
1093  scsi_device * scsidev = get_tunnel_dev();
1094  if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1095  "usbjmicron_device::get_registers: "))
1096  return set_err(scsidev->get_err());
1097 
1098  return true;
1099 }
1100 
1101 
1102 /////////////////////////////////////////////////////////////////////////////
1103 
1104 /// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
1105 
1107 : public tunnelled_device<
1108  /*implements*/ ata_device,
1109  /*by tunnelling through a*/ scsi_device
1110  >
1111 {
1112 public:
1114  const char * req_type);
1115 
1116  virtual ~usbprolific_device();
1117 
1118  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
1119 };
1120 
1121 
1123  const char * req_type)
1124 : smart_device(intf, scsidev->get_dev_name(), "usbprolific", req_type),
1126 {
1127  set_info().info_name = strprintf("%s [USB Prolific]", scsidev->get_info_name());
1128 }
1129 
1131 {
1132 }
1133 
1135 {
1136  if (!ata_cmd_is_supported(in,
1141  "Prolific" )
1142  )
1143  return false;
1144 
1145  scsi_cmnd_io io_hdr;
1146  memset(&io_hdr, 0, sizeof(io_hdr));
1147  unsigned char cmd_rw = 0x10; // Read
1148 
1149  switch (in.direction) {
1150  case ata_cmd_in::no_data:
1151  io_hdr.dxfer_dir = DXFER_NONE;
1152  break;
1153  case ata_cmd_in::data_in:
1154  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1155  io_hdr.dxfer_len = in.size;
1156  io_hdr.dxferp = (unsigned char *)in.buffer;
1157  memset(in.buffer, 0, in.size);
1158  break;
1159  case ata_cmd_in::data_out:
1160  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1161  io_hdr.dxfer_len = in.size;
1162  io_hdr.dxferp = (unsigned char *)in.buffer;
1163  cmd_rw = 0x0; // Write
1164  break;
1165  default:
1166  return set_err(EINVAL);
1167  }
1168 
1169  // Based on reverse engineering of iSmart.exe with API Monitor.
1170  // Seen commands:
1171  // D0 0 0 0 06 7B 0 0 0 0 0 0 // Read Firmware info?, reads 16 bytes
1172  // F4 0 0 0 06 7B // ??
1173  // D8 15 0 D8 06 7B 0 0 0 0 1 1 4F C2 A0 B0 // SMART Enable
1174  // D8 15 0 D0 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read values
1175  // D8 15 0 D1 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read thresholds
1176  // D8 15 0 D4 06 7B 0 0 0 0 0 1 4F C2 A0 B0 // SMART Execute self test
1177  // D7 0 0 0 06 7B 0 0 0 0 0 0 0 0 0 0 // Read status registers, Reads 16 bytes of data
1178  // Additional DATA OUT support based on document from Prolific
1179 
1180  // Build pass through command
1181  unsigned char cdb[16];
1182  cdb[ 0] = 0xD8; // Operation Code (D8 = Prolific ATA pass through)
1183  cdb[ 1] = cmd_rw|0x5; // Read(0x10)/Write(0x0) | NORMAL(0x5)/PREFIX(0x0)(?)
1184  cdb[ 2] = 0x0; // Reserved
1185  cdb[ 3] = in.in_regs.features; // Feature register (SMART command)
1186  cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1187  cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1188  sg_put_unaligned_be32(io_hdr.dxfer_len, cdb + 6);
1189  cdb[10] = in.in_regs.sector_count; // Sector Count
1190  cdb[11] = in.in_regs.lba_low; // LBA Low (7:0)
1191  cdb[12] = in.in_regs.lba_mid; // LBA Mid (15:8)
1192  cdb[13] = in.in_regs.lba_high; // LBA High (23:16)
1193  cdb[14] = in.in_regs.device | 0xA0; // Device/Head
1194  cdb[15] = in.in_regs.command; // ATA Command Register (only PIO supported)
1195  // Use '-r scsiioctl,1' to print CDB for debug purposes
1196 
1197  io_hdr.cmnd = cdb;
1198  io_hdr.cmnd_len = 16;
1199 
1200  scsi_device * scsidev = get_tunnel_dev();
1201  if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1202  "usbprolific_device::ata_pass_through: "))
1203  return set_err(scsidev->get_err());
1204 
1205  if (in.out_needed.is_set()) {
1206  // Read ATA output registers
1207  unsigned char regbuf[16] = {0, };
1208  memset(&io_hdr, 0, sizeof(io_hdr));
1209  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1210  io_hdr.dxfer_len = sizeof(regbuf);
1211  io_hdr.dxferp = regbuf;
1212 
1213  memset(cdb, 0, sizeof(cdb));
1214  cdb[ 0] = 0xD7; // Prolific read registers
1215  cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
1216  cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
1217  io_hdr.cmnd = cdb;
1218  io_hdr.cmnd_len = sizeof(cdb);
1219 
1220  if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1221  "usbprolific_device::scsi_pass_through (get registers): "))
1222  return set_err(scsidev->get_err());
1223 
1224  // Use '-r scsiioctl,2' to print input registers for debug purposes
1225  // Example: 50 00 00 00 00 01 4f 00 c2 00 a0 da 00 b0 00 50
1226  out.out_regs.status = regbuf[0]; // Status
1227  out.out_regs.error = regbuf[1]; // Error
1228  out.out_regs.sector_count = regbuf[2]; // Sector Count (7:0)
1229  out.out_regs.lba_low = regbuf[4]; // LBA Low (7:0)
1230  out.out_regs.lba_mid = regbuf[6]; // LBA Mid (7:0)
1231  out.out_regs.lba_high = regbuf[8]; // LBA High (7:0)
1232  out.out_regs.device = regbuf[10]; // Device/Head
1233  // = regbuf[11]; // ATA Feature (7:0)
1234  // = regbuf[13]; // ATA Command
1235  }
1236 
1237  return true;
1238 }
1239 
1240 
1241 /////////////////////////////////////////////////////////////////////////////
1242 
1243 /// SunplusIT USB Bridge support.
1244 
1246 : public tunnelled_device<
1247  /*implements*/ ata_device,
1248  /*by tunnelling through a*/ scsi_device
1249  >
1250 {
1251 public:
1252  usbsunplus_device(smart_interface * intf, scsi_device * scsidev,
1253  const char * req_type);
1254 
1255  virtual ~usbsunplus_device();
1256 
1257  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
1258 };
1259 
1260 
1262  const char * req_type)
1263 : smart_device(intf, scsidev->get_dev_name(), "usbsunplus", req_type),
1265 {
1266  set_info().info_name = strprintf("%s [USB Sunplus]", scsidev->get_info_name());
1267 }
1268 
1270 {
1271 }
1272 
1274 {
1275  if (!ata_cmd_is_supported(in,
1279  "Sunplus")
1280  )
1281  return false;
1282 
1283  scsi_cmnd_io io_hdr;
1284  unsigned char cdb[12];
1285 
1286  if (in.in_regs.is_48bit_cmd()) {
1287  // Set "previous" registers
1288  memset(&io_hdr, 0, sizeof(io_hdr));
1289  io_hdr.dxfer_dir = DXFER_NONE;
1290 
1291  cdb[ 0] = 0xf8;
1292  cdb[ 1] = 0x00;
1293  cdb[ 2] = 0x23; // Subcommand: Pass through presetting
1294  cdb[ 3] = 0x00;
1295  cdb[ 4] = 0x00;
1296  cdb[ 5] = in.in_regs.prev.features;
1297  cdb[ 6] = in.in_regs.prev.sector_count;
1298  cdb[ 7] = in.in_regs.prev.lba_low;
1299  cdb[ 8] = in.in_regs.prev.lba_mid;
1300  cdb[ 9] = in.in_regs.prev.lba_high;
1301  cdb[10] = 0x00;
1302  cdb[11] = 0x00;
1303 
1304  io_hdr.cmnd = cdb;
1305  io_hdr.cmnd_len = sizeof(cdb);
1306 
1307  scsi_device * scsidev = get_tunnel_dev();
1308  if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1309  "usbsunplus_device::scsi_pass_through (presetting): "))
1310  return set_err(scsidev->get_err());
1311  }
1312 
1313  // Run Pass through command
1314  memset(&io_hdr, 0, sizeof(io_hdr));
1315  unsigned char protocol;
1316  switch (in.direction) {
1317  case ata_cmd_in::no_data:
1318  io_hdr.dxfer_dir = DXFER_NONE;
1319  protocol = 0x00;
1320  break;
1321  case ata_cmd_in::data_in:
1322  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1323  io_hdr.dxfer_len = in.size;
1324  io_hdr.dxferp = (unsigned char *)in.buffer;
1325  memset(in.buffer, 0, in.size);
1326  protocol = 0x10;
1327  break;
1328  case ata_cmd_in::data_out:
1329  io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1330  io_hdr.dxfer_len = in.size;
1331  io_hdr.dxferp = (unsigned char *)in.buffer;
1332  protocol = 0x11;
1333  break;
1334  default:
1335  return set_err(EINVAL);
1336  }
1337 
1338  cdb[ 0] = 0xf8;
1339  cdb[ 1] = 0x00;
1340  cdb[ 2] = 0x22; // Subcommand: Pass through
1341  cdb[ 3] = protocol;
1342  cdb[ 4] = (unsigned char)(io_hdr.dxfer_len >> 9);
1343  cdb[ 5] = in.in_regs.features;
1344  cdb[ 6] = in.in_regs.sector_count;
1345  cdb[ 7] = in.in_regs.lba_low;
1346  cdb[ 8] = in.in_regs.lba_mid;
1347  cdb[ 9] = in.in_regs.lba_high;
1348  cdb[10] = in.in_regs.device | 0xa0;
1349  cdb[11] = in.in_regs.command;
1350 
1351  io_hdr.cmnd = cdb;
1352  io_hdr.cmnd_len = sizeof(cdb);
1353 
1354  scsi_device * scsidev = get_tunnel_dev();
1355  if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1356  "usbsunplus_device::scsi_pass_through: "))
1357  // Returns sense key 0x03 (medium error) on ATA command error
1358  return set_err(scsidev->get_err());
1359 
1360  if (in.out_needed.is_set()) {
1361  // Read ATA output registers
1362  unsigned char regbuf[8] = {0, };
1363  memset(&io_hdr, 0, sizeof(io_hdr));
1364  io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1365  io_hdr.dxfer_len = sizeof(regbuf);
1366  io_hdr.dxferp = regbuf;
1367 
1368  cdb[ 0] = 0xf8;
1369  cdb[ 1] = 0x00;
1370  cdb[ 2] = 0x21; // Subcommand: Get status
1371  memset(cdb+3, 0, sizeof(cdb)-3);
1372  io_hdr.cmnd = cdb;
1373  io_hdr.cmnd_len = sizeof(cdb);
1374 
1375  if (!scsidev->scsi_pass_through_and_check(&io_hdr,
1376  "usbsunplus_device::scsi_pass_through (get registers): "))
1377  return set_err(scsidev->get_err());
1378 
1379  out.out_regs.error = regbuf[1];
1380  out.out_regs.sector_count = regbuf[2];
1381  out.out_regs.lba_low = regbuf[3];
1382  out.out_regs.lba_mid = regbuf[4];
1383  out.out_regs.lba_high = regbuf[5];
1384  out.out_regs.device = regbuf[6];
1385  out.out_regs.status = regbuf[7];
1386  }
1387 
1388  return true;
1389 }
1390 
1391 
1392 } // namespace
1393 
1394 using namespace sat;
1395 
1396 
1397 /////////////////////////////////////////////////////////////////////////////
1398 
1399 // Return ATA->SCSI filter for SAT or USB.
1400 
1402 {
1403  if (!scsidev)
1404  throw std::logic_error("smart_interface: get_sat_device() called with scsidev=0");
1405 
1406  // Take temporary ownership of 'scsidev' to delete it on error
1407  scsi_device_auto_ptr scsidev_holder(scsidev);
1408  ata_device * satdev = 0;
1409 
1410  if (!strncmp(type, "sat", 3)) {
1411  const char * t = type + 3;
1413  if (!strncmp(t, ",auto", 5)) {
1414  t += 5;
1415  mode = sat_device::sat_auto;
1416  }
1417  int ptlen = 0, n = -1;
1418  if (*t && !(sscanf(t, ",%d%n", &ptlen, &n) == 1 && n == (int)strlen(t)
1419  && (ptlen == 0 || ptlen == 12 || ptlen == 16))) {
1420  set_err(EINVAL, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16");
1421  return 0;
1422  }
1423  satdev = new sat_device(this, scsidev, type, mode, ptlen);
1424  }
1425 
1426  else if (!strcmp(type, "scsi")) {
1427  satdev = new sat_device(this, scsidev, type, sat_device::scsi_always);
1428  }
1429 
1430  else if (!strncmp(type, "usbcypress", 10)) {
1431  unsigned signature = 0x24; int n1 = -1, n2 = -1;
1432  if (!(((sscanf(type, "usbcypress%n,0x%x%n", &n1, &signature, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type))
1433  && signature <= 0xff)) {
1434  set_err(EINVAL, "Option '-d usbcypress,<n>' requires <n> to be "
1435  "an hexadecimal number between 0x0 and 0xff");
1436  return 0;
1437  }
1438  satdev = new usbcypress_device(this, scsidev, type, signature);
1439  }
1440 
1441  else if (!strncmp(type, "usbjmicron", 10)) {
1442  const char * t = type + 10;
1443  bool prolific = false;
1444  if (!strncmp(t, ",p", 2)) {
1445  t += 2;
1446  prolific = true;
1447  }
1448  bool ata_48bit_support = false;
1449  if (!strncmp(t, ",x", 2)) {
1450  t += 2;
1451  ata_48bit_support = true;
1452  }
1453  int port = -1, n = -1;
1454  if (*t && !( (sscanf(t, ",%d%n", &port, &n) == 1
1455  && n == (int)strlen(t) && 0 <= port && port <= 1))) {
1456  set_err(EINVAL, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
1457  return 0;
1458  }
1459  satdev = new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
1460  }
1461 
1462  else if (!strcmp(type, "usbprolific")) {
1463  satdev = new usbprolific_device(this, scsidev, type);
1464  }
1465 
1466  else if (!strcmp(type, "usbsunplus")) {
1467  satdev = new usbsunplus_device(this, scsidev, type);
1468  }
1469 
1470  else {
1471  set_err(EINVAL, "Unknown USB device type '%s'", type);
1472  return 0;
1473  }
1474 
1475  // 'scsidev' is now owned by 'satdev'
1476  scsidev_holder.release();
1477  return satdev;
1478 }
1479 
1480 // Try to detect a SAT device behind a SCSI interface.
1481 
1483  const unsigned char * inqdata, unsigned inqsize)
1484 {
1485  if (!scsidev->is_open())
1486  return 0;
1487 
1488  // SAT ?
1489  if (inqdata && inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8)) {
1490  // TODO: Linux-specific? No, all SAT standards say the 'T10 Vendor
1491  // Identification' field shall be 'ATA '.
1492  ata_device_auto_ptr atadev( new sat_device(this, scsidev, "") , scsidev);
1493  if (has_sat_pass_through(atadev.get()))
1494  return atadev.release(); // Detected SAT
1495  }
1496 
1497  return 0;
1498 }
1499 
1500 
1501 /////////////////////////////////////////////////////////////////////////////
1502 // USB device type detection
1503 
1504 // Format USB ID for error messages
1505 static std::string format_usb_id(int vendor_id, int product_id, int version)
1506 {
1507  if (version >= 0)
1508  return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id, product_id, version);
1509  else
1510  return strprintf("[0x%04x:0x%04x]", vendor_id, product_id);
1511 }
1512 
1513 // Get type name for USB device with known VENDOR:PRODUCT ID.
1514 const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
1515  int version /*= -1*/)
1516 {
1517  usb_dev_info info, info2;
1518  int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
1519 
1520  if (n <= 0) {
1521  set_err(EINVAL, "Unknown USB bridge %s",
1522  format_usb_id(vendor_id, product_id, version).c_str());
1523  return 0;
1524  }
1525 
1526  if (n > 1) {
1527  set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
1528  format_usb_id(vendor_id, product_id, version).c_str(),
1529  (!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"),
1530  (!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
1531  return 0;
1532  }
1533 
1534  if (info.usb_type.empty()) {
1535  set_err(ENOSYS, "Unsupported USB bridge %s",
1536  format_usb_id(vendor_id, product_id, version).c_str());
1537  return 0;
1538  }
1539 
1540  // TODO: change return type to std::string
1541  static std::string type;
1542  type = info.usb_type;
1543  return type.c_str();
1544 }
#define ATA_SMART_AUTO_OFFLINE
Definition: atacmds.h:94
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:53
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:87
#define ATA_IDENTIFY_PACKET_DEVICE
Definition: atacmds.h:54
#define ATA_SMART_STATUS
Definition: atacmds.h:91
#define ATA_SMART_READ_VALUES
Definition: atacmds.h:81
#define ATA_SMART_READ_THRESHOLDS
Definition: atacmds.h:82
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:86
#define ATA_SMART_CMD
Definition: atacmds.h:56
#define ATA_SMART_IMMEDIATE_OFFLINE
Definition: atacmds.h:85
smart_command_set
Definition: atacmds.h:29
@ PIDENTIFY
Definition: atacmds.h:43
@ CHECK_POWER_MODE
Definition: atacmds.h:45
@ IDENTIFY
Definition: atacmds.h:42
@ STATUS_CHECK
Definition: atacmds.h:37
@ IMMEDIATE_OFFLINE
Definition: atacmds.h:34
@ AUTO_OFFLINE
Definition: atacmds.h:35
@ ENABLE
Definition: atacmds.h:31
@ WRITE_LOG
Definition: atacmds.h:47
@ READ_VALUES
Definition: atacmds.h:39
@ AUTOSAVE
Definition: atacmds.h:33
@ STATUS
Definition: atacmds.h:36
@ READ_THRESHOLDS
Definition: atacmds.h:40
@ DISABLE
Definition: atacmds.h:32
@ READ_LOG
Definition: atacmds.h:41
#define ATA_SMART_ENABLE
Definition: atacmds.h:89
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:83
#define ATA_SMART_DISABLE
Definition: atacmds.h:90
#define ATA_CHECK_POWER_MODE
Definition: atacmds.h:52
Smart pointer class for device pointers.
device_type * get() const
Return the pointer.
device_type * release()
Return the pointer and release ownership.
Adapter class to implement new ATA pass through old interface.
ATA device access.
@ supports_output_regs
@ supports_48bit_hi_null
@ supports_multi_sector
@ supports_smart_status
bool ata_cmd_is_supported(const ata_cmd_in &in, unsigned flags, const char *type=0)
Check command input parameters.
void hide_ata(bool hide=true)
Hide/unhide ATA interface.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)=0
ATA pass through.
SAT support.
Definition: scsiata.cpp:106
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: scsiata.cpp:248
virtual ~sat_device()
Definition: scsiata.cpp:151
virtual smart_device * autodetect_open() override
Open device with autodetection support.
Definition: scsiata.cpp:510
sat_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, sat_scsi_mode mode=sat_always, int passthrulen=0)
Definition: scsiata.cpp:131
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
Definition: scsiata.cpp:500
sat_scsi_mode m_mode
Definition: scsiata.cpp:127
Cypress USB Brigde support.
Definition: scsiata.cpp:610
unsigned char m_signature
Definition: scsiata.cpp:620
virtual ~usbcypress_device()
Definition: scsiata.cpp:633
virtual int ata_command_interface(smart_command_set command, int select, char *data) override
Old ATA interface called by ata_pass_through()
Definition: scsiata.cpp:640
usbcypress_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, unsigned char signature)
Definition: scsiata.cpp:624
JMicron USB Bridge support.
Definition: scsiata.cpp:882
virtual ~usbjmicron_device()
Definition: scsiata.cpp:914
bool get_registers(unsigned short addr, unsigned char *buf, unsigned short size)
Definition: scsiata.cpp:1067
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: scsiata.cpp:951
virtual bool open() override
Open device, return false on error.
Definition: scsiata.cpp:919
usbjmicron_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, bool prolific, bool ata_48bit_support, int port)
Definition: scsiata.cpp:903
Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
Definition: scsiata.cpp:1111
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: scsiata.cpp:1134
usbprolific_device(smart_interface *intf, scsi_device *scsidev, const char *req_type)
Definition: scsiata.cpp:1122
virtual ~usbprolific_device()
Definition: scsiata.cpp:1130
SunplusIT USB Bridge support.
Definition: scsiata.cpp:1250
virtual ~usbsunplus_device()
Definition: scsiata.cpp:1269
usbsunplus_device(smart_interface *intf, scsi_device *scsidev, const char *req_type)
Definition: scsiata.cpp:1261
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: scsiata.cpp:1273
SCSI device access.
void hide_scsi(bool hide=true)
Hide/unhide SCSI interface.
bool scsi_pass_through_and_check(scsi_cmnd_io *iop, const char *msg="")
virtual bool scsi_pass_through(scsi_cmnd_io *iop)=0
SCSI pass through.
Base class for all devices.
Definition: dev_interface.h:33
int get_errno() const
Get last error number.
const char * get_info_name() const
Get informal name.
const char * get_errmsg() const
Get last error message.
virtual bool close()=0
Close device, return false on error.
const error_info & get_err() const
Get last error info struct.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
const char * get_dev_type() const
Get device type.
virtual bool is_open() const =0
Return true if device is open.
virtual bool open()=0
Open device, return false on error.
device_info & set_info()
R/W access to device info struct.
The platform interface abstraction.
virtual const char * get_usb_dev_type_by_id(int vendor_id, int product_id, int version=-1)
Get type name for USB device with known VENDOR:PRODUCT ID.
Definition: scsiata.cpp:1514
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:1401
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:1482
virtual bool close() override
Close device, return false on error.
Implement a device by tunneling through another device.
Definition: dev_tunnelled.h:56
int lookup_usb_device(int vendor_id, int product_id, int bcd_device, usb_dev_info &info, usb_dev_info &info2)
u8 cdb[16]
Definition: megaraid.h:21
struct megasas_pd_address addr[MAX_SYS_PDS]
Definition: megaraid.h:2
ptr_t data
Definition: megaraid.h:15
u32 size
Definition: megaraid.h:0
uint32_t outlen
Definition: megaraid.h:1
Definition: scsiata.cpp:95
int smart_status(int fd)
#define SAT_ATA_PASSTHROUGH_16LEN
Definition: scsiata.cpp:89
#define ATA_RETURN_DESCRIPTOR
Definition: scsiata.cpp:92
#define USBCYPRESS_PASSTHROUGH_LEN
Definition: scsiata.cpp:639
#define SAT_ATA_PASSTHROUGH_12LEN
Definition: scsiata.cpp:88
const char * scsiata_cpp_cvsid
Definition: scsiata.cpp:58
#define DEF_SAT_ATA_PASSTHRU_SIZE
Definition: scsiata.cpp:91
static bool has_sat_pass_through(ata_device *dev, bool packet_interface=false)
Definition: scsiata.cpp:547
static int sg_scsi_normalize_sense(const unsigned char *sensep, int sb_len, struct sg_scsi_sense_hdr *sshp)
Definition: scsiata.cpp:565
static std::string format_usb_id(int vendor_id, int product_id, int version)
Definition: scsiata.cpp:1505
int scsiSimpleSenseFilter(const struct scsi_sense_disect *sinfo)
Definition: scsicmds.cpp:272
const char * scsiErrString(int scsiErr)
Definition: scsicmds.cpp:310
void scsi_do_sense_disect(const struct scsi_cmnd_io *io_buf, struct scsi_sense_disect *out)
Definition: scsicmds.cpp:250
const unsigned char * sg_scsi_sense_desc_find(const unsigned char *sensep, int sense_len, int desc_type)
Definition: scsicmds.cpp:2841
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
Definition: scsicmds.cpp:870
void dStrHex(const uint8_t *up, int len, int no_ascii)
Definition: scsicmds.cpp:78
unsigned char scsi_debugmode
Definition: scsicmds.cpp:45
#define SAT_ATA_PASSTHROUGH_12
Definition: scsicmds.h:89
#define DXFER_NONE
Definition: scsicmds.h:96
#define SCSI_ASCQ_ATA_PASS_THROUGH
Definition: scsicmds.h:319
#define DXFER_FROM_DEVICE
Definition: scsicmds.h:97
#define SCSI_TIMEOUT_DEFAULT
Definition: scsicmds.h:352
#define SAT_ATA_PASSTHROUGH_16
Definition: scsicmds.h:92
#define DXFER_TO_DEVICE
Definition: scsicmds.h:98
#define SCSI_STATUS_CHECK_CONDITION
Definition: scsicmds.h:298
#define SCSI_SK_NO_SENSE
Definition: scsicmds.h:301
#define SCSI_SK_RECOVERED_ERR
Definition: scsicmds.h:302
static void sg_put_unaligned_be32(uint32_t val, void *p)
Definition: sg_unaligned.h:279
static void sg_put_unaligned_be16(uint16_t val, void *p)
Definition: sg_unaligned.h:273
void pout(const char *fmt,...)
Definition: smartd.cpp:1308
ATA pass through input parameters.
enum ata_cmd_in::@29 direction
I/O direction.
void * buffer
Pointer to data buffer.
ata_in_regs_48bit in_regs
Input registers.
unsigned size
Size of buffer.
ata_out_regs_flags out_needed
True if output register value needed.
void set_data_in(void *buf, unsigned nsectors)
Prepare for 28-bit DATA IN command.
ATA pass through output parameters.
ata_out_regs_48bit out_regs
Output registers.
bool is_48bit_cmd() const
Return true if 48-bit command.
ata_in_regs prev
"previous content"
ATA Input registers (for 28-bit commands)
ata_register device
ata_register lba_high
ata_register sector_count
ata_register lba_low
ata_register features
ata_register command
ata_register lba_mid
ata_out_regs prev
read with HOB=1
bool is_set() const
Return true if any flag is set.
ATA Output registers (for 28-bit commands)
ata_register sector_count
ata_register lba_low
ata_register lba_mid
ata_register error
ata_register lba_high
ata_register device
ata_register status
uint8_t * sensep
Definition: scsicmds.h:108
uint8_t * dxferp
Definition: scsicmds.h:106
int dxfer_dir
Definition: scsicmds.h:104
size_t cmnd_len
Definition: scsicmds.h:103
size_t resp_sense_len
Definition: scsicmds.h:112
size_t dxfer_len
Definition: scsicmds.h:107
size_t max_sense_len
Definition: scsicmds.h:110
uint8_t scsi_status
Definition: scsicmds.h:113
uint8_t * cmnd
Definition: scsicmds.h:102
unsigned timeout
Definition: scsicmds.h:111
Abridged SCSI sense data.
Definition: scsiata.cpp:67
unsigned char byte4
Definition: scsiata.cpp:72
unsigned char byte6
Definition: scsiata.cpp:74
unsigned char asc
Definition: scsiata.cpp:70
unsigned char ascq
Definition: scsiata.cpp:71
unsigned char additional_length
Definition: scsiata.cpp:75
unsigned char sense_key
Definition: scsiata.cpp:69
unsigned char response_code
Definition: scsiata.cpp:68
unsigned char byte5
Definition: scsiata.cpp:73
std::string info_name
Informal name.
Definition: dev_interface.h:46
std::string dev_type
Actual device type.
Definition: dev_interface.h:47
Error (number,message) pair.
Definition: dev_interface.h:52
std::string msg
Error message.
Definition: dev_interface.h:61
int no
Error number.
Definition: dev_interface.h:60
std::string usb_type
Definition: knowndrives.h:31
void syserror(const char *message)
Definition: utility.cpp:382
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:772