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