]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - scsiata.cpp
Correct maintscript syntax
[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
d2e702cf 65const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 3922 2014-06-23 19:17:18Z chrfranke $";
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
206
207
208
209// PURPOSE
210// This interface routine takes ATA SMART commands and packages
211// them in the SAT-defined ATA PASS THROUGH SCSI commands. There are
212// two available SCSI commands: a 12 byte and 16 byte variant; the
2127e193 213// one used is chosen via this->m_passthrulen .
4d59bff9
GG
214// DETAILED DESCRIPTION OF ARGUMENTS
215// device: is the file descriptor provided by (a SCSI dvice type) open()
216// command: defines the different ATA operations.
217// select: additional input data if needed (which log, which type of
218// self-test).
219// data: location to write output data, if needed (512 bytes).
220// Note: not all commands use all arguments.
221// RETURN VALUES
222// -1 if the command failed
223// 0 if the command succeeded,
224// STATUS_CHECK routine:
225// -1 if the command failed
226// 0 if the command succeeded and disk SMART status is "OK"
227// 1 if the command succeeded and disk SMART status is "FAILING"
228
2127e193 229bool sat_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
4d59bff9 230{
ee38a438
GI
231 if (!ata_cmd_is_supported(in,
232 ata_device::supports_data_out |
233 ata_device::supports_output_regs |
234 ata_device::supports_multi_sector |
235 ata_device::supports_48bit,
236 "SAT")
2127e193
GI
237 )
238 return false;
239
4d59bff9
GG
240 struct scsi_cmnd_io io_hdr;
241 struct scsi_sense_disect sinfo;
242 struct sg_scsi_sense_hdr ssh;
243 unsigned char cdb[SAT_ATA_PASSTHROUGH_16LEN];
244 unsigned char sense[32];
1953ff6d
GG
245 const unsigned char * ardp;
246 int status, ard_len, have_sense;
4d59bff9 247 int extend = 0;
1953ff6d 248 int ck_cond = 0; /* set to 1 to read register(s) back */
4d59bff9
GG
249 int protocol = 3; /* non-data */
250 int t_dir = 1; /* 0 -> to device, 1 -> from device */
251 int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
252 int t_length = 0; /* 0 -> no data transferred */
4d59bff9
GG
253 int passthru_size = DEF_SAT_ATA_PASSTHRU_SIZE;
254
255 memset(cdb, 0, sizeof(cdb));
256 memset(sense, 0, sizeof(sense));
257
2127e193
GI
258 // Set data direction
259 // TODO: This works only for commands where sector_count holds count!
260 switch (in.direction) {
261 case ata_cmd_in::no_data:
4d59bff9 262 break;
2127e193
GI
263 case ata_cmd_in::data_in:
264 protocol = 4; // PIO data-in
265 t_length = 2; // sector_count holds count
4d59bff9 266 break;
2127e193
GI
267 case ata_cmd_in::data_out:
268 protocol = 5; // PIO data-out
269 t_length = 2; // sector_count holds count
270 t_dir = 0; // to device
4d59bff9 271 break;
2127e193
GI
272 default:
273 return set_err(EINVAL, "sat_device::ata_pass_through: invalid direction=%d",
274 (int)in.direction);
4d59bff9 275 }
2127e193
GI
276
277 // Check condition if any output register needed
278 if (in.out_needed.is_set())
279 ck_cond = 1;
280
281 if ((SAT_ATA_PASSTHROUGH_12LEN == m_passthrulen) ||
282 (SAT_ATA_PASSTHROUGH_16LEN == m_passthrulen))
283 passthru_size = m_passthrulen;
284
285 // Set extend bit on 48-bit ATA command
286 if (in.in_regs.is_48bit_cmd()) {
287 if (passthru_size != SAT_ATA_PASSTHROUGH_16LEN)
288 return set_err(ENOSYS, "48-bit ATA commands require SAT ATA PASS-THROUGH (16)");
289 extend = 1;
4d59bff9
GG
290 }
291
4d59bff9
GG
292 cdb[0] = (SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ?
293 SAT_ATA_PASSTHROUGH_12 : SAT_ATA_PASSTHROUGH_16;
294
295 cdb[1] = (protocol << 1) | extend;
1953ff6d 296 cdb[2] = (ck_cond << 5) | (t_dir << 3) |
4d59bff9 297 (byte_block << 2) | t_length;
2127e193
GI
298
299 if (passthru_size == SAT_ATA_PASSTHROUGH_12LEN) {
300 // ATA PASS-THROUGH (12)
301 const ata_in_regs & lo = in.in_regs;
302 cdb[3] = lo.features;
303 cdb[4] = lo.sector_count;
304 cdb[5] = lo.lba_low;
305 cdb[6] = lo.lba_mid;
306 cdb[7] = lo.lba_high;
307 cdb[8] = lo.device;
308 cdb[9] = lo.command;
309 }
310 else {
311 // ATA PASS-THROUGH (16)
312 const ata_in_regs & lo = in.in_regs;
313 const ata_in_regs & hi = in.in_regs.prev;
314 // Note: all 'in.in_regs.prev.*' are always zero for 28-bit commands
315 cdb[ 3] = hi.features;
316 cdb[ 4] = lo.features;
317 cdb[ 5] = hi.sector_count;
318 cdb[ 6] = lo.sector_count;
319 cdb[ 7] = hi.lba_low;
320 cdb[ 8] = lo.lba_low;
321 cdb[ 9] = hi.lba_mid;
322 cdb[10] = lo.lba_mid;
323 cdb[11] = hi.lba_high;
324 cdb[12] = lo.lba_high;
325 cdb[13] = lo.device;
326 cdb[14] = lo.command;
327 }
4d59bff9
GG
328
329 memset(&io_hdr, 0, sizeof(io_hdr));
330 if (0 == t_length) {
331 io_hdr.dxfer_dir = DXFER_NONE;
332 io_hdr.dxfer_len = 0;
333 } else if (t_dir) { /* from device */
334 io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
2127e193
GI
335 io_hdr.dxfer_len = in.size;
336 io_hdr.dxferp = (unsigned char *)in.buffer;
337 memset(in.buffer, 0, in.size); // prefill with zeroes
4d59bff9
GG
338 } else { /* to device */
339 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
2127e193
GI
340 io_hdr.dxfer_len = in.size;
341 io_hdr.dxferp = (unsigned char *)in.buffer;
4d59bff9
GG
342 }
343 io_hdr.cmnd = cdb;
344 io_hdr.cmnd_len = passthru_size;
345 io_hdr.sensep = sense;
346 io_hdr.max_sense_len = sizeof(sense);
347 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
348
2127e193
GI
349 scsi_device * scsidev = get_tunnel_dev();
350 if (!scsidev->scsi_pass_through(&io_hdr)) {
cfbba5b9 351 if (scsi_debugmode > 0)
2127e193
GI
352 pout("sat_device::ata_pass_through: scsi_pass_through() failed, "
353 "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
354 return set_err(scsidev->get_err());
4d59bff9 355 }
1953ff6d
GG
356 ardp = NULL;
357 ard_len = 0;
358 have_sense = sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len,
359 &ssh);
360 if (have_sense) {
361 /* look for SAT ATA Return Descriptor */
362 ardp = sg_scsi_sense_desc_find(io_hdr.sensep,
363 io_hdr.resp_sense_len,
364 ATA_RETURN_DESCRIPTOR);
365 if (ardp) {
366 ard_len = ardp[1] + 2;
367 if (ard_len < 12)
368 ard_len = 12;
369 else if (ard_len > 14)
370 ard_len = 14;
371 }
372 scsi_do_sense_disect(&io_hdr, &sinfo);
373 status = scsiSimpleSenseFilter(&sinfo);
374 if (0 != status) {
cfbba5b9 375 if (scsi_debugmode > 0) {
2127e193 376 pout("sat_device::ata_pass_through: scsi error: %s\n",
1953ff6d 377 scsiErrString(status));
cfbba5b9 378 if (ardp && (scsi_debugmode > 1)) {
1953ff6d
GG
379 pout("Values from ATA Return Descriptor are:\n");
380 dStrHex((const char *)ardp, ard_len, 1);
381 }
382 }
2127e193
GI
383 if (t_dir && (t_length > 0) && (in.direction == ata_cmd_in::data_in))
384 memset(in.buffer, 0, in.size);
385 return set_err(EIO, "scsi error %s", scsiErrString(status));
1953ff6d
GG
386 }
387 }
388 if (ck_cond) { /* expecting SAT specific sense data */
389 if (have_sense) {
390 if (ardp) {
cfbba5b9 391 if (scsi_debugmode > 1) {
1953ff6d
GG
392 pout("Values from ATA Return Descriptor are:\n");
393 dStrHex((const char *)ardp, ard_len, 1);
4d59bff9 394 }
2127e193
GI
395 // Set output registers
396 ata_out_regs & lo = out.out_regs;
397 lo.error = ardp[ 3];
398 lo.sector_count = ardp[ 5];
399 lo.lba_low = ardp[ 7];
400 lo.lba_mid = ardp[ 9];
401 lo.lba_high = ardp[11];
402 lo.device = ardp[12];
403 lo.status = ardp[13];
404 if (in.in_regs.is_48bit_cmd()) {
405 ata_out_regs & hi = out.out_regs.prev;
406 hi.sector_count = ardp[ 4];
407 hi.lba_low = ardp[ 6];
408 hi.lba_mid = ardp[ 8];
409 hi.lba_high = ardp[10];
4d59bff9
GG
410 }
411 }
412 }
1953ff6d
GG
413 if (ardp == NULL)
414 ck_cond = 0; /* not the type of sense data expected */
4d59bff9 415 }
1953ff6d
GG
416 if (0 == ck_cond) {
417 if (have_sense) {
4d59bff9
GG
418 if ((ssh.response_code >= 0x72) &&
419 ((SCSI_SK_NO_SENSE == ssh.sense_key) ||
420 (SCSI_SK_RECOVERED_ERR == ssh.sense_key)) &&
421 (0 == ssh.asc) &&
422 (SCSI_ASCQ_ATA_PASS_THROUGH == ssh.ascq)) {
1953ff6d 423 if (ardp) {
cfbba5b9 424 if (scsi_debugmode > 0) {
1953ff6d
GG
425 pout("Values from ATA Return Descriptor are:\n");
426 dStrHex((const char *)ardp, ard_len, 1);
4d59bff9 427 }
2127e193 428 return set_err(EIO, "SAT command failed");
4d59bff9
GG
429 }
430 }
4d59bff9
GG
431 }
432 }
2127e193 433 return true;
4d59bff9
GG
434}
435
d008864d
GI
436bool sat_device::scsi_pass_through(scsi_cmnd_io * iop)
437{
438 scsi_device * scsidev = get_tunnel_dev();
439 if (!scsidev->scsi_pass_through(iop)) {
440 set_err(scsidev->get_err());
441 return false;
442 }
443 return true;
444}
445
446smart_device * sat_device::autodetect_open()
447{
448 if (!open() || !m_enable_auto)
449 return this;
450
451 scsi_device * scsidev = get_tunnel_dev();
452
453 unsigned char inqdata[36] = {0, };
454 if (scsiStdInquiry(scsidev, inqdata, sizeof(inqdata))) {
455 smart_device::error_info err = scsidev->get_err();
456 close();
457 set_err(err.no, "INQUIRY [SAT]: %s", err.msg.c_str());
458 return this;
459 }
460
461 // Check for SAT "VENDOR"
462 int inqsize = inqdata[4] + 5;
463 bool sat = (inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8));
464
465 // Change interface
466 hide_ata(!sat);
467 hide_scsi(sat);
468
469 set_info().dev_type = (sat ? "sat" : scsidev->get_dev_type());
470 set_info().info_name = strprintf("%s [%s]", scsidev->get_info_name(),
471 (sat ? "SAT" : "SCSI"));
472 return this;
473}
474
2127e193
GI
475} // namespace
476
477/////////////////////////////////////////////////////////////////////////////
478
4d59bff9 479/* Attempt an IDENTIFY DEVICE ATA command via SATL when packet_interface
2127e193
GI
480 is false otherwise attempt IDENTIFY PACKET DEVICE. If successful
481 return true, else false */
482
483static bool has_sat_pass_through(ata_device * dev, bool packet_interface = false)
4d59bff9 484{
54965743
GI
485 /* Note: malloc() ensures the read buffer lands on a single
486 page. This avoids some bugs seen on LSI controlers under
487 FreeBSD */
488 char *data = (char *)malloc(512);
2127e193
GI
489 ata_cmd_in in;
490 in.in_regs.command = (packet_interface ? ATA_IDENTIFY_PACKET_DEVICE : ATA_IDENTIFY_DEVICE);
2127e193 491 in.set_data_in(data, 1);
54965743
GI
492 bool ret = dev->ata_pass_through(in);
493 free(data);
494 return ret;
4d59bff9
GG
495}
496
2127e193
GI
497/////////////////////////////////////////////////////////////////////////////
498
4d59bff9
GG
499/* Next two functions are borrowed from sg_lib.c in the sg3_utils
500 package. Same copyrght owner, same license as this file. */
2127e193
GI
501static int sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len,
502 struct sg_scsi_sense_hdr * sshp)
4d59bff9
GG
503{
504 if (sshp)
505 memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr));
506 if ((NULL == sensep) || (0 == sb_len) || (0x70 != (0x70 & sensep[0])))
507 return 0;
508 if (sshp) {
509 sshp->response_code = (0x7f & sensep[0]);
510 if (sshp->response_code >= 0x72) { /* descriptor format */
511 if (sb_len > 1)
512 sshp->sense_key = (0xf & sensep[1]);
513 if (sb_len > 2)
514 sshp->asc = sensep[2];
515 if (sb_len > 3)
516 sshp->ascq = sensep[3];
517 if (sb_len > 7)
518 sshp->additional_length = sensep[7];
519 } else { /* fixed format */
520 if (sb_len > 2)
521 sshp->sense_key = (0xf & sensep[2]);
522 if (sb_len > 7) {
523 sb_len = (sb_len < (sensep[7] + 8)) ? sb_len :
524 (sensep[7] + 8);
525 if (sb_len > 12)
526 sshp->asc = sensep[12];
527 if (sb_len > 13)
528 sshp->ascq = sensep[13];
529 }
530 }
531 }
532 return 1;
533}
534
535
2127e193
GI
536// Call scsi_pass_through and check sense.
537// TODO: Provide as member function of class scsi_device (?)
538static bool scsi_pass_through_and_check(scsi_device * scsidev, scsi_cmnd_io * iop,
539 const char * msg = "")
540{
541 // Provide sense buffer
542 unsigned char sense[32] = {0, };
543 iop->sensep = sense;
544 iop->max_sense_len = sizeof(sense);
545 iop->timeout = SCSI_TIMEOUT_DEFAULT;
546
547 // Run cmd
548 if (!scsidev->scsi_pass_through(iop)) {
cfbba5b9 549 if (scsi_debugmode > 0)
2127e193
GI
550 pout("%sscsi_pass_through() failed, errno=%d [%s]\n",
551 msg, scsidev->get_errno(), scsidev->get_errmsg());
552 return false;
553 }
554
555 // Check sense
556 scsi_sense_disect sinfo;
557 scsi_do_sense_disect(iop, &sinfo);
558 int err = scsiSimpleSenseFilter(&sinfo);
559 if (err) {
cfbba5b9 560 if (scsi_debugmode > 0)
2127e193
GI
561 pout("%sscsi error: %s\n", msg, scsiErrString(err));
562 return scsidev->set_err(EIO, "scsi error %s", scsiErrString(err));
563 }
564
565 return true;
566}
567
568
569/////////////////////////////////////////////////////////////////////////////
570
571namespace sat {
572
573/// Cypress USB Brigde support.
574
575class usbcypress_device
576: public tunnelled_device<
577 /*implements*/ ata_device_with_command_set
578 /*by tunnelling through a*/, scsi_device
579 >
580{
581public:
582 usbcypress_device(smart_interface * intf, scsi_device * scsidev,
583 const char * req_type, unsigned char signature);
584
585 virtual ~usbcypress_device() throw();
586
587protected:
588 virtual int ata_command_interface(smart_command_set command, int select, char * data);
589
590 unsigned char m_signature;
591};
592
593
594usbcypress_device::usbcypress_device(smart_interface * intf, scsi_device * scsidev,
595 const char * req_type, unsigned char signature)
596: smart_device(intf, scsidev->get_dev_name(), "sat", req_type),
597 tunnelled_device<ata_device_with_command_set, scsi_device>(scsidev),
598 m_signature(signature)
599{
600 set_info().info_name = strprintf("%s [USB Cypress]", scsidev->get_info_name());
601}
602
603usbcypress_device::~usbcypress_device() throw()
604{
605}
606
607
608/* see cy7c68300c_8.pdf for more information */
609#define USBCYPRESS_PASSTHROUGH_LEN 16
610int usbcypress_device::ata_command_interface(smart_command_set command, int select, char *data)
611{
612 struct scsi_cmnd_io io_hdr;
613 unsigned char cdb[USBCYPRESS_PASSTHROUGH_LEN];
614 unsigned char sense[32];
615 int copydata = 0;
616 int outlen = 0;
617 int ck_cond = 0; /* set to 1 to read register(s) back */
2127e193
GI
618 int t_dir = 1; /* 0 -> to device, 1 -> from device */
619 int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
620 int t_length = 0; /* 0 -> no data transferred */
621 int feature = 0;
622 int ata_command = 0;
623 int sector_count = 0;
624 int lba_low = 0;
625 int lba_mid = 0;
626 int lba_high = 0;
627 int passthru_size = USBCYPRESS_PASSTHROUGH_LEN;
628
629 memset(cdb, 0, sizeof(cdb));
630 memset(sense, 0, sizeof(sense));
631
632 ata_command = ATA_SMART_CMD;
633 switch (command) {
634 case CHECK_POWER_MODE:
635 ata_command = ATA_CHECK_POWER_MODE;
636 ck_cond = 1;
637 copydata = 1;
638 break;
639 case READ_VALUES: /* READ DATA */
640 feature = ATA_SMART_READ_VALUES;
641 sector_count = 1; /* one (512 byte) block */
2127e193
GI
642 t_length = 2; /* sector count holds count */
643 copydata = 512;
644 break;
645 case READ_THRESHOLDS: /* obsolete */
646 feature = ATA_SMART_READ_THRESHOLDS;
647 sector_count = 1; /* one (512 byte) block */
648 lba_low = 1;
2127e193
GI
649 t_length = 2; /* sector count holds count */
650 copydata=512;
651 break;
652 case READ_LOG:
653 feature = ATA_SMART_READ_LOG_SECTOR;
654 sector_count = 1; /* one (512 byte) block */
655 lba_low = select;
2127e193
GI
656 t_length = 2; /* sector count holds count */
657 copydata = 512;
658 break;
659 case WRITE_LOG:
660 feature = ATA_SMART_WRITE_LOG_SECTOR;
661 sector_count = 1; /* one (512 byte) block */
662 lba_low = select;
2127e193
GI
663 t_length = 2; /* sector count holds count */
664 t_dir = 0; /* to device */
665 outlen = 512;
666 break;
667 case IDENTIFY:
668 ata_command = ATA_IDENTIFY_DEVICE;
669 sector_count = 1; /* one (512 byte) block */
2127e193
GI
670 t_length = 2; /* sector count holds count */
671 copydata = 512;
672 break;
673 case PIDENTIFY:
674 ata_command = ATA_IDENTIFY_PACKET_DEVICE;
675 sector_count = 1; /* one (512 byte) block */
2127e193
GI
676 t_length = 2; /* sector count (7:0) holds count */
677 copydata = 512;
678 break;
679 case ENABLE:
680 feature = ATA_SMART_ENABLE;
681 lba_low = 1;
682 break;
683 case DISABLE:
684 feature = ATA_SMART_DISABLE;
685 lba_low = 1;
686 break;
687 case STATUS:
688 // this command only says if SMART is working. It could be
689 // replaced with STATUS_CHECK below.
690 feature = ATA_SMART_STATUS;
691 ck_cond = 1;
692 break;
693 case AUTO_OFFLINE:
694 feature = ATA_SMART_AUTO_OFFLINE;
695 sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
696 break;
697 case AUTOSAVE:
698 feature = ATA_SMART_AUTOSAVE;
699 sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
700 break;
701 case IMMEDIATE_OFFLINE:
702 feature = ATA_SMART_IMMEDIATE_OFFLINE;
703 lba_low = select;
704 break;
705 case STATUS_CHECK:
706 // This command uses HDIO_DRIVE_TASK and has different syntax than
707 // the other commands.
708 feature = ATA_SMART_STATUS; /* SMART RETURN STATUS */
709 ck_cond = 1;
710 break;
711 default:
712 pout("Unrecognized command %d in usbcypress_device::ata_command_interface()\n"
713 "Please contact " PACKAGE_BUGREPORT "\n", command);
714 errno=ENOSYS;
715 return -1;
716 }
717 if (ATA_SMART_CMD == ata_command) {
718 lba_mid = 0x4f;
719 lba_high = 0xc2;
720 }
721
722 cdb[0] = m_signature; // bVSCBSignature : vendor-specific command
723 cdb[1] = 0x24; // bVSCBSubCommand : 0x24 for ATACB
724 cdb[2] = 0x0;
725 if (ata_command == ATA_IDENTIFY_DEVICE || ata_command == ATA_IDENTIFY_PACKET_DEVICE)
726 cdb[2] |= (1<<7); //set IdentifyPacketDevice for these cmds
727 cdb[3] = 0xff - (1<<0) - (1<<6); //features, sector count, lba low, lba med
728 // lba high, command are valid
729 cdb[4] = byte_block; //TransferBlockCount : 512
730
731
732 cdb[6] = feature;
733 cdb[7] = sector_count;
734 cdb[8] = lba_low;
735 cdb[9] = lba_mid;
736 cdb[10] = lba_high;
737 cdb[12] = ata_command;
738
739 memset(&io_hdr, 0, sizeof(io_hdr));
740 if (0 == t_length) {
741 io_hdr.dxfer_dir = DXFER_NONE;
742 io_hdr.dxfer_len = 0;
743 } else if (t_dir) { /* from device */
744 io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
745 io_hdr.dxfer_len = copydata;
746 io_hdr.dxferp = (unsigned char *)data;
747 memset(data, 0, copydata); /* prefill with zeroes */
748 } else { /* to device */
749 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
750 io_hdr.dxfer_len = outlen;
751 io_hdr.dxferp = (unsigned char *)data;
752 }
753 io_hdr.cmnd = cdb;
754 io_hdr.cmnd_len = passthru_size;
755 io_hdr.sensep = sense;
756 io_hdr.max_sense_len = sizeof(sense);
757 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
758
759 scsi_device * scsidev = get_tunnel_dev();
760 if (!scsidev->scsi_pass_through(&io_hdr)) {
cfbba5b9 761 if (scsi_debugmode > 0)
2127e193
GI
762 pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
763 "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
764 set_err(scsidev->get_err());
765 return -1;
766 }
767
768 // if there is a sense the command failed or the
769 // device doesn't support usbcypress
770 if (io_hdr.scsi_status == SCSI_STATUS_CHECK_CONDITION &&
771 sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
772 return -1;
773 }
774 if (ck_cond) {
775 unsigned char ardp[8];
776 int ard_len = 8;
777 /* XXX this is racy if there other scsi command between
778 * the first usbcypress command and this one
779 */
780 //pout("If you got strange result, please retry without traffic on the disc\n");
781 /* we use the same command as before, but we set
782 * * the read taskfile bit, for not executing usbcypress command,
783 * * but reading register selected in srb->cmnd[4]
784 */
785 cdb[2] = (1<<0); /* ask read taskfile */
786 memset(sense, 0, sizeof(sense));
787
788 /* transfert 8 bytes */
789 memset(&io_hdr, 0, sizeof(io_hdr));
790 io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
791 io_hdr.dxfer_len = ard_len;
792 io_hdr.dxferp = (unsigned char *)ardp;
793 memset(ardp, 0, ard_len); /* prefill with zeroes */
794
795 io_hdr.cmnd = cdb;
796 io_hdr.cmnd_len = passthru_size;
797 io_hdr.sensep = sense;
798 io_hdr.max_sense_len = sizeof(sense);
799 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
800
801
802 if (!scsidev->scsi_pass_through(&io_hdr)) {
cfbba5b9 803 if (scsi_debugmode > 0)
2127e193
GI
804 pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
805 "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
806 set_err(scsidev->get_err());
807 return -1;
808 }
809 // if there is a sense the command failed or the
810 // device doesn't support usbcypress
811 if (io_hdr.scsi_status == SCSI_STATUS_CHECK_CONDITION &&
812 sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
813 return -1;
814 }
815
816
cfbba5b9 817 if (scsi_debugmode > 1) {
2127e193
GI
818 pout("Values from ATA Return Descriptor are:\n");
819 dStrHex((const char *)ardp, ard_len, 1);
820 }
821
822 if (ATA_CHECK_POWER_MODE == ata_command)
823 data[0] = ardp[2]; /* sector count (0:7) */
824 else if (STATUS_CHECK == command) {
825 if ((ardp[4] == 0x4f) && (ardp[5] == 0xc2))
826 return 0; /* GOOD smart status */
827 if ((ardp[4] == 0xf4) && (ardp[5] == 0x2c))
828 return 1; // smart predicting failure, "bad" status
829 // We haven't gotten output that makes sense so
830 // print out some debugging info
831 syserror("Error SMART Status command failed");
832 pout("This may be due to a race in usbcypress\n");
833 pout("Retry without other disc access\n");
834 pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
835 pout("Values from ATA Return Descriptor are:\n");
836 dStrHex((const char *)ardp, ard_len, 1);
837 return -1;
838 }
839 }
840 return 0;
841}
842
843#if 0 // Not used, see autodetect_sat_device() below.
844static int isprint_string(const char *s)
845{
846 while (*s) {
847 if (isprint(*s) == 0)
848 return 0;
849 s++;
850 }
851 return 1;
852}
853
854/* Attempt an IDENTIFY DEVICE ATA or IDENTIFY PACKET DEVICE command
855 If successful return 1, else 0 */
856// TODO: Combine with has_sat_pass_through above
857static int has_usbcypress_pass_through(ata_device * atadev, const char *manufacturer, const char *product)
858{
859 struct ata_identify_device drive;
860 char model[40], serial[20], firm[8];
861
862 /* issue the command and do a checksum if possible */
863 if (ataReadHDIdentity(atadev, &drive) < 0)
864 return 0;
865
866 /* check if model string match, revision doesn't work for me */
867 format_ata_string(model, drive.model, 40);
868 if (*model == 0 || isprint_string(model) == 0)
869 return 0;
870
871 if (manufacturer && strncmp(manufacturer, model, 8))
872 pout("manufacturer doesn't match in pass_through test\n");
873 if (product &&
874 strlen(model) > 8 && strncmp(product, model+8, strlen(model)-8))
875 pout("product doesn't match in pass_through test\n");
876
877 /* check serial */
878 format_ata_string(serial, drive.serial_no, 20);
879 if (isprint_string(serial) == 0)
880 return 0;
881 format_ata_string(firm, drive.fw_rev, 8);
882 if (isprint_string(firm) == 0)
883 return 0;
884 return 1;
885}
886#endif
887
888/////////////////////////////////////////////////////////////////////////////
889
890/// JMicron USB Bridge support.
891
892class usbjmicron_device
893: public tunnelled_device<
894 /*implements*/ ata_device,
895 /*by tunnelling through a*/ scsi_device
896 >
897{
898public:
899 usbjmicron_device(smart_interface * intf, scsi_device * scsidev,
ee38a438
GI
900 const char * req_type, bool prolific,
901 bool ata_48bit_support, int port);
2127e193
GI
902
903 virtual ~usbjmicron_device() throw();
904
905 virtual bool open();
906
907 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
908
909private:
910 bool get_registers(unsigned short addr, unsigned char * buf, unsigned short size);
911
ee38a438 912 bool m_prolific;
2127e193
GI
913 bool m_ata_48bit_support;
914 int m_port;
915};
916
917
918usbjmicron_device::usbjmicron_device(smart_interface * intf, scsi_device * scsidev,
ee38a438
GI
919 const char * req_type, bool prolific,
920 bool ata_48bit_support, int port)
2127e193
GI
921: smart_device(intf, scsidev->get_dev_name(), "usbjmicron", req_type),
922 tunnelled_device<ata_device, scsi_device>(scsidev),
ee38a438
GI
923 m_prolific(prolific), m_ata_48bit_support(ata_48bit_support),
924 m_port(port >= 0 || !prolific ? port : 0)
2127e193
GI
925{
926 set_info().info_name = strprintf("%s [USB JMicron]", scsidev->get_info_name());
927}
928
929usbjmicron_device::~usbjmicron_device() throw()
930{
931}
932
933
934bool usbjmicron_device::open()
935{
936 // Open USB first
937 if (!tunnelled_device<ata_device, scsi_device>::open())
938 return false;
939
940 // Detect port if not specified
941 if (m_port < 0) {
942 unsigned char regbuf[1] = {0};
943 if (!get_registers(0x720f, regbuf, sizeof(regbuf))) {
944 close();
945 return false;
946 }
947
948 switch (regbuf[0] & 0x44) {
949 case 0x04:
950 m_port = 0; break;
951 case 0x40:
952 m_port = 1; break;
953 case 0x44:
954 close();
955 return set_err(EINVAL, "Two devices connected, try '-d usbjmicron,[01]'");
956 default:
957 close();
958 return set_err(ENODEV, "No device connected");
959 }
960 }
961
962 return true;
963}
964
965
966bool usbjmicron_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
967{
ee38a438
GI
968 if (!ata_cmd_is_supported(in,
969 ata_device::supports_data_out |
970 ata_device::supports_smart_status |
971 (m_ata_48bit_support ? ata_device::supports_48bit_hi_null : 0),
972 "JMicron")
2127e193
GI
973 )
974 return false;
975
2127e193
GI
976 if (m_port < 0)
977 return set_err(EIO, "Unknown JMicron port");
978
979 scsi_cmnd_io io_hdr;
980 memset(&io_hdr, 0, sizeof(io_hdr));
981
982 bool rwbit = true;
d2e702cf 983 unsigned char smart_status = 0xff;
2127e193 984
ee38a438
GI
985 bool is_smart_status = ( in.in_regs.command == ATA_SMART_CMD
986 && in.in_regs.features == ATA_SMART_STATUS);
987
2127e193
GI
988 if (is_smart_status && in.out_needed.is_set()) {
989 io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
990 io_hdr.dxfer_len = 1;
991 io_hdr.dxferp = &smart_status;
992 }
993 else switch (in.direction) {
994 case ata_cmd_in::no_data:
995 io_hdr.dxfer_dir = DXFER_NONE;
996 break;
997 case ata_cmd_in::data_in:
998 io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
999 io_hdr.dxfer_len = in.size;
1000 io_hdr.dxferp = (unsigned char *)in.buffer;
1001 memset(in.buffer, 0, in.size);
1002 break;
1003 case ata_cmd_in::data_out:
1004 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1005 io_hdr.dxfer_len = in.size;
1006 io_hdr.dxferp = (unsigned char *)in.buffer;
1007 rwbit = false;
1008 break;
1009 default:
1010 return set_err(EINVAL);
1011 }
1012
1013 // Build pass through command
ee38a438 1014 unsigned char cdb[14];
2127e193
GI
1015 cdb[ 0] = 0xdf;
1016 cdb[ 1] = (rwbit ? 0x10 : 0x00);
1017 cdb[ 2] = 0x00;
1018 cdb[ 3] = (unsigned char)(io_hdr.dxfer_len >> 8);
1019 cdb[ 4] = (unsigned char)(io_hdr.dxfer_len );
1020 cdb[ 5] = in.in_regs.features;
1021 cdb[ 6] = in.in_regs.sector_count;
1022 cdb[ 7] = in.in_regs.lba_low;
1023 cdb[ 8] = in.in_regs.lba_mid;
1024 cdb[ 9] = in.in_regs.lba_high;
1025 cdb[10] = in.in_regs.device | (m_port == 0 ? 0xa0 : 0xb0);
1026 cdb[11] = in.in_regs.command;
ee38a438
GI
1027 // Prolific PL3507
1028 cdb[12] = 0x06;
1029 cdb[13] = 0x7b;
2127e193
GI
1030
1031 io_hdr.cmnd = cdb;
ee38a438 1032 io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
2127e193
GI
1033
1034 scsi_device * scsidev = get_tunnel_dev();
1035 if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1036 "usbjmicron_device::ata_pass_through: "))
1037 return set_err(scsidev->get_err());
1038
1039 if (in.out_needed.is_set()) {
1040 if (is_smart_status) {
d2e702cf
GI
1041 if (io_hdr.resid == 1)
1042 // Some (Prolific) USB bridges do not transfer a status byte
1043 return set_err(ENOSYS, "Incomplete response, status byte missing [JMicron]");
1044
2127e193 1045 switch (smart_status) {
d2e702cf 1046 case 0xc2:
2127e193
GI
1047 out.out_regs.lba_high = 0xc2;
1048 out.out_regs.lba_mid = 0x4f;
1049 break;
d2e702cf 1050 case 0x2c:
2127e193
GI
1051 out.out_regs.lba_high = 0x2c;
1052 out.out_regs.lba_mid = 0xf4;
1053 break;
d2e702cf
GI
1054 default:
1055 // Some (JM20336) USB bridges always return 0x01, regardless of SMART Status
1056 return set_err(ENOSYS, "Invalid status byte (0x%02x) [JMicron]", smart_status);
2127e193
GI
1057 }
1058 }
1059
1060#if 0 // Not needed for SMART STATUS, see also notes below
1061 else {
1062 // Read ATA output registers
1063 // NOTE: The register addresses are not valid for some older chip revisions
1064 // NOTE: There is a small race condition here!
1065 unsigned char regbuf[16] = {0, };
1066 if (!get_registers((m_port == 0 ? 0x8000 : 0x9000), regbuf, sizeof(regbuf)))
1067 return false;
1068
1069 out.out_regs.sector_count = regbuf[ 0];
1070 out.out_regs.lba_mid = regbuf[ 4];
1071 out.out_regs.lba_low = regbuf[ 6];
1072 out.out_regs.device = regbuf[ 9];
1073 out.out_regs.lba_high = regbuf[10];
1074 out.out_regs.error = regbuf[13];
1075 out.out_regs.status = regbuf[14];
1076 }
1077#endif
1078 }
1079
1080 return true;
1081}
1082
1083bool usbjmicron_device::get_registers(unsigned short addr,
1084 unsigned char * buf, unsigned short size)
1085{
ee38a438 1086 unsigned char cdb[14];
2127e193
GI
1087 cdb[ 0] = 0xdf;
1088 cdb[ 1] = 0x10;
1089 cdb[ 2] = 0x00;
1090 cdb[ 3] = (unsigned char)(size >> 8);
1091 cdb[ 4] = (unsigned char)(size );
1092 cdb[ 5] = 0x00;
1093 cdb[ 6] = (unsigned char)(addr >> 8);
1094 cdb[ 7] = (unsigned char)(addr );
1095 cdb[ 8] = 0x00;
1096 cdb[ 9] = 0x00;
1097 cdb[10] = 0x00;
1098 cdb[11] = 0xfd;
ee38a438
GI
1099 // Prolific PL3507
1100 cdb[12] = 0x06;
1101 cdb[13] = 0x7b;
2127e193
GI
1102
1103 scsi_cmnd_io io_hdr;
1104 memset(&io_hdr, 0, sizeof(io_hdr));
1105 io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1106 io_hdr.dxfer_len = size;
1107 io_hdr.dxferp = buf;
1108 io_hdr.cmnd = cdb;
1109 io_hdr.cmnd_len = sizeof(cdb);
ee38a438 1110 io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
2127e193
GI
1111
1112 scsi_device * scsidev = get_tunnel_dev();
1113 if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1114 "usbjmicron_device::get_registers: "))
1115 return set_err(scsidev->get_err());
1116
1117 return true;
1118}
1119
1120
1121/////////////////////////////////////////////////////////////////////////////
1122
1123/// SunplusIT USB Bridge support.
1124
1125class usbsunplus_device
1126: public tunnelled_device<
1127 /*implements*/ ata_device,
1128 /*by tunnelling through a*/ scsi_device
1129 >
1130{
1131public:
1132 usbsunplus_device(smart_interface * intf, scsi_device * scsidev,
1133 const char * req_type);
1134
1135 virtual ~usbsunplus_device() throw();
1136
1137 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
1138};
1139
1140
1141usbsunplus_device::usbsunplus_device(smart_interface * intf, scsi_device * scsidev,
1142 const char * req_type)
1143: smart_device(intf, scsidev->get_dev_name(), "usbsunplus", req_type),
1144 tunnelled_device<ata_device, scsi_device>(scsidev)
1145{
1146 set_info().info_name = strprintf("%s [USB Sunplus]", scsidev->get_info_name());
1147}
1148
1149usbsunplus_device::~usbsunplus_device() throw()
1150{
1151}
1152
1153bool usbsunplus_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
1154{
ee38a438
GI
1155 if (!ata_cmd_is_supported(in,
1156 ata_device::supports_data_out |
1157 ata_device::supports_output_regs |
1158 ata_device::supports_48bit,
1159 "Sunplus")
2127e193
GI
1160 )
1161 return false;
1162
1163 scsi_cmnd_io io_hdr;
1164 unsigned char cdb[12];
1165
1166 if (in.in_regs.is_48bit_cmd()) {
1167 // Set "previous" registers
1168 memset(&io_hdr, 0, sizeof(io_hdr));
1169 io_hdr.dxfer_dir = DXFER_NONE;
1170
1171 cdb[ 0] = 0xf8;
1172 cdb[ 1] = 0x00;
1173 cdb[ 2] = 0x23; // Subcommand: Pass through presetting
1174 cdb[ 3] = 0x00;
1175 cdb[ 4] = 0x00;
1176 cdb[ 5] = in.in_regs.prev.features;
1177 cdb[ 6] = in.in_regs.prev.sector_count;
1178 cdb[ 7] = in.in_regs.prev.lba_low;
1179 cdb[ 8] = in.in_regs.prev.lba_mid;
1180 cdb[ 9] = in.in_regs.prev.lba_high;
1181 cdb[10] = 0x00;
1182 cdb[11] = 0x00;
1183
1184 io_hdr.cmnd = cdb;
1185 io_hdr.cmnd_len = sizeof(cdb);
1186
1187 scsi_device * scsidev = get_tunnel_dev();
1188 if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1189 "usbsunplus_device::scsi_pass_through (presetting): "))
1190 return set_err(scsidev->get_err());
1191 }
1192
1193 // Run Pass through command
1194 memset(&io_hdr, 0, sizeof(io_hdr));
1195 unsigned char protocol;
1196 switch (in.direction) {
1197 case ata_cmd_in::no_data:
1198 io_hdr.dxfer_dir = DXFER_NONE;
1199 protocol = 0x00;
1200 break;
1201 case ata_cmd_in::data_in:
1202 io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1203 io_hdr.dxfer_len = in.size;
1204 io_hdr.dxferp = (unsigned char *)in.buffer;
1205 memset(in.buffer, 0, in.size);
1206 protocol = 0x10;
1207 break;
1208 case ata_cmd_in::data_out:
1209 io_hdr.dxfer_dir = DXFER_TO_DEVICE;
1210 io_hdr.dxfer_len = in.size;
1211 io_hdr.dxferp = (unsigned char *)in.buffer;
1212 protocol = 0x11;
1213 break;
1214 default:
1215 return set_err(EINVAL);
1216 }
1217
1218 cdb[ 0] = 0xf8;
1219 cdb[ 1] = 0x00;
1220 cdb[ 2] = 0x22; // Subcommand: Pass through
1221 cdb[ 3] = protocol;
1222 cdb[ 4] = (unsigned char)(io_hdr.dxfer_len >> 9);
1223 cdb[ 5] = in.in_regs.features;
1224 cdb[ 6] = in.in_regs.sector_count;
1225 cdb[ 7] = in.in_regs.lba_low;
1226 cdb[ 8] = in.in_regs.lba_mid;
1227 cdb[ 9] = in.in_regs.lba_high;
1228 cdb[10] = in.in_regs.device | 0xa0;
1229 cdb[11] = in.in_regs.command;
1230
1231 io_hdr.cmnd = cdb;
1232 io_hdr.cmnd_len = sizeof(cdb);
1233
1234 scsi_device * scsidev = get_tunnel_dev();
1235 if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1236 "usbsunplus_device::scsi_pass_through: "))
1237 // Returns sense key 0x03 (medium error) on ATA command error
1238 return set_err(scsidev->get_err());
1239
1240 if (in.out_needed.is_set()) {
1241 // Read ATA output registers
1242 unsigned char regbuf[8] = {0, };
1243 memset(&io_hdr, 0, sizeof(io_hdr));
1244 io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
1245 io_hdr.dxfer_len = sizeof(regbuf);
1246 io_hdr.dxferp = regbuf;
1247
1248 cdb[ 0] = 0xf8;
1249 cdb[ 1] = 0x00;
1250 cdb[ 2] = 0x21; // Subcommand: Get status
1251 memset(cdb+3, 0, sizeof(cdb)-3);
1252 io_hdr.cmnd = cdb;
1253 io_hdr.cmnd_len = sizeof(cdb);
1254
1255 if (!scsi_pass_through_and_check(scsidev, &io_hdr,
1256 "usbsunplus_device::scsi_pass_through (get registers): "))
1257 return set_err(scsidev->get_err());
1258
1259 out.out_regs.error = regbuf[1];
1260 out.out_regs.sector_count = regbuf[2];
1261 out.out_regs.lba_low = regbuf[3];
1262 out.out_regs.lba_mid = regbuf[4];
1263 out.out_regs.lba_high = regbuf[5];
1264 out.out_regs.device = regbuf[6];
1265 out.out_regs.status = regbuf[7];
1266 }
1267
1268 return true;
1269}
1270
1271
1272} // namespace
1273
1274using namespace sat;
1275
1276
1277/////////////////////////////////////////////////////////////////////////////
1278
1279// Return ATA->SCSI filter for SAT or USB.
1280
1281ata_device * smart_interface::get_sat_device(const char * type, scsi_device * scsidev)
1282{
1283 if (!strncmp(type, "sat", 3)) {
d008864d
GI
1284 const char * t = type + 3;
1285 bool enable_auto = false;
1286 if (!strncmp(t, ",auto", 5)) {
1287 t += 5;
1288 enable_auto = true;
1289 }
1290 int ptlen = 0, n = -1;
1291 if (*t && !(sscanf(t, ",%d%n", &ptlen, &n) == 1 && n == (int)strlen(t)
1292 && (ptlen == 0 || ptlen == 12 || ptlen == 16))) {
1293 set_err(EINVAL, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16");
2127e193
GI
1294 return 0;
1295 }
d008864d 1296 return new sat_device(this, scsidev, type, ptlen, enable_auto);
2127e193
GI
1297 }
1298
1299 else if (!strncmp(type, "usbcypress", 10)) {
1300 unsigned signature = 0x24; int n1 = -1, n2 = -1;
1301 if (!(((sscanf(type, "usbcypress%n,0x%x%n", &n1, &signature, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type))
1302 && signature <= 0xff)) {
1303 set_err(EINVAL, "Option '-d usbcypress,<n>' requires <n> to be "
1304 "an hexadecimal number between 0x0 and 0xff");
1305 return 0;
1306 }
1307 return new usbcypress_device(this, scsidev, type, signature);
1308 }
1309
1310 else if (!strncmp(type, "usbjmicron", 10)) {
1311 const char * t = type + 10;
ee38a438
GI
1312 bool prolific = false;
1313 if (!strncmp(t, ",p", 2)) {
1314 t += 2;
1315 prolific = true;
1316 }
2127e193
GI
1317 bool ata_48bit_support = false;
1318 if (!strncmp(t, ",x", 2)) {
1319 t += 2;
1320 ata_48bit_support = true;
1321 }
1322 int port = -1, n = -1;
1323 if (*t && !( (sscanf(t, ",%d%n", &port, &n) == 1
1324 && n == (int)strlen(t) && 0 <= port && port <= 1))) {
ee38a438 1325 set_err(EINVAL, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
2127e193
GI
1326 return 0;
1327 }
ee38a438 1328 return new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
2127e193
GI
1329 }
1330
1331 else if (!strcmp(type, "usbsunplus")) {
1332 return new usbsunplus_device(this, scsidev, type);
1333 }
1334
1335 else {
1336 set_err(EINVAL, "Unknown USB device type '%s'", type);
1337 return 0;
1338 }
1339}
1340
1341// Try to detect a SAT device behind a SCSI interface.
1342
1343ata_device * smart_interface::autodetect_sat_device(scsi_device * scsidev,
1344 const unsigned char * inqdata, unsigned inqsize)
1345{
1346 if (!scsidev->is_open())
1347 return 0;
1348
bed94269
GI
1349 // SAT ?
1350 if (inqdata && inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8)) { // TODO: Linux-specific?
1351 ata_device_auto_ptr atadev( new sat_device(this, scsidev, "") , scsidev);
1352 if (has_sat_pass_through(atadev.get()))
1353 return atadev.release(); // Detected SAT
2127e193
GI
1354 }
1355
1356 return 0;
1357}
1358
1359
1360/////////////////////////////////////////////////////////////////////////////
1361// USB device type detection
1362
2127e193
GI
1363// Format USB ID for error messages
1364static std::string format_usb_id(int vendor_id, int product_id, int version)
1365{
1366 if (version >= 0)
1367 return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id, product_id, version);
1368 else
1369 return strprintf("[0x%04x:0x%04x]", vendor_id, product_id);
1370}
1371
1372// Get type name for USB device with known VENDOR:PRODUCT ID.
1373const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
1374 int version /*= -1*/)
1375{
e9583e0c
GI
1376 usb_dev_info info, info2;
1377 int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
2127e193 1378
e9583e0c 1379 if (n <= 0) {
2127e193
GI
1380 set_err(EINVAL, "Unknown USB bridge %s",
1381 format_usb_id(vendor_id, product_id, version).c_str());
1382 return 0;
1383 }
e9583e0c
GI
1384
1385 if (n > 1) {
1386 set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
1387 format_usb_id(vendor_id, product_id, version).c_str(),
1388 (!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"),
1389 (!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
1390 return 0;
1391 }
1392
1393 if (info.usb_type.empty()) {
2127e193
GI
1394 set_err(ENOSYS, "Unsupported USB bridge %s",
1395 format_usb_id(vendor_id, product_id, version).c_str());
1396 return 0;
1397 }
e9583e0c
GI
1398
1399 // TODO: change return type to std::string
1400 static std::string type;
1401 type = info.usb_type;
1402 return type.c_str();
2127e193 1403}