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