1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 97bd698..ab2f282 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -1910,20 +1910,20 @@ static int disk_callback(int btn, struct gui_synclist *lists)
             strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
             simplelist_addline(SIMPLELIST_ADD_LINE,
                     "%s Rev %d.%d", card_name,
-                    (int) card_extract_bits(card->cid, 72, 4),
-                    (int) card_extract_bits(card->cid, 76, 4));
+                    (int) card_extract_bits(card->cid, 55, 4),
+                    (int) card_extract_bits(card->cid, 51, 4));
             simplelist_addline(SIMPLELIST_ADD_LINE,
                     "Prod: %d/%d",
-                    (int) card_extract_bits(card->cid, 112, 4),
-                    (int) card_extract_bits(card->cid, 116, 4) + 1997);
+                    (int) card_extract_bits(card->cid, 15, 4),
+                    (int) card_extract_bits(card->cid, 11, 4) + 1997);
             simplelist_addline(SIMPLELIST_ADD_LINE,
                     "Ser#: 0x%08lx",
-                    card_extract_bits(card->cid, 80, 32));
+                    card_extract_bits(card->cid, 47, 32));
             simplelist_addline(SIMPLELIST_ADD_LINE,
                     "M=%02x, O=%04x",
-                    (int) card_extract_bits(card->cid, 0, 8),
-                    (int) card_extract_bits(card->cid, 8, 16));
-            int temp = card_extract_bits(card->csd, 2, 4);
+                    (int) card_extract_bits(card->cid, 127, 8),
+                    (int) card_extract_bits(card->cid, 119, 16));
+            int temp = card_extract_bits(card->csd, 125, 4);
             simplelist_addline(SIMPLELIST_ADD_LINE,
                      CARDTYPE " v%s", temp < 5 ?
                             spec_vers[temp] : "?.?");
@@ -1943,12 +1943,12 @@ static int disk_callback(int btn, struct gui_synclist *lists)
                     "R2W: *%d", card->r2w_factor);
             simplelist_addline(SIMPLELIST_ADD_LINE,
                     "IRmax: %d..%d mA",
-                    i_vmin[card_extract_bits(card->csd, 66, 3)],
-                    i_vmax[card_extract_bits(card->csd, 69, 3)]);
+                    i_vmin[card_extract_bits(card->csd, 61, 3)],
+                    i_vmax[card_extract_bits(card->csd, 58, 3)]);
             simplelist_addline(SIMPLELIST_ADD_LINE,
                     "IWmax: %d..%d mA",
-                    i_vmin[card_extract_bits(card->csd, 72, 3)],
-                    i_vmax[card_extract_bits(card->csd, 75, 3)]);
+                    i_vmin[card_extract_bits(card->csd, 55, 3)],
+                    i_vmax[card_extract_bits(card->csd, 52, 3)]);
         }
         else if (card->initialized == 0)
         {
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c
index 1dc330c..0fe89c5 100644
--- a/firmware/drivers/ata_mmc.c
+++ b/firmware/drivers/ata_mmc.c
@@ -425,25 +425,25 @@ static int initialize_card(int card_no)
     if (rc)
         return rc * 10 - 5;

-    blk_exp = card_extract_bits(card->csd, 44, 4);
+    blk_exp = card_extract_bits(card->csd, 83, 4);
     if (blk_exp < 9) /* block size < 512 bytes not supported */
         return -6;

-    card->numblocks = (card_extract_bits(card->csd, 54, 12) + 1)
-                   << (card_extract_bits(card->csd, 78, 3) + 2 + blk_exp - 9);
+    card->numblocks = (card_extract_bits(card->csd, 73, 12) + 1)
+                   << (card_extract_bits(card->csd, 49, 3) + 2 + blk_exp - 9);
     card->blocksize = BLOCK_SIZE;

     /* max transmission speed, clock divider */
-    ts_exp = card_extract_bits(card->csd, 29, 3);
+    ts_exp = card_extract_bits(card->csd, 98, 3);
     ts_exp = (ts_exp > 3) ? 3 : ts_exp;
-    card->speed = mantissa[card_extract_bits(card->csd, 25, 4)]
+    card->speed = mantissa[card_extract_bits(card->csd, 102, 4)]
                 * exponent[ts_exp + 4];
     card->bitrate_register = (FREQ/4-1) / card->speed;

     /* NSAC, TAAC, read timeout */
-    card->nsac = 100 * card_extract_bits(card->csd, 16, 8);
-    card->taac = mantissa[card_extract_bits(card->csd, 9, 4)];
-    taac_exp = card_extract_bits(card->csd, 13, 3);
+    card->nsac = 100 * card_extract_bits(card->csd, 111, 8);
+    card->taac = mantissa[card_extract_bits(card->csd, 118, 4)];
+    taac_exp = card_extract_bits(card->csd, 114, 3);
     card->read_timeout = ((FREQ/4) / (card->bitrate_register + 1)
                          * card->taac / exponent[9 - taac_exp]
                          + (10 * card->nsac));
@@ -451,7 +451,7 @@ static int initialize_card(int card_no)
     card->taac = card->taac * exponent[taac_exp] / 10;

     /* r2w_factor, write timeout */
-    card->r2w_factor = BIT_N(card_extract_bits(card->csd, 99, 3));
+    card->r2w_factor = BIT_N(card_extract_bits(card->csd, 28, 3));
     card->write_timeout = card->read_timeout * card->r2w_factor;

     if (card->r2w_factor > 32) /* Such cards often need extra read delay */
diff --git a/firmware/hotswap.c b/firmware/hotswap.c
index 97c162c..ec298f7 100644
--- a/firmware/hotswap.c
+++ b/firmware/hotswap.c
@@ -33,9 +33,14 @@ unsigned long card_extract_bits(
     unsigned int start,     /* bit no. to start reading  */
     unsigned int size)      /* how many bits to read */
 {
-    unsigned int long_index = start / 32;
-    unsigned int bit_index = start % 32;
+    unsigned int long_index, bit_index;
     unsigned long result;
+
+    /* we assume words of CSD/CID are stored least significant word first */
+    start = 127 - start;
+
+    long_index = start / 32;
+    bit_index = start % 32;

     result = p[long_index] << bit_index;

diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c
index ade5b80..8f30195 100644
--- a/firmware/target/arm/ata-sd-pp.c
+++ b/firmware/target/arm/ata-sd-pp.c
@@ -1306,12 +1306,12 @@ tCardInfo *card_get_info_target(int card_no)
     for(i=0; i<4; i++)  card.cid[i] = card_info[card_no].cid[3-i];
     card.numblocks    = card_info[card_no].numblocks;
     card.blocksize    = card_info[card_no].blocksize;
-    temp              = card_extract_bits(card.csd, 29, 3);
-    card.speed        = mantissa[card_extract_bits(card.csd, 25, 4)]
+    temp              = card_extract_bits(card.csd, 98, 3);
+    card.speed        = mantissa[card_extract_bits(card.csd, 102, 4)]
                       * exponent[temp > 2 ? 7 : temp + 4];
-    card.nsac         = 100 * card_extract_bits(card.csd, 16, 8);
-    temp              = card_extract_bits(card.csd, 13, 3);
-    card.taac         = mantissa[card_extract_bits(card.csd, 9, 4)]
+    card.nsac         = 100 * card_extract_bits(card.csd, 111, 8);
+    temp              = card_extract_bits(card.csd, 114, 3);
+    card.taac         = mantissa[card_extract_bits(card.csd, 118, 4)]
                       * exponent[temp] / 10;
     card.cid[0]       = htobe32(card.cid[0]); /* ascii chars here */
     card.cid[1]       = htobe32(card.cid[1]); /* ascii chars here */
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
index 0ec1791..2a38156 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
@@ -1679,12 +1679,12 @@ tCardInfo* card_get_info_target(int card_no)
         card.csd[i] = (*((unsigned long*)&mmcinfo.csd+4*i));
     for(i=0; i<4; i++)
         card.cid[i] = (*((unsigned long*)&mmcinfo.cid+4*i));
-    temp              = card_extract_bits(card.csd, 29, 3);
-    card.speed        = sd_mantissa[card_extract_bits(card.csd, 25, 4)]
+    temp              = card_extract_bits(card.csd, 98, 3);
+    card.speed        = sd_mantissa[card_extract_bits(card.csd, 102, 4)]
                       * sd_exponent[temp > 2 ? 7 : temp + 4];
-    card.nsac         = 100 * card_extract_bits(card.csd, 16, 8);
-    temp              = card_extract_bits(card.csd, 13, 3);
-    card.taac         = sd_mantissa[card_extract_bits(card.csd, 9, 4)]
+    card.nsac         = 100 * card_extract_bits(card.csd, 111, 8);
+    temp              = card_extract_bits(card.csd, 114, 3);
+    card.taac         = sd_mantissa[card_extract_bits(card.csd, 118, 4)]
                       * sd_exponent[temp] / 10;
     card.numblocks = mmcinfo.block_num;
     card.blocksize = mmcinfo.block_len;