1 /* $OpenBSD: ahci_pci.c,v 1.6 2014/07/10 14:21:20 deraadt 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/atascsi.h> 39 #include <dev/ata/pmreg.h> 40 41 #include <dev/ic/ahcireg.h> 42 #include <dev/ic/ahcivar.h> 43 44 #define AHCI_PCI_BAR 0x24 45 #define AHCI_PCI_ATI_SB600_MAGIC 0x40 46 #define AHCI_PCI_ATI_SB600_LOCKED 0x01 47 #define AHCI_PCI_INTERFACE 0x01 48 49 struct ahci_pci_softc { 50 struct ahci_softc psc_ahci; 51 52 pci_chipset_tag_t psc_pc; 53 pcitag_t psc_tag; 54 55 int psc_flags; 56 }; 57 58 struct ahci_device { 59 pci_vendor_id_t ad_vendor; 60 pci_product_id_t ad_product; 61 int (*ad_match)(struct pci_attach_args *); 62 int (*ad_attach)(struct ahci_softc *, 63 struct pci_attach_args *); 64 }; 65 66 const struct ahci_device *ahci_lookup_device(struct pci_attach_args *); 67 68 int ahci_no_match(struct pci_attach_args *); 69 int ahci_vt8251_attach(struct ahci_softc *, 70 struct pci_attach_args *); 71 void ahci_ati_sb_idetoahci(struct ahci_softc *, 72 struct pci_attach_args *pa); 73 int ahci_ati_sb600_attach(struct ahci_softc *, 74 struct pci_attach_args *); 75 int ahci_ati_sb700_attach(struct ahci_softc *, 76 struct pci_attach_args *); 77 int ahci_amd_hudson2_attach(struct ahci_softc *, 78 struct pci_attach_args *); 79 int ahci_intel_attach(struct ahci_softc *, 80 struct pci_attach_args *); 81 int ahci_samsung_attach(struct ahci_softc *, 82 struct pci_attach_args *); 83 84 static const struct ahci_device ahci_devices[] = { 85 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON2_SATA_1, 86 NULL, ahci_amd_hudson2_attach }, 87 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON2_SATA_2, 88 NULL, ahci_amd_hudson2_attach }, 89 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON2_SATA_3, 90 NULL, ahci_amd_hudson2_attach }, 91 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON2_SATA_4, 92 NULL, ahci_amd_hudson2_attach }, 93 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON2_SATA_5, 94 NULL, ahci_amd_hudson2_attach }, 95 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON2_SATA_6, 96 NULL, ahci_amd_hudson2_attach }, 97 98 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB600_SATA, 99 NULL, ahci_ati_sb600_attach }, 100 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SBX00_SATA_1, 101 NULL, ahci_ati_sb700_attach }, 102 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SBX00_SATA_2, 103 NULL, ahci_ati_sb700_attach }, 104 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SBX00_SATA_3, 105 NULL, ahci_ati_sb700_attach }, 106 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SBX00_SATA_4, 107 NULL, ahci_ati_sb700_attach }, 108 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SBX00_SATA_5, 109 NULL, ahci_ati_sb700_attach }, 110 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SBX00_SATA_6, 111 NULL, ahci_ati_sb700_attach }, 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_XP941, 151 NULL, ahci_samsung_attach }, 152 153 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8251_SATA, 154 ahci_no_match, ahci_vt8251_attach } 155 }; 156 157 int ahci_pci_match(struct device *, void *, void *); 158 void ahci_pci_attach(struct device *, struct device *, 159 void *); 160 int ahci_pci_detach(struct device *, int); 161 int ahci_pci_activate(struct device *, int); 162 163 #ifdef HIBERNATE 164 #include <sys/hibernate.h> 165 #include <sys/disk.h> 166 #include <sys/disklabel.h> 167 168 #include <scsi/scsi_all.h> 169 #include <scsi/scsiconf.h> 170 171 void ahci_hibernate_io_start(struct ahci_port *, 172 struct ahci_ccb *); 173 int ahci_hibernate_io_poll(struct ahci_port *, 174 struct ahci_ccb *); 175 void ahci_hibernate_load_prdt(struct ahci_ccb *); 176 177 int ahci_hibernate_io(dev_t dev, daddr_t blkno, 178 vaddr_t addr, size_t size, int wr, void *page); 179 #endif 180 181 struct cfattach ahci_pci_ca = { 182 sizeof(struct ahci_pci_softc), 183 ahci_pci_match, 184 ahci_pci_attach, 185 ahci_pci_detach, 186 ahci_pci_activate 187 }; 188 189 struct cfattach ahci_jmb_ca = { 190 sizeof(struct ahci_pci_softc), 191 ahci_pci_match, 192 ahci_pci_attach, 193 ahci_pci_detach 194 }; 195 196 int ahci_map_regs(struct ahci_pci_softc *, 197 struct pci_attach_args *); 198 void ahci_unmap_regs(struct ahci_pci_softc *); 199 int ahci_map_intr(struct ahci_pci_softc *, 200 struct pci_attach_args *, pci_intr_handle_t); 201 void ahci_unmap_intr(struct ahci_pci_softc *); 202 203 const struct ahci_device * 204 ahci_lookup_device(struct pci_attach_args *pa) 205 { 206 int i; 207 const struct ahci_device *ad; 208 209 for (i = 0; i < (sizeof(ahci_devices) / sizeof(ahci_devices[0])); i++) { 210 ad = &ahci_devices[i]; 211 if (ad->ad_vendor == PCI_VENDOR(pa->pa_id) && 212 ad->ad_product == PCI_PRODUCT(pa->pa_id)) 213 return (ad); 214 } 215 216 return (NULL); 217 } 218 219 int 220 ahci_no_match(struct pci_attach_args *pa) 221 { 222 return (0); 223 } 224 225 int 226 ahci_vt8251_attach(struct ahci_softc *sc, struct pci_attach_args *pa) 227 { 228 sc->sc_flags |= AHCI_F_NO_NCQ; 229 230 return (0); 231 } 232 233 void 234 ahci_ati_sb_idetoahci(struct ahci_softc *sc, struct pci_attach_args *pa) 235 { 236 pcireg_t magic; 237 238 if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) { 239 magic = pci_conf_read(pa->pa_pc, pa->pa_tag, 240 AHCI_PCI_ATI_SB600_MAGIC); 241 pci_conf_write(pa->pa_pc, pa->pa_tag, 242 AHCI_PCI_ATI_SB600_MAGIC, 243 magic | AHCI_PCI_ATI_SB600_LOCKED); 244 245 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG, 246 PCI_CLASS_MASS_STORAGE << PCI_CLASS_SHIFT | 247 PCI_SUBCLASS_MASS_STORAGE_SATA << PCI_SUBCLASS_SHIFT | 248 AHCI_PCI_INTERFACE << PCI_INTERFACE_SHIFT | 249 PCI_REVISION(pa->pa_class) << PCI_REVISION_SHIFT); 250 251 pci_conf_write(pa->pa_pc, pa->pa_tag, 252 AHCI_PCI_ATI_SB600_MAGIC, magic); 253 } 254 } 255 256 int 257 ahci_ati_sb600_attach(struct ahci_softc *sc, struct pci_attach_args *pa) 258 { 259 ahci_ati_sb_idetoahci(sc, pa); 260 261 sc->sc_flags |= AHCI_F_IPMS_PROBE; 262 263 return (0); 264 } 265 266 int 267 ahci_ati_sb700_attach(struct ahci_softc *sc, struct pci_attach_args *pa) 268 { 269 ahci_ati_sb_idetoahci(sc, pa); 270 271 sc->sc_flags |= AHCI_F_IPMS_PROBE; 272 273 return (0); 274 } 275 276 int 277 ahci_amd_hudson2_attach(struct ahci_softc *sc, struct pci_attach_args *pa) 278 { 279 ahci_ati_sb_idetoahci(sc, pa); 280 281 sc->sc_flags |= AHCI_F_IPMS_PROBE; 282 283 return (0); 284 } 285 286 int 287 ahci_intel_attach(struct ahci_softc *sc, struct pci_attach_args *pa) 288 { 289 sc->sc_flags |= AHCI_F_NO_PMP; 290 return (0); 291 } 292 293 int 294 ahci_samsung_attach(struct ahci_softc *sc, struct pci_attach_args *pa) 295 { 296 sc->sc_flags |= AHCI_F_NO_MSI; 297 return (0); 298 } 299 300 int 301 ahci_pci_match(struct device *parent, void *match, void *aux) 302 { 303 struct pci_attach_args *pa = aux; 304 const struct ahci_device *ad; 305 306 ad = ahci_lookup_device(pa); 307 if (ad != NULL) { 308 /* the device may need special checks to see if it matches */ 309 if (ad->ad_match != NULL) 310 return (ad->ad_match(pa)); 311 312 return (2); /* match higher than pciide */ 313 } 314 315 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE && 316 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_SATA && 317 PCI_INTERFACE(pa->pa_class) == AHCI_PCI_INTERFACE) 318 return (2); 319 320 return (0); 321 } 322 323 void 324 ahci_pci_attach(struct device *parent, struct device *self, void *aux) 325 { 326 struct ahci_pci_softc *psc = (struct ahci_pci_softc *)self; 327 struct ahci_softc *sc = &psc->psc_ahci; 328 struct pci_attach_args *pa = aux; 329 const struct ahci_device *ad; 330 pci_intr_handle_t ih; 331 int mapped = 0; 332 333 psc->psc_pc = pa->pa_pc; 334 psc->psc_tag = pa->pa_tag; 335 sc->sc_dmat = pa->pa_dmat; 336 337 ad = ahci_lookup_device(pa); 338 if (ad != NULL && ad->ad_attach != NULL) { 339 if (ad->ad_attach(sc, pa) != 0) { 340 /* error should be printed by ad_attach */ 341 return; 342 } 343 } 344 345 if (!(sc->sc_flags & AHCI_F_NO_MSI)) 346 mapped = pci_intr_map_msi(pa, &ih) != 0 ? 0 : 1; 347 348 if (!mapped && pci_intr_map(pa, &ih) != 0) { 349 printf(": unable to map interrupt\n"); 350 return; 351 } 352 printf(": %s,", pci_intr_string(pa->pa_pc, ih)); 353 354 if (ahci_map_regs(psc, pa) != 0) { 355 /* error already printed by ahci_map_regs */ 356 return; 357 } 358 359 if (ahci_map_intr(psc, pa, ih) != 0) { 360 /* error already printed by ahci_map_intr */ 361 goto unmap; 362 } 363 364 if (ahci_attach(sc) != 0) { 365 /* error printed by ahci_attach */ 366 goto unmap; 367 } 368 369 return; 370 371 unmap: 372 ahci_unmap_regs(psc); 373 return; 374 } 375 376 int 377 ahci_pci_detach(struct device *self, int flags) 378 { 379 struct ahci_pci_softc *psc = (struct ahci_pci_softc *)self; 380 struct ahci_softc *sc = &psc->psc_ahci; 381 382 ahci_detach(sc, flags); 383 384 ahci_unmap_intr(psc); 385 ahci_unmap_regs(psc); 386 387 return (0); 388 } 389 390 int 391 ahci_map_regs(struct ahci_pci_softc *psc, struct pci_attach_args *pa) 392 { 393 pcireg_t maptype; 394 struct ahci_softc *sc = &psc->psc_ahci; 395 396 maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, AHCI_PCI_BAR); 397 if (pci_mapreg_map(pa, AHCI_PCI_BAR, maptype, 0, &sc->sc_iot, 398 &sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) { 399 printf(" unable to map registers\n"); 400 return (1); 401 } 402 403 return (0); 404 } 405 406 void 407 ahci_unmap_regs(struct ahci_pci_softc *psc) 408 { 409 struct ahci_softc *sc = &psc->psc_ahci; 410 411 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 412 sc->sc_ios = 0; 413 } 414 415 int 416 ahci_map_intr(struct ahci_pci_softc *psc, struct pci_attach_args *pa, 417 pci_intr_handle_t ih) 418 { 419 struct ahci_softc *sc = &psc->psc_ahci; 420 sc->sc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO, 421 ahci_intr, sc, DEVNAME(sc)); 422 if (sc->sc_ih == NULL) { 423 printf("%s: unable to map interrupt\n", DEVNAME(sc)); 424 return (1); 425 } 426 427 return (0); 428 } 429 430 void 431 ahci_unmap_intr(struct ahci_pci_softc *psc) 432 { 433 struct ahci_softc *sc = &psc->psc_ahci; 434 pci_intr_disestablish(psc->psc_pc, sc->sc_ih); 435 } 436 437 int 438 ahci_pci_activate(struct device *self, int act) 439 { 440 struct ahci_pci_softc *psc = (struct ahci_pci_softc *)self; 441 struct ahci_softc *sc = &psc->psc_ahci; 442 return ahci_activate((struct device *)sc, act); 443 } 444