#ifndef _DEV_ATA_ATAREG_H_
#define _DEV_ATA_ATAREG_H_
#define WDCS_BSY 0x80
#define WDCS_DRDY 0x40
#define WDCS_DWF 0x20
#define WDCS_DSC 0x10
#define WDCS_DRQ 0x08
#define WDCS_CORR 0x04
#define WDCS_IDX 0x02
#define WDCS_ERR 0x01
#define WDCS_BITS \
"\020\010bsy\007drdy\006dwf\005dsc\004drq\003corr\002idx\001err"
#define WDCE_BBK 0x80
#define WDCE_CRC 0x80
#define WDCE_UNC 0x40
#define WDCE_MC 0x20
#define WDCE_IDNF 0x10
#define WDCE_MCR 0x08
#define WDCE_ABRT 0x04
#define WDCE_TK0NF 0x02
#define WDCE_AMNF 0x01
#define WDCC_NOP 0x00
#define ATA_DATA_SET_MANAGEMENT 0x06
#define WDCC_RECAL 0x10
#define WDCC_READ 0x20
#define WDCC_READ_LOG_EXT 0x2f
#define WDCC_LOG_PAGE_NCQ 0x10
#define WDCC_LOG_NQ __BIT(7)
#define WDCC_WRITE 0x30
#define WDCC__LONG 0x02
#define WDCC__NORETRY 0x01
#define WDCC_READ_LOG_DMA_EXT 0x47
#define WDCC_FORMAT 0x50
#define WDCC_DIAGNOSE 0x90
#define WDCC_IDP 0x91
#define WDCC_SMART 0xb0
#define WDCC_READMULTI 0xc4
#define WDCC_WRITEMULTI 0xc5
#define WDCC_SETMULTI 0xc6
#define WDCC_READDMA 0xc8
#define WDCC_WRITEDMA 0xca
#define WDCC_ACKMC 0xdb
#define WDCC_LOCK 0xde
#define WDCC_UNLOCK 0xdf
#define WDCC_FLUSHCACHE 0xe7
#define WDCC_FLUSHCACHE_EXT 0xea
#define WDCC_IDENTIFY 0xec
#define SET_FEATURES 0xef
#define WDCC_IDLE 0xe3
#define WDCC_IDLE_IMMED 0xe1
#define WDCC_SLEEP 0xe6
#define WDCC_STANDBY 0xe2
#define WDCC_STANDBY_IMMED 0xe0
#define WDCC_CHECK_PWR 0xe5
#define WDCC_SECURITY_SET_PASSWORD 0xf1
#define WDCC_SECURITY_UNLOCK 0xf2
#define WDCC_SECURITY_ERASE_PREPARE 0xf3
#define WDCC_SECURITY_ERASE_UNIT 0xf4
#define WDCC_SECURITY_FREEZE 0xf5
#define WDCC_SECURITY_DISABLE_PASSWORD 0xf6
#define WDCC_READ_EXT 0x24
#define WDCC_WRITE_EXT 0x34
#define WDCC_READMULTI_EXT 0x29
#define WDCC_WRITEMULTI_EXT 0x39
#define WDCC_READDMA_EXT 0x25
#define WDCC_WRITEDMA_EXT 0x35
#define WDCC_WRITEDMA_FUA_EXT 0x3d
#if defined(_KERNEL) || defined(_STANDALONE)
#include <dev/ata/ataconf.h>
static __inline int
atacmd_to48(int cmd32)
{
switch (cmd32) {
case WDCC_READ:
return WDCC_READ_EXT;
case WDCC_WRITE:
return WDCC_WRITE_EXT;
case WDCC_READMULTI:
return WDCC_READMULTI_EXT;
case WDCC_WRITEMULTI:
return WDCC_WRITEMULTI_EXT;
#if NATA_DMA
case WDCC_READDMA:
return WDCC_READDMA_EXT;
case WDCC_WRITEDMA:
return WDCC_WRITEDMA_EXT;
#endif
default:
panic("atacmd_to48: illegal 32-bit command: %d", cmd32);
}
}
#endif
#define WDCC_READ_FPDMA_QUEUED 0x60
#define WDCC_WRITE_FPDMA_QUEUED 0x61
#define WDSF_8BIT_PIO_EN 0x01
#define WDSF_WRITE_CACHE_EN 0x02
#define WDSF_SET_MODE 0x03
#define WDSF_REASSIGN_EN 0x04
#define WDSF_APM_EN 0x05
#define WDSF_PUIS_EN 0x06
#define WDSF_PUIS_SPIN_UP 0x07
#define WDSF_SATA_EN 0x10
#define WDSF_RETRY_DS 0x33
#define WDSF_AAM_EN 0x42
#define WDSF_SET_CACHE_SGMT 0x54
#define WDSF_READAHEAD_DS 0x55
#define WDSF_POD_DS 0x66
#define WDSF_ECC_DS 0x77
#define WDSF_WRITE_CACHE_DS 0x82
#define WDSF_REASSIGN_DS 0x84
#define WDSF_APM_DS 0x85
#define WDSF_PUIS_DS 0x86
#define WDSF_ECC_EN 0x88
#define WDSF_SATA_DS 0x90
#define WDSF_RETRY_EN 0x99
#define WDSF_SET_CURRENT 0x9a
#define WDSF_READAHEAD_EN 0xaa
#define WDSF_PREFETCH_SET 0xab
#define WDSF_AAM_DS 0xc2
#define WDSF_POD_EN 0xcc
#define WDSF_SATA_NONZERO_OFFSETS 0x01
#define WDSF_SATA_DMA_SETUP_AUTO 0x02
#define WDSF_SATA_DRIVE_PWR_MGMT 0x03
#define WDSF_SATA_IN_ORDER_DATA 0x04
#define WDSF_SATA_ASYNC_NOTIFY 0x05
#define WDSF_SATA_SW_STTNGS_PRS 0x06
#define WDSM_RD_DATA 0xd0
#define WDSM_RD_THRESHOLDS 0xd1
#define WDSM_ATTR_AUTOSAVE_EN 0xd2
#define WDSM_SAVE_ATTR 0xd3
#define WDSM_EXEC_OFFL_IMM 0xd4
#define WDSM_RD_LOG 0xd5
#define WDSM_ENABLE_OPS 0xd8
#define WDSM_DISABLE_OPS 0xd9
#define WDSM_STATUS 0xda
#define WDSMART_CYL 0xc24f
#define WDSC_PRIO_HIGH __BIT(15)
#define WDSC_PRIO_ISOCHRONOUS __BIT(14)
#define WDSC_PRIO_NORMAL 0x0000
#define WDSD_IBM 0xa0
#define WDSD_CHS 0x00
#define WDSD_LBA 0x40
#define WDSD_FUA 0x80
#define ATAPI_CHECK_POWER_MODE 0xe5
#define ATAPI_EXEC_DRIVE_DIAGS 0x90
#define ATAPI_IDLE_IMMEDIATE 0xe1
#define ATAPI_NOP 0x00
#define ATAPI_PKT_CMD 0xa0
#define ATAPI_IDENTIFY_DEVICE 0xa1
#define ATAPI_SOFT_RESET 0x08
#define ATAPI_SLEEP 0xe6
#define ATAPI_STANDBY_IMMEDIATE 0xe0
#define ATAPI_PKT_CMD_FTRE_DMA 0x01
#define ATAPI_PKT_CMD_FTRE_OVL 0x02
#define WDCI_CMD 0x01
#define WDCI_IN 0x02
#define WDCI_RELEASE 0x04
#define PHASE_CMDOUT (WDCS_DRQ | WDCI_CMD)
#define PHASE_DATAIN (WDCS_DRQ | WDCI_IN)
#define PHASE_DATAOUT (WDCS_DRQ)
#define PHASE_COMPLETED (WDCI_IN | WDCI_CMD)
#define PHASE_ABORTED (0)
struct ataparams {
uint16_t atap_config;
#define WDC_CFG_CFA_MAGIC 0x848a
#define WDC_CFG_ATAPI 0x8000
#define ATA_CFG_REMOVABLE 0x0080
#define ATA_CFG_FIXED 0x0040
#define ATAPI_CFG_TYPE_MASK 0x1f00
#define ATAPI_CFG_TYPE(x) (((x) & ATAPI_CFG_TYPE_MASK) >> 8)
#define ATAPI_CFG_REMOV 0x0080
#define ATAPI_CFG_DRQ_MASK 0x0060
#define ATAPI_CFG_STD_DRQ 0x0000
#define ATAPI_CFG_IRQ_DRQ 0x0020
#define ATAPI_CFG_ACCEL_DRQ 0x0040
#define ATAPI_CFG_CMD_MASK 0x0003
#define ATAPI_CFG_CMD_12 0x0000
#define ATAPI_CFG_CMD_16 0x0001
uint16_t atap_cylinders;
uint16_t __reserved1;
uint16_t atap_heads;
uint16_t __retired1[2];
uint16_t atap_sectors;
uint16_t __retired2[3];
uint8_t atap_serial[20];
uint16_t __retired3[2];
uint16_t __obsolete1;
uint8_t atap_revision[8];
uint8_t atap_model[40];
uint16_t atap_multi;
uint16_t __reserved2;
uint16_t atap_capabilities1;
#define WDC_CAP_IORDY 0x0800
#define WDC_CAP_IORDY_DSBL 0x0400
#define WDC_CAP_LBA 0x0200
#define WDC_CAP_DMA 0x0100
#define ATA_CAP_STBY 0x2000
#define ATAPI_CAP_INTERL_DMA 0x8000
#define ATAPI_CAP_CMD_QUEUE 0x4000
#define ATAPI_CAP_OVERLP 0X2000
#define ATAPI_CAP_ATA_RST 0x1000
uint16_t atap_capabilities2;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t __junk2;
uint8_t atap_oldpiotiming;
uint8_t __junk3;
uint8_t atap_olddmatiming;
#else
uint8_t atap_oldpiotiming;
uint8_t __junk2;
uint8_t atap_olddmatiming;
uint8_t __junk3;
#endif
uint16_t atap_extensions;
#define WDC_EXT_UDMA_MODES 0x0004
#define WDC_EXT_MODES 0x0002
#define WDC_EXT_GEOM 0x0001
uint16_t atap_curcylinders;
uint16_t atap_curheads;
uint16_t atap_cursectors;
uint16_t atap_curcapacity[2];
uint16_t atap_curmulti;
#define WDC_MULTI_VALID 0x0100
#define WDC_MULTI_MASK 0x00ff
uint16_t atap_capacity[2];
uint16_t __retired4;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t atap_dmamode_supp;
uint8_t atap_dmamode_act;
uint8_t atap_piomode_supp;
uint8_t __junk4;
#else
uint8_t atap_dmamode_act;
uint8_t atap_dmamode_supp;
uint8_t __junk4;
uint8_t atap_piomode_supp;
#endif
uint16_t atap_dmatiming_mimi;
uint16_t atap_dmatiming_recom;
uint16_t atap_piotiming;
uint16_t atap_piotiming_iordy;
uint16_t __reserved3[2];
uint16_t atap_pkt_br;
uint16_t atap_pkt_bsyclr;
uint16_t __reserved4[2];
uint16_t atap_queuedepth;
#define WDC_QUEUE_DEPTH_MASK 0x1F
uint16_t atap_sata_caps;
#define SATA_SIGNAL_GEN1 0x02
#define SATA_SIGNAL_GEN2 0x04
#define SATA_SIGNAL_GEN3 0x08
#define SATA_NATIVE_CMDQ 0x0100
#define SATA_HOST_PWR_MGMT 0x0200
#define SATA_PHY_EVNT_CNT 0x0400
#define SATA_UNLOAD_W_NCQ 0x0800
#define SATA_NCQ_PRIO 0x1000
uint16_t atap_sata_reserved;
uint16_t atap_sata_features_supp;
#define SATA_NONZERO_OFFSETS 0x02
#define SATA_DMA_SETUP_AUTO 0x04
#define SATA_DRIVE_PWR_MGMT 0x08
#define SATA_IN_ORDER_DATA 0x10
#define SATA_SW_STTNGS_PRS 0x40
uint16_t atap_sata_features_en;
uint16_t atap_ata_major;
#define WDC_VER_ATA1 0x0002
#define WDC_VER_ATA2 0x0004
#define WDC_VER_ATA3 0x0008
#define WDC_VER_ATA4 0x0010
#define WDC_VER_ATA5 0x0020
#define WDC_VER_ATA6 0x0040
#define WDC_VER_ATA7 0x0080
#define WDC_VER_ATA8 0x0100
uint16_t atap_ata_minor;
uint16_t atap_cmd_set1;
#define WDC_CMD1_NOP 0x4000
#define WDC_CMD1_RB 0x2000
#define WDC_CMD1_WB 0x1000
#define WDC_CMD1_HPA 0x0400
#define WDC_CMD1_DVRST 0x0200
#define WDC_CMD1_SRV 0x0100
#define WDC_CMD1_RLSE 0x0080
#define WDC_CMD1_AHEAD 0x0040
#define WDC_CMD1_CACHE 0x0020
#define WDC_CMD1_PKT 0x0010
#define WDC_CMD1_PM 0x0008
#define WDC_CMD1_REMOV 0x0004
#define WDC_CMD1_SEC 0x0002
#define WDC_CMD1_SMART 0x0001
uint16_t atap_cmd_set2;
#define ATA_CMD2_FCE 0x2000
#define WDC_CMD2_FC 0x1000
#define WDC_CMD2_DCO 0x0800
#define ATA_CMD2_LBA48 0x0400
#define WDC_CMD2_AAM 0x0200
#define WDC_CMD2_SM 0x0100
#define WDC_CMD2_SFREQ 0x0040
#define WDC_CMD2_PUIS 0x0020
#define WDC_CMD2_RMSN 0x0010
#define ATA_CMD2_APM 0x0008
#define ATA_CMD2_CFA 0x0004
#define ATA_CMD2_RWQ 0x0002
#define WDC_CMD2_DM 0x0001
uint16_t atap_cmd_ext;
#define ATA_CMDE_TLCONT 0x1000
#define ATA_CMDE_TL 0x0800
#define ATA_CMDE_URGW 0x0400
#define ATA_CMDE_URGR 0x0200
#define ATA_CMDE_WWN 0x0100
#define ATA_CMDE_WQFE 0x0080
#define ATA_CMDE_WFE 0x0040
#define ATA_CMDE_GPL 0x0020
#define ATA_CMDE_STREAM 0x0010
#define ATA_CMDE_MCPTC 0x0008
#define ATA_CMDE_MS 0x0004
#define ATA_CMDE_SST 0x0002
#define ATA_CMDE_SEL 0x0001
uint16_t atap_cmd1_en;
uint16_t atap_cmd2_en;
uint16_t atap_cmd_def;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t atap_udmamode_supp;
uint8_t atap_udmamode_act;
#else
uint8_t atap_udmamode_act;
uint8_t atap_udmamode_supp;
#endif
uint16_t atap_seu_time;
uint16_t atap_eseu_time;
uint16_t atap_apm_val;
uint16_t __reserved5[8];
uint16_t atap_max_lba[4];
uint16_t __reserved6;
uint16_t max_dsm_blocks;
uint16_t atap_secsz;
#define ATA_SECSZ_VALID_MASK 0xc000
#define ATA_SECSZ_VALID 0x4000
#define ATA_SECSZ_LPS 0x2000
#define ATA_SECSZ_LLS 0x1000
#define ATA_SECSZ_LPS_SZMSK 0x000f
uint16_t atap_iso7779_isd;
uint16_t atap_wwn[4];
uint16_t __reserved7[5];
uint16_t atap_lls_secsz[2];
uint16_t __reserved8[8];
uint16_t atap_rmsn_supp;
#define WDC_RMSN_SUPP_MASK 0x0003
#define WDC_RMSN_SUPP 0x0001
uint16_t atap_sec_st;
#define WDC_SEC_LEV_MAX 0x0100
#define WDC_SEC_ESE_SUPP 0x0020
#define WDC_SEC_EXP 0x0010
#define WDC_SEC_FROZEN 0x0008
#define WDC_SEC_LOCKED 0x0004
#define WDC_SEC_EN 0x0002
#define WDC_SEC_SUPP 0x0001
uint16_t __reserved9[31];
uint16_t atap_cfa_power;
#define ATA_CFA_MAX_MASK 0x0fff
#define ATA_CFA_MODE1_DIS 0x1000
#define ATA_CFA_MODE1_REQ 0x2000
#define ATA_CFA_WORD160 0x8000
uint16_t __reserved10[8];
uint16_t support_dsm;
#define ATA_SUPPORT_DSM_TRIM 0x0001
uint16_t __reserved10a[6];
uint8_t atap_media_serial[60];
uint16_t __reserved11[3];
uint16_t atap_logical_align;
#define ATA_LA_VALID_MASK 0xc000
#define ATA_LA_VALID 0x4000
#define ATA_LA_MASK 0x3fff
uint16_t __reserved12[45];
uint16_t atap_integrity;
#define WDC_INTEGRITY_MAGIC_MASK 0x00ff
#define WDC_INTEGRITY_MAGIC 0x00a5
};
#define WDSM_ATTR_ADVISORY 1
#define WDSM_ATTR_COLLECTIVE 2
struct ata_smart_attr {
uint8_t id;
uint16_t flags;
uint8_t value;
uint8_t worst;
uint8_t raw[6];
uint8_t reserved;
} __packed;
struct ata_smart_attributes {
uint16_t data_structure_revision;
struct ata_smart_attr attributes[30];
uint8_t offline_data_collection_status;
uint8_t self_test_exec_status;
uint16_t total_time_to_complete_off_line;
uint8_t vendor_specific_366;
uint8_t offline_data_collection_capability;
uint16_t smart_capability;
uint8_t errorlog_capability;
uint8_t vendor_specific_371;
uint8_t short_test_completion_time;
uint8_t extend_test_completion_time;
uint8_t reserved_374_385[12];
uint8_t vendor_specific_386_509[125];
int8_t checksum;
} __packed;
struct ata_smart_thresh {
uint8_t id;
uint8_t value;
uint8_t reserved[10];
} __packed;
struct ata_smart_thresholds {
uint16_t data_structure_revision;
struct ata_smart_thresh thresholds[30];
uint8_t reserved[18];
uint8_t vendor_specific[131];
int8_t checksum;
} __packed;
struct ata_smart_selftest {
uint8_t number;
uint8_t status;
uint16_t time_stamp;
uint8_t failure_check_point;
uint32_t lba_first_error;
uint8_t vendor_specific[15];
} __packed;
struct ata_smart_selftestlog {
uint16_t data_structure_revision;
struct ata_smart_selftest log_entries[21];
uint8_t vendorspecific[2];
uint8_t mostrecenttest;
uint8_t reserved[2];
uint8_t checksum;
} __packed;
#endif