summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-03-28 23:39:28 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-03-28 23:39:28 +0000
commit58787280b808838b9812258645d6df69591bbb37 (patch)
treeb0bd7e398d3483d8413802f5999f685c358e01db
parent8f44dd2b72fd9b537512fece7bf13c5fe286d39c (diff)
downloadrockbox-58787280b808838b9812258645d6df69591bbb37.tar.gz
rockbox-58787280b808838b9812258645d6df69591bbb37.zip
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
-rw-r--r--firmware/drivers/ata.c68
-rw-r--r--firmware/thread.c14
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 @@
66#define ATA_POWER_OFF_TIMEOUT 2*HZ 66#define ATA_POWER_OFF_TIMEOUT 2*HZ
67#endif 67#endif
68 68
69#ifdef MAX_PHYS_SECTOR_SIZE
70/* Hack - what's the deal with 5g? */
71struct ata_lock
72{
73 struct thread_entry *thread;
74 int count;
75 volatile unsigned char locked;
76 IF_COP( struct corelock cl; )
77};
78
79static void ata_lock_init(struct ata_lock *l)
80{
81 corelock_init(&l->cl);
82 l->locked = 0;
83 l->count = 0;
84 l->thread = NULL;
85}
86
87static void ata_lock_lock(struct ata_lock *l)
88{
89 struct thread_entry * const current = thread_get_current();
90
91 if (current == l->thread)
92 {
93 l->count++;
94 return;
95 }
96
97 corelock_lock(&l->cl);
98
99 IF_PRIO( current->skip_count = -1; )
100
101 while (l->locked != 0)
102 {
103 corelock_unlock(&l->cl);
104 switch_thread();
105 corelock_lock(&l->cl);
106 }
107
108 l->locked = 1;
109 l->thread = current;
110 corelock_unlock(&l->cl);
111}
112
113static void ata_lock_unlock(struct ata_lock *l)
114{
115 if (l->count > 0)
116 {
117 l->count--;
118 return;
119 }
120
121 corelock_lock(&l->cl);
122
123 IF_PRIO( l->thread->skip_count = 0; )
124
125 l->thread = NULL;
126 l->locked = 0;
127
128 corelock_unlock(&l->cl);
129}
130
131#define mutex ata_lock
132#define mutex_init ata_lock_init
133#define mutex_lock ata_lock_lock
134#define mutex_unlock ata_lock_unlock
135#endif /* MAX_PHYS_SECTOR_SIZE */
136
69static struct mutex ata_mtx NOCACHEBSS_ATTR; 137static struct mutex ata_mtx NOCACHEBSS_ATTR;
70int ata_device; /* device 0 (master) or 1 (slave) */ 138int ata_device; /* device 0 (master) or 1 (slave) */
71 139
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)
161 * Processor-specific section 161 * Processor-specific section
162 */ 162 */
163 163
164#ifdef MAX_PHYS_SECTOR_SIZE
165/* Support a special workaround object for large-sector disks */
166#define IF_NO_SKIP_YIELD(...) __VA_ARGS__
167#else
168#define IF_NO_SKIP_YIELD(...)
169#endif
170
164#if defined(CPU_ARM) 171#if defined(CPU_ARM)
165/*--------------------------------------------------------------------------- 172/*---------------------------------------------------------------------------
166 * Start the thread running and terminate it if it returns 173 * Start the thread running and terminate it if it returns
@@ -1928,8 +1935,9 @@ void switch_thread(void)
1928#endif 1935#endif
1929 1936
1930#ifdef HAVE_PRIORITY_SCHEDULING 1937#ifdef HAVE_PRIORITY_SCHEDULING
1938 IF_NO_SKIP_YIELD( if (thread->skip_count != -1) )
1931 /* Reset the value of thread's skip count */ 1939 /* Reset the value of thread's skip count */
1932 thread->skip_count = 0; 1940 thread->skip_count = 0;
1933#endif 1941#endif
1934 1942
1935 for (;;) 1943 for (;;)
@@ -1985,6 +1993,7 @@ void switch_thread(void)
1985 * priority threads are runnable. The highest priority runnable 1993 * priority threads are runnable. The highest priority runnable
1986 * thread(s) are never skipped. */ 1994 * thread(s) are never skipped. */
1987 if (priority <= max || 1995 if (priority <= max ||
1996 IF_NO_SKIP_YIELD( thread->skip_count == -1 || )
1988 (diff = priority - max, ++thread->skip_count > diff*diff)) 1997 (diff = priority - max, ++thread->skip_count > diff*diff))
1989 { 1998 {
1990 cores[core].running = thread; 1999 cores[core].running = thread;
@@ -2129,7 +2138,8 @@ unsigned int wakeup_thread(struct thread_entry **list)
2129 if (bl == NULL) 2138 if (bl == NULL)
2130 { 2139 {
2131 /* No inheritance - just boost the thread by aging */ 2140 /* No inheritance - just boost the thread by aging */
2132 thread->skip_count = thread->priority; 2141 IF_NO_SKIP_YIELD( if (thread->skip_count != -1) )
2142 thread->skip_count = thread->priority;
2133 current = cores[CURRENT_CORE].running; 2143 current = cores[CURRENT_CORE].running;
2134 } 2144 }
2135 else 2145 else