1 /* $OpenBSD: ahci_acpi.c,v 1.5 2022/04/06 18:59:27 naddy Exp $ */ 2 /* 3 * Copyright (c) 2018 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/malloc.h> 20 #include <sys/systm.h> 21 22 #include <dev/acpi/acpireg.h> 23 #include <dev/acpi/acpivar.h> 24 #include <dev/acpi/acpidev.h> 25 #include <dev/acpi/amltypes.h> 26 #include <dev/acpi/dsdt.h> 27 28 #undef DEVNAME 29 #include <dev/ic/ahcireg.h> 30 #include <dev/ic/ahcivar.h> 31 32 struct ahci_acpi_softc { 33 struct ahci_softc sc; 34 struct acpi_softc *sc_acpi; 35 struct aml_node *sc_node; 36 void *sc_ih; 37 }; 38 39 int ahci_acpi_match(struct device *, void *, void *); 40 void ahci_acpi_attach(struct device *, struct device *, void *); 41 42 const struct cfattach ahci_acpi_ca = { 43 sizeof(struct ahci_acpi_softc), ahci_acpi_match, ahci_acpi_attach 44 }; 45 46 int 47 ahci_acpi_match(struct device *parent, void *match, void *aux) 48 { 49 struct acpi_attach_args *aaa = aux; 50 51 if (aaa->aaa_naddr < 1 || aaa->aaa_nirq < 1) 52 return 0; 53 return acpi_matchcls(aaa, PCI_CLASS_MASS_STORAGE, 54 PCI_SUBCLASS_MASS_STORAGE_SATA, PCI_INTERFACE_SATA_AHCI10); 55 } 56 57 void 58 ahci_acpi_attach(struct device *parent, struct device *self, void *aux) 59 { 60 struct ahci_acpi_softc *sc = (struct ahci_acpi_softc *)self; 61 struct acpi_attach_args *aaa = aux; 62 63 sc->sc_acpi = (struct acpi_softc *)parent; 64 sc->sc_node = aaa->aaa_node; 65 printf(" %s", sc->sc_node->name); 66 67 printf(" addr 0x%llx/0x%llx", aaa->aaa_addr[0], aaa->aaa_size[0]); 68 printf(" irq %d", aaa->aaa_irq[0]); 69 70 sc->sc.sc_iot = aaa->aaa_bst[0]; 71 sc->sc.sc_ios = aaa->aaa_size[0]; 72 sc->sc.sc_dmat = aaa->aaa_dmat; 73 74 if (bus_space_map(sc->sc.sc_iot, aaa->aaa_addr[0], aaa->aaa_size[0], 75 0, &sc->sc.sc_ioh)) { 76 printf(": can't map registers\n"); 77 return; 78 } 79 80 sc->sc_ih = acpi_intr_establish(aaa->aaa_irq[0], aaa->aaa_irq_flags[0], 81 IPL_BIO, ahci_intr, sc, sc->sc.sc_dev.dv_xname); 82 if (sc->sc_ih == NULL) { 83 printf(": can't establish interrupt\n"); 84 return; 85 } 86 87 printf(":"); 88 89 if (ahci_attach(&sc->sc) != 0) { 90 /* error printed by ahci_attach */ 91 goto irq; 92 } 93 94 return; 95 96 irq: 97 return; 98 } 99