RTEMS 7.0-rc1
Loading...
Searching...
No Matches
ata_internal.h
1/* SPDX-License-Identifier: GPL-2.0+-with-RTEMS-exception */
2
3/*
4 * ata_internal.h
5 *
6 * ATA RTEMS driver internal header file
7 *
8 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
9 * Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
10 * Alexandra Kossovsky <sasha@oktet.ru>
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 *
16 */
17#ifndef __ATA_INTERNAL_H__
18#define __ATA_INTERNAL_H__
19
20#include <sys/param.h>
21#include <sys/endian.h>
22#include <rtems.h>
23#include <sys/types.h>
24#include <rtems/libio.h>
25#include <stdlib.h>
26
27#include <rtems/blkdev.h>
28#include <rtems/diskdevs.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34/*
35 * Conversion from and to little-endian byte order. (no-op on i386/i486)
36 *
37 * Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian,
38 * BE = big-endian, c: W = word (16 bits), L = longword (32 bits)
39 */
40#define CF_LE_W(v) le16toh(v)
41#define CF_LE_L(v) le32toh(v)
42#define CT_LE_W(v) htole16(v)
43#define CT_LE_L(v) htole32(v)
44
45#define ATA_UNDEFINED_VALUE (-1)
46
47/* Sector size for all ATA devices */
48#define ATA_SECTOR_SIZE 512
49
50
51#define ATA_MAX_CMD_REG_OFFSET 8
52
53
54/* ATA Commands */
55
56/* Types of ATA commands */
57#define ATA_COMMAND_TYPE_NON_DATA 0
58#define ATA_COMMAND_TYPE_PIO_IN 1
59#define ATA_COMMAND_TYPE_PIO_OUT 2
60#define ATA_COMMAND_TYPE_DMA 3
61
62/* ATA commands opcodes */
63/*
64 * Commands present in both ATA-2 and ATA-4 specs.
65 * Some commands have two values in ATA-2,
66 * in such case value from ATA-4 used.
67 * Some commands have slightly different names in these specifications,
68 * so names from ATA-4 are used.
69 */
70#define ATA_COMMAND_NOP 0x00
71#define ATA_COMMAND_READ_SECTORS 0x20
72#define ATA_COMMAND_WRITE_SECTORS 0x30
73#define ATA_COMMAND_READ_VERIFY_SECTORS 0x40
74#define ATA_COMMAND_SEEK 0x70 /* or 0x7. */
75#define ATA_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC 0x90
76#define ATA_COMMAND_INITIALIZE_DEVICE_PARAMETERS 0x91
77#define ATA_COMMAND_DOWNLOAD_MICROCODE 0x92
78#define ATA_COMMAND_READ_MULTIPLE 0xc4
79#define ATA_COMMAND_WRITE_MULTIPLE 0xc5
80#define ATA_COMMAND_SET_MULTIPLE_MODE 0xc6
81#define ATA_COMMAND_READ_DMA 0xc8
82#define ATA_COMMAND_WRITE_DMA 0xca
83#define ATA_COMMAND_STANDBY_IMMEDIATE 0xe0 /* or 0x94 */
84#define ATA_COMMAND_IDLE_IMMEDIATE 0xe1 /* or 0x95 */
85#define ATA_COMMAND_STANDBY 0xe2 /* or 0x96 */
86#define ATA_COMMAND_IDLE 0xe3 /* or 0x97 */
87#define ATA_COMMAND_READ_BUFFER 0xe4
88#define ATA_COMMAND_CHECK_POWER_MODE 0xe5 /* or 0x98 in ATA-2 */
89#define ATA_COMMAND_SLEEP 0xe6 /* or 0x99 */
90#define ATA_COMMAND_WRITE_BUFFER 0xe8
91#define ATA_COMMAND_IDENTIFY_DEVICE 0xec
92#define ATA_COMMAND_SET_FEATURES 0xef
93
94/* Commands present in both ATA-2 and ATA-4 specs: removable media */
95#define ATA_COMMAND_MEDIA_LOCK 0xde
96#define ATA_COMMAND_MEDIA_UNLOCK 0xdf
97#define ATA_COMMAND_MEDIA_EJECT 0xed
98
99
100/* Commands present in ATA-2, but not in ATA-4 (not used) */
101#define ATA_COMMAND_RECALIBRATE 0x10 /* or 0x1. */
102#define ATA_COMMAND_READ_SECTOR_NON_RETRY 0x21
103#define ATA_COMMAND_READ_LONG_RETRY 0x22
104#define ATA_COMMAND_READ_LONG_NON_RETRY 0x23
105#define ATA_COMMAND_WRITE_SECTOR_NON_RETRY 0x31
106#define ATA_COMMAND_WRITE_LONG_RETRY 0x32
107#define ATA_COMMAND_WRITE_LONG_NON_RETRY 0x33
108#define ATA_COMMAND_WRITE_VERIFY 0x3c
109#define ATA_COMMAND_READ_VERIFY_SECTOR_NON_RETRY 0x41
110#define ATA_COMMAND_FORMAT_TRACK 0x50
111#define ATA_COMMAND_READ_DMA_NON_RETRY 0xc9
112#define ATA_COMMAND_WRITE_DMA_NON_RETRY 0xcb
113#define ATA_COMMAND_ACKNOWLEGE_MEDIA_CHANGE 0xdb
114#define ATA_COMMAND_BOOT_POST_BOOT 0xdc
115#define ATA_COMMAND_BOOT_PRE_BOOT 0xdd
116#define ATA_COMMAND_WRITE_SAME 0xe9
117
118/* Commands from ATA-4 specification: CFA feature set */
119#define ATA_COMMAND_CFA_REQUEST_EXTENDED_ERROR_CODE 0x03
120#define ATA_COMMAND_CFA_WRITE_SECTORS_WITHOUT_ERASE 0x38
121#define ATA_COMMAND_CFA_TRANSLATE_SECTOR 0x87
122#define ATA_COMMAND_CFA_ERASE_SECTORS 0xc0
123#define ATA_COMMAND_CFA_WRITE_MULTIPLE_WITHOUT_ERASE 0xcd
124
125/* Commands from ATA-4 specification: commands to use with PACKET command */
126#define ATA_COMMAND_DEVICE_RESET 0x08
127#define ATA_COMMAND_PACKET 0xa0
128#define ATA_COMMAND_IDENTIFY_PACKET_DEVICE 0xa1
129#define ATA_COMMAND_SERVICE 0xa2
130
131/* Commands from ATA-4 specification: SECURITY commands */
132#define ATA_COMMAND_SECURITY_SET_PASSWORD 0xf1
133#define ATA_COMMAND_SECURITY_UNLOCK 0xf2
134#define ATA_COMMAND_SECURITY_ERASE_PREPARE 0xf3
135#define ATA_COMMAND_SECURITY_ERASE_UNIT 0xf4
136#define ATA_COMMAND_SECURITY_FREEZE_LOCK 0xf5
137#define ATA_COMMAND_SECURITY_DISABLE_PASSWORD 0xf6
138
139/* Commands from ATA-4 specification: other commands */
140#define ATA_COMMAND_SMART 0xb0
141#define ATA_COMMAND_READ_DMA_QUEUED 0xc7
142#define ATA_COMMAND_WRITE_DMA_QUEUED 0xcc
143#define ATA_COMMAND_GET_MEDIA_STATUS 0xda
144#define ATA_COMMAND_FLUSH_CACHE 0xe7
145#define ATA_COMMAND_READ_NATIVE_MAX_ADDRESS 0xf8
146#define ATA_COMMAND_SET_MAX_ADDRESS 0xf9
147
148#define ATA_REGISTERS_VALUE(reg) (1 << (reg))
149
150/* ATA IDENTIFY DEVICE command words and bits */
151#define ATA_IDENT_WORD_RW_MULT 47
152#define ATA_IDENT_WORD_CAPABILITIES 49
153#define ATA_IDENT_WORD_FIELD_VALIDITY 53
154#define ATA_IDENT_WORD_NUM_OF_CURR_LOG_CLNDS 54
155#define ATA_IDENT_WORD_NUM_OF_CURR_LOG_HEADS 55
156#define ATA_IDENT_WORD_NUM_OF_CURR_LOG_SECS 56
157#define ATA_IDENT_WORD_MULT_SECS 59
158#define ATA_IDENT_WORD_NUM_OF_USR_SECS0 60
159#define ATA_IDENT_WORD_NUM_OF_USR_SECS1 61
160#define ATA_IDENT_WORD_PIO_SPPRTD 64
161
162#define ATA_IDENT_BIT_VALID 0x02
163
164/*
165 * It is OR for all ATA_REGISTERS_VALUE(reg), where reg is neccessary
166 * for setting block position
167 */
168#define ATA_REGISTERS_POSITION 0xfc
169
170#define ATA_MAX_RTEMS_INT_VEC_NUMBER 255
171
172#define ATA_MAX_NAME_LENGTH 10
173
174/* diagnostic codes */
175#define ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT 0x01
176#define ATA_DEV0_PASSED_DEV1_FAILED 0x81
177#define ATA_DEV1_PASSED_DEV0_FAILED 0x80
178
179/*
180 * Obtain ata device parameters by controller minor number and device number
181 */
182#define ATA_DEV_INFO(controller_minor, dev) \
183 ata_ide_ctrls[controller_minor].device[dev]
184
185/* ATA RTEMS driver internal data stuctures */
186
187/* Command block registers */
188typedef struct ata_registers_s {
189 uint16_t regs[8]; /* command block registers */
190 uint16_t to_read; /* mask: which ata registers should be read */
191 uint16_t to_write; /* mask: which ata registers should be written */
193
194/* ATA request */
195typedef struct ata_req_s {
196 rtems_chain_node link; /* link in requests chain */
197 char type; /* request type */
198 ata_registers_t regs; /* ATA command */
199 uint32_t cnt; /* Number of sectors to be exchanged */
200 uint32_t cbuf; /* number of current buffer from breq in use */
201 uint32_t pos; /* current position in 'cbuf' */
202 rtems_blkdev_request *breq; /* blkdev_request which corresponds to the
203 * ata request
204 */
205 rtems_id sema; /* semaphore which is used if synchronous
206 * processing of the ata request is required
207 */
208 rtems_status_code status; /* status of ata request processing */
209 int info; /* device info code */
210} ata_req_t;
211
212/* call callback provided by block device request if it is defined */
213#define ATA_EXEC_CALLBACK(areq, status) \
214 do {\
215 if ((areq)->breq != NULL) \
216 rtems_blkdev_request_done((areq)->breq, status); \
217 } while (0)
218
219/* ATA RTEMS driver events types */
220typedef enum ata_msg_type_s {
221 ATA_MSG_GEN_EVT = 1, /* general event */
222 ATA_MSG_SUCCESS_EVT, /* success event */
223 ATA_MSG_ERROR_EVT, /* error event */
224 ATA_MSG_PROCESS_NEXT_EVT /* process next request event */
225} ata_msg_type_t;
226
227/* ATA RTEMS driver message */
228typedef struct ata_queue_msg_s {
229 ata_msg_type_t type; /* message type */
230 rtems_device_minor_number ctrl_minor; /* IDE controller minor number */
231 int error; /* error code */
233
234/* macros for messages processing */
235#define ATA_FILL_MSG(msg, evt_type, ctrl, err)\
236 do {\
237 msg.type = evt_type;\
238 msg.ctrl_minor = ctrl;\
239 msg.error = err;\
240 } while (0)
241
242#define ATA_SEND_EVT(msg, type, ctrl, err)\
243 do {\
244 rtems_status_code rc;\
245 ATA_FILL_MSG(msg, type, ctrl, err);\
246 rc = rtems_message_queue_send(ata_queue_id, &msg,\
247 sizeof(ata_queue_msg_t));\
248 if (rc != RTEMS_SUCCESSFUL)\
249 rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);\
250 } while (0)
251
252/*
253 * Array of such structures is indexed by interrupt vecotrs and used for
254 * mapping of IDE controllers and interrupt vectors
255 */
256typedef struct ata_int_st_s {
257 rtems_chain_node link;
258 rtems_device_minor_number ctrl_minor;
260
261/*
262 * Mapping of rtems ATA devices to the following pairs:
263 * (IDE controller number served the device, device number on the controller)
264 */
265typedef struct ata_ide_dev_s {
266 int ctrl_minor;/* minor number of IDE controller served rtems ATA device */
267 int device; /* device number on IDE controller (0 or 1) */
269
270/*
271 * ATA device description
272 */
273typedef struct ata_dev_s {
274 int8_t present; /* 1 -- present, 0 -- not present, */
275 /* -1 -- non-initialized */
276 uint16_t cylinders;
277 uint16_t heads;
278 uint16_t sectors;
279 uint32_t lba_sectors; /* for small disk */
280 /* == cylinders * heads * sectors */
281
282 uint8_t lba_avaible; /* 0 - CHS mode, 1 - LBA mode */
283
284 uint16_t modes_available; /* OR of values for this modes */
285 uint16_t mode_active;
286} ata_dev_t;
287
288/*
289 * This structure describes controller state, devices configuration on the
290 * controller and chain of ATA requests to the controller. Array of such
291 * structures is indexed by controller minor number
292 */
293typedef struct ata_ide_ctrl_s {
294 bool present; /* controller state */
295 ata_dev_t device[2]; /* ata diveces description */
296 rtems_chain_control reqs; /* requests chain */
298
299/* Block device request with a single buffer provided */
300typedef struct blkdev_request1 {
304
305void ata_breq_init(blkdev_request1 *breq, uint16_t *sector_buffer);
306
307rtems_status_code ata_identify_device(
308 rtems_device_minor_number ctrl_minor,
309 int dev,
310 uint16_t *sector_buffer,
311 ata_dev_t *device_entry
312);
313
314void ata_process_request_on_init_phase(
315 rtems_device_minor_number ctrl_minor,
316 ata_req_t *areq
317);
318
319#ifdef __cplusplus
320}
321#endif
322
323#endif /* __ATA_INTERNAL_H__ */
Block Device Management.
Block Device Disk Management API.
uint32_t rtems_device_minor_number
This integer type represents the minor number of devices.
Definition: io.h:115
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
Definition: status.h:85
Objects_Id rtems_id
This type represents RTEMS object identifiers.
Definition: types.h:94
Basic IO API.
This header file defines the RTEMS Classic API.
This structure represents a chain node.
Definition: chain.h:78
Definition: ata_internal.h:273
Definition: ata_internal.h:293
Definition: ata_internal.h:265
Definition: ata_internal.h:256
Definition: ata_internal.h:228
Definition: ata_internal.h:188
Definition: ata_internal.h:195
Definition: ata_internal.h:300
The block device transfer request is used to read or write a number of blocks from or to the device.
Definition: blkdev.h:102
Block device scatter or gather buffer structure.
Definition: blkdev.h:68
This header file provides interfaces of the system endianness support.
This union represents a chain control block.
Definition: chain.h:96