]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - dev_ata_cmd_set.cpp
import smartmontools 7.0
[mirror_smartmontools-debian.git] / dev_ata_cmd_set.cpp
CommitLineData
2127e193
GI
1/*
2 * dev_ata_cmd_set.cpp
3 *
a86ec89e 4 * Home page of code is: http://www.smartmontools.org
2127e193 5 *
ff28b140 6 * Copyright (C) 2008-18 Christian Franke
2127e193 7 *
ff28b140 8 * SPDX-License-Identifier: GPL-2.0-or-later
2127e193
GI
9 */
10
11#include "config.h"
ff28b140 12
2127e193
GI
13#include "atacmds.h"
14#include "dev_ata_cmd_set.h"
15
16#include <errno.h>
17
ff28b140 18const char * dev_ata_cmd_set_cpp_cvsid = "$Id: dev_ata_cmd_set.cpp 4760 2018-08-19 18:45:53Z chrfranke $"
2127e193
GI
19 DEV_ATA_CMD_SET_H_CVSID;
20
21
22/////////////////////////////////////////////////////////////////////////////
23// ata_device_with_command_set
24
25// Adapter routine to implement new ATA pass through with old interface
26
27bool ata_device_with_command_set::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
28{
29 if (!ata_cmd_is_ok(in, true)) // data_out_support
30 return false;
31
32 smart_command_set command = (smart_command_set)-1;
33 int select = 0;
34 char * data = (char *)in.buffer;
35 char buffer[512];
36 switch (in.in_regs.command) {
37 case ATA_IDENTIFY_DEVICE:
38 command = IDENTIFY;
39 break;
40 case ATA_IDENTIFY_PACKET_DEVICE:
41 command = PIDENTIFY;
42 break;
43 case ATA_CHECK_POWER_MODE:
44 command = CHECK_POWER_MODE;
45 data = buffer; data[0] = 0;
46 break;
47 case ATA_SMART_CMD:
48 switch (in.in_regs.features) {
49 case ATA_SMART_ENABLE:
50 command = ENABLE;
51 break;
52 case ATA_SMART_READ_VALUES:
53 command = READ_VALUES;
54 break;
55 case ATA_SMART_READ_THRESHOLDS:
56 command = READ_THRESHOLDS;
57 break;
58 case ATA_SMART_READ_LOG_SECTOR:
59 command = READ_LOG;
60 select = in.in_regs.lba_low;
61 break;
62 case ATA_SMART_WRITE_LOG_SECTOR:
63 command = WRITE_LOG;
64 select = in.in_regs.lba_low;
65 break;
66 case ATA_SMART_DISABLE:
67 command = DISABLE;
68 break;
69 case ATA_SMART_STATUS:
70 command = (in.out_needed.lba_high ? STATUS_CHECK : STATUS);
71 break;
72 case ATA_SMART_AUTO_OFFLINE:
73 command = AUTO_OFFLINE;
74 select = in.in_regs.sector_count;
75 break;
76 case ATA_SMART_AUTOSAVE:
77 command = AUTOSAVE;
78 select = in.in_regs.sector_count;
79 break;
80 case ATA_SMART_IMMEDIATE_OFFLINE:
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