summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/ata.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 935b91271e..5e6df91cc5 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -110,6 +110,7 @@ static int wait_for_bsy(void) __attribute__ ((section (".icode")));
110static int wait_for_bsy(void) 110static int wait_for_bsy(void)
111{ 111{
112 int timeout = current_tick + HZ*10; 112 int timeout = current_tick + HZ*10;
113 last_disk_activity = timeout;
113 while (TIME_BEFORE(current_tick, timeout) && (ATA_ALT_STATUS & STATUS_BSY)) 114 while (TIME_BEFORE(current_tick, timeout) && (ATA_ALT_STATUS & STATUS_BSY))
114 sleep_thread(); 115 sleep_thread();
115 wake_up_thread(); 116 wake_up_thread();
@@ -129,7 +130,8 @@ static int wait_for_rdy(void)
129 return 0; 130 return 0;
130 131
131 timeout = current_tick + HZ*10; 132 timeout = current_tick + HZ*10;
132 133 last_disk_activity = timeout;
134
133 while (TIME_BEFORE(current_tick, timeout) && 135 while (TIME_BEFORE(current_tick, timeout) &&
134 !(ATA_ALT_STATUS & STATUS_RDY)) 136 !(ATA_ALT_STATUS & STATUS_RDY))
135 sleep_thread(); 137 sleep_thread();
@@ -180,12 +182,14 @@ int ata_read_sectors(unsigned long start,
180 if (poweroff) { 182 if (poweroff) {
181 if (ata_power_on()) { 183 if (ata_power_on()) {
182 mutex_unlock(&ata_mtx); 184 mutex_unlock(&ata_mtx);
185 led(false);
183 return -1; 186 return -1;
184 } 187 }
185 } 188 }
186 else { 189 else {
187 if (perform_soft_reset()) { 190 if (perform_soft_reset()) {
188 mutex_unlock(&ata_mtx); 191 mutex_unlock(&ata_mtx);
192 led(false);
189 return -1; 193 return -1;
190 } 194 }
191 } 195 }
@@ -198,6 +202,7 @@ int ata_read_sectors(unsigned long start,
198 if (!wait_for_rdy()) 202 if (!wait_for_rdy())
199 { 203 {
200 mutex_unlock(&ata_mtx); 204 mutex_unlock(&ata_mtx);
205 led(false);
201 return -2; 206 return -2;
202 } 207 }
203 208
@@ -218,6 +223,13 @@ int ata_read_sectors(unsigned long start,
218 ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA | ata_device; 223 ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA | ata_device;
219 ATA_COMMAND = CMD_READ_MULTIPLE; 224 ATA_COMMAND = CMD_READ_MULTIPLE;
220 225
226 /* wait at least 400ns between writing command and reading status */
227 asm volatile ("nop");
228 asm volatile ("nop");
229 asm volatile ("nop");
230 asm volatile ("nop");
231 asm volatile ("nop");
232
221 while (count) { 233 while (count) {
222 int j; 234 int j;
223 int sectors; 235 int sectors;
@@ -226,8 +238,6 @@ int ata_read_sectors(unsigned long start,
226 238
227 if (!wait_for_start_of_transfer()) { 239 if (!wait_for_start_of_transfer()) {
228 ret = -4; 240 ret = -4;
229 if(ata_hard_reset())
230 break;
231 goto retry; 241 goto retry;
232 } 242 }
233 243
@@ -312,17 +322,21 @@ int ata_write_sectors(unsigned long start,
312 322
313 last_disk_activity = current_tick; 323 last_disk_activity = current_tick;
314 324
325 led(true);
326
315 if ( sleeping ) { 327 if ( sleeping ) {
316 spinup = true; 328 spinup = true;
317 if (poweroff) { 329 if (poweroff) {
318 if (ata_power_on()) { 330 if (ata_power_on()) {
319 mutex_unlock(&ata_mtx); 331 mutex_unlock(&ata_mtx);
332 led(false);
320 return -1; 333 return -1;
321 } 334 }
322 } 335 }
323 else { 336 else {
324 if (perform_soft_reset()) { 337 if (perform_soft_reset()) {
325 mutex_unlock(&ata_mtx); 338 mutex_unlock(&ata_mtx);
339 led(false);
326 return -1; 340 return -1;
327 } 341 }
328 } 342 }
@@ -332,11 +346,10 @@ int ata_write_sectors(unsigned long start,
332 if (!wait_for_rdy()) 346 if (!wait_for_rdy())
333 { 347 {
334 mutex_unlock(&ata_mtx); 348 mutex_unlock(&ata_mtx);
349 led(false);
335 return -2; 350 return -2;
336 } 351 }
337 352
338 led(true);
339
340 if ( count == 256 ) 353 if ( count == 256 )
341 ATA_NSECTOR = 0; /* 0 means 256 sectors */ 354 ATA_NSECTOR = 0; /* 0 means 256 sectors */
342 else 355 else