From 58787280b808838b9812258645d6df69591bbb37 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Fri, 28 Mar 2008 23:39:28 +0000 Subject: Go back to the ata lock hack for 5g until whatever is going on there is discovered and fixed. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16870 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/ata.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ firmware/thread.c | 14 +++++++++-- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 56b303da8d..681160cf01 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c @@ -66,6 +66,74 @@ #define ATA_POWER_OFF_TIMEOUT 2*HZ #endif +#ifdef MAX_PHYS_SECTOR_SIZE +/* Hack - what's the deal with 5g? */ +struct ata_lock +{ + struct thread_entry *thread; + int count; + volatile unsigned char locked; + IF_COP( struct corelock cl; ) +}; + +static void ata_lock_init(struct ata_lock *l) +{ + corelock_init(&l->cl); + l->locked = 0; + l->count = 0; + l->thread = NULL; +} + +static void ata_lock_lock(struct ata_lock *l) +{ + struct thread_entry * const current = thread_get_current(); + + if (current == l->thread) + { + l->count++; + return; + } + + corelock_lock(&l->cl); + + IF_PRIO( current->skip_count = -1; ) + + while (l->locked != 0) + { + corelock_unlock(&l->cl); + switch_thread(); + corelock_lock(&l->cl); + } + + l->locked = 1; + l->thread = current; + corelock_unlock(&l->cl); +} + +static void ata_lock_unlock(struct ata_lock *l) +{ + if (l->count > 0) + { + l->count--; + return; + } + + corelock_lock(&l->cl); + + IF_PRIO( l->thread->skip_count = 0; ) + + l->thread = NULL; + l->locked = 0; + + corelock_unlock(&l->cl); +} + +#define mutex ata_lock +#define mutex_init ata_lock_init +#define mutex_lock ata_lock_lock +#define mutex_unlock ata_lock_unlock +#endif /* MAX_PHYS_SECTOR_SIZE */ + static struct mutex ata_mtx NOCACHEBSS_ATTR; int ata_device; /* device 0 (master) or 1 (slave) */ diff --git a/firmware/thread.c b/firmware/thread.c index 2ac7f6efc3..e6ab0e4a71 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -161,6 +161,13 @@ void switch_thread(void) * Processor-specific section */ +#ifdef MAX_PHYS_SECTOR_SIZE +/* Support a special workaround object for large-sector disks */ +#define IF_NO_SKIP_YIELD(...) __VA_ARGS__ +#else +#define IF_NO_SKIP_YIELD(...) +#endif + #if defined(CPU_ARM) /*--------------------------------------------------------------------------- * Start the thread running and terminate it if it returns @@ -1928,8 +1935,9 @@ void switch_thread(void) #endif #ifdef HAVE_PRIORITY_SCHEDULING + IF_NO_SKIP_YIELD( if (thread->skip_count != -1) ) /* Reset the value of thread's skip count */ - thread->skip_count = 0; + thread->skip_count = 0; #endif for (;;) @@ -1985,6 +1993,7 @@ void switch_thread(void) * priority threads are runnable. The highest priority runnable * thread(s) are never skipped. */ if (priority <= max || + IF_NO_SKIP_YIELD( thread->skip_count == -1 || ) (diff = priority - max, ++thread->skip_count > diff*diff)) { cores[core].running = thread; @@ -2129,7 +2138,8 @@ unsigned int wakeup_thread(struct thread_entry **list) if (bl == NULL) { /* No inheritance - just boost the thread by aging */ - thread->skip_count = thread->priority; + IF_NO_SKIP_YIELD( if (thread->skip_count != -1) ) + thread->skip_count = thread->priority; current = cores[CURRENT_CORE].running; } else -- cgit v1.2.3