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