Ticket #328: aacraid.diff
File aacraid.diff, 13.0 KB (added by , 11 years ago) |
---|
-
smartctl.8.in
380 380 .fi 381 381 For PERC5/6 controllers: \fBmegaraid_sas_ioctlN\fP 382 382 383 .I aacraid,L,ID 384 \- [Linux only] the device consists of one or more SCSI/SAS disks connected 385 to a AacRaid controller. The non-negative integer L is the Lun number and ID is the id number both of which 386 denotes which disk on the controller is monitored. 387 Use 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 395 The L and ID numbers of a disk can be found in 396 /proc/scsi/scsi 397 398 The following entry in /proc/devices must exist: 399 .fi 400 \fBaac\fP 401 402 383 403 .\" %ENDIF OS Linux 384 404 .\" %IF OS FreeBSD Linux 385 405 .I 3ware,N -
smartd.conf.5.in
146 146 .B # 147 147 .\" %ENDIF OS Linux 148 148 .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 149 160 .B # Four ATA disks on a 3ware 6/7/8000 controller. 150 161 .B # Start short self-tests daily between midnight and 1am, 151 162 .B # 1-2, 2-3, and 3-4 am. Starting with the Linux 2.6 -
ChangeLog
1 1 $Id$ 2 2 3 2014-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 3 10 2014-04-18 Douglas Gilbert <dgilbert@interlog.com> 4 11 5 12 scsicmds.cpp: -
Makefile.am
102 102 dev_areca.cpp \ 103 103 dev_areca.h \ 104 104 dev_legacy.cpp \ 105 megaraid.h 105 megaraid.h \ 106 aacraid.h 106 107 107 108 if OS_WIN32_MINGW 108 109 … … 161 162 dev_areca.cpp \ 162 163 dev_areca.h \ 163 164 dev_legacy.cpp \ 164 megaraid.h 165 megaraid.h \ 166 aacraid.h 165 167 166 168 if OS_WIN32_MINGW 167 169 -
os_linux.cpp
3 3 * 4 4 * Home page of code is: http://smartmontools.sourceforge.net 5 5 * 6 * Copyright (C) 2014 Raghava Aditya <Raghava.Aditya@pmcs.com> 6 7 * Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net> 7 8 * Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com> 8 9 * Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw> … … 80 81 #include "utility.h" 81 82 #include "cciss.h" 82 83 #include "megaraid.h" 84 #include "aacraid.h" 83 85 84 86 #include "dev_interface.h" 85 87 #include "dev_ata_cmd_set.h" … … 860 862 } 861 863 862 864 ///////////////////////////////////////////////////////////////////////////// 865 /// PMC AacRAID support 866 867 class linux_aacraid_device 868 :public scsi_device, 869 public /*extends */ linux_smart_device 870 { 871 public: 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 881 private: 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 895 linux_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 905 linux_aacraid_device::~linux_aacraid_device() throw() 906 { 907 908 } 909 910 bool 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 955 bool 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 ///////////////////////////////////////////////////////////////////////////// 863 1076 /// LSI MegaRAID support 864 1077 865 1078 class linux_megaraid_device … … 2939 3152 if (sscanf(type, "megaraid,%d", &disknum) == 1) { 2940 3153 return new linux_megaraid_device(this, name, 0, disknum); 2941 3154 } 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 2942 3166 return 0; 2943 3167 } 2944 3168 2945 3169 std::string linux_smart_interface::get_valid_custom_dev_types_str() 2946 3170 { 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" 2948 3172 #ifdef HAVE_LINUX_CCISS_IOCTL_H 2949 3173 ", cciss,N" 2950 3174 #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 45 typedef struct { 46 uint32_t lo32; 47 uint32_t hi32; 48 } address64; 49 50 typedef struct { 51 address64 addr64; 52 uint32_t length; /* Length. */ 53 } user_sgentry64; 54 55 typedef struct { 56 uint32_t aadr32; 57 uint32_t length; 58 } user_sgentry32; 59 60 typedef struct { 61 uint32_t count; 62 user_sgentry64 sg64[1]; 63 } user_sgmap64; 64 65 typedef struct { 66 uint32_t count; 67 user_sgentry32 sg32[1]; 68 } user_sgmap32; 69 70 typedef 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 84 typedef 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 98 typedef 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;