summaryrefslogtreecommitdiff
path: root/firmware/drivers/ata.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-01-18 12:32:03 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-01-18 12:32:03 +0000
commit3b36b98ff8dea187bd6c25174978da4f7b5e3231 (patch)
tree7cd2467638206b6e3aa167bd64cae85af5f1bcca /firmware/drivers/ata.c
parent536b5a0482454d3e3104f2a77a29d37319bc845c (diff)
Properly serialize ata_init with other threads. Fix a bug that always initialized the lock on every call to ata_init - that should be a one time init or else the lock could be corrupted on connect.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16104 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r--firmware/drivers/ata.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 67aab8a9ba..1b917686c5 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -1128,12 +1128,18 @@ static int init_and_check(bool hard_reset)
int ata_init(void)
{
- int rc;
- bool coldstart = ata_is_coldstart();
- /* must be called before ata_device_init() */
+ int rc = 0;
+ bool coldstart;
- spinlock_init(&ata_spinlock IF_COP(, SPINLOCK_TASK_SWITCH));
+ if ( !initialized ) {
+ spinlock_init(&ata_spinlock IF_COP(, SPINLOCK_TASK_SWITCH));
+ queue_init(&ata_queue, true);
+ }
+
+ spinlock_lock(&ata_spinlock);
+ /* must be called before ata_device_init() */
+ coldstart = ata_is_coldstart();
ata_led(false);
ata_device_init();
sleeping = false;
@@ -1143,6 +1149,9 @@ int ata_init(void)
#endif
if ( !initialized ) {
+ /* First call won't have multiple thread contention */
+ spinlock_unlock(&ata_spinlock);
+
if (!ide_powered()) /* somebody has switched it off */
{
ide_power_enable(true);
@@ -1202,8 +1211,6 @@ int ata_init(void)
if (rc)
return -60 + rc;
- queue_init(&ata_queue, true);
-
last_disk_activity = current_tick;
create_thread(ata_thread, ata_stack,
sizeof(ata_stack), 0, ata_thread_name
@@ -1214,9 +1221,10 @@ int ata_init(void)
}
rc = set_multiple_mode(multisectors);
if (rc)
- return -70 + rc;
+ rc = -70 + rc;
- return 0;
+ spinlock_unlock(&ata_spinlock);
+ return rc;
}
#if (CONFIG_LED == LED_REAL)