summaryrefslogtreecommitdiff
path: root/firmware/drivers/ata.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r--firmware/drivers/ata.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index d82fb173cc..7b9c4910cf 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -109,15 +109,15 @@ static long last_disk_activity = -1;
109static long power_off_tick = 0; 109static long power_off_tick = 0;
110#endif 110#endif
111 111
112static unsigned long total_sectors; 112static sector_t total_sectors;
113static int multisectors; /* number of supported multisectors */ 113static int multisectors; /* number of supported multisectors */
114static unsigned short identify_info[SECTOR_SIZE/2]; 114static unsigned short identify_info[ATA_IDENTIFY_WORDS];
115 115
116#ifdef MAX_PHYS_SECTOR_SIZE 116#ifdef MAX_PHYS_SECTOR_SIZE
117 117
118struct sector_cache_entry { 118struct sector_cache_entry {
119 bool inuse; 119 bool inuse;
120 unsigned long sectornum; /* logical sector */ 120 sector_t sectornum; /* logical sector */
121 unsigned char data[MAX_PHYS_SECTOR_SIZE]; 121 unsigned char data[MAX_PHYS_SECTOR_SIZE];
122}; 122};
123/* buffer for reading and writing large physical sectors */ 123/* buffer for reading and writing large physical sectors */
@@ -381,7 +381,7 @@ static ICODE_ATTR void copy_write_sectors(const unsigned char* buf,
381} 381}
382#endif /* !ATA_OPTIMIZED_WRITING */ 382#endif /* !ATA_OPTIMIZED_WRITING */
383 383
384static int ata_transfer_sectors(unsigned long start, 384static int ata_transfer_sectors(uint64_t start,
385 int incount, 385 int incount,
386 void* inbuf, 386 void* inbuf,
387 int write) 387 int write)
@@ -443,9 +443,9 @@ static int ata_transfer_sectors(unsigned long start,
443 ATA_OUT8(ATA_NSECTOR, count & 0xff); 443 ATA_OUT8(ATA_NSECTOR, count & 0xff);
444 ATA_OUT8(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */ 444 ATA_OUT8(ATA_SECTOR, (start >> 24) & 0xff); /* 31:24 */
445 ATA_OUT8(ATA_SECTOR, start & 0xff); /* 7:0 */ 445 ATA_OUT8(ATA_SECTOR, start & 0xff); /* 7:0 */
446 ATA_OUT8(ATA_LCYL, 0); /* 39:32 */ 446 ATA_OUT8(ATA_LCYL, (start >> 32) & 0xff); /* 39:32 */
447 ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */ 447 ATA_OUT8(ATA_LCYL, (start >> 8) & 0xff); /* 15:8 */
448 ATA_OUT8(ATA_HCYL, 0); /* 47:40 */ 448 ATA_OUT8(ATA_HCYL, (start >> 40) & 0xff); /* 47:40 */
449 ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */ 449 ATA_OUT8(ATA_HCYL, (start >> 16) & 0xff); /* 23:16 */
450 ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device); 450 ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device);
451#ifdef HAVE_ATA_DMA 451#ifdef HAVE_ATA_DMA
@@ -592,7 +592,7 @@ static int ata_transfer_sectors(unsigned long start,
592 592
593#ifndef MAX_PHYS_SECTOR_SIZE 593#ifndef MAX_PHYS_SECTOR_SIZE
594int ata_read_sectors(IF_MD(int drive,) 594int ata_read_sectors(IF_MD(int drive,)
595 unsigned long start, 595 sector_t start,
596 int incount, 596 int incount,
597 void* inbuf) 597 void* inbuf)
598{ 598{
@@ -607,7 +607,7 @@ int ata_read_sectors(IF_MD(int drive,)
607} 607}
608 608
609int ata_write_sectors(IF_MD(int drive,) 609int ata_write_sectors(IF_MD(int drive,)
610 unsigned long start, 610 sector_t start,
611 int count, 611 int count,
612 const void* buf) 612 const void* buf)
613{ 613{
@@ -623,7 +623,7 @@ int ata_write_sectors(IF_MD(int drive,)
623#endif /* ndef MAX_PHYS_SECTOR_SIZE */ 623#endif /* ndef MAX_PHYS_SECTOR_SIZE */
624 624
625#ifdef MAX_PHYS_SECTOR_SIZE 625#ifdef MAX_PHYS_SECTOR_SIZE
626static int cache_sector(unsigned long sector) 626static int cache_sector(sector_t sector)
627{ 627{
628 int rc; 628 int rc;
629 629
@@ -652,7 +652,7 @@ static inline int flush_current_sector(void)
652} 652}
653 653
654int ata_read_sectors(IF_MD(int drive,) 654int ata_read_sectors(IF_MD(int drive,)
655 unsigned long start, 655 sector_t start,
656 int incount, 656 int incount,
657 void* inbuf) 657 void* inbuf)
658{ 658{
@@ -718,7 +718,7 @@ int ata_read_sectors(IF_MD(int drive,)
718} 718}
719 719
720int ata_write_sectors(IF_MD(int drive,) 720int ata_write_sectors(IF_MD(int drive,)
721 unsigned long start, 721 sector_t start,
722 int count, 722 int count,
723 const void* buf) 723 const void* buf)
724{ 724{
@@ -916,7 +916,7 @@ static int identify(void)
916 return -2; 916 return -2;
917 } 917 }
918 918
919 for (i=0; i<SECTOR_SIZE/2; i++) { 919 for (i=0; i<ATA_IDENTIFY_WORDS; i++) {
920 /* the IDENTIFY words are already swapped, so we need to treat 920 /* the IDENTIFY words are already swapped, so we need to treat
921 this info differently that normal sector data */ 921 this info differently that normal sector data */
922 identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA)); 922 identify_info[i] = ATA_SWAP_IDENTIFY(ATA_IN16(ATA_DATA));
@@ -1269,10 +1269,8 @@ int STORAGE_INIT_ATTR ata_init(void)
1269 if (identify_info[83] & 0x0400 /* 48 bit address support */ 1269 if (identify_info[83] & 0x0400 /* 48 bit address support */
1270 && total_sectors == 0x0FFFFFFF) /* and disk size >= 128 GiB */ 1270 && total_sectors == 0x0FFFFFFF) /* and disk size >= 128 GiB */
1271 { /* (needs BigLBA addressing) */ 1271 { /* (needs BigLBA addressing) */
1272 if (identify_info[102] || identify_info[103]) 1272 total_sectors = identify_info[100] | (identify_info[101] << 16) | ((uint64_t)identify_info[102] << 32) | ((uint64_t)identify_info[103] << 48);
1273 panicf("Unsupported disk size: >= 2^32 sectors");
1274 1273
1275 total_sectors = identify_info[100] | (identify_info[101] << 16);
1276 lba48 = true; /* use BigLBA */ 1274 lba48 = true; /* use BigLBA */
1277 } 1275 }
1278#endif /* HAVE_LBA48 */ 1276#endif /* HAVE_LBA48 */
@@ -1360,7 +1358,13 @@ void ata_get_info(IF_MD(int drive,)struct storage_info *info)
1360 (void)drive; /* unused for now */ 1358 (void)drive; /* unused for now */
1361#endif 1359#endif
1362 int i; 1360 int i;
1363 info->sector_size = SECTOR_SIZE; 1361
1362 /* Logical sector size */
1363 if ((identify_info[106] & 0xd000) == 0x5000)
1364 info->sector_size = identify_info[117] | (identify_info[118] << 16);
1365 else
1366 info->sector_size = SECTOR_SIZE;
1367
1364 info->num_sectors = total_sectors; 1368 info->num_sectors = total_sectors;
1365 1369
1366 src = (unsigned short*)&identify_info[27]; 1370 src = (unsigned short*)&identify_info[27];