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