diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2014-10-20 08:08:16 -0400 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-11-10 06:40:42 -0500 |
commit | c197787ced5b42bde224d9ee70473d87a824119a (patch) | |
tree | 4040c515d4ab287ba05104d1d1efd4261d3ec66b | |
parent | 076ec38a58584dc85c837bd52b4ec3d9cd02b393 (diff) |
mmc: core: Let's callers of from mmc_get_ext_csd() do error handling
The callers of mmc_get_ext_csd() need the flexibility to handle errors
themselves, because they behave differently.
Let's clean up mmc_get_ext_csd() with its friends and adopt the error
handling as stated above.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r-- | drivers/mmc/core/mmc.c | 70 |
1 files changed, 31 insertions, 39 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 13f8e3672606..fe801e612b1f 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -188,10 +188,8 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) | |||
188 | BUG_ON(!card); | 188 | BUG_ON(!card); |
189 | BUG_ON(!new_ext_csd); | 189 | BUG_ON(!new_ext_csd); |
190 | 190 | ||
191 | *new_ext_csd = NULL; | ||
192 | |||
193 | if (!mmc_can_ext_csd(card)) | 191 | if (!mmc_can_ext_csd(card)) |
194 | return 0; | 192 | return -EOPNOTSUPP; |
195 | 193 | ||
196 | /* | 194 | /* |
197 | * As the ext_csd is so large and mostly unused, we don't store the | 195 | * As the ext_csd is so large and mostly unused, we don't store the |
@@ -202,32 +200,9 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) | |||
202 | return -ENOMEM; | 200 | return -ENOMEM; |
203 | 201 | ||
204 | err = mmc_send_ext_csd(card, ext_csd); | 202 | err = mmc_send_ext_csd(card, ext_csd); |
205 | if (err) { | 203 | if (err) |
206 | kfree(ext_csd); | 204 | kfree(ext_csd); |
207 | *new_ext_csd = NULL; | 205 | else |
208 | |||
209 | /* If the host or the card can't do the switch, | ||
210 | * fail more gracefully. */ | ||
211 | if ((err != -EINVAL) | ||
212 | && (err != -ENOSYS) | ||
213 | && (err != -EFAULT)) | ||
214 | return err; | ||
215 | |||
216 | /* | ||
217 | * High capacity cards should have this "magic" size | ||
218 | * stored in their CSD. | ||
219 | */ | ||
220 | if (card->csd.capacity == (4096 * 512)) { | ||
221 | pr_err("%s: unable to read EXT_CSD " | ||
222 | "on a possible high capacity card. " | ||
223 | "Card will be ignored.\n", | ||
224 | mmc_hostname(card->host)); | ||
225 | } else { | ||
226 | pr_warn("%s: unable to read EXT_CSD, performance might suffer\n", | ||
227 | mmc_hostname(card->host)); | ||
228 | err = 0; | ||
229 | } | ||
230 | } else | ||
231 | *new_ext_csd = ext_csd; | 206 | *new_ext_csd = ext_csd; |
232 | 207 | ||
233 | return err; | 208 | return err; |
@@ -395,9 +370,6 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
395 | 370 | ||
396 | BUG_ON(!card); | 371 | BUG_ON(!card); |
397 | 372 | ||
398 | if (!ext_csd) | ||
399 | return 0; | ||
400 | |||
401 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ | 373 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ |
402 | card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; | 374 | card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; |
403 | if (card->csd.structure == 3) { | 375 | if (card->csd.structure == 3) { |
@@ -639,12 +611,36 @@ out: | |||
639 | 611 | ||
640 | static int mmc_read_ext_csd(struct mmc_card *card) | 612 | static int mmc_read_ext_csd(struct mmc_card *card) |
641 | { | 613 | { |
642 | u8 *ext_csd = NULL; | 614 | u8 *ext_csd; |
643 | int err; | 615 | int err; |
644 | 616 | ||
617 | if (!mmc_can_ext_csd(card)) | ||
618 | return 0; | ||
619 | |||
645 | err = mmc_get_ext_csd(card, &ext_csd); | 620 | err = mmc_get_ext_csd(card, &ext_csd); |
646 | if (err) | 621 | if (err) { |
622 | /* If the host or the card can't do the switch, | ||
623 | * fail more gracefully. */ | ||
624 | if ((err != -EINVAL) | ||
625 | && (err != -ENOSYS) | ||
626 | && (err != -EFAULT)) | ||
627 | return err; | ||
628 | |||
629 | /* | ||
630 | * High capacity cards should have this "magic" size | ||
631 | * stored in their CSD. | ||
632 | */ | ||
633 | if (card->csd.capacity == (4096 * 512)) { | ||
634 | pr_err("%s: unable to read EXT_CSD on a possible high capacity card. Card will be ignored.\n", | ||
635 | mmc_hostname(card->host)); | ||
636 | } else { | ||
637 | pr_warn("%s: unable to read EXT_CSD, performance might suffer\n", | ||
638 | mmc_hostname(card->host)); | ||
639 | err = 0; | ||
640 | } | ||
641 | |||
647 | return err; | 642 | return err; |
643 | } | ||
648 | 644 | ||
649 | err = mmc_decode_ext_csd(card, ext_csd); | 645 | err = mmc_decode_ext_csd(card, ext_csd); |
650 | kfree(ext_csd); | 646 | kfree(ext_csd); |
@@ -660,11 +656,8 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) | |||
660 | return 0; | 656 | return 0; |
661 | 657 | ||
662 | err = mmc_get_ext_csd(card, &bw_ext_csd); | 658 | err = mmc_get_ext_csd(card, &bw_ext_csd); |
663 | 659 | if (err) | |
664 | if (err || bw_ext_csd == NULL) { | 660 | return err; |
665 | err = -EINVAL; | ||
666 | goto out; | ||
667 | } | ||
668 | 661 | ||
669 | /* only compare read only fields */ | 662 | /* only compare read only fields */ |
670 | err = !((card->ext_csd.raw_partition_support == | 663 | err = !((card->ext_csd.raw_partition_support == |
@@ -723,7 +716,6 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) | |||
723 | if (err) | 716 | if (err) |
724 | err = -EINVAL; | 717 | err = -EINVAL; |
725 | 718 | ||
726 | out: | ||
727 | kfree(bw_ext_csd); | 719 | kfree(bw_ext_csd); |
728 | return err; | 720 | return err; |
729 | } | 721 | } |