smartmontools SVN Rev 5640
Utility to control and monitor storage systems with "S.M.A.R.T."
dev_ata_cmd_set.cpp
Go to the documentation of this file.
1/*
2 * dev_ata_cmd_set.cpp
3 *
4 * Home page of code is: http://www.smartmontools.org
5 *
6 * Copyright (C) 2008-18 Christian Franke
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12
13#include "atacmds.h"
14#include "dev_ata_cmd_set.h"
15
16#include <errno.h>
17
18const char * dev_ata_cmd_set_cpp_cvsid = "$Id: dev_ata_cmd_set.cpp 4760 2018-08-19 18:45:53Z chrfranke $"
20
21
22/////////////////////////////////////////////////////////////////////////////
23// ata_device_with_command_set
24
25// Adapter routine to implement new ATA pass through with old interface
26
28{
29 if (!ata_cmd_is_ok(in, true)) // data_out_support
30 return false;
31
33 int select = 0;
34 char * data = (char *)in.buffer;
35 char buffer[512];
36 switch (in.in_regs.command) {
38 command = IDENTIFY;
39 break;
41 command = PIDENTIFY;
42 break;
44 command = CHECK_POWER_MODE;
45 data = buffer; data[0] = 0;
46 break;
47 case ATA_SMART_CMD:
48 switch (in.in_regs.features) {
50 command = ENABLE;
51 break;
53 command = READ_VALUES;
54 break;
56 command = READ_THRESHOLDS;
57 break;
59 command = READ_LOG;
60 select = in.in_regs.lba_low;
61 break;
63 command = WRITE_LOG;
64 select = in.in_regs.lba_low;
65 break;
67 command = DISABLE;
68 break;
70 command = (in.out_needed.lba_high ? STATUS_CHECK : STATUS);
71 break;
73 command = AUTO_OFFLINE;
74 select = in.in_regs.sector_count;
75 break;
77 command = AUTOSAVE;
78 select = in.in_regs.sector_count;
79 break;
81 command = IMMEDIATE_OFFLINE;
82 select = in.in_regs.lba_low;
83 break;
84 default:
85 return set_err(ENOSYS, "Unknown SMART command");
86 }
87 break;
88 default:
89 return set_err(ENOSYS, "Non-SMART commands not implemented");
90 }
91
92 clear_err(); errno = 0;
93 int rc = ata_command_interface(command, select, data);
94 if (rc < 0) {
95 if (!get_errno())
96 set_err(errno);
97 return false;
98 }
99
100 switch (command) {
101 case CHECK_POWER_MODE:
102 out.out_regs.sector_count = data[0];
103 break;
104 case STATUS_CHECK:
105 switch (rc) {
106 case 0: // Good SMART status
107 out.out_regs.lba_high = 0xc2; out.out_regs.lba_mid = 0x4f;
108 break;
109 case 1: // Bad SMART status
110 out.out_regs.lba_high = 0x2c; out.out_regs.lba_mid = 0xf4;
111 break;
112 }
113 break;
114 default:
115 break;
116 }
117 return true;
118}
119
#define ATA_SMART_AUTO_OFFLINE
Definition: atacmds.h:94
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:53
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:87
#define ATA_IDENTIFY_PACKET_DEVICE
Definition: atacmds.h:54
#define ATA_SMART_STATUS
Definition: atacmds.h:91
#define ATA_SMART_READ_VALUES
Definition: atacmds.h:81
#define ATA_SMART_READ_THRESHOLDS
Definition: atacmds.h:82
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:86
#define ATA_SMART_CMD
Definition: atacmds.h:56
#define ATA_SMART_IMMEDIATE_OFFLINE
Definition: atacmds.h:85
smart_command_set
Definition: atacmds.h:29
@ PIDENTIFY
Definition: atacmds.h:43
@ CHECK_POWER_MODE
Definition: atacmds.h:45
@ IDENTIFY
Definition: atacmds.h:42
@ STATUS_CHECK
Definition: atacmds.h:37
@ IMMEDIATE_OFFLINE
Definition: atacmds.h:34
@ AUTO_OFFLINE
Definition: atacmds.h:35
@ ENABLE
Definition: atacmds.h:31
@ WRITE_LOG
Definition: atacmds.h:47
@ READ_VALUES
Definition: atacmds.h:39
@ AUTOSAVE
Definition: atacmds.h:33
@ STATUS
Definition: atacmds.h:36
@ READ_THRESHOLDS
Definition: atacmds.h:40
@ DISABLE
Definition: atacmds.h:32
@ READ_LOG
Definition: atacmds.h:41
#define ATA_SMART_ENABLE
Definition: atacmds.h:89
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:83
#define ATA_SMART_DISABLE
Definition: atacmds.h:90
#define ATA_CHECK_POWER_MODE
Definition: atacmds.h:52
virtual int ata_command_interface(smart_command_set command, int select, char *data)=0
Old ATA interface called by ata_pass_through()
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through mapped to ata_command_interface().
bool ata_cmd_is_ok(const ata_cmd_in &in, bool data_out_support=false, bool multi_sector_support=false, bool ata_48bit_support=false)
Check command input parameters (old version).
int get_errno() const
Get last error number.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
void clear_err()
Clear last error info.
const char * dev_ata_cmd_set_cpp_cvsid
#define DEV_ATA_CMD_SET_H_CVSID
ptr_t buffer
Definition: megaraid.h:3
ptr_t data
Definition: megaraid.h:15
ATA pass through input parameters.
void * buffer
Pointer to data buffer.
ata_in_regs_48bit in_regs
Input registers.
ata_out_regs_flags out_needed
True if output register value needed.
ATA pass through output parameters.
ata_out_regs_48bit out_regs
Output registers.
ata_register sector_count
ata_register lba_low
ata_register features
ata_register command
ata_register sector_count
ata_register lba_mid
ata_register lba_high