summaryrefslogtreecommitdiffstats
path: root/firmware/export/ata.h
blob: e6ca9422ea836904607c9cc1991b1ae0fd5cc168 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2002 by Alan Korr
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
#ifndef __ATA_H__
#define __ATA_H__

#include <stdbool.h>
#include "config.h" /* for HAVE_MULTIVOLUME or not */
#include "mv.h" /* for IF_MV() and friends */

#ifdef HAVE_ATA_SMART
/* S.M.A.R.T. headers from smartmontools-5.42 */
#define NUMBER_ATA_SMART_ATTRIBUTES     30

struct ata_smart_attribute {
  unsigned char id;
  /* meaning of flag bits: see MACROS just below */
  /* WARNING: MISALIGNED! */
  unsigned short flags;
  unsigned char current;
  unsigned char worst;
  unsigned char raw[6];
  unsigned char reserv;
} __attribute__((packed));

/* MACROS to interpret the flags bits in the previous structure. */
/* These have not been implemented using bitflags and a union, to make */
/* it portable across bit/little endian and different platforms. */

/* 0: Prefailure bit */

/* From SFF 8035i Revision 2 page 19: Bit 0 (pre-failure/advisory bit) */
/* - If the value of this bit equals zero, an attribute value less */
/* than or equal to its corresponding attribute threshold indicates an */
/* advisory condition where the usage or age of the device has */
/* exceeded its intended design life period. If the value of this bit */
/* equals one, an attribute value less than or equal to its */
/* corresponding attribute threshold indicates a prefailure condition */
/* where imminent loss of data is being predicted. */
#define ATTRIBUTE_FLAGS_PREFAILURE(x) (x & 0x01)

/* 1: Online bit  */

/* From SFF 8035i Revision 2 page 19: Bit 1 (on-line data collection */
/* bit) - If the value of this bit equals zero, then the attribute */
/* value is updated only during off-line data collection */
/* activities. If the value of this bit equals one, then the attribute */
/* value is updated during normal operation of the device or during */
/* both normal operation and off-line testing. */
#define ATTRIBUTE_FLAGS_ONLINE(x) (x & 0x02)

/* The following are (probably) IBM's, Maxtors and  Quantum's definitions for the */
/* vendor-specific bits: */
/* 2: Performance type bit */
#define ATTRIBUTE_FLAGS_PERFORMANCE(x) (x & 0x04)

/* 3: Errorrate type bit */
#define ATTRIBUTE_FLAGS_ERRORRATE(x) (x & 0x08)

/* 4: Eventcount bit */
#define ATTRIBUTE_FLAGS_EVENTCOUNT(x) (x & 0x10)

/* 5: Selfpereserving bit */
#define ATTRIBUTE_FLAGS_SELFPRESERVING(x) (x & 0x20)

/* 6-15: Reserved for future use */
#define ATTRIBUTE_FLAGS_OTHER(x) ((x) & 0xffc0)

struct ata_smart_values
{
    unsigned short int revnumber;
    struct ata_smart_attribute vendor_attributes [NUMBER_ATA_SMART_ATTRIBUTES];
    unsigned char offline_data_collection_status;
    unsigned char self_test_exec_status;
    unsigned short int total_time_to_complete_off_line;
    unsigned char vendor_specific_366;
    unsigned char offline_data_collection_capability;
    unsigned short int smart_capability;
    unsigned char errorlog_capability;
    unsigned char vendor_specific_371;
    unsigned char short_test_completion_time;
    unsigned char extend_test_completion_time;
    unsigned char conveyance_test_completion_time;
    unsigned char reserved_375_385[11];
    unsigned char vendor_specific_386_510[125];
    unsigned char chksum;
} __attribute__((packed));

/* Raw attribute value print formats */
enum ata_attr_raw_format
{
    RAWFMT_DEFAULT,
    RAWFMT_RAW8,
    RAWFMT_RAW16,
    RAWFMT_RAW48,
    RAWFMT_HEX48,
    RAWFMT_RAW64,
    RAWFMT_HEX64,
    RAWFMT_RAW16_OPT_RAW16,
    RAWFMT_RAW16_OPT_AVG16,
    RAWFMT_RAW24_DIV_RAW24,
    RAWFMT_RAW24_DIV_RAW32,
    RAWFMT_SEC2HOUR,
    RAWFMT_MIN2HOUR,
    RAWFMT_HALFMIN2HOUR,
    RAWFMT_MSEC24_HOUR32,
    RAWFMT_TEMPMINMAX,
    RAWFMT_TEMP10X,
};
#endif /* HAVE_ATA_SMART */

struct storage_info;

void ata_enable(bool on);
void ata_spindown(int seconds);
void ata_sleep(void);
void ata_sleepnow(void);
/* NOTE: DO NOT use this to poll for disk activity.
         If you are waiting for the disk to become active before
         doing something use ata_idle_notify.h
 */
bool ata_disk_is_active(void);
int ata_soft_reset(void);
int ata_init(void) STORAGE_INIT_ATTR;
void ata_close(void);
int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf);
int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf);
void ata_spin(void);
#if (CONFIG_LED == LED_REAL)
void ata_set_led_enabled(bool enabled);
#endif
unsigned short* ata_get_identify(void);

#ifdef STORAGE_GET_INFO
void ata_get_info(IF_MD(int drive,) struct storage_info *info);
#endif
#ifdef HAVE_HOTSWAP
bool ata_removable(IF_MD_NONVOID(int drive));
bool ata_present(IF_MD_NONVOID(int drive));
#endif


#ifdef CONFIG_STORAGE_MULTI
int ata_num_drives(int first_drive);
#endif


long ata_last_disk_activity(void);
int ata_spinup_time(void); /* ticks */

#ifdef HAVE_ATA_DMA
/* Returns current DMA mode */
int ata_get_dma_mode(void);
#endif /* HAVE_ATA_DMA */

#ifdef HAVE_ATA_SMART
/* Returns current S.M.A.R.T. data */
int ata_read_smart(struct ata_smart_values*);
#endif

#ifdef BOOTLOADER
#define STORAGE_CLOSE
#endif

#endif /* __ATA_H__ */