Ticket #328: aacraid.diff

File aacraid.diff, 13.0 KB (added by adityaseven, 10 years ago)

Diff containing all changes

  • smartctl.8.in

     
    380380.fi
    381381For PERC5/6 controllers: \fBmegaraid_sas_ioctlN\fP
    382382
     383.I aacraid,L,ID
     384\- [Linux only] the device consists of one or more SCSI/SAS disks connected
     385to a AacRaid controller.  The non-negative integer L is the Lun number and ID is the id number both of which
     386denotes which disk on the controller is monitored.
     387Use syntax such as:
     388.nf
     389\fBsmartctl \-a \-d aacraid,0,66 /dev/sda\fP
     390.fi
     391.nf
     392\fBsmartctl \-a \-d aacraid,0,66 /dev/sdb\fP
     393.fi
     394
     395The L and ID numbers of a disk can be found in
     396/proc/scsi/scsi
     397
     398The following entry in /proc/devices must exist:
     399.fi
     400 \fBaac\fP
     401
     402
    383403.\" %ENDIF OS Linux
    384404.\" %IF OS FreeBSD Linux
    385405.I 3ware,N
  • smartd.conf.5.in

     
    146146.B #
    147147.\" %ENDIF OS Linux
    148148.nf
     149.\" %IF OS Linux
     150.B # Three disks connected to a AacRaid controller
     151.B # Start short self-tests daily between 1-2, 2-3, and
     152.B # 3-4 am.
     153.B \ \ /dev/sda -d aacraid,0,66 -a -s S/../.././01
     154.B \ \ /dev/sda -d aacraid,0,67 -a -s S/../.././02
     155.B \ \ /dev/sda -d aacraid,0,68 -a -s S/../.././03
     156.B
     157.B #
     158.\" %ENDIF OS Linux
     159.nf
    149160.B # Four ATA disks on a 3ware 6/7/8000 controller.
    150161.B # Start short self-tests daily between midnight and 1am,
    151162.B # 1-2, 2-3, and 3-4 am.  Starting with the Linux 2.6
  • ChangeLog

     
    11$Id$
    22
     32014-04-18  Raghava Aditya  <Raghava.Aditya@pmcs.com>
     4
     5        os_linux.cpp
     6        - Added support for aacraid drivers
     7        - Created a new interface for aacraid
     8                 smartctl -d aacraid,L,ID /dev/sdx
     9                 
    3102014-04-18  Douglas Gilbert  <dgilbert@interlog.com>
    411
    512        scsicmds.cpp:
  • Makefile.am

     
    102102        dev_areca.cpp \
    103103        dev_areca.h \
    104104        dev_legacy.cpp \
    105         megaraid.h
     105        megaraid.h \
     106                aacraid.h
    106107
    107108if OS_WIN32_MINGW
    108109
     
    161162        dev_areca.cpp \
    162163        dev_areca.h \
    163164        dev_legacy.cpp \
    164         megaraid.h
     165        megaraid.h \
     166                aacraid.h
    165167
    166168if OS_WIN32_MINGW
    167169
  • os_linux.cpp

     
    33 *
    44 * Home page of code is: http://smartmontools.sourceforge.net
    55 *
     6 * Copyright (C) 2014 Raghava Aditya <Raghava.Aditya@pmcs.com>
    67 * Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
    78 * Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com>
    89 * Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw>
     
    8081#include "utility.h"
    8182#include "cciss.h"
    8283#include "megaraid.h"
     84#include "aacraid.h"
    8385
    8486#include "dev_interface.h"
    8587#include "dev_ata_cmd_set.h"
     
    860862}
    861863
    862864/////////////////////////////////////////////////////////////////////////////
     865/// PMC AacRAID support
     866
     867class linux_aacraid_device
     868:public   scsi_device,
     869 public /*extends */   linux_smart_device
     870{
     871public:
     872  linux_aacraid_device(smart_interface *intf, const char *dev_name,
     873    unsigned int host, unsigned int channel, unsigned int device);
     874
     875  virtual ~linux_aacraid_device() throw();
     876
     877  virtual bool open();
     878
     879  virtual bool scsi_pass_through(scsi_cmnd_io *iop);
     880
     881private:
     882  int afd;
     883
     884  //Device Host number
     885  int aHost;
     886
     887  //Channel(Lun) of the device
     888  int aLun;
     889
     890  //Id of the device
     891  int aId;
     892
     893};
     894
     895linux_aacraid_device::linux_aacraid_device(smart_interface *intf,
     896  const char *dev_name, unsigned int host, unsigned int channel, unsigned int device)
     897   : smart_device(intf,dev_name,"aacraid","aacraid"),
     898     linux_smart_device(O_RDWR|O_NONBLOCK),
     899     afd(-1), aHost(host), aLun(channel), aId(device)
     900{
     901  set_info().info_name = strprintf("%s [aacraid_disk_%02d_%02d_%d]",dev_name,aHost,aLun,aId);
     902  set_info().dev_type  = strprintf("aacraid,%d,%d,%d",aHost,aLun,aId);
     903}
     904
     905linux_aacraid_device::~linux_aacraid_device() throw()
     906{
     907
     908}
     909
     910bool linux_aacraid_device::open()
     911{
     912
     913  //Create the character device name based on the host number
     914  //Required for get stats from disks connected to different controllers
     915  char dev_name[128];
     916  sprintf(dev_name,"/dev/aac%d",aHost);
     917
     918  //Initial open of dev name to check if it exsists
     919  afd = ::open(dev_name,O_RDWR);
     920
     921  if(afd < 0 && errno == ENOENT) {
     922
     923    FILE *fp = fopen("/proc/devices","r");
     924    if(NULL == fp)
     925      return set_err(errno,"cannot open /proc/devices:%s",
     926                     strerror(errno));
     927
     928    char line[256];
     929    int mjr = -1;
     930    int nc  = -1;
     931
     932    while(fgets(line,sizeof(line),fp) !=NULL) {
     933      if(sscanf(line,"%d aac%n",&mjr,&nc) == 1
     934                && nc > 0 && '\n' == line[nc])
     935        break;
     936    }
     937
     938    //work with /proc/devices is done
     939    fclose(fp);
     940
     941    //Create misc device file in /dev/ used for communication with driver
     942    if(mknod(dev_name,S_IFCHR,makedev(mjr,aHost)))
     943      return set_err(errno,"cannot create %s:%s",dev_name,strerror(errno));
     944
     945    afd = ::open(dev_name,O_RDWR);
     946  }
     947
     948  if(afd < 0)
     949    return set_err(errno,"cannot open %s:%s",dev_name,strerror(errno));
     950
     951  set_fd(afd);
     952  return true;
     953}
     954
     955bool linux_aacraid_device::scsi_pass_through(scsi_cmnd_io *iop)
     956{
     957  int report = scsi_debugmode;
     958
     959  if (report > 0) {
     960    int k, j;
     961    const unsigned char * ucp = iop->cmnd;
     962    const char * np;
     963    char buff[256];
     964    const int sz = (int)sizeof(buff);
     965
     966    np = scsi_get_opcode_name(ucp[0]);
     967    j  = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
     968    for (k = 0; k < (int)iop->cmnd_len; ++k)
     969      j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
     970      if ((report > 1) &&
     971        (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
     972        int trunc = (iop->dxfer_len > 256) ? 1 : 0;
     973
     974        j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
     975                      "data, len=%d%s:\n", (int)iop->dxfer_len,
     976                      (trunc ? " [only first 256 bytes shown]" : ""));
     977        dStrHex((const char *)iop->dxferp,
     978               (trunc ? 256 : iop->dxfer_len) , 1);
     979    }
     980    else
     981      j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
     982
     983    pout("%s", buff);
     984  }
     985
     986
     987  //return test commands
     988  if (iop->cmnd[0] == 0x00)
     989    return true;
     990
     991  user_aac_reply *pReply;
     992
     993  #ifdef ENVIRONMENT64
     994    // Create user 64 bit request
     995    user_aac_srb64  *pSrb;
     996    uint8_t aBuff[sizeof(user_aac_srb64) + sizeof(user_aac_reply)] = {0,};
     997
     998    pSrb    = (user_aac_srb64*)aBuff;
     999    pReply  = (user_aac_reply*)(aBuff+sizeof(user_aac_srb64));
     1000
     1001 #elif defined(ENVIRONMENT32)
     1002    //Create user 32 bit request
     1003    user_aac_srb32  *pSrb;
     1004    uint8_t aBuff[sizeof(user_aac_srb32) + sizeof(user_aac_reply)] = {0,};
     1005
     1006    pSrb    = (user_aac_srb32*)aBuff;
     1007    pReply  = (user_aac_reply*)(aBuff+sizeof(user_aac_srb32));
     1008
     1009 #endif
     1010
     1011  pSrb->function = SRB_FUNCTION_EXECUTE_SCSI;
     1012  //channel is 0 always
     1013  pSrb->channel  = 0;
     1014  pSrb->id       = aId;
     1015  pSrb->lun      = aLun;
     1016  pSrb->timeout  = 0;
     1017
     1018  pSrb->retry_limit = 0;
     1019  pSrb->cdb_size    = iop->cmnd_len;
     1020
     1021  switch(iop->dxfer_dir) {
     1022    case DXFER_NONE:
     1023      pSrb->flags = SRB_NoDataXfer;
     1024      break;
     1025    case DXFER_FROM_DEVICE:
     1026      pSrb->flags = SRB_DataIn;
     1027      break;
     1028    case DXFER_TO_DEVICE:
     1029      pSrb->flags = SRB_DataOut;
     1030      break;
     1031    default:
     1032      pout("aacraid: bad dxfer_dir\n");
     1033      return set_err(EINVAL, "aacraid: bad dxfer_dir\n");
     1034  }
     1035
     1036  if(iop->dxfer_len > 0) {
     1037
     1038    #ifdef ENVIRONMENT64
     1039      pSrb->sg64.count = 1;
     1040      pSrb->sg64.sg64[0].addr64.lo32 = ((intptr_t)iop->dxferp) &
     1041                                         0x00000000ffffffff;
     1042      pSrb->sg64.sg64[0].addr64.hi32 = ((intptr_t)iop->dxferp) >> 32;
     1043
     1044      pSrb->sg64.sg64[0].length = (uint32_t)iop->dxfer_len;
     1045      pSrb->count = sizeof(user_aac_srb64) +
     1046                          (sizeof(user_sgentry64)*(pSrb->sg64.count-1));
     1047    #elif defined(ENVIRONMENT32)
     1048      pSrb->sg32.count = 1;
     1049      pSrb->sg32.sg32[0].addr32 = (intptr_t)iop->dxferp;
     1050
     1051      pSrb->sg32.sg32[0].length = (uint32_t)iop->dxfer_len;
     1052      pSrb->count = sizeof(user_aac_srb32) +
     1053                          (sizeof(user_sgentry32)*(pSrb->sg32.count-1));
     1054    #endif
     1055
     1056  }
     1057
     1058  memcpy(pSrb->cdb,iop->cmnd,iop->cmnd_len);
     1059
     1060  int rc = 0;
     1061  errno = 0;
     1062  rc = ioctl(get_fd(),FSACTL_SEND_RAW_SRB,pSrb);
     1063  if(rc!= 0 || pReply->srb_status != 0x01) {
     1064    if(pReply->srb_status == 0x08) {
     1065      return set_err(EIO, "aacraid: Device %d %d does not exist\n" ,aLun,aId );
     1066    }
     1067  return set_err((errno ? errno : EIO), "aacraid result: %d.%d = %d/%d",
     1068                            aLun, aId, errno,
     1069                            pReply->srb_status);
     1070  }
     1071  return true;
     1072}
     1073
     1074
     1075/////////////////////////////////////////////////////////////////////////////
    8631076/// LSI MegaRAID support
    8641077
    8651078class linux_megaraid_device
     
    29393152  if (sscanf(type, "megaraid,%d", &disknum) == 1) {
    29403153    return new linux_megaraid_device(this, name, 0, disknum);
    29413154  }
     3155
     3156  //aacraid?
     3157  unsigned int device;
     3158  unsigned int host;
     3159  if(sscanf(type, "aacraid,%d,%d,%d", &host, &channel, &device)==3) {
     3160    //return new linux_aacraid_device(this,name,channel,device);
     3161    return get_sat_device("sat,auto",
     3162      new linux_aacraid_device(this, name, host, channel, device));
     3163
     3164  }
     3165
    29423166  return 0;
    29433167}
    29443168
    29453169std::string linux_smart_interface::get_valid_custom_dev_types_str()
    29463170{
    2947   return "marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N"
     3171  return "marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N aacraid,H,L,ID"
    29483172#ifdef HAVE_LINUX_CCISS_IOCTL_H
    29493173                                              ", cciss,N"
    29503174#endif
  • aacraid.h

     
     1/* aacraid.h
     2 * Copyright (C) 2014 Raghava Aditya <Raghava.Aditya@pmcs.com>
     3 *
     4 * This program is free software; you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation; either version 2, or (at your option)
     7 * any later version.
     8 *
     9 * You should have received a copy of the GNU General Public License
     10 * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
     11 *
     12 */
     13
     14// Check windows
     15#if _WIN32 || _WIN64
     16#if _WIN64
     17  #define ENVIRONMENT64
     18#else
     19  #define ENVIRONMENT32
     20#endif
     21#endif
     22
     23// Check GCC
     24#if __GNUC__
     25#if __x86_64__ || __ppc64__
     26  #define ENVIRONMENT64
     27#else
     28  #define ENVIRONMENT32
     29#endif
     30#endif
     31
     32#define METHOD_BUFFERED 0
     33#define METHOD_NEITHER  3
     34
     35#define CTL_CODE(function, method) ((4<< 16) | ((function) << 2) | (method) )
     36
     37#define FSACTL_SEND_RAW_SRB  CTL_CODE(2067, METHOD_BUFFERED)
     38
     39#define  SRB_FUNCTION_EXECUTE_SCSI 0X00
     40
     41#define  SRB_DataIn      0x0040
     42#define  SRB_DataOut     0x0080
     43#define  SRB_NoDataXfer  0x0000
     44
     45typedef struct {
     46  uint32_t lo32;
     47  uint32_t hi32;
     48  }  address64;
     49
     50typedef struct {
     51  address64 addr64;
     52  uint32_t length;  /* Length. */
     53  }  user_sgentry64;
     54
     55typedef struct {
     56  uint32_t aadr32;
     57  uint32_t length;
     58  }  user_sgentry32;
     59
     60typedef struct {
     61  uint32_t         count;
     62  user_sgentry64   sg64[1];
     63  }  user_sgmap64;
     64
     65typedef struct {
     66  uint32_t         count;
     67  user_sgentry32   sg32[1];
     68  }  user_sgmap32;
     69
     70typedef struct {
     71  uint32_t function;           //SRB_FUNCTION_EXECUTE_SCSI 0x00
     72  uint32_t channel;            //bus
     73  uint32_t id;                 //use the ID number this is wrong
     74  uint32_t lun;                //Logical unit number
     75  uint32_t timeout;
     76  uint32_t flags;              //Interesting stuff I must say
     77  uint32_t count;              // Data xfer size
     78  uint32_t retry_limit;        // We shall see
     79  uint32_t cdb_size;           // Length of CDB
     80  uint8_t  cdb[16];            // The actual cdb command
     81  user_sgmap64 sg64;           // pDatabuffer and address of Databuffer
     82  }  user_aac_srb64;
     83   
     84typedef struct {
     85  uint32_t function;           //SRB_FUNCTION_EXECUTE_SCSI 0x00
     86  uint32_t channel;            //bus
     87  uint32_t id;                 //use the ID number this is wrong
     88  uint32_t lun;                //Logical unit number
     89  uint32_t timeout;
     90  uint32_t flags;              //Interesting stuff I must say
     91  uint32_t count;              // Data xfer size
     92  uint32_t retry_limit;        // We shall see
     93  uint32_t cdb_size;           // Length of CDB
     94  uint8_t  cdb[16];            // The actual cdb command
     95  user_sgmap32 sg32;           // pDatabuffer and address of Databuffer
     96  }  user_aac_srb32;
     97
     98typedef struct {
     99  uint32_t status;
     100  uint32_t srb_status;
     101  uint32_t scsi_status;
     102  uint32_t data_xfer_length;
     103  uint32_t sense_data_size;
     104  uint8_t  sense_data[30];
     105  }  user_aac_reply;