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 */ |
