File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / smartmontools / os_linux.cpp
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:32:16 2012 UTC (12 years, 4 months ago) by misho
Branches: smartmontools, elwix, MAIN
CVS tags: v5_42, HEAD
smartmontools

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

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