From 9c43b2ce17cbc1f88b825ab8a5021575cee46dd7 Mon Sep 17 00:00:00 2001 From: Frank Gevaerts Date: Sun, 6 Jun 2010 13:20:47 +0000 Subject: [PATCH] Remove card_enable_monitoring() and use a mutex instead. The card_enable_monitoring() method actually didn't eliminate the possible race conditions it was meant to fix. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26627 a1c6a512-1295-4272-9138-f99709370657 --- apps/main.c | 3 + firmware/common/disk.c | 34 ++++++++--- firmware/drivers/ata_mmc.c | 60 ++++++++----------- firmware/export/disk.h | 3 +- firmware/export/sd.h | 1 - firmware/export/sdmmc.h | 5 -- firmware/target/arm/as3525/sd-as3525.c | 12 +--- firmware/target/arm/as3525/sd-as3525v2.c | 11 +--- firmware/target/arm/ata-sd-pp.c | 27 ++------- firmware/target/arm/s3c2440/sd-s3c2440.c | 21 ++----- firmware/target/arm/tcc780x/sd-tcc780x.c | 13 +--- .../mips/ingenic_jz47xx/ata-sd-jz4740.c | 8 --- 12 files changed, 73 insertions(+), 125 deletions(-) diff --git a/apps/main.c b/apps/main.c index e8043a79d4..f8dddcd9ae 100644 --- a/apps/main.c +++ b/apps/main.c @@ -342,6 +342,7 @@ static void init(void) sb_skin_init(); viewportmanager_init(); + disk_init_subsystem(); storage_init(); settings_reset(); settings_load(SETTINGS_ALL); @@ -506,6 +507,8 @@ static void init(void) } #endif + + disk_init_subsystem(); CHART(">storage_init"); rc = storage_init(); CHART(" +#include "kernel.h" #include "storage.h" #include "debug.h" #include "fat.h" #ifdef HAVE_HOTSWAP -#include "sdmmc.h" /* for card_enable_monitoring() */ #include "dir.h" /* for release_dirs() */ #include "file.h" /* for release_files() */ #endif @@ -60,12 +60,13 @@ static const unsigned char fat_partition_types[] = { static struct partinfo part[NUM_DRIVES*4]; /* space for 4 partitions on 2 drives */ static int vol_drive[NUM_VOLUMES]; /* mounted to which drive (-1 if none) */ +static struct mutex disk_mutex; #ifdef MAX_LOG_SECTOR_SIZE int disk_sector_multiplier = 1; #endif -struct partinfo* disk_init(IF_MD_NONVOID(int drive)) +static struct partinfo* disk_init(IF_MD_NONVOID(int drive)) { int i; unsigned char sector[SECTOR_SIZE]; @@ -113,13 +114,18 @@ struct partinfo* disk_partinfo(int partition) return &part[partition]; } +void disk_init_subsystem(void) +{ + mutex_init(&disk_mutex); +} + int disk_mount_all(void) { int mounted=0; int i; #ifdef HAVE_HOTSWAP - card_enable_monitoring(false); + mutex_lock(&disk_mutex); #endif fat_init(); /* reset all mounted partitions */ @@ -139,9 +145,8 @@ int disk_mount_all(void) #endif #ifdef HAVE_HOTSWAP - card_enable_monitoring(true); + mutex_unlock(&disk_mutex); #endif - return mounted; } @@ -160,11 +165,21 @@ static int get_free_volume(void) int disk_mount(int drive) { int mounted = 0; /* reset partition-on-drive flag */ - int volume = get_free_volume(); - struct partinfo* pinfo = disk_init(IF_MD(drive)); + int volume; + struct partinfo* pinfo; + +#ifdef HAVE_HOTSWAP + mutex_lock(&disk_mutex); +#endif + + volume = get_free_volume(); + pinfo = disk_init(IF_MD(drive)); if (pinfo == NULL) { +#ifdef HAVE_HOTSWAP + mutex_unlock(&disk_mutex); +#endif return 0; } #if defined(TOSHIBA_GIGABEAT_S) @@ -214,6 +229,9 @@ int disk_mount(int drive) vol_drive[volume] = drive; /* remember the drive for this volume */ } } +#ifdef HAVE_HOTSWAP + mutex_unlock(&disk_mutex); +#endif return mounted; } @@ -222,6 +240,7 @@ int disk_unmount(int drive) { int unmounted = 0; int i; + mutex_lock(&disk_mutex); for (i=0; i= 0) - countdown--; + last_mmc_status = current_status; + countdown = HZ/3; + } + else + { + /* Count down until it gets negative */ + if (countdown >= 0) + countdown--; - if (countdown == 0) + if (countdown == 0) + { + if (current_status) { - if (current_status) - { - queue_broadcast(SYS_HOTSWAP_INSERTED, 0); - } - else - { - queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); - mmc_status = MMC_UNTOUCHED; - card_info[1].initialized = false; - } + queue_broadcast(SYS_HOTSWAP_INSERTED, 0); + } + else + { + queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); + mmc_status = MMC_UNTOUCHED; + card_info[1].initialized = false; } } } diff --git a/firmware/export/disk.h b/firmware/export/disk.h index cd937fdf66..d73a2a7f88 100644 --- a/firmware/export/disk.h +++ b/firmware/export/disk.h @@ -35,8 +35,9 @@ struct partinfo { #define PARTITION_TYPE_OS2_HIDDEN_C_DRIVE 0x84 /* returns a pointer to an array of 8 partinfo structs */ -struct partinfo* disk_init(IF_MD_NONVOID(int drive)); struct partinfo* disk_partinfo(int partition); + +void disk_init_subsystem(void); /* Initialises mutexes */ int disk_mount_all(void); /* returns the # of successful mounts */ int disk_mount(int drive); int disk_unmount(int drive); diff --git a/firmware/export/sd.h b/firmware/export/sd.h index 1c61364566..c798f54e9a 100644 --- a/firmware/export/sd.h +++ b/firmware/export/sd.h @@ -48,7 +48,6 @@ void sd_get_info(IF_MD2(int drive,) struct storage_info *info); #ifdef HAVE_HOTSWAP bool sd_removable(IF_MV_NONVOID(int drive)); bool sd_present(IF_MV_NONVOID(int drive)); -void card_enable_monitoring_target(bool on); #endif long sd_last_disk_activity(void); diff --git a/firmware/export/sdmmc.h b/firmware/export/sdmmc.h index 6ac3bd2af5..4351c85c42 100644 --- a/firmware/export/sdmmc.h +++ b/firmware/export/sdmmc.h @@ -57,17 +57,12 @@ typedef struct tCardInfo *card_get_info_target(int card_no); void sd_parse_csd(tCardInfo *card); -#ifdef HAVE_HOTSWAP -#define card_enable_monitoring card_enable_monitoring_target -#endif - #else /* STORAGE_MMC */ #include "ata_mmc.h" #define card_get_info mmc_card_info tCardInfo *mmc_card_info(int card_no); #define card_touched mmc_touched -#define card_enable_monitoring mmc_enable_monitoring #endif diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c index 9c0b4124ac..8aaae55cf4 100644 --- a/firmware/target/arm/as3525/sd-as3525.c +++ b/firmware/target/arm/as3525/sd-as3525.c @@ -508,6 +508,8 @@ static void init_pl180_controller(const int drive) GPIOA_IS &= ~EXT_SD_BITS; /* detect both raising and falling edges */ GPIOA_IBE |= EXT_SD_BITS; + /* enable the card detect interrupt */ + GPIOA_IE |= EXT_SD_BITS; #else VIC_INT_ENABLE = INTERRUPT_NAND; @@ -922,16 +924,6 @@ tCardInfo *card_get_info_target(int card_no) return &card_info[card_no]; } -#ifdef HAVE_HOTSWAP -void card_enable_monitoring_target(bool on) -{ - if (on) /* enable interrupt */ - GPIOA_IE |= EXT_SD_BITS; - else /* disable interrupt */ - GPIOA_IE &= ~EXT_SD_BITS; -} -#endif /* HAVE_HOTSWAP */ - #endif /* !BOOTLOADER */ #ifdef CONFIG_STORAGE_MULTI diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c index ccc88be25d..1a555e745d 100644 --- a/firmware/target/arm/as3525/sd-as3525v2.c +++ b/firmware/target/arm/as3525/sd-as3525v2.c @@ -731,6 +731,9 @@ int sd_init(void) GPIOA_IS &= ~EXT_SD_BITS; /* detect both raising and falling edges */ GPIOA_IBE |= EXT_SD_BITS; + /* enable the card detect interrupt */ + GPIOA_IE |= EXT_SD_BITS; + /* Configure XPD for SD-MCI interface */ CCU_IO |= (1<<2); #endif @@ -989,14 +992,6 @@ void sd_gpioa_isr(void) /* acknowledge interrupt */ GPIOA_IC = EXT_SD_BITS; } - -void card_enable_monitoring_target(bool on) -{ - if (on) /* enable interrupt */ - GPIOA_IE |= EXT_SD_BITS; - else /* disable interrupt */ - GPIOA_IE &= ~EXT_SD_BITS; -} #endif /* HAVE_HOTSWAP */ #ifdef CONFIG_STORAGE_MULTI diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c index f7b4a992e4..a2dcfe518f 100644 --- a/firmware/target/arm/ata-sd-pp.c +++ b/firmware/target/arm/ata-sd-pp.c @@ -1190,27 +1190,6 @@ void sd_enable(bool on) } } -#ifdef HAVE_HOTSWAP -void card_enable_monitoring_target(bool on) -{ - if (on) - { -#ifdef SANSA_E200 - GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80); -#elif defined(SANSA_C200) - GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08); -#endif - } - else - { -#ifdef SANSA_E200 - GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80); -#elif defined(SANSA_C200) - GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08); -#endif - } -} -#endif int sd_init(void) { @@ -1275,6 +1254,9 @@ int sd_init(void) GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80); GPIOA_INT_CLR = 0x80; + + /* enable the card detect interrupt */ + GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80); #elif defined SANSA_C200 CPU_INT_EN = HI_MASK; CPU_HI_INT_EN = GPIO2_MASK; @@ -1282,6 +1264,9 @@ int sd_init(void) GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08); GPIOL_INT_CLR = 0x08; + + /* enable the card detect interrupt */ + GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08); #endif #endif } diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c index 33b995213e..f4c8a4f599 100644 --- a/firmware/target/arm/s3c2440/sd-s3c2440.c +++ b/firmware/target/arm/s3c2440/sd-s3c2440.c @@ -270,6 +270,11 @@ static void init_sdi_controller(const int card_no) /* Card Detect input */ S3C2440_GPIO_CONFIG (GPGCON, 8, GPIO_INPUT); + /* enable external irq 8-23 on the internal interrupt controller */ + INTMSK &= ~1<<5; + /* enable GPG8 IRQ on the external interrupt controller */ + EINTMASK &= ~(1<<16); + /* Write Protect input */ S3C2440_GPIO_CONFIG (GPHCON, 8, GPIO_INPUT); @@ -523,22 +528,6 @@ static int sd1_oneshot_callback(struct timeout *tmo) return 0; } -void card_enable_monitoring_target(bool on) -{ - if (on) - { /* enable external irq 8-23 on the internal interrupt controller */ - INTMSK &= ~1<<5; - /* enable GPG8 IRQ on the external interrupt controller */ - EINTMASK &= ~(1<<16); - } - else - { - /* mask internal and external IRQs */ - INTMSK |= 1<<5; - EINTMASK |= (1<<16); - } -} - void EINT8_23(void) { static struct timeout sd1_oneshot; diff --git a/firmware/target/arm/tcc780x/sd-tcc780x.c b/firmware/target/arm/tcc780x/sd-tcc780x.c index bfab9fdddd..88ccf187f0 100644 --- a/firmware/target/arm/tcc780x/sd-tcc780x.c +++ b/firmware/target/arm/tcc780x/sd-tcc780x.c @@ -214,18 +214,6 @@ static inline bool card_detect_target(void) #endif } -void card_enable_monitoring_target(bool on) -{ - if (on) - { - IEN |= EXT0_IRQ_MASK; - } - else - { - IEN &= ~EXT0_IRQ_MASK; - } -} - static int sd1_oneshot_callback(struct timeout *tmo) { (void)tmo; @@ -786,6 +774,7 @@ int sd_init(void) /* Configure interrupts for the card slot */ TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */ TMODEA |= EXT0_IRQ_MASK; /* trigger on both edges */ + IEN |= EXT0_IRQ_MASK; /* enable the interrupt */ #endif } diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c index be534bf24e..8fdf7d0287 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c @@ -1412,14 +1412,6 @@ bool sd_removable(IF_MV_NONVOID(int drive)) return true; } -void card_enable_monitoring_target(bool on) -{ - if(on) - sd_gpio_setup_irq(card_detect_target()); - else - __gpio_mask_irq(MMC_CD_PIN); -} - static int sd_oneshot_callback(struct timeout *tmo) { (void)tmo;