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