xref: /openbsd/sys/dev/ic/ahcivar.h (revision 9ced64ea)
1 /*	$OpenBSD: ahcivar.h,v 1.11 2021/05/30 15:05:33 visa Exp $ */
2 
3 /*
4  * Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
5  * Copyright (c) 2010 Conformal Systems LLC <info@conformal.com>
6  * Copyright (c) 2010 Jonathan Matthew <jonathan@d14n.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/mutex.h>
22 #include <sys/timeout.h>
23 #include <dev/ata/atascsi.h>
24 #include <dev/ata/pmreg.h>
25 
26 /* change to AHCI_DEBUG for dmesg spam */
27 #define NO_AHCI_DEBUG
28 
29 struct ahci_dmamem {
30 	bus_dmamap_t		adm_map;
31 	bus_dma_segment_t	adm_seg;
32 	size_t			adm_size;
33 	caddr_t			adm_kva;
34 };
35 #define AHCI_DMA_MAP(_adm)	((_adm)->adm_map)
36 #define AHCI_DMA_DVA(_adm)	((u_int64_t)(_adm)->adm_map->dm_segs[0].ds_addr)
37 #define AHCI_DMA_KVA(_adm)	((void *)(_adm)->adm_kva)
38 
39 struct ahci_softc;
40 struct ahci_port;
41 
42 struct ahci_ccb {
43 	/* ATA xfer associated with this CCB.  Must be 1st struct member. */
44 	struct ata_xfer		ccb_xa;
45 
46 	int			ccb_slot;
47 	struct ahci_port	*ccb_port;
48 
49 	bus_dmamap_t		ccb_dmamap;
50 	struct ahci_cmd_hdr	*ccb_cmd_hdr;
51 	struct ahci_cmd_table	*ccb_cmd_table;
52 
53 	void			(*ccb_done)(struct ahci_ccb *);
54 
55 	TAILQ_ENTRY(ahci_ccb)	ccb_entry;
56 };
57 
58 struct ahci_port {
59 	struct ahci_softc	*ap_sc;
60 	bus_space_handle_t	ap_ioh;
61 
62 #ifdef AHCI_COALESCE
63 	int			ap_num;
64 #endif
65 
66 	struct ahci_rfis	*ap_rfis;
67 	struct ahci_dmamem	*ap_dmamem_rfis;
68 
69 	struct ahci_dmamem	*ap_dmamem_cmd_list;
70 	struct ahci_dmamem	*ap_dmamem_cmd_table;
71 
72 	volatile u_int32_t	ap_active;
73 	volatile u_int32_t	ap_active_cnt;
74 	volatile u_int32_t	ap_sactive;
75 	volatile u_int32_t	ap_pmp_ncq_port;
76 	struct ahci_ccb		*ap_ccbs;
77 
78 	TAILQ_HEAD(, ahci_ccb)	ap_ccb_free;
79 	TAILQ_HEAD(, ahci_ccb)	ap_ccb_pending;
80 	struct mutex		ap_ccb_mtx;
81 	struct ahci_ccb		*ap_ccb_err;
82 
83 	u_int32_t		ap_state;
84 #define AP_S_NORMAL			0
85 #define AP_S_PMP_PROBE			1
86 #define AP_S_PMP_PORT_PROBE		2
87 #define AP_S_ERROR_RECOVERY		3
88 #define AP_S_FATAL_ERROR		4
89 
90 	int			ap_pmp_ports;
91 	int			ap_port;
92 	int			ap_pmp_ignore_ifs;
93 
94 	/* For error recovery. */
95 #ifdef DIAGNOSTIC
96 	int			ap_err_busy;
97 #endif
98 	u_int32_t		ap_err_saved_sactive;
99 	u_int32_t		ap_err_saved_active;
100 	u_int32_t		ap_err_saved_active_cnt;
101 	u_int32_t		ap_saved_cmd;
102 
103 	u_int8_t		*ap_err_scratch;
104 
105 #ifdef AHCI_DEBUG
106 	char			ap_name[16];
107 #define PORTNAME(_ap)	((_ap)->ap_name)
108 #else
109 #define PORTNAME(_ap)	DEVNAME((_ap)->ap_sc)
110 #endif
111 };
112 
113 struct ahci_softc {
114 	struct device		sc_dev;
115 
116 	void			*sc_ih;
117 
118 	bus_space_tag_t		sc_iot;
119 	bus_space_handle_t	sc_ioh;
120 	bus_size_t		sc_ios;
121 	bus_dma_tag_t		sc_dmat;
122 
123 	int			sc_flags;
124 #define AHCI_F_NO_NCQ			(1<<0)
125 #define AHCI_F_IPMS_PROBE		(1<<1)	/* IPMS on failed PMP probe */
126 #define AHCI_F_NO_PMP			(1<<2)	/* ignore PMP capability */
127 #define AHCI_F_NO_MSI			(1<<3)	/* disable MSI */
128 
129 	u_int			sc_ncmds;
130 
131 	struct ahci_port	*sc_ports[AHCI_MAX_PORTS];
132 
133 	struct atascsi		*sc_atascsi;
134 
135 	u_int32_t		sc_cap;
136 
137 #ifdef AHCI_COALESCE
138 	u_int32_t		sc_ccc_mask;
139 	u_int32_t		sc_ccc_ports;
140 	u_int32_t		sc_ccc_ports_cur;
141 #endif
142 
143 	int			(*sc_port_start)(struct ahci_port *, int);
144 };
145 
146 #define DEVNAME(_s)		((_s)->sc_dev.dv_xname)
147 #define ahci_port_start(_p, _f)	((_p)->ap_sc->sc_port_start((_p), (_f)))
148 
149 int			ahci_attach(struct ahci_softc *);
150 int			ahci_detach(struct ahci_softc *, int);
151 int			ahci_activate(struct device *, int);
152 
153 int			ahci_intr(void *);
154