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