]>
Commit | Line | Data |
---|---|---|
2127e193 GI |
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.4 2008/10/24 21:49:23 manfred99 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 |