diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2007-01-04 11:37:13 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2007-01-04 11:37:13 +0000 |
commit | 02995ecbc60e5f29215ac125bd1592309b0b46d6 (patch) | |
tree | df7ab05107439fa97d8f53a7a64228255a604a5e /sys/dev/pci/ahci.c | |
parent | 6c3f8db074d16bf614764a9e2f85e9b2d92f4f86 (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/pci/ahci.c')
-rw-r--r-- | sys/dev/pci/ahci.c | 39 |
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); |