xref: /openbsd-src/sys/dev/ic/ahcivar.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: ahcivar.h,v 1.9 2014/12/03 04:33:06 jsg 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/timeout.h>
22 #include <dev/ata/atascsi.h>
23 #include <dev/ata/pmreg.h>
24 
25 /* change to AHCI_DEBUG for dmesg spam */
26 #define NO_AHCI_DEBUG
27 
28 struct ahci_dmamem {
29 	bus_dmamap_t		adm_map;
30 	bus_dma_segment_t	adm_seg;
31 	size_t			adm_size;
32 	caddr_t			adm_kva;
33 };
34 #define AHCI_DMA_MAP(_adm)	((_adm)->adm_map)
35 #define AHCI_DMA_DVA(_adm)	((u_int64_t)(_adm)->adm_map->dm_segs[0].ds_addr)
36 #define AHCI_DMA_KVA(_adm)	((void *)(_adm)->adm_kva)
37 
38 struct ahci_softc;
39 struct ahci_port;
40 
41 struct ahci_ccb {
42 	/* ATA xfer associated with this CCB.  Must be 1st struct member. */
43 	struct ata_xfer		ccb_xa;
44 
45 	int			ccb_slot;
46 	struct ahci_port	*ccb_port;
47 
48 	bus_dmamap_t		ccb_dmamap;
49 	struct ahci_cmd_hdr	*ccb_cmd_hdr;
50 	struct ahci_cmd_table	*ccb_cmd_table;
51 
52 	void			(*ccb_done)(struct ahci_ccb *);
53 
54 	TAILQ_ENTRY(ahci_ccb)	ccb_entry;
55 };
56 
57 struct ahci_port {
58 	struct ahci_softc	*ap_sc;
59 	bus_space_handle_t	ap_ioh;
60 
61 #ifdef AHCI_COALESCE
62 	int			ap_num;
63 #endif
64 
65 	struct ahci_rfis	*ap_rfis;
66 	struct ahci_dmamem	*ap_dmamem_rfis;
67 
68 	struct ahci_dmamem	*ap_dmamem_cmd_list;
69 	struct ahci_dmamem	*ap_dmamem_cmd_table;
70 
71 	volatile u_int32_t	ap_active;
72 	volatile u_int32_t	ap_active_cnt;
73 	volatile u_int32_t	ap_sactive;
74 	volatile u_int32_t	ap_pmp_ncq_port;
75 	struct ahci_ccb		*ap_ccbs;
76 
77 	TAILQ_HEAD(, ahci_ccb)	ap_ccb_free;
78 	TAILQ_HEAD(, ahci_ccb)	ap_ccb_pending;
79 	struct mutex		ap_ccb_mtx;
80 	struct ahci_ccb		*ap_ccb_err;
81 
82 	u_int32_t		ap_state;
83 #define AP_S_NORMAL			0
84 #define AP_S_PMP_PROBE			1
85 #define AP_S_PMP_PORT_PROBE		2
86 #define AP_S_ERROR_RECOVERY		3
87 #define AP_S_FATAL_ERROR		4
88 
89 	int			ap_pmp_ports;
90 	int			ap_port;
91 	int			ap_pmp_ignore_ifs;
92 
93 	/* For error recovery. */
94 #ifdef DIAGNOSTIC
95 	int			ap_err_busy;
96 #endif
97 	u_int32_t		ap_err_saved_sactive;
98 	u_int32_t		ap_err_saved_active;
99 	u_int32_t		ap_err_saved_active_cnt;
100 
101 	u_int8_t		*ap_err_scratch;
102 
103 #ifdef AHCI_DEBUG
104 	char			ap_name[16];
105 #define PORTNAME(_ap)	((_ap)->ap_name)
106 #else
107 #define PORTNAME(_ap)	DEVNAME((_ap)->ap_sc)
108 #endif
109 };
110 
111 struct ahci_softc {
112 	struct device		sc_dev;
113 
114 	void			*sc_ih;
115 
116 	bus_space_tag_t		sc_iot;
117 	bus_space_handle_t	sc_ioh;
118 	bus_size_t		sc_ios;
119 	bus_dma_tag_t		sc_dmat;
120 
121 	int			sc_flags;
122 #define AHCI_F_NO_NCQ			(1<<0)
123 #define AHCI_F_IPMS_PROBE		(1<<1)	/* IPMS on failed PMP probe */
124 #define AHCI_F_NO_PMP			(1<<2)	/* ignore PMP capability */
125 #define AHCI_F_NO_MSI			(1<<3)	/* disable MSI */
126 
127 	u_int			sc_ncmds;
128 
129 	struct ahci_port	*sc_ports[AHCI_MAX_PORTS];
130 
131 	struct atascsi		*sc_atascsi;
132 
133 	u_int32_t		sc_cap;
134 
135 #ifdef AHCI_COALESCE
136 	u_int32_t		sc_ccc_mask;
137 	u_int32_t		sc_ccc_ports;
138 	u_int32_t		sc_ccc_ports_cur;
139 #endif
140 
141 	int			(*sc_port_start)(struct ahci_port *, int);
142 };
143 
144 #define DEVNAME(_s)		((_s)->sc_dev.dv_xname)
145 #define ahci_port_start(_p, _f)	((_p)->ap_sc->sc_port_start((_p), (_f)))
146 
147 int			ahci_attach(struct ahci_softc *);
148 int			ahci_detach(struct ahci_softc *, int);
149 int			ahci_activate(struct device *, int);
150 
151 int			ahci_intr(void *);
152