diff options
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r-- | firmware/drivers/ata.c | 36 |
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; | |||
109 | static long power_off_tick = 0; | 109 | static long power_off_tick = 0; |
110 | #endif | 110 | #endif |
111 | 111 | ||
112 | static unsigned long total_sectors; | 112 | static sector_t total_sectors; |
113 | static int multisectors; /* number of supported multisectors */ | 113 | static int multisectors; /* number of supported multisectors */ |
114 | static unsigned short identify_info[SECTOR_SIZE/2]; | 114 | static unsigned short identify_info[ATA_IDENTIFY_WORDS]; |
115 | 115 | ||
116 | #ifdef MAX_PHYS_SECTOR_SIZE | 116 | #ifdef MAX_PHYS_SECTOR_SIZE |
117 | 117 | ||
118 | struct sector_cache_entry { | 118 | struct 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 | ||
384 | static int ata_transfer_sectors(unsigned long start, | 384 | static 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 |
594 | int ata_read_sectors(IF_MD(int drive,) | 594 | int 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 | ||
609 | int ata_write_sectors(IF_MD(int drive,) | 609 | int 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 |
626 | static int cache_sector(unsigned long sector) | 626 | static 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 | ||
654 | int ata_read_sectors(IF_MD(int drive,) | 654 | int 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 | ||
720 | int ata_write_sectors(IF_MD(int drive,) | 720 | int 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]; |