summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2006-12-09 07:02:45 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2006-12-09 07:02:45 +0000
commit84f238046bd2253470fd9a5426c6b8a707960491 (patch)
tree1618830bfc31eebbfbae9ad44d3eceef6301fbb5 /sys/dev
parent770403284bd8e13d2efc1106f5a772db03815db3 (diff)
reset the hba and set the enable bit.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/ahci.c83
1 files changed, 61 insertions, 22 deletions
diff --git a/sys/dev/pci/ahci.c b/sys/dev/pci/ahci.c
index dcc2bca1b7b..a7ed9ce66ae 100644
--- a/sys/dev/pci/ahci.c
+++ b/sys/dev/pci/ahci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ahci.c,v 1.7 2006/12/09 06:42:53 dlg Exp $ */
+/* $OpenBSD: ahci.c,v 1.8 2006/12/09 07:02:44 dlg Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
@@ -110,6 +110,8 @@ struct cfdriver ahci_cd = {
int ahci_intr(void *);
int ahci_map_pci(struct ahci_softc *, struct pci_attach_args *);
+void ahci_unmap_pci(struct ahci_softc *, struct pci_attach_args *);
+int ahci_init(struct ahci_softc *);
u_int32_t ahci_read(struct ahci_softc *, bus_size_t);
void ahci_write(struct ahci_softc *, bus_size_t, u_int32_t);
@@ -135,16 +137,22 @@ ahci_attach(struct device *parent, struct device *self, void *aux)
/* error already printed by ahci_map_pci */
return;
}
+
+ if (ahci_init(sc) != 0) {
+ /* error already printed by ahci_init */
+ goto unmap;
+ }
+
+unmap:
+ ahci_unmap_pci(sc, pa);
}
int
ahci_map_pci(struct ahci_softc *sc, struct pci_attach_args *pa)
{
pcireg_t memtype;
- u_int32_t vs;
pci_intr_handle_t ih;
const char *intrstr;
- const char *revision;
memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, AHCI_PCI_BAR);
if (pci_mapreg_map(pa, AHCI_PCI_BAR, memtype, 0, &sc->sc_iot,
@@ -153,23 +161,6 @@ ahci_map_pci(struct ahci_softc *sc, struct pci_attach_args *pa)
return (1);
}
- vs = ahci_read(sc, AHCI_REG_VS);
- switch (vs) {
- case AHCI_REG_VS_0_95:
- revision = "0.95";
- break;
- case AHCI_REG_VS_1_0:
- revision = "1.0";
- break;
- case AHCI_REG_VS_1_1:
- revision = "1.1";
- break;
-
- default:
- printf(": unsupported revision (0x%08x)\n", vs);
- goto unmap;
- }
-
if (pci_intr_map(pa, &ih) != 0) {
printf(": unable to map interrupt\n");
goto unmap;
@@ -183,8 +174,7 @@ ahci_map_pci(struct ahci_softc *sc, struct pci_attach_args *pa)
intrstr == NULL ? "" : intrstr);
goto unmap;
}
-
- printf(": %s, AHCI %s\n", intrstr, revision);
+ printf(": %s", intrstr);
return (0);
@@ -194,6 +184,55 @@ unmap:
return (1);
}
+void
+ahci_unmap_pci(struct ahci_softc *sc, struct pci_attach_args *pa)
+{
+ pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
+
+ bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
+ sc->sc_ios = 0;
+}
+
+int
+ahci_init(struct ahci_softc *sc)
+{
+ u_int32_t vs;
+ const char *revision;
+
+ /* reset the controller */
+ ahci_write(sc, AHCI_REG_GHC, AHCI_REG_GHC_HR);
+ if (ahci_wait_ne(sc, AHCI_REG_GHC, AHCI_REG_GHC_HR,
+ AHCI_REG_GHC_HR) != 0) {
+ printf(": unable to reset controller\n");
+ return (1);
+ }
+
+ /* enable ahci */
+ ahci_write(sc, AHCI_REG_GHC, AHCI_REG_GHC_AE);
+
+ /* check the revision */
+ vs = ahci_read(sc, AHCI_REG_VS);
+ switch (vs) {
+ case AHCI_REG_VS_0_95:
+ revision = "0.95";
+ break;
+ case AHCI_REG_VS_1_0:
+ revision = "1.0";
+ break;
+ case AHCI_REG_VS_1_1:
+ revision = "1.1";
+ break;
+
+ default:
+ printf(": unsupported AHCI revision 0x%08x\n", vs);
+ return (1);
+ }
+
+ printf(": AHCI %s\n", revision);
+
+ return (0);
+}
+
int
ahci_intr(void *arg)
{