From owner-p4-projects@FreeBSD.ORG Thu Oct 5 00:54:06 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5EB2816A416; Thu, 5 Oct 2006 00:54:06 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E949816A40F for ; Thu, 5 Oct 2006 00:54:05 +0000 (UTC) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id AECBC43D46 for ; Thu, 5 Oct 2006 00:54:05 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k950s5rN082720 for ; Thu, 5 Oct 2006 00:54:05 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k950s5e0082716 for perforce@freebsd.org; Thu, 5 Oct 2006 00:54:05 GMT (envelope-from imp@freebsd.org) Date: Thu, 5 Oct 2006 00:54:05 GMT Message-Id: <200610050054.k950s5e0082716@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 107283 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Oct 2006 00:54:06 -0000 http://perforce.freebsd.org/chv.cgi?CH=107283 Change 107283 by imp@imp_lighthouse on 2006/10/05 00:53:44 First cut at a rock-simple bounce buffer for the stupid write path. Also, first cut at the write path. It seems to work.. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91_mci.c#24 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91_mci.c#24 (text+ko) ==== @@ -61,6 +61,8 @@ #include "mmcbr_if.h" +#define BBSZ 512 + struct at91_mci_softc { void *intrhand; /* Interrupt handle */ device_t dev; @@ -78,6 +80,7 @@ int bus_busy; struct mmc_request *req; struct mmc_command *curcmd; + char bounce_buffer[BBSZ]; }; static inline uint32_t @@ -313,9 +316,13 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd) { uint32_t cmdr, ier = 0, mr; + uint32_t *src, *dst; + int i; struct mmc_data *data; struct mmc_request *req; size_t block_size = 1 << 9; // Fixed, per mmc/sd spec for 2GB cards + void *vaddr; + bus_addr_t paddr; sc->curcmd = cmd; data = cmd->data; @@ -358,29 +365,41 @@ WR4(sc, MCI_MR, mr | (block_size << 16) | MCI_MR_PDCMODE); WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS); if (cmdr & MCI_CMDR_TRCMD_START) { + if (cmdr & MCI_CMDR_TRDIR) + vaddr = cmd->data->data; + else { + if (data->len != BBSZ) + panic("Write multiblock write support"); + vaddr = sc->bounce_buffer; + src = (uint32_t *)cmd->data->data; + dst = (uint32_t *)vaddr; + for (i = 0; i < data->len / 4; i++) + dst[i] = bswap32(src[i]); + } data->xfer_len = 0; + if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, data->len, + at91_mci_getaddr, &paddr, 0) != 0) { + if (req->cmd->flags & STOP_STARTED) + req->stop->error = MMC_ERR_NO_MEMORY; + else + req->cmd->error = MMC_ERR_NO_MEMORY; + sc->req = NULL; + sc->curcmd = NULL; + req->done(req); + return; + } + sc->mapped++; if (cmdr & MCI_CMDR_TRDIR) { - void *vaddr = cmd->data->data; - bus_addr_t paddr; - - if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, - data->len, at91_mci_getaddr, &paddr, 0) != 0) { - if (req->cmd->flags & STOP_STARTED) - req->stop->error = MMC_ERR_NO_MEMORY; - else - req->cmd->error = MMC_ERR_NO_MEMORY; - sc->req = NULL; - sc->curcmd = NULL; - req->done(req); - return; - } - sc->mapped++; bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREREAD); WR4(sc, PDC_RPR, paddr); WR4(sc, PDC_RCR, data->len / 4); ier = MCI_SR_ENDRX; - } else - panic("Write write support"); + } else { + bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREWRITE); + WR4(sc, PDC_TPR, paddr); + WR4(sc, PDC_TCR, data->len / 4); + ier = MCI_SR_TXBUFE; + } } // printf("CMDR %x ARGR %x with data\n", cmdr, cmd->arg); WR4(sc, MCI_ARGR, cmd->arg); @@ -495,6 +514,18 @@ } static void +at91_mci_xmit_done(struct at91_mci_softc *sc) +{ + // Finish up the sequence... + WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS); + WR4(sc, MCI_IDR, MCI_SR_TXBUFE); + WR4(sc, MCI_IER, MCI_SR_NOTBUSY); + bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->dmatag, sc->map); + sc->mapped--; +} + +static void at91_mci_intr(void *arg) { struct at91_mci_softc *sc = (struct at91_mci_softc*)arg; @@ -527,7 +558,7 @@ } else { if (sr & MCI_SR_TXBUFE) { // printf("TXBUFE\n"); -//XXX at91_mci_xmit_done(sc); + at91_mci_xmit_done(sc); } if (sr & MCI_SR_RXBUFF) { // printf("RXBUFF\n"); @@ -543,6 +574,7 @@ } if (sr & MCI_SR_NOTBUSY) { // printf("NOTBUSY\n"); + WR4(sc, MCI_IDR, MCI_SR_NOTBUSY); WR4(sc, MCI_IER, MCI_SR_CMDRDY); } if (sr & MCI_SR_DTIP) {