Annotation of embedaddon/smartmontools/scsiata.cpp, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * scsiata.cpp
                      3:  *
                      4:  * Home page of code is: http://smartmontools.sourceforge.net
                      5:  *
                      6:  * Copyright (C) 2006-10 Douglas Gilbert <dgilbert@interlog.com>
                      7:  * Copyright (C) 2009-10 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 <stdlib.h>
                     52: #include <ctype.h>
                     53: #include <errno.h>
                     54: 
                     55: #include "config.h"
                     56: #include "int64.h"
                     57: #include "scsicmds.h"
                     58: #include "atacmds.h" // ataReadHDIdentity()
                     59: #include "knowndrives.h" // lookup_usb_device()
                     60: #include "utility.h"
                     61: #include "dev_interface.h"
                     62: #include "dev_ata_cmd_set.h" // ata_device_with_command_set
                     63: #include "dev_tunnelled.h" // tunnelled_device<>
                     64: 
                     65: const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 3441 2011-10-12 17:22:15Z chrfranke $";
                     66: 
                     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
                     74: struct 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). */
                     92: static 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. */
                     98: static 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: 
                    104: #define DEF_SAT_ATA_PASSTHRU_SIZE 16
                    105: #define ATA_RETURN_DESCRIPTOR 9
                    106: 
                    107: 
                    108: namespace sat { // no need to publish anything, name provided for Doxygen
                    109: 
                    110: /// SAT support.
                    111: /// Implements ATA by tunnelling through SCSI.
                    112: 
                    113: class sat_device
                    114: : public tunnelled_device<
                    115:     /*implements*/ ata_device
                    116:     /*by tunnelling through a*/, scsi_device
                    117:   >
                    118: {
                    119: public:
                    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: 
                    127: private:
                    128:   int m_passthrulen;
                    129: };
                    130: 
                    131: 
                    132: sat_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: 
                    141: sat_device::~sat_device() throw()
                    142: {
                    143: }
                    144: 
                    145: 
                    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: //
                    181: // ATA Return Descriptor (component of descriptor sense data)
                    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
                    203: //   one used is chosen via this->m_passthrulen .
                    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: 
                    219: bool sat_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
                    220: {
                    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: 
                    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];
                    233:     const unsigned char * ardp;
                    234:     int status, ard_len, have_sense;
                    235:     int extend = 0;
                    236:     int ck_cond = 0;    /* set to 1 to read register(s) back */
                    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 */
                    241:     int passthru_size = DEF_SAT_ATA_PASSTHRU_SIZE;
                    242: 
                    243:     memset(cdb, 0, sizeof(cdb));
                    244:     memset(sense, 0, sizeof(sense));
                    245: 
                    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:
                    250:         break;
                    251:       case ata_cmd_in::data_in:
                    252:         protocol = 4;  // PIO data-in
                    253:         t_length = 2;  // sector_count holds count
                    254:         break;
                    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
                    259:         break;
                    260:       default:
                    261:         return set_err(EINVAL, "sat_device::ata_pass_through: invalid direction=%d",
                    262:             (int)in.direction);
                    263:     }
                    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;
                    278:     }
                    279: 
                    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;
                    284:     cdb[2] = (ck_cond << 5) | (t_dir << 3) |
                    285:              (byte_block << 2) | t_length;
                    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:     }
                    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;
                    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
                    326:     } else {                    /* to device */
                    327:         io_hdr.dxfer_dir = DXFER_TO_DEVICE;
                    328:         io_hdr.dxfer_len = in.size;
                    329:         io_hdr.dxferp = (unsigned char *)in.buffer;
                    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: 
                    337:     scsi_device * scsidev = get_tunnel_dev();
                    338:     if (!scsidev->scsi_pass_through(&io_hdr)) {
                    339:         if (scsi_debugmode > 0)
                    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());
                    343:     }
                    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) {
                    363:             if (scsi_debugmode > 0) {
                    364:                 pout("sat_device::ata_pass_through: scsi error: %s\n",
                    365:                      scsiErrString(status));
                    366:                 if (ardp && (scsi_debugmode > 1)) {
                    367:                     pout("Values from ATA Return Descriptor are:\n");
                    368:                     dStrHex((const char *)ardp, ard_len, 1);
                    369:                 }
                    370:             }
                    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));
                    374:         }
                    375:     }
                    376:     if (ck_cond) {     /* expecting SAT specific sense data */
                    377:         if (have_sense) {
                    378:             if (ardp) {
                    379:                 if (scsi_debugmode > 1) {
                    380:                     pout("Values from ATA Return Descriptor are:\n");
                    381:                     dStrHex((const char *)ardp, ard_len, 1);
                    382:                 }
                    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];
                    398:                 }
                    399:             }
                    400:         }
                    401:         if (ardp == NULL)
                    402:             ck_cond = 0;       /* not the type of sense data expected */
                    403:     }
                    404:     if (0 == ck_cond) {
                    405:         if (have_sense) {
                    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)) {
                    411:                 if (ardp) {
                    412:                     if (scsi_debugmode > 0) {
                    413:                         pout("Values from ATA Return Descriptor are:\n");
                    414:                         dStrHex((const char *)ardp, ard_len, 1);
                    415:                     }
                    416:                     return set_err(EIO, "SAT command failed");
                    417:                 }
                    418:             }
                    419:         }
                    420:     }
                    421:     return true;
                    422: }
                    423: 
                    424: } // namespace
                    425: 
                    426: /////////////////////////////////////////////////////////////////////////////
                    427: 
                    428: /* Attempt an IDENTIFY DEVICE ATA command via SATL when packet_interface
                    429:    is false otherwise attempt IDENTIFY PACKET DEVICE. If successful
                    430:    return true, else false */
                    431: 
                    432: static bool has_sat_pass_through(ata_device * dev, bool packet_interface = false)
                    433: {
                    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);
                    438:     ata_cmd_in in;
                    439:     in.in_regs.command = (packet_interface ? ATA_IDENTIFY_PACKET_DEVICE : ATA_IDENTIFY_DEVICE);
                    440:     in.set_data_in(data, 1);
                    441:     bool ret = dev->ata_pass_through(in);
                    442:     free(data);
                    443:     return ret;
                    444: }
                    445: 
                    446: /////////////////////////////////////////////////////////////////////////////
                    447: 
                    448: /* Next two functions are borrowed from sg_lib.c in the sg3_utils
                    449:    package. Same copyrght owner, same license as this file. */
                    450: static int sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len,
                    451:                                    struct sg_scsi_sense_hdr * sshp)
                    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: 
                    485: static const unsigned char * sg_scsi_sense_desc_find(const unsigned char * sensep,
                    486:                                                      int sense_len, int desc_type)
                    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: }
                    509: 
                    510: 
                    511: // Call scsi_pass_through and check sense.
                    512: // TODO: Provide as member function of class scsi_device (?)
                    513: static 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)) {
                    524:     if (scsi_debugmode > 0)
                    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) {
                    535:     if (scsi_debugmode > 0)
                    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: 
                    546: namespace sat {
                    547: 
                    548: /// Cypress USB Brigde support.
                    549: 
                    550: class usbcypress_device
                    551: : public tunnelled_device<
                    552:     /*implements*/ ata_device_with_command_set
                    553:     /*by tunnelling through a*/, scsi_device
                    554:   >
                    555: {
                    556: public:
                    557:   usbcypress_device(smart_interface * intf, scsi_device * scsidev,
                    558:     const char * req_type, unsigned char signature);
                    559: 
                    560:   virtual ~usbcypress_device() throw();
                    561: 
                    562: protected:
                    563:   virtual int ata_command_interface(smart_command_set command, int select, char * data);
                    564: 
                    565:   unsigned char m_signature;
                    566: };
                    567: 
                    568: 
                    569: usbcypress_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: 
                    578: usbcypress_device::~usbcypress_device() throw()
                    579: {
                    580: }
                    581: 
                    582: 
                    583: /* see cy7c68300c_8.pdf for more information */
                    584: #define USBCYPRESS_PASSTHROUGH_LEN 16
                    585: int 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 t_dir = 1;      /* 0 -> to device, 1 -> from device */
                    594:     int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
                    595:     int t_length = 0;   /* 0 -> no data transferred */
                    596:     int feature = 0;
                    597:     int ata_command = 0;
                    598:     int sector_count = 0;
                    599:     int lba_low = 0;
                    600:     int lba_mid = 0;
                    601:     int lba_high = 0;
                    602:     int passthru_size = USBCYPRESS_PASSTHROUGH_LEN;
                    603: 
                    604:     memset(cdb, 0, sizeof(cdb));
                    605:     memset(sense, 0, sizeof(sense));
                    606: 
                    607:     ata_command = ATA_SMART_CMD;
                    608:     switch (command) {
                    609:     case CHECK_POWER_MODE:
                    610:         ata_command = ATA_CHECK_POWER_MODE;
                    611:         ck_cond = 1;
                    612:         copydata = 1;
                    613:         break;
                    614:     case READ_VALUES:           /* READ DATA */
                    615:         feature = ATA_SMART_READ_VALUES;
                    616:         sector_count = 1;     /* one (512 byte) block */
                    617:         t_length = 2;   /* sector count holds count */
                    618:         copydata = 512;
                    619:         break;
                    620:     case READ_THRESHOLDS:       /* obsolete */
                    621:         feature = ATA_SMART_READ_THRESHOLDS;
                    622:         sector_count = 1;     /* one (512 byte) block */
                    623:         lba_low = 1;
                    624:         t_length = 2;   /* sector count holds count */
                    625:         copydata=512;
                    626:         break;
                    627:     case READ_LOG:
                    628:         feature = ATA_SMART_READ_LOG_SECTOR;
                    629:         sector_count = 1;     /* one (512 byte) block */
                    630:         lba_low = select;
                    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:         t_length = 2;   /* sector count holds count */
                    639:         t_dir = 0;      /* to device */
                    640:         outlen = 512;
                    641:         break;
                    642:     case IDENTIFY:
                    643:         ata_command = ATA_IDENTIFY_DEVICE;
                    644:         sector_count = 1;     /* one (512 byte) block */
                    645:         t_length = 2;   /* sector count holds count */
                    646:         copydata = 512;
                    647:         break;
                    648:     case PIDENTIFY:
                    649:         ata_command = ATA_IDENTIFY_PACKET_DEVICE;
                    650:         sector_count = 1;     /* one (512 byte) block */
                    651:         t_length = 2;   /* sector count (7:0) holds count */
                    652:         copydata = 512;
                    653:         break;
                    654:     case ENABLE:
                    655:         feature = ATA_SMART_ENABLE;
                    656:         lba_low = 1;
                    657:         break;
                    658:     case DISABLE:
                    659:         feature = ATA_SMART_DISABLE;
                    660:         lba_low = 1;
                    661:         break;
                    662:     case STATUS:
                    663:         // this command only says if SMART is working.  It could be
                    664:         // replaced with STATUS_CHECK below.
                    665:         feature = ATA_SMART_STATUS;
                    666:         ck_cond = 1;
                    667:         break;
                    668:     case AUTO_OFFLINE:
                    669:         feature = ATA_SMART_AUTO_OFFLINE;
                    670:         sector_count = select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
                    671:         break;
                    672:     case AUTOSAVE:
                    673:         feature = ATA_SMART_AUTOSAVE;
                    674:         sector_count = select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
                    675:         break;
                    676:     case IMMEDIATE_OFFLINE:
                    677:         feature = ATA_SMART_IMMEDIATE_OFFLINE;
                    678:         lba_low = select;
                    679:         break;
                    680:     case STATUS_CHECK:
                    681:         // This command uses HDIO_DRIVE_TASK and has different syntax than
                    682:         // the other commands.
                    683:         feature = ATA_SMART_STATUS;      /* SMART RETURN STATUS */
                    684:         ck_cond = 1;
                    685:         break;
                    686:     default:
                    687:         pout("Unrecognized command %d in usbcypress_device::ata_command_interface()\n"
                    688:              "Please contact " PACKAGE_BUGREPORT "\n", command);
                    689:         errno=ENOSYS;
                    690:         return -1;
                    691:     }
                    692:     if (ATA_SMART_CMD == ata_command) {
                    693:         lba_mid = 0x4f;
                    694:         lba_high = 0xc2;
                    695:     }
                    696: 
                    697:     cdb[0] = m_signature; // bVSCBSignature : vendor-specific command
                    698:     cdb[1] = 0x24; // bVSCBSubCommand : 0x24 for ATACB
                    699:     cdb[2] = 0x0;
                    700:     if (ata_command == ATA_IDENTIFY_DEVICE || ata_command == ATA_IDENTIFY_PACKET_DEVICE)
                    701:         cdb[2] |= (1<<7); //set  IdentifyPacketDevice for these cmds
                    702:     cdb[3] = 0xff - (1<<0) - (1<<6); //features, sector count, lba low, lba med
                    703:                                      // lba high, command are valid
                    704:     cdb[4] = byte_block; //TransferBlockCount : 512
                    705: 
                    706: 
                    707:     cdb[6] = feature;
                    708:     cdb[7] = sector_count;
                    709:     cdb[8] = lba_low;
                    710:     cdb[9] = lba_mid;
                    711:     cdb[10] = lba_high;
                    712:     cdb[12] = ata_command;
                    713: 
                    714:     memset(&io_hdr, 0, sizeof(io_hdr));
                    715:     if (0 == t_length) {
                    716:         io_hdr.dxfer_dir = DXFER_NONE;
                    717:         io_hdr.dxfer_len = 0;
                    718:     } else if (t_dir) {         /* from device */
                    719:         io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
                    720:         io_hdr.dxfer_len = copydata;
                    721:         io_hdr.dxferp = (unsigned char *)data;
                    722:         memset(data, 0, copydata); /* prefill with zeroes */
                    723:     } else {                    /* to device */
                    724:         io_hdr.dxfer_dir = DXFER_TO_DEVICE;
                    725:         io_hdr.dxfer_len = outlen;
                    726:         io_hdr.dxferp = (unsigned char *)data;
                    727:     }
                    728:     io_hdr.cmnd = cdb;
                    729:     io_hdr.cmnd_len = passthru_size;
                    730:     io_hdr.sensep = sense;
                    731:     io_hdr.max_sense_len = sizeof(sense);
                    732:     io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
                    733: 
                    734:     scsi_device * scsidev = get_tunnel_dev();
                    735:     if (!scsidev->scsi_pass_through(&io_hdr)) {
                    736:         if (scsi_debugmode > 0)
                    737:             pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
                    738:                  "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
                    739:         set_err(scsidev->get_err());
                    740:         return -1;
                    741:     }
                    742: 
                    743:     // if there is a sense the command failed or the
                    744:     // device doesn't support usbcypress
                    745:     if (io_hdr.scsi_status == SCSI_STATUS_CHECK_CONDITION && 
                    746:             sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
                    747:         return -1;
                    748:     }
                    749:     if (ck_cond) {
                    750:         unsigned char ardp[8];
                    751:         int ard_len = 8;
                    752:         /* XXX this is racy if there other scsi command between
                    753:          * the first usbcypress command and this one
                    754:          */
                    755:         //pout("If you got strange result, please retry without traffic on the disc\n");
                    756:         /* we use the same command as before, but we set
                    757:          * * the read taskfile bit, for not executing usbcypress command,
                    758:          * * but reading register selected in srb->cmnd[4]
                    759:          */
                    760:         cdb[2] = (1<<0); /* ask read taskfile */
                    761:         memset(sense, 0, sizeof(sense));
                    762: 
                    763:         /* transfert 8 bytes */
                    764:         memset(&io_hdr, 0, sizeof(io_hdr));
                    765:         io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
                    766:         io_hdr.dxfer_len = ard_len;
                    767:         io_hdr.dxferp = (unsigned char *)ardp;
                    768:         memset(ardp, 0, ard_len); /* prefill with zeroes */
                    769: 
                    770:         io_hdr.cmnd = cdb;
                    771:         io_hdr.cmnd_len = passthru_size;
                    772:         io_hdr.sensep = sense;
                    773:         io_hdr.max_sense_len = sizeof(sense);
                    774:         io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
                    775: 
                    776: 
                    777:         if (!scsidev->scsi_pass_through(&io_hdr)) {
                    778:             if (scsi_debugmode > 0)
                    779:                 pout("usbcypress_device::ata_command_interface: scsi_pass_through() failed, "
                    780:                      "errno=%d [%s]\n", scsidev->get_errno(), scsidev->get_errmsg());
                    781:             set_err(scsidev->get_err());
                    782:             return -1;
                    783:         }
                    784:         // if there is a sense the command failed or the
                    785:         // device doesn't support usbcypress
                    786:         if (io_hdr.scsi_status == SCSI_STATUS_CHECK_CONDITION && 
                    787:                 sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len, NULL)) {
                    788:             return -1;
                    789:         }
                    790: 
                    791: 
                    792:         if (scsi_debugmode > 1) {
                    793:             pout("Values from ATA Return Descriptor are:\n");
                    794:             dStrHex((const char *)ardp, ard_len, 1);
                    795:         }
                    796: 
                    797:         if (ATA_CHECK_POWER_MODE == ata_command)
                    798:             data[0] = ardp[2];      /* sector count (0:7) */
                    799:         else if (STATUS_CHECK == command) {
                    800:             if ((ardp[4] == 0x4f) && (ardp[5] == 0xc2))
                    801:                 return 0;    /* GOOD smart status */
                    802:             if ((ardp[4] == 0xf4) && (ardp[5] == 0x2c))
                    803:                 return 1;    // smart predicting failure, "bad" status
                    804:             // We haven't gotten output that makes sense so
                    805:             // print out some debugging info
                    806:             syserror("Error SMART Status command failed");
                    807:             pout("This may be due to a race in usbcypress\n");
                    808:             pout("Retry without other disc access\n");
                    809:             pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
                    810:             pout("Values from ATA Return Descriptor are:\n");
                    811:             dStrHex((const char *)ardp, ard_len, 1);
                    812:             return -1;
                    813:         }
                    814:     }
                    815:     return 0;
                    816: }
                    817: 
                    818: #if 0 // Not used, see autodetect_sat_device() below.
                    819: static int isprint_string(const char *s)
                    820: {
                    821:     while (*s) {
                    822:         if (isprint(*s) == 0)
                    823:             return 0;
                    824:         s++;
                    825:     }
                    826:     return 1;
                    827: }
                    828: 
                    829: /* Attempt an IDENTIFY DEVICE ATA or IDENTIFY PACKET DEVICE command
                    830:    If successful return 1, else 0 */
                    831: // TODO: Combine with has_sat_pass_through above
                    832: static int has_usbcypress_pass_through(ata_device * atadev, const char *manufacturer, const char *product)
                    833: {
                    834:     struct ata_identify_device drive;
                    835:     char model[40], serial[20], firm[8];
                    836: 
                    837:     /* issue the command and do a checksum if possible */
                    838:     if (ataReadHDIdentity(atadev, &drive) < 0)
                    839:         return 0;
                    840: 
                    841:     /* check if model string match, revision doesn't work for me */
                    842:     format_ata_string(model, drive.model, 40);
                    843:     if (*model == 0 || isprint_string(model) == 0)
                    844:         return 0;
                    845: 
                    846:     if (manufacturer && strncmp(manufacturer, model, 8))
                    847:         pout("manufacturer doesn't match in pass_through test\n");
                    848:     if (product &&
                    849:             strlen(model) > 8 && strncmp(product, model+8, strlen(model)-8))
                    850:         pout("product doesn't match in pass_through test\n");
                    851: 
                    852:     /* check serial */
                    853:     format_ata_string(serial, drive.serial_no, 20);
                    854:     if (isprint_string(serial) == 0)
                    855:         return 0;
                    856:     format_ata_string(firm, drive.fw_rev, 8);
                    857:     if (isprint_string(firm) == 0)
                    858:         return 0;
                    859:     return 1;
                    860: }
                    861: #endif
                    862: 
                    863: /////////////////////////////////////////////////////////////////////////////
                    864: 
                    865: /// JMicron USB Bridge support.
                    866: 
                    867: class usbjmicron_device
                    868: : public tunnelled_device<
                    869:     /*implements*/ ata_device,
                    870:     /*by tunnelling through a*/ scsi_device
                    871:   >
                    872: {
                    873: public:
                    874:   usbjmicron_device(smart_interface * intf, scsi_device * scsidev,
                    875:                     const char * req_type, bool ata_48bit_support, int port);
                    876: 
                    877:   virtual ~usbjmicron_device() throw();
                    878: 
                    879:   virtual bool open();
                    880: 
                    881:   virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
                    882: 
                    883: private:
                    884:   bool get_registers(unsigned short addr, unsigned char * buf, unsigned short size);
                    885: 
                    886:   bool m_ata_48bit_support;
                    887:   int m_port;
                    888: };
                    889: 
                    890: 
                    891: usbjmicron_device::usbjmicron_device(smart_interface * intf, scsi_device * scsidev,
                    892:                                      const char * req_type, bool ata_48bit_support, int port)
                    893: : smart_device(intf, scsidev->get_dev_name(), "usbjmicron", req_type),
                    894:   tunnelled_device<ata_device, scsi_device>(scsidev),
                    895:   m_ata_48bit_support(ata_48bit_support), m_port(port)
                    896: {
                    897:   set_info().info_name = strprintf("%s [USB JMicron]", scsidev->get_info_name());
                    898: }
                    899: 
                    900: usbjmicron_device::~usbjmicron_device() throw()
                    901: {
                    902: }
                    903: 
                    904: 
                    905: bool usbjmicron_device::open()
                    906: {
                    907:   // Open USB first
                    908:   if (!tunnelled_device<ata_device, scsi_device>::open())
                    909:     return false;
                    910: 
                    911:   // Detect port if not specified
                    912:   if (m_port < 0) {
                    913:     unsigned char regbuf[1] = {0};
                    914:     if (!get_registers(0x720f, regbuf, sizeof(regbuf))) {
                    915:       close();
                    916:       return false;
                    917:     }
                    918: 
                    919:     switch (regbuf[0] & 0x44) {
                    920:       case 0x04:
                    921:         m_port = 0; break;
                    922:       case 0x40:
                    923:         m_port = 1; break;
                    924:       case 0x44:
                    925:         close();
                    926:         return set_err(EINVAL, "Two devices connected, try '-d usbjmicron,[01]'");
                    927:       default:
                    928:         close();
                    929:         return set_err(ENODEV, "No device connected");
                    930:     }
                    931:   }
                    932: 
                    933:   return true;
                    934: }
                    935: 
                    936: 
                    937: bool usbjmicron_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
                    938: {
                    939:   if (!ata_cmd_is_ok(in,
                    940:     true,  // data_out_support
                    941:     false, // !multi_sector_support
                    942:     m_ata_48bit_support) // limited, see below
                    943:   )
                    944:     return false;
                    945: 
                    946:   bool is_smart_status = (   in.in_regs.command  == ATA_SMART_CMD
                    947:                           && in.in_regs.features == ATA_SMART_STATUS);
                    948: 
                    949:   // Support output registers for SMART STATUS
                    950:   if (in.out_needed.is_set() && !is_smart_status)
                    951:     return set_err(ENOSYS, "ATA output registers not supported");
                    952: 
                    953:   // Support 48-bit commands with zero high bytes
                    954:   if (in.in_regs.is_real_48bit_cmd())
                    955:     return set_err(ENOSYS, "48-bit ATA commands not fully supported");
                    956: 
                    957:   if (m_port < 0)
                    958:     return set_err(EIO, "Unknown JMicron port");
                    959: 
                    960:   scsi_cmnd_io io_hdr;
                    961:   memset(&io_hdr, 0, sizeof(io_hdr));
                    962: 
                    963:   bool rwbit = true;
                    964:   unsigned char smart_status = 0;
                    965: 
                    966:   if (is_smart_status && in.out_needed.is_set()) {
                    967:     io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
                    968:     io_hdr.dxfer_len = 1;
                    969:     io_hdr.dxferp = &smart_status;
                    970:   }
                    971:   else switch (in.direction) {
                    972:     case ata_cmd_in::no_data:
                    973:       io_hdr.dxfer_dir = DXFER_NONE;
                    974:       break;
                    975:     case ata_cmd_in::data_in:
                    976:       io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
                    977:       io_hdr.dxfer_len = in.size;
                    978:       io_hdr.dxferp = (unsigned char *)in.buffer;
                    979:       memset(in.buffer, 0, in.size);
                    980:       break;
                    981:     case ata_cmd_in::data_out:
                    982:       io_hdr.dxfer_dir = DXFER_TO_DEVICE;
                    983:       io_hdr.dxfer_len = in.size;
                    984:       io_hdr.dxferp = (unsigned char *)in.buffer;
                    985:       rwbit = false;
                    986:       break;
                    987:     default:
                    988:       return set_err(EINVAL);
                    989:   }
                    990: 
                    991:   // Build pass through command
                    992:   unsigned char cdb[12];
                    993:   cdb[ 0] = 0xdf;
                    994:   cdb[ 1] = (rwbit ? 0x10 : 0x00);
                    995:   cdb[ 2] = 0x00;
                    996:   cdb[ 3] = (unsigned char)(io_hdr.dxfer_len >> 8);
                    997:   cdb[ 4] = (unsigned char)(io_hdr.dxfer_len     );
                    998:   cdb[ 5] = in.in_regs.features;
                    999:   cdb[ 6] = in.in_regs.sector_count;
                   1000:   cdb[ 7] = in.in_regs.lba_low;
                   1001:   cdb[ 8] = in.in_regs.lba_mid;
                   1002:   cdb[ 9] = in.in_regs.lba_high;
                   1003:   cdb[10] = in.in_regs.device | (m_port == 0 ? 0xa0 : 0xb0);
                   1004:   cdb[11] = in.in_regs.command;
                   1005: 
                   1006:   io_hdr.cmnd = cdb;
                   1007:   io_hdr.cmnd_len = sizeof(cdb);
                   1008: 
                   1009:   scsi_device * scsidev = get_tunnel_dev();
                   1010:   if (!scsi_pass_through_and_check(scsidev, &io_hdr,
                   1011:          "usbjmicron_device::ata_pass_through: "))
                   1012:     return set_err(scsidev->get_err());
                   1013: 
                   1014:   if (in.out_needed.is_set()) {
                   1015:     if (is_smart_status) {
                   1016:       switch (smart_status) {
                   1017:         case 0x01: case 0xc2:
                   1018:           out.out_regs.lba_high = 0xc2;
                   1019:           out.out_regs.lba_mid = 0x4f;
                   1020:           break;
                   1021:         case 0x00: case 0x2c:
                   1022:           out.out_regs.lba_high = 0x2c;
                   1023:           out.out_regs.lba_mid = 0xf4;
                   1024:           break;
                   1025:       }
                   1026:     }
                   1027: 
                   1028: #if 0 // Not needed for SMART STATUS, see also notes below
                   1029:     else {
                   1030:       // Read ATA output registers
                   1031:       // NOTE: The register addresses are not valid for some older chip revisions
                   1032:       // NOTE: There is a small race condition here!
                   1033:       unsigned char regbuf[16] = {0, };
                   1034:       if (!get_registers((m_port == 0 ? 0x8000 : 0x9000), regbuf, sizeof(regbuf)))
                   1035:         return false;
                   1036: 
                   1037:       out.out_regs.sector_count = regbuf[ 0];
                   1038:       out.out_regs.lba_mid      = regbuf[ 4];
                   1039:       out.out_regs.lba_low      = regbuf[ 6];
                   1040:       out.out_regs.device       = regbuf[ 9];
                   1041:       out.out_regs.lba_high     = regbuf[10];
                   1042:       out.out_regs.error        = regbuf[13];
                   1043:       out.out_regs.status       = regbuf[14];
                   1044:     }
                   1045: #endif
                   1046:   }
                   1047: 
                   1048:   return true;
                   1049: }
                   1050: 
                   1051: bool usbjmicron_device::get_registers(unsigned short addr,
                   1052:                                       unsigned char * buf, unsigned short size)
                   1053: {
                   1054:   unsigned char cdb[12];
                   1055:   cdb[ 0] = 0xdf;
                   1056:   cdb[ 1] = 0x10;
                   1057:   cdb[ 2] = 0x00;
                   1058:   cdb[ 3] = (unsigned char)(size >> 8);
                   1059:   cdb[ 4] = (unsigned char)(size     );
                   1060:   cdb[ 5] = 0x00;
                   1061:   cdb[ 6] = (unsigned char)(addr >> 8);
                   1062:   cdb[ 7] = (unsigned char)(addr     );
                   1063:   cdb[ 8] = 0x00;
                   1064:   cdb[ 9] = 0x00;
                   1065:   cdb[10] = 0x00;
                   1066:   cdb[11] = 0xfd;
                   1067: 
                   1068:   scsi_cmnd_io io_hdr;
                   1069:   memset(&io_hdr, 0, sizeof(io_hdr));
                   1070:   io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
                   1071:   io_hdr.dxfer_len = size;
                   1072:   io_hdr.dxferp = buf;
                   1073:   io_hdr.cmnd = cdb;
                   1074:   io_hdr.cmnd_len = sizeof(cdb);
                   1075: 
                   1076:   scsi_device * scsidev = get_tunnel_dev();
                   1077:   if (!scsi_pass_through_and_check(scsidev, &io_hdr,
                   1078:          "usbjmicron_device::get_registers: "))
                   1079:     return set_err(scsidev->get_err());
                   1080: 
                   1081:   return true;
                   1082: }
                   1083: 
                   1084: 
                   1085: /////////////////////////////////////////////////////////////////////////////
                   1086: 
                   1087: /// SunplusIT USB Bridge support.
                   1088: 
                   1089: class usbsunplus_device
                   1090: : public tunnelled_device<
                   1091:     /*implements*/ ata_device,
                   1092:     /*by tunnelling through a*/ scsi_device
                   1093:   >
                   1094: {
                   1095: public:
                   1096:   usbsunplus_device(smart_interface * intf, scsi_device * scsidev,
                   1097:                     const char * req_type);
                   1098: 
                   1099:   virtual ~usbsunplus_device() throw();
                   1100: 
                   1101:   virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
                   1102: };
                   1103: 
                   1104: 
                   1105: usbsunplus_device::usbsunplus_device(smart_interface * intf, scsi_device * scsidev,
                   1106:                                      const char * req_type)
                   1107: : smart_device(intf, scsidev->get_dev_name(), "usbsunplus", req_type),
                   1108:   tunnelled_device<ata_device, scsi_device>(scsidev)
                   1109: {
                   1110:   set_info().info_name = strprintf("%s [USB Sunplus]", scsidev->get_info_name());
                   1111: }
                   1112: 
                   1113: usbsunplus_device::~usbsunplus_device() throw()
                   1114: {
                   1115: }
                   1116: 
                   1117: bool usbsunplus_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
                   1118: {
                   1119:   if (!ata_cmd_is_ok(in,
                   1120:     true,  // data_out_support
                   1121:     false, // !multi_sector_support
                   1122:     true)  // ata_48bit_support
                   1123:   )
                   1124:     return false;
                   1125: 
                   1126:   scsi_cmnd_io io_hdr;
                   1127:   unsigned char cdb[12];
                   1128: 
                   1129:   if (in.in_regs.is_48bit_cmd()) {
                   1130:     // Set "previous" registers
                   1131:     memset(&io_hdr, 0, sizeof(io_hdr));
                   1132:     io_hdr.dxfer_dir = DXFER_NONE;
                   1133: 
                   1134:     cdb[ 0] = 0xf8;
                   1135:     cdb[ 1] = 0x00;
                   1136:     cdb[ 2] = 0x23; // Subcommand: Pass through presetting
                   1137:     cdb[ 3] = 0x00;
                   1138:     cdb[ 4] = 0x00;
                   1139:     cdb[ 5] = in.in_regs.prev.features;
                   1140:     cdb[ 6] = in.in_regs.prev.sector_count;
                   1141:     cdb[ 7] = in.in_regs.prev.lba_low;
                   1142:     cdb[ 8] = in.in_regs.prev.lba_mid;
                   1143:     cdb[ 9] = in.in_regs.prev.lba_high;
                   1144:     cdb[10] = 0x00;
                   1145:     cdb[11] = 0x00;
                   1146: 
                   1147:     io_hdr.cmnd = cdb;
                   1148:     io_hdr.cmnd_len = sizeof(cdb);
                   1149: 
                   1150:     scsi_device * scsidev = get_tunnel_dev();
                   1151:     if (!scsi_pass_through_and_check(scsidev, &io_hdr,
                   1152:            "usbsunplus_device::scsi_pass_through (presetting): "))
                   1153:       return set_err(scsidev->get_err());
                   1154:   }
                   1155: 
                   1156:   // Run Pass through command
                   1157:   memset(&io_hdr, 0, sizeof(io_hdr));
                   1158:   unsigned char protocol;
                   1159:   switch (in.direction) {
                   1160:     case ata_cmd_in::no_data:
                   1161:       io_hdr.dxfer_dir = DXFER_NONE;
                   1162:       protocol = 0x00;
                   1163:       break;
                   1164:     case ata_cmd_in::data_in:
                   1165:       io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
                   1166:       io_hdr.dxfer_len = in.size;
                   1167:       io_hdr.dxferp = (unsigned char *)in.buffer;
                   1168:       memset(in.buffer, 0, in.size);
                   1169:       protocol = 0x10;
                   1170:       break;
                   1171:     case ata_cmd_in::data_out:
                   1172:       io_hdr.dxfer_dir = DXFER_TO_DEVICE;
                   1173:       io_hdr.dxfer_len = in.size;
                   1174:       io_hdr.dxferp = (unsigned char *)in.buffer;
                   1175:       protocol = 0x11;
                   1176:       break;
                   1177:     default:
                   1178:       return set_err(EINVAL);
                   1179:   }
                   1180: 
                   1181:   cdb[ 0] = 0xf8;
                   1182:   cdb[ 1] = 0x00;
                   1183:   cdb[ 2] = 0x22; // Subcommand: Pass through
                   1184:   cdb[ 3] = protocol;
                   1185:   cdb[ 4] = (unsigned char)(io_hdr.dxfer_len >> 9);
                   1186:   cdb[ 5] = in.in_regs.features;
                   1187:   cdb[ 6] = in.in_regs.sector_count;
                   1188:   cdb[ 7] = in.in_regs.lba_low;
                   1189:   cdb[ 8] = in.in_regs.lba_mid;
                   1190:   cdb[ 9] = in.in_regs.lba_high;
                   1191:   cdb[10] = in.in_regs.device | 0xa0;
                   1192:   cdb[11] = in.in_regs.command;
                   1193: 
                   1194:   io_hdr.cmnd = cdb;
                   1195:   io_hdr.cmnd_len = sizeof(cdb);
                   1196: 
                   1197:   scsi_device * scsidev = get_tunnel_dev();
                   1198:   if (!scsi_pass_through_and_check(scsidev, &io_hdr,
                   1199:          "usbsunplus_device::scsi_pass_through: "))
                   1200:     // Returns sense key 0x03 (medium error) on ATA command error
                   1201:     return set_err(scsidev->get_err());
                   1202: 
                   1203:   if (in.out_needed.is_set()) {
                   1204:     // Read ATA output registers
                   1205:     unsigned char regbuf[8] = {0, };
                   1206:     memset(&io_hdr, 0, sizeof(io_hdr));
                   1207:     io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
                   1208:     io_hdr.dxfer_len = sizeof(regbuf);
                   1209:     io_hdr.dxferp = regbuf;
                   1210: 
                   1211:     cdb[ 0] = 0xf8;
                   1212:     cdb[ 1] = 0x00;
                   1213:     cdb[ 2] = 0x21; // Subcommand: Get status
                   1214:     memset(cdb+3, 0, sizeof(cdb)-3);
                   1215:     io_hdr.cmnd = cdb;
                   1216:     io_hdr.cmnd_len = sizeof(cdb);
                   1217: 
                   1218:     if (!scsi_pass_through_and_check(scsidev, &io_hdr,
                   1219:            "usbsunplus_device::scsi_pass_through (get registers): "))
                   1220:       return set_err(scsidev->get_err());
                   1221: 
                   1222:     out.out_regs.error        = regbuf[1];
                   1223:     out.out_regs.sector_count = regbuf[2];
                   1224:     out.out_regs.lba_low      = regbuf[3];
                   1225:     out.out_regs.lba_mid      = regbuf[4];
                   1226:     out.out_regs.lba_high     = regbuf[5];
                   1227:     out.out_regs.device       = regbuf[6];
                   1228:     out.out_regs.status       = regbuf[7];
                   1229:   }
                   1230: 
                   1231:   return true;
                   1232: }
                   1233: 
                   1234: 
                   1235: } // namespace
                   1236: 
                   1237: using namespace sat;
                   1238: 
                   1239: 
                   1240: /////////////////////////////////////////////////////////////////////////////
                   1241: 
                   1242: // Return ATA->SCSI filter for SAT or USB.
                   1243: 
                   1244: ata_device * smart_interface::get_sat_device(const char * type, scsi_device * scsidev)
                   1245: {
                   1246:   if (!strncmp(type, "sat", 3)) {
                   1247:     int ptlen = 0, n1 = -1, n2 = -1;
                   1248:     if (!(((sscanf(type, "sat%n,%d%n", &n1, &ptlen, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type))
                   1249:         && (ptlen == 0 || ptlen == 12 || ptlen == 16))) {
                   1250:       set_err(EINVAL, "Option '-d sat,<n>' requires <n> to be 0, 12 or 16");
                   1251:       return 0;
                   1252:     }
                   1253:     return new sat_device(this, scsidev, type, ptlen);
                   1254:   }
                   1255: 
                   1256:   else if (!strncmp(type, "usbcypress", 10)) {
                   1257:     unsigned signature = 0x24; int n1 = -1, n2 = -1;
                   1258:     if (!(((sscanf(type, "usbcypress%n,0x%x%n", &n1, &signature, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type))
                   1259:           && signature <= 0xff)) {
                   1260:       set_err(EINVAL, "Option '-d usbcypress,<n>' requires <n> to be "
                   1261:                       "an hexadecimal number between 0x0 and 0xff");
                   1262:       return 0;
                   1263:     }
                   1264:     return new usbcypress_device(this, scsidev, type, signature);
                   1265:   }
                   1266: 
                   1267:   else if (!strncmp(type, "usbjmicron", 10)) {
                   1268:     const char * t = type + 10;
                   1269:     bool ata_48bit_support = false;
                   1270:     if (!strncmp(t, ",x", 2)) {
                   1271:       t += 2;
                   1272:       ata_48bit_support = true;
                   1273:     }
                   1274:     int port = -1, n = -1;
                   1275:     if (*t && !(  (sscanf(t, ",%d%n", &port, &n) == 1
                   1276:                 && n == (int)strlen(t) && 0 <= port && port <= 1))) {
                   1277:       set_err(EINVAL, "Option '-d usbmicron[,x],<n>' requires <n> to be 0 or 1");
                   1278:       return 0;
                   1279:     }
                   1280:     return new usbjmicron_device(this, scsidev, type, ata_48bit_support, port);
                   1281:   }
                   1282: 
                   1283:   else if (!strcmp(type, "usbsunplus")) {
                   1284:     return new usbsunplus_device(this, scsidev, type);
                   1285:   }
                   1286: 
                   1287:   else {
                   1288:     set_err(EINVAL, "Unknown USB device type '%s'", type);
                   1289:     return 0;
                   1290:   }
                   1291: }
                   1292: 
                   1293: // Try to detect a SAT device behind a SCSI interface.
                   1294: 
                   1295: ata_device * smart_interface::autodetect_sat_device(scsi_device * scsidev,
                   1296:   const unsigned char * inqdata, unsigned inqsize)
                   1297: {
                   1298:   if (!scsidev->is_open())
                   1299:     return 0;
                   1300: 
                   1301:   // SAT ?
                   1302:   if (inqdata && inqsize >= 36 && !memcmp(inqdata + 8, "ATA     ", 8)) { // TODO: Linux-specific?
                   1303:     ata_device_auto_ptr atadev( new sat_device(this, scsidev, "") , scsidev);
                   1304:     if (has_sat_pass_through(atadev.get()))
                   1305:       return atadev.release(); // Detected SAT
                   1306:   }
                   1307: 
                   1308:   return 0;
                   1309: }
                   1310: 
                   1311: 
                   1312: /////////////////////////////////////////////////////////////////////////////
                   1313: // USB device type detection
                   1314: 
                   1315: // Format USB ID for error messages
                   1316: static std::string format_usb_id(int vendor_id, int product_id, int version)
                   1317: {
                   1318:   if (version >= 0)
                   1319:     return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id, product_id, version);
                   1320:   else
                   1321:     return strprintf("[0x%04x:0x%04x]", vendor_id, product_id);
                   1322: }
                   1323: 
                   1324: // Get type name for USB device with known VENDOR:PRODUCT ID.
                   1325: const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
                   1326:                                                      int version /*= -1*/)
                   1327: {
                   1328:   usb_dev_info info, info2;
                   1329:   int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
                   1330: 
                   1331:   if (n <= 0) {
                   1332:     set_err(EINVAL, "Unknown USB bridge %s",
                   1333:             format_usb_id(vendor_id, product_id, version).c_str());
                   1334:     return 0;
                   1335:   }
                   1336: 
                   1337:   if (n > 1) {
                   1338:     set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
                   1339:             format_usb_id(vendor_id, product_id, version).c_str(),
                   1340:             (!info.usb_type.empty()  ? info.usb_type.c_str()  : "[unsupported]"),
                   1341:             (!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
                   1342:     return 0;
                   1343:   }
                   1344: 
                   1345:   if (info.usb_type.empty()) {
                   1346:     set_err(ENOSYS, "Unsupported USB bridge %s",
                   1347:             format_usb_id(vendor_id, product_id, version).c_str());
                   1348:     return 0;
                   1349:   }
                   1350: 
                   1351:   // TODO: change return type to std::string
                   1352:   static std::string type;
                   1353:   type = info.usb_type;
                   1354:   return type.c_str();
                   1355: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>