Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:43

0001 /*
0002  * ata_internal.h
0003  *
0004  * ATA RTEMS driver internal header file
0005  *
0006  * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
0007  * Authors: Eugeny S. Mints     <Eugeny.Mints@oktet.ru>
0008  *          Alexandra Kossovsky <sasha@oktet.ru>
0009  *
0010  * The license and distribution terms for this file may be
0011  * found in the file LICENSE in this distribution or at
0012  * http://www.rtems.org/license/LICENSE.
0013  *
0014  */
0015 #ifndef __ATA_INTERNAL_H__
0016 #define __ATA_INTERNAL_H__
0017 
0018 #include <sys/param.h>
0019 #include <sys/endian.h>
0020 #include <rtems.h>
0021 #include <sys/types.h>
0022 #include <rtems/libio.h>
0023 #include <stdlib.h>
0024 
0025 #include <rtems/blkdev.h>
0026 #include <rtems/diskdevs.h>
0027 
0028 #ifdef __cplusplus
0029 extern "C" {
0030 #endif
0031 
0032 /*
0033  * Conversion from and to little-endian byte order. (no-op on i386/i486)
0034  *
0035  * Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian,
0036  * BE = big-endian, c: W = word (16 bits), L = longword (32 bits)
0037  */
0038 #define CF_LE_W(v) le16toh(v)
0039 #define CF_LE_L(v) le32toh(v)
0040 #define CT_LE_W(v) htole16(v)
0041 #define CT_LE_L(v) htole32(v)
0042 
0043 #define ATA_UNDEFINED_VALUE   (-1)
0044 
0045 /* Sector size for all ATA devices */
0046 #define ATA_SECTOR_SIZE                 512
0047 
0048 
0049 #define ATA_MAX_CMD_REG_OFFSET          8
0050 
0051 
0052 /* ATA Commands */
0053 
0054 /* Types of ATA commands */
0055 #define ATA_COMMAND_TYPE_NON_DATA   0
0056 #define ATA_COMMAND_TYPE_PIO_IN     1
0057 #define ATA_COMMAND_TYPE_PIO_OUT    2
0058 #define ATA_COMMAND_TYPE_DMA        3
0059 
0060 /* ATA commands opcodes */
0061 /*
0062  * Commands present in both ATA-2 and ATA-4 specs.
0063  * Some commands have two values in ATA-2,
0064  * in such case value from ATA-4 used.
0065  * Some commands have slightly different names in these specifications,
0066  * so names from ATA-4 are used.
0067  */
0068 #define ATA_COMMAND_NOP                          0x00
0069 #define ATA_COMMAND_READ_SECTORS                 0x20
0070 #define ATA_COMMAND_WRITE_SECTORS                0x30
0071 #define ATA_COMMAND_READ_VERIFY_SECTORS          0x40
0072 #define ATA_COMMAND_SEEK                         0x70 /* or 0x7. */
0073 #define ATA_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC    0x90
0074 #define ATA_COMMAND_INITIALIZE_DEVICE_PARAMETERS 0x91
0075 #define ATA_COMMAND_DOWNLOAD_MICROCODE           0x92
0076 #define ATA_COMMAND_READ_MULTIPLE                0xc4
0077 #define ATA_COMMAND_WRITE_MULTIPLE               0xc5
0078 #define ATA_COMMAND_SET_MULTIPLE_MODE            0xc6
0079 #define ATA_COMMAND_READ_DMA                     0xc8
0080 #define ATA_COMMAND_WRITE_DMA                    0xca
0081 #define ATA_COMMAND_STANDBY_IMMEDIATE            0xe0 /* or 0x94 */
0082 #define ATA_COMMAND_IDLE_IMMEDIATE               0xe1 /* or 0x95 */
0083 #define ATA_COMMAND_STANDBY                      0xe2 /* or 0x96 */
0084 #define ATA_COMMAND_IDLE                         0xe3 /* or 0x97 */
0085 #define ATA_COMMAND_READ_BUFFER                  0xe4
0086 #define ATA_COMMAND_CHECK_POWER_MODE             0xe5 /* or 0x98 in ATA-2 */
0087 #define ATA_COMMAND_SLEEP                        0xe6 /* or 0x99 */
0088 #define ATA_COMMAND_WRITE_BUFFER                 0xe8
0089 #define ATA_COMMAND_IDENTIFY_DEVICE              0xec
0090 #define ATA_COMMAND_SET_FEATURES                 0xef
0091 
0092 /* Commands present in both ATA-2 and ATA-4 specs: removable media */
0093 #define ATA_COMMAND_MEDIA_LOCK                   0xde
0094 #define ATA_COMMAND_MEDIA_UNLOCK                 0xdf
0095 #define ATA_COMMAND_MEDIA_EJECT                  0xed
0096 
0097 
0098 /* Commands present in ATA-2, but not in ATA-4 (not used) */
0099 #define ATA_COMMAND_RECALIBRATE                  0x10 /* or 0x1. */
0100 #define ATA_COMMAND_READ_SECTOR_NON_RETRY        0x21
0101 #define ATA_COMMAND_READ_LONG_RETRY              0x22
0102 #define ATA_COMMAND_READ_LONG_NON_RETRY          0x23
0103 #define ATA_COMMAND_WRITE_SECTOR_NON_RETRY       0x31
0104 #define ATA_COMMAND_WRITE_LONG_RETRY             0x32
0105 #define ATA_COMMAND_WRITE_LONG_NON_RETRY         0x33
0106 #define ATA_COMMAND_WRITE_VERIFY                 0x3c
0107 #define ATA_COMMAND_READ_VERIFY_SECTOR_NON_RETRY 0x41
0108 #define ATA_COMMAND_FORMAT_TRACK                 0x50
0109 #define ATA_COMMAND_READ_DMA_NON_RETRY           0xc9
0110 #define ATA_COMMAND_WRITE_DMA_NON_RETRY          0xcb
0111 #define ATA_COMMAND_ACKNOWLEGE_MEDIA_CHANGE      0xdb
0112 #define ATA_COMMAND_BOOT_POST_BOOT               0xdc
0113 #define ATA_COMMAND_BOOT_PRE_BOOT                0xdd
0114 #define ATA_COMMAND_WRITE_SAME                   0xe9
0115 
0116 /* Commands from ATA-4 specification: CFA feature set */
0117 #define ATA_COMMAND_CFA_REQUEST_EXTENDED_ERROR_CODE  0x03
0118 #define ATA_COMMAND_CFA_WRITE_SECTORS_WITHOUT_ERASE  0x38
0119 #define ATA_COMMAND_CFA_TRANSLATE_SECTOR             0x87
0120 #define ATA_COMMAND_CFA_ERASE_SECTORS                0xc0
0121 #define ATA_COMMAND_CFA_WRITE_MULTIPLE_WITHOUT_ERASE 0xcd
0122 
0123 /* Commands from ATA-4 specification: commands to use with PACKET command */
0124 #define ATA_COMMAND_DEVICE_RESET                 0x08
0125 #define ATA_COMMAND_PACKET                       0xa0
0126 #define ATA_COMMAND_IDENTIFY_PACKET_DEVICE       0xa1
0127 #define ATA_COMMAND_SERVICE                      0xa2
0128 
0129 /* Commands from ATA-4 specification: SECURITY commands */
0130 #define ATA_COMMAND_SECURITY_SET_PASSWORD        0xf1
0131 #define ATA_COMMAND_SECURITY_UNLOCK              0xf2
0132 #define ATA_COMMAND_SECURITY_ERASE_PREPARE       0xf3
0133 #define ATA_COMMAND_SECURITY_ERASE_UNIT          0xf4
0134 #define ATA_COMMAND_SECURITY_FREEZE_LOCK         0xf5
0135 #define ATA_COMMAND_SECURITY_DISABLE_PASSWORD    0xf6
0136 
0137 /* Commands from ATA-4 specification: other commands */
0138 #define ATA_COMMAND_SMART                        0xb0
0139 #define ATA_COMMAND_READ_DMA_QUEUED              0xc7
0140 #define ATA_COMMAND_WRITE_DMA_QUEUED             0xcc
0141 #define ATA_COMMAND_GET_MEDIA_STATUS             0xda
0142 #define ATA_COMMAND_FLUSH_CACHE                  0xe7
0143 #define ATA_COMMAND_READ_NATIVE_MAX_ADDRESS      0xf8
0144 #define ATA_COMMAND_SET_MAX_ADDRESS              0xf9
0145 
0146 #define ATA_REGISTERS_VALUE(reg)    (1 << (reg))
0147 
0148 /* ATA IDENTIFY DEVICE command words and bits */
0149 #define ATA_IDENT_WORD_RW_MULT                   47
0150 #define ATA_IDENT_WORD_CAPABILITIES              49
0151 #define ATA_IDENT_WORD_FIELD_VALIDITY            53
0152 #define ATA_IDENT_WORD_NUM_OF_CURR_LOG_CLNDS     54
0153 #define ATA_IDENT_WORD_NUM_OF_CURR_LOG_HEADS     55
0154 #define ATA_IDENT_WORD_NUM_OF_CURR_LOG_SECS      56
0155 #define ATA_IDENT_WORD_MULT_SECS                 59
0156 #define ATA_IDENT_WORD_NUM_OF_USR_SECS0          60
0157 #define ATA_IDENT_WORD_NUM_OF_USR_SECS1          61
0158 #define ATA_IDENT_WORD_PIO_SPPRTD                64
0159 
0160 #define ATA_IDENT_BIT_VALID                      0x02
0161 
0162 /*
0163  * It is OR for all ATA_REGISTERS_VALUE(reg), where reg is neccessary
0164  * for setting block position
0165  */
0166 #define ATA_REGISTERS_POSITION       0xfc
0167 
0168 #define ATA_MAX_RTEMS_INT_VEC_NUMBER              255
0169 
0170 #define ATA_MAX_NAME_LENGTH                       10
0171 
0172 /* diagnostic codes */
0173 #define ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT  0x01
0174 #define ATA_DEV0_PASSED_DEV1_FAILED               0x81
0175 #define ATA_DEV1_PASSED_DEV0_FAILED               0x80
0176 
0177 /*
0178  * Obtain ata device parameters by controller minor number and device number
0179  */
0180 #define ATA_DEV_INFO(controller_minor, dev) \
0181     ata_ide_ctrls[controller_minor].device[dev]
0182 
0183 /* ATA RTEMS driver internal data stuctures */
0184 
0185 /* Command block registers */
0186 typedef struct ata_registers_s {
0187     uint16_t   regs[8];  /* command block registers */
0188     uint16_t   to_read;  /* mask: which ata registers should be read */
0189     uint16_t   to_write; /* mask: which ata registers should be written */
0190 } ata_registers_t;
0191 
0192 /* ATA request */
0193 typedef struct ata_req_s {
0194     rtems_chain_node  link;   /* link in requests chain */
0195     char              type;   /* request type */
0196     ata_registers_t   regs;   /* ATA command */
0197     uint32_t    cnt;    /* Number of sectors to be exchanged */
0198     uint32_t    cbuf;   /* number of current buffer from breq in use */
0199     uint32_t    pos;    /* current position in 'cbuf' */
0200     rtems_blkdev_request *breq;   /* blkdev_request which corresponds to the
0201                                * ata request
0202                                */
0203     rtems_id          sema;   /* semaphore which is used if synchronous
0204                                * processing of the ata request is required
0205                                */
0206     rtems_status_code status; /* status of ata request processing */
0207     int               info;  /* device info code */
0208 } ata_req_t;
0209 
0210 /* call callback provided by block device request if it is defined */
0211 #define ATA_EXEC_CALLBACK(areq, status) \
0212     do {\
0213         if ((areq)->breq != NULL) \
0214             rtems_blkdev_request_done((areq)->breq, status); \
0215     } while (0)
0216 
0217 /* ATA RTEMS driver events types */
0218 typedef enum ata_msg_type_s {
0219     ATA_MSG_GEN_EVT = 1,     /* general event */
0220     ATA_MSG_SUCCESS_EVT,     /* success event */
0221     ATA_MSG_ERROR_EVT,       /* error event */
0222     ATA_MSG_PROCESS_NEXT_EVT /* process next request event */
0223 } ata_msg_type_t;
0224 
0225 /* ATA RTEMS driver message */
0226 typedef struct ata_queue_msg_s {
0227     ata_msg_type_t            type;       /* message type */
0228     rtems_device_minor_number ctrl_minor; /* IDE controller minor number */
0229     int                       error;      /* error code */
0230 } ata_queue_msg_t;
0231 
0232 /* macros for messages processing */
0233 #define ATA_FILL_MSG(msg, evt_type, ctrl, err)\
0234     do {\
0235         msg.type = evt_type;\
0236         msg.ctrl_minor = ctrl;\
0237         msg.error = err;\
0238     } while (0)
0239 
0240 #define ATA_SEND_EVT(msg, type, ctrl, err)\
0241     do {\
0242         rtems_status_code rc;\
0243         ATA_FILL_MSG(msg, type, ctrl, err);\
0244         rc = rtems_message_queue_send(ata_queue_id, &msg,\
0245                                       sizeof(ata_queue_msg_t));\
0246         if (rc != RTEMS_SUCCESSFUL)\
0247             rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);\
0248     } while (0)
0249 
0250 /*
0251  * Array of such structures is indexed by interrupt vecotrs and used for
0252  * mapping of IDE controllers and interrupt vectors
0253  */
0254 typedef struct ata_int_st_s {
0255     rtems_chain_node          link;
0256     rtems_device_minor_number ctrl_minor;
0257 } ata_int_st_t;
0258 
0259 /*
0260  * Mapping of rtems ATA devices to the following pairs:
0261  * (IDE controller number served the device, device number on the controller)
0262  */
0263 typedef struct ata_ide_dev_s {
0264     int ctrl_minor;/* minor number of IDE controller served rtems ATA device */
0265     int device;    /* device number on IDE controller (0 or 1) */
0266 } ata_ide_dev_t;
0267 
0268 /*
0269  * ATA device description
0270  */
0271 typedef struct ata_dev_s {
0272     int8_t      present;     /* 1 -- present, 0 -- not present, */
0273                              /* -1 -- non-initialized */
0274     uint16_t    cylinders;
0275     uint16_t    heads;
0276     uint16_t    sectors;
0277     uint32_t    lba_sectors;  /* for small disk */
0278                               /* == cylinders * heads * sectors */
0279 
0280     uint8_t     lba_avaible;  /* 0 - CHS mode, 1 - LBA mode */
0281 
0282     uint16_t  modes_available; /* OR of values for this modes */
0283     uint16_t  mode_active;
0284 } ata_dev_t;
0285 
0286 /*
0287  * This structure describes controller state, devices configuration on the
0288  * controller and chain of ATA requests to the controller. Array of such
0289  * structures is indexed by controller minor number
0290  */
0291 typedef struct ata_ide_ctrl_s {
0292     bool          present;   /* controller state */
0293     ata_dev_t     device[2]; /* ata diveces description */
0294     rtems_chain_control reqs; /* requests chain */
0295 } ata_ide_ctrl_t;
0296 
0297 /* Block device request with a single buffer provided */
0298 typedef struct blkdev_request1 {
0299     rtems_blkdev_request   req;
0300     rtems_blkdev_sg_buffer sg[1];
0301 } blkdev_request1;
0302 
0303 void ata_breq_init(blkdev_request1 *breq, uint16_t *sector_buffer);
0304 
0305 rtems_status_code ata_identify_device(
0306   rtems_device_minor_number ctrl_minor,
0307   int dev,
0308   uint16_t *sector_buffer,
0309   ata_dev_t *device_entry
0310 );
0311 
0312 void ata_process_request_on_init_phase(
0313   rtems_device_minor_number ctrl_minor,
0314   ata_req_t *areq
0315 );
0316 
0317 #ifdef __cplusplus
0318 }
0319 #endif
0320 
0321 #endif /* __ATA_INTERNAL_H__ */