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