diff options
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r-- | firmware/drivers/ata.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 700e403b9f..e867ac2f50 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -84,7 +84,6 @@ static volatile unsigned char* ata_control; | |||
84 | 84 | ||
85 | bool old_recorder = false; | 85 | bool old_recorder = false; |
86 | static bool sleeping = false; | 86 | static bool sleeping = false; |
87 | static int sleep_timer = 0; | ||
88 | static int sleep_timeout = 5*HZ; | 87 | static int sleep_timeout = 5*HZ; |
89 | static char ata_stack[DEFAULT_STACK_SIZE]; | 88 | static char ata_stack[DEFAULT_STACK_SIZE]; |
90 | static char ata_thread_name[] = "ata"; | 89 | static char ata_thread_name[] = "ata"; |
@@ -94,6 +93,9 @@ static bool delayed_write = false; | |||
94 | static unsigned char delayed_sector[SECTOR_SIZE]; | 93 | static unsigned char delayed_sector[SECTOR_SIZE]; |
95 | static int delayed_sector_num; | 94 | static int delayed_sector_num; |
96 | 95 | ||
96 | static long last_user_activity = -1; | ||
97 | static long last_disk_activity = -1; | ||
98 | |||
97 | #ifdef USE_POWEROFF | 99 | #ifdef USE_POWEROFF |
98 | static int ata_power_on(void); | 100 | static int ata_power_on(void); |
99 | #endif | 101 | #endif |
@@ -149,6 +151,7 @@ int ata_read_sectors(unsigned long start, | |||
149 | int i; | 151 | int i; |
150 | int ret = 0; | 152 | int ret = 0; |
151 | 153 | ||
154 | last_disk_activity = current_tick; | ||
152 | #ifndef USE_STANDBY | 155 | #ifndef USE_STANDBY |
153 | if ( sleeping ) { | 156 | if ( sleeping ) { |
154 | #ifdef USE_POWEROFF | 157 | #ifdef USE_POWEROFF |
@@ -163,7 +166,6 @@ int ata_read_sectors(unsigned long start, | |||
163 | } | 166 | } |
164 | #endif | 167 | #endif |
165 | mutex_lock(&ata_mtx); | 168 | mutex_lock(&ata_mtx); |
166 | sleep_timer = sleep_timeout; | ||
167 | 169 | ||
168 | if (!wait_for_rdy()) | 170 | if (!wait_for_rdy()) |
169 | { | 171 | { |
@@ -223,6 +225,8 @@ int ata_read_sectors(unsigned long start, | |||
223 | if ( delayed_write ) | 225 | if ( delayed_write ) |
224 | ata_flush(); | 226 | ata_flush(); |
225 | 227 | ||
228 | last_disk_activity = current_tick; | ||
229 | |||
226 | return ret; | 230 | return ret; |
227 | } | 231 | } |
228 | 232 | ||
@@ -232,6 +236,8 @@ int ata_write_sectors(unsigned long start, | |||
232 | { | 236 | { |
233 | int i; | 237 | int i; |
234 | 238 | ||
239 | last_disk_activity = current_tick; | ||
240 | |||
235 | #ifndef USE_STANDBY | 241 | #ifndef USE_STANDBY |
236 | #ifdef USE_POWEROFF | 242 | #ifdef USE_POWEROFF |
237 | if (ata_power_on()) { | 243 | if (ata_power_on()) { |
@@ -244,7 +250,6 @@ int ata_write_sectors(unsigned long start, | |||
244 | #endif | 250 | #endif |
245 | #endif | 251 | #endif |
246 | mutex_lock(&ata_mtx); | 252 | mutex_lock(&ata_mtx); |
247 | sleep_timer = sleep_timeout; | ||
248 | 253 | ||
249 | if (!wait_for_rdy()) | 254 | if (!wait_for_rdy()) |
250 | { | 255 | { |
@@ -291,6 +296,8 @@ int ata_write_sectors(unsigned long start, | |||
291 | if ( delayed_write ) | 296 | if ( delayed_write ) |
292 | ata_flush(); | 297 | ata_flush(); |
293 | 298 | ||
299 | last_disk_activity = current_tick; | ||
300 | |||
294 | return i; | 301 | return i; |
295 | } | 302 | } |
296 | 303 | ||
@@ -379,7 +386,6 @@ static int ata_perform_sleep(void) | |||
379 | ret = -1; | 386 | ret = -1; |
380 | #endif | 387 | #endif |
381 | sleeping = true; | 388 | sleeping = true; |
382 | sleep_timer = 0; | ||
383 | mutex_unlock(&ata_mtx); | 389 | mutex_unlock(&ata_mtx); |
384 | return ret; | 390 | return ret; |
385 | } | 391 | } |
@@ -390,11 +396,25 @@ int ata_sleep(void) | |||
390 | return 0; | 396 | return 0; |
391 | } | 397 | } |
392 | 398 | ||
399 | void ata_spin(void) | ||
400 | { | ||
401 | last_user_activity = current_tick; | ||
402 | } | ||
403 | |||
393 | static void ata_thread(void) | 404 | static void ata_thread(void) |
394 | { | 405 | { |
395 | struct event ev; | 406 | struct event ev; |
396 | 407 | ||
397 | while (1) { | 408 | while (1) { |
409 | while ( queue_empty( &ata_queue ) ) { | ||
410 | if ( sleep_timeout && | ||
411 | TIME_AFTER( current_tick, | ||
412 | last_user_activity + sleep_timeout ) && | ||
413 | TIME_AFTER( current_tick, | ||
414 | last_disk_activity + sleep_timeout ) ) | ||
415 | ata_perform_sleep(); | ||
416 | sleep(HZ/4); | ||
417 | } | ||
398 | queue_wait(&ata_queue, &ev); | 418 | queue_wait(&ata_queue, &ev); |
399 | switch ( ev.id ) { | 419 | switch ( ev.id ) { |
400 | case SYS_USB_CONNECTED: | 420 | case SYS_USB_CONNECTED: |
@@ -407,21 +427,12 @@ static void ata_thread(void) | |||
407 | break; | 427 | break; |
408 | 428 | ||
409 | case Q_SLEEP: | 429 | case Q_SLEEP: |
410 | ata_perform_sleep(); | 430 | last_disk_activity = current_tick - sleep_timeout; |
411 | break; | 431 | break; |
412 | } | 432 | } |
413 | } | 433 | } |
414 | } | 434 | } |
415 | 435 | ||
416 | static void ata_tick(void) | ||
417 | { | ||
418 | if (sleep_timer) { | ||
419 | sleep_timer--; | ||
420 | if (!sleep_timer) | ||
421 | queue_post(&ata_queue, 0, NULL); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | int ata_hard_reset(void) | 436 | int ata_hard_reset(void) |
426 | { | 437 | { |
427 | int ret; | 438 | int ret; |
@@ -597,7 +608,6 @@ int ata_init(void) | |||
597 | queue_init(&ata_queue); | 608 | queue_init(&ata_queue); |
598 | create_thread(ata_thread, ata_stack, | 609 | create_thread(ata_thread, ata_stack, |
599 | sizeof(ata_stack), ata_thread_name); | 610 | sizeof(ata_stack), ata_thread_name); |
600 | tick_add_task(ata_tick); | ||
601 | initialized = true; | 611 | initialized = true; |
602 | } | 612 | } |
603 | 613 | ||