qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 19/25] sdcard: check if the card capacity is supp


From: Philippe Mathieu-Daudé
Subject: [Qemu-devel] [PATCH v2 19/25] sdcard: check if the card capacity is supported
Date: Wed, 3 Jan 2018 18:24:30 -0300

The current Spec (v2.00) does not support SDXC cards (> 32GB).

Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
---
 hw/sd/sd.c         | 41 +++++++++++++++++++++++++++++++++++++++++
 hw/sd/trace-events |  1 +
 2 files changed, 42 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index ed5874e4d6..a7cede8da6 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -63,6 +63,13 @@ typedef enum {
     SD_PHY_SPEC_VER_3_01 = 301, /* not yet supported */
 } sd_phy_spec_ver_t;
 
+typedef enum {
+    sd_capacity_unknown,
+    sd_capacity_sdsc,           /* not well supported */
+    sd_capacity_sdhc,
+    sd_capacity_sdxc,           /* not yet supported */
+} sd_card_capacity_t;
+
 typedef enum {
     sd_r0 = 0,    /* no response */
     sd_r1,        /* normal response command */
@@ -121,6 +128,7 @@ struct SDState {
 
     int spec_version;
     bool spi;
+    sd_card_capacity_t capacity;
 
     uint32_t mode;    /* current card mode, one of SDCardModes */
     int32_t state;    /* current card state, one of SDCardStates */
@@ -161,6 +169,17 @@ static const char *sd_state_name(enum SDCardStates state)
     return state_name[state];
 }
 
+static const char *sd_capacity(sd_card_capacity_t capacity)
+{
+    static const char *capacity_name[] = {
+        [sd_capacity_unknown]   = "UNKN",
+        [sd_capacity_sdsc]      = "SDSC",
+        [sd_capacity_sdhc]      = "SDHC",
+        [sd_capacity_sdxc]      = "SDXC",
+    };
+    return capacity_name[capacity];
+}
+
 static const char *sd_cmd_abbreviation(uint8_t cmd)
 {
     static const char *cmd_abbrev[SDCARD_CMD_MAX] = {
@@ -1991,11 +2010,33 @@ static void sd_realize(DeviceState *dev, Error **errp)
     }
 
     if (sd->blk) {
+        int64_t size;
+
         ret = blk_set_perm(sd->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
                            BLK_PERM_ALL, errp);
         if (ret < 0) {
             return;
         }
+
+        size = blk_getlength(sd->blk);
+        if (size < 0 || size <= 2 * G_BYTE) {
+            sd->capacity = sd_capacity_sdsc;
+        } else if (size <= 32 * G_BYTE) {
+            sd->capacity = sd_capacity_sdhc;
+        } else if (size <= 2 * T_BYTE) {
+            sd->capacity = sd_capacity_sdxc;
+        } else {
+            error_setg(errp, "block size unsupported: %lld TB", size / T_BYTE);
+            return;
+        }
+        trace_sdcard_capacity(sd_capacity(sd->capacity), size);
+
+        if (sd->capacity == sd_capacity_sdxc
+                && sd->spec_version < SD_PHY_SPEC_VER_3_01) {
+            error_setg(errp, "capacity SDHC requires at least Spec v3.01");
+            return;
+        }
+
         blk_set_dev_ops(sd->blk, &sd_block_ops, sd);
     }
 }
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
index 25ab339f97..215e0eec3a 100644
--- a/hw/sd/trace-events
+++ b/hw/sd/trace-events
@@ -28,6 +28,7 @@ sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" 
PRIx64 " size 0x%x"
 sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
 sdcard_write_data(uint8_t value) "value 0x%02x"
 sdcard_read_data(int length) "len %d"
+sdcard_capacity(const char *capacity, int64_t size) "%s card (%ld B)"
 
 # hw/sd/milkymist-memcard.c
 milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x 
value 0x%08x"
-- 
2.15.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]