[U-Boot] [PATCH] IDE: Improving speed on reading data Part 1/1
Stefan Althoefer
stefan.althoefer at web.de
Thu Dec 4 22:09:24 CET 2008
[PATCH] IDE: Improving speed on reading data
This patch improves the speed when reading blocks from
IDE devices by reading more than one block at a time. Up to
128 blocks are requested in one read command.
On my testplatform (Janz emPC-A400 with CompactFLASH card)
this nearly doubled speed.
Also the ide_wait() code was rewritten to have lower latency
by polling more frequently for status.
The patch is against "latest" u-boot git-repository
Please (still) be patient if style of submission or patches are
offending.
Signed-off-by: Stefan Althoefer <stefan.althoefer at web.de>
----
diff -uprN u-boot-orig//common/cmd_ide.c u-boot/common/cmd_ide.c
--- u-boot-orig//common/cmd_ide.c 2008-12-02 17:25:31.000000000 +0100
+++ u-boot/common/cmd_ide.c 2008-12-03 09:22:29.000000000 +0100
@@ -1302,6 +1361,7 @@ ulong ide_read (int device, lbaint_t blk
ulong n = 0;
unsigned char c;
unsigned char pwrsave=0; /* power save */
+ ulong scnt;
#ifdef CONFIG_LBA48
unsigned char lba48 = 0;
@@ -1346,7 +1406,7 @@ ulong ide_read (int device, lbaint_t blk
}
- while (blkcnt-- > 0) {
+ while (blkcnt > 0) {
c = ide_wait (device, IDE_TIME_OUT);
@@ -1368,7 +1428,8 @@ ulong ide_read (int device, lbaint_t blk
#endif
}
#endif
- ide_outb (device, ATA_SECT_CNT, 1);
+ scnt = (blkcnt > 128) ? 128 : blkcnt;
+ ide_outb (device, ATA_SECT_CNT, scnt);
ide_outb (device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
ide_outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
ide_outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
@@ -1387,32 +1448,36 @@ ulong ide_read (int device, lbaint_t blk
ide_outb (device, ATA_COMMAND, ATA_CMD_READ);
}
- udelay (50);
+ while (scnt > 0) {
+ udelay (50);
- if(pwrsave) {
- c = ide_wait (device, IDE_SPIN_UP_TIME_OUT); /* may take up to 4 sec */
- pwrsave=0;
- } else {
- c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */
- }
+ if(pwrsave) {
+ c = ide_wait (device, IDE_SPIN_UP_TIME_OUT); /* may take up to 4 sec */
+ pwrsave=0;
+ } else {
+ c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */
+ }
- if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
+ if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
#if defined(CONFIG_SYS_64BIT_LBA) && defined(CONFIG_SYS_64BIT_VSPRINTF)
- printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n",
- device, blknr, c);
+ printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n",
+ device, blknr, c);
#else
- printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
- device, (ulong)blknr, c);
+ printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
+ device, (ulong)blknr, c);
#endif
- break;
- }
+ break;
+ }
- input_data (device, buffer, ATA_SECTORWORDS);
- (void) ide_inb (device, ATA_STATUS); /* clear IRQ */
-
- ++n;
- ++blknr;
- buffer += ATA_BLOCKSIZE;
+ input_data (device, buffer, ATA_SECTORWORDS);
+ (void) ide_inb (device, ATA_STATUS); /* clear IRQ */
+
+ ++n;
+ ++blknr;
+ --blkcnt;
+ --scnt;
+ buffer += ATA_BLOCKSIZE;
+ }
}
IDE_READ_E:
ide_led (DEVICE_LED(device), 0); /* LED off */
@@ -1548,11 +1613,11 @@ OUT:
*/
static uchar ide_wait (int dev, ulong t)
{
- ulong delay = 10 * t; /* poll every 100 us */
+ ulong delay = (1000/5) * t; /* poll every 5 us */
uchar c;
while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
- udelay (100);
+ udelay (5);
if (delay-- == 0) {
break;
}
More information about the U-Boot
mailing list