forked from Imagelibrary/rtems
2003-03-27 Joel Sherrill <joel@OARcorp.com>
* ide/Makefile.am: ATA code depends upon libchip/ide which is not allowed in the cpukit source code since it must be buildable independent of any BSP. These files were moved to libchip/ide. * ide/ata.c, ide/ata.h, ide/ata_internal.h: New files.
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
2003-03-27 Joel Sherrill <joel@OARcorp.com>
|
||||
|
||||
* ide/Makefile.am: ATA code depends upon libchip/ide which is not
|
||||
allowed in the cpukit source code since it must be buildable
|
||||
independent of any BSP. These files were moved to libchip/ide.
|
||||
* ide/ata.c, ide/ata.h, ide/ata_internal.h: New files.
|
||||
|
||||
2003-03-25 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
|
||||
|
||||
PR 368/filesystems
|
||||
|
||||
@@ -8,12 +8,12 @@ include_idedir = $(includedir)/libchip
|
||||
LIBNAME = libide
|
||||
LIB = $(ARCH)/$(LIBNAME).a
|
||||
|
||||
C_FILES = ide_controller.c
|
||||
C_FILES = ata.c ide_controller.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
||||
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS = ata_internal.h
|
||||
|
||||
include_ide_HEADERS = ide_ctrl_cfg.h ide_ctrl.h ide_ctrl_io.h
|
||||
include_ide_HEADERS = ata.h ide_ctrl_cfg.h ide_ctrl.h ide_ctrl_io.h
|
||||
|
||||
OBJS = $(C_O_FILES)
|
||||
|
||||
|
||||
1316
c/src/libchip/ide/ata.c
Normal file
1316
c/src/libchip/ide/ata.c
Normal file
File diff suppressed because it is too large
Load Diff
55
c/src/libchip/ide/ata.h
Normal file
55
c/src/libchip/ide/ata.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* ata.h
|
||||
*
|
||||
* ATA RTEMS driver header file. This file should be included from an
|
||||
* application.
|
||||
*
|
||||
* Copyright (C) 2002 OKTET Ltd., St.-Petersburg, Russia
|
||||
* Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
#ifndef __ATA_H__
|
||||
#define __ATA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <rtems.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <rtems/blkdev.h>
|
||||
|
||||
rtems_device_driver ata_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *args);
|
||||
|
||||
#define ATA_DRIVER_TABLE_ENTRY \
|
||||
{ata_initialize, GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES}
|
||||
|
||||
/* ATA IOCTL request codes */
|
||||
#define ATAIO_SET_MULTIPLE_MODE _IO('A', 1)
|
||||
|
||||
/*
|
||||
* ATA driver configuration parameters
|
||||
* FIXME: should be configured more easy...
|
||||
*/
|
||||
#define ATA_DRIVER_MESSAGE_QUEUE_SIZE 50
|
||||
#define ATA_DRIVER_TASK_PRIORITY 140
|
||||
#define ATA_DRIVER_TASK_STACK_SIZE 16*1024
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __ATA_H__ */
|
||||
|
||||
|
||||
|
||||
328
c/src/libchip/ide/ata_internal.h
Normal file
328
c/src/libchip/ide/ata_internal.h
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* ata_internal.h
|
||||
*
|
||||
* ATA RTEMS driver internal header file
|
||||
*
|
||||
* Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
|
||||
* Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
|
||||
* Alexandra Kossovsky <sasha@oktet.ru>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
#ifndef __ATA_INTERNAL_H__
|
||||
#define __ATA_INTERNAL_H__
|
||||
|
||||
#include <rtems.h>
|
||||
#include <sys/types.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rtems/blkdev.h>
|
||||
#include <rtems/diskdevs.h>
|
||||
|
||||
/*
|
||||
* Conversion from and to little-endian byte order. (no-op on i386/i486)
|
||||
*
|
||||
* Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian,
|
||||
* BE = big-endian, c: W = word (16 bits), L = longword (32 bits)
|
||||
*/
|
||||
#if (CPU_BIG_ENDIAN == TRUE)
|
||||
# define CF_LE_W(v) CPU_swap_u16(v)
|
||||
# define CF_LE_L(v) CPU_swap_u32(v)
|
||||
# define CT_LE_W(v) CPU_swap_u16(v)
|
||||
# define CT_LE_L(v) CPU_swap_u32(v)
|
||||
#else
|
||||
# define CF_LE_W(v) (v)
|
||||
# define CF_LE_L(v) (v)
|
||||
# define CT_LE_W(v) (v)
|
||||
# define CT_LE_L(v) (v)
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define ATA_UNDEFINED_VALUE (-1)
|
||||
|
||||
/* Sector size for all ATA devices */
|
||||
#define ATA_SECTOR_SIZE 512
|
||||
|
||||
|
||||
#define ATA_MAX_CMD_REG_OFFSET 8
|
||||
|
||||
/* ATA modes */
|
||||
#define ATA_MODES_PIO3 0x001
|
||||
#define ATA_MODES_PIO4 0x002
|
||||
|
||||
#define ATA_MODES_PIO 0x003
|
||||
|
||||
#define ATA_MODES_DMA0 0x004
|
||||
#define ATA_MODES_DMA1 0x008
|
||||
#define ATA_MODES_DMA2 0x010
|
||||
|
||||
#define ATA_MODES_UDMA0 0x020
|
||||
#define ATA_MODES_UDMA1 0x040
|
||||
#define ATA_MODES_UDMA2 0x080
|
||||
#define ATA_MODES_UDMA3 0x100
|
||||
#define ATA_MODES_UDMA4 0x200
|
||||
#define ATA_MODES_UDMA5 0x400
|
||||
|
||||
#define ATA_MODES_UDMA 0x7e0
|
||||
#define ATA_MODES_DMA 0x7fc
|
||||
|
||||
|
||||
/* ATA Commands */
|
||||
|
||||
/* Types of ATA commands */
|
||||
#define ATA_COMMAND_TYPE_NON_DATA 0
|
||||
#define ATA_COMMAND_TYPE_PIO_IN 1
|
||||
#define ATA_COMMAND_TYPE_PIO_OUT 2
|
||||
#define ATA_COMMAND_TYPE_DMA 3
|
||||
|
||||
/* ATA commands opcodes */
|
||||
/*
|
||||
* Commands present in both ATA-2 and ATA-4 specs.
|
||||
* Some commands have two values in ATA-2,
|
||||
* in such case value from ATA-4 used.
|
||||
* Some commands have slightly different names in these specifications,
|
||||
* so names from ATA-4 are used.
|
||||
*/
|
||||
#define ATA_COMMAND_NOP 0x00
|
||||
#define ATA_COMMAND_READ_SECTORS 0x20
|
||||
#define ATA_COMMAND_WRITE_SECTORS 0x30
|
||||
#define ATA_COMMAND_READ_VERIFY_SECTORS 0x40
|
||||
#define ATA_COMMAND_SEEK 0x70 /* or 0x7. */
|
||||
#define ATA_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC 0x90
|
||||
#define ATA_COMMAND_INITIALIZE_DEVICE_PARAMETERS 0x91
|
||||
#define ATA_COMMAND_DOWNLOAD_MICROCODE 0x92
|
||||
#define ATA_COMMAND_READ_MULTIPLE 0xc4
|
||||
#define ATA_COMMAND_WRITE_MULTIPLE 0xc5
|
||||
#define ATA_COMMAND_SET_MULTIPLE_MODE 0xc6
|
||||
#define ATA_COMMAND_READ_DMA 0xc8
|
||||
#define ATA_COMMAND_WRITE_DMA 0xca
|
||||
#define ATA_COMMAND_STANDBY_IMMEDIATE 0xe0 /* or 0x94 */
|
||||
#define ATA_COMMAND_IDLE_IMMEDIATE 0xe1 /* or 0x95 */
|
||||
#define ATA_COMMAND_STANDBY 0xe2 /* or 0x96 */
|
||||
#define ATA_COMMAND_IDLE 0xe3 /* or 0x97 */
|
||||
#define ATA_COMMAND_READ_BUFFER 0xe4
|
||||
#define ATA_COMMAND_CHECK_POWER_MODE 0xe5 /* or 0x98 in ATA-2 */
|
||||
#define ATA_COMMAND_SLEEP 0xe6 /* or 0x99 */
|
||||
#define ATA_COMMAND_WRITE_BUFFER 0xe8
|
||||
#define ATA_COMMAND_IDENTIFY_DEVICE 0xec
|
||||
#define ATA_COMMAND_SET_FEATURES 0xef
|
||||
|
||||
/* Commands present in both ATA-2 and ATA-4 specs: removable media */
|
||||
#define ATA_COMMAND_MEDIA_LOCK 0xde
|
||||
#define ATA_COMMAND_MEDIA_UNLOCK 0xdf
|
||||
#define ATA_COMMAND_MEDIA_EJECT 0xed
|
||||
|
||||
|
||||
/* Commands present in ATA-2, but not in ATA-4 (not used) */
|
||||
#define ATA_COMMAND_RECALIBRATE 0x10 /* or 0x1. */
|
||||
#define ATA_COMMAND_READ_SECTOR_NON_RETRY 0x21
|
||||
#define ATA_COMMAND_READ_LONG_RETRY 0x22
|
||||
#define ATA_COMMAND_READ_LONG_NON_RETRY 0x23
|
||||
#define ATA_COMMAND_WRITE_SECTOR_NON_RETRY 0x31
|
||||
#define ATA_COMMAND_WRITE_LONG_RETRY 0x32
|
||||
#define ATA_COMMAND_WRITE_LONG_NON_RETRY 0x33
|
||||
#define ATA_COMMAND_WRITE_VERIFY 0x3c
|
||||
#define ATA_COMMAND_READ_VERIFY_SECTOR_NON_RETRY 0x41
|
||||
#define ATA_COMMAND_FORMAT_TRACK 0x50
|
||||
#define ATA_COMMAND_READ_DMA_NON_RETRY 0xc9
|
||||
#define ATA_COMMAND_WRITE_DMA_NON_RETRY 0xcb
|
||||
#define ATA_COMMAND_ACKNOWLEGE_MEDIA_CHANGE 0xdb
|
||||
#define ATA_COMMAND_BOOT_POST_BOOT 0xdc
|
||||
#define ATA_COMMAND_BOOT_PRE_BOOT 0xdd
|
||||
#define ATA_COMMAND_WRITE_SAME 0xe9
|
||||
|
||||
/* Commands from ATA-4 specification: CFA feature set */
|
||||
#define ATA_COMMAND_CFA_REQUEST_EXTENDED_ERROR_CODE 0x03
|
||||
#define ATA_COMMAND_CFA_WRITE_SECTORS_WITHOUT_ERASE 0x38
|
||||
#define ATA_COMMAND_CFA_TRANSLATE_SECTOR 0x87
|
||||
#define ATA_COMMAND_CFA_ERASE_SECTORS 0xc0
|
||||
#define ATA_COMMAND_CFA_WRITE_MULTIPLE_WITHOUT_ERASE 0xcd
|
||||
|
||||
/* Commands from ATA-4 specification: commands to use with PACKET command */
|
||||
#define ATA_COMMAND_DEVICE_RESET 0x08
|
||||
#define ATA_COMMAND_PACKET 0xa0
|
||||
#define ATA_COMMAND_IDENTIFY_PACKET_DEVICE 0xa1
|
||||
#define ATA_COMMAND_SERVICE 0xa2
|
||||
|
||||
/* Commands from ATA-4 specification: SECURITY commands */
|
||||
#define ATA_COMMAND_SECURITY_SET_PASSWORD 0xf1
|
||||
#define ATA_COMMAND_SECURITY_UNLOCK 0xf2
|
||||
#define ATA_COMMAND_SECURITY_ERASE_PREPARE 0xf3
|
||||
#define ATA_COMMAND_SECURITY_ERASE_UNIT 0xf4
|
||||
#define ATA_COMMAND_SECURITY_FREEZE_LOCK 0xf5
|
||||
#define ATA_COMMAND_SECURITY_DISABLE_PASSWORD 0xf6
|
||||
|
||||
/* Commands from ATA-4 specification: other commands */
|
||||
#define ATA_COMMAND_SMART 0xb0
|
||||
#define ATA_COMMAND_READ_DMA_QUEUED 0xc7
|
||||
#define ATA_COMMAND_WRITE_DMA_QUEUED 0xcc
|
||||
#define ATA_COMMAND_GET_MEDIA_STATUS 0xda
|
||||
#define ATA_COMMAND_FLUSH_CACHE 0xe7
|
||||
#define ATA_COMMAND_READ_NATIVE_MAX_ADDRESS 0xf8
|
||||
#define ATA_COMMAND_SET_MAX_ADDRESS 0xf9
|
||||
|
||||
#define ATA_REGISTERS_VALUE(reg) (1 << (reg))
|
||||
|
||||
/* ATA IDENTIFY DEVICE command words and bits */
|
||||
#define ATA_IDENT_WORD_RW_MULT 47
|
||||
#define ATA_IDENT_WORD_CAPABILITIES 49
|
||||
#define ATA_IDENT_WORD_FIELD_VALIDITY 53
|
||||
#define ATA_IDENT_WORD_NUM_OF_CURR_LOG_CLNDS 54
|
||||
#define ATA_IDENT_WORD_NUM_OF_CURR_LOG_HEADS 55
|
||||
#define ATA_IDENT_WORD_NUM_OF_CURR_LOG_SECS 56
|
||||
#define ATA_IDENT_WORD_MULT_SECS 59
|
||||
#define ATA_IDENT_WORD_NUM_OF_USR_SECS0 60
|
||||
#define ATA_IDENT_WORD_NUM_OF_USR_SECS1 61
|
||||
#define ATA_IDENT_WORD_PIO_SPPRTD 64
|
||||
|
||||
#define ATA_IDENT_BIT_VALID 0x02
|
||||
|
||||
/*
|
||||
* It is OR for all ATA_REGISTERS_VALUE(reg), where reg is neccessary
|
||||
* for setting block position
|
||||
*/
|
||||
#define ATA_REGISTERS_POSITION 0xfc
|
||||
|
||||
#define ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE 64
|
||||
|
||||
#define ATA_MAX_RTEMS_INT_VEC_NUMBER 255
|
||||
|
||||
#define ATA_MAX_NAME_LENGTH 10
|
||||
|
||||
/* diagnostic codes */
|
||||
#define ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT 0x01
|
||||
#define ATA_DEV0_PASSED_DEV1_FAILED 0x81
|
||||
#define ATA_DEV1_PASSED_DEV0_FAILED 0x80
|
||||
|
||||
/*
|
||||
* Obtain ata device parameters by controller minor number and device number
|
||||
*/
|
||||
#define ATA_DEV_INFO(controller_minor, dev) \
|
||||
ata_ide_ctrls[controller_minor].device[dev]
|
||||
|
||||
/* ATA RTEMS driver internal data stuctures */
|
||||
|
||||
/* Command block registers */
|
||||
typedef struct ata_registers_s {
|
||||
unsigned16 regs[8]; /* command block registers */
|
||||
unsigned16 to_read; /* mask: which ata registers should be read */
|
||||
unsigned16 to_write; /* mask: which ata registers should be written */
|
||||
} ata_registers_t;
|
||||
|
||||
/* ATA request */
|
||||
typedef struct ata_req_s {
|
||||
Chain_Node link; /* link in requests chain */
|
||||
char type; /* request type */
|
||||
ata_registers_t regs; /* ATA command */
|
||||
rtems_unsigned32 cnt; /* Number of sectors to be exchanged */
|
||||
rtems_unsigned32 cbuf; /* number of current buffer from breq in use */
|
||||
rtems_unsigned32 pos; /* current position in 'cbuf' */
|
||||
blkdev_request *breq; /* blkdev_request which corresponds to the
|
||||
* ata request
|
||||
*/
|
||||
rtems_id sema; /* semaphore which is used if synchronous
|
||||
* processing of the ata request is required
|
||||
*/
|
||||
rtems_status_code status; /* status of ata request processing */
|
||||
int error; /* device error code */
|
||||
} ata_req_t;
|
||||
|
||||
/* call callback provided by block device request if it is defined */
|
||||
#define ATA_EXEC_CALLBACK(areq, status, error) \
|
||||
do {\
|
||||
if (((areq)->breq != NULL) && ((areq)->breq->req_done != NULL)) \
|
||||
(areq)->breq->req_done((areq)->breq->done_arg, status, error); \
|
||||
} while (0)
|
||||
|
||||
/* ATA RTEMS driver events types */
|
||||
typedef enum ata_msg_type_s {
|
||||
ATA_MSG_GEN_EVT = 1, /* general event */
|
||||
ATA_MSG_SUCCESS_EVT, /* success event */
|
||||
ATA_MSG_ERROR_EVT, /* error event */
|
||||
ATA_MSG_PROCESS_NEXT_EVT /* process next request event */
|
||||
} ata_msg_type_t;
|
||||
|
||||
/* ATA RTEMS driver message */
|
||||
typedef struct ata_queue_msg_s {
|
||||
ata_msg_type_t type; /* message type */
|
||||
rtems_device_minor_number ctrl_minor; /* IDE controller minor number */
|
||||
int error; /* error code */
|
||||
} ata_queue_msg_t;
|
||||
|
||||
/* macros for messages processing */
|
||||
#define ATA_FILL_MSG(msg, evt_type, ctrl, err)\
|
||||
do {\
|
||||
msg.type = evt_type;\
|
||||
msg.ctrl_minor = ctrl;\
|
||||
msg.error = err;\
|
||||
} while (0)
|
||||
|
||||
#define ATA_SEND_EVT(msg, type, ctrl, err)\
|
||||
do {\
|
||||
rtems_status_code rc;\
|
||||
ATA_FILL_MSG(msg, type, ctrl, err);\
|
||||
rc = rtems_message_queue_send(ata_queue_id, &msg,\
|
||||
sizeof(ata_queue_msg_t));\
|
||||
if (rc != RTEMS_SUCCESSFUL)\
|
||||
rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);\
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Array of such structures is indexed by interrupt vecotrs and used for
|
||||
* mapping of IDE controllers and interrupt vectors
|
||||
*/
|
||||
typedef struct ata_int_st_s {
|
||||
Chain_Node link;
|
||||
rtems_device_minor_number ctrl_minor;
|
||||
} ata_int_st_t;
|
||||
|
||||
/*
|
||||
* Mapping of rtems ATA devices to the following pairs:
|
||||
* (IDE controller number served the device, device number on the controller)
|
||||
*/
|
||||
typedef struct ata_ide_dev_s {
|
||||
int ctrl_minor;/* minor number of IDE controller served rtems ATA device */
|
||||
int device; /* device number on IDE controller (0 or 1) */
|
||||
} ata_ide_dev_t;
|
||||
|
||||
/*
|
||||
* ATA device description
|
||||
*/
|
||||
typedef struct ata_dev_s {
|
||||
signed8 present; /* 1 -- present, 0 -- not present, */
|
||||
/* -1 -- non-initialized */
|
||||
unsigned16 cylinders;
|
||||
unsigned16 heads;
|
||||
unsigned16 sectors;
|
||||
unsigned32 lba_sectors; /* for small disk */
|
||||
/* == cylinders * heads * sectors */
|
||||
|
||||
unsigned8 lba_avaible; /* 0 - CHS mode, 1 - LBA mode */
|
||||
|
||||
unsigned8 max_multiple; /* 0 if READ/WRITE MULTIPLE is unsupported */
|
||||
unsigned8 current_multiple;
|
||||
|
||||
unsigned8 modes_avaible; /* OR of values for this modes */
|
||||
unsigned8 mode_active;
|
||||
} ata_dev_t;
|
||||
|
||||
/*
|
||||
* This structure describes controller state, devices configuration on the
|
||||
* controller and chain of ATA requests to the controller. Array of such
|
||||
* structures is indexed by controller minor number
|
||||
*/
|
||||
typedef struct ata_ide_ctrl_s {
|
||||
rtems_boolean present; /* controller state */
|
||||
ata_dev_t device[2]; /* ata diveces description */
|
||||
Chain_Control reqs; /* requests chain */
|
||||
} ata_ide_ctrl_t;
|
||||
|
||||
#endif /* __ATA_INTERNAL_H__ */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user