1 /* $OpenBSD: ahci_acpi.c,v 1.6 2024/10/09 00:38:25 jsg 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 NULL, ahci_activate 45 }; 46 47 int 48 ahci_acpi_match(struct device *parent, void *match, void *aux) 49 { 50 struct acpi_attach_args *aaa = aux; 51 52 if (aaa->aaa_naddr < 1 || aaa->aaa_nirq < 1) 53 return 0; 54 return acpi_matchcls(aaa, PCI_CLASS_MASS_STORAGE, 55 PCI_SUBCLASS_MASS_STORAGE_SATA, PCI_INTERFACE_SATA_AHCI10); 56 } 57 58 void 59 ahci_acpi_attach(struct device *parent, struct device *self, void *aux) 60 { 61 struct ahci_acpi_softc *sc = (struct ahci_acpi_softc *)self; 62 struct acpi_attach_args *aaa = aux; 63 64 sc->sc_acpi = (struct acpi_softc *)parent; 65 sc->sc_node = aaa->aaa_node; 66 printf(" %s", sc->sc_node->name); 67 68 printf(" addr 0x%llx/0x%llx", aaa->aaa_addr[0], aaa->aaa_size[0]); 69 printf(" irq %d", aaa->aaa_irq[0]); 70 71 sc->sc.sc_iot = aaa->aaa_bst[0]; 72 sc->sc.sc_ios = aaa->aaa_size[0]; 73 sc->sc.sc_dmat = aaa->aaa_dmat; 74 75 if (bus_space_map(sc->sc.sc_iot, aaa->aaa_addr[0], aaa->aaa_size[0], 76 0, &sc->sc.sc_ioh)) { 77 printf(": can't map registers\n"); 78 return; 79 } 80 81 sc->sc_ih = acpi_intr_establish(aaa->aaa_irq[0], aaa->aaa_irq_flags[0], 82 IPL_BIO, ahci_intr, sc, sc->sc.sc_dev.dv_xname); 83 if (sc->sc_ih == NULL) { 84 printf(": can't establish interrupt\n"); 85 return; 86 } 87 88 printf(":"); 89 90 if (ahci_attach(&sc->sc) != 0) { 91 /* error printed by ahci_attach */ 92 goto irq; 93 } 94 95 return; 96 97 irq: 98 return; 99 } 100