From patchwork Fri Oct 2 06:06:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Warren X-Patchwork-Id: 525394 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id DF72D1402C4 for ; Fri, 2 Oct 2015 16:07:17 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3C38B4B8D6; Fri, 2 Oct 2015 08:07:11 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8Exqljqhg0uQ; Fri, 2 Oct 2015 08:07:11 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 14CFD4B734; Fri, 2 Oct 2015 08:06:58 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id CA5814B889 for ; Fri, 2 Oct 2015 08:06:25 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id uSzJ8Ncu7ilA for ; Fri, 2 Oct 2015 08:06:25 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from avon.wwwdotorg.org (avon.wwwdotorg.org [70.85.31.133]) by theia.denx.de (Postfix) with ESMTPS id B28AC4B884 for ; Fri, 2 Oct 2015 08:06:21 +0200 (CEST) Received: from severn.wwwdotorg.org (unknown [192.168.65.5]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by avon.wwwdotorg.org (Postfix) with ESMTPS id 304CC66B1; Fri, 2 Oct 2015 00:06:20 -0600 (MDT) Received: from dart.wwwdotorg.org (localhost [127.0.0.1]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by severn.wwwdotorg.org (Postfix) with ESMTPSA id 29AA6E464C; Fri, 2 Oct 2015 00:06:19 -0600 (MDT) From: Stephen Warren To: Tom Rini Date: Fri, 2 Oct 2015 00:06:08 -0600 Message-Id: <1443765973-5897-5-git-send-email-swarren@wwwdotorg.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1443765973-5897-1-git-send-email-swarren@wwwdotorg.org> References: <1443765973-5897-1-git-send-email-swarren@wwwdotorg.org> X-NVConfidentiality: public X-Virus-Scanned: clamav-milter 0.98.6 at avon.wwwdotorg.org X-Virus-Status: Clean Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH V3 05/10] fat: ff: read max contiguous file data X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Enhance f_read() to find the maximum contiguous set of clusters to read, and read it all at once (which is fast) rather one by one (which is slow). Signed-off-by: Stephen Warren --- V3: New patch. --- fs/fat/ff.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/fs/fat/ff.c b/fs/fat/ff.c index 478daa7d6b0b..0df5a9ddcf7c 100644 --- a/fs/fat/ff.c +++ b/fs/fat/ff.c @@ -2593,7 +2593,7 @@ FRESULT f_read ( ) { FRESULT res; - DWORD clst, sect, remain; + DWORD clst, sect, remain, cfptr, cclst, maxclust; UINT rcnt, cc; BYTE csect, *rbuff = (BYTE*)buff; @@ -2614,27 +2614,46 @@ FRESULT f_read ( if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ if (!csect) { /* On the cluster boundary? */ - if (fp->fptr == 0) { /* On the top of the file? */ - clst = fp->sclust; /* Follow from the origin */ - } else { /* Middle or end of the file */ + maxclust = 0; + cfptr = fp->fptr; + cclst = fp->clust; + for (;;) { + if (cfptr == 0) { /* On the top of the file? */ + clst = fp->sclust; /* Follow from the origin */ + } else { /* Middle or end of the file */ #if _USE_FASTSEEK - if (fp->cltbl) - clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ - else + if (fp->cltbl) + clst = clmt_clust(fp, cfptr); /* Get cluster# from the CLMT */ + else #endif - clst = get_fat(fp->fs, fp->clust); /* Follow cluster chain on the FAT */ + clst = get_fat(fp->fs, cclst); /* Follow cluster chain on the FAT */ + } + if (clst < 2) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (!maxclust) { + fp->clust = clst; /* Update current cluster */ + } else { + if (clst != (cclst + 1)) + break; + } + maxclust++; + if ((maxclust * fp->fs->csize * SS(fp->fs)) >= btr) + break; + cclst = clst; + cfptr += fp->fs->csize * SS(fp->fs); } - if (clst < 2) ABORT(fp->fs, FR_INT_ERR); - if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); - fp->clust = clst; /* Update current cluster */ + } else { + maxclust = 1; } sect = clust2sect(fp->fs, fp->clust); /* Get current sector */ + if (maxclust > 1) + fp->clust += (maxclust - 1); if (!sect) ABORT(fp->fs, FR_INT_ERR); sect += csect; cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ if (cc) { /* Read maximum contiguous sectors directly */ - if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ - cc = fp->fs->csize - csect; + if (csect + cc > (fp->fs->csize * maxclust)) /* Clip at cluster boundary */ + cc = (fp->fs->csize * maxclust) - csect; if (disk_read(fp->fs->drv, rbuff, sect, cc) != RES_OK) ABORT(fp->fs, FR_DISK_ERR); #if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */