~ubuntu-branches/ubuntu/raring/smartmontools/raring

« back to all changes in this revision

Viewing changes to os_linux.cpp

  • Committer: Package Import Robot
  • Author(s): Giuseppe Iuculano
  • Date: 2012-05-12 13:02:49 UTC
  • mfrom: (2.2.17 sid)
  • Revision ID: package-import@ubuntu.com-20120512130249-x4vmqc2uu3bynss1
Tags: 5.42+svn3539-1
* [e165493] Imported Upstream version 5.42+svn3539
  (Closes: #668391, #608953)
* [9fcd449] Refreshed patches
* [65c801f] Do not install upstream init (Closes: #631075)
* [9a19418] Fixed check for /usr/bin/mail.
  Thanks to Martin von Gagern (Closes: #649515)

Show diffs side-by-side

added added

removed removed

Lines of Context:
89
89
 
90
90
#define ARGUSED(x) ((void)(x))
91
91
 
92
 
const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3317 2011-04-19 19:42:54Z chrfranke $"
 
92
const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3441 2011-10-12 17:22:15Z chrfranke $"
93
93
  OS_LINUX_H_CVSID;
94
94
 
95
95
 
940
940
  {
941
941
    // SAT or USB ?
942
942
    ata_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
943
 
    if (newdev)
 
943
    if (newdev) {
944
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");
945
948
      return newdev;
 
949
    }
946
950
  }
947
951
 
948
952
  // Nothing special found
1050
1054
  if (iop->cmnd[0] == 0x00)
1051
1055
    return true;
1052
1056
 
1053
 
  if (iop->cmnd[0] == 0xa1 || iop->cmnd[0] == 0x85) { // SAT_ATA_PASSTHROUGH_12/16
 
1057
  if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) { 
1054
1058
    // Controller does not return ATA output registers in SAT sense data
1055
1059
    if (iop->cmnd[2] & (1 << 5)) // chk_cond
1056
1060
      return set_err(ENOSYS, "ATA return descriptor not supported by controller firmware");
1057
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"); 
1058
1068
 
1059
1069
  if (pt_cmd == NULL)
1060
1070
    return false;
1115
1125
/* Issue passthrough scsi commands to PERC2/3/4 controllers */
1116
1126
bool linux_megaraid_device::megadev_cmd(int cdbLen, void *cdb, 
1117
1127
  int dataLen, void *data,
1118
 
  int senseLen, void *sense, int /*report*/)
 
1128
  int /*senseLen*/, void * /*sense*/, int /*report*/)
1119
1129
{
1120
1130
  struct uioctl_t uio;
1121
1131
  int rc;
1122
1132
 
1123
 
  sense = NULL;
1124
 
  senseLen = 0;
1125
 
 
1126
1133
  /* Don't issue to the controller */
1127
1134
  if (m_disknum == 7)
1128
1135
    return false;
1641
1648
/// Areca RAID support
1642
1649
 
1643
1650
class linux_areca_device
1644
 
: public /*implements*/ ata_device_with_command_set,
 
1651
: public /*implements*/ ata_device,
1645
1652
  public /*extends*/ linux_smart_device
1646
1653
{
1647
1654
public:
1648
1655
  linux_areca_device(smart_interface * intf, const char * dev_name, int disknum);
1649
1656
 
1650
1657
protected:
1651
 
  virtual int ata_command_interface(smart_command_set command, int select, char * data);
 
1658
  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out); 
1652
1659
 
1653
1660
private:
1654
1661
  int m_disknum; ///< Disk number.
1966
1973
}
1967
1974
 
1968
1975
// Areca RAID Controller
1969
 
int linux_areca_device::ata_command_interface(smart_command_set command, int select, char * data)
 
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) 
1970
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
 
1971
1986
        // ATA input registers
1972
1987
        typedef struct _ATA_INPUT_REGISTERS
1973
1988
        {
2041
2056
        areca_packet[4] = (unsigned char)(((areca_packet_len - 6) >> 8) & 0xff);
2042
2057
        areca_packet[5] = 0x1c; // areca defined code for ATA passthrough command
2043
2058
 
2044
 
 
2045
2059
        // ----- BEGIN TO SETUP PAYLOAD DATA -----
2046
 
 
2047
2060
        memcpy(&areca_packet[7], "SmrT", 4);    // areca defined password
2048
 
 
2049
2061
        ata_cmd = (sATA_INPUT_REGISTERS *)&areca_packet[12];
2050
 
        ata_cmd->cylinder_low    = 0x4F;
2051
 
        ata_cmd->cylinder_high   = 0xC2;
2052
 
 
2053
 
 
2054
 
        if ( command == READ_VALUES     ||
2055
 
                 command == READ_THRESHOLDS ||
2056
 
                 command == READ_LOG ||
2057
 
                 command == IDENTIFY ||
2058
 
                 command == PIDENTIFY )
 
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 )
2059
2081
        {
2060
 
                // the commands will return data
2061
 
                areca_packet[6] = 0x13;
2062
 
                ata_cmd->sector_count = 0x1;
 
2082
                // the commands will return no data
 
2083
                areca_packet[6] = 0x15;
2063
2084
        }
2064
 
        else if ( command == WRITE_LOG )
 
2085
        else if (in.direction == ata_cmd_in::data_out) 
2065
2086
        {
2066
2087
                // the commands will write data
 
2088
                memcpy(ata_cmd->data, in.buffer, in.size);
2067
2089
                areca_packet[6] = 0x14;
2068
2090
        }
2069
 
        else
2070
 
        {
2071
 
                // the commands will return no data
2072
 
                areca_packet[6] = 0x15;
 
2091
        else {
 
2092
            // COMMAND NOT SUPPORTED VIA ARECA IOCTL INTERFACE
 
2093
            return set_err(ENOTSUP, "DATA OUT not supported for this Areca controller type");
2073
2094
        }
2074
2095
 
2075
 
 
2076
 
        ata_cmd->command = ATA_SMART_CMD;
2077
 
        // Now set ATA registers depending upon command
2078
 
        switch ( command )
2079
 
        {
2080
 
        case CHECK_POWER_MODE:  
2081
 
                //printf("command = CHECK_POWER_MODE\n");
2082
 
                ata_cmd->command = ATA_CHECK_POWER_MODE;        
2083
 
                break;
2084
 
        case READ_VALUES:
2085
 
                //printf("command = READ_VALUES\n");
2086
 
                ata_cmd->features = ATA_SMART_READ_VALUES;
2087
 
                break;
2088
 
        case READ_THRESHOLDS:    
2089
 
                //printf("command = READ_THRESHOLDS\n");
2090
 
                ata_cmd->features = ATA_SMART_READ_THRESHOLDS;
2091
 
                break;
2092
 
        case READ_LOG: 
2093
 
                //printf("command = READ_LOG\n");
2094
 
                ata_cmd->features = ATA_SMART_READ_LOG_SECTOR;
2095
 
                ata_cmd->sector_number = select;        
2096
 
                break;
2097
 
        case WRITE_LOG:        
2098
 
                //printf("command = WRITE_LOG\n");    
2099
 
                ata_cmd->features = ATA_SMART_WRITE_LOG_SECTOR;
2100
 
                memcpy(ata_cmd->data, data, 512);
2101
 
                ata_cmd->sector_count = 1;
2102
 
                ata_cmd->sector_number = select;
2103
 
                break;
2104
 
        case IDENTIFY:
2105
 
                //printf("command = IDENTIFY\n");   
2106
 
                ata_cmd->command = ATA_IDENTIFY_DEVICE;         
2107
 
                break;
2108
 
        case PIDENTIFY:
2109
 
                //printf("command = PIDENTIFY\n");
2110
 
                errno=ENODEV;
2111
 
                return -1;
2112
 
        case ENABLE:
2113
 
                //printf("command = ENABLE\n");
2114
 
                ata_cmd->features = ATA_SMART_ENABLE;
2115
 
                break;
2116
 
        case DISABLE:
2117
 
                //printf("command = DISABLE\n");
2118
 
                ata_cmd->features = ATA_SMART_DISABLE;
2119
 
                break;
2120
 
        case AUTO_OFFLINE:
2121
 
                //printf("command = AUTO_OFFLINE\n");
2122
 
                ata_cmd->features = ATA_SMART_AUTO_OFFLINE;
2123
 
                // Enable or disable?
2124
 
                ata_cmd->sector_count = select;
2125
 
                break;
2126
 
        case AUTOSAVE:
2127
 
                //printf("command = AUTOSAVE\n");
2128
 
                ata_cmd->features = ATA_SMART_AUTOSAVE;
2129
 
                // Enable or disable?
2130
 
                ata_cmd->sector_count = select;
2131
 
                break;
2132
 
        case IMMEDIATE_OFFLINE:
2133
 
                //printf("command = IMMEDIATE_OFFLINE\n");
2134
 
                ata_cmd->features = ATA_SMART_IMMEDIATE_OFFLINE;
2135
 
                // What test type to run?
2136
 
                ata_cmd->sector_number = select;
2137
 
                break;
2138
 
        case STATUS_CHECK:
2139
 
                //printf("command = STATUS_CHECK\n");
2140
 
                ata_cmd->features = ATA_SMART_STATUS;           
2141
 
                break;
2142
 
        case STATUS:
2143
 
                //printf("command = STATUS\n");
2144
 
                ata_cmd->features = ATA_SMART_STATUS;       
2145
 
                break;
2146
 
        default:
2147
 
                //printf("command = UNKNOWN\n");
2148
 
                errno=ENOSYS;
2149
 
                return -1;
2150
 
        };
2151
 
 
2152
2096
        areca_packet[11] = m_disknum - 1;                  // drive number
2153
2097
 
2154
2098
        // ----- BEGIN TO SETUP CHECKSUM -----
2166
2110
        expected = arcmsr_command_handler(get_fd(), ARCMSR_IOCTL_CLEAR_RQBUFFER, NULL, 0, NULL);
2167
2111
        if (expected==-3) {
2168
2112
            find_areca_in_proc(NULL);
2169
 
            return -1;
 
2113
            return set_err(EIO);
2170
2114
        }
2171
2115
 
2172
2116
        expected = arcmsr_command_handler(get_fd(), ARCMSR_IOCTL_CLEAR_WQBUFFER, NULL, 0, NULL);
2189
2133
 
2190
2134
        if ( return_buff[expected - 1] != cs )
2191
2135
        {
2192
 
                errno = EIO;
2193
 
                return -1;
 
2136
                return set_err(EIO);
2194
2137
        }
2195
2138
 
2196
2139
        sATA_OUTPUT_REGISTERS *ata_out = (sATA_OUTPUT_REGISTERS *)&return_buff[5] ;
2197
2140
        if ( ata_out->status )
2198
2141
        {
2199
 
                if ( command == IDENTIFY )
2200
 
                {
2201
 
                        pout("The firmware of your Areca RAID controller appears to be outdated!\n" \
2202
 
                                 "Please update your controller to firmware version 1.46 or later.\n" \
2203
 
                                 "You may download it here: ftp://ftp.areca.com.tw/RaidCards/BIOS_Firmware\n\n");
2204
 
                }
2205
 
                errno = EIO;
2206
 
                return -1;
 
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
                 } 
2207
2147
        }
2208
2148
 
2209
2149
        // returns with data
2210
 
        if ( command == READ_VALUES     ||
2211
 
                 command == READ_THRESHOLDS ||
2212
 
                 command == READ_LOG ||
2213
 
                 command == IDENTIFY ||
2214
 
                 command == PIDENTIFY )
2215
 
        {
2216
 
                memcpy(data, &return_buff[7], 512); 
2217
 
        }
2218
 
 
2219
 
        if ( command == CHECK_POWER_MODE )
2220
 
        {
2221
 
                data[0] = ata_out->sector_count;
2222
 
        }
2223
 
 
2224
 
        if ( command == STATUS_CHECK &&
2225
 
                 ( ata_out->cylinder_low == 0xF4 && ata_out->cylinder_high == 0x2C ) )
2226
 
        {
2227
 
                return 1;
2228
 
        }
2229
 
 
2230
 
        return 0;
 
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;
2231
2166
}
2232
2167
 
2233
2168
 
3150
3085
      set_err(EINVAL, "Option '-d hpt,L/M/N' invalid controller id L supplied");
3151
3086
      return 0;
3152
3087
    }
3153
 
    if (!(1 <= channel && channel <= 8)) {
 
3088
    if (!(1 <= channel && channel <= 16)) {
3154
3089
      set_err(EINVAL, "Option '-d hpt,L/M/N' invalid channel number M supplied");
3155
3090
      return 0;
3156
3091
    }