xref: /openbsd/sys/dev/pci/ahci_pci.c (revision 3cab2bb3)
1 /*	$OpenBSD: ahci_pci.c,v 1.15 2018/08/03 22:18:13 kettenis 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/param.h>
22 #include <sys/systm.h>
23 #include <sys/buf.h>
24 #include <sys/kernel.h>
25 #include <sys/malloc.h>
26 #include <sys/device.h>
27 #include <sys/timeout.h>
28 #include <sys/queue.h>
29 #include <sys/mutex.h>
30 #include <sys/pool.h>
31 
32 #include <machine/bus.h>
33 
34 #include <dev/pci/pcireg.h>
35 #include <dev/pci/pcivar.h>
36 #include <dev/pci/pcidevs.h>
37 
38 #include <dev/ata/pmreg.h>
39 
40 #include <dev/ic/ahcireg.h>
41 #include <dev/ic/ahcivar.h>
42 
43 #define AHCI_PCI_BAR		0x24
44 #define AHCI_PCI_ATI_SB600_MAGIC	0x40
45 #define AHCI_PCI_ATI_SB600_LOCKED	0x01
46 
47 struct ahci_pci_softc {
48 	struct ahci_softc	psc_ahci;
49 
50 	pci_chipset_tag_t	psc_pc;
51 	pcitag_t		psc_tag;
52 
53 	int			psc_flags;
54 };
55 
56 struct ahci_device {
57 	pci_vendor_id_t		ad_vendor;
58 	pci_product_id_t	ad_product;
59 	int			(*ad_match)(struct pci_attach_args *);
60 	int			(*ad_attach)(struct ahci_softc *,
61 				    struct pci_attach_args *);
62 };
63 
64 const struct ahci_device *ahci_lookup_device(struct pci_attach_args *);
65 
66 int			ahci_no_match(struct pci_attach_args *);
67 int			ahci_vt8251_attach(struct ahci_softc *,
68 			    struct pci_attach_args *);
69 void			ahci_ati_sb_idetoahci(struct ahci_softc *,
70 			    struct pci_attach_args *pa);
71 int			ahci_ati_sb600_attach(struct ahci_softc *,
72 			    struct pci_attach_args *);
73 int			ahci_ati_sb700_attach(struct ahci_softc *,
74 			    struct pci_attach_args *);
75 int			ahci_amd_hudson2_attach(struct ahci_softc *,
76 			    struct pci_attach_args *);
77 int			ahci_intel_attach(struct ahci_softc *,
78 			    struct pci_attach_args *);
79 int			ahci_samsung_attach(struct ahci_softc *,
80 			    struct pci_attach_args *);
81 
82 static const struct ahci_device ahci_devices[] = {
83 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_HUDSON2_SATA_1,
84 	    NULL,		ahci_amd_hudson2_attach },
85 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_HUDSON2_SATA_2,
86 	    NULL,		ahci_amd_hudson2_attach },
87 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_HUDSON2_SATA_3,
88 	    NULL,		ahci_amd_hudson2_attach },
89 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_HUDSON2_SATA_4,
90 	    NULL,		ahci_amd_hudson2_attach },
91 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_HUDSON2_SATA_5,
92 	    NULL,		ahci_amd_hudson2_attach },
93 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_HUDSON2_SATA_6,
94 	    NULL,		ahci_amd_hudson2_attach },
95 
96 	{ PCI_VENDOR_ATI,	PCI_PRODUCT_ATI_SB600_SATA,
97 	    NULL,		ahci_ati_sb600_attach },
98 	{ PCI_VENDOR_ATI,	PCI_PRODUCT_ATI_SBX00_SATA_1,
99 	    NULL,		ahci_ati_sb700_attach },
100 	{ PCI_VENDOR_ATI,	PCI_PRODUCT_ATI_SBX00_SATA_2,
101 	    NULL,		ahci_ati_sb700_attach },
102 	{ PCI_VENDOR_ATI,	PCI_PRODUCT_ATI_SBX00_SATA_3,
103 	    NULL,		ahci_ati_sb700_attach },
104 	{ PCI_VENDOR_ATI,	PCI_PRODUCT_ATI_SBX00_SATA_4,
105 	    NULL,		ahci_ati_sb700_attach },
106 	{ PCI_VENDOR_ATI,	PCI_PRODUCT_ATI_SBX00_SATA_5,
107 	    NULL,		ahci_ati_sb700_attach },
108 	{ PCI_VENDOR_ATI,	PCI_PRODUCT_ATI_SBX00_SATA_6,
109 	    NULL,		ahci_ati_sb700_attach },
110 
111 	{ PCI_VENDOR_ASMEDIA,	PCI_PRODUCT_ASMEDIA_ASM1061_SATA },
112 
113 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_6SERIES_AHCI_1,
114 	    NULL,		ahci_intel_attach },
115 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_6SERIES_AHCI_2,
116 	    NULL,		ahci_intel_attach },
117 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_6321ESB_AHCI,
118 	    NULL,		ahci_intel_attach },
119 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801GR_AHCI,
120 	    NULL,		ahci_intel_attach },
121 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801GBM_AHCI,
122 	    NULL,		ahci_intel_attach },
123 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801H_AHCI_6P,
124 	    NULL,		ahci_intel_attach },
125 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801H_AHCI_4P,
126 	    NULL,		ahci_intel_attach },
127 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801HBM_AHCI,
128 	    NULL,		ahci_intel_attach },
129 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801I_AHCI_1,
130 	    NULL,		ahci_intel_attach },
131 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801I_AHCI_2,
132 	    NULL,		ahci_intel_attach },
133 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801I_AHCI_3,
134 	    NULL,		ahci_intel_attach },
135 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801JD_AHCI,
136 	    NULL,		ahci_intel_attach },
137 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801JI_AHCI,
138 	    NULL,		ahci_intel_attach },
139 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_3400_AHCI_1,
140 	    NULL,		ahci_intel_attach },
141 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_3400_AHCI_2,
142 	    NULL,		ahci_intel_attach },
143 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_3400_AHCI_3,
144 	    NULL,		ahci_intel_attach },
145 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_3400_AHCI_4,
146 	    NULL,		ahci_intel_attach },
147 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_EP80579_AHCI,
148 	    NULL,		ahci_intel_attach },
149 
150 	{ PCI_VENDOR_SAMSUNG2,	PCI_PRODUCT_SAMSUNG2_S4LN053X01,
151 	    NULL,		ahci_samsung_attach },
152 	{ PCI_VENDOR_SAMSUNG2,	PCI_PRODUCT_SAMSUNG2_XP941,
153 	    NULL,		ahci_samsung_attach },
154 	{ PCI_VENDOR_SAMSUNG2,	PCI_PRODUCT_SAMSUNG2_SM951_AHCI,
155 	    NULL,		ahci_samsung_attach },
156 
157 	{ PCI_VENDOR_VIATECH,	PCI_PRODUCT_VIATECH_VT8251_SATA,
158 	  ahci_no_match,	ahci_vt8251_attach }
159 };
160 
161 int			ahci_pci_match(struct device *, void *, void *);
162 void			ahci_pci_attach(struct device *, struct device *,
163 			    void *);
164 int			ahci_pci_detach(struct device *, int);
165 int			ahci_pci_activate(struct device *, int);
166 
167 struct cfattach ahci_pci_ca = {
168 	sizeof(struct ahci_pci_softc),
169 	ahci_pci_match,
170 	ahci_pci_attach,
171 	ahci_pci_detach,
172 	ahci_pci_activate
173 };
174 
175 struct cfattach ahci_jmb_ca = {
176 	sizeof(struct ahci_pci_softc),
177 	ahci_pci_match,
178 	ahci_pci_attach,
179 	ahci_pci_detach
180 };
181 
182 int			ahci_map_regs(struct ahci_pci_softc *,
183 			    struct pci_attach_args *);
184 void			ahci_unmap_regs(struct ahci_pci_softc *);
185 int			ahci_map_intr(struct ahci_pci_softc *,
186 			    struct pci_attach_args *, pci_intr_handle_t);
187 void			ahci_unmap_intr(struct ahci_pci_softc *);
188 
189 const struct ahci_device *
190 ahci_lookup_device(struct pci_attach_args *pa)
191 {
192 	int				i;
193 	const struct ahci_device	*ad;
194 
195 	for (i = 0; i < (sizeof(ahci_devices) / sizeof(ahci_devices[0])); i++) {
196 		ad = &ahci_devices[i];
197 		if (ad->ad_vendor == PCI_VENDOR(pa->pa_id) &&
198 		    ad->ad_product == PCI_PRODUCT(pa->pa_id))
199 			return (ad);
200 	}
201 
202 	return (NULL);
203 }
204 
205 int
206 ahci_no_match(struct pci_attach_args *pa)
207 {
208 	return (0);
209 }
210 
211 int
212 ahci_vt8251_attach(struct ahci_softc *sc, struct pci_attach_args *pa)
213 {
214 	sc->sc_flags |= AHCI_F_NO_NCQ;
215 
216 	return (0);
217 }
218 
219 void
220 ahci_ati_sb_idetoahci(struct ahci_softc *sc, struct pci_attach_args *pa)
221 {
222 	pcireg_t			magic;
223 
224 	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
225 		magic = pci_conf_read(pa->pa_pc, pa->pa_tag,
226 		    AHCI_PCI_ATI_SB600_MAGIC);
227 		pci_conf_write(pa->pa_pc, pa->pa_tag,
228 		    AHCI_PCI_ATI_SB600_MAGIC,
229 		    magic | AHCI_PCI_ATI_SB600_LOCKED);
230 
231 		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG,
232 		    PCI_CLASS_MASS_STORAGE << PCI_CLASS_SHIFT |
233 		    PCI_SUBCLASS_MASS_STORAGE_SATA << PCI_SUBCLASS_SHIFT |
234 		    PCI_INTERFACE_SATA_AHCI10 << PCI_INTERFACE_SHIFT |
235 		    PCI_REVISION(pa->pa_class) << PCI_REVISION_SHIFT);
236 
237 		pci_conf_write(pa->pa_pc, pa->pa_tag,
238 		    AHCI_PCI_ATI_SB600_MAGIC, magic);
239 	}
240 }
241 
242 int
243 ahci_ati_sb600_attach(struct ahci_softc *sc, struct pci_attach_args *pa)
244 {
245 	ahci_ati_sb_idetoahci(sc, pa);
246 
247 	sc->sc_flags |= AHCI_F_IPMS_PROBE;
248 
249 	return (0);
250 }
251 
252 int
253 ahci_ati_sb700_attach(struct ahci_softc *sc, struct pci_attach_args *pa)
254 {
255 	ahci_ati_sb_idetoahci(sc, pa);
256 
257 	sc->sc_flags |= AHCI_F_IPMS_PROBE;
258 
259 	return (0);
260 }
261 
262 int
263 ahci_amd_hudson2_attach(struct ahci_softc *sc, struct pci_attach_args *pa)
264 {
265 	ahci_ati_sb_idetoahci(sc, pa);
266 
267 	sc->sc_flags |= AHCI_F_IPMS_PROBE;
268 
269 	return (0);
270 }
271 
272 int
273 ahci_intel_attach(struct ahci_softc *sc, struct pci_attach_args *pa)
274 {
275 	sc->sc_flags |= AHCI_F_NO_PMP;
276 
277 	return (0);
278 }
279 
280 int
281 ahci_samsung_attach(struct ahci_softc *sc, struct pci_attach_args *pa)
282 {
283 	/*
284 	 * Disable MSI with the Samsung S4LN053X01 SSD controller as found
285 	 * in some Apple MacBook Air models such as the 6,1 and 6,2, as well
286 	 * as the XP941 SSD controller.
287 	 * https://bugzilla.kernel.org/show_bug.cgi?id=60731
288 	 * https://bugzilla.kernel.org/show_bug.cgi?id=89171
289 	 */
290 	sc->sc_flags |= AHCI_F_NO_MSI;
291 
292 	return (0);
293 }
294 
295 int
296 ahci_pci_match(struct device *parent, void *match, void *aux)
297 {
298 	struct pci_attach_args		*pa = aux;
299 	const struct ahci_device	*ad;
300 
301 	ad = ahci_lookup_device(pa);
302 	if (ad != NULL) {
303 		/* the device may need special checks to see if it matches */
304 		if (ad->ad_match != NULL)
305 			return (ad->ad_match(pa));
306 
307 		return (2); /* match higher than pciide */
308 	}
309 
310 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE &&
311 	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_SATA &&
312 	    PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_SATA_AHCI10)
313 		return (2);
314 
315 	return (0);
316 }
317 
318 void
319 ahci_pci_attach(struct device *parent, struct device *self, void *aux)
320 {
321 	struct ahci_pci_softc		*psc = (struct ahci_pci_softc *)self;
322 	struct ahci_softc		*sc = &psc->psc_ahci;
323 	struct pci_attach_args		*pa = aux;
324 	const struct ahci_device	*ad;
325 	pci_intr_handle_t		ih;
326 
327 	psc->psc_pc = pa->pa_pc;
328 	psc->psc_tag = pa->pa_tag;
329 	sc->sc_dmat = pa->pa_dmat;
330 
331 	ad = ahci_lookup_device(pa);
332 	if (ad != NULL && ad->ad_attach != NULL) {
333 		if (ad->ad_attach(sc, pa) != 0) {
334 			/* error should be printed by ad_attach */
335 			return;
336 		}
337 	}
338 
339 	if (sc->sc_flags & AHCI_F_NO_MSI)
340 		pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED;
341 
342 	if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
343 		printf(": unable to map interrupt\n");
344 		return;
345 	}
346 	printf(": %s,", pci_intr_string(pa->pa_pc, ih));
347 
348 	if (ahci_map_regs(psc, pa) != 0) {
349 		/* error already printed by ahci_map_regs */
350 		return;
351 	}
352 
353 	if (ahci_map_intr(psc, pa, ih) != 0) {
354 		/* error already printed by ahci_map_intr */
355 		goto unmap;
356 	}
357 
358 	if (ahci_attach(sc) != 0) {
359 		/* error printed by ahci_attach */
360 		goto unmap;
361 	}
362 
363 	return;
364 
365 unmap:
366 	ahci_unmap_regs(psc);
367 	return;
368 }
369 
370 int
371 ahci_pci_detach(struct device *self, int flags)
372 {
373 	struct ahci_pci_softc		*psc = (struct ahci_pci_softc *)self;
374 	struct ahci_softc		*sc = &psc->psc_ahci;
375 
376 	ahci_detach(sc, flags);
377 
378 	ahci_unmap_intr(psc);
379 	ahci_unmap_regs(psc);
380 
381 	return (0);
382 }
383 
384 int
385 ahci_map_regs(struct ahci_pci_softc *psc, struct pci_attach_args *pa)
386 {
387 	pcireg_t			maptype;
388 	struct ahci_softc		*sc = &psc->psc_ahci;
389 
390 	maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, AHCI_PCI_BAR);
391 	if (pci_mapreg_map(pa, AHCI_PCI_BAR, maptype, 0, &sc->sc_iot,
392 	    &sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) {
393 		printf(" unable to map registers\n");
394 		return (1);
395 	}
396 
397 	return (0);
398 }
399 
400 void
401 ahci_unmap_regs(struct ahci_pci_softc *psc)
402 {
403 	struct ahci_softc		*sc = &psc->psc_ahci;
404 
405 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
406 	sc->sc_ios = 0;
407 }
408 
409 int
410 ahci_map_intr(struct ahci_pci_softc *psc, struct pci_attach_args *pa,
411     pci_intr_handle_t ih)
412 {
413 	struct ahci_softc		*sc = &psc->psc_ahci;
414 	sc->sc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO,
415 	    ahci_intr, sc, DEVNAME(sc));
416 	if (sc->sc_ih == NULL) {
417 		printf("%s: unable to map interrupt\n", DEVNAME(sc));
418 		return (1);
419 	}
420 
421 	return (0);
422 }
423 
424 void
425 ahci_unmap_intr(struct ahci_pci_softc *psc)
426 {
427 	struct ahci_softc		*sc = &psc->psc_ahci;
428 	pci_intr_disestablish(psc->psc_pc, sc->sc_ih);
429 }
430 
431 int
432 ahci_pci_activate(struct device *self, int act)
433 {
434 	struct ahci_pci_softc		*psc = (struct ahci_pci_softc *)self;
435 	struct ahci_softc		*sc = &psc->psc_ahci;
436 	return ahci_activate((struct device *)sc, act);
437 }
438