summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2024-11-01 19:58:22 -0400
committerSolomon Peachy <pizza@shaftnet.org>2024-11-04 07:33:26 -0500
commit2824bd5f1644a6b9129a0c0fcfe2bafab91a7225 (patch)
treec50259c7efcd751ed4666e4e538609097f43ce80 /firmware
parentd60dee6188ee134ddd3019a219c41e39df1ae5ff (diff)
downloadrockbox-2824bd5f1644a6b9129a0c0fcfe2bafab91a7225.tar.gz
rockbox-2824bd5f1644a6b9129a0c0fcfe2bafab91a7225.zip
ipod6g: Support MAX_PHYS_SECTOR_SIZE of 4K
This lets us *natively* handle varying physical sector sizes without playing games and lying about the logical sector size. (The original drives use 4K _physical_ sectors with 512B logical sectors, but you have to access everything in 4K blocks...) Achieve this by splitting the MAX_PHYS_SECTOR_SIZE code out of the main ATA driver and re-using it. Change-Id: I0bc615ab4562f1e3e83171a8633c74fb60c7da1f
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/ata-common.c238
-rw-r--r--firmware/drivers/ata.c218
-rw-r--r--firmware/export/config/ipod6g.h4
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c179
4 files changed, 327 insertions, 312 deletions
diff --git a/firmware/drivers/ata-common.c b/firmware/drivers/ata-common.c
new file mode 100644
index 0000000000..53a7780262
--- /dev/null
+++ b/firmware/drivers/ata-common.c
@@ -0,0 +1,238 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2024 Solomon Peachy
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21/* This is intended to be #included into the ATA driver */
22
23#ifdef MAX_PHYS_SECTOR_SIZE
24
25struct sector_cache_entry {
26 unsigned char data[MAX_PHYS_SECTOR_SIZE];
27 sector_t sectornum; /* logical sector */
28 bool inuse;
29};
30/* buffer for reading and writing large physical sectors */
31static struct sector_cache_entry sector_cache STORAGE_ALIGN_ATTR;
32static int phys_sector_mult = 1;
33
34static int cache_sector(sector_t sector)
35{
36 int rc;
37
38 /* round down to physical sector boundary */
39 sector &= ~(phys_sector_mult - 1);
40
41 /* check whether the sector is already cached */
42 if (sector_cache.inuse && (sector_cache.sectornum == sector))
43 return 0;
44
45 /* not found: read the sector */
46 sector_cache.inuse = false;
47 rc = ata_transfer_sectors(sector, phys_sector_mult, sector_cache.data, false);
48 if (!rc)
49 {
50 sector_cache.sectornum = sector;
51 sector_cache.inuse = true;
52 }
53 return rc;
54}
55
56static inline int flush_current_sector(void)
57{
58 return ata_transfer_sectors(sector_cache.sectornum, phys_sector_mult,
59 sector_cache.data, true);
60}
61
62int ata_read_sectors(IF_MD(int drive,)
63 sector_t start,
64 int incount,
65 void* inbuf)
66{
67 int rc = 0;
68 int offset;
69
70#ifdef HAVE_MULTIDRIVE
71 (void)drive; /* unused for now */
72#endif
73 mutex_lock(&ata_mutex);
74
75 offset = start & (phys_sector_mult - 1);
76
77 if (offset) /* first partial sector */
78 {
79 int partcount = MIN(incount, phys_sector_mult - offset);
80
81 rc = cache_sector(start);
82 if (rc)
83 {
84 rc = rc * 10 - 1;
85 goto error;
86 }
87 memcpy(inbuf, sector_cache.data + offset * SECTOR_SIZE,
88 partcount * SECTOR_SIZE);
89
90 start += partcount;
91 inbuf += partcount * SECTOR_SIZE;
92 incount -= partcount;
93 }
94 if (incount)
95 {
96 offset = incount & (phys_sector_mult - 1);
97 incount -= offset;
98
99 if (incount)
100 {
101 rc = ata_transfer_sectors(start, incount, inbuf, false);
102 if (rc)
103 {
104 rc = rc * 10 - 2;
105 goto error;
106 }
107 start += incount;
108 inbuf += incount * SECTOR_SIZE;
109 }
110 if (offset)
111 {
112 rc = cache_sector(start);
113 if (rc)
114 {
115 rc = rc * 10 - 3;
116 goto error;
117 }
118 memcpy(inbuf, sector_cache.data, offset * SECTOR_SIZE);
119 }
120 }
121
122 error:
123 mutex_unlock(&ata_mutex);
124
125 return rc;
126}
127
128int ata_write_sectors(IF_MD(int drive,)
129 sector_t start,
130 int count,
131 const void* buf)
132{
133 int rc = 0;
134 int offset;
135
136#ifdef HAVE_MULTIDRIVE
137 (void)drive; /* unused for now */
138#endif
139 mutex_lock(&ata_mutex);
140
141 offset = start & (phys_sector_mult - 1);
142
143 if (offset) /* first partial sector */
144 {
145 int partcount = MIN(count, phys_sector_mult - offset);
146
147 rc = cache_sector(start);
148 if (rc)
149 {
150 rc = rc * 10 - 1;
151 goto error;
152 }
153 memcpy(sector_cache.data + offset * SECTOR_SIZE, buf,
154 partcount * SECTOR_SIZE);
155 rc = flush_current_sector();
156 if (rc)
157 {
158 rc = rc * 10 - 2;
159 goto error;
160 }
161 start += partcount;
162 buf += partcount * SECTOR_SIZE;
163 count -= partcount;
164 }
165 if (count)
166 {
167 offset = count & (phys_sector_mult - 1);
168 count -= offset;
169
170 if (count)
171 {
172 rc = ata_transfer_sectors(start, count, (void*)buf, true);
173 if (rc)
174 {
175 rc = rc * 10 - 3;
176 goto error;
177 }
178 start += count;
179 buf += count * SECTOR_SIZE;
180 }
181 if (offset)
182 {
183 rc = cache_sector(start);
184 if (rc)
185 {
186 rc = rc * 10 - 4;
187 goto error;
188 }
189 memcpy(sector_cache.data, buf, offset * SECTOR_SIZE);
190 rc = flush_current_sector();
191 if (rc)
192 {
193 rc = rc * 10 - 5;
194 goto error;
195 }
196 }
197 }
198
199 error:
200 mutex_unlock(&ata_mutex);
201
202 return rc;
203}
204
205static int ata_get_phys_sector_mult(void)
206{
207 int rc = 0;
208
209 /* Find out the physical sector size */
210 if((identify_info[106] & 0xe000) == 0x6000) /* B14, B13 */
211 phys_sector_mult = BIT_N(identify_info[106] & 0x000f);
212 else
213 phys_sector_mult = 1;
214
215 DEBUGF("ata: %d logical sectors per phys sector", phys_sector_mult);
216
217 if (phys_sector_mult > 1)
218 {
219 /* Check if drive really needs emulation - if we can access
220 sector 1 then assume the drive supports "512e" and will handle
221 it better than us, so ignore the large physical sectors.
222 */
223 char throwaway[SECTOR_SIZE];
224 rc = ata_transfer_sectors(1, 1, &throwaway, false);
225 if (rc == 0)
226 phys_sector_mult = 1;
227 }
228
229 if (phys_sector_mult > (MAX_PHYS_SECTOR_SIZE/SECTOR_SIZE))
230 panicf("Unsupported physical sector size: %d",
231 phys_sector_mult * SECTOR_SIZE);
232
233 memset(&sector_cache, 0, sizeof(sector_cache));
234
235 return 0;
236}
237
238#endif /* MAX_PHYS_SECTOR_SIZE */
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 119297ff02..7b43d3c536 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -115,17 +115,6 @@ static int multisectors; /* number of supported multisectors */
115 115
116static unsigned short identify_info[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR; 116static unsigned short identify_info[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR;
117 117
118#ifdef MAX_PHYS_SECTOR_SIZE
119struct sector_cache_entry {
120 unsigned char data[MAX_PHYS_SECTOR_SIZE];
121 sector_t sectornum; /* logical sector */
122 bool inuse;
123};
124/* buffer for reading and writing large physical sectors */
125static struct sector_cache_entry sector_cache STORAGE_ALIGN_ATTR;
126static int phys_sector_mult = 1;
127#endif
128
129#ifdef HAVE_ATA_DMA 118#ifdef HAVE_ATA_DMA
130static int dma_mode = 0; 119static int dma_mode = 0;
131#endif 120#endif
@@ -600,6 +589,8 @@ static int ata_transfer_sectors(uint64_t start,
600 return ret; 589 return ret;
601} 590}
602 591
592#include "ata-common.c"
593
603#ifndef MAX_PHYS_SECTOR_SIZE 594#ifndef MAX_PHYS_SECTOR_SIZE
604int ata_read_sectors(IF_MD(int drive,) 595int ata_read_sectors(IF_MD(int drive,)
605 sector_t start, 596 sector_t start,
@@ -632,179 +623,6 @@ int ata_write_sectors(IF_MD(int drive,)
632} 623}
633#endif /* ndef MAX_PHYS_SECTOR_SIZE */ 624#endif /* ndef MAX_PHYS_SECTOR_SIZE */
634 625
635#ifdef MAX_PHYS_SECTOR_SIZE
636static int cache_sector(sector_t sector)
637{
638 int rc;
639
640 /* round down to physical sector boundary */
641 sector &= ~(phys_sector_mult - 1);
642
643 /* check whether the sector is already cached */
644 if (sector_cache.inuse && (sector_cache.sectornum == sector))
645 return 0;
646
647 /* not found: read the sector */
648 sector_cache.inuse = false;
649 rc = ata_transfer_sectors(sector, phys_sector_mult, sector_cache.data, false);
650 if (!rc)
651 {
652 sector_cache.sectornum = sector;
653 sector_cache.inuse = true;
654 }
655 return rc;
656}
657
658static inline int flush_current_sector(void)
659{
660 return ata_transfer_sectors(sector_cache.sectornum, phys_sector_mult,
661 sector_cache.data, true);
662}
663
664int ata_read_sectors(IF_MD(int drive,)
665 sector_t start,
666 int incount,
667 void* inbuf)
668{
669 int rc = 0;
670 int offset;
671
672#ifdef HAVE_MULTIDRIVE
673 (void)drive; /* unused for now */
674#endif
675 mutex_lock(&ata_mutex);
676
677 offset = start & (phys_sector_mult - 1);
678
679 if (offset) /* first partial sector */
680 {
681 int partcount = MIN(incount, phys_sector_mult - offset);
682
683 rc = cache_sector(start);
684 if (rc)
685 {
686 rc = rc * 10 - 1;
687 goto error;
688 }
689 memcpy(inbuf, sector_cache.data + offset * SECTOR_SIZE,
690 partcount * SECTOR_SIZE);
691
692 start += partcount;
693 inbuf += partcount * SECTOR_SIZE;
694 incount -= partcount;
695 }
696 if (incount)
697 {
698 offset = incount & (phys_sector_mult - 1);
699 incount -= offset;
700
701 if (incount)
702 {
703 rc = ata_transfer_sectors(start, incount, inbuf, false);
704 if (rc)
705 {
706 rc = rc * 10 - 2;
707 goto error;
708 }
709 start += incount;
710 inbuf += incount * SECTOR_SIZE;
711 }
712 if (offset)
713 {
714 rc = cache_sector(start);
715 if (rc)
716 {
717 rc = rc * 10 - 3;
718 goto error;
719 }
720 memcpy(inbuf, sector_cache.data, offset * SECTOR_SIZE);
721 }
722 }
723
724 error:
725 mutex_unlock(&ata_mutex);
726
727 return rc;
728}
729
730int ata_write_sectors(IF_MD(int drive,)
731 sector_t start,
732 int count,
733 const void* buf)
734{
735 int rc = 0;
736 int offset;
737
738#ifdef HAVE_MULTIDRIVE
739 (void)drive; /* unused for now */
740#endif
741 mutex_lock(&ata_mutex);
742
743 offset = start & (phys_sector_mult - 1);
744
745 if (offset) /* first partial sector */
746 {
747 int partcount = MIN(count, phys_sector_mult - offset);
748
749 rc = cache_sector(start);
750 if (rc)
751 {
752 rc = rc * 10 - 1;
753 goto error;
754 }
755 memcpy(sector_cache.data + offset * SECTOR_SIZE, buf,
756 partcount * SECTOR_SIZE);
757 rc = flush_current_sector();
758 if (rc)
759 {
760 rc = rc * 10 - 2;
761 goto error;
762 }
763 start += partcount;
764 buf += partcount * SECTOR_SIZE;
765 count -= partcount;
766 }
767 if (count)
768 {
769 offset = count & (phys_sector_mult - 1);
770 count -= offset;
771
772 if (count)
773 {
774 rc = ata_transfer_sectors(start, count, (void*)buf, true);
775 if (rc)
776 {
777 rc = rc * 10 - 3;
778 goto error;
779 }
780 start += count;
781 buf += count * SECTOR_SIZE;
782 }
783 if (offset)
784 {
785 rc = cache_sector(start);
786 if (rc)
787 {
788 rc = rc * 10 - 4;
789 goto error;
790 }
791 memcpy(sector_cache.data, buf, offset * SECTOR_SIZE);
792 rc = flush_current_sector();
793 if (rc)
794 {
795 rc = rc * 10 - 5;
796 goto error;
797 }
798 }
799 }
800
801 error:
802 mutex_unlock(&ata_mutex);
803
804 return rc;
805}
806#endif /* MAX_PHYS_SECTOR_SIZE */
807
808static int STORAGE_INIT_ATTR check_registers(void) 626static int STORAGE_INIT_ATTR check_registers(void)
809{ 627{
810 int i; 628 int i;
@@ -1242,9 +1060,6 @@ int STORAGE_INIT_ATTR ata_init(void)
1242 ata_led(false); 1060 ata_led(false);
1243 ata_device_init(); 1061 ata_device_init();
1244 ata_enable(true); 1062 ata_enable(true);
1245#ifdef MAX_PHYS_SECTOR_SIZE
1246 memset(&sector_cache, 0, sizeof(sector_cache));
1247#endif
1248 1063
1249 if (ata_state == ATA_BOOT) { 1064 if (ata_state == ATA_BOOT) {
1250 ata_state = ATA_OFF; 1065 ata_state = ATA_OFF;
@@ -1309,31 +1124,12 @@ int STORAGE_INIT_ATTR ata_init(void)
1309 } 1124 }
1310 1125
1311#ifdef MAX_PHYS_SECTOR_SIZE 1126#ifdef MAX_PHYS_SECTOR_SIZE
1312 /* Find out the physical sector size */ 1127 rc = ata_get_phys_sector_mult();
1313 if((identify_info[106] & 0xe000) == 0x6000) /* B14, B13 */ 1128 if (rc) {
1314 phys_sector_mult = BIT_N(identify_info[106] & 0x000f); 1129 rc = -70 + rc;
1315 else 1130 goto error;
1316 phys_sector_mult = 1;
1317
1318 DEBUGF("ata: %d logical sectors per phys sector", phys_sector_mult);
1319
1320 if (phys_sector_mult > 1)
1321 {
1322 /* Check if drive really needs emulation - if we can access
1323 sector 1 then assume the drive supports "512e" and will handle
1324 it better than us, so ignore the large physical sectors.
1325 */
1326 char throwaway[SECTOR_SIZE];
1327 rc = ata_transfer_sectors(1, 1, &throwaway, false);
1328 if (rc == 0)
1329 phys_sector_mult = 1;
1330 } 1131 }
1331 1132#endif
1332 if (phys_sector_mult > (MAX_PHYS_SECTOR_SIZE/SECTOR_SIZE))
1333 panicf("Unsupported physical sector size: %d",
1334 phys_sector_mult * SECTOR_SIZE);
1335#endif /* MAX_PHYS_SECTOR_SIZE */
1336
1337 ata_state = ATA_ON; 1133 ata_state = ATA_ON;
1338 keep_ata_active(); 1134 keep_ata_active();
1339 } 1135 }
diff --git a/firmware/export/config/ipod6g.h b/firmware/export/config/ipod6g.h
index 58c91b29c6..7eb92f86db 100644
--- a/firmware/export/config/ipod6g.h
+++ b/firmware/export/config/ipod6g.h
@@ -191,10 +191,10 @@
191 191
192#define HAVE_ATA_SMART 192#define HAVE_ATA_SMART
193 193
194#define SECTOR_SIZE 512
195/* define this if the device has larger sectors when accessed via USB */ 194/* define this if the device has larger sectors when accessed via USB */
196#define MAX_LOG_SECTOR_SIZE 4096 195#define MAX_LOG_SECTOR_SIZE 4096
197//#define MAX_PHYS_SECTOR_SIZE 4096 // Only if we have various physical sector sizes 196/* This is the minimum access size for the device, even if it's larger than the logical sector size */
197#define MAX_PHYS_SECTOR_SIZE 4096
198 198
199#define HAVE_HARDWARE_CLICK 199#define HAVE_HARDWARE_CLICK
200 200
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
index 3c7935ad89..8cc5b44aca 100644
--- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
@@ -29,6 +29,9 @@
29#include "mmcdefs-target.h" 29#include "mmcdefs-target.h"
30#include "s5l8702.h" 30#include "s5l8702.h"
31#include "led.h" 31#include "led.h"
32#include "debug.h"
33#include "panic.h"
34#include "fs_defines.h"
32 35
33#ifndef ATA_RETRIES 36#ifndef ATA_RETRIES
34#define ATA_RETRIES 3 37#define ATA_RETRIES 3
@@ -58,21 +61,9 @@
58#define CEATA_DAT_NONBUSY_TIMEOUT 5000000 61#define CEATA_DAT_NONBUSY_TIMEOUT 5000000
59#define CEATA_MMC_RCA 1 62#define CEATA_MMC_RCA 1
60 63
61#if SECTOR_SIZE == 4096
62#define SIZE_SHIFT 3 /* ie 4096 >> 3 == 512 */
63#elif SECTOR_SIZE == 512
64#define SIZE_SHIFT 0
65#else
66#error "Need to define SIZE_SHIFT for SECTOR_SIZE"
67#endif
68
69#ifdef MAX_PHYS_SECTOR_SIZE
70#error "Driver does not work with MAX_PHYS_SECTOR_SIZE"
71#endif
72
73/** static, private data **/ 64/** static, private data **/
74static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; 65static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR;
75static uint16_t ata_identify_data[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR; 66static uint16_t identify_info[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR;
76static bool ceata; 67static bool ceata;
77static bool ata_lba48; 68static bool ata_lba48;
78static bool ata_dma; 69static bool ata_dma;
@@ -89,10 +80,6 @@ static struct semaphore mmc_comp_wakeup;
89static int spinup_time = 0; 80static int spinup_time = 0;
90static int dma_mode = 0; 81static int dma_mode = 0;
91 82
92#if SECTOR_SIZE > 512
93static char aligned_buffer[SECTOR_SIZE] STORAGE_ALIGN_ATTR;
94#endif
95
96static const int ata_retries = ATA_RETRIES; 83static const int ata_retries = ATA_RETRIES;
97static const bool ata_error_srst = true; 84static const bool ata_error_srst = true;
98 85
@@ -688,7 +675,7 @@ static int ata_power_up(void)
688 SDCI_CDIV = SDCI_CDIV_CLKDIV(4); 675 SDCI_CDIV = SDCI_CDIV_CLKDIV(4);
689 sleep(HZ / 100); 676 sleep(HZ / 100);
690 PASS_RC(ceata_init(8), 3, 1); 677 PASS_RC(ceata_init(8), 3, 1);
691 PASS_RC(ata_identify(ata_identify_data), 3, 2); 678 PASS_RC(ata_identify(identify_info), 3, 2);
692 } else { 679 } else {
693 PCON(7) = 0x44444444; 680 PCON(7) = 0x44444444;
694 PCON(8) = 0x44444444; 681 PCON(8) = 0x44444444;
@@ -710,14 +697,14 @@ static int ata_power_up(void)
710 ATA_CFG = BIT(6); 697 ATA_CFG = BIT(6);
711 while (!(ATA_PIO_READY & BIT(1))) yield(); 698 while (!(ATA_PIO_READY & BIT(1))) yield();
712 699
713 PASS_RC(ata_identify(ata_identify_data), 3, 3); 700 PASS_RC(ata_identify(identify_info), 3, 3);
714 701
715 uint32_t piotime = 0x11f3; /* PIO0-2? */ 702 uint32_t piotime = 0x11f3; /* PIO0-2? */
716 if (ata_identify_data[53] & BIT(1)) /* Word 64..70 valid */ 703 if (identify_info[53] & BIT(1)) /* Word 64..70 valid */
717 { 704 {
718 if (ata_identify_data[64] & BIT(1)) 705 if (identify_info[64] & BIT(1))
719 piotime = 0x2072; /* PIO mode 4 */ 706 piotime = 0x2072; /* PIO mode 4 */
720 else if (ata_identify_data[64] & BIT(0)) 707 else if (identify_info[64] & BIT(0))
721 piotime = 0x7083; /* PIO mode 3 */ 708 piotime = 0x7083; /* PIO mode 3 */
722 } 709 }
723 ATA_PIO_TIME = piotime; 710 ATA_PIO_TIME = piotime;
@@ -725,20 +712,20 @@ static int ata_power_up(void)
725 uint32_t param = 0; 712 uint32_t param = 0;
726 ata_dma_flags = 0; 713 ata_dma_flags = 0;
727#ifdef HAVE_ATA_DMA 714#ifdef HAVE_ATA_DMA
728 if ((ata_identify_data[53] & BIT(2)) && (ata_identify_data[88] & BITRANGE(0, 4))) /* Any UDMA */ 715 if ((identify_info[53] & BIT(2)) && (identify_info[88] & BITRANGE(0, 4))) /* Any UDMA */
729 { 716 {
730 int max_udma = ATA_MAX_UDMA; 717 int max_udma = ATA_MAX_UDMA;
731#if ATA_MAX_UDMA > 2 718#if ATA_MAX_UDMA > 2
732 if (!(ata_identify_data[93] & BIT(13))) 719 if (!(identify_info[93] & BIT(13)))
733 max_udma = 2; 720 max_udma = 2;
734#endif 721#endif
735 param = ata_get_best_mode(ata_identify_data[88], max_udma, 0x40); 722 param = ata_get_best_mode(identify_info[88], max_udma, 0x40);
736 ATA_UDMA_TIME = udmatimes[param & 0xf]; 723 ATA_UDMA_TIME = udmatimes[param & 0xf];
737 ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10); 724 ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
738 } 725 }
739 if (!param && ata_identify_data[63] & BITRANGE(0, 2)) /* Fall back to any MWDMA */ 726 if (!param && identify_info[63] & BITRANGE(0, 2)) /* Fall back to any MWDMA */
740 { 727 {
741 param = ata_get_best_mode(ata_identify_data[63], ATA_MAX_MWDMA, 0x20); 728 param = ata_get_best_mode(identify_info[63], ATA_MAX_MWDMA, 0x20);
742 ATA_MDMA_TIME = mwdmatimes[param & 0xf]; 729 ATA_MDMA_TIME = mwdmatimes[param & 0xf];
743 ata_dma_flags = BIT(3) | BIT(10); 730 ata_dma_flags = BIT(3) | BIT(10);
744 } 731 }
@@ -748,33 +735,32 @@ static int ata_power_up(void)
748 PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */ 735 PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */
749 736
750 /* SET_FEATURE only supported on PATA, not CE-ATA */ 737 /* SET_FEATURE only supported on PATA, not CE-ATA */
751 if (ata_identify_data[82] & BIT(5)) 738 if (identify_info[82] & BIT(5))
752 PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */ 739 PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */
753 if (ata_identify_data[82] & BIT(6)) 740 if (identify_info[82] & BIT(6))
754 PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */ 741 PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */
755 if (ata_identify_data[83] & BIT(3)) 742 if (identify_info[83] & BIT(3))
756 PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */ 743 PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */
757 if (ata_identify_data[83] & BIT(9)) 744 if (identify_info[83] & BIT(9))
758 PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */ 745 PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */
759 746
760 PASS_RC(ata_identify(ata_identify_data), 3, 9); /* Finally, re-read identify info */ 747 PASS_RC(ata_identify(identify_info), 3, 9); /* Finally, re-read identify info */
761 } 748 }
762 749
763 spinup_time = current_tick - spinup_start; 750 spinup_time = current_tick - spinup_start;
764 751
765 ata_total_sectors = (ata_identify_data[61] << 16) | ata_identify_data[60]; 752 ata_total_sectors = (identify_info[61] << 16) | identify_info[60];
766 if ( ata_identify_data[83] & BIT(10) && ata_total_sectors == 0x0FFFFFFF) 753 if ( identify_info[83] & BIT(10) && ata_total_sectors == 0x0FFFFFFF)
767 { 754 {
768 ata_total_sectors = ((uint64_t)ata_identify_data[103] << 48) | 755 ata_total_sectors = ((uint64_t)identify_info[103] << 48) |
769 ((uint64_t)ata_identify_data[102] << 32) | 756 ((uint64_t)identify_info[102] << 32) |
770 ((uint64_t)ata_identify_data[101] << 16) | 757 ((uint64_t)identify_info[101] << 16) |
771 ata_identify_data[100]; 758 identify_info[100];
772 ata_lba48 = true; 759 ata_lba48 = true;
773 } else { 760 } else {
774 ata_lba48 = false; 761 ata_lba48 = false;
775 } 762 }
776 763
777 ata_total_sectors >>= SIZE_SHIFT;
778 ata_powered = true; 764 ata_powered = true;
779 ata_set_active(); 765 ata_set_active();
780 return 0; 766 return 0;
@@ -798,18 +784,18 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
798 if (ceata) 784 if (ceata)
799 { 785 {
800 memset(ceata_taskfile, 0, 16); 786 memset(ceata_taskfile, 0, 16);
801 ceata_taskfile[0x2] = cnt >> (8-SIZE_SHIFT); 787 ceata_taskfile[0x2] = cnt >> 8;
802 ceata_taskfile[0x3] = sector >> (24-SIZE_SHIFT); 788 ceata_taskfile[0x3] = sector >> 24;
803 ceata_taskfile[0x4] = sector >> (32-SIZE_SHIFT); 789 ceata_taskfile[0x4] = sector >> 32;
804 ceata_taskfile[0x5] = sector >> (40-SIZE_SHIFT); 790 ceata_taskfile[0x5] = sector >> 40;
805 ceata_taskfile[0xa] = cnt << SIZE_SHIFT; 791 ceata_taskfile[0xa] = cnt;
806 ceata_taskfile[0xb] = sector << SIZE_SHIFT; 792 ceata_taskfile[0xb] = sector;
807 ceata_taskfile[0xc] = sector >> (8-SIZE_SHIFT); 793 ceata_taskfile[0xc] = sector >> 8;
808 ceata_taskfile[0xd] = sector >> (16-SIZE_SHIFT); 794 ceata_taskfile[0xd] = sector >> 16;
809 ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT; 795 ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT;
810 PASS_RC(ceata_wait_idle(), 2, 0); 796 PASS_RC(ceata_wait_idle(), 2, 0);
811 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); 797 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
812 PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << SIZE_SHIFT, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); 798 PASS_RC(ceata_rw_multiple_block(write, buffer, cnt, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2);
813 } 799 }
814 else 800 else
815 { 801 {
@@ -817,14 +803,14 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
817 ata_write_cbr(&ATA_PIO_DVR, 0); 803 ata_write_cbr(&ATA_PIO_DVR, 0);
818 if (ata_lba48) 804 if (ata_lba48)
819 { 805 {
820 ata_write_cbr(&ATA_PIO_SCR, (cnt >> (8-SIZE_SHIFT)) & 0xff); 806 ata_write_cbr(&ATA_PIO_SCR, (cnt >> 8) & 0xff);
821 ata_write_cbr(&ATA_PIO_SCR, (cnt << SIZE_SHIFT) & 0xff); 807 ata_write_cbr(&ATA_PIO_SCR, (cnt) & 0xff);
822 ata_write_cbr(&ATA_PIO_LHR, (sector >> (40-SIZE_SHIFT)) & 0xff); 808 ata_write_cbr(&ATA_PIO_LHR, (sector >> 40) & 0xff);
823 ata_write_cbr(&ATA_PIO_LMR, (sector >> (32-SIZE_SHIFT)) & 0xff); 809 ata_write_cbr(&ATA_PIO_LMR, (sector >> 32) & 0xff);
824 ata_write_cbr(&ATA_PIO_LLR, (sector >> (24-SIZE_SHIFT)) & 0xff); 810 ata_write_cbr(&ATA_PIO_LLR, (sector >> 24) & 0xff);
825 ata_write_cbr(&ATA_PIO_LHR, (sector >> (16-SIZE_SHIFT)) & 0xff); 811 ata_write_cbr(&ATA_PIO_LHR, (sector >> 16) & 0xff);
826 ata_write_cbr(&ATA_PIO_LMR, (sector >> (8-SIZE_SHIFT)) & 0xff); 812 ata_write_cbr(&ATA_PIO_LMR, (sector >> 8) & 0xff);
827 ata_write_cbr(&ATA_PIO_LLR, (sector << SIZE_SHIFT) & 0xff); 813 ata_write_cbr(&ATA_PIO_LLR, (sector) & 0xff);
828 ata_write_cbr(&ATA_PIO_DVR, BIT(6)); 814 ata_write_cbr(&ATA_PIO_DVR, BIT(6));
829 if (write) 815 if (write)
830 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); 816 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT);
@@ -833,11 +819,11 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
833 } 819 }
834 else 820 else
835 { 821 {
836 ata_write_cbr(&ATA_PIO_SCR, (cnt << SIZE_SHIFT) & 0xff); 822 ata_write_cbr(&ATA_PIO_SCR, (cnt) & 0xff);
837 ata_write_cbr(&ATA_PIO_LHR, (sector >> (16-SIZE_SHIFT)) & 0xff); 823 ata_write_cbr(&ATA_PIO_LHR, (sector >> 16) & 0xff);
838 ata_write_cbr(&ATA_PIO_LMR, (sector >> (8-SIZE_SHIFT)) & 0xff); 824 ata_write_cbr(&ATA_PIO_LMR, (sector >> 8) & 0xff);
839 ata_write_cbr(&ATA_PIO_LLR, (sector << SIZE_SHIFT) & 0xff); 825 ata_write_cbr(&ATA_PIO_LLR, (sector) & 0xff);
840 ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> (24-SIZE_SHIFT)) & 0xf)); 826 ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 24) & 0xf)); /* LBA28, mask off upper 4 bits of 32-bit sector address */
841 if (write) 827 if (write)
842 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS); 828 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS);
843 else 829 else
@@ -878,18 +864,17 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
878 else 864 else
879#endif // HAVE_ATA_DMA 865#endif // HAVE_ATA_DMA
880 { 866 {
881 cnt <<= SIZE_SHIFT;
882 while (cnt--) 867 while (cnt--)
883 { 868 {
884 int i; 869 int i;
885 PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); 870 PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
886 if (write) 871 if (write)
887 for (i = 0; i < 256; i++) 872 for (i = 0; i < SECTOR_SIZE/2; i++)
888 ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]); 873 ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
889 else 874 else
890 for (i = 0; i < 256; i++) 875 for (i = 0; i < SECTOR_SIZE/2; i++)
891 ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR); 876 ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
892 buffer += (SECTOR_SIZE >> SIZE_SHIFT); 877 buffer += SECTOR_SIZE;
893 } 878 }
894 } 879 }
895 PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3); 880 PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
@@ -905,30 +890,8 @@ static int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write)
905 return rc; 890 return rc;
906} 891}
907 892
908static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write) 893static int ata_transfer_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
909{ 894{
910#if SECTOR_SIZE > 512
911 if (STORAGE_OVERLAP((uint32_t)buffer))
912 {
913 while (count)
914 {
915 if (write)
916 memcpy(aligned_buffer, buffer, SECTOR_SIZE);
917
918 PASS_RC(ata_rw_sectors(sector, 1, aligned_buffer, write), 0, 0);
919
920 if (!write)
921 memcpy(buffer, aligned_buffer, SECTOR_SIZE);
922
923 buffer += SECTOR_SIZE;
924 sector++;
925 count--;
926 }
927
928 return 0;
929 }
930#endif
931
932 if (!ata_powered) 895 if (!ata_powered)
933 ata_power_up(); 896 ata_power_up();
934 if (sector + count > ata_total_sectors) 897 if (sector + count > ata_total_sectors)
@@ -943,7 +906,7 @@ static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool wr
943 906
944 while (count) 907 while (count)
945 { 908 {
946 uint32_t cnt = MIN(ata_lba48 ? (65536 >> SIZE_SHIFT) : (256 >> SIZE_SHIFT), count); 909 uint32_t cnt = MIN(ata_lba48 ? 65536 : 256, count);
947 int rc = -1; 910 int rc = -1;
948 rc = ata_rw_chunk(sector, cnt, buffer, write); 911 rc = ata_rw_chunk(sector, cnt, buffer, write);
949 if (rc && ata_error_srst) 912 if (rc && ata_error_srst)
@@ -1037,11 +1000,18 @@ static int ata_reset(void)
1037 return rc; 1000 return rc;
1038} 1001}
1039 1002
1003#include "ata-common.c"
1004
1005#ifndef MAX_PHYS_SECTOR_SIZE
1040int ata_read_sectors(IF_MD(int drive,) sector_t start, int incount, 1006int ata_read_sectors(IF_MD(int drive,) sector_t start, int incount,
1041 void* inbuf) 1007 void* inbuf)
1042{ 1008{
1009#ifdef HAVE_MULTIDRIVE
1010 (void)drive; /* unused for now */
1011#endif
1012
1043 mutex_lock(&ata_mutex); 1013 mutex_lock(&ata_mutex);
1044 int rc = ata_rw_sectors(start, incount, inbuf, false); 1014 int rc = ata_transfer_sectors(start, incount, inbuf, false);
1045 mutex_unlock(&ata_mutex); 1015 mutex_unlock(&ata_mutex);
1046 return rc; 1016 return rc;
1047} 1017}
@@ -1049,11 +1019,16 @@ int ata_read_sectors(IF_MD(int drive,) sector_t start, int incount,
1049int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, 1019int ata_write_sectors(IF_MD(int drive,) sector_t start, int count,
1050 const void* outbuf) 1020 const void* outbuf)
1051{ 1021{
1022#ifdef HAVE_MULTIDRIVE
1023 (void)drive; /* unused for now */
1024#endif
1025
1052 mutex_lock(&ata_mutex); 1026 mutex_lock(&ata_mutex);
1053 int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true); 1027 int rc = ata_transfer_sectors(start, count, (void*)((uint32_t)outbuf), true);
1054 mutex_unlock(&ata_mutex); 1028 mutex_unlock(&ata_mutex);
1055 return rc; 1029 return rc;
1056} 1030}
1031#endif /* ndef MAX_PHYS_SECTOR_SIZE */
1057 1032
1058void ata_spindown(int seconds) 1033void ata_spindown(int seconds)
1059{ 1034{
@@ -1073,11 +1048,11 @@ static void ata_flush_cache(void)
1073 } else { 1048 } else {
1074 if (!canflush) { 1049 if (!canflush) {
1075 return; 1050 return;
1076 } else if (ata_lba48 && ata_identify_data[83] & BIT(13)) { 1051 } else if (ata_lba48 && identify_info[83] & BIT(13)) {
1077 cmd = CMD_FLUSH_CACHE_EXT; /* Flag, optional, ATA-6 and up, for use with LBA48 devices. Mandatory for CE-ATA */ 1052 cmd = CMD_FLUSH_CACHE_EXT; /* Flag, optional, ATA-6 and up, for use with LBA48 devices. Mandatory for CE-ATA */
1078 } else if (ata_identify_data[83] & BIT(12)) { 1053 } else if (identify_info[83] & BIT(12)) {
1079 cmd = CMD_FLUSH_CACHE; /* Flag, mandatory, ATA-6 and up */ 1054 cmd = CMD_FLUSH_CACHE; /* Flag, mandatory, ATA-6 and up */
1080 } else if (ata_identify_data[80] >= BIT(5)) { /* Use >= instead of '&' because bits lower than the latest standard we support don't have to be set */ 1055 } else if (identify_info[80] >= BIT(5)) { /* Use >= instead of '&' because bits lower than the latest standard we support don't have to be set */
1081 cmd = CMD_FLUSH_CACHE; /* No flag, mandatory, ATA-5 (Optional for ATA-4) */ 1056 cmd = CMD_FLUSH_CACHE; /* No flag, mandatory, ATA-5 (Optional for ATA-4) */
1082 } else { 1057 } else {
1083 /* If neither command is supported then don't issue it. */ 1058 /* If neither command is supported then don't issue it. */
@@ -1145,8 +1120,8 @@ void ata_spin(void)
1145void ata_get_info(IF_MD(int drive,) struct storage_info *info) 1120void ata_get_info(IF_MD(int drive,) struct storage_info *info)
1146{ 1121{
1147 /* Logical sector size */ 1122 /* Logical sector size */
1148 if ((ata_identify_data[106] & 0xd000) == 0x5000) /* B14, B12 */ 1123 if ((identify_info[106] & 0xd000) == 0x5000) /* B14, B12 */
1149 info->sector_size = (ata_identify_data[117] | (ata_identify_data[118] << 16)) * 2; 1124 info->sector_size = (identify_info[117] | (identify_info[118] << 16)) * 2;
1150 else 1125 else
1151 info->sector_size = SECTOR_SIZE; 1126 info->sector_size = SECTOR_SIZE;
1152 1127
@@ -1172,13 +1147,19 @@ int ata_init(void)
1172 ata_powered = false; 1147 ata_powered = false;
1173 ata_total_sectors = 0; 1148 ata_total_sectors = 0;
1174 1149
1175 /* get ata_identify_data */ 1150 /* get identify_info */
1176 mutex_lock(&ata_mutex); 1151 mutex_lock(&ata_mutex);
1177 int rc = ata_power_up(); 1152 int rc = ata_power_up();
1178 mutex_unlock(&ata_mutex); 1153 mutex_unlock(&ata_mutex);
1179 if (IS_ERR(rc)) 1154 if (IS_ERR(rc))
1180 return rc; 1155 return rc;
1181 1156
1157#ifdef MAX_PHYS_SECTOR_SIZE
1158 rc = ata_get_phys_sector_mult();
1159 if (IS_ERR(rc))
1160 return rc;
1161#endif
1162
1182 return 0; 1163 return 0;
1183} 1164}
1184 1165
@@ -1194,7 +1175,7 @@ static int ata_smart(uint16_t* buf)
1194 ceata_taskfile[0xe] = BIT(6); 1175 ceata_taskfile[0xe] = BIT(6);
1195 ceata_taskfile[0xf] = CMD_SMART; 1176 ceata_taskfile[0xf] = CMD_SMART;
1196 PASS_RC(ceata_wait_idle(), 3, 1); 1177 PASS_RC(ceata_wait_idle(), 3, 1);
1197 if (((uint8_t*)ata_identify_data)[54] != 'A') /* Model != aAmsung */ 1178 if (((uint8_t*)identify_info)[54] != 'A') /* Model != aAmsung */
1198 { 1179 {
1199 ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */ 1180 ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */
1200 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2); 1181 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2);
@@ -1242,7 +1223,7 @@ static int ata_num_drives(int first_drive)
1242 1223
1243unsigned short* ata_get_identify(void) 1224unsigned short* ata_get_identify(void)
1244{ 1225{
1245 return ata_identify_data; 1226 return identify_info;
1246} 1227}
1247 1228
1248int ata_spinup_time(void) 1229int ata_spinup_time(void)