File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / smartmontools / os_linux.cpp
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:54:03 2013 UTC (10 years, 7 months ago) by misho
Branches: smartmontools, elwix, MAIN
CVS tags: v6_2, HEAD
v 6.2

    1: /*
    2:  *  os_linux.cpp
    3:  *
    4:  * Home page of code is: http://smartmontools.sourceforge.net
    5:  *
    6:  * Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
    7:  * Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com>
    8:  * Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw>
    9:  * Copyright (C) 2008    Oliver Bock <brevilo@users.sourceforge.net>
   10:  * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
   11:  * Copyright (C) 2008    Jordan Hargrave <jordan_hargrave@dell.com>
   12:  *
   13:  *  Parts of this file are derived from code that was
   14:  *
   15:  *  Written By: Adam Radford <linux@3ware.com>
   16:  *  Modifications By: Joel Jacobson <linux@3ware.com>
   17:  *                   Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   18:  *                    Brad Strand <linux@3ware.com>
   19:  *
   20:  *  Copyright (C) 1999-2003 3ware Inc.
   21:  *
   22:  *  Kernel compatablity By:     Andre Hedrick <andre@suse.com>
   23:  *  Non-Copyright (C) 2000      Andre Hedrick <andre@suse.com>
   24:  *
   25:  * Other ars of this file are derived from code that was
   26:  *
   27:  * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
   28:  * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
   29:  *
   30:  * This program is free software; you can redistribute it and/or modify
   31:  * it under the terms of the GNU General Public License as published by
   32:  * the Free Software Foundation; either version 2, or (at your option)
   33:  * any later version.
   34:  *
   35:  * You should have received a copy of the GNU General Public License
   36:  * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
   37:  *
   38:  * This code was originally developed as a Senior Thesis by Michael Cornwell
   39:  * at the Concurrent Systems Laboratory (now part of the Storage Systems
   40:  * Research Center), Jack Baskin School of Engineering, University of
   41:  * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
   42:  *
   43:  */
   44: 
   45: // This file contains the linux-specific IOCTL parts of
   46: // smartmontools. It includes one interface routine for ATA devices,
   47: // one for SCSI devices, and one for ATA devices behind escalade
   48: // controllers.
   49: 
   50: #include "config.h"
   51: 
   52: #include <errno.h>
   53: #include <fcntl.h>
   54: #include <glob.h>
   55: 
   56: #include <scsi/scsi.h>
   57: #include <scsi/scsi_ioctl.h>
   58: #include <scsi/sg.h>
   59: #include <stdlib.h>
   60: #include <string.h>
   61: #include <sys/ioctl.h>
   62: #include <sys/stat.h>
   63: #include <sys/utsname.h>
   64: #include <unistd.h>
   65: #include <stddef.h>  // for offsetof()
   66: #include <sys/uio.h>
   67: #include <sys/types.h>
   68: #include <dirent.h>
   69: #ifndef makedev // old versions of types.h do not include sysmacros.h
   70: #include <sys/sysmacros.h>
   71: #endif
   72: #ifdef WITH_SELINUX
   73: #include <selinux/selinux.h>
   74: #endif
   75: 
   76: #include "int64.h"
   77: #include "atacmds.h"
   78: #include "os_linux.h"
   79: #include "scsicmds.h"
   80: #include "utility.h"
   81: #include "cciss.h"
   82: #include "megaraid.h"
   83: 
   84: #include "dev_interface.h"
   85: #include "dev_ata_cmd_set.h"
   86: #include "dev_areca.h"
   87: 
   88: #ifndef ENOTSUP
   89: #define ENOTSUP ENOSYS
   90: #endif
   91: 
   92: #define ARGUSED(x) ((void)(x))
   93: 
   94: const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp,v 1.1.1.4 2013/10/14 07:54:03 misho Exp $"
   95:   OS_LINUX_H_CVSID;
   96: extern unsigned char failuretest_permissive;
   97: 
   98: namespace os_linux { // No need to publish anything, name provided for Doxygen
   99: 
  100: /////////////////////////////////////////////////////////////////////////////
  101: /// Shared open/close routines
  102: 
  103: class linux_smart_device
  104: : virtual public /*implements*/ smart_device
  105: {
  106: public:
  107:   explicit linux_smart_device(int flags, int retry_flags = -1)
  108:     : smart_device(never_called),
  109:       m_fd(-1),
  110:       m_flags(flags), m_retry_flags(retry_flags)
  111:       { }
  112: 
  113:   virtual ~linux_smart_device() throw();
  114: 
  115:   virtual bool is_open() const;
  116: 
  117:   virtual bool open();
  118: 
  119:   virtual bool close();
  120: 
  121: protected:
  122:   /// Return filedesc for derived classes.
  123:   int get_fd() const
  124:     { return m_fd; }
  125: 
  126:   void set_fd(int fd)
  127:     { m_fd = fd; }
  128: 
  129: private:
  130:   int m_fd; ///< filedesc, -1 if not open.
  131:   int m_flags; ///< Flags for ::open()
  132:   int m_retry_flags; ///< Flags to retry ::open(), -1 if no retry
  133: };
  134: 
  135: linux_smart_device::~linux_smart_device() throw()
  136: {
  137:   if (m_fd >= 0)
  138:     ::close(m_fd);
  139: }
  140: 
  141: bool linux_smart_device::is_open() const
  142: {
  143:   return (m_fd >= 0);
  144: }
  145: 
  146: bool linux_smart_device::open()
  147: {
  148:   m_fd = ::open(get_dev_name(), m_flags);
  149: 
  150:   if (m_fd < 0 && errno == EROFS && m_retry_flags != -1)
  151:     // Retry
  152:     m_fd = ::open(get_dev_name(), m_retry_flags);
  153: 
  154:   if (m_fd < 0) {
  155:     if (errno == EBUSY && (m_flags & O_EXCL))
  156:       // device is locked
  157:       return set_err(EBUSY,
  158:         "The requested controller is used exclusively by another process!\n"
  159:         "(e.g. smartctl or smartd)\n"
  160:         "Please quit the impeding process or try again later...");
  161:     return set_err((errno==ENOENT || errno==ENOTDIR) ? ENODEV : errno);
  162:   }
  163: 
  164:   if (m_fd >= 0) {
  165:     // sets FD_CLOEXEC on the opened device file descriptor.  The
  166:     // descriptor is otherwise leaked to other applications (mail
  167:     // sender) which may be considered a security risk and may result
  168:     // in AVC messages on SELinux-enabled systems.
  169:     if (-1 == fcntl(m_fd, F_SETFD, FD_CLOEXEC))
  170:       // TODO: Provide an error printing routine in class smart_interface
  171:       pout("fcntl(set  FD_CLOEXEC) failed, errno=%d [%s]\n", errno, strerror(errno));
  172:   }
  173: 
  174:   return true;
  175: }
  176: 
  177: // equivalent to close(file descriptor)
  178: bool linux_smart_device::close()
  179: {
  180:   int fd = m_fd; m_fd = -1;
  181:   if (::close(fd) < 0)
  182:     return set_err(errno);
  183:   return true;
  184: }
  185: 
  186: // examples for smartctl
  187: static const char  smartctl_examples[] =
  188: 		  "=================================================== SMARTCTL EXAMPLES =====\n\n"
  189: 		  "  smartctl --all /dev/hda                    (Prints all SMART information)\n\n"
  190: 		  "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
  191: 		  "                                              (Enables SMART on first disk)\n\n"
  192: 		  "  smartctl --test=long /dev/hda          (Executes extended disk self-test)\n\n"
  193: 		  "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
  194: 		  "                                      (Prints Self-Test & Attribute errors)\n"
  195: 		  "  smartctl --all --device=3ware,2 /dev/sda\n"
  196: 		  "  smartctl --all --device=3ware,2 /dev/twe0\n"
  197: 		  "  smartctl --all --device=3ware,2 /dev/twa0\n"
  198: 		  "  smartctl --all --device=3ware,2 /dev/twl0\n"
  199: 		  "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
  200: 		  "  smartctl --all --device=hpt,1/1/3 /dev/sda\n"
  201: 		  "          (Prints all SMART info for the SATA disk attached to the 3rd PMPort\n"
  202: 		  "           of the 1st channel on the 1st HighPoint RAID controller)\n"
  203: 		  "  smartctl --all --device=areca,3/1 /dev/sg2\n"
  204: 		  "          (Prints all SMART info for 3rd ATA disk of the 1st enclosure\n"
  205: 		  "           on Areca RAID controller)\n"
  206:   ;
  207: 
  208: /////////////////////////////////////////////////////////////////////////////
  209: /// Linux ATA support
  210: 
  211: class linux_ata_device
  212: : public /*implements*/ ata_device_with_command_set,
  213:   public /*extends*/ linux_smart_device
  214: {
  215: public:
  216:   linux_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
  217: 
  218: protected:
  219:   virtual int ata_command_interface(smart_command_set command, int select, char * data);
  220: };
  221: 
  222: linux_ata_device::linux_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
  223: : smart_device(intf, dev_name, "ata", req_type),
  224:   linux_smart_device(O_RDONLY | O_NONBLOCK)
  225: {
  226: }
  227: 
  228: // PURPOSE
  229: //   This is an interface routine meant to isolate the OS dependent
  230: //   parts of the code, and to provide a debugging interface.  Each
  231: //   different port and OS needs to provide it's own interface.  This
  232: //   is the linux one.
  233: // DETAILED DESCRIPTION OF ARGUMENTS
  234: //   device: is the file descriptor provided by open()
  235: //   command: defines the different operations.
  236: //   select: additional input data if needed (which log, which type of
  237: //           self-test).
  238: //   data:   location to write output data, if needed (512 bytes).
  239: //   Note: not all commands use all arguments.
  240: // RETURN VALUES
  241: //  -1 if the command failed
  242: //   0 if the command succeeded,
  243: //   STATUS_CHECK routine:
  244: //  -1 if the command failed
  245: //   0 if the command succeeded and disk SMART status is "OK"
  246: //   1 if the command succeeded and disk SMART status is "FAILING"
  247: 
  248: #define BUFFER_LENGTH (4+512)
  249: 
  250: int linux_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
  251: {
  252:   unsigned char buff[BUFFER_LENGTH];
  253:   // positive: bytes to write to caller.  negative: bytes to READ from
  254:   // caller. zero: non-data command
  255:   int copydata=0;
  256: 
  257:   const int HDIO_DRIVE_CMD_OFFSET = 4;
  258: 
  259:   // See struct hd_drive_cmd_hdr in hdreg.h.  Before calling ioctl()
  260:   // buff[0]: ATA COMMAND CODE REGISTER
  261:   // buff[1]: ATA SECTOR NUMBER REGISTER == LBA LOW REGISTER
  262:   // buff[2]: ATA FEATURES REGISTER
  263:   // buff[3]: ATA SECTOR COUNT REGISTER
  264: 
  265:   // Note that on return:
  266:   // buff[2] contains the ATA SECTOR COUNT REGISTER
  267: 
  268:   // clear out buff.  Large enough for HDIO_DRIVE_CMD (4+512 bytes)
  269:   memset(buff, 0, BUFFER_LENGTH);
  270: 
  271:   buff[0]=ATA_SMART_CMD;
  272:   switch (command){
  273:   case CHECK_POWER_MODE:
  274:     buff[0]=ATA_CHECK_POWER_MODE;
  275:     copydata=1;
  276:     break;
  277:   case READ_VALUES:
  278:     buff[2]=ATA_SMART_READ_VALUES;
  279:     buff[3]=1;
  280:     copydata=512;
  281:     break;
  282:   case READ_THRESHOLDS:
  283:     buff[2]=ATA_SMART_READ_THRESHOLDS;
  284:     buff[1]=buff[3]=1;
  285:     copydata=512;
  286:     break;
  287:   case READ_LOG:
  288:     buff[2]=ATA_SMART_READ_LOG_SECTOR;
  289:     buff[1]=select;
  290:     buff[3]=1;
  291:     copydata=512;
  292:     break;
  293:   case WRITE_LOG:
  294:     break;
  295:   case IDENTIFY:
  296:     buff[0]=ATA_IDENTIFY_DEVICE;
  297:     buff[3]=1;
  298:     copydata=512;
  299:     break;
  300:   case PIDENTIFY:
  301:     buff[0]=ATA_IDENTIFY_PACKET_DEVICE;
  302:     buff[3]=1;
  303:     copydata=512;
  304:     break;
  305:   case ENABLE:
  306:     buff[2]=ATA_SMART_ENABLE;
  307:     buff[1]=1;
  308:     break;
  309:   case DISABLE:
  310:     buff[2]=ATA_SMART_DISABLE;
  311:     buff[1]=1;
  312:     break;
  313:   case STATUS:
  314:     // this command only says if SMART is working.  It could be
  315:     // replaced with STATUS_CHECK below.
  316:     buff[2]=ATA_SMART_STATUS;
  317:     break;
  318:   case AUTO_OFFLINE:
  319:     // NOTE: According to ATAPI 4 and UP, this command is obsolete
  320:     // select == 241 for enable but no data transfer.  Use TASK ioctl.
  321:     buff[1]=ATA_SMART_AUTO_OFFLINE;
  322:     buff[2]=select;
  323:     break;
  324:   case AUTOSAVE:
  325:     // select == 248 for enable but no data transfer.  Use TASK ioctl.
  326:     buff[1]=ATA_SMART_AUTOSAVE;
  327:     buff[2]=select;
  328:     break;
  329:   case IMMEDIATE_OFFLINE:
  330:     buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
  331:     buff[1]=select;
  332:     break;
  333:   case STATUS_CHECK:
  334:     // This command uses HDIO_DRIVE_TASK and has different syntax than
  335:     // the other commands.
  336:     buff[1]=ATA_SMART_STATUS;
  337:     break;
  338:   default:
  339:     pout("Unrecognized command %d in linux_ata_command_interface()\n"
  340:          "Please contact " PACKAGE_BUGREPORT "\n", command);
  341:     errno=ENOSYS;
  342:     return -1;
  343:   }
  344: 
  345:   // This command uses the HDIO_DRIVE_TASKFILE ioctl(). This is the
  346:   // only ioctl() that can be used to WRITE data to the disk.
  347:   if (command==WRITE_LOG) {
  348:     unsigned char task[sizeof(ide_task_request_t)+512];
  349:     ide_task_request_t *reqtask=(ide_task_request_t *) task;
  350:     task_struct_t      *taskfile=(task_struct_t *) reqtask->io_ports;
  351:     int retval;
  352: 
  353:     memset(task,      0, sizeof(task));
  354: 
  355:     taskfile->data           = 0;
  356:     taskfile->feature        = ATA_SMART_WRITE_LOG_SECTOR;
  357:     taskfile->sector_count   = 1;
  358:     taskfile->sector_number  = select;
  359:     taskfile->low_cylinder   = 0x4f;
  360:     taskfile->high_cylinder  = 0xc2;
  361:     taskfile->device_head    = 0;
  362:     taskfile->command        = ATA_SMART_CMD;
  363: 
  364:     reqtask->data_phase      = TASKFILE_OUT;
  365:     reqtask->req_cmd         = IDE_DRIVE_TASK_OUT;
  366:     reqtask->out_size        = 512;
  367:     reqtask->in_size         = 0;
  368: 
  369:     // copy user data into the task request structure
  370:     memcpy(task+sizeof(ide_task_request_t), data, 512);
  371: 
  372:     if ((retval=ioctl(get_fd(), HDIO_DRIVE_TASKFILE, task))) {
  373:       if (retval==-EINVAL)
  374:         pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
  375:       return -1;
  376:     }
  377:     return 0;
  378:   }
  379: 
  380:   // There are two different types of ioctls().  The HDIO_DRIVE_TASK
  381:   // one is this:
  382:   if (command==STATUS_CHECK || command==AUTOSAVE || command==AUTO_OFFLINE){
  383:     int retval;
  384: 
  385:     // NOT DOCUMENTED in /usr/src/linux/include/linux/hdreg.h. You
  386:     // have to read the IDE driver source code.  Sigh.
  387:     // buff[0]: ATA COMMAND CODE REGISTER
  388:     // buff[1]: ATA FEATURES REGISTER
  389:     // buff[2]: ATA SECTOR_COUNT
  390:     // buff[3]: ATA SECTOR NUMBER
  391:     // buff[4]: ATA CYL LO REGISTER
  392:     // buff[5]: ATA CYL HI REGISTER
  393:     // buff[6]: ATA DEVICE HEAD
  394: 
  395:     unsigned const char normal_lo=0x4f, normal_hi=0xc2;
  396:     unsigned const char failed_lo=0xf4, failed_hi=0x2c;
  397:     buff[4]=normal_lo;
  398:     buff[5]=normal_hi;
  399: 
  400:     if ((retval=ioctl(get_fd(), HDIO_DRIVE_TASK, buff))) {
  401:       if (retval==-EINVAL) {
  402:         pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
  403:         pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
  404:       }
  405:       else
  406:         syserror("Error SMART Status command failed");
  407:       return -1;
  408:     }
  409: 
  410:     // Cyl low and Cyl high unchanged means "Good SMART status"
  411:     if (buff[4]==normal_lo && buff[5]==normal_hi)
  412:       return 0;
  413: 
  414:     // These values mean "Bad SMART status"
  415:     if (buff[4]==failed_lo && buff[5]==failed_hi)
  416:       return 1;
  417: 
  418:     // We haven't gotten output that makes sense; print out some debugging info
  419:     syserror("Error SMART Status command failed");
  420:     pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
  421:     pout("Register values returned from SMART Status command are:\n");
  422:     pout("ST =0x%02x\n",(int)buff[0]);
  423:     pout("ERR=0x%02x\n",(int)buff[1]);
  424:     pout("NS =0x%02x\n",(int)buff[2]);
  425:     pout("SC =0x%02x\n",(int)buff[3]);
  426:     pout("CL =0x%02x\n",(int)buff[4]);
  427:     pout("CH =0x%02x\n",(int)buff[5]);
  428:     pout("SEL=0x%02x\n",(int)buff[6]);
  429:     return -1;
  430:   }
  431: 
  432: #if 1
  433:   // Note to people doing ports to other OSes -- don't worry about
  434:   // this block -- you can safely ignore it.  I have put it here
  435:   // because under linux when you do IDENTIFY DEVICE to a packet
  436:   // device, it generates an ugly kernel syslog error message.  This
  437:   // is harmless but frightens users.  So this block detects packet
  438:   // devices and make IDENTIFY DEVICE fail "nicely" without a syslog
  439:   // error message.
  440:   //
  441:   // If you read only the ATA specs, it appears as if a packet device
  442:   // *might* respond to the IDENTIFY DEVICE command.  This is
  443:   // misleading - it's because around the time that SFF-8020 was
  444:   // incorporated into the ATA-3/4 standard, the ATA authors were
  445:   // sloppy. See SFF-8020 and you will see that ATAPI devices have
  446:   // *always* had IDENTIFY PACKET DEVICE as a mandatory part of their
  447:   // command set, and return 'Command Aborted' to IDENTIFY DEVICE.
  448:   if (command==IDENTIFY || command==PIDENTIFY){
  449:     unsigned short deviceid[256];
  450:     // check the device identity, as seen when the system was booted
  451:     // or the device was FIRST registered.  This will not be current
  452:     // if the user has subsequently changed some of the parameters. If
  453:     // device is a packet device, swap the command interpretations.
  454:     if (!ioctl(get_fd(), HDIO_GET_IDENTITY, deviceid) && (deviceid[0] & 0x8000))
  455:       buff[0]=(command==IDENTIFY)?ATA_IDENTIFY_PACKET_DEVICE:ATA_IDENTIFY_DEVICE;
  456:   }
  457: #endif
  458: 
  459:   // We are now doing the HDIO_DRIVE_CMD type ioctl.
  460:   if ((ioctl(get_fd(), HDIO_DRIVE_CMD, buff)))
  461:     return -1;
  462: 
  463:   // CHECK POWER MODE command returns information in the Sector Count
  464:   // register (buff[3]).  Copy to return data buffer.
  465:   if (command==CHECK_POWER_MODE)
  466:     buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
  467: 
  468:   // if the command returns data then copy it back
  469:   if (copydata)
  470:     memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
  471: 
  472:   return 0;
  473: }
  474: 
  475: // >>>>>> Start of general SCSI specific linux code
  476: 
  477: /* Linux specific code.
  478:  * Historically smartmontools (and smartsuite before it) used the
  479:  * SCSI_IOCTL_SEND_COMMAND ioctl which is available to all linux device
  480:  * nodes that use the SCSI subsystem. A better interface has been available
  481:  * via the SCSI generic (sg) driver but this involves the extra step of
  482:  * mapping disk devices (e.g. /dev/sda) to the corresponding sg device
  483:  * (e.g. /dev/sg2). In the linux kernel 2.6 series most of the facilities of
  484:  * the sg driver have become available via the SG_IO ioctl which is available
  485:  * on all SCSI devices (on SCSI tape devices from lk 2.6.6).
  486:  * So the strategy below is to find out if the SG_IO ioctl is available and
  487:  * if so use it; failing that use the older SCSI_IOCTL_SEND_COMMAND ioctl.
  488:  * Should work in 2.0, 2.2, 2.4 and 2.6 series linux kernels. */
  489: 
  490: #define MAX_DXFER_LEN 1024      /* can be increased if necessary */
  491: #define SEND_IOCTL_RESP_SENSE_LEN 16    /* ioctl limitation */
  492: #define SG_IO_RESP_SENSE_LEN 64 /* large enough see buffer */
  493: #define LSCSI_DRIVER_MASK  0xf /* mask out "suggestions" */
  494: #define LSCSI_DRIVER_SENSE  0x8 /* alternate CHECK CONDITION indication */
  495: #define LSCSI_DID_ERROR 0x7 /* Need to work around aacraid driver quirk */
  496: #define LSCSI_DRIVER_TIMEOUT  0x6
  497: #define LSCSI_DID_TIME_OUT  0x3
  498: #define LSCSI_DID_BUS_BUSY  0x2
  499: #define LSCSI_DID_NO_CONNECT  0x1
  500: 
  501: #ifndef SCSI_IOCTL_SEND_COMMAND
  502: #define SCSI_IOCTL_SEND_COMMAND 1
  503: #endif
  504: 
  505: #define SG_IO_PRESENT_UNKNOWN 0
  506: #define SG_IO_PRESENT_YES 1
  507: #define SG_IO_PRESENT_NO 2
  508: 
  509: static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
  510:                          int unknown);
  511: static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
  512: 
  513: static int sg_io_state = SG_IO_PRESENT_UNKNOWN;
  514: 
  515: /* Preferred implementation for issuing SCSI commands in linux. This
  516:  * function uses the SG_IO ioctl. Return 0 if command issued successfully
  517:  * (various status values should still be checked). If the SCSI command
  518:  * cannot be issued then a negative errno value is returned. */
  519: static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
  520:                          int unknown)
  521: {
  522: #ifndef SG_IO
  523:     ARGUSED(dev_fd); ARGUSED(iop); ARGUSED(report);
  524:     return -ENOTTY;
  525: #else
  526:     struct sg_io_hdr io_hdr;
  527: 
  528:     if (report > 0) {
  529:         int k, j;
  530:         const unsigned char * ucp = iop->cmnd;
  531:         const char * np;
  532:         char buff[256];
  533:         const int sz = (int)sizeof(buff);
  534: 
  535:         np = scsi_get_opcode_name(ucp[0]);
  536:         j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
  537:         for (k = 0; k < (int)iop->cmnd_len; ++k)
  538:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
  539:         if ((report > 1) &&
  540:             (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
  541:             int trunc = (iop->dxfer_len > 256) ? 1 : 0;
  542: 
  543:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
  544:                           "data, len=%d%s:\n", (int)iop->dxfer_len,
  545:                           (trunc ? " [only first 256 bytes shown]" : ""));
  546:             dStrHex((const char *)iop->dxferp,
  547:                     (trunc ? 256 : iop->dxfer_len) , 1);
  548:         }
  549:         else
  550:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
  551:         pout("%s", buff);
  552:     }
  553:     memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
  554:     io_hdr.interface_id = 'S';
  555:     io_hdr.cmd_len = iop->cmnd_len;
  556:     io_hdr.mx_sb_len = iop->max_sense_len;
  557:     io_hdr.dxfer_len = iop->dxfer_len;
  558:     io_hdr.dxferp = iop->dxferp;
  559:     io_hdr.cmdp = iop->cmnd;
  560:     io_hdr.sbp = iop->sensep;
  561:     /* sg_io_hdr interface timeout has millisecond units. Timeout of 0
  562:        defaults to 60 seconds. */
  563:     io_hdr.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000;
  564:     switch (iop->dxfer_dir) {
  565:         case DXFER_NONE:
  566:             io_hdr.dxfer_direction = SG_DXFER_NONE;
  567:             break;
  568:         case DXFER_FROM_DEVICE:
  569:             io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
  570:             break;
  571:         case DXFER_TO_DEVICE:
  572:             io_hdr.dxfer_direction = SG_DXFER_TO_DEV;
  573:             break;
  574:         default:
  575:             pout("do_scsi_cmnd_io: bad dxfer_dir\n");
  576:             return -EINVAL;
  577:     }
  578:     iop->resp_sense_len = 0;
  579:     iop->scsi_status = 0;
  580:     iop->resid = 0;
  581:     if (ioctl(dev_fd, SG_IO, &io_hdr) < 0) {
  582:         if (report && (! unknown))
  583:             pout("  SG_IO ioctl failed, errno=%d [%s]\n", errno,
  584:                  strerror(errno));
  585:         return -errno;
  586:     }
  587:     iop->resid = io_hdr.resid;
  588:     iop->scsi_status = io_hdr.status;
  589:     if (report > 0) {
  590:         pout("  scsi_status=0x%x, host_status=0x%x, driver_status=0x%x\n"
  591:              "  info=0x%x  duration=%d milliseconds  resid=%d\n", io_hdr.status,
  592:              io_hdr.host_status, io_hdr.driver_status, io_hdr.info,
  593:              io_hdr.duration, io_hdr.resid);
  594:         if (report > 1) {
  595:             if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
  596:                 int trunc, len;
  597: 
  598: 		len = iop->dxfer_len - iop->resid;
  599: 		trunc = (len > 256) ? 1 : 0;
  600:                 if (len > 0) {
  601:                     pout("  Incoming data, len=%d%s:\n", len,
  602:                          (trunc ? " [only first 256 bytes shown]" : ""));
  603:                     dStrHex((const char*)iop->dxferp, (trunc ? 256 : len),
  604:                             1);
  605:                 } else
  606:                     pout("  Incoming data trimmed to nothing by resid\n");
  607:             }
  608:         }
  609:     }
  610: 
  611:     if (io_hdr.info & SG_INFO_CHECK) { /* error or warning */
  612:         int masked_driver_status = (LSCSI_DRIVER_MASK & io_hdr.driver_status);
  613: 
  614:         if (0 != io_hdr.host_status) {
  615:             if ((LSCSI_DID_NO_CONNECT == io_hdr.host_status) ||
  616:                 (LSCSI_DID_BUS_BUSY == io_hdr.host_status) ||
  617:                 (LSCSI_DID_TIME_OUT == io_hdr.host_status))
  618:                 return -ETIMEDOUT;
  619:             else
  620:                /* Check for DID_ERROR - workaround for aacraid driver quirk */
  621:                if (LSCSI_DID_ERROR != io_hdr.host_status) {
  622:                        return -EIO; /* catch all if not DID_ERR */
  623:                }
  624:         }
  625:         if (0 != masked_driver_status) {
  626:             if (LSCSI_DRIVER_TIMEOUT == masked_driver_status)
  627:                 return -ETIMEDOUT;
  628:             else if (LSCSI_DRIVER_SENSE != masked_driver_status)
  629:                 return -EIO;
  630:         }
  631:         if (LSCSI_DRIVER_SENSE == masked_driver_status)
  632:             iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
  633:         iop->resp_sense_len = io_hdr.sb_len_wr;
  634:         if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
  635:             iop->sensep && (iop->resp_sense_len > 0)) {
  636:             if (report > 1) {
  637:                 pout("  >>> Sense buffer, len=%d:\n",
  638:                      (int)iop->resp_sense_len);
  639:                 dStrHex((const char *)iop->sensep, iop->resp_sense_len , 1);
  640:             }
  641:         }
  642:         if (report) {
  643:             if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
  644:                 if ((iop->sensep[0] & 0x7f) > 0x71)
  645:                     pout("  status=%x: [desc] sense_key=%x asc=%x ascq=%x\n",
  646:                          iop->scsi_status, iop->sensep[1] & 0xf,
  647:                          iop->sensep[2], iop->sensep[3]);
  648:                 else
  649:                     pout("  status=%x: sense_key=%x asc=%x ascq=%x\n",
  650:                          iop->scsi_status, iop->sensep[2] & 0xf,
  651:                          iop->sensep[12], iop->sensep[13]);
  652:             }
  653:             else
  654:                 pout("  status=0x%x\n", iop->scsi_status);
  655:         }
  656:     }
  657:     return 0;
  658: #endif
  659: }
  660: 
  661: struct linux_ioctl_send_command
  662: {
  663:     int inbufsize;
  664:     int outbufsize;
  665:     UINT8 buff[MAX_DXFER_LEN + 16];
  666: };
  667: 
  668: /* The Linux SCSI_IOCTL_SEND_COMMAND ioctl is primitive and it doesn't
  669:  * support: CDB length (guesses it from opcode), resid and timeout.
  670:  * Patches in Linux 2.4.21 and 2.5.70 to extend SEND DIAGNOSTIC timeout
  671:  * to 2 hours in order to allow long foreground extended self tests. */
  672: static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
  673: {
  674:     struct linux_ioctl_send_command wrk;
  675:     int status, buff_offset;
  676:     size_t len;
  677: 
  678:     memcpy(wrk.buff, iop->cmnd, iop->cmnd_len);
  679:     buff_offset = iop->cmnd_len;
  680:     if (report > 0) {
  681:         int k, j;
  682:         const unsigned char * ucp = iop->cmnd;
  683:         const char * np;
  684:         char buff[256];
  685:         const int sz = (int)sizeof(buff);
  686: 
  687:         np = scsi_get_opcode_name(ucp[0]);
  688:         j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
  689:         for (k = 0; k < (int)iop->cmnd_len; ++k)
  690:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
  691:         if ((report > 1) &&
  692:             (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
  693:             int trunc = (iop->dxfer_len > 256) ? 1 : 0;
  694: 
  695:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
  696:                           "data, len=%d%s:\n", (int)iop->dxfer_len,
  697:                           (trunc ? " [only first 256 bytes shown]" : ""));
  698:             dStrHex((const char *)iop->dxferp,
  699:                     (trunc ? 256 : iop->dxfer_len) , 1);
  700:         }
  701:         else
  702:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
  703:         pout("%s", buff);
  704:     }
  705:     switch (iop->dxfer_dir) {
  706:         case DXFER_NONE:
  707:             wrk.inbufsize = 0;
  708:             wrk.outbufsize = 0;
  709:             break;
  710:         case DXFER_FROM_DEVICE:
  711:             wrk.inbufsize = 0;
  712:             if (iop->dxfer_len > MAX_DXFER_LEN)
  713:                 return -EINVAL;
  714:             wrk.outbufsize = iop->dxfer_len;
  715:             break;
  716:         case DXFER_TO_DEVICE:
  717:             if (iop->dxfer_len > MAX_DXFER_LEN)
  718:                 return -EINVAL;
  719:             memcpy(wrk.buff + buff_offset, iop->dxferp, iop->dxfer_len);
  720:             wrk.inbufsize = iop->dxfer_len;
  721:             wrk.outbufsize = 0;
  722:             break;
  723:         default:
  724:             pout("do_scsi_cmnd_io: bad dxfer_dir\n");
  725:             return -EINVAL;
  726:     }
  727:     iop->resp_sense_len = 0;
  728:     iop->scsi_status = 0;
  729:     iop->resid = 0;
  730:     status = ioctl(dev_fd, SCSI_IOCTL_SEND_COMMAND, &wrk);
  731:     if (-1 == status) {
  732:         if (report)
  733:             pout("  SCSI_IOCTL_SEND_COMMAND ioctl failed, errno=%d [%s]\n",
  734:                  errno, strerror(errno));
  735:         return -errno;
  736:     }
  737:     if (0 == status) {
  738:         if (report > 0)
  739:             pout("  status=0\n");
  740:         if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
  741:             memcpy(iop->dxferp, wrk.buff, iop->dxfer_len);
  742:             if (report > 1) {
  743:                 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
  744: 
  745:                 pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
  746:                      (trunc ? " [only first 256 bytes shown]" : ""));
  747:                 dStrHex((const char*)iop->dxferp,
  748:                         (trunc ? 256 : iop->dxfer_len) , 1);
  749:             }
  750:         }
  751:         return 0;
  752:     }
  753:     iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */
  754:     if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf))
  755:         iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
  756:     len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
  757:                 SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
  758:     if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
  759:         iop->sensep && (len > 0)) {
  760:         memcpy(iop->sensep, wrk.buff, len);
  761:         iop->resp_sense_len = len;
  762:         if (report > 1) {
  763:             pout("  >>> Sense buffer, len=%d:\n", (int)len);
  764:             dStrHex((const char *)wrk.buff, len , 1);
  765:         }
  766:     }
  767:     if (report) {
  768:         if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
  769:             pout("  status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
  770:                  wrk.buff[2] & 0xf, wrk.buff[12], wrk.buff[13]);
  771:         }
  772:         else
  773:             pout("  status=0x%x\n", status);
  774:     }
  775:     if (iop->scsi_status > 0)
  776:         return 0;
  777:     else {
  778:         if (report > 0)
  779:             pout("  ioctl status=0x%x but scsi status=0, fail with EIO\n",
  780:                  status);
  781:         return -EIO;      /* give up, assume no device there */
  782:     }
  783: }
  784: 
  785: /* SCSI command transmission interface function, linux version.
  786:  * Returns 0 if SCSI command successfully launched and response
  787:  * received. Even when 0 is returned the caller should check
  788:  * scsi_cmnd_io::scsi_status for SCSI defined errors and warnings
  789:  * (e.g. CHECK CONDITION). If the SCSI command could not be issued
  790:  * (e.g. device not present or timeout) or some other problem
  791:  * (e.g. timeout) then returns a negative errno value */
  792: static int do_normal_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop,
  793:                                   int report)
  794: {
  795:     int res;
  796: 
  797:     /* implementation relies on static sg_io_state variable. If not
  798:      * previously set tries the SG_IO ioctl. If that succeeds assume
  799:      * that SG_IO ioctl functional. If it fails with an errno value
  800:      * other than ENODEV (no device) or permission then assume
  801:      * SCSI_IOCTL_SEND_COMMAND is the only option. */
  802:     switch (sg_io_state) {
  803:     case SG_IO_PRESENT_UNKNOWN:
  804:         /* ignore report argument */
  805:         if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, 1))) {
  806:             sg_io_state = SG_IO_PRESENT_YES;
  807:             return 0;
  808:         } else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
  809:             return res;         /* wait until we see a device */
  810:         sg_io_state = SG_IO_PRESENT_NO;
  811:         /* drop through by design */
  812:     case SG_IO_PRESENT_NO:
  813:         return sisc_cmnd_io(dev_fd, iop, report);
  814:     case SG_IO_PRESENT_YES:
  815:         return sg_io_cmnd_io(dev_fd, iop, report, 0);
  816:     default:
  817:         pout(">>>> do_scsi_cmnd_io: bad sg_io_state=%d\n", sg_io_state);
  818:         sg_io_state = SG_IO_PRESENT_UNKNOWN;
  819:         return -EIO;    /* report error and reset state */
  820:     }
  821: }
  822: 
  823: // >>>>>> End of general SCSI specific linux code
  824: 
  825: /////////////////////////////////////////////////////////////////////////////
  826: /// Standard SCSI support
  827: 
  828: class linux_scsi_device
  829: : public /*implements*/ scsi_device,
  830:   public /*extends*/ linux_smart_device
  831: {
  832: public:
  833:   linux_scsi_device(smart_interface * intf, const char * dev_name,
  834:                     const char * req_type, bool scanning = false);
  835: 
  836:   virtual smart_device * autodetect_open();
  837: 
  838:   virtual bool scsi_pass_through(scsi_cmnd_io * iop);
  839: 
  840: private:
  841:   bool m_scanning; ///< true if created within scan_smart_devices
  842: };
  843: 
  844: linux_scsi_device::linux_scsi_device(smart_interface * intf,
  845:   const char * dev_name, const char * req_type, bool scanning /*= false*/)
  846: : smart_device(intf, dev_name, "scsi", req_type),
  847:   // If opened with O_RDWR, a SATA disk in standby mode
  848:   // may spin-up after device close().
  849:   linux_smart_device(O_RDONLY | O_NONBLOCK),
  850:   m_scanning(scanning)
  851: {
  852: }
  853: 
  854: bool linux_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
  855: {
  856:   int status = do_normal_scsi_cmnd_io(get_fd(), iop, scsi_debugmode);
  857:   if (status < 0)
  858:       return set_err(-status);
  859:   return true;
  860: }
  861: 
  862: /////////////////////////////////////////////////////////////////////////////
  863: /// LSI MegaRAID support
  864: 
  865: class linux_megaraid_device
  866: : public /* implements */ scsi_device,
  867:   public /* extends */ linux_smart_device
  868: {
  869: public:
  870:   linux_megaraid_device(smart_interface *intf, const char *name, 
  871:     unsigned int bus, unsigned int tgt);
  872: 
  873:   virtual ~linux_megaraid_device() throw();
  874: 
  875:   virtual smart_device * autodetect_open();
  876: 
  877:   virtual bool open();
  878:   virtual bool close();
  879: 
  880:   virtual bool scsi_pass_through(scsi_cmnd_io *iop);
  881: 
  882: private:
  883:   unsigned int m_disknum;
  884:   unsigned int m_busnum;
  885:   unsigned int m_hba;
  886:   int m_fd;
  887: 
  888:   bool (linux_megaraid_device::*pt_cmd)(int cdblen, void *cdb, int dataLen, void *data,
  889:     int senseLen, void *sense, int report, int direction);
  890:   bool megasas_cmd(int cdbLen, void *cdb, int dataLen, void *data,
  891:     int senseLen, void *sense, int report, int direction);
  892:   bool megadev_cmd(int cdbLen, void *cdb, int dataLen, void *data,
  893:     int senseLen, void *sense, int report, int direction);
  894: };
  895: 
  896: linux_megaraid_device::linux_megaraid_device(smart_interface *intf,
  897:   const char *dev_name, unsigned int bus, unsigned int tgt)
  898:  : smart_device(intf, dev_name, "megaraid", "megaraid"),
  899:    linux_smart_device(O_RDWR | O_NONBLOCK),
  900:    m_disknum(tgt), m_busnum(bus), m_hba(0),
  901:    m_fd(-1), pt_cmd(0)
  902: {
  903:   set_info().info_name = strprintf("%s [megaraid_disk_%02d]", dev_name, m_disknum);
  904:   set_info().dev_type = strprintf("megaraid,%d", tgt);
  905: }
  906: 
  907: linux_megaraid_device::~linux_megaraid_device() throw()
  908: {
  909:   if (m_fd >= 0)
  910:     ::close(m_fd);
  911: }
  912: 
  913: smart_device * linux_megaraid_device::autodetect_open()
  914: {
  915:   int report = scsi_debugmode;
  916: 
  917:   // Open device
  918:   if (!open())
  919:     return this;
  920: 
  921:   // The code below is based on smartd.cpp:SCSIFilterKnown()
  922:   if (strcmp(get_req_type(), "megaraid"))
  923:     return this;
  924: 
  925:   // Get INQUIRY
  926:   unsigned char req_buff[64] = {0, };
  927:   int req_len = 36;
  928:   if (scsiStdInquiry(this, req_buff, req_len)) {
  929:       close();
  930:       set_err(EIO, "INQUIRY failed");
  931:       return this;
  932:   }
  933: 
  934:   int avail_len = req_buff[4] + 5;
  935:   int len = (avail_len < req_len ? avail_len : req_len);
  936:   if (len < 36)
  937:       return this;
  938: 
  939:   if (report)
  940:     pout("Got MegaRAID inquiry.. %s\n", req_buff+8);
  941: 
  942:   // Use INQUIRY to detect type
  943:   {
  944:     // SAT?
  945:     ata_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
  946:     if (newdev) // NOTE: 'this' is now owned by '*newdev'
  947:       return newdev;
  948:   }
  949: 
  950:   // Nothing special found
  951:   return this;
  952: }
  953: 
  954: bool linux_megaraid_device::open()
  955: {
  956:   char line[128];
  957:   int   mjr;
  958:   int report = scsi_debugmode;
  959: 
  960:   if(sscanf(get_dev_name(),"/dev/bus/%d", &m_hba) == 0) {
  961:     if (!linux_smart_device::open())
  962:       return false;
  963:     /* Get device HBA */
  964:     struct sg_scsi_id sgid;
  965:     if (ioctl(get_fd(), SG_GET_SCSI_ID, &sgid) == 0) {
  966:       m_hba = sgid.host_no;
  967:     }
  968:     else if (ioctl(get_fd(), SCSI_IOCTL_GET_BUS_NUMBER, &m_hba) != 0) {
  969:       int err = errno;
  970:       linux_smart_device::close();
  971:       return set_err(err, "can't get bus number");
  972:     } // we dont need this device anymore
  973:     linux_smart_device::close();
  974:   }
  975:   /* Perform mknod of device ioctl node */
  976:   FILE * fp = fopen("/proc/devices", "r");
  977:   while (fgets(line, sizeof(line), fp) != NULL) {
  978:     int n1 = 0;
  979:     if (sscanf(line, "%d megaraid_sas_ioctl%n", &mjr, &n1) == 1 && n1 == 22) {
  980:       n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR, makedev(mjr, 0));
  981:       if(report > 0)
  982:         pout("Creating /dev/megaraid_sas_ioctl_node = %d\n", n1 >= 0 ? 0 : errno);
  983:       if (n1 >= 0 || errno == EEXIST)
  984:         break;
  985:     }
  986:     else if (sscanf(line, "%d megadev%n", &mjr, &n1) == 1 && n1 == 11) {
  987:       n1=mknod("/dev/megadev0", S_IFCHR, makedev(mjr, 0));
  988:       if(report > 0)
  989:         pout("Creating /dev/megadev0 = %d\n", n1 >= 0 ? 0 : errno);
  990:       if (n1 >= 0 || errno == EEXIST)
  991:         break;
  992:     }
  993:   }
  994:   fclose(fp);
  995: 
  996:   /* Open Device IOCTL node */
  997:   if ((m_fd = ::open("/dev/megaraid_sas_ioctl_node", O_RDWR)) >= 0) {
  998:     pt_cmd = &linux_megaraid_device::megasas_cmd;
  999:   }
 1000:   else if ((m_fd = ::open("/dev/megadev0", O_RDWR)) >= 0) {
 1001:     pt_cmd = &linux_megaraid_device::megadev_cmd;
 1002:   }
 1003:   else {
 1004:     int err = errno;
 1005:     linux_smart_device::close();
 1006:     return set_err(err, "cannot open /dev/megaraid_sas_ioctl_node or /dev/megadev0");
 1007:   }
 1008:   set_fd(m_fd);
 1009:   return true;
 1010: }
 1011: 
 1012: bool linux_megaraid_device::close()
 1013: {
 1014:   if (m_fd >= 0)
 1015:     ::close(m_fd);
 1016:   m_fd = -1; m_hba = 0; pt_cmd = 0;
 1017:   set_fd(m_fd);
 1018:   return true;
 1019: }
 1020: 
 1021: bool linux_megaraid_device::scsi_pass_through(scsi_cmnd_io *iop)
 1022: {
 1023:   int report = scsi_debugmode;
 1024: 
 1025:   if (report > 0) {
 1026:         int k, j;
 1027:         const unsigned char * ucp = iop->cmnd;
 1028:         const char * np;
 1029:         char buff[256];
 1030:         const int sz = (int)sizeof(buff);
 1031: 
 1032:         np = scsi_get_opcode_name(ucp[0]);
 1033:         j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
 1034:         for (k = 0; k < (int)iop->cmnd_len; ++k)
 1035:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
 1036:         if ((report > 1) &&
 1037:             (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
 1038:             int trunc = (iop->dxfer_len > 256) ? 1 : 0;
 1039: 
 1040:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
 1041:                           "data, len=%d%s:\n", (int)iop->dxfer_len,
 1042:                           (trunc ? " [only first 256 bytes shown]" : ""));
 1043:             dStrHex((const char *)iop->dxferp,
 1044:                     (trunc ? 256 : iop->dxfer_len) , 1);
 1045:         }
 1046:         else
 1047:             j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
 1048:         pout("%s", buff);
 1049:   }
 1050: 
 1051:   // Controller rejects Test Unit Ready
 1052:   if (iop->cmnd[0] == 0x00)
 1053:     return true;
 1054: 
 1055:   if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) { 
 1056:     // Controller does not return ATA output registers in SAT sense data
 1057:     if (iop->cmnd[2] & (1 << 5)) // chk_cond
 1058:       return set_err(ENOSYS, "ATA return descriptor not supported by controller firmware");
 1059:   }
 1060:   // SMART WRITE LOG SECTOR causing media errors
 1061:   if ((iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16 // SAT16 WRITE LOG
 1062:       && iop->cmnd[14] == ATA_SMART_CMD && iop->cmnd[3]==0 && iop->cmnd[4] == ATA_SMART_WRITE_LOG_SECTOR) ||
 1063:       (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 // SAT12 WRITE LOG
 1064:        && iop->cmnd[9] == ATA_SMART_CMD && iop->cmnd[3] == ATA_SMART_WRITE_LOG_SECTOR)) 
 1065:   {
 1066:     if(!failuretest_permissive)
 1067:        return set_err(ENOSYS, "SMART WRITE LOG SECTOR may cause problems, try with -T permissive to force"); 
 1068:   }
 1069:   if (pt_cmd == NULL)
 1070:     return false;
 1071:   return (this->*pt_cmd)(iop->cmnd_len, iop->cmnd,
 1072:     iop->dxfer_len, iop->dxferp,
 1073:     iop->max_sense_len, iop->sensep, report, iop->dxfer_dir);
 1074: }
 1075: 
 1076: /* Issue passthrough scsi command to PERC5/6 controllers */
 1077: bool linux_megaraid_device::megasas_cmd(int cdbLen, void *cdb, 
 1078:   int dataLen, void *data,
 1079:   int /*senseLen*/, void * /*sense*/, int /*report*/, int dxfer_dir)
 1080: {
 1081:   struct megasas_pthru_frame	*pthru;
 1082:   struct megasas_iocpacket	uio;
 1083:   int rc;
 1084: 
 1085:   memset(&uio, 0, sizeof(uio));
 1086:   pthru = &uio.frame.pthru;
 1087:   pthru->cmd = MFI_CMD_PD_SCSI_IO;
 1088:   pthru->cmd_status = 0xFF;
 1089:   pthru->scsi_status = 0x0;
 1090:   pthru->target_id = m_disknum;
 1091:   pthru->lun = 0;
 1092:   pthru->cdb_len = cdbLen;
 1093:   pthru->timeout = 0;
 1094:   switch (dxfer_dir) {
 1095:     case DXFER_NONE:
 1096:       pthru->flags = MFI_FRAME_DIR_NONE;
 1097:       break;
 1098:     case DXFER_FROM_DEVICE:
 1099:       pthru->flags = MFI_FRAME_DIR_READ;
 1100:       break;
 1101:     case DXFER_TO_DEVICE:
 1102:       pthru->flags = MFI_FRAME_DIR_WRITE;
 1103:       break;
 1104:     default:
 1105:       pout("megasas_cmd: bad dxfer_dir\n");
 1106:       return set_err(EINVAL, "megasas_cmd: bad dxfer_dir\n");
 1107:   }
 1108: 
 1109:   if (dataLen > 0) {
 1110:     pthru->sge_count = 1;
 1111:     pthru->data_xfer_len = dataLen;
 1112:     pthru->sgl.sge32[0].phys_addr = (intptr_t)data;
 1113:     pthru->sgl.sge32[0].length = (uint32_t)dataLen;
 1114:   }
 1115:   memcpy(pthru->cdb, cdb, cdbLen);
 1116: 
 1117:   uio.host_no = m_hba;
 1118:   if (dataLen > 0) {
 1119:     uio.sge_count = 1;
 1120:     uio.sgl_off = offsetof(struct megasas_pthru_frame, sgl);
 1121:     uio.sgl[0].iov_base = data;
 1122:     uio.sgl[0].iov_len = dataLen;
 1123:   }
 1124: 
 1125:   rc = 0;
 1126:   errno = 0;
 1127:   rc = ioctl(m_fd, MEGASAS_IOC_FIRMWARE, &uio);
 1128:   if (pthru->cmd_status || rc != 0) {
 1129:     if (pthru->cmd_status == 12) {
 1130:       return set_err(EIO, "megasas_cmd: Device %d does not exist\n", m_disknum);
 1131:     }
 1132:     return set_err((errno ? errno : EIO), "megasas_cmd result: %d.%d = %d/%d",
 1133:                    m_hba, m_disknum, errno,
 1134:                    pthru->cmd_status);
 1135:   }
 1136:   return true;
 1137: }
 1138: 
 1139: /* Issue passthrough scsi commands to PERC2/3/4 controllers */
 1140: bool linux_megaraid_device::megadev_cmd(int cdbLen, void *cdb, 
 1141:   int dataLen, void *data,
 1142:   int /*senseLen*/, void * /*sense*/, int /*report*/, int /* dir */)
 1143: {
 1144:   struct uioctl_t uio;
 1145:   int rc;
 1146: 
 1147:   /* Don't issue to the controller */
 1148:   if (m_disknum == 7)
 1149:     return false;
 1150: 
 1151:   memset(&uio, 0, sizeof(uio));
 1152:   uio.inlen  = dataLen;
 1153:   uio.outlen = dataLen;
 1154: 
 1155:   memset(data, 0, dataLen);
 1156:   uio.ui.fcs.opcode = 0x80;             // M_RD_IOCTL_CMD
 1157:   uio.ui.fcs.adapno = MKADAP(m_hba);
 1158: 
 1159:   uio.data.pointer = (uint8_t *)data;
 1160: 
 1161:   uio.mbox.cmd = MEGA_MBOXCMD_PASSTHRU;
 1162:   uio.mbox.xferaddr = (intptr_t)&uio.pthru;
 1163: 
 1164:   uio.pthru.ars     = 1;
 1165:   uio.pthru.timeout = 2;
 1166:   uio.pthru.channel = 0;
 1167:   uio.pthru.target  = m_disknum;
 1168:   uio.pthru.cdblen  = cdbLen;
 1169:   uio.pthru.reqsenselen  = MAX_REQ_SENSE_LEN;
 1170:   uio.pthru.dataxferaddr = (intptr_t)data;
 1171:   uio.pthru.dataxferlen  = dataLen;
 1172:   memcpy(uio.pthru.cdb, cdb, cdbLen);
 1173: 
 1174:   rc=ioctl(m_fd, MEGAIOCCMD, &uio);
 1175:   if (uio.pthru.scsistatus || rc != 0) {
 1176:     return set_err((errno ? errno : EIO), "megadev_cmd result: %d.%d =  %d/%d",
 1177:                    m_hba, m_disknum, errno,
 1178:                    uio.pthru.scsistatus);
 1179:   }
 1180:   return true;
 1181: }
 1182: 
 1183: /////////////////////////////////////////////////////////////////////////////
 1184: /// CCISS RAID support
 1185: 
 1186: #ifdef HAVE_LINUX_CCISS_IOCTL_H
 1187: 
 1188: class linux_cciss_device
 1189: : public /*implements*/ scsi_device,
 1190:   public /*extends*/ linux_smart_device
 1191: {
 1192: public:
 1193:   linux_cciss_device(smart_interface * intf, const char * name, unsigned char disknum);
 1194: 
 1195:   virtual bool scsi_pass_through(scsi_cmnd_io * iop);
 1196: 
 1197: private:
 1198:   unsigned char m_disknum; ///< Disk number.
 1199: };
 1200: 
 1201: linux_cciss_device::linux_cciss_device(smart_interface * intf,
 1202:   const char * dev_name, unsigned char disknum)
 1203: : smart_device(intf, dev_name, "cciss", "cciss"),
 1204:   linux_smart_device(O_RDWR | O_NONBLOCK),
 1205:   m_disknum(disknum)
 1206: {
 1207:   set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);
 1208: }
 1209: 
 1210: bool linux_cciss_device::scsi_pass_through(scsi_cmnd_io * iop)
 1211: {
 1212:   int status = cciss_io_interface(get_fd(), m_disknum, iop, scsi_debugmode);
 1213:   if (status < 0)
 1214:       return set_err(-status);
 1215:   return true;
 1216: }
 1217: 
 1218: #endif // HAVE_LINUX_CCISS_IOCTL_H
 1219: 
 1220: /////////////////////////////////////////////////////////////////////////////
 1221: /// AMCC/3ware RAID support
 1222: 
 1223: class linux_escalade_device
 1224: : public /*implements*/ ata_device,
 1225:   public /*extends*/ linux_smart_device
 1226: {
 1227: public:
 1228:   enum escalade_type_t {
 1229:     AMCC_3WARE_678K,
 1230:     AMCC_3WARE_678K_CHAR,
 1231:     AMCC_3WARE_9000_CHAR,
 1232:     AMCC_3WARE_9700_CHAR
 1233:   };
 1234: 
 1235:   linux_escalade_device(smart_interface * intf, const char * dev_name,
 1236:     escalade_type_t escalade_type, int disknum);
 1237: 
 1238:   virtual bool open();
 1239: 
 1240:   virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
 1241: 
 1242: private:
 1243:   escalade_type_t m_escalade_type; ///< Controller type
 1244:   int m_disknum; ///< Disk number.
 1245: };
 1246: 
 1247: linux_escalade_device::linux_escalade_device(smart_interface * intf, const char * dev_name,
 1248:     escalade_type_t escalade_type, int disknum)
 1249: : smart_device(intf, dev_name, "3ware", "3ware"),
 1250:   linux_smart_device(O_RDONLY | O_NONBLOCK),
 1251:   m_escalade_type(escalade_type), m_disknum(disknum)
 1252: {
 1253:   set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
 1254: }
 1255: 
 1256: /* This function will setup and fix device nodes for a 3ware controller. */
 1257: #define MAJOR_STRING_LENGTH 3
 1258: #define DEVICE_STRING_LENGTH 32
 1259: #define NODE_STRING_LENGTH 16
 1260: static int setup_3ware_nodes(const char *nodename, const char *driver_name)
 1261: {
 1262:   int              tw_major      = 0;
 1263:   int              index         = 0;
 1264:   char             majorstring[MAJOR_STRING_LENGTH+1];
 1265:   char             device_name[DEVICE_STRING_LENGTH+1];
 1266:   char             nodestring[NODE_STRING_LENGTH];
 1267:   struct stat      stat_buf;
 1268:   FILE             *file;
 1269:   int              retval = 0;
 1270: #ifdef WITH_SELINUX
 1271:   security_context_t orig_context = NULL;
 1272:   security_context_t node_context = NULL;
 1273:   int                selinux_enabled  = is_selinux_enabled();
 1274:   int                selinux_enforced = security_getenforce();
 1275: #endif
 1276: 
 1277:   /* First try to open up /proc/devices */
 1278:   if (!(file = fopen("/proc/devices", "r"))) {
 1279:     pout("Error opening /proc/devices to check/create 3ware device nodes\n");
 1280:     syserror("fopen");
 1281:     return 0;  // don't fail here: user might not have /proc !
 1282:   }
 1283: 
 1284:   /* Attempt to get device major number */
 1285:   while (EOF != fscanf(file, "%3s %32s", majorstring, device_name)) {
 1286:     majorstring[MAJOR_STRING_LENGTH]='\0';
 1287:     device_name[DEVICE_STRING_LENGTH]='\0';
 1288:     if (!strncmp(device_name, nodename, DEVICE_STRING_LENGTH)) {
 1289:       tw_major = atoi(majorstring);
 1290:       break;
 1291:     }
 1292:   }
 1293:   fclose(file);
 1294: 
 1295:   /* See if we found a major device number */
 1296:   if (!tw_major) {
 1297:     pout("No major number for /dev/%s listed in /proc/devices. Is the %s driver loaded?\n", nodename, driver_name);
 1298:     return 2;
 1299:   }
 1300: #ifdef WITH_SELINUX
 1301:   /* Prepare a database of contexts for files in /dev
 1302:    * and save the current context */
 1303:   if (selinux_enabled) {
 1304:     if (matchpathcon_init_prefix(NULL, "/dev") < 0)
 1305:       pout("Error initializing contexts database for /dev");
 1306:     if (getfscreatecon(&orig_context) < 0) {
 1307:       pout("Error retrieving original SELinux fscreate context");
 1308:       if (selinux_enforced)
 1309:         matchpathcon_fini();
 1310:         return 6;
 1311:       }
 1312:   }
 1313: #endif
 1314:   /* Now check if nodes are correct */
 1315:   for (index=0; index<16; index++) {
 1316:     snprintf(nodestring, sizeof(nodestring), "/dev/%s%d", nodename, index);
 1317: #ifdef WITH_SELINUX
 1318:     /* Get context of the node and set it as the default */
 1319:     if (selinux_enabled) {
 1320:       if (matchpathcon(nodestring, S_IRUSR | S_IWUSR, &node_context) < 0) {
 1321:         pout("Could not retrieve context for %s", nodestring);
 1322:         if (selinux_enforced) {
 1323:           retval = 6;
 1324:           break;
 1325:         }
 1326:       }
 1327:       if (setfscreatecon(node_context) < 0) {
 1328:         pout ("Error setting default fscreate context");
 1329:         if (selinux_enforced) {
 1330:           retval = 6;
 1331:           break;
 1332:         }
 1333:       }
 1334:     }
 1335: #endif
 1336:     /* Try to stat the node */
 1337:     if ((stat(nodestring, &stat_buf))) {
 1338:       pout("Node %s does not exist and must be created. Check the udev rules.\n", nodestring);
 1339:       /* Create a new node if it doesn't exist */
 1340:       if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
 1341:         pout("problem creating 3ware device nodes %s", nodestring);
 1342:         syserror("mknod");
 1343:         retval = 3;
 1344:         break;
 1345:       } else {
 1346: #ifdef WITH_SELINUX
 1347: 	if (selinux_enabled && node_context) {
 1348: 	  freecon(node_context);
 1349: 	  node_context = NULL;
 1350: 	}
 1351: #endif
 1352:         continue;
 1353:       }
 1354:     }
 1355: 
 1356:     /* See if nodes major and minor numbers are correct */
 1357:     if ((tw_major != (int)(major(stat_buf.st_rdev))) ||
 1358:         (index    != (int)(minor(stat_buf.st_rdev))) ||
 1359:         (!S_ISCHR(stat_buf.st_mode))) {
 1360:       pout("Node %s has wrong major/minor number and must be created anew."
 1361:           " Check the udev rules.\n", nodestring);
 1362:       /* Delete the old node */
 1363:       if (unlink(nodestring)) {
 1364:         pout("problem unlinking stale 3ware device node %s", nodestring);
 1365:         syserror("unlink");
 1366:         retval = 4;
 1367:         break;
 1368:       }
 1369: 
 1370:       /* Make a new node */
 1371:       if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
 1372:         pout("problem creating 3ware device nodes %s", nodestring);
 1373:         syserror("mknod");
 1374:         retval = 5;
 1375:         break;
 1376:       }
 1377:     }
 1378: #ifdef WITH_SELINUX
 1379:     if (selinux_enabled && node_context) {
 1380:       freecon(node_context);
 1381:       node_context = NULL;
 1382:     }
 1383: #endif
 1384:   }
 1385: 
 1386: #ifdef WITH_SELINUX
 1387:   if (selinux_enabled) {
 1388:     if(setfscreatecon(orig_context) < 0) {
 1389:       pout("Error re-setting original fscreate context");
 1390:       if (selinux_enforced)
 1391:         retval = 6;
 1392:     }
 1393:     if(orig_context)
 1394:       freecon(orig_context);
 1395:     if(node_context)
 1396:       freecon(node_context);
 1397:     matchpathcon_fini();
 1398:   }
 1399: #endif
 1400:   return retval;
 1401: }
 1402: 
 1403: bool linux_escalade_device::open()
 1404: {
 1405:   if (m_escalade_type == AMCC_3WARE_9700_CHAR || m_escalade_type == AMCC_3WARE_9000_CHAR ||
 1406:       m_escalade_type == AMCC_3WARE_678K_CHAR) {
 1407:     // the device nodes for these controllers are dynamically assigned,
 1408:     // so we need to check that they exist with the correct major
 1409:     // numbers and if not, create them
 1410:     const char * node   = (m_escalade_type == AMCC_3WARE_9700_CHAR ? "twl"     :
 1411:                            m_escalade_type == AMCC_3WARE_9000_CHAR ? "twa"     :
 1412:                                                                      "twe"      );
 1413:     const char * driver = (m_escalade_type == AMCC_3WARE_9700_CHAR ? "3w-sas"  :
 1414:                            m_escalade_type == AMCC_3WARE_9000_CHAR ? "3w-9xxx" :
 1415:                                                                      "3w-xxxx"  );
 1416:     if (setup_3ware_nodes(node, driver))
 1417:       return set_err((errno ? errno : ENXIO), "setup_3ware_nodes(\"%s\", \"%s\") failed", node, driver);
 1418:   }
 1419:   // Continue with default open
 1420:   return linux_smart_device::open();
 1421: }
 1422: 
 1423: // TODO: Function no longer useful
 1424: //void printwarning(smart_command_set command);
 1425: 
 1426: // PURPOSE
 1427: //   This is an interface routine meant to isolate the OS dependent
 1428: //   parts of the code, and to provide a debugging interface.  Each
 1429: //   different port and OS needs to provide it's own interface.  This
 1430: //   is the linux interface to the 3ware 3w-xxxx driver.  It allows ATA
 1431: //   commands to be passed through the SCSI driver.
 1432: // DETAILED DESCRIPTION OF ARGUMENTS
 1433: //   fd: is the file descriptor provided by open()
 1434: //   disknum is the disk number (0 to 15) in the RAID array
 1435: //   escalade_type indicates the type of controller type, and if scsi or char interface is used
 1436: //   command: defines the different operations.
 1437: //   select: additional input data if needed (which log, which type of
 1438: //           self-test).
 1439: //   data:   location to write output data, if needed (512 bytes).
 1440: //   Note: not all commands use all arguments.
 1441: // RETURN VALUES
 1442: //  -1 if the command failed
 1443: //   0 if the command succeeded,
 1444: //   STATUS_CHECK routine:
 1445: //  -1 if the command failed
 1446: //   0 if the command succeeded and disk SMART status is "OK"
 1447: //   1 if the command succeeded and disk SMART status is "FAILING"
 1448: 
 1449: /* 512 is the max payload size: increase if needed */
 1450: #define BUFFER_LEN_678K      ( sizeof(TW_Ioctl)                  ) // 1044 unpacked, 1041 packed
 1451: #define BUFFER_LEN_678K_CHAR ( sizeof(TW_New_Ioctl)+512-1        ) // 1539 unpacked, 1536 packed
 1452: #define BUFFER_LEN_9000      ( sizeof(TW_Ioctl_Buf_Apache)+512-1 ) // 2051 unpacked, 2048 packed
 1453: #define TW_IOCTL_BUFFER_SIZE ( MAX(MAX(BUFFER_LEN_678K, BUFFER_LEN_9000), BUFFER_LEN_678K_CHAR) )
 1454: 
 1455: bool linux_escalade_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
 1456: {
 1457:   if (!ata_cmd_is_ok(in,
 1458:     true, // data_out_support
 1459:     false, // TODO: multi_sector_support
 1460:     true) // ata_48bit_support
 1461:   )
 1462:     return false;
 1463: 
 1464:   // Used by both the SCSI and char interfaces
 1465:   TW_Passthru *passthru=NULL;
 1466:   char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
 1467: 
 1468:   // only used for SCSI device interface
 1469:   TW_Ioctl   *tw_ioctl=NULL;
 1470:   TW_Output *tw_output=NULL;
 1471: 
 1472:   // only used for 6000/7000/8000 char device interface
 1473:   TW_New_Ioctl *tw_ioctl_char=NULL;
 1474: 
 1475:   // only used for 9000 character device interface
 1476:   TW_Ioctl_Buf_Apache *tw_ioctl_apache=NULL;
 1477: 
 1478:   memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
 1479: 
 1480:   // TODO: Handle controller differences by different classes
 1481:   if (m_escalade_type == AMCC_3WARE_9700_CHAR || m_escalade_type == AMCC_3WARE_9000_CHAR) {
 1482:     tw_ioctl_apache                               = (TW_Ioctl_Buf_Apache *)ioctl_buffer;
 1483:     tw_ioctl_apache->driver_command.control_code  = TW_IOCTL_FIRMWARE_PASS_THROUGH;
 1484:     tw_ioctl_apache->driver_command.buffer_length = 512; /* payload size */
 1485:     passthru                                      = (TW_Passthru *)&(tw_ioctl_apache->firmware_command.command.oldcommand);
 1486:   }
 1487:   else if (m_escalade_type==AMCC_3WARE_678K_CHAR) {
 1488:     tw_ioctl_char                                 = (TW_New_Ioctl *)ioctl_buffer;
 1489:     tw_ioctl_char->data_buffer_length             = 512;
 1490:     passthru                                      = (TW_Passthru *)&(tw_ioctl_char->firmware_command);
 1491:   }
 1492:   else if (m_escalade_type==AMCC_3WARE_678K) {
 1493:     tw_ioctl                                      = (TW_Ioctl *)ioctl_buffer;
 1494:     tw_ioctl->cdb[0]                              = TW_IOCTL;
 1495:     tw_ioctl->opcode                              = TW_ATA_PASSTHRU;
 1496:     tw_ioctl->input_length                        = 512; // correct even for non-data commands
 1497:     tw_ioctl->output_length                       = 512; // correct even for non-data commands
 1498:     tw_output                                     = (TW_Output *)tw_ioctl;
 1499:     passthru                                      = (TW_Passthru *)&(tw_ioctl->input_data);
 1500:   }
 1501:   else {
 1502:     return set_err(ENOSYS,
 1503:       "Unrecognized escalade_type %d in linux_3ware_command_interface(disk %d)\n"
 1504:       "Please contact " PACKAGE_BUGREPORT "\n", (int)m_escalade_type, m_disknum);
 1505:   }
 1506: 
 1507:   // Same for (almost) all commands - but some reset below
 1508:   passthru->byte0.opcode  = TW_OP_ATA_PASSTHRU;
 1509:   passthru->request_id    = 0xFF;
 1510:   passthru->unit          = m_disknum;
 1511:   passthru->status        = 0;
 1512:   passthru->flags         = 0x1;
 1513: 
 1514:   // Set registers
 1515:   {
 1516:     const ata_in_regs_48bit & r = in.in_regs;
 1517:     passthru->features     = r.features_16;
 1518:     passthru->sector_count = r.sector_count_16;
 1519:     passthru->sector_num   = r.lba_low_16;
 1520:     passthru->cylinder_lo  = r.lba_mid_16;
 1521:     passthru->cylinder_hi  = r.lba_high_16;
 1522:     passthru->drive_head   = r.device;
 1523:     passthru->command      = r.command;
 1524:   }
 1525: 
 1526:   // Is this a command that reads or returns 512 bytes?
 1527:   // passthru->param values are:
 1528:   // 0x0 - non data command without TFR write check,
 1529:   // 0x8 - non data command with TFR write check,
 1530:   // 0xD - data command that returns data to host from device
 1531:   // 0xF - data command that writes data from host to device
 1532:   // passthru->size values are 0x5 for non-data and 0x07 for data
 1533:   bool readdata = false;
 1534:   if (in.direction == ata_cmd_in::data_in) {
 1535:     readdata=true;
 1536:     passthru->byte0.sgloff = 0x5;
 1537:     passthru->size         = 0x7; // TODO: Other value for multi-sector ?
 1538:     passthru->param        = 0xD;
 1539:     // For 64-bit to work correctly, up the size of the command packet
 1540:     // in dwords by 1 to account for the 64-bit single sgl 'address'
 1541:     // field. Note that this doesn't agree with the typedefs but it's
 1542:     // right (agree with kernel driver behavior/typedefs).
 1543:     if ((m_escalade_type == AMCC_3WARE_9700_CHAR || m_escalade_type == AMCC_3WARE_9000_CHAR)
 1544:         && sizeof(long) == 8)
 1545:       passthru->size++;
 1546:   }
 1547:   else if (in.direction == ata_cmd_in::no_data) {
 1548:     // Non data command -- but doesn't use large sector
 1549:     // count register values.
 1550:     passthru->byte0.sgloff = 0x0;
 1551:     passthru->size         = 0x5;
 1552:     passthru->param        = 0x8;
 1553:     passthru->sector_count = 0x0;
 1554:   }
 1555:   else if (in.direction == ata_cmd_in::data_out) {
 1556:     if (m_escalade_type == AMCC_3WARE_9700_CHAR || m_escalade_type == AMCC_3WARE_9000_CHAR)
 1557:       memcpy(tw_ioctl_apache->data_buffer, in.buffer, in.size);
 1558:     else if (m_escalade_type == AMCC_3WARE_678K_CHAR)
 1559:       memcpy(tw_ioctl_char->data_buffer,   in.buffer, in.size);
 1560:     else {
 1561:       // COMMAND NOT SUPPORTED VIA SCSI IOCTL INTERFACE
 1562:       // memcpy(tw_output->output_data, data, 512);
 1563:       // printwarning(command); // TODO: Parameter no longer valid
 1564:       return set_err(ENOTSUP, "DATA OUT not supported for this 3ware controller type");
 1565:     }
 1566:     passthru->byte0.sgloff = 0x5;
 1567:     passthru->size         = 0x7;  // TODO: Other value for multi-sector ?
 1568:     passthru->param        = 0xF;  // PIO data write
 1569:     if ((m_escalade_type == AMCC_3WARE_9700_CHAR || m_escalade_type == AMCC_3WARE_9000_CHAR)
 1570:         && sizeof(long) == 8)
 1571:       passthru->size++;
 1572:   }
 1573:   else
 1574:     return set_err(EINVAL);
 1575: 
 1576:   // Now send the command down through an ioctl()
 1577:   int ioctlreturn;
 1578:   if (m_escalade_type == AMCC_3WARE_9700_CHAR || m_escalade_type == AMCC_3WARE_9000_CHAR)
 1579:     ioctlreturn=ioctl(get_fd(), TW_IOCTL_FIRMWARE_PASS_THROUGH, tw_ioctl_apache);
 1580:   else if (m_escalade_type==AMCC_3WARE_678K_CHAR)
 1581:     ioctlreturn=ioctl(get_fd(), TW_CMD_PACKET_WITH_DATA, tw_ioctl_char);
 1582:   else
 1583:     ioctlreturn=ioctl(get_fd(), SCSI_IOCTL_SEND_COMMAND, tw_ioctl);
 1584: 
 1585:   // Deal with the different error cases
 1586:   if (ioctlreturn) {
 1587:     if (AMCC_3WARE_678K==m_escalade_type
 1588:         && in.in_regs.command==ATA_SMART_CMD
 1589:         && (   in.in_regs.features == ATA_SMART_AUTO_OFFLINE
 1590:             || in.in_regs.features == ATA_SMART_AUTOSAVE    )
 1591:         && in.in_regs.lba_low) {
 1592:       // error here is probably a kernel driver whose version is too old
 1593:       // printwarning(command); // TODO: Parameter no longer valid
 1594:       return set_err(ENOTSUP, "Probably kernel driver too old");
 1595:     }
 1596:     return set_err(EIO);
 1597:   }
 1598: 
 1599:   // The passthru structure is valid after return from an ioctl if:
 1600:   // - we are using the character interface OR
 1601:   // - we are using the SCSI interface and this is a NON-READ-DATA command
 1602:   // For SCSI interface, note that we set passthru to a different
 1603:   // value after ioctl().
 1604:   if (AMCC_3WARE_678K==m_escalade_type) {
 1605:     if (readdata)
 1606:       passthru=NULL;
 1607:     else
 1608:       passthru=(TW_Passthru *)&(tw_output->output_data);
 1609:   }
 1610: 
 1611:   // See if the ATA command failed.  Now that we have returned from
 1612:   // the ioctl() call, if passthru is valid, then:
 1613:   // - passthru->status contains the 3ware controller STATUS
 1614:   // - passthru->command contains the ATA STATUS register
 1615:   // - passthru->features contains the ATA ERROR register
 1616:   //
 1617:   // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
 1618:   // If bit 0 (error bit) is set, then ATA ERROR register is valid.
 1619:   // While we *might* decode the ATA ERROR register, at the moment it
 1620:   // doesn't make much sense: we don't care in detail why the error
 1621:   // happened.
 1622: 
 1623:   if (passthru && (passthru->status || (passthru->command & 0x21))) {
 1624:     return set_err(EIO);
 1625:   }
 1626: 
 1627:   // If this is a read data command, copy data to output buffer
 1628:   if (readdata) {
 1629:     if (m_escalade_type == AMCC_3WARE_9700_CHAR || m_escalade_type == AMCC_3WARE_9000_CHAR)
 1630:       memcpy(in.buffer, tw_ioctl_apache->data_buffer, in.size);
 1631:     else if (m_escalade_type==AMCC_3WARE_678K_CHAR)
 1632:       memcpy(in.buffer, tw_ioctl_char->data_buffer, in.size);
 1633:     else
 1634:       memcpy(in.buffer, tw_output->output_data, in.size);
 1635:   }
 1636: 
 1637:   // Return register values
 1638:   if (passthru) {
 1639:     ata_out_regs_48bit & r = out.out_regs;
 1640:     r.error           = passthru->features;
 1641:     r.sector_count_16 = passthru->sector_count;
 1642:     r.lba_low_16      = passthru->sector_num;
 1643:     r.lba_mid_16      = passthru->cylinder_lo;
 1644:     r.lba_high_16     = passthru->cylinder_hi;
 1645:     r.device          = passthru->drive_head;
 1646:     r.status          = passthru->command;
 1647:   }
 1648: 
 1649:   // look for nonexistent devices/ports
 1650:   if (   in.in_regs.command == ATA_IDENTIFY_DEVICE
 1651:       && !nonempty(in.buffer, in.size)) {
 1652:     return set_err(ENODEV, "No drive on port %d", m_disknum);
 1653:   }
 1654: 
 1655:   return true;
 1656: }
 1657: 
 1658: /////////////////////////////////////////////////////////////////////////////
 1659: /// Areca RAID support
 1660: 
 1661: ///////////////////////////////////////////////////////////////////
 1662: // SATA(ATA) device behind Areca RAID Controller
 1663: class linux_areca_ata_device
 1664: : public /*implements*/ areca_ata_device,
 1665:   public /*extends*/ linux_smart_device
 1666: {
 1667: public:
 1668:   linux_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
 1669:   virtual smart_device * autodetect_open();
 1670:   virtual bool arcmsr_lock();
 1671:   virtual bool arcmsr_unlock();
 1672:   virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
 1673: };
 1674: 
 1675: ///////////////////////////////////////////////////////////////////
 1676: // SAS(SCSI) device behind Areca RAID Controller
 1677: class linux_areca_scsi_device
 1678: : public /*implements*/ areca_scsi_device,
 1679:   public /*extends*/ linux_smart_device
 1680: {
 1681: public:
 1682:   linux_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
 1683:   virtual smart_device * autodetect_open();
 1684:   virtual bool arcmsr_lock();
 1685:   virtual bool arcmsr_unlock();
 1686:   virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
 1687: };
 1688: 
 1689: // Looks in /proc/scsi to suggest correct areca devices
 1690: static int find_areca_in_proc()
 1691: {
 1692:     const char* proc_format_string="host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\tonline\n";
 1693: 
 1694:     // check data formwat
 1695:     FILE *fp=fopen("/proc/scsi/sg/device_hdr", "r");
 1696:     if (!fp) {
 1697:         pout("Unable to open /proc/scsi/sg/device_hdr for reading\n");
 1698:         return 1;
 1699:      }
 1700: 
 1701:      // get line, compare to format
 1702:      char linebuf[256];
 1703:      linebuf[255]='\0';
 1704:      char *out = fgets(linebuf, 256, fp);
 1705:      fclose(fp);
 1706:      if (!out) {
 1707:          pout("Unable to read contents of /proc/scsi/sg/device_hdr\n");
 1708:          return 2;
 1709:      }
 1710: 
 1711:      if (strcmp(linebuf, proc_format_string)) {
 1712:      	// wrong format!
 1713: 	// Fix this by comparing only tokens not white space!!
 1714: 	pout("Unexpected format %s in /proc/scsi/sg/device_hdr\n", proc_format_string);
 1715: 	return 3;
 1716:      }
 1717: 
 1718:     // Format is understood, now search for correct device
 1719:     fp=fopen("/proc/scsi/sg/devices", "r");
 1720:     if (!fp) return 1;
 1721:     int host, chan, id, lun, type, opens, qdepth, busy, online;
 1722:     int dev=-1;
 1723:     int found=0;
 1724:     // search all lines of /proc/scsi/sg/devices
 1725:     while (9 == fscanf(fp, "%d %d %d %d %d %d %d %d %d", &host, &chan, &id, &lun, &type, &opens, &qdepth, &busy, &online)) {
 1726:         dev++;
 1727: 	if (id == 16 && type == 3) {
 1728: 	   // devices with id=16 and type=3 might be Areca controllers
 1729: 	   pout("Device /dev/sg%d appears to be an Areca controller.\n", dev);
 1730:            found++;
 1731:         }
 1732:     }
 1733:     fclose(fp);
 1734:     return 0;
 1735: }
 1736: 
 1737: // Areca RAID Controller(SATA Disk)
 1738: linux_areca_ata_device::linux_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
 1739: : smart_device(intf, dev_name, "areca", "areca"),
 1740:   linux_smart_device(O_RDWR | O_EXCL | O_NONBLOCK)
 1741: {
 1742:   set_disknum(disknum);
 1743:   set_encnum(encnum);
 1744:   set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
 1745: }
 1746: 
 1747: smart_device * linux_areca_ata_device::autodetect_open()
 1748: {
 1749:   int is_ata = 1;
 1750: 
 1751:   // autodetect device type
 1752:   is_ata = arcmsr_get_dev_type();
 1753:   if(is_ata < 0)
 1754:   {
 1755:     set_err(EIO);
 1756:     return this;
 1757:   }
 1758: 
 1759:   if(is_ata == 1)
 1760:   {
 1761:     // SATA device
 1762:     return this;
 1763:   }
 1764: 
 1765:   // SAS device
 1766:   smart_device_auto_ptr newdev(new linux_areca_scsi_device(smi(), get_dev_name(), get_disknum(), get_encnum()));
 1767:   close();
 1768:   delete this;
 1769:   newdev->open();	// TODO: Can possibly pass open fd
 1770: 
 1771:   return newdev.release();
 1772: }
 1773: 
 1774: int linux_areca_ata_device::arcmsr_do_scsi_io(struct scsi_cmnd_io * iop)
 1775: {
 1776:   int ioctlreturn = 0;
 1777: 
 1778:   if(!is_open()) {
 1779:       if(!open()){
 1780:           find_areca_in_proc();
 1781:       }
 1782:   }
 1783: 
 1784:   ioctlreturn = do_normal_scsi_cmnd_io(get_fd(), iop, scsi_debugmode);
 1785:   if ( ioctlreturn || iop->scsi_status )
 1786:   {
 1787:     // errors found
 1788:     return -1;
 1789:   }
 1790: 
 1791:   return ioctlreturn;
 1792: }
 1793: 
 1794: bool linux_areca_ata_device::arcmsr_lock()
 1795: {
 1796:   return true;
 1797: }
 1798: 
 1799: bool linux_areca_ata_device::arcmsr_unlock()
 1800: {
 1801:   return true;
 1802: }
 1803: 
 1804: // Areca RAID Controller(SAS Device)
 1805: linux_areca_scsi_device::linux_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
 1806: : smart_device(intf, dev_name, "areca", "areca"),
 1807:   linux_smart_device(O_RDWR | O_EXCL | O_NONBLOCK)
 1808: {
 1809:   set_disknum(disknum);
 1810:   set_encnum(encnum);
 1811:   set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
 1812: }
 1813: 
 1814: smart_device * linux_areca_scsi_device::autodetect_open()
 1815: {
 1816:   return this;
 1817: }
 1818: 
 1819: int linux_areca_scsi_device::arcmsr_do_scsi_io(struct scsi_cmnd_io * iop)
 1820: {
 1821:   int ioctlreturn = 0;
 1822: 
 1823:   if(!is_open()) {
 1824:       if(!open()){
 1825:           find_areca_in_proc();
 1826:       }
 1827:   }
 1828: 
 1829:   ioctlreturn = do_normal_scsi_cmnd_io(get_fd(), iop, scsi_debugmode);
 1830:   if ( ioctlreturn || iop->scsi_status )
 1831:   {
 1832:     // errors found
 1833:     return -1;
 1834:   }
 1835: 
 1836:   return ioctlreturn;
 1837: }
 1838: 
 1839: bool linux_areca_scsi_device::arcmsr_lock()
 1840: {
 1841:   return true;
 1842: }
 1843: 
 1844: bool linux_areca_scsi_device::arcmsr_unlock()
 1845: {
 1846:   return true;
 1847: }
 1848: 
 1849: /////////////////////////////////////////////////////////////////////////////
 1850: /// Marvell support
 1851: 
 1852: class linux_marvell_device
 1853: : public /*implements*/ ata_device_with_command_set,
 1854:   public /*extends*/ linux_smart_device
 1855: {
 1856: public:
 1857:   linux_marvell_device(smart_interface * intf, const char * dev_name, const char * req_type);
 1858: 
 1859: protected:
 1860:   virtual int ata_command_interface(smart_command_set command, int select, char * data);
 1861: };
 1862: 
 1863: linux_marvell_device::linux_marvell_device(smart_interface * intf,
 1864:   const char * dev_name, const char * req_type)
 1865: : smart_device(intf, dev_name, "marvell", req_type),
 1866:   linux_smart_device(O_RDONLY | O_NONBLOCK)
 1867: {
 1868: }
 1869: 
 1870: int linux_marvell_device::ata_command_interface(smart_command_set command, int select, char * data)
 1871: {
 1872:   typedef struct {
 1873:     int  inlen;
 1874:     int  outlen;
 1875:     char cmd[540];
 1876:   } mvsata_scsi_cmd;
 1877: 
 1878:   int copydata = 0;
 1879:   mvsata_scsi_cmd  smart_command;
 1880:   unsigned char *buff = (unsigned char *)&smart_command.cmd[6];
 1881:   // See struct hd_drive_cmd_hdr in hdreg.h
 1882:   // buff[0]: ATA COMMAND CODE REGISTER
 1883:   // buff[1]: ATA SECTOR NUMBER REGISTER
 1884:   // buff[2]: ATA FEATURES REGISTER
 1885:   // buff[3]: ATA SECTOR COUNT REGISTER
 1886: 
 1887:   // clear out buff.  Large enough for HDIO_DRIVE_CMD (4+512 bytes)
 1888:   memset(&smart_command, 0, sizeof(smart_command));
 1889:   smart_command.inlen = 540;
 1890:   smart_command.outlen = 540;
 1891:   smart_command.cmd[0] = 0xC;  //Vendor-specific code
 1892:   smart_command.cmd[4] = 6;     //command length
 1893: 
 1894:   buff[0] = ATA_SMART_CMD;
 1895:   switch (command){
 1896:   case CHECK_POWER_MODE:
 1897:     buff[0]=ATA_CHECK_POWER_MODE;
 1898:     break;
 1899:   case READ_VALUES:
 1900:     buff[2]=ATA_SMART_READ_VALUES;
 1901:     copydata=buff[3]=1;
 1902:     break;
 1903:   case READ_THRESHOLDS:
 1904:     buff[2]=ATA_SMART_READ_THRESHOLDS;
 1905:     copydata=buff[1]=buff[3]=1;
 1906:     break;
 1907:   case READ_LOG:
 1908:     buff[2]=ATA_SMART_READ_LOG_SECTOR;
 1909:     buff[1]=select;
 1910:     copydata=buff[3]=1;
 1911:     break;
 1912:   case IDENTIFY:
 1913:     buff[0]=ATA_IDENTIFY_DEVICE;
 1914:     copydata=buff[3]=1;
 1915:     break;
 1916:   case PIDENTIFY:
 1917:     buff[0]=ATA_IDENTIFY_PACKET_DEVICE;
 1918:     copydata=buff[3]=1;
 1919:     break;
 1920:   case ENABLE:
 1921:     buff[2]=ATA_SMART_ENABLE;
 1922:     buff[1]=1;
 1923:     break;
 1924:   case DISABLE:
 1925:     buff[2]=ATA_SMART_DISABLE;
 1926:     buff[1]=1;
 1927:     break;
 1928:   case STATUS:
 1929:   case STATUS_CHECK:
 1930:     // this command only says if SMART is working.  It could be
 1931:     // replaced with STATUS_CHECK below.
 1932:     buff[2] = ATA_SMART_STATUS;
 1933:     break;
 1934:   case AUTO_OFFLINE:
 1935:     buff[2]=ATA_SMART_AUTO_OFFLINE;
 1936:     buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
 1937:     break;
 1938:   case AUTOSAVE:
 1939:     buff[2]=ATA_SMART_AUTOSAVE;
 1940:     buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
 1941:     break;
 1942:   case IMMEDIATE_OFFLINE:
 1943:     buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
 1944:     buff[1]=select;
 1945:     break;
 1946:   default:
 1947:     pout("Unrecognized command %d in mvsata_os_specific_handler()\n", command);
 1948:     EXIT(1);
 1949:     break;
 1950:   }
 1951:   // There are two different types of ioctls().  The HDIO_DRIVE_TASK
 1952:   // one is this:
 1953:   // We are now doing the HDIO_DRIVE_CMD type ioctl.
 1954:   if (ioctl(get_fd(), SCSI_IOCTL_SEND_COMMAND, (void *)&smart_command))
 1955:       return -1;
 1956: 
 1957:   if (command==CHECK_POWER_MODE) {
 1958:     // LEON -- CHECK THIS PLEASE.  THIS SHOULD BE THE SECTOR COUNT
 1959:     // REGISTER, AND IT MIGHT BE buff[2] NOT buff[3].  Bruce
 1960:     data[0]=buff[3];
 1961:     return 0;
 1962:   }
 1963: 
 1964:   // Always succeed on a SMART status, as a disk that failed returned
 1965:   // buff[4]=0xF4, buff[5]=0x2C, i.e. "Bad SMART status" (see below).
 1966:   if (command == STATUS)
 1967:     return 0;
 1968:   //Data returned is starting from 0 offset
 1969:   if (command == STATUS_CHECK)
 1970:   {
 1971:     // Cyl low and Cyl high unchanged means "Good SMART status"
 1972:     if (buff[4] == 0x4F && buff[5] == 0xC2)
 1973:       return 0;
 1974:     // These values mean "Bad SMART status"
 1975:     if (buff[4] == 0xF4 && buff[5] == 0x2C)
 1976:       return 1;
 1977:     // We haven't gotten output that makes sense; print out some debugging info
 1978:     syserror("Error SMART Status command failed");
 1979:     pout("Please get assistance from %s\n",PACKAGE_BUGREPORT);
 1980:     pout("Register values returned from SMART Status command are:\n");
 1981:     pout("CMD =0x%02x\n",(int)buff[0]);
 1982:     pout("FR =0x%02x\n",(int)buff[1]);
 1983:     pout("NS =0x%02x\n",(int)buff[2]);
 1984:     pout("SC =0x%02x\n",(int)buff[3]);
 1985:     pout("CL =0x%02x\n",(int)buff[4]);
 1986:     pout("CH =0x%02x\n",(int)buff[5]);
 1987:     pout("SEL=0x%02x\n",(int)buff[6]);
 1988:     return -1;
 1989:   }
 1990: 
 1991:   if (copydata)
 1992:     memcpy(data, buff, 512);
 1993:   return 0;
 1994: }
 1995: 
 1996: /////////////////////////////////////////////////////////////////////////////
 1997: /// Highpoint RAID support
 1998: 
 1999: class linux_highpoint_device
 2000: : public /*implements*/ ata_device_with_command_set,
 2001:   public /*extends*/ linux_smart_device
 2002: {
 2003: public:
 2004:   linux_highpoint_device(smart_interface * intf, const char * dev_name,
 2005:     unsigned char controller, unsigned char channel, unsigned char port);
 2006: 
 2007: protected:
 2008:   virtual int ata_command_interface(smart_command_set command, int select, char * data);
 2009: 
 2010: private:
 2011:   unsigned char m_hpt_data[3]; ///< controller/channel/port
 2012: };
 2013: 
 2014: linux_highpoint_device::linux_highpoint_device(smart_interface * intf, const char * dev_name,
 2015:   unsigned char controller, unsigned char channel, unsigned char port)
 2016: : smart_device(intf, dev_name, "hpt", "hpt"),
 2017:   linux_smart_device(O_RDONLY | O_NONBLOCK)
 2018: {
 2019:   m_hpt_data[0] = controller; m_hpt_data[1] = channel; m_hpt_data[2] = port;
 2020:   set_info().info_name = strprintf("%s [hpt_disk_%u/%u/%u]", dev_name, m_hpt_data[0], m_hpt_data[1], m_hpt_data[2]);
 2021: }
 2022: 
 2023: // this implementation is derived from ata_command_interface with a header
 2024: // packing for highpoint linux driver ioctl interface
 2025: //
 2026: // ioctl(fd,HPTIO_CTL,buff)
 2027: //          ^^^^^^^^^
 2028: //
 2029: // structure of hpt_buff
 2030: // +----+----+----+----+--------------------.....---------------------+
 2031: // | 1  | 2  | 3  | 4  | 5                                            |
 2032: // +----+----+----+----+--------------------.....---------------------+
 2033: //
 2034: // 1: The target controller                     [ int    ( 4 Bytes ) ]
 2035: // 2: The channel of the target controllee      [ int    ( 4 Bytes ) ]
 2036: // 3: HDIO_ ioctl call                          [ int    ( 4 Bytes ) ]
 2037: //    available from ${LINUX_KERNEL_SOURCE}/Documentation/ioctl/hdio
 2038: // 4: the pmport that disk attached,            [ int    ( 4 Bytes ) ]
 2039: //    if no pmport device, set to 1 or leave blank
 2040: // 5: data                                      [ void * ( var leangth ) ]
 2041: //
 2042: #define STRANGE_BUFFER_LENGTH (4+512*0xf8)
 2043: 
 2044: int linux_highpoint_device::ata_command_interface(smart_command_set command, int select, char * data)
 2045: {
 2046:   unsigned char hpt_buff[4*sizeof(int) + STRANGE_BUFFER_LENGTH];
 2047:   unsigned int *hpt = (unsigned int *)hpt_buff;
 2048:   unsigned char *buff = &hpt_buff[4*sizeof(int)];
 2049:   int copydata = 0;
 2050:   const int HDIO_DRIVE_CMD_OFFSET = 4;
 2051: 
 2052:   memset(hpt_buff, 0, 4*sizeof(int) + STRANGE_BUFFER_LENGTH);
 2053:   hpt[0] = m_hpt_data[0]; // controller id
 2054:   hpt[1] = m_hpt_data[1]; // channel number
 2055:   hpt[3] = m_hpt_data[2]; // pmport number
 2056: 
 2057:   buff[0]=ATA_SMART_CMD;
 2058:   switch (command){
 2059:   case CHECK_POWER_MODE:
 2060:     buff[0]=ATA_CHECK_POWER_MODE;
 2061:     copydata=1;
 2062:     break;
 2063:   case READ_VALUES:
 2064:     buff[2]=ATA_SMART_READ_VALUES;
 2065:     buff[3]=1;
 2066:     copydata=512;
 2067:     break;
 2068:   case READ_THRESHOLDS:
 2069:     buff[2]=ATA_SMART_READ_THRESHOLDS;
 2070:     buff[1]=buff[3]=1;
 2071:     copydata=512;
 2072:     break;
 2073:   case READ_LOG:
 2074:     buff[2]=ATA_SMART_READ_LOG_SECTOR;
 2075:     buff[1]=select;
 2076:     buff[3]=1;
 2077:     copydata=512;
 2078:     break;
 2079:   case WRITE_LOG:
 2080:     break;
 2081:   case IDENTIFY:
 2082:     buff[0]=ATA_IDENTIFY_DEVICE;
 2083:     buff[3]=1;
 2084:     copydata=512;
 2085:     break;
 2086:   case PIDENTIFY:
 2087:     buff[0]=ATA_IDENTIFY_PACKET_DEVICE;
 2088:     buff[3]=1;
 2089:     copydata=512;
 2090:     break;
 2091:   case ENABLE:
 2092:     buff[2]=ATA_SMART_ENABLE;
 2093:     buff[1]=1;
 2094:     break;
 2095:   case DISABLE:
 2096:     buff[2]=ATA_SMART_DISABLE;
 2097:     buff[1]=1;
 2098:     break;
 2099:   case STATUS:
 2100:     buff[2]=ATA_SMART_STATUS;
 2101:     break;
 2102:   case AUTO_OFFLINE:
 2103:     buff[2]=ATA_SMART_AUTO_OFFLINE;
 2104:     buff[3]=select;
 2105:     break;
 2106:   case AUTOSAVE:
 2107:     buff[2]=ATA_SMART_AUTOSAVE;
 2108:     buff[3]=select;
 2109:     break;
 2110:   case IMMEDIATE_OFFLINE:
 2111:     buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
 2112:     buff[1]=select;
 2113:     break;
 2114:   case STATUS_CHECK:
 2115:     buff[1]=ATA_SMART_STATUS;
 2116:     break;
 2117:   default:
 2118:     pout("Unrecognized command %d in linux_highpoint_command_interface()\n"
 2119:          "Please contact " PACKAGE_BUGREPORT "\n", command);
 2120:     errno=ENOSYS;
 2121:     return -1;
 2122:   }
 2123: 
 2124:   if (command==WRITE_LOG) {
 2125:     unsigned char task[4*sizeof(int)+sizeof(ide_task_request_t)+512];
 2126:     unsigned int *hpt_tf = (unsigned int *)task;
 2127:     ide_task_request_t *reqtask = (ide_task_request_t *)(&task[4*sizeof(int)]);
 2128:     task_struct_t *taskfile = (task_struct_t *)reqtask->io_ports;
 2129:     int retval;
 2130: 
 2131:     memset(task, 0, sizeof(task));
 2132: 
 2133:     hpt_tf[0] = m_hpt_data[0]; // controller id
 2134:     hpt_tf[1] = m_hpt_data[1]; // channel number
 2135:     hpt_tf[3] = m_hpt_data[2]; // pmport number
 2136:     hpt_tf[2] = HDIO_DRIVE_TASKFILE; // real hd ioctl
 2137: 
 2138:     taskfile->data           = 0;
 2139:     taskfile->feature        = ATA_SMART_WRITE_LOG_SECTOR;
 2140:     taskfile->sector_count   = 1;
 2141:     taskfile->sector_number  = select;
 2142:     taskfile->low_cylinder   = 0x4f;
 2143:     taskfile->high_cylinder  = 0xc2;
 2144:     taskfile->device_head    = 0;
 2145:     taskfile->command        = ATA_SMART_CMD;
 2146: 
 2147:     reqtask->data_phase      = TASKFILE_OUT;
 2148:     reqtask->req_cmd         = IDE_DRIVE_TASK_OUT;
 2149:     reqtask->out_size        = 512;
 2150:     reqtask->in_size         = 0;
 2151: 
 2152:     memcpy(task+sizeof(ide_task_request_t)+4*sizeof(int), data, 512);
 2153: 
 2154:     if ((retval=ioctl(get_fd(), HPTIO_CTL, task))) {
 2155:       if (retval==-EINVAL)
 2156:         pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
 2157:       return -1;
 2158:     }
 2159:     return 0;
 2160:   }
 2161: 
 2162:   if (command==STATUS_CHECK){
 2163:     int retval;
 2164:     unsigned const char normal_lo=0x4f, normal_hi=0xc2;
 2165:     unsigned const char failed_lo=0xf4, failed_hi=0x2c;
 2166:     buff[4]=normal_lo;
 2167:     buff[5]=normal_hi;
 2168: 
 2169:     hpt[2] = HDIO_DRIVE_TASK;
 2170: 
 2171:     if ((retval=ioctl(get_fd(), HPTIO_CTL, hpt_buff))) {
 2172:       if (retval==-EINVAL) {
 2173:         pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
 2174:         pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
 2175:       }
 2176:       else
 2177:         syserror("Error SMART Status command failed");
 2178:       return -1;
 2179:     }
 2180: 
 2181:     if (buff[4]==normal_lo && buff[5]==normal_hi)
 2182:       return 0;
 2183: 
 2184:     if (buff[4]==failed_lo && buff[5]==failed_hi)
 2185:       return 1;
 2186: 
 2187:     syserror("Error SMART Status command failed");
 2188:     pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
 2189:     pout("Register values returned from SMART Status command are:\n");
 2190:     pout("CMD=0x%02x\n",(int)buff[0]);
 2191:     pout("FR =0x%02x\n",(int)buff[1]);
 2192:     pout("NS =0x%02x\n",(int)buff[2]);
 2193:     pout("SC =0x%02x\n",(int)buff[3]);
 2194:     pout("CL =0x%02x\n",(int)buff[4]);
 2195:     pout("CH =0x%02x\n",(int)buff[5]);
 2196:     pout("SEL=0x%02x\n",(int)buff[6]);
 2197:     return -1;
 2198:   }
 2199: 
 2200: #if 1
 2201:   if (command==IDENTIFY || command==PIDENTIFY) {
 2202:     unsigned char deviceid[4*sizeof(int)+512*sizeof(char)];
 2203:     unsigned int *hpt_id = (unsigned int *)deviceid;
 2204: 
 2205:     hpt_id[0] = m_hpt_data[0]; // controller id
 2206:     hpt_id[1] = m_hpt_data[1]; // channel number
 2207:     hpt_id[3] = m_hpt_data[2]; // pmport number
 2208: 
 2209:     hpt_id[2] = HDIO_GET_IDENTITY;
 2210:     if (!ioctl(get_fd(), HPTIO_CTL, deviceid) && (deviceid[4*sizeof(int)] & 0x8000))
 2211:       buff[0]=(command==IDENTIFY)?ATA_IDENTIFY_PACKET_DEVICE:ATA_IDENTIFY_DEVICE;
 2212:   }
 2213: #endif
 2214: 
 2215:   hpt[2] = HDIO_DRIVE_CMD;
 2216:   if ((ioctl(get_fd(), HPTIO_CTL, hpt_buff)))
 2217:     return -1;
 2218: 
 2219:   if (command==CHECK_POWER_MODE)
 2220:     buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
 2221: 
 2222:   if (copydata)
 2223:     memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
 2224: 
 2225:   return 0;
 2226: }
 2227: 
 2228: #if 0 // TODO: Migrate from 'smart_command_set' to 'ata_in_regs' OR remove the function
 2229: // Utility function for printing warnings
 2230: void printwarning(smart_command_set command){
 2231:   static int printed[4]={0,0,0,0};
 2232:   const char* message=
 2233:     "can not be passed through the 3ware 3w-xxxx driver.  This can be fixed by\n"
 2234:     "applying a simple 3w-xxxx driver patch that can be found here:\n"
 2235:     PACKAGE_HOMEPAGE "\n"
 2236:     "Alternatively, upgrade your 3w-xxxx driver to version 1.02.00.037 or greater.\n\n";
 2237: 
 2238:   if (command==AUTO_OFFLINE && !printed[0]) {
 2239:     printed[0]=1;
 2240:     pout("The SMART AUTO-OFFLINE ENABLE command (smartmontools -o on option/Directive)\n%s", message);
 2241:   }
 2242:   else if (command==AUTOSAVE && !printed[1]) {
 2243:     printed[1]=1;
 2244:     pout("The SMART AUTOSAVE ENABLE command (smartmontools -S on option/Directive)\n%s", message);
 2245:   }
 2246:   else if (command==STATUS_CHECK && !printed[2]) {
 2247:     printed[2]=1;
 2248:     pout("The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n%s", message);
 2249:   }
 2250:   else if (command==WRITE_LOG && !printed[3])  {
 2251:     printed[3]=1;
 2252:     pout("The SMART WRITE LOG command (smartmontools -t selective) only supported via char /dev/tw[ae] interface\n");
 2253:   }
 2254: 
 2255:   return;
 2256: }
 2257: #endif
 2258: 
 2259: /////////////////////////////////////////////////////////////////////////////
 2260: /// SCSI open with autodetection support
 2261: 
 2262: smart_device * linux_scsi_device::autodetect_open()
 2263: {
 2264:   // Open device
 2265:   if (!open())
 2266:     return this;
 2267: 
 2268:   // No Autodetection if device type was specified by user
 2269:   bool sat_only = false;
 2270:   if (*get_req_type()) {
 2271:     // Detect SAT if device object was created by scan_smart_devices().
 2272:     if (!(m_scanning && !strcmp(get_req_type(), "sat")))
 2273:       return this;
 2274:     sat_only = true;
 2275:   }
 2276: 
 2277:   // The code below is based on smartd.cpp:SCSIFilterKnown()
 2278: 
 2279:   // Get INQUIRY
 2280:   unsigned char req_buff[64] = {0, };
 2281:   int req_len = 36;
 2282:   if (scsiStdInquiry(this, req_buff, req_len)) {
 2283:     // Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices
 2284:     // watch this spot ... other devices could lock up here
 2285:     req_len = 64;
 2286:     if (scsiStdInquiry(this, req_buff, req_len)) {
 2287:       // device doesn't like INQUIRY commands
 2288:       close();
 2289:       set_err(EIO, "INQUIRY failed");
 2290:       return this;
 2291:     }
 2292:   }
 2293: 
 2294:   int avail_len = req_buff[4] + 5;
 2295:   int len = (avail_len < req_len ? avail_len : req_len);
 2296:   if (len < 36) {
 2297:     if (sat_only) {
 2298:       close();
 2299:       set_err(EIO, "INQUIRY too short for SAT");
 2300:     }
 2301:     return this;
 2302:   }
 2303: 
 2304:   // Use INQUIRY to detect type
 2305:   if (!sat_only) {
 2306: 
 2307:     // 3ware ?
 2308:     if (!memcmp(req_buff + 8, "3ware", 5) || !memcmp(req_buff + 8, "AMCC", 4)) {
 2309:       close();
 2310:       set_err(EINVAL, "AMCC/3ware controller, please try adding '-d 3ware,N',\n"
 2311:                       "you may need to replace %s with /dev/twlN, /dev/twaN or /dev/tweN", get_dev_name());
 2312:       return this;
 2313:     }
 2314: 
 2315:     // DELL?
 2316:     if (!memcmp(req_buff + 8, "DELL    PERC", 12) || !memcmp(req_buff + 8, "MegaRAID", 8)
 2317:         || !memcmp(req_buff + 16, "PERC H700", 9) || !memcmp(req_buff + 8, "LSI\0",4)
 2318:     ) {
 2319:       close();
 2320:       set_err(EINVAL, "DELL or MegaRaid controller, please try adding '-d megaraid,N'");
 2321:       return this;
 2322:     }
 2323: 
 2324:     // Marvell ?
 2325:     if (len >= 42 && !memcmp(req_buff + 36, "MVSATA", 6)) {
 2326:       //pout("Device %s: using '-d marvell' for ATA disk with Marvell driver\n", get_dev_name());
 2327:       close();
 2328:       smart_device_auto_ptr newdev(
 2329:         new linux_marvell_device(smi(), get_dev_name(), get_req_type())
 2330:       );
 2331:       newdev->open(); // TODO: Can possibly pass open fd
 2332:       delete this;
 2333:       return newdev.release();
 2334:     }
 2335:   }
 2336: 
 2337:   // SAT or USB ?
 2338:   {
 2339:     smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
 2340:     if (newdev)
 2341:       // NOTE: 'this' is now owned by '*newdev'
 2342:       return newdev;
 2343:   }
 2344: 
 2345:   // Nothing special found
 2346: 
 2347:   if (sat_only) {
 2348:     close();
 2349:     set_err(EIO, "Not a SAT device");
 2350:   }
 2351:   return this;
 2352: }
 2353: 
 2354: //////////////////////////////////////////////////////////////////////
 2355: // USB bridge ID detection
 2356: 
 2357: // Read USB ID from /sys file
 2358: static bool read_id(const std::string & path, unsigned short & id)
 2359: {
 2360:   FILE * f = fopen(path.c_str(), "r");
 2361:   if (!f)
 2362:     return false;
 2363:   int n = -1;
 2364:   bool ok = (fscanf(f, "%hx%n", &id, &n) == 1 && n == 4);
 2365:   fclose(f);
 2366:   return ok;
 2367: }
 2368: 
 2369: // Get USB bridge ID for "sdX"
 2370: static bool get_usb_id(const char * name, unsigned short & vendor_id,
 2371:                        unsigned short & product_id, unsigned short & version)
 2372: {
 2373:   // Only "sdX" supported
 2374:   if (!(!strncmp(name, "sd", 2) && !strchr(name, '/')))
 2375:     return false;
 2376: 
 2377:   // Start search at dir referenced by symlink "/sys/block/sdX/device"
 2378:   // -> "/sys/devices/.../usb*/.../host*/target*/..."
 2379:   std::string dir = strprintf("/sys/block/%s/device", name);
 2380: 
 2381:   // Stop search at "/sys/devices"
 2382:   struct stat st;
 2383:   if (stat("/sys/devices", &st))
 2384:     return false;
 2385:   ino_t stop_ino = st.st_ino;
 2386: 
 2387:   // Search in parent directories until "idVendor" is found,
 2388:   // fail if "/sys/devices" reached or too many iterations
 2389:   int cnt = 0;
 2390:   do {
 2391:     dir += "/..";
 2392:     if (!(++cnt < 10 && !stat(dir.c_str(), &st) && st.st_ino != stop_ino))
 2393:       return false;
 2394:   } while (access((dir + "/idVendor").c_str(), 0));
 2395: 
 2396:   // Read IDs
 2397:   if (!(   read_id(dir + "/idVendor", vendor_id)
 2398:         && read_id(dir + "/idProduct", product_id)
 2399:         && read_id(dir + "/bcdDevice", version)   ))
 2400:     return false;
 2401: 
 2402:   if (scsi_debugmode > 1)
 2403:     pout("USB ID = 0x%04x:0x%04x (0x%03x)\n", vendor_id, product_id, version);
 2404:   return true;
 2405: }
 2406: 
 2407: //////////////////////////////////////////////////////////////////////
 2408: /// Linux interface
 2409: 
 2410: class linux_smart_interface
 2411: : public /*implements*/ smart_interface
 2412: {
 2413: public:
 2414:   virtual std::string get_os_version_str();
 2415: 
 2416:   virtual std::string get_app_examples(const char * appname);
 2417: 
 2418:   virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
 2419:     const char * pattern = 0);
 2420: 
 2421: protected:
 2422:   virtual ata_device * get_ata_device(const char * name, const char * type);
 2423: 
 2424:   virtual scsi_device * get_scsi_device(const char * name, const char * type);
 2425: 
 2426:   virtual smart_device * autodetect_smart_device(const char * name);
 2427: 
 2428:   virtual smart_device * get_custom_smart_device(const char * name, const char * type);
 2429: 
 2430:   virtual std::string get_valid_custom_dev_types_str();
 2431: 
 2432: private:
 2433:   bool get_dev_list(smart_device_list & devlist, const char * pattern,
 2434:     bool scan_ata, bool scan_scsi, const char * req_type, bool autodetect);
 2435:   bool get_dev_megasas(smart_device_list & devlist);
 2436:   smart_device * missing_option(const char * opt);
 2437:   int megasas_dcmd_cmd(int bus_no, uint32_t opcode, void *buf,
 2438:     size_t bufsize, uint8_t *mbox, size_t mboxlen, uint8_t *statusp);
 2439:   int megasas_pd_add_list(int bus_no, smart_device_list & devlist);
 2440: };
 2441: 
 2442: std::string linux_smart_interface::get_os_version_str()
 2443: {
 2444:   struct utsname u;
 2445:   if (!uname(&u))
 2446:     return strprintf("%s-linux-%s", u.machine, u.release);
 2447:   else
 2448:     return SMARTMONTOOLS_BUILD_HOST;
 2449: }
 2450: 
 2451: std::string linux_smart_interface::get_app_examples(const char * appname)
 2452: {
 2453:   if (!strcmp(appname, "smartctl"))
 2454:     return smartctl_examples;
 2455:   return "";
 2456: }
 2457: 
 2458: // we are going to take advantage of the fact that Linux's devfs will only
 2459: // have device entries for devices that exist.  So if we get the equivalent of
 2460: // ls /dev/hd[a-t], we have all the ATA devices on the system
 2461: bool linux_smart_interface::get_dev_list(smart_device_list & devlist,
 2462:   const char * pattern, bool scan_ata, bool scan_scsi,
 2463:   const char * req_type, bool autodetect)
 2464: {
 2465:   // Use glob to look for any directory entries matching the pattern
 2466:   glob_t globbuf;
 2467:   memset(&globbuf, 0, sizeof(globbuf));
 2468:   int retglob = glob(pattern, GLOB_ERR, NULL, &globbuf);
 2469:   if (retglob) {
 2470:     //  glob failed: free memory and return
 2471:     globfree(&globbuf);
 2472: 
 2473:     if (retglob==GLOB_NOMATCH){
 2474:       pout("glob(3) found no matches for pattern %s\n", pattern);
 2475:       return true;
 2476:     }
 2477: 
 2478:     if (retglob==GLOB_NOSPACE)
 2479:       set_err(ENOMEM, "glob(3) ran out of memory matching pattern %s", pattern);
 2480: #ifdef GLOB_ABORTED // missing in old versions of glob.h
 2481:     else if (retglob==GLOB_ABORTED)
 2482:       set_err(EINVAL, "glob(3) aborted matching pattern %s", pattern);
 2483: #endif
 2484:     else
 2485:       set_err(EINVAL, "Unexplained error in glob(3) of pattern %s", pattern);
 2486: 
 2487:     return false;
 2488:   }
 2489: 
 2490:   // did we find too many paths?
 2491:   const int max_pathc = 32;
 2492:   int n = (int)globbuf.gl_pathc;
 2493:   if (n > max_pathc) {
 2494:     pout("glob(3) found %d > MAX=%d devices matching pattern %s: ignoring %d paths\n",
 2495:          n, max_pathc, pattern, n - max_pathc);
 2496:     n = max_pathc;
 2497:   }
 2498: 
 2499:   // now step through the list returned by glob.  If not a link, copy
 2500:   // to list.  If it is a link, evaluate it and see if the path ends
 2501:   // in "disc".
 2502:   for (int i = 0; i < n; i++){
 2503:     // see if path is a link
 2504:     char linkbuf[1024];
 2505:     int retlink = readlink(globbuf.gl_pathv[i], linkbuf, sizeof(linkbuf)-1);
 2506: 
 2507:     char tmpname[1024]={0};
 2508:     const char * name = 0;
 2509:     bool is_scsi = scan_scsi;
 2510:     // if not a link (or a strange link), keep it
 2511:     if (retlink<=0 || retlink>1023)
 2512:       name = globbuf.gl_pathv[i];
 2513:     else {
 2514:       // or if it's a link that points to a disc, follow it
 2515:       linkbuf[retlink] = 0;
 2516:       const char *p;
 2517:       if ((p=strrchr(linkbuf, '/')) && !strcmp(p+1, "disc"))
 2518:         // This is the branch of the code that gets followed if we are
 2519:         // using devfs WITH traditional compatibility links. In this
 2520:         // case, we add the traditional device name to the list that
 2521:         // is returned.
 2522:         name = globbuf.gl_pathv[i];
 2523:       else {
 2524:         // This is the branch of the code that gets followed if we are
 2525:         // using devfs WITHOUT traditional compatibility links.  In
 2526:         // this case, we check that the link to the directory is of
 2527:         // the correct type, and then append "disc" to it.
 2528:         bool match_ata  = strstr(linkbuf, "ide");
 2529:         bool match_scsi = strstr(linkbuf, "scsi");
 2530:         if (((match_ata && scan_ata) || (match_scsi && scan_scsi)) && !(match_ata && match_scsi)) {
 2531:           is_scsi = match_scsi;
 2532:           snprintf(tmpname, sizeof(tmpname), "%s/disc", globbuf.gl_pathv[i]);
 2533:           name = tmpname;
 2534:         }
 2535:       }
 2536:     }
 2537: 
 2538:     if (name) {
 2539:       // Found a name, add device to list.
 2540:       smart_device * dev;
 2541:       if (autodetect)
 2542:         dev = autodetect_smart_device(name);
 2543:       else if (is_scsi)
 2544:         dev = new linux_scsi_device(this, name, req_type, true /*scanning*/);
 2545:       else
 2546:         dev = new linux_ata_device(this, name, req_type);
 2547:       if (dev) // autodetect_smart_device() may return nullptr.
 2548:         devlist.push_back(dev);
 2549:     }
 2550:   }
 2551: 
 2552:   // free memory
 2553:   globfree(&globbuf);
 2554:   return true;
 2555: }
 2556: 
 2557: // getting devices from LSI SAS MegaRaid, if available
 2558: bool linux_smart_interface::get_dev_megasas(smart_device_list & devlist)
 2559: {
 2560:   /* Scanning of disks on MegaRaid device */
 2561:   /* Perform mknod of device ioctl node */
 2562:   int   mjr, n1;
 2563:   char line[128];
 2564:   bool scan_megasas = false;
 2565:   FILE * fp = fopen("/proc/devices", "r");
 2566:   while (fgets(line, sizeof(line), fp) != NULL) {
 2567:     n1=0;
 2568:     if (sscanf(line, "%d megaraid_sas_ioctl%n", &mjr, &n1) == 1 && n1 == 22) {
 2569:       scan_megasas = true;
 2570:       n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR, makedev(mjr, 0));
 2571:       if(scsi_debugmode > 0)
 2572:         pout("Creating /dev/megaraid_sas_ioctl_node = %d\n", n1 >= 0 ? 0 : errno);
 2573:       if (n1 >= 0 || errno == EEXIST)
 2574:         break;
 2575:     }
 2576:   }
 2577:   fclose(fp);
 2578: 
 2579:   if(!scan_megasas)
 2580:     return false;
 2581: 
 2582:   // getting bus numbers with megasas devices
 2583:   struct dirent *ep;
 2584:   unsigned int host_no = 0;
 2585:   char sysfsdir[256];
 2586: 
 2587:   /* we are using sysfs to get list of all scsi hosts */
 2588:   DIR * dp = opendir ("/sys/class/scsi_host/");
 2589:   if (dp != NULL)
 2590:   {
 2591:     while ((ep = readdir (dp)) != NULL) {
 2592:       if (!sscanf(ep->d_name, "host%d", &host_no)) 
 2593:         continue;
 2594:       /* proc_name should be megaraid_sas */
 2595:       snprintf(sysfsdir, sizeof(sysfsdir) - 1,
 2596:         "/sys/class/scsi_host/host%d/proc_name", host_no);
 2597:       if((fp = fopen(sysfsdir, "r")) == NULL)
 2598:         continue;
 2599:       if(fgets(line, sizeof(line), fp) != NULL && !strncmp(line,"megaraid_sas",12)) {
 2600:         megasas_pd_add_list(host_no, devlist);
 2601:       }
 2602:       fclose(fp);
 2603:     }
 2604:     (void) closedir (dp);
 2605:   } else { /* sysfs not mounted ? */
 2606:     for(unsigned i = 0; i <=16; i++) // trying to add devices on first 16 buses
 2607:       megasas_pd_add_list(i, devlist);
 2608:   }
 2609:   return true;
 2610: }
 2611: 
 2612: bool linux_smart_interface::scan_smart_devices(smart_device_list & devlist,
 2613:   const char * type, const char * pattern /*= 0*/)
 2614: {
 2615:   if (pattern) {
 2616:     set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
 2617:     return false;
 2618:   }
 2619: 
 2620:   if (!type)
 2621:     type = "";
 2622: 
 2623:   bool scan_ata  = (!*type || !strcmp(type, "ata" ));
 2624:   // "sat" detection will be later handled in linux_scsi_device::autodetect_open()
 2625:   bool scan_scsi = (!*type || !strcmp(type, "scsi") || !strcmp(type, "sat"));
 2626:   if (!(scan_ata || scan_scsi))
 2627:     return true;
 2628: 
 2629:   if (scan_ata)
 2630:     get_dev_list(devlist, "/dev/hd[a-t]", true, false, type, false);
 2631:   if (scan_scsi) {
 2632:     bool autodetect = !*type; // Try USB autodetection if no type specifed
 2633:     get_dev_list(devlist, "/dev/sd[a-z]", false, true, type, autodetect);
 2634:     // Support up to 104 devices
 2635:     get_dev_list(devlist, "/dev/sd[a-c][a-z]", false, true, type, autodetect);
 2636:     // get device list from the megaraid device
 2637:     get_dev_megasas(devlist);
 2638:   }
 2639: 
 2640:   // if we found traditional links, we are done
 2641:   if (devlist.size() > 0)
 2642:     return true;
 2643: 
 2644:   // else look for devfs entries without traditional links
 2645:   // TODO: Add udev support
 2646:   return get_dev_list(devlist, "/dev/discs/disc*", scan_ata, scan_scsi, type, false);
 2647: }
 2648: 
 2649: ata_device * linux_smart_interface::get_ata_device(const char * name, const char * type)
 2650: {
 2651:   return new linux_ata_device(this, name, type);
 2652: }
 2653: 
 2654: scsi_device * linux_smart_interface::get_scsi_device(const char * name, const char * type)
 2655: {
 2656:   return new linux_scsi_device(this, name, type);
 2657: }
 2658: 
 2659: smart_device * linux_smart_interface::missing_option(const char * opt)
 2660: {
 2661:   set_err(EINVAL, "requires option '%s'", opt);
 2662:   return 0;
 2663: }
 2664: 
 2665: int
 2666: linux_smart_interface::megasas_dcmd_cmd(int bus_no, uint32_t opcode, void *buf,
 2667:   size_t bufsize, uint8_t *mbox, size_t mboxlen, uint8_t *statusp)
 2668: {
 2669:   struct megasas_iocpacket ioc;
 2670: 
 2671:   if ((mbox != NULL && (mboxlen == 0 || mboxlen > MFI_MBOX_SIZE)) ||
 2672:     (mbox == NULL && mboxlen != 0)) 
 2673:   {
 2674:     errno = EINVAL;
 2675:     return (-1);
 2676:   }
 2677: 
 2678:   bzero(&ioc, sizeof(ioc));
 2679:   struct megasas_dcmd_frame * dcmd = &ioc.frame.dcmd;
 2680:   ioc.host_no = bus_no;
 2681:   if (mbox)
 2682:     bcopy(mbox, dcmd->mbox.w, mboxlen);
 2683:   dcmd->cmd = MFI_CMD_DCMD;
 2684:   dcmd->timeout = 0;
 2685:   dcmd->flags = 0;
 2686:   dcmd->data_xfer_len = bufsize;
 2687:   dcmd->opcode = opcode;
 2688: 
 2689:   if (bufsize > 0) {
 2690:     dcmd->sge_count = 1;
 2691:     dcmd->data_xfer_len = bufsize;
 2692:     dcmd->sgl.sge32[0].phys_addr = (intptr_t)buf;
 2693:     dcmd->sgl.sge32[0].length = (uint32_t)bufsize;
 2694:     ioc.sge_count = 1;
 2695:     ioc.sgl_off = offsetof(struct megasas_dcmd_frame, sgl);
 2696:     ioc.sgl[0].iov_base = buf;
 2697:     ioc.sgl[0].iov_len = bufsize;
 2698:   }
 2699: 
 2700:   int fd;
 2701:   if ((fd = ::open("/dev/megaraid_sas_ioctl_node", O_RDWR)) <= 0) {
 2702:     return (errno);
 2703:   }
 2704: 
 2705:   int r = ioctl(fd, MEGASAS_IOC_FIRMWARE, &ioc);
 2706:   if (r < 0) {
 2707:     return (r);
 2708:   }
 2709: 
 2710:   if (statusp != NULL)
 2711:     *statusp = dcmd->cmd_status;
 2712:   else if (dcmd->cmd_status != MFI_STAT_OK) {
 2713:     fprintf(stderr, "command %x returned error status %x\n",
 2714:       opcode, dcmd->cmd_status);
 2715:     errno = EIO;
 2716:     return (-1);
 2717:   }
 2718:   return (0);
 2719: }
 2720: 
 2721: int
 2722: linux_smart_interface::megasas_pd_add_list(int bus_no, smart_device_list & devlist)
 2723: {
 2724:   /*
 2725:   * Keep fetching the list in a loop until we have a large enough
 2726:   * buffer to hold the entire list.
 2727:   */
 2728:   megasas_pd_list * list = 0;
 2729:   for (unsigned list_size = 1024; ; ) {
 2730:     list = (megasas_pd_list *)realloc(list, list_size);
 2731:     if (!list)
 2732:       throw std::bad_alloc();
 2733:     bzero(list, list_size);
 2734:     if (megasas_dcmd_cmd(bus_no, MFI_DCMD_PD_GET_LIST, list, list_size, NULL, 0,
 2735:       NULL) < 0) 
 2736:     {
 2737:       free(list);
 2738:       return (-1);
 2739:     }
 2740:     if (list->size <= list_size)
 2741:       break;
 2742:     list_size = list->size;
 2743:   }
 2744: 
 2745:   // adding all SCSI devices
 2746:   for (unsigned i = 0; i < list->count; i++) {
 2747:     if(list->addr[i].scsi_dev_type)
 2748:       continue; /* non disk device found */
 2749:     char line[128];
 2750:     snprintf(line, sizeof(line) - 1, "/dev/bus/%d", bus_no);
 2751:     smart_device * dev = new linux_megaraid_device(this, line, 0, list->addr[i].device_id);
 2752:     devlist.push_back(dev);
 2753:   }
 2754:   free(list);
 2755:   return (0);
 2756: }
 2757: 
 2758: // Return kernel release as integer ("2.6.31" -> 206031)
 2759: static unsigned get_kernel_release()
 2760: {
 2761:   struct utsname u;
 2762:   if (uname(&u))
 2763:     return 0;
 2764:   unsigned x = 0, y = 0, z = 0;
 2765:   if (!(sscanf(u.release, "%u.%u.%u", &x, &y, &z) == 3
 2766:         && x < 100 && y < 100 && z < 1000             ))
 2767:     return 0;
 2768:   return x * 100000 + y * 1000 + z;
 2769: }
 2770: 
 2771: // Guess device type (ata or scsi) based on device name (Linux
 2772: // specific) SCSI device name in linux can be sd, sr, scd, st, nst,
 2773: // osst, nosst and sg.
 2774: smart_device * linux_smart_interface::autodetect_smart_device(const char * name)
 2775: {
 2776:   const char * test_name = name;
 2777: 
 2778:   // Dereference symlinks
 2779:   struct stat st;
 2780:   std::string pathbuf;
 2781:   if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
 2782:     char * p = realpath(name, (char *)0);
 2783:     if (p) {
 2784:       pathbuf = p;
 2785:       free(p);
 2786:       test_name = pathbuf.c_str();
 2787:     }
 2788:   }
 2789: 
 2790:   // Remove the leading /dev/... if it's there
 2791:   static const char dev_prefix[] = "/dev/";
 2792:   if (str_starts_with(test_name, dev_prefix))
 2793:     test_name += strlen(dev_prefix);
 2794: 
 2795:   // form /dev/h* or h*
 2796:   if (str_starts_with(test_name, "h"))
 2797:     return new linux_ata_device(this, name, "");
 2798: 
 2799:   // form /dev/ide/* or ide/*
 2800:   if (str_starts_with(test_name, "ide/"))
 2801:     return new linux_ata_device(this, name, "");
 2802: 
 2803:   // form /dev/s* or s*
 2804:   if (str_starts_with(test_name, "s")) {
 2805: 
 2806:     // Try to detect possible USB->(S)ATA bridge
 2807:     unsigned short vendor_id = 0, product_id = 0, version = 0;
 2808:     if (get_usb_id(test_name, vendor_id, product_id, version)) {
 2809:       const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id, version);
 2810:       if (!usbtype)
 2811:         return 0;
 2812: 
 2813:       // Kernels before 2.6.29 do not support the sense data length
 2814:       // required for SAT ATA PASS-THROUGH(16)
 2815:       if (!strcmp(usbtype, "sat") && get_kernel_release() < 206029)
 2816:         usbtype = "sat,12";
 2817: 
 2818:       // Return SAT/USB device for this type
 2819:       // (Note: linux_scsi_device::autodetect_open() will not be called in this case)
 2820:       return get_sat_device(usbtype, new linux_scsi_device(this, name, ""));
 2821:     }
 2822: 
 2823:     // No USB bridge found, assume regular SCSI device
 2824:     return new linux_scsi_device(this, name, "");
 2825:   }
 2826: 
 2827:   // form /dev/scsi/* or scsi/*
 2828:   if (str_starts_with(test_name, "scsi/"))
 2829:     return new linux_scsi_device(this, name, "");
 2830: 
 2831:   // form /dev/ns* or ns*
 2832:   if (str_starts_with(test_name, "ns"))
 2833:     return new linux_scsi_device(this, name, "");
 2834: 
 2835:   // form /dev/os* or os*
 2836:   if (str_starts_with(test_name, "os"))
 2837:     return new linux_scsi_device(this, name, "");
 2838: 
 2839:   // form /dev/nos* or nos*
 2840:   if (str_starts_with(test_name, "nos"))
 2841:     return new linux_scsi_device(this, name, "");
 2842: 
 2843:   // form /dev/tw[ael]* or tw[ael]*
 2844:   if (str_starts_with(test_name, "tw") && strchr("ael", test_name[2]))
 2845:     return missing_option("-d 3ware,N");
 2846: 
 2847:   // form /dev/cciss/* or cciss/*
 2848:   if (str_starts_with(test_name, "cciss/"))
 2849:     return missing_option("-d cciss,N");
 2850: 
 2851:   // we failed to recognize any of the forms
 2852:   return 0;
 2853: }
 2854: 
 2855: smart_device * linux_smart_interface::get_custom_smart_device(const char * name, const char * type)
 2856: {
 2857:   // Marvell ?
 2858:   if (!strcmp(type, "marvell"))
 2859:     return new linux_marvell_device(this, name, type);
 2860: 
 2861:   // 3Ware ?
 2862:   int disknum = -1, n1 = -1, n2 = -1;
 2863:   if (sscanf(type, "3ware,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
 2864:     if (n2 != (int)strlen(type)) {
 2865:       set_err(EINVAL, "Option -d 3ware,N requires N to be a non-negative integer");
 2866:       return 0;
 2867:     }
 2868:     if (!(0 <= disknum && disknum <= 127)) {
 2869:       set_err(EINVAL, "Option -d 3ware,N (N=%d) must have 0 <= N <= 127", disknum);
 2870:       return 0;
 2871:     }
 2872: 
 2873:     if (!strncmp(name, "/dev/twl", 8))
 2874:       return new linux_escalade_device(this, name, linux_escalade_device::AMCC_3WARE_9700_CHAR, disknum);
 2875:     else if (!strncmp(name, "/dev/twa", 8))
 2876:       return new linux_escalade_device(this, name, linux_escalade_device::AMCC_3WARE_9000_CHAR, disknum);
 2877:     else if (!strncmp(name, "/dev/twe", 8))
 2878:       return new linux_escalade_device(this, name, linux_escalade_device::AMCC_3WARE_678K_CHAR, disknum);
 2879:     else
 2880:       return new linux_escalade_device(this, name, linux_escalade_device::AMCC_3WARE_678K, disknum);
 2881:   }
 2882: 
 2883:   // Areca?
 2884:   disknum = n1 = n2 = -1;
 2885:   int encnum = 1;
 2886:   if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
 2887:     if (!(1 <= disknum && disknum <= 128)) {
 2888:       set_err(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
 2889:       return 0;
 2890:     }
 2891:     if (!(1 <= encnum && encnum <= 8)) {
 2892:       set_err(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
 2893:       return 0;
 2894:     }
 2895:     return new linux_areca_ata_device(this, name, disknum, encnum);
 2896:   }
 2897: 
 2898:   // Highpoint ?
 2899:   int controller = -1, channel = -1; disknum = 1;
 2900:   n1 = n2 = -1; int n3 = -1;
 2901:   if (sscanf(type, "hpt,%n%d/%d%n/%d%n", &n1, &controller, &channel, &n2, &disknum, &n3) >= 2 || n1 == 4) {
 2902:     int len = strlen(type);
 2903:     if (!(n2 == len || n3 == len)) {
 2904:       set_err(EINVAL, "Option '-d hpt,L/M/N' supports 2-3 items");
 2905:       return 0;
 2906:     }
 2907:     if (!(1 <= controller && controller <= 8)) {
 2908:       set_err(EINVAL, "Option '-d hpt,L/M/N' invalid controller id L supplied");
 2909:       return 0;
 2910:     }
 2911:     if (!(1 <= channel && channel <= 128)) {
 2912:       set_err(EINVAL, "Option '-d hpt,L/M/N' invalid channel number M supplied");
 2913:       return 0;
 2914:     }
 2915:     if (!(1 <= disknum && disknum <= 15)) {
 2916:       set_err(EINVAL, "Option '-d hpt,L/M/N' invalid pmport number N supplied");
 2917:       return 0;
 2918:     }
 2919:     return new linux_highpoint_device(this, name, controller, channel, disknum);
 2920:   }
 2921: 
 2922: #ifdef HAVE_LINUX_CCISS_IOCTL_H
 2923:   // CCISS ?
 2924:   disknum = n1 = n2 = -1;
 2925:   if (sscanf(type, "cciss,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
 2926:     if (n2 != (int)strlen(type)) {
 2927:       set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
 2928:       return 0;
 2929:     }
 2930:     if (!(0 <= disknum && disknum <= 127)) {
 2931:       set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
 2932:       return 0;
 2933:     }
 2934:     return get_sat_device("sat,auto", new linux_cciss_device(this, name, disknum));
 2935:   }
 2936: #endif // HAVE_LINUX_CCISS_IOCTL_H
 2937: 
 2938:   // MegaRAID ?
 2939:   if (sscanf(type, "megaraid,%d", &disknum) == 1) {
 2940:     return new linux_megaraid_device(this, name, 0, disknum);
 2941:   }
 2942:   return 0;
 2943: }
 2944: 
 2945: std::string linux_smart_interface::get_valid_custom_dev_types_str()
 2946: {
 2947:   return "marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N"
 2948: #ifdef HAVE_LINUX_CCISS_IOCTL_H
 2949:                                               ", cciss,N"
 2950: #endif
 2951:     ;
 2952: }
 2953: 
 2954: } // namespace
 2955: 
 2956: /////////////////////////////////////////////////////////////////////////////
 2957: /// Initialize platform interface and register with smi()
 2958: 
 2959: void smart_interface::init()
 2960: {
 2961:   static os_linux::linux_smart_interface the_interface;
 2962:   smart_interface::set(&the_interface);
 2963: }

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