summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-05-16 21:28:21 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-05-16 21:28:21 +0000
commit39224664865222dcd46a39aa4a70d65e4b412d8e (patch)
tree784349a997707bd6fcafaa358bfe6fe93040415c
parent250c3b65dfb0eccce25bf71d5b31d248b7b95c8a (diff)
downloadrockbox-39224664865222dcd46a39aa4a70d65e4b412d8e.tar.gz
rockbox-39224664865222dcd46a39aa4a70d65e4b412d8e.zip
Added mutex protection
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@608 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/ata.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 0e0c48833c..716af74ae2 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -54,6 +54,8 @@
54#define CMD_SLEEP 0xE6 54#define CMD_SLEEP 0xE6
55#define CMD_SECURITY_FREEZE_LOCK 0xF5 55#define CMD_SECURITY_FREEZE_LOCK 0xF5
56 56
57struct mutex ata_mtx;
58
57static int wait_for_bsy(void) 59static int wait_for_bsy(void)
58{ 60{
59 int timeout = current_tick + HZ*4; 61 int timeout = current_tick + HZ*4;
@@ -96,9 +98,15 @@ int ata_read_sectors(unsigned long start,
96 void* buf) 98 void* buf)
97{ 99{
98 int i; 100 int i;
101 int ret = 0;
99 102
103 mutex_lock(&ata_mtx);
104
100 if (!wait_for_rdy()) 105 if (!wait_for_rdy())
106 {
107 mutex_unlock(&ata_mtx);
101 return -1; 108 return -1;
109 }
102 110
103 led(true); 111 led(true);
104 112
@@ -112,7 +120,10 @@ int ata_read_sectors(unsigned long start,
112 for (i=0; i<count; i++) { 120 for (i=0; i<count; i++) {
113 int j; 121 int j;
114 if (!wait_for_start_of_transfer()) 122 if (!wait_for_start_of_transfer())
123 {
124 mutex_unlock(&ata_mtx);
115 return -1; 125 return -1;
126 }
116 127
117 for (j=0; j<256; j++) 128 for (j=0; j<256; j++)
118 ((unsigned short*)buf)[j] = SWAB16(ATA_DATA); 129 ((unsigned short*)buf)[j] = SWAB16(ATA_DATA);
@@ -126,9 +137,10 @@ int ata_read_sectors(unsigned long start,
126 led(false); 137 led(false);
127 138
128 if(!wait_for_end_of_transfer()) 139 if(!wait_for_end_of_transfer())
129 return -1; 140 ret = -1;
130 else 141
131 return 0; 142 mutex_unlock(&ata_mtx);
143 return ret;
132} 144}
133 145
134#ifdef DISK_WRITE 146#ifdef DISK_WRITE
@@ -138,8 +150,13 @@ int ata_write_sectors(unsigned long start,
138{ 150{
139 int i; 151 int i;
140 152
153 mutex_lock(&ata_mtx);
154
141 if (!wait_for_rdy()) 155 if (!wait_for_rdy())
156 {
157 mutex_unlock(&ata_mtx);
142 return 0; 158 return 0;
159 }
143 160
144 led(true); 161 led(true);
145 162
@@ -153,7 +170,10 @@ int ata_write_sectors(unsigned long start,
153 for (i=0; i<count; i++) { 170 for (i=0; i<count; i++) {
154 int j; 171 int j;
155 if (!wait_for_start_of_transfer()) 172 if (!wait_for_start_of_transfer())
173 {
174 mutex_unlock(&ata_mtx);
156 return 0; 175 return 0;
176 }
157 177
158 for (j=0; j<256; j++) 178 for (j=0; j<256; j++)
159 ATA_DATA = SWAB16(((unsigned short*)buf)[j]); 179 ATA_DATA = SWAB16(((unsigned short*)buf)[j]);
@@ -166,14 +186,24 @@ int ata_write_sectors(unsigned long start,
166 186
167 led(false); 187 led(false);
168 188
169 return wait_for_end_of_transfer(); 189 i = wait_for_end_of_transfer();
190
191 mutex_unlock(&ata_mtx);
192 return i;
170} 193}
171#endif 194#endif
172 195
173static int check_registers(void) 196static int check_registers(void)
174{ 197{
198 int ret = 0;
199
200 mutex_lock(&ata_mtx);
201
175 if ( ATA_STATUS & STATUS_BSY ) 202 if ( ATA_STATUS & STATUS_BSY )
203 {
204 mutex_unlock(&ata_mtx);
176 return 0; 205 return 0;
206 }
177 207
178 ATA_NSECTOR = 0xa5; 208 ATA_NSECTOR = 0xa5;
179 ATA_SECTOR = 0x5a; 209 ATA_SECTOR = 0x5a;
@@ -184,9 +214,10 @@ static int check_registers(void)
184 (ATA_SECTOR == 0x5a) && 214 (ATA_SECTOR == 0x5a) &&
185 (ATA_LCYL == 0xaa) && 215 (ATA_LCYL == 0xaa) &&
186 (ATA_HCYL == 0x55)) 216 (ATA_HCYL == 0x55))
187 return 1; 217 ret = 1;
188 else 218
189 return 0; 219 mutex_unlock(&ata_mtx);
220 return ret;
190} 221}
191 222
192static int freeze_lock(void) 223static int freeze_lock(void)
@@ -204,38 +235,60 @@ static int freeze_lock(void)
204 235
205int ata_spindown(int time) 236int ata_spindown(int time)
206{ 237{
238 int ret = 0;
239
240 mutex_lock(&ata_mtx);
241
207 if(!wait_for_rdy()) 242 if(!wait_for_rdy())
243 {
244 mutex_unlock(&ata_mtx);
208 return -1; 245 return -1;
246 }
209 247
210 if ( time == -1 ) { 248 if ( time == -1 ) {
211 ATA_COMMAND = CMD_STANDBY_IMMEDIATE; 249 ATA_COMMAND = CMD_STANDBY_IMMEDIATE;
212 } 250 }
213 else { 251 else {
214 if (time > 255) 252 if (time > 255)
253 {
254 mutex_unlock(&ata_mtx);
215 return -1; 255 return -1;
256 }
216 ATA_NSECTOR = time & 0xff; 257 ATA_NSECTOR = time & 0xff;
217 ATA_COMMAND = CMD_STANDBY; 258 ATA_COMMAND = CMD_STANDBY;
218 } 259 }
219 260
220 if (!wait_for_rdy()) 261 if (!wait_for_rdy())
221 return -1; 262 ret = -1;
222 263
223 return 0; 264 mutex_unlock(&ata_mtx);
265 return ret;
224} 266}
225 267
226int ata_hard_reset(void) 268int ata_hard_reset(void)
227{ 269{
270 int ret;
271
272 mutex_lock(&ata_mtx);
273
228 PADR &= ~0x0002; 274 PADR &= ~0x0002;
229 275
230 sleep(2); 276 sleep(2);
231 277
232 PADR |= 0x0002; 278 PADR |= 0x0002;
233 279
234 return wait_for_rdy(); 280 ret = wait_for_rdy();
281
282 mutex_unlock(&ata_mtx);
283 return ret;
235} 284}
236 285
237int ata_soft_reset(void) 286int ata_soft_reset(void)
238{ 287{
288 int ret;
289
290 mutex_lock(&ata_mtx);
291
239 ATA_SELECT = SELECT_LBA; 292 ATA_SELECT = SELECT_LBA;
240 ATA_CONTROL = CONTROL_nIEN|CONTROL_SRST; 293 ATA_CONTROL = CONTROL_nIEN|CONTROL_SRST;
241 sleep(HZ/20000); /* >= 5us */ 294 sleep(HZ/20000); /* >= 5us */
@@ -243,11 +296,16 @@ int ata_soft_reset(void)
243 ATA_CONTROL = CONTROL_nIEN; 296 ATA_CONTROL = CONTROL_nIEN;
244 sleep(HZ/400); /* >2ms */ 297 sleep(HZ/400); /* >2ms */
245 298
246 return wait_for_rdy(); 299 ret = wait_for_rdy();
300
301 mutex_unlock(&ata_mtx);
302 return ret;
247} 303}
248 304
249int ata_init(void) 305int ata_init(void)
250{ 306{
307 mutex_init(&ata_mtx);
308
251 led(false); 309 led(false);
252 310
253 /* activate ATA */ 311 /* activate ATA */