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