diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2008-01-18 12:32:03 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2008-01-18 12:32:03 +0000 |
commit | 3b36b98ff8dea187bd6c25174978da4f7b5e3231 (patch) | |
tree | 7cd2467638206b6e3aa167bd64cae85af5f1bcca /firmware/drivers/ata.c | |
parent | 536b5a0482454d3e3104f2a77a29d37319bc845c (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.c | 24 |
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) |