diff options
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r-- | drivers/mmc/card/block.c | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index eed213a5c8cb..dabec556ebb8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, | |||
873 | { | 873 | { |
874 | struct mmc_blk_data *md = mq->data; | 874 | struct mmc_blk_data *md = mq->data; |
875 | struct mmc_card *card = md->queue.card; | 875 | struct mmc_card *card = md->queue.card; |
876 | unsigned int from, nr, arg; | 876 | unsigned int from, nr, arg, trim_arg, erase_arg; |
877 | int err = 0, type = MMC_BLK_SECDISCARD; | 877 | int err = 0, type = MMC_BLK_SECDISCARD; |
878 | 878 | ||
879 | if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { | 879 | if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { |
@@ -881,20 +881,26 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, | |||
881 | goto out; | 881 | goto out; |
882 | } | 882 | } |
883 | 883 | ||
884 | from = blk_rq_pos(req); | ||
885 | nr = blk_rq_sectors(req); | ||
886 | |||
884 | /* The sanitize operation is supported at v4.5 only */ | 887 | /* The sanitize operation is supported at v4.5 only */ |
885 | if (mmc_can_sanitize(card)) { | 888 | if (mmc_can_sanitize(card)) { |
886 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 889 | erase_arg = MMC_ERASE_ARG; |
887 | EXT_CSD_SANITIZE_START, 1, 0); | 890 | trim_arg = MMC_TRIM_ARG; |
888 | goto out; | 891 | } else { |
892 | erase_arg = MMC_SECURE_ERASE_ARG; | ||
893 | trim_arg = MMC_SECURE_TRIM1_ARG; | ||
889 | } | 894 | } |
890 | 895 | ||
891 | from = blk_rq_pos(req); | 896 | if (mmc_erase_group_aligned(card, from, nr)) |
892 | nr = blk_rq_sectors(req); | 897 | arg = erase_arg; |
893 | 898 | else if (mmc_can_trim(card)) | |
894 | if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) | 899 | arg = trim_arg; |
895 | arg = MMC_SECURE_TRIM1_ARG; | 900 | else { |
896 | else | 901 | err = -EINVAL; |
897 | arg = MMC_SECURE_ERASE_ARG; | 902 | goto out; |
903 | } | ||
898 | retry: | 904 | retry: |
899 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { | 905 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { |
900 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 906 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
@@ -904,25 +910,41 @@ retry: | |||
904 | INAND_CMD38_ARG_SECERASE, | 910 | INAND_CMD38_ARG_SECERASE, |
905 | 0); | 911 | 0); |
906 | if (err) | 912 | if (err) |
907 | goto out; | 913 | goto out_retry; |
908 | } | 914 | } |
915 | |||
909 | err = mmc_erase(card, from, nr, arg); | 916 | err = mmc_erase(card, from, nr, arg); |
910 | if (!err && arg == MMC_SECURE_TRIM1_ARG) { | 917 | if (err == -EIO) |
918 | goto out_retry; | ||
919 | if (err) | ||
920 | goto out; | ||
921 | |||
922 | if (arg == MMC_SECURE_TRIM1_ARG) { | ||
911 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { | 923 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { |
912 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 924 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
913 | INAND_CMD38_ARG_EXT_CSD, | 925 | INAND_CMD38_ARG_EXT_CSD, |
914 | INAND_CMD38_ARG_SECTRIM2, | 926 | INAND_CMD38_ARG_SECTRIM2, |
915 | 0); | 927 | 0); |
916 | if (err) | 928 | if (err) |
917 | goto out; | 929 | goto out_retry; |
918 | } | 930 | } |
931 | |||
919 | err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); | 932 | err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); |
933 | if (err == -EIO) | ||
934 | goto out_retry; | ||
935 | if (err) | ||
936 | goto out; | ||
920 | } | 937 | } |
921 | out: | 938 | |
922 | if (err == -EIO && !mmc_blk_reset(md, card->host, type)) | 939 | if (mmc_can_sanitize(card)) |
940 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
941 | EXT_CSD_SANITIZE_START, 1, 0); | ||
942 | out_retry: | ||
943 | if (err && !mmc_blk_reset(md, card->host, type)) | ||
923 | goto retry; | 944 | goto retry; |
924 | if (!err) | 945 | if (!err) |
925 | mmc_blk_reset_success(md, type); | 946 | mmc_blk_reset_success(md, type); |
947 | out: | ||
926 | spin_lock_irq(&md->lock); | 948 | spin_lock_irq(&md->lock); |
927 | __blk_end_request(req, err, blk_rq_bytes(req)); | 949 | __blk_end_request(req, err, blk_rq_bytes(req)); |
928 | spin_unlock_irq(&md->lock); | 950 | spin_unlock_irq(&md->lock); |
@@ -1623,24 +1645,6 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) | |||
1623 | return ret; | 1645 | return ret; |
1624 | } | 1646 | } |
1625 | 1647 | ||
1626 | static int | ||
1627 | mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | ||
1628 | { | ||
1629 | int err; | ||
1630 | |||
1631 | mmc_claim_host(card->host); | ||
1632 | err = mmc_set_blocklen(card, 512); | ||
1633 | mmc_release_host(card->host); | ||
1634 | |||
1635 | if (err) { | ||
1636 | pr_err("%s: unable to set block size to 512: %d\n", | ||
1637 | md->disk->disk_name, err); | ||
1638 | return -EINVAL; | ||
1639 | } | ||
1640 | |||
1641 | return 0; | ||
1642 | } | ||
1643 | |||
1644 | static void mmc_blk_remove_req(struct mmc_blk_data *md) | 1648 | static void mmc_blk_remove_req(struct mmc_blk_data *md) |
1645 | { | 1649 | { |
1646 | struct mmc_card *card; | 1650 | struct mmc_card *card; |
@@ -1768,7 +1772,6 @@ static const struct mmc_fixup blk_fixups[] = | |||
1768 | static int mmc_blk_probe(struct mmc_card *card) | 1772 | static int mmc_blk_probe(struct mmc_card *card) |
1769 | { | 1773 | { |
1770 | struct mmc_blk_data *md, *part_md; | 1774 | struct mmc_blk_data *md, *part_md; |
1771 | int err; | ||
1772 | char cap_str[10]; | 1775 | char cap_str[10]; |
1773 | 1776 | ||
1774 | /* | 1777 | /* |
@@ -1781,10 +1784,6 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
1781 | if (IS_ERR(md)) | 1784 | if (IS_ERR(md)) |
1782 | return PTR_ERR(md); | 1785 | return PTR_ERR(md); |
1783 | 1786 | ||
1784 | err = mmc_blk_set_blksize(md, card); | ||
1785 | if (err) | ||
1786 | goto out; | ||
1787 | |||
1788 | string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, | 1787 | string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, |
1789 | cap_str, sizeof(cap_str)); | 1788 | cap_str, sizeof(cap_str)); |
1790 | pr_info("%s: %s %s %s %s\n", | 1789 | pr_info("%s: %s %s %s %s\n", |
@@ -1809,7 +1808,7 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
1809 | out: | 1808 | out: |
1810 | mmc_blk_remove_parts(card, md); | 1809 | mmc_blk_remove_parts(card, md); |
1811 | mmc_blk_remove_req(md); | 1810 | mmc_blk_remove_req(md); |
1812 | return err; | 1811 | return 0; |
1813 | } | 1812 | } |
1814 | 1813 | ||
1815 | static void mmc_blk_remove(struct mmc_card *card) | 1814 | static void mmc_blk_remove(struct mmc_card *card) |
@@ -1825,7 +1824,7 @@ static void mmc_blk_remove(struct mmc_card *card) | |||
1825 | } | 1824 | } |
1826 | 1825 | ||
1827 | #ifdef CONFIG_PM | 1826 | #ifdef CONFIG_PM |
1828 | static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) | 1827 | static int mmc_blk_suspend(struct mmc_card *card) |
1829 | { | 1828 | { |
1830 | struct mmc_blk_data *part_md; | 1829 | struct mmc_blk_data *part_md; |
1831 | struct mmc_blk_data *md = mmc_get_drvdata(card); | 1830 | struct mmc_blk_data *md = mmc_get_drvdata(card); |
@@ -1845,8 +1844,6 @@ static int mmc_blk_resume(struct mmc_card *card) | |||
1845 | struct mmc_blk_data *md = mmc_get_drvdata(card); | 1844 | struct mmc_blk_data *md = mmc_get_drvdata(card); |
1846 | 1845 | ||
1847 | if (md) { | 1846 | if (md) { |
1848 | mmc_blk_set_blksize(md, card); | ||
1849 | |||
1850 | /* | 1847 | /* |
1851 | * Resume involves the card going into idle state, | 1848 | * Resume involves the card going into idle state, |
1852 | * so current partition is always the main one. | 1849 | * so current partition is always the main one. |