diff options
Diffstat (limited to 'drivers/mmc/core')
| -rw-r--r-- | drivers/mmc/core/core.c | 346 | ||||
| -rw-r--r-- | drivers/mmc/core/core.h | 2 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc.c | 47 | ||||
| -rw-r--r-- | drivers/mmc/core/sd.c | 82 | ||||
| -rw-r--r-- | drivers/mmc/core/sd_ops.c | 48 | ||||
| -rw-r--r-- | drivers/mmc/core/sd_ops.h | 1 |
6 files changed, 525 insertions, 1 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 83240faa1dc8..5db49b124ffa 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -1050,6 +1050,352 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay) | |||
| 1050 | 1050 | ||
| 1051 | EXPORT_SYMBOL(mmc_detect_change); | 1051 | EXPORT_SYMBOL(mmc_detect_change); |
| 1052 | 1052 | ||
| 1053 | void mmc_init_erase(struct mmc_card *card) | ||
| 1054 | { | ||
| 1055 | unsigned int sz; | ||
| 1056 | |||
| 1057 | if (is_power_of_2(card->erase_size)) | ||
| 1058 | card->erase_shift = ffs(card->erase_size) - 1; | ||
| 1059 | else | ||
| 1060 | card->erase_shift = 0; | ||
| 1061 | |||
| 1062 | /* | ||
| 1063 | * It is possible to erase an arbitrarily large area of an SD or MMC | ||
| 1064 | * card. That is not desirable because it can take a long time | ||
| 1065 | * (minutes) potentially delaying more important I/O, and also the | ||
| 1066 | * timeout calculations become increasingly hugely over-estimated. | ||
| 1067 | * Consequently, 'pref_erase' is defined as a guide to limit erases | ||
| 1068 | * to that size and alignment. | ||
| 1069 | * | ||
| 1070 | * For SD cards that define Allocation Unit size, limit erases to one | ||
| 1071 | * Allocation Unit at a time. For MMC cards that define High Capacity | ||
| 1072 | * Erase Size, whether it is switched on or not, limit to that size. | ||
| 1073 | * Otherwise just have a stab at a good value. For modern cards it | ||
| 1074 | * will end up being 4MiB. Note that if the value is too small, it | ||
| 1075 | * can end up taking longer to erase. | ||
| 1076 | */ | ||
| 1077 | if (mmc_card_sd(card) && card->ssr.au) { | ||
| 1078 | card->pref_erase = card->ssr.au; | ||
| 1079 | card->erase_shift = ffs(card->ssr.au) - 1; | ||
| 1080 | } else if (card->ext_csd.hc_erase_size) { | ||
| 1081 | card->pref_erase = card->ext_csd.hc_erase_size; | ||
| 1082 | } else { | ||
| 1083 | sz = (card->csd.capacity << (card->csd.read_blkbits - 9)) >> 11; | ||
| 1084 | if (sz < 128) | ||
| 1085 | card->pref_erase = 512 * 1024 / 512; | ||
| 1086 | else if (sz < 512) | ||
| 1087 | card->pref_erase = 1024 * 1024 / 512; | ||
| 1088 | else if (sz < 1024) | ||
| 1089 | card->pref_erase = 2 * 1024 * 1024 / 512; | ||
| 1090 | else | ||
| 1091 | card->pref_erase = 4 * 1024 * 1024 / 512; | ||
| 1092 | if (card->pref_erase < card->erase_size) | ||
| 1093 | card->pref_erase = card->erase_size; | ||
| 1094 | else { | ||
| 1095 | sz = card->pref_erase % card->erase_size; | ||
| 1096 | if (sz) | ||
| 1097 | card->pref_erase += card->erase_size - sz; | ||
| 1098 | } | ||
| 1099 | } | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | static void mmc_set_mmc_erase_timeout(struct mmc_card *card, | ||
| 1103 | struct mmc_command *cmd, | ||
| 1104 | unsigned int arg, unsigned int qty) | ||
| 1105 | { | ||
| 1106 | unsigned int erase_timeout; | ||
| 1107 | |||
| 1108 | if (card->ext_csd.erase_group_def & 1) { | ||
| 1109 | /* High Capacity Erase Group Size uses HC timeouts */ | ||
| 1110 | if (arg == MMC_TRIM_ARG) | ||
| 1111 | erase_timeout = card->ext_csd.trim_timeout; | ||
| 1112 | else | ||
| 1113 | erase_timeout = card->ext_csd.hc_erase_timeout; | ||
| 1114 | } else { | ||
| 1115 | /* CSD Erase Group Size uses write timeout */ | ||
| 1116 | unsigned int mult = (10 << card->csd.r2w_factor); | ||
| 1117 | unsigned int timeout_clks = card->csd.tacc_clks * mult; | ||
| 1118 | unsigned int timeout_us; | ||
| 1119 | |||
| 1120 | /* Avoid overflow: e.g. tacc_ns=80000000 mult=1280 */ | ||
| 1121 | if (card->csd.tacc_ns < 1000000) | ||
| 1122 | timeout_us = (card->csd.tacc_ns * mult) / 1000; | ||
| 1123 | else | ||
| 1124 | timeout_us = (card->csd.tacc_ns / 1000) * mult; | ||
| 1125 | |||
| 1126 | /* | ||
| 1127 | * ios.clock is only a target. The real clock rate might be | ||
| 1128 | * less but not that much less, so fudge it by multiplying by 2. | ||
| 1129 | */ | ||
| 1130 | timeout_clks <<= 1; | ||
| 1131 | timeout_us += (timeout_clks * 1000) / | ||
| 1132 | (card->host->ios.clock / 1000); | ||
| 1133 | |||
| 1134 | erase_timeout = timeout_us / 1000; | ||
| 1135 | |||
| 1136 | /* | ||
| 1137 | * Theoretically, the calculation could underflow so round up | ||
| 1138 | * to 1ms in that case. | ||
| 1139 | */ | ||
| 1140 | if (!erase_timeout) | ||
| 1141 | erase_timeout = 1; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | /* Multiplier for secure operations */ | ||
| 1145 | if (arg & MMC_SECURE_ARGS) { | ||
| 1146 | if (arg == MMC_SECURE_ERASE_ARG) | ||
| 1147 | erase_timeout *= card->ext_csd.sec_erase_mult; | ||
| 1148 | else | ||
| 1149 | erase_timeout *= card->ext_csd.sec_trim_mult; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | erase_timeout *= qty; | ||
| 1153 | |||
| 1154 | /* | ||
| 1155 | * Ensure at least a 1 second timeout for SPI as per | ||
| 1156 | * 'mmc_set_data_timeout()' | ||
| 1157 | */ | ||
| 1158 | if (mmc_host_is_spi(card->host) && erase_timeout < 1000) | ||
| 1159 | erase_timeout = 1000; | ||
| 1160 | |||
| 1161 | cmd->erase_timeout = erase_timeout; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | static void mmc_set_sd_erase_timeout(struct mmc_card *card, | ||
| 1165 | struct mmc_command *cmd, unsigned int arg, | ||
| 1166 | unsigned int qty) | ||
| 1167 | { | ||
| 1168 | if (card->ssr.erase_timeout) { | ||
| 1169 | /* Erase timeout specified in SD Status Register (SSR) */ | ||
| 1170 | cmd->erase_timeout = card->ssr.erase_timeout * qty + | ||
| 1171 | card->ssr.erase_offset; | ||
| 1172 | } else { | ||
| 1173 | /* | ||
| 1174 | * Erase timeout not specified in SD Status Register (SSR) so | ||
| 1175 | * use 250ms per write block. | ||
| 1176 | */ | ||
| 1177 | cmd->erase_timeout = 250 * qty; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | /* Must not be less than 1 second */ | ||
| 1181 | if (cmd->erase_timeout < 1000) | ||
| 1182 | cmd->erase_timeout = 1000; | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | static void mmc_set_erase_timeout(struct mmc_card *card, | ||
| 1186 | struct mmc_command *cmd, unsigned int arg, | ||
| 1187 | unsigned int qty) | ||
| 1188 | { | ||
| 1189 | if (mmc_card_sd(card)) | ||
| 1190 | mmc_set_sd_erase_timeout(card, cmd, arg, qty); | ||
| 1191 | else | ||
| 1192 | mmc_set_mmc_erase_timeout(card, cmd, arg, qty); | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | static int mmc_do_erase(struct mmc_card *card, unsigned int from, | ||
| 1196 | unsigned int to, unsigned int arg) | ||
| 1197 | { | ||
| 1198 | struct mmc_command cmd; | ||
| 1199 | unsigned int qty = 0; | ||
| 1200 | int err; | ||
| 1201 | |||
| 1202 | /* | ||
| 1203 | * qty is used to calculate the erase timeout which depends on how many | ||
| 1204 | * erase groups (or allocation units in SD terminology) are affected. | ||
| 1205 | * We count erasing part of an erase group as one erase group. | ||
| 1206 | * For SD, the allocation units are always a power of 2. For MMC, the | ||
| 1207 | * erase group size is almost certainly also power of 2, but it does not | ||
| 1208 | * seem to insist on that in the JEDEC standard, so we fall back to | ||
| 1209 | * division in that case. SD may not specify an allocation unit size, | ||
| 1210 | * in which case the timeout is based on the number of write blocks. | ||
| 1211 | * | ||
| 1212 | * Note that the timeout for secure trim 2 will only be correct if the | ||
| 1213 | * number of erase groups specified is the same as the total of all | ||
| 1214 | * preceding secure trim 1 commands. Since the power may have been | ||
| 1215 | * lost since the secure trim 1 commands occurred, it is generally | ||
| 1216 | * impossible to calculate the secure trim 2 timeout correctly. | ||
| 1217 | */ | ||
| 1218 | if (card->erase_shift) | ||
| 1219 | qty += ((to >> card->erase_shift) - | ||
| 1220 | (from >> card->erase_shift)) + 1; | ||
| 1221 | else if (mmc_card_sd(card)) | ||
| 1222 | qty += to - from + 1; | ||
| 1223 | else | ||
| 1224 | qty += ((to / card->erase_size) - | ||
| 1225 | (from / card->erase_size)) + 1; | ||
| 1226 | |||
| 1227 | if (!mmc_card_blockaddr(card)) { | ||
| 1228 | from <<= 9; | ||
| 1229 | to <<= 9; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1233 | if (mmc_card_sd(card)) | ||
| 1234 | cmd.opcode = SD_ERASE_WR_BLK_START; | ||
| 1235 | else | ||
| 1236 | cmd.opcode = MMC_ERASE_GROUP_START; | ||
| 1237 | cmd.arg = from; | ||
| 1238 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; | ||
| 1239 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | ||
| 1240 | if (err) { | ||
| 1241 | printk(KERN_ERR "mmc_erase: group start error %d, " | ||
| 1242 | "status %#x\n", err, cmd.resp[0]); | ||
| 1243 | err = -EINVAL; | ||
| 1244 | goto out; | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1248 | if (mmc_card_sd(card)) | ||
| 1249 | cmd.opcode = SD_ERASE_WR_BLK_END; | ||
| 1250 | else | ||
| 1251 | cmd.opcode = MMC_ERASE_GROUP_END; | ||
| 1252 | cmd.arg = to; | ||
| 1253 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; | ||
| 1254 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | ||
| 1255 | if (err) { | ||
| 1256 | printk(KERN_ERR "mmc_erase: group end error %d, status %#x\n", | ||
| 1257 | err, cmd.resp[0]); | ||
| 1258 | err = -EINVAL; | ||
| 1259 | goto out; | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1263 | cmd.opcode = MMC_ERASE; | ||
| 1264 | cmd.arg = arg; | ||
| 1265 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | ||
| 1266 | mmc_set_erase_timeout(card, &cmd, arg, qty); | ||
| 1267 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | ||
| 1268 | if (err) { | ||
| 1269 | printk(KERN_ERR "mmc_erase: erase error %d, status %#x\n", | ||
| 1270 | err, cmd.resp[0]); | ||
| 1271 | err = -EIO; | ||
| 1272 | goto out; | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | if (mmc_host_is_spi(card->host)) | ||
| 1276 | goto out; | ||
| 1277 | |||
| 1278 | do { | ||
| 1279 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1280 | cmd.opcode = MMC_SEND_STATUS; | ||
| 1281 | cmd.arg = card->rca << 16; | ||
| 1282 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 1283 | /* Do not retry else we can't see errors */ | ||
| 1284 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | ||
| 1285 | if (err || (cmd.resp[0] & 0xFDF92000)) { | ||
| 1286 | printk(KERN_ERR "error %d requesting status %#x\n", | ||
| 1287 | err, cmd.resp[0]); | ||
| 1288 | err = -EIO; | ||
| 1289 | goto out; | ||
| 1290 | } | ||
| 1291 | } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || | ||
| 1292 | R1_CURRENT_STATE(cmd.resp[0]) == 7); | ||
| 1293 | out: | ||
| 1294 | return err; | ||
| 1295 | } | ||
| 1296 | |||
| 1297 | /** | ||
| 1298 | * mmc_erase - erase sectors. | ||
| 1299 | * @card: card to erase | ||
| 1300 | * @from: first sector to erase | ||
| 1301 | * @nr: number of sectors to erase | ||
| 1302 | * @arg: erase command argument (SD supports only %MMC_ERASE_ARG) | ||
| 1303 | * | ||
| 1304 | * Caller must claim host before calling this function. | ||
| 1305 | */ | ||
| 1306 | int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, | ||
| 1307 | unsigned int arg) | ||
| 1308 | { | ||
| 1309 | unsigned int rem, to = from + nr; | ||
| 1310 | |||
| 1311 | if (!(card->host->caps & MMC_CAP_ERASE) || | ||
| 1312 | !(card->csd.cmdclass & CCC_ERASE)) | ||
| 1313 | return -EOPNOTSUPP; | ||
| 1314 | |||
| 1315 | if (!card->erase_size) | ||
| 1316 | return -EOPNOTSUPP; | ||
| 1317 | |||
| 1318 | if (mmc_card_sd(card) && arg != MMC_ERASE_ARG) | ||
| 1319 | return -EOPNOTSUPP; | ||
| 1320 | |||
| 1321 | if ((arg & MMC_SECURE_ARGS) && | ||
| 1322 | !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) | ||
| 1323 | return -EOPNOTSUPP; | ||
| 1324 | |||
| 1325 | if ((arg & MMC_TRIM_ARGS) && | ||
| 1326 | !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) | ||
| 1327 | return -EOPNOTSUPP; | ||
| 1328 | |||
| 1329 | if (arg == MMC_SECURE_ERASE_ARG) { | ||
| 1330 | if (from % card->erase_size || nr % card->erase_size) | ||
| 1331 | return -EINVAL; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | if (arg == MMC_ERASE_ARG) { | ||
| 1335 | rem = from % card->erase_size; | ||
| 1336 | if (rem) { | ||
| 1337 | rem = card->erase_size - rem; | ||
| 1338 | from += rem; | ||
| 1339 | if (nr > rem) | ||
| 1340 | nr -= rem; | ||
| 1341 | else | ||
| 1342 | return 0; | ||
| 1343 | } | ||
| 1344 | rem = nr % card->erase_size; | ||
| 1345 | if (rem) | ||
| 1346 | nr -= rem; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | if (nr == 0) | ||
| 1350 | return 0; | ||
| 1351 | |||
| 1352 | to = from + nr; | ||
| 1353 | |||
| 1354 | if (to <= from) | ||
| 1355 | return -EINVAL; | ||
| 1356 | |||
| 1357 | /* 'from' and 'to' are inclusive */ | ||
| 1358 | to -= 1; | ||
| 1359 | |||
| 1360 | return mmc_do_erase(card, from, to, arg); | ||
| 1361 | } | ||
| 1362 | EXPORT_SYMBOL(mmc_erase); | ||
| 1363 | |||
| 1364 | int mmc_can_erase(struct mmc_card *card) | ||
| 1365 | { | ||
| 1366 | if ((card->host->caps & MMC_CAP_ERASE) && | ||
| 1367 | (card->csd.cmdclass & CCC_ERASE) && card->erase_size) | ||
| 1368 | return 1; | ||
| 1369 | return 0; | ||
| 1370 | } | ||
| 1371 | EXPORT_SYMBOL(mmc_can_erase); | ||
| 1372 | |||
| 1373 | int mmc_can_trim(struct mmc_card *card) | ||
| 1374 | { | ||
| 1375 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) | ||
| 1376 | return 1; | ||
| 1377 | return 0; | ||
| 1378 | } | ||
| 1379 | EXPORT_SYMBOL(mmc_can_trim); | ||
| 1380 | |||
| 1381 | int mmc_can_secure_erase_trim(struct mmc_card *card) | ||
| 1382 | { | ||
| 1383 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN) | ||
| 1384 | return 1; | ||
| 1385 | return 0; | ||
| 1386 | } | ||
| 1387 | EXPORT_SYMBOL(mmc_can_secure_erase_trim); | ||
| 1388 | |||
| 1389 | int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, | ||
| 1390 | unsigned int nr) | ||
| 1391 | { | ||
| 1392 | if (!card->erase_size) | ||
| 1393 | return 0; | ||
| 1394 | if (from % card->erase_size || nr % card->erase_size) | ||
| 1395 | return 0; | ||
| 1396 | return 1; | ||
| 1397 | } | ||
| 1398 | EXPORT_SYMBOL(mmc_erase_group_aligned); | ||
| 1053 | 1399 | ||
| 1054 | void mmc_rescan(struct work_struct *work) | 1400 | void mmc_rescan(struct work_struct *work) |
| 1055 | { | 1401 | { |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index a811c52a1659..9d9eef50e5d1 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
| @@ -29,6 +29,8 @@ struct mmc_bus_ops { | |||
| 29 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 29 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
| 30 | void mmc_detach_bus(struct mmc_host *host); | 30 | void mmc_detach_bus(struct mmc_host *host); |
| 31 | 31 | ||
| 32 | void mmc_init_erase(struct mmc_card *card); | ||
| 33 | |||
| 32 | void mmc_set_chip_select(struct mmc_host *host, int mode); | 34 | void mmc_set_chip_select(struct mmc_host *host, int mode); |
| 33 | void mmc_set_clock(struct mmc_host *host, unsigned int hz); | 35 | void mmc_set_clock(struct mmc_host *host, unsigned int hz); |
| 34 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); | 36 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index ccba3869c029..6909a54c39be 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
| @@ -108,13 +108,23 @@ static int mmc_decode_cid(struct mmc_card *card) | |||
| 108 | return 0; | 108 | return 0; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static void mmc_set_erase_size(struct mmc_card *card) | ||
| 112 | { | ||
| 113 | if (card->ext_csd.erase_group_def & 1) | ||
| 114 | card->erase_size = card->ext_csd.hc_erase_size; | ||
| 115 | else | ||
| 116 | card->erase_size = card->csd.erase_size; | ||
| 117 | |||
| 118 | mmc_init_erase(card); | ||
| 119 | } | ||
| 120 | |||
| 111 | /* | 121 | /* |
| 112 | * Given a 128-bit response, decode to our card CSD structure. | 122 | * Given a 128-bit response, decode to our card CSD structure. |
| 113 | */ | 123 | */ |
| 114 | static int mmc_decode_csd(struct mmc_card *card) | 124 | static int mmc_decode_csd(struct mmc_card *card) |
| 115 | { | 125 | { |
| 116 | struct mmc_csd *csd = &card->csd; | 126 | struct mmc_csd *csd = &card->csd; |
| 117 | unsigned int e, m; | 127 | unsigned int e, m, a, b; |
| 118 | u32 *resp = card->raw_csd; | 128 | u32 *resp = card->raw_csd; |
| 119 | 129 | ||
| 120 | /* | 130 | /* |
| @@ -152,6 +162,13 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
| 152 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | 162 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); |
| 153 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | 163 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); |
| 154 | 164 | ||
| 165 | if (csd->write_blkbits >= 9) { | ||
| 166 | a = UNSTUFF_BITS(resp, 42, 5); | ||
| 167 | b = UNSTUFF_BITS(resp, 37, 5); | ||
| 168 | csd->erase_size = (a + 1) * (b + 1); | ||
| 169 | csd->erase_size <<= csd->write_blkbits - 9; | ||
| 170 | } | ||
| 171 | |||
| 155 | return 0; | 172 | return 0; |
| 156 | } | 173 | } |
| 157 | 174 | ||
| @@ -261,8 +278,30 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
| 261 | if (sa_shift > 0 && sa_shift <= 0x17) | 278 | if (sa_shift > 0 && sa_shift <= 0x17) |
| 262 | card->ext_csd.sa_timeout = | 279 | card->ext_csd.sa_timeout = |
| 263 | 1 << ext_csd[EXT_CSD_S_A_TIMEOUT]; | 280 | 1 << ext_csd[EXT_CSD_S_A_TIMEOUT]; |
| 281 | card->ext_csd.erase_group_def = | ||
| 282 | ext_csd[EXT_CSD_ERASE_GROUP_DEF]; | ||
| 283 | card->ext_csd.hc_erase_timeout = 300 * | ||
| 284 | ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; | ||
| 285 | card->ext_csd.hc_erase_size = | ||
| 286 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10; | ||
| 287 | } | ||
| 288 | |||
| 289 | if (card->ext_csd.rev >= 4) { | ||
| 290 | card->ext_csd.sec_trim_mult = | ||
| 291 | ext_csd[EXT_CSD_SEC_TRIM_MULT]; | ||
| 292 | card->ext_csd.sec_erase_mult = | ||
| 293 | ext_csd[EXT_CSD_SEC_ERASE_MULT]; | ||
| 294 | card->ext_csd.sec_feature_support = | ||
| 295 | ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; | ||
| 296 | card->ext_csd.trim_timeout = 300 * | ||
| 297 | ext_csd[EXT_CSD_TRIM_MULT]; | ||
| 264 | } | 298 | } |
| 265 | 299 | ||
| 300 | if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) | ||
| 301 | card->erased_byte = 0xFF; | ||
| 302 | else | ||
| 303 | card->erased_byte = 0x0; | ||
| 304 | |||
| 266 | out: | 305 | out: |
| 267 | kfree(ext_csd); | 306 | kfree(ext_csd); |
| 268 | 307 | ||
| @@ -274,6 +313,8 @@ MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], | |||
| 274 | MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | 313 | MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], |
| 275 | card->raw_csd[2], card->raw_csd[3]); | 314 | card->raw_csd[2], card->raw_csd[3]); |
| 276 | MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); | 315 | MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); |
| 316 | MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9); | ||
| 317 | MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9); | ||
| 277 | MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); | 318 | MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); |
| 278 | MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); | 319 | MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); |
| 279 | MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); | 320 | MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); |
| @@ -285,6 +326,8 @@ static struct attribute *mmc_std_attrs[] = { | |||
| 285 | &dev_attr_cid.attr, | 326 | &dev_attr_cid.attr, |
| 286 | &dev_attr_csd.attr, | 327 | &dev_attr_csd.attr, |
| 287 | &dev_attr_date.attr, | 328 | &dev_attr_date.attr, |
| 329 | &dev_attr_erase_size.attr, | ||
| 330 | &dev_attr_preferred_erase_size.attr, | ||
| 288 | &dev_attr_fwrev.attr, | 331 | &dev_attr_fwrev.attr, |
| 289 | &dev_attr_hwrev.attr, | 332 | &dev_attr_hwrev.attr, |
| 290 | &dev_attr_manfid.attr, | 333 | &dev_attr_manfid.attr, |
| @@ -421,6 +464,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 421 | err = mmc_read_ext_csd(card); | 464 | err = mmc_read_ext_csd(card); |
| 422 | if (err) | 465 | if (err) |
| 423 | goto free_card; | 466 | goto free_card; |
| 467 | /* Erase size depends on CSD and Extended CSD */ | ||
| 468 | mmc_set_erase_size(card); | ||
| 424 | } | 469 | } |
| 425 | 470 | ||
| 426 | /* | 471 | /* |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index e6d7d9fab446..0f5241085557 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
| @@ -119,6 +119,13 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
| 119 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | 119 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); |
| 120 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | 120 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); |
| 121 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | 121 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); |
| 122 | |||
| 123 | if (UNSTUFF_BITS(resp, 46, 1)) { | ||
| 124 | csd->erase_size = 1; | ||
| 125 | } else if (csd->write_blkbits >= 9) { | ||
| 126 | csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1; | ||
| 127 | csd->erase_size <<= csd->write_blkbits - 9; | ||
| 128 | } | ||
| 122 | break; | 129 | break; |
| 123 | case 1: | 130 | case 1: |
| 124 | /* | 131 | /* |
| @@ -147,6 +154,7 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
| 147 | csd->r2w_factor = 4; /* Unused */ | 154 | csd->r2w_factor = 4; /* Unused */ |
| 148 | csd->write_blkbits = 9; | 155 | csd->write_blkbits = 9; |
| 149 | csd->write_partial = 0; | 156 | csd->write_partial = 0; |
| 157 | csd->erase_size = 1; | ||
| 150 | break; | 158 | break; |
| 151 | default: | 159 | default: |
| 152 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", | 160 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", |
| @@ -154,6 +162,8 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
| 154 | return -EINVAL; | 162 | return -EINVAL; |
| 155 | } | 163 | } |
| 156 | 164 | ||
| 165 | card->erase_size = csd->erase_size; | ||
| 166 | |||
| 157 | return 0; | 167 | return 0; |
| 158 | } | 168 | } |
| 159 | 169 | ||
| @@ -179,10 +189,68 @@ static int mmc_decode_scr(struct mmc_card *card) | |||
| 179 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); | 189 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); |
| 180 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); | 190 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); |
| 181 | 191 | ||
| 192 | if (UNSTUFF_BITS(resp, 55, 1)) | ||
| 193 | card->erased_byte = 0xFF; | ||
| 194 | else | ||
| 195 | card->erased_byte = 0x0; | ||
| 196 | |||
| 182 | return 0; | 197 | return 0; |
| 183 | } | 198 | } |
| 184 | 199 | ||
| 185 | /* | 200 | /* |
| 201 | * Fetch and process SD Status register. | ||
| 202 | */ | ||
| 203 | static int mmc_read_ssr(struct mmc_card *card) | ||
| 204 | { | ||
| 205 | unsigned int au, es, et, eo; | ||
| 206 | int err, i; | ||
| 207 | u32 *ssr; | ||
| 208 | |||
| 209 | if (!(card->csd.cmdclass & CCC_APP_SPEC)) { | ||
| 210 | printk(KERN_WARNING "%s: card lacks mandatory SD Status " | ||
| 211 | "function.\n", mmc_hostname(card->host)); | ||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | |||
| 215 | ssr = kmalloc(64, GFP_KERNEL); | ||
| 216 | if (!ssr) | ||
| 217 | return -ENOMEM; | ||
| 218 | |||
| 219 | err = mmc_app_sd_status(card, ssr); | ||
| 220 | if (err) { | ||
| 221 | printk(KERN_WARNING "%s: problem reading SD Status " | ||
| 222 | "register.\n", mmc_hostname(card->host)); | ||
| 223 | err = 0; | ||
| 224 | goto out; | ||
| 225 | } | ||
| 226 | |||
| 227 | for (i = 0; i < 16; i++) | ||
| 228 | ssr[i] = be32_to_cpu(ssr[i]); | ||
| 229 | |||
| 230 | /* | ||
| 231 | * UNSTUFF_BITS only works with four u32s so we have to offset the | ||
| 232 | * bitfield positions accordingly. | ||
| 233 | */ | ||
| 234 | au = UNSTUFF_BITS(ssr, 428 - 384, 4); | ||
| 235 | if (au > 0 || au <= 9) { | ||
| 236 | card->ssr.au = 1 << (au + 4); | ||
| 237 | es = UNSTUFF_BITS(ssr, 408 - 384, 16); | ||
| 238 | et = UNSTUFF_BITS(ssr, 402 - 384, 6); | ||
| 239 | eo = UNSTUFF_BITS(ssr, 400 - 384, 2); | ||
| 240 | if (es && et) { | ||
| 241 | card->ssr.erase_timeout = (et * 1000) / es; | ||
| 242 | card->ssr.erase_offset = eo * 1000; | ||
| 243 | } | ||
| 244 | } else { | ||
| 245 | printk(KERN_WARNING "%s: SD Status: Invalid Allocation Unit " | ||
| 246 | "size.\n", mmc_hostname(card->host)); | ||
| 247 | } | ||
| 248 | out: | ||
| 249 | kfree(ssr); | ||
| 250 | return err; | ||
| 251 | } | ||
| 252 | |||
| 253 | /* | ||
| 186 | * Fetches and decodes switch information | 254 | * Fetches and decodes switch information |
| 187 | */ | 255 | */ |
| 188 | static int mmc_read_switch(struct mmc_card *card) | 256 | static int mmc_read_switch(struct mmc_card *card) |
| @@ -289,6 +357,8 @@ MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | |||
| 289 | card->raw_csd[2], card->raw_csd[3]); | 357 | card->raw_csd[2], card->raw_csd[3]); |
| 290 | MMC_DEV_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); | 358 | MMC_DEV_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); |
| 291 | MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); | 359 | MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); |
| 360 | MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9); | ||
| 361 | MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9); | ||
| 292 | MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); | 362 | MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); |
| 293 | MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); | 363 | MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); |
| 294 | MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); | 364 | MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); |
| @@ -302,6 +372,8 @@ static struct attribute *sd_std_attrs[] = { | |||
| 302 | &dev_attr_csd.attr, | 372 | &dev_attr_csd.attr, |
| 303 | &dev_attr_scr.attr, | 373 | &dev_attr_scr.attr, |
| 304 | &dev_attr_date.attr, | 374 | &dev_attr_date.attr, |
| 375 | &dev_attr_erase_size.attr, | ||
| 376 | &dev_attr_preferred_erase_size.attr, | ||
| 305 | &dev_attr_fwrev.attr, | 377 | &dev_attr_fwrev.attr, |
| 306 | &dev_attr_hwrev.attr, | 378 | &dev_attr_hwrev.attr, |
| 307 | &dev_attr_manfid.attr, | 379 | &dev_attr_manfid.attr, |
| @@ -397,6 +469,16 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, | |||
| 397 | return err; | 469 | return err; |
| 398 | 470 | ||
| 399 | /* | 471 | /* |
| 472 | * Fetch and process SD Status register. | ||
| 473 | */ | ||
| 474 | err = mmc_read_ssr(card); | ||
| 475 | if (err) | ||
| 476 | return err; | ||
| 477 | |||
| 478 | /* Erase init depends on CSD and SSR */ | ||
| 479 | mmc_init_erase(card); | ||
| 480 | |||
| 481 | /* | ||
| 400 | * Fetch switch information from card. | 482 | * Fetch switch information from card. |
| 401 | */ | 483 | */ |
| 402 | err = mmc_read_switch(card); | 484 | err = mmc_read_switch(card); |
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index 63772e7e7608..797cdb5887fd 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c | |||
| @@ -346,3 +346,51 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group, | |||
| 346 | return 0; | 346 | return 0; |
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | int mmc_app_sd_status(struct mmc_card *card, void *ssr) | ||
| 350 | { | ||
| 351 | int err; | ||
| 352 | struct mmc_request mrq; | ||
| 353 | struct mmc_command cmd; | ||
| 354 | struct mmc_data data; | ||
| 355 | struct scatterlist sg; | ||
| 356 | |||
| 357 | BUG_ON(!card); | ||
| 358 | BUG_ON(!card->host); | ||
| 359 | BUG_ON(!ssr); | ||
| 360 | |||
| 361 | /* NOTE: caller guarantees ssr is heap-allocated */ | ||
| 362 | |||
| 363 | err = mmc_app_cmd(card->host, card); | ||
| 364 | if (err) | ||
| 365 | return err; | ||
| 366 | |||
| 367 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 368 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 369 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 370 | |||
| 371 | mrq.cmd = &cmd; | ||
| 372 | mrq.data = &data; | ||
| 373 | |||
| 374 | cmd.opcode = SD_APP_SD_STATUS; | ||
| 375 | cmd.arg = 0; | ||
| 376 | cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_ADTC; | ||
| 377 | |||
| 378 | data.blksz = 64; | ||
| 379 | data.blocks = 1; | ||
| 380 | data.flags = MMC_DATA_READ; | ||
| 381 | data.sg = &sg; | ||
| 382 | data.sg_len = 1; | ||
| 383 | |||
| 384 | sg_init_one(&sg, ssr, 64); | ||
| 385 | |||
| 386 | mmc_set_data_timeout(&data, card); | ||
| 387 | |||
| 388 | mmc_wait_for_req(card->host, &mrq); | ||
| 389 | |||
| 390 | if (cmd.error) | ||
| 391 | return cmd.error; | ||
| 392 | if (data.error) | ||
| 393 | return data.error; | ||
| 394 | |||
| 395 | return 0; | ||
| 396 | } | ||
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index 9742d8a30664..ffc2305d905f 100644 --- a/drivers/mmc/core/sd_ops.h +++ b/drivers/mmc/core/sd_ops.h | |||
| @@ -19,6 +19,7 @@ int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca); | |||
| 19 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr); | 19 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr); |
| 20 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | 20 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, |
| 21 | u8 value, u8 *resp); | 21 | u8 value, u8 *resp); |
| 22 | int mmc_app_sd_status(struct mmc_card *card, void *ssr); | ||
| 22 | 23 | ||
| 23 | #endif | 24 | #endif |
| 24 | 25 | ||
