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