summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2007-01-04 11:37:13 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2007-01-04 11:37:13 +0000
commit02995ecbc60e5f29215ac125bd1592309b0b46d6 (patch)
treedf7ab05107439fa97d8f53a7a64228255a604a5e /sys/dev
parent6c3f8db074d16bf614764a9e2f85e9b2d92f4f86 (diff)
allocate the dmamem that each port will need, and hopefully point our
structs at all the right bits of it. the dma addresses arent taken care of yet, just the kva ones.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/ahci.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/sys/dev/pci/ahci.c b/sys/dev/pci/ahci.c
index c279da9380f..ec872c296de 100644
--- a/sys/dev/pci/ahci.c
+++ b/sys/dev/pci/ahci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ahci.c,v 1.32 2007/01/04 08:39:21 dlg Exp $ */
+/* $OpenBSD: ahci.c,v 1.33 2007/01/04 11:37:12 dlg Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
@@ -145,6 +145,7 @@ struct ahci_prdt {
u_int32_t flags;
} __packed;
+/* this makes ahci_cmd 512 bytes, which is good for alignment */
#define AHCI_MAX_PRDT 24
struct ahci_cmd {
@@ -174,6 +175,10 @@ struct ahci_dmamem {
struct ahci_softc;
struct ahci_ccb {
+ int ccb_id;
+
+ struct ahci_cmd *ccb_cmd;
+
bus_dmamap_t ccb_dmamap;
TAILQ_ENTRY(ahci_ccb) ccb_entry;
@@ -183,10 +188,12 @@ struct ahci_port {
struct ahci_softc *ap_sc;
bus_space_handle_t ap_ioh;
+ struct ahci_dmamem *ap_dmamem;
+ struct ahci_rfis *ap_rfis;
+ struct ahci_cmd_list *ap_cmd_list;
+
struct ahci_ccb *ap_ccbs;
TAILQ_HEAD(, ahci_ccb) ap_ccb_free;
-
- struct ahci_dmamem *ap_dmamem;
};
struct ahci_softc {
@@ -425,6 +432,7 @@ ahci_port_alloc(struct ahci_softc *sc, u_int port)
{
struct ahci_port *ap;
struct ahci_ccb *ccb;
+ u_int8_t *kva;
int i;
ap = malloc(sizeof(struct ahci_port), M_DEVBUF, M_NOWAIT);
@@ -454,7 +462,17 @@ ahci_port_alloc(struct ahci_softc *sc, u_int port)
goto freeccbs;
}
- /* XXX alloc dma mem */
+ /* calculate the size of the dmaable memory this port will need. */
+ i = sizeof(struct ahci_cmd) * sc->sc_ncmds +
+ sizeof(struct ahci_rfis) +
+ sizeof(struct ahci_cmd_list) * sc->sc_ncmds;
+ ap->ap_dmamem = ahci_dmamem_alloc(sc, i);
+ if (ap->ap_dmamem == NULL) {
+ printf("unable to allocate dmamem for port %d\n", DEVNAME(sc),
+ port);
+ goto freeccbs;
+ }
+ kva = AHCI_DMA_KVA(ap->ap_dmamem);
for (i = 0; i < sc->sc_ncmds; i++) {
ccb = &ap->ap_ccbs[i];
@@ -466,11 +484,18 @@ ahci_port_alloc(struct ahci_softc *sc, u_int port)
goto freemaps;
}
- /* XXX point ccb at its cmd structures in dma mem */
+ ccb->ccb_id = i;
+ ccb->ccb_cmd = (struct ahci_cmd *)kva;
+ kva += sizeof(struct ahci_cmd);
ahci_put_ccb(ap, ccb);
}
+ ap->ap_rfis = (struct ahci_rfis *)kva;
+ kva += sizeof(struct ahci_rfis);
+
+ ap->ap_cmd_list = (struct ahci_cmd_list *)kva;
+
sc->sc_ports[port] = ap;
return (0);
@@ -478,7 +503,7 @@ ahci_port_alloc(struct ahci_softc *sc, u_int port)
freemaps:
while ((ccb = ahci_get_ccb(ap)) != NULL)
bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
- /* XXX free dma mem */
+ ahci_dmamem_free(sc, ap->ap_dmamem);
freeccbs:
free(ap->ap_ccbs, M_DEVBUF);
freeport:
@@ -501,7 +526,7 @@ ahci_port_free(struct ahci_softc *sc, u_int port)
bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
}
- /* XXX free dma mem */
+ ahci_dmamem_free(sc, ap->ap_dmamem);
/* bus_space(9) says we dont free the subregions handle */
free(ap->ap_ccbs, M_DEVBUF);
free(ap, M_DEVBUF);