#ifndef _ATA_COMMON_H
#define _ATA_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/varargs.h>
#include <sys/scsi/scsi.h>
#include <sys/dktp/dadkio.h>
#include <sys/dktp/dadev.h>
#include <sys/dkio.h>
#include <sys/dktp/tgdk.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include "ghd.h"
#include "pciide.h"
#include "ata_cmd.h"
#include "ata_fsm.h"
#include "ata_debug.h"
#define ATA_DEV_NONE 0
#define ATA_DEV_DISK 1
#define ATA_DEV_ATAPI 2
#define MAX_28BIT_CAPACITY 0xfffffff
#define MAX_FWFILE_SIZE_ONECMD 0xffff
#define ATA_OPTIONS_DMA 0x01
#define ATAPRT(fmt) ghd_err fmt
#define AD_ATAPI 0x01
#define AD_DISK 0x02
#define AD_MUTEX_INIT 0x04
#define AD_NO_CDB_INTR 0x20
#define AD_1SECTOR 0x40
#define AD_INT13LBA 0x80
#define AD_NORVRT 0x100
#define AD_EXT48 0x200
#define AD_BLLBA48 0x400
#define ATAPIDRV(X) ((X)->ad_flags & AD_ATAPI)
#define ATA_MAXTARG 2
#define ATA_MAXLUN 16
#define ATA_DMA_NSEGS 17
#define ATA_BASE0 0x1f0
#define ATA_BASE1 0x170
#define AT_DATA 0x00
#define AT_ERROR 0x01
#define AT_FEATURE 0x01
#define AT_COUNT 0x02
#define AT_SECT 0x03
#define AT_LCYL 0x04
#define AT_HCYL 0x05
#define AT_DRVHD 0x06
#define AT_STATUS 0x07
#define AT_CMD 0x07
#define AT_ALTSTATUS 0x00
#define AT_DEVCTL 0x00
#define ATDC_NIEN 0x02
#define ATDC_SRST 0x04
#define ATDC_D3 0x08
#define ATDC_HOB 0x80
#define ATS_BSY 0x80
#define ATS_DRDY 0x40
#define ATS_DF 0x20
#define ATS_DSC 0x10
#define ATS_DRQ 0x08
#define ATS_CORR 0x04
#define ATS_IDX 0x02
#define ATS_ERR 0x01
#define ATE_BBK_ICRC 0x80
#define ATE_UNC 0x40
#define ATE_MC 0x20
#define ATE_IDNF 0x10
#define ATE_MCR 0x08
#define ATE_ABORT 0x04
#define ATE_TKONF 0x02
#define ATE_AMNF 0x01
#define ATE_NM 0x02
#define ATDH_LBA 0x40
#define ATDH_DRIVE0 0xa0
#define ATDH_DRIVE1 0xb0
#define ATF_ATAPI_DMA 0x01
#define ATF_XFRMOD_MDMA 0x20
#define ATF_XFRMOD_UDMA 0x40
#define ATACM_UDMA_SEL(id) (((id)->ai_ultradma >> 8) & 0x7f)
#define ATSF_SET_XFRMOD 0X03
#define ATSF_DIS_REVPOD 0x66
#define ATSF_ENA_REVPOD 0xcc
#define FC_WRITE_CACHE_ON 0x02
#define FC_WRITE_CACHE_OFF 0x82
#define IS_ATA_VERSION_SUPPORTED(idp, n) \
((idp->ai_majorversion != 0xffff) && \
(idp->ai_majorversion & (1<<n)))
#define IS_ATA_VERSION_GE(idp, n) \
((idp->ai_majorversion != 0xffff) && \
(idp->ai_majorversion != 0) && \
(idp->ai_majorversion >= (1<<n)))
#define IS_CDROM(dp) \
((dp->ad_flags & AD_ATAPI) && \
((dp->ad_id.ai_config >> 8) & DTYPE_MASK) == \
DTYPE_RODIRECT)
#define IS_WRITE_CACHE_SUPPORTED(x) \
((((x).ai_cmdset82) & 0x20) >> 5)
#define ATA_INTPROP(devi, pname, pval, plen) \
(ddi_prop_op(DDI_DEV_T_ANY, (devi), PROP_LEN_AND_VAL_BUF, \
DDI_PROP_DONTPASS, (pname), (caddr_t)(pval), (plen)))
#define ATA_LONGPROP(devi, pname, pval, plen) \
(ddi_getlongprop(DDI_DEV_T_ANY, (devi), DDI_PROP_DONTPASS, \
(pname), (caddr_t)(pval), (plen)))
#define CTL2DRV(cp, t, l) (cp->ac_drvp[t][l])
typedef struct ata_ctl {
dev_info_t *ac_dip;
uint_t ac_flags;
uint_t ac_timing_flags;
struct ata_drv *ac_drvp[ATA_MAXTARG][ATA_MAXLUN];
int ac_max_transfer;
uint_t ac_standby_time;
ccc_t ac_ccc;
struct ata_drv *ac_active_drvp;
struct ata_pkt *ac_active_pktp;
uchar_t ac_state;
scsi_hba_tran_t *ac_atapi_tran;
ddi_acc_handle_t ac_iohandle1;
caddr_t ac_ioaddr1;
ushort_t *ac_data;
uchar_t *ac_error;
uchar_t *ac_feature;
uchar_t *ac_count;
uchar_t *ac_sect;
uchar_t *ac_lcyl;
uchar_t *ac_hcyl;
uchar_t *ac_drvhd;
uchar_t *ac_status;
uchar_t *ac_cmd;
ddi_acc_handle_t ac_iohandle2;
caddr_t ac_ioaddr2;
uchar_t *ac_altstatus;
uchar_t *ac_devctl;
ddi_acc_handle_t ac_bmhandle;
caddr_t ac_bmaddr;
uchar_t ac_pciide;
uchar_t ac_pciide_bm;
caddr_t ac_sg_list;
paddr_t ac_sg_paddr;
ddi_acc_handle_t ac_sg_acc_handle;
ddi_dma_handle_t ac_sg_handle;
struct ata_pkt *ac_arq_pktp;
struct ata_pkt *ac_fault_pktp;
uchar_t ac_arq_cdb[6];
int ac_pm_support;
int ac_pm_level;
} ata_ctl_t;
#define AC_GHD_INIT 0x02
#define AC_ATAPI_INIT 0x04
#define AC_DISK_INIT 0x08
#define AC_ATTACHED 0x10
#define AC_SCSI_HBA_TRAN_ALLOC 0x1000
#define AC_SCSI_HBA_ATTACH 0x2000
#define AC_BMSTATREG_PIO_BROKEN 0x80000000
#define AC_BSY_WAIT 0x1
struct ata_id {
ushort_t ai_config;
ushort_t ai_fixcyls;
ushort_t ai_resv0;
ushort_t ai_heads;
ushort_t ai_trksiz;
ushort_t ai_secsiz;
ushort_t ai_sectors;
ushort_t ai_resv1[3];
char ai_drvser[20];
ushort_t ai_buftype;
ushort_t ai_bufsz;
ushort_t ai_ecc;
char ai_fw[8];
char ai_model[40];
ushort_t ai_mult1;
ushort_t ai_dwcap;
ushort_t ai_cap;
ushort_t ai_resv2;
ushort_t ai_piomode;
ushort_t ai_dmamode;
ushort_t ai_validinfo;
ushort_t ai_curcyls;
ushort_t ai_curheads;
ushort_t ai_cursectrk;
ushort_t ai_cursccp[2];
ushort_t ai_mult2;
ushort_t ai_addrsec[2];
ushort_t ai_sworddma;
ushort_t ai_dworddma;
ushort_t ai_advpiomode;
ushort_t ai_minmwdma;
ushort_t ai_recmwdma;
ushort_t ai_minpio;
ushort_t ai_minpioflow;
ushort_t ai_resv3[2];
ushort_t ai_resv4[4];
ushort_t ai_qdepth;
ushort_t ai_resv5[4];
ushort_t ai_majorversion;
ushort_t ai_minorversion;
ushort_t ai_cmdset82;
ushort_t ai_cmdset83;
ushort_t ai_cmdset84;
ushort_t ai_features85;
ushort_t ai_features86;
ushort_t ai_features87;
ushort_t ai_ultradma;
ushort_t ai_erasetime;
ushort_t ai_erasetimex;
ushort_t ai_padding1[9];
ushort_t ai_addrsecxt[4];
ushort_t ai_padding2[22];
ushort_t ai_lastlun;
ushort_t ai_resv6;
ushort_t ai_securestatus;
ushort_t ai_vendor[31];
ushort_t ai_padding3[16];
ushort_t ai_curmedser[30];
ushort_t ai_padding4[49];
ushort_t ai_integrity;
};
#define ATA_ID_REM_DRV 0x80
#define ATA_ID_COMPACT_FLASH 0x848a
#define ATA_ID_CF_TO_ATA 0x040a
#define ATA_ID_INCMPT 0x0004
#define ATAC_DMA_SUPPORT 0x0100
#define ATAC_LBA_SUPPORT 0x0200
#define ATAC_IORDY_DISABLE 0x0400
#define ATAC_IORDY_SUPPORT 0x0800
#define ATAC_RESERVED_IDPKT 0x1000
#define ATAC_STANDBYTIMER 0x2000
#define ATAC_ATA_TYPE_MASK 0x8001
#define ATAC_ATA_TYPE 0x0000
#define ATAC_ATAPI_TYPE_MASK 0xc000
#define ATAC_ATAPI_TYPE 0x8000
#define ATAC_VALIDINFO_83 0x0004
#define ATAC_VALIDINFO_70_64 0x0002
#define ATAC_MDMA_SUP_MASK 0x0007
#define ATAC_MDMA_SEL_MASK 0x0700
#define ATAC_MDMA_2_SEL 0x0400
#define ATAC_MDMA_1_SEL 0x0200
#define ATAC_MDMA_0_SEL 0x0100
#define ATAC_MDMA_2_SUP 0x0004
#define ATAC_MDMA_1_SUP 0x0002
#define ATAC_MDMA_0_SUP 0x0001
#define ATAC_ADVPIO_4_SUP 0x0002
#define ATAC_ADVPIO_3_SUP 0x0001
#define ATAC_ADVPIO_SERIAL 0x0003
#define ATAC_MAJVER_8 0x0100
#define ATAC_MAJVER_6 0x0040
#define ATAC_MAJVER_4 0x0010
#define ATACS_EXT48 0x0400
#define ATAC_FEATURES85_WCE 0x0020
#define ATAC_UDMA_SUP_MASK 0x007f
#define ATAC_UDMA_SEL_MASK 0x7f00
typedef struct ata_drv {
ata_ctl_t *ad_ctlp;
struct ata_id ad_id;
uint_t ad_flags;
uchar_t ad_pciide_dma;
uchar_t ad_targ;
uchar_t ad_lun;
uchar_t ad_drive_bits;
uchar_t ad_state;
uchar_t ad_cdb_len;
uchar_t ad_bogus_drq;
uchar_t ad_nec_bad_status;
struct scsi_device *ad_device;
struct scsi_inquiry ad_inquiry;
struct ctl_obj ad_ctl_obj;
uchar_t ad_rd_cmd;
uchar_t ad_wr_cmd;
ushort_t ad_acyl;
uint32_t ad_drvrcyl;
uint32_t ad_drvrhd;
uint32_t ad_drvrsec;
ushort_t ad_phhd;
ushort_t ad_phsec;
short ad_block_factor;
short ad_bytes_per_block;
uint64_t ad_capacity;
ushort_t ad_dma_cap;
ushort_t ad_dma_mode;
} ata_drv_t;
#define ATA_DMA_ULTRAMODE 0x1
#define ATA_DMA_MWORDMODE 0x2
typedef struct ata_tgt {
ata_drv_t *at_drvp;
int at_arq;
ulong_t at_total_sectors;
ddi_dma_attr_t at_dma_attr;
} ata_tgt_t;
#define ATA_DMA_OFF 0x0
#define ATA_DMA_ON 0x1
#define ATA_DMA_UNINITIALIZED 0x2
#define APKT2GCMD(apktp) (apktp->ap_gcmdp)
#define GCMD2APKT(gcmdp) ((ata_pkt_t *)gcmdp->cmd_private)
#define GTGTP2ATAP(gtgtp) ((ata_ctl_t *)GTGTP2HBA(gtgtp))
#define GTGTP2ATATGTP(gtgtp) ((ata_tgt_t *)GTGTP2TARGET(gtgtp))
#define GTGTP2ATADRVP(gtgtp) (GTGTP2ATATGTP(gtgtp)->at_drvp)
#define GCMD2TGT(gcmdp) GTGTP2ATATGTP(GCMDP2GTGTP(gcmdp))
#define GCMD2DRV(gcmdp) GTGTP2ATADRVP(GCMDP2GTGTP(gcmdp))
#define APKT2DRV(apktp) GCMD2DRV(APKT2GCMD(apktp))
#define TRAN2ATAP(tranp) ((ata_ctl_t *)TRAN2HBA(tranp))
typedef struct ata_pkt {
gcmd_t *ap_gcmdp;
uint_t ap_flags;
caddr_t ap_baddr;
size_t ap_boffset;
size_t ap_bcount;
caddr_t ap_v_addr;
size_t ap_resid;
uchar_t ap_pciide_dma;
prde_t ap_sg_list[ATA_DMA_NSEGS];
int ap_sg_cnt;
daddr_t ap_startsec;
ushort_t ap_count;
uchar_t ap_sec;
uchar_t ap_lwcyl;
uchar_t ap_hicyl;
uchar_t ap_hd;
uchar_t ap_cmd;
uchar_t ap_status;
uchar_t ap_error;
int (*ap_start)(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
struct ata_pkt *ata_pktp);
int (*ap_intr)(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
struct ata_pkt *ata_pktp);
void (*ap_complete)(ata_drv_t *ata_drvp,
struct ata_pkt *ata_pktp, int do_callback);
char ap_cdb;
char ap_scb;
uint_t ap_bytes_per_block;
uint_t ap_wrt_count;
caddr_t ap_v_addr_sav;
size_t ap_resid_sav;
uchar_t *ap_cdbp;
uchar_t ap_cdb_len;
uchar_t ap_cdb_pad;
struct scsi_arq_status *ap_scbp;
uchar_t ap_statuslen;
} ata_pkt_t;
#define AP_ATAPI 0x0001
#define AP_ERROR 0x0002
#define AP_TRAN_ERROR 0x0004
#define AP_READ 0x0008
#define AP_WRITE 0x0010
#define AP_ABORT 0x0020
#define AP_TIMEOUT 0x0040
#define AP_BUS_RESET 0x0080
#define AP_DEV_RESET 0x0100
#define AP_SENT_CMD 0x0200
#define AP_XFERRED_DATA 0x0400
#define AP_GOT_STATUS 0x0800
#define AP_ARQ_ON_ERROR 0x1000
#define AP_ARQ_OKAY 0x2000
#define AP_ARQ_ERROR 0x4000
#define AP_FREE 0x80000000u
int ata_check_drive_blacklist(struct ata_id *aidp, uint_t flags);
int ata_command(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp, int expect_drdy,
int silent, uint_t busy_wait, uchar_t cmd, uchar_t feature,
uchar_t count, uchar_t sector, uchar_t head, uchar_t cyl_low,
uchar_t cyl_hi);
int ata_get_status_clear_intr(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
int ata_id_common(uchar_t id_cmd, int drdy_expected,
ddi_acc_handle_t io_hdl1, caddr_t ioaddr1,
ddi_acc_handle_t io_hdl2, caddr_t ioaddr2,
struct ata_id *ata_idp);
int ata_prop_create(dev_info_t *tgt_dip, ata_drv_t *ata_drvp, char *name);
int ata_queue_cmd(int (*func)(ata_ctl_t *, ata_drv_t *, ata_pkt_t *),
void *arg, ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
gtgt_t *gtgtp);
int ata_set_feature(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
uchar_t feature, uchar_t value);
int ata_wait(ddi_acc_handle_t io_hdl, caddr_t ioaddr, uchar_t onbits,
uchar_t offbits, uint_t timeout_usec);
int ata_wait3(ddi_acc_handle_t io_hdl, caddr_t ioaddr, uchar_t onbits1,
uchar_t offbits1, uchar_t failure_onbits2,
uchar_t failure_offbits2, uchar_t failure_onbits3,
uchar_t failure_offbits3, uint_t timeout_usec);
int ata_test_lba_support(struct ata_id *aidp);
void ata_nsecwait(clock_t count);
int ata_set_dma_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp);
void ata_reset_dma_mode(ata_drv_t *ata_drvp);
void atapi_reset_dma_mode(ata_drv_t *ata_drvp, int need_wait);
extern ddi_dma_attr_t ata_pciide_dma_attr;
extern int ata_dma_disabled;
int ata_pciide_alloc(dev_info_t *dip, ata_ctl_t *ata_ctlp);
void ata_pciide_free(ata_ctl_t *ata_ctlp);
void ata_pciide_dma_sg_func(gcmd_t *gcmdp, ddi_dma_cookie_t *dmackp,
int single_segment, int seg_index);
void ata_pciide_dma_setup(ata_ctl_t *ata_ctlp, prde_t *srcp, int sg_cnt);
void ata_pciide_dma_start(ata_ctl_t *ata_ctlp, uchar_t direction);
void ata_pciide_dma_stop(ata_ctl_t *ata_ctlp);
int ata_pciide_status_clear(ata_ctl_t *ata_ctlp);
int ata_pciide_status_dmacheck_clear(ata_ctl_t *ata_ctlp);
int ata_pciide_status_pending(ata_ctl_t *ata_ctlp);
#ifdef __cplusplus
}
#endif
#endif