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