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