diff options
-rw-r--r-- | Documentation/00-INDEX | 2 | ||||
-rw-r--r-- | Documentation/mmc/00-INDEX | 4 | ||||
-rw-r--r-- | Documentation/mmc/mmc-dev-attrs.txt | 56 | ||||
-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 | ||||
-rw-r--r-- | include/linux/mmc/card.h | 20 | ||||
-rw-r--r-- | include/linux/mmc/core.h | 19 | ||||
-rw-r--r-- | include/linux/mmc/host.h | 1 | ||||
-rw-r--r-- | include/linux/mmc/mmc.h | 26 | ||||
-rw-r--r-- | include/linux/mmc/sd.h | 5 |
14 files changed, 651 insertions, 8 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 9e642c5bf526..8dfc6708a257 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX | |||
@@ -232,6 +232,8 @@ memory.txt | |||
232 | - info on typical Linux memory problems. | 232 | - info on typical Linux memory problems. |
233 | mips/ | 233 | mips/ |
234 | - directory with info about Linux on MIPS architecture. | 234 | - directory with info about Linux on MIPS architecture. |
235 | mmc/ | ||
236 | - directory with info about the MMC subsystem | ||
235 | mono.txt | 237 | mono.txt |
236 | - how to execute Mono-based .NET binaries with the help of BINFMT_MISC. | 238 | - how to execute Mono-based .NET binaries with the help of BINFMT_MISC. |
237 | mutex-design.txt | 239 | mutex-design.txt |
diff --git a/Documentation/mmc/00-INDEX b/Documentation/mmc/00-INDEX new file mode 100644 index 000000000000..fca586f5b853 --- /dev/null +++ b/Documentation/mmc/00-INDEX | |||
@@ -0,0 +1,4 @@ | |||
1 | 00-INDEX | ||
2 | - this file | ||
3 | mmc-dev-attrs.txt | ||
4 | - info on SD and MMC device attributes | ||
diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt new file mode 100644 index 000000000000..ff2bd685bced --- /dev/null +++ b/Documentation/mmc/mmc-dev-attrs.txt | |||
@@ -0,0 +1,56 @@ | |||
1 | SD and MMC Device Attributes | ||
2 | ============================ | ||
3 | |||
4 | All attributes are read-only. | ||
5 | |||
6 | cid Card Identifaction Register | ||
7 | csd Card Specific Data Register | ||
8 | scr SD Card Configuration Register (SD only) | ||
9 | date Manufacturing Date (from CID Register) | ||
10 | fwrev Firmware/Product Revision (from CID Register) (SD and MMCv1 only) | ||
11 | hwrev Hardware/Product Revision (from CID Register) (SD and MMCv1 only) | ||
12 | manfid Manufacturer ID (from CID Register) | ||
13 | name Product Name (from CID Register) | ||
14 | oemid OEM/Application ID (from CID Register) | ||
15 | serial Product Serial Number (from CID Register) | ||
16 | erase_size Erase group size | ||
17 | preferred_erase_size Preferred erase size | ||
18 | |||
19 | Note on Erase Size and Preferred Erase Size: | ||
20 | |||
21 | "erase_size" is the minimum size, in bytes, of an erase | ||
22 | operation. For MMC, "erase_size" is the erase group size | ||
23 | reported by the card. Note that "erase_size" does not apply | ||
24 | to trim or secure trim operations where the minimum size is | ||
25 | always one 512 byte sector. For SD, "erase_size" is 512 | ||
26 | if the card is block-addressed, 0 otherwise. | ||
27 | |||
28 | SD/MMC cards can erase an arbitrarily large area up to and | ||
29 | including the whole card. When erasing a large area it may | ||
30 | be desirable to do it in smaller chunks for three reasons: | ||
31 | 1. A single erase command will make all other I/O on | ||
32 | the card wait. This is not a problem if the whole card | ||
33 | is being erased, but erasing one partition will make | ||
34 | I/O for another partition on the same card wait for the | ||
35 | duration of the erase - which could be a several | ||
36 | minutes. | ||
37 | 2. To be able to inform the user of erase progress. | ||
38 | 3. The erase timeout becomes too large to be very | ||
39 | useful. Because the erase timeout contains a margin | ||
40 | which is multiplied by the size of the erase area, | ||
41 | the value can end up being several minutes for large | ||
42 | areas. | ||
43 | |||
44 | "erase_size" is not the most efficient unit to erase | ||
45 | (especially for SD where it is just one sector), | ||
46 | hence "preferred_erase_size" provides a good chunk | ||
47 | size for erasing large areas. | ||
48 | |||
49 | For MMC, "preferred_erase_size" is the high-capacity | ||
50 | erase size if a card specifies one, otherwise it is | ||
51 | based on the capacity of the card. | ||
52 | |||
53 | For SD, "preferred_erase_size" is the allocation unit | ||
54 | size specified by the card. | ||
55 | |||
56 | "preferred_erase_size" is in bytes. | ||
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 | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4d893eaf8174..6b7525099e56 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -31,6 +31,7 @@ struct mmc_csd { | |||
31 | unsigned int tacc_ns; | 31 | unsigned int tacc_ns; |
32 | unsigned int r2w_factor; | 32 | unsigned int r2w_factor; |
33 | unsigned int max_dtr; | 33 | unsigned int max_dtr; |
34 | unsigned int erase_size; /* In sectors */ | ||
34 | unsigned int read_blkbits; | 35 | unsigned int read_blkbits; |
35 | unsigned int write_blkbits; | 36 | unsigned int write_blkbits; |
36 | unsigned int capacity; | 37 | unsigned int capacity; |
@@ -42,9 +43,16 @@ struct mmc_csd { | |||
42 | 43 | ||
43 | struct mmc_ext_csd { | 44 | struct mmc_ext_csd { |
44 | u8 rev; | 45 | u8 rev; |
46 | u8 erase_group_def; | ||
47 | u8 sec_feature_support; | ||
45 | unsigned int sa_timeout; /* Units: 100ns */ | 48 | unsigned int sa_timeout; /* Units: 100ns */ |
46 | unsigned int hs_max_dtr; | 49 | unsigned int hs_max_dtr; |
47 | unsigned int sectors; | 50 | unsigned int sectors; |
51 | unsigned int hc_erase_size; /* In sectors */ | ||
52 | unsigned int hc_erase_timeout; /* In milliseconds */ | ||
53 | unsigned int sec_trim_mult; /* Secure trim multiplier */ | ||
54 | unsigned int sec_erase_mult; /* Secure erase multiplier */ | ||
55 | unsigned int trim_timeout; /* In milliseconds */ | ||
48 | }; | 56 | }; |
49 | 57 | ||
50 | struct sd_scr { | 58 | struct sd_scr { |
@@ -54,6 +62,12 @@ struct sd_scr { | |||
54 | #define SD_SCR_BUS_WIDTH_4 (1<<2) | 62 | #define SD_SCR_BUS_WIDTH_4 (1<<2) |
55 | }; | 63 | }; |
56 | 64 | ||
65 | struct sd_ssr { | ||
66 | unsigned int au; /* In sectors */ | ||
67 | unsigned int erase_timeout; /* In milliseconds */ | ||
68 | unsigned int erase_offset; /* In milliseconds */ | ||
69 | }; | ||
70 | |||
57 | struct sd_switch_caps { | 71 | struct sd_switch_caps { |
58 | unsigned int hs_max_dtr; | 72 | unsigned int hs_max_dtr; |
59 | }; | 73 | }; |
@@ -106,6 +120,11 @@ struct mmc_card { | |||
106 | #define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */ | 120 | #define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */ |
107 | /* (missing CIA registers) */ | 121 | /* (missing CIA registers) */ |
108 | 122 | ||
123 | unsigned int erase_size; /* erase size in sectors */ | ||
124 | unsigned int erase_shift; /* if erase unit is power 2 */ | ||
125 | unsigned int pref_erase; /* in sectors */ | ||
126 | u8 erased_byte; /* value of erased bytes */ | ||
127 | |||
109 | u32 raw_cid[4]; /* raw card CID */ | 128 | u32 raw_cid[4]; /* raw card CID */ |
110 | u32 raw_csd[4]; /* raw card CSD */ | 129 | u32 raw_csd[4]; /* raw card CSD */ |
111 | u32 raw_scr[2]; /* raw card SCR */ | 130 | u32 raw_scr[2]; /* raw card SCR */ |
@@ -113,6 +132,7 @@ struct mmc_card { | |||
113 | struct mmc_csd csd; /* card specific */ | 132 | struct mmc_csd csd; /* card specific */ |
114 | struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */ | 133 | struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */ |
115 | struct sd_scr scr; /* extra SD information */ | 134 | struct sd_scr scr; /* extra SD information */ |
135 | struct sd_ssr ssr; /* yet more SD information */ | ||
116 | struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ | 136 | struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ |
117 | 137 | ||
118 | unsigned int sdio_funcs; /* number of SDIO functions */ | 138 | unsigned int sdio_funcs; /* number of SDIO functions */ |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index e4898e9eeb59..7429033acb66 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
@@ -92,6 +92,8 @@ struct mmc_command { | |||
92 | * actively failing requests | 92 | * actively failing requests |
93 | */ | 93 | */ |
94 | 94 | ||
95 | unsigned int erase_timeout; /* in milliseconds */ | ||
96 | |||
95 | struct mmc_data *data; /* data segment associated with cmd */ | 97 | struct mmc_data *data; /* data segment associated with cmd */ |
96 | struct mmc_request *mrq; /* associated request */ | 98 | struct mmc_request *mrq; /* associated request */ |
97 | }; | 99 | }; |
@@ -134,6 +136,23 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); | |||
134 | extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, | 136 | extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, |
135 | struct mmc_command *, int); | 137 | struct mmc_command *, int); |
136 | 138 | ||
139 | #define MMC_ERASE_ARG 0x00000000 | ||
140 | #define MMC_SECURE_ERASE_ARG 0x80000000 | ||
141 | #define MMC_TRIM_ARG 0x00000001 | ||
142 | #define MMC_SECURE_TRIM1_ARG 0x80000001 | ||
143 | #define MMC_SECURE_TRIM2_ARG 0x80008000 | ||
144 | |||
145 | #define MMC_SECURE_ARGS 0x80000000 | ||
146 | #define MMC_TRIM_ARGS 0x00008001 | ||
147 | |||
148 | extern int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, | ||
149 | unsigned int arg); | ||
150 | extern int mmc_can_erase(struct mmc_card *card); | ||
151 | extern int mmc_can_trim(struct mmc_card *card); | ||
152 | extern int mmc_can_secure_erase_trim(struct mmc_card *card); | ||
153 | extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, | ||
154 | unsigned int nr); | ||
155 | |||
137 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); | 156 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); |
138 | extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); | 157 | extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); |
139 | 158 | ||
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 513ff0376b09..1575b52c3bfa 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -156,6 +156,7 @@ struct mmc_host { | |||
156 | #define MMC_CAP_DISABLE (1 << 7) /* Can the host be disabled */ | 156 | #define MMC_CAP_DISABLE (1 << 7) /* Can the host be disabled */ |
157 | #define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ | 157 | #define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ |
158 | #define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ | 158 | #define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ |
159 | #define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */ | ||
159 | 160 | ||
160 | mmc_pm_flag_t pm_caps; /* supported pm features */ | 161 | mmc_pm_flag_t pm_caps; /* supported pm features */ |
161 | 162 | ||
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 52ce98866287..dd11ae51fb68 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
@@ -251,13 +251,21 @@ struct _mmc_csd { | |||
251 | * EXT_CSD fields | 251 | * EXT_CSD fields |
252 | */ | 252 | */ |
253 | 253 | ||
254 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ | 254 | #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ |
255 | #define EXT_CSD_HS_TIMING 185 /* R/W */ | 255 | #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ |
256 | #define EXT_CSD_CARD_TYPE 196 /* RO */ | 256 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ |
257 | #define EXT_CSD_STRUCTURE 194 /* RO */ | 257 | #define EXT_CSD_HS_TIMING 185 /* R/W */ |
258 | #define EXT_CSD_REV 192 /* RO */ | 258 | #define EXT_CSD_REV 192 /* RO */ |
259 | #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ | 259 | #define EXT_CSD_STRUCTURE 194 /* RO */ |
260 | #define EXT_CSD_S_A_TIMEOUT 217 | 260 | #define EXT_CSD_CARD_TYPE 196 /* RO */ |
261 | #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ | ||
262 | #define EXT_CSD_S_A_TIMEOUT 217 /* RO */ | ||
263 | #define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ | ||
264 | #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ | ||
265 | #define EXT_CSD_SEC_TRIM_MULT 229 /* RO */ | ||
266 | #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ | ||
267 | #define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */ | ||
268 | #define EXT_CSD_TRIM_MULT 232 /* RO */ | ||
261 | 269 | ||
262 | /* | 270 | /* |
263 | * EXT_CSD field definitions | 271 | * EXT_CSD field definitions |
@@ -275,6 +283,10 @@ struct _mmc_csd { | |||
275 | #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ | 283 | #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ |
276 | #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ | 284 | #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ |
277 | 285 | ||
286 | #define EXT_CSD_SEC_ER_EN BIT(0) | ||
287 | #define EXT_CSD_SEC_BD_BLK_EN BIT(2) | ||
288 | #define EXT_CSD_SEC_GB_CL_EN BIT(4) | ||
289 | |||
278 | /* | 290 | /* |
279 | * MMC_SWITCH access modes | 291 | * MMC_SWITCH access modes |
280 | */ | 292 | */ |
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index f310062cffb4..3fd85e088cc3 100644 --- a/include/linux/mmc/sd.h +++ b/include/linux/mmc/sd.h | |||
@@ -21,8 +21,13 @@ | |||
21 | /* class 10 */ | 21 | /* class 10 */ |
22 | #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ | 22 | #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ |
23 | 23 | ||
24 | /* class 5 */ | ||
25 | #define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */ | ||
26 | #define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */ | ||
27 | |||
24 | /* Application commands */ | 28 | /* Application commands */ |
25 | #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ | 29 | #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ |
30 | #define SD_APP_SD_STATUS 13 /* adtc R1 */ | ||
26 | #define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ | 31 | #define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ |
27 | #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ | 32 | #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ |
28 | #define SD_APP_SEND_SCR 51 /* adtc R1 */ | 33 | #define SD_APP_SEND_SCR 51 /* adtc R1 */ |