#ifndef __ATA_TYPES_H__
#define __ATA_TYPES_H__
#include <iovec.h>
#include <lendian_bitfield.h>
union ata_task_file {
struct {
uint8 features;
uint8 sector_count;
uint8 sector_number;
uint8 cylinder_0_7;
uint8 cylinder_8_15;
B_LBITFIELD8_3(
head : 4,
device : 1,
mode : 3
);
uint8 command;
} chs;
struct {
uint8 features;
uint8 sector_count;
uint8 lba_0_7;
uint8 lba_8_15;
uint8 lba_16_23;
B_LBITFIELD8_3(
lba_24_27 : 4,
device : 1,
mode : 3
);
uint8 command;
} lba;
struct {
B_LBITFIELD8_3(
dma : 1,
ovl : 1,
_0_res2 : 6
);
B_LBITFIELD8_2(
_1_res0 : 3,
tag : 5
);
uint8 _2_res;
uint8 byte_count_0_7;
uint8 byte_count_8_15;
B_LBITFIELD8_6(
lun : 3,
_5_res3 : 1,
device : 1,
_5_one5 : 1,
_5_res6 : 1,
_5_one7 : 1
);
uint8 command;
} packet;
struct {
B_LBITFIELD8_5(
ili : 1,
eom : 1,
abrt : 1,
_0_res3 : 1,
sense_key : 4
);
B_LBITFIELD8_4(
cmd_or_data : 1,
input_or_output : 1,
release : 1,
tag : 5
);
uint8 _2_res;
uint8 byte_count_0_7;
uint8 byte_count_8_15;
B_LBITFIELD8_5(
_4_res0 : 4,
device : 1,
_4_obs5 : 1,
_4_res6 : 1,
_4_obs7 : 1
);
B_LBITFIELD8_7(
chk : 1,
_7_res1 : 2,
drq : 1,
serv : 1,
dmrd : 1,
drdy : 1,
bsy : 1
);
} packet_res;
struct {
uint8 sector_count;
B_LBITFIELD8_4(
cmd_or_data : 1,
input_or_output : 1,
release : 1,
tag : 5
);
uint8 lba_0_7;
uint8 lba_8_15;
uint8 lba_16_23;
B_LBITFIELD8_3(
lba_24_27 : 4,
device : 1,
mode : 3
);
uint8 command;
} queued;
struct {
uint8 features;
uint8 sector_count_0_7;
uint8 lba_0_7;
uint8 lba_8_15;
uint8 lba_16_23;
B_LBITFIELD8_3(
_5low_res0 : 4,
device : 1,
mode : 3
);
uint8 command;
uint8 _0high_res;
uint8 sector_count_8_15;
uint8 lba_24_31;
uint8 lba_32_39;
uint8 lba_40_47;
} lba48;
struct {
uint8 sector_count_0_7;
B_LBITFIELD8_4(
cmd_or_data : 1,
input_or_output : 1,
release : 1,
tag : 5
);
uint8 lba_0_7;
uint8 lba_8_15;
uint8 lba_16_23;
B_LBITFIELD8_3(
_5low_res0 : 4,
device : 1,
mode : 3
);
uint8 command;
uint8 sector_count_8_15;
uint8 _1high_res;
uint8 lba_24_31;
uint8 lba_32_39;
uint8 lba_40_47;
} queued48;
struct {
uint8 r[7+5];
} raw;
struct {
uint8 features;
uint8 sector_count;
uint8 sector_number;
uint8 cylinder_low;
uint8 cylinder_high;
uint8 device_head;
uint8 command;
} write;
struct {
uint8 error;
uint8 sector_count;
uint8 sector_number;
uint8 cylinder_low;
uint8 cylinder_high;
uint8 device_head;
uint8 status;
} read;
};
typedef union ata_task_file ata_task_file;
enum {
ATA_MODE_CHS = 5,
ATA_MODE_LBA = 7
};
enum {
ATA_MASK_FEATURES = 0x01,
ATA_MASK_SECTOR_COUNT = 0x02,
ATA_MASK_SECTOR_NUMBER = 0x04,
ATA_MASK_CYLINDER_LOW = 0x08,
ATA_MASK_CYLINDER_HIGH = 0x10,
ATA_MASK_LBA_LOW = 0x04,
ATA_MASK_LBA_MID = 0x08,
ATA_MASK_LBA_HIGH = 0x10,
ATA_MASK_BYTE_COUNT = 0x18,
ATA_MASK_ERROR = 0x01,
ATA_MASK_INTERRUPT_REASON = 0x02,
ATA_MASK_DEVICE_HEAD = 0x20,
ATA_MASK_COMMAND = 0x40,
ATA_MASK_STATUS = 0x40,
ATA_MASK_FEATURES_48 = 0x80 | ATA_MASK_FEATURES,
ATA_MASK_SECTOR_COUNT_48 = 0x100 | ATA_MASK_SECTOR_COUNT,
ATA_MASK_LBA_LOW_48 = 0x200 | ATA_MASK_LBA_LOW,
ATA_MASK_LBA_MID_48 = 0x400 | ATA_MASK_LBA_MID,
ATA_MASK_LBA_HIGH_48 = 0x800 | ATA_MASK_LBA_HIGH,
ATA_MASK_HOB = 0xf80
};
enum {
ATA_STATUS_ERROR = 0x01,
ATA_STATUS_INDEX = 0x02,
ATA_STATUS_CORR = 0x04,
ATA_STATUS_DATA_REQUEST = 0x08,
ATA_STATUS_DSC = 0x10,
ATA_STATUS_SERVICE = 0x10,
ATA_STATUS_DWF = 0x20,
ATA_STATUS_DMA = 0x20,
ATA_STATUS_DMA_READY = 0x20,
ATA_STATUS_DEVICE_FAULT = 0x20,
ATA_STATUS_DEVICE_READY = 0x40,
ATA_STATUS_BUSY = 0x80
};
enum {
ATA_DEVICE_CONTROL_DISABLE_INTS = 0x02,
ATA_DEVICE_CONTROL_SOFT_RESET = 0x04,
ATA_DEVICE_CONTROL_BIT3 = 0x08,
ATA_DEVICE_CONTROL_HIGH_ORDER_BYTE = 0x80
};
enum {
ATA_ERROR_ABORTED = 0x04,
ATA_ERROR_INTERFACE_CRC = 0x80,
ATA_ERROR_UNCORRECTABLE = 0x40,
ATA_ERROR_WRITE_PROTECTED = 0x40,
ATA_ERROR_MEDIUM_CHANGED = 0x20,
ATA_ERROR_INVALID_ADDRESS = 0x10,
ATA_ERROR_MEDIA_CHANGE_REQUESTED = 0x08,
ATA_ERROR_NO_MEDIA = 0x02,
ATA_ERROR_ALL = 0xfe
};
typedef struct ata_channel_info *ata_channel_cookie;
#endif