summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2010-06-22 08:37:26 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2010-06-22 08:37:26 +0000
commit58eccd0b7ce0d553d60d1f830a79a5a6ab536b36 (patch)
treefdce89308a0e36268afc895083cae220f1c284fb /c
parent2010-06-21 Joel Sherrill <joel.sherrill@oarcorp.com> (diff)
downloadrtems-58eccd0b7ce0d553d60d1f830a79a5a6ab536b36.tar.bz2
2010-06-22 Arnout Vandecappelle <arnout@mind.be>
PR 1567/misc * libchip/i2c/spi-sd-card.h, libchip/i2c/spi-sd-card.c: Fixed timeouts.
Diffstat (limited to 'c')
-rw-r--r--c/src/ChangeLog6
-rw-r--r--c/src/libchip/i2c/spi-sd-card.c27
-rw-r--r--c/src/libchip/i2c/spi-sd-card.h3
3 files changed, 31 insertions, 5 deletions
diff --git a/c/src/ChangeLog b/c/src/ChangeLog
index 41bdf2830c..fe1f6677d8 100644
--- a/c/src/ChangeLog
+++ b/c/src/ChangeLog
@@ -1,3 +1,9 @@
+2010-06-22 Arnout Vandecappelle <arnout@mind.be>
+
+ PR 1567/misc
+ * libchip/i2c/spi-sd-card.h, libchip/i2c/spi-sd-card.c: Fixed
+ timeouts.
+
2010-06-21 Arnout Vandecappelle <arnout@mind.be>
PR 1576/misc
diff --git a/c/src/libchip/i2c/spi-sd-card.c b/c/src/libchip/i2c/spi-sd-card.c
index 3289c72f9b..ac395304dc 100644
--- a/c/src/libchip/i2c/spi-sd-card.c
+++ b/c/src/libchip/i2c/spi-sd-card.c
@@ -301,9 +301,16 @@ static inline uint32_t sd_card_access_time( const uint8_t *csd)
static inline uint32_t sd_card_max_access_time( const uint8_t *csd, uint32_t transfer_speed)
{
uint64_t ac = sd_card_access_time( csd);
+ uint32_t ac_100ms = transfer_speed / 80;
uint32_t n = SD_CARD_CSD_GET_NSAC( csd) * 100;
- ac = (ac * transfer_speed) / 8000000000ULL;
- return n + (uint32_t) ac;
+ /* ac is in ns, transfer_speed in bps, max_access_time in bytes.
+ max_access_time is 100 times typical access time (taac+nsac) */
+ ac = ac * transfer_speed / 80000000;
+ ac = ac + 100*n;
+ if ((uint32_t)ac > ac_100ms)
+ return ac_100ms;
+ else
+ return (uint32_t)ac;
}
/** @} */
@@ -362,6 +369,10 @@ static int sd_card_wait( sd_card_driver_entry *e)
int rv = 0;
int r = 0;
int n = 2;
+ /* For writes, the timeout is 2.5 times that of reads; since we
+ don't know if it is a write or read, assume write.
+ FIXME should actually look at R2W_FACTOR for non-HC cards. */
+ int retries = e->n_ac_max * 25 / 10;
while (e->busy) {
/* Query busy tokens */
rv = sd_card_query( e, e->response, n);
@@ -374,6 +385,10 @@ static int sd_card_wait( sd_card_driver_entry *e)
return 0;
}
}
+ retries -= n;
+ if (retries <= 0) {
+ return -RTEMS_TIMEOUT;
+ }
n = SD_CARD_COMMAND_SIZE;
if (e->schedule_if_busy) {
@@ -957,6 +972,9 @@ static rtems_status_code sd_card_init( sd_card_driver_entry *e)
capacity = (c_size + 1) * 512 * 1024;
read_block_size = 512;
write_block_size = 512;
+
+ /* Timeout is fixed at 100ms in CSD Version 2.0 */
+ e->n_ac_max = transfer_speed / 80;
} else {
RTEMS_DO_CLEANUP_SC( RTEMS_IO_ERROR, sc, sd_card_driver_init_cleanup, "Unexpected CSD Structure number");
}
@@ -967,6 +985,7 @@ static rtems_status_code sd_card_init( sd_card_driver_entry *e)
RTEMS_SYSLOG( "CSD structure : %" PRIu8 "\n", SD_CARD_CSD_GET_CSD_STRUCTURE( block));
RTEMS_SYSLOG( "Spec version : %" PRIu8 "\n", SD_CARD_CSD_GET_SPEC_VERS( block));
RTEMS_SYSLOG( "Access time [ns] : %" PRIu32 "\n", sd_card_access_time( block));
+ RTEMS_SYSLOG( "Access time [N] : %" PRIu32 "\n", SD_CARD_CSD_GET_NSAC( block)*100);
RTEMS_SYSLOG( "Max access time [N] : %" PRIu32 "\n", e->n_ac_max);
RTEMS_SYSLOG( "Max read block size [B] : %" PRIu32 "\n", read_block_size);
RTEMS_SYSLOG( "Max write block size [B] : %" PRIu32 "\n", write_block_size);
@@ -1206,14 +1225,14 @@ static int sd_card_disk_ioctl( rtems_disk_device *dd, uint32_t req, void *arg)
case RTEMS_BLKDEV_REQ_WRITE:
return sd_card_disk_block_write( e, r);
default:
- errno = EINVAL;
+ errno = EINVAL;
return -1;
}
} else if (req == RTEMS_BLKIO_CAPABILITIES) {
*(uint32_t *) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
return 0;
} else {
- errno = EINVAL;
+ errno = EINVAL;
return -1;
}
}
diff --git a/c/src/libchip/i2c/spi-sd-card.h b/c/src/libchip/i2c/spi-sd-card.h
index 9817381c33..fecd89cbc6 100644
--- a/c/src/libchip/i2c/spi-sd-card.h
+++ b/c/src/libchip/i2c/spi-sd-card.h
@@ -52,7 +52,8 @@ extern "C" {
SD_CARD_IDLE_TOKEN \
}
-#define SD_CARD_N_AC_MAX_DEFAULT 8
+/* Default speed = 400kbps, default timeout = 100ms, n_ac_max is in bytes */
+#define SD_CARD_N_AC_MAX_DEFAULT 5000
typedef struct {
const char *device_name;