File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / smartmontools / dev_ata_cmd_set.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: v6_2, v6_1p0, v6_1, v5_43, v5_42, HEAD
smartmontools

    1: /*
    2:  * dev_ata_cmd_set.cpp
    3:  *
    4:  * Home page of code is: http://smartmontools.sourceforge.net
    5:  *
    6:  * Copyright (C) 2008 Christian Franke <smartmontools-support@lists.sourceforge.net>
    7:  *
    8:  * This program is free software; you can redistribute it and/or modify
    9:  * it under the terms of the GNU General Public License as published by
   10:  * the Free Software Foundation; either version 2, or (at your option)
   11:  * any later version.
   12:  *
   13:  * You should have received a copy of the GNU General Public License
   14:  * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
   15:  *
   16:  */
   17: 
   18: #include "config.h"
   19: #include "int64.h"
   20: #include "atacmds.h"
   21: #include "dev_ata_cmd_set.h"
   22: 
   23: #include <errno.h>
   24: 
   25: const char * dev_ata_cmd_set_cpp_cvsid = "$Id: dev_ata_cmd_set.cpp,v 1.1.1.1 2012/02/21 16:32:16 misho Exp $"
   26:   DEV_ATA_CMD_SET_H_CVSID;
   27: 
   28: 
   29: /////////////////////////////////////////////////////////////////////////////
   30: // ata_device_with_command_set
   31: 
   32: // Adapter routine to implement new ATA pass through with old interface
   33: 
   34: bool ata_device_with_command_set::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
   35: {
   36:   if (!ata_cmd_is_ok(in, true)) // data_out_support
   37:     return false;
   38: 
   39:   smart_command_set command = (smart_command_set)-1;
   40:   int select = 0;
   41:   char * data = (char *)in.buffer;
   42:   char buffer[512];
   43:   switch (in.in_regs.command) {
   44:     case ATA_IDENTIFY_DEVICE:
   45:       command = IDENTIFY;
   46:       break;
   47:     case ATA_IDENTIFY_PACKET_DEVICE:
   48:       command = PIDENTIFY;
   49:       break;
   50:     case ATA_CHECK_POWER_MODE:
   51:       command = CHECK_POWER_MODE;
   52:       data = buffer; data[0] = 0;
   53:       break;
   54:     case ATA_SMART_CMD:
   55:       switch (in.in_regs.features) {
   56:         case ATA_SMART_ENABLE:
   57:           command = ENABLE;
   58:           break;
   59:         case ATA_SMART_READ_VALUES:
   60:           command = READ_VALUES;
   61:           break;
   62:         case ATA_SMART_READ_THRESHOLDS:
   63:           command = READ_THRESHOLDS;
   64:           break;
   65:         case ATA_SMART_READ_LOG_SECTOR:
   66:           command = READ_LOG;
   67:           select = in.in_regs.lba_low;
   68:           break;
   69:         case ATA_SMART_WRITE_LOG_SECTOR:
   70:           command = WRITE_LOG;
   71:           select = in.in_regs.lba_low;
   72:           break;
   73:         case ATA_SMART_DISABLE:
   74:           command = DISABLE;
   75:           break;
   76:         case ATA_SMART_STATUS:
   77:           command = (in.out_needed.lba_high ? STATUS_CHECK : STATUS);
   78:           break;
   79:         case ATA_SMART_AUTO_OFFLINE:
   80:           command = AUTO_OFFLINE;
   81:           select = in.in_regs.sector_count;
   82:           break;
   83:         case ATA_SMART_AUTOSAVE:
   84:           command = AUTOSAVE;
   85:           select = in.in_regs.sector_count;
   86:           break;
   87:         case ATA_SMART_IMMEDIATE_OFFLINE:
   88:           command = IMMEDIATE_OFFLINE;
   89:           select = in.in_regs.lba_low;
   90:           break;
   91:         default:
   92:           return set_err(ENOSYS, "Unknown SMART command");
   93:       }
   94:       break;
   95:     default:
   96:       return set_err(ENOSYS, "Non-SMART commands not implemented");
   97:   }
   98: 
   99:   clear_err(); errno = 0;
  100:   int rc = ata_command_interface(command, select, data);
  101:   if (rc < 0) {
  102:     if (!get_errno())
  103:       set_err(errno);
  104:     return false;
  105:   }
  106: 
  107:   switch (command) {
  108:     case CHECK_POWER_MODE:
  109:       out.out_regs.sector_count = data[0];
  110:       break;
  111:     case STATUS_CHECK:
  112:       switch (rc) {
  113:         case 0: // Good SMART status
  114:           out.out_regs.lba_high = 0xc2; out.out_regs.lba_mid = 0x4f;
  115:           break;
  116:         case 1: // Bad SMART status
  117:           out.out_regs.lba_high = 0x2c; out.out_regs.lba_mid = 0xf4;
  118:           break;
  119:       }
  120:       break;
  121:     default:
  122:       break;
  123:   }
  124:   return true;
  125: }
  126: 

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