summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter Murphy <wmurphy@google.com>2012-10-29 05:24:03 +0000
committerTom Rini <trini@ti.com>2012-11-02 15:20:43 -0700
commitfe1f808ce79de0caa4674340958f02780b2f81f9 (patch)
tree41192d4b7e04eea0e6565c8042a0a48733d4cc86
parent766b16fe180087d8c59a79a4f6a92d1a500fa524 (diff)
downloadu-boot-imx-fe1f808ce79de0caa4674340958f02780b2f81f9.zip
u-boot-imx-fe1f808ce79de0caa4674340958f02780b2f81f9.tar.gz
u-boot-imx-fe1f808ce79de0caa4674340958f02780b2f81f9.tar.bz2
ahci: Expand HDD Logical Block addressability up to 32 bits
Currently, this driver uses a 28bit interface to AHCI, this limits the number of blocks addressable to 2^28, or the max disk size to 512(2^28) or about 137GB. This change allows supporting drives up to about 2TB. Testing this is a bit difficult. There is test code that can be inserted into U-Boot that will write test patterns into certain unused blocks. These patterns can be manually checked using 'dd' after boot. Another way is to confirm the original error that exposed this bug is fixed. IOW: see if AU (Auto Update) will now work on the drive. Also, check that there are no warning messages from the 'cgpt' utility. Signed-off-by: Walter Murphy <wmurphy@chromium.org> Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r--drivers/block/ahci.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index 963efec..8c785ae 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -707,7 +707,7 @@ static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
fis[0] = 0x27; /* Host to device FIS. */
fis[1] = 1 << 7; /* Command FIS. */
/* Command byte (read/write). */
- fis[2] = is_write ? ATA_CMD_WR_DMA : ATA_CMD_RD_DMA;
+ fis[2] = is_write ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
while (blocks) {
u16 now_blocks; /* number of blocks per iteration */
@@ -721,11 +721,15 @@ static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
return -EIO;
}
- /* LBA address, only support LBA28 in this driver */
+ /* LBA48 SATA command but only use 32bit address range within
+ * that. The next smaller command range (28bit) is too small.
+ */
fis[4] = (lba >> 0) & 0xff;
fis[5] = (lba >> 8) & 0xff;
fis[6] = (lba >> 16) & 0xff;
- fis[7] = ((lba >> 24) & 0xf) | 0xe0;
+ fis[7] = 1 << 6; /* device reg: set LBA mode */
+ fis[8] = ((lba >> 24) & 0xff);
+ fis[3] = 0xe0; /* features */
/* Block (sector) count */
fis[12] = (now_blocks >> 0) & 0xff;
@@ -963,7 +967,7 @@ static int ata_io_flush(u8 port)
memset(fis, 0, 20);
fis[0] = 0x27; /* Host to device FIS. */
fis[1] = 1 << 7; /* Command FIS. */
- fis[2] = ATA_CMD_FLUSH;
+ fis[2] = ATA_CMD_FLUSH_EXT;
memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
ahci_fill_cmd_slot(pp, cmd_fis_len);