ahci.h revision 199747
178189Sbrian/*-
278189Sbrian * Copyright (c) 1998 - 2008 S�ren Schmidt <sos@FreeBSD.org>
378189Sbrian * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
478189Sbrian * All rights reserved.
578189Sbrian *
66059Samurai * Redistribution and use in source and binary forms, with or without
778189Sbrian * modification, are permitted provided that the following conditions
878189Sbrian * are met:
978189Sbrian * 1. Redistributions of source code must retain the above copyright
1078189Sbrian *    notice, this list of conditions and the following disclaimer,
1178189Sbrian *    without modification, immediately at the beginning of the file.
1278189Sbrian * 2. Redistributions in binary form must reproduce the above copyright
1378189Sbrian *    notice, this list of conditions and the following disclaimer in the
1478189Sbrian *    documentation and/or other materials provided with the distribution.
156059Samurai *
1678189Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1778189Sbrian * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1878189Sbrian * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1978189Sbrian * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2078189Sbrian * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2178189Sbrian * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2278189Sbrian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2378189Sbrian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2478189Sbrian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2578189Sbrian * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2678189Sbrian *
276059Samurai * $FreeBSD: head/sys/dev/ahci/ahci.h 199747 2009-11-24 12:47:58Z mav $
2850479Speter */
296059Samurai
3036285Sbrian/* ATA register defines */
3143313Sbrian#define ATA_DATA                        0       /* (RW) data */
3230715Sbrian
3330715Sbrian#define ATA_FEATURE                     1       /* (W) feature */
3430715Sbrian#define         ATA_F_DMA               0x01    /* enable DMA */
3536285Sbrian#define         ATA_F_OVL               0x02    /* enable overlap */
3658032Sbrian
3758032Sbrian#define ATA_COUNT                       2       /* (W) sector count */
3830715Sbrian
3930715Sbrian#define ATA_SECTOR                      3       /* (RW) sector # */
406059Samurai#define ATA_CYL_LSB                     4       /* (RW) cylinder# LSB */
4111336Samurai#define ATA_CYL_MSB                     5       /* (RW) cylinder# MSB */
4230715Sbrian#define ATA_DRIVE                       6       /* (W) Sector/Drive/Head */
43102500Sbrian#define         ATA_D_LBA               0x40    /* use LBA addressing */
4430715Sbrian#define         ATA_D_IBM               0xa0    /* 512 byte sectors, ECC */
4552396Sbrian
4630715Sbrian#define ATA_COMMAND                     7       /* (W) command */
4797140Sbrian
486059Samurai#define ATA_ERROR                       8       /* (R) error */
4918786Sjkh#define         ATA_E_ILI               0x01    /* illegal length */
5049581Sbrian#define         ATA_E_NM                0x02    /* no media */
5130715Sbrian#define         ATA_E_ABORT             0x04    /* command aborted */
5250059Sbrian#define         ATA_E_MCR               0x08    /* media change request */
5358037Sbrian#define         ATA_E_IDNF              0x10    /* ID not found */
5458037Sbrian#define         ATA_E_MC                0x20    /* media changed */
5558037Sbrian#define         ATA_E_UNC               0x40    /* uncorrectable data */
5646086Sbrian#define         ATA_E_ICRC              0x80    /* UDMA crc error */
5739395Sbrian#define		ATA_E_ATAPI_SENSE_MASK	0xf0	/* ATAPI sense key mask */
5839395Sbrian
5958037Sbrian#define ATA_IREASON                     9       /* (R) interrupt reason */
6046686Sbrian#define         ATA_I_CMD               0x01    /* cmd (1) | data (0) */
6137141Sbrian#define         ATA_I_IN                0x02    /* read (1) | write (0) */
6230715Sbrian#define         ATA_I_RELEASE           0x04    /* released bus (1) */
6330715Sbrian#define         ATA_I_TAGMASK           0xf8    /* tag mask */
6430715Sbrian
6531061Sbrian#define ATA_STATUS                      10      /* (R) status */
6630715Sbrian#define ATA_ALTSTAT                     11      /* (R) alternate status */
6730715Sbrian#define         ATA_S_ERROR             0x01    /* error */
6836285Sbrian#define         ATA_S_INDEX             0x02    /* index */
696059Samurai#define         ATA_S_CORR              0x04    /* data corrected */
7031514Sbrian#define         ATA_S_DRQ               0x08    /* data request */
7113389Sphk#define         ATA_S_DSC               0x10    /* drive seek completed */
7236285Sbrian#define         ATA_S_SERVICE           0x10    /* drive needs service */
7336285Sbrian#define         ATA_S_DWF               0x20    /* drive write fault */
7436285Sbrian#define         ATA_S_DMA               0x20    /* DMA ready */
7581634Sbrian#define         ATA_S_READY             0x40    /* drive ready */
766059Samurai#define         ATA_S_BUSY              0x80    /* busy */
7736285Sbrian
7836285Sbrian#define ATA_CONTROL                     12      /* (W) control */
7936285Sbrian#define         ATA_A_IDS               0x02    /* disable interrupts */
8036285Sbrian#define         ATA_A_RESET             0x04    /* RESET controller */
8143313Sbrian#define         ATA_A_4BIT              0x08    /* 4 head bits */
8243313Sbrian#define         ATA_A_HOB               0x80    /* High Order Byte enable */
8343313Sbrian
8481634Sbrian/* SATA register defines */
8581634Sbrian#define ATA_SSTATUS                     13
8636285Sbrian#define         ATA_SS_DET_MASK         0x0000000f
876735Samurai#define         ATA_SS_DET_NO_DEVICE    0x00000000
8813389Sphk#define         ATA_SS_DET_DEV_PRESENT  0x00000001
8923840Sbrian#define         ATA_SS_DET_PHY_ONLINE   0x00000003
9030715Sbrian#define         ATA_SS_DET_PHY_OFFLINE  0x00000004
9136285Sbrian
9236285Sbrian#define         ATA_SS_SPD_MASK         0x000000f0
9336285Sbrian#define         ATA_SS_SPD_NO_SPEED     0x00000000
9436285Sbrian#define         ATA_SS_SPD_GEN1         0x00000010
9538174Sbrian#define         ATA_SS_SPD_GEN2         0x00000020
9636285Sbrian#define         ATA_SS_SPD_GEN3         0x00000040
9740561Sbrian
986059Samurai#define         ATA_SS_IPM_MASK         0x00000f00
996735Samurai#define         ATA_SS_IPM_NO_DEVICE    0x00000000
1006735Samurai#define         ATA_SS_IPM_ACTIVE       0x00000100
1016735Samurai#define         ATA_SS_IPM_PARTIAL      0x00000200
1026735Samurai#define         ATA_SS_IPM_SLUMBER      0x00000600
1036735Samurai
1046735Samurai#define ATA_SERROR                      14
10536431Sbrian#define         ATA_SE_DATA_CORRECTED   0x00000001
10630715Sbrian#define         ATA_SE_COMM_CORRECTED   0x00000002
10730715Sbrian#define         ATA_SE_DATA_ERR         0x00000100
10836285Sbrian#define         ATA_SE_COMM_ERR         0x00000200
10936285Sbrian#define         ATA_SE_PROT_ERR         0x00000400
110177100Spiso#define         ATA_SE_HOST_ERR         0x00000800
1116059Samurai#define         ATA_SE_PHY_CHANGED      0x00010000
11210528Samurai#define         ATA_SE_PHY_IERROR       0x00020000
113134789Sbrian#define         ATA_SE_COMM_WAKE        0x00040000
1146059Samurai#define         ATA_SE_DECODE_ERR       0x00080000
11536285Sbrian#define         ATA_SE_PARITY_ERR       0x00100000
11638008Sbrian#define         ATA_SE_CRC_ERR          0x00200000
1176059Samurai#define         ATA_SE_HANDSHAKE_ERR    0x00400000
1186059Samurai#define         ATA_SE_LINKSEQ_ERR      0x00800000
1196059Samurai#define         ATA_SE_TRANSPORT_ERR    0x01000000
12036285Sbrian#define         ATA_SE_UNKNOWN_FIS      0x02000000
1216059Samurai
12298970Sbrian#define ATA_SCONTROL                    15
12398970Sbrian#define         ATA_SC_DET_MASK         0x0000000f
12436285Sbrian#define         ATA_SC_DET_IDLE         0x00000000
12598970Sbrian#define         ATA_SC_DET_RESET        0x00000001
12698970Sbrian#define         ATA_SC_DET_DISABLE      0x00000004
12798970Sbrian
12898970Sbrian#define         ATA_SC_SPD_MASK         0x000000f0
12936285Sbrian#define         ATA_SC_SPD_NO_SPEED     0x00000000
1306059Samurai#define         ATA_SC_SPD_SPEED_GEN1   0x00000010
1316059Samurai#define         ATA_SC_SPD_SPEED_GEN2   0x00000020
1326059Samurai#define         ATA_SC_SPD_SPEED_GEN3   0x00000040
1336059Samurai
13428679Sbrian#define         ATA_SC_IPM_MASK         0x00000f00
1356059Samurai#define         ATA_SC_IPM_NONE         0x00000000
13626858Sbrian#define         ATA_SC_IPM_DIS_PARTIAL  0x00000100
13736285Sbrian#define         ATA_SC_IPM_DIS_SLUMBER  0x00000200
13836285Sbrian
13937018Sbrian#define ATA_SACTIVE                     16
14036285Sbrian
1416059Samurai#define AHCI_MAX_PORTS			32
1426059Samurai#define AHCI_MAX_SLOTS			32
1436059Samurai
14428679Sbrian/* SATA AHCI v1.0 register defines */
1456059Samurai#define AHCI_CAP                    0x00
14636285Sbrian#define		AHCI_CAP_NPMASK	0x0000001f
147134789Sbrian#define		AHCI_CAP_SXS	0x00000020
1486059Samurai#define		AHCI_CAP_EMS	0x00000040
1496059Samurai#define		AHCI_CAP_CCCS	0x00000080
15036285Sbrian#define		AHCI_CAP_NCS	0x00001F00
15136285Sbrian#define		AHCI_CAP_NCS_SHIFT	8
15210528Samurai#define		AHCI_CAP_PSC	0x00002000
15336285Sbrian#define		AHCI_CAP_SSC	0x00004000
15410528Samurai#define		AHCI_CAP_PMD	0x00008000
15547119Sbrian#define		AHCI_CAP_FBSS	0x00010000
15636285Sbrian#define		AHCI_CAP_SPM	0x00020000
15736285Sbrian#define		AHCI_CAP_SAM	0x00080000
15810528Samurai#define		AHCI_CAP_ISS	0x00F00000
15910528Samurai#define		AHCI_CAP_ISS_SHIFT	20
16010528Samurai#define		AHCI_CAP_SCLO	0x01000000
161134789Sbrian#define		AHCI_CAP_SAL	0x02000000
16210528Samurai#define		AHCI_CAP_SALP	0x04000000
16336285Sbrian#define		AHCI_CAP_SSS	0x08000000
16436285Sbrian#define		AHCI_CAP_SMPS	0x10000000
16510528Samurai#define		AHCI_CAP_SSNTF	0x20000000
16610528Samurai#define		AHCI_CAP_SNCQ	0x40000000
16726940Sbrian#define		AHCI_CAP_64BIT	0x80000000
168134789Sbrian
16926940Sbrian#define AHCI_GHC                    0x04
17036285Sbrian#define         AHCI_GHC_AE         0x80000000
17136285Sbrian#define         AHCI_GHC_MRSM       0x00000004
17236285Sbrian#define         AHCI_GHC_IE         0x00000002
17326940Sbrian#define         AHCI_GHC_HR         0x00000001
17426940Sbrian
17531081Sbrian#define AHCI_IS                     0x08
176134789Sbrian#define AHCI_PI                     0x0c
17731081Sbrian#define AHCI_VS                     0x10
17836285Sbrian
17971657Sbrian#define AHCI_CCCC                   0x14
18071657Sbrian#define		AHCI_CCCC_TV_MASK	0xffff0000
18131081Sbrian#define		AHCI_CCCC_TV_SHIFT	16
18231081Sbrian#define		AHCI_CCCC_CC_MASK	0x0000ff00
18330715Sbrian#define		AHCI_CCCC_CC_SHIFT	8
184134789Sbrian#define		AHCI_CCCC_INT_MASK	0x000000f8
18571657Sbrian#define		AHCI_CCCC_INT_SHIFT	3
18671657Sbrian#define		AHCI_CCCC_EN		0x00000001
18771657Sbrian#define AHCI_CCCP                   0x18
18871657Sbrian
18971657Sbrian#define AHCI_CAP2                   0x24
19071657Sbrian#define		AHCI_CAP2_BOH	0x00000001
19131343Sbrian#define		AHCI_CAP2_NVMP	0x00000002
1926059Samurai#define		AHCI_CAP2_APST	0x00000004
19395258Sdes
19467912Sbrian#define AHCI_OFFSET                 0x100
195139116Sru#define AHCI_STEP                   0x80
19650059Sbrian
19731343Sbrian#define AHCI_P_CLB                  0x00
19852396Sbrian#define AHCI_P_CLBU                 0x04
1996059Samurai#define AHCI_P_FB                   0x08
2006059Samurai#define AHCI_P_FBU                  0x0c
2016059Samurai#define AHCI_P_IS                   0x10
20252396Sbrian#define AHCI_P_IE                   0x14
20352396Sbrian#define         AHCI_P_IX_DHR       0x00000001
20452396Sbrian#define         AHCI_P_IX_PS        0x00000002
20552396Sbrian#define         AHCI_P_IX_DS        0x00000004
20652396Sbrian#define         AHCI_P_IX_SDB       0x00000008
20752396Sbrian#define         AHCI_P_IX_UF        0x00000010
20852396Sbrian#define         AHCI_P_IX_DP        0x00000020
20952396Sbrian#define         AHCI_P_IX_PC        0x00000040
21040797Sbrian#define         AHCI_P_IX_DI        0x00000080
21152396Sbrian
2126059Samurai#define         AHCI_P_IX_PRC       0x00400000
21340797Sbrian#define         AHCI_P_IX_IPM       0x00800000
2146059Samurai#define         AHCI_P_IX_OF        0x01000000
2156059Samurai#define         AHCI_P_IX_INF       0x04000000
21640797Sbrian#define         AHCI_P_IX_IF        0x08000000
21752396Sbrian#define         AHCI_P_IX_HBD       0x10000000
21852396Sbrian#define         AHCI_P_IX_HBF       0x20000000
21952396Sbrian#define         AHCI_P_IX_TFE       0x40000000
22052396Sbrian#define         AHCI_P_IX_CPD       0x80000000
22140797Sbrian
22240797Sbrian#define AHCI_P_CMD                  0x18
22336465Sbrian#define         AHCI_P_CMD_ST       0x00000001
22436465Sbrian#define         AHCI_P_CMD_SUD      0x00000002
22536465Sbrian#define         AHCI_P_CMD_POD      0x00000004
22652396Sbrian#define         AHCI_P_CMD_CLO      0x00000008
22750059Sbrian#define         AHCI_P_CMD_FRE      0x00000010
22852396Sbrian#define         AHCI_P_CMD_CCS_MASK 0x00001f00
22937191Sbrian#define         AHCI_P_CMD_CCS_SHIFT 8
23052396Sbrian#define         AHCI_P_CMD_ISS      0x00002000
23136285Sbrian#define         AHCI_P_CMD_FR       0x00004000
23236465Sbrian#define         AHCI_P_CMD_CR       0x00008000
23352396Sbrian#define         AHCI_P_CMD_CPS      0x00010000
23452396Sbrian#define         AHCI_P_CMD_PMA      0x00020000
23552396Sbrian#define         AHCI_P_CMD_HPCP     0x00040000
23652396Sbrian#define         AHCI_P_CMD_ISP      0x00080000
23752396Sbrian#define         AHCI_P_CMD_CPD      0x00100000
23853889Sbrian#define         AHCI_P_CMD_ATAPI    0x01000000
23953889Sbrian#define         AHCI_P_CMD_DLAE     0x02000000
24052396Sbrian#define         AHCI_P_CMD_ALPE     0x04000000
24152396Sbrian#define         AHCI_P_CMD_ASP      0x08000000
24252396Sbrian#define         AHCI_P_CMD_ICC_MASK 0xf0000000
24352396Sbrian#define         AHCI_P_CMD_NOOP     0x00000000
24453067Sbrian#define         AHCI_P_CMD_ACTIVE   0x10000000
24552396Sbrian#define         AHCI_P_CMD_PARTIAL  0x20000000
24653067Sbrian#define         AHCI_P_CMD_SLUMBER  0x60000000
24752396Sbrian
24852396Sbrian#define AHCI_P_TFD                  0x20
24952396Sbrian#define AHCI_P_SIG                  0x24
25052396Sbrian#define AHCI_P_SSTS                 0x28
25152396Sbrian#define AHCI_P_SCTL                 0x2c
25252396Sbrian#define AHCI_P_SERR                 0x30
25352396Sbrian#define AHCI_P_SACT                 0x34
25450059Sbrian#define AHCI_P_CI                   0x38
25552396Sbrian#define AHCI_P_SNTF                 0x3C
25650059Sbrian#define AHCI_P_FBS                  0x40
25736465Sbrian
25836465Sbrian/* Just to be sure, if building as module. */
25936465Sbrian#if MAXPHYS < 512 * 1024
26036465Sbrian#undef MAXPHYS
26136465Sbrian#define MAXPHYS				512 * 1024
26236465Sbrian#endif
26336465Sbrian/* Pessimistic prognosis on number of required S/G entries */
26436465Sbrian#define AHCI_SG_ENTRIES	(roundup(btoc(MAXPHYS) + 1, 8))
26536465Sbrian/* Command list. 32 commands. First, 1Kbyte aligned. */
26652396Sbrian#define AHCI_CL_OFFSET              0
26753830Sbrian#define AHCI_CL_SIZE                32
26853830Sbrian/* Command tables. Up to 32 commands, Each, 128byte aligned. */
26936465Sbrian#define AHCI_CT_OFFSET              (AHCI_CL_OFFSET + AHCI_CL_SIZE * AHCI_MAX_SLOTS)
2706059Samurai#define AHCI_CT_SIZE                (128 + AHCI_SG_ENTRIES * 16)
27136465Sbrian/* Total main work area. */
2726059Samurai#define AHCI_WORK_SIZE              (AHCI_CT_OFFSET + AHCI_CT_SIZE * ch->numslots)
27336285Sbrian
2746059Samuraistruct ahci_dma_prd {
2756059Samurai    u_int64_t                   dba;
27631197Sbrian    u_int32_t                   reserved;
27752396Sbrian    u_int32_t                   dbc;            /* 0 based */
27840797Sbrian#define AHCI_PRD_MASK		0x003fffff      /* max 4MB */
27936285Sbrian#define AHCI_PRD_MAX		(AHCI_PRD_MASK + 1)
28036285Sbrian#define AHCI_PRD_IPC		(1 << 31)
28136285Sbrian} __packed;
28240797Sbrian
2836059Samuraistruct ahci_cmd_tab {
2846059Samurai    u_int8_t                    cfis[64];
28540797Sbrian    u_int8_t                    acmd[32];
28640797Sbrian    u_int8_t                    reserved[32];
28740797Sbrian    struct ahci_dma_prd         prd_tab[AHCI_SG_ENTRIES];
28840797Sbrian} __packed;
28940797Sbrian
29040797Sbrianstruct ahci_cmd_list {
29140797Sbrian    u_int16_t                   cmd_flags;
29240797Sbrian#define AHCI_CMD_ATAPI		0x0020
29340797Sbrian#define AHCI_CMD_WRITE		0x0040
29440797Sbrian#define AHCI_CMD_PREFETCH		0x0080
29540797Sbrian#define AHCI_CMD_RESET		0x0100
29640797Sbrian#define AHCI_CMD_BIST		0x0200
29740797Sbrian#define AHCI_CMD_CLR_BUSY		0x0400
29840797Sbrian
29940797Sbrian    u_int16_t                   prd_length;     /* PRD entries */
30040797Sbrian    u_int32_t                   bytecount;
30126940Sbrian    u_int64_t                   cmd_table_phys; /* 128byte aligned */
30228679Sbrian} __packed;
3036059Samurai
30440797Sbrian/* misc defines */
30543187Sbrian#define ATA_IRQ_RID                     0
306134789Sbrian#define ATA_INTR_FLAGS                  (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY)
307134789Sbrian
30836285Sbrianstruct ata_dmaslot {
30936285Sbrian    bus_dmamap_t                data_map;       /* data DMA map */
31052396Sbrian    int				nsegs;		/* Number of segs loaded */
31126516Sbrian};
31281697Sbrian
31381697Sbrian/* structure holding DMA related information */
31479173Sbrianstruct ata_dma {
31579173Sbrian    bus_dma_tag_t               work_tag;       /* workspace DMA tag */
31679173Sbrian    bus_dmamap_t                work_map;       /* workspace DMA map */
31779173Sbrian    uint8_t                     *work;          /* workspace */
31879173Sbrian    bus_addr_t                  work_bus;       /* bus address of work */
31979173Sbrian    bus_dma_tag_t               rfis_tag;       /* RFIS list DMA tag */
32079173Sbrian    bus_dmamap_t                rfis_map;       /* RFIS list DMA map */
32179173Sbrian    uint8_t                     *rfis;          /* FIS receive area */
32279173Sbrian    bus_addr_t                  rfis_bus;       /* bus address of rfis */
32379173Sbrian    bus_dma_tag_t               data_tag;       /* data DMA tag */
32479173Sbrian    u_int64_t                   max_address;    /* highest DMA'able address */
32579186Sbrian};
32679173Sbrian
32730715Sbrianenum ahci_slot_states {
32836285Sbrian	AHCI_SLOT_EMPTY,
32926516Sbrian	AHCI_SLOT_LOADING,
33050059Sbrian	AHCI_SLOT_RUNNING,
331177100Spiso	AHCI_SLOT_EXECUTING
33238198Sbrian};
33352396Sbrian
33431121Sbrianstruct ahci_slot {
33536285Sbrian    device_t                    dev;            /* Device handle */
33644539Sbrian    u_int8_t			slot;           /* Number of this slot */
33744539Sbrian    enum ahci_slot_states	state;          /* Slot state */
33844539Sbrian    union ccb			*ccb;		/* CCB occupying slot */
33936285Sbrian    struct ata_dmaslot          dma;            /* DMA data of this slot */
34036285Sbrian    struct callout              timeout;        /* Execution timeout */
34136285Sbrian};
34252396Sbrian
34336285Sbrianstruct ahci_device {
34436285Sbrian	u_int			revision;
34536285Sbrian	int			mode;
34636285Sbrian	u_int			bytecount;
34736285Sbrian	u_int			tags;
34836285Sbrian};
34936285Sbrian
35036285Sbrian/* structure describing an ATA channel */
35152396Sbrianstruct ahci_channel {
35236285Sbrian	device_t		dev;            /* Device handle */
35343526Sbrian	int			unit;           /* Physical channel */
35436285Sbrian	struct resource		*r_mem;		/* Memory of this channel */
35536285Sbrian	struct resource		*r_irq;         /* Interrupt of this channel */
35631121Sbrian	void			*ih;            /* Interrupt handle */
35731158Sbrian	struct ata_dma		dma;            /* DMA data */
35831158Sbrian	struct cam_sim		*sim;
35931158Sbrian	struct cam_path		*path;
36074687Sbrian	uint32_t		caps;		/* Controller capabilities */
36131158Sbrian	uint32_t		caps2;		/* Controller capabilities */
36249581Sbrian	int			quirks;
36349581Sbrian	int			numslots;	/* Number of present slots */
36449581Sbrian	int			pm_level;	/* power management level */
36537019Sbrian	int			sata_rev;	/* Maximum allowed SATA generation */
36637019Sbrian
36731158Sbrian	struct ahci_slot	slot[AHCI_MAX_SLOTS];
36831158Sbrian	union ccb		*hold[AHCI_MAX_SLOTS];
36931158Sbrian	struct mtx		mtx;		/* state lock */
37031158Sbrian	int			devices;        /* What is present */
37131158Sbrian	int			pm_present;	/* PM presence reported */
37231158Sbrian	uint32_t		oslots;		/* Occupied slots */
37331158Sbrian	uint32_t		rslots;		/* Running slots */
37431158Sbrian	uint32_t		aslots;		/* Slots with atomic commands  */
37540797Sbrian	int			numrslots;	/* Number of running slots */
37640797Sbrian	int			numtslots;	/* Number of tagged slots */
37752396Sbrian	int			readlog;	/* Our READ LOG active */
37840797Sbrian	int			fatalerr;	/* Fatal error happend */
37952396Sbrian	int			lastslot;	/* Last used slot */
38031121Sbrian	int			taggedtarget;	/* Last tagged target */
38152396Sbrian	union ccb		*frozen;	/* Frozen command */
38252396Sbrian	struct callout		pm_timer;	/* Power management events */
38343526Sbrian
38453298Sbrian	struct ahci_device	user[16];	/* User-specified settings */
38526940Sbrian	struct ahci_device	curr[16];	/* Current settings */
38643187Sbrian};
38743187Sbrian
38843187Sbrian/* structure describing a AHCI controller */
38936285Sbrianstruct ahci_controller {
39052396Sbrian	device_t		dev;
39152396Sbrian	int			r_rid;
392138198Sbrian	struct resource		*r_mem;
39331121Sbrian	struct rman		sc_iomem;
39437008Sbrian	struct ahci_controller_irq {
39536285Sbrian		struct ahci_controller	*ctlr;
39636285Sbrian		struct resource		*r_irq;
39736285Sbrian		void			*handle;
39836285Sbrian		int			r_irq_rid;
39936285Sbrian		int			mode;
40036285Sbrian#define	AHCI_IRQ_MODE_ALL	0
40136285Sbrian#define	AHCI_IRQ_MODE_AFTER	1
40224753Sache#define	AHCI_IRQ_MODE_ONE	2
4036059Samurai	} irqs[16];
40452396Sbrian	uint32_t		caps;		/* Controller capabilities */
40536285Sbrian	uint32_t		caps2;		/* Controller capabilities */
40636285Sbrian	int			quirks;
40771657Sbrian	int			numirqs;
40836285Sbrian	int			channels;
40936285Sbrian	int			ichannels;
41053298Sbrian	int			ccc;		/* CCC timeout */
41140797Sbrian	int			cccv;		/* CCC vector */
41240797Sbrian	struct {
41343187Sbrian		void			(*function)(void *);
41453298Sbrian		void			*argument;
4156059Samurai	} interrupt[AHCI_MAX_PORTS];
41626940Sbrian};
41740797Sbrian
41840797Sbrianenum ahci_err_type {
41943187Sbrian	AHCI_ERR_NONE,		/* No error */
42040797Sbrian	AHCI_ERR_INVALID,	/* Error detected by us before submitting. */
42152396Sbrian	AHCI_ERR_INNOCENT,	/* Innocent victim. */
42281634Sbrian	AHCI_ERR_TFE,		/* Task File Error. */
42340797Sbrian	AHCI_ERR_SATA,		/* SATA error. */
42440797Sbrian	AHCI_ERR_TIMEOUT,	/* Command execution timeout. */
42540797Sbrian	AHCI_ERR_NCQ,		/* NCQ command error. CCB should be put on hold
42640797Sbrian				 * until READ LOG executed to reveal error. */
42740797Sbrian};
428218397Sbrian
429218397Sbrian/* macros to hide busspace uglyness */
430218397Sbrian#define ATA_INB(res, offset) \
431218397Sbrian	bus_read_1((res), (offset))
432218397Sbrian#define ATA_INW(res, offset) \
433218397Sbrian	bus_read_2((res), (offset))
43452396Sbrian#define ATA_INL(res, offset) \
43552396Sbrian	bus_read_4((res), (offset))
43652396Sbrian#define ATA_INSW(res, offset, addr, count) \
43750059Sbrian	bus_read_multi_2((res), (offset), (addr), (count))
43850059Sbrian#define ATA_INSW_STRM(res, offset, addr, count) \
43936285Sbrian	bus_read_multi_stream_2((res), (offset), (addr), (count))
44052396Sbrian#define ATA_INSL(res, offset, addr, count) \
44150059Sbrian	bus_read_multi_4((res), (offset), (addr), (count))
44250059Sbrian#define ATA_INSL_STRM(res, offset, addr, count) \
44350059Sbrian	bus_read_multi_stream_4((res), (offset), (addr), (count))
4446059Samurai#define ATA_OUTB(res, offset, value) \
44550059Sbrian	bus_write_1((res), (offset), (value))
44650059Sbrian#define ATA_OUTW(res, offset, value) \
44750059Sbrian	bus_write_2((res), (offset), (value))
44850059Sbrian#define ATA_OUTL(res, offset, value) \
44950059Sbrian	bus_write_4((res), (offset), (value))
45036285Sbrian#define ATA_OUTSW(res, offset, addr, count) \
45150059Sbrian	bus_write_multi_2((res), (offset), (addr), (count))
45250059Sbrian#define ATA_OUTSW_STRM(res, offset, addr, count) \
45359084Sbrian	bus_write_multi_stream_2((res), (offset), (addr), (count))
45411336Samurai#define ATA_OUTSL(res, offset, addr, count) \
45552396Sbrian	bus_write_multi_4((res), (offset), (addr), (count))
45650059Sbrian#define ATA_OUTSL_STRM(res, offset, addr, count) \
45750059Sbrian	bus_write_multi_stream_4((res), (offset), (addr), (count))
45850059Sbrian