--- zzzz-none-000/linux-3.10.107/drivers/mmc/card/block.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/mmc/card/block.c 2021-02-04 17:41:59.000000000 +0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -46,10 +47,13 @@ #include "queue.h" MODULE_ALIAS("mmc:block"); + +#ifdef KERNEL #ifdef MODULE_PARAM_PREFIX #undef MODULE_PARAM_PREFIX #endif #define MODULE_PARAM_PREFIX "mmcblk." +#endif #define INAND_CMD38_ARG_EXT_CSD 113 #define INAND_CMD38_ARG_ERASE 0x00 @@ -58,6 +62,8 @@ #define INAND_CMD38_ARG_SECTRIM1 0x81 #define INAND_CMD38_ARG_SECTRIM2 0x88 #define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ +#define MMC_SANITIZE_REQ_TIMEOUT 240000 +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) #define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ (rq_data_dir(req) == WRITE)) @@ -74,13 +80,16 @@ /* * We've only got one major, so number of mmcblk devices is - * limited to 256 / number of minors per device. + * limited to (1 << 20) / number of minors per device. It is also + * currently limited by the size of the static bitmaps below. */ static int max_devices; -/* 256 minors, so at most 256 separate devices */ -static DECLARE_BITMAP(dev_use, 256); -static DECLARE_BITMAP(name_use, 256); +#define MAX_DEVICES 256 + +/* TODO: Replace these with struct ida */ +static DECLARE_BITMAP(dev_use, MAX_DEVICES); +static DECLARE_BITMAP(name_use, MAX_DEVICES); /* * There is one mmc_blk_data per slot. @@ -108,7 +117,7 @@ /* * Only set in main mmc_blk_data associated - * with mmc_card with mmc_set_drvdata, and keeps + * with mmc_card with dev_set_drvdata, and keeps * track of the current selected device partition. */ unsigned int part_curr; @@ -223,7 +232,7 @@ md = mmc_blk_get(dev_to_disk(dev)); card = md->queue.card; - mmc_claim_host(card->host); + mmc_get_card(card); ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, card->ext_csd.boot_ro_lock | @@ -234,7 +243,7 @@ else card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN; - mmc_release_host(card->host); + mmc_put_card(card); if (!ret) { pr_info("%s: Locking boot partition ro until next power on\n", @@ -377,6 +386,24 @@ return ERR_PTR(err); } +static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr, + struct mmc_blk_ioc_data *idata) +{ + struct mmc_ioc_cmd *ic = &idata->ic; + + if (copy_to_user(&(ic_ptr->response), ic->response, + sizeof(ic->response))) + return -EFAULT; + + if (!idata->ic.write_flag) { + if (copy_to_user((void __user *)(unsigned long)ic->data_ptr, + idata->buf, idata->buf_bytes)) + return -EFAULT; + } + + return 0; +} + static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status, u32 retries_max) { @@ -409,12 +436,37 @@ return err; } -static int mmc_blk_ioctl_cmd(struct block_device *bdev, - struct mmc_ioc_cmd __user *ic_ptr) +static int ioctl_do_sanitize(struct mmc_card *card) +{ + int err; + + if (!mmc_can_sanitize(card)) { + pr_warn("%s: %s - SANITIZE is not supported\n", + mmc_hostname(card->host), __func__); + err = -EOPNOTSUPP; + goto out; + } + + pr_debug("%s: %s - SANITIZE IN PROGRESS...\n", + mmc_hostname(card->host), __func__); + + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_SANITIZE_START, 1, + MMC_SANITIZE_REQ_TIMEOUT); + + if (err) + pr_err("%s: %s - EXT_CSD_SANITIZE_START failed. err=%d\n", + mmc_hostname(card->host), __func__, err); + + pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host), + __func__); +out: + return err; +} + +static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, + struct mmc_blk_ioc_data *idata) { - struct mmc_blk_ioc_data *idata; - struct mmc_blk_data *md; - struct mmc_card *card; struct mmc_command cmd = {0}; struct mmc_data data = {0}; struct mmc_request mrq = {NULL}; @@ -423,37 +475,24 @@ int is_rpmb = false; u32 status = 0; - /* - * The caller must have CAP_SYS_RAWIO, and must be calling this on the - * whole block device, not on a partition. This prevents overspray - * between sibling partitions. - */ - if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) - return -EPERM; - - idata = mmc_blk_ioctl_copy_from_user(ic_ptr); - if (IS_ERR(idata)) - return PTR_ERR(idata); - - md = mmc_blk_get(bdev->bd_disk); - if (!md) { - err = -EINVAL; - goto cmd_err; - } + if (!card || !md || !idata) + return -EINVAL; if (md->area_type & MMC_BLK_DATA_AREA_RPMB) is_rpmb = true; - card = md->queue.card; - if (IS_ERR(card)) { - err = PTR_ERR(card); - goto cmd_done; - } - cmd.opcode = idata->ic.opcode; cmd.arg = idata->ic.arg; cmd.flags = idata->ic.flags; + if (idata->ic.postsleep_max_us < idata->ic.postsleep_min_us) { + pr_err("%s: min value: %u must not be greater than max value: %u\n", + __func__, idata->ic.postsleep_min_us, + idata->ic.postsleep_max_us); + WARN_ON(1); + return -EPERM; + } + if (idata->buf_bytes) { data.sg = &sg; data.sg_len = 1; @@ -492,23 +531,32 @@ mrq.cmd = &cmd; - mmc_claim_host(card->host); - err = mmc_blk_part_switch(card, md); if (err) - goto cmd_rel_host; + return err; if (idata->ic.is_acmd) { err = mmc_app_cmd(card->host, card); if (err) - goto cmd_rel_host; + return err; } if (is_rpmb) { err = mmc_set_blockcount(card, data.blocks, idata->ic.write_flag & (1 << 31)); if (err) - goto cmd_rel_host; + return err; + } + + if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) && + (cmd.opcode == MMC_SWITCH)) { + err = ioctl_do_sanitize(card); + + if (err) + pr_err("%s: ioctl_do_sanitize() failed. err = %d", + __func__, err); + + return err; } mmc_wait_for_req(card->host, &mrq); @@ -516,14 +564,12 @@ if (cmd.error) { dev_err(mmc_dev(card->host), "%s: cmd error %d\n", __func__, cmd.error); - err = cmd.error; - goto cmd_rel_host; + return cmd.error; } if (data.error) { dev_err(mmc_dev(card->host), "%s: data error %d\n", __func__, data.error); - err = data.error; - goto cmd_rel_host; + return data.error; } /* @@ -533,18 +579,7 @@ if (idata->ic.postsleep_min_us) usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); - if (copy_to_user(&(ic_ptr->response), cmd.resp, sizeof(cmd.resp))) { - err = -EFAULT; - goto cmd_rel_host; - } - - if (!idata->ic.write_flag) { - if (copy_to_user((void __user *)(unsigned long) idata->ic.data_ptr, - idata->buf, idata->buf_bytes)) { - err = -EFAULT; - goto cmd_rel_host; - } - } + memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); if (is_rpmb) { /* @@ -558,24 +593,140 @@ __func__, status, err); } -cmd_rel_host: - mmc_release_host(card->host); + return err; +} + +static int mmc_blk_ioctl_cmd(struct block_device *bdev, + struct mmc_ioc_cmd __user *ic_ptr) +{ + struct mmc_blk_ioc_data *idata; + struct mmc_blk_data *md; + struct mmc_card *card; + int err = 0, ioc_err = 0; + + /* + * The caller must have CAP_SYS_RAWIO, and must be calling this on the + * whole block device, not on a partition. This prevents overspray + * between sibling partitions. + */ + if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) + return -EPERM; + + idata = mmc_blk_ioctl_copy_from_user(ic_ptr); + if (IS_ERR(idata)) + return PTR_ERR(idata); + + md = mmc_blk_get(bdev->bd_disk); + if (!md) { + err = -EINVAL; + goto cmd_err; + } + + card = md->queue.card; + if (IS_ERR(card)) { + err = PTR_ERR(card); + goto cmd_done; + } + + mmc_get_card(card); + + ioc_err = __mmc_blk_ioctl_cmd(card, md, idata); + + mmc_put_card(card); + + err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata); cmd_done: mmc_blk_put(md); cmd_err: kfree(idata->buf); kfree(idata); - return err; + return ioc_err ? ioc_err : err; +} + +static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, + struct mmc_ioc_multi_cmd __user *user) +{ + struct mmc_blk_ioc_data **idata = NULL; + struct mmc_ioc_cmd __user *cmds = user->cmds; + struct mmc_card *card; + struct mmc_blk_data *md; + int i, err = 0, ioc_err = 0; + __u64 num_of_cmds; + + /* + * The caller must have CAP_SYS_RAWIO, and must be calling this on the + * whole block device, not on a partition. This prevents overspray + * between sibling partitions. + */ + if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) + return -EPERM; + + if (copy_from_user(&num_of_cmds, &user->num_of_cmds, + sizeof(num_of_cmds))) + return -EFAULT; + + if (num_of_cmds > MMC_IOC_MAX_CMDS) + return -EINVAL; + + idata = kcalloc(num_of_cmds, sizeof(*idata), GFP_KERNEL); + if (!idata) + return -ENOMEM; + + for (i = 0; i < num_of_cmds; i++) { + idata[i] = mmc_blk_ioctl_copy_from_user(&cmds[i]); + if (IS_ERR(idata[i])) { + err = PTR_ERR(idata[i]); + num_of_cmds = i; + goto cmd_err; + } + } + + md = mmc_blk_get(bdev->bd_disk); + if (!md) + goto cmd_err; + + card = md->queue.card; + if (IS_ERR(card)) { + err = PTR_ERR(card); + goto cmd_done; + } + + mmc_get_card(card); + + for (i = 0; i < num_of_cmds && !ioc_err; i++) + ioc_err = __mmc_blk_ioctl_cmd(card, md, idata[i]); + + mmc_put_card(card); + + /* copy to user if data and response */ + for (i = 0; i < num_of_cmds && !err; i++) + err = mmc_blk_ioctl_copy_to_user(&cmds[i], idata[i]); + +cmd_done: + mmc_blk_put(md); +cmd_err: + for (i = 0; i < num_of_cmds; i++) { + kfree(idata[i]->buf); + kfree(idata[i]); + } + kfree(idata); + return ioc_err ? ioc_err : err; } static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - int ret = -EINVAL; - if (cmd == MMC_IOC_CMD) - ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg); - return ret; + switch (cmd) { + case MMC_IOC_CMD: + return mmc_blk_ioctl_cmd(bdev, + (struct mmc_ioc_cmd __user *)arg); + case MMC_IOC_MULTI_CMD: + return mmc_blk_ioctl_multi_cmd(bdev, + (struct mmc_ioc_multi_cmd __user *)arg); + default: + return -EINVAL; + } } #ifdef CONFIG_COMPAT @@ -601,7 +752,7 @@ struct mmc_blk_data *md) { int ret; - struct mmc_blk_data *main_md = mmc_get_drvdata(card); + struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); if (main_md->part_curr == md->part_type) return 0; @@ -680,19 +831,6 @@ return result; } -static int send_stop(struct mmc_card *card, u32 *status) -{ - struct mmc_command cmd = {0}; - int err; - - cmd.opcode = MMC_STOP_TRANSMISSION; - cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - err = mmc_wait_for_cmd(card->host, &cmd, 5); - if (err == 0) - *status = cmd.resp[0]; - return err; -} - static int get_card_status(struct mmc_card *card, u32 *status, int retries) { struct mmc_command cmd = {0}; @@ -708,6 +846,99 @@ return err; } +static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, + bool hw_busy_detect, struct request *req, int *gen_err) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); + int err = 0; + u32 status; + + do { + err = get_card_status(card, &status, 5); + if (err) { + pr_err("%s: error %d requesting status\n", + req->rq_disk->disk_name, err); + return err; + } + + if (status & R1_ERROR) { + pr_err("%s: %s: error sending status cmd, status %#x\n", + req->rq_disk->disk_name, __func__, status); + *gen_err = 1; + } + + /* We may rely on the host hw to handle busy detection.*/ + if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && + hw_busy_detect) + break; + + /* + * Timeout if the device never becomes ready for data and never + * leaves the program state. + */ + if (time_after(jiffies, timeout)) { + pr_err("%s: Card stuck in programming state! %s %s\n", + mmc_hostname(card->host), + req->rq_disk->disk_name, __func__); + return -ETIMEDOUT; + } + + /* + * Some cards mishandle the status bits, + * so make sure to check both the busy + * indication and the card state. + */ + } while (!(status & R1_READY_FOR_DATA) || + (R1_CURRENT_STATE(status) == R1_STATE_PRG)); + + return err; +} + +static int send_stop(struct mmc_card *card, unsigned int timeout_ms, + struct request *req, int *gen_err, u32 *stop_status) +{ + struct mmc_host *host = card->host; + struct mmc_command cmd = {0}; + int err; + bool use_r1b_resp = rq_data_dir(req) == WRITE; + + /* + * Normally we use R1B responses for WRITE, but in cases where the host + * has specified a max_busy_timeout we need to validate it. A failure + * means we need to prevent the host from doing hw busy detection, which + * is done by converting to a R1 response instead. + */ + if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) + use_r1b_resp = false; + + cmd.opcode = MMC_STOP_TRANSMISSION; + if (use_r1b_resp) { + cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + cmd.busy_timeout = timeout_ms; + } else { + cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; + } + + err = mmc_wait_for_cmd(host, &cmd, 5); + if (err) + return err; + + *stop_status = cmd.resp[0]; + + /* No need to check card status in case of READ. */ + if (rq_data_dir(req) == READ) + return 0; + + if (!mmc_host_is_spi(host) && + (*stop_status & R1_ERROR)) { + pr_err("%s: %s: general error sending stop command, resp %#x\n", + req->rq_disk->disk_name, __func__, *stop_status); + *gen_err = 1; + } + + return card_busy_detect(card, timeout_ms, use_r1b_resp, req, gen_err); +} + #define ERR_NOMEDIUM 3 #define ERR_RETRY 2 #define ERR_ABORT 1 @@ -789,6 +1020,9 @@ if (!err) break; + /* Re-tune if needed */ + mmc_retune_recheck(card->host); + prev_cmd_status_valid = false; pr_err("%s: error %d sending status command, %sing\n", req->rq_disk->disk_name, err, retry ? "retry" : "abort"); @@ -824,26 +1058,21 @@ */ if (R1_CURRENT_STATE(status) == R1_STATE_DATA || R1_CURRENT_STATE(status) == R1_STATE_RCV) { - err = send_stop(card, &stop_status); - if (err) + err = send_stop(card, + DIV_ROUND_UP(brq->data.timeout_ns, 1000000), + req, gen_err, &stop_status); + if (err) { pr_err("%s: error %d sending stop command\n", req->rq_disk->disk_name, err); - - /* - * If the stop cmd also timed out, the card is probably - * not present, so abort. Other errors are bad news too. - */ - if (err) + /* + * If the stop cmd also timed out, the card is probably + * not present, so abort. Other errors are bad news too. + */ return ERR_ABORT; + } + if (stop_status & R1_CARD_ECC_FAILED) *ecc_err = 1; - if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) - if (stop_status & R1_ERROR) { - pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n", - req->rq_disk->disk_name, __func__, - stop_status); - *gen_err = 1; - } } /* Check for set block count errors */ @@ -861,7 +1090,7 @@ return ERR_CONTINUE; /* Now for stop errors. These aren't fatal to the transfer. */ - pr_err("%s: error %d sending stop command, original cmd response %#x, card status %#x\n", + pr_info("%s: error %d sending stop command, original cmd response %#x, card status %#x\n", req->rq_disk->disk_name, brq->stop.error, brq->cmd.resp[0], status); @@ -888,7 +1117,8 @@ err = mmc_hw_reset(host); /* Ensure we switch back to the correct partition */ if (err != -EOPNOTSUPP) { - struct mmc_blk_data *main_md = mmc_get_drvdata(host->card); + struct mmc_blk_data *main_md = + dev_get_drvdata(&host->card->dev); int part_err; main_md->part_curr = main_md->part_type; @@ -969,10 +1199,10 @@ { struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; - unsigned int from, nr, arg, trim_arg, erase_arg; + unsigned int from, nr, arg; int err = 0, type = MMC_BLK_SECDISCARD; - if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { + if (!(mmc_can_secure_erase_trim(card))) { err = -EOPNOTSUPP; goto out; } @@ -980,23 +1210,11 @@ from = blk_rq_pos(req); nr = blk_rq_sectors(req); - /* The sanitize operation is supported at v4.5 only */ - if (mmc_can_sanitize(card)) { - erase_arg = MMC_ERASE_ARG; - trim_arg = MMC_TRIM_ARG; - } else { - erase_arg = MMC_SECURE_ERASE_ARG; - trim_arg = MMC_SECURE_TRIM1_ARG; - } + if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) + arg = MMC_SECURE_TRIM1_ARG; + else + arg = MMC_SECURE_ERASE_ARG; - if (mmc_erase_group_aligned(card, from, nr)) - arg = erase_arg; - else if (mmc_can_trim(card)) - arg = trim_arg; - else { - err = -EINVAL; - goto out; - } retry: if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -1032,9 +1250,6 @@ goto out; } - if (mmc_can_sanitize(card)) - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_SANITIZE_START, 1, 0); out_retry: if (err && !mmc_blk_reset(md, card->host, type)) goto retry; @@ -1099,6 +1314,7 @@ mmc_active); struct mmc_blk_request *brq = &mq_mrq->brq; struct request *req = mq_mrq->req; + int need_retune = card->host->need_retune; int ecc_err = 0, gen_err = 0; /* @@ -1142,8 +1358,7 @@ * program mode, which we have to wait for it to complete. */ if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { - u32 status; - unsigned long timeout; + int err; /* Check stop command response */ if (brq->stop.resp[0] & R1_ERROR) { @@ -1153,39 +1368,10 @@ gen_err = 1; } - timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS); - do { - int err = get_card_status(card, &status, 5); - if (err) { - pr_err("%s: error %d requesting status\n", - req->rq_disk->disk_name, err); - return MMC_BLK_CMD_ERR; - } - - if (status & R1_ERROR) { - pr_err("%s: %s: general error sending status command, card status %#x\n", - req->rq_disk->disk_name, __func__, - status); - gen_err = 1; - } - - /* Timeout if the device never becomes ready for data - * and never leaves the program state. - */ - if (time_after(jiffies, timeout)) { - pr_err("%s: Card stuck in programming state!"\ - " %s %s\n", mmc_hostname(card->host), - req->rq_disk->disk_name, __func__); - - return MMC_BLK_CMD_ERR; - } - /* - * Some cards mishandle the status bits, - * so make sure to check both the busy - * indication and the card state. - */ - } while (!(status & R1_READY_FOR_DATA) || - (R1_CURRENT_STATE(status) == R1_STATE_PRG)); + err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, false, req, + &gen_err); + if (err) + return MMC_BLK_CMD_ERR; } /* if general error occurs, retry the write operation. */ @@ -1196,6 +1382,12 @@ } if (brq->data.error) { + if (need_retune && !brq->retune_retry_done) { + pr_info("%s: retrying because a re-tune was needed\n", + req->rq_disk->disk_name); + brq->retune_retry_done = 1; + return MMC_BLK_RETRY; + } pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n", req->rq_disk->disk_name, brq->data.error, (unsigned)blk_rq_pos(req), @@ -1249,19 +1441,11 @@ } if (status & R1_EXCEPTION_EVENT) { - ext_csd = kzalloc(512, GFP_KERNEL); - if (!ext_csd) { - pr_err("%s: unable to allocate buffer for ext_csd\n", - req->rq_disk->disk_name); - return -ENOMEM; - } - - err = mmc_send_ext_csd(card, ext_csd); + err = mmc_get_ext_csd(card, &ext_csd); if (err) { pr_err("%s: error %d sending ext_csd\n", req->rq_disk->disk_name, err); - check = MMC_BLK_ABORT; - goto free; + return MMC_BLK_ABORT; } if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] & @@ -1279,7 +1463,6 @@ req->rq_disk->disk_name, packed->nr_entries, packed->blocks, packed->idx_failure); } -free: kfree(ext_csd); } @@ -1316,7 +1499,6 @@ brq->data.blksz = 512; brq->stop.opcode = MMC_STOP_TRANSMISSION; brq->stop.arg = 0; - brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; brq->data.blocks = blk_rq_sectors(req); /* @@ -1336,10 +1518,15 @@ if (disable_multi) brq->data.blocks = 1; - /* Some controllers can't do multiblock reads due to hw bugs */ - if (card->host->caps2 & MMC_CAP2_NO_MULTI_READ && - rq_data_dir(req) == READ) - brq->data.blocks = 1; + /* + * Some controllers have HW issues while operating + * in multiple I/O mode + */ + if (card->host->ops->multi_io_quirk) + brq->data.blocks = card->host->ops->multi_io_quirk(card, + (rq_data_dir(req) == READ) ? + MMC_DATA_READ : MMC_DATA_WRITE, + brq->data.blocks); } if (brq->data.blocks > 1 || do_rel_wr) { @@ -1359,9 +1546,15 @@ if (rq_data_dir(req) == READ) { brq->cmd.opcode = readcmd; brq->data.flags |= MMC_DATA_READ; + if (brq->mrq.stop) + brq->stop.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | + MMC_CMD_AC; } else { brq->cmd.opcode = writecmd; brq->data.flags |= MMC_DATA_WRITE; + if (brq->mrq.stop) + brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | + MMC_CMD_AC; } if (do_rel_wr) @@ -1431,6 +1624,7 @@ } mqrq->mmc_active.mrq = &brq->mrq; + mqrq->mmc_active.mrq->req = mqrq->req; mqrq->mmc_active.err_check = mmc_blk_err_check; mmc_queue_bounce_pre(mqrq); @@ -1570,7 +1764,7 @@ struct mmc_blk_data *md = mq->data; struct mmc_packed *packed = mqrq->packed; bool do_rel_wr, do_data_tag; - u32 *packed_cmd_hdr; + __le32 *packed_cmd_hdr; u8 hdr_blocks; u8 i = 1; @@ -1750,7 +1944,7 @@ struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_blk_request *brq = &mq->mqrq_cur->brq; - int ret = 1, disable_multi = 0, retry = 0, type; + int ret = 1, disable_multi = 0, retry = 0, type, retune_retry_done = 0; enum mmc_blk_status status; struct mmc_queue_req *mq_rq; struct request *req = rqc; @@ -1836,6 +2030,7 @@ goto start_new_req; break; case MMC_BLK_RETRY: + retune_retry_done = brq->retune_retry_done; if (retry++ < 5) break; /* Fall through */ @@ -1857,8 +2052,8 @@ case MMC_BLK_ECC_ERR: if (brq->data.blocks > 1) { /* Redo read one sector at a time */ - pr_warning("%s: retrying using single block read\n", - req->rq_disk->disk_name); + pr_warn("%s: retrying using single block read\n", + req->rq_disk->disk_name); disable_multi = 1; break; } @@ -1898,6 +2093,7 @@ mmc_start_req(card->host, &mq_rq->mmc_active, NULL); } + mq_rq->brq.retune_retry_done = retune_retry_done; } } while (ret); @@ -1946,7 +2142,7 @@ if (req && !mq->mqrq_prev->req) /* claim host only for the first request */ - mmc_claim_host(card->host); + mmc_get_card(card); ret = mmc_blk_part_switch(card, md); if (ret) { @@ -1962,8 +2158,7 @@ /* complete ongoing async transfer before issuing discard */ if (card->host->areq) mmc_blk_issue_rw_rq(mq, NULL); - if (req->cmd_flags & REQ_SECURE && - !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN)) + if (req->cmd_flags & REQ_SECURE) ret = mmc_blk_issue_secdiscard_rq(mq, req); else ret = mmc_blk_issue_discard_rq(mq, req); @@ -1990,7 +2185,7 @@ * In case sepecial request, there is no reentry to * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'. */ - mmc_release_host(card->host); + mmc_put_card(card); return ret; } @@ -2023,7 +2218,7 @@ /* * !subname implies we are creating main mmc_blk_data that will be - * associated with mmc_card with mmc_set_drvdata. Due to device + * associated with mmc_card with dev_set_drvdata. Due to device * partitions, devidx will not coincide with a per-physical card * index anymore so we keep track of a name index. */ @@ -2066,7 +2261,7 @@ md->disk->queue = md->queue.queue; md->disk->driverfs_dev = parent; set_disk_ro(md->disk, md->read_only || default_ro); - if (area_type & MMC_BLK_DATA_AREA_RPMB) + if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) md->disk->flags |= GENHD_FL_NO_PART_SCAN; /* @@ -2082,7 +2277,7 @@ */ snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), - "mmcblk%d%s", md->name_idx, subname ? subname : ""); + "mmcblk%u%s", md->name_idx, subname ? subname : ""); if (mmc_card_mmc(card)) blk_queue_logical_block_size(md->queue.queue, @@ -2129,7 +2324,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) { sector_t size; - struct mmc_blk_data *md; if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { /* @@ -2142,12 +2336,12 @@ * The CSD capacity field is in units of read_blkbits. * set_capacity takes units of 512 bytes. */ - size = card->csd.capacity << (card->csd.read_blkbits - 9); + size = (typeof(sector_t))card->csd.capacity + << (card->csd.read_blkbits - 9); } - md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL, + return mmc_blk_alloc_req(card, &card->dev, size, false, NULL, MMC_BLK_DATA_AREA_MAIN); - return md; } static int mmc_blk_alloc_part(struct mmc_card *card, @@ -2168,7 +2362,7 @@ part_md->part_type = part_type; list_add(&part_md->part, &md->part); - string_get_size((u64)get_capacity(part_md->disk) << 9, STRING_UNITS_2, + string_get_size((u64)get_capacity(part_md->disk), 512, STRING_UNITS_2, cap_str, sizeof(cap_str)); pr_info("%s: %s %s partition %u %s\n", part_md->disk->disk_name, mmc_card_id(card), @@ -2210,7 +2404,15 @@ struct mmc_card *card; if (md) { + /* + * Flush remaining requests and free queues. It + * is freeing the queue that stops new requests + * from being accepted. + */ card = md->queue.card; + mmc_cleanup_queue(&md->queue); + if (md->flags & MMC_BLK_PACKED_CMD) + mmc_packed_clean(&md->queue); if (md->disk->flags & GENHD_FL_UP) { device_remove_file(disk_to_dev(md->disk), &md->force_ro); if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && @@ -2218,14 +2420,8 @@ device_remove_file(disk_to_dev(md->disk), &md->power_ro_lock); - /* Stop new requests from getting into the queue */ del_gendisk(md->disk); } - - /* Then flush out any already in there */ - mmc_cleanup_queue(&md->queue); - if (md->flags & MMC_BLK_PACKED_CMD) - mmc_packed_clean(&md->queue); mmc_blk_put(md); } } @@ -2293,6 +2489,7 @@ #define CID_MANFID_TOSHIBA 0x11 #define CID_MANFID_MICRON 0x13 #define CID_MANFID_SAMSUNG 0x15 +#define CID_MANFID_KINGSTON 0x70 static const struct mmc_fixup blk_fixups[] = { @@ -2315,6 +2512,10 @@ * * N.B. This doesn't affect SD cards. */ + MMC_FIXUP("SDMB-32", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_BLK_NO_CMD23), + MMC_FIXUP("SDM032", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_BLK_NO_CMD23), MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, MMC_QUIRK_BLK_NO_CMD23), MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, @@ -2352,6 +2553,15 @@ MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), + /* + * On Some Kingston eMMCs, performing trim can result in + * unrecoverable data conrruption occasionally due to a firmware bug. + */ + MMC_FIXUP("V10008", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_TRIM_BROKEN), + MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_TRIM_BROKEN), + END_FIXUP }; @@ -2366,11 +2576,13 @@ if (!(card->csd.cmdclass & CCC_BLOCK_READ)) return -ENODEV; + mmc_fixup_device(card, blk_fixups); + md = mmc_blk_alloc(card); if (IS_ERR(md)) return PTR_ERR(md); - string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, + string_get_size((u64)get_capacity(md->disk), 512, STRING_UNITS_2, cap_str, sizeof(cap_str)); pr_info("%s: %s %s %s %s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), @@ -2379,8 +2591,7 @@ if (mmc_blk_alloc_parts(card, md)) goto out; - mmc_set_drvdata(card, md); - mmc_fixup_device(card, blk_fixups); + dev_set_drvdata(&card->dev, md); if (mmc_add_disk(md)) goto out; @@ -2389,6 +2600,19 @@ if (mmc_add_disk(part_md)) goto out; } + + pm_runtime_set_autosuspend_delay(&card->dev, 3000); + pm_runtime_use_autosuspend(&card->dev); + + /* + * Don't enable runtime PM for SD-combo cards here. Leave that + * decision to be taken during the SDIO init sequence instead. + */ + if (card->type != MMC_TYPE_SD_COMBO) { + pm_runtime_set_active(&card->dev); + pm_runtime_enable(&card->dev); + } + return 0; out: @@ -2399,21 +2623,24 @@ static void mmc_blk_remove(struct mmc_card *card) { - struct mmc_blk_data *md = mmc_get_drvdata(card); + struct mmc_blk_data *md = dev_get_drvdata(&card->dev); mmc_blk_remove_parts(card, md); + pm_runtime_get_sync(&card->dev); mmc_claim_host(card->host); mmc_blk_part_switch(card, md); mmc_release_host(card->host); + if (card->type != MMC_TYPE_SD_COMBO) + pm_runtime_disable(&card->dev); + pm_runtime_put_noidle(&card->dev); mmc_blk_remove_req(md); - mmc_set_drvdata(card, NULL); + dev_set_drvdata(&card->dev, NULL); } -#ifdef CONFIG_PM -static int mmc_blk_suspend(struct mmc_card *card) +static int _mmc_blk_suspend(struct mmc_card *card) { struct mmc_blk_data *part_md; - struct mmc_blk_data *md = mmc_get_drvdata(card); + struct mmc_blk_data *md = dev_get_drvdata(&card->dev); if (md) { mmc_queue_suspend(&md->queue); @@ -2424,10 +2651,23 @@ return 0; } -static int mmc_blk_resume(struct mmc_card *card) +static void mmc_blk_shutdown(struct mmc_card *card) +{ + _mmc_blk_suspend(card); +} + +#ifdef CONFIG_PM_SLEEP +static int mmc_blk_suspend(struct device *dev) +{ + struct mmc_card *card = mmc_dev_to_card(dev); + + return _mmc_blk_suspend(card); +} + +static int mmc_blk_resume(struct device *dev) { struct mmc_blk_data *part_md; - struct mmc_blk_data *md = mmc_get_drvdata(card); + struct mmc_blk_data *md = dev_get_drvdata(dev); if (md) { /* @@ -2442,19 +2682,18 @@ } return 0; } -#else -#define mmc_blk_suspend NULL -#define mmc_blk_resume NULL #endif +static SIMPLE_DEV_PM_OPS(mmc_blk_pm_ops, mmc_blk_suspend, mmc_blk_resume); + static struct mmc_driver mmc_driver = { .drv = { .name = "mmcblk", + .pm = &mmc_blk_pm_ops, }, .probe = mmc_blk_probe, .remove = mmc_blk_remove, - .suspend = mmc_blk_suspend, - .resume = mmc_blk_resume, + .shutdown = mmc_blk_shutdown, }; static int __init mmc_blk_init(void) @@ -2464,7 +2703,7 @@ if (perdev_minors != CONFIG_MMC_BLOCK_MINORS) pr_info("mmcblk: using %d minors per device\n", perdev_minors); - max_devices = 256 / perdev_minors; + max_devices = min(MAX_DEVICES, (1 << MINORBITS) / perdev_minors); res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); if (res)