Message ID | 1341564244-6178-6-git-send-email-loic.pallardy@stericsson.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Jul 6, 2012 at 10:44 AM, Loic Pallardy <loic.pallardy@stericsson.com> wrote: > RPMB partition is accessing though /dev/block/mmcXrpmb device > User callers can read and write entire data frame(s) as defined > by JEDEC Standard JESD84-A441, using standard IOCTL interface. > > Signed-off-by: Alex Macro <alex.macro@stericsson.com> > Signed-off-by: Loic Pallardy <loic.pallardy@stericsson.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
2012/7/8 Linus Walleij <linus.walleij@linaro.org>: > On Fri, Jul 6, 2012 at 10:44 AM, Loic Pallardy > <loic.pallardy@stericsson.com> wrote: > >> RPMB partition is accessing though /dev/block/mmcXrpmb device >> User callers can read and write entire data frame(s) as defined >> by JEDEC Standard JESD84-A441, using standard IOCTL interface. >> >> Signed-off-by: Alex Macro <alex.macro@stericsson.com> >> Signed-off-by: Loic Pallardy <loic.pallardy@stericsson.com> > > Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Johan Rudholm <johan.rudholm@stericsson.com> -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> > + err = mmc_blk_part_switch(card, md); > + if (err) > + goto cmd_rel_host; > + Should it wrapped by if (is_rpbm) condition ? It can be called in other ioctl. > if (idata->ic.is_acmd) { > err = mmc_app_cmd(card->host, card); > if (err) > goto cmd_rel_host; > } -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Repost in text format 2012/7/10 Namjae Jeon <linkinjeon@gmail.com> > > > > > + err = mmc_blk_part_switch(card, md); > > + if (err) > > + goto cmd_rel_host; > > + > Should it wrapped by if (is_rpbm) condition ? It can be called in other > ioctl. It was my first implementation, but in that case you have to manage a session, switching on RPMB partition at the begining of the IOCTL and restore previous partition at the end. (because RPMB partition doesn't support all commands). Having a look to how mmc driver manages partition selection, I saw that mmc_blk_issue_rq for instance calls mmc_blk_part_switch in the beginning to be sure it's on the right partition, but never restores The proposal is to use same way and to make it compliant with Boot and GP partitions if there are any special commands supported by them. > > > if (idata->ic.is_acmd) { > > err = mmc_app_cmd(card->host, card); > > if (err) > > goto cmd_rel_host; > > } > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
2012/7/10, Loic pallardy <loic.pallardy@gmail.com>: > Repost in text format > > 2012/7/10 Namjae Jeon <linkinjeon@gmail.com> >> >> > >> > + err = mmc_blk_part_switch(card, md); >> > + if (err) >> > + goto cmd_rel_host; >> > + >> Should it wrapped by if (is_rpbm) condition ? It can be called in other >> ioctl. > It was my first implementation, but in that case you have to manage a > session, switching on RPMB partition at the begining of the IOCTL and > restore previous partition at the end. (because RPMB partition doesn't > support all commands). > > Having a look to how mmc driver manages partition selection, I saw > that mmc_blk_issue_rq for instance calls mmc_blk_part_switch in the > beginning to be sure it's on the right partition, but never restores > > The proposal is to use same way and to make it compliant with Boot and > GP partitions if there are any special commands supported by them. Okay, I understood what you mean. we should change partition switching in other ioctl again after ioctl about rpmb is called. Reviewed-by: Namjae Jeon <linkinjeon@gmail.com> >> >> > if (idata->ic.is_acmd) { >> > err = mmc_app_cmd(card->host, card); >> > if (err) >> > goto cmd_rel_host; >> > } >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1b202fe..a9956cf 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -126,6 +126,10 @@ enum mmc_blk_status { module_param(perdev_minors, int, 0444); MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); +static inline int mmc_blk_part_switch(struct mmc_card *card, + struct mmc_blk_data *md); +static int get_card_status(struct mmc_card *card, u32 *status, int retries); + static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) { struct mmc_blk_data *md; @@ -357,6 +361,38 @@ out: return ERR_PTR(err); } +static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status, + u32 retries_max) +{ + int err; + u32 retry_count = 0; + + if (!status || !retries_max) + return -EINVAL; + + do { + err = get_card_status(card, status, 5); + if (err) + break; + + if (!R1_STATUS(*status) && + (R1_CURRENT_STATE(*status) != R1_STATE_PRG)) + break; /* RPMB programming operation complete */ + + /* + * Rechedule to give the MMC device a chance to continue + * processing the previous command without being polled too + * frequently. + */ + usleep_range(1000, 5000); + } while (++retry_count < retries_max); + + if (retry_count == retries_max) + err = -EPERM; + + return err; +} + static int mmc_blk_ioctl_cmd(struct block_device *bdev, struct mmc_ioc_cmd __user *ic_ptr) { @@ -368,6 +404,8 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, struct mmc_request mrq = {NULL}; struct scatterlist sg; int err; + int is_rpmb = false; + u32 status = 0; /* * The caller must have CAP_SYS_RAWIO, and must be calling this on the @@ -387,6 +425,9 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, goto cmd_err; } + if (md->area_type & MMC_BLK_DATA_AREA_RPMB) + is_rpmb = true; + card = md->queue.card; if (IS_ERR(card)) { err = PTR_ERR(card); @@ -437,12 +478,23 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, mmc_claim_host(card->host); + err = mmc_blk_part_switch(card, md); + if (err) + goto cmd_rel_host; + if (idata->ic.is_acmd) { err = mmc_app_cmd(card->host, card); if (err) goto cmd_rel_host; } + if (is_rpmb) { + err = mmc_set_blockcount(card, data.blocks, + idata->ic.write_flag & (1 << 31)); + if (err) + goto cmd_rel_host; + } + mmc_wait_for_req(card->host, &mrq); if (cmd.error) { @@ -478,6 +530,18 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, } } + if (is_rpmb) { + /* + * Ensure RPMB command has completed by polling CMD13 + * "Send Status". + */ + err = ioctl_rpmb_card_status_poll(card, &status, 5); + if (err) + dev_err(mmc_dev(card->host), + "%s: Card Status=0x%08X, error %d\n", + __func__, status, err); + } + cmd_rel_host: mmc_release_host(card->host);